From ddbd6c371d08c09018149eca014242f1f98bb70d Mon Sep 17 00:00:00 2001 From: arnaud Date: Fri, 20 Jan 2017 11:58:30 +0100 Subject: [PATCH 001/233] MERGE DEGUEU --- build/pad/DoliWamp.pml | 2 +- build/pad/Dolibarr.pml | 16 ++++++++-------- build/pad/pad_dolibarr.xml | 16 ++++++++-------- build/pad/pad_doliwamp.xml | 2 +- .../phpexcel/Classes/PHPExcel/locale/cs/config | 2 +- .../Classes/PHPExcel/locale/cs/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/da/config | 4 ++-- .../Classes/PHPExcel/locale/da/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/de/config | 4 ++-- .../Classes/PHPExcel/locale/de/functions | 2 +- .../Classes/PHPExcel/locale/en/uk/config | 2 +- .../phpexcel/Classes/PHPExcel/locale/es/config | 4 ++-- .../Classes/PHPExcel/locale/es/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/fi/config | 4 ++-- .../Classes/PHPExcel/locale/fi/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/fr/config | 4 ++-- .../Classes/PHPExcel/locale/fr/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/hu/config | 2 +- .../Classes/PHPExcel/locale/hu/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/it/config | 4 ++-- .../Classes/PHPExcel/locale/it/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/nl/config | 4 ++-- .../Classes/PHPExcel/locale/nl/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/no/config | 4 ++-- .../Classes/PHPExcel/locale/no/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/pl/config | 4 ++-- .../Classes/PHPExcel/locale/pl/functions | 2 +- .../Classes/PHPExcel/locale/pt/br/config | 4 ++-- .../phpexcel/Classes/PHPExcel/locale/pt/config | 4 ++-- .../phpexcel/Classes/PHPExcel/locale/ru/config | 4 ++-- .../Classes/PHPExcel/locale/ru/functions | 2 +- .../phpexcel/Classes/PHPExcel/locale/sv/config | 4 ++-- .../phpexcel/Classes/PHPExcel/locale/tr/config | 4 ++-- .../Classes/PHPExcel/locale/tr/functions | 2 +- 34 files changed, 62 insertions(+), 62 deletions(-) diff --git a/build/pad/DoliWamp.pml b/build/pad/DoliWamp.pml index e0f2b99bfec..fa2da1902aa 100644 --- a/build/pad/DoliWamp.pml +++ b/build/pad/DoliWamp.pml @@ -42,7 +42,7 @@ DoliWamp, the easy to use Dolibarr for Windows to manage your company,foundation DoliWamp is the Dolibarr ERP/CRM for Windows, the easy to use open source software to manage your activity (invoices, customers, suppliers, contracts, agenda, emailings...) and any other things a small or mid-sized business or a foundation needs. DoliWamp is the Dolibarr ERP/CRM autoinstaller for Windows users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. Dolibarr ERP/CRM is a software package built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. - DoliWamp is the Dolibarr ERP/CRM for Windows. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations (You can manage or follow contacts, invoices, orders, commercial proposals, products, stock management, agenda, mass emailings, members of a foundation, bank accounts...). Based on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems), you can install it as a standalone program or use it from anywhere with any web browser. Dolibarr is an OpenSource project. It differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: Simple to install, Simple to use, Simple to develop. + DoliWamp is the Dolibarr ERP/CRM for Windows. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations (You can manage or follow contacts, invoices, orders, commercial proposals, products, stock management, agenda, mass emailings, members of a foundation, bank accounts...). Based on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems), you can install it as a standalone program or use it from anywhere with any web browser. Dolibarr is an OpenSource project. It differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: Simple to install, Simple to use, Simple to develop. DoliWamp is the auto-installer for Windows users with no technical knowledge to install Dolibarr ERP/CRM and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. diff --git a/build/pad/Dolibarr.pml b/build/pad/Dolibarr.pml index 250aed0d791..3ef5e16137c 100644 --- a/build/pad/Dolibarr.pml +++ b/build/pad/Dolibarr.pml @@ -42,10 +42,10 @@ Dolibarr ERP & CRM, the easy to use open source software to manage your activity Dolibarr ERP & CRM, the easy to use open source software to manage your activity (invoices, customers, suppliers, contracts, agenda, emailings...) and any other things a small or mid-sized business or a foundation needs to follow. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or medium companies, freelancers or foundations. We can say Dolibarr is an ERP or CRM. Dolibarr is also available with an auto-installer for Windows users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. See DoliWamp software for this. - Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. We can say Dolibarr is an ERP or CRM (or both depending on activated modules). It's an OpenSource project base on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems). Dolibarr differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: -Simple to install -Simple to use -Simple to develop + Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. We can say Dolibarr is an ERP or CRM (or both depending on activated modules). It's an OpenSource project base on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems). Dolibarr differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: +Simple to install +Simple to use +Simple to develop Note that Dolibarr is also available with an auto-installer for Windows or Ubuntu users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. This version is called DoliWamp (for Windows) or DoliBuntu (for Ubuntu/Debian). @@ -62,10 +62,10 @@ Note that Dolibarr is also available with an auto-installer for Windows or Ubunt Dolibarr ERP & CRM, le gestionnaire simple pour gérer votre activité Dolibarr ERP & CRM, le logiciel simple et OpenSource pour gérer votre activité (factures, devis, facturation, commandes, compta, trésorerie, stocks, produits, agenda, comptes bancaires, associations) Dolibarr ERP/CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). - Dolibarr ERP/CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). Dolibarr vient compléter les offres déjà nombreuses de logiciels de cette catégorie (comme OpenBravo, OpenERP, SugarCRM, Neogia, Compiere, etc.) mais se démarque par le fait qu'ici tout est fait pour offrir de la simplicité (règle des 3 S): -Simple pour l'installation (avec au choix des installeurs clé en main pour ceux qui ignorent comment installer un serveur Web, ou une installation manuelle) -Simple pour l'utilisation (fonctions modulaires pour ne pas surcharger les menus, informations claires à la saisie) -Simple pour le développement (pas de frameworks lourds). + Dolibarr ERP/CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). Dolibarr vient compléter les offres déjà nombreuses de logiciels de cette catégorie (comme OpenBravo, OpenERP, SugarCRM, Neogia, Compiere, etc.) mais se démarque par le fait qu'ici tout est fait pour offrir de la simplicité (règle des 3 S): +Simple pour l'installation (avec au choix des installeurs clé en main pour ceux qui ignorent comment installer un serveur Web, ou une installation manuelle) +Simple pour l'utilisation (fonctions modulaires pour ne pas surcharger les menus, informations claires à la saisie) +Simple pour le développement (pas de frameworks lourds). Dolibarr intègre en effet sa propre architecture (design patterns) permettant à tout développeur d'être tout de suite opérationnel sans connaissances particulières autre que le PHP. diff --git a/build/pad/pad_dolibarr.xml b/build/pad/pad_dolibarr.xml index c8ad2c62cfb..0920a19311d 100644 --- a/build/pad/pad_dolibarr.xml +++ b/build/pad/pad_dolibarr.xml @@ -72,10 +72,10 @@ Dolibarr ERP & CRM, the easy to use open source software to manage your activity Dolibarr ERP & CRM, the easy to use open source software to manage your activity (invoices, customers, suppliers, contracts, agenda, emailings...) and any other things a small or mid-sized business or a foundation needs to manage. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or medium companies, freelancers or foundations. We can say Dolibarr is an ERP or CRM. Dolibarr is also available with an auto-installer for Windows users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. See DoliWamp software for this. - Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. We can say Dolibarr is an ERP or CRM (or both depending on activated modules). It's an OpenSource project base on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems). Dolibarr differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: -Simple to install -Simple to use -Simple to develop + Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. We can say Dolibarr is an ERP or CRM (or both depending on activated modules). It's an OpenSource project base on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems). Dolibarr differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: +Simple to install +Simple to use +Simple to develop Note that Dolibarr is also available with an auto-installer for Windows or Ubuntu users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. This version is called DoliWamp (for Windows) or DoliBuntu (for Ubuntu/Debian). @@ -84,10 +84,10 @@ Note that Dolibarr is also available with an auto-installer for Windows or Ubunt Dolibarr ERP & CRM, le gestionnaire simple pour gérer votre activité Dolibarr ERP & CRM, le logiciel simple et OpenSource pour gérer votre activité (factures, devis, facturation, commandes, compta, trésorerie, stocks, produits, agenda, comptes bancaires, associations) Dolibarr ERP & CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). - Dolibarr ERP & CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). Dolibarr vient compléter les offres déjà nombreuses de logiciels de cette catégorie (comme OpenBravo, OpenERP, SugarCRM, Neogia, Compiere, etc.) mais se démarque par le fait qu'ici tout est fait pour offrir de la simplicité (règle des 3 S): -Simple pour l'installation (avec au choix des installeurs clé en main pour ceux qui ignorent comment installer un serveur Web, ou une installation manuelle) -Simple pour l'utilisation (fonctions modulaires pour ne pas surcharger les menus, informations claires à la saisie) -Simple pour le développement (pas de frameworks lourds). + Dolibarr ERP & CRM est un logiciel modulaire (on n'active que les fonctions que l'on désire) de gestions de TPE/PME, d'indépendants, d'entrepreneurs ou d'associations. En terme plus techniques, c'est un ERP et CRM. C'est un projet OpenSource qui s'exécute au sein d'un serveur Web et peut donc être accessible depuis n'importe quel lieu disposant d'une connexion Internet (Projet basé sur un serveur WAMP, MAMP ou LAMP: Apache, MySQL, PHP). Dolibarr vient compléter les offres déjà nombreuses de logiciels de cette catégorie (comme OpenBravo, OpenERP, SugarCRM, Neogia, Compiere, etc.) mais se démarque par le fait qu'ici tout est fait pour offrir de la simplicité (règle des 3 S): +Simple pour l'installation (avec au choix des installeurs clé en main pour ceux qui ignorent comment installer un serveur Web, ou une installation manuelle) +Simple pour l'utilisation (fonctions modulaires pour ne pas surcharger les menus, informations claires à la saisie) +Simple pour le développement (pas de frameworks lourds). Dolibarr intègre en effet sa propre architecture (design patterns) permettant à tout développeur d'être tout de suite opérationnel sans connaissances particulières autre que le PHP. diff --git a/build/pad/pad_doliwamp.xml b/build/pad/pad_doliwamp.xml index 3ee629c644b..8abf126d5f7 100644 --- a/build/pad/pad_doliwamp.xml +++ b/build/pad/pad_doliwamp.xml @@ -72,7 +72,7 @@ DoliWamp, the easy to use Dolibarr for Windows to manage your company,foundation DoliWamp is the Dolibarr ERP/CRM for Windows, the easy to use open source software to manage your activity (invoices, customers, suppliers, contracts, agenda, emailings...) and any other things a small or mid-sized business or a foundation needs. DoliWamp is the Dolibarr ERP/CRM autoinstaller for Windows users with no technical knowledge to install Dolibarr and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. Dolibarr ERP/CRM is a software package built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations. - DoliWamp is the Dolibarr ERP/CRM for Windows. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations (You can manage or follow contacts, invoices, orders, commercial proposals, products, stock management, agenda, mass emailings, members of a foundation, bank accounts...). Based on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems), you can install it as a standalone program or use it from anywhere with any web browser. Dolibarr is an OpenSource project. It differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: Simple to install, Simple to use, Simple to develop. + DoliWamp is the Dolibarr ERP/CRM for Windows. Dolibarr ERP & CRM is a software built by modules addition (you enable only features you need), to manage small or mid-sized businesses, freelancers or foundations (You can manage or follow contacts, invoices, orders, commercial proposals, products, stock management, agenda, mass emailings, members of a foundation, bank accounts...). Based on a WAMP, MAMP or LAMP server (Apache, Mysql, PHP for all Operating Systems), you can install it as a standalone program or use it from anywhere with any web browser. Dolibarr is an OpenSource project. It differs from other ERP or CRM softwares (like OpenAguila, OpenBravo, OpenERP, Neogia, Compiere, etc) because everything was made to be more simple: Simple to install, Simple to use, Simple to develop. DoliWamp is the auto-installer for Windows users with no technical knowledge to install Dolibarr ERP/CRM and all its prerequisites (Apache, Mysql, PHP) with just one auto-exe file. diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/config index 500460e8ab5..8992916acaf 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/functions index b648e20c2b0..f9d69784ae2 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/config index b959379b133..cef47e9502d 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -37,7 +37,7 @@ currencySymbol = kr ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NUL! DIV0 = #DIVISION/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/functions index 1599ccd1815..1db4d30bb1c 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/da/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/config index 7e2ba9d2891..ff7e29899cc 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = € ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NULL! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/functions index 8214f384878..ce85641a3c9 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/de/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/en/uk/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/en/uk/config index 00acff8bc34..f008e61cc90 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/en/uk/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/en/uk/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/config index 8f7d9e084ec..fa16f5639df 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = $ ## I'm surprised that the Excel Documentation suggests $ rath ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #¡NULO! DIV0 = #¡DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/functions index aa065969f3d..51ce48b3153 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/es/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/config index 36bc3fc70b8..a481864a6fa 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = $ # Symbol not known, should it be a € (Euro)? ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #TYHJÄ! DIV0 = #JAKO/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/functions index c10b3b9f381..7bed722a641 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/config index 80f7d5411a6..2240d6b9f8b 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = € ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NUL! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/functions index cce977b15bc..8d25f6ac193 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/config index c6c315814c4..dec7cbde15d 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/functions index 941c1b740d0..4abce13b91b 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/config index 97af8b9a570..f862a02d72d 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = € ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NULLO! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/functions index 862cf8302c8..b9219a6a4ce 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/it/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/config index a14b476c945..7377a181df0 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = € ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #LEEG! DIV0 = #DEEL/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/functions index 79b7acd1ef9..b6b8296ef04 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/config index e3e3cc4f786..15fcc128640 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = kr ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NULL! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/functions index 3cccce42a1d..57a80a7a406 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/no/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/config index ea111797270..fb1e7b13d9d 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = zł ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #ZERO! DIV0 = #DZIEL/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/functions index 5607f8f672c..2e5697973c1 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/br/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/br/config index d39c5c63438..e99aad6bea4 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/br/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/br/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = R$ ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NULO! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/config index 5e486bb29ff..36df63cc012 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = € ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #NULO! DIV0 = #DIV/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/config index 098c8075d29..205c342ada4 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = р ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #ПУСТО! DIV0 = #ДЕЛ/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/functions index 86bcd4f63a7..324c3df2a81 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/sv/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/sv/config index c2094c06249..454e52ef52f 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/sv/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/sv/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = kr ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #Skärning! DIV0 = #Division/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/config b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/config index cca084b2ba5..8a103d3c196 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/config +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/config @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ currencySymbol = YTL ## -## Excel Error Codes (For future use) +## Excel Error Codes (For future use) ## NULL = #BOŞ! DIV0 = #SAYI/0! diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/functions b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/functions index 3e7c225f402..79645214714 100644 --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/functions +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/functions @@ -1,6 +1,6 @@ ## ## PHPExcel -## +## ## Copyright (c) 2006 - 2013 PHPExcel ## ## This library is free software; you can redistribute it and/or From dccddf5c7ec0745a2c777fa1587e1651692cfa4e Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 3 Feb 2017 09:25:26 +0100 Subject: [PATCH 002/233] NEW : change render extrafields checkbox list for multiselectarray --- htdocs/core/class/extrafields.class.php | 74 ++++++++++--------------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 1211c334617..b14f7c65ed9 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -993,23 +993,12 @@ class ExtraFields } elseif ($type == 'checkbox') { - $out=''; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + $form = new Form($db); + $value_arr=explode(',',$value); + $out=$form->multiselectarray($keysuffix.'options_'.$key.$keyprefix, $param['options'], $value_arr, '', 0, '', 0, '100%'); - foreach ($param['options'] as $keyopt=>$val ) - { - - $out.=''; - } } elseif ($type == 'radio') { @@ -1100,6 +1089,9 @@ class ExtraFields if ($resql) { $num = $this->db->num_rows($resql); $i = 0; + + $data=array(); + while ( $i < $num ) { $labeltoshow = ''; $obj = $this->db->fetch_object($resql); @@ -1125,12 +1117,9 @@ class ExtraFields $labeltoshow = dol_trunc($obj->$field_toshow, 18) . ' '; } } - $out .= 'rowid . '"'; - - $out .= 'checked'; - - $out .= '/>' . $labeltoshow . '
'; + + $data[$obj->rowid]=$labeltoshow; + } else { if (! $notrans) { $translabel = $langs->trans($obj->{$InfoFieldList[1]}); @@ -1144,32 +1133,25 @@ class ExtraFields $labeltoshow = '(not defined)'; if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { - $out .= 'rowid . '"'; - - $out .= 'checked'; - $out .= ''; - - $out .= '/>' . $labeltoshow . '
'; + $data[$obj->rowid]=$labeltoshow; } if (! empty($InfoFieldList[3])) { $parent = $parentName . ':' . $obj->{$parentField}; } - $out .= 'rowid . '"'; - - $out .= ((is_array($value_arr) && in_array($obj->rowid, $value_arr)) ? ' checked ' : ''); - ; - $out .= ''; - - $out .= '/>' . $labeltoshow . '
'; + $data[$obj->rowid]=$labeltoshow; } - + $i ++; } $this->db->free($resql); + + require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + $form = new Form($db); + + $out=$form->multiselectarray($keysuffix.'options_'.$key.$keyprefix, $data, $value_arr, '', 0, '', 0, '100%'); + } else { print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.
'; } @@ -1380,9 +1362,10 @@ class ExtraFields if (is_array($value_arr)) { foreach ($value_arr as $keyval=>$valueval) { - $value.=$params['options'][$valueval].'
'; + $toprint[]='
  • '.$params['options'][$valueval].'
  • '; } } + $value='
      '.implode(' ', $toprint).'
    '; } elseif ($type == 'chkbxlst') { @@ -1417,7 +1400,7 @@ class ExtraFields $resql = $this->db->query($sql); if ($resql) { $value = ''; // value was used, so now we reste it to use it to build final output - + $toprint=array(); while ( $obj = $this->db->fetch_object($resql) ) { // Several field into label (eq table:code|libelle:rowid) @@ -1430,9 +1413,9 @@ class ExtraFields $translabel = $langs->trans($obj->$field_toshow); } if ($translabel != $field_toshow) { - $value .= dol_trunc($translabel, 18) . '
    '; + $toprint[]='
  • '.dol_trunc($translabel, 18).'
  • '; } else { - $value .= $obj->$field_toshow . '
    '; + $toprint[]='
  • '.$obj->$field_toshow.'
  • '; } } } else { @@ -1441,15 +1424,18 @@ class ExtraFields $translabel = $langs->trans($obj->{$InfoFieldList[1]}); } if ($translabel != $obj->{$InfoFieldList[1]}) { - $value .= dol_trunc($translabel, 18) . '
    '; + $toprint[]='
  • '.dol_trunc($translabel, 18).'
  • '; } else { - $value .= $obj->{$InfoFieldList[1]} . '
    '; + $toprint[]='
  • '.$obj->{$InfoFieldList[1]}.'
  • '; } } } } - } else + $value='
      '.implode(' ', $toprint).'
    '; + + } else { dol_syslog(get_class($this) . '::showOutputField error ' . $this->db->lasterror(), LOG_WARNING); + } } elseif ($type == 'link') { From c06aedc54da2dadd3d01e8dd3c5200ea847ed8c3 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 15 Feb 2017 20:55:52 +0100 Subject: [PATCH 003/233] [FP17] : Add data in llx_accountancy_journal --- htdocs/install/mysql/data/llx_accounting.sql | 8 +++++++- htdocs/install/mysql/migration/5.0.0-6.0.0.sql | 6 ++++++ htdocs/install/mysql/tables/llx_accounting_journal.sql | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/htdocs/install/mysql/data/llx_accounting.sql b/htdocs/install/mysql/data/llx_accounting.sql index 149d7fea394..dc7aeb27bef 100644 --- a/htdocs/install/mysql/data/llx_accounting.sql +++ b/htdocs/install/mysql/data/llx_accounting.sql @@ -5,7 +5,7 @@ -- Copyright (C) 2004 Guillaume Delecourt -- Copyright (C) 2005-2009 Regis Houssin -- Copyright (C) 2007 Patrick Raguin --- Copyright (C) 2011-2016 Alexandre Spangaro +-- Copyright (C) 2011-2017 Alexandre Spangaro -- -- This 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 +29,13 @@ delete from llx_accounting_account; delete from llx_accounting_system; +delete from llx_accounting_journal; +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (1,'VT', 'Journal des ventes', 1, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (2,'AC', 'Journal des achats', 2, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (3,'BQ', 'Journal de banque', 3, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (4,'OD', 'Journal des opérations diverses', 4, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (5,'AN', 'Journal des à-nouveaux', 9, 1); -- -- Descriptif des plans comptables FR PCG99-ABREGE -- diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index aa755daa09a..0d47261503c 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -98,3 +98,9 @@ CREATE TABLE llx_product_attribute_combination entity INT DEFAULT 1 NOT NULL ); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (1,'VT', 'Journal des ventes', 1, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (2,'AC', 'Journal des achats', 2, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (3,'BQ', 'Journal de banque', 3, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (4,'OD', 'Journal des opérations diverses', 4, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (5,'AN', 'Journal des à-nouveaux', 9, 1); + diff --git a/htdocs/install/mysql/tables/llx_accounting_journal.sql b/htdocs/install/mysql/tables/llx_accounting_journal.sql index bc514f0ed9b..f3ee2a2e010 100644 --- a/htdocs/install/mysql/tables/llx_accounting_journal.sql +++ b/htdocs/install/mysql/tables/llx_accounting_journal.sql @@ -1,5 +1,5 @@ -- ============================================================================ --- Copyright (C) 2016 Alexandre Spangaro +-- Copyright (C) 2016-2017 Alexandre Spangaro -- -- This 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,6 +22,6 @@ create table llx_accounting_journal rowid integer AUTO_INCREMENT PRIMARY KEY, code varchar(32) NOT NULL, label varchar(128) NOT NULL, - nature smallint DEFAULT 0 NOT NULL, -- type of journals (Sale / purchase / bank / various operations) + nature smallint DEFAULT 0 NOT NULL, -- type of journals (1:Sale / 2:purchase / 3:bank / 4:various operations / 9: has-new) active smallint DEFAULT 0 )ENGINE=innodb; From 1401e9267b5ec5a9554e2cb08f1d22b15847c9d3 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 21 Feb 2017 07:09:58 +0100 Subject: [PATCH 004/233] [FP17] Modify menu for multijournal --- htdocs/core/menus/standard/eldy.lib.php | 32 +++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index e16e6601940..5f2a5f5def6 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -993,6 +993,37 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu { if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add('',$langs->trans("Journalization"),1,$user->rights->accounting->comptarapport->lire); + // Multi journal + $sql = "SELECT rowid, code, label, nature"; + $sql.= " FROM ".MAIN_DB_PREFIX."accounting_journal"; + // $sql.= " WHERE entity = ".$conf->entity; + $sql.= " ORDER BY code"; + + $resql = $db->query($sql); + if ($resql) + { + $numr = $db->num_rows($resql); + $i = 0; + + if ($numr > 0) + while ($i < $numr) + { + $objp = $db->fetch_object($resql); + + if ($objp->nature == 1) $nature="sells"; + if ($objp->nature == 2) $nature="purchases"; + if ($objp->nature == 3) $nature="bank"; + if ($objp->nature == 4) $nature="various"; + if ($objp->nature == 9) $nature="hasnew"; + + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&code_journal='.$objp->code,dol_trunc($objp->label,25),2,$user->rights->accounting->comptarapport->lire); + $i++; + } + } + else dol_print_error($db); + $db->free($resql); + + /* $sql = "SELECT rowid, label, accountancy_journal"; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; $sql.= " WHERE entity = ".$conf->entity; @@ -1020,6 +1051,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/journal/sellsjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal",$langs->trans("SellsJournal"),2,$user->rights->accounting->comptarapport->lire); if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/journal/purchasesjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal",$langs->trans("PurchasesJournal"),2,$user->rights->accounting->comptarapport->lire); if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/journal/expensereportsjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal",$langs->trans("ExpenseReportsJournal"),2,$user->rights->accounting->comptarapport->lire); + */ } // General Ledger From 38ccf7ffdd74ae5d36f3a3ff20702a97f8c79119 Mon Sep 17 00:00:00 2001 From: hugome Date: Thu, 2 Mar 2017 20:16:12 +0100 Subject: [PATCH 005/233] Fix : Agenda getCalendarEvents hook Return of getCalendarEvents on agenda page : The array_merge change key of merged array. --- htdocs/comm/action/index.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 5366720bfc6..321d15ba485 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -919,7 +919,14 @@ if (count($listofextcals)) // Complete $eventarray with events coming from external module $parameters=array(); $object=null; $reshook=$hookmanager->executeHooks('getCalendarEvents',$parameters,$object,$action); -if (! empty($hookmanager->resArray['eventarray'])) $eventarray=array_merge($eventarray, $hookmanager->resArray['eventarray']); +if (! empty($hookmanager->resArray['eventarray'])) { + foreach ($hookmanager->resArray['eventarray'] as $keyDate => $events) { + if (!isset($eventarray[$keyDate])) { + $eventarray[$keyDate]=array(); + } + $eventarray[$keyDate]=array_merge($eventarray[$keyDate], $events); + } +} From 8199ac9f89600273b91fe20a118b466c0f1d3381 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 22 Mar 2017 19:49:58 +0100 Subject: [PATCH 006/233] FIX Can't download delivery receipts (function dol_check_secure_access_document) --- htdocs/core/lib/files.lib.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 59e5a3426a2..586622538e9 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1725,9 +1725,8 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu } $original_file=$conf->expedition->dir_output."/sending/".$original_file; } - // Wrapping pour les bons de livraison - else if ($modulepart == 'livraison' && !empty($conf->livraison->dir_output)) + if ($modulepart == 'livraison' && !empty($conf->expedition->dir_output)) { if ($fuser->rights->expedition->livraison->lire || preg_match('/^specimen/i',$original_file)) { From 9b42177bd5c47079a030053bef0ad37caad06d53 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Mar 2017 10:52:09 +0100 Subject: [PATCH 007/233] Fix half day for leave request. --- htdocs/hrm/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php index 30d0c911ba1..714f329add3 100644 --- a/htdocs/hrm/index.php +++ b/htdocs/hrm/index.php @@ -148,7 +148,7 @@ $langs->load("boxes"); -// Last leave requests +// Latest leave requests if (! empty($conf->holiday->enabled) && $user->rights->holiday->read) { $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.photo, u.statut, x.rowid, x.rowid as ref, x.fk_type, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.tms as dm, x.statut as status"; @@ -204,7 +204,7 @@ if (! empty($conf->holiday->enabled) && $user->rights->holiday->read) $starthalfday=($obj->halfday == -1 || $obj->halfday == 2)?'afternoon':'morning'; $endhalfday=($obj->halfday == 1 || $obj->halfday == 2)?'morning':'afternoon'; - print ''.dol_print_date($obj->date_start,'day').' '.$langs->trans($listhalfday[$endhalfday]); + print ''.dol_print_date($obj->date_start,'day').' '.$langs->trans($listhalfday[$starthalfday]); print ''.dol_print_date($obj->date_end,'day').' '.$langs->trans($listhalfday[$endhalfday]); print ''.dol_print_date($db->jdate($obj->dm),'day').''; print ''.$holidaystatic->LibStatut($obj->status,3).''; From aa9d991923ba17f675c883472d953501f21bd90f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 01:03:02 +0100 Subject: [PATCH 008/233] Fix css --- htdocs/comm/index.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index 4e99b7072fc..7ea7b840d6b 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -158,10 +158,10 @@ if (! empty($conf->propal->enabled) && $user->rights->propal->lire) print ''; print ''.$langs->trans("ProposalsDraft").($num?' '.$num.'':'').''; + $var=true; if ($num > 0) { $i = 0; - $var=true; while ($i < $num) { $obj = $db->fetch_object($resql); @@ -239,10 +239,10 @@ if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_propos print ''; print ''.$langs->trans("SupplierProposalsDraft").($num?' '.$num.'':'').''; + $var=true; if ($num > 0) { $i = 0; - $var=true; while ($i < $num) { $obj = $db->fetch_object($resql); @@ -318,10 +318,10 @@ if (! empty($conf->commande->enabled) && $user->rights->commande->lire) print ''; print ''.$langs->trans("DraftOrders").($num?' '.$num.'':'').''; - if ($num) + $var = true; + if ($num > 0) { $i = 0; - $var = true; while ($i < $num) { $var=!$var; @@ -399,10 +399,10 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande print ''; print ''.$langs->trans("DraftSuppliersOrders").($num?' '.$num.'':'').''; - if ($num) + $var = true; + if ($num > 0) { $i = 0; - $var = true; while ($i < $num) { $var=!$var; From df59a595de716f16a3c7aa2ca75debf1c355f7af Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 01:29:19 +0100 Subject: [PATCH 009/233] Fix link to files --- htdocs/core/lib/files.lib.php | 2 +- htdocs/core/tpl/ajaxrow.tpl.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 586622538e9..d27d6c1cdb1 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1726,7 +1726,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $original_file=$conf->expedition->dir_output."/sending/".$original_file; } // Wrapping pour les bons de livraison - if ($modulepart == 'livraison' && !empty($conf->expedition->dir_output)) + else if ($modulepart == 'livraison' && !empty($conf->expedition->dir_output)) { if ($fuser->rights->expedition->livraison->lire || preg_match('/^specimen/i',$original_file)) { diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php index 123fcef662c..a28bbac5e5a 100644 --- a/htdocs/core/tpl/ajaxrow.tpl.php +++ b/htdocs/core/tpl/ajaxrow.tpl.php @@ -40,6 +40,7 @@ $(document).ready(function(){ $(".tdlineupdown").css("background-repeat","no-repeat"); $(".tdlineupdown").css("background-position","center center"); + console.log("Prepare tableDnd for #"); $("#").tableDnD({ onDrop: function(table, row) { var reloadpage = ""; From 2f4a4f493e4a04507ce96748d15e81ace1afd4bc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 01:47:52 +0100 Subject: [PATCH 010/233] Missin translation --- htdocs/product/fournisseurs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 69a9344832b..6ff8d9deca0 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -39,7 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class. $langs->load("products"); $langs->load("suppliers"); $langs->load("bills"); -if (! empty($conf->margin->enabled)) $langs->load("margins"); +$langs->load("margins"); $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); From 106d19a8af74db6cc24c0862cdd4138e106a6ea3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 03:53:11 +0100 Subject: [PATCH 011/233] FIX #6468 + Fix missing translation --- htdocs/comm/action/card.php | 15 +--------- .../class/fournisseur.commande.class.php | 27 ++++++++++------- htdocs/fourn/commande/dispatch.php | 30 ++++--------------- htdocs/langs/en_US/errors.lang | 1 + 4 files changed, 25 insertions(+), 48 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 7378e35db80..90596b54197 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1208,20 +1208,12 @@ if ($id > 0) // Affichage fiche action en mode visu print ''; - // Ref - /*print '';*/ - // Type if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) { print ''; } - // Title - //print ''; - // Full day event print ''; @@ -1243,11 +1235,6 @@ if ($id > 0) if ($object->percentage > 0 && $object->percentage < 100 && $object->datef && $object->datef < ($now- $delay_warning)) print img_warning($langs->trans("Late")); print ''; - // Status - /*print '';*/ - // Location if (empty($conf->global->AGENDA_DISABLE_LOCATION)) { @@ -1281,7 +1268,7 @@ if ($id > 0) print '
    '; print $form->select_dolusers_forevent('view', 'assignedtouser', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); print '
    '; - if (in_array($user->id,array_keys($listofuserid))) + if ($object->datep != $object->datef && in_array($user->id,array_keys($listofuserid))) { print '
    '; print $langs->trans("MyAvailability").': '.(($object->userassigned[$user->id]['transparency'] > 0)?$langs->trans("Busy"):$langs->trans("Available")); // We show nothing if event is assigned to nobody diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 98939ee01f2..676ca9f23ab 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1949,7 +1949,7 @@ class CommandeFournisseur extends CommonOrder } } - if (! $error && ! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS_NEED_APPROVE) && ($type == 'tot')) // Accept to move to rception done, only if status of all line are ok (refuse denied) + 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) { $dispatcheddenied=$this->getDispachedLines(2); if (count($dispatchedlinearray) > 0) @@ -1988,7 +1988,8 @@ class CommandeFournisseur extends CommonOrder $result = 0; $old_statut = $this->statut; $this->statut = $statut; - + $this->actionmsg2 = $comment; + // Call trigger $result=$this->call_trigger('ORDER_SUPPLIER_RECEIVE',$user); if ($result < 0) $error++; @@ -2810,13 +2811,14 @@ class CommandeFournisseur extends CommonOrder * * @param User $user User action * @param int $closeopenorder Close if received + * @param string $comment Comment * @return int <0 if KO, 0 if not applicable, >0 if OK */ - public function calcAndSetStatusDispatch(User $user, $closeopenorder=1) + public function calcAndSetStatusDispatch(User $user, $closeopenorder=1, $comment='') { - global $conf; + global $conf, $langs; - if (! empty($conf->commande->enabled) && ! empty($conf->fournisseur->enabled)) + if (! empty($conf->fournisseur->enabled)) { require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php'; @@ -2845,14 +2847,18 @@ class CommandeFournisseur extends CommonOrder foreach($this->lines as $line) { $qtywished[$line->fk_product]+=$line->qty; } + + $date_liv = dol_now(); + //Compare array $diff_array=array_diff_assoc($qtydelivered,$qtywished); - if (count($diff_array)==0) + + if (count($diff_array)==0) //No diff => mean everythings is received { - //No diff => mean everythings is received if ($closeopenorder) { - $ret=$this->setStatus($user,5); + //$ret=$this->setStatus($user,5); + $ret = $this->Livraison($user, $date_liv, 'tot', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' if ($ret<0) { return -1; } @@ -2861,7 +2867,8 @@ class CommandeFournisseur extends CommonOrder else { //Diff => received partially - $ret=$this->setStatus($user,4); + //$ret=$this->setStatus($user,4); + $ret = $this->Livraison($user, $date_liv, 'par', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' if ($ret<0) { return -1; } @@ -2871,7 +2878,7 @@ class CommandeFournisseur extends CommonOrder else { //Diff => received partially - $ret=$this->setStatus($user,4); + $ret = $this->Livraison($user, $date_liv, 'par', $comment); // GETPOST("type") is 'tot', 'par', 'nev', 'can' if ($ret<0) { return -1; } diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index dc34686361f..c87b3a62bed 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -230,7 +230,7 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner) } if (! $error) { - $result = $object->calcAndSetStatusDispatch($user, GETPOST('closeopenorder')?1:0); + $result = $object->calcAndSetStatusDispatch($user, GETPOST('closeopenorder')?1:0, GETPOST('comment')); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error ++; @@ -340,26 +340,7 @@ if ($id > 0 || ! empty($ref)) { print '
    '; print '
    '.$langs->trans("Ref").''; - print $form->showrefnav($object, 'id', $linkback, ($user->societe_id?0:1), 'id', 'ref', ''); - print '
    '.$langs->trans("Type").''.$object->type.'
    '.$langs->trans("Title").''.dol_htmlentities($object->label).'
    '.$langs->trans("EventOnFullDay").''.yn($object->fulldayevent, 3).'
    '.$langs->trans("Status").' / '.$langs->trans("Percentage").''; - print $object->getLibStatut(4); - print '
    '; -/* - // Ref - print ''; - print ''; - print ''; - // Fournisseur - print '"; - print ''; - print ''; - - // Statut - print ''; - print ''; - print '"; -*/ // Date if ($object->methode_commande_id > 0) { print '\n"; @@ -609,7 +591,7 @@ if ($id > 0 || ! empty($ref)) { print '
    '; print $langs->trans("Comment") . ' : '; - print 'trans("DispatchSupplierOrder", $object->ref); // print ' / '.$object->ref_supplier; // Not yet available print '" class="flat">
    '; @@ -662,7 +644,7 @@ if ($id > 0 || ! empty($ref)) { print '
    ' . $langs->trans("Ref") . ''; - print $form->showrefnav($object, 'ref', '', 1, 'ref', 'ref'); - print '
    ' . $langs->trans("Supplier") . "' . $soc->getNomUrl(1, 'supplier') . '
    ' . $langs->trans("Status") . ''; - print $object->getLibStatut(4); - print "
    ' . $langs->trans("Date") . ''; @@ -585,7 +566,8 @@ if ($id > 0 || ! empty($ref)) { } elseif (count($listwarehouses) == 1) { print $formproduct->selectWarehouses(GETPOST("entrepot" . $suffix), "entrepot" . $suffix, '', 0, 0, $objp->fk_product); } else { - print $langs->trans("NoWarehouseDefined"); + $langs->load("errors"); + print $langs->trans("ErrorNoWarehouseDefined"); } print "
    '; print ''; - print ''; + print ''; if (! empty($conf->productbatch->enabled)) { print ''; print ''; @@ -705,7 +687,7 @@ if ($id > 0 || ! empty($ref)) { print ''; // Comment - print ''; + print ''; // Status if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) { diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 77a99994fef..af18693f9d4 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -184,6 +184,7 @@ ErrorTaskAlreadyAssigned=Task already assigned to user ErrorModuleFileSeemsToHaveAWrongFormat=The module package seems to have a wrong format. ErrorFilenameDosNotMatchDolibarrPackageRules=The name of the module package (%s) does not match expected name syntax: %s ErrorDuplicateTrigger=Error, duplicate trigger name %s. Already loaded from %s. +ErrorNoWarehouseDefined=Error, no warehouses defined. # 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. From 447607ecd96381ca307c335b8cb2214bcfb7cf0a Mon Sep 17 00:00:00 2001 From: Inovea Conseil Date: Sat, 25 Mar 2017 12:46:32 +0100 Subject: [PATCH 012/233] Update pdf.php Missing translate #6577 --- htdocs/admin/pdf.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/pdf.php b/htdocs/admin/pdf.php index 74684c823e7..55bd83cbc19 100644 --- a/htdocs/admin/pdf.php +++ b/htdocs/admin/pdf.php @@ -98,7 +98,7 @@ $formadmin=new FormAdmin($db); $arraydetailsforpdffoot = array( 0 => $langs->trans('NoDetails'), 1 => $langs->trans('DisplayCompanyInfo'), - 2 => $langs->trans('DisplayManagersInfo'), + 2 => $langs->trans('DisplayCompanyManagers'), 3 => $langs->trans('DisplayCompanyInfoAndManagers') ); From 4012aeff908e0ecaf158275713feeb9dbda55056 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Mar 2017 18:35:17 +0100 Subject: [PATCH 013/233] Fix translation --- dev/translation/sanity_check_en_langfiles.php | 2 ++ htdocs/core/boxes/box_graph_product_distribution.php | 2 ++ htdocs/langs/en_US/mails.lang | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/dev/translation/sanity_check_en_langfiles.php b/dev/translation/sanity_check_en_langfiles.php index f566938d7e0..bb3430eb22c 100755 --- a/dev/translation/sanity_check_en_langfiles.php +++ b/dev/translation/sanity_check_en_langfiles.php @@ -300,6 +300,8 @@ if ((! empty($_REQUEST['unused']) && $_REQUEST['unused'] == 'true') || (isset($a if (preg_match('/^BoxTitleLatest/', $value)) $qualifiedforclean=0; // install.lang if (preg_match('/^KeepDefaultValues/', $value)) $qualifiedforclean=0; + // mail.lang + if (preg_match('/MailingModuleDesc/i', $value)) $qualifiedforclean=0; // main.lang if (preg_match('/^Duration/', $value)) $qualifiedforclean=0; if (preg_match('/^FormatDate/', $value)) $qualifiedforclean=0; diff --git a/htdocs/core/boxes/box_graph_product_distribution.php b/htdocs/core/boxes/box_graph_product_distribution.php index a709a7aef3a..2b3c69a9e15 100644 --- a/htdocs/core/boxes/box_graph_product_distribution.php +++ b/htdocs/core/boxes/box_graph_product_distribution.php @@ -249,6 +249,8 @@ 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) { diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index 897085ec423..61dddb46691 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -79,6 +79,10 @@ MailingModuleDescContactsWithThirdpartyFilter=Contact with customer filters MailingModuleDescContactsByCompanyCategory=Contacts by third party category MailingModuleDescContactsByCategory=Contacts by categories MailingModuleDescContactsByFunction=Contacts by position +MailingModuleDescEmailsFromFile=Emails from file +MailingModuleDescEmailsFromUser=Emails input by user +MailingModuleDescDolibarrUsers=Users with Emails +MailingModuleDescThirdPartiesByCategories=Third parties (by categories) # Libelle des modules de liste de destinataires mailing LineInFile=Line %s in file From 68656dd29cb8e4df78cfc199b3ca087310d13b1b Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 25 Mar 2017 12:06:02 +0100 Subject: [PATCH 014/233] FIX : supplier default condition not retrived on create --- htdocs/supplier_proposal/card.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 050e0186444..6a34a5ddd61 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1050,7 +1050,9 @@ if ($action == 'create') } else { - if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; + $cond_reglement_id = $soc->cond_reglement_supplier_id; + $mode_reglement_id = $soc->mode_reglement_supplier_id; + if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; } $object = new SupplierProposal($db); @@ -1087,12 +1089,12 @@ if ($action == 'create') // Terms of payment print ''; // Mode of payment print ''; // Bank Account From f4a7217f20382e39fc29265d5a10fd4f41a97d04 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Fri, 24 Mar 2017 23:39:25 +0100 Subject: [PATCH 015/233] display total line for all total line --- htdocs/comm/propal/list.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index aa6df1afb2b..44a2b9356e8 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -977,7 +977,12 @@ if ($resql) } // Show total line - if (isset($totalarray['totalhtfield'])) + if (isset($totalarray['totalhtfield']) + || isset($totalarray['totalvatfield']) + || isset($totalarray['totalttcfield']) + || isset($totalarray['totalamfield']) + || isset($totalarray['totalrtpfield']) + ) { print ''; $i=0; From afefb475984ae29ef30e014e3c3f50da3b75e096 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Fri, 24 Mar 2017 23:40:34 +0100 Subject: [PATCH 016/233] Update list.php --- htdocs/commande/list.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index c72671319bc..073a20bc391 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1398,7 +1398,12 @@ if ($resql) } // Show total line - if (isset($totalarray['totalhtfield'])) + if (isset($totalarray['totalhtfield']) + || isset($totalarray['totalvatfield']) + || isset($totalarray['totalttcfield']) + || isset($totalarray['totalamfield']) + || isset($totalarray['totalrtpfield']) + ) { print ''; $i=0; From 8d6819c6642e976c0e9235e72a06474f3785c334 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Fri, 24 Mar 2017 23:53:32 +0100 Subject: [PATCH 017/233] Update list.php --- htdocs/fourn/facture/list.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index bff5c773cfc..3afb97c5fb1 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -956,7 +956,12 @@ if ($resql) } // Show total line - if (isset($totalarray['totalhtfield'])) + if (isset($totalarray['totalhtfield']) + || isset($totalarray['totalvatfield']) + || isset($totalarray['totalttcfield']) + || isset($totalarray['totalamfield']) + || isset($totalarray['totalrtpfield']) + ) { print ''; $i=0; From 6e133e5bf6f3c03083cefaa5355a65015ad8d97d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 26 Mar 2017 01:57:09 +0100 Subject: [PATCH 018/233] Fix security escapment --- htdocs/loan/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 8ef8e09eba9..d0ab75127ab 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -230,7 +230,7 @@ if ($action == 'create') } // Capital - print ''; + print ''; // Date Start print ""; @@ -245,10 +245,10 @@ if ($action == 'create') print ''; // Number of terms - print ''; + print ''; // Rate - print ''; + print ''; // Note Private print ''; From e38ad37ce33df734439f73ab4df49d7393a2659c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 26 Mar 2017 05:02:06 +0200 Subject: [PATCH 019/233] FIX #6517 #6525 Autocompletion of thirdparty after n chars not implemented --- htdocs/core/class/html.form.class.php | 86 ++++++++++++++------------- htdocs/core/lib/agenda.lib.php | 2 +- htdocs/societe/ajax/company.php | 32 ++++------ 3 files changed, 59 insertions(+), 61 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 60ff30c6433..664997129df 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -931,36 +931,40 @@ class Form /** * Output html form to select a third party * - * @param string $selected Preselected type - * @param string $htmlname Name of field in form - * @param string $filter optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)') - * @param string $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty') - * @param int $showtype Show third party type in combolist (customer, prospect or supplier) - * @param int $forcecombo Force to use combo box - * @param array $events Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @param int $limit Maximum number of elements - * @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 - * @return string HTML string with select box for thirdparty. + * @param string $selected Preselected type + * @param string $htmlname Name of field in form + * @param string $filter optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)') + * @param string $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty') + * @param int $showtype Show third party type in combolist (customer, prospect or supplier) + * @param int $forcecombo Force to use combo box + * @param array $events Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param int $limit Maximum number of elements + * @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 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 + * @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='') + 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()) { + global $conf,$user,$langs; + $out=''; - /* TODO Use ajax_autocompleter like for products (not finished) if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT) && ! $forcecombo) { $placeholder=''; - if ($selected && empty($selected_input_value)) { - require_once DOL_DOCUMENT_ROOT.'/societe/ajaxcompanies.php'; - $societe = new Societe($this->db); - $societe->fetch($selected); - $selected_input_value=$societe->ref; + require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; + $societetmp = new Societe($this->db); + $societetmp->fetch($selected); + $selected_input_value=$societetmp->name; + unset($societetmp); } - // mode=1 means customers products - $urloption='htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status.'&finished='.$finished; + // mode 1 + $urloption='htmlname='.$htmlname.'&outjson=1&filter='.$filter; print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/societe/ajax/company.php', $urloption, $conf->global->COMPANY_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : '; else if ($hidelabel > 1) { @@ -970,15 +974,15 @@ class Form print img_picto($langs->trans("Search"), 'search'); } } - print ''; + print 'global->THIRDPARTY_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />'; if ($hidelabel == 3) { print img_picto($langs->trans("Search"), 'search'); } } else - {*/ + { $out.=$this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam); - //} + } return $out; } @@ -1004,7 +1008,8 @@ class Form { global $conf,$user,$langs; - $out=''; $num=0; + $out=''; + $num=0; $outarray=array(); // On recherche les societes @@ -1020,19 +1025,18 @@ class Form if ($filterkey && $filterkey != '') { $sql.=" AND ("; - if (! empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)) // Can use index - { - $sql.="(s.name LIKE '".$this->db->escape($filterkey)."%')"; + $prefix=empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)?'%':''; // Can use index if COMPANY_DONOTSEARCH_ANYWHERE is on + // For natural search + $scrit = explode(' ', $filterkey); + $i=0; + if (count($scrit) > 1) $sql.="("; + foreach ($scrit as $crit) { + if ($i > 0) $sql.=" AND "; + $sql.="(s.nom LIKE '".$this->db->escape($prefix.$crit)."%')"; + $i++; } - else - { - // For natural search - $scrit = explode(' ', $filterkey); - foreach ($scrit as $crit) { - $sql.=" AND (s.name LIKE '%".$this->db->escape($crit)."%')"; - } - } - if (! empty($conf->barcode->enabled)) + if (count($scrit) > 1) $sql.=")"; + if (! empty($conf->barcode->enabled)) { $sql .= " OR s.barcode LIKE '".$this->db->escape($filterkey)."%'"; } @@ -1041,20 +1045,22 @@ class Form $sql.=$this->db->order("nom","ASC"); if ($limit > 0) $sql.=$this->db->plimit($limit); + // Build output string dol_syslog(get_class($this)."::select_thirdparty_list", LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { + $events = null; + if ($conf->use_javascript_ajax && ! $forcecombo) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement =ajax_combobox($htmlname, $events, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } // Construct $out and $outarray - $out.= ''."\n"; $textifempty=''; // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. @@ -1066,7 +1072,7 @@ class Form } if ($showempty) $out.= ''."\n"; - $num = $this->db->num_rows($resql); + $num = $this->db->num_rows($resql); $i = 0; if ($num) { @@ -1109,7 +1115,7 @@ class Form $out.= ''; } - array_push($outarray, array('key'=>$obj->rowid, 'value'=>$obj->rowid, 'label'=>$label)); + array_push($outarray, array('key'=>$obj->rowid, 'value'=>$label, 'label'=>$label)); $i++; if (($i % 10) == 0) $out.="\n"; diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 09f89ba0c3f..b16792a0235 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -118,7 +118,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh print ''; } diff --git a/htdocs/societe/ajax/company.php b/htdocs/societe/ajax/company.php index d2a244f9444..32f57f73c25 100644 --- a/htdocs/societe/ajax/company.php +++ b/htdocs/societe/ajax/company.php @@ -18,8 +18,8 @@ */ /** - * \file htdocs/product/ajax/company.php - * \brief File to return Ajax response on product list request + * \file htdocs/societe/ajax/company.php + * \brief File to return Ajax response on thirdparty list request */ if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal @@ -33,15 +33,11 @@ if (empty($_GET['keysearch']) && ! defined('NOREQUIREHTML')) define('NOREQUIREH require '../../main.inc.php'; $htmlname=GETPOST('htmlname','alpha'); -$socid=GETPOST('socid','int'); -$type=GETPOST('type','int'); -$mode=GETPOST('mode','int'); -$status=((GETPOST('status','int') >= 0) ? GETPOST('status','int') : -1); +$filter=GETPOST('filter','alpha'); $outjson=(GETPOST('outjson','int') ? GETPOST('outjson','int') : 0); -$price_level=GETPOST('price_level','int'); $action=GETPOST('action', 'alpha'); $id=GETPOST('id', 'int'); -$price_by_qty_rowid=GETPOST('pbq', 'int'); + /* * View @@ -49,7 +45,7 @@ $price_by_qty_rowid=GETPOST('pbq', 'int'); //print ''."\n"; -dol_syslog(join(',',$_GET)); +dol_syslog(join(',', $_GET)); //print_r($_GET); if (! empty($action) && $action == 'fetch' && ! empty($id)) @@ -63,8 +59,11 @@ if (! empty($action) && $action == 'fetch' && ! empty($id)) if ($ret > 0) { $outname=$object->name; - - $outjson = array('name'=>$outname); + $outlabel = ''; + $outdesc = ''; + $outtype = $object->type; + + $outjson = array('ref' => $outref,'name' => $outname,'desc' => $outdesc,'type' => $outtype); } echo json_encode($outjson); @@ -73,7 +72,7 @@ else { require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; - $langs->load("products"); + $langs->load("companies"); $langs->load("main"); top_httphead(); @@ -90,14 +89,7 @@ else $searchkey=(GETPOST($id)?GETPOST($id):(GETPOST($htmlname)?GETPOST($htmlname):'')); $form = new Form($db); - if (empty($mode) || $mode == 'customer') - { - $arrayresult=$form->select_company_html($socid,$htmlname,"client IN (1,3)",0,0,0,null,$searchkey,$outjson); - } - elseif ($mode == 'supplier') - { - $arrayresult=$form->select_company_html($socid,$htmlname,"fournisseur=1",0,0,0,null,$searchkey,$outjson); - } + $arrayresult=$form->select_thirdparty_list(0,$htmlname,$filter,1,0,0,null,$searchkey,$outjson); $db->close(); From 3148841ecf47e1047f8509e31b0e15db9506033b Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 26 Mar 2017 21:26:05 +0200 Subject: [PATCH 020/233] Fix : integration of expense report in accounatncy bank journal --- htdocs/accountancy/journal/bankjournal.php | 90 ++++++++++++++++++---- 1 file changed, 77 insertions(+), 13 deletions(-) diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 4aab9a09fcc..012a773b875 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -4,7 +4,7 @@ * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2012 Regis Houssin * Copyright (C) 2013 Christophe Battarel - * Copyright (C) 2013-2016 Alexandre Spangaro + * Copyright (C) 2013-2017 Alexandre Spangaro * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2013-2014 Olivier Geffroy * @@ -48,6 +48,9 @@ require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture.class.php'; require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.class.php'; require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php'; require_once DOL_DOCUMENT_ROOT . '/societe/class/client.class.php'; +require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; +require_once DOL_DOCUMENT_ROOT . '/expensereport/class/paymentexpensereport.class.php'; + // Langs $langs->load("companies"); @@ -57,6 +60,8 @@ $langs->load("banks"); $langs->load('bills'); $langs->load('donations'); $langs->load("accountancy"); +$langs->load("trips"); +$langs->load("hrm"); $id_bank_account = GETPOST('id_account', 'int'); @@ -103,11 +108,14 @@ $idpays = $p[0]; $sql = "SELECT b.rowid , b.dateo as do, b.datev as dv, b.amount, b.label, b.rappro, b.num_releve, b.num_chq, b.fk_type,"; $sql .= " ba.courant, ba.ref as baref, ba.account_number,"; -$sql .= " soc.code_compta, soc.code_compta_fournisseur, soc.rowid as socid, soc.nom as name, bu1.type as typeop"; +$sql .= " soc.code_compta, soc.code_compta_fournisseur, soc.rowid as socid, soc.nom as name, bu1.type as typeop,"; +$sql .= " u.accountancy_code, u.rowid as userid, u.lastname as name, u.firstname as firstname, bu2.type as typeop"; $sql .= " FROM " . MAIN_DB_PREFIX . "bank as b"; $sql .= " JOIN " . MAIN_DB_PREFIX . "bank_account as ba on b.fk_account=ba.rowid"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url as bu1 ON bu1.fk_bank = b.rowid AND bu1.type='company'"; +$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url as bu2 ON bu2.fk_bank = b.rowid AND bu2.type='user'"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as soc on bu1.url_id=soc.rowid"; +$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "user as u on bu2.url_id=u.rowid"; $sql .= " WHERE ba.rowid=" . $id_bank_account; $sql .= ' AND ba.entity IN ('.getEntity('bank_account', 0).')'; // We don't share object for accountancy if ($date_start && $date_end) @@ -123,6 +131,8 @@ $chargestatic = new ChargeSociales($db); $paymentdonstatic = new PaymentDonation($db); $paymentvatstatic = new TVA($db); $paymentsalstatic = new PaymentSalary($db); +$paymentsalstatic = new PaymentSalary($db); +$paymentexpensereportstatic = new PaymentExpenseReport($db); // Get code of finance journal $bank_code_journal = new Account($db); @@ -143,6 +153,7 @@ if ($result) { $account_transfer = (! empty($conf->global->ACCOUNTING_ACCOUNT_TRANSFER_CASH) ? $conf->global->ACCOUNTING_ACCOUNT_TRANSFER_CASH : $langs->trans("CodeNotDef")); $tabcompany = array(); + $tabuser = array(); $tabpay = array (); $tabbq = array (); $tabtp = array (); @@ -169,6 +180,15 @@ if ($result) { 'name' => $obj->name, 'code_compta' => $compta_soc, ); + + $compta_user = (! empty($obj->accountancy_code) ? $obj->accountancy_code : $account_employee); + + $tabuser[$obj->rowid] = array ( + 'id' => $obj->userid, + 'lastname' => $obj->lastname, + 'firstname' => $obj->firstname, + 'accountancy_code' => $compta_user, + ); // Variable bookkeeping $tabpay[$obj->rowid]["date"] = $obj->do; @@ -187,7 +207,7 @@ if ($result) { // Now loop on each link of record in bank. foreach ( $links as $key => $val ) { - if (in_array($links[$key]['type'], array('sc', 'payment_sc', 'payment', 'payment_supplier', 'payment_vat'))) // So we excluded 'company' here + if (in_array($links[$key]['type'], array('sc', 'payment_sc', 'payment', 'payment_supplier', 'payment_vat', 'payment_expensereport'))) // So we excluded 'company' here { // We save tabtype for a future use, to remember what kind of payment it is $tabtype[$obj->rowid] = $links[$key]['type']; @@ -211,7 +231,7 @@ if ($result) { $userstatic->id = $links[$key]['url_id']; $userstatic->name = $links[$key]['label']; $tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(1, '', 30); - // $tabtp[$obj->rowid][$compta_user] += $obj->amount; + $tabtp[$obj->rowid][$compta_user] += $obj->amount; } else if ($links[$key]['type'] == 'sc') { $chargestatic->id = $links[$key]['url_id']; $chargestatic->ref = $links[$key]['url_id']; @@ -256,7 +276,12 @@ if ($result) { $paymentsalstatic->ref = $links[$key]['url_id']; $paymentsalstatic->label = $links[$key]['label']; $tabpay[$obj->rowid]["lib"] .= ' ' . $paymentsalstatic->getNomUrl(2); - $tabtp[$obj->rowid][$account_employee] += $obj->amount; + // $tabtp[$obj->rowid][$account_employee] += $obj->amount; + } else if ($links[$key]['type'] == 'payment_expensereport') { + $paymentexpensereportstatic->id = $links[$key]['url_id']; + $paymentexpensereportstatic->fk_expensereport = $links[$key]['url_id']; + $tabpay[$obj->rowid]["lib"] .= ' ' . $paymentexpensereportstatic->getNomUrl(2); + $tabpay[$obj->rowid]["fk_expensereport"] = $paymentexpensereportstatic->id; } else if ($links[$key]['type'] == 'banktransfert') { $tabpay[$obj->rowid]["lib"] .= ' ' . $langs->trans("BankTransfer"); $tabtp[$obj->rowid][$account_transfer] += $obj->amount; @@ -335,10 +360,10 @@ if (! $error && $action == 'writebookkeeping') { if ($tabtype[$key] == 'payment') { $bookkeeping->code_tiers = $tabcompany[$key]['code_compta']; - + $sqlmid = 'SELECT fac.facnumber'; - $sqlmid .= " FROM " . MAIN_DB_PREFIX . "facture fac "; - $sqlmid .= " INNER JOIN " . MAIN_DB_PREFIX . "paiement_facture as payfac ON payfac.fk_facture=fac.rowid"; + $sqlmid .= " FROM " . MAIN_DB_PREFIX . "facture fac"; + $sqlmid .= " INNER JOIN " . MAIN_DB_PREFIX . "paiement_facture as payfac ON payfac.fk_facture=fac.rowid"; $sqlmid .= " INNER JOIN " . MAIN_DB_PREFIX . "paiement as pay ON payfac.fk_paiement=pay.rowid"; $sqlmid .= " WHERE pay.fk_bank=" . $key; dol_syslog("accountancy/journal/bankjournal.php:: sqlmid=" . $sqlmid, LOG_DEBUG); @@ -349,10 +374,10 @@ if (! $error && $action == 'writebookkeeping') { } } else if ($tabtype[$key] == 'payment_supplier') { $bookkeeping->code_tiers = $tabcompany[$key]['code_compta']; - + $sqlmid = 'SELECT facf.ref_supplier, facf.ref'; - $sqlmid .= " FROM " . MAIN_DB_PREFIX . "facture_fourn facf "; - $sqlmid .= " INNER JOIN " . MAIN_DB_PREFIX . "paiementfourn_facturefourn as payfacf ON payfacf.fk_facturefourn=facf.rowid"; + $sqlmid .= " FROM " . MAIN_DB_PREFIX . "facture_fourn facf"; + $sqlmid .= " INNER JOIN " . MAIN_DB_PREFIX . "paiementfourn_facturefourn as payfacf ON payfacf.fk_facturefourn=facf.rowid"; $sqlmid .= " INNER JOIN " . MAIN_DB_PREFIX . "paiementfourn as payf ON payfacf.fk_paiementfourn=payf.rowid"; $sqlmid .= " WHERE payf.fk_bank=" . $key; dol_syslog("accountancy/journal/bankjournal.php:: sqlmid=" . $sqlmid, LOG_DEBUG); @@ -361,6 +386,19 @@ if (! $error && $action == 'writebookkeeping') { $objmid = $db->fetch_object($resultmid); $bookkeeping->doc_ref = $objmid->ref_supplier . ' (' . $objmid->ref . ')'; // Ref on invoice } + } else if ($tabtype[$key] == 'payment_expensereport') { + $bookkeeping->code_tiers = $tabuser[$key]['accountancy_code']; + + $sqlmid = 'SELECT e.ref'; + $sqlmid .= " FROM " . MAIN_DB_PREFIX . "expensereport as e"; + $sqlmid .= " INNER JOIN " . MAIN_DB_PREFIX . "payment_expensereport as payer ON payer.fk_expensereport=e.rowid"; + $sqlmid .= " WHERE payer.fk_expensereport=" . $val["fk_expensereport"]; + dol_syslog("accountancy/journal/bankjournal.php:: sqlmid=" . $sqlmid, LOG_DEBUG); + $resultmid = $db->query($sqlmid); + if ($resultmid) { + $objmid = $db->fetch_object($resultmid); + $bookkeeping->doc_ref = $objmid->ref; // Ref of expensereport + } } $result = $bookkeeping->create($user); @@ -481,6 +519,7 @@ if ($action == 'export_csv') { include DOL_DOCUMENT_ROOT . '/accountancy/tpl/export_journal.tpl.php'; $companystatic = new Client($db); + $userstatic = new User($db); // Model Cegid Expert Export if ($conf->global->ACCOUNTING_EXPORT_MODELCSV == 2) @@ -504,12 +543,19 @@ if ($action == 'export_csv') { $reflabel = $langs->trans('Donation'); } if ($reflabel == '(SubscriptionPayment)') { - $reflabel = $langs->trans('Donation'); + $reflabel = $langs->trans('Subscription'); + } + if ($reflabel == '(ExpenseReportPayment)') { + $reflabel = $langs->trans('Employee'); } $companystatic->id = $tabcompany[$key]['id']; $companystatic->name = $tabcompany[$key]['name']; + $userstatic->id = $tabuser[$key]['id']; + $userstatic->lastname = $tabuser[$key]['lastname']; + $userstatic->firstname = $tabuser[$key]['firstname']; + // Bank foreach ( $tabbq[$key] as $k => $mt ) { print $date . $sep; @@ -646,6 +692,7 @@ $form = new Form($db); if (empty($action) || $action == 'view') { $invoicestatic = new Facture($db); $invoicesupplierstatic = new FactureFournisseur($db); + $expensereportstatic = new ExpenseReport($db); llxHeader('', $langs->trans("FinanceJournal")); @@ -723,7 +770,10 @@ if (empty($action) || $action == 'view') { $reflabel = $langs->trans('Donation'); } if ($reflabel == '(SubscriptionPayment)') { - $reflabel = $langs->trans('SubscriptionPayment'); + $reflabel = $langs->trans('Subscription'); + } + if ($reflabel == '(ExpenseReportPayment)') { + $reflabel = $langs->trans('Employee'); } $ref=$reflabel; @@ -755,6 +805,20 @@ if (empty($action) || $action == 'view') { } else dol_print_error($db); } + elseif ($tabtype[$key] == 'payment_expensereport') + { + $sqlmid = 'SELECT payer.fk_expensereport as id'; + $sqlmid .= " FROM " . MAIN_DB_PREFIX . "payment_expensereport as payer"; + $sqlmid .= " WHERE payer.fk_expensereport=" . $val["fk_expensereport"]; + dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG); + $resultmid = $db->query($sqlmid); + if ($resultmid) { + $objmid = $db->fetch_object($resultmid); + $expensereportstatic->fetch($objmid->id); + $ref=$langs->trans("ExpenseReport").' '.$expensereportstatic->getNomUrl(1); + } + else dol_print_error($db); + } /*$invoicestatic->id = $key; From 262d1d5f8c13d2bb5511734f4cefbaba67d7fe28 Mon Sep 17 00:00:00 2001 From: dolibarr95 Date: Mon, 27 Mar 2017 09:19:46 +0200 Subject: [PATCH 021/233] Create a trigger for company rib create --- .../class/companybankaccount.class.php | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index ec770d628a0..a30eee1820a 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -130,7 +130,9 @@ class CompanyBankAccount extends Account */ function update(User $user = null, $notrigger = 0) { - global $conf; + global $conf; + $error = 0; + if (! $this->id) { @@ -167,7 +169,28 @@ class CompanyBankAccount extends Account $result = $this->db->query($sql); if ($result) { - return 1; + + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('COMPANY_RIB_UPDATE',$user); + if ($result < 0) $error++; + // End call triggers + if(! $error ) + { + return 1; + } + else + { + return 0; + } + } + else + { + return 1; + } + } else { From 6ee1c79f6f20e1d9b538ad2711eb8f0d1a6ed585 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Mon, 27 Mar 2017 18:26:24 +0200 Subject: [PATCH 022/233] SOCIETE_ADD_REF_IN_LIST more display case GetNomUrl 0 = only socname (usual) 1 = socname and code_customer and supplier (like before) 2 = only code customer 3 = only code supplier --- htdocs/societe/class/societe.class.php | 33 +++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index ed3fdad13c4..36f9e8c609b 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1838,18 +1838,29 @@ class Societe extends CommonObject $name=$this->name?$this->name:$this->nom; - if (! empty($conf->global->SOCIETE_ADD_REF_IN_LIST) && (!empty($withpicto))) - { - if (($this->client) && (! empty ( $this->code_client ))) { - $code = $this->code_client . ' - '; - } - if (($this->fournisseur) && (! empty ( $this->code_fournisseur ))) { - $code .= $this->code_fournisseur . ' - '; - } - $name =$code.' '.$name; - } + if (! empty($conf->global->SOCIETE_ADD_REF_IN_LIST) && (!empty($withpicto))) + { + if (($this->client) && (! empty ( $this->code_client )) + && ($conf->global->SOCIETE_ADD_REF_IN_LIST == 1 + || $conf->global->SOCIETE_ADD_REF_IN_LIST == 2 + ) + ) + $code = $this->code_client . ' - '; - if (!empty($this->name_alias)) $name .= ' ('.$this->name_alias.')'; + if (($this->fournisseur) && (! empty ( $this->code_fournisseur )) + && ($conf->global->SOCIETE_ADD_REF_IN_LIST == 1 + || $conf->global->SOCIETE_ADD_REF_IN_LIST == 3 + ) + ) + $code .= $this->code_fournisseur . ' - '; + + if ($conf->global->SOCIETE_ADD_REF_IN_LIST == 1) + $name =$code.' '.$name; + else + $name =$code; + } + + if (!empty($this->name_alias)) $name .= ' ('.$this->name_alias.')'; $result=''; $label=''; $linkstart=''; $linkend=''; From 219bcb0d54f5c1b332d9df453c1b50e441e88599 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Mar 2017 22:44:50 +0200 Subject: [PATCH 023/233] Work on 6.0 features. --- htdocs/admin/modules.php | 67 +++++++------ ...nLog.class.php => modBlockedLog.class.php} | 17 ++-- htdocs/core/modules/modFacture.class.php | 5 +- htdocs/langs/en_US/admin.lang | 1 + htdocs/product/admin/dynamic_prices.php | 88 ++++++++++-------- htdocs/product/dynamic_price/editor.php | 20 ++-- htdocs/product/stock/mouvement.php | 93 ++++++++++--------- htdocs/theme/eldy/style.css.php | 13 +-- 8 files changed, 163 insertions(+), 141 deletions(-) rename htdocs/core/modules/{modBlockChainLog.class.php => modBlockedLog.class.php} (86%) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 52b250e8cf0..bfaeabf67d4 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -471,12 +471,10 @@ if ($mode == 'common') if (! empty($moreforfilter)) { - //print '
    '; print $moreforfilter; $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; - //print '
    '; } @@ -485,8 +483,6 @@ if ($mode == 'common') $moreforfilter=''; // Show list of modules - print '
    '; - print '
    ' . $langs->trans("Description") . '' . $langs->trans("Product") . '' . $langs->trans("batch_number") . '' . $langs->trans("EatByDate") . '' . dol_trunc($objp->comment) . '' . $objp->comment . '
    ' . $langs->trans('PaymentConditionsShort') . ''; - $form->select_conditions_paiements(GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $soc->cond_reglement_id, 'cond_reglement_id', -1, 1); + $form->select_conditions_paiements(GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $cond_reglement_id, 'cond_reglement_id', -1, 1); print '
    ' . $langs->trans('PaymentMode') . ''; - $form->select_types_paiements(GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $soc->mode_reglement_id, 'mode_reglement_id'); + $form->select_types_paiements(GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $mode_reglement_id, 'mode_reglement_id'); print '
    '.$langs->trans("LoanCapital").'
    '.$langs->trans("LoanCapital").'
    '.$langs->trans("Nbterms").'
    '.$langs->trans("Nbterms").'
    '.$langs->trans("Rate").' %
    '.$langs->trans("Rate").' %
    '; print $langs->trans("ThirdParty").'   '; print ''; - print $form->select_company($socid, 'socid', '', 1); + print $form->select_company($socid, 'socid', '', 'SelectThirdParty', 0, 0, null, 0); print '
    '."\n"; $oldfamily=''; @@ -570,14 +566,15 @@ if ($mode == 'common') // Print a separator if we change family if ($familykey!=$oldfamily) { - print ''."\n"; - print '
    '; + if ($oldfamily) print '

    '; + $familytext=empty($familyinfo[$familykey]['label'])?$familykey:$familyinfo[$familykey]['label']; - print $familytext; - print "\n"; - print ''.$langs->trans("SetupShort").''."\n"; - print "\n"; - $atleastoneforfamily=0; + print_fiche_titre($familytext, '', ''); + + print '
    '; + print ''."\n"; + + $atleastoneforfamily=0; } $atleastoneforfamily++; @@ -606,43 +603,38 @@ if ($mode == 'common') $imginfo="info_black"; } - print '\n"; + print ''."\n"; - // Picto - print ' '; - - // Name - print '\n"; // Desc - print '\n"; // Help - print ''; // Version - print '\n"; @@ -651,8 +643,12 @@ if ($mode == 'common') { $disableSetup = 0; - print ''; + print ''; } else { - print ''; + print ''; } } else { - print ''; + print ''; } } else // Module not yet activated { - print '\n"; - print ''; + print ''; } print "\n"; } + print "
    '; + // Picto + Name of module + print ' '; $alttext=''; //if (is_array($objMod->need_dolibarr_version)) $alttext.=($alttext?' - ':'').'Dolibarr >= '.join('.',$objMod->need_dolibarr_version); //if (is_array($objMod->phpmin)) $alttext.=($alttext?' - ':'').'PHP >= '.join('.',$objMod->phpmin); if (! empty($objMod->picto)) { if (preg_match('/^\//i',$objMod->picto)) print img_picto($alttext,$objMod->picto,' width="14px"',1); - else print img_object($alttext,$objMod->picto,' width="14px"'); + else print img_object($alttext, $objMod->picto, 'class="valignmiddle" width="14px"'); } else { - print img_object($alttext,'generic'); + print img_object($alttext, 'generic', 'class="valignmiddle"'); } - print ''.$objMod->getName(); + print ' '.$objMod->getName().''; print "'; + print ''; print nl2br($objMod->getDesc()); print "'; - + print ''; //print $form->textwithpicto('', $text, 1, $imginfo, 'minheight20', 0, 2, 1); print ''.img_picto($langs->trans("ClickToShowDescription"), $imginfo).''; - print ''; + print ''; print $versiontrans; print "'; - if (! empty($objMod->disabled)) + print ''; + if (! empty($arrayofwarnings[$modName])) + { + print ''."\n"; + } + if (! empty($objMod->disabled)) { print $langs->trans("Disabled"); } @@ -674,7 +670,7 @@ if ($mode == 'common') { if (is_array($objMod->config_page_url)) { - print ''; + print ''; $i=0; foreach ($objMod->config_page_url as $page) { @@ -700,22 +696,22 @@ if ($mode == 'common') } else if (preg_match('/^([^@]+)@([^@]+)$/i',$objMod->config_page_url,$regs)) { - print ''.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').''.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').''.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').''.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').''.img_picto($langs->trans("NothingToSetup"),"setup",'class="opacitytransp" style="padding-right: 6px"').''.img_picto($langs->trans("NothingToSetup"),"setup",'class="opacitytransp" style="padding-right: 6px"').''; + print ''; if (! empty($objMod->always_enabled)) { // Should never happened @@ -754,17 +750,20 @@ if ($mode == 'common') } } print ''."\n"; - print ''; + print ''; print img_picto($langs->trans("Disabled"),'switch_off'); print "\n"; } print "'.img_picto($langs->trans("NothingToSetup"),"setup",'class="opacitytransp" style="padding-right: 6px"').''.img_picto($langs->trans("NothingToSetup"),"setup",'class="opacitytransp" style="padding-right: 6px"').'
    \n"; print '
    '; diff --git a/htdocs/core/modules/modBlockChainLog.class.php b/htdocs/core/modules/modBlockedLog.class.php similarity index 86% rename from htdocs/core/modules/modBlockChainLog.class.php rename to htdocs/core/modules/modBlockedLog.class.php index dbf9cc406e9..30e4734e843 100644 --- a/htdocs/core/modules/modBlockChainLog.class.php +++ b/htdocs/core/modules/modBlockedLog.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2017 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,20 +16,19 @@ */ /** - * \defgroup blockchainlog Module BlockChainLog + * \defgroup blockedlog Module BlockedLog * \brief Add a log into a block chain for some actions. - * \file htdocs/core/modules/modBlockChainLog.class.php - * \ingroup blockchainlog - * \brief Description and activation file for module BlockChainLog + * \file htdocs/core/modules/modBlockedLog.class.php + * \ingroup blockedlog + * \brief Description and activation file for module BlockedLog */ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** * Class to describe a Cron module */ -class modBlockChainLog extends DolibarrModules +class modBlockedLog extends DolibarrModules { - /** * Constructor. Define names, constants, directories, boxes, permissions * @@ -47,14 +46,14 @@ class modBlockChainLog extends DolibarrModules $this->family = "technic"; // 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 of some business events into a non reversible block chain. This module may be mandatory for some countries."; + $this->description = "Enable a log on some business events into a reserved log. This module may be mandatory for some countries."; $this->version = 'development'; // 'development', 'experimental' or 'dolibarr' or version // 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); // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) $this->special = 1; // Name of image file used for this module. - $this->picto='skype'; + $this->picto='technic'; // Data directories to create when module is enabled $this->dirs = array(); diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index d6e6bfd2575..8022b21279f 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -64,11 +64,12 @@ class modFacture extends DolibarrModules $this->dirs = array("/facture/temp"); // Dependencies - $this->depends = array('always'=>"modSociete", 'FR'=>'modBlockChainLog'); + $this->depends = array('always'=>"modSociete", 'FR'=>'modBlockedLog'); $this->requiredby = array("modComptabilite","modAccounting"); $this->conflictwith = array(); $this->langfiles = array("bills","companies","compta","products"); - $this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='text') + $this->warnings_activation = array('FR'=>'WarningNoteModuleInvoiceForFrenchLaw'); // Warning to show when we activate module. array('always'='text') or array('FR'='text') + $this->warnings_activation = array(); $this->warnings_activation_ext = array('FR'=>'WarningInstallationMayBecomeNotCompliantWithLaw'); // Warning to show when we activate an external module. array('always'='text') or array('FR'='text') // Config pages diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index b8ba74995a7..3831fb49007 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1663,6 +1663,7 @@ ModuleEnabledAdminMustCheckRights=Module has been activated. Permissions for act 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")
    Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "Offset" in days)
    Use "Current/Next" to have payment term date being the first Nth of the month (N is stored into field "Nb of days") 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). WarningInstallationMayBecomeNotCompliantWithLaw=You try to install the module %s that is an external module. Activate an external module only if it does not alterate negatively the behavior required by your country laws (%s). If the module bring a non legal feature, you are the only responsible for the use of a non-compliant software. ##### Resource #### ResourceSetup=Configuration du module Resource diff --git a/htdocs/product/admin/dynamic_prices.php b/htdocs/product/admin/dynamic_prices.php index 7949b47c346..4345ea095ae 100644 --- a/htdocs/product/admin/dynamic_prices.php +++ b/htdocs/product/admin/dynamic_prices.php @@ -16,7 +16,7 @@ */ /** - * \file htdocs/product/admin/expression_globals.php + * \file htdocs/product/admin/dynamic_prices.php * \ingroup product * \brief Page for configuring dynamic prices */ @@ -161,16 +161,25 @@ if ($action != 'create_updater' && $action != 'edit_updater') { print ' '; //Space for buttons print ''; - $var=True; - foreach ($price_globals->listGlobalVariables() as $i=>$entry) { - $var = !$var; - print ''; - print ''.$entry->code.''; - print ''.$entry->description.''; - print ''.price($entry->value).''; - print 'id.'">'.img_edit().'  '; - print 'id.'">'.img_delete().''; - print ''; + $arrayglobalvars=$price_globals->listGlobalVariables(); + if (! empty($arrayglobalvars)) + { + foreach ($arrayglobalvars as $i=>$entry) { + $var = !$var; + print ''; + print ''.$entry->code.''; + print ''.$entry->description.''; + print ''.price($entry->value).''; + print 'id.'">'.img_edit().'  '; + print 'id.'">'.img_delete().''; + print ''; + } + } + else + { + print ''; + print $langs->trans("None"); + print ''; } print ''; @@ -218,16 +227,9 @@ if ($action == 'create_variable' || $action == 'edit_variable') { print ''; print ''; print ''; -} else if ($action != 'create_updater') { - //Action Buttons - print '
    '; - print ''.$langs->trans("Add").''; - print '
    '; - //Separator is only need for updaters table is showed after buttons - print '

    '; } -//Updaters table +// Updaters table if ($action != 'create_variable' && $action != 'edit_variable') { print $langs->trans("GlobalVariableUpdaters"); print ''; @@ -241,26 +243,34 @@ if ($action != 'create_variable' && $action != 'edit_variable') { print ''; //Space for buttons print ''; - $var=True; - foreach ($price_updaters->listUpdaters() as $i=>$entry) { - $code = ""; - if ($entry->fk_variable > 0) { - $res = $price_globals->fetch($entry->fk_variable); - if ($res > 0) { - $code = $price_globals->code; - } - } - $var = !$var; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + $arraypriceupdaters = $price_updaters->listUpdaters(); + if (! empty($arraypriceupdaters)) + { + foreach ($arraypriceupdaters as $i=>$entry) { + $code = ""; + if ($entry->fk_variable > 0) { + $res = $price_globals->fetch($entry->fk_variable); + if ($res > 0) { + $code = $price_globals->code; + } + } + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + } + else + { + print ''; } print '
     
    '.$code.''.$entry->description.''.$langs->trans("GlobalVariableUpdaterType".$entry->type).''.$entry->parameters.''.$entry->update_interval.''.$entry->getLastUpdated().'id.'">'.img_edit().'  '; - print 'id.'">'.img_delete().'
    '.$code.''.$entry->description.''.$langs->trans("GlobalVariableUpdaterType".$entry->type).''.$entry->parameters.''.$entry->update_interval.''.$entry->getLastUpdated().'id.'">'.img_edit().'  '; + print 'id.'">'.img_delete().'
    '; + print $langs->trans("None"); + print '
    '; diff --git a/htdocs/product/dynamic_price/editor.php b/htdocs/product/dynamic_price/editor.php index 0b93d17749a..055da4a3ad7 100644 --- a/htdocs/product/dynamic_price/editor.php +++ b/htdocs/product/dynamic_price/editor.php @@ -16,9 +16,9 @@ */ /** - * \file htdocs/product/dynamic_price/editor.php + * \file htdocs/product/dynamic_price/editor.php * \ingroup product - * \brief Page for editing expression + * \brief Page for editing expression */ require '../../main.inc.php'; @@ -60,6 +60,7 @@ else if ($action != 'delete') $price_expression->fetch($eid); } + /* * Actions */ @@ -157,23 +158,28 @@ if ($action == 'delete') } } + /* * View */ -//Header -llxHeader("","",$langs->trans("CardProduct".$product->type)); -print load_fiche_titre($langs->trans("PriceExpressionEditor")); $form = new Form($db); +llxHeader("","",$langs->trans("CardProduct".$product->type)); + +print load_fiche_titre($langs->trans("PriceExpressionEditor")); + //Form/Table print '
    '; print ''; print ''; + +dol_fiche_head(); + print ''; // Price expression selector -print ''; print '
    '.$langs->trans("PriceExpressionSelected").''; +print '
    '.$langs->trans("PriceExpressionSelected").''; $price_expression_list = array(0 => $langs->trans("New")); //Put the new as first option foreach ($price_expression->list_price_expression() as $entry) { $price_expression_list[$entry->id] = $entry->title; @@ -204,6 +210,8 @@ $doleditor->Create(); print '
    '; +dol_fiche_end(); + //Buttons print '
    '; print ''; diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php index d2ba81db86c..a3742dcc00d 100644 --- a/htdocs/product/stock/mouvement.php +++ b/htdocs/product/stock/mouvement.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2014 Regis Houssin * Copyright (C) 2015 Juanjo Menent * @@ -418,7 +418,7 @@ $sql.= " e.label as stock, e.rowid as entrepot_id, e.lieu,"; $sql.= " m.rowid as mid, m.value as qty, m.datem, m.fk_user_author, m.label, m.inventorycode, m.fk_origin, m.origintype,"; $sql.= " m.batch,"; $sql.= " pl.rowid as lotid, pl.eatby, pl.sellby,"; -$sql.= " u.login"; +$sql.= " u.login, u.photo, u.lastname, u.firstname"; // 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 @@ -728,43 +728,8 @@ if ($resql) print '
    '; print ''."\n"; - print ""; - if (! empty($arrayfields['m.rowid']['checked'])) print_liste_field_titre($arrayfields['m.rowid']['label'],$_SERVER["PHP_SELF"],'m.rowid','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['m.datem']['checked'])) print_liste_field_titre($arrayfields['m.datem']['label'],$_SERVER["PHP_SELF"],'m.datem','',$param,'',$sortfield,$sortorder); - 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['p.label']['checked'])) print_liste_field_titre($arrayfields['p.label']['label'],$_SERVER["PHP_SELF"],'p.label','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['m.batch']['checked'])) print_liste_field_titre($arrayfields['m.batch']['label'],$_SERVER["PHP_SELF"],'m.batch','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['pl.eatby']['checked'])) print_liste_field_titre($arrayfields['pl.eatby']['label'],$_SERVER["PHP_SELF"],'pl.eatby','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['pl.sellby']['checked'])) print_liste_field_titre($arrayfields['pl.sellby']['label'],$_SERVER["PHP_SELF"],'pl.sellby','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['e.label']['checked'])) print_liste_field_titre($arrayfields['e.label']['label'],$_SERVER["PHP_SELF"], "e.label","",$param,"",$sortfield,$sortorder); // We are on a specific warehouse card, no filter on other should be possible - if (! empty($arrayfields['m.fk_user_author']['checked'])) print_liste_field_titre($arrayfields['m.fk_user_author']['label'],$_SERVER["PHP_SELF"], "m.fk_user_author","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['m.inventorycode']['checked'])) print_liste_field_titre($arrayfields['m.inventorycode']['label'],$_SERVER["PHP_SELF"], "m.inventorycode","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['m.label']['checked'])) print_liste_field_titre($arrayfields['m.label']['label'],$_SERVER["PHP_SELF"], "m.label","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['origin']['checked'])) print_liste_field_titre($arrayfields['origin']['label'],$_SERVER["PHP_SELF"], "","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['m.value']['checked'])) print_liste_field_titre($langs->trans("Qty"),$_SERVER["PHP_SELF"], "m.value","",$param,'align="right"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['m.datec']['checked'])) print_liste_field_titre($arrayfields['p.datec']['label'],$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['m.tms']['checked'])) print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Lignes des champs de filtre - print ''; + print ''; if (! empty($arrayfields['m.rowid']['checked'])) { // Ref @@ -901,9 +866,44 @@ if ($resql) print ''; print "\n"; + print ''; + if (! empty($arrayfields['m.rowid']['checked'])) print_liste_field_titre($arrayfields['m.rowid']['label'],$_SERVER["PHP_SELF"],'m.rowid','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['m.datem']['checked'])) print_liste_field_titre($arrayfields['m.datem']['label'],$_SERVER["PHP_SELF"],'m.datem','',$param,'',$sortfield,$sortorder); + 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['p.label']['checked'])) print_liste_field_titre($arrayfields['p.label']['label'],$_SERVER["PHP_SELF"],'p.label','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['m.batch']['checked'])) print_liste_field_titre($arrayfields['m.batch']['label'],$_SERVER["PHP_SELF"],'m.batch','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['pl.eatby']['checked'])) print_liste_field_titre($arrayfields['pl.eatby']['label'],$_SERVER["PHP_SELF"],'pl.eatby','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['pl.sellby']['checked'])) print_liste_field_titre($arrayfields['pl.sellby']['label'],$_SERVER["PHP_SELF"],'pl.sellby','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['e.label']['checked'])) print_liste_field_titre($arrayfields['e.label']['label'],$_SERVER["PHP_SELF"], "e.label","",$param,"",$sortfield,$sortorder); // We are on a specific warehouse card, no filter on other should be possible + if (! empty($arrayfields['m.fk_user_author']['checked'])) print_liste_field_titre($arrayfields['m.fk_user_author']['label'],$_SERVER["PHP_SELF"], "m.fk_user_author","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['m.inventorycode']['checked'])) print_liste_field_titre($arrayfields['m.inventorycode']['label'],$_SERVER["PHP_SELF"], "m.inventorycode","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['m.label']['checked'])) print_liste_field_titre($arrayfields['m.label']['label'],$_SERVER["PHP_SELF"], "m.label","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['origin']['checked'])) print_liste_field_titre($arrayfields['origin']['label'],$_SERVER["PHP_SELF"], "","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['m.value']['checked'])) print_liste_field_titre($langs->trans("Qty"),$_SERVER["PHP_SELF"], "m.value","",$param,'align="right"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['m.datec']['checked'])) print_liste_field_titre($arrayfields['p.datec']['label'],$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['m.tms']['checked'])) print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + + $arrayofuniqueproduct=array(); - $var=True; while ($i < min($num,$limit)) { $objp = $db->fetch_object($resql); @@ -913,6 +913,7 @@ if ($resql) $productstatic->label=$objp->produit; $productstatic->type=$objp->type; $productstatic->entity=$objp->entity; + $productlot->id = $objp->lotid; $productlot->batch= $objp->batch; $productlot->eatby= $objp->eatby; @@ -929,8 +930,7 @@ if ($resql) $origin = ''; } - $var=!$var; - print ""; + print ""; // Id movement if (! empty($arrayfields['m.rowid']['checked'])) { @@ -984,10 +984,13 @@ if ($resql) // Author if (! empty($arrayfields['m.fk_user_author']['checked'])) { - print '\n"; } if (! empty($arrayfields['m.inventorycode']['checked'])) @@ -998,7 +1001,7 @@ if ($resql) if (! empty($arrayfields['m.label']['checked'])) { // Label of movement - print ''; + print ''; } if (! empty($arrayfields['origin']['checked'])) { diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index c8c0dda380b..babc2a190e2 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -272,18 +272,19 @@ input.select2-input { .liste_titre input[name=smonth], .liste_titre input[name=month], .liste_titre input[name=month_lim] { margin-right: 4px; } +input, input.flat, form.flat select, select, select.flat, .dataTables_length label select { + global->THEME_ELDY_SHOW_BORDER_INPUT)) + print "border: none;" + ?> +} input, input.flat, textarea, textarea.flat, form.flat select, select, select.flat, .dataTables_length label select { font-size: px; font-family: ; - -global->THEME_ELDY_SHOW_BORDER_INPUT)) - print "border: none;" -?> - - border-bottom: solid 1px rgba(0,0,0,.2); outline: none; margin: 0px 0px 0px 0px; + border-bottom: solid 1px rgba(0,0,0,.2); } + input { line-height: 17px; padding: 4px; From fc2b9a858b0e518b4088698c08b30faddbdd665c Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 28 Mar 2017 06:35:03 +0200 Subject: [PATCH 024/233] New : [FP17] Add multijournals in accountancy admin --- htdocs/accountancy/admin/journals.php | 170 ++++++ htdocs/accountancy/admin/journals_card.php | 296 ++++++++++ .../class/accountingjournal.class.php | 525 ++++++++++++++++++ htdocs/core/lib/accounting.lib.php | 4 +- htdocs/install/mysql/data/llx_accounting.sql | 2 +- .../install/mysql/migration/5.0.0-6.0.0.sql | 3 +- .../mysql/tables/llx_accounting_journal.sql | 2 +- htdocs/langs/en_US/accountancy.lang | 8 + 8 files changed, 1004 insertions(+), 6 deletions(-) create mode 100644 htdocs/accountancy/admin/journals.php create mode 100644 htdocs/accountancy/admin/journals_card.php create mode 100644 htdocs/accountancy/class/accountingjournal.class.php diff --git a/htdocs/accountancy/admin/journals.php b/htdocs/accountancy/admin/journals.php new file mode 100644 index 00000000000..72f81dc90ba --- /dev/null +++ b/htdocs/accountancy/admin/journals.php @@ -0,0 +1,170 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * \file htdocs/accountancy/admin/journals.php + * \ingroup Advanced accountancy + * \brief Setup page to configure journals + */ +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; + +$action = GETPOST('action'); + +// Load variable for pagination +$limit = GETPOST("limit")?GETPOST("limit","int"):$conf->liste_limit; +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if ($page == -1) { $page = 0; } +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortfield) $sortfield="j.rowid"; // Set here default search field +if (! $sortorder) $sortorder="ASC"; + +$langs->load("admin"); +$langs->load("compta"); +$langs->load("accountancy"); + +// Security check +if ($user->societe_id > 0) + accessforbidden(); +if (! $user->rights->accounting->fiscalyear) // If we can read accounting records, we shoul be able to see fiscal year. + accessforbidden(); + +$error = 0; + +// List of status +/* +static $tmptype2label = array ( + '0' => 'AccountingJournalTypeVariousOperation', + '1' => 'AccountingJournalTypeSale', + '2' => 'AccountingJournalTypePurchase', + '3' => 'AccountingJournalTypeBank', + '9' => 'AccountingJournalTypeHasNew' +); +$type2label = array ( + '' +); +foreach ( $tmptype2label as $key => $val ) + $type2label[$key] = $langs->trans($val); +*/ + +$errors = array (); + +$object = new AccountingJournal($db); + + +/* + * Actions + */ + + + +/* + * View + */ +$title = $langs->trans('AccountingJournals'); +$helpurl = ""; +llxHeader('', $title, $helpurl); + +$max = 100; +$form = new Form($db); + +$linkback = '' . $langs->trans("BackToModuleList") . ''; +print load_fiche_titre($langs->trans('ConfigAccountingExpert'), $linkback, 'title_setup'); + +$head = admin_accounting_prepare_head(null); + +dol_fiche_head($head, 'journal', $langs->trans("Configuration"), 0, 'cron'); + +$sql = "SELECT j.rowid, j.code, j.label, j.nature, j.active"; +$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_journal as j"; +// $sql .= " WHERE j.entity = " . $conf->entity; +$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); + +$result = $db->query($sql); +if ($result) { + $var = false; + $num = $db->num_rows($result); + + $i = 0; + + // $title = $langs->trans('AccountingJournals'); + // print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $params, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit, 1); + + // Load attribute_label + print '
    '; + print ''; $userstatic->id=$objp->fk_user_author; - $userstatic->lastname=$objp->login; - print $userstatic->getNomUrl(1); + $userstatic->login=$objp->login; + $userstatic->lastname=$objp->lastname; + $userstatic->firstname=$objp->firstname; + $userstatic->photo=$objp->photo; + print $userstatic->getNomUrl(-1); print "'.$objp->label.''.$objp->label.'
    '; + print ''; + // print ''; + print ''; + print ''; + print ''; + print ''; + + if ($num) { + $accountingjournalstatic = new AccountingJournal($db); + + while ( $i < $num && $i < $max ) { + $obj = $db->fetch_object($result); + $accountingjournalstatic->id = $obj->rowid; + print ''; + print ''; + print ''; + print ''; + print ''; + $var = ! $var; + $i ++; + } + } else { + print ''; + } + print '
    ' . $langs->trans("Ref") . '' . $langs->trans("Code") . '' . $langs->trans("Label") . '' . $langs->trans("Nature") . '
    ' . img_object($langs->trans("ShowJournal"), "technic") . ' ' . $obj->code . '' . $obj->label . '' . $accountingjournalstatic->LibType($obj->nature, 0) . '
    ' . $langs->trans("None") . '
    '; +} else { + dol_print_error($db); +} + +dol_fiche_end(); + +// Buttons +print '
    '; +if (! empty($user->rights->accounting->fiscalyear)) +{ + print '' . $langs->trans("NewAccountingJournal") . ''; +} +else +{ + print '' . $langs->trans("NewAccountingJournal") . ''; +} +print '
    '; + +llxFooter(); +$db->close(); \ No newline at end of file diff --git a/htdocs/accountancy/admin/journals_card.php b/htdocs/accountancy/admin/journals_card.php new file mode 100644 index 00000000000..c9c45f9a4e5 --- /dev/null +++ b/htdocs/accountancy/admin/journals_card.php @@ -0,0 +1,296 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/accountancy/admin/journals_card.php + * \ingroup Advanced accountancy + * \brief Page to show an accounting journal + */ +require '../../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; + +$langs->load("admin"); +$langs->load("compta"); +$langs->load("accountancy"); + +// Security check +if ($user->societe_id > 0) + accessforbidden(); +if (empty($user->rights->accounting->fiscalyear)) + accessforbidden(); + +$error = 0; + +$action = GETPOST('action', 'alpha'); +$confirm = GETPOST('confirm', 'alpha'); +$id = GETPOST('id', 'int'); + +// List of status +static $tmptype2label = array ( + '0' => 'AccountingJournalTypeVariousOperation', + '1' => 'AccountingJournalTypeSale', + '2' => 'AccountingJournalTypePurchase', + '3' => 'AccountingJournalTypeBank', + '9' => 'AccountingJournalTypeHasNew' +); +$type2label = array ( + '' +); +foreach ( $tmptype2label as $key => $val ) + $type2label[$key] = $langs->trans($val); + +$object = new AccountingJournal($db); + +/* + * Actions + */ + +if ($action == 'confirm_delete' && $confirm == "yes") { + $result = $object->delete($id); + if ($result >= 0) { + header("Location: journals.php"); + exit(); + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } +} + +else if ($action == 'add') { + if (! GETPOST('cancel', 'alpha')) { + $error = 0; + + $object->code = GETPOST('code', 'alpha'); + $object->label = GETPOST('label', 'alpha'); + $object->nature = GETPOST('nature', 'int'); + + if (empty($object->code)) { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Code")), null, 'errors'); + $error ++; + } + if (empty($object->label)) { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors'); + $error ++; + } + + if (! $error) { + $db->begin(); + + $id = $object->create($user); + + if ($id > 0) { + $db->commit(); + + header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id); + exit(); + } else { + $db->rollback(); + + setEventMessages($object->error, $object->errors, 'errors'); + $action = 'create'; + } + } else { + $action = 'create'; + } + } else { + header("Location: ./journals.php"); + exit(); + } +} + +// Update record +else if ($action == 'update') { + if (! GETPOST('cancel', 'alpha')) { + $result = $object->fetch($id); + + $object->code = GETPOST('code', 'alpha'); + $object->label = GETPOST('label', 'alpha'); + $object->nature = GETPOST('nature', 'int'); + + $result = $object->update($user); + + if ($result > 0) { + header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id); + exit(); + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } + } else { + header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id); + exit(); + } +} + + + +/* + * View + */ + +$title = $langs->trans("Journal") . " - " . $langs->trans("Card"); +$helpurl = ""; +llxHeader("",$title,$helpurl); + +$form = new Form($db); + +if ($action == 'create') +{ + print load_fiche_titre($langs->trans("NewAccountingJournal")); + + print ''; + print ''; + print ''; + + dol_fiche_head(); + + print ''; + + // Code + print ''; + + + // Label + print ''; + + // Nature + print ''; + print ''; + print ''; + + print '
    ' . $langs->trans("Code") . '
    ' . $langs->trans("Label") . '
    ' . $langs->trans("Status") . ''; + print $form->selectarray('nature', $type2label, GETPOST('nature')); + print '
    '; + + dol_fiche_end(); + + print '
    '; + print ''; + print '     '; + print ''; + print '
    '; + + print ''; +} else if ($id) { + $result = $object->fetch($id); + if ($result > 0) { + $head = fiscalyear_prepare_head($object); + + if ($action == 'edit') { + dol_fiche_head($head, 'card', $langs->trans("Fiscalyear"), 0, 'cron'); + + print '
    ' . "\n"; + print ''; + print ''; + print ''; + + print ''; + + // Ref + print ""; + print ''; + + // Label + print ''; + + // Date start + print ''; + + // Date end + print ''; + + // Nature + print ''; + + print '
    ' . $langs->trans("Ref") . ''; + print $object->ref; + print '
    ' . $langs->trans("Label") . ''; + print ''; + print '
    ' . $langs->trans("DateStart") . ''; + print $form->select_date($object->date_start ? $object->date_start : - 1, 'fiscalyear'); + print '
    ' . $langs->trans("DateEnd") . ''; + print $form->select_date($object->date_end ? $object->date_end : - 1, 'fiscalyearend'); + print '
    ' . $langs->trans("Type") . ''; + // print $form->selectarray('statut', $statut2label, $object->statut); + print $object->getLibStatut(4); + print '
    '; + + print '
    '; + print ''; + print '     '; + print ''; + print '
    '; + + print '
    '; + + dol_fiche_end(); + } else { + /* + * Confirm delete + */ + if ($action == 'delete') { + print $form->formconfirm($_SERVER["PHP_SELF"] . "?id=" . $id, $langs->trans("DeleteFiscalYear"), $langs->trans("ConfirmDeleteFiscalYear"), "confirm_delete"); + } + + dol_fiche_head($head, 'card', $langs->trans("Fiscalyear"), 0, 'cron'); + + print ''; + + $linkback = '' . $langs->trans("BackToList") . ''; + + // Ref + print ''; + + // Label + print '"; + + // Nature + print ''; + + print "
    ' . $langs->trans("Ref") . ''; + print $object->ref; + print ''; + print $linkback; + print '
    '; + print $form->editfieldkey("Label", 'label', $object->label, $object, $conf->global->MAIN_EDIT_ALSO_INLINE, 'alpha:32'); + print ''; + print $form->editfieldval("Label", 'label', $object->label, $object, $conf->global->MAIN_EDIT_ALSO_INLINE, 'alpha:32'); + print "
    ' . $langs->trans("Type") . '' . $object->getLibType(0) . '
    "; + + dol_fiche_end(); + + if (! empty($user->rights->accounting->fiscalyear)) + { + /* + * Barre d'actions + */ + print '
    '; + + print '' . $langs->trans('Modify') . ''; + + // print '' . $langs->trans('Delete') . ''; + + print '
    '; + } + } + } else { + dol_print_error($db); + } +} + +llxFooter(); +$db->close(); diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php new file mode 100644 index 00000000000..7b34c4171d8 --- /dev/null +++ b/htdocs/accountancy/class/accountingjournal.class.php @@ -0,0 +1,525 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/accountancy/class/accountingjournal.class.php + * \ingroup Advanced accountancy + * \brief File of class to manage accounting journals + */ + +/** + * Class to manage accounting accounts + */ +class AccountingJournal extends CommonObject +{ + 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; + + /** + * Constructor + * + * @param DoliDB $db Database handle + */ + function __construct($db) { + $this->db = $db; + } + + /** + * Load record in memory + * + * @param int $rowid Id + * @param string $account_number Account number + * @param int $limittocurrentchart 1=Do not load record if it is into another accounting system + * @return int <0 if KO, Id of record if OK and found + */ + function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0) { + global $conf; + + if ($rowid || $account_number) { + $sql = "SELECT a.rowid as rowid, a.datec, a.tms, a.fk_pcg_version, a.pcg_type, a.pcg_subtype, a.account_number, a.account_parent, a.label, a.fk_accounting_category, a.fk_user_author, a.fk_user_modif, a.active"; + $sql .= ", ca.label as category_label"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as a"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as ca ON a.fk_accounting_category = ca.rowid"; + $sql .= " WHERE"; + if ($rowid) { + $sql .= " a.rowid = '" . $rowid . "'"; + } elseif ($account_number) { + $sql .= " a.account_number = '" . $account_number . "'"; + } + if (! empty($limittocurrentchart)) { + $sql .= ' AND a.fk_pcg_version IN (SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid=' . $conf->global->CHARTOFACCOUNTS . ')'; + } + + dol_syslog(get_class($this) . "::fetch sql=" . $sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) { + $obj = $this->db->fetch_object($result); + + if ($obj) { + $this->id = $obj->rowid; + $this->rowid = $obj->rowid; + $this->datec = $obj->datec; + $this->tms = $obj->tms; + $this->fk_pcg_version = $obj->fk_pcg_version; + $this->pcg_type = $obj->pcg_type; + $this->pcg_subtype = $obj->pcg_subtype; + $this->account_number = $obj->account_number; + $this->account_parent = $obj->account_parent; + $this->label = $obj->label; + $this->account_category = $obj->fk_accounting_category; + $this->account_category_label = $obj->category_label; + $this->fk_user_author = $obj->fk_user_author; + $this->fk_user_modif = $obj->fk_user_modif; + $this->active = $obj->active; + $this->status = $obj->active; + + return $this->id; + } else { + return 0; + } + } else { + $this->error = "Error " . $this->db->lasterror(); + $this->errors[] = "Error " . $this->db->lasterror(); + } + } + return - 1; + } + + /** + * Insert new accounting account in chart of accounts + * + * @param User $user Use making action + * @param int $notrigger Disable triggers + * @return int <0 if KO, >0 if OK + */ + function create($user, $notrigger = 0) { + global $conf; + $error = 0; + $now = dol_now(); + + // Clean parameters + if (isset($this->fk_pcg_version)) + $this->fk_pcg_version = trim($this->fk_pcg_version); + if (isset($this->pcg_type)) + $this->pcg_type = trim($this->pcg_type); + if (isset($this->pcg_subtype)) + $this->pcg_subtype = trim($this->pcg_subtype); + if (isset($this->account_number)) + $this->account_number = trim($this->account_number); + if (isset($this->account_parent)) + $this->account_parent = trim($this->account_parent); + if (isset($this->label)) + $this->label = trim($this->label); + if (isset($this->account_category)) + $this->account_category = trim($this->account_category); + if (isset($this->fk_user_author)) + $this->fk_user_author = trim($this->fk_user_author); + if (isset($this->active)) + $this->active = trim($this->active); + + if (empty($this->pcg_type) || $this->pcg_type == '-1') + { + $this->pcg_type = 'XXXXXX'; + } + if (empty($this->pcg_subtype) || $this->pcg_subtype == '-1') + { + $this->pcg_subtype = 'XXXXXX'; + } + // Check parameters + // Put here code to add control on parameters values + + // Insert request + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_account("; + $sql .= "datec"; + $sql .= ", entity"; + $sql .= ", fk_pcg_version"; + $sql .= ", pcg_type"; + $sql .= ", pcg_subtype"; + $sql .= ", account_number"; + $sql .= ", account_parent"; + $sql .= ", label"; + $sql .= ", fk_accounting_category"; + $sql .= ", fk_user_author"; + $sql .= ", active"; + $sql .= ") VALUES ("; + $sql .= " '" . $this->db->idate($now) . "'"; + $sql .= ", " . $conf->entity; + $sql .= ", " . (empty($this->fk_pcg_version) ? 'NULL' : "'" . $this->db->escape($this->fk_pcg_version) . "'"); + $sql .= ", " . (empty($this->pcg_type) ? 'NULL' : "'" . $this->db->escape($this->pcg_type) . "'"); + $sql .= ", " . (empty($this->pcg_subtype) ? 'NULL' : "'" . $this->pcg_subtype . "'"); + $sql .= ", " . (empty($this->account_number) ? 'NULL' : "'" . $this->account_number . "'"); + $sql .= ", " . (empty($this->account_parent) ? 'NULL' : "'" . $this->db->escape($this->account_parent) . "'"); + $sql .= ", " . (empty($this->label) ? 'NULL' : "'" . $this->db->escape($this->label) . "'"); + $sql .= ", " . (empty($this->account_category) ? 'NULL' : "'" . $this->db->escape($this->account_category) . "'"); + $sql .= ", " . $user->id; + $sql .= ", " . (! isset($this->active) ? 'NULL' : $this->db->escape($this->active)); + $sql .= ")"; + + $this->db->begin(); + + dol_syslog(get_class($this) . "::create sql=" . $sql, LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { + $error ++; + $this->errors[] = "Error " . $this->db->lasterror(); + } + + if (! $error) { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_account"); + + // if (! $notrigger) { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action calls a trigger. + + // // 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 + if ($error) { + foreach ( $this->errors as $errmsg ) { + dol_syslog(get_class($this) . "::create " . $errmsg, LOG_ERR); + $this->error .= ($this->error ? ', ' . $errmsg : $errmsg); + } + $this->db->rollback(); + return - 1 * $error; + } else { + $this->db->commit(); + return $this->id; + } + } + + /** + * Update record + * + * @param User $user Use making update + * @return int <0 if KO, >0 if OK + */ + function update($user) + { + // Check parameters + if (empty($this->pcg_type) || $this->pcg_type == '-1') + { + $this->pcg_type = 'XXXXXX'; + } + if (empty($this->pcg_subtype) || $this->pcg_subtype == '-1') + { + $this->pcg_subtype = 'XXXXXX'; + } + + $this->db->begin(); + + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; + $sql .= " SET fk_pcg_version = " . ($this->fk_pcg_version ? "'" . $this->db->escape($this->fk_pcg_version) . "'" : "null"); + $sql .= " , pcg_type = " . ($this->pcg_type ? "'" . $this->db->escape($this->pcg_type) . "'" : "null"); + $sql .= " , pcg_subtype = " . ($this->pcg_subtype ? "'" . $this->db->escape($this->pcg_subtype) . "'" : "null"); + $sql .= " , account_number = '" . $this->account_number . "'"; + $sql .= " , account_parent = '" . $this->account_parent . "'"; + $sql .= " , label = " . ($this->label ? "'" . $this->db->escape($this->label) . "'" : "null"); + $sql .= " , fk_accounting_category = '" . $this->account_category . "'"; + $sql .= " , fk_user_modif = " . $user->id; + $sql .= " , active = '" . $this->active . "'"; + $sql .= " WHERE rowid = " . $this->id; + + dol_syslog(get_class($this) . "::update sql=" . $sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) { + $this->db->commit(); + return 1; + } else { + $this->error = $this->db->lasterror(); + $this->db->rollback(); + return - 1; + } + } + + /** + * Check usage of accounting code + * + * @return int <0 if KO, >0 if OK + */ + function checkUsage() { + global $langs; + + $sql = "(SELECT fk_code_ventilation FROM " . MAIN_DB_PREFIX . "facturedet"; + $sql .= " WHERE fk_code_ventilation=" . $this->id . ")"; + $sql .= "UNION"; + $sql .= "(SELECT fk_code_ventilation FROM " . MAIN_DB_PREFIX . "facture_fourn_det"; + $sql .= " WHERE fk_code_ventilation=" . $this->id . ")"; + + dol_syslog(get_class($this) . "::checkUsage sql=" . $sql, LOG_DEBUG); + $resql = $this->db->query($sql); + + if ($resql) { + $num = $this->db->num_rows($resql); + if ($num > 0) { + $this->error = $langs->trans('ErrorAccountancyCodeIsAlreadyUse'); + return 0; + } else { + return 1; + } + } else { + $this->error = $this->db->lasterror(); + return - 1; + } + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param int $notrigger 0=triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function delete($user, $notrigger = 0) { + $error = 0; + + $result = $this->checkUsage(); + + if ($result > 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. + + // // Call triggers + // include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + // $interface=new Interfaces($this->db); + // $result=$interface->run_triggers('ACCOUNTANCY_ACCOUNT_DELETE',$this,$user,$langs,$conf); + // if ($result < 0) { $error++; $this->errors=$interface->errors; } + // // End call triggers + // } + // } + + if (! $error) { + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_account"; + $sql .= " WHERE rowid=" . $this->id; + + dol_syslog(get_class($this) . "::delete sql=" . $sql); + $resql = $this->db->query($sql); + if (! $resql) { + $error ++; + $this->errors[] = "Error " . $this->db->lasterror(); + } + } + + // Commit or rollback + if ($error) { + 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->db->commit(); + return 1; + } + } else { + return - 1; + } + } + + /** + * Return clicable name (with picto eventually) + * + * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto + * @return string Chaine avec URL + */ + function getNomUrl($withpicto = 0) { + global $langs; + + $result = ''; + + $link = ''; + $linkend = ''; + + $picto = 'billr'; + + $label = $langs->trans("Show") . ': ' . $this->account_number . ' - ' . $this->label; + + if ($withpicto) + $result .= ($link . img_object($label, $picto) . $linkend); + if ($withpicto && $withpicto != 2) + $result .= ' '; + if ($withpicto != 2) + require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; + $result .= $link . length_accountg($this->account_number) . ' - ' . $this->label . $linkend; + return $result; + } + + /** + * Information on record + * + * @param int $id of record + * @return void + */ + 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; + + dol_syslog(get_class($this) . '::info sql=' . $sql); + $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->date_creation = $this->db->jdate($obj->datec); + $this->date_modification = $this->db->jdate($obj->tms); + } + $this->db->free($result); + } else { + dol_print_error($this->db); + } + } + + /** + * Account desactivate + * + * @param int $id Id + * @return int <0 if KO, >0 if OK + */ + function account_desactivate($id) { + $result = $this->checkUsage(); + + if ($result > 0) { + $this->db->begin(); + + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; + $sql .= "SET active = '0'"; + $sql .= " WHERE rowid = " . $this->db->escape($id); + + dol_syslog(get_class($this) . "::desactivate sql=" . $sql, LOG_DEBUG); + $result = $this->db->query($sql); + + if ($result) { + $this->db->commit(); + return 1; + } else { + $this->error = $this->db->lasterror(); + $this->db->rollback(); + return - 1; + } + } else { + return - 1; + } + } + + /** + * Account activate + * + * @param int $id Id + * @return int <0 if KO, >0 if OK + */ + function account_activate($id) { + $this->db->begin(); + + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; + $sql .= "SET active = '1'"; + $sql .= " WHERE rowid = " . $this->db->escape($id); + + dol_syslog(get_class($this) . "::activate sql=" . $sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) { + $this->db->commit(); + return 1; + } else { + $this->error = $this->db->lasterror(); + $this->db->rollback(); + return - 1; + } + } + + + /** + * Retourne le libelle du statut d'un user (actif, inactif) + * + * @param int $mode 0=libelle long, 1=libelle court + * @return string Label of type + */ + function getLibType($mode=0) + { + return $this->LibType($this->nature,$mode); + } + + /** + * Return type of an accounting journal + * + * @param int $nature Id type + * @param int $mode 0=libelle long, 1=libelle court + * @return string Label of type + */ + function LibType($nature,$mode=0) + { + global $langs; + + $langs->load("accountancy"); + + if ($mode == 0) + { + $prefix=''; + if ($nature == 9) return $langs->trans('AccountingJournalTypeHasNew'); + if ($nature == 3) return $langs->trans('AccountingJournalTypeBank'); + if ($nature == 2) return $langs->trans('AccountingJournalTypePurchase'); + if ($nature == 1) return $langs->trans('AccountingJournalTypeSale'); + if ($nature == 0) return $langs->trans('AccountingJournalTypeVariousOperation'); + } + if ($mode == 1) + { + if ($nature == 9) return $langs->trans('AccountingJournalTypeHasNew'); + if ($nature == 3) return $langs->trans('AccountingJournalTypeBank'); + if ($nature == 2) return $langs->trans('AccountingJournalTypePurchase'); + if ($nature == 1) return $langs->trans('AccountingJournalTypeSale'); + if ($nature == 0) return $langs->trans('AccountingJournalTypeVariousOperation'); + } + } +} diff --git a/htdocs/core/lib/accounting.lib.php b/htdocs/core/lib/accounting.lib.php index 8ec0713b01a..205acb9ba80 100644 --- a/htdocs/core/lib/accounting.lib.php +++ b/htdocs/core/lib/accounting.lib.php @@ -1,6 +1,6 @@ - * Copyright (C) 2013-2016 Alexandre Spangaro + * Copyright (C) 2013-2017 Alexandre Spangaro * Copyright (C) 2014 Florian Henry * * This program is free software; you can redistribute it and/or modify @@ -41,7 +41,7 @@ function admin_accounting_prepare_head(AccountingAccount $object=null) $head[$h][2] = 'general'; $h ++; - $head[$h][0] = DOL_URL_ROOT.'/accountancy/admin/journal.php'; + $head[$h][0] = DOL_URL_ROOT.'/accountancy/admin/journals.php'; $head[$h][1] = $langs->trans("Journaux"); $head[$h][2] = 'journal'; $h ++; diff --git a/htdocs/install/mysql/data/llx_accounting.sql b/htdocs/install/mysql/data/llx_accounting.sql index 1db22e7408d..5f0e8dd5416 100644 --- a/htdocs/install/mysql/data/llx_accounting.sql +++ b/htdocs/install/mysql/data/llx_accounting.sql @@ -34,7 +34,7 @@ delete from llx_accounting_journal; INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (1,'VT', 'Journal des ventes', 1, 1); INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (2,'AC', 'Journal des achats', 2, 1); INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (3,'BQ', 'Journal de banque', 3, 1); -INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (4,'OD', 'Journal des opérations diverses', 4, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (4,'OD', 'Journal des opérations diverses', 0, 1); INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (5,'AN', 'Journal des à-nouveaux', 9, 1); -- -- Descriptif des plans comptables FR PCG99-ABREGE diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 18683f71638..1ce53af43fe 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -101,7 +101,7 @@ CREATE TABLE llx_product_attribute_combination INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (1,'VT', 'Journal des ventes', 1, 1); INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (2,'AC', 'Journal des achats', 2, 1); INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (3,'BQ', 'Journal de banque', 3, 1); -INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (4,'OD', 'Journal des opérations diverses', 4, 1); +INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (4,'OD', 'Journal des opérations diverses', 0, 1); INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (5,'AN', 'Journal des à-nouveaux', 9, 1); ALTER TABLE llx_paiementfourn ADD COLUMN model_pdf varchar(255); @@ -150,4 +150,3 @@ create table llx_payment_various fk_user_author integer, fk_user_modif integer )ENGINE=innodb; ->>>>>>> uptream/develop diff --git a/htdocs/install/mysql/tables/llx_accounting_journal.sql b/htdocs/install/mysql/tables/llx_accounting_journal.sql index f3ee2a2e010..d9c6ea76e3e 100644 --- a/htdocs/install/mysql/tables/llx_accounting_journal.sql +++ b/htdocs/install/mysql/tables/llx_accounting_journal.sql @@ -22,6 +22,6 @@ create table llx_accounting_journal rowid integer AUTO_INCREMENT PRIMARY KEY, code varchar(32) NOT NULL, label varchar(128) NOT NULL, - nature smallint DEFAULT 0 NOT NULL, -- type of journals (1:Sale / 2:purchase / 3:bank / 4:various operations / 9: has-new) + nature smallint DEFAULT 0 NOT NULL, -- type of journals (0:various operations / 1:sale / 2:purchase / 3:bank / 9: has-new) active smallint DEFAULT 0 )ENGINE=innodb; diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index d8313e2a11b..f35b61055ad 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -198,6 +198,14 @@ ChangeBinding=Change the binding ApplyMassCategories=Apply mass categories AddAccountFromBookKeepingWithNoCategories=Add acccount already used with no categories CategoryDeleted=Category for the accounting account has been removed +AccountingJournals=Accounting journals +NewAccountingJournal=New accounting journal +ShowAccoutingJournal=Show accounting journal +AccountingJournalTypeVariousOperation=Various operation +AccountingJournalTypeSale=Sale +AccountingJournalTypePurchase=Purchase +AccountingJournalTypeBank=Bank +AccountingJournalTypeHasNew=Has-new ## Export Exports=Exports From 90a90e1a3c97717274caa9267844eaee85218ff3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Mar 2017 12:45:09 +0200 Subject: [PATCH 025/233] FIX #6533 #6590 --- htdocs/fourn/facture/paiement.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index bc01a38fc59..416e8c3c7c1 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -565,19 +565,16 @@ if (empty($action)) if (!$user->rights->societe->client->voir) $sql .= ' sc.fk_soc, sc.fk_user,'; $sql.= ' SUM(f.amount)'; $sql.= ' FROM '.MAIN_DB_PREFIX.'paiementfourn AS p'; - if (!$user->rights->societe->client->voir) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn AS pf ON p.rowid=pf.fk_paiementfourn'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn AS f ON f.rowid=pf.fk_facturefourn'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement AS c ON p.fk_paiement = c.id'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe AS s ON s.rowid = f.fk_soc'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; + if (!$user->rights->societe->client->voir) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE f.entity = ".$conf->entity; if (!$user->rights->societe->client->voir) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) - { - $sql .= ' AND f.fk_soc = '.$socid; - } + if ($socid > 0) $sql .= ' AND f.fk_soc = '.$socid; // Search criteria if ($search_ref) $sql .= natural_search('p.rowid', $search_ref); if ($search_account > 0) $sql .=" AND b.fk_account=".$search_account; From 80715ec61b7e0837e0c67e214aa67b407ed5bcd5 Mon Sep 17 00:00:00 2001 From: dolibarr95 Date: Tue, 28 Mar 2017 14:50:01 +0200 Subject: [PATCH 026/233] Return -1 instead of 0 if error --- htdocs/societe/class/companybankaccount.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index a30eee1820a..6a00de29259 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -183,7 +183,7 @@ class CompanyBankAccount extends Account } else { - return 0; + return -1; } } else @@ -195,7 +195,7 @@ class CompanyBankAccount extends Account else { dol_print_error($this->db); - return 0; + return -1; } } From e416ea275e0a808ebb46b686a05a7bce1902e26b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Mar 2017 18:42:23 +0200 Subject: [PATCH 027/233] Work on 6.0 look and feel --- htdocs/adherents/list.php | 93 ++++++++++--------- htdocs/adherents/subscription/list.php | 32 +++---- htdocs/comm/action/index.php | 12 +-- htdocs/comm/action/listactions.php | 8 +- htdocs/comm/action/peruser.php | 4 +- htdocs/compta/bank/annuel.php | 2 +- htdocs/compta/bank/bankentries.php | 74 ++++++++------- htdocs/compta/bank/card.php | 6 +- htdocs/compta/bank/class/account.class.php | 59 +++++++++++- htdocs/compta/bank/class/bankcateg.class.php | 5 +- htdocs/compta/bank/document.php | 2 +- htdocs/compta/bank/index.php | 64 +++++++------ htdocs/compta/bank/info.php | 24 +++-- htdocs/compta/bank/ligne.php | 15 ++- htdocs/compta/bank/treso.php | 2 +- htdocs/compta/facture/list.php | 82 ++++++++-------- htdocs/contrat/card.php | 38 ++++---- htdocs/contrat/contact.php | 2 +- htdocs/contrat/document.php | 2 +- htdocs/contrat/info.php | 20 ++-- htdocs/contrat/note.php | 2 +- htdocs/core/class/html.formactions.class.php | 2 +- htdocs/core/lib/agenda.lib.php | 2 +- htdocs/core/lib/bank.lib.php | 5 + htdocs/core/lib/functions.lib.php | 10 +- htdocs/core/tpl/objectline_create.tpl.php | 1 - htdocs/core/tpl/resource_add.tpl.php | 3 +- htdocs/core/tpl/resource_view.tpl.php | 8 +- htdocs/fichinter/list.php | 64 ++++++------- htdocs/fourn/commande/list.php | 83 +++++++++-------- htdocs/fourn/facture/list.php | 81 ++++++++-------- .../install/mysql/migration/5.0.0-6.0.0.sql | 2 + .../mysql/tables/llx_supplier_proposaldet.sql | 2 +- htdocs/projet/list.php | 70 +++++++------- htdocs/projet/tasks/list.php | 70 +++++++------- htdocs/resource/element_resource.php | 1 + htdocs/supplier_proposal/list.php | 29 +++--- htdocs/theme/eldy/style.css.php | 8 +- htdocs/theme/md/style.css.php | 5 +- 39 files changed, 550 insertions(+), 444 deletions(-) diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 28cd8773d53..8d00194993b 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -377,52 +377,10 @@ $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfiel print '
    '; print ''."\n"; -print ''; -if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) -{ - print ''; -} -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.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); -if (! empty($arrayfields['d.login']['checked'])) print_liste_field_titre($arrayfields['d.login']['label'],$_SERVER["PHP_SELF"],'d.login','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.morphy']['checked'])) print_liste_field_titre($arrayfields['d.morphy']['label'],$_SERVER["PHP_SELF"],'d.morphy','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['t.libelle']['checked'])) print_liste_field_titre($arrayfields['t.libelle']['label'],$_SERVER["PHP_SELF"],'t.libelle','',$param,'',$sortfield,$sortorder); -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($langs->trans("StateShort"),$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($langs->trans("Country"),$_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); -if (! empty($arrayfields['d.phone_mobile']['checked'])) print_liste_field_titre($arrayfields['d.phone_mobile']['label'],$_SERVER["PHP_SELF"],'d.phone_mobile','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.email']['checked'])) print_liste_field_titre($arrayfields['d.email']['label'],$_SERVER["PHP_SELF"],'d.email','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['d.datefin']['checked'])) print_liste_field_titre($arrayfields['d.datefin']['label'],$_SERVER["PHP_SELF"],'d.datefin','',$param,'align="center"',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['d.statut']['checked'])) print_liste_field_titre($arrayfields['d.statut']['label'],$_SERVER["PHP_SELF"],"d.statut","",$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; + // Line for filters fields -print ''; +print ''; // Line numbering if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) @@ -595,7 +553,50 @@ print ''; print "\n"; -$var=True; +print ''; +if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) +{ + print ''; +} +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.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); +if (! empty($arrayfields['d.login']['checked'])) print_liste_field_titre($arrayfields['d.login']['label'],$_SERVER["PHP_SELF"],'d.login','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.morphy']['checked'])) print_liste_field_titre($arrayfields['d.morphy']['label'],$_SERVER["PHP_SELF"],'d.morphy','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['t.libelle']['checked'])) print_liste_field_titre($arrayfields['t.libelle']['label'],$_SERVER["PHP_SELF"],'t.libelle','',$param,'',$sortfield,$sortorder); +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($langs->trans("StateShort"),$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($langs->trans("Country"),$_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); +if (! empty($arrayfields['d.phone_mobile']['checked'])) print_liste_field_titre($arrayfields['d.phone_mobile']['label'],$_SERVER["PHP_SELF"],'d.phone_mobile','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.email']['checked'])) print_liste_field_titre($arrayfields['d.email']['label'],$_SERVER["PHP_SELF"],'d.email','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['d.datefin']['checked'])) print_liste_field_titre($arrayfields['d.datefin']['label'],$_SERVER["PHP_SELF"],'d.datefin','',$param,'align="center"',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['d.statut']['checked'])) print_liste_field_titre($arrayfields['d.statut']['label'],$_SERVER["PHP_SELF"],"d.statut","",$param,'align="right"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; + $i = 0; while ($i < min($num, $limit)) { @@ -619,7 +620,7 @@ while ($i < min($num, $limit)) } $var=!$var; - print ""; + print ""; if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index d8116c79e94..0705a035ba0 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -159,22 +159,6 @@ if ($result) print '
    '; print '
    '.$langs->trans("NumberingShort").'
    '.$langs->trans("NumberingShort").'
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"c.rowid",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Name"),$_SERVER["PHP_SELF"],"d.lastname",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Login"),$_SERVER["PHP_SELF"],"d.login",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"c.note",$param,"",'align="left"',$sortfield,$sortorder); - if (! empty($conf->banque->enabled)) - { - print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"b.fk_account",$pram,"","",$sortfield,$sortorder); - } - print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"c.dateadh",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateEnd"),$_SERVER["PHP_SELF"],"c.datef",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"c.subscription",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre(''); - print "\n"; - - // Line for filters fields print ''; @@ -214,6 +198,22 @@ if ($result) print "\n"; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"c.rowid",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Name"),$_SERVER["PHP_SELF"],"d.lastname",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Login"),$_SERVER["PHP_SELF"],"d.login",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"c.note",$param,"",'align="left"',$sortfield,$sortorder); + if (! empty($conf->banque->enabled)) + { + print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"b.fk_account",$pram,"","",$sortfield,$sortorder); + } + print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"c.dateadh",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateEnd"),$_SERVER["PHP_SELF"],"c.datef",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"c.subscription",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + + // Static objects $subscription=new Subscription($db); $adherent=new Adherent($db); diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 25d410e7bdb..13fb3d9624f 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -306,28 +306,28 @@ $param.="&maxprint=".$maxprint; // Show navigation bar if (empty($action) || $action=='show_month') { - $nav ="".img_previous($langs->trans("Previous"), 'class="valignbottom"')."\n"; + $nav ="  \n"; $nav.=" ".dol_print_date(dol_mktime(0,0,0,$month,1,$year),"%b %Y"); $nav.=" \n"; - $nav.="".img_next($langs->trans("Next"), 'class="valignbottom"')."\n"; + $nav.="   \n"; $nav.="   (".$langs->trans("Today").")"; $picto='calendar'; } if ($action=='show_week') { - $nav ="".img_previous($langs->trans("Previous"), 'class="valignbottom"')."\n"; + $nav ="trans("Previous"))."\">  \n"; $nav.=" ".dol_print_date(dol_mktime(0,0,0,$first_month,$first_day,$first_year),"%Y").", ".$langs->trans("Week")." ".$week; $nav.=" \n"; - $nav.="".img_next($langs->trans("Next"), 'class="valignbottom"')."\n"; + $nav.="   trans("Next"))."\">\n"; $nav.="   (".$langs->trans("Today").")"; $picto='calendarweek'; } if ($action=='show_day') { - $nav ="".img_previous($langs->trans("Previous"), 'class="valignbottom"')."\n"; + $nav ="  \n"; $nav.=" ".dol_print_date(dol_mktime(0,0,0,$month,$day,$year),"daytextshort"); $nav.=" \n"; - $nav.="".img_next($langs->trans("Next"), 'class="valignbottom"')."\n"; + $nav.="   \n"; $nav.="   (".$langs->trans("Today").")"; $picto='calendarday'; } diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php index 0a08b6e55f1..8776984345b 100644 --- a/htdocs/comm/action/listactions.php +++ b/htdocs/comm/action/listactions.php @@ -29,6 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; +include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $langs->load("users"); $langs->load("companies"); @@ -147,6 +148,7 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETP $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); @@ -227,6 +229,7 @@ if ($type) $sql.= " AND c.id = ".$type; if ($status == '0') { $sql.= " AND a.percent = 0"; } if ($status == '-1') { $sql.= " AND a.percent = -1"; } // Not applicable if ($status == '50') { $sql.= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started +if ($status == '100') { $sql.= " AND a.percent = 100"; } if ($status == 'done' || $status == '100') { $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep2 <= '".$db->idate($now)."'))"; } if ($status == 'todo') { $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep2 > '".$db->idate($now)."'))"; } if ($search_title) $sql.=natural_search("a.label", $search_title); @@ -324,7 +327,6 @@ if ($resql) if ($optioncss != '') $nav.= ''; if ($actioncode) $nav.=''; if ($resourceid) $nav.=''; - if ($status || isset($_GET['status']) || isset($_POST['status'])) $nav.=''; if ($filter) $nav.=''; if ($filtert) $nav.=''; if ($socid) $nav.=''; @@ -368,7 +370,9 @@ if ($resql) print ''; print ''; print ''; - print ''; + print ''; // Action column print ''; } - if ($canedit) + if ($canedit && ! preg_match('/listaction/', $_SERVER["PHP_SELF"])) { // Status print ''; diff --git a/htdocs/core/lib/bank.lib.php b/htdocs/core/lib/bank.lib.php index 8e9fb7bc77a..ed13b736a7d 100644 --- a/htdocs/core/lib/bank.lib.php +++ b/htdocs/core/lib/bank.lib.php @@ -91,6 +91,11 @@ function bank_prepare_head(Account $object) // $this->tabs = array('entity:-tabname); to remove a tab complete_head_from_modules($conf, $langs, $object, $head, $h, 'bank'); + /*$head[$h][0] = DOL_URL_ROOT . "/compta/bank/info.php?id=" . $object->id; + $head[$h][1] = $langs->trans("Info"); + $head[$h][2] = 'info'; + $h++;*/ + complete_head_from_modules($conf, $langs, $object, $head, $h, 'bank', 'remove'); return $head; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 20186ebe28d..f9ba39f870e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2589,7 +2589,7 @@ function img_edit_remove($titlealt = 'default', $other='') * @param string $other Add more attributes on img * @return string Return tag img */ -function img_edit($titlealt = 'default', $float = 0, $other = '') +function img_edit($titlealt = 'default', $float = 0, $other = 'class="pictoedit"') { global $conf, $langs; @@ -2624,7 +2624,7 @@ function img_view($titlealt = 'default', $float = 0, $other = '') * @param string $other Add more attributes on img * @return string Retourne tag img */ -function img_delete($titlealt = 'default', $other = '') +function img_delete($titlealt = 'default', $other = 'class="pictodelete"') { global $conf, $langs; @@ -3450,8 +3450,7 @@ function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betwee } if ($page > 0) { - if (($conf->dol_use_jmobile != 4)) print ''; - else print '
  • '.$langs->trans("Previous").'
  • '; + print ''; } if ($betweenarrows) { @@ -3459,8 +3458,7 @@ function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betwee } if ($nextpage > 0) { - if (($conf->dol_use_jmobile != 4)) print ''; - else print '
  • '.$langs->trans("Next").'
  • '; + print ''; } if ($afterarrows) { diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 83725580db5..ed6bb2c9979 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -57,7 +57,6 @@ $nolinesbefore=(count($this->lines) == 0 || $forcetoshowtitlelines); if ($nolinesbefore) { ?> - diff --git a/htdocs/core/tpl/resource_add.tpl.php b/htdocs/core/tpl/resource_add.tpl.php index b521445701b..28c42c85b71 100644 --- a/htdocs/core/tpl/resource_add.tpl.php +++ b/htdocs/core/tpl/resource_add.tpl.php @@ -17,7 +17,8 @@ $out .= ''.$langs->trans("SelectResource").'
    '; +$out .= '
    '.$langs->trans("SelectResource").'
    '; +$out .= '
    '; $events=array(); $out .= $formresources->select_resource_list('','fk_resource','',1,1,0,$events,'',2); $out .= '
    '; diff --git a/htdocs/core/tpl/resource_view.tpl.php b/htdocs/core/tpl/resource_view.tpl.php index ecc9f32d837..cad54932c71 100644 --- a/htdocs/core/tpl/resource_view.tpl.php +++ b/htdocs/core/tpl/resource_view.tpl.php @@ -62,7 +62,7 @@ if( (array) $linked_resources && count($linked_resources) > 0) if ($linked_resource['rowid'] == GETPOST('lineid')) $style='style="background: orange;"'; - print '
    '; + print '
    '; print '
    '; print $object_resource->getNomUrl(1); @@ -90,19 +90,19 @@ if( (array) $linked_resources && count($linked_resources) > 0) print ''; print '
    '; - print '
    '; + print ''; } } } else { - print '
    '; + print '
    '; print '
    '.$langs->trans('NoResourceLinked').'
    '; print '
    '; print '
    '; print '
    '; print '
    '; - print '
    '; + print ''; } print '
    '; diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 563c57f5ad7..2ec1eb2af70 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -137,6 +137,8 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETP $form = new Form($db); $formfile = new FormFile($db); $objectstatic=new Fichinter($db); +$companystatic=new Societe($db); + llxHeader('', $langs->trans("Intervention")); @@ -253,36 +255,8 @@ if ($result) print '
    '; print '
    '; + print $formactions->form_select_status_action('formaction',$status,1,'status',1,2); + print ''; $searchpitco=$form->showFilterAndCheckAddButtons(0); diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index f5de3fa6ca3..61bf98634c4 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -242,10 +242,10 @@ $max_day_in_month = date("t",dol_mktime(0,0,0,$month,1,$year)); $tmpday = $first_day; -$nav ="".img_previous($langs->trans("Previous"), 'class="valignbottom"')."\n"; +$nav ="trans("Previous"))."\">   \n"; $nav.=" ".dol_print_date(dol_mktime(0,0,0,$first_month,$first_day,$first_year),"%Y").", ".$langs->trans("Week")." ".$week; $nav.=" \n"; -$nav.="".img_next($langs->trans("Next"), 'class="valignbottom"')."\n"; +$nav.="   trans("Next"))."\">\n"; $nav.="   (".$langs->trans("Today").")"; $picto='calendarweek'; diff --git a/htdocs/compta/bank/annuel.php b/htdocs/compta/bank/annuel.php index af63247f48d..a81a0072302 100644 --- a/htdocs/compta/bank/annuel.php +++ b/htdocs/compta/bank/annuel.php @@ -144,7 +144,7 @@ else // Onglets $head=bank_prepare_head($object); -dol_fiche_head($head,'annual',$langs->trans("FinancialAccount"),0,'account'); +dol_fiche_head($head, 'annual', $langs->trans("FinancialAccount"), -1, 'account'); $title=$langs->trans("FinancialAccount")." : ".$object->label; $link=($year_start?"".img_previous('', 'class="valignbottom"')." ".$langs->trans("Year")." ".img_next('', 'class="valignbottom"')."":""); diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index 9af9b6f4707..c7596a0aee2 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -720,43 +720,8 @@ if ($resql) print '
    '; print ''."\n"; - - // Fields title - print ''; - if (! empty($arrayfields['b.rowid']['checked'])) print_liste_field_titre($arrayfields['b.rowid']['label'],$_SERVER['PHP_SELF'],'b.rowid','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['description']['checked'])) print_liste_field_titre($arrayfields['description']['label'],$_SERVER['PHP_SELF'],'','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['b.dateo']['checked'])) print_liste_field_titre($arrayfields['b.dateo']['label'],$_SERVER['PHP_SELF'],'b.dateo','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['b.datev']['checked'])) print_liste_field_titre($arrayfields['b.datev']['label'],$_SERVER['PHP_SELF'],'b.datev, b.dateo, b.rowid','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['type']['checked'])) print_liste_field_titre($arrayfields['type']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['b.num_chq']['checked'])) print_liste_field_titre($arrayfields['b.num_chq']['label'],$_SERVER['PHP_SELF'],'b.num_chq','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['bu.label']['checked'])) print_liste_field_titre($arrayfields['bu.label']['label'],$_SERVER['PHP_SELF'],'bu.label','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['ba.ref']['checked'])) print_liste_field_titre($arrayfields['ba.ref']['label'],$_SERVER['PHP_SELF'],'ba.ref','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['b.debit']['checked'])) print_liste_field_titre($arrayfields['b.debit']['label'],$_SERVER['PHP_SELF'],'b.amount','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['b.credit']['checked'])) print_liste_field_titre($arrayfields['b.credit']['label'],$_SERVER['PHP_SELF'],'b.amount','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['balance']['checked'])) print_liste_field_titre($arrayfields['balance']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['b.num_releve']['checked'])) print_liste_field_titre($arrayfields['b.num_releve']['label'],$_SERVER['PHP_SELF'],'b.num_releve','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['b.conciliated']['checked'])) print_liste_field_titre($arrayfields['b.conciliated']['label'],$_SERVER['PHP_SELF'],'b.rappro','',$param,'align="center"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - print ''; + print ''; if (! empty($arrayfields['b.rowid']['checked'])) { print ''; print "\n"; + + // Fields title + print ''; + if (! empty($arrayfields['b.rowid']['checked'])) print_liste_field_titre($arrayfields['b.rowid']['label'],$_SERVER['PHP_SELF'],'b.rowid','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['description']['checked'])) print_liste_field_titre($arrayfields['description']['label'],$_SERVER['PHP_SELF'],'','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['b.dateo']['checked'])) print_liste_field_titre($arrayfields['b.dateo']['label'],$_SERVER['PHP_SELF'],'b.dateo','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['b.datev']['checked'])) print_liste_field_titre($arrayfields['b.datev']['label'],$_SERVER['PHP_SELF'],'b.datev, b.dateo, b.rowid','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['type']['checked'])) print_liste_field_titre($arrayfields['type']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['b.num_chq']['checked'])) print_liste_field_titre($arrayfields['b.num_chq']['label'],$_SERVER['PHP_SELF'],'b.num_chq','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['bu.label']['checked'])) print_liste_field_titre($arrayfields['bu.label']['label'],$_SERVER['PHP_SELF'],'bu.label','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['ba.ref']['checked'])) print_liste_field_titre($arrayfields['ba.ref']['label'],$_SERVER['PHP_SELF'],'ba.ref','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['b.debit']['checked'])) print_liste_field_titre($arrayfields['b.debit']['label'],$_SERVER['PHP_SELF'],'b.amount','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['b.credit']['checked'])) print_liste_field_titre($arrayfields['b.credit']['label'],$_SERVER['PHP_SELF'],'b.amount','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['balance']['checked'])) print_liste_field_titre($arrayfields['balance']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['b.num_releve']['checked'])) print_liste_field_titre($arrayfields['b.num_releve']['label'],$_SERVER['PHP_SELF'],'b.num_releve','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['b.conciliated']['checked'])) print_liste_field_titre($arrayfields['b.conciliated']['label'],$_SERVER['PHP_SELF'],'b.rappro','',$param,'align="center"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + + $balance = 0; // For balance $balancecalculated = false; diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index dcc0fc85ecc..0bb518662d6 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -713,7 +713,7 @@ else print '
    '; @@ -837,6 +802,43 @@ if ($resql) print '
    '; - print ''; + print ''; print ''; // Show fields of bank account @@ -957,7 +957,7 @@ else print '
    '; - print '
    '; + //print '
    '; print '
    '.$langs->trans("BankName").'
    '.$langs->trans("BankName").''.$object->bank.'
    '; @@ -991,7 +991,7 @@ else { print '
    '; - print '
    '; + //print '
    '; print '
    '; diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 1670ac2917c..8925a67d593 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1553,7 +1553,8 @@ class AccountLine extends CommonObject var $db; var $element='bank'; var $table_element='bank'; - + var $picto = 'generic'; + var $id; var $ref; var $datec; @@ -2040,5 +2041,61 @@ class AccountLine extends CommonObject return $result; } + + /** + * Return label of status (activity, closed) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long + * @return string Libelle + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->status,$mode); + } + + /** + * Renvoi le libelle d'un statut donne + * + * @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) + { + global $langs; + //$langs->load('companies'); + /* + if ($mode == 0) + { + if ($statut==0) return $langs->trans("ActivityCeased"); + if ($statut==1) return $langs->trans("InActivity"); + } + if ($mode == 1) + { + if ($statut==0) return $langs->trans("ActivityCeased"); + if ($statut==1) return $langs->trans("InActivity"); + } + if ($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"); + } + if ($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"'); + } + if ($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"); + } + if ($mode == 5) + { + if ($statut==0) return $langs->trans("ActivityCeased").' '.img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"'); + if ($statut==1) return $langs->trans("InActivity").' '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"'); + }*/ + } + } diff --git a/htdocs/compta/bank/class/bankcateg.class.php b/htdocs/compta/bank/class/bankcateg.class.php index 073c28be1ca..176fdb626a5 100644 --- a/htdocs/compta/bank/class/bankcateg.class.php +++ b/htdocs/compta/bank/class/bankcateg.class.php @@ -30,10 +30,11 @@ 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; - + /** * Constructor diff --git a/htdocs/compta/bank/document.php b/htdocs/compta/bank/document.php index db70acc7373..084cddf51cd 100644 --- a/htdocs/compta/bank/document.php +++ b/htdocs/compta/bank/document.php @@ -107,7 +107,7 @@ if ($id > 0 || !empty($ref)) { // Onglets $head = bank_prepare_head($object); - dol_fiche_head($head, 'document', $langs->trans("FinancialAccount"), 0, 'account'); + dol_fiche_head($head, 'document', $langs->trans("FinancialAccount"), -1, 'account'); // Construit liste des fichiers diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 29877302104..71397f695d6 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -285,39 +285,7 @@ $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfiel print '
    '; print '
    '."\n"; -// Fields title -print ''; -if (! empty($arrayfields['b.ref']['checked'])) print_liste_field_titre($arrayfields['b.ref']['label'],$_SERVER["PHP_SELF"],'b.ref','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['b.label']['checked'])) print_liste_field_titre($arrayfields['b.label']['label'],$_SERVER["PHP_SELF"],'b.label','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['accountype']['checked'])) print_liste_field_titre($arrayfields['accountype']['label'],$_SERVER["PHP_SELF"],'','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['b.number']['checked'])) print_liste_field_titre($arrayfields['b.number']['label'],$_SERVER["PHP_SELF"],'b.number','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['b.account_number']['checked'])) print_liste_field_titre($arrayfields['b.account_number']['label'],$_SERVER["PHP_SELF"],'b.account_number','',$param,'',$sortfield,$sortorder); -if (! empty($arrayfields['toreconcile']['checked'])) print_liste_field_titre($arrayfields['toreconcile']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['b.datec']['checked'])) print_liste_field_titre($arrayfields['b.datec']['label'],$_SERVER["PHP_SELF"],"b.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['b.tms']['checked'])) print_liste_field_titre($arrayfields['b.tms']['label'],$_SERVER["PHP_SELF"],"b.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['b.clos']['checked'])) print_liste_field_titre($arrayfields['b.clos']['label'],$_SERVER["PHP_SELF"],'b.clos','',$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['balance']['checked'])) print_liste_field_titre($arrayfields['balance']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; - - -print ''; +print ''; // Ref if (! empty($arrayfields['b.ref']['checked'])) { @@ -419,6 +387,36 @@ print $searchpitco; print ''; print ''; +// Fields title +print ''; +if (! empty($arrayfields['b.ref']['checked'])) print_liste_field_titre($arrayfields['b.ref']['label'],$_SERVER["PHP_SELF"],'b.ref','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['b.label']['checked'])) print_liste_field_titre($arrayfields['b.label']['label'],$_SERVER["PHP_SELF"],'b.label','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['accountype']['checked'])) print_liste_field_titre($arrayfields['accountype']['label'],$_SERVER["PHP_SELF"],'','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['b.number']['checked'])) print_liste_field_titre($arrayfields['b.number']['label'],$_SERVER["PHP_SELF"],'b.number','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['b.account_number']['checked'])) print_liste_field_titre($arrayfields['b.account_number']['label'],$_SERVER["PHP_SELF"],'b.account_number','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['toreconcile']['checked'])) print_liste_field_titre($arrayfields['toreconcile']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['b.datec']['checked'])) print_liste_field_titre($arrayfields['b.datec']['label'],$_SERVER["PHP_SELF"],"b.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['b.tms']['checked'])) print_liste_field_titre($arrayfields['b.tms']['label'],$_SERVER["PHP_SELF"],"b.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['b.clos']['checked'])) print_liste_field_titre($arrayfields['b.clos']['label'],$_SERVER["PHP_SELF"],'b.clos','',$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['balance']['checked'])) print_liste_field_titre($arrayfields['balance']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="right"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; $total = array(); $found = 0; $i=0; $lastcurrencycode=''; diff --git a/htdocs/compta/bank/info.php b/htdocs/compta/bank/info.php index a1952ab5957..15555e45338 100644 --- a/htdocs/compta/bank/info.php +++ b/htdocs/compta/bank/info.php @@ -30,6 +30,8 @@ $langs->load("banks"); $langs->load("categories"); $langs->load("companies"); +$id = GETPOST("rowid"); + /* * View @@ -37,27 +39,35 @@ $langs->load("companies"); llxHeader(); -$line = new AccountLine($db); -$line->fetch($_GET["rowid"]); -$line->info($_GET["rowid"]); +$object = new AccountLine($db); +$object->fetch($id); +$object->info($id); $h=0; -$head[$h][0] = DOL_URL_ROOT.'/compta/bank/ligne.php?rowid='.$_GET["rowid"]; +$head[$h][0] = DOL_URL_ROOT.'/compta/bank/ligne.php?rowid='.$id; $head[$h][1] = $langs->trans("Card"); $h++; -$head[$h][0] = DOL_URL_ROOT.'/compta/bank/info.php?rowid='.$_GET["rowid"]; +$head[$h][0] = DOL_URL_ROOT.'/compta/bank/info.php?rowid='.$id; $head[$h][1] = $langs->trans("Info"); $hselected = $h; $h++; -dol_fiche_head($head, $hselected, $langs->trans("LineRecord"),0,'account'); +dol_fiche_head($head, $hselected, $langs->trans("LineRecord"), -1, 'account'); + +$linkback = ''.$langs->trans("BackToList").''; + + +dol_banner_tab($object, 'rowid', $linkback); + +print '
    '; +print '
    '; print '
    '; -dol_print_object_info($line); +dol_print_object_info($object); print '
    '; print '
    '; diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index 558f1b0c042..f403f676f07 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -269,22 +269,27 @@ if ($result) print ''; print ''; - print ''; - $linkback = ''.$langs->trans("BackToList").''; + + dol_banner_tab($bankline, 'rowid', $linkback); + + print '
    '; + print '
    '; + // Ref + /* print '"; print ''; print ''; - + */ + $i++; - // Bank account - print ""; + print ''; print ''; diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php index e889b4dff19..5a42e516020 100644 --- a/htdocs/compta/bank/treso.php +++ b/htdocs/compta/bank/treso.php @@ -91,7 +91,7 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) // Onglets $head=bank_prepare_head($object); - dol_fiche_head($head,'cash',$langs->trans("FinancialAccount"),0,'account'); + dol_fiche_head($head, 'cash', $langs->trans("FinancialAccount"), -1, 'account'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 8ed52eddb97..eafd8900d37 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -742,48 +742,8 @@ if ($resql) print '
    '; print '
    '.$langs->trans("Ref")."'; print $form->showrefnav($bankline, 'rowid', $linkback, 1, 'rowid', 'rowid'); print '
    ".$langs->trans("Account")."
    '.$langs->trans("Account").''; print $acct->getNomUrl(1,'transactions'); print '
    '."\n"; - print ''; - if (! empty($arrayfields['f.facnumber']['checked'])) print_liste_field_titre($arrayfields['f.facnumber']['label'],$_SERVER['PHP_SELF'],'f.facnumber','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.ref_client']['checked'])) print_liste_field_titre($arrayfields['f.ref_client']['label'],$_SERVER["PHP_SELF"],'f.ref_client','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.type']['checked'])) print_liste_field_titre($arrayfields['f.type']['label'],$_SERVER["PHP_SELF"],'f.type','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.date']['checked'])) print_liste_field_titre($arrayfields['f.date']['label'],$_SERVER['PHP_SELF'],'f.datef','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'],$_SERVER['PHP_SELF'],"f.date_lim_reglement",'',$param,'align="center"',$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.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['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['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'],$_SERVER["PHP_SELF"],"f.fk_mode_reglement","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'],$_SERVER['PHP_SELF'],'f.total','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'],$_SERVER['PHP_SELF'],'f.tva','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],'f.total_ttc','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['dynamount_payed']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye,type,dynamount_payed","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Filters lines - print ''; + print ''; // Ref if (! empty($arrayfields['f.facnumber']['checked'])) { @@ -953,6 +913,46 @@ if ($resql) print ''; print "\n"; + print ''; + if (! empty($arrayfields['f.facnumber']['checked'])) print_liste_field_titre($arrayfields['f.facnumber']['label'],$_SERVER['PHP_SELF'],'f.facnumber','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.ref_client']['checked'])) print_liste_field_titre($arrayfields['f.ref_client']['label'],$_SERVER["PHP_SELF"],'f.ref_client','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.type']['checked'])) print_liste_field_titre($arrayfields['f.type']['label'],$_SERVER["PHP_SELF"],'f.type','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.date']['checked'])) print_liste_field_titre($arrayfields['f.date']['label'],$_SERVER['PHP_SELF'],'f.datef','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'],$_SERVER['PHP_SELF'],"f.date_lim_reglement",'',$param,'align="center"',$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.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['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['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'],$_SERVER["PHP_SELF"],"f.fk_mode_reglement","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'],$_SERVER['PHP_SELF'],'f.total','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'],$_SERVER['PHP_SELF'],'f.tva','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],'f.total_ttc','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['dynamount_payed']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye,type,dynamount_payed","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + if ($num > 0) { $i=0; diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 34f44c4f690..dc3ea846eee 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1868,7 +1868,7 @@ else print ''; print ''; - print '
    '; + print '
    '; // Definie date debut et fin par defaut $dateactstart = $objp->date_debut; @@ -1887,23 +1887,25 @@ else } } - print ''; + print ''; print ''; - print ''; - - print ''; print ''; - print ''; + print ''; + print ''; + print ''; + print ''; print '
    '.$langs->trans("DateServiceActivate").''; print $form->select_date($dateactstart,'',$usehm,$usehm,'',"active",1,0,1); print ''.$langs->trans("DateEndPlanned").''; print $form->select_date($dateactend,"end",$usehm,$usehm,'',"active",1,0,1); print ''; - print '
    '; - print ''; + print '
    '; print '
    '.$langs->trans("Comment").'
    '.$langs->trans("Comment").''; + print '   '; + print ''; + print '
    '; @@ -1913,13 +1915,13 @@ else if ($user->rights->contrat->activer && $action == 'unactivateline' && $object->lines[$cursorline-1]->id == GETPOST('ligne')) { /** - * Desactiver la ligne de contrat + * Disable a contract line */ print ''; print ''; - print ''; + print '
    '; // Definie date debut et fin par defaut $dateactstart = $objp->date_debut_reelle; @@ -1940,7 +1942,7 @@ else $now=dol_now(); if ($dateactend > $now) $dateactend=$now; - print ''; - - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print '
    '; + print '
    '; if ($objp->statut >= 4) { if ($objp->statut == 4) @@ -1950,13 +1952,17 @@ else } } print ''; - print '
    '; - print ''; + print '
    '; print '
    '.$langs->trans("Comment").'
    '.$langs->trans("Comment").''; + print '   '; + print ''; + print '
    '; print ''; diff --git a/htdocs/contrat/contact.php b/htdocs/contrat/contact.php index e6607729767..8510888cf35 100644 --- a/htdocs/contrat/contact.php +++ b/htdocs/contrat/contact.php @@ -130,7 +130,7 @@ if ($id > 0 || ! empty($ref)) $hselected=1; - dol_fiche_head($head, $hselected, $langs->trans("Contract"), 0, 'contract'); + dol_fiche_head($head, $hselected, $langs->trans("Contract"), -1, 'contract'); // Contract card diff --git a/htdocs/contrat/document.php b/htdocs/contrat/document.php index 289ec50b78b..35fbdf065b9 100644 --- a/htdocs/contrat/document.php +++ b/htdocs/contrat/document.php @@ -93,7 +93,7 @@ if ($object->id) { $head=contract_prepare_head($object); - dol_fiche_head($head, 'documents', $langs->trans("Contract"), 0, 'contract'); + dol_fiche_head($head, 'documents', $langs->trans("Contract"), -1, 'contract'); // Construit liste des fichiers diff --git a/htdocs/contrat/info.php b/htdocs/contrat/info.php index 7f20b21c888..35cca237b21 100644 --- a/htdocs/contrat/info.php +++ b/htdocs/contrat/info.php @@ -28,10 +28,14 @@ require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; $langs->load("contracts"); +$action = GETPOST('action','alpha'); +$confirm = GETPOST('confirm','alpha'); +$id = GETPOST('id','int'); +$ref = GETPOST('ref','alpha'); + // Security check -$contratid = GETPOST("id",'int'); if ($user->societe_id) $socid=$user->societe_id; -$result = restrictedArea($user, 'contrat',$contratid,''); +$result = restrictedArea($user, 'contrat', $id, ''); /* @@ -41,13 +45,17 @@ $result = restrictedArea($user, 'contrat',$contratid,''); llxHeader('',$langs->trans("Contract"),""); $object = new Contrat($db); -$object->fetch($contratid); -$object->fetch_thirdparty(); -$object->info($contratid); +$object->fetch($id, $ref); +if ($object->id > 0) +{ + $object->fetch_thirdparty(); +} + +$object->info($object->id); $head = contract_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans("Contract"), 0, 'contract'); +dol_fiche_head($head, 'info', $langs->trans("Contract"), -1, 'contract'); // Contract card diff --git a/htdocs/contrat/note.php b/htdocs/contrat/note.php index 212fa465266..7d4927d19b8 100644 --- a/htdocs/contrat/note.php +++ b/htdocs/contrat/note.php @@ -70,7 +70,7 @@ if ($id > 0 || ! empty($ref)) $hselected = 2; - dol_fiche_head($head, 'note', $langs->trans("Contract"), 0, 'contract'); + dol_fiche_head($head, 'note', $langs->trans("Contract"), -1, 'contract'); // Contract card diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index b44f854087c..6050679631f 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -120,7 +120,7 @@ class FormActions { //var_dump($selected); if ($selected == 'done') $selected='100'; - print ''; if ($showempty) print ''; foreach($listofstatus as $key => $val) { diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 91c5d24f36c..6c6f2d2f1d8 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -135,7 +135,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh print '
    global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="2"' : ''); ?>>
    trans('AddNewLine'); ?>trans("FreeZone"); ?>
    '."\n"; - print ''; - if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"f.ref","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER["PHP_SELF"],"s.nom","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.description']['checked'])) print_liste_field_titre($langs->trans("Description"),$_SERVER["PHP_SELF"],"f.description","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['fd.description']['checked'])) print_liste_field_titre('',$_SERVER["PHP_SELF"],''); - if (! empty($arrayfields['fd.date']['checked'])) print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"fd.date","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['fd.duree']['checked'])) print_liste_field_titre($langs->trans("Duration"),$_SERVER["PHP_SELF"],"fd.duree","",$param,'align="right"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"f.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - print ''; + print ''; if (! empty($arrayfields['f.ref']['checked'])) { print ''; print "\n"; - $companystatic=new Societe($db); - - $var=True; + print ''; + if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"f.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER["PHP_SELF"],"s.nom","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.description']['checked'])) print_liste_field_titre($langs->trans("Description"),$_SERVER["PHP_SELF"],"f.description","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['fd.description']['checked'])) print_liste_field_titre('',$_SERVER["PHP_SELF"],''); + if (! empty($arrayfields['fd.date']['checked'])) print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"fd.date","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['fd.duree']['checked'])) print_liste_field_titre($langs->trans("Duration"),$_SERVER["PHP_SELF"],"fd.duree","",$param,'align="right"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"f.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $total = 0; $i = 0; $totalarray=array(); diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 49de2dac7a3..f8062cc70bc 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -494,47 +494,7 @@ if ($resql) print '
    '; print '
    '; @@ -367,9 +341,35 @@ if ($result) print '
    '."\n"; - print ''; - if (! empty($arrayfields['cf.ref']['checked'])) print_liste_field_titre($arrayfields['cf.ref']['label'],$_SERVER["PHP_SELF"],"cf.ref","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['cf.ref_supplier']['checked'])) print_liste_field_titre($arrayfields['cf.ref_supplier']['label'],$_SERVER["PHP_SELF"],"cf.ref_supplier","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['p.project_ref']['checked'])) print_liste_field_titre($arrayfields['p.project_ref']['label'],$_SERVER["PHP_SELF"],"p.ref","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['u.login']['checked'])) print_liste_field_titre($arrayfields['u.login']['label'],$_SERVER["PHP_SELF"],"u.login","",$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.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['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['cf.fk_author']['checked'])) print_liste_field_titre($arrayfields['cf.fk_author']['label'],$_SERVER["PHP_SELF"],"cf.fk_author","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['cf.date_commande']['checked'])) print_liste_field_titre($arrayfields['cf.date_commande']['label'],$_SERVER["PHP_SELF"],"cf.date_commande","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.date_delivery']['checked'])) print_liste_field_titre($arrayfields['cf.date_delivery']['label'],$_SERVER["PHP_SELF"],'cf.date_livraison','',$param, 'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.total_ht']['checked'])) print_liste_field_titre($arrayfields['cf.total_ht']['label'],$_SERVER["PHP_SELF"],"cf.total_ht","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.total_vat']['checked'])) print_liste_field_titre($arrayfields['cf.total_vat']['label'],$_SERVER["PHP_SELF"],"cf.tva","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.total_ttc']['checked'])) print_liste_field_titre($arrayfields['cf.total_ttc']['label'],$_SERVER["PHP_SELF"],"cf.total_ttc","",$param,'align="right"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['cf.datec']['checked'])) print_liste_field_titre($arrayfields['cf.datec']['label'],$_SERVER["PHP_SELF"],"cf.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.tms']['checked'])) print_liste_field_titre($arrayfields['cf.tms']['label'],$_SERVER["PHP_SELF"],"cf.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.fk_statut']['checked'])) print_liste_field_titre($arrayfields['cf.fk_statut']['label'],$_SERVER["PHP_SELF"],"cf.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['cf.billed']['checked'])) print_liste_field_titre($arrayfields['cf.billed']['label'],$_SERVER["PHP_SELF"],'cf.billed','',$param,'align="center"',$sortfield,$sortorder,''); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - - print ''; + print ''; // Ref if (! empty($arrayfields['cf.ref']['checked'])) { @@ -687,6 +647,47 @@ if ($resql) print "\n"; + print ''; + if (! empty($arrayfields['cf.ref']['checked'])) print_liste_field_titre($arrayfields['cf.ref']['label'],$_SERVER["PHP_SELF"],"cf.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['cf.ref_supplier']['checked'])) print_liste_field_titre($arrayfields['cf.ref_supplier']['label'],$_SERVER["PHP_SELF"],"cf.ref_supplier","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['p.project_ref']['checked'])) print_liste_field_titre($arrayfields['p.project_ref']['label'],$_SERVER["PHP_SELF"],"p.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['u.login']['checked'])) print_liste_field_titre($arrayfields['u.login']['label'],$_SERVER["PHP_SELF"],"u.login","",$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.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['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['cf.fk_author']['checked'])) print_liste_field_titre($arrayfields['cf.fk_author']['label'],$_SERVER["PHP_SELF"],"cf.fk_author","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['cf.date_commande']['checked'])) print_liste_field_titre($arrayfields['cf.date_commande']['label'],$_SERVER["PHP_SELF"],"cf.date_commande","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.date_delivery']['checked'])) print_liste_field_titre($arrayfields['cf.date_delivery']['label'],$_SERVER["PHP_SELF"],'cf.date_livraison','',$param, 'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.total_ht']['checked'])) print_liste_field_titre($arrayfields['cf.total_ht']['label'],$_SERVER["PHP_SELF"],"cf.total_ht","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.total_vat']['checked'])) print_liste_field_titre($arrayfields['cf.total_vat']['label'],$_SERVER["PHP_SELF"],"cf.tva","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.total_ttc']['checked'])) print_liste_field_titre($arrayfields['cf.total_ttc']['label'],$_SERVER["PHP_SELF"],"cf.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['cf.datec']['checked'])) print_liste_field_titre($arrayfields['cf.datec']['label'],$_SERVER["PHP_SELF"],"cf.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.tms']['checked'])) print_liste_field_titre($arrayfields['cf.tms']['label'],$_SERVER["PHP_SELF"],"cf.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.fk_statut']['checked'])) print_liste_field_titre($arrayfields['cf.fk_statut']['label'],$_SERVER["PHP_SELF"],"cf.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['cf.billed']['checked'])) print_liste_field_titre($arrayfields['cf.billed']['label'],$_SERVER["PHP_SELF"],'cf.billed','',$param,'align="center"',$sortfield,$sortorder,''); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + + $total=0; $subtotal=0; $productstat_cache=array(); diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 3afb97c5fb1..dbfc9d8fd3c 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -490,48 +490,10 @@ if ($resql) print '
    '; print '
    '."\n"; - print ''; - if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($arrayfields['f.ref']['label'],$_SERVER['PHP_SELF'],'f.ref,f.rowid','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.ref_supplier']['checked'])) print_liste_field_titre($arrayfields['f.ref_supplier']['label'],$_SERVER["PHP_SELF"],'f.ref_supplier','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.label']['checked'])) print_liste_field_titre($arrayfields['f.label']['label'],$_SERVER['PHP_SELF'],"f.libelle,f.rowid",'',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.datef']['checked'])) print_liste_field_titre($arrayfields['f.datef']['label'],$_SERVER['PHP_SELF'],'f.datef,f.rowid','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'],$_SERVER['PHP_SELF'],"f.date_lim_reglement",'',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'],$_SERVER['PHP_SELF'],"p.ref",'',$param,'align="center"',$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.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['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['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'],$_SERVER["PHP_SELF"],"f.fk_mode_reglement","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'],$_SERVER['PHP_SELF'],'f.total','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'],$_SERVER['PHP_SELF'],'f.tva','',$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],'f.total_ttc','',$param,'align="right"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; + // Line for filters - - print ''; + print ''; // Ref if (! empty($arrayfields['f.ref']['checked'])) { @@ -690,6 +652,45 @@ if ($resql) print "\n"; + print ''; + if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($arrayfields['f.ref']['label'],$_SERVER['PHP_SELF'],'f.ref,f.rowid','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.ref_supplier']['checked'])) print_liste_field_titre($arrayfields['f.ref_supplier']['label'],$_SERVER["PHP_SELF"],'f.ref_supplier','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.label']['checked'])) print_liste_field_titre($arrayfields['f.label']['label'],$_SERVER['PHP_SELF'],"f.libelle,f.rowid",'',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.datef']['checked'])) print_liste_field_titre($arrayfields['f.datef']['label'],$_SERVER['PHP_SELF'],'f.datef,f.rowid','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'],$_SERVER['PHP_SELF'],"f.date_lim_reglement",'',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'],$_SERVER['PHP_SELF'],"p.ref",'',$param,'align="center"',$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.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['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['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'],$_SERVER["PHP_SELF"],"f.fk_mode_reglement","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'],$_SERVER['PHP_SELF'],'f.total','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'],$_SERVER['PHP_SELF'],'f.tva','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],'f.total_ttc','',$param,'align="right"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $facturestatic=new FactureFournisseur($db); $supplierstatic=new Fournisseur($db); $projectstatic=new Project($db); diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 6e098e4f59d..db85e68c8cd 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -25,6 +25,8 @@ -- -- VMYSQL4.1 DELETE FROM llx_usergroup_user WHERE fk_usergroup NOT IN (SELECT rowid from llx_usergroup); +ALTER TABLE llx_supplier_proposaldet ADD COLUMN fk_unit integer DEFAULT NULL; + ALTER TABLE llx_ecm_files ADD COLUMN ref varchar(128) AFTER rowid; ALTER TABLE llx_ecm_files CHANGE COLUMN fullpath filepath varchar(255); ALTER TABLE llx_ecm_files CHANGE COLUMN filepath filepath varchar(255); diff --git a/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql b/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql index ebe44b0f702..4b669f60ba3 100644 --- a/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql +++ b/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql @@ -52,5 +52,5 @@ CREATE TABLE llx_supplier_proposaldet ( multicurrency_total_ht double(24,8) DEFAULT 0, multicurrency_total_tva double(24,8) DEFAULT 0, multicurrency_total_ttc double(24,8) DEFAULT 0, - fk_unit integer DEFAULT NULL -- lien vers table des unités + fk_unit integer DEFAULT NULL ) ENGINE=innodb; \ No newline at end of file diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 7126e454d5c..236671eea4c 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -453,42 +453,8 @@ $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfiel print '
    '; print '
    '."\n"; - -print ''; -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['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'],$_SERVER["PHP_SELF"],"p.title","",$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['commercial']['checked'])) print_liste_field_titre($arrayfields['commercial']['label'],$_SERVER["PHP_SELF"],"","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['p.dateo']['checked'])) print_liste_field_titre($arrayfields['p.dateo']['label'],$_SERVER["PHP_SELF"],"p.dateo","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['p.datee']['checked'])) print_liste_field_titre($arrayfields['p.datee']['label'],$_SERVER["PHP_SELF"],"p.datee","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['p.public']['checked'])) print_liste_field_titre($arrayfields['p.public']['label'],$_SERVER["PHP_SELF"],"p.public","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['p.opp_amount']['checked'])) print_liste_field_titre($arrayfields['p.opp_amount']['label'],$_SERVER["PHP_SELF"],'p.opp_amount',"",$param,'align="right"',$sortfield,$sortorder); -if (! empty($arrayfields['p.fk_opp_status']['checked'])) print_liste_field_titre($arrayfields['p.fk_opp_status']['label'],$_SERVER["PHP_SELF"],'p.fk_opp_status',"",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['p.opp_percent']['checked'])) print_liste_field_titre($arrayfields['p.opp_percent']['label'],$_SERVER["PHP_SELF"],'p.opp_percent',"",$param,'align="right"',$sortfield,$sortorder); -if (! empty($arrayfields['p.budget_amount']['checked'])) print_liste_field_titre($arrayfields['p.budget_amount']['label'],$_SERVER["PHP_SELF"],'p.budget_amount',"",$param,'align="right"',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$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.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; -print ''; +print ''; if (! empty($arrayfields['p.ref']['checked'])) { print ''; print ''."\n"; +print ''; +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['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'],$_SERVER["PHP_SELF"],"p.title","",$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['commercial']['checked'])) print_liste_field_titre($arrayfields['commercial']['label'],$_SERVER["PHP_SELF"],"","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['p.dateo']['checked'])) print_liste_field_titre($arrayfields['p.dateo']['label'],$_SERVER["PHP_SELF"],"p.dateo","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['p.datee']['checked'])) print_liste_field_titre($arrayfields['p.datee']['label'],$_SERVER["PHP_SELF"],"p.datee","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['p.public']['checked'])) print_liste_field_titre($arrayfields['p.public']['label'],$_SERVER["PHP_SELF"],"p.public","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['p.opp_amount']['checked'])) print_liste_field_titre($arrayfields['p.opp_amount']['label'],$_SERVER["PHP_SELF"],'p.opp_amount',"",$param,'align="right"',$sortfield,$sortorder); +if (! empty($arrayfields['p.fk_opp_status']['checked'])) print_liste_field_titre($arrayfields['p.fk_opp_status']['label'],$_SERVER["PHP_SELF"],'p.fk_opp_status',"",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['p.opp_percent']['checked'])) print_liste_field_titre($arrayfields['p.opp_percent']['label'],$_SERVER["PHP_SELF"],'p.opp_percent',"",$param,'align="right"',$sortfield,$sortorder); +if (! empty($arrayfields['p.budget_amount']['checked'])) print_liste_field_titre($arrayfields['p.budget_amount']['label'],$_SERVER["PHP_SELF"],'p.budget_amount',"",$param,'align="right"',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$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.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="right"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; + $i=0; $totalarray=array(); while ($i < min($num,$limit)) diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 7d5e4eea1ae..dd43fd61d93 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -446,41 +446,7 @@ $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfiel print '
    '; print '
    '; @@ -617,6 +583,40 @@ print '
    '."\n"; -print ''; -if (! empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'],$_SERVER["PHP_SELF"],"t.ref","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['t.label']['checked'])) print_liste_field_titre($arrayfields['t.label']['label'],$_SERVER["PHP_SELF"],"t.label","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['t.dateo']['checked'])) print_liste_field_titre($arrayfields['t.dateo']['label'],$_SERVER["PHP_SELF"],"t.dateo","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['t.datee']['checked'])) print_liste_field_titre($arrayfields['t.datee']['label'],$_SERVER["PHP_SELF"],"t.datee","",$param,'align="center"',$sortfield,$sortorder); -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['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'],$_SERVER["PHP_SELF"],"p.title","",$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['p.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['t.planned_workload']['checked'])) print_liste_field_titre($arrayfields['t.planned_workload']['label'],$_SERVER["PHP_SELF"],"t.planned_workload","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['t.duration_effective']['checked'])) print_liste_field_titre($arrayfields['t.duration_effective']['label'],$_SERVER["PHP_SELF"],"t.duration_effective","",$param,'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['t.progress_calculated']['checked'])) print_liste_field_titre($arrayfields['t.progress_calculated']['label'],$_SERVER["PHP_SELF"],"","",$param,'align="center"'); -if (! empty($arrayfields['t.progress']['checked'])) print_liste_field_titre($arrayfields['t.progress']['label'],$_SERVER["PHP_SELF"],"t.progress","",$param,'align="center"',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; - -print ''; +print ''; if (! empty($arrayfields['t.ref']['checked'])) { print ''; print "\n"; +print ''; +if (! empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'],$_SERVER["PHP_SELF"],"t.ref","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['t.label']['checked'])) print_liste_field_titre($arrayfields['t.label']['label'],$_SERVER["PHP_SELF"],"t.label","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['t.dateo']['checked'])) print_liste_field_titre($arrayfields['t.dateo']['label'],$_SERVER["PHP_SELF"],"t.dateo","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['t.datee']['checked'])) print_liste_field_titre($arrayfields['t.datee']['label'],$_SERVER["PHP_SELF"],"t.datee","",$param,'align="center"',$sortfield,$sortorder); +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['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'],$_SERVER["PHP_SELF"],"p.title","",$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['p.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['t.planned_workload']['checked'])) print_liste_field_titre($arrayfields['t.planned_workload']['label'],$_SERVER["PHP_SELF"],"t.planned_workload","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['t.duration_effective']['checked'])) print_liste_field_titre($arrayfields['t.duration_effective']['label'],$_SERVER["PHP_SELF"],"t.duration_effective","",$param,'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['t.progress_calculated']['checked'])) print_liste_field_titre($arrayfields['t.progress_calculated']['label'],$_SERVER["PHP_SELF"],"","",$param,'align="center"'); +if (! empty($arrayfields['t.progress']['checked'])) print_liste_field_titre($arrayfields['t.progress']['label'],$_SERVER["PHP_SELF"],"t.progress","",$param,'align="center"',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; + $plannedworkloadoutputformat='allhourmin'; $timespentoutputformat='allhourmin'; diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php index fbb75e021ff..fc6e9ecb743 100644 --- a/htdocs/resource/element_resource.php +++ b/htdocs/resource/element_resource.php @@ -39,6 +39,7 @@ if (! empty($conf->projet->enabled)) { // Load traductions files requiredby by page $langs->load("resource"); $langs->load("other"); +$langs->load("interventions"); /* $sortorder = GETPOST('sortorder','alpha'); diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index caf79597e53..09dd0eb240c 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -509,23 +509,12 @@ if ($result) $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 '
    '; print '
    '; @@ -588,6 +554,40 @@ print $searchpitco; print '
    '; - // Fields title - print ''; - print_liste_field_titre($langs->trans('Ref'),$_SERVER["PHP_SELF"],'sp.ref','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Supplier'),$_SERVER["PHP_SELF"],'s.nom','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Date'),$_SERVER["PHP_SELF"],'sp.date_valid','',$param, 'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('SupplierProposalDate'),$_SERVER["PHP_SELF"],'sp.date_livraison','',$param, 'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('AmountHT'),$_SERVER["PHP_SELF"],'sp.total_ht','',$param, 'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Author'),$_SERVER["PHP_SELF"],'u.login','',$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Status'),$_SERVER["PHP_SELF"],'sp.fk_statut','',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - - print ''; + print ''; print ''; @@ -564,12 +553,24 @@ if ($result) print ''; // Check boxes print ''; print "\n"; + // Fields title + print ''; + print_liste_field_titre($langs->trans('Ref'),$_SERVER["PHP_SELF"],'sp.ref','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Supplier'),$_SERVER["PHP_SELF"],'s.nom','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Date'),$_SERVER["PHP_SELF"],'sp.date_valid','',$param, 'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('SupplierProposalDate'),$_SERVER["PHP_SELF"],'sp.date_livraison','',$param, 'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('AmountHT'),$_SERVER["PHP_SELF"],'sp.total_ht','',$param, 'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Author'),$_SERVER["PHP_SELF"],'u.login','',$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Status'),$_SERVER["PHP_SELF"],'sp.fk_statut','',$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $now = dol_now(); $var=true; $total=0; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 8d3ea40cb14..9b90e92e30d 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -269,7 +269,7 @@ input.select2-input { border-bottom: solid 1px rgba(0,0,0,.2) !important; /* required to avoid to lose bottom line when focus is lost on select2. */ } -.liste_titre input[name=smonth], .liste_titre input[name=month], .liste_titre input[name=month_lim] { +.liste_titre input[name=monthvalid], .liste_titre input[name=smonth], .liste_titre input[name=month], .liste_titre input[name=month_lim] { margin-right: 4px; } input, input.flat, form.flat select, select, select.flat, .dataTables_length label select { @@ -1064,6 +1064,9 @@ div.nopadding { .pictowarning, .pictopreview { padding-: 3px; } +.pictoedit, .pictowarning, .pictopreview, .pictodelete { + vertical-align: text-bottom; +} .colorthumb { padding-left: 1px !important; padding-right: 1px; @@ -2729,7 +2732,6 @@ tr.liste_titre th, tr.liste_titre td, th.liste_titre /* border-bottom: 1px solid #; */ border-bottom: 1px solid #888; } -/* TODO Once title line is moved under title search, make border bottom of all th black and force to white when it's first tr */ tr.liste_titre:first-child th, tr:first-child th.liste_titre { border-bottom: 1px solid #ddd ! important; } @@ -2758,7 +2760,7 @@ tr.liste_titre_topborder td { background: transparent; } tr.liste_titre:last-child th.liste_titre, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ - border-bottom: 1px solid rgb(); + border-bottom: 1px solid #ddd; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index d80630f0501..2ae5decbf96 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -281,7 +281,7 @@ textarea.cke_source:focus box-shadow: none; } -.liste_titre input[name=month], .liste_titre input[name=month_lim] { +.liste_titre input[name=monthvalid], .liste_titre input[name=smonth], .liste_titre input[name=month], .liste_titre input[name=month_lim] { margin-right: 4px; } input, input.flat, textarea, textarea.flat, form.flat select, select, select.flat, .dataTables_length label select { @@ -1109,6 +1109,9 @@ table.noborder tr.liste_titre td { .pictowarning, .pictopreview { padding-: 3px; } +.pictoedit, .pictowarning, .pictopreview, .pictodelete { + vertical-align: text-bottom; +} .colorthumb { padding-left: 1px !important; padding-right: 1px; From c84e20abaf246b51f32d7d269d0aa1b4c1e844ba Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Mar 2017 21:05:11 +0200 Subject: [PATCH 028/233] Fix translation --- htdocs/langs/en_US/propal.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index f383af9f1af..aefe8e89cd2 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -28,7 +28,7 @@ ShowPropal=Show proposal PropalsDraft=Drafts PropalsOpened=Open PropalStatusDraft=Draft (needs to be validated) -PropalStatusValidated=Validated (proposal is open) +PropalStatusValidated=Validated (proposal is opened) PropalStatusSigned=Signed (needs billing) PropalStatusNotSigned=Not signed (closed) PropalStatusBilled=Billed From ad3b54b93a01348a5ec65a88b4ae137629a70353 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Mar 2017 21:09:15 +0200 Subject: [PATCH 029/233] Fix regression --- htdocs/accountancy/customer/card.php | 2 +- htdocs/accountancy/expensereport/card.php | 2 +- htdocs/accountancy/journal/bankjournal.php | 1 - htdocs/accountancy/supplier/card.php | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/accountancy/customer/card.php b/htdocs/accountancy/customer/card.php index 7ec2a1903c8..baa70bf51e8 100644 --- a/htdocs/accountancy/customer/card.php +++ b/htdocs/accountancy/customer/card.php @@ -73,7 +73,7 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) { * View */ -llxHeader("", $langs->trans(FicheVentilation)); +llxHeader("", $langs->trans('FicheVentilation')); if ($cancel == $langs->trans("Cancel")) { $action = ''; diff --git a/htdocs/accountancy/expensereport/card.php b/htdocs/accountancy/expensereport/card.php index 808214becce..52440385e50 100644 --- a/htdocs/accountancy/expensereport/card.php +++ b/htdocs/accountancy/expensereport/card.php @@ -76,7 +76,7 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) { /* * View */ -llxHeader("", $langs->trans(FicheVentilation)); +llxHeader("", $langs->trans('FicheVentilation')); if ($cancel == $langs->trans("Cancel")) { $action = ''; diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 012a773b875..dc18a3417e8 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -131,7 +131,6 @@ $chargestatic = new ChargeSociales($db); $paymentdonstatic = new PaymentDonation($db); $paymentvatstatic = new TVA($db); $paymentsalstatic = new PaymentSalary($db); -$paymentsalstatic = new PaymentSalary($db); $paymentexpensereportstatic = new PaymentExpenseReport($db); // Get code of finance journal diff --git a/htdocs/accountancy/supplier/card.php b/htdocs/accountancy/supplier/card.php index 02b7a6aee59..b7c5979aa7a 100644 --- a/htdocs/accountancy/supplier/card.php +++ b/htdocs/accountancy/supplier/card.php @@ -76,7 +76,7 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) { /* * View */ -llxHeader("", $langs->trans(FicheVentilation)); +llxHeader("", $langs->trans('FicheVentilation')); if ($cancel == $langs->trans("Cancel")) { $action = ''; From 06c2f049270d69f00f1917590593d6e3f63656b1 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 29 Mar 2017 06:32:26 +0200 Subject: [PATCH 030/233] Finish work on multijournal admin part Need harmonization on rights --- htdocs/accountancy/admin/journals_card.php | 54 ++-- .../class/accountingjournal.class.php | 273 ++++++------------ htdocs/core/lib/accounting.lib.php | 29 ++ htdocs/langs/en_US/accountancy.lang | 4 + 4 files changed, 140 insertions(+), 220 deletions(-) diff --git a/htdocs/accountancy/admin/journals_card.php b/htdocs/accountancy/admin/journals_card.php index c9c45f9a4e5..9e04d75ce9f 100644 --- a/htdocs/accountancy/admin/journals_card.php +++ b/htdocs/accountancy/admin/journals_card.php @@ -122,6 +122,15 @@ else if ($action == 'update') { $object->label = GETPOST('label', 'alpha'); $object->nature = GETPOST('nature', 'int'); + if (empty($object->code)) { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Code")), null, 'errors'); + $error ++; + } + if (empty($object->label)) { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors'); + $error ++; + } + $result = $object->update($user); if ($result > 0) { @@ -161,15 +170,15 @@ if ($action == 'create') print '
    '; print ''; print ''; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpitco=$form->showFilterButtons(); print $searchpitco; print '
    '; // Code - print ''; + print ''; // Label - print ''; + print ''; // Nature print ''; - print ''; + print ''; print ''; @@ -188,10 +197,10 @@ if ($action == 'create') } else if ($id) { $result = $object->fetch($id); if ($result > 0) { - $head = fiscalyear_prepare_head($object); + $head = accounting_journal_prepare_head($object); if ($action == 'edit') { - dol_fiche_head($head, 'card', $langs->trans("Fiscalyear"), 0, 'cron'); + dol_fiche_head($head, 'card', $langs->trans("AccountingJournal"), 0, 'cron'); print '' . "\n"; print ''; @@ -200,10 +209,10 @@ if ($action == 'create') print '
    ' . $langs->trans("Code") . '
    ' . $langs->trans("Code") . '
    ' . $langs->trans("Label") . '
    ' . $langs->trans("Label") . '
    ' . $langs->trans("Status") . '' . $langs->trans("Type") . ''; print $form->selectarray('nature', $type2label, GETPOST('nature')); print '
    '; - // Ref + // Code print ""; - print ''; // Label @@ -211,20 +220,9 @@ if ($action == 'create') print ''; print ''; - // Date start - print ''; - - // Date end - print ''; - // Nature print ''; print '
    ' . $langs->trans("Ref") . ''; - print $object->ref; + print '' . $langs->trans("Code") . ''; + print ''; print '
    ' . $langs->trans("DateStart") . ''; - print $form->select_date($object->date_start ? $object->date_start : - 1, 'fiscalyear'); - print '
    ' . $langs->trans("DateEnd") . ''; - print $form->select_date($object->date_end ? $object->date_end : - 1, 'fiscalyearend'); - print '
    ' . $langs->trans("Type") . ''; - // print $form->selectarray('statut', $statut2label, $object->statut); - print $object->getLibStatut(4); + print $form->selectarray('nature', $type2label, $object->nature); print '
    '; @@ -246,15 +244,15 @@ if ($action == 'create') print $form->formconfirm($_SERVER["PHP_SELF"] . "?id=" . $id, $langs->trans("DeleteFiscalYear"), $langs->trans("ConfirmDeleteFiscalYear"), "confirm_delete"); } - dol_fiche_head($head, 'card', $langs->trans("Fiscalyear"), 0, 'cron'); + dol_fiche_head($head, 'card', $langs->trans("AccountingJournal"), 0, 'cron'); print ''; - $linkback = '' . $langs->trans("BackToList") . ''; + $linkback = '' . $langs->trans("BackToList") . ''; // Ref - print ''; @@ -267,7 +265,7 @@ if ($action == 'create') print ""; // Nature - print ''; + print ''; print "
    ' . $langs->trans("Ref") . ''; - print $object->ref; + print '
    ' . $langs->trans("Code") . ''; + print $object->code; print ''; print $linkback; print '
    ' . $langs->trans("Type") . '' . $object->getLibType(0) . '
    ' . $langs->trans("Type") . '' . $object->getLibType(0) . '
    "; @@ -281,9 +279,9 @@ if ($action == 'create') print ''; } } diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php index 7b34c4171d8..d7cc61d6418 100644 --- a/htdocs/accountancy/class/accountingjournal.class.php +++ b/htdocs/accountancy/class/accountingjournal.class.php @@ -26,24 +26,18 @@ */ class AccountingJournal extends CommonObject { - var $db; - var $error; - var $errors; - var $id; + public $element='accounting_journal'; + public $table_element='accounting_journal'; + public $fk_element = ''; + protected $ismultientitymanaged = 0; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + 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 $code; var $label; - var $fk_user_author; - var $fk_user_modif; - var $active; // duplicate with status - var $status; - + var $nature; // 0:various operations, 1:sale, 2:purchase, 3:bank, 9: has-new + var $active; + /** * Constructor * @@ -54,133 +48,75 @@ class AccountingJournal extends CommonObject } /** - * Load record in memory - * - * @param int $rowid Id - * @param string $account_number Account number - * @param int $limittocurrentchart 1=Do not load record if it is into another accounting system - * @return int <0 if KO, Id of record if OK and found - */ - function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0) { - global $conf; - - if ($rowid || $account_number) { - $sql = "SELECT a.rowid as rowid, a.datec, a.tms, a.fk_pcg_version, a.pcg_type, a.pcg_subtype, a.account_number, a.account_parent, a.label, a.fk_accounting_category, a.fk_user_author, a.fk_user_modif, a.active"; - $sql .= ", ca.label as category_label"; - $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as a"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as ca ON a.fk_accounting_category = ca.rowid"; - $sql .= " WHERE"; - if ($rowid) { - $sql .= " a.rowid = '" . $rowid . "'"; - } elseif ($account_number) { - $sql .= " a.account_number = '" . $account_number . "'"; - } - if (! empty($limittocurrentchart)) { - $sql .= ' AND a.fk_pcg_version IN (SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid=' . $conf->global->CHARTOFACCOUNTS . ')'; - } + * Load an object from database + * + * @param int $id Id of record to load + * @return int <0 if KO, >0 if OK + */ + function fetch($id) + { + $sql = "SELECT rowid, code, label, nature, active"; + $sql.= " FROM ".MAIN_DB_PREFIX."accounting_journal"; + $sql.= " WHERE rowid = ".$id; - dol_syslog(get_class($this) . "::fetch sql=" . $sql, LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) { - $obj = $this->db->fetch_object($result); - - if ($obj) { - $this->id = $obj->rowid; - $this->rowid = $obj->rowid; - $this->datec = $obj->datec; - $this->tms = $obj->tms; - $this->fk_pcg_version = $obj->fk_pcg_version; - $this->pcg_type = $obj->pcg_type; - $this->pcg_subtype = $obj->pcg_subtype; - $this->account_number = $obj->account_number; - $this->account_parent = $obj->account_parent; - $this->label = $obj->label; - $this->account_category = $obj->fk_accounting_category; - $this->account_category_label = $obj->category_label; - $this->fk_user_author = $obj->fk_user_author; - $this->fk_user_modif = $obj->fk_user_modif; - $this->active = $obj->active; - $this->status = $obj->active; - - return $this->id; - } else { - return 0; - } - } else { - $this->error = "Error " . $this->db->lasterror(); - $this->errors[] = "Error " . $this->db->lasterror(); - } + dol_syslog(get_class($this)."::fetch sql=" . $sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ( $result ) + { + $obj = $this->db->fetch_object($result); + + $this->id = $obj->rowid; + + $this->code = $obj->code; + $this->ref = $obj->code; + $this->label = $obj->label; + $this->nature = $obj->nature; + $this->active = $obj->active; + + return 1; + } + else + { + $this->error=$this->db->lasterror(); + return -1; } - return - 1; } /** - * Insert new accounting account in chart of accounts + * Insert journal in database * - * @param User $user Use making action - * @param int $notrigger Disable triggers - * @return int <0 if KO, >0 if OK + * @param User $user Use making action + * @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(); // Clean parameters - if (isset($this->fk_pcg_version)) - $this->fk_pcg_version = trim($this->fk_pcg_version); - if (isset($this->pcg_type)) - $this->pcg_type = trim($this->pcg_type); - if (isset($this->pcg_subtype)) - $this->pcg_subtype = trim($this->pcg_subtype); - if (isset($this->account_number)) - $this->account_number = trim($this->account_number); - if (isset($this->account_parent)) - $this->account_parent = trim($this->account_parent); + if (isset($this->code)) + $this->code = trim($this->code); if (isset($this->label)) $this->label = trim($this->label); - if (isset($this->account_category)) - $this->account_category = trim($this->account_category); - if (isset($this->fk_user_author)) - $this->fk_user_author = trim($this->fk_user_author); - if (isset($this->active)) - $this->active = trim($this->active); - - if (empty($this->pcg_type) || $this->pcg_type == '-1') - { - $this->pcg_type = 'XXXXXX'; - } - if (empty($this->pcg_subtype) || $this->pcg_subtype == '-1') - { - $this->pcg_subtype = 'XXXXXX'; - } + // Check parameters - // Put here code to add control on parameters values - + if (empty($this->nature) || $this->nature == '-1') + { + $this->nature = '0'; + } + // Insert request - $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_account("; - $sql .= "datec"; - $sql .= ", entity"; - $sql .= ", fk_pcg_version"; - $sql .= ", pcg_type"; - $sql .= ", pcg_subtype"; - $sql .= ", account_number"; - $sql .= ", account_parent"; + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_journal("; + $sql .= "code"; $sql .= ", label"; - $sql .= ", fk_accounting_category"; - $sql .= ", fk_user_author"; + $sql .= ", nature"; $sql .= ", active"; $sql .= ") VALUES ("; - $sql .= " '" . $this->db->idate($now) . "'"; - $sql .= ", " . $conf->entity; - $sql .= ", " . (empty($this->fk_pcg_version) ? 'NULL' : "'" . $this->db->escape($this->fk_pcg_version) . "'"); - $sql .= ", " . (empty($this->pcg_type) ? 'NULL' : "'" . $this->db->escape($this->pcg_type) . "'"); - $sql .= ", " . (empty($this->pcg_subtype) ? 'NULL' : "'" . $this->pcg_subtype . "'"); - $sql .= ", " . (empty($this->account_number) ? 'NULL' : "'" . $this->account_number . "'"); - $sql .= ", " . (empty($this->account_parent) ? 'NULL' : "'" . $this->db->escape($this->account_parent) . "'"); + $sql .= " " . (empty($this->code) ? 'NULL' : "'" . $this->db->escape($this->code) . "'"); $sql .= ", " . (empty($this->label) ? 'NULL' : "'" . $this->db->escape($this->label) . "'"); - $sql .= ", " . (empty($this->account_category) ? 'NULL' : "'" . $this->db->escape($this->account_category) . "'"); - $sql .= ", " . $user->id; + $sql .= ", " . (empty($this->nature) ? '0' : "'" . $this->db->escape($this->nature) . "'"); $sql .= ", " . (! isset($this->active) ? 'NULL' : $this->db->escape($this->active)); $sql .= ")"; @@ -194,7 +130,7 @@ class AccountingJournal extends CommonObject } if (! $error) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_account"); + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_journal"); // if (! $notrigger) { // Uncomment this and change MYOBJECT to your own tag if you @@ -232,26 +168,17 @@ class AccountingJournal extends CommonObject function update($user) { // Check parameters - if (empty($this->pcg_type) || $this->pcg_type == '-1') + if (empty($this->nature) || $this->nature == '-1') { - $this->pcg_type = 'XXXXXX'; + $this->nature = '0'; } - if (empty($this->pcg_subtype) || $this->pcg_subtype == '-1') - { - $this->pcg_subtype = 'XXXXXX'; - } - + $this->db->begin(); - $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; - $sql .= " SET fk_pcg_version = " . ($this->fk_pcg_version ? "'" . $this->db->escape($this->fk_pcg_version) . "'" : "null"); - $sql .= " , pcg_type = " . ($this->pcg_type ? "'" . $this->db->escape($this->pcg_type) . "'" : "null"); - $sql .= " , pcg_subtype = " . ($this->pcg_subtype ? "'" . $this->db->escape($this->pcg_subtype) . "'" : "null"); - $sql .= " , account_number = '" . $this->account_number . "'"; - $sql .= " , account_parent = '" . $this->account_parent . "'"; + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_journal "; + $sql .= " SET code = " . ($this->code ? "'" . $this->db->escape($this->code) . "'" : "null"); $sql .= " , label = " . ($this->label ? "'" . $this->db->escape($this->label) . "'" : "null"); - $sql .= " , fk_accounting_category = '" . $this->account_category . "'"; - $sql .= " , fk_user_modif = " . $user->id; + $sql .= " , nature = " . ($this->nature ? "'" . $this->db->escape($this->nature) . "'" : "0"); $sql .= " , active = '" . $this->active . "'"; $sql .= " WHERE rowid = " . $this->id; @@ -268,7 +195,7 @@ class AccountingJournal extends CommonObject } /** - * Check usage of accounting code + * Check usage of accounting journal * * @return int <0 if KO, >0 if OK */ @@ -287,7 +214,7 @@ class AccountingJournal extends CommonObject if ($resql) { $num = $this->db->num_rows($resql); if ($num > 0) { - $this->error = $langs->trans('ErrorAccountancyCodeIsAlreadyUse'); + $this->error = $langs->trans('ErrorAccountingJournalIsAlreadyUse'); return 0; } else { return 1; @@ -329,7 +256,7 @@ class AccountingJournal extends CommonObject // } if (! $error) { - $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_account"; + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_journal"; $sql .= " WHERE rowid=" . $this->id; dol_syslog(get_class($this) . "::delete sql=" . $sql); @@ -360,85 +287,47 @@ class AccountingJournal extends CommonObject /** * Return clicable name (with picto eventually) * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @return string Chaine avec URL + * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto + * @return string Chaine avec URL */ function getNomUrl($withpicto = 0) { global $langs; $result = ''; - $link = ''; + $link = ''; $linkend = ''; $picto = 'billr'; - $label = $langs->trans("Show") . ': ' . $this->account_number . ' - ' . $this->label; + $label = $langs->trans("Show") . ': ' . $this->code . ' - ' . $this->label; if ($withpicto) $result .= ($link . img_object($label, $picto) . $linkend); if ($withpicto && $withpicto != 2) $result .= ' '; if ($withpicto != 2) - require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; - $result .= $link . length_accountg($this->account_number) . ' - ' . $this->label . $linkend; + $result .= $link . $this->code . ' - ' . $this->label . $linkend; return $result; } /** - * Information on record - * - * @param int $id of record - * @return void - */ - 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; - - dol_syslog(get_class($this) . '::info sql=' . $sql); - $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->date_creation = $this->db->jdate($obj->datec); - $this->date_modification = $this->db->jdate($obj->tms); - } - $this->db->free($result); - } else { - dol_print_error($this->db); - } - } - - /** - * Account desactivate + * Deactivate journal * * @param int $id Id * @return int <0 if KO, >0 if OK */ - function account_desactivate($id) { + function journal_deactivate($id) { $result = $this->checkUsage(); if ($result > 0) { $this->db->begin(); - $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_journal "; $sql .= "SET active = '0'"; $sql .= " WHERE rowid = " . $this->db->escape($id); - dol_syslog(get_class($this) . "::desactivate sql=" . $sql, LOG_DEBUG); + dol_syslog(get_class($this) . "::deactivate sql=" . $sql, LOG_DEBUG); $result = $this->db->query($sql); if ($result) { @@ -455,15 +344,15 @@ class AccountingJournal extends CommonObject } /** - * Account activate + * Activate journal * * @param int $id Id * @return int <0 if KO, >0 if OK */ - function account_activate($id) { + function journal_activate($id) { $this->db->begin(); - $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_journal "; $sql .= "SET active = '1'"; $sql .= " WHERE rowid = " . $this->db->escape($id); diff --git a/htdocs/core/lib/accounting.lib.php b/htdocs/core/lib/accounting.lib.php index 205acb9ba80..56fdc8e6de9 100644 --- a/htdocs/core/lib/accounting.lib.php +++ b/htdocs/core/lib/accounting.lib.php @@ -91,6 +91,35 @@ function accounting_prepare_head(AccountingAccount $object) return $head; } +/** + * Prepare array with list of tabs + * + * @param AccountingAccount $object Accounting account + * @return array Array of tabs to show + */ +function accounting_journal_prepare_head(AccountingJournal $object) +{ + global $langs, $conf; + + $h = 0; + $head = array (); + + $head[$h][0] = DOL_URL_ROOT.'/accountancy/admin/journals_card.php?id=' . $object->id; + $head[$h][1] = $langs->trans("Card"); + $head[$h][2] = 'card'; + $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, $object, $head, $h, 'accounting_journal'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'accounting_journal', 'remove'); + + return $head; +} + /** * Return accounting account without zero on the right * diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index f35b61055ad..42c5c519d2c 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -199,13 +199,17 @@ ApplyMassCategories=Apply mass categories AddAccountFromBookKeepingWithNoCategories=Add acccount already used with no categories CategoryDeleted=Category for the accounting account has been removed AccountingJournals=Accounting journals +AccountingJournal=Accounting journal NewAccountingJournal=New accounting journal ShowAccoutingJournal=Show accounting journal +Code=Code +Nature=Nature AccountingJournalTypeVariousOperation=Various operation AccountingJournalTypeSale=Sale AccountingJournalTypePurchase=Purchase AccountingJournalTypeBank=Bank AccountingJournalTypeHasNew=Has-new +ErrorAccountingJournalIsAlreadyUse=This journal is already use ## Export Exports=Exports From 4fa5448aaba62721831283922f62683037efc760 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 10:34:33 +0200 Subject: [PATCH 031/233] FIX Detection of color brightness --- htdocs/core/class/html.formother.class.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 4ae2d81539d..270deb2134e 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -604,10 +604,22 @@ class FormOther $textcolor='FFF'; if ($color) { - $hex=$color; - $r = hexdec($hex[0].$hex[1]); - $g = hexdec($hex[2].$hex[3]); - $b = hexdec($hex[4].$hex[5]); + $tmp=explode(',', $color); + if (count($tmp) > 1) // This is a comma RGB ('255','255','255') + { + $r = $tmp[0]; + $g = $tmp[1]; + $b = $tmp[2]; + } + else + { + $hexr=$color[0].$color[1]; + $hexg=$color[2].$color[3]; + $hexb=$color[4].$color[5]; + $r = hexdec($hexr); + $g = hexdec($hexg); + $b = hexdec($hexb); + } $bright = (max($r, $g, $b) + min($r, $g, $b)) / 510.0; // HSL algorithm if ($bright > 0.6) $textcolor='000'; } From 54b03a35522b0d4b2171c0bad41de0e641def478 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 11:03:13 +0200 Subject: [PATCH 032/233] Work on 6.0 new look and feel --- htdocs/admin/ihm.php | 40 +++++++------- htdocs/comm/propal/list.php | 2 +- htdocs/commande/list.php | 3 +- htdocs/contact/list.php | 6 +-- htdocs/contrat/list.php | 2 +- htdocs/core/boxes/modules_boxes.php | 2 +- htdocs/core/lib/usergroups.lib.php | 2 +- htdocs/product/list.php | 83 ++++++++++++++--------------- htdocs/projet/list.php | 2 +- htdocs/projet/tasks/list.php | 2 +- htdocs/societe/list.php | 6 +-- htdocs/theme/eldy/style.css.php | 25 +++------ htdocs/theme/md/style.css.php | 7 ++- 13 files changed, 87 insertions(+), 95 deletions(-) diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 03fab048962..83f6701e2a1 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -165,14 +165,14 @@ if ($action == 'edit') // Edit print ''; // Default language - print ''.$langs->trans("DefaultLanguage").''; + print ''.$langs->trans("DefaultLanguage").''; print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'main_lang_default', 1, 0, 0, 0, 0, 'minwidth300'); print ''; print ' '; print ''; // Multilingual GUI - print ''.$langs->trans("EnableMultilangInterface").''; + print ''.$langs->trans("EnableMultilangInterface").''; print $form->selectyesno('main_multilangs',$conf->global->MAIN_MULTILANGS,1); print ''; print ' '; @@ -348,7 +348,7 @@ else // Show print ''; print ''; - print ''; print ""; - print ''; + print ''; print ''; print ""; @@ -378,7 +378,7 @@ else // Show foreach ($searchform as $key => $value) { - print ''; + print ''; print ''; @@ -391,11 +391,11 @@ else // Show print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").' 
    '.$langs->trans("DefaultLanguage").''; + print '
    '.$langs->trans("DefaultLanguage").''; $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)); @@ -358,7 +358,7 @@ else // Show print '
    '.$langs->trans("EnableMultilangInterface").'' . yn($conf->global->MAIN_MULTILANGS) . '
    '.$langs->trans("EnableMultilangInterface").'' . yn($conf->global->MAIN_MULTILANGS) . ' 
    '.$searchformtitle[$key].''.yn($searchformconst[$key]).'
    '.$searchformtitle[$key].''.yn($searchformconst[$key]).''; if (! empty($searchformmodule[$key])) print $langs->trans("IfModuleEnabled",$langs->transnoentitiesnoconv($searchformmodule[$key])); print '
    '; print ''; - print ''; + print ''; print ''; print ""; - print ''; + print ''; print ''; print ""; @@ -407,7 +407,7 @@ else // Show */ // Disable javascript/ajax - print '"; print ''; print ""; @@ -416,35 +416,35 @@ else // Show if (class_exists("Imagick")) { - print '"; print ''; print ""; } // First day for weeks - print ''; print ''; print ''; // DefaultWorkingDays - print ''; print ''; print ''; // DefaultWorkingHours - print ''; print ''; print ''; // Firstname / Name position - print ''; @@ -452,12 +452,12 @@ else // Show print ''; // Hide unauthorized button - print ''; // Show logo - print ''; + print ''; print ''; print ""; @@ -471,29 +471,29 @@ else // Show */ // Show bugtrack link - print '"; print ''; print ""; // Link to wiki help - print ''; // Link to help center - print ''; // Message login - print ''."\n"; // Message of the day - print ''."\n"; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 0ff70fe9107..fdcbdde5ca8 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -751,7 +751,7 @@ if ($resql) $objectstatic->id=$obj->rowid; $objectstatic->ref=$obj->ref; - print ''; + print ''; if (! empty($arrayfields['p.ref']['checked'])) { diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 03b9cfce56a..37170e0af84 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1048,7 +1048,8 @@ if ($resql) while ($i < min($num,$limit)) { $obj = $db->fetch_object($resql); - print ''; + + print ''; $notshippable=0; $warning = 0; diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 80649ef4e06..4e7a9c6f190 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -651,7 +651,7 @@ while ($i < min($num,$limit)) { $obj = $db->fetch_object($result); - print ""; + print ''; $contactstatic->lastname=$obj->lastname; $contactstatic->firstname=''; @@ -669,8 +669,8 @@ while ($i < min($num,$limit)) if (! empty($arrayfields['p.lastname']['checked'])) { print ''; + print $contactstatic->getNomUrl(1,'',0); + print ''; } // Firstname if (! empty($arrayfields['p.firstname']['checked'])) diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index c382bfc7612..0224da7d88c 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -563,7 +563,7 @@ if ($resql) $contracttmp->ref_customer=$obj->ref_customer; $contracttmp->ref_supplier=$obj->ref_supplier; - print ''; + print ''; if (! empty($arrayfields['c.ref']['checked'])) { print ''; + $out.= ''; $out.= ' 0) { $out.= ' colspan="'.$nbcol.'"'; } $out.= '>'; diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 0c735a97c2f..6e6e0c7b511 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -589,7 +589,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) { print $formother->showColor($conf->global->THEME_ELDY_BACKTITLE1, $langs->trans("Default")); } - print '   ('.$langs->trans("Default").': e6e6e6) '; + print '   ('.$langs->trans("Default").': f0f0f0) '; // $colorbacktitle1 in CSS print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); print ''; diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 85b63077a05..69108a893d9 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -473,45 +473,9 @@ else print '
    '; print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").'
    '.$langs->trans("DefaultMaxSizeList").'' . $conf->global->MAIN_SIZE_LISTE_LIMIT . '
    '.$langs->trans("DefaultMaxSizeList").'' . $conf->global->MAIN_SIZE_LISTE_LIMIT . ' 
    '.$langs->trans("DefaultMaxSizeShortList").'' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . '
    '.$langs->trans("DefaultMaxSizeShortList").'' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . ' 
    '.$langs->trans("DisableJavascript").''; + print '
    '.$langs->trans("DisableJavascript").''; print yn($conf->global->MAIN_DISABLE_JAVASCRIPT)." 
    '.$langs->trans("UsePreviewTabs").''; + print '
    '.$langs->trans("UsePreviewTabs").''; print yn(isset($conf->global->MAIN_USE_PREVIEW_TABS)?$conf->global->MAIN_USE_PREVIEW_TABS:0)." 
    '.$langs->trans("WeekStartOnDay").''; + print '
    '.$langs->trans("WeekStartOnDay").''; print $langs->trans("Day".(isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1')); print ' 
    '.$langs->trans("DefaultWorkingDays").''; + print '
    '.$langs->trans("DefaultWorkingDays").''; print isset($conf->global->MAIN_DEFAULT_WORKING_DAYS)?$conf->global->MAIN_DEFAULT_WORKING_DAYS:'1-5'; print ' 
    '.$langs->trans("DefaultWorkingHours").''; + print '
    '.$langs->trans("DefaultWorkingHours").''; print isset($conf->global->MAIN_DEFAULT_WORKING_HOURS)?$conf->global->MAIN_DEFAULT_WORKING_HOURS:'9-18'; print ' 
    '.$langs->trans("FirstnameNamePosition").''; + print '
    '.$langs->trans("FirstnameNamePosition").''; if (empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { print $langs->trans("Firstname").' '.$langs->trans("Lastname"); } else { print $langs->trans("Lastname").' '.$langs->trans("Firstname"); } print '
    '.$langs->trans("ButtonHideUnauthorized").''; + print '
    '.$langs->trans("ButtonHideUnauthorized").''; print yn((isset($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)?$conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED:0),1); print '
    '.$langs->trans("EnableShowLogo").'' . yn($conf->global->MAIN_SHOW_LOGO) . '
    '.$langs->trans("EnableShowLogo").'' . yn($conf->global->MAIN_SHOW_LOGO) . ' 
    '.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; + print '
    '.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; print yn($conf->global->MAIN_BUGTRACK_ENABLELINK)." 
    '.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; + print '
    '.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; print yn((isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0),1); print '
    '.$langs->trans("DisableLinkToHelpCenter").''; + print '
    '.$langs->trans("DisableLinkToHelpCenter").''; print yn((isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0),1); print '
    '.$langs->trans("MessageLogin").''; + print '
    '.$langs->trans("MessageLogin").''; if (isset($conf->global->MAIN_HOME)) print dol_htmlcleanlastbr($conf->global->MAIN_HOME); else print ' '; print '
    '.$langs->trans("MessageOfDay").''; + print '
    '.$langs->trans("MessageOfDay").''; if (isset($conf->global->MAIN_MOTD)) print dol_htmlcleanlastbr($conf->global->MAIN_MOTD); else print ' '; print '
    '; - print $contactstatic->getNomUrl(1,'',0); - print '
    '; diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 26ee34bdca0..c016741cb39 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -234,7 +234,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" // Show box title if (! empty($head['text']) || ! empty($head['sublink']) || ! empty($head['subpicto'])) { - $out.= '
    '."\n"; - print ''; - 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.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.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); - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $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($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"],"p.tosell","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['p.tobuy']['checked'])) print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"],"p.tobuy","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - + // Lines with input filters - print ''; + print ''; if (! empty($arrayfields['p.ref']['checked'])) { print ''; - + print ''; + 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.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.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); + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $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($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"],"p.tosell","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['p.tobuy']['checked'])) print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"],"p.tobuy","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + + $product_static=new Product($db); $product_fourn =new ProductFournisseur($db); - $var=true; $i = 0; while ($i < min($num,$limit)) { @@ -669,8 +669,7 @@ else } - $var=!$var; - print ''; + print ''; // Ref if (! empty($arrayfields['p.ref']['checked'])) diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 236671eea4c..c8335676700 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -634,7 +634,7 @@ while ($i < min($num,$limit)) $userAccess = $projectstatic->restrictedProjectArea($user); // why this ? if ($userAccess >= 0) { - print ""; + print ''; // Project url if (! empty($arrayfields['p.ref']['checked'])) diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index dd43fd61d93..a6a4c855474 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -619,7 +619,7 @@ while ($i < min($num,$limit)) $userAccess = $projectstatic->restrictedProjectArea($user); // why this ? if ($userAccess >= 0) { - print ""; + print ''; // Ref if (! empty($arrayfields['t.ref']['checked'])) diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index c4412660ea7..1a9980bbf12 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -907,10 +907,10 @@ while ($i < min($num, $limit)) $companystatic->code_compta_client=$obj->code_compta; $companystatic->code_compta_fournisseur=$obj->code_compta_fournisseur; - $companystatic->fk_prospectlevel=$obj->fk_prospectlevel; - $companystatic->name_alias=$obj->name_alias; + $companystatic->fk_prospectlevel=$obj->fk_prospectlevel; + $companystatic->name_alias=$obj->name_alias; - print ""; + print ''; if (! empty($arrayfields['s.nom']['checked'])) { print '';\n"; + } + } + $targetcontent=preg_replace('/LIST_OF_TD_TITLE_SEARCH/', $varprop, $targetcontent); + + // Substitute where for + $varprop="\n"; + $cleanparam=''; + foreach($property as $key => $prop) + { + if ($prop['field'] != 'rowid' && $prop['field'] != 'id' && ! $prop['istime']) + { + $varprop.="if (! empty(\$arrayfields['t.".$prop['field']."']['checked'])) print '';\n"; + } + } + $targetcontent=preg_replace('/'.preg_quote("if (! empty(\$arrayfields['t.field1']['checked'])) print '';",'/').'/', $varprop, $targetcontent); + $targetcontent=preg_replace('/'.preg_quote("if (! empty(\$arrayfields['t.field2']['checked'])) print '';",'/').'/', '', $targetcontent); + + // LIST_OF_TD_LABEL_FIELDS_CREATE - List of td for card view + $varprop="\n"; + $cleanparam=''; + foreach($property as $key => $prop) + { + if ($prop['field'] != 'rowid' && $prop['field'] != 'id' && ! $prop['istime']) + { + $varprop.="print '';\n"; + } + } + $targetcontent=preg_replace('/LIST_OF_TD_LABEL_FIELDS_CREATE/', $varprop, $targetcontent); + + // LIST_OF_TD_LABEL_FIELDS_EDIT - List of td for card view + $varprop="\n"; + $cleanparam=''; + foreach($property as $key => $prop) + { + if ($prop['field'] != 'rowid' && $prop['field'] != 'id' && ! $prop['istime']) + { + $baseString = 'print "";'; + $varprop.= sprintf("\t ".$baseString." \n", $prop['field'], $prop['field'], $prop['field']); + } + } + $targetcontent=preg_replace('/LIST_OF_TD_LABEL_FIELDS_EDIT/', $varprop, $targetcontent); + + // LIST_OF_TD_LABEL_FIELDS_VIEW - List of td for card view + $varprop="\n"; + $cleanparam=''; + foreach($property as $key => $prop) + { + if ($prop['field'] != 'rowid' && $prop['field'] != 'id' && ! $prop['istime']) + { + $varprop.=sprintf("\t print '';\n",$prop['field'],$prop['field']); + } + } + $targetcontent=preg_replace('/LIST_OF_TD_LABEL_FIELDS_VIEW/', $varprop, $targetcontent); + + + // LIST_OF_TD_FIELDS_LIST + + + + // Build file + $fp=fopen($outfile,"w"); + if ($fp) + { + fputs($fp, $targetcontent); + fclose($fp); + print "File '".$outfile."' has been built in current directory.\n"; + } + else $error++; +} + + +// -------------------- END OF BUILD_CLASS_FROM_TABLE SCRIPT -------------------- + +print "You can now move generated files to store them into directory /yourmodule/class (for .class.php file) or /yourmodule.\n"; +return $error; diff --git a/htdocs/modulebuilder/skeletons/build_webservice_from_class.php b/htdocs/modulebuilder/skeletons/build_webservice_from_class.php new file mode 100755 index 00000000000..c91347a424d --- /dev/null +++ b/htdocs/modulebuilder/skeletons/build_webservice_from_class.php @@ -0,0 +1,179 @@ +#!/usr/bin/env 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 . + */ + +/** + * \file dev/skeletons/build_webservice_from_class.php + * \ingroup core + * \brief Create a complete webservice file from CRUD functions of a PHP class + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit; +} + +// Include Dolibarr environment +require_once($path."../../htdocs/master.inc.php"); +// After this $db is a defined handler to database. + +// Main +$version='1.8'; +@set_time_limit(0); +$error=0; + +$langs->load("main"); + + +print "***** $script_file ($version) *****\n"; + + +// -------------------- START OF BUILD_CLASS_FROM_TABLE SCRIPT -------------------- + +// Check parameters +if (! isset($argv[1]) && ! isset($argv[2])) +{ + print "Usage: $script_file phpClassFile phpClassName\n"; + exit; +} + +// Show parameters +print 'Classfile='.$argv[1]."\n"; +print 'Classname='.$argv[2]."\n"; + +$classfile=$argv[1]; +$classname=$argv[2]; +$classmin=strtolower($classname); +$property=array(); +$targetcontent=''; + +// Load the class and read properties +require_once($classfile); + +$property=array(); +$class = new $classname($db); +$values=get_class_vars($classname); + +unset($values['db']); +unset($values['error']); +unset($values['errors']); +unset($values['element']); +unset($values['table_element']); +unset($values['table_element_line']); +unset($values['fk_element']); +unset($values['ismultientitymanaged']); + +$properties=array_keys($values); + +// Read skeleton_class.class.php file +$skeletonfile='skeleton_webservice_server.php'; +$sourcecontent=file_get_contents($skeletonfile); +if (! $sourcecontent) +{ + print "\n"; + print "Error: Failed to read skeleton sample '".$skeletonfile."'\n"; + print "Try to run script from skeletons directory.\n"; + exit; +} + +// Define output variables +$outfile='out.server_'.$classmin.'.php'; +$targetcontent=$sourcecontent; + + + +// Substitute class name +$targetcontent=preg_replace('/Skeleton/', $classname, $targetcontent); +$targetcontent=preg_replace('/skeleton/', $classmin, $targetcontent); + +// Substitute declaration parameters +$varprop="\n"; +$cleanparam=''; +$i=0; + +while($i array('name'=>'".$properties[$i]."','type'=>'xsd:string')"; + $i++; + + if ($i == count($properties)) + $varprop.="\n"; + else + $varprop.=",\n"; +} + +$targetcontent=preg_replace('/\'prop1\'=>\'xxx\',/', $varprop, $targetcontent); +$targetcontent=preg_replace('/\'prop2\'=>\'xxx\',/', '', $targetcontent); +// Substitute get method parameters +$varprop="\n"; +$cleanparam=''; +$i=0; + +while($i $".$classmin."->".$properties[$i]; + + $i++; + if ($i == count($properties)) + $varprop.="\n"; + else + $varprop.=",\n"; +} + +$targetcontent=preg_replace('/\'prop1\'=>\$'.$classmin.'->prop1,/', $varprop, $targetcontent); +$targetcontent=preg_replace('/\'prop2\'=>\$'.$classmin.'->prop2,/', '', $targetcontent); + +// Substitute get method parameters +$varprop="\n\t\t"; +$cleanparam=''; +$i=0; + +while($i'.$properties[$i].';'; + + $i++; + if ($i == count($properties)) + $varprop.="\n"; + else + $varprop.="\n\t\t"; +} +$targetcontent=preg_replace('/\$newobject->prop1=\$'.$classmin.'->prop1;/', $varprop, $targetcontent); +$targetcontent=preg_replace('/\$newobject->prop2=\$'.$classmin.'->prop2;/', '', $targetcontent); + + + +// Build file +$fp=fopen($outfile,"w"); +if ($fp) +{ + fputs($fp, $targetcontent); + fclose($fp); + print "File '".$outfile."' has been built in current directory.\n"; +} +else $error++; + +// -------------------- END OF BUILD_CLASS_FROM_TABLE SCRIPT -------------------- + +print "You must rename files by removing the 'out.' prefix in their name.\n"; +return $error; diff --git a/htdocs/modulebuilder/skeletons/modMyModule.class.php b/htdocs/modulebuilder/skeletons/modMyModule.class.php new file mode 100644 index 00000000000..4f994c7c654 --- /dev/null +++ b/htdocs/modulebuilder/skeletons/modMyModule.class.php @@ -0,0 +1,291 @@ + + * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2005-2016 Regis Houssin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \defgroup mymodule Module MyModule + * \brief Example of a module descriptor. + * Such a file must be copied into htdocs/mymodule/core/modules directory. + * \file htdocs/mymodule/core/modules/modMyModule.class.php + * \ingroup mymodule + * \brief Description and activation file for module MyModule + */ +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; + + +/** + * Description and activation class for module MyModule + */ +class modMyModule 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 = 500000; // TODO Go on page http://wiki.dolibarr.org/index.php/List_of_modules_id to reserve id number for your module + // Key text used to identify module (for permissions, menus, etc...) + $this->rights_class = 'mymodule'; + + // 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 = "other"; + // Module position in the family + $this->module_position = 500; + // 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' => '001', 'label' => $langs->trans("MyOwnFamily"))); + + // 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 = "Description of module MyModule"; + $this->descriptionlong = "A very long description. Can be a full HTML content"; + $this->editor_name = 'Editor name'; + $this->editor_url = 'https://www.dolibarr.org'; + + // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' + $this->version = '1.0'; + // 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. + // 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: /mymodule/core/xxxxx) (0=disable, 1=enable) + // 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' => 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 directory (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) + // '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'), // Set this to relative path of js file if module must load a js on all pages + // 'hooks' => array('hookcontext1','hookcontext2',...) // Set here all hooks context managed by module. You can also set hook context 'all' + // 'dir' => array('output' => 'othermodulename'), // To force the default directories names + // 'workflow' => array('WORKFLOW_MODULE1_YOURACTIONTYPE_MODULE2'=>array('enabled'=>'! empty($conf->module1->enabled) && ! empty($conf->module2->enabled)', 'picto'=>'yourpicto@mymodule')) // Set here all workflow context managed by module + // ); + $this->module_parts = array(); + + // Data directories to create when module is enabled. + // Example: this->dirs = array("/mymodule/temp"); + $this->dirs = array(); + + // Config pages. Put here list of php page, stored into mymodule/admin directory, to use to setup module. + $this->config_page_url = array("mysetuppage.php@mymodule"); + + // 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,0); // Minimum version of PHP required by module + $this->need_dolibarr_version = array(3,0); // Minimum version of Dolibarr required by module + $this->langfiles = array("mylangfile@mymodule"); + + // 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('MYMODULE_MYNEWCONST1','chaine','myvalue','This is a constant to add',1), + // 1=>array('MYMODULE_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1) + // ); + $this->const = array(); + + // Array to add new pages in new tabs + // Example: $this->tabs = array('objecttype:+tabname1:Title1:mylangfile@mymodule:$user->rights->mymodule->read:/mymodule/mynewtab1.php?id=__ID__', // To add a new tab identified by code tabname1 + // 'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@mymodule:$user->rights->othermodule->read:/mymodule/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. + // '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 + $this->tabs = array(); + + if (! isset($conf->mymodule) || ! isset($conf->mymodule->enabled)) + { + $conf->mymodule=new stdClass(); + $conf->mymodule->enabled=0; + } + + // Dictionaries + $this->dictionaries=array(); + /* Example: + $this->dictionaries=array( + 'langs'=>'mylangfile@mymodule', + '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->mymodule->enabled,$conf->mymodule->enabled,$conf->mymodule->enabled) // Condition to show each dictionary + ); + */ + + // Boxes + // Add here list of php file(s) stored in core/boxes that contains class to show a box. + $this->boxes = array(); // List of boxes + // Example: + //$this->boxes=array( + // 0=>array('file'=>'myboxa.php@mymodule','note'=>'','enabledbydefaulton'=>'Home'), + // 1=>array('file'=>'myboxb.php@mymodule','note'=>''), + // 2=>array('file'=>'myboxc.php@mymodule','note'=>'') + //); + + // Cronjobs + $this->cronjobs = array(); // List of cron jobs entries to add + // Example: $this->cronjobs=array(0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'test'=>true), + // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'test'=>true) + // ); + + // Permissions + $this->rights = array(); // Permission array used by this module + $r=0; + + // Add here list of permission defined by an id, a label, a boolean and two constant strings. + // Example: + // $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + // $this->rights[$r][1] = 'Permision label'; // Permission label + // $this->rights[$r][3] = 1; // Permission by default for new user (0/1) + // $this->rights[$r][4] = 'level1'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + // $this->rights[$r][5] = 'level2'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + // $r++; + + // Main menu entries + $this->menu = array(); // List of menus to add + $r=0; + + // Add here entries to declare new menus + // + // Example to declare a new Top Menu entry and its Left menu entry: + // $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'=>'MyModule top menu', + // 'mainmenu'=>'mymodule', + // 'leftmenu'=>'mymodule', + // 'url'=>'/mymodule/pagetop.php', + // 'langs'=>'mylangfile@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + // 'position'=>100, + // 'enabled'=>'$conf->mymodule->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. + // 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + // 'target'=>'', + // 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both + // $r++; + // + // Example to declare a Left Menu entry into an existing Top menu entry: + // $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=xxx', // '' 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'=>'MyModule left menu', + // 'mainmenu'=>'xxx', + // 'leftmenu'=>'mymodule', + // 'url'=>'/mymodule/pagelevel2.php', + // 'langs'=>'mylangfile@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + // 'position'=>100, + // 'enabled'=>'$conf->mymodule->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->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->mymodule->level1->level2' if you want your menu with a permission rules + // 'target'=>'', + // 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both + // $r++; + + + // Exports + $r=1; + + // Example: + // $this->export_code[$r]=$this->rights_class.'_'.$r; + // $this->export_label[$r]='MyModule'; // Translation key (used only if key ExportDataset_xxx_z not found) + // $this->export_enabled[$r]='1'; // Condition to show export in list (ie: '$user->id==3'). Set to 1 to always show when module is enabled. + // $this->export_icon[$r]='generic:MyModule'; // Put here code of icon then string for translation key of module name + // $this->export_permission[$r]=array(array("mymodule","level1","level2")); + // $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','s.fk_pays'=>'Country','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.code_compta'=>'CustomerAccountancyCode','s.code_compta_fournisseur'=>'SupplierAccountancyCode','f.rowid'=>"InvoiceId",'f.facnumber'=>"InvoiceRef",'f.datec'=>"InvoiceDateCreation",'f.datef'=>"DateInvoice",'f.total'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.tva'=>"TotalVAT",'f.paye'=>"InvoicePaid",'f.fk_statut'=>'InvoiceStatus','f.note'=>"InvoiceNote",'fd.rowid'=>'LineId','fd.description'=>"LineDescription",'fd.price'=>"LineUnitPrice",'fd.tva_tx'=>"LineVATRate",'fd.qty'=>"LineQty",'fd.total_ht'=>"LineTotalHT",'fd.total_tva'=>"LineTotalTVA",'fd.total_ttc'=>"LineTotalTTC",'fd.date_start'=>"DateStart",'fd.date_end'=>"DateEnd",'fd.fk_product'=>'ProductId','p.ref'=>'ProductRef'); + // $this->export_TypeFields_array[$r]=array('t.date'=>'Date', 't.qte'=>'Numeric', 't.poids'=>'Numeric', 't.fad'=>'Numeric', 't.paq'=>'Numeric', 't.stockage'=>'Numeric', 't.fadparliv'=>'Numeric', 't.livau100'=>'Numeric', 't.forfait'=>'Numeric', 's.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Numeric",'f.total_ttc'=>"Numeric",'f.tva'=>"Numeric",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_private'=>"Text",'f.note_public'=>"Text",'fd.description'=>"Text",'fd.subprice'=>"Numeric",'fd.tva_tx'=>"Numeric",'fd.qty'=>"Numeric",'fd.total_ht'=>"Numeric",'fd.total_tva'=>"Numeric",'fd.total_ttc'=>"Numeric",'fd.date_start'=>"Date",'fd.date_end'=>"Date",'fd.special_code'=>'Numeric','fd.product_type'=>"Numeric",'fd.fk_product'=>'List:product:label','p.ref'=>'Text','p.label'=>'Text','p.accountancy_code_sell'=>'Text'); + // $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','s.fk_pays'=>'company','s.phone'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company','f.rowid'=>"invoice",'f.facnumber'=>"invoice",'f.datec'=>"invoice",'f.datef'=>"invoice",'f.total'=>"invoice",'f.total_ttc'=>"invoice",'f.tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice','f.note'=>"invoice",'fd.rowid'=>'invoice_line','fd.description'=>"invoice_line",'fd.price'=>"invoice_line",'fd.total_ht'=>"invoice_line",'fd.total_tva'=>"invoice_line",'fd.total_ttc'=>"invoice_line",'fd.tva_tx'=>"invoice_line",'fd.qty'=>"invoice_line",'fd.date_start'=>"invoice_line",'fd.date_end'=>"invoice_line",'fd.fk_product'=>'product','p.ref'=>'product'); + // $this->export_dependencies_array[$r]=array('invoice_line'=>'fd.rowid','product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them + // $this->export_sql_start[$r]='SELECT DISTINCT '; + // $this->export_sql_end[$r] =' FROM ('.MAIN_DB_PREFIX.'facture as f, '.MAIN_DB_PREFIX.'facturedet as fd, '.MAIN_DB_PREFIX.'societe as s)'; + // $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product as p on (fd.fk_product = p.rowid)'; + // $this->export_sql_end[$r] .=' WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_facture'; + // $this->export_sql_order[$r] .=' ORDER BY s.nom'; + // $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 + */ + public function init($options='') + { + $sql = array(); + + //$this->_load_tables('/mymodule/sql/'); + + 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/modulebuilder/skeletons/skeleton_api_class.class.php b/htdocs/modulebuilder/skeletons/skeleton_api_class.class.php new file mode 100644 index 00000000000..a40b00af72c --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_api_class.class.php @@ -0,0 +1,289 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + use Luracast\Restler\RestException; + + +/** + * API class for skeleton object + * + * @smart-auto-routing false + * @access protected + * @class DolibarrApiAccess {@requires user,external} + * + * + */ +class SkeletonApi extends DolibarrApi +{ + /** + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + static $FIELDS = array( + 'name' + ); + + /** + * @var Skeleton $skeleton {@type Skeleton} + */ + public $skeleton; + + /** + * Constructor + * + * @url GET skeleton/ + * + */ + function __construct() + { + global $db, $conf; + $this->db = $db; + $this->skeleton = new Skeleton($this->db); + } + + /** + * Get properties of a skeleton object + * + * Return an array with skeleton informations + * + * @param int $id ID of skeleton + * @return array|mixed data without useless information + * + * @url GET skeleton/{id} + * @throws RestException + */ + function get($id) + { + if(! DolibarrApiAccess::$user->rights->skeleton->read) { + throw new RestException(401); + } + + $result = $this->skeleton->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Skeleton not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('skeleton',$this->skeleton->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + return $this->_cleanObjectDatas($this->skeleton); + } + + /** + * List skeletons + * + * Get a list of skeletons + * + * @param int $mode Use this param to filter list + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101') or (t.import_key:=:'20160101')" + * @return array Array of skeleton objects + * + * @url GET /skeletons/ + */ + function index($mode, $sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $sqlfilters = '') { + global $db, $conf; + + $obj_ret = array(); + + $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : ''; + + // If the internal user must only see his customers, force searching by him + if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; + + $sql = "SELECT s.rowid"; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $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."skeleton as s"; + + if ((!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.= ", ".MAIN_DB_PREFIX."c_stcomm as st"; + $sql.= " WHERE s.fk_stcomm = st.id"; + + // Example of use $mode + //if ($mode == 1) $sql.= " AND s.client IN (1, 3)"; + //if ($mode == 2) $sql.= " AND s.client IN (2, 3)"; + + $sql.= ' AND s.entity IN ('.getEntity('skeleton', 1).')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND s.fk_soc = sc.fk_soc"; + if ($socid) $sql.= " AND s.fk_soc = ".$socid; + if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale + // Insert sale filter + if ($search_sale > 0) + { + $sql .= " AND sc.fk_user = ".$search_sale; + } + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql.= $db->order($sortfield, $sortorder); + if ($limit) { + if ($page < 0) + { + $page = 0; + } + $offset = $limit * $page; + + $sql.= $db->plimit($limit + 1, $offset); + } + + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + while ($i < $num) + { + $obj = $db->fetch_object($result); + $skeleton_static = new Skeleton($db); + if($skeleton_static->fetch($obj->rowid)) { + $obj_ret[] = parent::_cleanObjectDatas($skeleton_static); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve skeleton list'); + } + if( ! count($obj_ret)) { + throw new RestException(404, 'No skeleton found'); + } + return $obj_ret; + } + + /** + * Create skeleton object + * + * @param array $request_data Request datas + * @return int ID of skeleton + * + * @url POST skeleton/ + */ + function post($request_data = NULL) + { + if(! DolibarrApiAccess::$user->rights->skeleton->create) { + throw new RestException(401); + } + // Check mandatory fields + $result = $this->_validate($request_data); + + foreach($request_data as $field => $value) { + $this->skeleton->$field = $value; + } + if( ! $this->skeleton->create(DolibarrApiAccess::$user)) { + throw new RestException(500); + } + return $this->skeleton->id; + } + + /** + * Update skeleton + * + * @param int $id Id of skeleton to update + * @param array $request_data Datas + * @return int + * + * @url PUT skeleton/{id} + */ + function put($id, $request_data = NULL) + { + if(! DolibarrApiAccess::$user->rights->skeleton->create) { + throw new RestException(401); + } + + $result = $this->skeleton->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Skeleton not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('skeleton',$this->skeleton->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + foreach($request_data as $field => $value) { + $this->skeleton->$field = $value; + } + + if($this->skeleton->update($id, DolibarrApiAccess::$user)) + return $this->get ($id); + + return false; + } + + /** + * Delete skeleton + * + * @param int $id Skeleton ID + * @return array + * + * @url DELETE skeleton/{id} + */ + function delete($id) + { + if(! DolibarrApiAccess::$user->rights->skeleton->supprimer) { + throw new RestException(401); + } + $result = $this->skeleton->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Skeleton not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('skeleton',$this->skeleton->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if( !$this->skeleton->delete($id)) + { + throw new RestException(500); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Skeleton deleted' + ) + ); + + } + + /** + * Validate fields before create or update object + * + * @param array $data Data to validate + * @return array + * + * @throws RestException + */ + function _validate($data) + { + $skeleton = array(); + foreach (SkeletonApi::$FIELDS as $field) { + if (!isset($data[$field])) + throw new RestException(400, "$field field missing"); + $skeleton[$field] = $data[$field]; + } + return $skeleton; + } +} diff --git a/htdocs/modulebuilder/skeletons/skeleton_card.php b/htdocs/modulebuilder/skeletons/skeleton_card.php new file mode 100644 index 00000000000..f0a9dd23c26 --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_card.php @@ -0,0 +1,351 @@ + + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file dev/skeletons/skeleton_card.php + * \ingroup mymodule othermodule1 othermodule2 + * \brief This file is an example of a php page + * Put here some comments + */ + +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) + +// Change this following line to use the correct relative path (../, ../../, etc) +$res=0; +if (! $res && file_exists("../main.inc.php")) $res=@include '../main.inc.php'; // to work if your module directory is into dolibarr root htdocs directory +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 && 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"); +// Change this following line to use the correct relative path from htdocs +include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); +dol_include_once('/mymodule/class/skeleton_class.class.php'); + +// Load traductions files requiredby by page +$langs->load("mymodule"); +$langs->load("other"); + +// Get parameters +$id = GETPOST('id','int'); +$action = GETPOST('action','alpha'); +$cancel = GETPOST('cancel'); +$backtopage = GETPOST('backtopage'); +$myparam = GETPOST('myparam','alpha'); + +$search_field1=GETPOST("search_field1"); +$search_field2=GETPOST("search_field2"); + +if (empty($action) && empty($id) && empty($ref)) $action='view'; + +// Protection if external user +if ($user->societe_id > 0) +{ + //accessforbidden(); +} +//$result = restrictedArea($user, 'mymodule', $id); + + +$object = new Skeleton_Class($db); +$extrafields = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + +// 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 + +// Initialize technical object to manage hooks of modules. Note that conf->hooks_modules contains array array +$hookmanager->initHooks(array('skeleton')); + + + +/******************************************************************* +* ACTIONS +* +* Put here all code to do according to value of "action" parameter +********************************************************************/ + +$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)) +{ + if ($cancel) + { + if ($action != 'addlink') + { + $urltogo=$backtopage?$backtopage:dol_buildpath('/mymodule/list.php',1); + header("Location: ".$urltogo); + exit; + } + if ($id > 0 || ! empty($ref)) $ret = $object->fetch($id,$ref); + $action=''; + } + + // Action to add record + if ($action == 'add') + { + if (GETPOST('cancel')) + { + $urltogo=$backtopage?$backtopage:dol_buildpath('/mymodule/list.php',1); + header("Location: ".$urltogo); + exit; + } + + $error=0; + + /* object_prop_getpost_prop */ + $object->prop1=GETPOST("field1"); + $object->prop2=GETPOST("field2"); + + if (empty($object->ref)) + { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors'); + } + + if (! $error) + { + $result=$object->create($user); + if ($result > 0) + { + // Creation OK + $urltogo=$backtopage?$backtopage:dol_buildpath('/mymodule/list.php',1); + header("Location: ".$urltogo); + exit; + } + { + // Creation KO + if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors'); + else setEventMessages($object->error, null, 'errors'); + $action='create'; + } + } + else + { + $action='create'; + } + } + + // Action to update record + if ($action == 'update') + { + $error=0; + + $object->prop1=GETPOST("field1"); + $object->prop2=GETPOST("field2"); + + if (empty($object->ref)) + { + $error++; + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors'); + } + + if (! $error) + { + $result=$object->update($user); + if ($result > 0) + { + $action='view'; + } + else + { + // Creation KO + if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors'); + else setEventMessages($object->error, null, 'errors'); + $action='edit'; + } + } + else + { + $action='edit'; + } + } + + // Action to delete + if ($action == 'confirm_delete') + { + $result=$object->delete($user); + if ($result > 0) + { + // Delete OK + setEventMessages("RecordDeleted", null, 'mesgs'); + header("Location: ".dol_buildpath('/mymodule/list.php',1)); + exit; + } + else + { + if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors'); + else setEventMessages($object->error, null, 'errors'); + } + } +} + + + + +/*************************************************** +* VIEW +* +* Put here all code to build page +****************************************************/ + +llxHeader('','MyPageName',''); + +$form=new Form($db); + + +// Put here content of your page + +// Example : Adding jquery code +print ''; + + +// Part to create +if ($action == 'create') +{ + print load_fiche_titre($langs->trans("NewMyModule")); + + print ''; + print ''; + print ''; + + dol_fiche_head(); + + print '
    '; @@ -624,11 +588,47 @@ else print '
    '; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 9b90e92e30d..49c17a749f0 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -82,7 +82,7 @@ $dol_no_mouse_hover=$conf->dol_no_mouse_hover; $colorbackhmenu1='110,120,160'; // topmenu $colorbackvmenu1='255,255,255'; // vmenu $colortopbordertitle1='120,120,120'; // top border of title -$colorbacktitle1='230,230,230'; // title of tables,list +$colorbacktitle1='240,240,240'; // title of tables,list $colorbacktabcard1='255,255,255'; // card $colorbacktabactive='234,234,234'; $colorbacklineimpair1='255,255,255'; // line impair @@ -98,7 +98,6 @@ $colortextlink='0,0,120'; $fontsize='13'; $fontsizesmaller='12'; $usegradienttop=(isset($conf->global->THEME_ELDY_TOPMENU_BACK1)?0:1); -$usegradienttitle=(isset($conf->global->THEME_ELDY_BACKTITLE1)?0:1); $useboldtitle=(isset($conf->global->THEME_ELDY_USEBOLDTITLE)?$conf->global->THEME_ELDY_USEBOLDTITLE:1); $borderwith=2; @@ -2399,8 +2398,11 @@ table.paddingtopbottomonly tr td { padding-top: 1px; padding-bottom: 2px; } +.liste_titre_filter { + background: rgb() !important; +} tr.liste_titre_filter td.liste_titre { - border-bottom: 1px solid #eee; + border-bottom: 1px solid #ddd; } .liste_titre_add td, .liste_titre_add th, .liste_titre_add .tagtd { @@ -2715,11 +2717,7 @@ tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, tabl } div.liste_titre_bydiv, .liste_titre div.tagtr, tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, table.dataTable thead tr { - background: linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%); - background: -ms-linear-gradient(bottom, rgb() 85%, rgb() 100%); + background: rgb(); font-weight: ; border-bottom: 1px solid #ddd; @@ -2987,16 +2985,7 @@ tr.box_titre { color: #000 !important;*/ /* TO MATCH ELDY */ - - background-image: -o-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(,0.4) 100%); - background-image: -moz-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(,0.4) 100%); - background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(,0.4) 100%); - background-image: -ms-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(,0.4) 100%); - background-image: linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(,0.4) 100%); - - background: rgb(); - - + background: rgb() color: rgb(); font-family: , sans-serif; font-weight: ; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 2ae5decbf96..1908fcfef4a 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -82,7 +82,7 @@ $dol_no_mouse_hover=$conf->dol_no_mouse_hover; $colorbackhmenu1='90,50,120'; // topmenu $colorbackvmenu1='255,255,255'; // vmenu $colortopbordertitle1=''; // top border of tables-lists title. not defined = default to colorbackhmenu1 -$colorbacktitle1='230,230,230'; // title of tables-lists +$colorbacktitle1='240,240,240'; // title of tables-lists $colorbacktabcard1='255,255,255'; // card $colorbacktabactive='234,234,234'; $colorbacklineimpair1='255,255,255'; // line impair @@ -2304,8 +2304,11 @@ table.paddingtopbottomonly tr td { padding-bottom: 2px; } +.liste_titre_filter { + background: rgb() !important; +} tr.liste_titre_filter td.liste_titre { - border-bottom: 1px solid #eee; + border-bottom: 1px solid #FDFFFF; } .liste_titre_add td, .liste_titre_add th, .liste_titre_add .tagtd { From e3d3d32b4a55cfbab14bb45ba2e7563164067b0c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 11:11:37 +0200 Subject: [PATCH 033/233] Translation --- htdocs/langs/en_US/products.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index b38b714ddfb..046521e398e 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -303,7 +303,7 @@ ErrorDeletingGeneratedProducts=There was an error while trying to delete existin NbOfDifferentValues=Nb of different values NbProducts=Nb. of products ParentProduct=Parent product -HideChildProducts=Hide child products +HideChildProducts=Hide variant products ConfirmCloneProductCombinations=Would you like to copy all the product variant to the product with the given reference? CloneDestinationReference=Destination product reference ErrorCopyProductCombinations=There was an error while copying the product variants From 527fa27fb786c3df0325fd63276b823c5d970e85 Mon Sep 17 00:00:00 2001 From: fappels Date: Wed, 29 Mar 2017 11:18:03 +0200 Subject: [PATCH 034/233] Add jquery-migrate to handle jquery 3.0 removes --- htdocs/includes/jquery/js/jquery-migrate.js | 540 ++++++++++++++++++ .../includes/jquery/js/jquery-migrate.min.js | 2 + htdocs/main.inc.php | 2 + htdocs/public/test/test_arrays.php | 2 + 4 files changed, 546 insertions(+) create mode 100644 htdocs/includes/jquery/js/jquery-migrate.js create mode 100644 htdocs/includes/jquery/js/jquery-migrate.min.js diff --git a/htdocs/includes/jquery/js/jquery-migrate.js b/htdocs/includes/jquery/js/jquery-migrate.js new file mode 100644 index 00000000000..350b79958d1 --- /dev/null +++ b/htdocs/includes/jquery/js/jquery-migrate.js @@ -0,0 +1,540 @@ +/*! + * jQuery Migrate - v3.0.0 - 2016-06-09 + * Copyright jQuery Foundation and other contributors + */ +(function( jQuery, window ) { +"use strict"; + + +jQuery.migrateVersion = "3.0.0"; + + +( function() { + + // Support: IE9 only + // IE9 only creates console object when dev tools are first opened + // Also, avoid Function#bind here to simplify PhantomJS usage + var log = window.console && window.console.log && + function() { window.console.log.apply( window.console, arguments ); }, + rbadVersions = /^[12]\./; + + if ( !log ) { + return; + } + + // Need jQuery 3.0.0+ and no older Migrate loaded + if ( !jQuery || rbadVersions.test( jQuery.fn.jquery ) ) { + log( "JQMIGRATE: jQuery 3.0.0+ REQUIRED" ); + } + if ( jQuery.migrateWarnings ) { + log( "JQMIGRATE: Migrate plugin loaded multiple times" ); + } + + // Show a message on the console so devs know we're active + log( "JQMIGRATE: Migrate is installed" + + ( jQuery.migrateMute ? "" : " with logging active" ) + + ", version " + jQuery.migrateVersion ); + +} )(); + +var warnedAbout = {}; + +// List of warnings already given; public read only +jQuery.migrateWarnings = []; + +// Set to false to disable traces that appear with warnings +if ( jQuery.migrateTrace === undefined ) { + jQuery.migrateTrace = true; +} + +// Forget any warnings we've already given; public +jQuery.migrateReset = function() { + warnedAbout = {}; + jQuery.migrateWarnings.length = 0; +}; + +function migrateWarn( msg ) { + var console = window.console; + if ( !warnedAbout[ msg ] ) { + warnedAbout[ msg ] = true; + jQuery.migrateWarnings.push( msg ); + if ( console && console.warn && !jQuery.migrateMute ) { + console.warn( "JQMIGRATE: " + msg ); + if ( jQuery.migrateTrace && console.trace ) { + console.trace(); + } + } + } +} + +function migrateWarnProp( obj, prop, value, msg ) { + Object.defineProperty( obj, prop, { + configurable: true, + enumerable: true, + get: function() { + migrateWarn( msg ); + return value; + } + } ); +} + +if ( document.compatMode === "BackCompat" ) { + + // JQuery has never supported or tested Quirks Mode + migrateWarn( "jQuery is not compatible with Quirks Mode" ); +} + + +var oldInit = jQuery.fn.init, + oldIsNumeric = jQuery.isNumeric, + oldFind = jQuery.find, + rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, + rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g; + +jQuery.fn.init = function( arg1 ) { + var args = Array.prototype.slice.call( arguments ); + + if ( typeof arg1 === "string" && arg1 === "#" ) { + + // JQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0 + migrateWarn( "jQuery( '#' ) is not a valid selector" ); + args[ 0 ] = []; + } + + return oldInit.apply( this, args ); +}; +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.find = function( selector ) { + var args = Array.prototype.slice.call( arguments ); + + // Support: PhantomJS 1.x + // String#match fails to match when used with a //g RegExp, only on some strings + if ( typeof selector === "string" && rattrHashTest.test( selector ) ) { + + // The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0 + // First see if qS thinks it's a valid selector, if so avoid a false positive + try { + document.querySelector( selector ); + } catch ( err1 ) { + + // Didn't *look* valid to qSA, warn and try quoting what we think is the value + selector = selector.replace( rattrHashGlob, function( _, attr, op, value ) { + return "[" + attr + op + "\"" + value + "\"]"; + } ); + + // If the regexp *may* have created an invalid selector, don't update it + // Note that there may be false alarms if selector uses jQuery extensions + try { + document.querySelector( selector ); + migrateWarn( "Attribute selector with '#' must be quoted: " + args[ 0 ] ); + args[ 0 ] = selector; + } catch ( err2 ) { + migrateWarn( "Attribute selector with '#' was not fixed: " + args[ 0 ] ); + } + } + } + + return oldFind.apply( this, args ); +}; + +// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML) +var findProp; +for ( findProp in oldFind ) { + if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) { + jQuery.find[ findProp ] = oldFind[ findProp ]; + } +} + +// The number of elements contained in the matched element set +jQuery.fn.size = function() { + migrateWarn( "jQuery.fn.size() is deprecated; use the .length property" ); + return this.length; +}; + +jQuery.parseJSON = function() { + migrateWarn( "jQuery.parseJSON is deprecated; use JSON.parse" ); + return JSON.parse.apply( null, arguments ); +}; + +jQuery.isNumeric = function( val ) { + + // The jQuery 2.2.3 implementation of isNumeric + function isNumeric2( obj ) { + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; + } + + var newValue = oldIsNumeric( val ), + oldValue = isNumeric2( val ); + + if ( newValue !== oldValue ) { + migrateWarn( "jQuery.isNumeric() should not be called on constructed objects" ); + } + + return oldValue; +}; + +migrateWarnProp( jQuery, "unique", jQuery.uniqueSort, + "jQuery.unique is deprecated, use jQuery.uniqueSort" ); + +// Now jQuery.expr.pseudos is the standard incantation +migrateWarnProp( jQuery.expr, "filters", jQuery.expr.pseudos, + "jQuery.expr.filters is now jQuery.expr.pseudos" ); +migrateWarnProp( jQuery.expr, ":", jQuery.expr.pseudos, + "jQuery.expr[\":\"] is now jQuery.expr.pseudos" ); + + +var oldAjax = jQuery.ajax; + +jQuery.ajax = function( ) { + var jQXHR = oldAjax.apply( this, arguments ); + + // Be sure we got a jQXHR (e.g., not sync) + if ( jQXHR.promise ) { + migrateWarnProp( jQXHR, "success", jQXHR.done, + "jQXHR.success is deprecated and removed" ); + migrateWarnProp( jQXHR, "error", jQXHR.fail, + "jQXHR.error is deprecated and removed" ); + migrateWarnProp( jQXHR, "complete", jQXHR.always, + "jQXHR.complete is deprecated and removed" ); + } + + return jQXHR; +}; + + +var oldRemoveAttr = jQuery.fn.removeAttr, + oldToggleClass = jQuery.fn.toggleClass, + rmatchNonSpace = /\S+/g; + +jQuery.fn.removeAttr = function( name ) { + var self = this; + + jQuery.each( name.match( rmatchNonSpace ), function( i, attr ) { + if ( jQuery.expr.match.bool.test( attr ) ) { + migrateWarn( "jQuery.fn.removeAttr no longer sets boolean properties: " + attr ); + self.prop( attr, false ); + } + } ); + + return oldRemoveAttr.apply( this, arguments ); +}; + +jQuery.fn.toggleClass = function( state ) { + + // Only deprecating no-args or single boolean arg + if ( state !== undefined && typeof state !== "boolean" ) { + return oldToggleClass.apply( this, arguments ); + } + + migrateWarn( "jQuery.fn.toggleClass( boolean ) is deprecated" ); + + // Toggle entire class name of each element + return this.each( function() { + var className = this.getAttribute && this.getAttribute( "class" ) || ""; + + if ( className ) { + jQuery.data( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || state === false ? + "" : + jQuery.data( this, "__className__" ) || "" + ); + } + } ); +}; + + +var internalSwapCall = false; + +// If this version of jQuery has .swap(), don't false-alarm on internal uses +if ( jQuery.swap ) { + jQuery.each( [ "height", "width", "reliableMarginRight" ], function( _, name ) { + var oldHook = jQuery.cssHooks[ name ] && jQuery.cssHooks[ name ].get; + + if ( oldHook ) { + jQuery.cssHooks[ name ].get = function() { + var ret; + + internalSwapCall = true; + ret = oldHook.apply( this, arguments ); + internalSwapCall = false; + return ret; + }; + } + } ); +} + +jQuery.swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + if ( !internalSwapCall ) { + migrateWarn( "jQuery.swap() is undocumented and deprecated" ); + } + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + +var oldData = jQuery.data; + +jQuery.data = function( elem, name, value ) { + var curData; + + // If the name is transformed, look for the un-transformed name in the data object + if ( name && name !== jQuery.camelCase( name ) ) { + curData = jQuery.hasData( elem ) && oldData.call( this, elem ); + if ( curData && name in curData ) { + migrateWarn( "jQuery.data() always sets/gets camelCased names: " + name ); + if ( arguments.length > 2 ) { + curData[ name ] = value; + } + return curData[ name ]; + } + } + + return oldData.apply( this, arguments ); +}; + +var oldTweenRun = jQuery.Tween.prototype.run; + +jQuery.Tween.prototype.run = function( percent ) { + if ( jQuery.easing[ this.easing ].length > 1 ) { + migrateWarn( + "easing function " + + "\"jQuery.easing." + this.easing.toString() + + "\" should use only first argument" + ); + + jQuery.easing[ this.easing ] = jQuery.easing[ this.easing ].bind( + jQuery.easing, + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } + + oldTweenRun.apply( this, arguments ); +}; + +var oldLoad = jQuery.fn.load, + originalFix = jQuery.event.fix; + +jQuery.event.props = []; +jQuery.event.fixHooks = {}; + +jQuery.event.fix = function( originalEvent ) { + var event, + type = originalEvent.type, + fixHook = this.fixHooks[ type ], + props = jQuery.event.props; + + if ( props.length ) { + migrateWarn( "jQuery.event.props are deprecated and removed: " + props.join() ); + while ( props.length ) { + jQuery.event.addProp( props.pop() ); + } + } + + if ( fixHook && !fixHook._migrated_ ) { + fixHook._migrated_ = true; + migrateWarn( "jQuery.event.fixHooks are deprecated and removed: " + type ); + if ( ( props = fixHook.props ) && props.length ) { + while ( props.length ) { + jQuery.event.addProp( props.pop() ); + } + } + } + + event = originalFix.call( this, originalEvent ); + + return fixHook && fixHook.filter ? fixHook.filter( event, originalEvent ) : event; +}; + +jQuery.each( [ "load", "unload", "error" ], function( _, name ) { + + jQuery.fn[ name ] = function() { + var args = Array.prototype.slice.call( arguments, 0 ); + + // If this is an ajax load() the first arg should be the string URL; + // technically this could also be the "Anything" arg of the event .load() + // which just goes to show why this dumb signature has been deprecated! + // jQuery custom builds that exclude the Ajax module justifiably die here. + if ( name === "load" && typeof args[ 0 ] === "string" ) { + return oldLoad.apply( this, args ); + } + + migrateWarn( "jQuery.fn." + name + "() is deprecated" ); + + args.splice( 0, 0, name ); + if ( arguments.length ) { + return this.on.apply( this, args ); + } + + // Use .triggerHandler here because: + // - load and unload events don't need to bubble, only applied to window or image + // - error event should not bubble to window, although it does pre-1.7 + // See http://bugs.jquery.com/ticket/11820 + this.triggerHandler.apply( this, args ); + return this; + }; + +} ); + +// Trigger "ready" event only once, on document ready +jQuery( function() { + jQuery( document ).triggerHandler( "ready" ); +} ); + +jQuery.event.special.ready = { + setup: function() { + if ( this === document ) { + migrateWarn( "'ready' event is deprecated" ); + } + } +}; + +jQuery.fn.extend( { + + bind: function( types, data, fn ) { + migrateWarn( "jQuery.fn.bind() is deprecated" ); + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + migrateWarn( "jQuery.fn.unbind() is deprecated" ); + return this.off( types, null, fn ); + }, + delegate: function( selector, types, data, fn ) { + migrateWarn( "jQuery.fn.delegate() is deprecated" ); + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + migrateWarn( "jQuery.fn.undelegate() is deprecated" ); + return arguments.length === 1 ? + this.off( selector, "**" ) : + this.off( types, selector || "**", fn ); + } +} ); + + +var oldOffset = jQuery.fn.offset; + +jQuery.fn.offset = function() { + var docElem, + elem = this[ 0 ], + origin = { top: 0, left: 0 }; + + if ( !elem || !elem.nodeType ) { + migrateWarn( "jQuery.fn.offset() requires a valid DOM element" ); + return origin; + } + + docElem = ( elem.ownerDocument || document ).documentElement; + if ( !jQuery.contains( docElem, elem ) ) { + migrateWarn( "jQuery.fn.offset() requires an element connected to a document" ); + return origin; + } + + return oldOffset.apply( this, arguments ); +}; + + +var oldParam = jQuery.param; + +jQuery.param = function( data, traditional ) { + var ajaxTraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + + if ( traditional === undefined && ajaxTraditional ) { + + migrateWarn( "jQuery.param() no longer uses jQuery.ajaxSettings.traditional" ); + traditional = ajaxTraditional; + } + + return oldParam.call( this, data, traditional ); +}; + +var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack; + +jQuery.fn.andSelf = function() { + migrateWarn( "jQuery.fn.andSelf() replaced by jQuery.fn.addBack()" ); + return oldSelf.apply( this, arguments ); +}; + + +var oldDeferred = jQuery.Deferred, + tuples = [ + + // Action, add listener, callbacks, .then handlers, final state + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), "rejected" ], + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ) ] + ]; + +jQuery.Deferred = function( func ) { + var deferred = oldDeferred(), + promise = deferred.promise(); + + deferred.pipe = promise.pipe = function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + migrateWarn( "deferred.pipe() is deprecated" ); + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + + // Deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + + }; + + if ( func ) { + func.call( deferred, deferred ); + } + + return deferred; +}; + + + +})( jQuery, window ); \ No newline at end of file diff --git a/htdocs/includes/jquery/js/jquery-migrate.min.js b/htdocs/includes/jquery/js/jquery-migrate.min.js new file mode 100644 index 00000000000..a2813c5d2d8 --- /dev/null +++ b/htdocs/includes/jquery/js/jquery-migrate.min.js @@ -0,0 +1,2 @@ +/*! jQuery Migrate v3.0.0 | (c) jQuery Foundation and other contributors | jquery.org/license */ +"undefined"==typeof jQuery.migrateMute&&(jQuery.migrateMute=!0),function(a,b){"use strict";function c(c){var d=b.console;e[c]||(e[c]=!0,a.migrateWarnings.push(c),d&&d.warn&&!a.migrateMute&&(d.warn("JQMIGRATE: "+c),a.migrateTrace&&d.trace&&d.trace()))}function d(a,b,d,e){Object.defineProperty(a,b,{configurable:!0,enumerable:!0,get:function(){return c(e),d}})}a.migrateVersion="3.0.0",function(){var c=b.console&&b.console.log&&function(){b.console.log.apply(b.console,arguments)},d=/^[12]\./;c&&(a&&!d.test(a.fn.jquery)||c("JQMIGRATE: jQuery 3.0.0+ REQUIRED"),a.migrateWarnings&&c("JQMIGRATE: Migrate plugin loaded multiple times"),c("JQMIGRATE: Migrate is installed"+(a.migrateMute?"":" with logging active")+", version "+a.migrateVersion))}();var e={};a.migrateWarnings=[],void 0===a.migrateTrace&&(a.migrateTrace=!0),a.migrateReset=function(){e={},a.migrateWarnings.length=0},"BackCompat"===document.compatMode&&c("jQuery is not compatible with Quirks Mode");var f=a.fn.init,g=a.isNumeric,h=a.find,i=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,j=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g;a.fn.init=function(a){var b=Array.prototype.slice.call(arguments);return"string"==typeof a&&"#"===a&&(c("jQuery( '#' ) is not a valid selector"),b[0]=[]),f.apply(this,b)},a.fn.init.prototype=a.fn,a.find=function(a){var b=Array.prototype.slice.call(arguments);if("string"==typeof a&&i.test(a))try{document.querySelector(a)}catch(d){a=a.replace(j,function(a,b,c,d){return"["+b+c+'"'+d+'"]'});try{document.querySelector(a),c("Attribute selector with '#' must be quoted: "+b[0]),b[0]=a}catch(e){c("Attribute selector with '#' was not fixed: "+b[0])}}return h.apply(this,b)};var k;for(k in h)Object.prototype.hasOwnProperty.call(h,k)&&(a.find[k]=h[k]);a.fn.size=function(){return c("jQuery.fn.size() is deprecated; use the .length property"),this.length},a.parseJSON=function(){return c("jQuery.parseJSON is deprecated; use JSON.parse"),JSON.parse.apply(null,arguments)},a.isNumeric=function(b){function d(b){var c=b&&b.toString();return!a.isArray(b)&&c-parseFloat(c)+1>=0}var e=g(b),f=d(b);return e!==f&&c("jQuery.isNumeric() should not be called on constructed objects"),f},d(a,"unique",a.uniqueSort,"jQuery.unique is deprecated, use jQuery.uniqueSort"),d(a.expr,"filters",a.expr.pseudos,"jQuery.expr.filters is now jQuery.expr.pseudos"),d(a.expr,":",a.expr.pseudos,'jQuery.expr[":"] is now jQuery.expr.pseudos');var l=a.ajax;a.ajax=function(){var a=l.apply(this,arguments);return a.promise&&(d(a,"success",a.done,"jQXHR.success is deprecated and removed"),d(a,"error",a.fail,"jQXHR.error is deprecated and removed"),d(a,"complete",a.always,"jQXHR.complete is deprecated and removed")),a};var m=a.fn.removeAttr,n=a.fn.toggleClass,o=/\S+/g;a.fn.removeAttr=function(b){var d=this;return a.each(b.match(o),function(b,e){a.expr.match.bool.test(e)&&(c("jQuery.fn.removeAttr no longer sets boolean properties: "+e),d.prop(e,!1))}),m.apply(this,arguments)},a.fn.toggleClass=function(b){return void 0!==b&&"boolean"!=typeof b?n.apply(this,arguments):(c("jQuery.fn.toggleClass( boolean ) is deprecated"),this.each(function(){var c=this.getAttribute&&this.getAttribute("class")||"";c&&a.data(this,"__className__",c),this.setAttribute&&this.setAttribute("class",c||b===!1?"":a.data(this,"__className__")||"")}))};var p=!1;a.swap&&a.each(["height","width","reliableMarginRight"],function(b,c){var d=a.cssHooks[c]&&a.cssHooks[c].get;d&&(a.cssHooks[c].get=function(){var a;return p=!0,a=d.apply(this,arguments),p=!1,a})}),a.swap=function(a,b,d,e){var f,g,h={};p||c("jQuery.swap() is undocumented and deprecated");for(g in b)h[g]=a.style[g],a.style[g]=b[g];f=d.apply(a,e||[]);for(g in b)a.style[g]=h[g];return f};var q=a.data;a.data=function(b,d,e){var f;return d&&d!==a.camelCase(d)&&(f=a.hasData(b)&&q.call(this,b),f&&d in f)?(c("jQuery.data() always sets/gets camelCased names: "+d),arguments.length>2&&(f[d]=e),f[d]):q.apply(this,arguments)};var r=a.Tween.prototype.run;a.Tween.prototype.run=function(b){a.easing[this.easing].length>1&&(c('easing function "jQuery.easing.'+this.easing.toString()+'" should use only first argument'),a.easing[this.easing]=a.easing[this.easing].bind(a.easing,b,this.options.duration*b,0,1,this.options.duration)),r.apply(this,arguments)};var s=a.fn.load,t=a.event.fix;a.event.props=[],a.event.fixHooks={},a.event.fix=function(b){var d,e=b.type,f=this.fixHooks[e],g=a.event.props;if(g.length)for(c("jQuery.event.props are deprecated and removed: "+g.join());g.length;)a.event.addProp(g.pop());if(f&&!f._migrated_&&(f._migrated_=!0,c("jQuery.event.fixHooks are deprecated and removed: "+e),(g=f.props)&&g.length))for(;g.length;)a.event.addProp(g.pop());return d=t.call(this,b),f&&f.filter?f.filter(d,b):d},a.each(["load","unload","error"],function(b,d){a.fn[d]=function(){var a=Array.prototype.slice.call(arguments,0);return"load"===d&&"string"==typeof a[0]?s.apply(this,a):(c("jQuery.fn."+d+"() is deprecated"),a.splice(0,0,d),arguments.length?this.on.apply(this,a):(this.triggerHandler.apply(this,a),this))}}),a(function(){a(document).triggerHandler("ready")}),a.event.special.ready={setup:function(){this===document&&c("'ready' event is deprecated")}},a.fn.extend({bind:function(a,b,d){return c("jQuery.fn.bind() is deprecated"),this.on(a,null,b,d)},unbind:function(a,b){return c("jQuery.fn.unbind() is deprecated"),this.off(a,null,b)},delegate:function(a,b,d,e){return c("jQuery.fn.delegate() is deprecated"),this.on(b,a,d,e)},undelegate:function(a,b,d){return c("jQuery.fn.undelegate() is deprecated"),1===arguments.length?this.off(a,"**"):this.off(b,a||"**",d)}});var u=a.fn.offset;a.fn.offset=function(){var b,d=this[0],e={top:0,left:0};return d&&d.nodeType?(b=(d.ownerDocument||document).documentElement,a.contains(b,d)?u.apply(this,arguments):(c("jQuery.fn.offset() requires an element connected to a document"),e)):(c("jQuery.fn.offset() requires a valid DOM element"),e)};var v=a.param;a.param=function(b,d){var e=a.ajaxSettings&&a.ajaxSettings.traditional;return void 0===d&&e&&(c("jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),d=e),v.call(this,b,d)};var w=a.fn.andSelf||a.fn.addBack;a.fn.andSelf=function(){return c("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()"),w.apply(this,arguments)};var x=a.Deferred,y=[["resolve","done",a.Callbacks("once memory"),a.Callbacks("once memory"),"resolved"],["reject","fail",a.Callbacks("once memory"),a.Callbacks("once memory"),"rejected"],["notify","progress",a.Callbacks("memory"),a.Callbacks("memory")]];a.Deferred=function(b){var d=x(),e=d.promise();return d.pipe=e.pipe=function(){var b=arguments;return c("deferred.pipe() is deprecated"),a.Deferred(function(c){a.each(y,function(f,g){var h=a.isFunction(b[f])&&b[f];d[g[1]](function(){var b=h&&h.apply(this,arguments);b&&a.isFunction(b.promise)?b.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[g[0]+"With"](this===e?c.promise():this,h?[b]:arguments)})}),b=null}).promise()},b&&b.call(d,d),d}}(jQuery,window); \ No newline at end of file diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 9c0a98cbcfb..3a6ec46d61f 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1146,6 +1146,8 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; if (constant('JS_JQUERY')) print ''."\n"; else print ''."\n"; + if (constant('JS_JQUERY_MIGRATE')) print ''."\n"; + else print ''."\n"; if (constant('JS_JQUERY_UI')) print ''."\n"; else print ''."\n"; if (! defined('DISABLE_JQUERY_TABLEDND')) print ''."\n"; diff --git a/htdocs/public/test/test_arrays.php b/htdocs/public/test/test_arrays.php index 3de7196a696..0776c36f74a 100644 --- a/htdocs/public/test/test_arrays.php +++ b/htdocs/public/test/test_arrays.php @@ -38,6 +38,8 @@ if (empty($usedolheader)) " /> + + From 1d6e760fc8a2a1395bfa3c493dcabf39639c84db Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 11:44:14 +0200 Subject: [PATCH 035/233] FIX Notification sending was broken. --- .../interface_50_modNotification_Notification.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php index d9952d441f4..d55a1a776a0 100644 --- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php +++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php @@ -66,7 +66,7 @@ class InterfaceNotification extends DolibarrTriggers require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; $notify = new Notify($this->db); - if (! in_array($notifcode, $notify->arrayofnotifsupported)) return 0; + if (! in_array($action, $notify->arrayofnotifsupported)) return 0; dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); From fbca800246e66df7870f546abcc6da71d938c952 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 10:34:33 +0200 Subject: [PATCH 036/233] FIX Detection of color brightness --- htdocs/core/class/html.formother.class.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 4ac3eb99c50..7e78f7bbe4d 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -604,10 +604,22 @@ class FormOther $textcolor='FFF'; if ($color) { - $hex=$color; - $r = hexdec($hex[0].$hex[1]); - $g = hexdec($hex[2].$hex[3]); - $b = hexdec($hex[4].$hex[5]); + $tmp=explode(',', $color); + if (count($tmp) > 1) // This is a comma RGB ('255','255','255') + { + $r = $tmp[0]; + $g = $tmp[1]; + $b = $tmp[2]; + } + else + { + $hexr=$color[0].$color[1]; + $hexg=$color[2].$color[3]; + $hexb=$color[4].$color[5]; + $r = hexdec($hexr); + $g = hexdec($hexg); + $b = hexdec($hexb); + } $bright = (max($r, $g, $b) + min($r, $g, $b)) / 510.0; // HSL algorithm if ($bright > 0.6) $textcolor='000'; } From a76ddc8b3ff6b96f7bc2e2dcfefc7fc588421f4f Mon Sep 17 00:00:00 2001 From: Thomas Raschbacher Date: Wed, 29 Mar 2017 15:33:32 +0200 Subject: [PATCH 037/233] Add phone phone numbers to project contacts Add phone number(s) for project contacts to be used in odt --- .../doc/doc_generic_project_odt.modules.php | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) 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 06b188496a5..32be29b082c 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 @@ -186,6 +186,25 @@ class doc_generic_project_odt extends ModelePDFProjects { global $conf; + // adding phone numbers if external + $phone_pro = ''; + $phone_perso = ''; + $phone_mobile = ''; + + $ct = new Contact($this->db); + if ($contact['source']=='external') { + $ct = new Contact($this->db); + $ct->fetch($contact['id']); + $phone_pro = $ct->phone_pro; + $phone_perso = $ct->phone_perso; + $phone_mobile = $ct->phone_mobile; + } elseif ($contact['source']=='internal') { + $ct = new User($this->db); + $ct->fetch($contact['id']); + $phone_pro = $ct->office_phone; + $phone_mobile = $ct->user_mobile; + } + return array( 'projcontacts_id'=>$contact['id'], 'projcontacts_rowid'=>$contact['rowid'], @@ -194,7 +213,10 @@ class doc_generic_project_odt extends ModelePDFProjects 'projcontacts_firstname'=>$contact['firstname'], 'projcontacts_fullcivname'=>$contact['fullname'], 'projcontacts_socname'=>$contact['socname'], - 'projcontacts_email'=>$contact['email'] + 'projcontacts_email'=>$contact['email'], + 'projcontacts_phone_pro'=>$phone_pro, + 'projcontacts_phone_perso'=>$phone_perso, + 'projcontacts_phone_mobile'=>$phone_mobile ); } From 2dc721c53812968f8b4fd7492998d02c240c2fc3 Mon Sep 17 00:00:00 2001 From: phf Date: Wed, 29 Mar 2017 16:10:59 +0200 Subject: [PATCH 038/233] Fix picture with jpeg extension are not visible --- htdocs/categories/class/categorie.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 122d62b1d76..c58b3261c5f 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1489,14 +1489,14 @@ class Categorie extends CommonObject { while (($file = readdir($handle)) !== false) { - if (dol_is_file($dir.$file) && preg_match('/(\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$dir.$file)) + if (dol_is_file($dir.$file) && preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$dir.$file)) { $nbphoto++; $photo = $file; // On determine nom du fichier vignette $photo_vignette=''; - if (preg_match('/(\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$photo,$regs)) + if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$photo,$regs)) { $photo_vignette=preg_replace('/'.$regs[0].'/i','',$photo).'_small'.$regs[0]; } @@ -1539,7 +1539,7 @@ class Categorie extends CommonObject dol_delete_file($file,1); // Si elle existe, on efface la vignette - if (preg_match('/(\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$filename,$regs)) + if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$filename,$regs)) { $photo_vignette=preg_replace('/'.$regs[0].'/i','',$filename).'_small'.$regs[0]; if (file_exists($dirthumb.$photo_vignette)) From 4df8dcf9800d81225265fd534ea1cef35869fb63 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Mar 2017 21:36:50 +0200 Subject: [PATCH 039/233] Work on module modBlockedLog and modModuleBuilder --- htdocs/admin/menus.php | 2 +- htdocs/admin/menus/index.php | 2 +- htdocs/admin/menus/other.php | 2 +- htdocs/admin/modules.php | 3 +- htdocs/core/modules/modBlockedLog.class.php | 2 +- .../core/modules/modModuleBuilder.class.php | 89 +++ htdocs/cron/card.php | 8 +- htdocs/cron/class/cronjob.class.php | 57 +- htdocs/langs/en_US/modulebuilder.lang | 3 + htdocs/main.inc.php | 36 +- htdocs/modulebuilder/index.php | 91 +++ htdocs/modulebuilder/skeletons/.gitignore | 2 + htdocs/modulebuilder/skeletons/README | 34 + .../skeletons/build_api_class.php | 123 ++++ .../skeletons/build_class_from_table.php | 677 ++++++++++++++++++ .../skeletons/build_webservice_from_class.php | 179 +++++ .../skeletons/modMyModule.class.php | 291 ++++++++ .../skeletons/skeleton_api_class.class.php | 289 ++++++++ .../modulebuilder/skeletons/skeleton_card.php | 351 +++++++++ .../skeletons/skeleton_class.class.php | 593 +++++++++++++++ .../modulebuilder/skeletons/skeleton_list.php | 569 +++++++++++++++ .../skeletons/skeleton_script.php | 166 +++++ .../skeletons/skeleton_webservice_server.php | 272 +++++++ htdocs/theme/eldy/style.css.php | 4 + htdocs/theme/md/style.css.php | 4 + htdocs/user/class/user.class.php | 2 +- 26 files changed, 3828 insertions(+), 23 deletions(-) create mode 100644 htdocs/core/modules/modModuleBuilder.class.php create mode 100644 htdocs/langs/en_US/modulebuilder.lang create mode 100644 htdocs/modulebuilder/index.php create mode 100644 htdocs/modulebuilder/skeletons/.gitignore create mode 100644 htdocs/modulebuilder/skeletons/README create mode 100755 htdocs/modulebuilder/skeletons/build_api_class.php create mode 100755 htdocs/modulebuilder/skeletons/build_class_from_table.php create mode 100755 htdocs/modulebuilder/skeletons/build_webservice_from_class.php create mode 100644 htdocs/modulebuilder/skeletons/modMyModule.class.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_api_class.class.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_card.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_class.class.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_list.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_script.php create mode 100644 htdocs/modulebuilder/skeletons/skeleton_webservice_server.php diff --git a/htdocs/admin/menus.php b/htdocs/admin/menus.php index f8b89c515aa..0d6ff4d34a0 100644 --- a/htdocs/admin/menus.php +++ b/htdocs/admin/menus.php @@ -155,7 +155,7 @@ print ''; print ''; print ''; -dol_fiche_head($head, 'handler', $langs->trans("Menus")); +dol_fiche_head($head, 'handler', $langs->trans("Menus"), -1); print $langs->trans("MenusDesc")."
    \n"; print "
    \n"; diff --git a/htdocs/admin/menus/index.php b/htdocs/admin/menus/index.php index acfa9d2dccd..ed5f56954c0 100644 --- a/htdocs/admin/menus/index.php +++ b/htdocs/admin/menus/index.php @@ -234,7 +234,7 @@ $head[$h][1] = $langs->trans("Miscellaneous"); $head[$h][2] = 'misc'; $h++; -dol_fiche_head($head, 'editor', $langs->trans("Menus")); +dol_fiche_head($head, 'editor', $langs->trans("Menus"), -1); print $langs->trans("MenusEditorDesc")."
    \n"; print "
    \n"; diff --git a/htdocs/admin/menus/other.php b/htdocs/admin/menus/other.php index 471edf58e79..0a3cb6b99bc 100644 --- a/htdocs/admin/menus/other.php +++ b/htdocs/admin/menus/other.php @@ -77,7 +77,7 @@ $head[$h][1] = $langs->trans("Miscellaneous"); $head[$h][2] = 'misc'; $h++; -dol_fiche_head($head, 'misc', $langs->trans("Menus")); +dol_fiche_head($head, 'misc', $langs->trans("Menus"), -1); // Other Options diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index bfaeabf67d4..ddaf940492f 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -278,13 +278,12 @@ foreach ($modulesdir as $dir) try { - $res=include_once $dir.$file; + $res=include_once $dir.$file; // A class already exists in a different file will send a non catchable fatal error. if (class_exists($modName)) { try { $objMod = new $modName($db); $modNameLoaded[$modName]=$dir; - if (! $objMod->numero > 0 && $modName != 'modUser') { dol_syslog('The module descriptor '.$modName.' must have a numero property', LOG_ERR); diff --git a/htdocs/core/modules/modBlockedLog.class.php b/htdocs/core/modules/modBlockedLog.class.php index 30e4734e843..c3e2cb6345a 100644 --- a/htdocs/core/modules/modBlockedLog.class.php +++ b/htdocs/core/modules/modBlockedLog.class.php @@ -25,7 +25,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Class to describe a Cron module + * Class to describe a BlockedLog module */ class modBlockedLog extends DolibarrModules { diff --git a/htdocs/core/modules/modModuleBuilder.class.php b/htdocs/core/modules/modModuleBuilder.class.php new file mode 100644 index 00000000000..b68148377c3 --- /dev/null +++ b/htdocs/core/modules/modModuleBuilder.class.php @@ -0,0 +1,89 @@ + + * + * This 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 . + */ + +/** + * \defgroup modulebuilder Module ModuleBuilder + * \brief Add a log into a block chain for some actions. + * \file htdocs/core/modules/modBlockedLog.class.php + * \ingroup blockedlog + * \brief Description and activation file for module ModuleBuilder + */ +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; + +/** + * Class to describe a ModuleBuilder module + */ +class modModuleBuilder extends DolibarrModules +{ + /** + * Constructor. Define names, constants, directories, boxes, permissions + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $langs,$conf; + + $this->db = $db; + $this->numero = 3300; + + // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' + // It is used to group modules in module setup page + $this->family = "technic"; + // 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 = "A tool to help developers to build their own module."; + $this->version = 'development'; // 'development', 'experimental' or 'dolibarr' or version + // 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); + // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) + $this->special = 1; + // Name of image file used for this module. + $this->picto='technic'; + + // Data directories to create when module is enabled + $this->dirs = array(); + + // Config pages + //------------- + $this->config_page_url = array(); + + // Dependancies + //------------- + $this->hidden = false; // A condition to disable 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->conflictwith = array(); // List of modules id this module is in conflict with + $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/cron/card.php b/htdocs/cron/card.php index 5e2bc435e56..fc89f6eb3cf 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -321,8 +321,8 @@ if (($action=="create") || ($action=="edit")) print ''."\n"; } - - dol_fiche_head(''); + if ($action=="edit") dol_fiche_head($head, 'card', $langs->trans("CronTask"), 0, 'cron'); + else dol_fiche_head(''); print ''; @@ -558,6 +558,8 @@ else dol_fiche_head($head, 'card', $langs->trans("CronTask"), -1, 'cron'); $linkback = '' . $langs->trans("BackToList") . ''; + + // TODO Use dol_banner // box add_jobs_box print '
    '; @@ -616,7 +618,7 @@ else print '
    "; print '
    '; print $langs->trans('Active').""; - print yn($object->status); + print $object->getLibStatut(4); print "
    '; diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 2f9ad12a57f..789e3bafcec 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1199,8 +1199,63 @@ class Cronjob extends CommonObject } return 1; - } + + /** + * Return label of status of user (active, inactive) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->status,$mode); + } + + /** + * Renvoi le libelle d'un statut donne + * + * @param int $status Id statut + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status + */ + function LibStatut($status,$mode=0) + { + global $langs; + $langs->load('users'); + + if ($mode == 0) + { + $prefix=''; + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($mode == 1) + { + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($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'); + } + if ($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"'); + } + if ($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'); + } + if ($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"'); + } + } } diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang new file mode 100644 index 00000000000..6605a7b6a63 --- /dev/null +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -0,0 +1,3 @@ +# Dolibarr language file - Source file is en_US - loan +ModuleBuilder=Module Builder +ModuleBuilderDesc=This tools give you utilites to build your own module. Your modules will be generated into the first alternative directory: %s. diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 8d1138e5758..fe1ed01a68f 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1377,8 +1377,6 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a $menumanager->showmenu('top', array('searchform'=>$searchform, 'bookmarks'=>$bookmarks)); // This contains a \n print "\n"; - //$form=new Form($db); - // Define link to login card $appli=constant('DOL_APPLICATION_TITLE'); if (! empty($conf->global->MAIN_APPLICATION_TITLE)) @@ -1403,7 +1401,8 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a $logouthtmltext.=$langs->trans("Logout").'
    '; $logouttext .=''; - $logouttext .= img_picto($langs->trans('Logout').":".$langs->trans('Logout'), 'logout_top.png', 'class="login"', 0, 0, 1); + //$logouttext .= img_picto($langs->trans('Logout').":".$langs->trans('Logout'), 'logout_top.png', 'class="login"', 0, 0, 1); + $logouttext .=''; $logouttext .=''; } else @@ -1427,6 +1426,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a $toprightmenu.=''; $toprightmenu.='
    .fieldx.'.\$obj->".$prop['field'].".''.\$obj->field1.''.\$obj->field2.'
    '.\$langs->trans(\"Field".$prop['field']."\").'
    ".\$langs->trans("Field%s")."%s."\">
    '.\$langs->trans(\"Field%s\").''.\$object->%s.'
    '."\n"; + // print ''; + // LIST_OF_TD_LABEL_FIELDS_CREATE + print '
    '.$langs->trans("Label").'
    '."\n"; + + dol_fiche_end(); + + print '
     
    '; + + print ''; +} + + + +// Part to edit record +if (($id || $ref) && $action == 'edit') +{ + print load_fiche_titre($langs->trans("MyModule")); + + print '
    '; + print ''; + print ''; + print ''; + + dol_fiche_head(); + + print ''."\n"; + // print ''; + // LIST_OF_TD_LABEL_FIELDS_EDIT + print '
    '.$langs->trans("Label").'
    '; + + dol_fiche_end(); + + print '
    '; + print '   '; + print '
    '; + + print '
    '; +} + + + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) +{ + $res = $object->fetch_optionals($object->id, $extralabels); + + $head = commande_prepare_head($object); + dol_fiche_head($head, 'order', $langs->trans("CustomerOrder"), 0, 'order'); + + print load_fiche_titre($langs->trans("MyModule")); + + dol_fiche_head(); + + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteMyOjbect'), $langs->trans('ConfirmDeleteMyObject'), 'confirm_delete', '', 0, 1); + print $formconfirm; + } + + print ''."\n"; + // print ''; + // LIST_OF_TD_LABEL_FIELDS_VIEW + print '
    '.$langs->trans("Label").''.$object->label.'
    '; + + dol_fiche_end(); + + + // Buttons + print '
    '."\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'); + + if (empty($reshook)) + { + if ($user->rights->mymodule->write) + { + print ''."\n"; + } + + if ($user->rights->mymodule->delete) + { + print ''."\n"; + } + } + print '
    '."\n"; + + + // Example 2 : Adding links to objects + // Show links to link elements + //$linktoelem = $form->showLinkToObjectBlock($object, null, array('skeleton')); + //$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + +} + + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/modulebuilder/skeletons/skeleton_class.class.php b/htdocs/modulebuilder/skeletons/skeleton_class.class.php new file mode 100644 index 00000000000..01b48c35f75 --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_class.class.php @@ -0,0 +1,593 @@ + + * Copyright (C) 2014-2016 Juanjo Menent + * Copyright (C) 2015 Florian Henry + * Copyright (C) 2015 Raphaël Doursenaud + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file 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 + */ + +// 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'; + +/** + * Class Skeleton_Class + * + * Put here description of your class + * + * @see CommonObject + */ +class Skeleton_Class extends CommonObject +{ + /** + * @var string Id to identify managed objects + */ + public $element = 'skeleton'; + /** + * @var string Name of table without prefix where object is stored + */ + public $table_element = 'skeleton'; + + /** + * @var Skeleton_ClassLine[] Lines + */ + public $lines = array(); + + /** + * @var mixed Sample property 1 + */ + public $prop1; + /** + * @var mixed Sample property 2 + */ + public $prop2; + //... + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } + + /** + * Create object into database + * + * @param User $user User that creates + * @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) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $error = 0; + + // Clean parameters + if (isset($this->prop1)) { + $this->prop1 = trim($this->prop1); + } + if (isset($this->prop2)) { + $this->prop2 = trim($this->prop2); + } + //... + + // Check parameters + // Put here code to add control on parameters values + + // Insert request + $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '('; + $sql .= ' field1,'; + $sql .= ' field2'; + //... + $sql .= ') VALUES ('; + $sql .= ' \'' . $this->prop1 . '\','; + $sql .= ' \'' . $this->prop2 . '\''; + //... + $sql .= ')'; + + $this->db->begin(); + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + } + + 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. + + //// Call triggers + //$result=$this->call_trigger('MYOBJECT_CREATE',$user); + //if ($result < 0) $error++; + //// End call triggers + } + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return - 1 * $error; + } else { + $this->db->commit(); + + return $this->id; + } + } + + /** + * Load object in memory from the database + * + * @param int $id Id object + * @param string $ref Ref + * + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetch($id, $ref = null) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = 'SELECT'; + $sql .= ' t.rowid,'; + $sql .= ' t.field1,'; + $sql .= ' t.field2'; + //... + $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t'; + $sql.= ' WHERE 1 = 1'; + if (! empty($conf->multicompany->enabled)) { + $sql .= " AND entity IN (" . getEntity("skeleton", 1) . ")"; + } + if (null !== $ref) { + $sql .= ' AND t.ref = ' . '\'' . $ref . '\''; + } else { + $sql .= ' AND t.rowid = ' . $id; + } + + $resql = $this->db->query($sql); + if ($resql) { + $numrows = $this->db->num_rows($resql); + if ($numrows) { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; + $this->prop1 = $obj->field1; + $this->prop2 = $obj->field2; + //... + } + + // Retrieve all extrafields for invoice + // fetch optionals attributes and labels + /* + 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); + $this->fetch_optionals($this->id,$extralabels); + */ + + // $this->fetch_lines(); + + $this->db->free($resql); + + if ($numrows) { + return 1; + } else { + return 0; + } + } else { + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + + return - 1; + } + } + + /** + * Load object in memory from the database + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit offset limit + * @param int $offset offset limit + * @param array $filter filter array + * @param string $filtermode filter mode (AND or OR) + * + * @return int <0 if KO, >0 if OK + */ + public function fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter = array(), $filtermode='AND') + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = 'SELECT'; + $sql .= ' t.rowid,'; + $sql .= ' t.field1,'; + $sql .= ' t.field2'; + //... + $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element. ' as t'; + + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + $sqlwhere [] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\''; + } + } + $sql.= ' WHERE 1 = 1'; + if (! empty($conf->multicompany->enabled)) { + $sql .= " AND entity IN (" . getEntity("skeleton", 1) . ")"; + } + if (count($sqlwhere) > 0) { + $sql .= ' AND ' . implode(' '.$filtermode.' ', $sqlwhere); + } + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield,$sortorder); + } + if (!empty($limit)) { + $sql .= ' ' . $this->db->plimit($limit, $offset); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + + while ($obj = $this->db->fetch_object($resql)) { + $line = new self($this->db); + + $line->id = $obj->rowid; + $line->prop1 = $obj->field1; + $line->prop2 = $obj->field2; + //... + } + $this->db->free($resql); + + return $num; + } else { + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + + return - 1; + } + } + + /** + * Update object into database + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = false) + { + $error = 0; + + dol_syslog(__METHOD__, LOG_DEBUG); + + // Clean parameters + if (isset($this->prop1)) { + $this->prop1 = trim($this->prop1); + } + if (isset($this->prop2)) { + $this->prop2 = trim($this->prop2); + } + //... + + // Check parameters + // Put here code to add a control on parameters values + + // Update request + $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET'; + $sql .= " field1=".(isset($this->field1)?"'".$this->db->escape($this->field1)."'":"null").","; + $sql .= " field2=".(isset($this->field2)?"'".$this->db->escape($this->field2)."'":"null").""; + //... + $sql .= ' WHERE rowid=' . $this->id; + + $this->db->begin(); + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + 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. + + //// 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) { + $this->db->rollback(); + + return - 1 * $error; + } else { + $this->db->commit(); + + return 1; + } + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + 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. + + //// 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 + + if (!$error) { + $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element; + $sql .= ' WHERE rowid=' . $this->id; + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + } + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return - 1 * $error; + } else { + $this->db->commit(); + + return 1; + } + } + + /** + * Load an object from its id and create a new one in database + * + * @param int $fromid Id of object to clone + * + * @return int New id of clone + */ + public function createFromClone($fromid) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + global $user; + $error = 0; + $object = new Skeleton_Class($this->db); + + $this->db->begin(); + + // Load source object + $object->fetch($fromid); + // Reset object + $object->id = 0; + + // Clear fields + // ... + + // Create clone + $result = $object->create($user); + + // Other options + if ($result < 0) { + $error ++; + $this->errors = $object->errors; + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + } + + // End + if (!$error) { + $this->db->commit(); + + return $object->id; + } else { + $this->db->rollback(); + + return - 1; + } + } + + /** + * 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 + * @param int $notooltip 1=Disable tooltip + * @param int $maxlen Max length of visible user name + * @param string $morecss Add more css on link + * @return string String with URL + */ + function getNomUrl($withpicto=0, $option='', $notooltip=0, $maxlen=24, $morecss='') + { + global $db, $conf, $langs; + global $dolibarr_main_authentication, $dolibarr_main_demo; + global $menumanager; + + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + + $result = ''; + $companylink = ''; + + $label = '' . $langs->trans("MyModule") . ''; + $label.= '
    '; + $label.= '' . $langs->trans('Ref') . ': ' . $this->ref; + + $url = DOL_URL_ROOT.'/mymodule/'.$this->table_name.'_card.php?id='.$this->id; + + $linkclose=''; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowProject"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; + } + else $linkclose = ($morecss?' class="'.$morecss.'"':''); + + $linkstart = ''; + $linkend=''; + + if ($withpicto) + { + $result.=($linkstart.img_object(($notooltip?'':$label), 'label', ($notooltip?'':'class="classfortooltip"')).$linkend); + if ($withpicto != 2) $result.=' '; + } + $result.= $linkstart . $this->ref . $linkend; + return $result; + } + + /** + * Retourne le libelle du status d'un user (actif, inactif) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->status,$mode); + } + + /** + * Return the status + * + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 5=Long label + Picto + * @return string Label of status + */ + static function LibStatut($status,$mode=0) + { + global $langs; + + if ($mode == 0) + { + $prefix=''; + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($mode == 1) + { + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($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) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5'); + } + if ($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) + { + 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) + { + 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'); + } + } + + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + $this->id = 0; + $this->prop1 = 'prop1'; + $this->prop2 = 'prop2'; + } + +} + +/** + * Class Skeleton_ClassLine + */ +class Skeleton_ClassLine +{ + /** + * @var int ID + */ + public $id; + /** + * @var mixed Sample line property 1 + */ + public $prop1; + /** + * @var mixed Sample line property 2 + */ + public $prop2; +} diff --git a/htdocs/modulebuilder/skeletons/skeleton_list.php b/htdocs/modulebuilder/skeletons/skeleton_list.php new file mode 100644 index 00000000000..77485c6d638 --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_list.php @@ -0,0 +1,569 @@ + + * Copyright (C) 2014-2016 Juanjo Menent + * Copyright (C) 2016 Jean-François Ferry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file dev/skeletons/skeleton_list.php + * \ingroup mymodule othermodule1 othermodule2 + * \brief This file is an example of a php page + * Put here some comments + */ + +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) + +// Change this following line to use the correct relative path (../, ../../, etc) +$res=0; +if (! $res && file_exists("../main.inc.php")) $res=@include '../main.inc.php'; // to work if your module directory is into dolibarr root htdocs directory +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 && 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"); +// Change this following line to use the correct relative path from htdocs +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/skeleton_class.class.php'); + +// Load traductions files requiredby by page +$langs->load("mymodule"); +$langs->load("other"); + +$action=GETPOST('action','alpha'); +$massaction=GETPOST('massaction','alpha'); +$show_files=GETPOST('show_files','int'); +$confirm=GETPOST('confirm','alpha'); +$toselect = GETPOST('toselect', 'array'); + +$id = GETPOST('id','int'); +$backtopage = GETPOST('backtopage'); +$myparam = GETPOST('myparam','alpha'); + +$search_all=trim(GETPOST("sall")); +$search_field1=GETPOST("search_field1"); +$search_field2=GETPOST("search_field2"); +$search_myfield=GETPOST('search_myfield'); +$optioncss = GETPOST('optioncss','alpha'); + +// Load variable for pagination +$limit = GETPOST("limit")?GETPOST("limit","int"):$conf->liste_limit; +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if ($page == -1) { $page = 0; } +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortfield) $sortfield="t.rowid"; // Set here default search field +if (! $sortorder) $sortorder="ASC"; + +// Protection if external user +$socid=0; +if ($user->societe_id > 0) +{ + $socid = $user->societe_id; + //accessforbidden(); +} + +// Initialize technical object to manage context to save list fields +$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'mymodulelist'; + +// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array +$hookmanager->initHooks(array('mymodulelist')); +$extrafields = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label('mymodule'); +$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_'); + +// List of fields to search into when doing a "search in all" +$fieldstosearchall = array( + 't.ref'=>'Ref', + 't.note_public'=>'NotePublic', +); +if (empty($user->socid)) $fieldstosearchall["t.note_private"]="NotePrivate"; + +// Definition of fields for list +$arrayfields=array( + 't.field1'=>array('label'=>$langs->trans("Field1"), 'checked'=>1), + 't.field2'=>array('label'=>$langs->trans("Field2"), 'checked'=>1), + //'t.entity'=>array('label'=>$langs->trans("Entity"), 'checked'=>1, 'enabled'=>(! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode))), + 't.datec'=>array('label'=>$langs->trans("DateCreationShort"), 'checked'=>0, 'position'=>500), + 't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), + //'t.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), +); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + } +} + + +// Load object if id or ref is provided as parameter +$object=new Skeleton_Class($db); +if (($id > 0 || ! empty($ref)) && $action != 'add') +{ + $result=$object->fetch($id,$ref); + if ($result < 0) dol_print_error($db); +} + + + + +/******************************************************************* +* ACTIONS +* +* Put here all code to do according to value of "action" parameter +********************************************************************/ + +if (GETPOST('cancel')) { $action='list'; $massaction=''; } +if (! GETPOST('confirmmassaction') && $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") || GETPOST("button_removefilter.x") ||GETPOST("button_removefilter")) // All tests are required to be compatible with all browsers + { + $search_field1=''; + $search_field2=''; + $search_date_creation=''; + $search_date_update=''; + $toselect=''; + $search_array_options=array(); + } + + // Mass actions + $objectclass='Skeleton'; + $objectlabel='Skeleton'; + $permtoread = $user->rights->skeleton->read; + $permtodelete = $user->rights->skeleton->delete; + $uploaddir = $conf->skeleton->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; +} + + + +/*************************************************** +* VIEW +* +* Put here all code to build page +****************************************************/ + +$now=dol_now(); + +$form=new Form($db); + +//$help_url="EN:Module_Customers_Orders|FR:Module_Commandes_Clients|ES:Módulo_Pedidos_de_clientes"; +$help_url=''; +$title = $langs->trans('MyModuleListTitle'); + +// Put here content of your page + +// Example : Adding jquery code +print ''; + + +$sql = "SELECT"; +$sql.= " t.rowid,"; +$sql.= " t.field1,"; +$sql.= " t.field2"; +// 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."mytable as t"; +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."mytable_extrafields as ef on (t.rowid = ef.fk_object)"; +$sql.= " WHERE 1 = 1"; +//$sql.= " WHERE u.entity IN (".getEntity('mytable',1).")"; +if ($search_field1) $sql.= natural_search("field1",$search_field1); +if ($search_field2) $sql.= natural_search("field2",$search_field2); +if ($sall) $sql.= natural_search(array_keys($fieldstosearchall), $sall); +// Add where from extra fields +foreach ($search_array_options as $key => $val) +{ + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $typ=$extrafields->attribute_type[$tmpkey]; + $mode=0; + if (in_array($typ, array('int','double'))) $mode=1; // Search on a numeric + if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit))) + { + $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); + } +} +// 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); +//$sql.= $db->plimit($conf->liste_limit+1, $offset); + +// 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); + +dol_syslog($script_file, LOG_DEBUG); +$resql=$db->query($sql); +if (! $resql) +{ + dol_print_error($db); + exit; +} + +$num = $db->num_rows($resql); + +// Direct jump if only one record found +if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all) +{ + $obj = $db->fetch_object($resql); + $id = $obj->rowid; + header("Location: ".DOL_URL_ROOT.'/skeleton/card.php?id='.$id); + exit; +} + +llxHeader('', $title, $help_url); + +$arrayofselected=is_array($toselect)?$toselect:array(); + +$param=''; +if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; +if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; +if ($search_field1 != '') $param.= '&search_field1='.urlencode($search_field1); +if ($search_field2 != '') $param.= '&search_field2='.urlencode($search_field2); +if ($optioncss != '') $param.='&optioncss='.$optioncss; +// Add $param from extra fields +foreach ($search_array_options as $key => $val) +{ + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); +} + +$arrayofmassactions = array( + 'presend'=>$langs->trans("SendByMail"), + 'builddoc'=>$langs->trans("PDFMerge"), +); +if ($user->rights->mymodule->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); +if ($massaction == 'presend') $arrayofmassactions=array(); +$massactionbutton=$form->selectMassAction('', $arrayofmassactions); + +print '
    '; +if ($optioncss != '') print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit); + +if ($sall) +{ + foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); + print $langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall); +} + +$moreforfilter = ''; +$moreforfilter.='
    '; +$moreforfilter.= $langs->trans('MyFilter') . ': '; +$moreforfilter.= '
    '; + +$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 (! empty($moreforfilter)) +{ + print '
    '; + print $moreforfilter; + print '
    '; +} + +$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; +$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields + +print '
    '; +print ''."\n"; + +// Fields title +print ''; +// LIST_OF_TD_TITLE_FIELDS +//if (! empty($arrayfields['t.field1']['checked'])) print_liste_field_titre($arrayfields['t.field1']['label'],$_SERVER['PHP_SELF'],'t.field1','',$param,'',$sortfield,$sortorder); +//if (! empty($arrayfields['t.field2']['checked'])) print_liste_field_titre($arrayfields['t.field2']['label'],$_SERVER['PHP_SELF'],'t.field2','',$param,'',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +//if (! empty($arrayfields['t.status']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"t.status","",$param,'align="center"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print ''."\n"; + +// Fields title search +print ''; +// LIST_OF_TD_TITLE_SEARCH +//if (! empty($arrayfields['t.field1']['checked'])) print ''; +//if (! empty($arrayfields['t.field2']['checked'])) print ''; +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print ''; + } + } +} +// Fields from hook +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['t.datec']['checked'])) +{ + // Date creation + print ''; +} +if (! empty($arrayfields['t.tms']['checked'])) +{ + // Date modification + print ''; +} +/*if (! empty($arrayfields['u.statut']['checked'])) +{ + // Status + print ''; +}*/ +// Action column +print ''; +print ''."\n"; + + +$i=0; +$var=true; +$totalarray=array(); +while ($i < min($num, $limit)) +{ + $obj = $db->fetch_object($resql); + if ($obj) + { + $var = !$var; + + // Show here line of result + print ''; + // LIST_OF_TD_FIELDS_LIST + /* + if (! empty($arrayfields['t.field1']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['t.field2']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + }*/ + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + print 'getAlignFlag($key); + if ($align) print ' align="'.$align.'"'; + print '>'; + $tmpkey='options_'.$key; + print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); + print ''; + if (! $i) $totalarray['nbfield']++; + } + } + } + // 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['t.datec']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Date modification + if (! empty($arrayfields['t.tms']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Status + /* + if (! empty($arrayfields['u.statut']['checked'])) + { + $userstatic->statut=$obj->statut; + print ''; + }*/ + + // Action column + print ''; + if (! $i) $totalarray['nbfield']++; + + print ''; + } + $i++; +} + +// Show total line +if (isset($totalarray['totalhtfield'])) +{ + print ''; + $i=0; + while ($i < $totalarray['nbfield']) + { + $i++; + if ($i == 1) + { + if ($num < $limit) print ''; + else print ''; + } + elseif ($totalarray['totalhtfield'] == $i) print ''; + elseif ($totalarray['totalvatfield'] == $i) print ''; + elseif ($totalarray['totalttcfield'] == $i) print ''; + else print ''; + } + print ''; +} + +$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 '
    '; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $searchclass=''; + if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; + if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; + print ''; + } + print ''; + print ''; + print ''; + print $form->selectarray('search_statut', array('-1'=>'','0'=>$langs->trans('Disabled'),'1'=>$langs->trans('Enabled')),$search_statut); + print ''; +$searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); +print $searchpitco; +print '
    '.$obj->field1.''.$obj->field2.''; + print dol_print_date($db->jdate($obj->date_creation), 'dayhour'); + print ''; + print dol_print_date($db->jdate($obj->date_update), 'dayhour'); + print ''.$userstatic->getLibStatut(3).''; + 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 ''; + } + print '
    '.$langs->trans("Total").''.$langs->trans("Totalforthispage").''.price($totalarray['totalht']).''.price($totalarray['totalvat']).''.price($totalarray['totalttc']).'
    '."\n"; +print '
    '."\n"; + +print '
    '."\n"; + + +if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) +{ + // Show list of available documents + $urlsource=$_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder; + $urlsource.=str_replace('&','&',$param); + + $filedir=$diroutputmassaction; + $genallowed=$user->rights->facture->lire; + $delallowed=$user->rights->facture->lire; + + print $formfile->showdocuments('massfilesarea_mymodule','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,''); +} +else +{ + print '
    '.$langs->trans("ShowTempMassFilesArea").''; +} + + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/modulebuilder/skeletons/skeleton_script.php b/htdocs/modulebuilder/skeletons/skeleton_script.php new file mode 100644 index 00000000000..5eb1565d4a3 --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_script.php @@ -0,0 +1,166 @@ +#!/usr/bin/env php + + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file dev/skeletons/skeleton_script.php + * \ingroup mymodule + * \brief This file is an example for a command line script + * Put here some comments + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit(-1); +} + +// Global variables +$version='1.0'; +$error=0; + + +// -------------------- START OF YOUR CODE HERE -------------------- +@set_time_limit(0); // No timeout for this script +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"); +// 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. + +//$langs->setDefaultLang('en_US'); // To change default language of $langs +$langs->load("main"); // To load language file for default language + +// Load user and its permissions +$result=$user->fetch('','admin'); // Load user for login 'admin'. Comment line to run as anonymous user. +if (! $result > 0) { dol_print_error('',$user->error); exit; } +$user->getrights(); + + +print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; +if (! isset($argv[1])) { // Check parameters + print "Usage: ".$script_file." param1 param2 ...\n"; + exit(-1); +} +print '--- start'."\n"; +print 'Argument 1='.$argv[1]."\n"; +print 'Argument 2='.$argv[2]."\n"; + + +// Start of transaction +$db->begin(); + + +// Examples for manipulating class skeleton_class +require_once(DOL_DOCUMENT_ROOT."/../dev/skeletons/skeleton_class.class.php"); +$myobject=new Skeleton_Class($db); + +// Example for inserting creating object in database +/* +dol_syslog($script_file." CREATE", LOG_DEBUG); +$myobject->prop1='value_prop1'; +$myobject->prop2='value_prop2'; +$id=$myobject->create($user); +if ($id < 0) { $error++; dol_print_error($db,$myobject->error); } +else print "Object created with id=".$id."\n"; +*/ + +// Example for reading object from database +/* +dol_syslog($script_file." FETCH", LOG_DEBUG); +$result=$myobject->fetch($id); +if ($result < 0) { $error; dol_print_error($db,$myobject->error); } +else print "Object with id=".$id." loaded\n"; +*/ + +// Example for updating object in database ($myobject must have been loaded by a fetch before) +/* +dol_syslog($script_file." UPDATE", LOG_DEBUG); +$myobject->prop1='newvalue_prop1'; +$myobject->prop2='newvalue_prop2'; +$result=$myobject->update($user); +if ($result < 0) { $error++; dol_print_error($db,$myobject->error); } +else print "Object with id ".$myobject->id." updated\n"; +*/ + +// Example for deleting object in database ($myobject must have been loaded by a fetch before) +/* +dol_syslog($script_file." DELETE", LOG_DEBUG); +$result=$myobject->delete($user); +if ($result < 0) { $error++; dol_print_error($db,$myobject->error); } +else print "Object with id ".$myobject->id." deleted\n"; +*/ + + +// An example of a direct SQL read without using the fetch method +/* +$sql = "SELECT field1, field2"; +$sql.= " FROM ".MAIN_DB_PREFIX."skeleton"; +$sql.= " WHERE field3 = 'xxx'"; +$sql.= " ORDER BY field1 ASC"; + +dol_syslog($script_file, LOG_DEBUG); +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + $i = 0; + if ($num) + { + while ($i < $num) + { + $obj = $db->fetch_object($resql); + if ($obj) + { + // You can use here results + print $obj->field1; + print $obj->field2; + } + $i++; + } + } +} +else +{ + $error++; + dol_print_error($db); +} +*/ + + +// -------------------- END OF YOUR CODE -------------------- + +if (! $error) +{ + $db->commit(); + print '--- end ok'."\n"; +} +else +{ + print '--- end error code='.$error."\n"; + $db->rollback(); +} + +$db->close(); // Close $db database opened handler + +exit($error); diff --git a/htdocs/modulebuilder/skeletons/skeleton_webservice_server.php b/htdocs/modulebuilder/skeletons/skeleton_webservice_server.php new file mode 100644 index 00000000000..54a050ff9da --- /dev/null +++ b/htdocs/modulebuilder/skeletons/skeleton_webservice_server.php @@ -0,0 +1,272 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/webservices/server_skeleton.php + * \brief File that is entry point to call Dolibarr WebServices + * \version $Id: server_skeleton.php,v 1.7 2010/12/19 11:49:37 eldy Exp $ + */ + +// This is to make Dolibarr working with Plesk +set_include_path($_SERVER['DOCUMENT_ROOT'].'/htdocs'); + +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."/skeleton/class/skeleton.class.php"); + + +dol_syslog("Call Skeleton webservices interfaces"); + +// Enable and test if module web services is enabled +if (empty($conf->global->MAIN_MODULE_WEBSERVICES)) +{ + $langs->load("admin"); + dol_syslog("Call Dolibarr webservices interfaces with module webservices disabled"); + print $langs->trans("WarningModuleNotActive",'WebServices').'.

    '; + print $langs->trans("ToActivateModule"); + exit; +} + +// Create the soap Object +$server = new nusoap_server(); +$server->soap_defencoding='UTF-8'; +$server->decode_utf8=false; +$ns='http://www.dolibarr.org/ns/'; +$server->configureWSDL('WebServicesDolibarrSkeleton',$ns); +$server->wsdl->schemaTargetNamespace=$ns; + + +// Define WSDL Authentication object +$server->wsdl->addComplexType( + 'authentication', + 'complexType', + 'struct', + 'all', + '', + array( + 'dolibarrkey' => array('name'=>'dolibarrkey','type'=>'xsd:string'), + 'sourceapplication' => array('name'=>'sourceapplication','type'=>'xsd:string'), + 'login' => array('name'=>'login','type'=>'xsd:string'), + 'password' => array('name'=>'password','type'=>'xsd:string'), + 'entity' => array('name'=>'entity','type'=>'xsd:string'), + ) +); + +// Define WSDL Return object +$server->wsdl->addComplexType( + 'result', + 'complexType', + 'struct', + 'all', + '', + array( + 'result_code' => array('name'=>'result_code','type'=>'xsd:string'), + 'result_label' => array('name'=>'result_label','type'=>'xsd:string'), + ) +); + +// Define other specific objects +$server->wsdl->addComplexType( + 'skeleton', + 'complexType', + 'struct', + 'all', + '', + array( + 'prop1'=>'xxx', + 'prop2'=>'xxx', + //... + ) +); + + + +// 5 styles: RPC/encoded, RPC/literal, Document/encoded (not WS-I compliant), Document/literal, Document/literal wrapped +// Style merely dictates how to translate a WSDL binding to a SOAP message. Nothing more. You can use either style with any programming model. +// http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/ +$styledoc='rpc'; // rpc/document (document is an extend into SOAP 1.0 to support unstructured messages) +$styleuse='encoded'; // encoded/literal/literal wrapped +// Better choice is document/literal wrapped but literal wrapped not supported by nusoap. + + +// Register WSDL +$server->register( + 'getSkeleton', + // Entry values + array('authentication'=>'tns:authentication','id'=>'xsd:string','ref'=>'xsd:string','ref_ext'=>'xsd:string'), + // Exit values + array('result'=>'tns:result','skeleton'=>'tns:skeleton'), + $ns, + $ns.'#getSkeleton', + $styledoc, + $styleuse, + 'WS to get skeleton' +); + +// Register WSDL +$server->register( + 'createSkeleton', + // Entry values + array('authentication'=>'tns:authentication','skeleton'=>'tns:skeleton'), + // Exit values + array('result'=>'tns:result','id'=>'xsd:string'), + $ns, + $ns.'#createSkeleton', + $styledoc, + $styleuse, + 'WS to create a skeleton' +); + + + + +/** + * Get Skeleton + * + * @param array $authentication Array of authentication information + * @param int $id Id of object + * @param string $ref Ref of object + * @param string $ref_ext Ref external of object + * @return mixed + */ +function getSkeleton($authentication,$id,$ref='',$ref_ext='') +{ + global $db,$conf,$langs; + + dol_syslog("Function: getSkeleton login=".$authentication['login']." id=".$id." ref=".$ref." ref_ext=".$ref_ext); + + if ($authentication['entity']) $conf->entity=$authentication['entity']; + + // Init and check authentication + $objectresp=array(); + $errorcode='';$errorlabel=''; + $error=0; + $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); + // Check parameters + if (! $error && (($id && $ref) || ($id && $ref_ext) || ($ref && $ref_ext))) + { + $error++; + $errorcode='BAD_PARAMETERS'; $errorlabel="Parameter id, ref and ref_ext can't be both provided. You must choose one or other but not both."; + } + + if (! $error) + { + $fuser->getrights(); + + if ($fuser->rights->skeleton->read) + { + $skeleton=new Skeleton($db); + $result=$skeleton->fetch($id,$ref,$ref_ext); + if ($result > 0) + { + // Create + $objectresp = array( + 'result'=>array('result_code'=>'OK', 'result_label'=>''), + 'skeleton'=>array( + 'prop1'=>$skeleton->prop1, + 'prop2'=>$skeleton->prop2, + //... + ) + ); + } + else + { + $error++; + $errorcode='NOT_FOUND'; $errorlabel='Object not found for id='.$id.' nor ref='.$ref.' nor ref_ext='.$ref_ext; + } + } + else + { + $error++; + $errorcode='PERMISSION_DENIED'; $errorlabel='User does not have permission for this request'; + } + } + + if ($error) + { + $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel)); + } + + return $objectresp; +} + + +/** + * Create Skeleton + * + * @param array $authentication Array of authentication information + * @param Skeleton $skeleton $skeleton + * @return array Array result + */ +function createSkeleton($authentication,$skeleton) +{ + global $db,$conf,$langs; + + $now=dol_now(); + + dol_syslog("Function: createSkeleton login=".$authentication['login']); + + if ($authentication['entity']) $conf->entity=$authentication['entity']; + + // Init and check authentication + $objectresp=array(); + $errorcode='';$errorlabel=''; + $error=0; + $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); + // Check parameters + + + if (! $error) + { + $newobject=new Skeleton($db); + $newobject->prop1=$skeleton->prop1; + $newobject->prop2=$skeleton->prop2; + //... + + $db->begin(); + + $result=$newobject->create($fuser); + if ($result <= 0) + { + $error++; + } + + if (! $error) + { + $db->commit(); + $objectresp=array('result'=>array('result_code'=>'OK', 'result_label'=>''),'id'=>$newobject->id,'ref'=>$newobject->ref); + } + else + { + $db->rollback(); + $error++; + $errorcode='KO'; + $errorlabel=$newobject->error; + } + } + + if ($error) + { + $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel)); + } + + return $objectresp; +} + +// Return the results. +$server->service(file_get_contents("php://input")); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 49c17a749f0..f7cb1c0bb5a 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1642,6 +1642,10 @@ div.login_block_other { padding-top: 3px; text-align: right; } .alogin:hover, .atoplogin:hover { text-decoration:underline !important; } +span.fa.atoplogin, span.fa.atoplogin:hover { + font-size: 16px; + text-decoration: none !important; +} img.login, img.printer, img.entity { /* padding: 0px 0px 0px 4px; */ /* margin: 0px 0px 0px 8px; */ diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 1908fcfef4a..f83d5df0d50 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1675,6 +1675,10 @@ div.login_block_other { padding-top: 3px; } .alogin:hover, .atoplogin:hover { text-decoration:underline !important; } +span.fa.atoplogin, span.fa.atoplogin:hover { + font-size: 16px; + text-decoration: none !important; +} img.login, img.printer, img.entity { /* padding: 0px 0px 0px 4px; */ /* margin: 0px 0px 0px 8px; */ diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 4b9c1c9960c..26af6c659ff 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2118,7 +2118,7 @@ class User extends CommonObject } /** - * Retourne le libelle du statut d'un user (actif, inactif) + * Return label of status of user (active, inactive) * * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto * @return string Label of status From 1489847a7412bd70bbcf530cfce9bcfa125e0986 Mon Sep 17 00:00:00 2001 From: dolibarr95 Date: Thu, 30 Mar 2017 09:49:34 +0200 Subject: [PATCH 040/233] Display mobile icon Display a specific icon when mobile --- htdocs/core/class/commonobject.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index b79c72e6336..e6a5b5d6b92 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -495,7 +495,7 @@ abstract class CommonObject $out.=dol_print_phone($this->phone_pro,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhonePro")); $outdone++; } if (! empty($this->phone_mobile)) { - $out.=dol_print_phone($this->phone_mobile,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhoneMobile")); $outdone++; + $out.=dol_print_phone($this->phone_mobile,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','mobile',$langs->trans("PhoneMobile")); $outdone++; } if (! empty($this->phone_perso)) { $out.=dol_print_phone($this->phone_perso,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhonePerso")); $outdone++; @@ -507,7 +507,7 @@ abstract class CommonObject $out.=dol_print_phone($this->office_phone,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhonePro")); $outdone++; } if (! empty($this->user_mobile)) { - $out.=dol_print_phone($this->user_mobile,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','phone',$langs->trans("PhoneMobile")); $outdone++; + $out.=dol_print_phone($this->user_mobile,$this->country_code,$contactid,$thirdpartyid,'AC_TEL',' ','mobile',$langs->trans("PhoneMobile")); $outdone++; } if (! empty($this->office_fax)) { $out.=dol_print_phone($this->fax,$this->country_code,$contactid,$thirdpartyid,'AC_FAX',' ','fax',$langs->trans("Fax")); $outdone++; From 78cc976e9f6d6f2d835ec8cf517e54ee120b9010 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 10:40:15 +0200 Subject: [PATCH 041/233] Work on module builder --- htdocs/core/modules/modCron.class.php | 2 +- htdocs/core/modules/modModuleBuilder.class.php | 14 ++++++++++++++ htdocs/core/modules/modPrinting.class.php | 2 +- htdocs/langs/en_US/admin.lang | 2 +- htdocs/langs/en_US/main.lang | 1 + htdocs/langs/en_US/modulebuilder.lang | 1 - htdocs/main.inc.php | 2 +- 7 files changed, 19 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/modCron.class.php b/htdocs/core/modules/modCron.class.php index 88b154f891e..7f949501023 100644 --- a/htdocs/core/modules/modCron.class.php +++ b/htdocs/core/modules/modCron.class.php @@ -138,7 +138,7 @@ class modCron extends DolibarrModules 'url'=>'/cron/list.php?status=-2&leftmenu=admintools', 'langs'=>'cron', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>200, - 'enabled'=>'($leftmenu==\'admintools\' || $leftmenu==\'admintools_info\')', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'enabled'=>'$conf->cron->enabled && preg_match(\'/^admintools/\', $leftmenu)', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'$user->rights->cron->read', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'target'=>'', 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both diff --git a/htdocs/core/modules/modModuleBuilder.class.php b/htdocs/core/modules/modModuleBuilder.class.php index b68148377c3..dce442720a3 100644 --- a/htdocs/core/modules/modModuleBuilder.class.php +++ b/htdocs/core/modules/modModuleBuilder.class.php @@ -85,5 +85,19 @@ class modModuleBuilder extends DolibarrModules // Main menu entries //------------------ $this->menu = array(); + + $this->menu[$r]=array('fk_menu'=>'fk_mainmenu=home,fk_leftmenu=admintools', + 'type'=>'left', + 'titre'=>'ModuleBuilder', + 'mainmenu'=>'home', + 'leftmenu'=>'admintools_modulebuilder', + 'url'=>'/modulebuilder/index.php?mainmenu=home&leftmenu=admintools_modulebuilder', + 'langs'=>'modulebuilder', + 'position'=>100, + 'perms'=>'1', + 'enabled'=>'$conf->modulebuilder->enabled && preg_match(\'/^admintools/\',$leftmenu) && ($user->admin || $conf->global->MODULEBUILDER_FOREVERYONE)', + 'target'=>'_modulebuilder', + 'user'=>0); + } } diff --git a/htdocs/core/modules/modPrinting.class.php b/htdocs/core/modules/modPrinting.class.php index fd101615809..89bf6115dae 100644 --- a/htdocs/core/modules/modPrinting.class.php +++ b/htdocs/core/modules/modPrinting.class.php @@ -111,7 +111,7 @@ class modPrinting extends DolibarrModules 'url'=>'/printing/index.php?mainmenu=home&leftmenu=admintools', 'langs'=>'printing', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>300, - 'enabled'=>'$conf->printing->enabled && ($leftmenu==\'admintools\' || $leftmenu==\'admintools_info\')', + 'enabled'=>'$conf->printing->enabled && preg_match(\'/^admintools/\', $leftmenu)', 'perms'=>'$user->rights->printing->read', // Use 'perms'=>'1' if you want your menu with no permission rules 'target'=>'', 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 3831fb49007..b3f43698843 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1664,7 +1664,7 @@ 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")
    Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "Offset" in days)
    Use "Current/Next" to have payment term date being the first Nth of the month (N is stored into field "Nb of days") 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). -WarningInstallationMayBecomeNotCompliantWithLaw=You try to install the module %s that is an external module. Activate an external module only if it does not alterate negatively the behavior required by your country laws (%s). If the module bring a non legal feature, you are the only responsible for the use of a non-compliant software. +WarningInstallationMayBecomeNotCompliantWithLaw=You try to install the module %s that is an external module. Activating an external module means you trust the editor 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. ##### Resource #### ResourceSetup=Configuration du module Resource UseSearchToSelectResource=Use a search form to choose a resource (rather than a drop-down list). diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 53d727d9965..918f46a44b7 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -763,6 +763,7 @@ DirectDownloadLink=Direct download link Download=Download ActualizeCurrency=Update currency rate Fiscalyear=Fiscal year +ModuleBuilder=Module Builder # Week day Monday=Monday Tuesday=Tuesday diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 6605a7b6a63..9979760bc4f 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -1,3 +1,2 @@ # Dolibarr language file - Source file is en_US - loan -ModuleBuilder=Module Builder ModuleBuilderDesc=This tools give you utilites to build your own module. Your modules will be generated into the first alternative directory: %s. diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index fe1ed01a68f..88e2760ecb4 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1440,7 +1440,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a // Link to module builder if (! empty($conf->modulebuilder->enabled)) { - $text =''; + $text =''; //$text.= img_picto(":".$langs->trans("ModuleBuilder"), 'printer_top.png', 'class="printer"'); $text.=''; $text.=''; From f01815519a1fcdc59f883de3969c7eba5e6d1131 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 11:25:28 +0200 Subject: [PATCH 042/233] Fix trigger of automatic events --- htdocs/adherents/agenda.php | 4 +-- htdocs/core/lib/company.lib.php | 7 ++++-- ...terface_50_modAgenda_ActionsAuto.class.php | 24 ++++++++++++++---- .../mysql/data/llx_c_action_trigger.sql | 25 +++++++++++-------- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php index 74f9e8234ad..ecb0b672250 100644 --- a/htdocs/adherents/agenda.php +++ b/htdocs/adherents/agenda.php @@ -167,10 +167,10 @@ if ($object->id > 0) print load_fiche_titre($langs->trans("ActionsOnMember"),$out,''); // List of todo actions - show_actions_todo($conf,$langs,$db,$object); + //show_actions_todo($conf,$langs,$db,$object); // List of done actions - show_actions_done($conf,$langs,$db,$object); + show_actions_done($conf,$langs,$db,$object,null,0,'',''); } diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index b010f8143b4..4e52f2d8f01 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -960,7 +960,7 @@ function show_actions_todo($conf,$langs,$db,$filterobj,$objcon='',$noprint=0,$ac * @param Contact $objcon Object contact * @param int $noprint Return string but does not output it * @param string $actioncode Filter on actioncode - * @param string $donetodo Filter on event 'done' or 'todo' or ''=nofilter. + * @param string $donetodo Filter on event 'done' or 'todo' or ''=nofilter (all). * @param array $filters Filter on other fields * @param string $sortfield Sort field * @param string $sortorder Sort order @@ -1181,7 +1181,10 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= { $out.=''; if (get_class($filterobj) == 'Societe') $out.=''; - $out.=$langs->trans("ActionsToDoShort").' / '.$langs->trans("ActionsDoneShort"); + $out.=($donetodo != 'done' ? $langs->trans("ActionsToDoShort") : ''); + $out.=($donetodo != 'done' && $donetodo != 'todo' ? ' / ' : ''); + $out.=($donetodo != 'todo' ? $langs->trans("ActionsDoneShort") : ''); + //$out.=$langs->trans("ActionsToDoShort").' / '.$langs->trans("ActionsDoneShort"); if (get_class($filterobj) == 'Societe') $out.=''; $out.=''; } diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index bce6cd02eee..d5354ab385f 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -658,6 +658,21 @@ class InterfaceActionsAuto extends DolibarrTriggers $object->sendtoid=0; } + elseif ($action == 'MEMBER_MODIFY') + { + $langs->load("agenda"); + $langs->load("other"); + $langs->load("members"); + + $object->actiontypecode='AC_OTH_AUTO'; + if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberModifiedInDolibarr",$object->ref); + $object->actionmsg=$langs->transnoentities("MemberModifiedInDolibarr",$object->ref); + $object->actionmsg.="\n".$langs->transnoentities("Member").': '.$object->getFullName($langs); + $object->actionmsg.="\n".$langs->transnoentities("Type").': '.$object->type; + $object->actionmsg.="\n".$langs->transnoentities("Author").': '.$user->login; + + $object->sendtoid=0; + } elseif ($action == 'MEMBER_SUBSCRIPTION') { $langs->load("agenda"); @@ -721,21 +736,20 @@ class InterfaceActionsAuto extends DolibarrTriggers $object->sendtoid=0; } - elseif($action == 'PROJECT_CREATE') { + elseif($action == 'PROJECT_VALIDATE') { $langs->load("agenda"); $langs->load("other"); $langs->load("projects"); $object->actiontypecode='AC_OTH_AUTO'; - if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProjectCreatedInDolibarr",$object->ref); - $object->actionmsg=$langs->transnoentities("ProjectCreatedInDolibarr",$object->ref); - $object->actionmsg.="\n".$langs->transnoentities("Task").': '.$object->ref; + if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProjectValidatedInDolibarr",$object->ref); + $object->actionmsg=$langs->transnoentities("ProjectValidatedInDolibarr",$object->ref); + $object->actionmsg.="\n".$langs->transnoentities("Project").': '.$object->ref; $object->actionmsg.="\n".$langs->transnoentities("Author").': '.$user->login; $object->sendtoid=0; } - elseif($action == 'PROJECT_MODIFY') { $langs->load("agenda"); $langs->load("other"); diff --git a/htdocs/install/mysql/data/llx_c_action_trigger.sql b/htdocs/install/mysql/data/llx_c_action_trigger.sql index 2111a6c265c..5cbc7745080 100644 --- a/htdocs/install/mysql/data/llx_c_action_trigger.sql +++ b/htdocs/install/mysql/data/llx_c_action_trigger.sql @@ -68,19 +68,22 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value 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 ('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_SUBSCRIPTION','Member subscribed','Executed when a member is subscribed','member',23); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_RESILIATE','Member resiliated','Executed when a member is resiliated','member',24); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_MODIFY','Member modified','Executed when a member is modified','member',24); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_DELETE','Member deleted','Executed when a member is deleted','member',25); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_VALIDATE','Intervention validated','Executed when a intervention is validated','ficheinter',19); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_CLASSIFY_BILLED','Intervention set billed','Executed when a intervention is set to billed (when option FICHINTER_CLASSIFY_BILLED is set)','ficheinter',19); -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',19); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_REOPEN','Intervention opened','Executed when a intervention is re-opened','ficheinter',19); -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',19); --- actions not enabled by default (no constant created for that) when we enable module agenda +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_MODIFY','Member modified','Executed when a member is modified','member',23); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_SUBSCRIPTION','Member subscribed','Executed when a member is subscribed','member',24); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_RESILIATE','Member resiliated','Executed when a member is resiliated','member',25); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_DELETE','Member deleted','Executed when a member is deleted','member',27); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_VALIDATE','Intervention validated','Executed when a intervention is validated','ficheinter',30); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_CLASSIFY_BILLED','Intervention set billed','Executed when a intervention is set to billed (when option FICHINTER_CLASSIFY_BILLED is set)','ficheinter',32); +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 ('PROJECT_CREATE','Project creation','Executed when a project is created','project',140); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_MODIFY','Project modified','Executed when a project is modified','project',141); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_VALIDATE','Project validation','Executed when a project is validated','project',140); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_DELETE','Project deleted','Executed when a project is deleted','project',142); +-- actions not enabled by default (no constant created for that) when we enable module agenda +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_MODIFY','Member modified','Executed when a member is modified','member',26); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_MODIFY','Intervention modified','Executed when a intervention is modified','ficheinter',31); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_MODIFY','Project modified','Executed when a project is modified','project',141); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_CREATE','Task created','Executed when a project task is created','project',150); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_MODIFY','Task modified','Executed when a project task is modified','project',151); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_DELETE','Task deleted','Executed when a project task is deleted','project',152); From ce7368d10e00a44e0d8ba409720ed301956016d9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 11:51:07 +0200 Subject: [PATCH 043/233] Fix events create from member card not linked to member --- htdocs/adherents/agenda.php | 2 +- htdocs/langs/en_US/agenda.lang | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php index ecb0b672250..fc73892d44d 100644 --- a/htdocs/adherents/agenda.php +++ b/htdocs/adherents/agenda.php @@ -141,7 +141,7 @@ if ($object->id > 0) if (! empty($conf->agenda->enabled)) { - print ''; + print ''; } print '
    '; diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index a429fc7159e..d0f3456987d 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -47,6 +47,7 @@ InvoiceDeleteDolibarr=Invoice %s deleted InvoicePaidInDolibarr=Invoice %s changed to paid InvoiceCanceledInDolibarr=Invoice %s canceled MemberValidatedInDolibarr=Member %s validated +MemberModifiedInDolibarr=Member %s modified MemberResiliatedInDolibarr=Member %s terminated MemberDeletedInDolibarr=Member %s deleted MemberSubscriptionAddedInDolibarr=Subscription for member %s added From 141ef91dea91b0662ba166c75e0deceacc4ba64c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 11:53:58 +0200 Subject: [PATCH 044/233] Fix default auto events --- htdocs/core/modules/modAgenda.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/modAgenda.class.php b/htdocs/core/modules/modAgenda.class.php index a0c2a6e9de4..83175bcdefc 100644 --- a/htdocs/core/modules/modAgenda.class.php +++ b/htdocs/core/modules/modAgenda.class.php @@ -82,9 +82,9 @@ class modAgenda extends DolibarrModules { while ($obj = $this->db->fetch_object($sqlreadactions)) { - if (preg_match('/_CREATE$/',$obj->code) && (! in_array($obj->code, array('COMPANY_CREATE','PRODUCT_CREATE')))) continue; // We don't track such events (*_CREATE) by default, we prefer validation (except thirdparty or product creation because there is no validation). - if (preg_match('/^PROJECT_/',$obj->code)) continue; // We don't track such events by default. + if (preg_match('/_CREATE$/',$obj->code) && (! in_array($obj->code, array('COMPANY_CREATE','PRODUCT_CREATE','TASK_CREATE')))) continue; // We don't track such events (*_CREATE) by default, we prefer validation (except thirdparty/product/task creation because there is no validation). if (preg_match('/^TASK_/',$obj->code)) continue; // We don't track such events by default. + if (preg_match('/^_MODIFY/',$obj->code)) continue; // We don't track such events by default. $this->const[] = array('MAIN_AGENDA_ACTIONAUTO_'.$obj->code, "chaine", "1"); } } From 6bd112db5e844ba957e188d1db78d2ef45950dbb Mon Sep 17 00:00:00 2001 From: dolibarr95 Date: Thu, 30 Mar 2017 14:49:40 +0200 Subject: [PATCH 045/233] Unify the trigger name Should be COMPANY_RIB_MODIFY instead of COMPANY_RIB_UPDATE --- htdocs/societe/class/companybankaccount.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index 6a00de29259..4101910005e 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -174,7 +174,7 @@ class CompanyBankAccount extends Account if (! $notrigger) { // Call trigger - $result=$this->call_trigger('COMPANY_RIB_UPDATE',$user); + $result=$this->call_trigger('COMPANY_RIB_MODIFY',$user); if ($result < 0) $error++; // End call triggers if(! $error ) From 2448b9ee55ed0eef1844aba8383e63842c600a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Thu, 30 Mar 2017 14:52:26 +0200 Subject: [PATCH 046/233] FIX #6619 Template invoices list do not respect restricted thirdparty user rights --- htdocs/compta/facture/fiche-rec.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index c7bf362ab7d..3a55c8b57c2 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -1384,8 +1384,14 @@ else $sql = "SELECT s.nom as name, s.rowid as socid, f.rowid as facid, f.titre, f.total, f.tva as total_vat, f.total_ttc, f.frequency,"; $sql.= " f.date_last_gen, f.date_when"; $sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture_rec as f"; + 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 (! $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) $sql .= natural_search('f.frequency', $search_frequency); From cd5b074a4829abf1bcaa32d1f1dfe925d8aaca19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Thu, 30 Mar 2017 15:21:20 +0200 Subject: [PATCH 047/233] FIX #6621 Documents tab shows greyed out upload form even if the option to show actions not available is disabled --- htdocs/core/class/html.formfile.class.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index c117417e428..0821b9b2d2b 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -89,6 +89,11 @@ class FormFile } else { + //If there is no permission and the option to hide unauthorized actions is enabled, then nothing is printed + if (!$perm && !empty($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)) { + return 1; + } + $maxlength=$size; $out = "\n\n\n"; From 8e70c4a0b738e42b42b845dae8af885aa95083b8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 15:39:50 +0200 Subject: [PATCH 048/233] Work on 6.0 new look and feel --- htdocs/adherents/agenda.php | 38 ++--- htdocs/adherents/document.php | 2 +- htdocs/adherents/note.php | 3 +- htdocs/contact/list.php | 9 +- htdocs/core/class/html.formother.class.php | 2 +- htdocs/core/lib/company.lib.php | 123 ++++++++------- htdocs/core/lib/functions.lib.php | 10 +- htdocs/core/modules/modAgenda.class.php | 4 +- htdocs/expedition/list.php | 73 +++++---- htdocs/imports/import.php | 53 ++++--- htdocs/langs/en_US/exports.lang | 2 + htdocs/product/popuprop.php | 7 +- htdocs/product/reassort.php | 171 +++++++++------------ htdocs/product/reassortlot.php | 68 ++++---- htdocs/product/stock/list.php | 22 +-- htdocs/product/stock/productlot_list.php | 129 ++++++++-------- htdocs/product/stock/replenish.php | 32 ++-- htdocs/product/stock/replenishorders.php | 135 ++++++++-------- htdocs/theme/eldy/style.css.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 20 files changed, 429 insertions(+), 458 deletions(-) diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php index fc73892d44d..f85761ff266 100644 --- a/htdocs/adherents/agenda.php +++ b/htdocs/adherents/agenda.php @@ -36,7 +36,7 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; $langs->load("companies"); $langs->load("members"); -$id = GETPOST('id','int'); +$id = GETPOST('id','int')?GETPOST('id','int'):GETPOST('rowid','int'); // Security check $result=restrictedArea($user,'adherent',$id); @@ -85,12 +85,13 @@ if ($object->id > 0) if (! empty($conf->notification->enabled)) $langs->load("mails"); $head = member_prepare_head($object); - dol_fiche_head($head, 'agenda', $langs->trans("Member"),0,'user'); + dol_fiche_head($head, 'agenda', $langs->trans("Member"), -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'rowid', $linkback); + /* print '
    '; print '
    '; @@ -107,9 +108,6 @@ if ($object->id > 0) // Morphy print ''.$langs->trans("Nature").''.$object->getmorphylib().''; - /*print ''; - print $form->showphoto('memberphoto',$member); - print '';*/ print ''; // Company @@ -120,15 +118,16 @@ if ($object->id > 0) print ''; print ''; - + */ - print '
    '; + print '
    '; + + print '
    '; $object->info($id); print dol_print_object_info($object, 1); - - print '
    '; + print '
    '; dol_fiche_end(); @@ -146,30 +145,11 @@ if ($object->id > 0) print '
    '; - print '
    '; - $out=''; - /*$objthirdparty=$object->thirdparty; - $objcon=new stdClass(); - - $permok=$user->rights->agenda->myactions->create; - if ((! empty($objthirdparty->id) || ! empty($objcon->id)) && $permok) - { - $out.=''; - $out.=$langs->trans("AddAnAction").' '; - $out.=img_picto($langs->trans("AddAnAction"),'filenew'); - $out.=""; - }*/ - print load_fiche_titre($langs->trans("ActionsOnMember"),$out,''); - // List of todo actions - //show_actions_todo($conf,$langs,$db,$object); - - // List of done actions + // List of actions show_actions_done($conf,$langs,$db,$object,null,0,'',''); } diff --git a/htdocs/adherents/document.php b/htdocs/adherents/document.php index 47fbebbf976..cbc6d7f090c 100644 --- a/htdocs/adherents/document.php +++ b/htdocs/adherents/document.php @@ -108,7 +108,7 @@ if ($id > 0) $head = member_prepare_head($object); - dol_fiche_head($head, 'document', $langs->trans("Member"),0,'user'); + dol_fiche_head($head, 'document', $langs->trans("Member"), -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/adherents/note.php b/htdocs/adherents/note.php index 9e6a20f6cb3..325b14680e7 100644 --- a/htdocs/adherents/note.php +++ b/htdocs/adherents/note.php @@ -69,7 +69,7 @@ if ($id) { $head = member_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans("Member"), 0, 'user'); + dol_fiche_head($head, 'note', $langs->trans("Member"), -1, 'user'); print "
    "; print ''; @@ -109,7 +109,6 @@ if ($id) print ""; print '
    '; - print '
    '; $cssclass='titlefield'; diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 4e7a9c6f190..e7d4f603618 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -784,12 +784,13 @@ while ($i < min($num,$limit)) print ''.$contactstatic->getLibStatut(3).''; } // Action column - Links Add action and Export vcard - print ''; - print ''.img_object($langs->trans("AddAction"),"action").''; + print ''; + /*print ''.img_object($langs->trans("AddAction"),"action").''; print '   '; - print ''; + print ''; print img_picto($langs->trans("VCard"),'vcard.png').' '; - print ''; + print ''; */ + print ''; print "\n"; $i++; diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 270deb2134e..66e624e96b9 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -121,7 +121,7 @@ class FormOther $result = $this->db->query($sql); if ($result) { - print ''; if ($useempty) { print ''; diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 13152f85ac8..bbe9febd481 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1005,7 +1005,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $sql.= " a.fk_element, a.elementtype,"; $sql.= " a.fk_user_author, a.fk_contact,"; $sql.= " c.code as acode, c.libelle as alabel, c.picto as apicto,"; - $sql.= " u.login, u.rowid as user_id"; + $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 (get_class($filterobj) == 'Societe') $sql.= ", sp.lastname, sp.firstname"; if (get_class($filterobj) == 'Adherent') $sql.= ", m.lastname, m.firstname"; if (get_class($filterobj) == 'CommandeFournisseur') $sql.= ", o.ref"; @@ -1078,9 +1078,14 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= 'dateend'=>$db->jdate($obj->dp2), 'note'=>$obj->label, 'percent'=>$obj->percent, + 'userid'=>$obj->user_id, - 'login'=>$obj->login, - 'contact_id'=>$obj->fk_contact, + 'login'=>$obj->user_login, + 'userfirstname'=>$obj->user_firstname, + 'userlastname'=>$obj->user_lastname, + 'userphoto'=>$obj->user_photo, + + 'contact_id'=>$obj->fk_contact, 'lastname'=>$obj->lastname, 'firstname'=>$obj->firstname, 'fk_element'=>$obj->fk_element, @@ -1109,7 +1114,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $sql = "SELECT m.rowid as id, mc.date_envoi as da, m.titre as note, '100' as percentage,"; $sql.= " 'AC_EMAILING' as acode,"; - $sql.= " u.rowid as user_id, u.login"; // User that valid action + $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"; // User that valid action $sql.= " FROM ".MAIN_DB_PREFIX."mailing as m, ".MAIN_DB_PREFIX."mailing_cibles as mc, ".MAIN_DB_PREFIX."user as u"; $sql.= " WHERE mc.email = '".$db->escape($objcon->email)."'"; // Search is done on email. $sql.= " AND mc.statut = 1"; @@ -1136,8 +1141,12 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= 'note'=>$obj->note, 'percent'=>$obj->percentage, 'acode'=>$obj->acode, - 'userid'=>$obj->user_id, - 'login'=>$obj->login + + 'userid'=>$obj->user_id, + 'login'=>$obj->user_login, + 'userfirstname'=>$obj->user_firstname, + 'userlastname'=>$obj->user_lastname, + 'userphoto'=>$obj->user_photo ); $numaction++; $i++; @@ -1189,52 +1198,50 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $out.='
    '; $out.=''; + + $out.=''; + if ($donetodo) + { + $out.=''; + } + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + // Action column + $out.=''; + $out.=''; + $out.=''; if ($donetodo) { - $out.=''; + if (get_class($filterobj) == 'Societe') $tmp.=''; + $out.=getTitleFieldOfList($tmp); } - $out.=getTitleFieldOfList($langs->trans("Ref"), 0, $_SERVER["PHP_SELF"], 'a.id', '', $param, '', $sortfield, $sortorder); - $out.=''; - $out.=getTitleFieldOfList($langs->trans("Date"), 0, $_SERVER["PHP_SELF"], 'a.datep,a.id', '', $param, '', $sortfield, $sortorder); - $out.=''; - $out.=''; - $out.=''; - $out.=''; + $out.=getTitleFieldOfList($langs->trans("Ref"), 0, $_SERVER["PHP_SELF"], 'a.id', '', $param, '', $sortfield, $sortorder); + $out.=getTitleFieldOfList($langs->trans("Owner")); + $out.=getTitleFieldOfList($langs->trans("Label"), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder); + $out.=getTitleFieldOfList($langs->trans("Date"), 0, $_SERVER["PHP_SELF"], 'a.datep,a.id', '', $param, 'align="center"', $sortfield, $sortorder); + $out.=getTitleFieldOfList($langs->trans("Type")); + $out.=getTitleFieldOfList(''); + $out.=getTitleFieldOfList(''); $out.=getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], 'a.percent', '', $param, 'align="center"', $sortfield, $sortorder); - $out.=''; - $out.=''; - - - $out.=''; - if ($donetodo) - { - $out.=''; - } - $out.=''; - $out.=''; - $out.=''; - $out.=''; - $out.=''; - $out.=''; - $out.=''; - $out.=''; - // Action column - $out.=''; + $out.=getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'maxwidthsearch '); $out.=''; foreach ($histo as $key=>$value) @@ -1256,6 +1263,15 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $out.=$actionstatic->getNomUrl(1, -1); $out.=''; + // Author of event + $out.=''; + // Title $out.=''; - + // Date - $out.=''; } - // Auteur - $out.=''; - - // Statut + // Status $out.=''; // Actions diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index f9ba39f870e..ea92fb5a63b 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2711,7 +2711,7 @@ function img_error($titlealt = 'default') if ($titlealt == 'default') $titlealt = $langs->trans('Error'); - return img_picto($titlealt, 'error.png'); + return img_picto($titlealt, 'error.png', 'class="valigntextbottom"'); } /** @@ -2727,7 +2727,8 @@ function img_next($titlealt = 'default', $morealt='') if ($titlealt == 'default') $titlealt = $langs->trans('Next'); - return img_picto($titlealt, 'next.png', $morealt); + //return img_picto($titlealt, 'next.png', $morealt); + return ''; } /** @@ -2743,7 +2744,8 @@ function img_previous($titlealt = 'default', $morealt='') if ($titlealt == 'default') $titlealt = $langs->trans('Previous'); - return img_picto($titlealt, 'previous.png', $morealt); + //return img_picto($titlealt, 'previous.png', $morealt); + return ''; } /** @@ -3109,7 +3111,7 @@ function print_liste_field_titre($name, $file="", $field="", $begin="", $morepar * @param string $field Field to use for new sorting. Empty if this field is not sortable. * @param string $begin ("" by defaut) * @param string $moreparam Add more parameters on sort url links ("" by default) - * @param string $moreattrib Add more attributes on th ("" by defaut) + * @param string $moreattrib Add more attributes on th ("" by defaut). To add more css class, use param $prefix. * @param string $sortfield Current field used to sort * @param string $sortorder Current sort order * @param string $prefix Prefix for css. Use space after prefix to add your own CSS tag. diff --git a/htdocs/core/modules/modAgenda.class.php b/htdocs/core/modules/modAgenda.class.php index 291ca6bdbfd..339a208fc31 100644 --- a/htdocs/core/modules/modAgenda.class.php +++ b/htdocs/core/modules/modAgenda.class.php @@ -86,9 +86,9 @@ class modAgenda extends DolibarrModules { while ($obj = $this->db->fetch_object($sqlreadactions)) { - if (preg_match('/_CREATE$/',$obj->code) && (! in_array($obj->code, array('COMPANY_CREATE','PRODUCT_CREATE','TASK_CREATE')))) continue; // We don't track such events (*_CREATE) by default, we prefer validation (except thirdparty/product/task creation because there is no validation). + //if (preg_match('/_CREATE$/',$obj->code) && (! in_array($obj->code, array('COMPANY_CREATE','PRODUCT_CREATE','TASK_CREATE')))) continue; // We don't track such events (*_CREATE) by default, we prefer validation (except thirdparty/product/task creation because there is no validation). if (preg_match('/^TASK_/',$obj->code)) continue; // We don't track such events by default. - if (preg_match('/^_MODIFY/',$obj->code)) continue; // We don't track such events by default. + //if (preg_match('/^_MODIFY/',$obj->code)) continue; // We don't track such events by default. $this->const[] = array('MAIN_AGENDA_ACTIONAUTO_'.$obj->code, "chaine", "1"); } } diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 65d7fd5223e..4166bbb3791 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -308,44 +308,8 @@ if ($resql) print '
    '; print '
    '; + $out.=$formactions->select_type_actions($actioncode, "actioncode", '', empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:-1, 0, 0, 1); + $out.=''; + $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $out.=$searchpitco; + $out.='
    '; - if (get_class($filterobj) == 'Societe') $out.=''; - $out.=($donetodo != 'done' ? $langs->trans("ActionsToDoShort") : ''); - $out.=($donetodo != 'done' && $donetodo != 'todo' ? ' / ' : ''); - $out.=($donetodo != 'todo' ? $langs->trans("ActionsDoneShort") : ''); + $tmp=''; + if (get_class($filterobj) == 'Societe') $tmp.=''; + $tmp.=($donetodo != 'done' ? $langs->trans("ActionsToDoShort") : ''); + $tmp.=($donetodo != 'done' && $donetodo != 'todo' ? ' / ' : ''); + $tmp.=($donetodo != 'todo' ? $langs->trans("ActionsDoneShort") : ''); //$out.=$langs->trans("ActionsToDoShort").' / '.$langs->trans("ActionsDoneShort"); - if (get_class($filterobj) == 'Societe') $out.=''; - $out.=''.$langs->trans("Label").''.$langs->trans("Type").''.$langs->trans("Owner").''; - //TODO Add selection of fields - $out.='
    '; - $out.=$formactions->select_type_actions($actioncode, "actioncode", '', empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:-1, 0, 0, 1); - $out.=''; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); - $out.=$searchpitco; - $out.='
    '; + //$userstatic->id=$histo[$key]['userid']; + //$userstatic->login=$histo[$key]['login']; + //$out.=$userstatic->getLoginUrl(1); + $userstatic->fetch($histo[$key]['userid']); + $out.=$userstatic->getNomUrl(-1); + $out.=''; if (isset($histo[$key]['type']) && $histo[$key]['type']=='action') @@ -1276,9 +1292,9 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $out.=dol_trunc($libelle,120); } $out.=''; + $out.=''; $out.=dol_print_date($histo[$key]['datestart'],'dayhour'); if ($histo[$key]['dateend'] && $histo[$key]['dateend'] != $histo[$key]['datestart']) { @@ -1374,16 +1390,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $out.=' '; - //$userstatic->id=$histo[$key]['userid']; - //$userstatic->login=$histo[$key]['login']; - //$out.=$userstatic->getLoginUrl(1); - $userstatic->fetch($histo[$key]['userid']); - $out.=$userstatic->getNomUrl(1); - $out.=''.$actionstatic->LibStatut($histo[$key]['percent'],3,1,$histo[$key]['datestart']).'
    '."\n"; - print ''; - - if (! empty($arrayfields['e.ref']['checked'])) print_liste_field_titre($arrayfields['e.ref']['label'], $_SERVER["PHP_SELF"],"e.ref","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['e.ref_customer']['checked'])) print_liste_field_titre($arrayfields['e.ref_customer']['label'], $_SERVER["PHP_SELF"],"e.ref_customer","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"],"s.nom", "", $param,'align="left"',$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['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['e.date_delivery']['checked'])) print_liste_field_titre($arrayfields['e.date_delivery']['label'], $_SERVER["PHP_SELF"],"e.date_delivery","",$param, 'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['l.ref']['checked'])) print_liste_field_titre($arrayfields['l.ref']['label'], $_SERVER["PHP_SELF"],"l.ref","",$param, '',$sortfield,$sortorder); - if (! empty($arrayfields['l.date_delivery']['checked'])) print_liste_field_titre($arrayfields['l.date_delivery']['label'], $_SERVER["PHP_SELF"],"l.date_delivery","",$param, 'align="center"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['e.datec']['checked'])) print_liste_field_titre($arrayfields['e.datec']['label'],$_SERVER["PHP_SELF"],"e.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['e.tms']['checked'])) print_liste_field_titre($arrayfields['e.tms']['label'],$_SERVER["PHP_SELF"],"e.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['e.fk_statut']['checked'])) print_liste_field_titre($arrayfields['e.fk_statut']['label'],$_SERVER["PHP_SELF"],"e.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['l.fk_statut']['checked'])) print_liste_field_titre($arrayfields['l.fk_statut']['label'], $_SERVER["PHP_SELF"],"l.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Lignes des champs de filtre - print ''; + print ''; // Ref if (! empty($arrayfields['e.ref']['checked'])) { @@ -462,6 +426,41 @@ if ($resql) print ''; print "\n"; + print ''; + if (! empty($arrayfields['e.ref']['checked'])) print_liste_field_titre($arrayfields['e.ref']['label'], $_SERVER["PHP_SELF"],"e.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['e.ref_customer']['checked'])) print_liste_field_titre($arrayfields['e.ref_customer']['label'], $_SERVER["PHP_SELF"],"e.ref_customer","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"],"s.nom", "", $param,'align="left"',$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['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['e.date_delivery']['checked'])) print_liste_field_titre($arrayfields['e.date_delivery']['label'], $_SERVER["PHP_SELF"],"e.date_delivery","",$param, 'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['l.ref']['checked'])) print_liste_field_titre($arrayfields['l.ref']['label'], $_SERVER["PHP_SELF"],"l.ref","",$param, '',$sortfield,$sortorder); + if (! empty($arrayfields['l.date_delivery']['checked'])) print_liste_field_titre($arrayfields['l.date_delivery']['label'], $_SERVER["PHP_SELF"],"l.date_delivery","",$param, 'align="center"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['e.datec']['checked'])) print_liste_field_titre($arrayfields['e.datec']['label'],$_SERVER["PHP_SELF"],"e.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['e.tms']['checked'])) print_liste_field_titre($arrayfields['e.tms']['label'],$_SERVER["PHP_SELF"],"e.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['e.fk_statut']['checked'])) print_liste_field_titre($arrayfields['e.fk_statut']['label'],$_SERVER["PHP_SELF"],"e.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['l.fk_statut']['checked'])) print_liste_field_titre($arrayfields['l.fk_statut']['label'], $_SERVER["PHP_SELF"],"l.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $i=0; $var=true; $totalarray=array(); diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 21348a5c948..8de637df3cc 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -507,8 +507,11 @@ if ($step == 3 && $datatoimport) print $objimport->array_import_label[0]; print ''; - print '

    '; - print ''.$langs->trans("InformationOnSourceFile").''; + print ''; + + print '
    '; + + print ''.$langs->trans("InformationOnSourceFile").'
    '; print ''; //print ''; @@ -752,8 +755,11 @@ if ($step == 4 && $datatoimport) print $objimport->array_import_label[0]; print ''; - print '
    '.$langs->trans("InformationOnSourceFile").'

    '; - print ''.$langs->trans("InformationOnSourceFile").''; + print ''; + + print '
    '; + + print ''.$langs->trans("InformationOnSourceFile").'
    '; print ''; //print ''; @@ -1219,8 +1225,11 @@ if ($step == 5 && $datatoimport) print $objimport->array_import_label[0]; print ''; - print '
    '.$langs->trans("InformationOnSourceFile").'

    '; - print ''.$langs->trans("InformationOnSourceFile").''; + print ''; + + print '
    '; + + print ''.$langs->trans("InformationOnSourceFile").'
    '; print ''; //print ''; @@ -1261,38 +1270,33 @@ if ($step == 5 && $datatoimport) // Do not import first lines print ''; - - // Do not import end lines - print ''; - + print '
    '.$langs->trans("InformationOnSourceFile").'
    '; - print $langs->trans("ImportFromLine"); + print $langs->trans("ImportFromToLine"); print ''; if ($action=='launchsimu') { - print ''; + print ''; print ''; print '   '.$langs->trans("Modify").''; } else { - print ''; + print ''; print $form->textwithpicto("", $langs->trans("SetThisValueTo2ToExcludeFirstLine")); } - print '
    '; - print $langs->trans("EndAtLineNb"); - print ''; + print ' - '; if ($action=='launchsimu') { - print ''; + print ''; print ''; print '   '.$langs->trans("Modify").''; } else { - print ''; + print ''; print $form->textwithpicto("", $langs->trans("KeepEmptyToGoToEndOfFile")); } print '
    '; print $langs->trans("KeysToUseForUpdates"); print ''; @@ -1304,7 +1308,7 @@ if ($step == 5 && $datatoimport) print '   '.$langs->trans("Modify").''; } else { print $form->multiselectarray('updatekeys', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%'); - print $form->textwithpicto("", $langs->trans("SelectColumnsOfYourFileForUpdateAttempt")); + print $form->textwithpicto("", $langs->trans("SelectPrimaryColumnsForUpdateAttempt")); } /*echo '
    ';
     	print_r($objimport->array_import_updatekeys);
    @@ -1315,7 +1319,7 @@ if ($step == 5 && $datatoimport)
     
     	print '
    '; - print ''.$langs->trans("InformationOnTargetTables").''; + print ''.$langs->trans("InformationOnTargetTables").'
    '; print ''; //print ''; @@ -1643,8 +1647,11 @@ if ($step == 6 && $datatoimport) print $objimport->array_import_label[0]; print ''; - print '
    '.$langs->trans("InformationOnTargetTables").'

    '; - print ''.$langs->trans("InformationOnSourceFile").''; + print '
    '; + + print '
    '; + + print ''.$langs->trans("InformationOnSourceFile").'
    '; print ''; //print ''; @@ -1701,7 +1708,7 @@ if ($step == 6 && $datatoimport) print '
    '; - print ''.$langs->trans("InformationOnTargetTables").''; + print ''.$langs->trans("InformationOnTargetTables").'
    '; print '
    '.$langs->trans("InformationOnSourceFile").'
    '; //print ''; diff --git a/htdocs/langs/en_US/exports.lang b/htdocs/langs/en_US/exports.lang index 47b6fde9840..acbf407fd62 100644 --- a/htdocs/langs/en_US/exports.lang +++ b/htdocs/langs/en_US/exports.lang @@ -113,8 +113,10 @@ ExportDateFilter=YYYY, YYYYMM, YYYYMMDD : filters by one year/month/day
    YYYY+ ExportNumericFilter=NNNNN filters by one value
    NNNNN+NNNNN filters over a range of values
    < NNNNN filters by lower values
    > NNNNN filters by higher values ImportFromLine=Import starting from line number EndAtLineNb=End at line number +ImportFromToLine=Import line numbers (from - to) SetThisValueTo2ToExcludeFirstLine=For example, set this value to 3 to exclude the 2 first lines 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 ## filters SelectFilterFields=If you want to filter on some values, just input values here. FilteredFields=Filtered fields diff --git a/htdocs/product/popuprop.php b/htdocs/product/popuprop.php index 52ed6c9c969..5320e637316 100644 --- a/htdocs/product/popuprop.php +++ b/htdocs/product/popuprop.php @@ -103,7 +103,7 @@ $head[$h][1] = $title; $head[$h][2] = 'popularityprop'; $h++; -dol_fiche_head($head,'popularityprop',$langs->trans("Statistics")); +dol_fiche_head($head, 'popularityprop', $langs->trans("Statistics"), -1); // Array of liens to show @@ -136,7 +136,6 @@ if ($resql) $num = $db->num_rows($resql); $i = 0; - $var=True; while ($i < $num) { $objp = $db->fetch_object($resql); @@ -166,7 +165,6 @@ print_liste_field_titre($langs->trans('Label'), $_SERVER["PHP_SELF"], 'p.label', print_liste_field_titre($langs->trans('NbOfQtyInProposals'), $_SERVER["PHP_SELF"], 'c', '', $param, 'align="right"', $sortfield, $sortorder); print "\n"; -$var=True; foreach($infoprod as $prodid => $vals) { // Multilangs @@ -186,8 +184,7 @@ foreach($infoprod as $prodid => $vals) } } - $var=!$var; - print ""; + print ""; print ''; + $out.= "\n"; } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 271f87ab4a0..99b27c20822 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -219,10 +219,10 @@ class Form if (empty($notabletag)) $ret.=''; if (empty($notabletag)) $ret.=''; if (empty($notabletag)) $ret.='
    '.$langs->trans("InformationOnTargetTables").'
    '; if ($vals['type'] == 1) print img_object($langs->trans("ShowService"),"service"); else print img_object($langs->trans("ShowProduct"),"product"); diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index 13bc0fef186..8e3d1aa1985 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -121,10 +121,7 @@ $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as s on p.rowid = s.fk_produc if ($search_categ) $sql.= ", ".MAIN_DB_PREFIX."categorie_product as cp"; $sql.= " WHERE p.entity IN (".getEntity('product', 1).")"; if ($search_categ) $sql.= " AND p.rowid = cp.fk_product"; // Join for the needed table to filter by categ -if ($sall) -{ - $sql.= " AND (p.ref LIKE '%".$db->escape($sall)."%' OR p.label LIKE '%".$db->escape($sall)."%' OR p.description LIKE '%".$db->escape($sall)."%' OR p.note LIKE '%".$db->escape($sall)."%')"; -} +if ($sall) $sql.=natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $all); // if the type is not 1, we show all products (type = 0,2,3) if (dol_strlen($type)) { @@ -137,41 +134,32 @@ if (dol_strlen($type)) $sql.= " AND p.fk_product_type <> '1'"; } } -if ($sref) $sql.= " AND p.ref LIKE '%".$sref."%'"; -if ($sbarcode) $sql.= " AND p.barcode LIKE '%".$sbarcode."%'"; -if ($snom) $sql.= " AND p.label LIKE '%".$db->escape($snom)."%'"; -if (! empty($tosell)) -{ - $sql.= " AND p.tosell = ".$tosell; -} -if (! empty($tobuy)) -{ - $sql.= " AND p.tobuy = ".$tobuy; -} -if (! empty($canvas)) -{ - $sql.= " AND p.canvas = '".$db->escape($canvas)."'"; -} -if($catid) -{ - $sql.= " AND cp.fk_categorie = ".$catid; -} -if ($fourn_id > 0) -{ - $sql.= " AND p.rowid = pf.fk_product AND pf.fk_soc = ".$fourn_id; -} +if ($sref) $sql.= natural_search('p.ref', $ref); +if ($sbarcode) $sql.= natural_search('p.barcode', $sbarcode); +if ($snom) $sql.= natural_search('p.label', $snom); +if (! empty($tosell)) $sql.= " AND p.tosell = ".$tosell; +if (! empty($tobuy)) $sql.= " AND p.tobuy = ".$tobuy; +if (! empty($canvas)) $sql.= " AND p.canvas = '".$db->escape($canvas)."'"; +if($catid) $sql.= " AND cp.fk_categorie = ".$catid; +if ($fourn_id > 0) $sql.= " AND p.rowid = pf.fk_product AND pf.fk_soc = ".$fourn_id; // Insert categ filter -if ($search_categ) -{ - $sql .= " AND cp.fk_categorie = ".$db->escape($search_categ); -} +if ($search_categ) $sql .= " AND cp.fk_categorie = ".$db->escape($search_categ); $sql.= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,"; $sql.= " p.fk_product_type, p.tms, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock"; -if ($toolowstock) $sql.= " HAVING SUM(".$db->ifsql('s.reel IS NULL', '0', 's.reel').") < p.seuil_stock_alerte"; // Not used yet +if ($toolowstock) $sql.= " HAVING SUM(".$db->ifsql('s.reel IS NULL', '0', 's.reel').") < p.seuil_stock_alerte"; $sql.= $db->order($sortfield,$sortorder); -$sql.= $db->plimit($limit + 1, $offset); -$resql = $db->query($sql); +// 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) { $num = $db->num_rows($resql); @@ -197,31 +185,31 @@ if ($resql) llxHeader("", $texte, $helpurl); - if ($sref || $snom || $sall || GETPOST('search')) - { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, 'title_products'); - } - else - { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":"").(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, 'title_products'); - } - - if (! empty($catid)) - { - print "
    "; - $c = new Categorie($db); - $c->fetch($catid); - $ways = $c->print_all_ways(' > ','product/reassort.php'); - print " > ".$ways[0]."
    \n"; - print "

    "; - } - print ''; print ''; print ''; print ''; print ''; + if ($sref || $snom || $sall || GETPOST('search')) + { + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit); + } + else + { + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":"").(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit); + } + + if (! empty($catid)) + { + print "
    "; + $c = new Categorie($db); + $c->fetch($catid); + $ways = $c->print_all_ways(' > ','product/reassort.php'); + print " > ".$ways[0]."
    \n"; + print "

    "; + } + // Filter on categories $moreforfilter=''; if (! empty($conf->categorie->enabled)) @@ -264,32 +252,8 @@ if ($resql) print '
    '; print ''; - // Lignes des titres - print ""; - print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label",$param,"","",$sortfield,$sortorder); - if (! empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans("Duration"), $_SERVER["PHP_SELF"], "p.duration",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("StockLimit"), $_SERVER["PHP_SELF"], "p.seuil_stock_alerte",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DesiredStock"), $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stock_physique",$param,"",'align="right"',$sortfield,$sortorder); - // Details per warehouse - if (! empty($conf->global->STOCK_DETAIL_ON_WAREHOUSE)) // TODO This should be moved into the selection of fields on page product/list (page product/stock will be removed and replaced with product/list with its own context) - { - if ($nb_warehouse>1) { - foreach($warehouses_list as &$wh) { - print_liste_field_titre($wh['label'], '', '','','','align="right"'); - } - - } - } - if ($virtualdiffersfromphysical) print_liste_field_titre($langs->trans("VirtualStock"),$_SERVER["PHP_SELF"], "",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre(''); - print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"], "p.tobuy",$param,"",'align="right"',$sortfield,$sortorder); - print "\n"; - // Lignes des champs de filtre - print ''; + print ''; print ''; @@ -310,24 +274,47 @@ if ($resql) if ($virtualdiffersfromphysical) print ''; print ''; print ''; + print ''; print ''; print ''; - $var=True; + // Lignes des titres + print ""; + print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label",$param,"","",$sortfield,$sortorder); + if (! empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans("Duration"), $_SERVER["PHP_SELF"], "p.duration",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("StockLimit"), $_SERVER["PHP_SELF"], "p.seuil_stock_alerte",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DesiredStock"), $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stock_physique",$param,"",'align="right"',$sortfield,$sortorder); + // Details per warehouse + if (! empty($conf->global->STOCK_DETAIL_ON_WAREHOUSE)) // TODO This should be moved into the selection of fields on page product/list (page product/stock will be removed and replaced with product/list with its own context) + { + if ($nb_warehouse>1) { + foreach($warehouses_list as &$wh) { + print_liste_field_titre($wh['label'], '', '','','','align="right"'); + } + + } + } + if ($virtualdiffersfromphysical) print_liste_field_titre($langs->trans("VirtualStock"),$_SERVER["PHP_SELF"], "",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"], "p.tobuy",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + while ($i < min($num,$limit)) { $objp = $db->fetch_object($resql); - $var=!$var; - print ''; + print ''; @@ -376,27 +363,17 @@ if ($resql) } print ''; print ''; - print ''; - print "\n"; + print ''; + print ''; + print "\n"; $i++; } print "
    '; print ''; print '   '; $searchpitco=$form->showFilterAndCheckAddButtons(0); print $searchpitco; print '
    '; - + print '
    '; $product=new Product($db); $product->fetch($objp->rowid); $product->load_stock(); - print $product->getNomUrl(1,'',16); //if ($objp->stock_theorique < $objp->seuil_stock_alerte) print ' '.img_warning($langs->trans("StockTooLow")); print ''.$langs->trans("Movements").''.$product->LibStatut($objp->statut,5,0).''.$product->LibStatut($objp->tobuy,5,1).'
    '.$product->LibStatut($objp->tobuy,5,1).'
    "; print '
    '; + print ''; - if ($num > $conf->liste_limit) - { - if ($sref || $snom || $sall || GETPOST('search')) - { - print_barre_liste('', $page, "reassort.php", "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, ''); - } - else - { - print_barre_liste('', $page, "reassort.php", "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":"")."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, ''); - } - } - $db->free($resql); } diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php index 01285f09417..af1c6f2ec15 100644 --- a/htdocs/product/reassortlot.php +++ b/htdocs/product/reassortlot.php @@ -160,15 +160,17 @@ $sql.= " pb.batch, pb.eatby, pb.sellby,"; $sql.= " pl.eatby, pl.sellby"; if ($toolowstock) $sql.= " HAVING SUM(".$db->ifsql('ps.reel IS NULL', '0', 'ps.reel').") < p.seuil_stock_alerte"; // Not used yet $sql.= $db->order($sortfield,$sortorder); + $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); +$sql.= $db->plimit($limit + 1, $offset); + +$resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); @@ -194,13 +196,19 @@ if ($resql) llxHeader("",$title,$helpurl,$texte); + print '
    '; + print ''; + print ''; + print ''; + print ''; + if ($sref || $snom || $sall || GETPOST('search')) { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy, $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products'); + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy, $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit); } else { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":""), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products'); + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":""), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit); } if (! empty($catid)) @@ -213,12 +221,6 @@ if ($resql) print "
    "; } - print ''; - print ''; - print ''; - print ''; - print ''; - // Filter on categories $moreforfilter=''; if (! empty($conf->categorie->enabled)) @@ -255,26 +257,8 @@ if ($resql) print '
    '; print ''; - // Lignes des titres - print ""; - print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label",$param,"","",$sortfield,$sortorder); - if (! empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans("Duration"), $_SERVER["PHP_SELF"], "p.duration",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Warehouse"), $_SERVER["PHP_SELF"], "e.label",$param,"",'',$sortfield,$sortorder); - //print_liste_field_titre($langs->trans("DesiredStock"), $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Batch"), $_SERVER["PHP_SELF"], "pb.batch",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("EatByDate"), $_SERVER["PHP_SELF"], "pb.eatby",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("SellByDate"), $_SERVER["PHP_SELF"], "pb.sellby",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stock_physique",$param,"",'align="right"',$sortfield,$sortorder); - // TODO Add info of running suppliers/customers orders - //print_liste_field_titre($langs->trans("TheoreticalStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre(''); - print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"], "p.tobuy","",$param,'align="right"',$sortfield,$sortorder); - print "\n"; - // Lignes des champs de filtre - print ''; + print ''; print ''; @@ -294,16 +278,35 @@ if ($resql) print ''; print ''; print ''; + print ''; print ''; print ''; + // Lignes des titres + print ""; + print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label",$param,"","",$sortfield,$sortorder); + if (! empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans("Duration"), $_SERVER["PHP_SELF"], "p.duration",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Warehouse"), $_SERVER["PHP_SELF"], "e.label",$param,"",'',$sortfield,$sortorder); + //print_liste_field_titre($langs->trans("DesiredStock"), $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Batch"), $_SERVER["PHP_SELF"], "pb.batch",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("EatByDate"), $_SERVER["PHP_SELF"], "pb.eatby",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("SellByDate"), $_SERVER["PHP_SELF"], "pb.sellby",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stock_physique",$param,"",'align="right"',$sortfield,$sortorder); + // TODO Add info of running suppliers/customers orders + //print_liste_field_titre($langs->trans("TheoreticalStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"], "p.tobuy","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + $product_static=new Product($db); $warehousetmp=new Entrepot($db); - $var=True; while ($i < min($num,$limit)) { $objp = $db->fetch_object($resql); @@ -337,9 +340,7 @@ if ($resql) $warehousetmp->label=$objp->warehouse_ref; $warehousetmp->fk_parent=$objp->warehouse_parent; - $var=!$var; - - print ''; + print ''; // Ref print ''; print ''; print ''; + print ''; print "\n"; $i++; } diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 0bfd9048352..f31b7c9eb6e 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -149,18 +149,8 @@ if ($result) print '
    '; print '
    '; print ''; print '    '; $searchpitco=$form->showFilterAndCheckAddButtons(0); print $searchpitco; print '
    '; @@ -380,6 +381,7 @@ if ($resql) print ''.$langs->trans("Movements").''.$product_static->LibStatut($objp->statut,5,0).''.$product_static->LibStatut($objp->tobuy,5,1).'
    '."\n"; - print ""; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"], "e.label","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("LocationSummary"),$_SERVER["PHP_SELF"], "e.lieu","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stockqty",'',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("EstimatedStockValue"), $_SERVER["PHP_SELF"], "estimatedvalue",'',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("EstimatedStockValueSell"), $_SERVER["PHP_SELF"], "",'',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"], "e.statut",'',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'',$param,'',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Lignes des champs de filtre - print ''; + print ''; print ''; print ''; + + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"], "e.label","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("LocationSummary"),$_SERVER["PHP_SELF"], "e.lieu","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PhysicalStock"), $_SERVER["PHP_SELF"], "stockqty",'',$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("EstimatedStockValue"), $_SERVER["PHP_SELF"], "estimatedvalue",'',$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("EstimatedStockValueSell"), $_SERVER["PHP_SELF"], "",'',$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"], "e.statut",'',$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'',$param,'',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; if ($num) { diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index 2910103e380..58bb6f6a3cb 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -236,8 +236,7 @@ if ($search_fk_user_creat) $sql.= natural_search("fk_user_creat",$search_fk_user if ($search_fk_user_modif) $sql.= natural_search("fk_user_modif",$search_fk_user_modif); if ($search_import_key) $sql.= natural_search("import_key",$search_import_key); - -if ($sall) $sql.= natural_search(array_keys($fieldstosearchall), $sall); +if ($sall) $sql.= natural_search(array_keys($fieldstosearchall), $sall); // Add where from extra fields foreach ($search_array_options as $key => $val) { @@ -342,6 +341,69 @@ if ($resql) print '
    '; print '
    '; print ''; @@ -183,6 +173,16 @@ if ($result) print '
    '."\n"; + // Fields title search + print ''; + if (! empty($arrayfields['t.entity']['checked'])) print ''; + if (! empty($arrayfields['t.batch']['checked'])) print ''; + if (! empty($arrayfields['t.fk_product']['checked'])) print ''; + if (! empty($arrayfields['t.eatby']['checked'])) print ''; + if (! empty($arrayfields['t.sellby']['checked'])) print ''; + if (! empty($arrayfields['t.fk_user_creat']['checked'])) print ''; + if (! empty($arrayfields['t.fk_user_modif']['checked'])) print ''; + if (! empty($arrayfields['t.import_key']['checked'])) print ''; + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print ''; + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['t.datec']['checked'])) + { + // Date creation + print ''; + } + if (! empty($arrayfields['t.tms']['checked'])) + { + // Date modification + print ''; + } + /*if (! empty($arrayfields['u.statut']['checked'])) + { + // Status + print ''; + }*/ + // Action column + print ''; + print ''."\n"; + // Fields title print ''; if (! empty($arrayfields['t.entity']['checked'])) print_liste_field_titre($arrayfields['t.entity']['label'],$_SERVER['PHP_SELF'],'t.entity','',$param,'',$sortfield,$sortorder); @@ -374,69 +436,6 @@ if ($resql) print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); print ''."\n"; - // Fields title search - print ''; - if (! empty($arrayfields['t.entity']['checked'])) print ''; - if (! empty($arrayfields['t.batch']['checked'])) print ''; - if (! empty($arrayfields['t.fk_product']['checked'])) print ''; - if (! empty($arrayfields['t.eatby']['checked'])) print ''; - if (! empty($arrayfields['t.sellby']['checked'])) print ''; - if (! empty($arrayfields['t.fk_user_creat']['checked'])) print ''; - if (! empty($arrayfields['t.fk_user_modif']['checked'])) print ''; - if (! empty($arrayfields['t.import_key']['checked'])) print ''; - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } - } - // Fields from hook - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['t.datec']['checked'])) - { - // Date creation - print ''; - } - if (! empty($arrayfields['t.tms']['checked'])) - { - // Date modification - print ''; - } - /*if (! empty($arrayfields['u.statut']['checked'])) - { - // Status - print ''; - }*/ - // Action column - print ''; - print ''."\n"; - $productlot = new Productlot($db); $i=0; diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 9185406a6ef..ded0feec881 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -403,7 +403,7 @@ $head[1][2] = 'replenishorders'; print load_fiche_titre($langs->trans('Replenishment'), '', 'title_generic.png'); -dol_fiche_head($head, 'replenish', '', 0, ''); +dol_fiche_head($head, 'replenish', '', -1, ''); print $langs->trans("ReplenishmentStatusDesc").'
    '."\n"; if ($usevirtualstock == 1) @@ -501,22 +501,8 @@ print '' ''. ''; -// Lines of title -print ''; -print_liste_field_titre('', $_SERVER["PHP_SELF"], ''); -print_liste_field_titre($langs->trans('Ref'), $_SERVER["PHP_SELF"], 'p.ref', $param, '', '', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('Label'), $_SERVER["PHP_SELF"], 'p.label', $param, '', '', $sortfield, $sortorder); -if (!empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans('Duration'), $_SERVER["PHP_SELF"], 'p.duration', $param, '', 'align="center"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('DesiredStock'), $_SERVER["PHP_SELF"], 'p.desiredstock', $param, '', 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('StockLimitShort'), $_SERVER["PHP_SELF"], 'p.seuil_stock_alerte', $param, '', 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($stocklabel, $_SERVER["PHP_SELF"], 'stock_physique', $param, '', 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('Ordered'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('StockToBuy'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('SupplierRef'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); -print "\n"; - // Lignes des champs de filtre -print ''; +print ''; print ''; print ''; print ''; @@ -532,6 +518,20 @@ print $searchpitco; print ''; print ''; +// Lines of title +print ''; +print_liste_field_titre('', $_SERVER["PHP_SELF"], ''); +print_liste_field_titre($langs->trans('Ref'), $_SERVER["PHP_SELF"], 'p.ref', $param, '', '', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('Label'), $_SERVER["PHP_SELF"], 'p.label', $param, '', '', $sortfield, $sortorder); +if (!empty($conf->service->enabled) && $type == 1) print_liste_field_titre($langs->trans('Duration'), $_SERVER["PHP_SELF"], 'p.duration', $param, '', 'align="center"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('DesiredStock'), $_SERVER["PHP_SELF"], 'p.desiredstock', $param, '', 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('StockLimitShort'), $_SERVER["PHP_SELF"], 'p.seuil_stock_alerte', $param, '', 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($stocklabel, $_SERVER["PHP_SELF"], 'stock_physique', $param, '', 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('Ordered'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('StockToBuy'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans('SupplierRef'), $_SERVER["PHP_SELF"], '', $param, '', 'align="right"', $sortfield, $sortorder); +print "\n"; + $prod = new Product($db); $var = True; diff --git a/htdocs/product/stock/replenishorders.php b/htdocs/product/stock/replenishorders.php index 4986d7c524d..607e28165ed 100644 --- a/htdocs/product/stock/replenishorders.php +++ b/htdocs/product/stock/replenishorders.php @@ -97,7 +97,7 @@ $head[1][0] = DOL_URL_ROOT.'/product/stock/replenishorders.php'; $head[1][1] = $texte; $head[1][2] = 'replenishorders'; -dol_fiche_head($head, 'replenishorders', '', 0, ''); +dol_fiche_head($head, 'replenishorders', '', -1, ''); $commandestatic = new CommandeFournisseur($db); @@ -160,71 +160,9 @@ if ($resql) print ''; - print '
    '; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $searchclass=''; + if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; + if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; + print ''; + } + print ''; + print ''; + print ''; + print $form->selectarray('search_statut', array('-1'=>'','0'=>$langs->trans('Disabled'),'1'=>$langs->trans('Enabled')),$search_statut); + print ''; + $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + print $searchpitco; + print '
    '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print ''; - print ''; - print ''; - print $form->selectarray('search_statut', array('-1'=>'','0'=>$langs->trans('Disabled'),'1'=>$langs->trans('Enabled')),$search_statut); - print ''; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); - print $searchpitco; - print '
     
    '. - ''; - print_liste_field_titre( - $langs->trans('Ref'), - $_SERVER['PHP_SELF'], - 'cf.ref', - '', - '', - '', - $sortfield, - $sortorder - ); - print_liste_field_titre( - $langs->trans('Company'), - $_SERVER['PHP_SELF'], - 's.nom', - '', - '', - '', - $sortfield, - $sortorder - ); - print_liste_field_titre( - $langs->trans('Author'), - $_SERVER['PHP_SELF'], - 'u.login', - '', - '', - '', - $sortfield, - $sortorder - ); - print_liste_field_titre( - $langs->trans('AmountTTC'), - $_SERVER['PHP_SELF'], - 'cf.total_ttc', - '', - '', - '', - $sortfield, - $sortorder - ); - print_liste_field_titre( - $langs->trans('OrderCreation'), - $_SERVER['PHP_SELF'], - 'cf.date_creation', - '', - '', - '', - $sortfield, - $sortorder - ); - print_liste_field_titre( - $langs->trans('Status'), - $_SERVER['PHP_SELF'], - 'cf.fk_statut', - '', - '', - 'align="right"', - $sortfield, - $sortorder - ); - print ''. + print '
    '; - ''. + print ''. ''. @@ -246,20 +184,81 @@ if ($resql) ''. ''; - $var = true; + print ''; + print_liste_field_titre( + $langs->trans('Ref'), + $_SERVER['PHP_SELF'], + 'cf.ref', + '', + '', + '', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('Company'), + $_SERVER['PHP_SELF'], + 's.nom', + '', + '', + '', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('Author'), + $_SERVER['PHP_SELF'], + 'u.login', + '', + '', + '', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('AmountTTC'), + $_SERVER['PHP_SELF'], + 'cf.total_ttc', + '', + '', + '', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('OrderCreation'), + $_SERVER['PHP_SELF'], + 'cf.date_creation', + '', + '', + '', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('Status'), + $_SERVER['PHP_SELF'], + 'cf.fk_statut', + '', + '', + 'align="right"', + $sortfield, + $sortorder + ); + print ''; + $userstatic = new User($db); while ($i < min($num,$conf->liste_limit)) { $obj = $db->fetch_object($resql); - $var = !$var; $showline = dolDispatchToDo($obj->rowid) && (!$sproduct || in_array($sproduct, getProducts($obj->rowid))); if ($showline) { $href = DOL_URL_ROOT . '/fourn/commande/card.php?id=' . $obj->rowid; - print ''. + print ''. // Ref ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; + if (! empty($conf->use_javascript_ajax)) { - $out.= '
    '. ''. '
    '. ''. diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index f7cb1c0bb5a..b43eb6450c1 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1948,7 +1948,7 @@ div.popuptab { padding-right: 5px; } div.tabsAction { - margin: 20px 0em 25px 0em; + margin: 20px 0em 20px 0em; padding: 0em 0em; text-align: right; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index f83d5df0d50..2a393dee748 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1941,7 +1941,7 @@ div.tabBar table.tableforservicepart2:last-child { } div.tabsAction { - margin: 20px 0em 25px 0em; + margin: 20px 0em 20px 0em; padding: 0em 0em; text-align: right; } From 18e1e5b7806c67938c03391c9fabfd54ea97286f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 15:54:48 +0200 Subject: [PATCH 049/233] NEW Add "depends on" and "required by "into module informations --- htdocs/admin/modulehelp.php | 18 ++++++++++-------- htdocs/core/modules/modHRM.class.php | 5 ++++- htdocs/langs/en_US/admin.lang | 2 ++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index 5b428443248..3fe6addea2d 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -1,12 +1,5 @@ - * Copyright (C) 2003 Jean-Louis Bergamo - * Copyright (C) 2004-2017 Laurent Destailleur - * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2011 Juanjo Menent - * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2015 Raphaël Doursenaud +/* Copyright (C) 2017 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -343,6 +336,15 @@ if ($mode == 'desc') if ($mode == 'feature') { + $text.='
    '.$langs->trans("DependsOn").': '; + if (count($objMod->requiredby)) $text.=join(',', $objMod->depends); + else $text.=$langs->trans("None"); + $text.='
    '.$langs->trans("RequiredBy").': '; + if (count($objMod->requiredby)) $text.=join(',', $objMod->requiredby); + else $text.=$langs->trans("None"); + + $text.='


    '; + $text.=''.$langs->trans("AddRemoveTabs").': '; if (isset($objMod->tabs) && is_array($objMod->tabs) && count($objMod->tabs)) { diff --git a/htdocs/core/modules/modHRM.class.php b/htdocs/core/modules/modHRM.class.php index 5cbb282424a..74a0107aedb 100644 --- a/htdocs/core/modules/modHRM.class.php +++ b/htdocs/core/modules/modHRM.class.php @@ -52,7 +52,10 @@ class modHRM extends DolibarrModules $this->const_name = 'MAIN_MODULE_' . strtoupper($this->name); $this->special = 0; - // $this->picto = ''; + // 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'; // define triggers $this->module_parts = array(); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index b3f43698843..1d16fefa959 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -425,6 +425,8 @@ Use3StepsApproval=By default, Purchase Orders need to be created and approved by UseDoubleApproval=Use a 3 steps approval when amount (without tax) is higher than... WarningPHPMail=WARNING: Some email providers (like Yahoo) does not allow you to send an email from another server than the Yahoo server if the email address used as a sender is your Yahoo email (like myemail@yahoo.com, myemail@yahoo.fr, ...). Your current setup use the server of the application to send email, so some recipients (the one compatible with the restrictive DMARC protocol), will ask Yahoo if they can accept your email and Yahoo will respond "no" because the server is not a server owned by Yahoo, so few of your sent Emails may not be accepted.
    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). ClickToShowDescription=Click to show description +DependsOn=This module need the module(s) +RequiredBy=This module is required by module(s) # Modules Module0Name=Users & groups Module0Desc=Users / Employees and Groups management From da1427ef5411a38ce9956965d8e785c4999653cb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Mar 2017 16:00:53 +0200 Subject: [PATCH 050/233] Work on 6.0 look and feel --- htdocs/comm/mailing/list.php | 29 +++++++------- htdocs/opensurvey/list.php | 52 ++++++++++++++---------- htdocs/resource/list.php | 39 +++++++++--------- htdocs/user/hierarchy.php | 16 ++++---- htdocs/user/index.php | 76 ++++++++++++++++++------------------ 5 files changed, 114 insertions(+), 98 deletions(-) diff --git a/htdocs/comm/mailing/list.php b/htdocs/comm/mailing/list.php index 2d6fae37b98..622783d7ca5 100644 --- a/htdocs/comm/mailing/list.php +++ b/htdocs/comm/mailing/list.php @@ -122,18 +122,7 @@ if ($result) print '
    '; print ''."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"m.rowid",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Title"),$_SERVER["PHP_SELF"],"m.titre",$param,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateCreation"),$_SERVER["PHP_SELF"],"m.date_creat",$param,"",'align="center"',$sortfield,$sortorder); - if (! $filteremail) print_liste_field_titre($langs->trans("NbOfEMails"),$_SERVER["PHP_SELF"],"m.nbemail",$param,"",'align="center"',$sortfield,$sortorder); - if (! $filteremail) print_liste_field_titre($langs->trans("DateLastSend"),$_SERVER["PHP_SELF"],"m.date_envoi",$param,"",'align="center"',$sortfield,$sortorder); - else print_liste_field_titre($langs->trans("DateSending"),$_SERVER["PHP_SELF"],"mc.date_envoi",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],($filteremail?"mc.statut":"m.statut"),$param,"",'align="right"',$sortfield,$sortorder); - print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - - print ''; + print ''; print ''; @@ -151,8 +140,18 @@ if ($result) print ''; print "\n"; - $var=True; - + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"m.rowid",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Title"),$_SERVER["PHP_SELF"],"m.titre",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateCreation"),$_SERVER["PHP_SELF"],"m.date_creat",$param,"",'align="center"',$sortfield,$sortorder); + if (! $filteremail) print_liste_field_titre($langs->trans("NbOfEMails"),$_SERVER["PHP_SELF"],"m.nbemail",$param,"",'align="center"',$sortfield,$sortorder); + if (! $filteremail) print_liste_field_titre($langs->trans("DateLastSend"),$_SERVER["PHP_SELF"],"m.date_envoi",$param,"",'align="center"',$sortfield,$sortorder); + else print_liste_field_titre($langs->trans("DateSending"),$_SERVER["PHP_SELF"],"mc.date_envoi",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],($filteremail?"mc.statut":"m.statut"),$param,"",'align="right"',$sortfield,$sortorder); + print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + + $email=new Mailing($db); while ($i < min($num,$limit)) @@ -161,7 +160,7 @@ if ($result) $var=!$var; - print ""; + print ""; print ''; print ''; diff --git a/htdocs/opensurvey/list.php b/htdocs/opensurvey/list.php index 9a95797736d..203602bde6e 100644 --- a/htdocs/opensurvey/list.php +++ b/htdocs/opensurvey/list.php @@ -33,8 +33,9 @@ if (!$user->rights->opensurvey->read) accessforbidden(); $action=GETPOST('action'); $id=GETPOST('id','alpha'); $numsondage= $id; -$surveytitle=GETPOST('surveytitle'); -$status=GETPOST('status'); +$search_ref = GETPOST('search_ref', 'alpha'); +$surveytitle=GETPOST('surveytitle', 'alpha'); +$status=GETPOST('status', 'int'); //if (! isset($_POST['status']) && ! isset($_GET['status'])) $status='opened'; // If filter unknown, we choose 'opened' $sortfield = GETPOST("sortfield",'alpha'); @@ -61,6 +62,7 @@ if (GETPOST('button_removefilter')) { $status=''; $surveytitle=''; + $search_ref=''; } @@ -93,19 +95,8 @@ $moreforfilter = ''; print '
    '; print '
    '; print ''; print '
    '; print img_object($langs->trans("ShowEMail"),"email").' '.stripslashes($obj->rowid).''.$obj->titre.'
    '."\n"; -print ''; -print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.id_sondage",$param,"","",$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Title"), $_SERVER["PHP_SELF"], "p.titre",$param,"","",$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Type")); -print_liste_field_titre($langs->trans("Author"), $_SERVER["PHP_SELF"], "u.".$fieldtosortuser,$param,"","",$sortfield,$sortorder); -print_liste_field_titre($langs->trans("NbOfVoters")); -print_liste_field_titre($langs->trans("ExpireDate"), $_SERVER["PHP_SELF"], "p.date_fin",$param,"",'align="center"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Status"), $_SERVER["PHP_SELF"], "p.status",$param,"",'align="center"',$sortfield,$sortorder); -print_liste_field_titre(''); -print ''."\n"; - -print ''; -print ''; +print ''; +print ''; print ''; print ''; print ''; @@ -119,6 +110,17 @@ print $searchpitco; print ''; print ''."\n"; +print ''; +print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.id_sondage", $param,"","",$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Title"), $_SERVER["PHP_SELF"], "p.titre", $param,"","",$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Type")); +print_liste_field_titre($langs->trans("Author"), $_SERVER["PHP_SELF"], "u.".$fieldtosortuser, $param,"","",$sortfield,$sortorder); +print_liste_field_titre($langs->trans("NbOfVoters"), $_SERVER["PHP_SELF"], "", $param,"",'align="right"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("ExpireDate"), $_SERVER["PHP_SELF"], "p.date_fin", $param,"",'align="center"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Status"), $_SERVER["PHP_SELF"], "p.status", $param,"",'align="center"',$sortfield,$sortorder); +print_liste_field_titre(''); +print ''."\n"; + $sql = "SELECT p.id_sondage, p.fk_user_creat, p.format, p.date_fin, p.status, p.titre, p.nom_admin,"; $sql.= " u.login, u.firstname, u.lastname"; $sql.= " FROM ".MAIN_DB_PREFIX."opensurvey_sondage as p"; @@ -133,9 +135,20 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $sql.= " WHERE p.entity = ".getEntity('survey',1); if ($status == 'expired') $sql.=" AND date_fin < '".$db->idate($now)."'"; if ($status == 'opened') $sql.=" AND date_fin >= '".$db->idate($now)."'"; -if ($surveytitle) $sql.=" AND titre LIKE '%".$db->escape($surveytitle)."%'"; +if ($search_ref) $sql.=natural_search("p.id_sondage", $search_ref); +if ($surveytitle) $sql.=natural_search("p.titre", $surveytitle); + $sql.= $db->order($sortfield,$sortorder); -$sql.= $db->plimit($conf->liste_limit+1, $offset); + +// 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); @@ -159,8 +172,7 @@ while ($i < min($num,$limit)) $opensurvey_static->id=$obj->id_sondage; $opensurvey_static->status=$obj->status; - $var=!$var; - print ''; + print ''; print ''; - print''."\n"; + print''."\n"; print ''; print ''; - // Activate preview tab on element card - if (class_exists("Imagick")) - { - print ''; - print ''; - print ''; - } - // First day for weeks print ''; print ""; - // Activate preview tab on element card - if (class_exists("Imagick")) - { - - print '"; - print ''; - print ""; - } - // First day for weeks print '
    '; print ''.img_picto('','object_opensurvey').' '.$obj->id_sondage.''; print ''.dol_htmlentities($obj->titre).''; @@ -184,7 +196,7 @@ while ($i < min($num,$limit)) print ''.$nbuser.''.$nbuser.''.dol_print_date($db->jdate($obj->date_fin),'day'); if ($db->jdate($obj->date_fin) < time()) { print ' ('.$langs->trans("Expired").')'; } diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 2c97b68f7ed..5a3d5390bb0 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -194,25 +194,7 @@ $moreforfilter = ''; print '
    '; print ''."\n"; -print ''; -if (! empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'],$_SERVER["PHP_SELF"],"t.ref","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['ty.label']['checked'])) print_liste_field_titre($arrayfields['ty.label']['label'],$_SERVER["PHP_SELF"],"t.code","",$param,"",$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; - -print ''; +print ''; if (! empty($arrayfields['t.ref']['checked'])) { print ''; print "\n"; +print ''; +if (! empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'],$_SERVER["PHP_SELF"],"t.ref","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['ty.label']['checked'])) print_liste_field_titre($arrayfields['ty.label']['label'],$_SERVER["PHP_SELF"],"t.code","",$param,"",$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; + + if ($ret) { foreach ($object->lines as $resource) diff --git a/htdocs/user/hierarchy.php b/htdocs/user/hierarchy.php index 888d4ca5317..734b1aa0d14 100644 --- a/htdocs/user/hierarchy.php +++ b/htdocs/user/hierarchy.php @@ -144,14 +144,8 @@ print ''; -print ''; -print_liste_field_titre($langs->trans("HierarchicView")); -print_liste_field_titre('',$_SERVER['PHP_SELF'],"",'',"",'align="center"'); -print_liste_field_titre($langs->trans("Status"),$_SERVER['PHP_SELF'],"",'',"",'align="right"'); -print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','','','','maxwidthsearch '); -print ''; -print ''; +print ''; print ''; print ''; // Status @@ -164,6 +158,14 @@ print $searchpitco; print ''; print ''; +print ''; +print_liste_field_titre($langs->trans("HierarchicView")); +print_liste_field_titre('',$_SERVER['PHP_SELF'],"",'',"",'align="center"'); +print_liste_field_titre($langs->trans("Status"),$_SERVER['PHP_SELF'],"",'',"",'align="right"'); +print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','','','','maxwidthsearch '); +print ''; + + $nbofentries=(count($data) - 1); if ($nbofentries > 0) diff --git a/htdocs/user/index.php b/htdocs/user/index.php index 60defe580a7..3e1da6a7431 100644 --- a/htdocs/user/index.php +++ b/htdocs/user/index.php @@ -174,6 +174,7 @@ if (empty($reshook)) * View */ +$user2=new User($db); $buttonviewhierarchy=''; @@ -315,43 +316,8 @@ $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfiel print '
    '; print '
    '; @@ -255,6 +237,25 @@ print $searchpitco; print '
      
    '."\n"; -print ''; -if (! empty($arrayfields['u.login']['checked'])) print_liste_field_titre($langs->trans("Login"),$_SERVER['PHP_SELF'],"u.login",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.lastname']['checked'])) print_liste_field_titre($langs->trans("Lastname"),$_SERVER['PHP_SELF'],"u.lastname",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.firstname']['checked'])) print_liste_field_titre($langs->trans("FirstName"),$_SERVER['PHP_SELF'],"u.firstname",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.gender']['checked'])) print_liste_field_titre($langs->trans("Gender"),$_SERVER['PHP_SELF'],"u.gender",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.employee']['checked'])) print_liste_field_titre($langs->trans("Employee"),$_SERVER['PHP_SELF'],"u.employee",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.accountancy_code']['checked'])) print_liste_field_titre($langs->trans("AccountancyCode"),$_SERVER['PHP_SELF'],"u.accountancy_code",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.email']['checked'])) print_liste_field_titre($langs->trans("EMail"),$_SERVER['PHP_SELF'],"u.email",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.fk_soc']['checked'])) print_liste_field_titre($langs->trans("Company"),$_SERVER['PHP_SELF'],"u.fk_soc",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.entity']['checked'])) print_liste_field_titre($langs->trans("Entity"),$_SERVER['PHP_SELF'],"u.entity",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.fk_user']['checked'])) print_liste_field_titre($langs->trans("HierarchicalResponsible"),$_SERVER['PHP_SELF'],"u.fk_user",$param,"","",$sortfield,$sortorder); -if (! empty($arrayfields['u.datelastlogin']['checked'])) print_liste_field_titre($langs->trans("LastConnexion"),$_SERVER['PHP_SELF'],"u.datelastlogin",$param,"",'align="center"',$sortfield,$sortorder); -if (! empty($arrayfields['u.datepreviouslogin']['checked'])) print_liste_field_titre($langs->trans("PreviousConnexion"),$_SERVER['PHP_SELF'],"u.datepreviouslogin",$param,"",'align="center"',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['u.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"u.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['u.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"u.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['u.statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"u.statut","",$param,'align="center"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; - // Search bar -print ''; +print ''; if (! empty($arrayfields['u.login']['checked'])) { print ''; @@ -459,7 +425,43 @@ print ''; print "\n"; -$user2=new User($db); + +print ''; +if (! empty($arrayfields['u.login']['checked'])) print_liste_field_titre($langs->trans("Login"),$_SERVER['PHP_SELF'],"u.login",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.lastname']['checked'])) print_liste_field_titre($langs->trans("Lastname"),$_SERVER['PHP_SELF'],"u.lastname",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.firstname']['checked'])) print_liste_field_titre($langs->trans("FirstName"),$_SERVER['PHP_SELF'],"u.firstname",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.gender']['checked'])) print_liste_field_titre($langs->trans("Gender"),$_SERVER['PHP_SELF'],"u.gender",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.employee']['checked'])) print_liste_field_titre($langs->trans("Employee"),$_SERVER['PHP_SELF'],"u.employee",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.accountancy_code']['checked'])) print_liste_field_titre($langs->trans("AccountancyCode"),$_SERVER['PHP_SELF'],"u.accountancy_code",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.email']['checked'])) print_liste_field_titre($langs->trans("EMail"),$_SERVER['PHP_SELF'],"u.email",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.fk_soc']['checked'])) print_liste_field_titre($langs->trans("Company"),$_SERVER['PHP_SELF'],"u.fk_soc",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.entity']['checked'])) print_liste_field_titre($langs->trans("Entity"),$_SERVER['PHP_SELF'],"u.entity",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.fk_user']['checked'])) print_liste_field_titre($langs->trans("HierarchicalResponsible"),$_SERVER['PHP_SELF'],"u.fk_user",$param,"","",$sortfield,$sortorder); +if (! empty($arrayfields['u.datelastlogin']['checked'])) print_liste_field_titre($langs->trans("LastConnexion"),$_SERVER['PHP_SELF'],"u.datelastlogin",$param,"",'align="center"',$sortfield,$sortorder); +if (! empty($arrayfields['u.datepreviouslogin']['checked'])) print_liste_field_titre($langs->trans("PreviousConnexion"),$_SERVER['PHP_SELF'],"u.datepreviouslogin",$param,"",'align="center"',$sortfield,$sortorder); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } +} +// Hook fields +$parameters=array('arrayfields'=>$arrayfields); +$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (! empty($arrayfields['u.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"u.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['u.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"u.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['u.statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"u.statut","",$param,'align="center"',$sortfield,$sortorder); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; + + $i = 0; while ($i < min($num,$limit)) From 979bcd3a9b225c7e7e6b672a4fb8b6ea390f2240 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Mar 2017 11:39:12 +0200 Subject: [PATCH 051/233] NEW Can add a background image on login page --- htdocs/admin/company.php | 40 ++-- htdocs/admin/ihm.php | 181 ++++++++++++++++-- htdocs/cashdesk/index.php | 2 +- htdocs/cashdesk/tpl/ticket.tpl.php | 2 +- htdocs/core/lib/files.lib.php | 2 +- htdocs/core/lib/security2.lib.php | 4 +- htdocs/core/menus/standard/auguria.lib.php | 2 +- htdocs/core/menus/standard/eldy.lib.php | 4 +- htdocs/core/tpl/login.tpl.php | 28 ++- htdocs/core/tpl/passwordforgotten.tpl.php | 26 +-- .../mycompany/background_computer_coffee.jpg | Bin 0 -> 385205 bytes htdocs/langs/en_US/admin.lang | 2 + htdocs/margin/tabs/productMargins.php | 2 +- htdocs/opensurvey/fonctions.php | 2 +- htdocs/product/document.php | 3 +- htdocs/product/fournisseurs.php | 5 +- htdocs/product/info.php | 3 +- htdocs/product/note.php | 2 +- htdocs/product/price.php | 3 +- htdocs/product/stock/product.php | 3 +- htdocs/public/members/new.php | 4 +- htdocs/public/paybox/newpayment.php | 4 +- htdocs/public/paypal/newpayment.php | 4 +- htdocs/theme/eldy/style.css.php | 17 +- htdocs/theme/md/style.css.php | 16 +- htdocs/user/passwordforgotten.php | 4 +- htdocs/viewimage.php | 4 +- 27 files changed, 270 insertions(+), 99 deletions(-) create mode 100644 htdocs/install/doctemplates/mycompany/background_computer_coffee.jpg diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 0f8efb23da0..d73f23d0ef7 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; @@ -51,8 +52,6 @@ $error=0; if ( ($action == 'update' && empty($_POST["cancel"])) || ($action == 'updateedit') ) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $tmparray=getCountry(GETPOST('country_id','int'),'all',$db,$langs,0); if (! empty($tmparray['id'])) { @@ -76,21 +75,23 @@ if ( ($action == 'update' && empty($_POST["cancel"])) dolibarr_set_const($db, "MAIN_INFO_SOCIETE_WEB",$_POST["web"],'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOTE",$_POST["note"],'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_GENCOD",$_POST["barcode"],'chaine',0,'',$conf->entity); - if ($_FILES["logo"]["tmp_name"]) + + $varforimage='logo'; $dirforimage=$conf->mycompany->dir_output.'/logos/'; + if ($_FILES[$varforimage]["tmp_name"]) { - if (preg_match('/([^\\/:]+)$/i',$_FILES["logo"]["name"],$reg)) + if (preg_match('/([^\\/:]+)$/i',$_FILES[$varforimage]["name"],$reg)) { $original_file=$reg[1]; $isimage=image_format_supported($original_file); if ($isimage >= 0) { - dol_syslog("Move file ".$_FILES["logo"]["tmp_name"]." to ".$conf->mycompany->dir_output.'/logos/'.$original_file); - if (! is_dir($conf->mycompany->dir_output.'/logos/')) + dol_syslog("Move file ".$_FILES[$varforimage]["tmp_name"]." to ".$dirforimage.$original_file); + if (! is_dir($dirforimage)) { - dol_mkdir($conf->mycompany->dir_output.'/logos/'); + dol_mkdir($dirforimage); } - $result=dol_move_uploaded_file($_FILES["logo"]["tmp_name"],$conf->mycompany->dir_output.'/logos/'.$original_file,1,0,$_FILES['logo']['error']); + $result=dol_move_uploaded_file($_FILES[$varforimage]["tmp_name"],$dirforimage.$original_file,1,0,$_FILES[$varforimage]['error']); if ($result > 0) { dolibarr_set_const($db, "MAIN_INFO_SOCIETE_LOGO",$original_file,'chaine',0,'',$conf->entity); @@ -101,8 +102,8 @@ if ( ($action == 'update' && empty($_POST["cancel"])) // Create thumbs //$object->addThumbs($newfile); // We can't use addThumbs here yet because we need name of generated thumbs to add them into constants. TODO Check if need such constants. We should be able to retreive value with get... - // Used on logon for example - $imgThumbSmall = vignette($conf->mycompany->dir_output.'/logos/'.$original_file, $maxwidthsmall, $maxheightsmall, '_small', $quality); + // Create small thumb, Used on logon for example + $imgThumbSmall = vignette($dirforimage.$original_file, $maxwidthsmall, $maxheightsmall, '_small', $quality); if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbSmall,$reg)) { $imgThumbSmall = $reg[1]; // Save only basename @@ -110,9 +111,8 @@ if ( ($action == 'update' && empty($_POST["cancel"])) } else dol_syslog($imgThumbSmall); - // Create mini thumbs for company (Ratio is near 16/9) - // Used on menu or for setup page for example - $imgThumbMini = vignette($conf->mycompany->dir_output.'/logos/'.$original_file, $maxwidthmini, $maxheightmini, '_mini', $quality); + // Create mini thumb, Used on menu or for setup page for example + $imgThumbMini = vignette($dirforimage.$original_file, $maxwidthmini, $maxheightmini, '_mini', $quality); if (image_format_supported($imgThumbMini) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbMini,$reg)) { $imgThumbMini = $reg[1]; // Save only basename @@ -143,6 +143,7 @@ if ( ($action == 'update' && empty($_POST["cancel"])) } } } + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_MANAGERS",$_POST["MAIN_INFO_SOCIETE_MANAGERS"],'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_INFO_CAPITAL",$_POST["capital"],'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_INFO_SOCIETE_FORME_JURIDIQUE",$_POST["forme_juridique_code"],'chaine',0,'',$conf->entity); @@ -196,7 +197,7 @@ if ( ($action == 'update' && empty($_POST["cancel"])) } } -if ($action == 'addthumb') +if ($action == 'addthumb') // Regenerate thumbs { if (file_exists($conf->mycompany->dir_output.'/logos/'.$_GET["file"])) { @@ -208,7 +209,7 @@ if ($action == 'addthumb') // Create thumbs //$object->addThumbs($newfile); // We can't use addThumbs here yet because we need name of generated thumbs to add them into constants. TODO Check if need such constants. We should be able to retreive value with get... - // Used on logon for example + // Create small thumb. Used on logon for example $imgThumbSmall = vignette($conf->mycompany->dir_output.'/logos/'.$_GET["file"], $maxwidthsmall, $maxheightsmall, '_small',$quality); if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbSmall,$reg)) { @@ -217,8 +218,7 @@ if ($action == 'addthumb') } else dol_syslog($imgThumbSmall); - // Create mini thumbs for company (Ratio is near 16/9) - // Used on menu or for setup page for example + // Create mini thumbs. Used on menu or for setup page for example $imgThumbMini = vignette($conf->mycompany->dir_output.'/logos/'.$_GET["file"], $maxwidthmini, $maxheightmini, '_mini',$quality); if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbMini,$reg)) { @@ -300,7 +300,7 @@ if ($action == 'edit' || $action == 'updateedit') });'; print ''."\n"; - print '
    '; + print ''; print ''; print ''; $var=true; @@ -383,7 +383,7 @@ if ($action == 'edit' || $action == 'updateedit') print ''.img_delete($langs->trans("Delete")).''; if (file_exists($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini)) { print '   '; - print ''; + print ''; } } else { print ''; @@ -775,7 +775,7 @@ else } else if ($mysoc->logo_mini && is_file($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini)) { - print ''; + print ''; } else { diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 83f6701e2a1..ff3bb89946b 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -26,6 +26,8 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; @@ -70,6 +72,26 @@ if (GETPOST('cancel')) $action=''; } +if ($action == 'removebackgroundlogin' && ! empty($conf->global->MAIN_LOGIN_BACKGROUND)) +{ + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $logofile=$conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND; + dol_delete_file($logofile); + dolibarr_del_const($db, "MAIN_LOGIN_BACKGROUND",$conf->entity); + $mysoc->logo=''; + + /*$logosmallfile=$conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small; + dol_delete_file($logosmallfile); + dolibarr_del_const($db, "MAIN_INFO_SOCIETE_LOGO_SMALL",$conf->entity); + $mysoc->logo_small=''; + + $logominifile=$conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini; + dol_delete_file($logominifile); + dolibarr_del_const($db, "MAIN_INFO_SOCIETE_LOGO_MINI",$conf->entity); + $mysoc->logo_mini='';*/ +} + if ($action == 'update') { dolibarr_set_const($db, "MAIN_LANG_DEFAULT", $_POST["main_lang_default"],'chaine',0,'',$conf->entity); @@ -123,6 +145,78 @@ if ($action == 'update') // This one is not always defined if (isset($_POST["MAIN_USE_PREVIEW_TABS"])) dolibarr_set_const($db, "MAIN_USE_PREVIEW_TABS", $_POST["MAIN_USE_PREVIEW_TABS"],'chaine',0,'',$conf->entity); + $varforimage='imagebackground'; $dirforimage=$conf->mycompany->dir_output.'/logos/'; + if ($_FILES[$varforimage]["tmp_name"]) + { + if (preg_match('/([^\\/:]+)$/i',$_FILES[$varforimage]["name"],$reg)) + { + $original_file=$reg[1]; + + $isimage=image_format_supported($original_file); + if ($isimage >= 0) + { + dol_syslog("Move file ".$_FILES[$varforimage]["tmp_name"]." to ".$dirforimage.$original_file); + if (! is_dir($dirforimage)) + { + dol_mkdir($dirforimage); + } + $result=dol_move_uploaded_file($_FILES[$varforimage]["tmp_name"],$dirforimage.$original_file,1,0,$_FILES[$varforimage]['error']); + if ($result > 0) + { + dolibarr_set_const($db, "MAIN_LOGIN_BACKGROUND",$original_file,'chaine',0,'',$conf->entity); + + // Create thumbs of logo (Note that PDF use original file and not thumbs) + /* + if ($isimage > 0) + { + // Create thumbs + //$object->addThumbs($newfile); // We can't use addThumbs here yet because we need name of generated thumbs to add them into constants. TODO Check if need such constants. We should be able to retreive value with get... + + // Create small thumb, Used on logon for example + $imgThumbSmall = vignette($dirforimage.$original_file, $maxwidthsmall, $maxheightsmall, '_small', $quality); + if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbSmall,$reg)) + { + $imgThumbSmall = $reg[1]; // Save only basename + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_LOGO_SMALL",$imgThumbSmall,'chaine',0,'',$conf->entity); + } + else dol_syslog($imgThumbSmall); + + // Create mini thumb, Used on menu or for setup page for example + $imgThumbMini = vignette($dirforimage.$original_file, $maxwidthmini, $maxheightmini, '_mini', $quality); + if (image_format_supported($imgThumbMini) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbMini,$reg)) + { + $imgThumbMini = $reg[1]; // Save only basename + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_LOGO_MINI",$imgThumbMini,'chaine',0,'',$conf->entity); + } + else dol_syslog($imgThumbMini); + } + else dol_syslog("ErrorImageFormatNotSupported",LOG_WARNING); + */ + } + else if (preg_match('/^ErrorFileIsInfectedWithAVirus/',$result)) + { + $error++; + $langs->load("errors"); + $tmparray=explode(':',$result); + setEventMessages($langs->trans('ErrorFileIsInfectedWithAVirus',$tmparray[1]), null, 'errors'); + } + else + { + $error++; + setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors'); + } + } + else + { + $error++; + $langs->load("errors"); + setEventMessages($langs->trans("ErrorBadImageFormat"), null, 'errors'); + } + } + } + + + $_SESSION["mainmenu"]=""; // Le gestionnaire de menu a pu changer header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup"); @@ -152,7 +246,7 @@ if ($action == 'edit') // Edit //WYSIWYG Editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - print ''; + print ''; print ''; print ''; @@ -160,7 +254,7 @@ if ($action == 'edit') // Edit print '
    '; print '
    '; - print ''; + print ''; print ''; print ''; @@ -315,14 +409,6 @@ if ($action == 'edit') // Edit print ''; print ''; - // Message on login page - print ''."\n"; - // Message of the day on home page print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").'
    '.$langs->trans("Language").' 
     
    '.$langs->trans("MessageLogin").''; - - $doleditor = new DolEditor('main_home', (isset($conf->global->MAIN_HOME)?$conf->global->MAIN_HOME:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); - $doleditor->Create(); - - print '
    '.$langs->trans("MessageOfDay").''; @@ -333,6 +419,40 @@ if ($action == 'edit') // Edit print '
    '."\n"; + print '
    '; + + // Other + print ''; + print ''; + print ''; + print ''; + + // Message on login page + print ''."\n"; + + // Logo + $var=!$var; + print ''; + + print '
    '.$langs->trans("LoginPage").' 
    '.$langs->trans("MessageLogin").''; + $doleditor = new DolEditor('main_home', (isset($conf->global->MAIN_HOME)?$conf->global->MAIN_HOME:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); + $doleditor->Create(); + print '
    '; + print '
    '; + print ''; + print ''; + if (! empty($conf->global->MAIN_LOGIN_BACKGROUND)) { + print ''.img_delete($langs->trans("Delete")).''; + if (file_exists($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND)) { + print '   '; + print ''; + } + } else { + print ''; + } + print '
    '; + print '
    '."\n"; + print '
    '; print ''; @@ -346,7 +466,7 @@ else // Show { // Language print ''; - print ''; + print ''; print ''; - // Message login - print ''."\n"; - // Message of the day print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").' 
    '.$langs->trans("Language").' 
    '.$langs->trans("DefaultLanguage").''; $s=picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); @@ -486,12 +606,6 @@ else // Show print yn((isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0),1); print '
    '.$langs->trans("MessageLogin").''; - if (isset($conf->global->MAIN_HOME)) print dol_htmlcleanlastbr($conf->global->MAIN_HOME); - else print ' '; - print '
    '.$langs->trans("MessageOfDay").''; if (isset($conf->global->MAIN_MOTD)) print dol_htmlcleanlastbr($conf->global->MAIN_MOTD); @@ -500,6 +614,39 @@ else // Show print '
    '."\n"; + print '
    '; + + // Login page + print ''; + print ''; + + // Message login + print ''."\n"; + + // Background login + // Logo + $var=!$var; + print ''; + + print '
    '.$langs->trans("LoginPage").' 
    '.$langs->trans("MessageLogin").''; + if (isset($conf->global->MAIN_HOME)) print dol_htmlcleanlastbr($conf->global->MAIN_HOME); + else print ' '; + print '
    '.$langs->trans("BackgroundImageLogin").''; + print '
    '; + print $conf->global->MAIN_LOGIN_BACKGROUND; + print '
    '; + // It offers the generation of the thumbnail if it does not exist + if ($conf->global->MAIN_LOGIN_BACKGROUND && is_file($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND)) + { + print ''; + } + else + { + print ''; + } + print '
    '; + print '
    '."\n"; + print '
    '; print ''.$langs->trans("Modify").''; print '
    '; diff --git a/htdocs/cashdesk/index.php b/htdocs/cashdesk/index.php index 9a61a50b38a..8f6af8b6d4d 100644 --- a/htdocs/cashdesk/index.php +++ b/htdocs/cashdesk/index.php @@ -63,7 +63,7 @@ top_htmlhead('','',0,0,'',$arrayofcss); logo_small)) { - print 'Logo company'; + print 'Logo company'; } else { diff --git a/htdocs/cashdesk/tpl/ticket.tpl.php b/htdocs/cashdesk/tpl/ticket.tpl.php index 78ce86f45f7..40be470c429 100644 --- a/htdocs/cashdesk/tpl/ticket.tpl.php +++ b/htdocs/cashdesk/tpl/ticket.tpl.php @@ -37,7 +37,7 @@ $object->fetch($facid);

    name; ?>
    diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 1cb4da03488..0d4c1dff71e 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1590,7 +1590,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $relative_original_file = $original_file; // Wrapping for some images - if ($modulepart == 'companylogo' && !empty($conf->mycompany->dir_output)) + if (($modulepart == 'mycompany' || $modulepart == 'companylogo') && !empty($conf->mycompany->dir_output)) { $accessallowed=1; $original_file=$conf->mycompany->dir_output.'/logos/'.$original_file; diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index fc05e2c9194..cadf133169d 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -227,11 +227,11 @@ function dol_loginfunction($langs,$conf,$mysoc) if (! empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) { - $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=companylogo&file='.urlencode('thumbs/'.$mysoc->logo_small); + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('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&modulepart=companylogo&file='.urlencode($mysoc->logo); + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode($mysoc->logo); $width=128; } elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png')) diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index 2c2d2c5ec63..e95359e5683 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -257,7 +257,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&modulepart=companylogo&file='.urlencode('thumbs/'.$mysoc->logo_mini); + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('thumbs/'.$mysoc->logo_mini); } else { diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 178f1ca9db7..ccf6902a289 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -466,7 +466,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&modulepart=companylogo&file='.urlencode('thumbs/'.$mysoc->logo_mini); + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('thumbs/'.$mysoc->logo_mini); } else { @@ -478,7 +478,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu print '

    '; print ''; print ''; print ''; print '
    '."\n"; diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index e0aa28ce2d6..a23d14a979d 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -45,7 +45,7 @@ print top_htmlhead('', $titleofloginpage, 0, 0, $arrayofjs, array(), 0, $disable ?> - +global->MAIN_LOGIN_BACKGROUND)?'':' style="background-image: url(\''.DOL_URL_ROOT.'/viewimage.php?cache=1&noalt=1&modulepart=mycompany&file='.urlencode($conf->global->MAIN_LOGIN_BACKGROUND).'\')"'; ?>> dol_use_jmobile)) { ?> -
    +
     
    '.$langs->trans("UsePreviewTabs").''; - print $form->selectyesno('MAIN_USE_PREVIEW_TABS',isset($conf->global->MAIN_USE_PREVIEW_TABS)?$conf->global->MAIN_USE_PREVIEW_TABS:0,1); - print ' 
    '.$langs->trans("WeekStartOnDay").''; print $formother->select_dayofweek((isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1'),'MAIN_START_WEEK',0); @@ -532,16 +519,6 @@ else // Show print ' 
    '.$langs->trans("UsePreviewTabs").''; - print yn(isset($conf->global->MAIN_USE_PREVIEW_TABS)?$conf->global->MAIN_USE_PREVIEW_TABS:0)." 
    '.$langs->trans("WeekStartOnDay").''; print $langs->trans("Day".(isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1')); diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index f853e88a0df..c5fe89593b6 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -752,6 +752,8 @@ if ($action == 'create') print '
    '; print '

    '; + + print ''; // Related company @@ -1184,7 +1186,7 @@ if ($id > 0) } else { - dol_fiche_head($head, 'card', $langs->trans("Action"),0,'action'); + dol_fiche_head($head, 'card', $langs->trans("Action"), -1, 'action'); // Clone event @@ -1255,6 +1257,8 @@ if ($id > 0) dol_banner_tab($object, 'id', $linkback, ($user->societe_id?0:1), 'id', 'ref', $morehtmlref); + print '
    '; + print '
    '; // Affichage fiche action en mode visu @@ -1345,6 +1349,7 @@ if ($id > 0) print '
    '; + print '
    '; print '
    '; if ($conf->societe->enabled) @@ -1380,21 +1385,6 @@ if ($id > 0) } print ''; } - - // Project - /* - if (! empty($conf->projet->enabled)) - { - print ''; - } - */ // Priority print '
    '.$langs->trans("Project").''; - if ($object->fk_project) - { - $project=new Project($db); - $project->fetch($object->fk_project); - print $project->getNomUrl(1,'',1); - } - print '
    '.$langs->trans("Priority").''; @@ -1423,7 +1413,9 @@ if ($id > 0) //Extra field if (empty($reshook) && ! empty($extrafields->attribute_label)) { - print '

    '; + print '

    '; + print '
    '; + print '
    '; foreach($extrafields->attribute_label as $key=>$label) { if (isset($_POST["options_" . $key])) { @@ -1443,6 +1435,8 @@ if ($id > 0) print '
    '; } + print ''; + dol_fiche_end(); } diff --git a/htdocs/comm/action/document.php b/htdocs/comm/action/document.php index 241843623c2..3edc08d87cb 100644 --- a/htdocs/comm/action/document.php +++ b/htdocs/comm/action/document.php @@ -121,7 +121,7 @@ if ($object->id > 0) $now=dol_now(); $delay_warning=$conf->global->MAIN_DELAY_ACTIONS_TODO*24*60*60; - dol_fiche_head($head, 'documents', $langs->trans("Action"),0,'action'); + dol_fiche_head($head, 'documents', $langs->trans("Action"), -1, 'action'); $linkback = img_picto($langs->trans("BackToList"),'object_list','class="hideonsmartphone pictoactionview"'); $linkback.= ''.$langs->trans("BackToList").''; @@ -164,6 +164,8 @@ if ($object->id > 0) dol_banner_tab($object, 'id', $linkback, ($user->societe_id?0:1), 'id', 'ref', $morehtmlref); + print '
    '; + print '
    '; // Affichage fiche action en mode visu @@ -236,9 +238,6 @@ if ($object->id > 0) print '
    '; - - print '
    '; - print ''; // Construit liste des fichiers @@ -255,7 +254,9 @@ if ($object->id > 0) print '
    '; - dol_fiche_end(); + print '
    '; + + dol_fiche_end(); $modulepart = 'actions'; diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 13fb3d9624f..5d9c84a22b6 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1332,7 +1332,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if ($user->rights->agenda->allactions->create || (($event->authorid == $user->id || $event->userownerid == $user->id) && $user->rights->agenda->myactions->create)) { - $cssclass.= " movable"; + $cssclass.= " movable cursormove"; }else{ $cssclass.= " unmovable"; } diff --git a/htdocs/comm/action/info.php b/htdocs/comm/action/info.php index 2ad3f424b12..7bee5550453 100644 --- a/htdocs/comm/action/info.php +++ b/htdocs/comm/action/info.php @@ -59,7 +59,7 @@ $object->fetch($id); $object->info($object->id); $head=actions_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans("Action"),0,'action'); +dol_fiche_head($head, 'info', $langs->trans("Action"), -1, 'action'); $linkback = img_picto($langs->trans("BackToList"),'object_list','class="hideonsmartphone pictoactionview"'); $linkback.= '
    '.$langs->trans("BackToList").''; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 9b70ee36ace..444669a6f49 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1516,7 +1516,7 @@ if ($action == 'create') // Public note print '
    ' . $langs->trans('NotePublic') . '' . $langs->trans('NotePublic') . ''; $note_public = $object->getDefaultCreateValueFor('note_public', (is_object($objectsrc)?$objectsrc->note_public:null)); $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); @@ -1526,7 +1526,7 @@ if ($action == 'create') if (empty($user->societe_id)) { print '
    ' . $langs->trans('NotePrivate') . '' . $langs->trans('NotePrivate') . ''; $note_private = $object->getDefaultCreateValueFor('note_private', ((! empty($origin) && ! empty($originid) && is_object($objectsrc))?$objectsrc->note_private:null)); $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); diff --git a/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php index 315293281cc..7c3d6ab4e7f 100644 --- a/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php +++ b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php @@ -223,7 +223,7 @@ class box_graph_invoices_supplier_permonth extends ModeleBoxes $stringtoshow.=' '.$langs->trans("AmountOfBillsByMonthHT"); $stringtoshow.='
    '; $stringtoshow.=$langs->trans("Year").' '; - $stringtoshow.=''; + $stringtoshow.=''; $stringtoshow.=''; $stringtoshow.=''; if ($shownb && $showtot) diff --git a/htdocs/core/boxes/box_lastlogin.php b/htdocs/core/boxes/box_lastlogin.php index 7211877a593..05bd3043b0a 100644 --- a/htdocs/core/boxes/box_lastlogin.php +++ b/htdocs/core/boxes/box_lastlogin.php @@ -79,7 +79,7 @@ class box_lastlogin extends ModeleBoxes ); $this->info_box_contents[$line][1] = array( 'td' => '', - 'text' => $user->getNomUrl(1), + 'text' => $user->getNomUrl(-1), 'asis' => 1 ); diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index c016741cb39..39f39524b41 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -247,25 +247,26 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" $s=dol_trunc($head['text'],isset($head['limit'])?$head['limit']:$MAXLENGTHBOX); $out.= $s; } - $out.= ' '; - - $sublink=''; - if (! empty($head['sublink'])) $sublink.= ''; - if (! empty($head['subpicto'])) $sublink.= img_picto($head['subtext'], $head['subpicto'], 'class="'.(empty($head['subclass'])?'':$head['subclass']).'" id="idsubimg'.$this->boxcode.'"'); - if (! empty($head['sublink'])) $sublink.= ''; + $out.= '
    '; + $sublink=''; + if (! empty($head['sublink'])) $sublink.= ''; + if (! empty($head['subpicto'])) $sublink.= img_picto($head['subtext'], $head['subpicto'], 'class="'.(empty($head['subclass'])?'':$head['subclass']).'" id="idsubimg'.$this->boxcode.'"'); + if (! empty($head['sublink'])) $sublink.= ''; + + $out.= ''; $out.=$sublink; // The image must have the class 'boxhandle' beause it's value used in DOM draggable objects to define the area used to catch the full object - $out.= img_picto($langs->trans("MoveBox",$this->box_id),'grip_title','class="boxhandle hideonsmartphone" style="cursor:move;"'); - $out.= img_picto($langs->trans("CloseBox",$this->box_id),'close_title','class="boxclose" rel="x:y" style="cursor:pointer;" id="imgclose'.$this->box_id.'"'); + $out.= img_picto($langs->trans("MoveBox",$this->box_id),'grip_title','class="boxhandle hideonsmartphone cursormove"'); + $out.= img_picto($langs->trans("CloseBox",$this->box_id),'close_title','class="boxclose cursorpointer" rel="x:y" id="imgclose'.$this->box_id.'"'); $label=$head['text']; if (! empty($head['graph'])) $label.=' ('.$langs->trans("Graph").')'; $out.= ''; $out.= '
    '; } - $out.= '
    '; - else $ret.='
    '; - $ret.=''; + //else $ret.='
    '; + $ret.=''; if (preg_match('/ckeditor|textarea/',$typeofdata) && empty($notabletag)) $ret.='
    '."\n"; - $ret.=''; + $ret.=''; if (empty($notabletag)) $ret.='
    '."\n"; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ea92fb5a63b..6028f9bcabc 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1164,7 +1164,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3) || $conf->browser->layout=='phone') $tmptxt=$object->getLibStatut(5, $object->totalpaye); $morehtmlstatus.=$tmptxt; } - elseif ($object->element == 'contrat') + elseif ($object->element == 'contrat' || $object->element == 'contract') { if ($object->statut==0) $morehtmlstatus.=$object->getLibStatut(2); else $morehtmlstatus.=$object->getLibStatut(4); @@ -2375,14 +2375,14 @@ function dol_trunc($string,$size=40,$trunc='right',$stringencoding='UTF-8',$nodo * Example: picto.png if picto.png is stored into htdocs/theme/mytheme/img * Example: picto.png@mymodule if picto.png is stored into htdocs/mymodule/img * Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1) - * @param string $morealt Add more attribute on img tag (For example 'style="float: right"') + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @param int $pictoisfullpath If 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. * @return string Return img tag * @see #img_object, #img_picto_common */ -function img_picto($titlealt, $picto, $morealt = '', $pictoisfullpath = false, $srconly=0, $notitle=0) +function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $srconly=0, $notitle=0) { global $conf; @@ -2434,7 +2434,8 @@ function img_picto($titlealt, $picto, $morealt = '', $pictoisfullpath = false, $ if (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]; - return ''.dol_escape_htmltag($alt).''; // Alt is used for accessibility, title for popup + if ($picto == 'refresh') var_dump($moreatt); + return ''.dol_escape_htmltag($alt).''; // Alt is used for accessibility, title for popup } } @@ -2444,16 +2445,16 @@ function img_picto($titlealt, $picto, $morealt = '', $pictoisfullpath = false, $ * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param string $picto Name of image to show object_picto (example: user, group, action, bill, contract, propal, product, ...) * For external modules use imagename@mymodule to search into directory "img" of module. - * @param string $morealt Add more attribute on img tag (ie: class="datecallink") + * @param string $moreatt Add more attribute on img tag (ie: class="datecallink") * @param int $pictoisfullpath If 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. * @return string Return img tag * @see #img_picto, #img_picto_common */ -function img_object($titlealt, $picto, $morealt = '', $pictoisfullpath = false, $srconly=0, $notitle=0) +function img_object($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $srconly=0, $notitle=0) { - return img_picto($titlealt, 'object_'.$picto, $morealt, $pictoisfullpath, $srconly, $notitle); + return img_picto($titlealt, 'object_'.$picto, $moreatt, $pictoisfullpath, $srconly, $notitle); } /** @@ -2461,12 +2462,12 @@ function img_object($titlealt, $picto, $morealt = '', $pictoisfullpath = false, * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param string $picto Name of image file to show (If no extension provided, we use '.png'). Image must be stored into htdocs/theme/common directory. - * @param string $morealt Add more attribute on img tag + * @param string $moreatt Add more attribute on img tag * @param int $pictoisfullpath If 1, image path is a full path * @return string Return img tag * @see #img_object, #img_picto */ -function img_weather($titlealt, $picto, $morealt = '', $pictoisfullpath = 0) +function img_weather($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0) { global $conf; @@ -2474,7 +2475,7 @@ function img_weather($titlealt, $picto, $morealt = '', $pictoisfullpath = 0) $path = DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/weather/'.$picto; - return img_picto($titlealt, $path, $morealt, 1); + return img_picto($titlealt, $path, $moreatt, 1); } /** @@ -2482,12 +2483,12 @@ function img_weather($titlealt, $picto, $morealt = '', $pictoisfullpath = 0) * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param string $picto Name of image file to show (If no extension provided, we use '.png'). Image must be stored into htdocs/theme/common directory. - * @param string $morealt Add more attribute on img tag + * @param string $moreatt Add more attribute on img tag * @param int $pictoisfullpath If 1, image path is a full path * @return string Return img tag * @see #img_object, #img_picto */ -function img_picto_common($titlealt, $picto, $morealt = '', $pictoisfullpath = 0) +function img_picto_common($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0) { global $conf; @@ -2506,7 +2507,7 @@ function img_picto_common($titlealt, $picto, $morealt = '', $pictoisfullpath = 0 } } - return img_picto($titlealt, $path, $morealt, 1); + return img_picto($titlealt, $path, $moreatt, 1); } /** @@ -2612,9 +2613,9 @@ function img_view($titlealt = 'default', $float = 0, $other = '') if ($titlealt == 'default') $titlealt = $langs->trans('View'); - $morealt = ($float ? 'style="float: right" ' : '').$other; + $moreatt = ($float ? 'style="float: right" ' : '').$other; - return img_picto($titlealt, 'view.png', $morealt); + return img_picto($titlealt, 'view.png', $moreatt); } /** @@ -2686,17 +2687,17 @@ function img_info($titlealt = 'default') * Show warning logo * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. - * @param string $morealt Add more attribute on img tag (For example 'style="float: right"'). If 1 + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"'). If 1 * @return string Return img tag */ -function img_warning($titlealt = 'default', $morealt = '') +function img_warning($titlealt = 'default', $moreatt = '') { global $conf, $langs; if ($titlealt == 'default') $titlealt = $langs->trans('Warning'); - //return '
    '.img_picto($titlealt, 'warning_white.png', 'class="pictowarning valignmiddle"'.($morealt ? ($morealt == '1' ? ' style="float: right"' : ' '.$morealt): '')).'
    '; - return img_picto($titlealt, 'warning.png', 'class="pictowarning valignmiddle"'.($morealt ? ($morealt == '1' ? ' style="float: right"' : ' '.$morealt): '')); + //return '
    '.img_picto($titlealt, 'warning_white.png', 'class="pictowarning valignmiddle"'.($moreatt ? ($moreatt == '1' ? ' style="float: right"' : ' '.$moreatt): '')).'
    '; + return img_picto($titlealt, 'warning.png', 'class="pictowarning valignmiddle"'.($moreatt ? ($moreatt == '1' ? ' style="float: right"' : ' '.$moreatt): '')); } /** @@ -2718,16 +2719,16 @@ function img_error($titlealt = 'default') * Show next logo * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. -* @param string $morealt Add more attribute on img tag (For example 'style="float: right"') +* @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @return string Return img tag */ -function img_next($titlealt = 'default', $morealt='') +function img_next($titlealt = 'default', $moreatt='') { global $conf, $langs; if ($titlealt == 'default') $titlealt = $langs->trans('Next'); - //return img_picto($titlealt, 'next.png', $morealt); + //return img_picto($titlealt, 'next.png', $moreatt); return ''; } @@ -2735,16 +2736,16 @@ function img_next($titlealt = 'default', $morealt='') * Show previous logo * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. - * @param string $morealt Add more attribute on img tag (For example 'style="float: right"') + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @return string Return img tag */ -function img_previous($titlealt = 'default', $morealt='') +function img_previous($titlealt = 'default', $moreatt='') { global $conf, $langs; if ($titlealt == 'default') $titlealt = $langs->trans('Previous'); - //return img_picto($titlealt, 'previous.png', $morealt); + //return img_picto($titlealt, 'previous.png', $moreatt); return ''; } @@ -2787,16 +2788,16 @@ function img_up($titlealt = 'default', $selected = 0, $moreclass='') * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param int $selected Selected - * @param string $morealt Add more attribute on img tag (For example 'style="float: right"') + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @return string Return img tag */ -function img_left($titlealt = 'default', $selected = 0, $morealt='') +function img_left($titlealt = 'default', $selected = 0, $moreatt='') { global $conf, $langs; if ($titlealt == 'default') $titlealt = $langs->trans('Left'); - return img_picto($titlealt, ($selected ? '1leftarrow_selected.png' : '1leftarrow.png'), $morealt); + return img_picto($titlealt, ($selected ? '1leftarrow_selected.png' : '1leftarrow.png'), $moreatt); } /** @@ -2804,16 +2805,16 @@ function img_left($titlealt = 'default', $selected = 0, $morealt='') * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param int $selected Selected - * @param string $morealt Add more attribute on img tag (For example 'style="float: right"') + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @return string Return img tag */ -function img_right($titlealt = 'default', $selected = 0, $morealt='') +function img_right($titlealt = 'default', $selected = 0, $moreatt='') { global $conf, $langs; if ($titlealt == 'default') $titlealt = $langs->trans('Right'); - return img_picto($titlealt, ($selected ? '1rightarrow_selected.png' : '1rightarrow.png'), $morealt); + return img_picto($titlealt, ($selected ? '1rightarrow_selected.png' : '1rightarrow.png'), $moreatt); } /** diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 6e6e0c7b511..d2567f30c04 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -334,8 +334,6 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) $thumbsbyrow=6; print ''; - $var=false; - // Title if ($foruserprofile) { @@ -343,10 +341,10 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) print ''; print ''; - print ''; + print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; } @@ -362,7 +360,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) print ''; print ''; - print ''; + print ''; print ''; print ''; } - //$var=!$var; - print ''; + print '
    '.$langs->trans("NoPhotoYet")."
    "; } - - print '
     
    '.$langs->trans("DefaultSkin").''.$conf->global->MAIN_THEME.' '.$langs->trans("UsePersonalValue").' '.$langs->trans("UsePersonalValue").' 
    '.$langs->trans("ThemeDir").''; foreach($dirthemes as $dirtheme) @@ -373,8 +371,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) print '
    '; + print '
    '; print ''; + /* + print ''; print ''; print ''; print ''; + print ''; print ''; print ''; + /* + print ''; print ''; print ''; print ''; + print ''; print ''; print ''; + /* + print ''; print ''; print ''; print ''; + print ''; print ''; print ''; + print ''; print ''; print ''; + print ''; print ''; print ''; + /* + print ''; print ''; print ''; print ''; + print ''; print ''; print ''; + print ''; print ''; print ''; print ''; @@ -686,7 +677,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - print ''; + print ''; print ''; print ''; - // Do not import first lines + // Lines nb to import print ''; @@ -2346,7 +2346,7 @@ else if (! empty($conf->adherent->enabled)) { $langs->load("members"); - print ''; + print ''; print ''; print "\n"; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index ed3fdad13c4..dce0e5c19bc 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1854,7 +1854,14 @@ class Societe extends CommonObject $result=''; $label=''; $linkstart=''; $linkend=''; - $label.= '
    '; + if (! empty($this->logo) && class_exists('Form')) + { + $label.= '
    '; + $label.= Form::showphoto('societe', $this, 80, 0, 0, 'photowithmargin', 'mini'); + $label.= '
    '; + } + + $label.= '
    '; if ($option == 'customer' || $option == 'compta' || $option == 'category' || $option == 'category_supplier') { @@ -1908,12 +1915,6 @@ class Societe extends CommonObject if (! empty($conf->accounting->enabled) && $this->fournisseur) $label.= '
    ' . $langs->trans('SupplierAccountancyCode') . ': '. $this->code_compta_fournisseur; - if (! empty($this->logo) && class_exists('Form')) - { - $label.= '
    '; - $label.= Form::showphoto('societe', $this, 80, 0, 0, 'photowithmargin', 'mini'); - $label.= '
    '; - } $label.= '
    '; // Add type of canvas diff --git a/htdocs/societe/tpl/linesalesrepresentative.tpl.php b/htdocs/societe/tpl/linesalesrepresentative.tpl.php index d8d4b4b08bb..34a7ce3f4c4 100644 --- a/htdocs/societe/tpl/linesalesrepresentative.tpl.php +++ b/htdocs/societe/tpl/linesalesrepresentative.tpl.php @@ -37,5 +37,5 @@ if ($i < $nbofsalesrepresentative) print ', '; } } - else print $langs->trans("NoSalesRepresentativeAffected"); + else print ''.$langs->trans("NoSalesRepresentativeAffected").''; print ''; diff --git a/htdocs/theme/eldy/img/refresh.png b/htdocs/theme/eldy/img/refresh.png index 9994475cdfe0fb8c646eb1877a84443066a73d93..a4fac077e7aa050f4a84419d6d3df6af9af4d16d 100644 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mrg*wIhEy;fJ!7wTyg;VmVfw;# z3XjYVH8e}Kd|^AApH(;6IMmbY==^!jM;xqceSE*Jp1kz@pJ!X=+3pO>|DZB`;RK5- zoKu5Viru@@@#Ruwc}hu^K;{(g;6rYIdZVU#Do$GzmwC{Bk^A?Gw(Lap^d8T>-j}!PC{xWt~$( F695yoR&f9T literal 722 zcmV;@0xkWCP)YH zKm%ON42;6;44maEEON_y_)3;}a?MFlVvu6M2S6HfG??{Q1@TrKZ_qjae0RaWBQ;JJ z3v{?_RJj@Wd6{r%^pjyw+!)2X_{kcRZ-39Z|NnbB?%&Jx$=}a5yPjL)FIN>K$D+u~ z!oY~3QJs&0x5JJ-`a-wjxgUqk|NPly@&Elw+y6h-2K|3JHSq1GaD{$%ekMs)kYXMd z2IfR%2I&N429-E@22od02JS9PR==~&ve(|O()+q2mS_8w3h67~X4(C}*I@N#vMG0z z01E>vgD5AX=+;D%AB z^#AV(5m+h8!63*W!ObXlp+fP?>+Pw(weOTlLQ|~a4||Th;uPWpUIVY_-S?E-#wW+^DRXfB>7kwm_^tb1O-?bz~N}X z!@#`EovY$ii^A8NSt4I0ftE3da4-n$4Ch|*ZNB~g>+ROJVzfEJYxNm)SNn@Bm|)Is zDb3EnVj;l5zQUEg@O-Aom4gvHr^LA!B^iW(9-VK@5`M2v>CKk~ZvRi0=$%^QFEahk zoRp8p>)g(^8gsh<1B@eHfk81@jlm{Sjlmcgpll2rK&M3TGe~U>;+p!RP2=O&S&sjo zOmzMEV^iM0uN%{TpQ>>@)?&>csLBiRI|=|sDpP_oqxu$qj?SxvlK0+q>;3*a-R$4L zX}bU4PImaUJzjCEuPlQO)>Oj>Oc5IV45G!lOfH9G_)dOoRrq^7TlnpcVD5#pj5xfV z*%|oprq@VW2JYo9EXy|du+8r_W3&MU9xxnO*wNGh0HJEuBo)&9!2kdN07*qoM6N<$ Eg5ua`M*si- diff --git a/htdocs/theme/eldy/img/reload.png b/htdocs/theme/eldy/img/reload.png deleted file mode 100644 index a4029f119def5d9ca4c5f7f1bc6a452176bf5b06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 704 zcmb7??@Lor9LBF`=^U1X>V4y5N$e2{G6k^_+1%BMO-*2b|;o^^|?8?hdl^qD(~U7?6ySOppu+gG7)!Q4hvMSYQj|No=(Kykg?MTQ)Jvq%YX^x9` z<~II3e3`G%>{>ifvstipIJmpH^0&q~lxANZzwr5ye<^4kE@;2R-G0>>G;ihPIQy!4 zPOU`7?hhi(v26Y5#Cl)v*noY9_R!V0D-$zQvwQt=_^YF8PlvI>ZY}jIQu5~uf4Ht} zo_Tsr-L__EPhx)dj^+;R&tEea_v^b=+0TwYzo$4q)c;r;XZ_XkX7U7UEu8!?m_9wd z{6H*CU+OGAZOdol_hide_leftmenu; $dol_optimize_smallscreen=$conf->dol_optimize_smallscreen; $dol_no_mouse_hover=$conf->dol_no_mouse_hover; - //$conf->global->THEME_ELDY_ENABLE_PERSONALIZED=0; //$user->conf->THEME_ELDY_ENABLE_PERSONALIZED=0; //var_dump($user->conf->THEME_ELDY_RGB); // Colors -$colorbackhmenu1='110,120,160'; // topmenu +$colorbackhmenu1='90,100,130'; // topmenu $colorbackvmenu1='255,255,255'; // vmenu $colortopbordertitle1='120,120,120'; // top border of title $colorbacktitle1='240,240,240'; // title of tables,list @@ -97,7 +96,6 @@ $colortext='0,0,0'; $colortextlink='0,0,120'; $fontsize='13'; $fontsizesmaller='12'; -$usegradienttop=(isset($conf->global->THEME_ELDY_TOPMENU_BACK1)?0:1); $useboldtitle=(isset($conf->global->THEME_ELDY_USEBOLDTITLE)?$conf->global->THEME_ELDY_USEBOLDTITLE:1); $borderwith=2; @@ -125,7 +123,7 @@ if (empty($conf->global->THEME_ELDY_ENABLE_PERSONALIZED)) $conf->global->THEME_ELDY_FONT_SIZE2='12'; } - + // Case of option availables only if THEME_ELDY_ENABLE_PERSONALIZED is on $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); $colorbackvmenu1 =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_VERMENU_BACK1)?$colorbackvmenu1:$conf->global->THEME_ELDY_VERMENU_BACK1) :(empty($user->conf->THEME_ELDY_VERMENU_BACK1)?$colorbackvmenu1:$user->conf->THEME_ELDY_VERMENU_BACK1); @@ -137,7 +135,6 @@ $colorbacklineimpair1=empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty( $colorbacklineimpair2=empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_LINEIMPAIR2) ?$colorbacklineimpair2:$conf->global->THEME_ELDY_LINEIMPAIR2):(empty($user->conf->THEME_ELDY_LINEIMPAIR2)?$colorbacklineimpair2:$user->conf->THEME_ELDY_LINEIMPAIR2); $colorbacklinepair1 =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_LINEPAIR1) ?$colorbacklinepair1:$conf->global->THEME_ELDY_LINEPAIR1) :(empty($user->conf->THEME_ELDY_LINEPAIR1)?$colorbacklinepair1:$user->conf->THEME_ELDY_LINEPAIR1); $colorbacklinepair2 =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_LINEPAIR2) ?$colorbacklinepair2:$conf->global->THEME_ELDY_LINEPAIR2) :(empty($user->conf->THEME_ELDY_LINEPAIR2)?$colorbacklinepair2:$user->conf->THEME_ELDY_LINEPAIR2); -$colorbacklinepairhover=empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_LINEPAIRHOVER) ?$colorbacklinepairhover:$conf->global->THEME_ELDY_LINEPAIRHOVER) :(empty($user->conf->THEME_ELDY_LINEPAIRHOVER)?$colorbacklinepairhover:$user->conf->THEME_ELDY_LINEPAIRHOVER); $colorbackbody =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_BACKBODY) ?$colorbackbody:$conf->global->THEME_ELDY_BACKBODY) :(empty($user->conf->THEME_ELDY_BACKBODY)?$colorbackbody:$user->conf->THEME_ELDY_BACKBODY); $colortexttitlenotab =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_TEXTTITLENOTAB)?$colortexttitlenotab:$conf->global->THEME_ELDY_TEXTTITLENOTAB) :(empty($user->conf->THEME_ELDY_TEXTTITLENOTAB)?$colortexttitlenotab:$user->conf->THEME_ELDY_TEXTTITLENOTAB); $colortexttitle =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_TEXTTITLE) ?$colortexttitle:$conf->global->THEME_ELDY_TEXTTITLE) :(empty($user->conf->THEME_ELDY_TEXTTITLE)?$colortexttitle:$user->conf->THEME_ELDY_TEXTTITLE); @@ -145,6 +142,7 @@ $colortext =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty( $colortextlink =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_TEXTLINK) ?$colortextlink:$conf->global->THEME_ELDY_TEXTLINK) :(empty($user->conf->THEME_ELDY_TEXTLINK)?$colortextlink:$user->conf->THEME_ELDY_TEXTLINK); $fontsize =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_FONT_SIZE1) ?$fontsize:$conf->global->THEME_ELDY_FONT_SIZE1) :(empty($user->conf->THEME_ELDY_FONT_SIZE1)?$fontsize:$user->conf->THEME_ELDY_FONT_SIZE1); $fontsizesmaller =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_FONT_SIZE2) ?$fontsize:$conf->global->THEME_ELDY_FONT_SIZE2) :(empty($user->conf->THEME_ELDY_FONT_SIZE2)?$fontsize:$user->conf->THEME_ELDY_FONT_SIZE2); + // 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)); if (! empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)) @@ -271,6 +269,9 @@ input.select2-input { .liste_titre input[name=monthvalid], .liste_titre input[name=smonth], .liste_titre input[name=month], .liste_titre input[name=month_lim] { margin-right: 4px; } +input[type=submit] { + margin-left: 5px; +} input, input.flat, form.flat select, select, select.flat, .dataTables_length label select { global->THEME_ELDY_SHOW_BORDER_INPUT)) print "border: none;" @@ -519,6 +520,9 @@ textarea.centpercent { .nowrap { white-space: ; } +.nowraponall { + white-space: nowrap; +} .nobold { font-weight: normal !important; } @@ -534,6 +538,9 @@ textarea.centpercent { .cursorpointer { cursor: pointer; } +.cursormove { + cursor: move; +} .badge { display: inline-block; min-width: 10px; @@ -548,9 +555,6 @@ textarea.centpercent { background-color: #777; border-radius: 10px; } -.movable { - cursor: move; -} .borderrightlight { border-right: 1px solid #DDD; @@ -876,7 +880,7 @@ td.showDragHandle { } #id-right, #id-left { padding-top: 16px; - padding-bottom: 8px; + padding-bottom: 16px; display: table-cell; /* DOL_XXX Empeche fonctionnement correct du scroll horizontal sur tableau, avec datatable ou CSS */ float: none; @@ -1100,6 +1104,9 @@ div.statusref { margin-bottom: 10px; clear: both; } +div.statusref img { + padding-left: 8px; +} img.photoref, div.photoref { border: 1px solid #CCC; -moz-box-shadow: 3px 3px 4px #DDD; @@ -1156,14 +1163,14 @@ div#id-top { background: rgb(); /*-webkit-box-shadow: 0 0 6px rgba(0,0,0,0.4); box-shadow: 0 0 6px rgba(0,0,0,0.4); */ - + /* background-image: linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -o-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -moz-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -webkit-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -ms-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -webkit-gradient( linear, left top, left bottom, color-stop(0, rgba(255,255,255,.1)), color-stop(1, rgba(0,0,0,.4)) ); - + */ /* height: 34px; @@ -1240,15 +1247,15 @@ ul.tmenu { /* t r b l */ display: table; } ul.tmenu li { /* We need this to have background color when menu entry wraps on new lines */ -/* background: rgb(); - + /* background: rgb(); + /* background-image: linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -o-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -moz-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -webkit-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -ms-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); background-image: -webkit-gradient( linear, left top, left bottom, color-stop(0, rgba(255,255,255,.1)), color-stop(1, rgba(0,0,0,.4)) ); - */ + */ } li.tmenu, li.tmenusel { @@ -1293,7 +1300,7 @@ div.tmenuleft div.tmenucenter { padding-left: 0px; - padding-right: 0px; + padding-right: 3px; padding-top: 8px; height: 26px; @@ -1335,7 +1342,7 @@ div.mainmenu { position : relative; background-repeat:no-repeat; background-position:center top; - height: px; + height: px; margin-left: 0px; min-width: 40px; } @@ -1526,9 +1533,9 @@ form#login { background-color: #FFFFFF; - -moz-box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(60,60,60,0.15); - -webkit-box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(60,60,60,0.15); - box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(60,60,60,0.15); + -moz-box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(60,60,60,0.15); + -webkit-box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(60,60,60,0.15); + box-shadow: 0 2px 23px 2px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(60,60,60,0.15); border-radius: 5px; /*border-top:solid 1px rgba(180,180,180,.4); @@ -2063,82 +2070,32 @@ span.butAction, span.butActionDelete { margin: 0em em; padding: 0.6em em; font-family: ; -/* for bootstrap look - color: #fff; - background-color: #337ab7; - border-color: #2e6da4; - display: inline-block; - padding: 6px 12px; - margin-bottom: 0; - font-weight: normal; - line-height: 1.42857143; - text-align: center; - white-space: nowrap; - vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-image: none; - border: 1px solid transparent; - border-radius: 4px; - */ - - font-weight: normal; - border-color: #c5c5c5; - border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); - display: inline-block; - text-align: center; - cursor: pointer; - color: #fff; - background: rgb(); - background-image: linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); - background-image: -o-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); - background-image: -moz-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); - background-image: -webkit-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); - background-image: -ms-linear-gradient(top, rgba(255,255,255,.1) 0%, rgba(0,0,0,.4) 100%); - - color: #333333; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - background-color: #f5f5f5; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); - - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - border: 1px solid #bbbbbb; - border-bottom-color: #a2a2a2; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + font-weight: normal; + border-color: #c5c5c5; + border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); + display: inline-block; + text-align: center; + cursor: pointer; + color: #fff; + background: rgb(); + border: 1px solid rgb(); } .butAction:hover { - -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); - -webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); - box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); + -moz-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); + -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); } .butActionDelete, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active, .buttonDelete { - color: #800 !important; + background: #633; + border: 1px solid #633; } .butActionDelete:hover { - -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); - -webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); - box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); + -moz-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); + -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); } .butActionRefused { @@ -2148,130 +2105,14 @@ span.butAction, span.butActionDelete { margin: 0em em; padding: 0.6em em; font-family: !important; -/* for bootstrap look - color: #333; - background-color: #e6e6e6; - border-color: #adadad; - display: inline-block; - margin-bottom: 0; - font-weight: normal !important; - line-height: 1.42857143; - text-align: center; - white-space: nowrap; - vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-image: none; - border: 1px solid transparent; - border-radius: 4px; -*/ - - font-weight: normal !important; - border-color: #c5c5c5; - border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); - display: inline-block; - margin: 0em em; - padding: 0.6em em; - text-align: center; - cursor: pointer; - color: #999 !important; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - background-color: #f5f5f5; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - border: 1px solid #bbbbbb; - border-bottom-color: #a2a2a2; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - + font-weight: normal !important; + display: inline-block; + text-align: center; + cursor: pointer; + color: #999 !important; + border: 1px solid #bbb; } -/* Prepare for bootstrap look -.butAction, .butActionDelete, .butActionRefused { - border-color: #c5c5c5; - border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); - display: inline-block; - padding: 4px 14px; - margin-bottom: 0; - line-height: 20px; - text-align: center; - vertical-align: middle; - cursor: pointer; - color: #333333; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - background-color: #f5f5f5; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - border: 1px solid #bbbbbb; - border-bottom-color: #a2a2a2; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.butAction { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #006dcc; - background-image: -moz-linear-gradient(top, #0088cc, #0044cc); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); - background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); - background-image: -o-linear-gradient(top, #0088cc, #0044cc); - background-image: linear-gradient(to bottom, #0088cc, #0044cc); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); - border-color: #0044cc #0044cc #002a80; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} - -.butActionDelete { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #cc6d00; - background-image: -moz-linear-gradient(top, #cc8800, #cc4400); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#cc8800), to(#cc4400)); - background-image: -webkit-linear-gradient(top, #cc8800, #cc4400); - background-image: -o-linear-gradient(top, #cc8800, #cc4400); - background-image: linear-gradient(to bottom, #cc8800, #cc4400); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffcc8800', endColorstr='#ffcc4400', GradientType=0); - border-color: #cc4400 #cc4400 #802a00; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} -a.butAction:link, a.butAction:visited, a.butAction:hover, a.butAction:active { - color: #FFFFFF; -} -End bootstrap */ - global->MAIN_BUTTON_HIDE_UNAUTHORIZED) && (! $user->admin)) { ?> .butActionRefused { display: none; @@ -2531,14 +2372,12 @@ div.pagination li.pagination span.inactive { cursor: default; color: #ccc; } +li.noborder.litext, li.noborder.litext a, div.pagination li a.inactive:hover, div.pagination li span.inactive:hover { - background-color: #f5f5f5; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + -moz-box-shadow: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; } /*div.pagination li.litext { padding-top: 8px; @@ -2563,7 +2402,7 @@ div.pagination li.noborder a:hover { } div.pagination li a, div.pagination li span { - background-color: #fff; + /* background-color: #fff; */ /* border: 1px solid #ddd; */ } div.pagination li:first-child a, @@ -2581,6 +2420,10 @@ div.pagination li a:hover, div.pagination li span:hover, div.pagination li a:focus, div.pagination li span:focus { + -moz-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); + -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); + /* color: #000; background-color: #eee; border-color: #ccc; @@ -2591,7 +2434,7 @@ div.pagination li span:focus { background-image: -o-linear-gradient(top, #eee, #ddd); background-image: linear-gradient(to bottom, #eee, #ddd); background-repeat: repeat-x; - +*/ } div.pagination li .active a, div.pagination li .active span, @@ -3123,15 +2966,13 @@ td.legendLabel { padding: 2px 2px 2px 0 !important; } margin-bottom: 2px; margin-top: 10px; } -.photowithmargin { -/* -webkit-box-shadow: 0px 0px 3px #777; - -moz-box-shadow: 0px 0px 3px #777; - box-shadow: 0px 0px 3px #777;*/ -} -.photointoolitp { +.photointooltip { margin-top: 6px; - float: left; - /*text-align: center; */ + margin-bottom: 6px; + text-align: center; + /*-moz-box-shadow: 3px 3px 4px #DDD; + -webkit-box-shadow: 3px 3px 4px #DDD; + box-shadow: 3px 3px 4px #DDD;*/ } .photodelete { margin-top: 6px !important; @@ -4651,7 +4492,7 @@ border-top-right-radius: 6px; /* nboftopmenuentries = , fontsize= */ /* rule to reduce top menu - 1st reduction */ -@media only screen and (max-width: px) +@media only screen and (max-width: px) /* reduction 1 */ { div.tmenucenter { width: px; /* size of viewport */ @@ -4680,7 +4521,7 @@ border-top-right-radius: 6px; } } /* rule to reduce top menu - 2nd reduction */ -@media only screen and (max-width: px) +@media only screen and (max-width: px) /* reduction 2 */ { div.mainmenu { height: 23px; @@ -4689,6 +4530,9 @@ border-top-right-radius: 6px; max-width: px; /* size of viewport */ text-overflow: clip; } + span.mainmenuaspan { + margin-left: 1px; + } .mainmenuaspan { /*display: none;*/ font-size: 10px; @@ -4696,10 +4540,11 @@ border-top-right-radius: 6px; .topmenuimage { background-size: 20px auto; margin-top: 2px; + left: 4px; } } /* rule to reduce top menu - 3rd reduction */ -@media only screen and (max-width: px) +@media only screen and (max-width: px) /* reduction 3 */ { /* Reduce login top right info */ .usertextatoplogin { @@ -4743,6 +4588,7 @@ border-top-right-radius: 6px; .topmenuimage { background-size: 20px auto; margin-top: 2px !important; + left: 2px; } div.mainmenu { min-width: 20px; diff --git a/htdocs/theme/md/img/edit.png b/htdocs/theme/md/img/edit.png index 7012f52be5ae6acc556b223c8a822b5883ce62ac..6334689a36e2cc1be67f0f5ea5233231e0d99130 100644 GIT binary patch delta 278 zcmbQjxQuCnWIY=L14G!kzHlJLmgMd3!tfsi7wla=87RV8;1OBOz`!jG!i)^F=12eq z*-JcqUD+Qp%k#3b=v?_T5h%3T)5S5w;`G@|8+i{I2(&)57jstF$iQsC^yXv05``l! z4b6F+Tv}Q)8grc{dmM9>k>-kty!LbV=bsPi-B+L5n~=tr(a5`D+83q*)|2NO8dwX= zH>YZTVc1n?&z{Gyx##(uhUH7TXNK0MiWbZb3GA;}z_w@R)k#qc82b(=-h9JwlkK?d z1&>dOYfihgJy~sWFIDOA`nQvdO&D)_zH(a_^o02rTW57h&yfJbNm3_Ho{*T*`saBS a^R&mF4IlX1PKp3Mz~JfX=d#Wzp$Pz}xNtoH delta 130 zcmV-|0Db?a0+a!e8G8f(008{QM%(}Z09#2!K~#7F#m(IbfG`jQ;fd8)ms*nq@uxOH zu#1aJp3NB$ap(1e<=q-K4q6{ABz5|%!!p}TN3#g@nT_{kC1D~k5D6usFcH8biug<> k!jFU+LJgsYP#_=d0-J70jk-!ing9R*07*qoM6N<$f-|=>8~^|S diff --git a/htdocs/theme/md/img/reload.png b/htdocs/theme/md/img/reload.png deleted file mode 100644 index a4fac077e7aa050f4a84419d6d3df6af9af4d16d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mrg*wIhEy;fJ!7wTyg;VmVfw;# z3XjYVH8e}Kd|^AApH(;6IMmbY==^!jM;xqceSE*Jp1kz@pJ!X=+3pO>|DZB`;RK5- zoKu5Viru@@@#Ruwc}hu^K;{(g;6rYIdZVU#Do$GzmwC{Bk^A?Gw(Lap^d8T>-j}!PC{xWt~$( F695yoR&f9T diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 28c3c6c0193..94f0b11b560 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -521,6 +521,9 @@ textarea.centpercent { .nowrap { white-space: ; } +.nowraponall { + white-space: nowrap; +} .nobold { font-weight: normal !important; } @@ -536,6 +539,9 @@ textarea.centpercent { .cursorpointer { cursor: pointer; } +.cusormove { + cursor: move; +} .badge { display: inline-block; min-width: 10px; @@ -550,9 +556,6 @@ textarea.centpercent { background-color: #777; border-radius: 10px; } -.movable { - cursor: move; -} .borderrightlight { @@ -1145,6 +1148,9 @@ div.statusref { margin-bottom: 10px; clear: both; } +div.statusref img { + padding-left: 8px; +} img.photoref, div.photoref { border: 1px solid #CCC; -moz-box-shadow: 3px 3px 4px #DDD; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 26af6c659ff..811f39b3c88 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1986,12 +1986,18 @@ class User extends CommonObject if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0; - $result = ''; - $companylink = ''; - $link = ''; - - $label = '' . $langs->trans("User") . ''; - $label.= '
    '; + $result=''; $label=''; + $linkstart=''; $linkend=''; + + if (! empty($this->photo)) + { + $label.= '
    '; + $label.= Form::showphoto('userphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1); + $label.= '
    '; + } + + $label.= '
    '; + $label.= '' . $langs->trans("User") . '
    '; $label.= '' . $langs->trans('Name') . ': ' . $this->getFullName($langs,'',''); if (! empty($this->login)) $label.= '
    ' . $langs->trans('Login') . ': ' . $this->login; @@ -2008,12 +2014,6 @@ class User extends CommonObject $type=($this->societe_id?$langs->trans("External").$company:$langs->trans("Internal")); $label.= '
    ' . $langs->trans("Type") . ': ' . $type; $label.='
    '; - if (! empty($this->photo)) - { - $label.= '
    '; - $label.= Form::showphoto('userphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1); - $label.= '
    '; - } // Info Login if ($infologin) From ee86b7bcefe182574dac69a4bb13a35d16302446 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Mar 2017 17:50:54 +0200 Subject: [PATCH 054/233] Avoid javascript warning when in stable mode. --- htdocs/main.inc.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index ab156334c4f..bc1af5cc340 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1146,8 +1146,11 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; if (constant('JS_JQUERY')) print ''."\n"; else print ''."\n"; - if (constant('JS_JQUERY_MIGRATE')) print ''."\n"; - else print ''."\n"; + if (! empty($conf->global->MAIN_FEATURES_LEVEL)) + { + if (constant('JS_JQUERY_MIGRATE')) print ''."\n"; + else print ''."\n"; + } if (constant('JS_JQUERY_UI')) print ''."\n"; else print ''."\n"; if (! defined('DISABLE_JQUERY_TABLEDND')) print ''."\n"; From 9d193924bdaac93976cd53998d1fdffdea9f15eb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Mar 2017 18:05:20 +0200 Subject: [PATCH 055/233] Fix bad constants --- htdocs/main.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index bc1af5cc340..c8dac96f11e 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1144,14 +1144,14 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs { // JQuery. Must be before other includes print ''."\n"; - if (constant('JS_JQUERY')) print ''."\n"; + if (defined('JS_JQUERY')) print ''."\n"; else print ''."\n"; if (! empty($conf->global->MAIN_FEATURES_LEVEL)) { - if (constant('JS_JQUERY_MIGRATE')) print ''."\n"; + if (defined('JS_JQUERY_MIGRATE')) print ''."\n"; else print ''."\n"; } - if (constant('JS_JQUERY_UI')) print ''."\n"; + if (defined('JS_JQUERY_UI')) print ''."\n"; else print ''."\n"; if (! defined('DISABLE_JQUERY_TABLEDND')) print ''."\n"; if (! defined('DISABLE_JQUERY_TIPTIP')) print ''."\n"; From 2903518fb1329b4b8e6f4851b19ebd052d03c21f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Mar 2017 18:11:01 +0200 Subject: [PATCH 056/233] Fix bad links --- htdocs/main.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index c8dac96f11e..074f626f299 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1144,14 +1144,14 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs { // JQuery. Must be before other includes print ''."\n"; - if (defined('JS_JQUERY')) print ''."\n"; + if (defined('JS_JQUERY') && constant('JS_JQUERY')) print ''."\n"; else print ''."\n"; if (! empty($conf->global->MAIN_FEATURES_LEVEL)) { - if (defined('JS_JQUERY_MIGRATE')) print ''."\n"; + if (defined('JS_JQUERY_MIGRATE') && constant('JS_JQUERY_MIGRATE')) print ''."\n"; else print ''."\n"; } - if (defined('JS_JQUERY_UI')) print ''."\n"; + if (defined('JS_JQUERY_UI') && constant('JS_JQUERY_UI')) print ''."\n"; else print ''."\n"; if (! defined('DISABLE_JQUERY_TABLEDND')) print ''."\n"; if (! defined('DISABLE_JQUERY_TIPTIP')) print ''."\n"; From 93687997c98ef4a60d88aea568f2d2f60f916374 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Mar 2017 18:40:53 +0200 Subject: [PATCH 057/233] Work on 6.0 look and feel --- htdocs/adherents/stats/index.php | 2 +- htdocs/comm/propal/stats/index.php | 2 +- htdocs/commande/stats/index.php | 2 +- htdocs/compta/deplacement/stats/index.php | 2 +- htdocs/compta/facture/fiche-rec.php | 29 +++++++++++------------ htdocs/compta/facture/stats/index.php | 2 +- htdocs/don/stats/index.php | 2 +- htdocs/expedition/stats/index.php | 2 +- htdocs/expensereport/stats/index.php | 2 +- htdocs/fichinter/stats/index.php | 2 +- htdocs/projet/stats/index.php | 2 +- 11 files changed, 24 insertions(+), 25 deletions(-) diff --git a/htdocs/adherents/stats/index.php b/htdocs/adherents/stats/index.php index 6acdd1e56b7..aec8cd588f6 100644 --- a/htdocs/adherents/stats/index.php +++ b/htdocs/adherents/stats/index.php @@ -141,7 +141,7 @@ if (! $mesg) $head = member_stats_prepare_head($adh); -dol_fiche_head($head, 'statssubscription', $langs->trans("Statistics"), 0, 'user'); +dol_fiche_head($head, 'statssubscription', $langs->trans("Statistics"), -1, 'user'); print '
    '; diff --git a/htdocs/comm/propal/stats/index.php b/htdocs/comm/propal/stats/index.php index 04c1af11e1d..2ec1a3d660b 100644 --- a/htdocs/comm/propal/stats/index.php +++ b/htdocs/comm/propal/stats/index.php @@ -242,7 +242,7 @@ $h++; complete_head_from_modules($conf,$langs,null,$head,$h,'propal_stats'); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/commande/stats/index.php b/htdocs/commande/stats/index.php index d900709b835..534011d73fe 100644 --- a/htdocs/commande/stats/index.php +++ b/htdocs/commande/stats/index.php @@ -253,7 +253,7 @@ if ($mode == 'supplier') $type='supplier_order_stats'; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/compta/deplacement/stats/index.php b/htdocs/compta/deplacement/stats/index.php index 216988b6a7a..36bc107d672 100644 --- a/htdocs/compta/deplacement/stats/index.php +++ b/htdocs/compta/deplacement/stats/index.php @@ -223,7 +223,7 @@ $h++; complete_head_from_modules($conf,$langs,null,$head,$h,'trip_stats'); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index 9d4329a671b..46a7bc299f6 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -1637,21 +1637,8 @@ else print '
    '; print '
    '; @@ -410,11 +407,11 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) print '
    '; if ($subdir == $selected_theme) { - print ' '.$subdir.''; + print ' '.$subdir.''; } else { - print ' '.$subdir; + print ' '.$subdir; } print '
    '; @@ -432,8 +429,8 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) // BackgroundColor if ($foruserprofile) { - /*$var=!$var; - print '
    '.$langs->trans("TopMenuBackgroundColor").''.($conf->global->THEME_ELDY_TOPMENU_BACK1?$conf->global->THEME_ELDY_TOPMENU_BACK1:$langs->trans("Default")).'conf->THEME_ELDY_TOPMENU_BACK1)?" checked":""); @@ -455,8 +452,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $var=!$var; - print '
    '.$langs->trans("BackgroundColor").''; //var_dump($conf->global->THEME_ELDY_BACKBODY); @@ -478,8 +474,8 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) // TopMenuBackgroundColor if ($foruserprofile) { - /*$var=!$var; - print '
    '.$langs->trans("TopMenuBackgroundColor").''.($conf->global->THEME_ELDY_TOPMENU_BACK1?$conf->global->THEME_ELDY_TOPMENU_BACK1:$langs->trans("Default")).'conf->THEME_ELDY_TOPMENU_BACK1)?" checked":""); @@ -501,10 +497,10 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $default='515870'; - if ($conf->theme == 'md') $default='5A3278'; + $default='5a6482'; + if ($conf->theme == 'md') $default='5a3278'; $var=!$var; - print '
    '.$langs->trans("TopMenuBackgroundColor").''; if ($edit) @@ -525,8 +521,8 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) // TopMenuBackgroundColor if ($foruserprofile) { - /*$var=!$var; - print '
    '.$langs->trans("TopMenuBackgroundColor").''.($conf->global->THEME_ELDY_TOPMENU_BACK1?$conf->global->THEME_ELDY_TOPMENU_BACK1:$langs->trans("Default")).'conf->THEME_ELDY_TOPMENU_BACK1)?" checked":""); @@ -549,8 +545,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) else { $default=$langs->trans('No'); - $var=!$var; - print '
    '.$langs->trans("TopMenuDisableImages").''; if ($edit) @@ -577,8 +572,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $var=!$var; - print '
    '.$langs->trans("BackgroundTableTitleColor").''; if ($edit) @@ -604,8 +598,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $var=!$var; - print '
    '.$langs->trans("TextTitleColor").''; if ($edit) @@ -627,8 +620,8 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) // Text LinkColor if ($foruserprofile) { - /*$var=!$var; - print '
    '.$langs->trans("TopMenuBackgroundColor").''.($conf->global->THEME_ELDY_TOPMENU_BACK1?$conf->global->THEME_ELDY_TOPMENU_BACK1:$langs->trans("Default")).'conf->THEME_ELDY_TOPMENU_BACK1)?" checked":""); @@ -650,8 +643,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $var=!$var; - print '
    '.$langs->trans("LinkColor").''; if ($edit) @@ -670,11 +662,10 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } // Use Hover - $var=!$var; if ($foruserprofile) { /* Must first change option to choose color of highlight instead of yes or no. - print '
    '.$langs->trans("HighlightLinesOnMouseHover").'global->THEME_ELDY_USE_HOVER?" checked":"").'> '.$langs->trans("UsePersonalValue").'
    '.$langs->trans("HighlightLinesColor").''; //print ''; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 8de637df3cc..29bcc04d54b 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -1268,7 +1268,7 @@ if ($step == 5 && $datatoimport) print $nboflines; print '
    '; print $langs->trans("ImportFromToLine"); print ''; @@ -1307,8 +1307,15 @@ if ($step == 5 && $datatoimport) } print '   '.$langs->trans("Modify").''; } else { - print $form->multiselectarray('updatekeys', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%'); - print $form->textwithpicto("", $langs->trans("SelectPrimaryColumnsForUpdateAttempt")); + if (count($objimport->array_import_updatekeys[0])) + { + print $form->multiselectarray('updatekeys', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%'); + } + else + { + print ''.$langs->trans("UpdateNotYetSupportedForThisImport").''; + } + print $form->textwithpicto("", $langs->trans("SelectPrimaryColumnsForUpdateAttempt")); } /*echo '
    ';
     	print_r($objimport->array_import_updatekeys);
    diff --git a/htdocs/install/doctemplates/mycompany/background_dolibarr.jpg b/htdocs/install/doctemplates/mycompany/background_dolibarr.jpg
    new file mode 100644
    index 0000000000000000000000000000000000000000..31177b1b5c2bd609f69d46bcb5f40ce6ff9e5004
    GIT binary patch
    literal 337251
    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 *t*wru8UyS-Ivy?BEW;6vH@VChTi0 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 +|XIw%`F&R zXJ(n26@PGj!6W{D;^qg11jlFHa^P3#mL4|)VKi3Y!+ie7tjXsi2%a)0s9p6%VYXfI zBh~H8Mme|V&ipP^XKBks^?EJCTMYWXO{hjziMelp_g^3Jwh~b~hqa$Y$`yq^P>%hz z%vO!5ozwXX78-Yt`D-arwB+nvY(`SLw5=ZFnQ46jvVW4!VDvMVuI3x9t=ir*V|i2V zLAlRk9^@v32!0tTP4mzOCE-BY2Ho!a%~3tN!7uHNg)K6G!srbTPkswCC}Q9-X^4$|DyX*SeDqxZC&U{l(I4L(`l}ife(B093HVy zKw|3m<=b?93yzPV{7ji4KHWvx6|2D+@3Pbn!+y`?H$l+vwNgQAEHJT-Vfv+$y zx2i|9!WZhQLRzUa+B(8Rje%Sa)grm9qBT1mgDi$p#cw~~^^n`9^k!IUU*vFy&sJ!6 z&5h|}aB_hq`v#inz-4NP&}k0!%v$2Nu?QnAJI`9;0;2ww(a-Q-m)p1l`;! zcI*E(Y~}D0`GcZ%d&h4jCj-Q5n8Sk%Pny&G_;!`5bZm=32Up)nkIm`#6LmJk!%KDxIMocn#)}311kMkkq+NHinqGc=DQj z?UZ7P_oq$aPK<*>O!A>l^L_nxI`6aSHIfWYeMo;sRb69Ptx)1HXfN+l%^D-om(?2NS}Gu_4&~I_}Z0SmRagO`&5U^4^(b55^_@kz*;qx6G29>B7%od zL`vJ)F|i)gTf8J4pxt)=@?*}ZoU1et#^+u&Tv`d)3tYdq3pu93@ZI&PDT-edhbqX= zYsjk6uek_tGE)Ulo4auJ;rbrUvzn=?Lo1Bh=}^TX1yitSn&W&^nC1ihgQP z;Ps4BQ9_ia(s+N;ei1ti!F(GScs5%sSw+^(EiTrf->ZSbCC&=)# zTKTZ#ASOZM+Wrk+1r#wmC+;L>%?mbOl*wTItlJ--#?(+Dhh$mNCGX3@2J&bQbw!-4 z)_SgC*t+zC9=sW^1?`evc0@ei5A9JD&h;HCw-<{H-o~-xXA-4zDyNnuWT6hVcs*Ee znvbZrV(K%W0Qry8%QngnKs2t>lP8bGGlG9VdFt68eE=wYh{8_~YH&+|@VFa|X3rcr zHDW1*%-H|1-(HI}vxjJVZ7Y42OOa11QN#N}y~nAlu&VyH?3q7 zU0O`DY`Fqf=Qw|LHL45i>`b2%^~th4AmrQ^dVl82%0c~E9&ep>?-GA$g6Y3G004&3 zZ;0NXJM*?2pywHyROkJyoL0KW!O>fo2OvzOGWrIh#u93hd1^MaUW7wX#H(+3c4M0h zh{ocyV;rw{TkJbDzAyBJ+ijop{I#_S#c$&M!%8pH)2a97!FpGDZL ztl1A1FVpOlg)R|>acggdyRa_B1z8#Y3=OT^N_$H=N%{Lp`0~rwAAT;YXnoN?e5-|JB{RJ?Y86$qsA6R)_hF&yjOaBu~WR2rPGm6%xE)Wf-OVa1~ z6@m3Mm2PD9le!C}7v@mqoX$tSOYy=66s#a2mj!EvO00Xo6pIeSluf2BEH{-_h*xCG zq1OJn-ZpmXG>eNpFRR&-Zxej#+ue$3|08_)X-0}C8ESshbbVv59`GKbQKIf%ZPntdF)W;1HRz+6FxiW)4=>_&blxCp`0hngQxKmZI?I|Lo8CX1w%p)0S)Dw&0JVFSnsHFGOPeSkbl5`8 zk3ag2{aFd~$Jq}loPwGyC=48B)ckfi6rIV7G|x@(pQa#9z(=HR_Aa z^09=dE41QQwniNEIQat7NxRySyWGY%9NN601Jy8+cB^FC1J#I{F8i=%n`}?Y)rRFN z#YXvCE{!XaM%9+rxmPjT zwl#DYfc4%A5RT&Yrz-Pzi^iB4kd%DekcsH<6u|s?3!5d6!0rtnQ_#$9LOT3q?3g|7 z%2rfZK8W)MEs3<5qz?rM_AIHYjR7uLBreJdX1(cOsGOz5GQlvZ!o*i<`*t|^GEsCa)Bk>)`@7kow!=hO$xAa(sIS#sC0xEeTp3SzKD zZWd2XHj};-BG|zIM)%3fsADr)yg~qrUso&s&R|8k^wwYSMLevxoqDzY3l1)*G1?Vn z*N)GSvkm7~{eJRC{wemh{0Rldr)sR?km4HKs;7h%wtP}^c>IIAG%FI4&?*cUgF6?!h&y|WcAo9S9*VqXCk{OThr52_ z(dn*e0|4~#i&BjgPFQImsYrMEM; zy+;4_6M5Um$<;aJ-0Xo5;x)HzW`IMQEG@YTqct`&Ihoaz1rB3ylRu-4*`-b|Vz2bI zRD1`-p;?juvZ^$e$A`UbYxopy)l^~c9F$?v!k^(OD$<*ItUG@Qz?Fd7PWwM_?J=0J z%dYzu#*Fv8z^XR>LQ-wA|4Tx&R71eM#`~4MlQC4W5Jk)4RBPj+zJoVuR>MuG6I$Ft z(V;P5tw~Mq?655lTeG&9;kdZ^Y~pgl%`9Uo#VL^8&U#rPo6>saW~G3?p3Wvkd&1SO`gPOpX1k zo2084Lc9BznZ6E@h`arg5=D-6VU4S$V{AXHB1O!a&@o7+atLoW+}w=iyf zBw}ATp&WfUcU5+IR?rJva`@vVt17Dk6%#&v`r(Tz^$>+0ZZ?!NR;tRyyZGN#06T~t zca=8>Jn#d(^1^x9)Ck-f{S^0w+%>U?_vEawc(q|-QS4D}78RdMut{Kzk+tW<%3S60 zIMut#G5N3GUe5}i(0(YwQpTuCt96DbkIBXRqb_`-R46*c+BaEau;Lc02+L!FRBIL^ z!(rkwcxoxA5>2GW4~th_+Q_D7Jk?}j(V3blIb31_e#JwN=ik43=FrUZW*;1% zKk-gZJ>!(}1&DS6k^Mlv#-&-s2^EmbeL&bNY#0R6N2QTej=SaR_ZI;b8zdd~Y=w&< z+N&DQR9$Xz*3Luq6`xb8zF(9sOEl98vcWnv?V`Psl=WD&VV>+-3p}-&+@5_%s|)N* zGgo;tB_LBUxxN`zf^6T|fzuaMR@g8Y;0zLt zGtZS_BJoUEC0|v}3pXhwZ=+(3w=CBsG3GE#x^e&K$~duBxi_u4YJN3t?<}rXPq9M; zM@0w`Y%2`eBTwVw%>&T<% z)iEEV@}juHDHj5+#HM=V3;K&%B`?n;yA)l&KgihzLvFF@645iu)QZ(8?`N=CZQ6bE zWG!j5HTRrWcyqHOFT<)Ec_Qk^jd7{j)Z}gpo9nn2u7o+Gin$EU7@1XUhKk*0;Bnco zDR+Dk&QrbAnVonk=01KL!m^A}X3-2T7pWmDs>+|UyI{=4G<;{LJt{sE*ked-Zy}nVAIF_5QF!rtRN}+*XZ!qDJjCoIq=DHj&`ELLF+gjIQ59NiC9{{Goc3ln0^3)dzQl#`L!!8K68>h zw5VBCGy?=p9?uBlhJ2k-_@}h%4f&m&ZQ3L;)% zEOvuZ_pJu)E(MiCdN$>A7Y^&llnd$G_&QCPDnpWNO=1(0 z?zXE)WXS!{1y^`Zt$bSQ!}&h3dDngLL(j_yPHp_}3B-h%@QZgEf0`=#8-fCDj-3cp z@)3nD1Wewe-ML@KELFl~whUj6X)VmerVO1OHhLY_9HCI{)<@MW3sj;UVs;0XMlL+| zI3}MEG{vl1%w@Z{gyV(z5Lb;uVU>1ddb(;wp(dnyW0I=UWVUimCd^lbEA91Mu0bbY zyMkot$_0sAho;QSpqrB3Sb`EZ^6QI;WE=JG{$ZXH!DyLs$;hyKr~snf{Z$5D-vG@O zO3shKjvoV~p*moH3cX@yHY9Cf@U62^gocFT5 zMjNa%cOJc3IzG%ACOlMpfW(da+ET8fD8)_3mv(fS`W4a{R-cCrh5_!Nb9PP+1I2U5d*V$P56$d?(2kXpAGFy9E$xCzy6 zN_2QoHf46Z%`ktnth~eV-z%4Tu{|i|iXVboexTw(KJOiN^g7!y?80pj`-*-~{Ut3a zTRVa^YTo&qTp5rE5@~nLgqN(@Yia(FzomtMb2=6Ktz;y6^J2-t8dP*H9fQO`mtN)i1Uxx~wngng^ z$v#)n7;T-+H!|bB!9fIr?dZp3D-&3rw4qE@hqEzv#crQuTNypOhxIR@IZw9q;C36- ze1zS;Khst@JhOTu9XehAOd{h(?k`FncE}B6b?XPX#%s01vmUQ^Ie4q&hE9xZZC7pB zR#tZQ1+AnaQ~HJCX43N;i7!JEdVuPmx~1-?-l4;LCfQUKTilQq`soV=p;^TD^HgCP zM^=g(x5S`L8GIo4b8IGJ_BHu8E^)f5=^yF3%THARRn>YWE}=xeFI9CbKJ`H1pJeQR zd!1X;&*F{FN*NgoPC!om%-}AF8?h2k2N@?CQs*Q2*^AQ>2dB$B_H7L~NsU!y@K@4> zR~>j%wF~RH8;*KiEOC#DkwJ<`8SSs3D2^^o-{9vVp(!J$RJ78VQK4CoxfU?rqBs%# zZi{J%Alxm%MscEVLungiJ10|=D4xL_u|H%%o*YoO<$`Yrv5j~CIbw@{?{Qbs{^bYuRnf&tGR_lO%C}#Ln zxCbKgP)Zrq$?UG%-3B%T^@a%*Rnu{-M9Lcx)7waxl)n(@m;yNp|N(S55$7K** zllPO*B%G3=)(SSkwkY{|`!w=1?jtTS$IK|=#_sc=2lMkR=FcR#;{e?v%U+*yhA)Fu z^u>bM`ud&2t(k+*ALXwIf9!Q=b@(hF53$+tyU^l^9TE!dAbkM2a9neYESGw2Qo}t| zTJB6CL59T#<|2-9Bc$ee?aq=3J;PqHwVvmctD(-p=ueGT@g!9TH6CUl!NGP~%IXs7 zd2H=+;jc4w={A+;rPS3R%+Z(Mxw!OPV>zQx1GJm(-lRZiWy*)sM6} z1uvak=*Suf>qBW$w=g9eN)PY~dL?Py2ECvTQ3Ev->9YH3jPe!6XB01FOn)jrY6Wci zB&GqO5fyt#@9Hll2Z2J(lDC@Ng(*U2f{`{Rai4YEFej_o#Qyey_iiW;YAK{k=32BQ zy<}thRK%z##gx>4$!98$0!oj$;FUupf_O*GYJgu6yUiJ#^&&uKsc{+m!Zl%5WF`c2 zdWfenGR!EvG!&&=ElTyV&e@ocgX+&|GCj$`_GF3QPX_!>bYrV478L7Tfl5dgT(9S| zKufMsHj2+&m@MZs0!;qiaw3Pm)9LM6Ue0)6wG|0a*|2iVCiN_CVIt&ie1bb#yO^Qc zzDaT~P6Ec7AH0z>RuR@UFF?%6^J*sJ+6WCXRbN#;42436AlqRSGXu79vvE*`dKFQ3M)tnqMkVv^1L^^nB&4SRh=XdhSbwH z8Dqg$*uh?w(B#ulc#pCvZc(Ac`=Eo0YqwR`(7M-P9r2>g#;bXmBAp+Kmx z&$$E6X{3wKz(3}esF7DLb0Z%~8Pkm|`V(ZxR$*c7*!MPaJ+kp@_`HqFKSl`gDI>w?u6@5!d_@KKc}+9OHqBf|9W4f`c+ zi}|~>?BkgiS}q&+?utMm)(%@t1i~@a;oW?Tc)SAK`J^qDVJ-lAE8%vE`W*g^rSc3X zDQAEywyLglVx_^%>C@yK8)KP@qA{X>yFv!>Hk+_`!-)*-#2D?nKW2Ib5ml!FvyD43 z>@v%#j#lig;$O59w{BceweQc00Cp#?T^LJ!(YW?Qu4btny@{8`=jcD0!}v;rT;uxV zh)Xq5yX8(6HLYE571r_FVh0N?o@YtAxp}->{sZ@IBC*BHPbXH$fyY^>MsKxse98Pi zUIz%MUiKKm3Bom>MkapmMWrnv9WJyd)!$cZFEr;T@k_wYqD{fYYkIPrd0FEylZIzz z$_()5Hc?I}6Jv=Ki9VFoKbLFP#O^F#wLWQoR*wv@!7XJAE_cJYSje}Pi#BV#!06xz zO@t=c&~Ho#mD$9d<8d)YONc3GFK$nt3sd`bUtF;N=Mt$*9|lBBNQ+mgdqSdFxpJR{ zCfl$kZcwRim&3T}i=h|3?4@bqzG7lF#}%SNNf!jpTW~_Ea?1c;0{k{Bug(^!AGUh4 zrnEf#Fyxg+stOC#M3GY(=$Dr}&}JG@ z#(v3T3CPFv9MfO{8$CsNB+NZ>(rZU}PllhiPqipo__+)Qkc8d=Io&YHSBkf~6A zo(Jh2vm&N@zwO)^)w@y#>R4cQuoN1OXaD^q*Q?R*kHM961~r>i`t6tyOc{S8bvqvu zWrLjp=~;-gLp>%ri!J7U9vxYDJ+F-xRzp*4SWtNLfI&`agh`*LG}`6)+RmK(lzR?$ z;K3*jNH%^w^{k7|OevkZ0N#v$&J7nVrXZGmJ!CUd04f-1`i;^<4SewxLT zcN*H3owT;U)AyD<7dgUS+h_1F1MZ@2G0uDujoG3}sGjut1z=(AcsafQ3FFnkaJgXIQlq7n5Ef z&6)YN7s_`4f?^C$@afM7mda|h@a*s?-0~AE*eAfB*4_#0SsY6POw2lWot(a z4r}kok&HaaQ4Y{3Kp>0ore#}Yk6IAFQcW2&bq=mpp?LmQqXY&CFs-K+58ZGhwAUsY zeJ_I1PFt>>#LQx$LQzERY}u%9?b>oh65!@T3&)+A#dlRL;E1?XQn(NKTYWK!M=2)< z$EsDVGq~4&m|LNmY}MS@d@tb;qa}RL7;sT@DsIPa#eL3NZ-D7YEIu+xjqUs3Z`FQQ zZM8Fc3F2v1bpHMwlJtc5A88VVeloDV&keSoZZ`4>mI*Yo#wEshvmzFRiQ%fIzY30m zCB&`TyjDe1Y$(Tg zCi{yLGq&~F#z^>`bvH86oJ?$^dBw=K=yZ?wO02hyhg0m3 z93fzEP%CO^`p*n(cOd@|T7MU0$g&15Yx@Vr*5Nhs<-YD=x=(I32Px@7jqV9kmSW>W zjGOrcnM#?u4E(t%zW4xyHGu8nb|~yEQ)csP{~Pb>_Y>gg1RLW24zK%| zF{|HCk|KUTA={W*{tm{f96I~pXWLfK+}cI9qC)vS9mDwn?@t6q($JMO#hN*c8~5}< z{lgv8z`8OveE`<#AU2C@ogfPqP1V>AV)(19JYx7qJB*obHmPMQEdTk8p-ElGLx~^+ zXj@x;Q!6~LnxyPTa!mE|*7m+p{erRW&)9S#W^Mp_x8UJ@vfFJ zV}0N2x&U$8iy$thJeiN@Ahmzvk11=GeMjACY}K>YC)qYNTqEORq%s7m*WpD)@-XXr zY(pR(&KXg1nPck^rls=6xOFPoSClOOnbX@@xzZ}%pNQ%l0=z{Zsra4s zcKgQEC^k4#m`2am-$=82zblN=yOiQ5_*`Z$DgIgdc5IkRCpj?Z`DeAhcE7j7oK^t% zrL4Otxh&5zCVJ&zhezFqE0X=Iu`auWeOL<9C_MwXP6O2k<&r|+BxDWQ07Q4bv(k%vDEoRLGJ#G$GpQW7R z(qq$&c&Y$O(&%2vIpPS>-YNMC{iPozf6%8oAHGMe^yvg>-LiZ3O4gyH2ZYA(AA+Y% zCY!~mc{=-0)q^iOe7-cK9E4BL=u(p{oAfhSZpY>bxECp46H)WQQiFelie}R@n=l#(0R6H3YU9agDNL8u2cM9Fc zww1WJceGWj6z4Jx+-i`N7~N-(o!T#Gdbg?33*gg9bzpc>Db8@ zzE`^AK#?&1gRE<&@6GFjyFdLL{=K1q0#8zQn3(901Hp}U%T7V40(fS`IS3^<)bnt+xOa$Lk>>hARkc+$;~wYp)|~S`--SoUso;=ft9i{SbGjM;djZTur#1nQp=gM7 z@Lz_?!xm6~#2CT>PRmg=(!z17=No)wYf|&-;L96n@b4#oo!{H}xB0xXzEoYtx?uVb zWj_oD@u@d4=W=w05NVl>NJZZ=*T%xb-o_A4>HYPgqiZRjyQ)(zpJnZDgEzUQJ$P7g z4B3u<3XEQvY>wlA<@`n|BLd1MxBx?9+bYE~o@NC=lS-RWltp(-<_*~#!xGn#WgOn< zGDqNrdR=yKBIMy6qoPu35H{>_(E5}*H1+R&^Q6g^A;p61LpQHuaQP8f-_hA-c^GY^}$FZKI7zwDF z;qvj5)0)LANGi|B2HQcdG`8mKC1Hv+$y}!l?esp#V*rpS>-Cfn8T|d^fAR7E-5yXQ zpL(NSr7rhAZESk>r!r~Q`1K;1H={WN4efQ(P6vc-5Yt3c@ZWatJiT7DP#MJ!nvDrf zNo(=S+y)1|9m$g7S*D_5B^va4X8-5xrA;H%?lz$=J`R|>Fkj>14mmcBwZV7AvI6@j zKa^$7vy>e)p?gZH>DMqkT7C*Tb5Z`(^mMfm&ubobsfw4jr=3|nC-I=d|u5B z_U!{L*nOt#edj#`)nDl(4i`gHI41@oNSHJ zAIqyukCU0-1FOdc9iHvj%rgH+%53YK?+lkXhciLP1qa~fB;9H!oB#F7S~04^9>G-r zt!o{oBfrS^@ZG>P@TZ`Ga}U0h4BV1;B5a(f20E#eRBg>vRf_R;og!l47)@+DNck~G zjw5{KG1!Fm*$??t#fK7p-^(BSkDT^!A8JVI`_rpYz0n3Js5C<4y&`|g!HpjNX7euD z=BE3{m#1Kv{O8p}VtiBDJgQ`b$@)ui1>GW<=YU6!BexIm!twXR5%LBAP z9ye3re|n!;YTw$sE)jo7Da?a=UB3&P#Fc1dQ)W|csjRb6*!!ogWjj;hzef;Ru>bdR zQAe-4rfIk&aEAhC>-pa$g>l*iPa3Q#1a=+KeFybIv|jha@ujhQH_4_vtK~i-ymCw- zCi4&E)8EVwPjd3)nU!T2;fyJKQk-PTmfF7D>vW+}*;nBo`<%j@V!e#Y2mKkY?G&dj z>x-8EQ9PhrMm@cay6-&L(AYMJaRwtsA*L3&>MF*3C^(!KMH<*3>5=hM5G^0trEuz~ z>=jPH)cc451Kq2V0EYr?rn*fy0f?JNC5IfZC0nJsW2*Akdsy`)WL;iZ=U@TR)Tw=L zB*14$UZZi*LEgs7zp#^WpgJzbjB1NHu_;XTLi zCl{?CpV<@!LzMmFoiKkm6>;QKrw3}7vhCr+_2{knP3OT=zRl~5Q|}> z2>3#G)4A-FZ|XYZr#E1REO?hey556Uo7RdT9gnn;iC`o*l^S!9%q>JQNLu7itSbNa zFE<^Q55RFTb74*k{^1`o*9ie~nMLo`)L-bXF*NU7$lrG=Mi>v=Z~Cq|6*J=`Xg4*c z_q{<&@s-AJsQRxRyUL9Xb2{?!TqQ_W>2Gm{aE5R>OM!1PmUk@;L1Ncw`kPkna4GLD ziczDlC-V4I2TXD?1KK+5lyuFzhmUxZZ>H_h3`Kjgqn$@vO|qj--=oMjh0MWd z&k1|b)K8DBdNTC+%#uZU_o#R8eCPMKm3U71A;!4Pg;SJ!B2 zYT0ntG=~OV8=ed8;Gr~YbGNwXpiX>tV`Z%=jfE(W<0rXl!lLa9_Yw)1Cm-Brbouua zQnb9{4ler4n(ioDlgH{30=WN*cC0GN?*qI>2RqnzIQ+&_i-7N{MVdvGm!fPQaNpIv zC|FLRqAJrRl{lhrjj)-5liV;dEKt{vTCx4y?L7I5A$P9PPa2p8pAW{Hrg0y&?Qg`2 z8D*M{?fm_ufV;eyUl&tXco*fjkW%bgzf3q^F#~pgb2tO!IeoHE@RJN-+v_)M+x&o} z9|YtY%dqV}N(A8e=g4DPs;2+vp`u5m-@{V?JpS(+nKZSL#~%O>t^zK=Awf>z`1Cw} zczj9%B4z2&$oxJ|u?gsE^)%?*gWb*r30*$6J8zIffdB8eApZMFY)0|I*~&4CzQT`6 zs#%Jb@%^hDi66K_P$I3$^!B5&^prv=Vf04Y0F}`ZX6X+ugVFbUc-N`=rcSH{$_AAh zs=01uA40A42ef5J1rX>AWL`&Xng{v&JJo6eQ?3elp7$Wu=D(5*NVKzG(cnV? zAm3cFUxf6|ohM^72uG+^beMM7Z?#GuCR=;kycNF_yFZG8;pN-kPuBh48FyQ2*7RV{ zBvcq{8g(boM}W9*neSNWw*Qj&2PJ%ghslX|gvt+ZZ~+Rx$~`xuJ8sAcblG2^WwT8~ zvVaY+RZic-Cl1={XNm7R@sFN&D%?lBxkrm!)6JB=&DdPsrutEfKthU03eW8*nAoDL z-B{v^B$6bo-*0&NB}?H%;JX$_4InLEo$uukfk?}|bVs;RIedfy&sH|0vt?eLN8$Uc zPqM{D>l9<)qD;d^FQDpG=m*tnnVh2M>aNnI5Bbc#DYKam#@Gk9f2g#5dSt*#zlC;S z)_{$?PH>z-q@1j(3_%O8Bz3Q36PY?*idr#gEWkl^|I@ZmZ(^^{_#}>HD^qn?k;C&^{(FH-)PLPARp&p9yaA-!;p{CVa834uk&uq zWwu(uklA+r-PWYTg9*E&*mYzJ*-P}m=#e10l*f6ZbgNi9Mzh+3d@y~3OZ!13R#>dk zS3D!&g#1n<_B`1;q#V2<*Zz8NxSY>NuwCC#9a$sc?PFrjNbl zbxheWO1|^jf-T|Nn!By356A#N8i` z_-)1%2)w?dj2L^*_YKRj=M&e8hQFU!o%>%?YK!#V3{jmURrj=drcigoWx01fQ*|+^ zH&dghlsY=X&U*qhFejBtq<*tAa3!t|sHl3q^k45q_Y85lmhNN#(4hmWe|LfHr0_y)^s@Bsy z@XZ&ICwh>>TV3p;vGou2MPXNet}*z{L3yM^M}Q0gH%X@|Z#h+uR=FNd7gbpYb-wHY z>A$XPp3+3HUZzY^Q~gB63uea#R7utSMlgeKiSE}mNu+iKkt{q2pu-5~pZ5z7 z94#zkFmV;qkuB0k$K&EUt8y7MMYieO>s-LA?j0G|nbwmrA8pmclYa)LO5a$LM=4FZ z`rPH-`rHCeKY-!`c|pK707_48P}(^P6h6-T>y$Hk8RSXrkv`SnYwlL}z9vhm)UR?& z{{%mT)c56!_3#bFow%el{;QlMf9Bs$cHgz_zzSO&Z85-9@%|b9GcS?fPd4Qu%UBh*<>_E6YX!RQYMH^)c&}*{kVV;fwv-$_ zo{}@`yVARXneV4s+N2#tkWwjFd&l$xVzqktG=xf`UejL3n z-D2(gUis7D`nC1`+vL~dc*3kFv;z>uvneS;!k8;fk&of&y`~4Uo-C@JL!)mtLAB!7 zk-uVFO{S^5d&OCl8Y(=tkFkHLdDvh;_k4{UqDZjLrJ8LOxa$AzCkga{>iFnAx;IAL^Yh=GEeO0;}T1_=89OuuaNkhieSlrCV z^ljYLEzx-v=FM<_HLZg`)W4tTx>Ih39KDZ)u|H7cRT;iiN~$CKdcR@5`v7~FJdNKj>G+dMQav6a#{#mCC_v3^UvJVhdr<0h>Ea5Ds-jO zr;v5NFlbU6r{xeH=_GQ0H?>KtRvhR#u+iA>zuip%=006!L`IIA>w4tPvUR2gW(A++ zn|VhQ2co-}Qsb)HJf7c(y9a6U(Vp=3DD1EG$-UYMubk`3*1-wAX|!+|bq22&%g3PA zOr>~S;}?U6u?-H8f9ZTGQRg2~z}2f_JTvH|ol(~F(Kt7#qN^Tt% zwZ13%SpZ9!D4)zV^XOKo3uk27cMI3ji9ubd!@Byx-0#ehV_rC~cR(l{j*RNmq&JuREc>N9DGmVr#bUw^IY=Mb4 zbgr1b_n53g9zvtq5vWFa^Ts52BDi8h)op;n?`)#~ho#{?H|Lp)J%NyfYD=%hA7RUH z2S@NvN#?#Xz+3Dr0YM4nzIy_ zAy`ksLzLrVp;L@#L_JYEfO7=SL-r`sxUheYh7A&hXGGbdD_ZF4Ws80_+Mwg$T(j`Z zSsQdhUDe!@DxH`OxT1HQ(@ETs9y*xZO)krVs#R?mDsoer^a^8^*^n-Q(+gY8yS;Md zfV3CQ)YJT|#+P%0NM7khhT&r}#(mI98a4;_z+#ky>rjuq)K2-YsvZGraJgcdVA*AufBHf zVl>Vo zaG*YUnF}-r=mMo21s$h#Brs13Pe0=z9fJ*>5g41U7QYxLW~-v0`nhueY24vwuN+23 z*QCl}f^M%j3QMtSDy*kw;xeXQ{!wCXB0Kz`OH?z1OM5z2B9@@ZL2<(s@D?DpZLxF+zY5Pa67HV> zR$y=-Hbdp8$-|cvg<})D98`D^)g*<{8S^=qL>|$6bDtY*7&j)m+jH;)Je{V{Brv1 zoUmvq1|6sKjid^jt}yHbE4d2OS5R=L9^c)w*2Fv$22&;}z*dM#WfSQjLYxhSwXE`Z#{hwX2sP@myT(5J{l^Pn<2{K2wr zCrJ|E*K_j4M&8Lg{pJMbX0PRG*FjCT+VAwkl-lJfGRNWsP^re$#tPMV9HjLcJA4pt zZoQ^1<0gfq=V~oL1E<2c>&P@)K!9oGMQSdPVO0U^1an!dt*DTZjmQHUxtbRpWsb;~ zSLdtcOXBo*rp)2hu(-?Lh-U9M2{DZfXJwaZcYpqIQWf+uj1N~rD_Ns<(Y80pvQnq9 zA#_KeP|qP5QqhBPVA3>K#Xwm2`^mTT^805Bgbb7TuHM`Bg9#7C9tjuBC!A`js88UQ z=gw~vidk;7G1M_WE(WXrB_R=pbuLcMATJc)+HV1Gi%W=1S(NP?$>CD`l*1*vUc*w& z)k1pG4A4w=$L%Dmd$^!K%Z%+U&#%8g zlePm-q94Z^S+yBTvC#f<8?$>Mm}OrxXli=sF_NR8kNGYwUByv1KV@oP{x1=hli4)$ zAm?4W|Hsr<$2I+Z|4V~(kCB5>N)1L!ZDVwbgrdR-M@k!nQiIVONQ;b;@(lw-N+n0@ zCvf;h=>AyelL7~KHtX={@CDkUpLM@_udotJWnf9>|9=+b=o$@Qy%7m36q_+ zsIdb=X1ktPNVI5|UWecd9FGQ__;R)L#tJI4!mMU1>Mz3yQyS_v?wK0`@;L8%E$Rea zQv4KPsHzQ5cM5`$cJtr9UsT*BxtX+kBf#c$v}Q1==OwSV#SKy5S&RgJ{p22V%meZrr0St; zG1y{2!S_wg@EI|Gj5g+`&RaVme)=}MR;hA{OhS4mf9kW;fs_B#NRCBUokq9u)^j{Flhi&UPVj$4B zCs#u8Dzoah70b|8Tb=BLGzrTP=eqhk4*0C1qF(7Qq&|~;L!$pi>UyVr?~ixEbFtZ> zn`Ls1v1^q`=Y7%;#rA6ywY(lbQgNn8;0-FI;96T+!sYx~Dsb{Wmw`W*)c^oF0k})R zHU#FBJ$gwJ5dHJ*m1c9@>?(4sQQ9#GsN|8T(=Deuio#`t@vIgmZ;17roMS!AsBiv@*?glN` zEq93W8S*gx<#;FOXKOnR?fQdlFY@A5?v`7sck`peFP+xp9j$)52{fp+tDTdFuMkj- zyhC0IXM46H!{tFap=hO6z=BIA;+vbD3$f1x$#1w~$ zI`6m30GdV>L04>5zUV%w?3%venzrjt(fm8wqRoXkJM>S;{pvrydoHTk^3{MMS!Gmo zM{%+v05bZ|?XgPG$KuDeY0o~Bs!k{X%m>oqFTkl>>R+T&Qq^BVonVSST+|a#@W!G2 zuMr%d4I!n^k4)08337#u`3LuFd$x@_oC7d@_O7YoYwNCBiM1saOs3VM6S?|M;P z-O6=SP3zGIq}D+<)$6}1B}p80A3_J`!5`7^_vMJG7dYNJ zk-7%t#F-y!gykvNkMS4ut^=1SGVS=|&fF4x8CJU3gwJFCB?3DKI6V%c>IZHKywwy@ zbc~gA&(zv_SN>KzZ&EHCZC|qHJqWzB4?t0FQzvT@ z(-msMwQ~s-fDyGOS;G&=S!ctd1uWsbBa?q7Ew^Ty;)&nyWC@*ooPYa6Q}8er zaAAIK{co8oSN^}}K(VqPKqQ)DjV*AIZ2#4>VW8CV73Y780Q`6I3sj}@@M%4OT>H13 z!yw1*$iF?>dQJGZnG<&X%fSLCI^#Of8BIY=!80z~0C4XKwD7;fTfTDfe@%1#yQ=;! z^<;xz|8um)%>bkM>)8Tc3;ve^PnQf2e+TB{ z(CVu1zq18U{l6QFVx;QB`Nb2wUZBGnd3BD@gJ}PwbQg|T03bB0RL>rs0QCZNIO7i> z*B;l^Olm1co(8V*{~w!mJ@BpnI}InroSNR80h+J=cSkvoDS;otfcJ~jP9~u$i{!k3p{e!p?`4g|Cm0w?&{FyzY}@V`7_9?w{2C=*Q93ljkST0BGZX-}zs$`jb)qJ5oV_CI6_-{w39Rt@kyz{kJ;h@XIh zpXE74Psd14PshMS2mG7@et=8H5Ey_2E)^QDMj#oJ`*yxfy|?%HFXT6!5rl{`WX$j` z+L!r9+*>Jc$xE#z;yY5Et?q+Ble5a3xM1yav5(idu~t(fdeBWht9eO*2w^qXAzG`f z7NoDu>s+^xo7ij|1zY2E7?*UdSH0eAC5-E~&pO{>BSUmx7;Jlmk!TqZ3Xxu>FM zMvXng1*I3-dZ|GustLwvS$fN9b7HTu@c0AOPlZSe3L6AonqQ~1%PLVC{b|~XRT~w9 z)Qrc1Pg9}Z6+BZJKqE!cCh2gWYO*Fe#rS<*joLh6D_WS<+x4*vB*{35Qpd1{@%G;n z3`FQi1xWB1q)H{W0MPR)a1%c1!3%qJ0+~D}36hMQs$SyK=sfmKYu~}ZJ2R5!sbx~d zH)Zt>d48bnJo$Rwm|9*ml@d$BtQT#~2qDnnTOiG{q`+Tj#@dnPti+0RAOV&Q)llKH z9`oR<78Eq7aG!FESL0W@t9uenr7UQwrJTx9%o!s55iQozucOD6TfR~LJG*>A!+sH# zS)x^`#Ix$3{RBbrP89fXfKCQ&gT|G)%YWO)qDPYYwF1$hr9WVzo;pdCzNg&SxMVZq z-&9ZBNGfVR%_sGZ7UjTNNfShUSebgAK`1M?CNc72dr}E_o-&w`2lsM@Y-XEE6m#Yj z$(nFun53C-jd47#L@-Y=>cRrwj7);RIDAP4NoZaUEP%I+&RcXEI;fC|imA0APN}Up`*DXtW&!NI4 z_0_JIW>(=q-h=}YnF<$ zSWE{edUKPg8u2Y1OQ`p*_G|N^`N3GXh+e`u{f~idQOOm@m$XD`+wbdG9!qUc~NJdqKV1JyzQtYIc=;L zvRIN7#IdpgFwmYTM2PkRcIfp+Yd}=WEfe%Ac}ML!i;Vj zg5hOgF6A&xq@@&dbknsmR?NiR~zcu4IY1#8_SOGibo`OIP7k8?RTo@Io5vL0_6 zY5_uBkY*s#4nP%)S4QzaDsF%(XrjuTm(SdknZ?O*YJposN9Sye->`>Vhf{EVi^)VK zH*tBu+X>J?w0GRR&EiRQYkYKN`mS<|Gm_KwMG8FhH0|~XK%~U_#5iW$CA^lC;{w|) z(Se)F2^>k3Z4PWWvQ4(KoK~yBt1q|W>b%gRP48^!4e1DQTGWm&Bj7gkNBl<~k?k-N zgUP9!%x$-^YAdc#t=c4ZPEg8)pdn^X63;tAibYE3GrA|pEA~`0!m21(-Z+TEAz#sG z7s)Yi;^QxN`?elqb@*L=+FwGCLg!u7A!6N5v3i&I~dW6R-DnTx*vg$gEsoVe-)OP#6$6c4F?6*o}{It9P z=s6GK>Unpc0{?s8Cd#k!L;iE>CmiQ<0U)NpWq_Pvq(qu=ljpNqe&uoH#5kdm0Qfam zZN!qQsHUq%a;m@S?wX#SZEn?u$Y;?U$JLQoc~V>0xkp(JoGb0=xC}3JhjTKMy42LP zRXyhlrh|HhF}ow*wV=S&^AWL#1K>x*TNX$V50+N`J9COPkTd5GT77co)nH?*6eYuI zj(I2I!X+ghRx5`~d{A$8SOc$Fm1n*bA8yJVqA)Uzt`MOZr3E2vgyG1dR}pMw=`AS< zjC*IiC+A#6#2uo>!KI*s1lvTgJqL7oOjiLsAaXmez294TA>Px3Q4y*18M)7x zWlj)ShREC?kr@%k+yw^5*MY%c&@so5$cB<7vZiA1%7a~_2zjZ!xTVBRjcNBj5`;gE z`MyFdSNso=eB9s+nSSNdgksg$eqH+6Zw^i4U&ZzD=ajcs!gZ0e@|euKC0oHFb5d`Wl+!MJmZ{p{?VFCw!A|F!zx490YMmH{ zkn2R_uM6{fT@nM?yjQRYN&cJ_$grC^z9*0MZ>%cM+puR(P^<{pk#Sy!Hg z5sH>B`K;79tO0Cr!Q*uTKf>1IAM3p;SC2AExfdqX z-$W=4axuNw3wnOxkjHpq=c>26*P3^j`iH(A`+JIBvNtoY{*;pav;HkDSJ<-(CgzJ& zIM7hB!xpwuZyaL8MLmeg{k0Dqx~M<(Sg5hg1KucvKAYUJu~9d^VM?LCMmyCBXeNT!t2LpT+nsSAx@MM#;LSiwI7%`N;l$g;v5MR8(QO)`E6krfO4z zsGQ3}4I*^$v^zPwhT$l8gOiR6I6(`fOm1vcGTgu)I340kIWeAH8W~Xo3%f+qX-uAgIK%h zS5&!>D_FtOnGU21S#EN@G4&9P6p`^#DK`teuzr_fv^4R4flhi;tnW&eg-A8p;T^NW zmBPl>^*wUwK{_&WTTFqbXEqz<5ik|bV!RZ=-P9M1heonF2F$ib|EjiU4V9g^FF@s_ z*5#*;OT8F*WAV~d9S9rz0c>pL0Pik|GfvU5c?T8tao)WOxm2!a(j(LtDn+To?W9zD zN-cR&W6h`=dgu^Mo)Tmrq%}vgShtJ6-O`)+{ZlU5su1-D0pMwQ^EXKQ2apzxiQxJD z4YZcYRvsnM7Y7GIKf!H=56#CT6Bzu^YZwViJ2YC_Et9#?sy-sS{6hjAuhL8b#>BpP zDpR2uJAk<;#gnLl8M`pFhLlYF9T=egEpeF*#f!$_nq>4e5gv6Z>OKhH9H{5CR)YZb z)qT)5y4GtHqhydpiGV|3dy)c?$XhM)LMV1$-?7wTwL=&rP*6{K?BUXAr4D2>J!M{F znJM&n;#niKY>Y$1$w_KhxfwyUe3HnndZ_d5kXx>`Fr3W z1$w9uU_S)*xpI$LCFbiz%_5L73Kq9A&&L5C%M&EILy)sTbtY7}f6anucuW{97#Ez} z3`liaCnv6Om4TR7)rOueA(iRwaFOu1ZsDupea#jnGF@{3LITvIrfOBFrga10W)f^C5$e@pKI5L7yS>5tp7^TZC(Ts#Q1p zT4Ux!i}eNfPT%u&)%qwE)`7AceRq9mDZi$Y%)Q@{IZN3hfMs?9K^7GOX})+|BIJJIxk|K?i{}Aa}1rg^9BMX~)n0rutPpCZvope+qm-R2-*)3ezNR zbLq*@G*@OAjNg+wmbBxSBMezXs6SV(4`v?qBLGdLM{sRHUk9+)F&wVdYnFiTj`A> zzC?PQ*UN*F{LR9K!_CZwS+w4?<2qBj@<$*N8RLv<1;d)?bthtmO@>y z9Wlg?R6gZpHQ71>L&6jS$bUE+))kwUVbaHWOB3vi;JfiHcC#5nhL!L`y zY)P6#@;CG@-7Q1LcwD@{$aGrFN`@;fI46A!&Q|0DUJ$EX7`Gk}XV^djW5<%Q*BS0& zz;Kju{Jza@24>su3J$KgnR@_gi?FAO%5*@k zGpY~vkhe1eE%%L^sR6wO^_-Fpdm^bejG39xd7NS(8cPjuz@-x}@V-ZYhNhRY_m>gv{f7DzPY%E-)=o{p(XV42^= z-mF})@%G9$z4Mf}&cpbfITXBc52=tihUDW|L)?^X3wwYzhyjDesMaY{eVxya3(%iD zdSUU0l;NKc*&)v>rs6S!MxjA?4GxQkgxtVo4eTV%O14DBxA|d2l5IayD(^)r<{;j9 zC|?p9aUT!{#98P8r8-oqd{I;uRQQq8!G_$%ALVYEiG2;mxUwlY?N(N8NS=@9Sh?Oy zMPz6N7PX1C>)NZm9Zly1QE+X#^)a43;w&~o0}+UHk4qR)eVmp)`4L`3Aqfr+k)_$O zn7;)SCJ~~P7Q$(6qzsjfadhx32hOdQ-y9QNe2hG%_91X%BsIliP?j9D$G#ckaG;qk z04>jFXBonffkesqA0Ty=tDG~Dw<;HQVWe6~^+>eg@PWiiW-I%7=ro8|N{;_lUrfFn zYe`Dra4!IzD14VD1J5p;DplTmQR4vIJF_#Hx1}k+ES2^AkG;v zpR_OWn{3bc7C`*cuA*(~l2a5_QcPBEMT+rn2mdP6vZzUbg_i4!$?~^@{pTUDN-6~h zR|?Zf)RA=fA<9W$4NL~0b*8wzNA%`lNOHP}4c?n2%pKR7Ei833eGFmh&(| zyRIgibRe9>+uBVnLHZ%CBk106dc$nBQ!fo2N>R2Qxv;C4E`sASaK^;i5`F-}(=`SR zulk~f0a{{f0IaJnDzeb5g(95?Tdf}2WDN}3 z6-&toKwhkxBLTG(LCG}OLyHM zF7Zs5g_l|574JrChIX`&9=eDt$oKJpgs0kK(u(x#YgA6hGjAEDm`uC%0b(435Uv4V z$Jc>$&lR{OxU9~wXL2830;m=Xq*kP!&L`eMo|D_bhIyB2kf!ZC^X;xr@`F7z7|g?Q8@mMWo1s;9w5rO$LKm>zn5Tby3t^ zVTmXhd*3UI-%8QysEClOrgL~t6{EBLioc{wCZ!@0cTGyBDtBRDa`X&5Zf86EBjwkd z#oWVP`#W>MkB}IcLbqv^p8K`(`#G15DnfzF=+SGK?MT%wO3{#Y6e?>k^Xs>_{78)g z=8$jX%0Q*HHvN(;zyq9JATd}mFBJ!vlDNyWSm3=Yl}eoW5QGwQP+osgWKoM2^N6+5 z2;jTqC9mJFB*lvbv#jJ>rI3z;VvUGycO!Q_%tnI(_I)aYl{{0-Mvpc`2ajRr z1hj@)1ltV|TJ*ky+i9%iZscw8DT;zZLVm)vzniG>R3WRw*}!G?!1GG$9D!cGG%s&A z3`a1q@FPN4Sg|*0fDAi~j6lhEbXjzXw95xZdx`QH;0J3EU{1ymxkTp_s?Q!YosmrU zFrUZVk zzni)xDL)bHk0p#R;GZ+hzPx^?Q(vdwN`5hpa*TH-(+9sC=kSpq`2A)lO;r&?@z#98 z?Nqz=2f>5?wyoPqQ;14`-%Nloo&`0Y>dTd&*#u*P{$Jg&E?}-IlZm`QF+gM?)gd_&V5+$Mh z{uq60_@gCd@_2RMLeVjMaw=D#`A7I@k8`RAVvZ(WrxqiD%uoGl@|U?Bd9yO!3$ z$8Vx8c$&3|o`>p5HLT=RUwdrR|ErMJ^Dh0HFC*iCz~H+?abKba1Is1o&E6?SXQ5>g z2ARQEESSOlbkyc5Qyo5STl$do9+Rx~_Y@7ZGh6%BN`=X}88bEwUGHq}Tn*us2dyj7 zKVg^4hE-&tDI>SZ(ii!H6^L*hJ5N=Ng4fU(a$cGGz}GKz#>>10FJ@D4$i(?R{nc@; z+=Itq@?a*4xTX+`qwUo0b&8Rxv`^v=LVbx5h*%4wbBplF*f&onZ!nHU_1dlJ%zuMw z07B@N?J}#iKV^~w8-R#Vzxx6ZEA&`quQL?hz4wN1KxiIE36m!rX9307P>=>uxF+cw zy9nuI*W-8sa#emG`tarxGB?HqLO%$prTVKcMR;2X%gOVaUa$d!d{V5WVWxoW`YJBB zp<({HnkeilI*ub61VcqcH*zOJO+DgC70jB9VTQHTe31qYzwEkG2bI*I-meI#T>{p) zQ$=<=%?NSRQ#{FPiu5Zl@|k*vb)@dc1J)(}c$YAc929F9e#Yl0GeJ+mfD|R`dv24h zll~daE2(n83kBN$h3Y4$uV>ANH<_-kHF!Jq27mH+RgmkZLMo&4n7r8jh`}e&;#fN3 zLJXbHHy;=@?)X2anll3~eMF%fqn@i+F(F@A97W&ALY-$^7fO-ILfMiHR_bV^H4 zx!uzbRr@0D20koR09B&c=?9=PAKGek%!RzRtM29QqM2@B=i7Z$m9-^QfUs)b&HtR{2rqkqEXcrwF z8P?JP&F3Y`0tcXL8DofA-xG#SJq;zkr22Z-gvv8HsXQV+`6BoDZ*7EB{DNg%;r{%X z!o)3idKyT4>?c!M$*aQy=;*u{MFD_SS*5Voda19Gh;UR&UUnjWGc>+QKpki>)`Avo zvT0c3st1b8C_BRZ>5DOUR~ptL8%qC)SIprHP4FOSvvHkKV7t(Gwe+HpmdUYr7HbDs zgFHOae3eT{Iq+%kmkZ?H1qFlRQ(;nBN4-Pg9B{wZEY?ebO$c8R3?XRzD;XBIf&3BwL7CH;P^$fE{m>gO>l>%M(U8wMzl4&qCy zz_PID&PN`66KyO(JSOKzW>?llMRKc^Pf~JUc+9pYh-1ry-hnlBisruut5>G%0LCkT z$tbkDR$BetA|p@9lP4-JRLU&}06wX-Wxi_iL(*g#hc}T55}dz0gccwRs0}E=^{iyy zhcwP*rGGXOO8R009`{TJ&<_9*aL@z?<9l-;D|Hn%fz?0~p558P>JF;nh=4)76DJ*4 ziRgDfh5mEuZcWqLOPyt(*S&xr?|mgT77JJj``~fcQbtlR`YL^klO(ydI~SoXV1j2w z$Cvgof3v`!##xO092smX9ldTZu2@vj2g?2ANM;Znc~X|LrL~~;C;UP;H-TSRB+p9$ z`Mv3e7FV#Z`D&cjZl}w9Qfo|btl}Xlc&`3qaUHM zN3HZiKT<@y+L|nW?GeY(pNF4{%t~EWMvZJ;8$T+;@MBFxA#vO=P`#(>@wl7MLM+Y@c!Dgq_PNajWMeBmD< zY?&LU$flyul_vSXl!)sJ@gYJPFF55opDY9ys>v-qp693?&A}I1nmBH@>Ay*_1A9A9 zdjS42-cMqViVTe$SRAc9*_~WGQ`(A{5l5$Qso`T_TN-9x%uWrqWVm^|@(iP|$7z3( z90|J_mQ8pD7Tiwd9YODibBFb&KHQz3f^U(xCJgE^;&&csjGMI0Z>vW36m;VoP* z3ib>(PR-{g(sF`0{N1Y`=9xVFcsHRbW(9gHI+~r>ZG7**gOt9x8hmL%M0i)OOx%uZ|u_qM_Ut}~Z z<4;$peug@RfBnxX#*5B>hWz#>@pA{&dC#rQ2Qv}@-BNSKjvm_@|D1tlSgF36B$Y4g zRBk72i>k74N`Nv~a%j->>_;)7jDitU)2wX8mS@cChfP<8_aw8JKB9&bS#l^R^p*j& zIGM`S_et=s(RMYfV3`rI15SLm1Qd8ogzS^WM%;u%DS4N< z+RvL4^J2}(=Am@u`K~1X%llaHeyXV@J415!HP2{hCwp@@L2)D@S6#^IU_?P7Q4By} zGu?$hAP9c<7J>=AdS$g)W7TFyOYLDja!x9snZ22NCi>ISSIM-XZ{$4_9(T7`9-}_l z0p<(c>LuLUzza#0Jx!Ny_e=8MXLfq9*Zu<@LR zrzEG)n&lY$U{jJd~t&pp_f^uR$l8f!J#r| zi7z6i!rYJ5p8OctD|mt1c=DL>+A@lXBycRl0lB^CpacET+sZb2 zGcWX~j7rp7>I!GQkoWylereO==@Z1B6|1qm!Q%cXuWb>{UCW!1!DAw_I-dPUm7L$^ zkq55LVo&;eON5=%bqy7b6Nt?L?-=t{#*3S8N%88lmdInEmNgx_XFUUslhaBLy8fUz zzol`{qoyQYj)`ktyXEvCA<}g0xmo?l4b?p_{2rH?=_6KwrY-b8yQ`Y!F(}jXcJ*v; z0EGikD@!@ipjfl>(&hlH#AY31MKwHumu}iK#lq2bqkbq`4wlxm$06Q7287fO{I8R=u4C{eK7{CVTwMs^UA^UY%Qf1 zQ{L!O&NZc9xxZM=`?h#oSoghCM$Z=aRQsldkF;Ihy2GTSap5SCv|{2*hQfSEE|OwfXW% z*|pD-TCBXMj$w--;2z_{c95Jr^V#xjteG@|k)5X&xERNw_B;F0En$AFby7d8Dr+u^ z2ap`qX26&wOP6#I1;R~xUWpo5p1RxXY4MGa;Z4+F_LZg92_&48N?dK6p96!Y7@WK| zQL(HcI^HLOrs*TN}qPU?LS|1hPcwT;sgn&bLMPDBeIDY!7!Sg zjXEu`_r;Xqy$p?aQW>8^Q@!!k_^@K7=)!v&8LuPt9lIdD*)JfeEjNBU3r{B%Tc2L< zrSmq+`_jo7KF(hq5*Us&_pqAJz1PF4ROk57i2jX?np@Zln8cX5n+pDl>+>YWr)3F$ z#B%RO+k2->dfc);FnZ77RNQ{R-$%Q%k+7l;sY!{nsZ#3tsZA(m~S%bcd1-KltMCdpBB+hnnlW3vw4_Qc?w@b?p(lrjh zng8jTKE+vUm!O|hI&qtqZY$*Vt6`IXp9jJ~3`5PJ>2hOlNqWr9bCOTZ?Y?4@WXSF| zXR=RWTz}BXt3*{?z4V)X=Ga`#{LK^CT{@J=uJv1+#myp2b6q^+0ylzH2YR{hZE1aF;-OT+D0@Z~WZz%W|XVWSyxfR9(Wh_|i3z2Q+R`9z7c-(KKlA1Qtrs zue`LF2T6^E?qTT&HvPxB{k^jganP(0nbVB^@bTDMDp#l213IqA1qPF`y_-fiUrZCf z*rHZ_su0h^vMjVDN;D$(1cuus3#y^sSGMI#!Yrr9lZf)mDFLak4(av0+K?A~KxBg~ zA93Q*eyaMD;Pc@OgmVj|+Q%Ye`sOY3G&~xLoQOZWb$O&2UtUE2d@!KcXQM#X>CPRc zy+Dt}Uu`C-z4yvkB!RqCu8(yET&-d@4Nv2etZehz8Nsr$4|2YkRaF70lq-Nllh_@EwolR1ykq7Rokm^|lh;Lz` zm?kAqwnG`NS~zxJ_*_zrn|uV^9QFFz+CO&~idd8Y8CGjC;=?aqo5#~Pwg`(uO@}1W zgiG-UqJ+iUum^GmT6_gwj=x1i3==B{=*Ki{PxU?MaraY;ak5gQoe{4WHrBQ)yQv`<&H96?XWeS`sl@@ z68?fw_qDDllev_1cNuj?_30ko{yKGSutsHdOOMl}ds(VG-+k(I&Bocx45D?S{`J66 zUSWE~aG_fAYZa8$Xy3HZwp>+?r}O}O+C<*>NKzH$u?AVT<7|T}q6_ChXkhESB09!r zu=h*EWHdx*8B_K8iF`yI+a1c#k(Au$U5|qAE_u%}N3(?Lmt^ z9^RPYmpITB<0})#Sl>p1+V?%}cJ$8~R{tViGV|b#EjC=2|C4Mx7Xp%$(JE+dLt5jC<9dw)raW ze^a|c$C(7_hpeLf-k;WHxLwyU~ zIDqm3f@(7V>|^Z~)vmG|c@>D>xd*Xy$~Gusn$Up=rR2P-m;H10ph{wo=Zzj;ivxz2 zu6!1&HV}%ZP6$Kg`BN);z<_U3%CqE|vp+>6jw^d~8f}+6bQY}O0T?KtzhK$@X+s`9 z8#{0lDuu+gYDQY|GGS(sUdxI%oT6@9Vq%2YriIlKN1hELK9m`T`G`C{=sju_UBcRW z@~@A7-@C&7PL^o7V-;24akY6vNV20GEr>DdN?+F4cPJ#MeE(f&C;NojSkV0gbw6W& z&@jjj&u;F-#PczDOP_LXq^^?BJ*~OAI!~lU-P4Xa464&Hr(~tRawDJ1n(5Qs0%$U6 zgFGN64M1y#M(3+ve06bU(oP!uvcB9TJFGXGL_5sTwfV=f_x_ozi%4aq7ZDaVSA6cx zSARZ_y^}!Oohf^*2HVKW{W?@F6!4?#8?T7gIOz@SnR>)od-LgJHwO09%xg#Kw9YK6 zJLbiLyGk1Z8JA{Dy`-IFmC!E#Bpi3LmT|w!8STXB8Kvn4=R{BvSb6rLYnG_^v%RUa zSaq6hmHM7-o^Ya#xc${~FUgYM{1(uN9`K6V+YJn$iWyqS4`sxO-8`(68G4(6_2%Tb zW@*-^-byR z?qE`Ocy#4x%3`>#lE7ND+1aFX<>PX{V4dUSn2~b%Y8>>d8vHnc>2BP68FHLFkWK(tP-XT)2hL4G5^H zdP;9pY~D(h73U~E8Z?;tL?;h>GkQPNe$xz$%$erM+z=?df`RK z_aXRu7yhZ9v#`&RM+yo!vN84$q%0ey8O>#MDd!riZE<*c*81yd*O+jx3d8`hp@7Nr0MY)a9=b$ zHSu=%{qZNkq}`n5+5?Xjmr-U=qO(cEFUW{yNEb6}Kq`e?W#!I2`-sMPR9R_tgx<-7g(1G^t* zyk;_7XCIs~Z+{s?U-+Jnh*Yv*6;H&t7X>i~XR+n1uT^uZ)GKBZ;cTr*Sk-4Sv#aX$(TDCP* zO@7)wWgb9qO1^e9Z94o#e3z55`jWkK3VR~U9@bw1kR_i$T{ zA%(;pi>M%F`k!O{^`WlUG|cz!V73NUrjPLKNt&ymR~OX>Dd(jucMC>Ki}bhRX19!% z^8gGj1i0YWMa8BS3$Z8NcFUg=zuC*4Gn#pyvdsp$&sbHoh*wz5c=(3?)(;0F!90@g zF>yh3JZoSMx0xjbWl+#2%#VbTYn}mxSNm$ZmTjQ+})} z$f=qv{mH1=7+AGx195C2dWAlt5J0+SER!|lMRKT7k9eWK=*nr{sCYV(LY@WmK-~{Y z)W)n7@61v|0eS%>tOQX$4|!2kT`R?1hl@azXcd@yW(MyvBsAGX+QTaOmjqrk{6Nx` z%D)uYe(12D`2C!7EaYJ~kArKU?8xi;JZy?2=k-aUxBUnmGDo9jf6}vC$1_Y{vi6@& zpD)TP;>r!Eb0-YoFzBV)6`f)eLZ|$v0dn{(`lw-LkK_6aL%OEZl>2g;fjT~;vSD_4 zRuYrr{Y zv3CS+-r#T$U^A_wmoYi<(~NuO4~`1U=JK;v^wbij@T^J}pJbHOm%N8cC>>d2fc6=rW-Wt0iDrMV_TFzL-9pAJigan zAImSV2dnwo{O03T`ZjJWexVFFCE;~GEN>Lmr08WucO){VdEHw?q9`+9uAgmu-zjbQ zZDFX43(J=MRDmSF^i!i5c$s~%a0KkE-HTZx%&mu#XJp^C#p@l+iD)gbSN}1~VhX0q zK<=(n>H+`{j`?f9DUo*<49c>O&StuA>c;-()O(xE^T`NB#wLs{$}vaQSrBj)qVx2M zh>(IlY0T*wfJ8H=bByC988(eQ^TA~))J<^r$jc0rlYyUD!P+7d_fCq84g8oh zaJc*~%9;IEjy^NvBw;PZ5CYB2{F4~rW$57raBEp!KSqL`X+p(893PzbY++p2>3;RV zIB=TBq}>hw2J?*cSqdYtQyg?9lZZ^i&J~ZSb zJk`3vS|vNyj{A8l5aeqVF}x(pDDgp=5+yC*xj2C`kD;*4;0!Va0<0%#(Nz?JPm^7R zGbA^`rRZ(u!n6LnzGr>M*GhGA{HDEZkyb>aSnk@Q^;?Dw4%^xbE!#RTzvw7V2>$E| zgR-mkon`;EDg0gi+MBm%_l%ysKTp?57#Bn5uO3wnd{VCK5+4s4ji20%iA~umvX{oG zW!XOHbJ-(EuO;<+>Le&Ky+7}|qs%Pg(=lHpz4n|xIdyG~bSYZ%NomfpIN-`T4J#WUIr7n7a(jI(IjEP~7&B%CW)1PvHxN>1f#VHr?7d`ii zxXyXB`sl*cD`unkjDW;h02P_v0P8SkSP{&)mQGU3q8P|sk5eLZ{}Pv(QdcV4et~*1 zeVN$#ZSqSF2kZ7>jt62pwIxXxBWg_3cvS1e9oAe|;Na=$6Ow9Kcs%oSHkdz#uRGt1 zZfKls5Wh|>nUMKe6Y7P7lIf3~ZLTb*vEr8J7Z23Dn@3s-q$6EMAIq)sd#Z&7zJP|h z;0SKhov!D+o)Wv6I~Cz)@4c(MJEih~$RTmh`y#ACDJ=QduR4(4b#a&_B*XklFQJJ} zjEsL6iGg19JOr}E&wPT91ECauG&!Hx`Kx}ELKumDOHH?YUdrivX!q{WNbrg;H2szo zT#0=^cnz<3Wq`}RfP?T@xy}4-w&Z5b#Xs1WsUg~;xhp@Q);RZkd49HJQ_xL|M&6Zq zPaG(csMWt9+^za(X? zLwL4;oD_zQDR4}d?`B7|?9?TW7TKCb$k6$zS`u7XM_pbv75-uS1ZlId zCu+Ia0RSFG1dU}bW;&E6%AHiS<>^}`tX8rYzpT;hoKo-18f{+^=1S!O zX9B?!%@epIzLopJvPAw0#92!2DwR6G(LA7xD^{wx)NfosVCtl*^`y6;#3$6rFNII1%r9B6~!cnFa&dTvlRrfi}$qNuVWFIpY`s^aFFQuQpG-AXxgRgz>DUNZXp{to<~g{j6NdHZ+dst&|#<^G6KN#c?T6 zV2jzgh!1Qj$Ss?`p+kb`E^_FG_YVWbJy7ygjrY&hW#vbzNcFD#)x5JG&4Mnf9$BwF z?JNx}D_!Ls6=%qc3cculLfg4w-@H~0+v2d|ru7Ri1ieciMVxDU^9kukHM!AAj_;9) zC<0BwN(X;@xd=J^|9JWmXsF&dep{HVW8a3s*vf7q>oA5fwn-F9S%xghmaSrhvF}6H zGFggBwkTxZ35~6Wlx>KTgzWUczQ6zffA4#S8u+$;o4+-W&sZj-v$ew`OU*HrNPKZ{+??duB>TYe z<23ZQ>qAy>hNAkrLa@JFsaC z)-y|DjSe0eRgzfVn35E)Vu7ygtw}B>o-ZFH94(0%O^&|Qi$hypiZ$GSensDWLuNyU zi)+n$F4M%9oJ%=@qz#EheGa0fGqYAN#MM6#S~J?3^SCu`S}Vx8^mRk#Yc)`{wCb6c zjzWkHKpp`;YgLECLTwj73$?TJdr(`=k^UasqlC?O-E8?4t`WtWuvcVt2w z8L;9X9KJl%8g=>6j;J0qpSEMa`cs(H( zOKQ)V;95Y)2#1f*wp+_~7K7jCsNQ|vD*L7@4($RPl)oZT_?_cSt5*Q?;}&&!=HS+x zGAakt?^=DFc-VPeQaDH+lfH6Y z0;A)H2dI4r`+?-DVn@UkK4u=yKpin5i0)1%nzQ_ofnH~*< zmR{|_dIerSoE5i*lYtMBc$XqofMWL;Fl^1tRlde|905&ZiFo5%#JqCF^vbBIG?5UdsTZmKs2bCvD%q_W}=W66_abNpY)2K^KHHYl4<9?)T z;HdM;>$-N)GU?C9QD)$HZZAxoDRpqNjb-=c4C{~bh^X4Q>d^;P8F{NOLhra@p)ym$pG)Epuq6L93)*GzoD|lXk+99fDMcE z0xJMFT)B(AI*^Tx8LqzyISaqIAD&RQ>UB`%-hlhusfP)D1U^uXRK!|*;Fw4o~ zqB}M8b=yydwz^0io%i5h8xw^hS@mF=>R)^B%N5nMZ|3Qa@5UrT*L||}1@Z|yK}Y#` z1MZCGe2Hu1k$6ja4_4Lrycb+G&rQzTvbKvK3gQM7)y@p|Li$Y$dqKAmC|IIzC^5`< z*(FUU`O$T^4-7T8SS>v@FE&2y>+ludBEaWttQ+p&WhjR8p9dhMyD2PQ!I4Au;H9Ly zJ1ihLXvBXq1pZR@*IcaUHc|y5iDs6W!7Fl|EyHVMcNwZe0)CKHlCwGTx|A zkHzxm&{xMCt8F$DYp=J7J1)4EBCcgrldomO7RWoaKGe=B74qlX9A1A+Fv`|u$VTtz z9wZ_cp3p1Z$6F}7K0hR$xQ)GaSk3BLIZ7O%3w@22ysxTW-CHVXQ6$R!H&=C6qjWn8dDAVy+P5$}9k%WZrlM?SNX>Q)P;8A!6l;kb~2)}ZwAVfd!zYu6f; z2>Kh3nw6NeRE3%9KX?4T9ldKWJnj%XD|r7C!HQDy>^yr>d=m5XdI66kL;m8`&e-dM z_V2kW>!o%x-!fZgEtS^BM@QdIB#ce}h%I3uKj&l8h575m@;V zwGi9cY4@Y{Poh$h3;U1O_pcz1(E`0n8BHv)+zs3qkh-PRm==1*FxxC+nvh9y z;Y?e4Wc6PS349p~gt8VtBq&_zTwH>IlL+`T;f6Dp&qsFE5>5NQT^4&B`&RrV{;#|T zq>w%>R;Y6U-^K36#hxZ_y^&lPrzh+80L*GlpiChiwi?$Me%!rS_KW?TFO*i7ege^m z^^R1#|7V~3H3Pq*nH2JA?hA%f*)`xX5T%WU&@n@M5uAZ4%cI^i#D(Ke=B4W2*Vqo8ScE;s>`SuR9TK$hpd0^a zVE2yV>4zeRrgsR(prpv6vhCmUbBRbdOIzA*%Ci?`%b%7e#rpa8Y-0m%$dL#818%lk zbaE|FwF`bV;3QGlsyCI3sr^JC!uMyT)YsDYyHslN4BGhJi^;8(i)tl(%D>N7g2ewd3Ah&+wq_;W?5<2F}`F-@!Ym@Q1kV1kgk9wsq4pRB)Y79_g^K#M0 zBc?U{Bi=oRQpZ*t%#eTU%{g`p!jP1>E?eHAp-^Yja zPKqwH?NE#=Ej@t1`XqY)Fo^Aot8*1F*WLrUC&G@9(Cy?0I$)m+?7%BM%pZvlFKR{3 zr@9GiaO+ja#`c~2n>n7?Ub07bEEgLVPrR&pHv3D%`gNXq4b(+tABAy|^ODt}3%)j2 zHdQ>puNWU&-a`cpD94EhlV@Zc@IErvbGD95j?Z1%qO3y@_% zt0tgYGbT}?!vI=#z{UnzFwcVaS*5UDaW#A(F1Me-=x7&>{z$lIB)LM3Ob!AJcCS{2 zF6htoPkDZdrF+FLvMyN`2iU=leMIYm5qAg>0o~WRFZ>ox3U#fMbJmwgsQQ)Q3fqp^ znV{nBTSx@u?;%gnNVV&atK2)hIV1u(Z;quJrIseB)v{mfbjVcs#^w=%^Aaz@$$%cq zvR_T^WKU2x198kFkKVRu@vk=ktrnhr-@hke&l(NS$*>LH^k?Y%u3AG9v*iUuq#VR&YpS5CS4sxS2;0ccQtS3jgSl--=er8$_hMS zufgr**5M4F(dM<79xfNq2otT8D!%+=^vU~{60-Jrsu?Duq?Hxj*9h-1h<`d{$yxz3 z<`xymFt=A6djdJ^YHKh!=e7+01UT8y#J(Zancn5W z3IH%(4d8tP0H#1((W-6a%KgGe$L4>qua)m(M=Do+w_hvCnBwPScS_@PY8J!=L%6Xc z`6un8OX9GarGhDSvTmw|kozv{)XtTS4jpC{`#_%O*MyQ-5|XeWV(71WsYQ{vl1eMH zqr|Oi(!YL>c(P?h&=1*w-1Ha`Ux1?ccB3aV1(Iw);`4xA*3WKyOzq^gSd;pNSvQ{a zj}Z@R@;2>>9v0;@_w)Cm)p$$sXzrbOi!!z_YYF(CCU_&bt-9bvz^tvWYo%8k=Y~r~ zja?>El1<5QUH<&s9H=qzW}Wh!6S1XzC@YQfv?=rAHTA+fQEQT48YnRSb!pTLg^|ED@u}31?(@ z-?zOHhIsK4Tl5qCB9*zt{X4+wTAh~aSmPIDd`0`d+gvIZ&RfO~wX4hi63!altOZsq zoo4&~;xR1{!id&O&Zoz}ljwKMp%86hRTWb?VS>u4bmW^Ah?3kQNr7YK?dLTPH=km&LucQc-Yc=5`nq5Dise$+WeG-5e`pmimQbxfuR z>vr3`)nXoJU*vRjcAhcEP>eh_&SFgEX>YSwhEH`mgf{FyQ zFAx5sVV*vb!!;OWHlK8e>cwk;IM1D;<8UIrWCIYZ|jM4pz@kA;~a#d?m#$%mrQ9|azb9_ju(r)~sYcV22 zV}ocew?T2a_(}iUp{ICw5Rq(`w!hi;Wm`D`F1iHm&&eKry`ySv%g>r4GZQ8GGOH^8WX~Rt2-Ip_boVL834o=AmnUZdX%td@SHy-V=KPZh3I?t(*{@N@4pzqQj zG776*I;k=2e>|+CP}9l%StZ@d_j!I_1{Y`Cz3y$LI#_54Gqd!^!vdK6&t@~-E_tIA z{q;)L+`<-XW?Y zDtkg|lmR5wYDAD#Un)&7t>O=XCP>Cd-F^ELIb14d&!s9~LYs)W^A%>*PkOUKcyQUAXss|ZFdE#PTt zna!TG%owj+CYOsPq0?1{ADRGnb zZ8Do?HaHiykNb6?)a%%I9K!UADH?oqe&INcR|s-1f=>8jeBLhtn_~84(pYPuiCU@0 zVE)6+v`2qGr)%B_<6kX?2L>Pl?z31n+sb7s=~AR$ftH53n}vKV=f`(gL7fKb{O%HW zFxSldun#NAnYL~M9Gx3!$Lh6O#l%55zYEl#Zw;I|^YaHqK-aD_nr&t)v;Wa!Supcf z>2sl)B)pS#BPQpyu-zx&9sd}k@9C(5u6mxP0)a99{ijw z=Ov%C6qI&m+m;Z{e-&6W!)=ufm7=0#|BfF<9yd_oSnCNlhI<{W=okHu!L4w-exJEw zPt9?$hJ)r4J{~i^hF6l{!uj8>$_{lIF1;Qs!YQfYQ+)FoVH10czYch58I#yoX}fmB zXa3R9w$c1C#2WhxL?0RZI~~tY8k&4);5lurzm=Ls`v}*|lrDn=CwxLfr(obX@%0Wlb9* zfBM^yxR;Hu*8EWtjxO!%CRsrkxNt6e8-M?A>7X{r2bs|1KdFrj7tSi|#Kne0?zXUI zQmX)c$7zHcJY6Q4j$=Mx86a#aqvZOpsy4S2Te9Iwqx!8;$2?X*R9zx)2r(X#zd!yH z`(i~rTIG9Hl^x5h=WUotNttH|=Nkz;lyZuN{oVIu{;$W7Gb zfHs1%o)*2JB}uhV;D%eWHZnte0tyP!7*5Pfz;?hXA7Ds+Tz{)BQ@Kghd@BW&UwGFDFg%TxAVLFo4kxzsl@8Ow^?nMw* zv{Li&ojPfr(?wBxnN7xev!xKH7P-TcuF=PK6@tAb+ zm_0d`{Mptq&+tZMnyc$M%FNMu$1i2*0+oq>(NCz~GEPiW@RFMGtx~*9Cp|cGO4f^p zUop>P!TiPZ>jIq3PgMDnER`g#t6MHR6i?))6b=5$pgw#{;^KOdM|CWWe&^!d@&{|r zG;RP(HS_7=>lsQI1DcP`x8-|m69CP^h0VHmxS0l$t_8%zq*o;c0Iq->1@bI(awV!G zeI#W}X0)Vp_9}D5RpviIxIl036?Kif)kNb}byVO$u);8;7-?t9wFz4>!*GGXPrUKi zxCItO%N<@i&;InhSPG7V#wFXvl5y+0UJN#<=0e3Gr{|Wn`+VBFmCHF+N$>Yr%Fh;fv9vkS@mO~J?H8(D)vo53qR{o zMnaw1qd|RvCMLWWo^jo&wUw||=bXxyYHluLiB!2mN)woVTYe+NHX6coeN9_>YUQ4o zEH)TKvz!!GXKy$@n&5_g^d&zcm?7dq&`0+FX_M1WyLT&fDx=BX-ayvTLqE$@NUG-=V*6=oD6ZehGtHPxc!HD*8 z)gVUQp$Jx!ug5(uY0aiB`EnB6a<{Zx`n^F);>aqY1pc3+|KU9?%L?j98KX2LV!2Axk5runic!c;=GYu_*A zvRJC#Z1K_RF`8+8eD^D#m9tnTHtYQt;k71*Wm;y>knJ?Gjm)o=1vIq6?Rd?+@`IW} zS-&Nwp!&Tc`n3;QN>C*b&Tbf{#TRj+Tm9IX%19au=( z_jvNa)6h1RDg0L%FpY0fe)e|vW8Thimc>#&ZU+^A-T$Qj+I=joh#_3CbPtG7;ec&q zj0dXyZOSl?xpH`oXRKNwYLZy2e$M7-a z?MXoCwE*#F;asQI43>Goh;C@t<_G+n2 zCIdxf9|)`r#;vSWKr_jm4xo1uR72(VjFoe!CO`S3?@N0T{sYHM9IpUvRCThHe1o~W zQRmi+xO%;Se>7ny?~L)iz%PDBPxS5z)RI=|v9JC%46LOG>1{X145`dcA^LUy(ctP< z(sa0hG794@$0K6RLF}Vldu)#f+D7~T(Ht5qnSWPg$@@I9uXh`kiP^}Eu=sBSslbTJ zT^#0CcGm(k%3oC#LH3XEQD}gjC|q)p{q%U4hN16K?Ck#K%I`B_X#hg9!&E5-v*S}B zZ3y|X*;$=94aMaQq-Ux8FBahx>oq~RD>yFQ1TxQ1o1buY-agrfM0SJ=q6Xq} zgJUPPZRXLii%yfkN2Q||a)q#uKZq8t#IWZ?3mB zW_4nY!K4QnDd;d~hqidxznSTw8_4RtDZ{I9tjnTuf8;m)>`x1KqU5b!x0c^s9a+m4+Z_nY4@P{P9F$yvvcnHasf+Rq;U zX!x04@hle6c>&^$O^0G15*ditQ}c|0ovIr$aCKcdt;T6kezbntr; zA`KvTtU;&8%~xD_nbS@k8ffI4eM`;$pvP!0P!;yTN3ZI)b#dTG4$N5znSUYreqQ&N9M3ob0egb8+YX^B_SNJ>AB~n(KfKI5w2@T$lV@zz@tgDwFJQ`W zjGp+Kg=qI4hi?V_&JFcztU#j*lXNN0xJ%GSeQ|0+Q9ys;c^N98X1}r*_Nr`XiNqs| zLW@G*Z1qu_5!KX_=(Jad-2n@HGH!dCR*a6DhS~A|Xq=z}8_?rSs0bX-4!tON{c=pp zO^QQXgXQ>|OjNMmM!`dw#WmCnSc5K8EOgE21xs`h1otv#5tcQ z+9HfCqa?-4N*Y5%8a4Gul6QKpVu{TR^LcQ^h8oAk&V`1qdR*87_I{ zL(%Uog68qiD8sHCS%01b)l%@%)?8~6kY*eZSXnvs+5t5I&bajIr2_Mn$azvaLU;Zc zEwlYN-0_>*f#9=uI^r;7vc4B)!L*X)I{6 zM>4$aSd%HYJCw3NHed*-#T)PhA3oE1wac+qAMdIv$l4fi6n;^n+Q>001;}zKcd@Ge zS&c zIdMBPq_6&eBSJr{xU-|HW6CgW^66Pi?E_rHrD!^zfg%|-8@5=K44p;9BCV_N`pH{I zcs_D|N9NRX@#J0oUG!UfiZU|#RhK|0Z?P^7WT)Ow zjhQc8gDlpC^uq&ks9~xYDXs)m6|boLz%yXm`=&fL^xeb{i}1hMlFi1a(2^^D6nx*P?Ma@^;ZNJs@#o)uZ&l?y-8>r6OreYtx%#XP)GIE-_c%m!{N$wRGDHCkB37IL<#_ZxTe2F2b*;4gN)VDi_RPuXzAwkmdkFf|RVZT8T{%x&^S;z_+1x^EE%nbW5z@B;^UM*bx&@Nc5k<=ZPElIXxzF+J1`wzQ;vfpB zb1KPRy{@o$&PWEXQZP`nLWkjABrrvK6erw(0hk~BzYF@=&<5TMXH}+rAybx`(vc-m z%t#XqKoOoyYvA}0+Or3!%dW0y7Tv<=7ZB!E$lX`-mvSTlrM9IVcU|{;!!D$i#V2x7 zs|>XYp|9bjKKi(#7AoHVrY6GxPtUw3<^eyDSPKwTliAg52#^f~pY62v%~;l~y-9C+ zIBd_sS^X9_5?g25w<*I#--SJ(iI-bopt$7R>Gp_O_sS=CaS1DR{&80{BVjazS z5`hG)7$cBEksP8mk5vH@*TSU<@mFqj*8~=0GkjebI8CCMi_gq)8l5I!(I`3aQ zDf;i~cgwbSey+kK(QGAN5!WA4^D5ND=*Tw71zTd%rv~?q&blSf>IgTUhbXAY(LSxIGi2twZBdQ85;qppacU3fp9VtERue&D z(b zCBhKiv#Ck&%1oNbbN@}7feV;y1^9q37Ptg%xAR?7rgBB;e`j{i=0z#-&cn%Vet6r? z-#_f|YClfq)4hoc!3nQ44Zlt?_2&Sc2Q{_TJDJ^`>zx=XSQeOX-{e!x`Bos`H_t;R ziYuK+Z0y?Au=1X#jl}}BCg20dhVw>cmlCKPoF{#}i;>FGT#s3)je$CU+Y!?98Xe)y zLr%dAL*7@-SceXS^gR3u?j8(A=vH~-QWS4sm7nFt6b~-Z`T}(d?hB1Cc14SOyC=XJ1Lf$llu+NLS zH}7UrvE6h}tX~GDPR_%A0PZA{bzk;-^tnIwZyGic&4R61%7wpXyRwLcMByvPu=*o@ zlFlj#ZtNzHLNQY9z8F6`{vdMP_x3P8`B@AF%QLs}e*T)8^xSBCv(f12WT+C8P1v~J zJpf;0y&&}2%m9R{qD_)M%XRv`{ye-kwI0Hi`5l%y5BmhbOwt!20OjuGX`RhK7+Dw$ zCjS2vG(3C_9~RW&_>F0<74X>NRI3{VbWNqay^T{~_d%g(+zh7$?Q3?>vanBQ*X2(i zRK@@V259)L6Y7LldsrrEdXnz?yymYNf0ImF3Bycf=H~S-gYPT$z(&^`b#qi|DqJ7OOZoW7*I~Nwhrub?lqQ zUd&quDI1a|;GmR_VS(@q_<3q*y>S?_hbL%M<$e^183riV{{S`EZrZ?}1L-&YpV@1g zNf4!)&xfJTB8>DRY4!3OYDmWwu^(c;fqNYy);M`c`u1_f9k(8G^8N6e>#%mj5@{lB z4HdBoL>L(-RwtN~dneA5J7N=Q?v%9%T>WwC=N&{N^8|P z1n36r9uP6;ooNrtR}BM}Lip5giv$BQ^XR* z&u|fqyx_d_yF19IV5gnt(dPIC7X=7th z{14>%#~%C8KJ;=qP~!!4yJOEoNQkQ~iQz(IFI0VrE%0vaOv)L8RIxWS-i>$0tp7br zb@Bt4z0^IPnsE>Nazl!j>!HwO{?8SYpYZ(>fG2t=4D&HY;Dpz_y}iJfQ7c#S#Y3Cf zcInX7THgRCPi`;i$I0CDv(|=hyF~r^S8C^^Vm3le$Z6rG^Fj_PuNBxo%UKrOGOKEi zXb3v_{Xo^if+PLtKW&mWVF-5E#MESTKA&N6c=DNq{8vj=LL-VWux@kL?p){c4G zTheg&9zN{C21INE2etV-U$hqr^)O2mrxI40Ucrm_n4ZLQxp7}aK1_G$PwEEf(2+6{ z=kI9>UNnSuX4nAjRmQ}!_DrT=qcyb{m@83TrRhCuzVcy7QHs^s7<-rvuy4E%$w&P^ zkJGp}^eS&I8#K#st|$9dC)4nTMD`KNZ&5faq}>EnyN6wvr{|>`nP+_*kK7s=s5LlB zuiBoe{8*RUVZM!P=dWJsR_J-35A7=frN3T$wrZy)cmoxWZ6e1>j`sRf z>i>@hescS`r;$$(&1-8U`Tpm3+H?aOuM*S%edsxXpV$)Y46tp zak*EVoK8;m0@Z@087GPV0W`iHnHa$f88uB>D&#I)3$wHeT#IlN)vY)Bv7qnzqvJU| z)8z4}R0bt=`~FA!Z>bZ(CH0W{1-0~Jpz&6 zfuZdvAz}e|On;R5-^~qtz5#A<<9qiGH6Zwj=*LL0tbqh%BI3P7JY%^`e?;McLJ-RT z4d~tXGpI9FwY+8@yB(=@k$_X+e=z$=>AaN-1du7siZ>8zbEb%~GHDXQwI zs&a-ne$Nk^M)*6Okxjc%{AXN&xqzp(iBXeJ8v)gB2Hc zbiV?aF<`(><=8b4a4#=o1TT4K)EqIW>8lh~KZY+MV24N(Mtj&gBw^XW|1=xJY$^?#rx`<67=^KOwk^pwvk6fAbP`f@MzJPo1k*kl5yIP4-BX_B76&=Oy^C zJ-CQ34f2Elh92K%y9RjTl$CoAiH@JjbI^}eB#);~hW^pqj3_~TBCTO}`wk6{J5Kfh zTp%QT{BUOV@H_S^f=pV)Zo416IkrD({zqdOQG}Qw{bt{t32FVIv8`6JtJUT|`L(`d zS~~)F2tJOF=suIccztGmvI(p#_KSN7@s#MP$BHW(w(B$QO)jRtM#yGVlmWLtDLO|c zM=_Y_vR#yr;i08a9n4pmT5ti*%!Xj8z3!-*A~s9h@-^h$Aku#{d3kd(fhK~``jix zTLGLI54{UPN5ouRX&u!XumZP=SyA~tU&otaWrLUvyf=pR+6OOYHk$x;kKX=G3z&1Q zr=ICqW`j{9r^M438sISll=mG~uU?hb-d@Von#O|^iZAZIu&`kWEZ6{+xm`L?LrTQk zcE9B?7BF}_mG+ZD2)kTMu^=JSBxPgpdZ^O$WC7cvf;L8d^Is#v+CKso_#N(^A-XE9 z!0nCR0PWq^@ZbN@q{JG|#kG$W^`B5f!sGV7?-gIs2H%NzU(*y6@|!41dc6;UI7XFV zpPru;7_{k)qLqa8uM;|{{Nn08{feA16)Vszz>PEq%y5n23Q*fmwTrcOlojWv4Dj@O z2XOZVH#LgL8ex}!YAYBC*GynRu|&`4al|ynilU2C;X#vGqzN!mU0HO z5YP;PU8aH!OOkYn+!)ECU6F_(1F@Nswjr@Ojt#2VCW#uawnKjtKjSrEVGn)>9uMAa>;80Tgk#J-aRx92VQsrc&bGe|vUI zXy>T60|ct>uz<@C|^ zTiQuE;t&9|)}#N?jB+6Hi(_fAx@Y%OD7O8+ogZ$cf2q)zr+p9FW6M9G4^E4peYuzN zUg_aCZl{#lt$#F;Z~oCJ?P<9GE^33`>$?|sPb^U9W20!uOd6Camm42ZMwuo3-qHCm zJ1hBYuW$WH;~_8U8SEGYEZzo5H$J~684k7yVX_|!f*?b+VprMb$lM)Z4w>c{>8PHe z-77|Pr!t$5jTQn@@&eA=0?uP~eUe0DliuDB{asv*GHK){1RE)DqYyeGcz%Qdtw+0*m{HN*Hhd+rZcwxXfBDm&#>*g_umr>Q+NN(l(*Y;3*|e& z)+pX4rE#9{75J_qe&rucKtz=cP)K#g_1Re-8Q4FXZ7H6qL+buvT*P`XC~Oa#e5`q4 zUJoILG$UGQ%x@i-_Z-`QajeGxiVb1;znvCg+^Y}tM%arr&onGuDK{6;LY1?nPZpt( z%IOKAzMZ$>L4mH~z_jA@yVO12&fRVAlQCqot@S(=tss(8pZjtccneeUkLK?Q!U$24 z#?u)>r=eMUnEXX-_a^s}%m8c*hyg|spp8HrG!p1ON6#t57Ai&ybWUM17z+f2N}7l9 zfDf+5rgzELes~sGp&?zX9&9pm>{+$g_K!wfZAs7e+0XlqotRCRzhg(KF4YJz7*)(Q5@x?24%W+0-T~Y%2fF17K2@=WRif?zS1*2HDC&YB}Umn zsg09@TJ)AB#wFO}BvQXZQ`(5t`HVk|(&&*3jIW3 z#UoT%q7Dt}lvcJ~PR1h`F9FIsk2#aze15)=#dnbVO+*%NlrQoGyHdS_w~1JDN$W?u zQS>?$2j|vQ2=3}TDo2dM8-OsA^sMb)`3GE;{;8DhOCOmY*KgFU{)RCiJ0)(7wX=og z{bA2)@R@Bq)Hl3KVHaQtuSd)zZ>Wj6N}(c^4#`bxCv1F2DWe;vL_8s@S28UlVefE3 zN(ZyG4VHdI$*>!auTGC*mZ;f=Miw&*M8+YRg#`Mp0?{vkSod>r0ZIs%bLMy9mAgIp zVT&sUXZD^S3BK&H;xTS+)p4n@g8~{67&$=CsX)kLb;!u-H$*RY#Js5`Y?v@@_ZV8o zUvmfD|L(XWVwIVeptUE*Z>%ccui|-F<7z)Y_4v!2>4`x8Z6B@A-`~u1cUcXik{V92Y!4SHufqTlnsby5WB)xX6 z;xKpIJr+F~nSAE)Ti>PGM;-oD^y>=}q0Nrr^$9xMoA)0CQcgU*jsRCO+SJGciv(hC;!;)e69%-n^3 z=f*@nmW@r77q259()vW_x<*?^T5{CEo$;OHiz|1KPvo~@A!mi_P!BEo^-Feic_QB+ z!mJ&Cr;HtytR8jcqSr{WCgM4thCxmZ1p~_6Uc&2w47N%9P+qJeNSfi%(|a`xS)>_p zmRGTiVDAYcr2u zhnb8}bBzaiM~)}^jyZX8ow+r9VHzJT7X@=XI;sZNpX=C$nE#`h6PvNs-)mBS2XmyB z<^~F7DbYD}?67Z9!dNR2)$gfG(h2g73F$!GlLyz!q2jc(*%vx`X5Mx^J;*NX_QG7h z$nDG+AjzMx+q#_VEbz@95u=#ihT}XiZ!{2n$|LuH*`)F_P|BO9td?1_Q|HFD(#wqT z0xpaI_rke|5rDYT$)gMj@yOy$5{rH$J2s_&y+FhjN{;nL&0i|wYzEzkEdu${3H6(M z#d%s>&cAj8R;?8Zg^o%xGDyDW3RJC(y_gzlJud)T4@fFiaVTCAq z%N>@~U}1@2XXZ&Me{Q7OV3uJ@o?;GR12-~o)JM4sfcxp+SaJ2YZ}3xdbU$pXRGjyY zt(X9v{mC3z`+$ozKCl02DxJBkm4(58%$zgEg`lkbb39Xe&nTzl)`w(`{x8RKJ3VUw zwdxKku6lj8))JPPXi0ym$J&B&XUs+AXL?!u%Gw&mzQOY(qF9WpCwtk-T-TKfm<24b zb7zlLk3X<2SX-JTmshgij`JT%8jYWV<>x0n0M}+}e;(!cHT*cU&l?i<+2pvZT)6w= zWp$;wn+i&am%c~zH^;L>)d8czC=VZz1F2w1M$8>PE2-BCTn%iN z-1zj`@iJ~wdPe0Tx%>RISc_p=SW51jRmutW;cnhWI%z3!wlH8}>Q}B(weq>FHTm~2 zMMjxgUQ8D!j!<9tb5!`*!jYlAK^f&|`aGwaT`($Cr3s_qUaUv3+5>#Q&!>>y>4Duq z;F#BrG@$zaH!^JtjdK`?3~~m;BIk0KiU#LDYCuJD_bnH~Qu<^~?!qh_?7M}zrPXEh zeL$r}f&oY$BSoTfH|A~M42Kot-QIsLUoLeWP$g~?DzEv)I*pz5Gm~y>=>3$Ay`o5!Y-^Xb_~l&PdvExJ zQExymVukzF^VRU&E&4}~cns{fn+VPecYOak(-%kFUc@5kYcAiKN)V;rNbh>k95Hl6k{$gPb3_`$QjY}VmW^gN zu%sv)`j829;3<6f2WJFrM%veL^Buw1ePfO=bMHN|4q8bu*R&HR>ow%!K=O6b2E)Pe zk-Sh&0@7KvZN`{s?G~028|&-DvB~nIxke7i7zvET4squdJnp>k9c9OMPk&`n;OLq_ zpD|pY++~OaUa?7T-hbBZ)YFbPcCKv{Rabz-$rn33aS7EON%k=O#KdF&m16@wDsNj% zyJq3Zlj@nocBP0&kXJc(;c0t+mT9Q4XIhs_i}y!1ct8TQwKw-pXS0!;AtJ(l+)u9p{W!Ru)+0~oFO{^9XPtvx>`q`yk?b043{wg6E1?6u zywfA*lS6R{f!2O(s7;-n$&m+6`XJprr9-#^q#lS52U!FcGceZzwO2C&H95Bb-nMC1 z;FP{)X=(KCQ6MEn#%^FE_E%7#SmXQRfosPPe@{aM`XYgBpj3sLURZ7w#cM=#7&m7} zk1+Zlo$C~}Cy&C2(im901(yYgC@n2T{84Ib&z_EnE)QoSqv@YV8J@-NiI)8md@HnT zlx#VvvYJK58_gZ*5FB;qOs^?y970VmU??|qSLzm*Ol9*CE^3G|Pk}pljA(2^`%5oG zw%3~byUrLkFka|};0S9jG)>}DoZZSQ8Zk9i-x%hk&)0M3o9A?NLAvaVcRU0P6*AAq z+85~=&g&R5qF^q3w+5Z=Tab$)QABq4R-?Z~o){+-R*~6jx#f>qfB|6^R^XWiZPL4* z?igkB%{rQwHXs!G_G*3xo4BWhMQ3xutY(KgDs^5QS6y&TWyzEh`TIl}VPc5L^&c+E6`OXKookR5>Aa7dgcRwO z#vEot6!d!H2Hl8=mh64>9R{GD)OfA&04GVtUtz3~A&vKD)?p^~5vPPHtIL#O1A2;89iykO8PL%VAfgQN)HU6Y0avi(sW7~fD3CN{j3b9#I!J!T(7`=o z7BxVdE;W!SPM@5fz+@aNVcOMLl4*R#4Q(Q?T})?k$y1OwTHv!6e1L_KC9?5pJS9`g z!6f%e0E#bG=V4!I)E#!~>pKukd_gDC$p-vvUwo%g`PO&(+xHApLFSCB^qWxCYH#mw z6A@H5pB&2+$Ls!se>7YN{nU4o(zV)1?OvnnUuyiVBHjO#C+M?*7UBd(#lqu_V>BEgNArZNPF^oB&-TK zf`8w6^9F4=DwHS2ayz4krnnK*`AB{H&EhM=W&DmxRM@q*;ouu5cJH0`wd(-4is@Gu z@utJ`F-zP8pT{Zy(EjfVi6)P$;bN(RsgRiI9G^PvnJv#Z?B+OWcq&|jN4o5&>&kjog)S*JkeIT`Oe0?7iz~9)u?#R57;5C{C$oD@` zW?Ukgq)P?7*z-WhsnFSZ%tlf9ts|QE5069avOluR%6CnXu@Pg5EZrA<2YJBzA=Vp_~>L9N67o-F$QI} znF;c4B>Z&N&4NopBbm8iLAm+N!VQ~OkQMf$w~UjH#!-+mD-Ix-P{CfW!unHuiisoG zF*M;mswdb+p1Mg?-{9HVN-ce>u2faBs=OzERwc8!>-(#}c#LS_J{!<0{oi(e-T<^9r zU~C0|P>DiAdQ@CLP&dUn<>0yUsR8%W+0iD*A)q$5m*=;BsCh#JAk~0>n{`wJ7u*Y% z=OuEiAdF~NjP}aiCT=yl(dW8nUwR-oZWoQv#(hj1x=Q=ZHVw4>xaQnKrZ?en>XmV2 zr0GCiDrEHA=oZj9gjy#~h9vaGF%FL#(MZ^;Pid9?mFS0L7DpWJA$j!;YN5W+AaAgt7$zZ)&{()rX=VRy}X zBfnNH2`YiSly&*B4@5`>-xzyyb~A1@v0#|WX<);G;LNVT0x(f%}vFFU`yv4a{?P81yUyAT(nuOcGLyUVl3v+OkZ zdVEqL?gf=)Zb|0t7u}RcY0v&8QJr{x;mblJkB}q8hQu@1xZ8~1>qPgPYL>W-cRwnx z(W%h(Q;Zv{_xTIby$gMIx?j?IN5aH8-s4mO+hx=Wt7Sp#NLx@jH?8z5>jT+bnD%w5 zTw7U>ypcrJopZ(s(e5%O%RSq|uJ>b&$aEZgMi)-mOu=0I95Sf>qsowNG4cr&ADc8X zPCrW=V&~BIwzceqWU*T-t~{R-79G7omN>% zFWdQuzV~~)e?dIbu!q-p?pcGJjD-uuaLk>*wOK8fcl}R;4fT zGuZiJ)L)QIa+Peh_P!0;5s#JpPb$j;t6ok#ZT7drdtlm5Dpm`JBGUQ3BYURdEXjz< z%>Fhk^ZM5o(!sUqglo(p4N7j`jG0A=DT>NE4(nC=+DuvY?#gM_e2chsd`gx1inXUOPb9s;gXa}L_Z%*D$!@w%s{^gIU%|t=a(tT{I;b%+pY)XR4OgX7t4rT$Z`16M`F7-!(_Y8XQ(Ky`#qORFjdFiM zA}5#aqSre{p22wa&Vum@4mf#&Xx$U>VYePUpP9C$=A&uCtjGnjPK`ewZv0K46rq!blS$^(d%<7x4BhRp1Lv$GNRpt7)?*XD4 z2o$nZbmR()WfZ;eXt8R=@qOrK%466LtN(5&pw+OJxWpp z9y#k@Z=nIB6nWjMIc?lc+mE7e#rf8Vt3%4h<6blB87S{%?1VS_rXPQ&^Y;8Y?_gJ_ zj@|qcLN}1(_bf4<)*Hs&98YXXeXE$QjN`3CSuVK0og z)MYL3skaShd1=ipJhkl{>n4H>h_1}RmpyC~G*8_)@!!n#qjw)4Rqi?_(|=~8^f<DePjjZL{a+SQuXvV-FNQo-<^gJXgm{78Y}M3ft7 zoO5OnwpU3vVN;=3I-;GpLK+pzos@*g=Qmui?N#P^obZ04_$hkK6a5j9Qf4mY|BbK3 zw?ReL2pQF9Dv)*fz!4IWoFqN?N?}w4aCvvHV|gV4TFJ0PSNiWBD0T`GjY;d-<##9P zTYYG;H{qF649K8uZ76hLRC@VaW-vyHc20?@lkbN%&r;iscI2`1;a5uBOOB7;o-mG* z2evZb4<&pI8@sj2v>D~hxsV=b%TC6Nk+*YJ3KQAk%S8rH(n}G^Q(=mQA_S;87mQE< z(XK{D8jbp-MGHbv7cBxVx+@4!39Zg*$gUPb1q%*`(`MPYTozraQJyypfbzx2`YzDC zAGY?c{_v4J>7^0sP1A+&K+WDw^}b#Ov6_GT53{YTd?`iYLH64-mKx!s-xDpPWx^ zA(Ck2Q6U}3h1G2qj{GsuymO}7Wuvq2oE-yH@Xlo+hV&D&4T*faSoR;l3I+W5!bw?=1uK+7zXLC7jHfh0G%gj zV=qnDch?4q+!t_92L~en1ZKAr1zYRhob+06{z!}f)jKU3CRuR|sTlLbUcn2#-8`!b z9|?|`B1Lr=v0P}IN(dCY5>(}gU660J%v0tW;Zv*%Q2YxDZdIHFH~C9CW)cct>KHYM zS$=iTS5Hm%#hCVn#isOpChhe71$|LYUw*N^Gr!#4)K|U0oE<;9*3?PHUD z_9$;eTML%8K<=P91Kf zk0USVqL0yigIcG}wZjQxq1b=fDOWPS+!@#p9)50#kD&QlKPR}X1WVB-ZxfDU7s_1S zXCkS*qCgh2?%(4Mhjpj4@$IO>I1*a@`E_R?`HAgpe?eWvP7RyL2%1&W_9Nzel^LaL zN1PIv%1wvT4d-y=*G_VVWB51e?prMve7lf*pidZeE6_8JEbfeU@I(!Xyf z0CO!@2J^XWUz>3Mc}4{U2;jN|QVrh9d#Ex?e@#tPp!X_Bt9Xv*Y3yKn#x<vtjHYb z(Y0xE%e3KJr;c!KfJF7E)?WD=Y|_E01nu9X&?SPo9=9RBmi(_oqJpHE`01j~k}#4e z0u;aN-G^~${}QCVdmYC1bdRU}i;l|9$o#ZX^bCvgA2%haKkh>EEV5#u5Gn4c>VEyq z#okG69&H>ZLnY4J339;;^HXpq{f7ph|H_R-~7r)%ho@#huQ220Ii690m>POt>Fi@g<&sKUAl zml2EGrpXfDWD@*EuXa=4VOKq&%p_I?BXi+i>eyOc;mRZ$8^w%d;So=E82NK?mhBN;-haY-Xh;&d+cYlWycUk zgDr-#87NkTr%JCLBU-ztmS*+&FPs~BzH2lDYS2-*#?pFao^wGekJI;v0Psj-p`T8- zoh9I6!XI6g1t4Rrw16(g`1U@woKkY)f0aJ#TDTviXBKt%`>HlKU-^W@Z68Lrh66R@ zvya8(#_w$hef@o)qIraP&OMNM|J)-~#y_~fwzN$bONP!Z9CQg6lA;|~zKZPyUhCKa z_al4oDu1A|1Kipm1M4v4H`=f%5asZo+!%RJ3+emW<%?~DlVa?;)u%l07hO+<6vj&Ci`oD{jMq`6Bea9Eq=bO#1_v#PM0zwA{iXDb&|ZdH zrrnoPulEroTPAR-J+1PCABknO!-9os)IOXlE66bE9ryaZv_E@L-g(p4b##jD%mF1* zVshrOovY*QGrRoDG_M(<1#EASV2yy#SYbR8@2tcD-F>;Xnvq!g6uRNZ{gKKbfcSmyY^9l8u>epac*j0h8crLc!dbOhFT`QubYP%o7F1L?*Q;U&CAXWL>&hi%rEy_r#SJ7IL&(zH?fb@l*^#6PC|>LxuJv~ed0Bm z{mEQs6s?BuXt4YRE$X@b#9-nwVsLkiU?zzhTpKBx1`Vu^8SZD`7SOn^2y`+&(%8GT zUX@nV=X~X@#h4Y8-Ejie?Ep_`9{E!7`^v(_QPuLOrwz}Ye1@8ghS5im&xH3n7vLL8 z$;g-rAIAE3a}G~WUbmm4S=hH4S)5`C&?`mhJr-GRpg9M3RvlT10QHUr`pOs{@01_8 z=JDC27ijH!c_#CD!WNEnKDfbmXfGXCY7o77prxL$u%o;>*qH~$lmMr4FU2_Oaz&jC7ihl@ z7T8%$5TxzL5B6_b0Ljf#75Z?-k*@~0cM_ZjOTia;?x+0P;rR<1TrthcKG8FLE&cG% z>4}@?;3HXtrw}e77LjF*GaWG-Ztr7+mS=BrCcRWv2~B~`Dr81Mobj%+bdpyY)v5pLWZoQ$kWY7FU6%S>#%Z z7g@zFsfqw9U7?mr&lB%~&QHC^yu-2B3bjEdst*WI-WhbK-WPVNUxl4M8`X!o$r-n! z;wutNyJ&C~6gBXd;Zyt}i)B93ruyXV;hz+S32Ty&m{i6GMN#|H@icdTc(_w;@_Q?Vl>-xe7NKXX6!>-gP*b{ zMEx`sl6{hqK6(ChfO8g~OuBtmUmfb|55UR2A)GNYuw;zxU)vRGD7f=7_UOUJHIj#t zK{q=6wE_##LRaiTIrK$Rn9c>5qUP3DYZL)+W%3NsqzG-!7-0!)uYy6#VanmiAscp} zrT1FH4xhi$lE>gaK_=15Ox%5jSg*{+MM(i~&BwI?70;TPyeiVes&bB>>F*08#uc#x z5+hC?U52-C;>(^ouakI>OKn2K-==ezIf0K%WT7%qbMn^9k!fSJB4o_Y#vsq(xj&lMvt;{viTP z^h|Bwxcp{6uDd>mtby`tsYyR0z4CVIIBqAZtN#w(PPo1}w)V2rOnHSxJE#VOM2gej z0w)6w^@b>N{y3aO4`8r_uN|M!D4~rLpE&9FQC{~Tb#IJho^skc-|cFVd-TKfm35W! zEgNBl2Wn$9o_>w89712;xnVKVd8`UI^bvYgK>@BGSCRR%ZkFq!`oskf^Rst?)Q{S^ z;-`!66gzzis|irA33AP*c@9#m0o5x=4IJDQC+_fVDna^E83KgwG`Gj(dwS|2dO3 z0>wO<&;VoQddy-tLXNrwxd4OU%D@+p-F!C+{=w892>~Id^ben(1I<=2upua|>9ut9 zgCsF?R-lhm=e9Ttj!Ay1IP&vNPbV9GWh3#S@bh*Nrud4)gsY^`Z;!Iee)ixWJ3ej1 z7#qG44(uw^d0wv-h@`F?S_EkJN(K{-*|-IuJKnXhwyKzu+!W`9NH!Q?DWmmwC79x^m`XZzWk0A zI_GHU$5o$u9G88MBuCjQ^9PWsZ6ALBdXT?aa zB$Qq^Djb;43_lxlOLI1c8P+p%S#)U^sBVrIx%Rw7DG$! zAdx0|GG6Dn{(?pd!Z-0Ts%+WCZ+-oCmh(4_zZB+IyeACAK6>f2{BwD*4akNai3hAp z0W+b>Y72wQ+!NtqPc4=er=Qt z(|d=sIN#6fgY6AB08}mAxnE3q$)#;d**H%T@@0{SwLl?rAf}#=LnS7Vx2`8|_zfHV zW29CBTwl}yyde^G?{uT+{N<7CsDQEzExFU8sDC0loj!6DEcd~XFOA`renEmN^Mz>$ zK^~Stm=>-6^a?j@dKNmQ@U)?oozM}gVDM{T{?Eb(tcSz6=+=$gE$7MGxr$<9rodBB z@K{(7o(p44yaj}&NMhpi6QiV}JJFgO`Yu9EBEnyW;C9iMvriyCWd`j$n#N(y&d4Q-O~vY=%`n(Bc6&iwPjV?GmEgLAgU{s?R}mrUYoHeAn^dc?H5Oh zi0+ql2 z{MkPHfy7|`-w|kry3ajK$LdHwe)O8HOk;I4n?pkcqiF2LntP`;bpIHjC-6*#=xRq%SEh8IfObV$Q@nzlLQfD#>JN6q@wIu zD`CsB(LY4z4bk&@S0bO3L`w;mb~1JpUz;lX3o6Zf%4EHXfg)L!tXUz9Pf}3vT%5-c z)7KZ-9LVzLV^>df0H32x&MbiX+h*S{z_9i>XxllDkDbW|E=u9Ac?oS#&|gjzs{wj; z)DW+kTev5pN$!2B5+yeqxYz@OV@c2Qk=0_p+tArJ?_s z=r#z%x-5p}Cs+4KK%uzS2(ZX|P<&SsYYEX@m=4T^10aRpnh!S3BE$M)Zs}Y51FaR4 zuF_xEc3?BlzH&L+PhJOmIVB!q4`s(&KIG2 z*Tj%mT`C;<%mhvTjjwp0R|d^Rp{>fqNM^%m;yiw%%&C^Fy|)pipPb1eK<6O6j25*h z4OB<9T+|~Juvl|-yV2hy_=(Qjazq7O)Gc5w0X8EnQExs0*op?r)jx;BL)})WSh|Ew zU5~*x_u+#t8g3>-^c*7ZX&^10_t_3CS;dWDDSVsMCY2EW4ZE26)h4sNaLHM$XZg41 zM!8Rfla;QUxW1Iejj}Uq&H}4e0NSxxBy1Qj6V=QW)JRmgxCALwy!#Yc4+wA265(i) zInXqb&!hqGYhYf~KR<%u8bi{wmM`i}*m4k&mjKC|f(r!ce>_N#jW!2!qfzJn8I9_? zN)01Bosa)I1b%d=`ADq!cWB}V({x!`^;po*FNTU47RGKT21*s@>1N{;T4ukJ{mniN z`+k|aWMP)%SbY22Nd$N2Xnt@6IAiIy5&+v@&C;m^U$%9RzBK+Anu{ixLh2sBk9Hna z49%!1M4RSv&Dy&MNCRV^9|i}FDOh*CtO?OkoIL48H1k9_?if+Z_Tdvj_>Li*%L%DOTMwj=iIFpXfR0rG#pvdnh?q$Z)?f$E?$kHi2ZLVbzed*!>HIalP^zE0~ zz{Q^9(M6sro4_Yk6oW^v!FA;-Pp5yBt3;oW@LQrahn)3?oGlZEuQCdwThG7;3&ADv zx6c_@JU>pqpiB)YZw0)qhWcXk*wVPF?75vFA>Y%*5Z(tzLPxI8zhZunfazjZ0To7a z+AOFfd6A*ckt$>JyTt3deYE0x#zh{JoFosFqobPhUiGyf#oSj(-d3A-N0Psb$EaA{ zgx*!9CE(cw%S}zYd0A~vH`dV07Q$XtL}6Pl#MnY(MDi=K4z0?{;#U?GO`P|C=Lf%c z{&;nNt624EgK>5(3tPvcbp7W<7b;6h5(Ec~;T;Qq{uoWP{^GI+|MglJsI$Q0r!XzK z>U?NzEt~mfY?{&Sfd{vlrpdo6U4v1l+s1XSeoUOiDvPz(l-P=sbUErCj^j zPXW$m(SSSbAms16y(vDJlaoU@go^^wD8w3*s6Yj%`>PLJXd3w&S#MVC`NG_?_#6DO z^cY^et3RvpkWFbREG`yV@xeWdn;A(gk0H3Klh}^(jbg}e?Z9P|1Y<1) zMf^MwhQA18GNOHq;d-n3j~^-JaG@N_0*tSkw%@NS)zA-h>%Dc}^e6gp(Vy9?Oh6w( zzVwzu!SZ!61NZvK4BMW`*Nlkg^);$-VSRDRy$;XWKlk^B6JXIbL$&?lRohRdMuX5Zg4`T+iPecJ-{2-uv{&IQZ^D*>*8xWK!C3bD zY)hdKxO(CXZ<{2t@s02OG-aQnp^Hakt9JSGFK-v#sH;>T<%+Wv<8=&WDT@|-RR2O` zVD3i;_Gts&d9|o-pIa0r=NKYJ3IIx)8jW>#&f#LyA!SJ>+}z$)kGbKsA8#p|{cD2# z@XN_(_FW!N>Z<%dvu_IAZO^>x-T`{-PrmDRuy*u21BG>NOS!Ifp1aYW8gt0cP790c z4O9`s|NgTbw)f_7?Z?s5ZyBL`4}QN;ztJhl&+8IrdGCs4wY3xX&m6uJNVUEG*MAkybB0n!QoKALU^Lkd4VQq67Z7;Fw(*U*ni@KqZ{Es zym+7mklr|P7l`SE^;>FF4IkfHTPj}*OMD_S93U%BX@LP&-(w=wqBBDGV z-}`=1_N_%|gFn7X60=uP^h!1$Xi+K8Cm$8R_iIKe(*Yv>LEC(9cD>i!}*a!oS67syZGudC4 z>gZe-kR@g~t0;C4#SP~|1&L8`If+j>o`RuKT);RFW%prhcn47N1*4?TXP4da*A*{cGF{ri z6_C-?e;C9a(-ko)T#+DVY=Qp($T$?8iN}hp>7ENIT9j22zDo;>r-h}B?g(uv0$eMs zc0Y8^rxPeB-E!%5rLR9zW5X;cIpI_;roX8&!|O9d6)U{KT|6?=e{y~i{b%9V>-{&C zS>$vFXDnh$t5IFuUS%4I|o-+e*m6%MG)J^YnoYWx=EX6Agd-QXxzhUopN! zWHC)lCcM*Dt^<&vLff+Q<_ z_o3E-Q}M~8RHpV+rb`XYm^X>yoe=T&^SifJ#5{ig3Bru7KVKZ(+Qv#L=#=%gIK&CZ znI&!9I=WG8XE=uk!m+;JQSdo*Vkwr2HY-)Xn!8-o2YeYXnUYMzNGSIuD>K7zp|fr3 zKSGF0-$E=#ye58k4{Nf|5~=fn{iI zPi^M}GRC+G{O%{fj^eB5Drr%)SovWEp|OzkcFu-Xtd~Qv19@GXxWU=Z)-3xirbL7o znnpRbl#ZAa)qvjCV%;F zA$#~uyQ*fwF=w=Abf{ZhCHisg^FEjHfLUO|lEF2=$-O2aoMAv+jVR0OEY+|!3iIgz zOe7qxW9|}LUyO1LJx>${w-#+L8RR)oA3|lMQO+Tpt&9|b^!iaRKx6NiivX6pXgQCg zTc_T|^=*`EOk;;y+Gx}-H&33O{yqLp<)wV#Xn+sf;wuNwUR8I8S;>6|n(@_@gzZJ+ z!{vY=rJiXmN@~?HI5ky89 z1<;?%8y=|%p$%W3wK67=V)dT{r~v5ux;TlNR{RnpJe*<1J^}xJRSiUy#qZk+pgFEnlNBiiyVM^3s{&FtlBj zapw0LF0C3*OT&R(myuYz*0s!+%4(huLOqe~x_b)o1GPq!%RPcrrIkQ2XIu6;@2s_4 zwTMmKCMx>)K-2mqUitdUIvd4{?L|SLSD@r+A+t40HF#J{*ovtmeDmc?Q(npR*q^+c zMe5i-*2@B)N4Dx?Ndw<hP;u?lzM)SY2~mzUEvKk9RnBf=*L|wl?fTJcY`Hplw@QJX%om%5$QdK zT*^GUwM{9wsMH|ack`>djjpFe%}?*pspO|8o6$7(Ul;v(UwT(I%~{W@jZz}uZ6Y7< zK>OE!enj%Cm~I92=eYj`rE}rtpJ)lIre&eX9z661lSf-1kZ zJZpM`aULA+B0oHg!Iw&&Yir^>1gdtkteo(o&A=N@#&}8y{4eOBDpw0pJu_UdQKc;^ zvoorcsmb6v+IdH)%^@)&#bU}pTUc~n@uHN3Z9yeX>3eT zd(F2Jq0BrJ)<~Ih!dLIkkUR^Qn-DKwwC!iVj)HnQS>CI=00h;GC4Z|~GRpk2*%*#s zEoTTnf7NIC`S!0T@4pR9zu=+f+993%K8B-AILc-Tp{#RFppX+tpK|Sen(|-JFG>JS z8?W*gG(+(nTQko&{~`5l6IHW!_xiIyK@F1=+WAmJW__uA@s8~C`8OjYA8GAfciUVI zd%=5i^0u|h1?TujWb}G@nPNa{#X9|rn7q`Qv_8rEiKQ99ldY@Pr@WPRXDXX_-esEz zuW=KdTOgGn=q&Rc@8M+PI_6h-31mLUy*c zm)u;9UVU)hAi}e*)H8CO{`5MVTb}@Ts9o;PmG6?CO-mi&q&<85g1m#BqLP)I@yBfvyGLa1Vb5guncd zvlB_h%N;y8$MQ4&xJc>`^PR5sx%{C+>qvR5xZBRO*~`$vETh{%wfiyUjns6{o85gs z1r>PrusqNGm7mYVccSuw_!yH`SK1;+T#?v!d0&Gs^peT|EXIYP@*dl`hIqkt7 z^VLnLoqg;;5fPkp6%xvuy_4!K!v4!S3t9x!kJp353*!?;yk)!5@zt^+71sK4W{mG9 zNu5kF*4!;M+L?tyw4wD6xdSP4KGqZ?qfPL+7rwpml-scrvkH+mgGhYSQfg;A*Yq`r zs8mMr@YjhFoirQAT%%Qk!gy~FPGMgiD}8IaW?RpG>~7KgJU}@Y9Q$gQl$olsPY^$u z@xq}aoC|mxmGpKF!!~a~bHW#bx)sP3I*gy?+CL-2hx-mze%$p$XB{WObc|(&r8H>o|QqKXEC6=YWo5nTd|nMbo#;s z8?Wzg)n+aK%G<)L8DRPkbCwXu3zt-H)J(?bxhDr6K89Tk9lOW>D9;?5vqGK@H<~jg z&;I#*W{te-zbe1N-YfJIdN!UL7CUhqI4^>^oY9thhE44ZZT;A{UR8P5XTVWJ`)#{xpsdb&8HBZRl+2 z#>L15z0PkTuN%~Y_HM#%)`NWL79TBGK8<)DGVFQRXZ6W%GUhL+dG2UBq9Q+{Vp?;k z)5Bk^1lBcSb8@s6k?&of@B0_@?|XO3aQVHvMM1sY>o5_AVe`YabUiPA4)g_3H1ytk zJl(5VWe{*Q$YV!_fkSW8&Q`=f)a%K!y35BcQlT>uwRtvJARPJ^Gz^St@Z%`SZhqsX zY530JkIP@sTm-=S<`cfZpt1|9!G@|l9vrR~3bze2B81c!d7p?S_5X4*{Qz1h3N`Dr zLjwtpmk%mM{HGd=)qT#d9d23{wpr7wc|UgssLz;9fv?m%H=pd{eN)U=5%JJf$Y4=3-;sE7^UJJn}(G8vv{>qClo zy5&K=o$Kqid5lm5PMr^Y5)L<~LCL4HMwN2gDf{jJ5pVtp=l}BVi@WuER4sjvTI`02 zYhzJJ=M8H@sJT&~$fK#lsj$s(x~3Tw@wKV6U90x2lNqa%F`M>76RWK!BWcFd(|}k` z#_x_A`4=V2&w@mzWx}M-Z+@Nw{yO8^x&H_@dg$$OdtDaH;=U~Ka^{n_xa8CBU6^Dt zCLm(?>z*35B5~#~XyslHd${3n=%J52JqDG4#U~fH`DlI0K6AP+|RqjwFB!* zdJ^G|br5a01OD%S{P_!N^Sb16X;%`+%v2G`aX)7*to{@WYez=2(HW{?hurr0rz#R{ z{yatB@Lg*ISlT&bU6i}lf*#u4lzXFLSY0o-^W(Fc3N4oGBKJN}zl`(K9z#%}fyn!c?xYssp z*X4VU#oN3KVS_7QB;%OdhNF8ltGc~%UlvCH1jw&7&;8n22~oW9sU=_q#Pr1OZehLB zqPl)L^PIN>0~{j>=&$(3YpAw&_#El*gZ0M}jUFbNXJpU)auAORg?Km3 zD0NCk8{xx0X1(8?!9auo49Z-p>u`AX%KN6bare>Ot}*tL$DQnBNWr+`}&C6Rz%tsyw{{_W5oQDclPRXrPbKbj8D?8>$ z%yVI{4j=2_*C&^4J5~c}uQDKDcGu-Xahz5$6U~eqzJHe=j3yg1z3vhCNj3s(&v?Kq z+Kpj`#}J__y*EVcIS-2FVkOSPPM6LEvwDFXt(gvgH75eDAdK^HP5N-Np~I=^m+0=> zl+l?C$R-Sr;NIqb6U1lfpY&@|A~>x}+aA#+k?B>o+H_s5QUiahJS{*?4eGEcKq!mhNh!}RxlLMh?RZd@`Ij# zaMCJ!Ip?d(;^5-!rYjLAHZ!FX2vh)5c}c$a`-CO_Tj)coO!K1tNXZ#vl-Ew-}Jh4u{mtdsyd8 zU8{Garf_xV+Q}&B&E(4J+z9i|5s3~#Psa&B3DA*17DMa*QOBMCDhWp;k0t0i2iK<* zWL6zbF6kuz4$noMW6|Xlvfa%s{ZNifG4IXBY>(rUnWuYZjhg&`C8Zt_5uJtoZQsL1 zc9!kg(a{jKwciLR1Rae>`v?F3@1S~bns|GYDo1S)=En=oD`r9H3>(C{9(G9($xExt{fYP?s{a`6X&+Caet~ zfhJ{gXKJ!a*PTp}AP6W9+^@;lUXQYC1wjGg09=6+{Xe#A_IET#d2GzC+ZhCCH6_0A zJCn`raa9#)67^CAAzqR>b(2;1$DU1j_;B^1zcM*6#=9x*##Jc1w+=`)`rr{H7SIJv zv`x3jeu>au&_0?ThbHNDI%@t$A9#;9(Rzu;-fQ3R9ixkNs=g_zr%@8qL>5i!Z0=!kKxD9hfcA)~Z7jM1K1*z*2u?_fEej~8%|qZQ@}g*RPNFlE@y<=ub92_W6>iASwl#f<)&$rAX7K>A zLBPYBpzHpE>vR{{{*N-AUGd)=MC5da%Ffr&WleZx!9#h}&f9`&@et(J8Q;2)hbMsh z;G9J>9k0qcGb4ep5}7+bYJ!eyk()vuTo*c%R zDjG544E};X+4_MqAfRXn2*d(Dr3wD5i5?~L1L@lg3lP!dG>NU`;VT6Dh*Gn!&8DSr zom_~hG-dQxUp0<22-tGY*)<16>UI;u)-acJ{@U*0xZ__?5nQX^(*m+{WX)?`&w`Gm zLu6=yKy;uC9GaqqR>TRD7wqZ(+$6anl4O8d@sC=}NR6H;RdJM>vJ9zfd0C^D6mH>R zWN_?_RJ6I5MYpxW;8GmXe8}Y)G3B*(3wbW)cm}c*Gy<9n>qOH72M!*TK?g+JP!xRI zS|SLfkMVFY?`+`JTV*mEkTGNJoz$pF`iH zEYb$dTJr|HrO2%Pb5Wdg2Do!PDD79rVJNU}JUSABh{hp`blvW?6R3lrs2#enDXJaY zqZhLK-ZzU$nuxV}5P)Nt^m=>)GzR!70G!yHaQ1=slpJ9D3bHabV9mSv?s@hzCqHKk zfQnwp;n&PalYGHqUmnlr9l zGhP&%(vJqL1cMa2JUa4P)#jj+QhI z%6lOsJ-v(HkV3q&cS>?FQ^%yY?rV)K=!_i6h3!ZqF+i`Sn`S(~&f63sqiFn}lw|9G z3Ev zE6o#;x|wcUKoKzw^n3zKRE}txp;?=Vx}!rmXP}cq-Vt4d`ou;Y7<0;lfA5Ty*yOKc z3VntI)ml)o1L+MSsu zdsidXiWweb9e_ZC`XjRe|G)jA^#r$ z_W)?$e{02~VRUGJkN>?-3oIcc8WVmUL|1Rdv{-TFUC%&w0^^L2IHtrM*ll)Kh$kPf z?H-2h9$>>Gh9)?&LP=h(nBqbS9-j7k9-hb<+8k(aCK{_Ayi< zX6~0$GE-A2y11Oa-59onO_8jTLc&KzNvUQio6OelS?7HJ`2GI)Wx4M2e%{af`g*^g z=kt6<+-;@I;J5DR*67Xk;x7j(_y0@TJsa4DjvRXcVLKuBqY!aZK&Mpq-FiFYc%_3u zeH2jN-HKJYZD3)``UJ1Z+;o;x~9T3z>b-6l|sQZlrI6QT0J)qRHV6rvK9R z=>V`2>^_#$#{NcTPY77P=_&}M`$X|}442L4#U3PE&5xAB*Dm)cZun4wZYgGo1Wm3W zRKtp@5{_tGarZQ|Ss2R~2_B}v><*g$o&O0$nWlkQlE*2)wq=YcgjXa-_u%Bx+6O8u zMsP`N0%Rr9FNLYEr}gY!8>8npM<6h(Y2u3>joG9k8M=Cx7$^OvYecczLI4d^?#(Pl-K@c{;)i} z4f2JSx3;L=Req_mTppMCP(o@3&4qjX;z)@wBHef3u7Jr83gHND25#a^{>zx0o&(LZ z(!l2*+9-Wr0vCP$-@i8P5sG?ZVTjkjloIGdbN!QSV9sxxpbbE`5-+ZJ9LEfn?WzPy zl?ayznS1R|*2gXUU&M_*?he^C@KXrxh)i{5s)qdgOoVcA1GiFLJAekk4K#AJK5TBV z0F2|h>*0);>*D+rg1n}e6jK*tHDpj;hf^M2px;K5FlZ=fA}pmI%#)26`Yf7FE)MQxdy3DscF8Wz#Yp8QE$SuxIp z>W{QmW6@{WzgaH20>}A*0Q!GNbYFRNZ!>KlR(h1> z5RF18XJ?7~^p>Ilp!`mrH6UB{Ibcx;4TQ!&65sQuSN%1B)<8L#u7OxnYnZNF1~uN% zV1h2I`-sJ{*j+dBNOQ*W)|ix-KICRPrp#AVoE8wZ&^~BI?Q6v{k-fH#3>2)}8Xu+vxEaTmxdlz5p$*dtA=)%|bQQA$5Tv>(vC=`O8Dv;@u$WjMgpEuw z1osi~Wgnl?S~fF;&S7TDDZ2}?Gn4=Fi~!&SmFaE#7K>8zfuY99Of_C)b+=|!$pKXG%B9RoIc=X>3MlXe zoTqQy5$SFSeIOZc<46VNt4=T^O{XGZX!Tog&^-jq44@E+z9;#aYkBn6yjA?>d!Rz` zVjNv@U}kX4p+ui6`+@NNHCig>O92}yte@nuJJI$`GTTD=;B4#z-2|*k67kxtb8QuM!y{l_HTfS zA{bh`?=QYz+U#f$ndXcBZ(2#TmG^X)V$e)qbj>my8#5osA8Y(auX1wAG&e-L2AYOI z$bDZk=$<+<{}>E4RO+h)K^wyL>|h{mP#1_n`wTvHEZF8Ry^mYQW%L2ccf#{>t|J-} zSZ1@TXz)5C?r#TioUyEbgaT?|00(8djN6X?Pdva2F?K1CGTho zWfF=^Wa%xk`x_6Y&S-}3?zS(~LMz(AbQnNfaAJ&j1PJgS))D$Z7(mz> zD18JP2?DsfoBmPoxNYz&j9vz+A+n8xVX#;|l@-%geFVYUg8{?0RQjfFNse5LT-6uF z#Wq7&!rv4rZDu5eyubhx{DJ8G*A5l_XC_b9pRYY;)_v6#AR0)> z8(?b@e;A#f_WaS<<&c_|Yot9DsTZ0m!+U%*Q%JVWLWzVTl8{7jJCl`nXTMwH|A#Vl zga9(%DM>>gut}g@I6^cCqpQF4`7J4fEFb0-JE^T)E|b9tl?W7c)K~x6N^Dyx~i|Y)*Bvul2&be#$3ti(}Rc4r`CI(Ty{9R`o3ffpe};RGB`@y zhqJ9D$>1UFYtk4u!FX~ee~I`t(#mHY_NXgBS0HXMC1gOI#;gjX7!-dRJ9-4v!oTwN z_1x!_iRq`LvLy-~rhvXL30Rd-%BHaA0ePWZ=syFafGxsC(D1f*9lWEn&U=UXC#87? z1@7%3Dn)Pdstk(c3qcIRfw-v1nl>Xo)H!p4F11>Io4QpDI@mD80*f$wsazBi`BH=Y zLqcJS(S5=H{2>1mXAld~aS??~@Q~2?(@{HuT$CtDdj&H(&{It1@LpIUN+bj`2?R3% z?gvSPzz;?8g%mjnKAFiUgYJ&}dkO&FA{YV_0jx_>dpn6VEQ<}8kV={J&o1q-#@wnL zo38<cEqqY^;uwVhu0$^~6DUn|-0f__XW?l%G7sDjLB*5PP^3Mkm z7nXvzNyM9{a}6hHewLy>DeF5VoA+=tqY-aaU#01BJ|fk|zm$oDUyrBLpWHp#oN5&* zl}SkAkt(1$IqTIDvK3Gd_=ydJpk|{m2oV^yAFw84a72f50?1 z<6*`hzot-P&36;@{kO6NM88|ZP$9w{rLRdLA`1$4?`R#`DQs9on_T>5?cUP)-@|R$ zsl5(K>H+4gu`$V^4}J@c>CSXXg-w4~E#HXbtW|TT`hSXiT0R}3#Akvo7*zF08 zvS}$m0viP6ab-oUZSlbre4UZDY-V5UQ{^3@rn~WqYVptCBsm^vqK4P2zk0#6-Z#P9 z7Q0c4ykpZdoeNsZyb~qKP(;OYSt6C@P;}((OFHL0p@MvH&pLNkQk{J@9bkp;D1A5E z44iOZG@+g|L2j`9^5o-~s!G<4Dx;5{BU3t^4f`ziMvYr~=g-?iFOCm|A1tpRFYP>N zm1MfT3nJ>^kP2-`o4pAvbzqW=q+c`nA=!@cEotLl9fi*vMux0@5U~@~!Y*mr?7oQx`YzJz%|lGRRtpoI|Pn$^d#et zkwP?l+l&NEzOH}b8i^?Tbmi;+xGgSEvuM3tI`9hx<;o9vk01E|rh<(=*EdYykQP&( z{zuc5XjobF<6U!WW|lMc*5#lz9Tnl0#t-c<8Jh7TJ&K^1uUfLwl3< zCx5D9V)cc;`Q{pe@5U@PUnrKP56~M*`|!W*dDK`N;LR`K4XZrr$9H_`RI4=HXmr}M zW_!DzD0BW(d4-_mJn3O{6;$>EQSXH(UO5q0JT(Xl#1g%)zLR|iX-fV_NALH4RMICJ zOIHJb7B6LLhTXT~OJ%LkA0}&FD6ksTy{}*Iz5bqs@iofdZfJyU>MqIh?jMM;Hy$*w znSVM$c zmaPbQq}Ish7a!%mHMl}bMSoU@WW_eu@O0tPU`r++0K~qibciFA*jyKv;c|@Zk(Z+z zE-E-&_KT$vK=Ki=VEx@M1*IK0s4!qpVWn5A;9)dZ^t!TGKkN9Lydb}1aQg!1T4^*& zZ=nD@1}vpIp;{^}s}V~SebAX+qW}fYZ5yRm^9QhGdit-})Qh&&u-~1_1S}|*L9RvY zo+I%mgCg$oR12!Tnn3>}h}pk|N<(z264y6Qj3pG0pteS|S&#h}v3rN8#6-%GKx}@% z<>;A4zJMc%dqPCnRMkm4fXjQX>7*IV4O$-H8OC7bR_8B zDq^krvBJ6v9Htg(1mW2Gd+g}75;iPk@>^8O?t(kr=>pbzhn4<^vtu9PjGT#zN= zqR%=|I1&o8^`gXJXdJU#%a@&q;$(qILPN?Dg zUHzNxXr{3D^{@ae1C}9&B`mHKP1l(3LDQl^3j^ZtQ!fWnR~SnE-&DW1=()ZKq2CQolKsJ{4+Troe3F#ydY zXe;NZ>Ayk_CDFhn`BDaD>sV0$$~O3X@-nh2#?qUdpCXG4;@z zw)*Q8WK+#s_gg!zgQu(+z@+HyfdISrAq44X0JkaI@ zZ^03nR8R+923X&(vJXP=0ovkMdH|Q=P*#|V9Ez9`o6uhy>D1@B4(~p=om{zv4huI( zegbnTkd7Rm0W&9)M%Tk|L%$!h#0z5a0gh`>Uwt2B6&!*21))5m8xe!IKsp$D`6=7J>lO<~|~!9o)7nn4Mf1p{Y~)vzcu4g)M# z(xNL%LIhwaHoRLM^?sQH_F*r(p`Iy*44Z3Imr$w?P1mmBWEwi`=FI)e#8z z63I$JsVtz}=R$KBN7?+$wbk3{qC82Ezhe9rPV#wo$T-PHQPD38G(y2fWQf87v1#5{ z3=D?Dx2~&nuQLW4t5SfaN%SvAGhZ5ms4A}?qU*hG%D$%Z+qTNRcjqt3b&kvj z&-@Qo##UYxr+ia%ujmgxas}vbYcnq#yETj=WJ?4x2}L9t0Y%6L7@bhKe?FKzpCS}V z5T4Q1v_uH_znl*WRO%SjOg1+I`r`*G&vC;opKWBS$}X{%E51ZjyqbGR$r}?i*+?;* z<;w{{fcFfh1nk4W%bDSbPBzqH3rUrYtwM=k4X{tv1AC;eUjxk_IIvJ2%sxM;vSUEe zu3zXCxY%i|&E~+B^etKiLLjfymQq}k{npnb&^M4oiDj~qV4NK+lnX@0=h^|g8eC{x z7r)jzkChC4jjj?&8tV)cHIy69(?L{_2-z^iO5D2Mo!qp&XCg6ce#^{;H!O0Q;Nijl ze6tx6THhr5C^P;+ehKd*28rJt? z3PnJj3k(vQzlHwycuWGkQ0YAL@SxVwd zrP+#xe~-T&`>9xwAnkH=Whs|QMeDB!+0vg#wu6z{bjnhYbb&z@!&9Z#_pV47Zd^r9 zI`kfdil``9HiDx-%waSgXVv2nN*D|B7!p_@zpudu4L34Y2j)6@>&<3k=-y<&SaYKtoHjVc0}UBV2KXEVICB^wfQ3`55x;aTI^{R`7)EV) zgS^W2lSzaC;#*yYw!k6j2xaD=Xbb2nf$Ip2ATgNX1{k&y32f=uV_4N;ZJ~%E2fvsK zyd@0_F<^*J5l=JwKq8E8C?QmB$8W0s6@U_8>5Vd&0&F?UXb}v96u;!R1?RO@ zGziu!XrTM)jwUZN1-48e%Xu7{1`{|G6e^R3#R66YEV&H7;VkKRTLund1VzwDGC>1> zS{XhScqAhrH-Sq6!r%*q5}r(g2N4GBqQY)bB(Rtwv^wa4f*nn0VIvbH2yT>!Yg<8D zrd8tn9Qr|4bCCcXhHs!6VVGP34M(KG5p*EcLHzs?8sp?|PiO*=&*TI_xIQI!5e_V6 zf-HnUSIqlrfZi<{p{@*eIY=95!=R}YI}a1fB_!nbYHZ}Prfh=VFY6s^lFKK{W4rEm$c!@9cD&ph=Kgi@(;OwSbV7n7F);M z1)-n`g&55iSh!Jrlo4R90t6VWGU$>9*~-aK2xUUC0ALFMJuZl0A(1A;&~ZSk5sZLc z9GF=61EJ&j!S)3*#9qqeLm-K9VBmbGKJ`S1B=TK!qm_^a0jy5|nd^gnLI^a)l7SoM#cDvn!O;v{1f6FsZ_+h@etsF&Q3go1l<`FK zK^x{_44rpxFq-66U1{uSEfD}QlSF(FQ9)x3mK!BNM*ToeTtqPn&v4TRQc*ypW6?mj z=?GiF0&O_54;UuJ4tNIN>N2*n4_j5AB5W)Z$oOz0BOoB{50#SZ&ww_;Bp(Jff;Oz2 zCdiTiQV3-g&;y%vtTqlz33@5Rls-x0N<*%fJE|aQM|DkX5n97Md5D?lm;l+`LS^MjOy(0Y{KCERRWm z=+A5ft_0x#Y#=WOzpO>!#C)h8TX|8rQe8P63l0D*1+ zD`h2+6)n1!Q>u8dGe0aa7M(Kw|Np>-c{0(?XTnKixK2dyfJ-f|^_-kuO{`b+tMnG`@FnH6A%sxEP> z3f%^#1BzHMm&Qtcb!9LD6@dc0Bf#N67VF^D<$qprT1Q%gtQ@}Av85?A~LCnO0^1jYakB$JR)+BAf1G1Q#q zW()=c%z+>}grNC=Erh@-!LpiigQp)T{(f{Itn?JXKZK&9lKcz!git`}AyMWVH@Ug* z|2;H5B%}EH1h_F&T><>f70JUeM1}O-hj0ARJZyOWe4fC1W@IZ=c=t9mJzj$Binu^M z?`!Qd)SbQd@83z9L8z9$6Cc)TecKm>P1Up#itP>HYchyT^+6QZcrl zp0DV}We_)&TevGwpI2`k-`HWJ%5w@!Ry#9injE#VXZFw1o_XGOEkRXI8OA=cv14lg z0%c}}WglLH(_xM|^y(9SEnhJ9zULaJdBRkI-iR*&OfGftUKIz;V6|h@?vV=UV;g#!xU38$=2;S zg<(ymu70%BOq&U(uIwrFw7~ioMBEU0P`O>dQ>ia+I{^{T1)(?pJ)DnS*ML9$SD1gN zmZA1dXod&n@-*ReCk*Y3zWva}_WWB&bL0J|9%N)pNh}q+TP@BLvXN~eEipIRzT$ZY zFcyaNy`dp(8L`hRcj~XYFn!c(bB9G)p?ieUt2^}uADY8f>Y#|MH^Kqhvqtk!lj;fB zl67aP7K20u)LD79Us(y+e!^Pw=qD48a2&w4&)V-1G&m)r*aD}dtGcOYS|wERmr9JP z62yc_9wxcY-JX_ts0dp8PQfkpT+dwfH_gNyFB7(=kfJekO}vIi4}I1~#b!mHsyVy! z@iTk8f72#RvD3l|PxQncEswtp+D{YOiSI2}Iyw!|@H_Q`W3X8NuDw=d&lUKcDqD{Z zhh=ugxLo(h>j+^C*#{7hFp-{yX9Lh&Lj5nXqfUtz6Bl*N;-3sGzr%c5bUj<6_aI|A zYBA&7*=?kJc-)fOb(zMqG;pZx@@h>SG~8|dh7LnaD&CyNEx|Afb`{>zAliGTw|lr{ zx0=tjaJ94xEA*=}Y|ox;&-L+C*3O*Y$WO#(WY9hQN53^#P`xUV?jf5V5eyAYF*pn^ z)Z*$j!+?#Z=F|}%ADksFHH?Z;{Wb*ITAlZ4zoJ7m&uojlc1dyl;cB>Zf;j}`!lAk5 zXnO;sp69om(Cwoave*x_K0YT+mhdHV1CL~3n-u38z?0;g&vU%An)tTou!@p^!& z;p2s@-B^@3G*LJ+C^j!Kr#+6_zwT1&NSnLITU8}w*vdCE9)V0jfmVY4$^viGyFLVq zy^5VTGj=iiG{aUt(&)L=S^P;4UAb}h&4Wya7G2dyL!;@~P+V84kB6SB=V}91e=e1q zinO_{g?t|QshhdV9{TvKFR;76&^#-YIh3@6xUs#f%X|N@UuX2&wb;uy@K!il+`C!p z=j;t1{L%K@b@V{AwRwWJcFJ+%(chrFW{5dwZx~X#MN~jIyYH3;*5ZuCuPUJN8}x$a zm5Yo1ZQXfhz*U`1S~SCr0otOVAf1TpQMX4n>v-tBrzijRb!*E|nA{JxO=e`AKTr3$ zvS4`D2isw&rB;6nxl=*0^EEBx=}}eHJ_+^t;&rq}*f*~Y8{0zcwPs>&G4PlRPMzOI zcrI%D6t^eoz`Cw+MLKB{UESdPY@VCs!cq49ro~|E_hXxqJS}rQSAUASo1JX|f`?m( z1FX~D!yF15C={ll9V{&pmj0V*Z`09>Tz1-M6meQ zR;N8Q8#r8lHeX9$zvR;9>y`F;>TmT{_^%l5+@o%3X<6bNXJLd{7h1T>E_ziPk!bCl zlADx?yhyYUn7nXwV#O-j0k3%-MBA&jy36eL<&dk&Ih_QIADr=k{i50zK3b zy~y?fW})G<|hnRjN? zDXpqR{AheO5e{3ez4ZH{zTbS>pW}(f(D-q*5Bw^(T}gSR;oIZHMsTh_O-ZHj@hOPa z)+vhr6i-?jRvv%TIDz}@+v1W3Y<+A z=MnFSDa^_BTuU7#b%@Sq0#m-z-TIiyJ#A^eaVRvD=JC?<6463WXS-RaU4mvGki^FO2$9Ba&76_Xv{xq{I8OHpbdr~w~MrV&54Dbw+U z8-v4^XPvS<+(J#EyTG9NdiGA0v;zO<_DglhAzgWmV0tIWg+_IKiHVvotu8Kki|N^k~Z(9{98)0BLDZNg#MO8e&xSYH72B`^|}s zPD54Zh&GbnnSk3Dj#m8MN!(_q*WNbK-hED6ly{GVO&Om(RW@s9Ry-R7%>Ze-fe4@1 zed-bGb-JXM))kWRaRSo{b$P9-bWwa1vQwKWPQE+yS8}hQ(vsMVB-Za(+QDJrFbIX-3cXsKi=d3UcTR9@?s=7X& zedF8JsoDap)2fWR(}a!j@!MJn%)wRkD~R^c+V)2sQ}G&6Z4={h6H`fK;jQ7*rEINj zkEVb{ij%$z*t&<>p?L%UXL?%a-?~3eiGz>WFBP2)_)8O``s9;GDyj}^sek4T!$>Q8 zmzKdg9L^T7cn~x@CiJ9Uiiid+7;Dx>2V(~K;mvA%qPrt#uz!+i-L=#${2Jsp;rdpeHUTkEVnwNW>_q9vaI&fWmG~Dv) zaJ#9lQg+-q6Bmme>Jm0>fqeI4`=i;hv|{nwWzt_*_BP;{OIq;};5@d!)B`YU4#vd9 z4mid8`lq-P9gMVcy|hdY4-FG-j%H@&U<{N}yqus~UQEQzkRd{?8xQ?9K03N5Op*S$ zTkDw3UQ5YEI!;MV+1lRPdE4J!v^YbIXI%SHE@9(N(|D&kR^gDpk>(984~d7p%~8r> z6JJ|=PiVXOtoiNLx3u!Eb-r)XG0Ag#Rk<*p3LYTq6!&#)j`%E@kDInj^CWKkn!M!A zKQjT6an@vo#^afj(U@Ba1-l9`>4dWSIUO$>pTo5wwZ^LZj8Fb|KjwTO{l=wS&-Av? z>v!53-<`&zpC%X{u`#zqN84fZ6TGwxwbVD}mygC@#fDBYR$aLC$QIy>%Gh;=7?0DD zO6KE?f{4PFt{jtMca`*!BbA%)*{q`nj6Bs}Rk>BAcI-9F(l=*EPgi$j-|_LdxwUyp zs9AN#OX0e43p{qIFwZ-Sq?VFaBjkR6J#OJYo17I{r57=#+UCXX9{Ct8&!=VW#MXd_Dpc+G?xn!^JL|kG_97m4-k?s1kG9*c&3tCL zvTSoW zxJTq#&N(F&w`Yv6(fTOX{r$sq+G3Kf_qGh*U|=Msc#;&=uaOh0%(2*E`1@ zXnlChlRYtI-X7-Ei4Lt}j$EIbF-4uwP-?rbvgMkvJ_9|ibb0{lFK{1VeUv}dt;@&v z%5g(~10$`{0-X+fExLiRM)y=0L65j@|Im51NGsR#(fcbynQvXL*Jn*SotRj&(=#tU zh23(hPdZFEaXLvuG?&Wc|5CbxxtOtH6_PsI7!>g(hgC+>&6o964Dr8oUk)7k8vemZ z=a+ky?V)wPdl$cq`^KlVZgYy&Gs?*9s%>Z}c#u-?<_=I8tsu(maBRnVx}Jg}5KfC9 zt*z}DZe2tCf`$?DHd;L+glXrGccAgsv5ro)BXewgW7|{qgdces-ov5`?JTyRm^IZI zdzjSi9N#;->@`c?$Ik>R{9f{oxp>3#`JE~x(!^aMCnI`1^`x|?ckKQ7*b_XQt@m=A zWlf2hi><9KrZC&XA_vJ=sItmxH+pj0Hao}MB*?r&OMMQi&t@2g64BQBXSOexUZ>{! zbCEggm|Y+q=qjHFPD{UXMl0KMZM=>VWTZvc!6ZlGBknkLAD~`u2#Kt_Z^BHNUt6>H zTwId#PTdFX1JXEY?>YSVKD7bqLIe+5#4ZlKrZafwea{Cqnp3;Hypm1NX9Sgt+9`V$ zQg*bpvIUQaqLd^>?~WSVEUb_k(CL=D1u-bYj{unt) z+Vp;*k6ir3z$5E`g;uVI^pO+}Oxu75L9oG->0yy_r0h`cygu)Mj@8IxbL5TldVf#4 zL-@yi)LI{3zu2fPz z;YNaefYB|*UvB&{wZ_+tWt*F^!z`3mhWa_tDVLd=o}_m{w{&VcqYGCej;zwOm5n(>!`m%(1|=sVhA9 zZ>*&~Up8=m%=^ixseAX^-FkNSTn0~J>br_oZl1%`JCC)R{t{Z7pCFEbYC)K3c>e3+ z1jQaJVkYt9)bgK_8ZmGG00(i@9rL_PjiH{bc7MHeR9uvJs|v2znq;d8!Ns)(<`2L%z>dg*%1!wzMyD+pj(!|x_{Hf9Op$vEmf5> zxZOQheF*V?-10xOYeuoZL~n)1`^>pB{h`}0cHTQ4<>+Lt?!S7hr~YwMZmLq=-r}|? zFC(>dFT4AipX=1@d6@Z~x+U{27`I35<{g>}nR8$U%!ujVw$6pVGpp_p?QRyaC(J}} zC()eUwO8ls=XInc^>5&0&FV+J)g6X`)TOnWW{r$3?ECESrvpol%_Qd|cUnhUzUfp6 z3>RG3O<-eT;CNGd*-_bss9d#AuO-`MUtF)?DU4`h4jrG;XpX$@nYXHP1OND0Iw*-V z-BO|Dw|y6CNRquVZ5jVO@)v{m(ArC`flPmp`33G^dE&qPhJis9!^u7sU`lD%DM5xO7g z>v*)#OBIp-aV{~~*Z-Z;Myb8*@}R;1p6q3{E15S07Jbk9rQ#L6=JWi1lqsgWGCJH_%jH7k{cl z5`WM$>s)UY9UDPEc1Jgg-3|6H*e$aS7zF7>0V*r$NASsK`yWYg%&tlCy70@E&8P zfDy{XS7aV;)e`4! zhHknOb1CBX$}*zIsvL8V&dsKxrnBF#%4NC6LdSUeIsEw=KFUMqefi17;0nMWG@djT z-hu84-B}Tps~@!T)D|?uZuoR?qQ;C_%DTp;F!G}o@>i!1BRou_i@>PP0>s>63yHD! zCqCXZS3K}^aJampO(Ohk%YJu#lcZ!s>X!E9=2E?O^rDNPl`oyEm{03?SxDYcedYM2 zl<|Cmy}6Hn$w=Qxi!iIY1Dm&9>VZ7hZdw7J!e`w*y=HBV&-9v&f~8Wm{50F|3o}WD z0EM(9NtYGxl95fKogIYSz8=t+SHqfKbibq~QhcZ6G;kCSJ{Wv>lgk)dF+O4j8Qa!I zek$^S9f_ye;|pgEo73K!{k}8=eRiBxS!0`Z-z@F^C}mr1L6>r?-Kbea%f0)YW(rRC z_48Wep|tyy<%_RqRR-w0x07tt0i*3H{KP#mfv;DdBO0_Do=u2zo;TU<4Y*ueQ7 z-y7U^k2fo51wF#qZcQy?91a&M2Tnz1oQ)E(Y3awS9YJF0Q}&Z|moFyL<)nm;G8yr1 z*(XgUkI*l58Al7DyFAl-!vsW|6rYm01sbkX`{v;(n{c_PRS`SZdrJ~PR(&3I7xcfC zASG1P#^>bLxFE`q_otT?nXVP59+HO|2n@WvRbvr`VV78maf%-`yo?XyZT;GFp0Rl4 zUru*FcJ^vYrpLK#U*^4M_U2X%(Rl>>bzxbMUhcw+-kPUhW<148r^bd%$0>19(~J1< z%;Ygb?vQkHE9^Y{rM{b?T{m5HKmcQEQ)r!!b;VX@Um7Hh(vh@xABzqxpN+^u6&mb0 zereJ394tYTogbSl)i!RcnO}(3pa?0a_-$@sr8t~Zc;GAjyQK^$`iny9Jw3sQrv?;FkU>8!I)dXtl>lz!&0YUrF~``S-n%h_%5 zJn2q0w@2~#SkSrD2R=!brNk4pX;q{FvtervqiyK*tD*vZ%?P@K+3&6ooG6TyUvd?x zvpKTC2GPM6SI25VaDO6{RF;Q{hWPo2TwC* zbF=rWVtT9fXN#6za(-#vNH-Gs4ylbk*rW~dKHojZIA4V_G${Q1sIl4UkV?x?*s3b)dkMXl z+5tOj)@HP~873TItKz2?gSA<+qA|xd=+omzwOkta?c+u16`1_t`>=VP)$jr`t`ixK zY9oqc$4K7JJoXnx*Q?S8cB5K$!)hWwCGy7DcC+tVD;L7}Cv|7&DbMpp%b*RHqm!orF`pS7;fY_4IHk zy?3gb*Z%HH;hpe2Nzc?WzBd)7tc8~EnD#}a-G#50pzbMR?d%rO9@b8WX_7~jCOLUS<;3w6{uDpRLePe(0# z2OS@k@Z9xa{kmv{?^~&(cGJEK zhzgZ|PT5@DJwM-RXR6l@;*K?p-r19-JIB_QYsDN|fB1oyM(jXrs>hu?in2pLcOdzm zXZ2Nnd#~;C70UsXtlQyDG63t8$bzkZ#3VH^X}W92#jIwk)@6>0vGkIEdvPy@@*s4*D2u zNo0&+Wa^=nDOa}I=5emXFQyAQt1>rpC+fb8rL@ZQ*Om&miNAM6-07V=-ClG$JJ-{i z?%d6@Zq~lz-kt}HiG0VXh|==3xG?#Oyp2q&v^AoE(b5;y60?+5^n5b_Ih|zBR zM7U&K)Y8jia_8jsB?p0DF;0=IYl_}{KRu|mFvTwYZYo{0dX$?)J~?%qpUAiTGYb_D z_aC}@rBtOTYSHS?TfGj(BfYjUzkaB|Z*J-VJF0B zc{t{3qSLBz4{F?l&k8xUL!qWFJ4oaAfqTt>+XxqPqf?TaTI*FbEGuQ6(km`9j}!G~ zkM{Yv=O(Md3-f02ncqM4=DDuk$>OCo=?2_9r(*6K-?!j2w%mMiu!ZqF&%rnhnPa{w zc8JI%%szS6NV?f`|EzlQG<(%-r#MFQ*nt14o0gXJzW$wmt|_|+K~y*pvuNjrUC`R$Ln-LqIE6%QEcdY`&K!AanmJn9>;-*$dLt&MtSO8cOM z_v*9tYqq2n2>JWHq|9=zSn$=k9Y05UZWcT#B@dThy1!-*&%SHw|?kTHfB7n2lt;rf)XJbj`po za%{T3SoB)wT-8L4L3PNvr23UlXhQ|%J9#_#PtF)%0_q~46sgRnc~9^(HPoEytvUu< zhUT>9C24^q{w4BgYv=b!_~~ezgwAd$B&YcV3pSo!UOD~huGo7m$KWfb{!wA-N`MnF zQ|%@Dw9(#5BApDkX*R^PO4u}fu#QBPO z|F)ZS->iO7ts4HmmQGH-k1V?P;oWZr7dzvY&4&3$L=}eDj=!0TFFF%q0*5lUJDGHO zXt|*9YDVQIHYXMqy~j__&GOGLI+j7qZ!k15=`lRl$#hNBux>uJi?gpNb#nzfoIJ!o zJVttZHma;AZFkDD9iN;s7GDm9=5bdfI9<`yMW$}VoFlBUFjqfm(m7VY(`hM5H#j@d z%<;aN_V;~Rrw0ee9Q#4n8+qWJC@F3u&soS5T`>Q!V5(LVaj!zrdfG^r-z#2pjmrBq z&C~4guh6QeW!!@f_;+l#x5sy`HNX=L@ckG@*O}znr>bVZe0DuJo3tok!e2SY9rH#7 z^ESSFhLW~B@R4c3QTZ0%Vy!sbICzx9>MHv@p4PMQm2CV0^I(3DtL{skwJ$7ACOcvF z7MD1sv9*>}myWMZ8EcJy@bT$$e3VjE9q>55LM?#pT{St#ad+KAk7o0V#szG<&i2VG zR;i`yUrmRH%e%Oqwc{~d(aiBJ&yT+T>Nu;muz0Rzu-&{bn zt>eY%>6)f-UK)E7dD~}hMHTaH@E@njU16L~Q4y#&K`IR$pEg%Txkp@?I)%A3AI0Xc z`ntB6G`@K;pg2r)d2r{*>)ZYgMHeJfc!dNqVadUH`q#49x4YTb&E_30Qc}P6wbyjo zESTZ->G#;K@t=&WH*O)i2TGGT2m0Ug7CM)%J+R%PEQ@1iOvq-eelXlJK!3Z(SRGajSHk|{x0!W$)f7xNdBPV zm{q8h^IpPBu6|EH{$@s;0wVG9!qc5PNBIStXL_kI1GVcpqJG(>*|HPi?^MCmz$+@z z82ac3GCt$EGLocdp>6>NFKxq_w`_L(i>`vWq<^CtgIf7j^v)mLxKh6g{vSv%XI|Ac$Yg>%10*!h7W7khZU+y(an~{?tciq^61A3h4W}K-v+vC*GB3(jf~Fa~ z(~F!`cY4enY4AZx8DQCYOv3z5a-4XSXEN@0vdhfT`+AYKQb{j;*3P}?@SmrgDwK`> zo!x<(Q`;U*=&5_GW17~FC!o2<&n*7-b*Ibjo#c_m)%)LHe>*q)F>@9_@=UBXpp z;XmW|B9`Xc-@fkqt~5Qn#@Ssrf%XFI&$0esSaW;2>GW*r?mk-}3>PI1;n~Qo9bNWhTB*dCn%l)*h*)|0)?s)X^n4stN$z!L6$LqyCr${MvH``pm z?YLwocU?;Hg4t=<+ivIwf;YBlT63`T`mbA<{j7dST+tlPf7`+}e5*Dp5han%Me%Nu zr9qrs?cwAYs&JsMJ}jF{{D`3m;LnxFun=z4 z+D{ShAh!7gb0INU<=w0cA*m(mR`Kkkx+^>l4SRG^hHGkgKlA9>a>gFxrIHhpABbN( zVe-S?r)r|oY8Bag(OaWQL!oLMNznDu@aZTyN!Wj>>QF*DxS^+bVqs>X`y6>Jtqh)K z!aXctZ}_NGMsNCYUMSO)TBhZ7;@#$zI_;6V2X>~ZfcE(85suP3x>r(5Ss}B6L zh~WsAF{B0h>uK?S|im)JWo?sEL&whdwRU>AA4__5_vQQ)m@xldo` z)lS+QHUzwtoL&$sEFeF)%$VK}rvAFvtk-1g;-isLTlxs5^xKju4skiu_2JNnvPVn+pKLcHwO-|V}QSmG|f6@NAwT}9n zY3kV%CWfgF!$71q;rL~zx-*Mo<8g|v@CoqbbV9Tr`Fqsy%fD9)3BZ}3_qFE8$)qzM z$WNm$PXi&g1Ju|GC++AD1wD|wtZ`3W@1p$4-r(8)L)Lr8HJNnp!!!XUbT)uMLPvK) zUnvqg3J8MYK1x985EWu53ZeHVy=(x1uqui^h(M5_LLd;Tp(rB7P!gJg0-<;I9elpO zzg~S(j!b5^zOqA--0)hbIqiwq44Abcr&aejkI%H zWWtJjW$nX{o_}zsmdU-jUG$@{O!32rfFoDlvYQeg{p?!=4F}GGkfN?#bCnaZD$SC@ zB#q)Uerm8hWRhD~r6u=%99?C3mma?Z*m$CqS5%X$V0EQ&a8&hVE1|k!#~8D5q!z>n zBqA8nh#_%`0n#B}uyp(P_E-D&!gtJ62rRyp;l0s|pTV8w2r8Al`#YC`{cGq#ETg7@ zH89OadC3TH$?#?hc?tJ6JZ)XPF$j;)+KeceiO`uUTt^=7K>>Q_gcgw(b|m2pzxN&rr3i-5y7f&BYlG#)jFeK(_waObta23AYy@;QsTpe{46B7 zr1gr_p?WCaNbHp0jh-mWSsF4+n}%7ZM-brE;ww}|`bz9dw0@wW>B>Z;YxXC_NdF81 z$aGHB3cs5*!nSnn>2;YNn`YqC(qU5A)TJgFa3xUXhY51a>sdl^di2Gu?#br&4X>h&L*Czl|I3DqIf7?K>QQ5$;J|VNiUf}W z>U2MdiuwNSqD+#!LP9`6eEOl~Ta_&FdBNCS5TL^PigoU|O;)>bJ7WVQVd^{VGv!%E zlg8+T{pxqSq3HRe{kOD5F#ELu4X|S0u@o4WkcBX}>G1Vcd{i|qpe!|lr{mySyW%QM z)oDpct+)ZE@6!toSw@(^R@rm*m4@=mrC3ImWA5g0*7D7)I@n-^B2DOW&4#o>aX1+4_aTFcYSIa+$ZZqz>fHL3-?&? z*GoXQ|9dnWfEQREu;sEis}aH2uUtYH@W->98P1s27P8wGG+_z151nZiPJzq+;^L<8Qtz{s10VeX5hIjVfgI2hi+77Rul*0>BD#5)Ic!*Uu~OI1}XI>T4D zeU|~l&F)A{RP~dnoxKZvSzT;e0~%QZ`uXK@0trRl0~`%5l4WTa7Sffg2l(TtVmTzOvW@|FB>~1L`Nd<#XtB-Gh+92)1{g-KXpC4n1Xb(>HS~UBY`w8{R*63KsWf zGAw40pOGy<;rtwHIZmYL$U4?}42p<+E}|v}3dnFN%O&fDhMVW$(ToUl*nd?;{<9}R#tF}9(Vk#ioy_TJb1n{!C$@M{PZI+ST8u07TMc@*YRTm7| zl|305jGaD*;M`Sz^F}f%yXH+o*^9?32hrs_kw=X9ZvEkj3_xC1qx79g? z=l-8gVRKB%$?6lW`5|=^hD6Er+bsEw>4YMW%TtK-4{{Qze zpoicQt+`hw*g`o!D76W7wU7U@vF7Ev8*2Z$%x2Iv&{`OtBtwtj^$<%Oa>zVu=ea;0 zCzo)O!e)&1dE!~6ygGb{y4dl$cV1CCpQbo>U`M&FZ^AH}H7##xHXJ$oli#fslc>*+ zbpD_Aljz3Rm|HtXWrClXd$_V2Szi`szZhQ=h8Oy0rW;DQGgwSDKF8hxo`=@pun4Uv z#3ixTjujL<^vY5USuL@}%Kho!mwpXDQ$kBSfE-Yl`dD;Kfr@`~3%9FlJhmdaX|D-e z!SklqBFeo@?mP8Ul5~=EX0yFx7?S`tw!Q3*=sPbNJ_N%n;{P@aYl%4EDs*%zd7OL7 z`8J)sVRisgR|I^`|6Tdla}SVH19f9&b4O=y?0AnE(HCZ-4zT2np9eD(rjUh@h3ScG z8)Jt}nfRf@UY0Wm-|p(sj1YB26yiXNY&SBn|M{+9M~gr-&l&rlu2xi%amX0Pa+iOL zWi-QxYCgXgp)x{Uh@3n;5M9sWOt66Z13w+o{B3cMWmNrUfG2ZlsRylPZDbqA4+O%% zaS8dsIRcLTu|_OUPZ@C!Cb+*cbhrZ#U?Gjl*b6>0_R3rZpKXO&Fb_VrJ7c~>U>r{V z0ef_FJMR)nU~J@hf)WrcmGi3+It*73n77URP@w4EIfoW&p&z9J0jB`?e=%{Nd9NFj{6B$j9x`E&vYD4z1%)Ie*9WCE^>f!$pIG`Vf=hw zDalwvPxuqFD9en6c($L{9<>tu*xAqQ&-gQCF`3Ws5zOpRm`WR%Q**cKyTzU@Q*p);Z#>Ga&Ma>4t?@<<3KBxL-|G9^+co@b=( z?{bc(+rAom`K_RS(ePHaYxywwWyFoej;(DkxlLB|>wRUR1KVFpd){>LnwB+}8JE!P zwbE5Ss1m|iBf%Z=xU3S_?jLn*?ah0aQE&mI$*(ahhQ(_gVSHemavS7_y*3J98QbXE)Z4q497Xsus+`x~7y(9XkDBq;dl_cBa*1PD9= z=@D9_$)7swp(LuG&KNp&9_O9I;sQ34x~;ScM6@ROrl@w`OO!fz|40`8kYFz4#*{vf zla>e+x$k6490rKoNf0>r>2#%p5+uE%?i$~;(_PMW8|$?n3g2iQm0FHOL^}V=)_#a1 z5X!>8M}@K~0{e^57v(6JRXw2u1(}`P&=R?MDt`@KAPAFua6hU^H?7&=-a%uZ`gOc< z!=XATakeZ)19~UWGw*vejF(#Oh>fa>MnvOV3J$7woDvSLBC|^cFSc2mV}Q#Knly$~ z7QvlOHt0WU3RF~4iaIBX^&)%Vfstv-Q2Ijd{tDp~Xw~uLispmU;QjhzwFfP$(ev%S z1E4*#ckj@3=lgcn)AfNo1c{Cz@*;IcaY!j}-%X4@skg~qA;AE0JYOoNhJ|T3aF`lf zcHuN$GX`;Gw=3w2D7FV=QEJ;q^ds6)<5Akt{!!%-&2B`dZyHJ<3N4Kb*+Vo-i>bSTI*VCqXK?_!@A9b^;KY1CwXGOYf?m~=MjzG z1Ox`1AjhIfw8ZO`aU^Z~ie zo92i0&d5m5C_9i^YHk@Y77Ej#V>w$XvweZMs8zDgXxK4wS1^eVPA;&b;2G@SV^{58 z(04cmHQqVnMV`FVF}f-9R*kwF%X&0}VHpX}V8|CkJUf7|1+qCH0{}i)L-j-cQVWf5 zAh~v&K;Bi~RqO&>bacB1Vz#Qucearooy|U|wFD_9zA7NIs7^MA$`m*Uwp{SM_ph(Q zkbp-H6bne1?sqJ3LEZQoI!Gl8Y|x|G$<`}O^8o~~As`7!c6o(RZRp5KlM=6>@RzGL zK?jdMmNj2YJL6nXuB9(HQ5t#KH|%mRxrGx`Q&WFXe{=y4`oa*hk*1fTk5oZl3}C)?PeE!bu=Q_G@y-Q#@7xAR$4<-i5aZ zLjSU9BUWYT4NP5Z7rT#bnvTb*0F|%q{!h-GvPs(*jjkYktPX;B(^t0dZjJhzY%BQ8 zBF4t2ZFhn)qE(~iYFe`YWy@}~1nVz$8vfy5w)}4s`=pzpN2W&s3wtRhb%Z(Bo6$3r zbVt@xJujZ$Un@)`rfGdENxv5aqKauGkT8IkACIm{3LwofNm2lHr#*ezY4y<{DBh+; z+14>=`oO}(fQ{E~3W6_QK0aB0LL!g!{fWk}md$iqz1}_y2A#+PY5v#ymM?=1&4pYo za())PP)MHmemJJoJl{J%`OhTSUiAbLn*EFPRNDp2hKwh;;kN6%YhUG+R){{PI%Stf z@X!>r*oZg!bjZ_N5{9F>Gw(X0Ef7Gk9O zM*W!mMEZVb2U9@E%U_2+Yq%NqrjGLiTj)=}Xi$m$@~mtON-d~(YiZ~qG5n?RdO&uM zmkw0BXmbW^hIJt6RtB|(719XwdI_Xz>U#7Vs8%MPH&N&$DuSjm0p8Wm)2!Mg4IR@l zbjI?q&jdPq$G4Y61__r+;3NHS)uo&Gbj+w%N{YH#HK=|h0B$59!u++>b+M;a;mG!C*>n^E}DRwz-CPeP# z^p%!)MW$_cUp=heN6mtJ2!hhrdVXu|Lw4%?ekrx% ziqJ~6XzR`a+ktdu!+6x4WLJJy_iCdgqeY z>kB(rFZO!q#K$M8-H6qpMIFE0=JzccY^;JO4&Aqj^HNawDNN2Qz<0e_L`ddp|}+8g+=-?<1=RaUum} zR7sy1dO-rnn6RKheG2c~d)R=wa3nL3BZDRJPS< zDg1QYo~xV z08d$0J(1aO{<{AussY`osqq4~Bwe$#f9DQGG~u_hn_Co7UY!#aL!-JiZqlb}2CrS~ z)uCkDzOwQeGNfxs2zM()^?g4>SV0y1x4t>|hLn4I-3pBF}S?JU<%sZA)bf z>!r2HXXUv}(|N$Y%%v%kvpf~`^eD~QCKQh=@E~Kh|b^ zBiXBG8=Fj5|6CWbx#p;Un_${MowXa`-&W_Js)mn@H~7fuAc{934_f1s-XxwFEAODzPJuU>I8bnd5Sp47sG0 zboZe&V+>Oq^40(qGa+YmVUpPJEBRR;~W$Awk*Q};pX&qQW+;l%)m1Y&n zF5;c`IKwm-n}lkg(E@%fL|Kx%HT}=WZPHnd4|3Vj{?0#*o~|mhlDAwZl80W4!h`FU z$H|X%mi3c$_8R^c6$`&#B=QgJ4^N+|U`N&@KK-4SywNk)2$a7m2lbClwx0sSc`f5L zX;67D#pH|reRYV2^P$qT^H;Nb3ZDplKOL6tWZo>diVQ7>PM-EUOnepD9n1f;z?B;u zxc?h7c%C1fmK-X7+8ZSjF*ZX*%m|9*MWB>wGkFU6r{duTt)79pJ%biI&Rkxm~+ zV&}(L5juuYeeXG;(t7*EBacpytgdmAMw?_U+ud1`sPkxN{pX#ded6h-&RC929!^cI zejzGBr43ic{w?p_$O(kag?z6c3L?Wsw#3l-%BTe1eW`nFhEtVeJQUhfh7_jJ8}!>O zTE)?Fv0imXGhb@HQS6gYow(ItD_0lm**tBzmqAM9+X(!oqvLL3%7`@$ur`!Nk}6^f zTm7VLtOC0v)vuUCg%mkNE~K(f5D&~6iUz-U^`zZtV8&9p+a21iXdKov8wt>dy6GW!*8OpA?r2MR5P;#;J~V_gbR8>;~D(>d{MI8%$Li z{e1yXMf+x%9O8#cAc&RvOJ=_aC1G#Euc9#cw+-fL%cZe3vT&g+ZGh+LRv^L_lZhug+H97k76aGHKWQVO(!twaW zf5+i6Y0T&v6Dc6AKmorj(*@f>8k2>zS8!rIKBW&qKn=$lzEsk~^E)89Cb4eclycG{ z>X~F~1hK7+9)=+gYISaZ?0Np-P(aG=*&3YUm51vW+BAZ^Sua!3SciNchzX?ofmpvT zxgC#EwqApu1pQJl9s;U;4W6*WyTHH^F3+2Can+La&oyv}Ke3k04!QQ{^Zzi;(-4#1 zrF3TuaU@=k#>Zy>bFP5j7K4v-i0DmG=@AZgy6!W}M*cLU`6>;u8`wWrc9wCUC6P(6 zq&2}snMOBRXhSD+dCQ6Yv5_GvMg;cLW$tVK*T3)55VWA@Ku9~Dx1A{(6D^g{USq0&wjUD@vNUY0G z+@IJNSWp@BT`528<6CsCDp!9C^%||e3x?iBad-FAx@22DM6O!uH;&}xq)erO(k#sQ zl(q2b_-If-;acde>yX{a%mD+}^LHP}CJu-u+htL(Ql;0>WiA!(jQOQ4L+uV@v{ z{+Yu31WHF~AZWkOlESQRoy)k{LC2pXuj|RZ$W*u1>Psk=i%*i=#p`nOr?*{qBQ`%% zt@ib`z4xIb?URh4^s3$feSMbSN#XG;2fF8fMUUeS4irFxeRXwT4OSw;XH=+XkU2A@rW zZ>&wF#@Qft&CC5WVFtd_Jn`k*AUyKye1OpUnf>%_uY)xCCln2xxPx?jP?+)AojXS`KoxP4(JV{sCO=*aJSW``y67g4%!a$b zEt~UK*Tg}Nn?Vm>Mo9hN3r^iN?d2>m)FTIVQ!a1B^5=K)x^#^6uoZg z=Edz4wCf-xSL@bftPPsd z{PDd>QqEVIgh6alkOD0Tkvm2@k?c({>Dj!am~D%$=00cp()~j{i>6SMKs#@_GnZ~A zHdpi!Z8w+Ie}H~yt=S4TQ&c24f*J-etNM5s0)O^q&%ATV#sX>J?a&LaVh9N7y3fmS z^%c&e!pUF1`e7^~&=V!x?DCcu0k(g1`SNkqn}%4x4k%6j zU%qWx)JTv@G@~o!KniQwyGKG&_3;)^lwh`(h^h3c z8!uL)pcdVTT)KduR{yR$qEjv?_%VxNY zmlD!!xcC>ud}=ec$xWbGIsgK0*-ljzuUgkCP0UarbAFYbt*Fo07J27!H ztT)Jrtt&!NUyqK(g1LkouQPF=01>}B*&=~L+m0rj$WwN~vzoliB-b!xM;s0&qtb3< z$+T8UlBj#NLSSbYe4rLN2Aq8`J0o7d1e3)3Yk|v7a}0K*eNO0CuFrUIzHnE+$*(LG zAIdYg)Qkdk_M8VoOa0nAjbI|`aR)rHOiZnj&1#FNMqx_4kbm8Cdu~%N(Ln{l6CFRi z@ehjbf&BdO3i>rG1L)EEc41}k(t#W>R?;@dln>g0$Zt^HAX>5>*`t0<1W77Nq!1*9h+GdB>nJ@{|0;zM`(i2_lAc6hxf^ z`?8vMXDW84tD^dmwIb^=V{UsBz{@CLIb87HbOr}IQqw(yKB#o6`l5gXV=xPkvF0h> zO-`cEh9Kf2IJ(}QG7Fo!PCq(12Z9x_PXha!6lS7$vLt4_^H}99jm=A;Cb;;?i4xpJ zHDviny0+i0Dfbb(A`CkZm-HsEmwtHgO*ae6->^Qw-@yD;&|lTtDT#m?Moe+dtSx2F zUbdEo*fn!PJehg%oxP6U%P8*>fgBMqY)M!(-qKI1CKR^kYc! z_=OUhYG9z8eS)z;D>#DfTfry8NjqS4J2OM8f{DzviqzG%V;uk$$n)6|Or9McW^(KT z(#{68?ou6@pGEvt?NMe#7;I$*AX{UBe`2+^6k zX|>r~PYWPeatN*QHynzBT$4Nz!E@dFu>J!dRK@@1l2 z?>B-L9}ZlJX8cKKa*0I$ICHF+@NRlUnfQ3v0SD`V3KyQ$_*S$-$7UXz(9in#$2(ft z<+2X|tIVB|^<)-l3RKEvyO~F#vpa-uBmFY)D@UlT6c!z4gl1yM^lf?3)fSBFZ);#%&R?mFGj<~_1>Yia zg)_+Q`ipj#%!>-!gTRsfA9N3AdjSfS+3Es7z?|%i15W^*XaE^MSFo~}#h)PC3Y5HV zm0FD5%epZg21R`u#o^!rC~CXhH@$hYHwkBX&q$=skd8QK!1SL2EEEwST7gHO-*RwP z-YpBH=_6Tf;GFJ!&vh?U?Aduv8s^~XLDe!)TKWu7fc7J2P^gF(gkN0-n3#ybZX8V^ z`N>D3+{pwV$UF`(vV@b4+}DELkvSvKmPZRlp>O`<9xe*WX`d38Mf#o*V0A$y119#-9zxnipkd!pOxY-?(v|Dp%qY8=G+v6k^|rC`8)sl|5Tfbqdv}d83vq zq?a0-B((f5TOfhy?)MFW)^?8Twg`CINnuSi+H&(0btQ_j$C%)ClsS3(wHzIBVmb1+ z6Q1g0rKDoUh;nY8%pgR*Pj?bSvr>=e%@wG)P5Cw9w`oM7R?S(>DT;+9`}CndfZYZ5 z>$Zd4H5(`|Qo_jxflA5ZWbF;Fs&8c1)OsfnJDR0@|gOR}?!tR}yA5VGwD}HJ;R-bzrxSYi6+}f7Z(7=2G9x=>Bn!rm*Fj z8kX8)bwv*;*-zJ(9Tm4a=7w?ejDq~v>EL$R^*|9Qw28am=40Lx!dD$#X>GS>A=;m? zi=7U>E)ayQjfJRGN}-h96|b5aQV?ER!DCb6p;XG?@E}c55}`@VBk)T<6iugF>8Oio zXa>GQd0et`?ril8UP^+(q9tvvT&=qJ%^@8>I4H_rQxnhC0;*akD{>|7FeGXL#k&63 z^gh$ah>al|?^lW*v~}QDYkI7Q?Ra@13Z2?75fH!jgz_hz z1`TT2JxPH^vTi>8y%q@DJdsq3aoRiUP7g`Z*Kb44jazr-=1Du^Q>{}*C4{(bKe^$) zI$S+{%MUT_W~wLIl%(Sk=rFXPjri+fuLM`7zVZz6vg zXLrh8%wEfDS6};}-4%OyU7YCJ*ls_Hil`xtl&Y#u%R5|E6bdxJXhA1wABDT*?40$U z;e*mDD^)SMxg{1~ojM;AN4>3Pg|Z9BiEWE04xdD#Xilw$rNM zLvgO@^0R7LuNrFST;gD>_qbR>t!9m*-&m@9M1WJPmBoRR$?AAKCqz1~=fd0BSNGrK zyCtMRt`_)wm5Yh}BgD6r(F>?VZ9Q{E6s>bS;C5{4V+=K zf^bhNZsurzcFjO+T@t@>UHv*ZA|_t3q|?n50j*RLCwrsIEX5tyaq3?-zQeIPs-GXR zJMhz4In{Is1S;Hsc0fTc*Z&lMk)3T$WN+=82^5yduT9Mq;l!S{V|scM#80-f!V={~ zq5em0ZI+^vuV>tSvh!{9A(!j|&Y!tAQ8<$GCZWJtODtKkjney|zMc`PDBlW=kf%`G zBvqH`XY2(9NFMRJ`_P|{sU66>~rs%c8Ed2cgBMx7w(k?ua6tLOH zwyMnPPE<6qRxW7j|LHoDgz_#5tLsvG)u<}eqeS3!b`co4BUV0j{is}4E4N>gVf$w0 z%dj+8oj>QD6OAa%!)KR>n8d*Ok`e zNxUk_$*n~!bgN2En9Jue8P6{yD;D?CiK3h4&Q@y*@$q>e1mU7%W)S3Cs=2wW5^hfR zj7!X7{l$%IiqYzu?q2;;{W>VLlz>=yxrT2!*SF(7LTbazFIf7^cSxHUM zpW1~W0(!%%l;O+7ZblZ{Hw1$?kmc;?*?#sURz{@T`cLze*lmoC_jjd8^LRwPHzCsL zQotB5-oZsEG37E{$H9pg;iZ(9X-gaof1mRCt%crPlkHt)*5ya#^$n+TQ`?8{6T2NG zIiiFxo+19Wck}*Xn4!*1TXnImUu^HtMRS=^Iosw2eg0vjJ_aYD7+MmM#Ovp$idWRS zmg0OzTA!0sO4P0K@ic1(iPT2cF$=1`%#gd@K2SN?iSoh+l(VomON6^a@hD2@k1gtE zLkzl6k=RKO9h?kN70E5(Gmq&k>=(LCigU5 z+3Z)^paSuF}hd-TFEKyKMo?IwB zy0q3~ZEaDP25cIcwb)wIASaZ1Qtu+)iAMiEM)?Z~zvoJJp>4J)DLG%C%H@IdDL0>Y zt|Uam@zP~qX~5eE20x>tEA=MbYdXn>OZ3BKtn-lknc0suicp!lhh8=2tqIe;>892Q z1XOJxP|nS*w(x#F>9Rf_dt(4(6&C@MoFl-wiXW?e6IzzBZu25|X}9z0#xwMc*y8wW zx=!+Awup}p$p6_LcA-6;Xqm|K`9p2ETy3dnNJ>Y7XAG|dAOiETa(BaBIAvx! z)J}VSIX9^0gOyDuxF}z6t)HW}2}^yJ@1$PCA(8fFaaa!%ZjgPOJgKMPd z6)XrskaPozCxzWBf(mT89aekq{Yrs1giwWDzLK`u&O zQA_e(fs17lE)<8xhoZCW*}}CvweD2*8AvovNtE&fu&6`XALlTIF+72c&apdi2W5A=7NY z7nPXNxkP$^^pwx^R#Xyo>MvJiT(K0kxji~0p1J#*!g{uuS&&{~wxX7U!?4b|(;0M< zx)@QyPLNg_n?Q2KPB}o0D2{7{6I5ZoN>LBy)~QK+O@b z&9G0)8{ZJ$6hWeH-=!pH1|L)cXJ`HN(B?~!jiX@HJ|iFz`bybt-JwFZXY!o@RSG)6 zt)@mo^=n^Ew;N8x@yau+)x?6=I{iEfBDq55oScxS;nR3?K0e?Xfgu*9DbWHY<<4@6 z7`wmT`iZ}6%l{_fSl<)hT)Je=g-}geXk?Brb3?7crq|EKOLLxxnOOc=t2zDZ$<;IY znR=AmPTk=CB|mq9x;muEh>yTmLZs&{ZclqMqvR+^0RaIU#JZp=z#)wW_cg?%c*#o& zpzazTgykS;C}#PaHyV!CfNo3nu}JsDwy%LFpStJcX7{?qLOxzjP7yFndu%(>NDtXoVbK6fSmfpoKVXMi40Y-?*z zKWa5u5}o1|$U4(J<b83H7t*@UzFU6p4-!FsPCeBHy2;xZY%MfVv84 zKV~ZproDUV?vA@I_V;jr3IyYxn;Y=^Ur^z>@lS3^Z4Q9{M1J9{T)U74N$PoUPZp1L z;4?r>I4t}DaBe+l9a=wuzbdbj(tGP*1u}r>1;&GBRPkjg%H`9KS!qIxBm>92<6W}Y z5A-}}s!OFUmn=>Sp z#Gho&$#Z7<>TN&+^G@_?Fc1Z|&4&k3+^pWU-d+}~30b!od8_z5x!P)Br%l>0f&&DC zdFezwnjVDMAJ{VupDhV%5#gD8I_8d+)B;gi_#{F9{>4(tq3gE7;b_#Y=o`@^Bc|Cs z?rsdTJI@i%(xLYi&!s)bi7Jc7T3g4zR_FF3J5wy=!zCmnAkd}Y?ukAdPCi8W6Ej?0 z%&eBj2Pm(U>euDq%cYkkBo*^*5Ev`-?sP~B|L4WFe)X6WxmSao(mOrk#<0QC5{o_> zmXFqY2jcv}*e^x8tR?yt3KToW=G&j zwN#Ro7MQBuO*^$|bG_n}yGy)X-C)FCdD>K3*^QR7i-tQG(i+P@a#7d<>eZSD_S4Rz&FRxb2wS1j= z9WR$l>0xqRk>GO;B(olE%1l75&u6y*X0qR}s!d5dQ)+rnS}|i2;y{<6hIIGv?KGz3F!)5v7-YwQ1$SmhC%6khLA7 z<%B(Qb$3WuSK2HXb}b_?0^R!M*|W693q9KY+(2eRw zwBi`r+;Uvc;kwjoJa~ZA*-ELil0b;(gILyvEAzLKe&q(eyUW6mTpKHiajE*DrLPuv zZh;H!)4unevabL#PCiPSHjudulKbr}V9ork+~JOgI}4&`K)r&M zS9!S*^-`_G1Z&avmI>>{-)Hc*{1Sm#HV0`2%tW3OAT>bX?XNdoGUMQ5>+QRzX9H*ElYd#W#c1N&C57I`+%0TcvdN{8F0_U-xori5f{4 zbWeY)JPE<`!o(0br{2r$Z%j6)3KcI0 z-Os<3or;K1Q_44C?4ai6a5&UjFxF;pn+#%s;~WtQ6_j*H)~}b7 zVr4=EjV-{%0Xr+sLTEXxyNh&J=t0?dfjXr`KMTE4Tz19d{k>(p+qPPNm0U~Xr>@P+Y3rXrt9eBBc z@YAn5>5k@Ze1zn^gttKofboL~@UbVP&oM*J=bWx#s^FH-!Mb zq4yQ(b#`WJDoe>E`GJcHd8$dVexs8oZ)Xv|oTfPw$AYny)z8n}bJBgg*mrM0&yiVq z9T)ui&V#Cudo@}%4(Q9N8i8Fa!{LCI zR$QJZjNe8sPuWvqCOLr3iuEXC9Wf?Xaf}%yrWK>AMC)mJVrQS6y!LS-OFH$o_?4N;)~kfjJKz8Pdw?Du zcrN8-W}wthVr*cr7q**eA@lT>eR|YX0ZV%mb;T&c8Uej zKSfunzMkHbMgH8yZr}w~%My5%XD4X$G*5Zeb8KExStO zpLHu33C{#V0p_J|62f@~4<^vLdQ`4B^I*}$8gCwi^`-x)t$kmU=RT)H_ruA_<#yww z2ZS^3d7b4=GGlOxCCajTytH3JMnuzsb)FHW|A;cc@~6iMCK6Bt$ugeABC`6u=% z2L}{l;`mpMAjHcvQZV2+D#dbhb9O|jS^PE(VUG36)bQ(WnFPI96tS+YzNx$Pv?N`{ zBk+$U(b9qTvS@+x@>}iU9b@5y^?f~q_gr;VL>d43OpURdp6-9{&XwExQ{j_uxihgL>S7k9k!J)QfEUfU>t3UEFG`gK34)+$fOcS<6P zb!n$P&Z#Cv*sifyy}bkKMop_#Ey6_%m zMBp&gfE5~#={ksY3XgS6RbKmVN5UV9n(6n13X zQ`(?YL{h}ditxuxoAGJhK!aRKj|0`$ zU&B_RNYD0=K)4tP_N6B9I*dw=?))Xtg|9IxR38-#na)`ed89>_GJlh1EsAQ?JbcWE z4yf?FqKelFv$*Y4Y*^t!Gy4(c)nLyic&pXN(m-wGrSD5ytw5>I?(Yn}Q~7+8R8?6t z=|{DBww|?Z^urd(W&S)w;$i$q*WuK1+k*SONHJR{Bzqh;RRVNab!j_w^s7K=MDf&= z1dy@3gDH_%$8z%G@)*6Wfi!Ip=!Q*x)?75~g6u%L6a&k2P^*s>&K%&Q{Aq}9AYz~X zH3uEOce<6gWC^8~5m_TM!V6iZ@rUt0V;AJq2&OfD%524M%STn^#&3^)z{g2n-{54* z8Lm&l%#@L5xRMP0*|u5)jNiWhnV{23AKzd%6w6f&QH8$s_}qo?|56FlIW4TbeT%U< zkyw(p#L@S3{d`Zun~=NaNmkZe2nWxk36#f!^LgibM?}M%vb(*^#2&fKpX9X=6p4@| zNUr*zlh9cyBX#TGf63XVXW}ghrt_81#1wu<%rVA|} zl%F+6evL3Vu@G~ZHE2G@yJ)}I?a3Qjd}pw)uu;%|e`*QyiGyCPQcHc3nUQ1E+A7@9 zbML!Bg8xn(19yF`I?Hs_;*xfLiO%;cG9m8glxF)1-z2i+>IXQ z+dq96hhF};Ma`R1nBu&1?<%6+^LIxoqmzqQHR%(vqaZZH)9IyGqZCov?6(YEgLKf2c9@Rs_+}+~0(PQN2ziD%!f1z)I#)v}dnfq;By( zX*(MNdQI{z;Lmxs1RM8Hs@b>qXrn)0;X{Z%6r^vBrj015s>Cohavn{Ulbgb$o`kh; z{ZCYoEV5)KpM5gCwTsX4vJ6JqM`-T_ ziYmnjOT2$Ldg6Q9wnEqQZyWC3~@?#S8Dvg*jd(bzWX#UZ0+%i)iw zZEV|}=hGX-nNr?wTm7W{B>cap(0D(|Z@F|vDOTTOyFKyqpTgXaQ6JFz9*6Z^*Ia+J zEOzPG&J5Bf9+d)WWd2gqCdJ$D{ix>&7QwL`=lYtwQh~*h)OKWjuaz^C>yVr29Ygb? zxk15{8;6Tr95F|_~*g_l>B)E=iVcx&Ypm)I=T$ZaPqJ@s2s!APPFBg0+ zxWzXy+6sRx;5IwlYN!LiB)hzfrRB&~O3nggowgp}u;_e-wn54suh9%w&N|@WfZ0`H&Kb67@ z_EkQ!A0B&{BkC(5C3Hg7;Xr~U)Jnsk%H2v&pw*~J?RHoFVt;$p3Cg<9-h=KcQ?j> zTKDXaZ5dh*5T5l-?jAIyTDiP)uf1u1d){@D%i%REsmc`bq?k#t_yaL@ z6yj>0M5kst4bge73L9(~x{o#R!^A0|=^lE21;N{p5 zGwh0LB1$hc%Pc5#l{PG(@rOC~SE34yM_p$2g^rlf?va{MvboUYKd}o*Z=zh*p{v}l zxH&mE@3?nfE~)aBeD~ja&yZ7^?ax5TvLnSKP71^H15#Oq-bVb$36_i@yM-v=cTDVRa?>}dIZoK(z$|8q@!1hxk57zi>u=E*6Hi(~c=* zl4z}R6r4`8W^d;c+al>T2WXl_X``@Epfn8KbG)Sh`zvVP;sXj}>+^&ga%4RIlW&IL zX>9Fj|Kw5HuHmj*&i)bZ`Pdv8-3SYUy!9)cZ5lii+k5$T?ZJv0AD$yN~`iSe2zfmA|J7 zH_UV+lY{3Va(jI#Bhs2=XI1Llxj8@53ZIts`O;qBo3=KHQ0~sJ z;Aj2Rklyvj&KP>)z3~8_zCs)YffLRDt(w6~2)_0IG4&qsRR7WcxD}N>GO~B-+GXTg zWh6q1TzlV&YlbV=-r3|LH(E*|adQ!w*Iu8>>>Br)rEo9dn*Cn-e*fRc|9X47!+nkO z+UGpa^Vmh`M`JFfbpnRffP1#0IPwhU2f!sEqa-xxfnCx4F-rCI)$ws zLO@I0hYY=MUwe8A=naH4;u4q=^ZmHTzYM7ob>EbfPAI~mk2QyO^08&&vx3Cu+jgIg z8+dgMm+$(Y9Zzyl8ErItp#g9#I6@z}JEp>$e@s%6T)qxY>Ua(hZoWF2_U&R?MzW{@ z5z5X2Ajkj~46uI3OGwC!l+Xq1Uvm%l*k7)mFv!%Fq8Qf+z{gZS(!WKw7%qRI9nBR{ zPp?2lq_2#LpSH?X4gtdklGB@pv>Vezn^~{?Tw(}xix`eu6C>^!Gtmygwn5TEW@KAO z+(IejTavYsI7kbS0@+sj$M`ZcG{jF_zKTBX1{zOc+E2Jkb%i;^@;L-O--KVp^Y3 z77ovS31g_1(NHR#_GFj;#UAlYVM+sW{Fl;O(h;JlLKYEJ6g)o1L@LLe>zMbEcAQs2r@)v=0M3;1XTagD=L>H@aHZjKoRN+3 zL~jtBeS6w#y=;BFC-~Rk79ZWi-3-z~#z<7qg7&iDVhhKJgnk85y$~M6S#@>zmjK6h zBN_f59IxQG$)gdkVXhj7$nS*ISa7)ac{#BQI>~0$^ec*cVmMp3I+HVBarpQni)Ftu zFv};hGu=R&rK)ID2botnbC1jJ(!kzN7QcV2L;5zb*HSmzf%%{o+I2uD*|i|GE-u;K zV&w?9fH)@l?`xYsIvU&YLb-&`SII<>)f2o2yq4Udez6*CbePV0$RgAV$W>XYM9eWi zM>03=SGxw(B8>vIc-E8|{rqYIdrHAeS3_~y-rxmof5!y&zcijduN~+%klCHqjc~y& zc*dyFrTU~D?XYl){!c|SJ=JgB+YG6&-ye(sbJ8E5!4tEQ3Rvy2bO)v|dc zZ&6OqEDEl>_|y{G2as2J+l}ck7|Sw^$NT#WVLVG{=a40rshM%m;M%1TEz3FX;0cPh z{YlEWfa}_g9hm~cSlCWz7eG$6$qYv-EL&b}VcpnSV9E@v@@oy39A6jN7|81{h}!Nu z`W7BQ2nddG`-UNbey*dm3Bk=U9v|fqID4QRI&NwcsRgk(B%A4b56(Yq=2urdbGyKP zfkIoeGQm&y{)eLNA2N1eYE%;NJIl62ee_#x(qc68*ZGHyC+grcW}%awm{9NlN$z}M z{x%e}0_#SFDj?aWQ5hL5qApQr=Rbv7HERuf$yONI6b@!V-OCenpqElKS$PF*^gsoF^a9iVl?xwPCtb&;lH>LCTvQoGkO#XmDl zY4Ah`OwVfhp(!o&NguL54>O`)R!D27=@!eMwP)vR21bDy5l5WD&K$l8Kukm#842uY zLf>&5N98m(6JS3zmK+=q%M_}C+CvsH%-QK%!`L~gYQUx5Rqj%%3S{Hg(*~R8X`d(> z-)!jp?1dW;E$|U7zv&1Q^MjCIB~D1KVm)C|`jnNSL*+62$yvDl?4c9&TMNf7w#P4j z*YkLn813bGepJO>CkrPC_pWp3*@t zHNoT3e)KbVpWX~x5jQqn2U&{>XGX{NTRm4u3uPHE-~IGo4Pe^YF}X z3)4f)Qz%oJd-nthWEwDyjwsSiVTYhzZB2-DjGYEh57)X#p zQqB;&I2c5v%qI{1e>jo#Ise3JYO=pLpaNDSrgEz*8r@agF%Lc$u4q>`Zb9w=UIR&n zoh*D)%)+f7o<0S-K)peFn1a-$<@dIVBML0JL_@_CBPK#K6FSKk4D|e zMI;*@kJ^4IQcxZm22LF24$FX(JtdqNUwjXsc!@~S%ZE^Y%7JZxetuO-7c5+*f5$aV zHvyS5Fu12DQgOWFREzQj9gZvvUmWkQx%DLzVEY=XN$Wk^05qwo+_%BMq0*x<3E)#< z{2&}+qNghKL#BX-0IP3&IB^l}&kK|K7gZo4q7JR2J2k!ARyNO`a&RlD0h{UIx)ta5 zv)x+ejUkH{HO|&F^<|o%=!zfHUz#vLx;zslkDFCDtJWw6oMZsfs@bopGQ|C~5Gc4j zbAahem1tmy>pr2g%U%{3LEi}|_Q;?s2TR;Y6>%-d6Ph~QBLzhnq&rWdS>@GC5>nTqngpjT9Si9R-Wa&Ob|>%ZnAYqzK|z*_Ra)S_5LjJ3 zSv`Gp^#CYWJP9jD1j+>jV3jx&!ops;QPrDe6Kw-MlfX_%Mh*0L;KoJpW0nUen|^T0 zDnv1g#k!ts(>a+5!Tu1rI=8FXO5Q~@ODe{2&jmj5ObcEa+8$V&*4l4<&q>JFJ-oRu zqPs`_-o6ev8WsDC7Gg!6J@=s*tVyJPfW$Y$_OQ6C^g{||6VPTk9wZ9ewf>P8VwusJ z7SRj4B7B|z9gfLwO`+%}{-ycxM7FqP$MKg=eIqZKSASaEb>qszeTA<*#ED3MdQdY2 zg%<|4Of@D_y&6yv5do-iEZ5dKFkpr(vPno$fPwGLmAPU2Z!0=Faw7guW>ouUBjMi^ zkoKIP=wUwKx0nUrAFd#O@ZmZh>z)l=U>MTaqsBe+6ABBx9P_h?ve8MQS7SJKoh4(T z>}Tc?yW6t>Unmtc-$N&F%jJF`*I4<4xuv&0SaI!@o?}!w_PwnZ6(2Pb8=STLN=$U^ zFbv(&HSRQ4lzZ5c7sf{B&IP+T#R3-WJTK@Fi2UBdLL>osQbsJJ?p6!~sw%q;INcEd z0`_u3FQCmqiPMjdsu2)-4a$cQ?H+9ayX`Xm?Blon1osrx&x+0T4FZfn!UuwYsdL?Q z3;-~Wb&NoRfdp~}FaF0aLsBspC@jn|(YU6;l5sL^d6w=ZRb`k7zd*eM-G(g#zCDEe z@qc6SkcEdOQFs1*^Z5IX|NA%=H*V!uMsw`FwDpD%r8I2AwE5Q`5h&~+Y3E_Uepn)i zx3Gv=1TsX!`i^fh8@Z|g$tPnX#WBOgAU?7jo&3L9=A-VU&x0%@i&nG`E9ViE*`oi; zPhsu&vF;7Et#<1yjv&-}w^rKKy1V~TfhW2B-i>1i+-Im(s3-$TJw7)bgfs@B&fUb} zI`cxA%_k3J6&164D91(Zuc7LA*MKL7cSgeZ{K|fF-EjXFh!+l}e=eavojI-Ef%@D` ze?j+0`>Mju6(mG%CZZ};zm%; zWbq<%o`TYuJz~_SusJzPW>26(CQ;6pcAXz@=^Q;DdE&9{Q4~(H9{W9Ec_h3_>}4ea ze&zMO&7}dI62{!Dwy*eDN8icslPo)aaVzlR;k3f_`TaUT!t8Jc+(K4uCnkmlD**@9 zK+OP%2ttO(O!-#pB}-zkah)6D%YY+)@?U$*W+KR_z+u&q{k{0#yeT$PuNm@d#<$!h zqBz1Sf2b$(OL4tT;V6OJ^$vS`OAT?~>!JOsJ=j)YNr3Vf7U}2~%M}YzLtCQViAF%R zXWON;D6pWA?IRY~0U=VtoWRsI69QxiCL2J22!ucaSmdkV6fzutxwzzQk;>PtM!%;y zs#_c!@HRhzX@7BO*15N74yAVZslz3c^B z)arCpi0yQ~^~mQr$qq0SaFZcUAiK^qKWRm{=1lCDx0p_HFl{IsWQZ-koq>&Ol zNo8lP>jl~5cY{sgiG8M)5xW8Rp(UO(zj)o*^=U3AMu$r!;-mQXxmEW5zpQWsALFD~ zD5qI=?Bc%a@EggbHEf6MsXh;Y@idV!(Y}ggx0+$_Hw9B?QO6=~6SvVYw}~TDnuTi#|6 z_^*ij(GoNy;TE^v>fSu{v;<$=BZB2A<@8(F<$_}L%aA}2YngH;khH^2+4e7Z2 z3LI(YR>Bwfi3g3qSB0zqWKH!^1HMAAh48;LZQ4-oZsp4ga$5ym_4NLK+IvTUxV>Zd(JLv7$NsA_95Y z>EOoyrVCmZc+>n~FxK+v1kVyrl10t6ftmo8CY;`^)?~0@ab`FHiQ4EjKt&UlaTL)= zrvLElE${2#4!zFlg!S+fS6JKqSZA^0gX5z*A^(!29N)wKC*=eR+ewh_Jk-$xsX!TL zs4>IYzj}?(Fu!0IsF+MZI`JW$PoN!0)Z5B^2QPt+t0|y^7vkTUsib^wTaSk3#LuV- z`j?Re*PoB~clGF<#6e=m*Z1Q;|5gC73V>JM;CUr@$8V=sgnjbZQ8s?Tm}TIAon^rF zbC`){FH}E88Uu)pNo3R*0p1zuikpd0jDk>Ak05(#$r_T7&<;#C@zAkuUW6&Vu182! zb*`yNb)<&Mnnr+-K=+fCF;Ui3O={bK1rp$Gk#9;@7yN(Qeg$z6xDyu`9w4UUY>x^6 zFBJbU9W-#b>;SmWfii9s^^naLGwEBs&tApcvg{ZlC@P+knUqGuq|h+1x_0#I((dWx z*9`?v@7J|}Hv|QpN2>tVh50~n19#9e*zyIqFz>g3iQ~?Z^KYYRFtuJ}iDIDOk3?vEmRU)uTT8 zYs3FjgoV?B-emh-j2W%vOZTt<=BPQ#1km-Od$(k8ts=RN0#lBuoMI%&}2Wx zO5cit$Y~9@EH86Z>0cUC(b4fO_&$6;*cHC->Us$9a~1?$g3O@2E(wLDF4=qHhUvyr zd3`pwh!juE8vv!pNRh$m-!sRoSH=TvLFW%P1j~Ouzd1745vpExNNuJsfl;@?rV>I% zed~Z=F<>JImQHZ>LKb=<^HMc{45A+#RUkE{QaSxnIm7Qn@;?GvJ<5EF3RuX9UsBSq z01n@QLnZOHO|#smMC{PY@W18v7~G=)DhARr0r!93K7Ot#`eN(zUz!r|e6+mL9{U&J2n9W zpkm7qpoJPz`JXz0Wh^bH7lO?OL6cyABK)G3AABV9SGx_Ss`-SuR!lb@Afn_;ALT93 z@4NKuBcek0XV<;=qrARN4Npb!A5>kHx~wPc!7$*`0$OLQ><4h_`@+6n$euhmSjgoi z;%ShgqETn!IJ`5w{XKH_XJ->IUL75Du#2%Xg$8sWB`k%+M4l@=PZujCs)qo`~<`6sm5N@*O)zH!PBmHAnFW}+`J3tf_lZM1y zXH-kpVMw?gp(4aKzJTwlm*pqSMRgsnuVC0;VxRu7jOFQ4p?E|zO zol;=#IWA!?C?SxhDUj^0u{=c0!{iBBxx&q)56PtE7rP1cJ`I-obF9JbOYK)WQy>Mr zkiv_fvT4Fx*$e=$jcj8Jz3Wvxu(d33ncc{;V85v<-y<%jE2*8eaG)9Ely+u+?Y(he z0Q5m}U|8tc?A;LS@;42cEBL|?w*a&W2_1x+bSJXGNa1zfQX*C6BoFy7ZWDYqynHsc zIej4BddCMp4cHv!O$H30v^>xz?Z6@k?*_J;6oVVdWF7vH4KH$zKgX2;O21fcT3o)l z$}mqXpvoOqHl|k@QgI9DB6x@NA&|CeYfQh_rc~~Yz7paRSR2G#G2{$6(reX2 zb3Pmf#B9cY=3#f=7Gkkqkv=lzaR3e5vO!Zn6->QR zS%AJ$n*1;votqMrH|fTjD_g}9drG!Lo&=@$l0(t^FslR;Pw{8->T||rDILmkEHpyC zwa@}6uV;GY>wq>D2+m|BgrF|{@W)K|>66>ldznUTv0lET>dnt)Ym~Eh;rvE(n9A#w z@`bKjJ?d0PT}^GcPvd-J13?ht1Gd((Keci8+kGef;~00I4dPHw{Ar`pc0_+O(hu4C z7kVBa=h_2{x?sR_(<8_4SkQEn24EfUfTf=N)iXeaY_Yt;MnB3)mCk|3gki#KrjpG9 zAZmQ?*->l(MXj14(GyOU1fL0gw?xCSKA-vwlGK%pBxSs+v5ngoKf%kf0^&nBgRE;V z9S<{34lThV{arrwO5gI^nb5|EyKCdW{gfQ=Qs#Nm=M@YW9LWlr9$_Rz3IUhrOhu`! zM~78=CMm6CPq+&b%AU>QA!W25AC2&(g5C=d_Wvd;5OkA!*>atMpYkxV$49*Q>ioKE z%ZUaSK{(sihY2NeuCG6)sL4UR2VZZ3nW}QoGIFiq>ih)rkJn1UL`c7<6*hWv%YrsB ztMUy`e5i-d#IH0sbJvG{WoWc(Puty(*T^M=&Ir>DNQq75HGEX%(a!cON5YLgOPw#j zuN5o}%vVk_BhW3lqt{O!=D49WkNYd5Ms8AmCWXHdTfMk5BYH8tk-5@^#&QfqtA-jS%dBJ)U|QX>M%8t?^;PXT4lC z?+sIDorvetDkeGz)1{w=FC zjHnRrzo*}))S+M$R;~ZEo=L(rC79R`sW7K+1}u6W8iQ%oRzjphE|}9QTh*ZFYXpTsj*Qowa`g03hN+DEB+*y{bTpuq9Wl*2mel6~9HoEFn zJy(hJRF%B-zy#OtXXaTwjS(1PjejTpp|Kx3n#9aP)wcB)`CZc)pY~rD+1>L&V`JjI z?2ps800PFA$kH0CCn4c6p+T^Rg*eA7qOZ7}6-;|n62)=@y8Vr$u><+o?y{5Co&0S* z+WM{sHUz*w#E++uFa}M2BC{zo!ebts!(VgwF{KwDTR{Yoj@cdXft}VY`aD*QoY zi8ohbWQtNL`h-^E5MsSP3C8)a6OXIxTQnl2K;(-~q(Z~+JpT2F^4722(bLma^w;wm8v#7wMvaL|zlKkah!ubp z@%2)jnTAb0#RtU^ib3N&5wd9&yXMR)fdOkw4Q(zvQAHPv>yzA05>>z)itpEC#LERR zN-{Ge&#J;+2!-j&&Dpo3iddUmi(iJiyE8{GViY@lXO$8%#o}neHbzS|PD;s?nVFZD zjlV>hKy+_a1)A_<)i)IVb+Ux14W%}tG8{v(h@qgI8IfZ{?J_JKJdz{b%&OC)sn8*F zUNugfws?D#C7-{Yx(x_5?pgUt|7uDBrwJP6k{?y0^ZPSdh#YwfpQvGx>zXY7Hrs0; zr^_t)iJBSFLtogmqtWL3f@b2AqAE^gA&$zK1XMx&5}ue<9Dw1>)ht7(P)N;kB7uYs z(~-*wYgSAp4k!7~3!SwKZ`_|(2k>fmVQ+iy)9W2-@k3j!4>T+*JMsE@(I4v)p}s-5 zU95a0l3%B(7aeFZ0DZ$mPv*dDD1$aqMvBmEd_TCriX%k&gSab^SYo3hJIgRT0GG?g zkz44=&2l{p?vK@2?y@Z4mjZ%aCLHa9FUQn=B*GTfOzlN%`=ML+`z2FVrbr2?ruN7u zr7BtCbHXU8g9ZQW^=zsd{{m1G0GB>5!u<4X2O8A@h;tJOf1FP&k_t(S8w8{|cRneS ziG&JzN`Ta6q_bY~ zhJ-*)uTBIgdgv-(+4Spfp`$i6L7`187o>9nsXD+jsGo$}Y?^m>SGZ0&E$hfnNSbL0!SM(b|t1&&1HCFT43cEcwW6PS0W{!B!JES@AodC!NhiI-kjh zIys4mI5`(Va`W5BDDW)7SR*Fc67pzEcHw8c+X=HS&td^!jX^Z25#+C2xtbxS@2G(0 zMJkM+DG{Q;e_)DF4H1Oi^aCaHSxRYBdh;oYV$l*6x>%yMj3z8&K9QQGgsv1br}8qq zd_cUK#jNRm*~}oJv=sN<$Nsi-*-g^|HD+c61*qO5!Fi?RRPQ`GP-(GAb~9`UkSAw8 zqE<94?KZP#02U1FGEfxXDzJJSKUh!?`B**BrThsvZN(z8_*s%-3|@@Z`_Iv}(aJ#x zFmR|4JXTTHby9&yHX~_f*kcx46FnA+5PMbRA|ItiU@|PCRI#%k>nCu>3Si74pjhWx zn-%$D7G}z9QlzLQWQMe*>}1gBr{npPQkC7l+9PUfakDQ<&ZE}b1w`qI#sabohoRH} z>TF6F5_lZ~VkQ`ZsKq#W%;sS(6bM)-nplv z3IUKW{9RDi(PckWlcJzgWTj&r(o9C^9EXQVw4Ou(mih-LK+612RB}N}bt`1H1@z7? zV{prbl%fefWEBwMpjE6VDLYd+OttHKpnHZ-P-rc}KAw=+;i4Z$CznZ^3;0%e$(Y}b z%G`E`=TMoFt;;OEy8Zt4g8tW1XeoWNmMCB@Obwu6I5(5-Aeop{sjzIf^y*qNTI2?ht_hSYEY<5=}L z>;=uqT9*z&x5z***EZJr3fEiCWpTJiziRIQ`aMJ)xP`%X<9;ooJ-?;0Ns2J7vX>x; zsG!HY8^cg626U4DyN+MU*I^)<1cW~UfhL$D3O3ayD<>lX=MJI6-Uq}XXukF2{G!a7G?+eMm5;PZec#qfU|KD{SKIc#s1bbEMrq4p% zBI~;B4d0w9>O#Tbnx1G>qhCAtcaWyfzc2Z8x7txwyt^xL2Tboznp4=6^rQ8~On5PC zNVVA)fXD$PhFwBFnZ6+ag{Oi@&6ExnY&(##CuX694GecI0(U?o!dlnSQNZ zB_KY1w+lel);4}5xB~ET)+-t0Dvm$_zlfUO;MTO-a&wnG2F$*dsAtAmyDH#BOX^9A zpN%_~jZ+8!R1i>62y~dBA7G?(9~##o^nnUO>=BJ2wfCW_NA1)c(6m}U zEy26&XNq~7!VyiLm?WmGefHLf9R9%GlrH=K5e+%|-(ND7-Z?(%U%i)PKBz&1*)!^S zUde4kKU@M7(c{Zsn^EP?6&;&+gEkl5(VkG@<49ksNsa)wHkRgs>563ev z(RWef!Y@X+krweu>Rk#6fo3 zS*f$Ct7)1(QL5WEPf!_1tUgeFQ5uNi{GgBpjttRhK|*TL=k=~9%VKm+YcEgO~8>BnD+Ml zrXnMbJ2m1Xh3!ZH-fB^_fFo=N4#$vneo$4VdQW*23<7C~5H#+Oi<1n*NeeQlazu;u zergTS-0p+`s9vH>6ZW>a)-?7dv*B|0Y@1^mH6uR?%r1`wC? z5+dh!N>W|O1g~ZYY`+06$28inNr+6|5am5|T}Dujjj>?KdP@G+Qo?n4`|C44HT~@J zln|_gC{b;eC+^20+BOiR_9t+7ahrfRy0M=E*X&v-mN)CtHAF{9?S+B<56ZvU2>!|M zcp*|a^!c!PmQvSLm$9nmcj`a~wh7X(_tWy*4EO76l*b(!5u#H2b-=MulVIw>-A=i* zFZ)XcaNpr(xdnAg2$9x%>lDr7VFjr2lC&1oV=}q5+qxq1sf^$aP%(5=N3rOK-UEC2 zx)K{obp~T?rr=J}WWNsR;RsyU@IpS7Dd{&OAN7- z*ls-~Mhan%nc6VeBYv>v4rhS*WC@c~375~8sRqDWGUCHu8hJ2Df>GQPfR4h8mLQI_ z(~z5P?mPr9?+!p#v5>Tj0w-c1%)c~gx;o&jZZXvl4fSh%jdW6L`o~z20Z#G$_4Cm#jLom-&$)k z&%WPj@GM~knq0<%sxO*OOuJ9())p~8fvE^EX#oI&XI-Lf3^}BlNQfdn?}7n)Is2Gy zJ|Xgma4cysd)0t$T1|8haU;xug{BzP`P6Z@M2S{JsU37~9Fr>jGirj^Bk~zqx$V;$ zmx!~ksJREnZ2*#kD~|W;7DX}wYs4{`S}$&>NrvE4Lk^Qi0{T9N22zO$MRpg8oj;bA zX5@#c3xJvG0>?2g6&)=DAg2NxRe+ZYFjI*u>)&+c2#CpkUfo6(`$8cp=~=q`1 z>vDvdNxK&aTb;DhaWbrQiUp&`z&a*sTh$`T?ua4?g)8sq#Zj)enAJ*x(#1;9| z0ETjal!c33?7wi8(Z>ncNoo}E<{t(w2~NPcaf%WgW_C4t(;{AmAk3FGI&H2exdrMa z&9oMzviRz&>CXp4tOL)m_T(;X?FUo$`E z%YAC79KCjXOwQrFh#PU=H9<76Txb{L7U(gjnju3z)PJ&lbqVGl@j|c)kiPYv{5eIg zt}<}qY}5X{5f*Tvg$G5J%pH@WDI8t5p9p*~6fR7gV_ zALscyB3?7+k~T{Akn9(dF&veq6;~cSbWgZuZ5*q7*BIK+ql~IYuO94iU}l$Gq!Z@| zV&CIe)a{-oJqxP;<;Jq)!UN%BdQ6`hTL5AL6z+auWT;`?&$xVwo%shytb0h1jq z9NiTszW7@X_;)c?S~geQ%aa;?kat&bO>%PcT;E~aBZ~r=;lk|Ka2L;>H+cDprP6t1 z!%Yf$W!%dx`TXdU#|mG@RW#%)yKptvjxL%iJFJvWC>7O*J-#xVcAZYxOvL2*%iDd8 zZTZS#_sq(L`$idPusf&5*Y2H6G7uG~^MT{%l5ecHUn%;mUt_a%K@GPgaTe$JU~$Q- zk!$wu}@h#ILMa?1|~!*=yFR{Q*Lq z9Ivn3a(m{-m3C=QPv)OXlqjal7?M`&7@_WG|jM9|VV+twfO#i-v(YNWBNH55)m@T#P8;uD zzZ1c#@OwGf=dJH1KUl24cQ0bFhD*ISFJGSs<@))q)0Zx>?t=W6=F*e3j9Yg2itMCel}e*ObsYJb_3t|2np1Ktq8^-b z6+vw8;@j}$;lA%-P4YoP<*z**5`wL;DC@s8WpQr|Xe)RYmgpS<(|?KzxP4Q+97D?F zJaNg}+SldMC&`YJXxe)^FNBV~q$_L`18d@nrRnuC(!NqXn%_9p?D$vs;yg)Tg#WW% z+K)jrs1HfpAJIro_%bKwKXa8+q2FBbW|DhJl(GUfptFlx-tAFpwVt;&HN8E*WdFR{ z7xm=Cd-uO52O)lacR(lm%#M8Gt#^QaaPoccXr<`~DD}186eQp8EN7{jRweG%bM`LX z6tf5`79N1|wXs`BrM`NT&(XMv%zMJTs{C7&Kkl=)sz!*6+E~!rCUG;rTO0gkFCv}` zY3x(f)FNJdP*xjhV|ahwQ_gPGP1|L6Q_ax7$)L3*bigimGvLJ^B_$3vmA2rBzGsm{ zhW+QZSqw~K{A}_0I7R&Mft+Dhla!m$H9E9p+egpjqQ93{CMG;Yd%{k(;4$Ry2K*Gt4*K81DzY!qkDT6o$)ElrZ#ns*M1ltD`t*?m z%^MxB(6q66EI*gbxFjbOGAHg^K5IGk`s;faM|EuX6lYk4o^6M}Jbkbc>&QDB=Y1t5 z=&Myk`Q&SoaMM0cNIC6D#I=MJstTQrvOq?tYY z=v{f0a%*pc&&H*q-IP1scsf{rDw;8X=Dly=g-e0`HTwg1FY>(aDY$TFwcv==DY=mD zC*ib>vUL@{_EUJqecKaWmuEK<@`GM#~Y(@xTLAnMGH=|`2y?y z#)P+!oq{^7y5`wX7CGu}a(Am_y0vxE{v((dQpP&LJz(R@?{2*Z8bgbQdCJW{IN{ng zy|A0{cj9B-y)jgm@mHM_uAN#_nVCW+<#PF7r2d(Q3CzL2ZJnf~Wj*^5-EdV+`?q@= zNv>b|!3D@cM{t5mM_xdYQc7p(+^MHO-U+_Jvxk0UwK=e$-#SN=NcV6(NS0?e?_CIKcp{G zY>syHM)lDfqXLEwCR4ien!&dK$mOvzE|}S~`FVvO-v8TP{)5bv#=UOlq?GGjcT!?` zPO)mIAoQqd@~07%m9ZuOAB>^FUZfl$DWy&g}i&GXQ=!#KLvMoyKt%YJ?Uxvc_if9 zI<0<)?~?H%MD6qK7WxUd_rC)A8pqtJ^vq{xlTV)x=2%OcO;+@w7Qmd8dCujZYxNI4 z+Z5x#H8Q5yb+R_liG0QX?1owAr9oebGQLkwE5Bvx`YZinl=!%?^n%`IT(`{LE~=rX zrsxHyD{>%VqWH%b5j`!*=)RT@zUNQ2;CGeIUE*;&Xjf4jP*HL&;5|ct)P`&x-cp~6J`m(``q`LXnqo`yd9OL8~(`GkJy zxTOggY3{e1sV<#$-?aXh~$o@A$4@aM}zIKH{m^buMJWpsPbi1l`r((9AD zymtyRW>+9~Wom^LFT&eTia+tlfAO*lb9-F>w=TzjPoe~fg_laW=5l=}hc23(em>A@ zPov5=z%jtB&Y^mG#DXhBg0oQ&sj8*NSUE zRhs_Lz2&=d_nrov86D;rc!TG;gCh=FE~C$tF6Pa%n*~)bEA{Zv4)S^@TP3Un--#-- zRMHvpr2E9JQlb9zgF;QnB^p1cElx(auIf8@Gvx@p(7N3te;&4H$ZfQf`d*588s1DH z*bEUzXDKdcY_4^QcOPo{sGJ_7F9dK`w$ID8Y#S<_JZZz22lXzx`-U>7&Quo`|LksR z;CEV0@OIkxX!fKr9TIu+0(!M$i|L_%8?y?AXMX zu;}}w8{aT3H`}c8oFv7cWxzz0TbrJCJZYFJzwo;5oI>$$9#tKeC5u9AnKf25$%$N1 zqUROv_QFNiMs+Ym#U@Iidv3~mgOawZJr$} z-69YQa98K}4)neamzgRAv*jU+L>xNF;l5T4{+*$%D6?@se2`ZFkIGBFfQL38yf_&z zDGmtc(7Bf=4V?OR^Oxxb)wm@`YlZvys_8G|T$f69sWHyK)aP%m)9n^hF?bka^DMX1 z#IA3BoZ;)mOQL}<*&ANz`cJ9Mfc|{N@yZ~_p5mM)1Axj3R2Zk{$@8x$+$Sz51hM$( zq?KcLF3zt75t3A7PV#1&3wF=>;T`hMP4dMm-Yj|?%s<4L2MIp&IBUoyXUt8K8aG1j z*6`Z?JbyOxq0i*24{KdP7ef76uWQBd-NbOf83tZxUH2>>uCK3GLeTZZi7n9RX)-XU z7+YmXj*29&mJzH)$}+S$hYcR4w8`YjBuEQMKqWUVVtFO)<5K+0j6cNn8IlQe95l2e zmq5^}-$6|VXV{b9%X{EIzUX|GWnOpN%~4_UUCOEW<=`cc^4&E{iIvmu>y}&%=L*n7 z1=^_8LZPvofJjxk*L*1B#xV)Iv4)Ir`#BjiPs&Z!q^O%J@b+5|yly6 zU6@u`v9)ys{%b4mc)<0bBhtGws4bO#^%xB=Tfq}cx9&xUhB|I?Qu|NCJ1GNKWu>ME zUpBG z@L!sE#F>rrEnI027pu>XI|mk=zm*30zG^+^uvnGjSuJ{3#;`c0rHG;`e70+zk#(An zv+>&{yu(gQvN2nt+`BKSk0#tpSpK{7s1l{;>N4r?_`+8%>y#7h-O}@-+kx$U?w|YP zF03=i1$3M^tG>i|Gtz5NMpR%^jwIfjJ;!&0`eYf`<>M51BSpANGBNhkYo}+<9lx?;%kdBhJxJ##xjcd2MoL4XsuS7+9@f!Pn32Z?+H0PW8G1y zSPT~0%~RjGQcJ~f`OF1~Cf{;%{z*r;{pGvw_od`c!tfcUz_Jm)fp&!z`6=ZKYTM!; zz}l-cc8Re%H2Bu#h)@o>2k-*&&C%)#-HUIr8+|2{7me2hUwuAx`I=GIK}v*mV#Yp1 zzJ%*gkfLxt6Ys?SD8(Adl!X6qqtn0C>%zy|b^J*u8I4}@+psL8`1qG$?%NU%3~^Sp zZ9fecMY(>zvK!&8`hH_g_K6S`1WudDIucwSxlpn>yq{CWFha`TMIaKr4t1ErQ^lf}f za&u#eSz?%@rO8{dR8~ubb$t2wRr;ZXL4CINoIk$oTrxhn&A@fl!1rDN$I==}IW3sx zn%S9G%+eUa6`0#>a>S+Z>y+0Vr%~Q}`e*byZ5C6VPM!O2SR?w4UB|gaGbU??mNoj+ zAqrIBahES8uAnY=w(!m%B{zVkrtjp~BfF7++n?R!8?5fQcqA7KmZjvT!0xZWVuBRy z>*sDIa&k&q)1EKkWEU2mx`)BE-yAklrOUo~|7T@~k-cka;O-iO%dpyg8nug)$!E$f zhM+^x%L9!HyU4uzspp0~Cwbo$;+lZkuyA(f=)^SYoGm{5DS&+7p;goD=HP za|}JNKU{EckZ@r$r~%7up8eHqusTxuT^>d8EuF14r07YbbeSLO`BcIk%}Ca?V4hD0 z?#(|Qlc#7>TjrGH&2Hax-4T*x6f5GgiKd-m;RvZMAVqPXkza=dBQ^7Q!S=$*Lg~=; z#Oc^@{)OAjcjlaI_wsLWE+eNtIi0s{-;qq`3>C0CtcEO}{p3Ao`CW{JKMP3n%%rQ& zZ9Y~z=sIU&(!1oEeg4A}3JXc1i93)xp?@GkhDibu>zBbteyY^OHeq%$`--ZFPLD6; z{;e4|uBs2HzTYxwA4uACtQ_&L<~UO=ZD((I-JX2xTUyGAF?@8C6FbgXO`BCHdY+d7Wk?hf7_f+H}=j8fwmLKjE^gVwvTXmj8@fp zIGWieTKfEf%N$vFy3@TY)o!0pV=b3l;trB+|KK~JEfws z{TLa$2p7z_*)DCtz~?z&8UN7*fuTNnq;vjuk}jv^N5@mtLIxSJvjMR;OQMicAF7sa zjyV@4-z=ZLu4bjMn~*u7*Ogr8LrJuE;~g)`ONv>M;81*O+&uJxIs3*O-A8~`cM3Ec z^Y?@5J3PM6{EL;En9A6gkF`}^=THj@$>yyNToRI{B+GkKgz|IL>1VbwT)s})Lh&`| z^_$8t>AH81&lsN*Oz@p$e4bTMzWsP%?vJ%89-2(gtomMt<8{!Ih(x8I3OYgU>|+nY zC;nDvWWOa=jNac;RCC2<@--G2%j2S*AAC-koM4qdq0;R^PQCrvG0Q-5kbgd5F^F@@ zL4I1%=}5dm!RCThLf`b%m*DxC@M8B1eqqhe8zQKK_;-k*ll5xBWp87I;SKdC)tii( zE^YBLeh5-hgp4zIB#(AMkh18=dklO;;L z3|H~0($H+U_`;)wb*`@bDfIR?JnTlsv++FxirXpYjXXKb8%> zGKsx2A{zO8^vRWx!oM^rXvU9T_A=V@&z>2Qt9fR*o)83i`^sZeMg1j3>um~)#wFEs5sff}rF=BA*K%1pW zImf!4zsulzP39`o^V=OJ*!u4>1#xrIyta$U9(c<={$c^lf||5kn?n@mS!p}Pxl3)q z=jSe)X+o|PydI+;;44s6a+7>z)EmIlr018sL?_q5FwYTs{lZ!4tG!C;H^j_!JatJT z8FN8gFZ{dxVZsKa6w6ybOjB-3+@`^ve^Z{`@t8X#ZG`&xWZ|P^<7p)$ZoH4znQK?9 zN}O^|ztY0@-w%3wrzxn z|89!@Y`5?Ygrd;ol*ztWmb16&_32Rmth|q(^}|lgh#T%QPhE}aY&Ux2?Q;DI|L3)f zmP6`0r{znXR21m3+O1Wje1$vVmOfPnbk@=l2hQ^ zZF0g4U`8{K!&!;uoHPSZsc-yZbp^T^VRGgg#LknF8_E^IQ;T?+3qkEuaAB;^`jc{C zI1`jT3fULnjT}80QKAbqEk7woDRdyh{$(Cmo>izSw4l$t*D}pCPHv#yH zaftlsE71)rMX?CxT|jw+^8o8IshEAn(Hn}z8H%(ed`j-+6duxpP&t8KmCZ_Gp6GEC zhC7MRqqv?TTj-TEiQx1~iE%0?iMCUFQ!0WxMGclPPh^;pgt)7T7`Cc%M}$k3LNt>N zE%6tpSD0IPU^Xtda1&|fu2+qIBbSbuShR5h&*`~M^A?q9d+{vh`ObAR@8&dRbYrNL z)?mqu*Y%VIxAx8&8Jo3yVhVCx-kQ&H;@lhzKCKl6D+eDl12w%tZzaUYstpNTOnVyk zAyRoL#7b*F)U}+utq}}cEUqFN*Ls5f+JgDut~^WEZEm5pXBM@XCm=frN<>z2!O*U8 zxX3i$9wAtBF^7n*1*1kuxqhA^l+PK(wE+bj>zLJ!7j?gxpjjN4d`!@}=RY#Pag#N1 z67w&2nP#I{xKYd9$AxdsphcVamBk;Kfm7yhGIdM|fu7;{vDq}|=#<)ToX^P75w%Ye z{+4-)Zw%(9TMW$oA(vud!}Acx$5m6o@!^?kI$e?M&fGTuzoIE(X1(B5YL+&&T=f!I z+7*UmOi=1B8iU!{yur&9)@bu6@zw4EVfO{9u&c5Gre@faKtgh#64J={BDYNHa+kR* za=|pG#K^g0>R`r^0?a+9zK6Q<)G?33Rl)jj>R9E(Sg-;i&JLqHN{x;WFw*}3 zDZ{?~5>}aM4NyOrUA%Ic3h+sn5SW zMzXO9hx33G<}_LRnqf78fVN6~M};_oap=8ANYqmnmmj84_-c4(SxmCrxr_FS6rz=E zMS=XF1UBUPgyZs@^cR!R=_ANX!Vd%$;tO#`*Hbe@7C|7qU6DY&LhTCz&LQ^=s8=%1 zWvI3&h$0L}h9^-v+%Z{>vjWY-V&QFJU0g=?fO#O?#1{={fT|^7i9`i|i+RFnHva$y z(@6IdnCfj3;&UFNMB$F(rI~QDsez`-ujg|Racb@OG_37)y_6o;?ER znPc{WU2w!KS3Jx-YkkzBQTdrR^Wu8~1sBJDCOH?{A?!EiX_o|a23$2C&i6Aj`oR@Q znj0$PjClK-uw17L1@XRWA)vL0t=?%nl)7!-V;pA4YiJS>4xiK$fTPE8?YibQd%A^N zv>RN@H6zIgD@sZuEK^KlnQ&I@VG_@rQ8X)kaTRUkm?2qa-l7EtrMU^>p#@RmWVxq) zYGzvQsDR{Qw-H8D(ic+}N4d|Lw1ME5idBv^P>kWVH;AExUMlVc+j|#!>Unk6@iLEd zk_5t2RT#sgcEj&$Igjmv*uiyfuZYohzHV?&-!Qy3`GJY{N}FhR6NVsp_)t4b*h@y= zh&!j)fVle@jy-sRXe2B$wjWpGV$Ef43WQdwzcF3p4kaaA z=jCw`Gy9anqk`}AD=a~^%ml%jCR*k_NOqG*Js26Hpj=vRuQ+Y>Ezz$LDXk?V&vKSD znzg;oQHe$iFi#O zB{)sqAps6H^Bz;h^)saiR$vnq5M7bGwVBqV#!fd1^G9-xRR%B%W%h*||sI$UA*^!8qn%*Id*7K594uX{d!uLdT z4XDqUh8*tdVJ5J0-M^v83|Z(HN~+QjRZJp<~plY^(g1T z;toOK(#CWHh+u_{USpu9oZAB4yfMLHb+|GCcbq{^{{Wd#{zz$U4a#Sz0|FO;6F%44 zU)|(F%AX`L!u2dZhGSr*Zpb+WJWDr>Gf|fmyphqf^#BpED!M2+nS~s5aU4pTwPHF( z_vRW62(^m2Di8%*A|_KXzj5)i-c(upg9UTu52xIwvon;3B#xy+G&6D~{u%KYW}lgu z3V4@S_(v>P%*l#+o=`+Kmw%a_+_%(ysP_HEt!pQk4dC!f6-%CF$Ss~?`{HljURcn6 zNrZk$TW8Ft!VzGa5%&nM;t#2}64s7mu83@b7TTj6u2G{=oC;TvuHfEAUyE2+=GgNq z3t7aZxAO-CXz%ibn9BMRn6g|MwuFBP#346Sh13IY>M6DLGeemxG}my$%-t>`nM^Az zMNu{eaELKi1c;*CMw*G@4^a&fjv{qafUZ3wyJOjB1;ld?cL6s5@en8Q{a(Et#m>DQdOB4U0jq(lBKxR@ zE+NJ+j6;Z%-6)>OnTgCn3b~1Sn+x6C!2qjs0*f2ZQ8fN#6=v6%fLQD1VT0mO?0en8 zTi@b5lW_*q;$uZtA-4n#sh*&6=Jd_+jP)p%c-25V-|iOJti@(p8YcZC{UU{2XEnsC zR$N>Ks1GvA1vjpsN&p|Y-l+p0jmtP@v)eZcaNMc@q|Z|AhL+SBY6ezd@=9Fs2}Zlj z7^mh_sC>gg9vXrcuc{#Y-cV)IXR{OP8pM}1hZIYzHRTfU#&e_$fa@86=$D=`3a%7Y zftkZsP=%WLfwl+CTEh5aBS3FySQU|!K=Ulj0ccxJadMoa7Pd-yJFyvo6bX#Ll$>Io zB82)y2QjK}M{plIgcstBXV`m!7GEXHdu0^|%%`*WD~f&1ibHP58G)GV(>Dv^b&n)o zw~foD&xvPg@=IFZ5b2^3m>Z{#VJ9Dn#^h@gEvvhjZk{OWRfc&?x2U`fa~)Sxq~oG! zAKQol!JW$dzV#@DeaFSWaAAKbTvzT>W0}T2;QC6*WO~pHh;wEP(fF5a`6iAeS1OKT zjeZ%kgbp&)uN);N52#DYcLKL*q8vj_d}nhAaN-MirA4xu%r$NImDf*rWukEi4TXmw zl%SfNB5`;o1YQrs76S~n{-*9e)BB0TP?tp058M;BG8T;0vF2A=AY$WSb1QM0K{QOZ zTNAL4xW2|%;S_Az3jVQ7vzj`{=NByV5UYL1vayP`BMc@r(5G-hQrQv2%rqc8#6+PxiyD~-yu<|51_Ke;r{Yv7lt6X<3vqg^^nLHu?lsJN z^mQ_N8spIK-YOoIKNBFltiJ;(Va%w`rUTTM#M&kza}@UyquMZU3l2|+E7uaa+NI1t z2Xd~g%obT&+*<*PEao?#%CH|TUSg%;P`=<|t?p$^oEAh<)7iKxm&WQX*eW0uG{31p zZ@*?#&NKb^m2GRgh)}n&lG)T<%z z_%2c#iFa_7KX4-<<`@ZQGLD1`s278N^D{cGPQ_KPa~qlQ>+`=sb#jha9Vgso&esfP zzTzl5Jhuucd8ZNJu+^--RC(cz!RNcUO}9Zvch)EBAX#0m=4yn>j0)4JIao7Mycdh& zElKw%3w(?y()pFReaei`yHn;9RGnfvRTap7CQ8S36xm=Gd-o>?_DgCvcj|CvXUek9lIR04ibmEw;vR0F6QuW>Qfu&woOp^*R9%Y? z<|BpI+~xAB+-Ohk7(Xj3?93%*X1RiFo#^$Z$TNaYKlLmqRJNe*18xGwP7c%ahHkU% z7REY`xc$yqC{<0;`m8qJybTTNRDKwKJMA`fGgP;;QpaRuQD zbt{|2RZOibTZ*nyu*K>&usQjONIY{EF;^0{HGGqS`A8A6-VgT>5Ca;cP!QnzfV2)j z5YRxO<1(&`!IJJNfN)+qmJ;2DIt8e=a%?kWyi-l4Za zIPV&OwiGjtCH#P5?|;NZ4638eri;`*&w<3c$y>~%2gfm{$#c0}H5MO9Yon;Pu-<)m z&#$}br>*&xoWr@ACRdsG>Skxo3oG6wtN;u;b3AaBCTS~$zxOE`*BNmEDG+H)EGTe1 zpb7`sm_gr%QjrpOn1!_LE?2gc57{fJ$DPDMA99ly=2PT`T_Ech9V%fNGhlwEOs}*D zcg(iLGbp@xnO1#3kaEFZIZU)o8#m%vj?s+m#K6N1$`~+3CGirn#F}EMQDIO5*W5zw z`^P@zz;PHpOd_i^2QVfQEjTYuT;ugK1%0OYHSIP}>Sd=n+cxafZ`u-9E#haZnWBXz z*qsmVVJ>rtv23slDG$p48vVoYVYfzd#LKC}L$w5|eM`p)PLIU8;R?&oiNM8fqL_kw zKU2<_OK~;|ZJ)eMT)%#TP*D4dK4kIRa+) z6Hjnf*E*DKtg{<=Wg}E8IDw3*%;z%}2enHCX8g|ykeFIk)(F-r_cm`d{KlcDea6?r zpDY+o^A*;~d&b;f?qIi6%r++xDRN_R#b*Uoa|LSd89A;TLCTtQxm95hhGW(727K&-WWOe5LUy&LcG5l1WM&#I5{q^th`4`crTfb3>P4`{`aI)(%_#6DiG*-cPz zcL-#8SQ4Vl=P@KPISO?L8+i~7KV^1>+J{VZwW(fcu4PrHi-w_e=W@8C#mXT$lqDPU zHbI?7UKv-Yd`+6j?~w zZs4-j5e4MLz^lwe7xx^i+fBuV@a_XhgcwdQ55W6^@<**Ok;P{8{X|_#7TyQE#;!Jh zgbCn{#+THiDNnStQz+m@8FtisrF}-rbWNw$yX*pJH7F;5*M5HBrCrKB~%2{Mb0~N$}hphS@o4A*ojy zg_vR$aY_~sEO#+nkb8w2mOjuJt|bZJi5~R<#2+uzPq}k(Y(cK`T9=BBCXwHuznRgB z)4GO>t9-z4a7=Dh z53hKPa}&W%dWy{t`-y6Ay17L*cPYb!YjH7qFy6~G2329x8U&)M)-);4m^!<@V`eO| z?j3_n`$w|O?-4z57+AOCbCtglRo3+!+lpeylqV0VzkEbw72*QHQy%cDpS;pq`IS2u z`HH=IiZ`R4r5rbGYmfIi&C;A>(+{STjKR6SJ$c8j@Upn6wY5_kC@tfl-4daIuK%4s{$wr`0i~m4Td1aLbfdV1!5gTBwG_ogHFA#N z`;ac40$qyMmIB%pN5dQP$K4M59EtL^&*}SV{zYucPu!Iz8lPG`a}`ZV-&hdK1FU`JkH zE}Fmn)W|LW0PGJ?yRYV87hhS3ifT}-M9uAhx+|^RtE&G1)N*0x+B;!G_bQOKqEmM3 z+5*9`!sQoN+yLIYV^?*9Im9cV-z0nHpycMrt<}6{3T@BeSb(v0@2D9S-%wRwwLr$( z$P;H;@)4zb;^~L3BB>HAw9>B-7MAqVoD1)b_tH z$#dQR04F&A0O6mxgqFZsSctLWkwK)^^lmjR-TxR7MiealV47Rg` zZx7*RJ8){5Q+m6Y1ow&~O@EZA!|rj%<`b;Z2p>_-LUBoNjL{#6F`_PSpQz?g)km~n z`kas9I(C?P)U>~cbDUy0>5dh;;EQeJGL{PNS5ltYDJ|oeIEE!Nh5f*_nsW|OGx?7i zcm&%CwJpY7R{E5zKFIRt2IX#ik5rL4KrA)MHuJepkt;0!0CDPGJi^fzg)+Mzxvw`k zMI| zh;E5b5&HZ@&5@>MTEy=_-A^+t49X_qZeV$t#+VGK#1Jq_fvv%eK(AL(!EbJ^-l>Lo!fS({<{ zAxlELcPjBYEPvdsWNSIxGhR8UYQ8=u4SU1`8MaVqgOo_<(KH3t(8w zQsCb&+}7rk8uT0_9w)bML0-9z(`NRBF)5bm$W`4Vt@5QG2_V239{rUU2IxikLpj7d zewm3@%~RwmEd$t6e0tltqR;cl%<34|qWhPeY9Dgmn@jNe9``xi$pF(Tm%J$iG$mow zOtV-km0%uniKaPd=>|Gk%0Y(T#e)@J4P|NusfO8rcM7~c++9Ml@`IO0yujA|;J7{^ ztUl%RLA4c9CuzQ>thi+MgvcLLINQWF(eXY+x&`a;5BH0A@WgEdxRGm!w+n_ESB>Ul z2vKE?=2TmhML#fFxHl$LW1llpb2tP!(w8xQ34o3fIH%O((%>x@@fd>NpHioj?J;SH z#?SnKx`ec-aw>8JXDU?+mVYGT9+WdkzDPeaJ_yZxOKe2(EYTFyIOR$>h;ap?RLA0S zOr*FhtT${_6bC3IqcGwv#9I{&%|q&S412oNZlW2?3=*xulYB5AFG{`2%mBnJK(Fz9 z$C=G>G@j2_aXIv8j^bQOf+Aug=}E)U)1L@spz_B~a85)&5$JD^N_&>~EyVZ2^RM#} z7g6^sc+{s7v?^RI#R*vaN*o!?0C45aK<<`Au`BLSZ8eXXRMzu#5E>6;R`ks%tQnR@ ze&(LMW?74&y2~x&LXDOO#8HBxD?nk?JH3ig z4b#NZyIhZT6w*~%4j5jDpzQNf<8WQc#yFVT5%7#}g2tofr!*wiKMW}-)g+DYmQU=P z8eDJkA!F=+*$tSR!u_6%ulTvot3Q5)b2-GodOS@ru4lKV_dVgg`rC#+Bz!d}YYhXK zV`wXt!Ezn`W1%>+N6Qnlg=!ioO<*kNPr)jaD~*Ax{G&DdW89y)un@`&cj?8*mP>t4 z5^#ySjwAIMs!W80;=*lxMKJyo`w5vpNEvE%8HUXy31Nv%RQkld@1aQTH0BJaIO&Em6yu~p7GduiY-BTOdaGs9`Xuk4-{{Sdz zv_|5NjG)4D(~_1;BAi8VM{zG*M>Izv#;PphCRHiPbFhyYW1D6`SZ>%)FdZ-~5teEx z5d)}wRHE^yu(NtJW8y)Wiv^VgIJj&49Y-IfJr<(!$8mV{+B@}YskBR;eRxGqUao9H zD>)?~)UAEJ3P$+!+G*&s*%qU;T*_YIy0Z;C`FFR}S#8qdxtFu3BC_BpzF#p*%e}E~ zhj*-}nQAC&@wik)LkCWah^zvtQT@HaV7 zbjRICVOtn~KBh)zUbg=L4{7FOS212DnVrk-S?TfVqaK2i+(bnq;i%z&(71?|*Z{xI z<*{`G^w}J0Y_@(%VuH4ezhIDtsmdIEH~5dK2Jrl)Lqvt2s~e7Ng>Sg35%(!loTIoI=!c*R%qp7N9i@=a`#S zgxdob9fEL(o? z6;Lg!&zYYW;!&jF#Golv?;ICyCQMOcC^&ti zO2NM1t(xW{T@#Yqzr?L%qeZ~kXR^w{!mz#}9iDN!lrFuiiIXn7?f~qDYCSe*80(+J z#?phwFaVy%q6kP`{6x$NdF+*sE*?lQc;-9eX)sQ81nOjXV#$`72)R+rP_@Gv&80WX03Y@V=ZJmiN{_lG2C&=j z4__0|Z1aWrWAJ*#eZyH*LNI0cZINur+6RoHqEi=5if;1VOJRg`A-EYbdV{c< zr4YHSVp&6~)0Y)8iDS|aJrwWZ8$AR93!Kd8#&hE8?iDy#i}Iu%P?x@K2 zW(O4ZY7QH3y^9o7n;Sla&iy_;57hHh%sQVROXD;OZHPADtiyAC7X;GQ{^efjZ}XR$pEWb)PB#zwJ|P_BW9@o^t6kE;?T6~djvl!#*V3FSv))pMM z6LW%4+M5uIf^Y%%0RI4at20pp^#N?00XS*H5ql8?lXO5{E)RG{w$wufB{`@Iq6o+C zVC{-+n}ajug5nfIIU&e{OD(xe<|Bx%A~R4riPTeLJTXXwJD^;!3Ro`S)bh-<#KpKI zL5Xz<#DEM+0vfMXsc89*DrfSWMY*I{v1%_YT*cxoMY%|&k!+6r7Nru&GneLEzi=@| z4r5$RUeQ{X_ZFq5T95oodzNs=F{_Ia%O4L(Qg{4JKSh>YyzjY|1$#v3$LdvK&B~^p zu>*OPgA3;})Ui%t6swMNDmRPXAlXJtM#ZHH$r{;Gha-E4v#eYTq_vGcpsf=E(QzCp ze36$8*}e%U zvKt!lQoI|?TFo(n;s!4rks~6ZV6i1({aod%t|ew(aS{=I?yeHWs(FIF=k7b#r{WF8 zdY{e$=n|FM7fS9RMgveTpJw_CI^HnV2e(vJAw?G4sF$!vQ}#?qdCe{ zeKxBXG}AKbZp5461hmDYA7V0sR)pV(*brM!V+?!?smIO{)-523@Wm(0qI-H<*RPLS zKcxBJr^;WMS z>l3%|pO}COc*$S8@hD7!hw=dY!*3ZIZ>58R-t0ikVEWAffwpE_l(a!KONawV?NOPr z`h|HwLL1}MFZ_B%+CVypXq;tz=Dy0Bmt0EAP+2xDPN7BqfKK!ARu92Q>$&Mo62erx6K~ zSlqvGrrBD%hYR%4=4La@!eU?`@_O6ou~BCeY2^y2_>TPx<}Yl#++HK7z01YL>Nmt* z2(=XMEL=l9jK@ydj8eJt6`XDw!}yO6X@7}^*!fE)5DurpTm5CG1_-lOYf$HmN}7mp zYT=jh0MmGZ!n3HB>bm~`QR7rN4+_k+3Q?+J)3xvBA$XzYS-;C3`PLGYF?_=1 z7R}syx9tIvQgMyzFy0ufv66o7R%Krl zlO5)B`*XWcCXWybMwSQC?v~OL<;k8L@&KKTxqA z8Ech}W-aO>F4*l{d0Zmk+W{)hbdr}?4yH+1yxdh=e#{YV^Bzi8 zqGuX)IcHL}bQyr);)8gI&H z)FFAi{$ME{c!4Mw6h~%*=ndDPsXuw^1yd zGDnc}1#7-v<|V>1%IDNNTP;y9Y85+xC@8n@(~SC;xZ;4c)E>NHW^Lr-DJ*9dm|%#l z0H$1VBZUJj6Ddlb$l$jP@JwLtiP*}(@#sd0L^m57WnM{InoUzBrxflA3A)+bbGlGG(L{+u&z1O&M=%iwHj>+>f`iFX6JC_V z?80vHgpZRj6)h4z@c`f!AB&dB=GuQ@F#hBI(vRuty^zjSfs8Lsb z@!uU$)X}`=6+!6~*zvNShjw85-!5^vH3T6;>7I=W>QeqwGM7A_G3(PM~z}_L} zDD@hMJC_=r1P+O7h?Nw~YMJ_o1|}j3EBscXJB!TQ(6<&WyNhvni&1%E++HHZJBygD z;fogH)Ok))U{0g9o0uy%4DbSO#Z<1DL9h87ZoI9iVnjUI`VmygNr*@; zrNt~%msNIPdX@{vF#Y&}+%F^-s_IeXQBvdWF>8Y#CL}O1`iT?pD8iQUMHiI}M+Bwf zzZX)4iwgVEa5mSJ54%G2aZtY%o1)`G_KJ2euKOYdiYMlKrn0a*^!Gh4vKZ&m@8Wft zjimUP!=HJ-czw;YEXd14bAhjz`IXwI@e!k%1U{RNh_uBHJe3yaFgE@z8xb&p{J)81 zdCs-=MPWQFeKGQ_U;+ANDQ_UoXn|t9!{6GDh%;#Ud_Ms#$ zFDzWe?G~ckT8kD^uVt9cZ}Ab6eWZ3(lW>;T1b8y*h_~q1Q)s1$rdh0hk?k13$9$It zp8nt%`rHwcoK6s`u4O8+PGt=#_>X~ZV4`o5K36E#q9SgpB5m>QG>*1rBHTnX#%PF& z0i4`(&F3(k?~9Z?CU;OGD~tA>BD$Jgz-zq53~7wF2YO*37*G6+HEtWf`4pEu@OXy= z^Ogz*)kW91+$_E(XA9+&*xo^&Gw&T#{mwDg;n#7k&VBQUaEG%t#Q6qLNT*TJAS0ru zFSa82^zrE0g&&!NaLQ>-d`2EYA>s%}qag7VhN0YR)4ZW^m2Wn+H z=WWds-Xj@ltqM!lSa?&Ip+>YRB|rhv<^0sixPi(d*bZe3ve+iB6S&TKaF8RLoENw> zKhsRLO+#gQfVT=kTv`%A7F1izOrw)4p|~%EiV4z)@SGqgeN2;qK@}!y84fL)sPG@C z4llXvFTf}6VjS}xmB1DW;q}umxdo?uPOI$AYCXd)G9A)WY>vXe%0glaQjC##*c@C~ zi`VL1EDG1!g=xa}n7`r1=xB7q2m{rNA8RK){j>H4=QP3?`NAv<+JyLLpWF$j)7#NJPW^7`U2{13m(;ve z=WMsRWX7fGmYP{_3zG?+_+!=+lZkYS2&67ypAAJtL7u`T@ba9KQIT1 z=E%Cy(Ni4p7HHEfHM{c;?cRBv(7=!^B6nM;EoQv2Qq!B6+8h+H z6M9=)h6i{WOX^l^Jurq!+vcVQ<1a=vex-@h!ie9*P)SV}ZmJ^_5R@JxTl+KgK`sNV z{6aIew0ChNtZ5Y`--!b%uN5q9%7Ai^VXegH0%$twK9JLHZ1pmS5fC;_$Nqs(wxjPvSbtb<%`yJ~7#lO92qs!X ze9HuN*Wi^Kbzzb7Q-+`Im^QqPT;4CpdH@W7eVrl-27z619GkQqdFUBrH#r2VPs?>I5z)81BY zafy|cx$`mS*7KQ<9)(n@(LaR3?y6cCY5?Jup?L^Wjp0ghwwskxD$^zgrsB#(8sSiV z!j0arf`PiBh2X#(YG)S2QgVQb%sYsAV+IJE$4HUkSn4rGCbmchmlI^p>lE7s+Z~&T z<_nk=s0LW(QHw^XE@~%&cw%&sdW$y#8jAPnP=q>5nwD!YVE+IM7ahgoDDf213&dKT zBKj{ZTZ_a}_Z7(&;_(;EURba<$$6+l=XuPu7jk#jS z@|1a>!Ygve#49Y<5h^l|5NC%TV8x#>(>^sQd(Pu-BGdCaV=>L{znHI{rEz(Cl~$X( ziJmo?UNl}mP&ZWj#JZ;$n{^th>Lv|ihcef)0NCF$lARj)g4QkfxmUX^&^{}Qm<{|u zAMy>iXccw1s?9Is61BQN5U3vr+@kS}ea71r-ME-k~VxgMV=(hR#>w5-sf7{7(F# zihykhjedSwaPgO@xkrvSxh8w!j)wSY=hR1$4WJQGu+$JUfS(S7#y$?6O|Q zEU3{)_=Z78XBQYWgE;99qcHhQ_9Z=ZQBP@NnRJ*njp0yB1GtCt#r~!PH$fox@Q5aZ z?D|mbg;%{3U_RKExVz23niJI!QiDVXG<*d?NkQDg7SQalnFB;#e;bI+gM0CC-Z_J$Amq3}>xi+J(-^l|uSK||Ll=C_ zE-y0-M#p4!FuOZ}zAm1%6P=wvzVHM(=#CLA<1;MN;Fjq3iFIEDr#Z|_(J*iEQL~$| zaT9A{juOnDH7eeJ+!#>r5icitJBg6gc3=-OhL;^mCgmB<7>!m_xkG_#wl$C};tH#L z)Ezxxpw0N0S050o^_k5twkFyb`GA#;)l>_z&k?ww?JIu-fNHvz?RpI* zX@n~gQK$NNoT^knmHbA6kye9r3^?f|Y+|?&k)W0+Xgoc_Fl)%gwD*;Qa;}FP?j%fD zptL^`0zs1lsGA`B&*p0y?I;|4$Ml#_y8Wl%*ufnm=!am>%|M%Sd#VF~_sq6WbzjuW zOUcP)N8W@2+P4<>8wWN0I7+85Q0%ThFm~%Su;6)`itb|&>m{{< zKF3jH;k#d&i&exB1(aJ*FNEpGgYq+n@Wj3na*!ual@@O?`ywcyCl99@gMZ<8^=iE> zEj@|v=~&;yUg@zNFjw;Mt_6VXK&~L`aZRizaF}MT2P-0=hTyDAA|4`~MYxFK4dPQ5 zsJ%v#{1S~pFdKl}Q<-Kj&5;36GVv6N>Lua_2}NQWInUu1=96zt zvFNQuxV**gE-~n=cbK?~#9YOwtb3FxUsXiBu~&lPOeIu4=_mdX&wm5)yEzfzgnM<;xLwkaS23oteXb${;W>3m8@kFWV}Ub zU|H=q`M2-WEaM)P9|!XEWzU0>Ze=Lu+O0a_5`g?kUPO$$^k$=%%px4~L6G>5a$F)^ zkv_O8QlIeI?Kbfw!@ zz3&kK3<%;oU^Io0(lo<`JXjOrPmuora=~<*XPAV*(r13e5U9fjbM{b=FSvyr%ld(k ziIf1X&~`!7am%5Q8heE2R>|zk()W? zF^CfdPzzuA0uQKAJWVuA%dcqAU#x)p(pQpUYCap3j{^XmT~4s2lkBO{ZOHHq#u)CT z`wET+@TGk};BI?+&b?2G?>P9E+=_a5JcGj4tt%>|VI+_KTYhZT7?gL8+;R&qb zBbWwRrdo(TlFUR7qB@Jy6RU~VWx9%#oXZ{{&BQ9%<%Qg`mryR45&KS(kXecx52l&y z^jNhNUYmL?MHb@JSAr=Qn7Q0uBJ&r_Sg~#`#o{X{QvqpYMb-A^Cv5o!C0izsXtgwE zUvYDaj|MG8ZevaJ7P*dy<@V+$H5=8-H&7k0GJqG~a4Thjv^=md-8aiCIL0WR$dCPn zGuEXwn(+~zJ@XTeDhyuwh^Ak}OBUcc3S*lLVmG_R=M!rO3%(#sHC|Jj6OOXomtJF6K=Wj#i{*Yf(KRUKUbkk|m007))GF*Xf9 zaMHjf&C|kb&a62>a7yB=14a<*+jlikNDu(OKASzJ-*hbU1EEY@SV`Lka#rI10A}&l zM~HZ3U%5 z!T9!VbP$|KC0AOHO@PFD)MW}4%%0w63RDz6FkL{9Ozq0ck~cB!v9B{ZYCGE602>I6 zHozNNgSWZDR$=?4+Sn`?;tbM>cWgyAV<>Yf=vuNe70xe~nUpA($8iC;s6^aA2NX26 zOzmSWbt=qY3L49(VU$!*D(k;6AlX2&gx1@_w{1>J#B*vZunrYGc5VM9flcBdNA zR!6eyxY4U%vRGU@Tl;Msr~d%q)qW+R?NT2Um1CdC5A>ZGP`phlrk{c_Wllj$+LbE+wUiw+Gz3uP$XTbqN5$bi=5qhqZcZ(P}8VihDgv z7NXQrEk~5LFA;l-QDTu)T8qWSs5JpROmNlXPzBcy@jdmNFp!zf9xuGS01PQ{{gBUpVwN=1)@4Cw2bOIW43^7`2|k=s6agf(KxxtJ{fLgQW7L04Vg? z?Kk_QlBGoiV~fiQY83$lAGc&K>ikR+Fo3Dm%%I~@7}O)Xu$<6px`m7aQt$r&pfqQa z;HYPIzlfWckza_XAW2B73!$MyMbzI9OSY6bPUCO2IRZFW9lQF=*#$6?t$R(PdCrV*`I2}hQ ze_U7s#!Y8tgEzP+7;3Hk#J8nUu*!{_Ut>|Rd~Y+{TdAc6?JI)gquM*YyO~Qc_=C*6 zd{)xJsNl>YMz0ig9l6{vkl8EfZXg3lnt6yt&oqj7j7H^LV`Qft^=O^5#2_a?L)Wr# z)wE~gZSTHldxkS!Z&*O@+J~YJ$-2JqGAB61&b6R%U8TU9(h&U2ED2$cBh+w+Y^n7Q zS}!!ss5>StUgJ6H$C9C(FVCy2LPoy{G@mhlkTb!HgWw1?KvY2TraU;70a6-(7m$67 zFpy$wAVp@86T>rE`G9N%{9`+GitLNL5xA+qh8#k2f-*(I$5Q4cj>so>4e7}+4P1WV zyuo>Z^8>gR1$&k=9wHHFo}e+2c$8`{Q4%B=p}3LWC8&c~^tY{%d5Sot=I4$ses|KBBa9_Dmv0+~Dw%|TyaC72WZEJ`)rQADA-*5p` zz9rs&+;h%I8A6KBl~@`2PUuv)XU>KxhYS9>{oZQM&a(*%|C$ zlx7B=O80;H0MkG$zbe6aKiUQpZ~U=ciX#62h#K$3KA5Sm!|?+&sWgc$6fG5wrf6|n zN$m+CA%W9~Y@0R%x46_)y5xtv@inPp!F{3%g6I&GnP%H?%d`MuwBkG{#JauiDF76e zBQ0;6+;kfU@tAJ+3ipNxfZWiVC(6-GmG))NWmpR85>PU*=_efA3z&(FwM!W;d1jWL z)NtDA@d1iAUCN~0uWSfYyvZ*y`4pKd8YcA1iXr=& zX=1H1ua?WGKJI0~?Ii;9QNVNRsIbTPX37aD>=&-0>@96CtF1ubt4cORg|HsX;!kLWsShkt<>AC` zv2t{u?10oMEE5WSN3^njJt0jBHSn+$G8vS(JhaOq+)ji;qHRCvRlw7v*nE03& zFK|ewhFa`rIgeGIC5@MT%p6nWsaQ5~oPHp&V>Sdx4p?j2Jf)uE!YbmYJdY*bcMpv! zE*Mg+>R>$EpFW=+s?@5}x`u+6X<&wcUYA79d8O!o@!9P+d!lX?Wk`F=6}3U`^O>1= zXq!ieoWRT*Y(zeJiB;SOMRgv#5xB;V3nTEzIFqLtfe~x4dZe{z4RT?~2TJH0E>ykj6NvE9l?S#PJX(Nf!eN^Veq3XHn$XeQ`aE8XY~L)HQy)%=-| z8~stoD-qA49l|4$4a_?ro0KsOOT=4IjAtt zp=1lp2JU6dZ_H96rZ3E)YNhh1D6jHgF>l0Ki@!mrxSV{;^A_Us7l^*`dSdYwqSRRU zMdgp-J&{`$?=q?&0eH-@rvgS?8@{0{jp|UlsIKF}S~f8*;RLi=i{Ei`a`DVZh_6I; zZc!X=8@e(|t_qlBbt;@k4okR&4l_NsDcaoLW|!A-@UCSR{{U_WHT4ipMeV+BWT0vw zwfP{$YP?L3iQxP_!428s<7sQ3Xn7QbFdvwy5L1jwy1sdc0QeowgS*Ae9z@WBG;Z3PsH;fQH{lWaaH? z@O6j{32aqz?pmgmI&m3{Q%MLLmdO!-Tomoy^Hvob5bDq zWv7+FIz7g{C3J;V#e;Y~_e^f)jYlXGE>*1|Na9=xFtXBd(A?v(_DVFP*&CBqJ z0W9S3#33<`rvPF_xE1t(yn^B$v0CsjxFL1gf4GLP7@h$AkkB`b_K2hqdGY9nZJQ$C@Lmw%A4Atqw z{4d@+i^NfSEtHFKc#F##f4KIHD~P;B6eb9#p!iLtoJFXpTl5RlqS<#Be8Lx(#}Hdq z+0f#B!M~a0h%zy2F?@W+n2XIsaU7|SOvUOWS8=tI5m|P^T^qaf3~HrYmLaUfwpVA= zqGxpz5X(t2`5}h>Se3i;3F6LTSGO_U^HSRHrV7s-Q@Psi4m9^J*K(nJ_=;XN$C+#H zdrkqr0UFzVh+p;d3pSIPM9pW&_KnQKjML^QX-^TjQ<&o5r^KgXjd3k0BB=nl-I)CZ z2m=dDlQ$}|e=%)sx9({g$EmMWJImagFQy|;*vh3pkxQH}d`?fdjuG~5G@>aR2^}!4 zDox(#^&&SoWP@sb!4SV8g|S+p;(LOh6$*?eWmPOc4&vUEs*Vuxk^UCIG_VbO;4|~4 zCGykEhTAw=a8037a0$e8?Chp!;M;8ZmRpC^Oc3Z&g8lbd_{mr!ksojW06GrAi2%Dl zXiiK?xA#-HFctcW0PPQe&Q$$4G+71onL_XG0P9uSMHGf@FhG2SK%n3AL>oXoELOiM z)eoS@{{X2^KT^&Q{-LscB7(`rQkEk_hzQt=kz++y(-;}2-tn8Fy>afP_>m~#{}C>B(b zr)}{ort#NNVxMdC4L=D$`$n0cIM*}5DOVdstTNd-CRdw|hN92K%ukrV9%D0d*I&c} zwoG^D+H8&U_Ce?I5zZxE<}ZvfD(nb|)oY$1g|1!1Gsh9l?_9?{JV)@9rQhNqYlVKL z+QoazWyjPhy~|ayJVGwb%AW$k$<68`RfiV_D==%S`qDRN+AE4)Fp!#GW^KMQX30lr z@6&cf@BX8ExoSVcIOi#q>`p1j>BOP%+yc9nl!rW*0(2(|M`QS}qE^a_>xTz@Kl8WsSseV_jTI5dAi#OT`>{6g&84SphN zPE@anW^K>_fpp^k03sx`h6VeHpnVtd8dq(v_={Q1pSUOePekjifBKIay>bme$vk30 ztFn-CvsAyBFsN}`^9}+}c3Kc_D;sKX(S=JY=`TcS=2j8q9#bt+o&d`uGuOBWx@xaEcT ziD}o&Ns@fRhxe2SeZVr4cuSVo+)2iK41bCvoHybXm50o!kGvCCirrr$EU)03BBzxU z4nD{uIV>lNoU7aS>6P@s4@a+H;E<&BIJ(GH$+936Kw<^$V)NW7g#yIJ1vr=nTQ*uH zP@#h2<~3OT3uFm!uB%yK?7p}cr%{KM}1p@7&YhyMW1 zkaMsGkt$9<6%B83i1fWuFyv7^XV1F?p?&k!aMsU>7wlC&h{vX9b zp|O_~JjFPVMCeY0=|ph`^*RV6QA1EpqtPhFNxtBJ5G-d9T-;NiOden!U|wZc4ERcR zL`ITXy3;W)u42{`5z42F9PrEN zm%6yyQ)%Ne=TXWoF7dhTW-l2%Exe#}h829=46`)QOgXuRHp(l1QkNw1H4>d3aZ;P0 zpR zXnrR2qZo~20|>|21HI75pd8$+UHzfZ)9xh{{lsRza}CM+o79^aG%N0Kgh@-XwJTnG z4(2E29Pu0CZ+@B#4S}02kLZq@gKeqklDiMgr}iaI6Wo+-J(*tLhGVDk4n;l4K7c_{ArzGuD&nO-jC}%IkPoVlLpW|cEAKKxO{M*r z`c_4Be-q6F(tnM;$~j@w7m&}%Xo=d+)AW~ZylX>CO$cE+zA61pcATP%fo6~iMM{EX zD)lPC4CS`)+&8mF@*z4@ z2|g(sHYx|RZHF#8ILp#7l^e7?w7H zV&GVaV&_W%0`n@J#IY3$uq+^BGU8GJ0?Rf}9D1c9dLlZB<{pp49={MB5IX!zSO|xN zOe2gdU#R_#^%2MFFaH2Cfkhr=`W3ih7`Rcb?-O;N^4Za-U#YQ}RT|>NwkEV%h|KoO ziGVA6xGHG8Fio9zE6SOcI*Z&|ly8qq+E_8>H&es8$Q(wT&vc_J#YW!J-8z^saTYj^ zA&N8lnC-Y=sYPUWDwt=D?l)SQ;^ti4aWiy&A+q%o!4b=dD}2Vw*NK4hm_%w&8QH|S zpj(`^RS|RiOpa2fd&({d0M1a&erIRp3I71zbMl^wk?91YSqSD1o8nVsR`m3TpHIw= zr{{ewHqx$$V35qN(5Flz@4V8CMsV9oc?tMGOhQ*pr1IufPXX9(ConJqm<6jlZZ88j zRIgIBVuZj=k+8)EqDLN4!TSDtoI9A`|xiLC1tp<>$#3s z0GX6GiW~W#m4ex|rzpbIhdGbLdYk^HA~c)D58O7#dSCwe0VT8((py;bbb18*gK*KP3whxvHcQD} z50!UteWaj=boQ0YDTj9yOhD^XE^x8Oyf3-orXu-eJydTA%Z$XcvQ`4TMEj_U!S^b? z;&B0Pq7`>s69}F&;trgfs)z>IXvdyodlxaZydA}H{{Uf1&1KXrpwp-kwy(??ZPv(* zS(T#3aM2pM(xpWzn1&5Ilzy=-&&~|uC@L>h6?101J|!!`JVl}`2RW}50JhW!Ri68l zl)O|h?PKB^KQB&xeKNr0`QT#8pO;RC0-Qbh!aQ#fYInaukX`eKvlOz zqH0u8mLGDJ3?vXsCg89F=i&a7@mWIEm>KF=BFdDUCd3?OQUdC|pfn1lhpLB)KDOzc zz@~EXF9W53!-sG@5#&gE`;Y>&m@m4^EQ2+uWM;$d*cO+hOM`PtD=6VV6(=l*17QCE zH6PRrNARF%4 zDgD5&+lC0_Z~RmRbVi8lv$i>cQAZau+VbuEBL4suo?|Fvf~`YX_o^l=9oZcP$^I_z z{8Up>L=<<&N&`eoq*d(@#PMnc3Tjuj4a*12>`yEUxDPPyfq8*>&%C248jU%*N{NW- zA>tw82Lv9bd#IzRhY%*BH5(s3@Xi#A8A=%F46cB%W}rbhMDTNkrJ>-9E;_?H&` zCCw4>h|_GuJ8pR<_P;2%;d24gnL`6Gn?#-)frs9rIK{(*sOPLRWi!Y1l-1Kvp{JR4 z1aN0kn$g=G%V9^vTyFTp$-Df)MTUK*9NOg`cPKouETargYySWxYRjm~tg}kb@f8Xl z?iFlH1=H50#mSkYtMxCxz=)$lJenOu_y=7|>^@>Q_Nm^l%s8e_W0IeQ(+AWtaQCR& zAyFD+BOR^YS&i}N^5@V+GHk2)q8p?;ZGk*PwIGTc$x$V-SzlR!WH~s??FoeD2y#Vs zUx>cMctrMP4L_Mym&rJZ?+|FyvVM2afV7K>96gxgttoUKh!sX?wGy(<@)F9x{pC8} zXtiAhJt{8U8q5*5J)jJy&S9wDNN;;4e;P1~;MwSLRhnShPnl+e^BTlK0*A1PGU|=q zXsh)67|Yvd;D0`XVEWRNOYti8NtA42z^t1ic6f$PTG-(o zf)yd|d&>kpENzQsho8~|Il=^cK{rf9SCv(Ox5EyCE07!VVeF0(w}?{?k^}JqEztp9 zn=|n?a!=qH!|;F3LSoJjL>+^k=8gPCO)qkI)5w2?y~{gp8AbS6$~RSx%l*t6G#Ugy zGf4)6jMXlYuw4{${@8r8Nd6;~eWe|?UKKx>VQuLD0C36#QP%g&;z~FDTT>Hn+B9D8 z7?>b@;u}xqR>-bsQy1dpoHzLjh)JaSJqXM6=A*=0iDwZLq38p_6Q(3Xh!12!@~KC} zvD~XlIAB?}a*&d8%OD!e1Iz_VGLpw|u47!pIE2HV32Ue>$Q% z6sG3>AEa^^WO$596mUM+D7YT#SPw7132 zD0BQrzTVUJB7rN=Sy=6XGXec_z&th(5eWx4JaVM3sq)kgsTQ ztUOdYFXAQIejxJKwk8}Q(47G563Cks^*Pmc{rY2mtZQ{+f}Xfs4cY#bYHD%HHF4YH z-k)!85g@#@o&NxvrhZe?@DS8QigSqQfFRodhY=zN^$(b)5|sjRQHwlcuY)i0JuG6w zo{>hG!&o;8mOV64i`fOxT7i*yBL?8=SppxpD)d5&DbYD!QbAu?14`U?xdW0HbR3T1 zQZ|gTJd7i!xg7v>mPcMb2NYH6So0lC-tXKt^%r_WQ!jx)*RSKo>%-FQ_@PVOxGgM2 zIZhd_ewzkZK3j>vCEdi<@c#hh?HA%~U&P}_v|j%JG!8es4)?h<-pQLa?LSXat=aBN zxJw;B;YTpaAHd6O-)1ptyHC-BudUGgkJ>9hm})`XKTtoGRrw~oO{PIMo^d|ORhIDY z`I+0k_vwKx#9r9%YpCIwf3>=p@hF}lrINMr0o*kV3(NEiQ2e)vU zTb`of9DGHk?fZ=uZ^mZG`$VYcscTk;Pfv)iPiT0QgK_sGt!jwojdc)qYplRKSF};n z;wSziY*8`H9W-d_Ae2VOGxDFf^Zpw`;OPNJ)f@`D9Ylyb5n}6@Mv-<6?aVP_Vuj$B zWzS|+uLI=wB|2}3M$_6=v*H~O#A393lUvKv@Q~5zKmbtfhkM|d7r*g}bY5*T& z1rYu*{2^RVCJC38;E4SG;6d&S2Xqf`XK+bmvr>&>BdDID8^lFw3yO(&h`m6E!ds}L zh^MhKB9{A#$&^)pC>{w1`)3PZ znDXoQH6P9axZ$VVF4yjKKXEvx++K&=A4l#MYxf4@_YJ4n1=0J0?ET8Ne&b%haGCs* z_W>ROS!+VLA&o$8{-!H9h-T_n%wgxmOfxyAxrvR;Rv6~vwRaFK4Z-5PM;ZPiahXh6 zitZq2cPu-Os0ZFUu_@q|Zt)znV(}Ha%uCNz%qTa{oJA}0LxH#M8y2$(k)DQpHWH;nzc6R5Z8UYz-1a( z4T(2yyjdCdm*GLH>3UqT9Fh)dJ;k$xQ|mRBUb|$)JFoDgsL-@(Z+UuPXrPNwf{wX{ zhusKzU17;_o=CP0;p_Zs_B}x4WocCWJ$HMbxuNYZCgc`4iWfK=cZp^)tt`|KA`;{W zVF0?uSRoYqh}uMlBL3h7yQ$Wv<1+8?cvFnbo}RAzeT>71En=-cCF|5O?U#%-w0MI* z9?G{-Hfq3J!80cp9)T4%qG9rbdvzWu_GbqDqQABfhWl~l8Mcj&OaouIfywxyAAn~H z`!@o|zC-&Es@FgMFg#Ovc_YLa7?+4u!F~pdC6bt?F9P%aF2H@swLcSLUeojmoImfF z9q)2zJ|=8e*}0%llVW?2eF#+!;2G0x|tfel}{9AF<1PS_3?(I-4l zBp&J`m*j=kYmsH7JjW2+l# zu3VL!53xH9adQ^ib9XB?D_&-f+RQjn^D+KQhAG*(S_?XWgLmDTvi{*}+wK-&{4gpY zmY3W}Pt7RBA21frx){qVDZBfin(|94H?tNgUokR$zcSHk!+1SD;$ACcu79MZX(zuh zJ$uKAS-Pv9&oQp~k6+9l`ngbW5qNVlsacvF5w{tQWa~2{DUK(T&$Y~*_<*W0)B;&V zlymt&)mbnNm?c|b%&kjV<_5CRCQtn}nLHHy$FJuWgBRlUY+V>^EyLji&Rg?rjVL+Wd$T%jq zAZ<6yqokjhe&%D^3KROTM}Px7wZuzC&LXF=CyBwbDEq%mQ_5`inm?vvfP?QC!2oq` zqFRQoHq%jPkr_gFQkhy;hqOmqa@%Ge_8zx|^cNh`K00pBh*D=5>}oG6j{tQ75X^wb zWy*vXquqwctt9=ym{T?=wAYxJ99JclVT+l9@LWMmw}RTaU*MSM6u*D}03D?qUKr4m zqTUBkZkjCHgUn5#uJ~X5whQ8a8s>=##KQOb9vVkWIP+02u!<14PEMlwh)1d{H7s!z z6lX-MmK+!tF!R8ME;9cyIpPqFU0`Cpat2F~^C#eC`Yoqay$?0NKR-jxx$z9XAG zP)SF_*N3G)J?n2*lUaP4W1v3dc~IJlxNq(KvrqQS9ttaV8x)ULmqA5L2<2sv1F*9U zY8NZI2FBkpGHHtSO!_%CEbay9TH&eV0lePKqx2W>{{VzWmOVeue&u1Jb`bBT0-hox)gGvmh^G^zM7&0keQqn_Jreyz z)VU~ykl0)n;dR>w%p^Kzz8B5I3GS9uTOt#Z2T%rMoK44g9YN|7pG(CPsHASU7NJZx z@hx5aM4QC?9wU#o{KbXniwlUiS;QMRo?>&Ao8nTH-Qj|;USOgp`-f99yqV5!Gb+=A z4sjvk@3?t?QiACCoK`>bHF?wAXdOiDiJQGl@hhL=8m0Yq>t@FLjx4!0|aVu_SntaSMUY;fexPt7+seq2JiAP%?#jbx*V&WY0 z3v`}-VQN{M`-w*!xAz0lzMCOjF$DoSnU zqFPvdkXAQs#<`jC>Z=^T()ovJWPqJEvA*B1wrUNqu>_A%n5&6y0gDcBpl<^nY7FtuNVa2xdewhORZMNdG5ogFo zZMF#WP$j@8G4mP)@R&@_iAwTS5%^I^jCS4#p#_vWEgos5i$`AY28%yXq30h=;AV3} z>gnhZY}F1>?ft@Vz2Pix=T6b=%C-I@LhPW%vZ$90PqG?~^910Asy9pRe!th|YX2k%!e;x7i(07Qi(U0C%&WS% z+juyLy7`QM9K?{hTzhTc>&zJ0Rs=Uki_A64<$<8Dh?Qzzr@dt2VQ=PA87ekn@lRTv zVgwXZ6n89sA(vdt9A<0UQLFqw#@{fl)?jya0C{{utpbiSD52+=Ui@NKDdHV|KunzjRRDlXPPQ37iq3aZYf zGf{od@fLO}U-b<#d@qYSRzn63`ZhFL0rryUq@64O&H!%e-X19D%>3o*tb)`^Hdm}upCRFTmlzt#_LEg zhwMS$Sts%U!4YG1azRX?21%i)VbnPU{`REs1;SYARNB% z>U)x+{>?6lSBU=rIZHsIVHOWP0psSB@_RD9KZtV=#2SWJ+ zzx0;4xW2uAY;VM6by@TUW_&$4v|eR%D>E@E%K&1aUZ8)-2QWB1O~IOJ+3QmH3z{l9fVRX6|L{aVPFTe7(W?@MZrd5B5s_R#PL-yE*OrgAmjMdHJ&H! z;-Rd-d2Us4s2IX$#4_sTUpi%XpEFs*2M-dt(Won!8h&_3IhAfd6MK#^QA|sCd5$96T*`f7B9o9XM;f>&Ok=1yFya~*uA|vmuX)Mb z2Kn}hW=>Wcf7HW=m>aBkjIn4P2j&k7eWieh#7{orrGrrygA-oSRj6UDOZE2!s;_@Y zg0p8)Mx(ol+`O}>*E7NC&fuW_w3Z>O^H){WZfRoG$q6GefPR?BFoBb^h^GG3VR=Rb zNT780u|*gOOLKqV>JPQ)P!<~w;84WI8HS(4Mvyp079*tlOkNMN4W#*uYe)Pi(!4nC zGXCRRGIZyZ&Wh)MBkTVF4L=?F^-6q-puc3;n8PQurL+>G+`&8Ujw3aE;=s|D1$VTFTa z`63P(dhycMt|fP-*0Jfh`j)F|FpM`MxA2cGMhmf-X$Z3=l<|DbS-EUoYF1da#fx(+ zZfkkxiwU>nnI*3B`d%@<$iEZWhjGHYD-VdxH3B6q8{rb4G4^80Bz=040+6fNNMC~kr zIe~eA?p1(u2a;uFr6G8(ruy{Lsh){xq+RNJBjY)!9n~ppG z08-2ErXu3wh~m66+gwD(WjN!Qn==xy`()-eMowixi>8(gmebpxs3O05(F_LZ3cfq6 zLcNmZd5OSd#C59XIBWTjTa;Q2Vgpay7fnEW`jpCBrS^f0-aN|9gHoxw%%g>=ma8)g zvf+DUH3N#M73bay$kPKEHp;DUQ_m8(=QM*+Nn_+_}+_8#@;^I>FhhSOe zQONT)jB@kKmEneyS2k(#O!qHxEVJ*6>+_pIXz+az3>Wtx^r%6|R_-AUY`d&L9^yO9 z!6`A~3O#<5Mu{&en%Zqw^#Vsg8&0NiqLOnwwu=$ky`g3fCWVp*0R;|)e}k#1mbf61M zm-L0M$}idprumk40BDtim1B+i?z|(Y-Ikt}dz^>uAHu8vkRyqSqvJ*4_cTys;pTxtQaP6@VHjcna$}jF zypH{csWd1P0?NV#CIeYB5UW9Pkt9uHOJ@)x0cs1Ty)aKt(V~WJ0n6H5$(8IjQGkm` za|_~wt(9zw{{ViQep4XwfSxEU3z#R(qoam2IC+V2r36Ia-B`>wiFRmfn!;Rpcbl1(p8)H}843@1Bj)}og0lh?Za?Gt^m>iKij#m&V z{$Obn+9iMNp|AH>DL)DFQ5=+*nO$a~yuhod94RyZ0ARVi!25t+Tk3KC)=gZ) z^{Hcm&(zM5-p=AVvKQR!j&oMaqqKNBXDGxoYpw4RkZzPXFU;hWPX*kfHX~5C+-8UJ zg^6AqL@nFNJQ8j2L@XT%?W(;huVANH)mwRuA=Qqp<8(*Y0%c6U;&*G!koYxliX5KVc;PTZW2!!8W~_Xh(72XR{yHQBI%C=P$W9 z9^i)Cfjt%$SR9h6%P~j1F8zqBTUcu^%r%4aKN&H9FI815fDkHk$F4us*P(s`(Bed_?Ty4Ts`UZ#9IB3{B@LdDJ#sQ#IIA@N2+jCMe0|n;h1_?>J!>Tih3Zx<@6i$ zE15*1Arj&fnR%n14VPnh!^Tai7r3FVH`zfudxl~(;?vLWlrX=UWp#Z-Ij9~jgFL4ZaOMQfR2yj^K|c{j z=so3!I@C8uzo>><)U9p#lq)^&FssTN*YyHw);fXwryzc1ss^fXHsQzICVtUMw8wnF zxkW=8*SttA<{xXgOsZ4D*Kx18MpzY>?mb+?FhHqM1Fyr#~01RA^4O~0{daNCn1 z)q6#sCeQ~S;6^LnLQ&Gc4E%iw_>Tssl%%WLbr_oIT?}q#;Kl zc$K?=EELUr#3O@Z6(gflFdSqp?lK!W@Qc_dV@6kDl zaX4aeJQH-ch-o}GEaE8YRSCLvEU|{15Sy7d1H+rSdb-5Pmv<^!9^!1`A?6!8cep3Q z2FSS7fV&;dhmNWR=`UF@L!Cf49sA6e{kWBi&$L3@)J}CVck=+d+&!)XmA9LeaBg@A z*tGV6Ry8UsH7eW?Gmd2|!~@y~vj7VPtiZgIvzhLddHu|@&zbKirm60GMQog1{{ZYt z`-xbIdty^D+TiHPh%ep-v7^SAmHUn`o0bae%vgGhuUg2+Z@Nf ztjVZe@bNE9SHuy!N{Yh#L0wh+OcIPO6(pgI=bB8_ACxo0pWg0raLgyc#s9zh_c zD3p(1;_7}*UmovJt+aqRSExv=(SI$J)A|8>Vo=HoLr;l}l-O7ay|BTq1Dg&>hy%eZu3}9pV*ZSC)bca(Od#9GK*5jUXl>B)+8Wi|PtL&@KHbck z(e^sWM*b&tyQl7c5sds`78^_1h&u@FKg8H5SBu*ckJM8c593wO+(@tDX*r(Ke~kkz z{D}|T3JbdXi48Bh4yWpm@b)XDdokl)(O>OL2~E|1i-2gaKtHLXD9>=A=9Jt<+TAM{ z8(1|pxgScmpnvg$W5qiDA z%0D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 XTdN}e0t*0GsX|4%|Bk)(zlHw;vn+8r literal 0 HcmV?d00001 diff --git a/htdocs/langs/en_US/exports.lang b/htdocs/langs/en_US/exports.lang index acbf407fd62..139b3e463b8 100644 --- a/htdocs/langs/en_US/exports.lang +++ b/htdocs/langs/en_US/exports.lang @@ -117,6 +117,7 @@ ImportFromToLine=Import line numbers (from - to) SetThisValueTo2ToExcludeFirstLine=For example, set this value to 3 to exclude the 2 first lines 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) ## filters SelectFilterFields=If you want to filter on some values, just input values here. FilteredFields=Filtered fields diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php index fc6e9ecb743..a886dcf475b 100644 --- a/htdocs/resource/element_resource.php +++ b/htdocs/resource/element_resource.php @@ -241,8 +241,10 @@ else dol_banner_tab($act, 'element_id', $linkback, ($user->societe_id?0:1), 'id', 'ref', $morehtmlref, '&element='.$element, 0, '', ''); + print '

    '; + dol_fiche_end(); } } diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index c9fb0de6edf..bb043076157 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1670,7 +1670,7 @@ else // Zip / Town print '
    '.fieldLabel('Zip','zipcode').''; - print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6); + print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 0, 0, '', 'maxwidth50onsmartphone'); print ''.fieldLabel('Town','town').''; print $formcompany->select_ziptown($object->town, 'town', array('zipcode', 'selectcountry_id', 'state_id')); print '
    '.$langs->trans("LinkedToDolibarrMember").'
    '.$langs->trans("LinkedToDolibarrMember").''; $adh=new Adherent($db); $result=$adh->fetch('','',$object->id); @@ -2357,7 +2357,7 @@ else } else { - print $langs->trans("ThirdpartyNotLinkedToMember"); + print ''.$langs->trans("ThirdpartyNotLinkedToMember").''; } print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER['PHP_SELF'],"f.titre","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER['PHP_SELF'],"s.nom","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("AmountHT"),$_SERVER['PHP_SELF'],"f.total","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("AmountVAT"),$_SERVER['PHP_SELF'],"f.tva","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER['PHP_SELF'],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("RecurringInvoiceTemplate"),$_SERVER['PHP_SELF'],"f.frequency","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateLastGeneration"),$_SERVER['PHP_SELF'],"f.date_last_gen","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("NextDateToExecution"),$_SERVER['PHP_SELF'],"f.date_when","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre(''); // Field may contains ling text - print "\n"; - - // Filters lines - print ''; + print ''; // Ref if (! empty($arrayfields['f.titre']['checked'])) { @@ -1756,7 +1743,19 @@ else print ''; print "\n"; - + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER['PHP_SELF'],"f.titre","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER['PHP_SELF'],"s.nom","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AmountHT"),$_SERVER['PHP_SELF'],"f.total","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AmountVAT"),$_SERVER['PHP_SELF'],"f.tva","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER['PHP_SELF'],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("RecurringInvoiceTemplate"),$_SERVER['PHP_SELF'],"f.frequency","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateLastGeneration"),$_SERVER['PHP_SELF'],"f.date_last_gen","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("NextDateToExecution"),$_SERVER['PHP_SELF'],"f.date_when","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre(''); // Field may contains ling text + print "\n"; + + if ($num > 0) { $var=true; diff --git a/htdocs/compta/facture/stats/index.php b/htdocs/compta/facture/stats/index.php index 5c5aa8489be..767082997d8 100644 --- a/htdocs/compta/facture/stats/index.php +++ b/htdocs/compta/facture/stats/index.php @@ -225,7 +225,7 @@ if ($mode == 'supplier') $type='supplier_invoice_stats'; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); $tmp_companies = $form->select_thirdparty_list($socid,'socid',$filter,1, 0, 0, array(), '', 1); //Array passed as an argument to Form::selectarray to build a proper select input diff --git a/htdocs/don/stats/index.php b/htdocs/don/stats/index.php index 7da3fadcc6e..b8cd532d35a 100644 --- a/htdocs/don/stats/index.php +++ b/htdocs/don/stats/index.php @@ -224,7 +224,7 @@ $type='donation_stats'; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/expedition/stats/index.php b/htdocs/expedition/stats/index.php index 3dfe5af6b48..f4e8d45f5a1 100644 --- a/htdocs/expedition/stats/index.php +++ b/htdocs/expedition/stats/index.php @@ -223,7 +223,7 @@ $type='shipment_stats'; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/expensereport/stats/index.php b/htdocs/expensereport/stats/index.php index c81996fda3b..f0448db1771 100644 --- a/htdocs/expensereport/stats/index.php +++ b/htdocs/expensereport/stats/index.php @@ -206,7 +206,7 @@ $h++; complete_head_from_modules($conf,$langs,null,$head,$h,'trip_stats'); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/fichinter/stats/index.php b/htdocs/fichinter/stats/index.php index c053239de1c..e6e1470b47a 100644 --- a/htdocs/fichinter/stats/index.php +++ b/htdocs/fichinter/stats/index.php @@ -231,7 +231,7 @@ if ($mode == 'supplier') $type='supplier_order_stats'; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics")); +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); print '
    '; diff --git a/htdocs/projet/stats/index.php b/htdocs/projet/stats/index.php index 15a2f3403c4..e9aad0d0b7e 100644 --- a/htdocs/projet/stats/index.php +++ b/htdocs/projet/stats/index.php @@ -271,7 +271,7 @@ $h++; complete_head_from_modules($conf,$langs,null,$head,$h,$type); -dol_fiche_head($head,'byyear',$langs->trans("Statistics"), 0, ''); +dol_fiche_head($head,'byyear',$langs->trans("Statistics"), -1, ''); print '
    '; From 7254b54a0401c37fdd0bbe37c144658cc26d4276 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 00:35:05 +0200 Subject: [PATCH 058/233] Work on 6.0 look and feel --- htdocs/comm/action/index.php | 154 +++++++++++++++++------------- htdocs/theme/eldy/graph-color.php | 2 +- htdocs/theme/eldy/style.css.php | 24 +++-- htdocs/theme/md/style.css.php | 23 +++-- htdocs/user/card.php | 59 ++++++------ htdocs/user/class/user.class.php | 6 +- 6 files changed, 152 insertions(+), 116 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 87fc887560c..cb93f8bffab 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -364,12 +364,19 @@ if (! empty($conf->use_javascript_ajax)) // If javascript on $s.=''."\n"; $s.='' . "\n"; @@ -384,7 +391,6 @@ if (! empty($conf->use_javascript_ajax)) // If javascript on $s.='jQuery(document).ready(function () { jQuery("table input[name^=\"check_ext\"]").click(function() { var name = $(this).attr("name"); - jQuery(".family_ext" + name.replace("check_ext", "")).toggle(); }); });' . "\n"; @@ -1007,10 +1013,10 @@ if (empty($action) || $action == 'show_month') // View by month print $langs->trans($labelshort[$numdayinweek]); } else print $langs->trans("Day".$numdayinweek); - print "\n"; + print ' '."\n"; $i++; } - echo " \n"; + echo ' '."\n"; $todayarray=dol_getdate($now,'fast'); $todaytms=dol_mktime(0, 0, 0, $todayarray['mon'], $todayarray['mday'], $todayarray['year']); @@ -1193,21 +1199,23 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa global $theme_datacolor; global $cachethirdparties, $cachecontacts, $cacheusers, $colorindexused; - print "\n".'
    '; + $dateint = sprintf("%04d",$year).sprintf("%02d",$month).sprintf("%02d",$day); + + print "\n"; // Line with title of day $curtime = dol_mktime(0, 0, 0, $month, $day, $year); - print '
    '."\n"; + print '
    '."\n"; - print '
    '."\n"; + print ''."\n"; // Line with td contains all div of each events - print ''; + print ''; // td tr - print '
    '; - print ''; + print '
    '; if ($user->rights->agenda->myactions->create || $user->rights->agenda->allactions->create) { $newparam.='&month='.str_pad($month, 2, "0", STR_PAD_LEFT).'&year='.$year; @@ -1218,11 +1226,11 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print img_picto($langs->trans("NewAction"),'edit_add.png'); print ''; } - print '
    '; - print '
    '; + print '
    '; + print '
    '; //$curtime = dol_mktime (0, 0, 0, $month, $day, $year); $i=0; $nummytasks=0; $numother=0; $numbirthday=0; $numical=0; $numicals=array(); @@ -1242,26 +1250,26 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa { if ($i < $maxprint || $maxprint == 0 || ! empty($conf->global->MAIN_JS_SWITCH_AGENDA)) { - $keysofuserassigned=array_keys($event->userassigned); + $keysofuserassigned=array_keys($event->userassigned); $ponct=($event->date_start_in_calendar == $event->date_end_in_calendar); // Define $color (Hex string like '0088FF') and $cssclass of event $color=-1; $colorindex=-1; - if (in_array($user->id, $keysofuserassigned)) - { - $nummytasks++; $cssclass='family_mytasks'; - - if (empty($cacheusers[$event->userownerid])) - { - $newuser=new User($db); - $newuser->fetch($event->userownerid); - $cacheusers[$event->userownerid]=$newuser; - } - //var_dump($cacheusers[$event->userownerid]->color); - - // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event) - if (! empty($cacheusers[$event->userownerid]->color)) $color=$cacheusers[$event->userownerid]->color; + if (in_array($user->id, $keysofuserassigned)) + { + $nummytasks++; $cssclass='family_mytasks'; + + if (empty($cacheusers[$event->userownerid])) + { + $newuser=new User($db); + $newuser->fetch($event->userownerid); + $cacheusers[$event->userownerid]=$newuser; + } + //var_dump($cacheusers[$event->userownerid]->color); + + // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event) + if (! empty($cacheusers[$event->userownerid]->color)) $color=$cacheusers[$event->userownerid]->color; } else if ($event->type_code == 'ICALEVENT') // Event come from external ical file { @@ -1352,19 +1360,25 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa // Show rect of event print "\n"; - print '
    '."\n"; + print '
    '; - print '
      '; // always 1 li per ul, 1 ul per event - print '
    • '; - print 'transparency)?'':' cal_event_busy').'" style="'.$h; + print 'background: #'.$color.';'; + //print 'background: -webkit-gradient(linear, left top, left bottom, from(#'.dol_color_minus($color, -5).'), to(#'.dol_color_minus($color, -5).'));'; //if (! empty($event->transparency)) print 'background: #'.$color.'; background: -webkit-gradient(linear, left top, left bottom, from(#'.$color.'), to(#'.dol_color_minus($color,1).'));'; //else print 'background-color: transparent !important; background: none; border: 1px solid #bbb;'; - print ' -moz-border-radius:4px;" width="100%">'; - print ''; + print ''; // Status - Percent - print '
      '; + //print ' -moz-border-radius:4px;"'; + //print 'border: 1px solid #ccc" width="100%"'; + print '">'; + print '
      '; + + $daterange=''; + if ($event->type_code == 'BIRTHDAY') // It's a birthday { print $event->getNomUrl(1,$maxnbofchar,'cal_event','birthday','contact'); @@ -1380,9 +1394,6 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa // Date if (empty($event->fulldayevent)) { - //print ''; - $daterange=''; - // Show hours (start ... end) $tmpyearstart = date('Y',$event->date_start_in_calendar); $tmpmonthstart = date('m',$event->date_start_in_calendar); @@ -1415,22 +1426,6 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if ($tmpyearend == $annee && $tmpmonthend == $mois && $tmpdayend == $jour) $daterange.=dol_print_date($event->date_end_in_calendar,'%H:%M'); // Il faudrait utiliser ici tzuser, mais si on ne peut pas car qd on rentre un date dans fiche action, en input la conversion local->gmt se base sur le TZ server et non user } - //print $daterange; - if ($event->type_code != 'ICALEVENT') - { - $savlabel=$event->libelle; - $event->libelle=$daterange; - //print ''; - print $event->getNomUrl(0); - //print ''; - $event->libelle=$savlabel; - } - else - { - print $daterange; - } - //print ' '; - print " "; } else { @@ -1441,9 +1436,36 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } // Show title - if ($event->type_code == 'ICALEVENT') print dol_trunc($event->libelle,$maxnbofchar); - else print $event->getNomUrl(0,$maxnbofchar,'cal_event'); + $titletoshow = $daterange; + $titletoshow.=($titletoshow?' ':'').$event->libelle; + + if ($event->type_code == 'ICALEVENT') print $titletoshow; + else + { + $savlabel=$event->libelle; + $event->libelle=$titletoshow; + print $event->getNomUrl(0,$maxnbofchar,'cal_event','',0,1); + $event->libelle=$savlabel; + } + // Loop on each assigned user + $listofusertoshow=''; + $posuserassigned=0; + foreach($event->userassigned as $tmpid => $tmpdata) + { + if (! $posuserassigned && $titletoshow) $listofusertoshow.='
      '; + $posuserassigned++; + if (empty($cacheusers[$tmpid])) + { + $newuser=new User($db); + $newuser->fetch($tmpid); + $cacheusers[$tmpid]=$newuser; + } + + $listofusertoshow.=$cacheusers[$tmpid]->getNomUrl(-3, '', 0, 0, 0, 0, '', 'valigntextbottom'); + } + print $listofusertoshow; + if ($event->type_code == 'ICALEVENT') print '
      ('.dol_trunc($event->icalname,$maxnbofchar).')'; // If action related to company / contact @@ -1486,12 +1508,16 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print '
      '; - if ($event->type_code != 'BIRTHDAY' && $event->type_code != 'ICALEVENT') print $event->getLibStatut(3,1); + $withstatus=0; + if ($event->type_code != 'BIRTHDAY' && $event->type_code != 'ICALEVENT') + { + $withstatus=1; + if ($event->percentage >= 0) $withstatus=2; + } + print ''; + if ($withstatus) print $event->getLibStatut(3,1); else print ' '; print '
      '; - print '
    • '; - print '
    '; print '
    '."\n"; $i++; } @@ -1533,10 +1559,10 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print ''."\n"; } - print '
    '; - print '
    '."\n"; + print ''; // table + print "\n"; } diff --git a/htdocs/theme/eldy/graph-color.php b/htdocs/theme/eldy/graph-color.php index 42989907747..d270936aedc 100644 --- a/htdocs/theme/eldy/graph-color.php +++ b/htdocs/theme/eldy/graph-color.php @@ -28,7 +28,7 @@ global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet; $theme_bordercolor = array(235,235,224); -$theme_datacolor = array(array(120,140,220), array(190,120,120), array(0,160,140), array(190,190,100), array(115,125,150), array(100,170,20), array(250,190,30), array(150,135,125), array(85,135,150), array(150,135,80), array(150,80,150)); +$theme_datacolor = array(array(136,102,136), array(140,140,180), array(190,120,120), array(0,160,140), array(190,190,100), array(115,125,150), array(100,170,20), array(250,190,30), array(150,135,125), array(85,135,150), array(150,135,80), array(150,80,150)); $theme_bgcolor = array(hexdec('F4'),hexdec('F4'),hexdec('F4')); $theme_bgcoloronglet = array(hexdec('DE'),hexdec('E7'),hexdec('EC')); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index d0b423804cf..913bcac5f30 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1670,11 +1670,22 @@ img.login, img.printer, img.entity { .userimgatoplogin img.userphoto { /* size for user photo in login bar */ width: 16px; height: 16px; + border-radius: 8px; + background-size: contain; + background-size: contain; } img.userphoto { /* size for user photo in lists */ - border-radius: 2px; + border-radius: 9px; width: 18px; height: 18px; + background-size: contain; + vertical-align: middle; +} +img.userphotosmall { /* size for user photo in lists */ + border-radius: 6px; + width: 12px; + height: 12px; + background-size: contain; vertical-align: middle; } .span-icon-user { @@ -3271,6 +3282,7 @@ a.websitebuttonsitepreview img { /* Module agenda */ /* ============================================================================== */ +.agendacell { height: 60px; } table.cal_month { border-spacing: 0px; } table.cal_month td:first-child { border-left: 0px; } table.cal_month td:last-child { border-right: 0px; } @@ -3294,18 +3306,10 @@ table.cal_month td:last-child { border-right: 0px; } .cal_today_peruser_impair { background: #F8F8F0; } .peruser_busy { background: #CC8888; } .peruser_notbusy { background: #EEDDDD; opacity: 0.5; } -table.cal_event { border: none; border-collapse: collapse; margin-bottom: 1px; -webkit-border-radius: 6px; border-radius: 6px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - background: -webkit-gradient(linear, left top, left bottom, from(#006aac), to(#00438d)); - min-height: 20px; - } +table.cal_event { border: none; border-collapse: collapse; margin-bottom: 1px; -webkit-border-radius: 6px; border-radius: 6px; min-height: 20px; } table.cal_event td { border: none; padding-: 2px; padding-: 2px; padding-top: 0px; padding-bottom: 0px; } table.cal_event td.cal_event { padding: 4px 4px !important; } table.cal_event td.cal_event_right { padding: 4px 4px !important; } -ul.cal_event { padding-right: 2px; padding-top: 1px; border: none; list-style-type: none; margin: 0 auto; padding-left: 0px; padding-start: 0px; -khtml-padding-start: 0px; -o-padding-start: 0px; -moz-padding-start: 0px; -webkit-padding-start: 0px; } -li.cal_event { border: none; list-style-type: none; } .cal_event a:link { color: #111111; font-size: 11px; font-weight: normal !important; } .cal_event a:visited { color: #111111; font-size: 11px; font-weight: normal !important; } .cal_event a:active { color: #111111; font-size: 11px; font-weight: normal !important; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 94f0b11b560..947b8a57168 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1701,14 +1701,24 @@ img.login, img.printer, img.entity { font-weight: bold; } .userimgatoplogin img.userphoto { /* size for user photo in login bar */ - border-radius: 5px; + border-radius: 8px; width: 16px; height: 16px; + background-size: contain; vertical-align: text-bottom; } img.userphoto { /* size for user photo in lists */ + border-radius: 9px; width: 18px; height: 18px; + background-size: contain; + vertical-align: middle; +} +img.userphotosmall { /* size for user photo in lists */ + border-radius: 6px; + width: 12px; + height: 12px; + background-size: contain; vertical-align: middle; } .span-icon-user { @@ -3366,6 +3376,7 @@ a.websitebuttonsitepreview img { /* Module agenda */ /* ============================================================================== */ +.agendacell { height: 60px; } table.cal_month { border-spacing: 0px; } table.cal_month td:first-child { border-left: 0px; } table.cal_month td:last-child { border-right: 0px; } @@ -3389,18 +3400,10 @@ table.cal_month td:last-child { border-right: 0px; } .cal_today_peruser_impair { background: #F8F8F0; } .peruser_busy { background: #CC8888; } .peruser_notbusy { background: #EEDDDD; opacity: 0.5; } -table.cal_event { border: none; border-collapse: collapse; margin-bottom: 1px; -webkit-border-radius: 3px; border-radius: 3px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); - background: -webkit-gradient(linear, left top, left bottom, from(#006aac), to(#00438d)); - min-height: 20px; - } +table.cal_event { border: none; border-collapse: collapse; margin-bottom: 1px; -webkit-border-radius: 3px; border-radius: 3px; min-height: 20px; } table.cal_event td { border: none; padding-: 2px; padding-: 2px; padding-top: 0px; padding-bottom: 0px; } table.cal_event td.cal_event { padding: 4px 4px !important; } table.cal_event td.cal_event_right { padding: 4px 4px !important; } -ul.cal_event { padding-right: 2px; padding-top: 1px; border: none; list-style-type: none; margin: 0 auto; padding-left: 0px; padding-start: 0px; -khtml-padding-start: 0px; -o-padding-start: 0px; -moz-padding-start: 0px; -webkit-padding-start: 0px; } -li.cal_event { border: none; list-style-type: none; } .cal_event a:link { color: #111111; font-size: 11px; font-weight: normal !important; } .cal_event a:visited { color: #111111; font-size: 11px; font-weight: normal !important; } .cal_event a:active { color: #111111; font-size: 11px; font-weight: normal !important; } diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 839d09ee9c7..37a0042c137 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -2346,35 +2346,38 @@ else print ''; } - print '
    '; - /* - * Documents generes - */ - $filename = dol_sanitizeFileName($object->ref); - $filedir = $conf->user->dir_output . "/" . dol_sanitizeFileName($object->ref); - $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; - $genallowed = $user->rights->user->user->creer; - $delallowed = $user->rights->user->user->supprimer; - - $var = true; - - $somethingshown = $formfile->show_documents('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); - - // Show links to link elements - $linktoelem = $form->showLinkToObjectBlock($object, null, null); - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - - print '
    '; - - // List of actions on element - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; - $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'user', $socid); + if ($action != 'edit') + { + print '
    '; + /* + * Documents generes + */ + $filename = dol_sanitizeFileName($object->ref); + $filedir = $conf->user->dir_output . "/" . dol_sanitizeFileName($object->ref); + $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; + $genallowed = $user->rights->user->user->creer; + $delallowed = $user->rights->user->user->supprimer; + + $var = true; + + $somethingshown = $formfile->show_documents('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); + + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object, null, null); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + + print '
    '; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'user', $socid); + + + print '
    '; + } - - print '
    '; - - if (! empty($conf->ldap->enabled) && ! empty($object->ldap_sid)) $ldap->close; + if (! empty($conf->ldap->enabled) && ! empty($object->ldap_sid)) $ldap->close(); } } diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 811f39b3c88..112609ce521 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1968,7 +1968,7 @@ class User extends CommonObject * Return a link to the user card (with optionaly the picto) * Use this->id,this->lastname, this->firstname * - * @param int $withpictoimg Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo) + * @param int $withpictoimg Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small) * @param string $option On what the link point to * @param integer $infologin Add complete info tooltip * @param integer $notooltip 1=Disable tooltip on picto and name @@ -2074,10 +2074,10 @@ class User extends CommonObject // Only picto if ($withpictoimg > 0) $picto='
    '.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'
    '; // Picto must be a photo - else $picto='
    '.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto', 'mini', 0, 1).'
    '; + else $picto='
    '.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'
    '; $result.=$picto; } - if (abs($withpictoimg) != 2) + if ($withpictoimg > -2 && $withpictoimg != 2) { if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='
    '; if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen); From 65be3107c36cb0299fe1909d1a926d10c0cec506 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 00:51:16 +0200 Subject: [PATCH 059/233] Fix phpunit --- test/phpunit/FunctionsLibTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index a53f971904c..28e55fd793b 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -712,15 +712,15 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase $s=img_picto('title','/fullpath/img.png','',1); print __METHOD__." s=".$s."\n"; - $this->assertEquals('',$s,'testImgPicto3'); + $this->assertEquals('',$s,'testImgPicto3'); $s=img_picto('title','/fullpath/img.png','',true); print __METHOD__." s=".$s."\n"; - $this->assertEquals('',$s,'testImgPicto4'); + $this->assertEquals('',$s,'testImgPicto4'); $s=img_picto('title:alt','/fullpath/img.png','',true); print __METHOD__." s=".$s."\n"; - $this->assertEquals('alt',$s,'testImgPicto5'); + $this->assertEquals('alt',$s,'testImgPicto5'); } /** From e221c48997c195389d122814e26f6d4796ea3b42 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 00:59:21 +0200 Subject: [PATCH 060/233] Css --- htdocs/comm/action/index.php | 2 +- htdocs/theme/eldy/graph-color.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index cb93f8bffab..d365acef38b 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1368,7 +1368,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print '>'; print ' Date: Sat, 1 Apr 2017 01:06:23 +0200 Subject: [PATCH 061/233] Fix php dependencies --- build/debian/control | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/debian/control b/build/debian/control index 75ffb43b2c0..29c2469a4e6 100755 --- a/build/debian/control +++ b/build/debian/control @@ -10,12 +10,12 @@ Build-Depends: debhelper (>= 9), po-debconf Package: dolibarr Architecture: all -Depends: libapache2-mod-php5 | libapache2-mod-php5filter | php5-cgi | php5-fpm | php5, - php5-cli, +Depends: libapache2-mod-php | libapache2-mod-phpfilter | php-cgi | php-fpm | php, + php-cli, # Required PHP extensions - php5-mysql | php5-mysqli, php5-curl, php5-gd, php5-ldap, + php-mysql | php-mysqli, php-curl, php-gd, php-ldap, # Required PHP libraries - php-pear, php-mail-mime, + php-pear, php-mail-mime, php-xml, php-mbstring, # php-tcpdf, # libfpdf-tpl-php, php-fpdf, # libphp-adodb, From d975e7f442f959d2eb4c4e6944a29fbe6c06b32f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 12:46:47 +0200 Subject: [PATCH 062/233] Work on 6.0 look and feel --- htdocs/accountancy/admin/account.php | 28 +++++------ htdocs/accountancy/admin/categories_list.php | 12 +++-- htdocs/accountancy/admin/productaccount.php | 43 ++++++++--------- htdocs/accountancy/bookkeeping/balance.php | 41 +++++++--------- htdocs/accountancy/bookkeeping/list.php | 36 +++++++------- htdocs/accountancy/customer/lines.php | 43 +++++++++-------- htdocs/accountancy/customer/list.php | 35 +++++++------- htdocs/accountancy/expensereport/lines.php | 33 ++++++------- htdocs/accountancy/expensereport/list.php | 32 +++++++------ htdocs/accountancy/supplier/lines.php | 44 +++++++++--------- htdocs/accountancy/supplier/list.php | 40 +++++++++------- htdocs/compta/paiement/list.php | 49 ++++++++++---------- htdocs/compta/salaries/index.php | 26 +++++------ htdocs/compta/sociales/index.php | 27 ++++++----- htdocs/compta/tva/reglement.php | 30 ++++++------ htdocs/core/class/html.form.class.php | 2 +- htdocs/core/get_menudiv.php | 8 +++- htdocs/core/lib/company.lib.php | 3 +- htdocs/core/lib/functions.lib.php | 4 +- htdocs/core/menus/standard/eldy.lib.php | 31 ++++++++----- htdocs/don/list.php | 37 +++++++-------- htdocs/fourn/facture/paiement.php | 28 +++++------ htdocs/loan/card.php | 47 +++++++++++++------ htdocs/loan/class/loan.class.php | 4 +- htdocs/loan/document.php | 2 +- htdocs/loan/index.php | 22 ++++----- htdocs/loan/info.php | 2 +- htdocs/loan/note.php | 2 +- htdocs/theme/eldy/style.css.php | 36 +++----------- htdocs/theme/md/style.css.php | 12 +++-- 30 files changed, 386 insertions(+), 373 deletions(-) diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 4e05b019d08..b10463361f8 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -242,20 +242,8 @@ if ($resql) print '
    '; print '
    '."\n"; - print ''; - - if (! empty($arrayfields['aa.account_number']['checked'])) print_liste_field_titre($arrayfields['aa.account_number']['label'], $_SERVER["PHP_SELF"],"aa.account_number","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['aa.label']['checked'])) print_liste_field_titre($arrayfields['aa.label']['label'], $_SERVER["PHP_SELF"],"aa.label","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['aa.account_parent']['checked'])) print_liste_field_titre($arrayfields['aa.account_parent']['label'], $_SERVER["PHP_SELF"],"aa.account_parent", "", $param,'align="left"',$sortfield,$sortorder); - if (! empty($arrayfields['aa.pcg_type']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_type']['label'],$_SERVER["PHP_SELF"],'aa.pcg_type','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['aa.pcg_subtype']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_subtype']['label'],$_SERVER["PHP_SELF"],'aa.pcg_subtype','',$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['aa.active']['checked'])) print_liste_field_titre($arrayfields['aa.active']['label'],$_SERVER["PHP_SELF"],'aa.active','',$param,'',$sortfield,$sortorder); - - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Line for search fields - print ''; + print ''; if (! empty($arrayfields['aa.account_number']['checked'])) print ''; if (! empty($arrayfields['aa.label']['checked'])) print ''; if (! empty($arrayfields['aa.account_parent']['checked'])) print ''; @@ -268,8 +256,16 @@ if ($resql) print ''; print ''; - $var = false; - + print ''; + if (! empty($arrayfields['aa.account_number']['checked'])) print_liste_field_titre($arrayfields['aa.account_number']['label'], $_SERVER["PHP_SELF"],"aa.account_number","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['aa.label']['checked'])) print_liste_field_titre($arrayfields['aa.label']['label'], $_SERVER["PHP_SELF"],"aa.label","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['aa.account_parent']['checked'])) print_liste_field_titre($arrayfields['aa.account_parent']['label'], $_SERVER["PHP_SELF"],"aa.account_parent", "", $param,'align="left"',$sortfield,$sortorder); + if (! empty($arrayfields['aa.pcg_type']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_type']['label'],$_SERVER["PHP_SELF"],'aa.pcg_type','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['aa.pcg_subtype']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_subtype']['label'],$_SERVER["PHP_SELF"],'aa.pcg_subtype','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['aa.active']['checked'])) print_liste_field_titre($arrayfields['aa.active']['label'],$_SERVER["PHP_SELF"],'aa.active','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $accountstatic = new AccountingAccount($db); $accountparent = new AccountingAccount($db); @@ -281,7 +277,7 @@ if ($resql) $accountstatic->label = $obj->label; $accountstatic->account_number = $obj->account_number; - print ''; + print ''; // Account number if (! empty($arrayfields['aa.account_number']['checked'])) diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index 3a775149987..30466926f0a 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -806,7 +806,7 @@ if ($id) print ''; // Title line with search boxes - print ''; + print ''; $filterfound=0; foreach ($fieldlist as $field => $value) { @@ -831,14 +831,16 @@ if ($id) } if ($id == 4) print ''; print ''; - print ''; + print ''; + print ''; - print ''; + print ''; if ($num) { @@ -860,7 +862,9 @@ if ($id) // Show fields if (empty($reshook)) fieldList($fieldlist,$obj,$tabname[$id],'edit'); - print ''; + print ''; + print '"; if ($objp->amount < 0) @@ -568,3 +601,102 @@ else llxFooter(); $db->close(); + +/*Function to generate the HTML code used to show the file name & download link attached to the Item covered by the bank line + * @param $db Object database object + * @param $bankId int bank line id + * @param $label + * + */ +function Get_attach_files($db, $bankId,$label=''){ + $out=''; + global$conf; + $sql='SELECT u.url_id, u.type,ff.rowid as id , ff.`ref` AS reff, f.facnumber AS `ref`,'; + $sql.=' e.`ref` AS refe, sp.rowid AS ids, d.rowid AS idd'; + $sql.=' FROM '.MAIN_DB_PREFIX.'bank_url AS u'; + if ( !empty($label) || $label=='(CustomerInvoicePayment)'){ + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiement AS p ON p.fk_bank = u.fk_bank'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiement_facture AS pf ON pf.fk_paiement = p.rowid'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'facture AS f ON f.rowid = pf.fk_facture'; + } + if( !empty($label) || $label=='(SupplierInvoicePayment)'){ + //invoice suplier (SupplierInvoicePayment) + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn AS fp ON fp.fk_bank = u.fk_bank'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn AS fpf ON fpf.fk_paiementfourn = fp.rowid'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn AS ff ON ff.rowid = fpf.fk_facturefourn'; + } + if( !empty($label) || $label=='(ExpenseReportPayment)'){ + //EXPENSEs (ExpenseReportPayment) + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_expensereport AS ep ON ep.fk_bank = u.fk_bank'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport AS e ON e.rowid = ep.fk_expensereport'; + } + if( !empty($label) || $label=='(DonationPayment)'){ + //donation + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_donation AS dp ON dp.fk_bank = u.fk_bank'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'don AS d ON d.rowid = dp.fk_donation'; + } + if( !empty($label) || $label=='(SalaryPayment)'){ + //loan +// $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_loan AS lp ON lp.fk_bank = u.fk_bank'; + //salary + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_salary AS sp ON sp.fk_bank = u.fk_bank'; + } + //END SQL + $sql.=" WHERE u.fk_bank in('".$bankId."')AND u.type in ('payment','payment_supplier','payment_expensereport','payment_salary','payment_donation' )"; + $resd = $db->query($sql); + $files=array(); + $link=''; + if ($resd) + { + $numd = $db->num_rows($resd); + $upload_dir =''; + $i=0; + if($numd>0) + { + + + $objd = $db->fetch_object($resd); + + switch($objd->type){ + case "payment": + $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 "payment_supplier": + $subdir=get_exdir($objd->id,2,0,0,$objd,'invoice_supplier').$objd->reff; + $upload_dir = $conf->fournisseur->facture->dir_output.'/'.$subdir; + $link="../../document.php?modulepart=facture_fournisseur&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + case "payment_expensereport": + $subdir=dol_sanitizeFileName($objd->refe); + $upload_dir = $conf->expensereport->dir_output.'/'.$subdir; + $link="../../document.php?modulepart=expensereport&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + case "payment_salary": + $subdir=dol_sanitizeFileName($objd->ids); + $upload_dir = $conf->salaries->dir_output.'/'.$subdir; + $link="../../document.php?modulepart=salaries&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + case "payment_donation": + $subdir=get_exdir(null,2,0,1,$objd,'donation'). '/'. dol_sanitizeFileName($objd->idd); + $upload_dir = $conf->don->dir_output . '/' . $subdir; + $link="../../document.php?modulepart=don&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + default: + break; + } + + if(!empty($upload_dir)){ + $files=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$','',SORT_ASC,1); + foreach ($files as $key => $file){ + $out.= '
    '.$file['name'].''; + } + $_SESSION["releve"][$num][]=$files; + } + } + } + $db->free($resd); + return $out; +} From ca72e5e19f04dd908c7fcd542d2c610164fcd151 Mon Sep 17 00:00:00 2001 From: delcroix Patrick Date: Wed, 5 Apr 2017 20:53:41 +0200 Subject: [PATCH 092/233] NEW : download button --- htdocs/compta/bank/releve.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index 2ab6df9047f..4eb52dd2178 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -595,6 +595,9 @@ else print ""; print "\n"; + // download button + echo ''.$langs->trans('DownloadFile')." \n"; + } From 337eac30c17a8f08d38f8eed856423cc0b3f8ee0 Mon Sep 17 00:00:00 2001 From: delcroix Patrick Date: Wed, 5 Apr 2017 21:14:41 +0200 Subject: [PATCH 093/233] Update releve.php --- htdocs/compta/bank/releve.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index 4eb52dd2178..2acb0b327ce 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -552,7 +552,7 @@ else dol_print_error($db); } } - print Get_attach_files($db,$objp->rowid,$objp->label); + print Get_attach_files($db,$objp->rowid,$num,$objp->label); print ""; if ($objp->amount < 0) @@ -608,10 +608,11 @@ $db->close(); /*Function to generate the HTML code used to show the file name & download link attached to the Item covered by the bank line * @param $db Object database object * @param $bankId int bank line id - * @param $label + * @param $num int bank statement + * @param $label string label used to optimise the sql querry * */ -function Get_attach_files($db, $bankId,$label=''){ +function Get_attach_files($db, $bankId,$num,$label=''){ $out=''; global$conf; $sql='SELECT u.url_id, u.type,ff.rowid as id , ff.`ref` AS reff, f.facnumber AS `ref`,'; From 18fc5bec9b143276c09df9b50ff8497d61b60a8c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Apr 2017 10:56:37 +0200 Subject: [PATCH 094/233] Better log --- htdocs/product/stock/class/mouvementstock.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 631f6697c33..6088c14ed60 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -176,8 +176,8 @@ class MouvementStock extends CommonObject if ($this->db->jdate($obj->eatby) != $eatby && $this->db->jdate($obj->eatby) != $eatbywithouthour) // We test date without hours and with hours for backward compatibility { // If found and eatby/sellby defined into table and provided and differs, return error - $this->errors[]=$langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby)), dol_print_date($eatby)); - dol_syslog($langs->transnoentities("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby)), dol_print_date($eatby)), LOG_ERR); + $this->errors[]=$langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby), 'dayhour'), dol_print_date($eatby, 'dayhour')); + dol_syslog("ThisSerialAlreadyExistWithDifferentDate batch=".$batch.", eatby found into product_lot = ".$obj->eatby." = ".dol_print_date($this->db->jdate($obj->eatby), 'dayhourrfc')." so eatbywithouthour = ".$eatbywithouthour." = ".dol_print_date($eatbywithouthour)." - eatby provided = ".$eatby." = ".dol_print_date($eatby, 'dayhourrfc'), LOG_ERR); $this->db->rollback(); return -3; } From 6b2d8a3c34e911de4f110ae512d33565178c92ed Mon Sep 17 00:00:00 2001 From: arnaud Date: Thu, 6 Apr 2017 11:14:15 +0200 Subject: [PATCH 095/233] FIX limit+1 dosn't show Total line --- htdocs/compta/facture/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index b2b95d74963..14a5c484e8c 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -551,7 +551,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $nbtotalofrecords = $db->num_rows($result); } -$sql.= $db->plimit($limit+1,$offset); +$sql.= $db->plimit($limit,$offset); //print $sql; $resql = $db->query($sql); From e2ea5945ddc772a60ef2e5229fbe302c8126bb6b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 14:48:24 +0200 Subject: [PATCH 096/233] Work on look and feel v6 --- htdocs/adherents/class/adherent.class.php | 85 ++++++++--- htdocs/adherents/list.php | 6 +- htdocs/categories/photos.php | 16 +-- htdocs/categories/traduction.php | 4 +- htdocs/categories/viewcat.php | 4 +- htdocs/compta/bank/ligne.php | 16 ++- htdocs/core/class/commonobject.class.php | 4 +- htdocs/core/class/html.form.class.php | 4 +- htdocs/core/class/html.formfile.class.php | 19 ++- htdocs/core/lib/functions.lib.php | 3 +- htdocs/core/tpl/contacts.tpl.php | 4 +- htdocs/main.inc.php | 2 +- htdocs/projet/card.php | 13 +- htdocs/projet/class/task.class.php | 11 ++ htdocs/projet/contact.php | 13 +- htdocs/projet/element.php | 18 +-- htdocs/projet/ganttchart.inc.php | 4 +- htdocs/projet/ganttview.php | 13 +- htdocs/projet/tasks.php | 11 +- htdocs/projet/tasks/contact.php | 44 +++--- htdocs/projet/tasks/document.php | 31 +++- htdocs/projet/tasks/note.php | 31 ++-- htdocs/projet/tasks/task.php | 42 ++++-- htdocs/projet/tasks/time.php | 163 ++++++++++++---------- htdocs/user/class/user.class.php | 4 +- 25 files changed, 355 insertions(+), 210 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 833b5bf224e..f3dfd857973 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1570,40 +1570,85 @@ class Adherent extends CommonObject /** * Return clicable name (with picto eventually) * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @param int $maxlen length max libelle - * @param string $option Page lien + * @param int $withpictoimg 0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small) + * @param int $maxlen length max label + * @param string $option Page for link + * @param string $mode ''=Show firstname and lastname, 'firstname'=Show only firstname, 'login'=Show login, 'ref'=Show ref + * @param string $morecss Add more css on link * @return string Chaine avec URL */ - function getNomUrl($withpicto=0,$maxlen=0,$option='card') + function getNomUrl($withpictoimg=0,$maxlen=0,$option='card',$mode='ref',$morecss='') { - global $langs; + global $conf, $langs; - $result=''; - $label = '' . $langs->trans("ShowMember") . ''; + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0; + + $result=''; $label=''; + $link=''; $linkstart=''; $linkend=''; + + if (! empty($this->photo)) + { + $label.= '
    '; + $label.= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1); + $label.= '
    '; + } + + $label.= '
    '; + $label.= '' . $langs->trans("Member") . ''; if (! empty($this->ref)) $label.= '
    ' . $langs->trans('Ref') . ': ' . $this->ref; if (! empty($this->firstname) || ! empty($this->lastname)) $label.= '
    ' . $langs->trans('Name') . ': ' . $this->getFullName($langs); - $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; - - $link=''; $linkend=''; + $label.='
    '; + if ($option == 'card' || $option == 'category') { - $link = ''; + $link = 'ref,$maxlen):$this->ref) : '').$linkend; + + $linkclose=""; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $langs->load("users"); + $label=$langs->trans("ShowUser"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; + } + + $link.=$linkclose.'>'; + $linkend=''; + + //if ($withpictoimg == -1) $result.='
    '; + $result.=$link; + if ($withpictoimg) + { + $paddafterimage=''; + if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"'; + // Only picto + if ($withpictoimg > 0) $picto='
    '.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'
    '; + // Picto must be a photo + else $picto='
    '.Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'
    '; + $result.=$picto; + } + if ($withpictoimg > -2 && $withpictoimg != 2) + { + if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='
    '; + if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen); + elseif ($mode == 'ref') $result.=$this->id; + else $result.=$this->getFullName($langs,'',($mode == 'firstname' ? 2 : -1),$maxlen); + if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='
    '; + } + $result.=$linkend; + //if ($withpictoimg == -1) $result.='
    '; + return $result; } diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index e492e31b440..4589cdc754f 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -611,6 +611,7 @@ while ($i < min($num, $limit)) $memberstatic->statut=$obj->statut; $memberstatic->datefin= $datefin; $memberstatic->socid = $obj->fk_soc; + $memberstatic->photo = $obj->photo; if (! empty($obj->fk_soc)) { $memberstatic->fetch_thirdparty(); @@ -619,8 +620,7 @@ while ($i < min($num, $limit)) $companyname=$obj->company; } - $var=!$var; - print "
    "; + print ''; if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { @@ -631,7 +631,7 @@ while ($i < min($num, $limit)) if (! empty($arrayfields['d.ref']['checked'])) { print "\n"; } // Firstname diff --git a/htdocs/categories/photos.php b/htdocs/categories/photos.php index ee03f9f4771..100d2d0d48e 100644 --- a/htdocs/categories/photos.php +++ b/htdocs/categories/photos.php @@ -105,7 +105,7 @@ if ($object->id) $head = categories_prepare_head($object,$type); - dol_fiche_head($head, 'photos', $title, 0, 'category'); + dol_fiche_head($head, 'photos', $title, -1, 'category'); $linkback = ''.$langs->trans("BackToList").''; @@ -130,6 +130,7 @@ if ($object->id) print '
    '; + print '
    '; print '
    '; print '
    '; + print ''; if ($filterfound) { $searchpitco=$form->showFilterAndCheckAddButtons(0); print $searchpitco; } print '
    '; + print ''; print ''; print ''; print ''; diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php index cae9295229b..dda7d545043 100644 --- a/htdocs/accountancy/admin/productaccount.php +++ b/htdocs/accountancy/admin/productaccount.php @@ -312,22 +312,8 @@ if ($result) print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, '', 0, '', '', $limit); print ''; - print ''; - print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC)) print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "p.description", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("OnSell"), $_SERVER["PHP_SELF"], "p.tosell", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("OnBuy"), $_SERVER["PHP_SELF"], "p.tobuy", "", $param, 'align="center"', $sortfield, $sortorder); - if ($accounting_product_mode == 'ACCOUNTANCY_BUY') { - $fieldtosortaccount="p.accountancy_code_buy"; - } - else $fieldtosortaccount="p.accountancy_code_sell"; - print_liste_field_titre($langs->trans("CurrentDedicatedAccountingAccount"), $_SERVER["PHP_SELF"], $fieldtosortaccount, "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("AssignDedicatedAccountingAccount")); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print ''; - - print ''; + + print ''; print ''; print ''; if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC)) print ''; @@ -342,12 +328,28 @@ if ($result) print ' '.$langs->trans("or").' '.$form->selectarray('search_current_account_valid', $listofvals, $search_current_account_valid, 1); print ''; print ''; - print ''; print ''; + print ''; + print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); + if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC)) print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "p.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("OnSell"), $_SERVER["PHP_SELF"], "p.tosell", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("OnBuy"), $_SERVER["PHP_SELF"], "p.tobuy", "", $param, 'align="center"', $sortfield, $sortorder); + if ($accounting_product_mode == 'ACCOUNTANCY_BUY') { + $fieldtosortaccount="p.accountancy_code_buy"; + } + else $fieldtosortaccount="p.accountancy_code_sell"; + print_liste_field_titre($langs->trans("CurrentDedicatedAccountingAccount"), $_SERVER["PHP_SELF"], $fieldtosortaccount, "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("AssignDedicatedAccountingAccount")); + $clickpitco=$form->showCheckAddButtons('checkforselect', 1); + print_liste_field_titre($clickpitco, '', '', '', '', 'align="center"'); + print ''; + $product_static = new Product($db); $var = true; @@ -381,8 +383,7 @@ if ($result) $compta_prodbuy_id = $aarowid_servbuy; } - $var = ! $var; - print ''; + print ''; print ''; print ""; $i ++; diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 8f6fab3ec3f..5f4801da32c 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -182,6 +182,22 @@ else { } print '
     '; - $searchpitco=$form->showFilterAndCheckAddButtons(1, 'checkforselect', 1); + print ''; + $searchpitco=$form->showFilterButtons(); print $searchpitco; print '
    '; print $product_static->getNomUrl(1); @@ -440,7 +441,7 @@ if ($result) } // Checkbox select - print ''; + print ''; print '
    '; + + print ''; + print ''; + print ''; + + print ''; + print ''; print_liste_field_titre($langs->trans("AccountAccounting"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder); print_liste_field_titre($langs->trans("Label"), $_SERVER['PHP_SELF'], "t.label_compte", "", $options, "", $sortfield, $sortorder); @@ -191,28 +207,6 @@ else { print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $options, "", 'width="60" align="center"', $sortfield, $sortorder); print "\n"; - print ''; - print ''; - - print ''; - print ''; - print ''; - - print ''; - - print ''; - - $var = True; - $total_debit = 0; $total_credit = 0; $sous_total_debit = 0; @@ -220,7 +214,6 @@ else { $displayed_account = ""; foreach ($object->lines as $line) { - $var = ! $var; $link = ''; $total_debit += $line->debit; $total_credit += $line->credit; @@ -229,7 +222,7 @@ else { if (empty($description)) { $link = '' . img_edit_add() . ''; } - print ''; + print ''; // Permet d'afficher le compte comptable if ($root_account_description != $displayed_account) { diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index ae38233afac..9cd649ce4be 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -371,20 +371,8 @@ print ''; -print_liste_field_titre($langs->trans("TransactionNumShort"), $_SERVER['PHP_SELF'], "t.piece_num", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Docdate"), $_SERVER['PHP_SELF'], "t.doc_date", "", $param, 'align="center"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Docref"), $_SERVER['PHP_SELF'], "t.doc_ref", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre($langs->trans("AccountAccountingShort"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Code_tiers"), $_SERVER['PHP_SELF'], "t.code_tiers", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Label"), $_SERVER['PHP_SELF'], "t.label_compte", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "t.debit", "", $param, 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "t.credit", "", $param, 'align="right"', $sortfield, $sortorder); -print_liste_field_titre($langs->trans("Codejournal"), $_SERVER['PHP_SELF'], "t.code_journal", "", $param, 'align="center"', $sortfield, $sortorder); -print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder); -print "\n"; -print ''; +print ''; print ''; print ''; print ''; print ''; print ''; print ''; -$var = True; +print ''; +print_liste_field_titre($langs->trans("TransactionNumShort"), $_SERVER['PHP_SELF'], "t.piece_num", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Docdate"), $_SERVER['PHP_SELF'], "t.doc_date", "", $param, 'align="center"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Docref"), $_SERVER['PHP_SELF'], "t.doc_ref", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($langs->trans("AccountAccountingShort"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Code_tiers"), $_SERVER['PHP_SELF'], "t.code_tiers", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Label"), $_SERVER['PHP_SELF'], "t.label_compte", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "t.debit", "", $param, 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "t.credit", "", $param, 'align="right"', $sortfield, $sortorder); +print_liste_field_titre($langs->trans("Codejournal"), $_SERVER['PHP_SELF'], "t.code_journal", "", $param, 'align="center"', $sortfield, $sortorder); +$checkpicto=''; +if ($massactionbutton) $checkpicto=$form->showCheckAddButtons('checkforselect', 1); +print_liste_field_titre($checkpicto, $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder); +print "\n"; + $total_debit = 0; $total_credit = 0; @@ -431,7 +433,7 @@ foreach ($object->lines as $line ) { $total_debit += $line->debit; $total_credit += $line->credit; - print ''; + print ''; print ''; print ''; diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index a759472304e..a015fa05929 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -256,22 +256,7 @@ if ($result) { print '
    '; print '
    '; + print $langs->trans('From'); + print $formventilation->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array(), 1, 1, ''); + print ' '; + print $langs->trans('to'); + print $formventilation->select_account($search_accountancy_code_end, 'search_accountancy_code_end', 1, array(), 1, 1, ''); + print ''; + $searchpitco=$form->showFilterAndCheckAddButtons(0); + print $searchpitco; + print '
    '; - print $langs->trans('From'); - print $formventilation->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array(), 1, 1, ''); - print '
    '; - print $langs->trans('to'); - print $formventilation->select_account($search_accountancy_code_end, 'search_accountancy_code_end', 1, array(), 1, 1, ''); - print '
       '; - $searchpitco=$form->showFilterAndCheckAddButtons(0); - print $searchpitco; - print '
    '; print $langs->trans('From') . ': '; @@ -415,12 +403,26 @@ print '  '; -$searchpitco=$form->showFilterAndCheckAddButtons(0); -print $searchpitco; +$searchpicto=$form->showFilterButtons(); +print $searchpicto; print '
    ' . $line->piece_num . '' . dol_print_date($line->doc_date, 'day') . '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "fd.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.facnumber", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.facnumber, fd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); - //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "fd.description", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "fd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "fd.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Country"), $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATIntra"), $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; - - print ''; + print ''; print ''; print ''; print ''; @@ -284,16 +269,30 @@ if ($result) { print ''; print ''; print '\n"; + + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "fd.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.facnumber", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.facnumber, fd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "fd.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "fd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "fd.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Country"), $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATIntra"), $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder); + $clickpicto=$form->showCheckAddButtons(); + print_liste_field_titre($clickpicto, '', '', '', '', 'align="center"'); + print "\n"; $facture_static = new Facture($db); $product_static = new Product($db); - $var = True; while ( $objp = $db->fetch_object($result) ) { - $var = ! $var; $codecompta = length_accountg($objp->account_number) . ' - ' . $objp->label_compte; $facture_static->ref = $objp->facnumber; @@ -304,7 +303,7 @@ if ($result) { $product_static->type = $objp->product_type; $product_static->label = $objp->product_label; - print ''; + print ''; print ''; @@ -335,7 +334,7 @@ if ($result) { print ''; print ''; print ''; - print ''; + print ''; print ""; $i ++; diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 09ad316a398..e8e10b4a0be 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -271,22 +271,9 @@ if ($result) { print '
    '; print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons(1); - print $searchpitco; + $searchpicto=$form->showFilterButtons(); + print $searchpicto; print "
    ' . $objp->rowid . '' . $objp->country .'' . $objp->tva_intra . '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.facnumber", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.facnumber, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); - //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); - print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; // We add search filter - print ''; + print ''; print ''; print ''; print ''; @@ -298,11 +285,27 @@ if ($result) { print ''; print ''; print ''; print ''; + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.facnumber", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.facnumber, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); + print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); + $checkpicto=''; + if ($massactionbutton) $checkpicto=$form->showCheckAddButtons('checkforselect', 1); + print_liste_field_titre($checkpitco, '', '', '', '', 'align="center"'); + print "\n"; + $facture_static = new Facture($db); $product_static = new Product($db); $form = new Form($db); diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php index 56298045532..20994d76a93 100644 --- a/htdocs/accountancy/expensereport/lines.php +++ b/htdocs/accountancy/expensereport/lines.php @@ -233,20 +233,7 @@ if ($result) { print '
    '; print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); - print $searchpitco; + $searchpicto=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + print $searchpicto; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "erd.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ExpenseReport"), $_SERVER["PHP_SELF"], "er.ref", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "erd.date, erd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("TypeFees"), $_SERVER["PHP_SELF"], "f.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "erd.comments", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "erd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "erd.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre(''); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; - - print ''; + print ''; print ''; print ''; print ''; @@ -257,11 +244,25 @@ if ($result) { print ''; print ''; print ''; print "\n"; + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "erd.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ExpenseReport"), $_SERVER["PHP_SELF"], "er.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "erd.date, erd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("TypeFees"), $_SERVER["PHP_SELF"], "f.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "erd.comments", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "erd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "erd.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre(''); + $checkpicto=$form->showCheckAddButtons(); + print_liste_field_titre($checkpicto, '', '', '', '', 'align="center"'); + print "\n"; + $expensereport_static = new ExpenseReport($db); $var = True; @@ -300,7 +301,7 @@ if ($result) { print img_edit(); print ''; - print ''; + print ''; print ""; $i ++; diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php index 5bb232fc7c1..49a63a15698 100644 --- a/htdocs/accountancy/expensereport/list.php +++ b/htdocs/accountancy/expensereport/list.php @@ -259,21 +259,9 @@ if ($result) { print '
    '; print '
    '; - $searchpicto=$form->showFilterAndCheckAddButtons(1); + $searchpicto=$form->showFilterButtons(); print $searchpicto; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "erd.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ExpenseReport"), $_SERVER["PHP_SELF"], "er.ref", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "erd.date, erd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("TypeFees"), $_SERVER["PHP_SELF"], "f.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "erd.comments", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "erd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "erd.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); - print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; // We add search filter - print ''; + print ''; print ''; print ''; print ''; @@ -284,11 +272,27 @@ if ($result) { print ''; print ''; print ''; print ''; + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "erd.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ExpenseReport"), $_SERVER["PHP_SELF"], "er.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "erd.date, erd.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("TypeFees"), $_SERVER["PHP_SELF"], "f.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "erd.comments", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "erd.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "erd.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); + print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); + $checkpicto=''; + if ($massactionbutton) $checkpicto=$form->showCheckAddButtons('checkforselect', 1); + print_liste_field_titre($checkpicto, '', '', '', '', 'align="center"'); + print "\n"; + + $expensereport_static = new ExpenseReport($db); $form = new Form($db); diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php index 121ba0e9f46..1f0d06fbec6 100644 --- a/htdocs/accountancy/supplier/lines.php +++ b/htdocs/accountancy/supplier/lines.php @@ -239,21 +239,7 @@ if ($result) { print '
    '; print '
    '; - $searchpicto=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpicto=$form->showFilterButtons(); print $searchpicto; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("InvoiceLabel"), $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); - //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; - - print ''; + print ''; print ''; print ''; print ''; @@ -265,18 +251,32 @@ if ($result) { print ''; print ''; print ''; print "\n"; + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("InvoiceLabel"), $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Account"), $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder); + $checkpicto=$form->showCheckAddButtons(); + print_liste_field_titre($checkpicto, '', '', '', '', 'align="center"'); + print "\n"; + $facturefournisseur_static = new FactureFournisseur($db); $product_static = new Product($db); - $var = True; - while ( $i < min($num_lines, $limit) ) { + while ($i < min($num_lines, $limit)) { $objp = $db->fetch_object($result); - $var = ! $var; + $codecompta = length_accountg($objp->account_number) . ' - ' . $objp->label; $facturefournisseur_static->ref = $objp->facnumber; @@ -287,7 +287,7 @@ if ($result) { $product_static->type = $objp->type; $product_static->label = $objp->product_label; - print ''; + print ''; print ''; @@ -320,7 +320,7 @@ if ($result) { print img_edit(); print ''; - print ''; + print ''; print ""; $i ++; diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index 19ef52f0d85..9b42337852c 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -267,24 +267,11 @@ if ($result) { $moreforfilter = ''; print '
    '; - print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons(1); - print $searchpitco; + $searchpicto=$form->showFilterButtons(); + print $searchpicto; print '
    ' . $objp->rowid . '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("InvoiceLabel"), $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); - //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); - print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); - print_liste_field_titre('', '', '', '', '', 'align="center"'); - print "\n"; + + print '
    '."\n"; // We add search filter - print ''; + print ''; print ''; print ''; print ''; @@ -297,11 +284,28 @@ if ($result) { print ''; print ''; print ''; print ''; + print ''; + print_liste_field_titre($langs->trans("LineId"), $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Invoice"), $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("InvoiceLabel"), $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Date"), $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("ProductRef"), $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + //print_liste_field_titre($langs->trans("ProductLabel"), $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Description"), $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Amount"), $_SERVER["PHP_SELF"], "l.total_ht", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("VATRate"), $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("AccountAccountingSuggest"), '', '', '', '', 'align="center"'); + print_liste_field_titre($langs->trans("IntoAccount"), '', '', '', '', 'align="center"'); + $checkpicto=''; + if ($massactionbutton) $checkpicto=$form->showCheckAddButtons('checkforselect', 1); + print_liste_field_titre($checkpicto, '', '', '', '', 'align="center"'); + print "\n"; + $facturefourn_static = new FactureFournisseur($db); $productfourn_static = new ProductFournisseur($db); $form = new Form($db); diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php index 4cb63b7d905..d0ba0373457 100644 --- a/htdocs/compta/paiement/list.php +++ b/htdocs/compta/paiement/list.php @@ -225,29 +225,8 @@ if ($resql) print '
    '; print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); - print $searchpitco; + $searchpicto=$form->showFilterButtons(); + print $searchpicto; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("RefPayment"),$_SERVER["PHP_SELF"],"p.rowid","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"dp","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"c.libelle","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Numero"),$_SERVER["PHP_SELF"],"p.num_paiement","",$param,"",$sortfield,$sortorder); - if (! empty($conf->banque->enabled)) - { - print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); - } - print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"p.amount","",$param,'align="right"',$sortfield,$sortorder); - //print_liste_field_titre($langs->trans("Invoices"),"","","",$param,'align="left"',$sortfield,$sortorder); - - $parameters=array(); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - - if (! empty($conf->global->BILL_ADD_PAYMENT_VALIDATION)) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"p.statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Lines for filters fields - print ''; + print ''; print ''; @@ -285,12 +264,32 @@ if ($resql) } print "\n"; - $var=true; + print ''; + print_liste_field_titre($langs->trans("RefPayment"),$_SERVER["PHP_SELF"],"p.rowid","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"dp","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"c.libelle","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Numero"),$_SERVER["PHP_SELF"],"p.num_paiement","",$param,"",$sortfield,$sortorder); + if (! empty($conf->banque->enabled)) + { + print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); + } + print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"p.amount","",$param,'align="right"',$sortfield,$sortorder); + //print_liste_field_titre($langs->trans("Invoices"),"","","",$param,'align="left"',$sortfield,$sortorder); + + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + + if (! empty($conf->global->BILL_ADD_PAYMENT_VALIDATION)) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"p.statut","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + while ($i < min($num,$limit)) { $objp = $db->fetch_object($resql); - $var=!$var; - print ""; + + print ''; print ''; } - print ''; // Notification for this thirdparty + /*print ''; // Notification for this thirdparty print ''; + print '';*/ + print '
    '; print ''; print '
    '; $paymentstatic->id=$objp->rowid; diff --git a/htdocs/compta/salaries/index.php b/htdocs/compta/salaries/index.php index 88414e45566..a6d99cbdaad 100644 --- a/htdocs/compta/salaries/index.php +++ b/htdocs/compta/salaries/index.php @@ -85,7 +85,7 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETP * View */ -llxHeader(); +llxHeader('', $langs->trans("Salaries")); $form = new Form($db); $salstatic = new PaymentSalary($db); @@ -155,18 +155,7 @@ if ($result) print '
    '; print ''."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"s.rowid","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Employee"),$_SERVER["PHP_SELF"],"u.rowid","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"s.label","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DatePayment"),$_SERVER["PHP_SELF"],"s.datep","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PaymentMode"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); - if (! empty($conf->banque->enabled)) print_liste_field_titre($langs->trans("BankAccount"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PayedByThisPayment"),$_SERVER["PHP_SELF"],"s.amount","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - - print ''; + print ''; // Ref print ''; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"s.rowid","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Employee"),$_SERVER["PHP_SELF"],"u.rowid","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"s.label","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DatePayment"),$_SERVER["PHP_SELF"],"s.datep","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PaymentMode"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); + if (! empty($conf->banque->enabled)) print_liste_field_titre($langs->trans("BankAccount"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PayedByThisPayment"),$_SERVER["PHP_SELF"],"s.amount","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + print "\n"; while ($i < min($num,$limit)) diff --git a/htdocs/compta/sociales/index.php b/htdocs/compta/sociales/index.php index 66d6a65dd56..706c75fab07 100644 --- a/htdocs/compta/sociales/index.php +++ b/htdocs/compta/sociales/index.php @@ -177,18 +177,7 @@ if ($resql) print '
    '; print '
    '; print ''; @@ -198,6 +187,17 @@ if ($result) print $searchpitco; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"id","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"cs.libelle","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PeriodEndDate"),$_SERVER["PHP_SELF"],"periode","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"cs.amount","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateDue"),$_SERVER["PHP_SELF"],"cs.date_ech","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"cs.paye","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - - print ''; + print ''; // Ref print ''; print "\n"; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"id","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"cs.libelle","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PeriodEndDate"),$_SERVER["PHP_SELF"],"periode","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"cs.amount","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateDue"),$_SERVER["PHP_SELF"],"cs.date_ech","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"cs.paye","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + $i=0; $totalarray=array(); while ($i < min($num,$limit)) { $obj = $db->fetch_object($resql); - $var = !$var; - print ""; + print ''; // Ref print '"; + print ""; // Photo - Name print ''; print '
    '; print ''; @@ -218,14 +207,24 @@ if ($resql) print '
    '; diff --git a/htdocs/compta/tva/reglement.php b/htdocs/compta/tva/reglement.php index 1a45b8a91c7..15a6df0a717 100644 --- a/htdocs/compta/tva/reglement.php +++ b/htdocs/compta/tva/reglement.php @@ -157,19 +157,10 @@ if ($result) print_barre_liste($langs->trans("VATPayments"),$page,$_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,'',$num,$totalnboflines, 'title_accountancy', 0, '', '', $limit); + print '
    '; print ''; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"t.rowid","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"t.label","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateValue"),$_SERVER["PHP_SELF"],"dv","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DatePayment"),$_SERVER["PHP_SELF"],"dp","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); - if (! empty($conf->banque->enabled)) print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("PayedByThisPayment"),$_SERVER["PHP_SELF"],"t.amount","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - print ''; + print ''; print ''; print ''; print ''; @@ -196,10 +187,20 @@ if ($result) print ''; print "\n"; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"t.rowid","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"t.label","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateValue"),$_SERVER["PHP_SELF"],"dv","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DatePayment"),$_SERVER["PHP_SELF"],"dp","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); + if (! empty($conf->banque->enabled)) print_liste_field_titre($langs->trans("Account"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("PayedByThisPayment"),$_SERVER["PHP_SELF"],"t.amount","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + while ($i < min($num,$limit)) { $obj = $db->fetch_object($result); - $var=!$var; if ($obj->payment_code <> '') { @@ -210,7 +211,7 @@ if ($result) $type = ''; } - print ""; + print ''; $tva_static->id=$obj->rowid; $tva_static->ref=$obj->rowid; @@ -254,7 +255,8 @@ if ($result) print ""; print "
     
     
    "; - + print '
    '; + print ''; $db->free($result); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 99b27c20822..a01d54f0bef 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1634,7 +1634,7 @@ class Form { if ($value['id'] == $ownerid) continue; $userstatic->fetch($value['id']); - $out.=$userstatic->getNomUrl(1); + $out.=$userstatic->getNomUrl(-1); if ($i == 0) { $ownerid = $value['id']; $out.=' ('.$langs->trans("Owner").')'; } if ($nbassignetouser > 1 && $action != 'view') $out.=' '; //$out.=' '.($value['mandatory']?$langs->trans("Mandatory"):$langs->trans("Optional")); diff --git a/htdocs/core/get_menudiv.php b/htdocs/core/get_menudiv.php index d8a7cb1b34c..fd80124e7df 100644 --- a/htdocs/core/get_menudiv.php +++ b/htdocs/core/get_menudiv.php @@ -93,11 +93,15 @@ print ' padding: 1em 15px 1em 40px; } li.lilevel1 { - padding: 1em 15px 0.5em 20px; - border-top: 1px solid #ccc; + padding: 1em 15px 0.5em 40px; + border-top: 1px solid #aaa; margin-right: 20px; border-right: 0px ! important; } + li.lilevel1:first-child { + margin-right: 0px; + margin-left: 0px; + } li.lilevel1 a { padding-bottom: 5px; } diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index bbe9febd481..e6e154220b8 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -763,7 +763,6 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') while ($i < $num) { $obj = $db->fetch_object($result); - $var = !$var; $contactstatic->id = $obj->rowid; $contactstatic->ref = $obj->ref; @@ -789,7 +788,7 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') $contactstatic->setGenderFromCivility(); - print "
    '; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 6028f9bcabc..e51541272bd 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2038,12 +2038,12 @@ function dol_print_address($address, $htmlid, $mode, $id, $noprint=0, $charfornl if ($showgmap) { $url=dol_buildpath('/google/gmaps.php?mode='.$mode.'&id='.$id,1); - $out.=' '; + $out.=' '; } if ($showomap) { $url=dol_buildpath('/openstreetmap/maps.php?mode='.$mode.'&id='.$id,1); - $out.=' '; + $out.=' '; } } } diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 3874afb5198..7207f8f2189 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1005,18 +1005,25 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $i = 0; if ($numr > 0) - while ($i < $numr) { - $objp = $db->fetch_object($resql); - - if ($objp->nature == 1) $nature="sells"; - if ($objp->nature == 2) $nature="purchases"; - if ($objp->nature == 3) $nature="bank"; - if ($objp->nature == 4) $nature="various"; - if ($objp->nature == 9) $nature="hasnew"; - - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&code_journal='.$objp->code,dol_trunc($objp->label,25),2,$user->rights->accounting->comptarapport->lire); - $i++; + while ($i < $numr) + { + $objp = $db->fetch_object($resql); + + if ($objp->nature == 1) $nature="sells"; + if ($objp->nature == 2) $nature="purchases"; + if ($objp->nature == 3) $nature="bank"; + if ($objp->nature == 4) $nature="various"; + if ($objp->nature == 9) $nature="hasnew"; + + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&code_journal='.$objp->code,dol_trunc($objp->label,25),2,$user->rights->accounting->comptarapport->lire); + $i++; + } + } + else + { + // Should not happend. Entries are added + $newmenu->add('',$langs->trans("NoJournalDefined"), 2, $user->rights->accounting->comptarapport->lire); } } else dol_print_error($db); @@ -1075,7 +1082,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu // Fiscal year if ($conf->global->MAIN_FEATURES_LEVEL > 0) // Not yet used. In a future will lock some periods. { - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("FiscalPeriod"),1,$user->rights->accounting->fiscalyear, '', $mainmenu, 'fiscalyear'); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_periods", $langs->trans("FiscalPeriod"),1,$user->rights->accounting->fiscalyear, '', $mainmenu, 'fiscalyear'); } } diff --git a/htdocs/don/list.php b/htdocs/don/list.php index d925573b859..1e08cbae121 100644 --- a/htdocs/don/list.php +++ b/htdocs/don/list.php @@ -160,23 +160,8 @@ if ($resql) print '
    '; print ''."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"d.rowid","", $param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"d.societe","", $param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Name"),$_SERVER["PHP_SELF"],"d.lastname","", $param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"d.datedon","", $param,'align="center"',$sortfield,$sortorder); - if (! empty($conf->projet->enabled)) - { - $langs->load("projects"); - print_liste_field_titre($langs->trans("Project"),$_SERVER["PHP_SELF"],"fk_projet","", $param,"",$sortfield,$sortorder); - } - print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"d.amount","", $param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"d.fk_statut","", $param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre(''); - print "\n"; - // Filters lines - print ''; + print ''; print ''; @@ -203,12 +188,26 @@ if ($resql) print ''; print "\n"; - $var=True; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"d.rowid","", $param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"d.societe","", $param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Name"),$_SERVER["PHP_SELF"],"d.lastname","", $param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"d.datedon","", $param,'align="center"',$sortfield,$sortorder); + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + print_liste_field_titre($langs->trans("Project"),$_SERVER["PHP_SELF"],"fk_projet","", $param,"",$sortfield,$sortorder); + } + print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"d.amount","", $param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"d.fk_statut","", $param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + while ($i < min($num,$limit)) { $objp = $db->fetch_object($resql); - $var=!$var; - print ""; + + print ''; $donationstatic->id=$objp->rowid; $donationstatic->ref=$objp->rowid; $donationstatic->lastname=$objp->lastname; diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index 8d55404659e..952d1e13dbd 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -700,20 +700,8 @@ if (empty($action)) print '
    '; print '
    '; print ''; print '
    '."\n"; - print ''; - print_liste_field_titre($langs->trans('RefPayment'),$_SERVER["PHP_SELF"],'p.rowid','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Date'),$_SERVER["PHP_SELF"],'dp','',$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('ThirdParty'),$_SERVER["PHP_SELF"],'s.nom','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Type'),$_SERVER["PHP_SELF"],'c.libelle','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Numero"),$_SERVER["PHP_SELF"],"p.num_paiement","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Account'),$_SERVER["PHP_SELF"],'ba.label','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Amount'),$_SERVER["PHP_SELF"],'p.amount','',$param,'align="right"',$sortfield,$sortorder); - //print_liste_field_titre($langs->trans('Invoice'),$_SERVER["PHP_SELF"],'ref_supplier','',$param,'',$sortfield,$sortorder); - print_liste_field_titre(''); - print "\n"; - // Lines for filters fields - print ''; + print ''; print ''; @@ -739,11 +727,23 @@ if (empty($action)) print ''; print "\n"; + print ''; + print_liste_field_titre($langs->trans('RefPayment'),$_SERVER["PHP_SELF"],'p.rowid','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Date'),$_SERVER["PHP_SELF"],'dp','',$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('ThirdParty'),$_SERVER["PHP_SELF"],'s.nom','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Type'),$_SERVER["PHP_SELF"],'c.libelle','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Numero"),$_SERVER["PHP_SELF"],"p.num_paiement","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Account'),$_SERVER["PHP_SELF"],'ba.label','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Amount'),$_SERVER["PHP_SELF"],'p.amount','',$param,'align="right"',$sortfield,$sortorder); + //print_liste_field_titre($langs->trans('Invoice'),$_SERVER["PHP_SELF"],'ref_supplier','',$param,'',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + while ($i < min($num,$limit)) { $objp = $db->fetch_object($resql); $var=!$var; - print ''; + print ''; // Ref payment print ''; diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 4b1384aeedb..e063734cc51 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -98,13 +98,30 @@ if (empty($reshook)) $datestart = dol_mktime(12, 0, 0, GETPOST('startmonth','int'), GETPOST('startday','int'), GETPOST('startyear','int')); $dateend = dol_mktime(12, 0, 0, GETPOST('endmonth','int'), GETPOST('endday','int'), GETPOST('endyear','int')); $capital = price2num(GETPOST('capital')); - + $rate = GETPOST('rate'); + if (! $capital) { + $error++; $action = 'create'; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("LoanCapital")), null, 'errors'); - $action = 'create'; } - else + if (! $datestart) + { + $error++; $action = 'create'; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateStart")), null, 'errors'); + } + if (! $dateend) + { + $error++; $action = 'create'; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateEnd")), null, 'errors'); + } + if ($rate == '') + { + $error++; $action = 'create'; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Rate")), null, 'errors'); + } + + if (! $error) { $object->label = GETPOST('label'); $object->fk_bank = GETPOST('accountid'); @@ -112,7 +129,7 @@ if (empty($reshook)) $object->datestart = $datestart; $object->dateend = $dateend; $object->nbterm = GETPOST('nbterm'); - $object->rate = GETPOST('rate'); + $object->rate = $rate; $object->note_private = GETPOST('note_private'); $object->note_public = GETPOST('note_public'); $object->fk_project = GETPOST('fk_project'); @@ -128,7 +145,9 @@ if (empty($reshook)) $id=$object->create($user); if ($id <= 0) { + $error++; setEventMessages($object->error, $object->errors, 'errors'); + $action = 'create'; } } } @@ -263,21 +282,21 @@ if ($action == 'create') // Date Start print ""; - print ''; // Date End print ""; - print ''; // Number of terms - print ''; + print ''; // Rate - print ''; + print ''; // Project if (! empty($conf->projet->enabled)) @@ -296,8 +315,8 @@ if ($action == 'create') // Note Private print ''; - print ''; - print ''; + print ''; - print ''; - print ''; + print ''; @@ -463,7 +482,7 @@ if ($id > 0) } // Date start - print ""; + print '"; print ""; // Date end - print ""; + print '"; print "'; print ''; }*/ - if ($user->admin) + + /*if ($user->admin) { $var = ! $var; print ''; - } + }*/ print '
    '; print ''; print '
    '.img_object($langs->trans('ShowPayment'),'payment').' '.$objp->pid.'
    '.$langs->trans("DateStart").''; + print ''.$langs->trans("DateStart").''; print $form->select_date($datestart?$datestart:-1,'start','','','','add',1,1,1); print '
    '.$langs->trans("DateEnd").''; + print ''.$langs->trans("DateEnd").''; print $form->select_date($dateend?$dateend:-1,'end','','','','add',1,1,1); print '
    '.$langs->trans("Nbterms").'
    '.$langs->trans("Nbterms").'
    '.$langs->trans("Rate").' %
    '.$langs->trans("Rate").' %
    '.$langs->trans('NotePrivate').''; + print ''.$langs->trans('NotePrivate').''; $doleditor = new DolEditor('note_private', GETPOST('note_private', 'alpha'), '', 160, 'dolibarr_notes', 'In', false, true, true, ROWS_6, '90%'); print $doleditor->Create(1); @@ -306,8 +325,8 @@ if ($action == 'create') // Note Public print '
    '.$langs->trans('NotePublic').''; + print ''.$langs->trans('NotePublic').''; $doleditor = new DolEditor('note_public', GETPOST('note_public', 'alpha'), '', 160, 'dolibarr_notes', 'In', false, true, true, ROWS_6, '90%'); print $doleditor->Create(1); print '
    ".$langs->trans("DateStart")."
    '.$langs->trans("DateStart").""; if ($action == 'edit') { @@ -476,7 +495,7 @@ if ($id > 0) print "
    ".$langs->trans("DateEnd")."
    '.$langs->trans("DateEnd").""; if ($action == 'edit') { diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php index bb51cf3b8f1..d9d4da6fb20 100644 --- a/htdocs/loan/class/loan.class.php +++ b/htdocs/loan/class/loan.class.php @@ -129,7 +129,7 @@ class Loan extends CommonObject */ function create($user) { - global $conf; + global $conf, $langs; $error=0; @@ -155,7 +155,7 @@ class Loan extends CommonObject } if (($conf->accounting->enabled) && empty($this->account_capital) && empty($this->account_insurance) && empty($this->account_interest)) { - $this->error="ErrorAccountingParameter"; + $this->error=$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Accounting")); return -2; } diff --git a/htdocs/loan/document.php b/htdocs/loan/document.php index 575be293de0..3e0654ace3f 100644 --- a/htdocs/loan/document.php +++ b/htdocs/loan/document.php @@ -85,7 +85,7 @@ if ($object->id) $head = loan_prepare_head($object); - dol_fiche_head($head, 'documents', $langs->trans("Loan"), 0, 'bill'); + dol_fiche_head($head, 'documents', $langs->trans("Loan"), -1, 'bill'); $morehtmlref='
    '; // Ref loan diff --git a/htdocs/loan/index.php b/htdocs/loan/index.php index d2a60973a7f..fdc8cf67073 100644 --- a/htdocs/loan/index.php +++ b/htdocs/loan/index.php @@ -124,17 +124,8 @@ if ($resql) print '
    '; print ''."\n"; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"l.rowid","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"l.label","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("LoanCapital"),$_SERVER["PHP_SELF"],"l.capital","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateStart"),$_SERVER["PHP_SELF"],"l.datestart","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"l.paid","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre(''); - print "\n"; - // Filters lines - print ''; + print ''; print ''; print ''; print ''; @@ -146,6 +137,15 @@ if ($resql) print ''; print ''; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"l.rowid","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"l.label","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("LoanCapital"),$_SERVER["PHP_SELF"],"l.capital","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateStart"),$_SERVER["PHP_SELF"],"l.datestart","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"l.paid","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + while ($i < min($num,$limit)) { $obj = $db->fetch_object($resql); @@ -154,7 +154,7 @@ if ($resql) $loan_static->label = $obj->label; $var = !$var; - print ""; + print ''; // Ref print ''; diff --git a/htdocs/loan/info.php b/htdocs/loan/info.php index 87bd25fbe3b..f61b9312432 100644 --- a/htdocs/loan/info.php +++ b/htdocs/loan/info.php @@ -53,7 +53,7 @@ $object->info($id); $head = loan_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans("Loan"), 0, 'bill'); +dol_fiche_head($head, 'info', $langs->trans("Loan"), -1, 'bill'); $morehtmlref='
    '; // Ref loan diff --git a/htdocs/loan/note.php b/htdocs/loan/note.php index b03880a832e..e28320470a2 100644 --- a/htdocs/loan/note.php +++ b/htdocs/loan/note.php @@ -70,7 +70,7 @@ if ($id > 0) $head = loan_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans("Loan"), 0, 'bill'); + dol_fiche_head($head, 'note', $langs->trans("Loan"), -1, 'bill'); $morehtmlref='
    '; // Ref loan diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 913bcac5f30..e270cc3b030 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -590,7 +590,8 @@ div.myavailability { .checkallactions { vertical-align: text-bottom; margin-top: 6px; - margin-left: 4px; + margin-left: 4px; /* left must be same than right to keep checkbox centered */ + margin-right: 4px; /* left must be same than right to keep checkbox centered */ } .selectlimit, .marginrightonly { margin-right: 10px !important; @@ -1736,7 +1737,7 @@ div.vmenu, td.vmenu { } #menu_contenu_logo { padding-top: 0; } .companylogo { } -.searchform { padding-top: 4px; } +.searchform { padding-top: 10px; } a.vmenu:link, a.vmenu:visited, a.vmenu:hover, a.vmenu:active { white-space: nowrap; font-size:px; font-family: ; text-align: ; font-weight: bold; } font.vmenudisabled { font-size:px; font-family: ; text-align: ; font-weight: bold; color: #aaa; margin-left: 4px; } @@ -2434,18 +2435,7 @@ div.pagination li span:focus { -moz-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); -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); - /* - color: #000; - background-color: #eee; - border-color: #ccc; - - background-image: -moz-linear-gradient(top, #eee, #ddd); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#eee), to(#ddd)); - background-image: -webkit-linear-gradient(top, #eee, #ddd); - background-image: -o-linear-gradient(top, #eee, #ddd); - background-image: linear-gradient(to bottom, #eee, #ddd); - background-repeat: repeat-x; -*/ + padding-top: 8px; } div.pagination li .active a, div.pagination li .active span, @@ -2622,7 +2612,7 @@ tr.liste_titre_topborder td { .liste_titre td a.notasortlink:hover { background: transparent; } -tr.liste_titre:last-child th.liste_titre, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ +tr.liste_titre:last-child th.liste_titre, tr.liste_titre:last-child th.liste_titre_sel, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ border-bottom: 1px solid #ddd; } @@ -4316,6 +4306,7 @@ ul.ulmenu { } .alilevel0 { color: rgb() !important; + background: #f8f8f8 } .ulmenu { box-shadow: none !important; @@ -4339,24 +4330,9 @@ ul.ulmenu { color: # !important; text-shadow: none !important; } -/* -.ui-btn-up-c { - background: transparent; -} -*/ div.tabsElem a.tab { background: transparent; } - -/*.ui-controlgroup-horizontal .ui-btn.ui-first-child { --webkit-border-top-left-radius: 6px; -border-top-left-radius: 6px; -} -.ui-controlgroup-horizontal .ui-btn.ui-last-child { --webkit-border-top-right-radius: 6px; -border-top-right-radius: 6px; -}*/ - .alilevel1 { color: rgb() !important; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 947b8a57168..6885bfad144 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1768,7 +1768,7 @@ div.vmenu, td.vmenu { } #menu_contenu_logo { padding-right: 4px; } .companylogo { padding-top: 4px; } -.searchform { padding-top: 8px; } +.searchform { padding-top: 10px; } a.vmenu:link, a.vmenu:visited, a.vmenu:hover, a.vmenu:active { white-space: nowrap; font-size:px; font-family: ; text-align: ; font-weight: bold; } font.vmenudisabled { font-size:px; font-family: ; text-align: ; font-weight: bold; color: #aaa; margin-left: 4px; } @@ -2447,6 +2447,7 @@ div.pagination li { div.pagination li.pagination a, div.pagination li.pagination span { padding: 6px 12px; + padding-top: 8px; line-height: 1.42857143; color: #000; text-decoration: none; @@ -2486,9 +2487,10 @@ div.pagination li a:hover, div.pagination li span:hover, div.pagination li a:focus, div.pagination li span:focus { - color: #000; - background-color: #eee; - border-color: #ddd; + color: #000; + background-color: #eee; + border-color: #ddd; + padding-top: 8px; } div.pagination li .active a, div.pagination li .active span, @@ -2700,7 +2702,7 @@ tr.liste_titre_topborder td { .liste_titre td a.notasortlink:hover { background: transparent; } -tr.liste_titre:last-child th.liste_titre, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ +tr.liste_titre:last-child th.liste_titre, tr.liste_titre:last-child th.liste_titre_sel, tr.liste_titre td.liste_titre, tr.liste_titre td.liste_titre_sel, form.liste_titre div.tagtd { /* For last line of table headers only */ border-bottom: 1px solid rgb(); } From 17a1874e36810047f0ab66d9e3ea9b89f81e823f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 13:43:05 +0200 Subject: [PATCH 063/233] FIX Counter of notification of a thirdparty --- htdocs/core/class/notify.class.php | 80 ++++++++++++++++-------------- htdocs/societe/notify/card.php | 16 ++++-- 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index fd3b1e7187d..1205f0c5c63 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -117,9 +117,10 @@ class Notify * @param int $socid Id of third party or 0 for all thirdparties or -1 for no thirdparties * @param Object $object Object the notification is about (need it to check threshold value of some notifications) * @param int $userid Id of user or 0 for all users or -1 for no users + * @param array $scope Scope where to search * @return array|int <0 if KO, array of notifications to send if OK */ - function getNotificationsArray($notifcode,$socid=0,$object=null,$userid=0) + function getNotificationsArray($notifcode, $socid=0, $object=null, $userid=0, $scope=array('thirdparty', 'user', 'global')) { global $conf, $user; @@ -131,7 +132,7 @@ class Notify if (! $error) { - if ($socid >= 0) + if ($socid >= 0 && in_array('thirdparty', $scope)) { $sql = "SELECT a.code, c.email, c.rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,"; @@ -178,7 +179,7 @@ class Notify if (! $error) { - if ($userid >= 0) + if ($userid >= 0 && in_array('user', $scope)) { $sql = "SELECT a.code, c.email, c.rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,"; @@ -223,42 +224,45 @@ class Notify if (! $error) { - // List of notifications enabled for fixed email - foreach($conf->global as $key => $val) + if (in_array('global', $scope)) { - if ($notifcode) - { - if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; - } - else - { - if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_.*_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; - } - - $threshold = (float) $reg[1]; - if ($valueforthreshold < $threshold) continue; - - $tmpemail=explode(',',$val); - foreach($tmpemail as $key2 => $val2) - { - $newval2=trim($val2); - if ($newval2 == '__SUPERVISOREMAIL__') - { - if ($user->fk_user > 0) - { - $tmpuser=new User($this->db); - $tmpuser->fetch($user->fk_user); - if ($tmpuser->email) $newval2=trim($tmpuser->email); - else $newval2=''; - } - else $newval2=''; - } - if ($newval2) - { - $isvalid=isValidEmail($newval2, 0); - if (empty($resarray[$newval2])) $resarray[$newval2]=array('type'=> 'tofixedemail', 'code'=>trim($key), 'emaildesc'=>trim($val2), 'email'=>$newval2, 'isemailvalid'=>$isvalid); - } - } + // List of notifications enabled for fixed email + foreach($conf->global as $key => $val) + { + if ($notifcode) + { + if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; + } + else + { + if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_.*_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; + } + + $threshold = (float) $reg[1]; + if ($valueforthreshold < $threshold) continue; + + $tmpemail=explode(',',$val); + foreach($tmpemail as $key2 => $val2) + { + $newval2=trim($val2); + if ($newval2 == '__SUPERVISOREMAIL__') + { + if ($user->fk_user > 0) + { + $tmpuser=new User($this->db); + $tmpuser->fetch($user->fk_user); + if ($tmpuser->email) $newval2=trim($tmpuser->email); + else $newval2=''; + } + else $newval2=''; + } + if ($newval2) + { + $isvalid=isValidEmail($newval2, 0); + if (empty($resarray[$newval2])) $resarray[$newval2]=array('type'=> 'tofixedemail', 'code'=>trim($key), 'emaildesc'=>trim($val2), 'email'=>$newval2, 'isemailvalid'=>$isvalid); + } + } + } } } diff --git a/htdocs/societe/notify/card.php b/htdocs/societe/notify/card.php index 63d33dcee1d..d7445233c71 100644 --- a/htdocs/societe/notify/card.php +++ b/htdocs/societe/notify/card.php @@ -188,11 +188,16 @@ if ($result > 0) print '
    '; } - print ''; + print ''; // Notification for this thirdparty print ''; print '
    '.$loan_static->getNomUrl(1, 42).'
    '.$langs->trans("NbOfActiveNotifications").'
    '.$langs->trans("NbOfActiveNotifications").''; + $nbofrecipientemails=0; $notify=new Notify($db); - $tmparray = $notify->getNotificationsArray('', $object->id); - print count($tmparray); + $tmparray = $notify->getNotificationsArray('', $object->id, null, 0, array('thirdparty')); + foreach($tmparray as $tmpkey => $tmpval) + { + if (! empty($tmpkey)) $nbofrecipientemails++; + } + print $nbofrecipientemails; print '
    '; @@ -394,13 +399,14 @@ if ($result > 0) print '
    '.$langs->trans("SeeModuleSetup", $langs->transnoentitiesnoconv("Module600Name")).'
    '; print '+ '.$langs->trans("SeeModuleSetup", $langs->transnoentitiesnoconv("Module600Name")).''; print '
    '; From ed898528071881d29380715d9903dd19e3da3fa9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Apr 2017 13:49:17 +0200 Subject: [PATCH 064/233] Work on look and feel v6 --- htdocs/user/document.php | 6 ++++-- htdocs/user/info.php | 2 +- htdocs/user/note.php | 4 +++- htdocs/user/notify/card.php | 30 +++--------------------------- 4 files changed, 11 insertions(+), 31 deletions(-) diff --git a/htdocs/user/document.php b/htdocs/user/document.php index 081bf2bc408..5b86c7d490d 100644 --- a/htdocs/user/document.php +++ b/htdocs/user/document.php @@ -129,12 +129,13 @@ if ($object->id) $form=new Form($db); - dol_fiche_head($head, 'document', $langs->trans("User"),0,'user'); + dol_fiche_head($head, 'document', $langs->trans("User"), -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin); + print '
    '; print '
    '; // Construit liste des fichiers @@ -158,7 +159,8 @@ if ($object->id) print '
    '.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
    '; - + print '
    '; + dol_fiche_end(); diff --git a/htdocs/user/info.php b/htdocs/user/info.php index 5ea7200a0f7..ff4c44c6e23 100644 --- a/htdocs/user/info.php +++ b/htdocs/user/info.php @@ -65,7 +65,7 @@ llxHeader(); $head = user_prepare_head($object); $title = $langs->trans("User"); -dol_fiche_head($head, 'info', $title, 0, 'user'); +dol_fiche_head($head, 'info', $title, -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/user/note.php b/htdocs/user/note.php index 38aef489b87..3f9be2b4142 100644 --- a/htdocs/user/note.php +++ b/htdocs/user/note.php @@ -88,7 +88,7 @@ if ($id) $head = user_prepare_head($object); $title = $langs->trans("User"); - dol_fiche_head($head, 'note', $title, 0, 'user'); + dol_fiche_head($head, 'note', $title, -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; @@ -99,6 +99,7 @@ if ($id) print "
    "; print ''; + print '
    '; print ''; // Login @@ -123,6 +124,7 @@ if ($id) print ""; print "
    "; + print '
    '; dol_fiche_end(); diff --git a/htdocs/user/notify/card.php b/htdocs/user/notify/card.php index 4e84a8b83fa..305bb3d226b 100644 --- a/htdocs/user/notify/card.php +++ b/htdocs/user/notify/card.php @@ -135,36 +135,12 @@ if ($result > 0) $head = user_prepare_head($object); - dol_fiche_head($head, 'notify', $langs->trans("User"),0,'user'); + dol_fiche_head($head, 'notify', $langs->trans("User"), 0, 'user'); $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); - - /*print ''; - - // Ref - print ''; - print ''; - print ''."\n"; - - print ''; - print ''; - - // Firstname - print ''; - print ''; - print ''."\n"; - - // EMail - print ''; - print ''; - print "\n"; - - print '
    '.$langs->trans("Ref").''; - print $form->showrefnav($object,'id','',$user->rights->user->user->lire || $user->admin); - print '
    '.$langs->trans("Lastname").''.$object->lastname.'
    '.$langs->trans("Firstname").''.$object->firstname.'
    '.$langs->trans("EMail").''.dol_print_email($object->email,0,0,1).'
    ';*/ - + dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', '', '', 0, '', '', 1, ''); + dol_fiche_end(); print "\n"; From 4d7b059eb33ecf74c8443f125d735c2df8c8767a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Apr 2017 18:50:34 +0200 Subject: [PATCH 065/233] Release 4.0.5 --- ChangeLog | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/ChangeLog b/ChangeLog index cc6f1364f17..5fe3c741499 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,42 @@ Upgrading to any other version or any other database system is abolutely require make a Dolibarr upgrade. +***** ChangeLog for 4.0.5 to 4.0.4 ***** +FIX: #6234 +FIX: #6259 +FIX: #6330 +FIX: #6360 +FIX: #6411 +FIX: #6443 +FIX: #6444 +FIX: #6453 +FIX: #6503: SQL error in "Last pending payment invoices" +FIX: #6505 Project elements page shows greyed-out links even if the option to show actions not available is disabled +FIX: #6507: Statistics counter show wrong total Contract numbers when the user does not have full access +FIX: #6533 #6590 +FIX: #6619 Template invoices list do not respect restricted thirdparty user rights +FIX: #6621 Documents tab shows greyed out upload form even if the option to show actions not available is disabled +FIX: add entity param to document link +FIX: Can use quote into supplier ref on order line add +FIX: Change the customer code only if error on duplicate +FIX: Creation of credit note on invoice with deposit stole the discount. +FIX: delete bank class lines when we delete bank_categ +FIX: deletion of bank tag +FIX: detail of deposit and credit not was not visible into final invoice +FIX: Error management during bank account creation +FIX: error management in bank account deletion. +FIX: event status is not modified when assign an user +FIX: forgotten fk_facture_fourn attribute on supplierinvoice line object +FIX: If bank module on, field must be required to register payment of expense report. +FIX: load multicurrency informations on supplier order and bill lines fetch +FIX: Missing total on project overview. +FIX: multicurrency_subprice +FIX: param billed when we change page +FIX: protection against infinite loop on hierarchy +FIX: Supplier Order list filter by project +FIX: the dolCopyDir fails if target dir does not exists. +FIX: use param for http links + ***** ChangeLog for 4.0.4 to 4.0.3 ***** FIX: #6227 Document models table header "Unit" is shown in 2 lines in Spanish FIX: #6230 From 4902df7e3faf7d9ceb1018cecb28cef799129383 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Apr 2017 19:28:38 +0200 Subject: [PATCH 066/233] Work on look and feel v6 --- htdocs/langs/en_US/mails.lang | 4 +- htdocs/societe/agenda.php | 4 +- htdocs/societe/list.php | 2 +- htdocs/societe/notify/card.php | 62 +++++++++++++++-------- htdocs/user/card.php | 6 +-- htdocs/user/notify/card.php | 91 +++++++++++++++++++++++++++------- 6 files changed, 121 insertions(+), 48 deletions(-) diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index 93c3e584ff6..e546965d60d 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -116,8 +116,8 @@ Notifications=Notifications NoNotificationsWillBeSent=No email notifications are planned for this event and company ANotificationsWillBeSent=1 notification will be sent by email SomeNotificationsWillBeSent=%s notifications will be sent by email -AddNewNotification=Activate a new email notification target -ListOfActiveNotifications=List all active targets for email notification +AddNewNotification=Activate a new email notification target/event +ListOfActiveNotifications=List all active targets/events for email notification 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 '%s' 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. diff --git a/htdocs/societe/agenda.php b/htdocs/societe/agenda.php index 36fbe790bf3..e1dc1c12671 100644 --- a/htdocs/societe/agenda.php +++ b/htdocs/societe/agenda.php @@ -58,7 +58,7 @@ if ($page == -1) { $page = 0; } $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -if (! $sortfield) $sortfield='a.datep, a.id'; +if (! $sortfield) $sortfield='a.datep,a.id'; if (! $sortorder) $sortorder='DESC'; // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array @@ -190,7 +190,7 @@ if ($socid > 0) $filters=array(); $filters['search_agenda_label']=$search_agenda_label; - // TODO Replace this with smae code then into listactions.php + // TODO Replace this with same code than into listactions.php show_actions_done($conf,$langs,$db,$object,null,0,$actioncode, '', $filters, $sortfield, $sortorder); } } diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 1a9980bbf12..9bde47887ed 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -88,7 +88,7 @@ $sortorder=GETPOST("sortorder",'alpha'); $page=GETPOST("page",'int'); if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="s.nom"; -if (empty($page) || $page == -1) { $page = 0 ; } +if (empty($page) || $page == -1) { $page = 0; } $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/societe/notify/card.php b/htdocs/societe/notify/card.php index d7445233c71..8b77c8f52a4 100644 --- a/htdocs/societe/notify/card.php +++ b/htdocs/societe/notify/card.php @@ -44,15 +44,16 @@ $actionid=GETPOST('actionid'); if ($user->societe_id) $socid=$user->societe_id; $result = restrictedArea($user, 'societe','',''); -$sortfield = GETPOST("sortfield",'alpha'); -$sortorder = GETPOST("sortorder",'alpha'); -$page = GETPOST("page",'int'); -if ($page == -1) { $page = 0; } -$offset = $conf->liste_limit * $page; -$pageprev = $page - 1; -$pagenext = $page + 1; +$limit = GETPOST("limit")?GETPOST("limit","int"):$conf->liste_limit; +$sortfield=GETPOST("sortfield",'alpha'); +$sortorder=GETPOST("sortorder",'alpha'); +$page=GETPOST("page",'int'); if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="n.daten"; +if (empty($page) || $page == -1) { $page = 0; } +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; $now=dol_now(); @@ -188,7 +189,7 @@ if ($result > 0) print '
    '.$langs->trans("NbOfActiveNotifications").'
    '.$langs->trans("NbOfActiveNotifications").''; $nbofrecipientemails=0; $notify=new Notify($db); @@ -198,7 +199,8 @@ if ($result > 0) if (! empty($tmpkey)) $nbofrecipientemails++; } print $nbofrecipientemails; - print '
    '; print ''; @@ -286,7 +288,7 @@ if ($result > 0) $sql.= " WHERE a.rowid = n.fk_action"; $sql.= " AND c.rowid = n.fk_contact"; $sql.= " AND c.fk_soc = ".$object->id; - + $resql=$db->query($sql); if ($resql) { @@ -299,8 +301,7 @@ if ($result > 0) // List of active notifications print load_fiche_titre($langs->trans("ListOfActiveNotifications").' ('.$num.')','',''); - $var=true; - + // Line with titles print ''; print ''; @@ -321,14 +322,12 @@ if ($result > 0) while ($i < $num) { - $var = !$var; - $obj = $db->fetch_object($resql); $contactstatic->id=$obj->contactid; $contactstatic->lastname=$obj->lastname; $contactstatic->firstname=$obj->firstname; - print ''; print ''; print ''; From 00d485b2c5eff2416d621bb3ebf4c4791f0f5f14 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Apr 2017 22:09:06 +0200 Subject: [PATCH 068/233] Start 4.0.6 --- htdocs/filefunc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index c0f95fe76f7..d2ca04278ff 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','4.0.5'); +if (! defined('DOL_VERSION')) define('DOL_VERSION','4.0.6'); if (! defined('EURO')) define('EURO',chr(128)); From da3fdbc9f0fe9dfdc3439ca93dba9f522df0d266 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Apr 2017 22:18:41 +0200 Subject: [PATCH 069/233] Prepare 5.0.1 --- ChangeLog | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d8387c6a0e3..2b3e6e9d026 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,8 +2,28 @@ English Dolibarr ChangeLog -------------------------------------------------------------- - - +***** ChangeLog for 5.0.1 compared to 5.0.0 ***** +FIX: #6503: SQL error in "Last pending payment invoices" +FIX: #6505 Project elements page shows greyed-out links even if the option to show actions not available is disabled +FIX: #6507: Statistics counter show wrong total Contract numbers when the user does not have full access +FIX: #6533 #6590 +FIX: #6535 +FIX: bank account not visible on payment card +FIX: colspan +FIX: Data lost during merge of thirdparties +FIX: Detection of color brightness +FIX: Filter on date lost after submit on time spent page +FIX: forgottent fk_unit field on llx_supplier_propaldet +FIX: list of projects +FIX: LOG_ERROR does not exists. Use LOG_ERR. +FIX: Missing total on project overview. +FIX: multicurrency management on supplier order/invoice +FIX: Notification sending was broken. +FIX: origin & origin id on supplier order line +FIX: param php doc +FIX: Picto of project on dol_banner and box +FIX: Some errors when downloading files. + ***** ChangeLog for 5.0.0 compared to 4.0.* ***** For users: NEW: Add module mulicurrency. From a5a09953138373dbf991e4fa8c5b9cc1be5a0349 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 10:11:29 +0200 Subject: [PATCH 070/233] More comments --- htdocs/core/class/extrafields.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 1211c334617..673f069d1b3 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -112,7 +112,7 @@ class ExtraFields * * @param string $attrname Code of attribute * @param string $label label of attribute - * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') + * @param int $type Type of attribute ('boolean', 'int', 'text', 'varchar', 'date', 'datehour','price','phone','mail','password','url','select','checkbox', ...) * @param int $pos Position of attribute * @param string $size Size/length of attribute * @param string $elementtype Element type ('member', 'product', 'thirdparty', ...) @@ -164,7 +164,7 @@ class ExtraFields * This is a private method. For public method, use addExtraField. * * @param string $attrname code of attribute - * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') + * @param int $type Type of attribute ('boolean', 'int', 'text', 'varchar', 'date', 'datehour','price','phone','mail','password','url','select','checkbox', ...) * @param string $length Size/length of attribute ('5', '24,8', ...) * @param string $elementtype Element type ('member', 'product', 'thirdparty', 'contact', ...) * @param int $unique Is field unique or not From 9678c2128ec8de77de62766b65af14d255e04c80 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 10:29:20 +0200 Subject: [PATCH 071/233] Add field langs into extrafields definition table --- htdocs/install/mysql/migration/5.0.0-6.0.0.sql | 1 + htdocs/install/mysql/tables/llx_extrafields.sql | 1 + 2 files changed, 2 insertions(+) diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 3a2359fccb4..78f378e8c1a 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -24,6 +24,7 @@ -- -- VPGSQL8.2 DELETE FROM llx_usergroup_user WHERE fk_user NOT IN (SELECT rowid from llx_user); -- -- VMYSQL4.1 DELETE FROM llx_usergroup_user WHERE fk_usergroup NOT IN (SELECT rowid from llx_usergroup); +ALTER TABLE llx_extrafields ADD COLUMN langs varchar(24); ALTER TABLE llx_supplier_proposaldet ADD COLUMN fk_unit integer DEFAULT NULL; diff --git a/htdocs/install/mysql/tables/llx_extrafields.sql b/htdocs/install/mysql/tables/llx_extrafields.sql index b7a7288980b..2cc144db092 100644 --- a/htdocs/install/mysql/tables/llx_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_extrafields.sql @@ -34,5 +34,6 @@ 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 integer DEFAULT 0, -- list of values for field that are combo lists + langs varchar(24), -- example: fileofmymodule@mymodule ishidden integer DEFAULT 0 -- ??? example of use case ??? )ENGINE=innodb; From 6a69f9349b8372771f4b70140705c4b4eb16a631 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 10:43:04 +0200 Subject: [PATCH 072/233] Fix too much logs in list --- htdocs/core/class/hookmanager.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index b860e083469..24ba86c7115 100644 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -126,7 +126,7 @@ class HookManager if (! is_array($this->hooks) || empty($this->hooks)) return ''; $parameters['context']=join(':',$this->contextarray); - dol_syslog(get_class($this).'::executeHooks method='.$method." action=".$action." context=".$parameters['context']); + //dol_syslog(get_class($this).'::executeHooks method='.$method." action=".$action." context=".$parameters['context']); // Define type of hook ('output' or 'addreplace'. 'returnvalue' is deprecated because a 'addreplace' hook can also return resPrint and resArray). $hooktype='output'; @@ -200,6 +200,9 @@ class HookManager // test to avoid running twice a hook, when a module implements several active contexts if (in_array($module,$modulealreadyexecuted)) continue; + + dol_syslog(get_class($this).'::executeHooks a qualified hook was found for method='.$method.' module='.$module." action=".$action." context=".$context); + $modulealreadyexecuted[$module]=$module; // Use the $currentcontext in method to avoid running twice // Clean class (an error may have been set from a previous call of another method for same module/hook) From 13587fa13e6e32139bc3c350ef8373e6900b9cc2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 10:44:55 +0200 Subject: [PATCH 073/233] Fix key were not translated --- htdocs/core/class/html.form.class.php | 4 ++-- htdocs/societe/list.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 60ff30c6433..d432bf61d8a 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5176,7 +5176,7 @@ class Form */ static function multiSelectArrayWithCheckbox($htmlname, &$array, $varpage) { - global $conf,$user; + global $conf,$langs,$user; if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) return ''; @@ -5209,7 +5209,7 @@ class Form } if ($val['label']) { - $lis.='
  • '.dol_escape_htmltag($val['label']).'
  • '; + $lis.='
  • '.dol_escape_htmltag($langs->trans($val['label'])).'
  • '; $listcheckedstring.=(empty($val['checked'])?'':$key.','); } } diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 4a0be451c45..82b29865233 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -624,7 +624,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } From d99b0461c714afe791632cd36f22b4735d223162 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 10:47:25 +0200 Subject: [PATCH 074/233] Extrafields multilanguage support. --- dev/skeletons/skeleton_list.php | 2 +- htdocs/adherents/list.php | 2 +- htdocs/comm/propal/list.php | 2 +- htdocs/commande/list.php | 2 +- htdocs/compta/bank/bankentries.php | 2 +- htdocs/compta/bank/index.php | 2 +- htdocs/compta/facture/list.php | 2 +- htdocs/contact/list.php | 2 +- htdocs/contrat/list.php | 2 +- htdocs/contrat/services.php | 2 +- htdocs/core/lib/functions.lib.php | 6 +++--- htdocs/expedition/list.php | 2 +- htdocs/expensereport/list.php | 2 +- htdocs/fichinter/list.php | 2 +- htdocs/fourn/commande/list.php | 2 +- htdocs/fourn/facture/list.php | 2 +- htdocs/modulebuilder/skeletons/skeleton_list.php | 14 +++++++------- htdocs/product/list.php | 2 +- htdocs/product/stock/mouvement.php | 2 +- htdocs/product/stock/productlot_list.php | 2 +- htdocs/projet/list.php | 2 +- htdocs/projet/tasks/list.php | 2 +- htdocs/projet/tasks/time.php | 2 +- htdocs/resource/list.php | 2 +- htdocs/societe/list.php | 2 +- htdocs/user/index.php | 2 +- 26 files changed, 34 insertions(+), 34 deletions(-) diff --git a/dev/skeletons/skeleton_list.php b/dev/skeletons/skeleton_list.php index 77485c6d638..ca66990a9f7 100644 --- a/dev/skeletons/skeleton_list.php +++ b/dev/skeletons/skeleton_list.php @@ -354,7 +354,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 8d00194993b..e492e31b440 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -583,7 +583,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index fdcbdde5ca8..d1ccf6547ce 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -726,7 +726,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 37170e0af84..fa94541cdbf 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1021,7 +1021,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index c7596a0aee2..ca786c1e3e0 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -826,7 +826,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 71397f695d6..e67441036c4 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -403,7 +403,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index eafd8900d37..03612cbb932 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -939,7 +939,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index e7d4f603618..917c59006f2 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -631,7 +631,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 0224da7d88c..af68e789da2 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -534,7 +534,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/contrat/services.php b/htdocs/contrat/services.php index 42ff4b04e83..62b9fddf743 100644 --- a/htdocs/contrat/services.php +++ b/htdocs/contrat/services.php @@ -371,7 +371,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index e51541272bd..8c27b101fa4 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3106,7 +3106,7 @@ function print_liste_field_titre($name, $file="", $field="", $begin="", $morepar /** * Get title line of an array * - * @param string $name Label of field + * @param string $name Translation key of field * @param int $thead 0=To use with standard table format, 1=To use inside
    , 2=To use with
    * @param string $file Url used when we click on sort picto * @param string $field Field to use for new sorting. Empty if this field is not sortable. @@ -3120,7 +3120,7 @@ function print_liste_field_titre($name, $file="", $field="", $begin="", $morepar */ function getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="") { - global $conf; + global $conf, $langs; //print "$name, $file, $field, $begin, $options, $moreattrib, $sortfield, $sortorder
    \n"; $sortorder=strtoupper($sortorder); @@ -3154,7 +3154,7 @@ function getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $m } } - $out.=$name; + $out.=$langs->trans($name); if (empty($thead) && $field) // If this is a sort field { diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 4166bbb3791..29f6978b24e 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -446,7 +446,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index 8e2b46459b0..9339b33ee7f 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -363,7 +363,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 2ec1eb2af70..4a24f0d0c6d 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -356,7 +356,7 @@ if ($result) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index f8062cc70bc..be3cb384e96 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -672,7 +672,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index dbfc9d8fd3c..52320ec9580 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -677,7 +677,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/modulebuilder/skeletons/skeleton_list.php b/htdocs/modulebuilder/skeletons/skeleton_list.php index 77485c6d638..561dc98da35 100644 --- a/htdocs/modulebuilder/skeletons/skeleton_list.php +++ b/htdocs/modulebuilder/skeletons/skeleton_list.php @@ -109,12 +109,12 @@ if (empty($user->socid)) $fieldstosearchall["t.note_private"]="NotePrivate"; // Definition of fields for list $arrayfields=array( - 't.field1'=>array('label'=>$langs->trans("Field1"), 'checked'=>1), - 't.field2'=>array('label'=>$langs->trans("Field2"), 'checked'=>1), - //'t.entity'=>array('label'=>$langs->trans("Entity"), 'checked'=>1, 'enabled'=>(! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode))), - 't.datec'=>array('label'=>$langs->trans("DateCreationShort"), 'checked'=>0, 'position'=>500), - 't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), - //'t.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), + 't.field1'=>array('label'=>"Field1", 'checked'=>1), + 't.field2'=>array('label'=>"Field2", 'checked'=>1), + //'t.entity'=>array('label'=>"Entity", 'checked'=>1, 'enabled'=>(! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode))), + 't.datec'=>array('label'=>"DateCreationShort", 'checked'=>0, 'position'=>500), + 't.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500), + //'t.statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000), ); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) @@ -354,7 +354,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 69108a893d9..2e651398766 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -610,7 +610,7 @@ else if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php index a3742dcc00d..45ace2031cb 100644 --- a/htdocs/product/stock/mouvement.php +++ b/htdocs/product/stock/mouvement.php @@ -888,7 +888,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index 58bb6f6a3cb..ac6bc7b9948 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -422,7 +422,7 @@ if ($resql) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index c8335676700..790dde6e1aa 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -603,7 +603,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index a6a4c855474..13e15eb7eb6 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -575,7 +575,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 22293039c86..4b2b0b4c21e 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -731,7 +731,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } }*/ diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 5a3d5390bb0..2d93a0ab2df 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -248,7 +248,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 9bde47887ed..ae77ec3148c 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -875,7 +875,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } diff --git a/htdocs/user/index.php b/htdocs/user/index.php index 3e1da6a7431..312416afa29 100644 --- a/htdocs/user/index.php +++ b/htdocs/user/index.php @@ -447,7 +447,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab if (! empty($arrayfields["ef.".$key]['checked'])) { $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); } } } From 17bd393965fe961b4f33484e5ef587141c09f684 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 12:48:09 +0200 Subject: [PATCH 075/233] Fix typo --- build/debian/dolibarr.postinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/debian/dolibarr.postinst b/build/debian/dolibarr.postinst index 4b946fda433..6ee2a89931f 100644 --- a/build/debian/dolibarr.postinst +++ b/build/debian/dolibarr.postinst @@ -61,7 +61,7 @@ apache_install() { # Enable dolibarr conf if which a2enconf >/dev/null 2>&1 ;then # a2enconf exists for ubuntu only - echo "Enable link for Apache config file with a3enconf" + echo "Enable link for Apache config file with a2enconf" a2enconf dolibarr else if [ -d /etc/$webserver/conf.d ] && [ ! -e /etc/$webserver/conf.d/dolibarr.conf ]; then From 5b5380659e1be3b2512a99a897afce05edb221fa Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Mon, 3 Apr 2017 15:58:48 +0200 Subject: [PATCH 076/233] ERROR Categories Bank vs categories transactions PB since 4.0, present in 5.0 and develop version There is a confusion between the categorization function of bank accounts and the categorization function of the records. The categorization of the entries has been removed or it is not replaced by the categorization of the bank accounts. I propose for the moment to restore the old category of writings but to envisage the creation of a new type of category "bank records" (or if it is not necessary with the new account) to leave so --- htdocs/core/menus/standard/eldy.lib.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 748a4532cb5..eab8f5a8c19 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1071,10 +1071,11 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if (! empty($conf->categorie->enabled)) { $langs->load("categories"); - //$newmenu->add("/compta/bank/categ.php",$langs->trans("Rubriques"),1,$user->rights->banque->configurer); $newmenu->add("/categories/index.php?type=5",$langs->trans("Rubriques"),0,$user->rights->categorie->creer, '', $mainmenu, 'tags'); $newmenu->add("/categories/card.php?action=create&type=5",$langs->trans("NewCategory"),1,$user->rights->categorie->creer); - } + $newmenu->add("/compta/bank/categ.php",$langs->trans("RubriquesTransactions"),1,$user->rights->banque->configurer); + + } // Prelevements if (! empty($conf->prelevement->enabled)) From 761ece3125000fec1827c02d3b6b296bceecdc63 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2017 16:59:22 +0200 Subject: [PATCH 077/233] Remove $maxfilenamelength replace with auto overflow. --- htdocs/core/class/html.formfile.class.php | 24 +++++++++++------------ htdocs/theme/eldy/style.css.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 1dfb5a08855..258c2c9c962 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -229,7 +229,7 @@ class FormFile * @param integer $allowgenifempty Show warning if no model activated * @param integer $forcenomultilang Do not show language option (even if MAIN_MULTILANGS defined) * @param int $iconPDF Show only PDF icon with link (1/0) - * @param int $maxfilenamelength Max length for filename shown + * @param int $notused Not used * @param integer $noform Do not output html form tags * @param string $param More param on http links * @param string $title Title to show on top of form @@ -238,10 +238,10 @@ class FormFile * @return int <0 if KO, number of shown files if OK * @deprecated Use print xxx->showdocuments() instead. */ - function show_documents($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$maxfilenamelength=28,$noform=0,$param='',$title='',$buttonlabel='',$codelang='') + 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='') { $this->numoffiles=0; - print $this->showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed,$modelselected,$allowgenifempty,$forcenomultilang,$iconPDF,$maxfilenamelength,$noform,$param,$title,$buttonlabel,$codelang); + print $this->showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed,$modelselected,$allowgenifempty,$forcenomultilang,$iconPDF,$notused,$noform,$param,$title,$buttonlabel,$codelang); return $this->numoffiles; } @@ -259,7 +259,7 @@ class FormFile * @param integer $allowgenifempty Allow generation even if list of template ($genallowed) is empty (show however a warning) * @param integer $forcenomultilang Do not show language option (even if MAIN_MULTILANGS defined) * @param int $iconPDF Deprecated, see getDocumentsLink - * @param int $maxfilenamelength Max length for filename shown + * @param int $notused Not used * @param integer $noform Do not output html form tags * @param string $param More param on http links * @param string $title Title to show on top of form @@ -269,7 +269,7 @@ class FormFile * @param Object $object Object when method is called from an object card. * @return string Output string with HTML array of documents (might be empty string) */ - function showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$maxfilenamelength=28,$noform=0,$param='',$title='',$buttonlabel='',$codelang='',$morepicto='',$object=null) + function showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$notused=0,$noform=0,$param='',$title='',$buttonlabel='',$codelang='',$morepicto='',$object=null) { // Deprecation warning if (0 !== $iconPDF) { @@ -297,7 +297,6 @@ class FormFile $hookmanager->initHooks(array('formfile')); $forname='builddoc'; $out=''; - $var=true; $headershown=0; $showempty=0; @@ -691,27 +690,26 @@ class FormFile { foreach($file_list as $file) { - $var=!$var; - // Define relative path for download link (depends on module) $relativepath=$file["name"]; // Cas general if ($modulesubdir) $relativepath=$modulesubdir."/".$file["name"]; // Cas propal, facture... if ($modulepart == 'export') $relativepath = $file["name"]; // Other case - $out.= "
    "; + $out.= ''; $documenturl = DOL_URL_ROOT.'/document.php'; if (isset($conf->global->DOL_URL_ROOT_DOCUMENT_PHP)) $documenturl=$conf->global->DOL_URL_ROOT_DOCUMENT_PHP; // Show file name with link to download - $out.= ''; // Show file size diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index e270cc3b030..dac7cf43f5e 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1068,7 +1068,7 @@ div.nopadding { .pictowarning, .pictopreview { padding-: 3px; } -.pictoedit, .pictowarning, .pictopreview, .pictodelete { +.pictoedit, .pictowarning, .pictodelete { vertical-align: text-bottom; } .colorthumb { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 6885bfad144..f4b38d08012 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1112,7 +1112,7 @@ table.noborder tr.liste_titre td { .pictowarning, .pictopreview { padding-: 3px; } -.pictoedit, .pictowarning, .pictopreview, .pictodelete { +.pictoedit, .pictowarning, .pictodelete { vertical-align: text-bottom; } .colorthumb { From 422bdd1ef64b4416f4de41d47cf7426f4db58fd1 Mon Sep 17 00:00:00 2001 From: delcroix Patrick Date: Tue, 4 Apr 2017 09:06:29 +0200 Subject: [PATCH 078/233] FIX: Supplier is not the project customer --- htdocs/projet/element.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 1efc4465d81..ee2fc06c2b2 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -308,7 +308,7 @@ $listofreferent=array( 'margin'=>'minus', 'table'=>'facture_fourn', 'datefieldname'=>'datef', - 'urlnew'=>DOL_URL_ROOT.'/fourn/facture/card.php?action=create&projectid='.$id.'&socid='.$socid, + 'urlnew'=>DOL_URL_ROOT.'/fourn/facture/card.php?action=create&projectid='.$id, 'lang'=>'suppliers', 'buttonnew'=>'AddSupplierInvoice', 'testnew'=>$user->rights->fournisseur->facture->creer, From 9df4bac2028e6f5d90b41ddae74da13dbd6f7b12 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2017 11:56:19 +0200 Subject: [PATCH 079/233] NEW Bookmarks are into a combo list. --- htdocs/bookmarks/bookmarks.lib.php | 42 ++++++++++++++++++++--- htdocs/bookmarks/card.php | 10 ++++-- htdocs/bookmarks/list.php | 4 +-- htdocs/core/class/html.form.class.php | 2 +- htdocs/core/lib/ajax.lib.php | 3 +- htdocs/core/menus/standard/eldy.lib.php | 20 +++++------ htdocs/langs/en_US/bookmarks.lang | 4 ++- htdocs/theme/eldy/style.css.php | 44 ++++++++++++++++--------- htdocs/theme/md/style.css.php | 36 ++++++++++++++------ 9 files changed, 116 insertions(+), 49 deletions(-) diff --git a/htdocs/bookmarks/bookmarks.lib.php b/htdocs/bookmarks/bookmarks.lib.php index 3cee534e797..d84713d1e62 100644 --- a/htdocs/bookmarks/bookmarks.lib.php +++ b/htdocs/bookmarks/bookmarks.lib.php @@ -41,9 +41,12 @@ function printBookmarksList($aDb, $aLangs) $langs->load("bookmarks"); $url= $_SERVER["PHP_SELF"].(! empty($_SERVER["QUERY_STRING"])?'?'.$_SERVER["QUERY_STRING"]:''); - + // TODO Add post param to $url + $ret = ''; + // Menu bookmark + /* $ret.= '
    '.$contactstatic->getNomUrl(1); + print '
    '.$contactstatic->getNomUrl(1); if ($obj->type == 'email') { if (isValidEmail($obj->email)) @@ -425,6 +424,16 @@ if ($result > 0) $sql.= " AND n.fk_soc = ".$object->id; $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) { @@ -435,9 +444,20 @@ if ($result > 0) dol_print_error($db); } - // List of notifications done - print load_fiche_titre($langs->trans("ListOfNotificationsDone").' ('.$num.')','',''); - $var=true; + $param='&socid='.$object->id; + if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; + if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; + + print ''; + if ($optioncss != '') print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + // List of active notifications + print_barre_liste($langs->trans("ListOfNotificationsDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, '', 0, '', '', $limit); // Line with titles print ''; @@ -457,11 +477,9 @@ if ($result > 0) while ($i < $num) { - $var = !$var; - $obj = $db->fetch_object($resql); - print '
    '; + print '
    '; if ($obj->id > 0) { $contactstatic->id=$obj->id; @@ -501,6 +519,8 @@ if ($result > 0) } print '
    '; + + print ''; } else dol_print_error('','RecordNotFound'); diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 37a0042c137..e213578b860 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -723,11 +723,10 @@ if (($action == 'create') || ($action == 'adduserldap')) print dol_set_focus('#lastname'); - print ''; - - print ''; + print '
    '; // Lastname + print ''; print ''; print ''; print ''; }*/ - if ($user->admin) + /*if ($user->admin) { $var = ! $var; print ''; - } + }*/ print '
    '.$langs->trans("Lastname").''; if (! empty($ldap_lastname)) @@ -1257,7 +1256,6 @@ else dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin); - print '
    '; print '
    '; diff --git a/htdocs/user/notify/card.php b/htdocs/user/notify/card.php index 305bb3d226b..f18197dccc8 100644 --- a/htdocs/user/notify/card.php +++ b/htdocs/user/notify/card.php @@ -44,15 +44,16 @@ $actionid=GETPOST('actionid'); if ($user->societe_id) $id=$user->societe_id; $result = restrictedArea($user, 'societe','',''); -$sortfield = GETPOST("sortfield",'alpha'); -$sortorder = GETPOST("sortorder",'alpha'); -$page = GETPOST("page",'int'); -if ($page == -1) { $page = 0; } -$offset = $conf->liste_limit * $page; -$pageprev = $page - 1; -$pagenext = $page + 1; +$limit = GETPOST("limit")?GETPOST("limit","int"):$conf->liste_limit; +$sortfield=GETPOST("sortfield",'alpha'); +$sortorder=GETPOST("sortorder",'alpha'); +$page=GETPOST("page",'int'); if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="n.daten"; +if (empty($page) || $page == -1) { $page = 0; } +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; $now=dol_now(); @@ -135,12 +136,45 @@ if ($result > 0) $head = user_prepare_head($object); - dol_fiche_head($head, 'notify', $langs->trans("User"), 0, 'user'); + dol_fiche_head($head, 'notify', $langs->trans("User"), -1, 'user'); $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', '', '', 0, '', '', 1, ''); + dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', '', '', 0, '', '', 0, ''); + print '
    '; + + print '
    '; + print ''; + + // Login + print ''; + if (! empty($object->ldap_sid) && $object->statut==0) + { + print ''; + } + else + { + print ''; + } + print ''."\n"; + + /*print ''; // Notification for this thirdparty + print '';*/ + + print '
    '.$langs->trans("Login").''.$langs->trans("LoginAccountDisableInDolibarr").''.$object->login.'
    '.$langs->trans("NbOfActiveNotifications").''; + $nbofrecipientemails=0; + $notify=new Notify($db); + $tmparray = $notify->getNotificationsArray('', 0, null, $object->id, array('user')); + foreach($tmparray as $tmpkey => $tmpval) + { + $nbofrecipientemails++; + } + print $nbofrecipientemails; + print '
    '; + + print '
    '; + dol_fiche_end(); print "\n"; @@ -345,13 +379,13 @@ if ($result > 0) print '
    '.$langs->trans("SeeModuleSetup", $langs->transnoentitiesnoconv("Module600Name")).'
    '; print '+ '.$langs->trans("SeeModuleSetup", $langs->transnoentitiesnoconv("Module600Name")).''; print '
    '; @@ -364,12 +398,22 @@ if ($result > 0) $sql.= " c.rowid as id, c.lastname, c.firstname, c.email as contactemail,"; $sql.= " a.code, a.label"; $sql.= " FROM ".MAIN_DB_PREFIX."c_action_trigger as a,"; - $sql.= " ".MAIN_DB_PREFIX."notify as n "; + $sql.= " ".MAIN_DB_PREFIX."notify as n"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as c ON n.fk_user = c.rowid"; $sql.= " WHERE a.rowid = n.fk_action"; $sql.= " AND n.fk_user = ".$object->id; $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) { @@ -380,10 +424,21 @@ if ($result > 0) dol_print_error($db); } + $param='&id='.$object->id; + if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; + if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; + + print '
    '; + if ($optioncss != '') print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + // List of notifications done - print_fiche_titre($langs->trans("ListOfNotificationsDone").' ('.$num.')','',''); - $var=true; - + print_barre_liste($langs->trans("ListOfNotificationsDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, '', 0, '', '', $limit); + // Line with titles print ''; print ''; @@ -402,11 +457,9 @@ if ($result > 0) while ($i < $num) { - $var = !$var; - $obj = $db->fetch_object($resql); - print '
    '; + print '
    '; if ($obj->id > 0) { $userstatic->id=$obj->id; @@ -446,6 +499,8 @@ if ($result > 0) } print '
    '; + + print '
    '; } else dol_print_error('','RecordNotFound'); From a2da0dab7dcfa8992a5617336e9c431ea238e9a1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Apr 2017 21:42:16 +0200 Subject: [PATCH 067/233] FIX bank account not visible on payment card --- htdocs/compta/paiement/card.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php index 31b4ea8e993..8a58b842ab6 100644 --- a/htdocs/compta/paiement/card.php +++ b/htdocs/compta/paiement/card.php @@ -236,7 +236,7 @@ $disable_delete = 0; // Bank account if (! empty($conf->banque->enabled)) { - if ($object->bank_account) + if ($object->fk_account > 0) { $bankline=new AccountLine($db); $bankline->fetch($object->bank_line); @@ -257,9 +257,8 @@ if (! empty($conf->banque->enabled)) print '
    '.$langs->trans('BankAccount').''; $accountstatic=new Account($db); - $accountstatic->id=$bankline->fk_account; - $accountstatic->label=$bankline->bank_account_ref.' - '.$bankline->bank_account_label; - print $accountstatic->getNomUrl(0); + $accountstatic->fetch($bankline->fk_account); + print $accountstatic->getNomUrl(1); print '
    '; - $out.= 'showPreview($file,$modulepart,$relativepath); + $out.= ($tmp?$tmp.' ':''); + $out.= 'trans("File").': '.$file["name"]).' '.dol_trunc($file["name"],$maxfilenamelength); + $out.= img_mime($file["name"],$langs->trans("File").': '.$file["name"]).' '.$file["name"]; $out.= ''."\n"; - $out.= $this->showPreview($file,$modulepart,$relativepath); $out.= '
    '; $ret.= ''.$langs->trans('Bookmarks').''; @@ -56,9 +59,18 @@ function printBookmarksList($aDb, $aLangs) } $ret.= '
    '; $ret.= ''; - + */ $ret.= ''."\n"; + $ret.= '
    '; + $ret.= ''; + $ret.= '
    '; + + $ret.=ajax_combobox('boxbookmark'); + + $ret.=''; $ret .= ''; return $ret; diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index cf5a52cf9c6..a9d4a39ef85 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -157,15 +157,19 @@ if ($action == 'create') print ''; - print ''; - - print ''; + print ''; + dol_set_focus('#titlebookmark'); + + // Url + print ''; + // Target print ''; + // Owner print ''; diff --git a/htdocs/bookmarks/list.php b/htdocs/bookmarks/list.php index d72fb19a6e5..b0cda58951c 100644 --- a/htdocs/bookmarks/list.php +++ b/htdocs/bookmarks/list.php @@ -71,9 +71,9 @@ if ($_GET["action"] == 'delete') $userstatic=new User($db); -llxHeader(); +llxHeader('', $langs->trans("ListOfBookmarks")); -print load_fiche_titre($langs->trans("Bookmarks")); +print load_fiche_titre($langs->trans("ListOfBookmarks")); $sql = "SELECT b.fk_soc as rowid, b.dateb, b.rowid as bid, b.fk_user, b.url, b.target, b.title, b.favicon, b.position,"; $sql.= " u.login, u.lastname, u.firstname"; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 2771161572f..f58bd0953ab 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5087,7 +5087,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 delayed 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 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) * @return string HTML select string */ static function selectArrayAjax($htmlname, $url, $id='', $moreparam='', $moreparamtourl='', $disabled=0, $minimumInputLength=1, $morecss='', $callurlonselect=0, $placeholder='', $acceptdelayedhtml=0) diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index a1041e9358b..942c17f5df9 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -401,7 +401,7 @@ function ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $ if ($forcefocus) $msg.= '.select2(\'focus\')'; $msg.= ';'."\n"; - if (count($events)) + if (count($events)) // If an array of js events to do were provided. { $msg.= ' jQuery("#'.$htmlname.'").change(function () { @@ -414,6 +414,7 @@ function ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $ }); function runJsCodeForEvent'.$htmlname.'(obj) { + console.log("Run runJsCodeForEvent'.$htmlname.'"); var id = $("#'.$htmlname.'").val(); var method = obj.method; var url = obj.url; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 7207f8f2189..f78a38d20b0 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -494,6 +494,16 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu print "\n"; } + if (is_array($moredata) && ! empty($moredata['bookmarks'])) + { + print "\n"; + print "\n"; + print '
    '."\n"; + print $moredata['bookmarks']; + print '
    '."\n"; + print "\n"; + } + /** * We update newmenu with entries found into database * -------------------------------------------------- @@ -1632,16 +1642,6 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if ($altok) print '
    '; } - if (is_array($moredata) && ! empty($moredata['bookmarks'])) - { - print "\n"; - print "\n"; - print '
    '."\n"; - print $moredata['bookmarks']; - print '
    '."\n"; - print "\n"; - } - return count($menu_array); } diff --git a/htdocs/langs/en_US/bookmarks.lang b/htdocs/langs/en_US/bookmarks.lang index e529130e1bc..0b6216c6be4 100644 --- a/htdocs/langs/en_US/bookmarks.lang +++ b/htdocs/langs/en_US/bookmarks.lang @@ -1,7 +1,9 @@ # Dolibarr language file - Source file is en_US - marque pages -AddThisPageToBookmarks=Add this page to bookmarks +AddThisPageToBookmarks=Add current page to bookmarks Bookmark=Bookmark Bookmarks=Bookmarks +ListOfBookmarks=List of bookmarks +EditBookmarks=Edit bookmarks NewBookmark=New bookmark ShowBookmark=Show bookmark OpenANewWindow=Open a new window diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index dac7cf43f5e..a797d6f760b 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -349,6 +349,12 @@ span.timesheetalreadyrecorded input { select.flat, form.flat select { font-weight: normal; } +.optionblue { + color: rgb() !important; +} +.select2-results .select2-highlighted.optionblue { + color: #FFF !important; +} .optiongrey, .opacitymedium { opacity: 0.5; } @@ -906,14 +912,14 @@ div.blockvmenulogo { border-bottom: 0 !important; } -div.blockvmenupair, div.blockvmenuimpair, div.blockvmenubookmarks { +div.blockvmenupair, div.blockvmenuimpair { border-top: none !important; border-left: none !important; border-right: none !important; border-bottom: 1px solid #e0e0e0; padding-left: 0 !important; } -div.blockvmenuend { +div.blockvmenuend, div.blockvmenubookmarks { border: none !important; padding-left: 0 !important; } @@ -1718,14 +1724,19 @@ div.vmenu, td.vmenu { } .vmenu { + width: 190px; margin-left: 4px; display: none; } +/* Force vmenusearchselectcombo with type=text differently than without because beautify with select2 affect vmenusearchselectcombo differently */ +input.vmenusearchselectcombo[type=text] { + width: 180px !important; +} .vmenusearchselectcombo { - width: 188px; + width: 188px; } .menu_contenu { @@ -1757,10 +1768,6 @@ a.help:link, a.help:visited, a.help:hover, a.help:active, span.help { font-size: a.vsmenu.addbookmarkpicto { padding-right: 10px; } -.vmenu div.blockvmenubookmarks, .vmenu div.blockvmenuend, .vmenu div.blockvmenulogo, .vmenu div.blockvmenusearchphone -{ -/* border-bottom: 1px solid #BBB; */ -} div.blockvmenusearchphone { border-bottom: none !important; @@ -1771,7 +1778,7 @@ div.blockvmenusearchphone } .vmenu div.blockvmenusearch { - padding-bottom: 14px; + padding-bottom: 4px; /* border-bottom: 1px solid #e0e0e0; */ } .vmenu div.blockvmenuend @@ -1785,7 +1792,7 @@ div.blockvmenusearchphone } div.blockvmenubookmarks { - padding-bottom: 6px !important; + padding-bottom: 16px !important; } div.blockvmenupair, div.blockvmenuimpair, div.blockvmenubookmarks, div.blockvmenuend { @@ -3862,14 +3869,19 @@ div.dataTables_length select { /* Select2 */ /* ============================================================================== */ +.select2-default { + color: #999 !important; + /*opacity: 0.2;*/ +} .select2-choice, .select2-container .select2-choice { - border-bottom: solid 1px rgba(0,0,0,.2); + border-bottom: solid 1px rgba(0,0,0,.4); } .select2-container .select2-choice > .select2-chosen { margin-right: 23px; } .select2-container .select2-choice .select2-arrow { border-radius: 0; + background: transparent; } .select2-container-multi .select2-choices { background-image: none; @@ -3988,18 +4000,18 @@ a span.select2-chosen /* Special case for the select2 add widget */ -#addbox .select2-container .select2-choice > .select2-chosen { +#addbox .select2-container .select2-choice > .select2-chosen, #actionbookmark .select2-container .select2-choice > .select2-chosen { text-align: left; - opacity: 0.2; + opacity: 0.4; } /* Style used before the select2 js is executed on boxcombo */ -#boxcombo.boxcombo { +#boxbookmark.boxcombo, #boxcombo.boxcombo { text-align: left; - opacity: 0.2; - border-bottom: 1px solid #000; + opacity: 0.4; + border-bottom: solid 1px rgba(0,0,0,.4) !important; height: 26px; line-height: 24px; - padding: 0 0 5px 5px; + padding: 0 0 2px 0; vertical-align: top; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index f4b38d08012..6e85ca8eb7d 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -346,6 +346,12 @@ span.timesheetalreadyrecorded input { select.flat, form.flat select { font-weight: normal; } +.optionblue { + color: rgb() !important; +} +.select2-results .select2-highlighted.optionblue { + color: #FFF !important; +} .optiongrey, .opacitymedium { opacity: 0.5; } @@ -1782,7 +1788,7 @@ font.vsmenudisabledmargin { margin: 1px 1px 1px 8px; } a.help:link, a.help:visited, a.help:hover, a.help:active, span.help { font-size:px; font-family: ; text-align: ; font-weight: normal; color: #666666; text-decoration: none; } -div.blockvmenupair, div.blockvmenuimpair, div.blockvmenubookmarks +div.blockvmenupair, div.blockvmenuimpair { font-family: ; color: #000000; @@ -1797,11 +1803,21 @@ div.blockvmenupair, div.blockvmenuimpair, div.blockvmenubookmarks padding-bottom: 10px; border-bottom: 1px solid #e0e0e0; } +div.blockvmenubookmarks +{ + padding-bottom: 16px !important; +} +div.blockvmenuend { + border: none !important; + padding-left: 0 !important; +} a.vsmenu.addbookmarkpicto { padding-right: 10px; } - -div.blockvmenusearch +div.blockvmenufirst { + padding-top: 10px; +} +div.blockvmenusearch, div.blockvmenubookmarks { font-family: ; color: #000000; @@ -1811,7 +1827,7 @@ div.blockvmenusearch padding-right: 1px; padding-top: 3px; padding-bottom: 3px; - margin: 1px 0px 12px 0px; + margin: 1px 0px 2px 0px; padding-bottom: 10px; /* border-bottom: 1px solid #f4f4f4; */ @@ -4103,15 +4119,15 @@ a span.select2-chosen /* Special case for the select2 add widget */ -#addbox .select2-container .select2-choice > .select2-chosen { +#addbox .select2-container .select2-choice > .select2-chosen, #actionbookmark .select2-container .select2-choice > .select2-chosen { text-align: left; - opacity: 0.2; + opacity: 0.3; } /* Style used before the select2 js is executed on boxcombo */ -#boxcombo.boxcombo { +#boxbookmark.boxcombo, #boxcombo.boxcombo { text-align: left; - opacity: 0.2; - border-bottom: 1px solid #000; + opacity: 0.3; + border-bottom: solid 1px rgba(0,0,0,.4) !important; height: 26px; line-height: 24px; padding: 0 0 5px 5px; @@ -4124,7 +4140,7 @@ a span.select2-chosen margin: 0 0 2px 3px; position: relative; line-height: 13px; - color: #333; + color: #444; cursor: default; border: 1px solid #ddd; border-radius: 3px; From 89716a86a5642d7506177b6cbce6068ac738dea4 Mon Sep 17 00:00:00 2001 From: Widee Date: Tue, 4 Apr 2017 12:22:51 +0200 Subject: [PATCH 080/233] Avoid (DEPOSIT) (1) & (2) descriptions When splitting a rebate into two parts, the word "DEPOSIT" is no longer translated on the invoices. --- htdocs/comm/remx.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 8c35c6c9e1f..6481c891d45 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -92,7 +92,7 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes') $newdiscount2->fk_facture=$discount->fk_facture; $newdiscount1->fk_facture_line=$discount->fk_facture_line; $newdiscount2->fk_facture_line=$discount->fk_facture_line; - if ($discount->description == '(CREDIT_NOTE)') + if ($discount->description == '(CREDIT_NOTE)' || $discount->description == '(DEPOSIT)') { $newdiscount1->description=$discount->description; $newdiscount2->description=$discount->description; From c4d48569970197784d07f114615871aa2548f35f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2017 12:23:44 +0200 Subject: [PATCH 081/233] FIX sql errors on user card --- htdocs/core/class/html.form.class.php | 28 +++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index f58bd0953ab..06405f28b01 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5547,20 +5547,24 @@ class Form if (! is_object($object->thirdparty)) $object->fetch_thirdparty(); - $possiblelinks=array( - 'propal'=>array('enabled'=>$conf->propal->enabled, 'perms'=>1, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.facnumber as ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'contrat'=>array('enabled'=>$conf->contrat->enabled , 'perms'=>1, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'order_supplier'=>array('enabled'=>$conf->fournisseur->commande->enabled , 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), - 'invoice_supplier'=>array('enabled'=>$conf->fournisseur->facture->enabled , 'perms'=>1, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id) - ); - + $possiblelinks=array(); + if (is_object($object->thirdparty) && ! empty($object->thirdparty->id) && $object->thirdparty->id > 0) + { + $possiblelinks=array( + 'propal'=>array('enabled'=>$conf->propal->enabled, 'perms'=>1, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.facnumber as ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'contrat'=>array('enabled'=>$conf->contrat->enabled , 'perms'=>1, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'order_supplier'=>array('enabled'=>$conf->fournisseur->commande->enabled , 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id), + 'invoice_supplier'=>array('enabled'=>$conf->fournisseur->facture->enabled , 'perms'=>1, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id) + ); + } + global $action; - // Can complet the possiblelink array + // Can complete the possiblelink array $hookmanager->initHooks(array('commonobject')); $parameters=array(); $reshook=$hookmanager->executeHooks('showLinkToObjectBlock',$parameters,$object,$action); // Note that $action and $object may have been modified by hook From 01d69e4b58173750f314db3f5a1335fae7ad4e85 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2017 12:55:54 +0200 Subject: [PATCH 082/233] NEW Better reponsive design --- htdocs/core/lib/functions.lib.php | 4 +-- htdocs/theme/eldy/style.css.php | 43 +++++++++++++++++++++++-------- htdocs/theme/md/style.css.php | 4 +-- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8c27b101fa4..67713d7bd2c 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5618,11 +5618,11 @@ function printCommonFooter($zone='private') if (empty($conf->dol_use_jmobile)) { - print ''."\n"; + print ''."\n"; print 'jQuery(".menuhider").click(function() {'; print ' console.log("We click on .menuhider");'."\n"; print " $('.side-nav').toggle();"; - if ($conf->theme == 'md') print " $('.login_block').toggle();"; + print " $('.login_block').toggle();"; print '});'."\n"; } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index a797d6f760b..a63593292b6 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -691,7 +691,7 @@ div.fiche>form>div.div-table-responsive { justify-content: flex-start; } .thumbstat { - flex: 1 1 120px; + flex: 1 1 114px; } .thumbstat150 { flex: 1 1 170px; @@ -4538,10 +4538,17 @@ div.tabsElem a.tab { /* rule to reduce top menu - 3rd reduction */ @media only screen and (max-width: px) /* reduction 3 */ { - /* Reduce login top right info */ - .usertextatoplogin { - display: none; + .side-nav { + z-index: 200; + background: #FFF; + padding-top: 70px; + } + #id-left { + z-index: 201; + background: #FFF; } + + /* Reduce login top right info */ .help { display: none; @@ -4551,19 +4558,33 @@ div.tabsElem a.tab { display:none; - padding-: 78px; + padding-: 0; } div.login_block_user { min-width: 0; + width: 100%; } div.login_block { - top: 2px; - - max-width: 100px; - - max-width: 82px; - + display: none; + top: inherit !important; + left: 0 !important; + text-align: center; + vertical-align: middle; + background: #FFF; + height: 42px; + padding-top: 20px; + padding-left: 20px; + padding-right: 20px; + z-index: 202; + min-width: 190px; + max-width: 190px; + width: 190px; + } + div.login_block_user, div.login_block_other { clear: both; } + .atoplogin, .atoplogin:hover + { + color: #000 !important; } .login_block_elem { padding: 0 !important; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 6e85ca8eb7d..26c4c4d0a93 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -692,7 +692,7 @@ div.fiche>form>div.div-table-responsive { justify-content: flex-start; } .thumbstat { - flex: 1 1 120px; + flex: 1 1 114px; } .thumbstat150 { flex: 1 1 150px; @@ -1681,7 +1681,7 @@ div.login_block_other { padding-top: 3px; } height: 16px; } .login_block_elem_name { - margin-top: 5px; + margin-top: 1px; } .atoplogin, .atoplogin:hover { color: # !important; From 4f292d124737decc420f248f1b1c3761c7d0a8d8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2017 13:01:53 +0200 Subject: [PATCH 083/233] Prepare 5.0.2 --- htdocs/filefunc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index f385fa2a524..427f428d652 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','5.0.1'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','5.0.2'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); From 13333ffd73ff9de16db36667684bd6ce20502595 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 00:39:32 +0200 Subject: [PATCH 084/233] Add multipart text version into html emails. --- htdocs/core/class/conf.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 1692b58c5f9..08763cc346b 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -390,7 +390,8 @@ class Conf // Set some default values $this->global->MAIN_ACTIVATE_HTML5=1; - + $this->global->MAIN_MAIL_USE_MULTI_PART=1; + // societe if (empty($this->global->SOCIETE_CODECLIENT_ADDON)) $this->global->SOCIETE_CODECLIENT_ADDON="mod_codeclient_leopard"; if (empty($this->global->SOCIETE_CODECOMPTA_ADDON)) $this->global->SOCIETE_CODECOMPTA_ADDON="mod_codecompta_panicum"; From 7c868888a50b74b351998072df11ec9882be7a93 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 01:01:43 +0200 Subject: [PATCH 085/233] FIX Add option MAIN_MAIL_USE_MULTI_PART to include text content into HTML email and add option MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS to restore the inline images feature. --- htdocs/core/class/CMailFile.class.php | 83 ++++++++++++++++----------- htdocs/core/class/smtps.class.php | 50 +++++++++++++--- 2 files changed, 92 insertions(+), 41 deletions(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 396952ace9c..878e0372ab3 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -55,7 +55,6 @@ class CMailFile var $eol; var $eol2; - var $atleastonefile=0; var $error=''; var $smtps; // Contains SMTPs object (if this method is used) @@ -74,7 +73,7 @@ class CMailFile // Image var $html; var $image_boundary; - var $atleastoneimage=0; + var $atleastoneimage=0; // at least one image file with file=xxx.ext into content (TODO Debug this. How can this case be tested. Remove if not used). var $html_images=array(); var $images_encoded=array(); var $image_types = array('gif' => 'image/gif', @@ -108,7 +107,7 @@ class CMailFile */ 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='') { - global $conf; + global $conf, $dolibarr_main_data_root; // We define end of line (RFC 821). $this->eol="\r\n"; @@ -160,8 +159,12 @@ class CMailFile if ($this->msgishtml) { $this->html = $msg; - $findimg = $this->findHtmlImages($conf->fckeditor->dir_output); + if (! empty($conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS)) + { + $findimg = $this->findHtmlImages($dolibarr_main_data_root.'/medias'); + } + // Define if there is at least one file if ($findimg) { @@ -231,17 +234,6 @@ class CMailFile // Define body in text_body $text_body = $this->write_body($msg); - // Encode images - $images_encoded = ''; - if ($this->atleastoneimage) - { - $images_encoded.= $this->write_images($this->images_encoded); - // always end related and end alternative after inline images - $images_encoded.= "--" . $this->related_boundary . "--" . $this->eol; - $images_encoded.= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol; - $images_encoded.= $this->eol; - } - // Add attachments to text_encoded if ($this->atleastonefile) { @@ -255,8 +247,8 @@ class CMailFile // comme des injections mail par les serveurs de messagerie. $this->headers = preg_replace("/([\r\n]+)$/i","",$this->headers); - $this->message = 'This is a message with multiple parts in MIME format.'.$this->eol; - $this->message.= $text_body . $images_encoded . $files_encoded; + $this->message = $this->eol.'This is a message with multiple parts in MIME format.'.$this->eol; + $this->message.= $text_body . $files_encoded; $this->message.= "--" . $this->mixed_boundary . "--" . $this->eol; } else if ($conf->global->MAIN_MAIL_SENDMODE == 'smtps') @@ -917,7 +909,7 @@ class CMailFile $out.= "Content-Type: multipart/mixed; boundary=\"".$this->mixed_boundary."\"".$this->eol2; $out.= "Content-Transfer-Encoding: 8bit".$this->eol2; - + dol_syslog("CMailFile::write_smtpheaders smtp_header=\n".$out); return $out; } @@ -973,23 +965,23 @@ class CMailFile $out.= "--" . $this->alternative_boundary . $this->eol; } - if ($this->msgishtml) - { - // Check if html header already in message - $strContent = $this->checkIfHTML($msgtext); - } - else - { - $strContent = $msgtext; - } - // Make RFC821 Compliant, replace bare linefeeds - $strContent = preg_replace("/(?global->MAIN_FIX_FOR_BUGGED_MTA)) { $strContent = preg_replace("/\r\n/si", "\n", $strContent); } + $strContentAltText = ''; + if ($this->msgishtml) + { + $strContentAltText = html_entity_decode(strip_tags($strContent)); + $strContentAltText = rtrim(wordwrap($strContentAltText, 75, "\r\n")); + + // Check if html header already in message, if not complete the message + $strContent = $this->checkIfHTML($strContent); + } + // Make RFC2045 Compliant, split lines //$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content $strContent = rtrim(wordwrap($strContent)); // TODO Using this method creates unexpected line break on text/plain content. @@ -999,14 +991,30 @@ class CMailFile if ($this->atleastoneimage) { $out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol; - $out.= $this->eol.strip_tags($strContent).$this->eol; // Add plain text message + $out.= $this->eol.($strContentAltText?$strContentAltText:strip_tags($strContent)).$this->eol; // Add plain text message $out.= "--" . $this->alternative_boundary . $this->eol; $out.= "Content-Type: multipart/related; boundary=\"".$this->related_boundary."\"".$this->eol; $out.= $this->eol; $out.= "--" . $this->related_boundary . $this->eol; } + + if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part before html part + { + $out.= "Content-Type: multipart/alternative; boundary=\"".$this->alternative_boundary."\"".$this->eol; + $out.= $this->eol; + $out.= "--" . $this->alternative_boundary . $this->eol; + $out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol; + $out.= $this->eol.$strContentAltText.$this->eol; + $out.= "--" . $this->alternative_boundary . $this->eol; + } + $out.= "Content-Type: text/html; charset=".$conf->file->character_set_client.$this->eol; $out.= $this->eol.$strContent.$this->eol; + + if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part after html part + { + $out.= "--" . $this->alternative_boundary . "--". $this->eol; + } } else { @@ -1016,6 +1024,16 @@ class CMailFile $out.= $this->eol; + // Encode images + if ($this->atleastoneimage) + { + $out .= $this->write_images($this->images_encoded); + // always end related and end alternative after inline images + $out .= "--" . $this->related_boundary . "--" . $this->eol; + $out .= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol; + $out .= $this->eol; + } + return $out; } @@ -1184,14 +1202,15 @@ class CMailFile $extensions = array_keys($this->image_types); - preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches); + preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches); // If "xxx.ext" or 'xxx.ext' found if ($matches) { $i=0; foreach ($matches[1] as $full) { - if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs)) + + if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs)) // If xxx is 'file=aaa' { $img = $regs[1]; diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index e7c7b343ac9..c99ca2c4850 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -1283,15 +1283,23 @@ class SMTPs // Make RFC821 Compliant, replace bare linefeeds $strContent = preg_replace("/(?_msgContent[$strType] = array(); $this->_msgContent[$strType]['mimeType'] = $strMimeType; $this->_msgContent[$strType]['data'] = $strContent; - + $this->_msgContent[$strType]['dataText'] = $strContentAltText; + if ( $this->getMD5flag() ) $this->_msgContent[$strType]['md5'] = dol_hash($strContent, 3); //} @@ -1304,6 +1312,8 @@ class SMTPs */ function getBodyContent() { + global $conf; + // Generate a new Boundary string $this->_setBoundary(); @@ -1318,7 +1328,7 @@ class SMTPs die ("Sorry, no content"); // If we have ONE, we can use the simple format - else if( $keyCount === 1 ) + else if( $keyCount === 1 && empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) { $_msgData = $this->_msgContent; $_msgData = $_msgData[$_types[0]]; @@ -1336,7 +1346,7 @@ class SMTPs } // If we have more than ONE, we use the multi-part format - else if( $keyCount > 1 ) + else if( $keyCount >= 1 || ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) { // Since this is an actual multi-part message // We need to define a content message Boundary @@ -1351,14 +1361,18 @@ class SMTPs $content .= "\r\n"; $content .= "--" . $this->_getBoundary('mixed') . "\r\n"; - - if (key_exists('image', $this->_msgContent)) + + if (key_exists('image', $this->_msgContent)) // If inline image found { $content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n"; $content .= "\r\n"; $content .= "--" . $this->_getBoundary('alternative') . "\r\n"; } + + // $this->_msgContent must be sorted with key 'text' or 'html' first then 'image' then 'attachment' + + // Loop through message content array foreach ($this->_msgContent as $type => $_content ) { @@ -1409,13 +1423,24 @@ class SMTPs if (key_exists('image', $this->_msgContent)) { $content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n"; - $content.= "\r\n" . strip_tags($_content['data']) . "\r\n"; // Add plain text message + $content.= "\r\n" . ($_content['dataText']?$_content['dataText']:strip_tags($_content['data'])) . "\r\n"; // Add plain text message $content.= "--" . $this->_getBoundary('alternative') . "\r\n"; $content.= 'Content-Type: multipart/related; boundary="' . $this->_getBoundary('related') . '"' . "\r\n"; $content.= "\r\n"; $content.= "--" . $this->_getBoundary('related') . "\r\n"; } - + + if (! key_exists('image', $this->_msgContent) && $_content['dataText'] && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part before html part + { + $content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n"; + $content .= "\r\n"; + $content .= "--" . $this->_getBoundary('alternative') . "\r\n"; + + $content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n"; + $content.= "\r\n". $_content['dataText'] . "\r\n"; + $content.= "--" . $this->_getBoundary('alternative') . "\r\n"; + } + $content .= 'Content-Type: ' . $_content['mimeType'] . '; ' // . 'charset="' . $this->getCharSet() . '"'; . 'charset=' . $this->getCharSet() . ''; @@ -1431,7 +1456,14 @@ class SMTPs if ( $this->getMD5flag() ) $content .= 'Content-MD5: ' . $_content['md5'] . "\r\n"; - $content .= "\r\n" . $_content['data'] . "\r\n\r\n"; + $content .= "\r\n" . $_content['data'] . "\r\n"; + + if (! key_exists('image', $this->_msgContent) && $_content['dataText'] && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part after html part + { + $content.= "--" . $this->_getBoundary('alternative') . "--". "\r\n"; + } + + $content .= "\r\n"; } } From a6c60e4a9a84f413f19651a99bfcf1cf0a41469d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 11:14:02 +0200 Subject: [PATCH 086/233] FIX shared bank account with multicompany not visible in invoice setup --- htdocs/admin/facture.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php index 21ddabc1b65..b9c994fba28 100644 --- a/htdocs/admin/facture.php +++ b/htdocs/admin/facture.php @@ -638,7 +638,7 @@ if (! empty($conf->banque->enabled)) $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; $sql.= " WHERE clos = 0"; $sql.= " AND courant = 1"; - $sql.= " AND entity IN (".getEntity('bank', 1).")"; + $sql.= " AND entity IN (".getEntity('bank_account', 1).")"; $resql=$db->query($sql); if ($resql) { @@ -683,7 +683,7 @@ $sql = "SELECT rowid, label"; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; $sql.= " WHERE clos = 0"; $sql.= " AND courant = 1"; -$sql.= " AND entity IN (".getEntity('bank', 1).")"; +$sql.= " AND entity IN (".getEntity('bank_account', 1).")"; $var=True; $resql=$db->query($sql); if ($resql) From 1dc2cae3a5f92bbf68afc2e6716d65e9fa4a9475 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 11:51:55 +0200 Subject: [PATCH 087/233] NEW Show company into combo list of projects --- htdocs/core/class/html.formprojet.class.php | 22 ++++++++++----------- htdocs/expensereport/card.php | 9 ++++----- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index 7cdd745193e..30481497163 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -150,10 +150,9 @@ class FormProjets $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); } - // Search all projects - $sql = 'SELECT p.rowid, p.ref, p.title, p.fk_soc, p.fk_statut, p.public'; - $sql.= ' FROM '.MAIN_DB_PREFIX .'projet as p'; + $sql = 'SELECT p.rowid, p.ref, p.title, p.fk_soc, p.fk_statut, p.public, s.nom as name, s.name_alias'; + $sql.= ' FROM '.MAIN_DB_PREFIX .'projet as p LEFT JOIN '.MAIN_DB_PREFIX .'societe as s ON s.rowid = p.fk_soc'; $sql.= " WHERE p.entity IN (".getEntity('project', 1).")"; if ($projectsListId !== false) $sql.= " AND p.rowid IN (".$projectsListId.")"; if ($socid == 0) $sql.= " AND (p.fk_soc=0 OR p.fk_soc IS NULL)"; @@ -165,15 +164,9 @@ class FormProjets $sql.= " AND (p.fk_soc IN (".$socid.", ".$conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY.") OR p.fk_soc IS NULL)"; } } - if (!empty($filterkey)) { - $sql .= ' AND ('; - $sql .= ' p.title LIKE "%'.$this->db->escape($filterkey).'%"'; - $sql .= ' OR p.ref LIKE "%'.$this->db->escape($filterkey).'%"'; - $sql .= ')'; - } + if (!empty($filterkey)) $sql .= natural_search(array('p.title', 'p.ref'), $filterkey); $sql.= " ORDER BY p.ref ASC"; - dol_syslog(__METHOD__, LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { @@ -219,8 +212,13 @@ class FormProjets $labeltoshow=dol_trunc($obj->ref,18); //if ($obj->public) $labeltoshow.=' ('.$langs->trans("SharedProject").')'; //else $labeltoshow.=' ('.$langs->trans("Private").')'; - $labeltoshow.=' '.dol_trunc($obj->title,$maxlength); - + $labeltoshow.=', '.dol_trunc($obj->title, $maxlength); + if ($obj->name) + { + $labeltoshow.=' - '.$obj->name; + if ($obj->name_alias) $labeltoshow.=' ('.$obj->name_alias.')'; + } + $disabled=0; if ($obj->fk_statut == 0) { diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index fa6018fcd07..488c4c547ed 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1896,15 +1896,15 @@ else } print ''; - $var=true; while ($i < $num_lignes) { $piece_comptable = $i + 1; $objp = $db->fetch_object($resql); - $var=!$var; + if ($action != 'editline' || $objp->rowid != GETPOST('rowid')) { - print ''; + print ''; + print ''; @@ -1953,8 +1953,7 @@ else if ($action == 'editline' && $objp->rowid == GETPOST('rowid')) { - //modif ligne!!!!! - print ''; + print ''; print ''; From e2b96abd0bfcaa5198cbeb2fd4f545885f102a33 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 13:34:52 +0200 Subject: [PATCH 088/233] Fix translation --- htdocs/langs/en_US/admin.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 7cd29345e98..d305eb5e540 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -208,7 +208,7 @@ MainDbPasswordFileConfEncrypted=Database password encrypted in conf.php (Activat InstrucToEncodePass=To have password encoded into the conf.php file, replace the line
    $dolibarr_main_db_pass="...";
    by
    $dolibarr_main_db_pass="crypted:%s"; InstrucToClearPass=To have password decoded (clear) into the conf.php file, replace the line
    $dolibarr_main_db_pass="crypted:...";
    by
    $dolibarr_main_db_pass="%s"; ProtectAndEncryptPdfFiles=Protection of generated pdf files (Activated 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 make building of a global cumulated pdf not working (like unpaid invoices). +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 Developpers=Developers/contributors From dc14268ac6699d8ea0ee8ab2b6cdd6758914dcbf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Apr 2017 15:24:41 +0200 Subject: [PATCH 089/233] FIX complete hourly rate when not defined into table of time spent --- htdocs/install/repair.php | 76 ++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 9 deletions(-) diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index cdaa0b22b7f..0338945df0f 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -76,6 +76,7 @@ print 'Option restore_thirdparties_logos is '.(GETPOST('restore_thirdparties_log print 'Option clean_linked_elements is '.(GETPOST('clean_linked_elements')?GETPOST('clean_linked_elements'):'0').'
    '."\n"; print 'Option clean_orphelin_dir (1 or confirmed) is '.(GETPOST('clean_orphelin_dir')?GETPOST('clean_orphelin_dir'):'0').'
    '."\n"; print 'Option clean_product_stock_batch (1 or confirmed) is '.(GETPOST('clean_product_stock_batch')?GETPOST('clean_product_stock_batch'):'0').'
    '."\n"; +print 'Option set_empty_time_spent_amount (1 or confirmed) is '.(GETPOST('set_empty_time_spent_amount')?GETPOST('set_empty_time_spent_amount'):'0').'
    '."\n"; print '
    '; print '
    '.$langs->trans("BookmarkTitle").''.$langs->trans("SetHereATitleForLink").'
    '.$langs->trans("UrlOrLink").''.$langs->trans("UseAnExternalHttpLinkOrRelativeDolibarrLink").'
    '.$langs->trans("BookmarkTitle").''.$langs->trans("SetHereATitleForLink").'
    '.$langs->trans("UrlOrLink").''.$langs->trans("UseAnExternalHttpLinkOrRelativeDolibarrLink").'
    '.$langs->trans("BehaviourOnClick").''; $liste=array(0=>$langs->trans("ReplaceWindow"),1=>$langs->trans("OpenANewWindow")); print $form->selectarray('target',$liste,1); print ''.$langs->trans("ChooseIfANewWindowMustBeOpenedOnClickOnBookmark").'
    '.$langs->trans("Owner").''; print $form->select_dolusers(isset($_POST['userid'])?$_POST['userid']:$user->id, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); print ' 
    '; print img_picto($langs->trans("Document"), "object_generic"); print ' '.$piece_comptable.'
    '; @@ -151,7 +152,7 @@ if ($ok) } // Show wait message -print ''; +print ''; flush(); @@ -190,7 +191,7 @@ if ($ok) // Loop on each file foreach($filelist as $file) { - print ''; $name = substr($file, 0, dol_strlen($file) - 4); @@ -210,7 +211,7 @@ if ($ok) 'socpeople'=>'socpeople', 'commande'=>'commande', 'facture'=>'facture', 'commande_fournisseur'=>'commande_fournisseur', 'actioncomm'=>'actioncomm', 'adherent_type'=>'adherent_type','user'=>'user','projet'=>'projet', 'projet_task'=>'projet_task'); - print ''; + print ''; foreach($listofmodulesextra as $tablename => $elementtype) { // Get list of fields @@ -324,7 +325,7 @@ if ($ok && GETPOST('restore_thirdparties_logos')) $ext=''; - print ''; + print ''; // propal => order print '\n"; @@ -435,7 +436,7 @@ if ($ok && GETPOST('clean_orphelin_dir')) if (empty($upload_dir)) continue; - print ''; + print ''; $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','(\.meta|_preview\.png)$','^temp$','^payments$','^CVS$','^thumbs$'),'',SORT_DESC,1,true); @@ -546,7 +547,7 @@ if ($ok && GETPOST('clean_orphelin_dir')) // clean_linked_elements: Check and clean linked elements if ($ok && GETPOST('clean_product_stock_batch')) { - print ''; + print ''; $sql ="SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch"; $sql.=" FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product_batch as pb"; @@ -636,12 +637,69 @@ if ($ok && GETPOST('clean_product_stock_batch')) { dol_print_error($db); } - - } +// clean_linked_elements: Check and clean linked elements +if ($ok && GETPOST('set_empty_time_spent_amount')) +{ + print ''; + + $sql ="SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm"; + $sql.=" FROM ".MAIN_DB_PREFIX."projet_task_time as ptt, ".MAIN_DB_PREFIX."user as u"; + $sql.=" WHERE ptt.fk_user = u.rowid"; + $sql.=" AND ptt.thm IS NULL and u.thm > 0"; + $sql.=" GROUP BY u.rowid, u.login, u.thm"; + + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + + if ($num) + { + $i = 0; + while ($i < $num) + { + $obj=$db->fetch_object($resql); + print ''; + + if ($error) break; + + $i++; + } + } + else + { + print ''; + } + } + else + { + dol_print_error($db); + } + + +} + + print '
    '.$langs->trans("PleaseBePatient").'
    '.$langs->trans("PleaseBePatient").'

    '; + print '
    *** '; print $langs->trans("Script").''.$file.'

    Check fields into extra table structure match table of definition. If not add column into table

    *** Check fields into extra table structure match table of definition. If not add column into table

    '; + print '

    *** Restore thirdparties logo
    '; //foreach($exts as $ext) //{ $sql="SELECT s.rowid, s.nom as name, s.logo FROM ".MAIN_DB_PREFIX."societe as s ORDER BY s.nom"; @@ -395,7 +396,7 @@ if ($ok && GETPOST('restore_thirdparties_logos')) // clean_linked_elements: Check and clean linked elements if ($ok && GETPOST('clean_linked_elements')) { - print '

    Check table of linked elements and delete orphelins links

    *** Check table of linked elements and delete orphelins links
    '.checkLinkedElements('propal', 'commande')."

    Clean orphelins files into files '.$upload_dir.'

    *** Clean orphelins files into files '.$upload_dir.'

    Clean table product_batch

    *** Clean table product_batch

    *** Set value of time spent without amount
    '.$obj->login.'-'.$obj->user_id.' ('.$obj->nb.' lines to fix) -> '.$obj->user_thm; + + $db->begin(); + + $sql2 ="UPDATE ".MAIN_DB_PREFIX."projet_task_time"; + $sql2.=" SET thm = ".$obj->user_thm." WHERE thm IS NULL AND fk_user = ".$obj->user_id; + $resql2=$db->query($sql2); + if (! $resql2) + { + $error++; + dol_print_error($db); + } + + if (!$error) $db->commit(); + else $db->rollback(); + + print'
    No time spent with empty line on users with a hourly rate defined
    '; From ae2e40e5e760ff34d6c80dd6bfac831eaf85cb75 Mon Sep 17 00:00:00 2001 From: De Coninck Laurent Date: Wed, 5 Apr 2017 19:06:21 +0200 Subject: [PATCH 090/233] mark expense report as paid if payement set the remaining sold to 0 --- htdocs/expensereport/payment/payment.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/htdocs/expensereport/payment/payment.php b/htdocs/expensereport/payment/payment.php index ebcc1056fe4..56a5b1c7fb3 100644 --- a/htdocs/expensereport/payment/payment.php +++ b/htdocs/expensereport/payment/payment.php @@ -134,6 +134,18 @@ if ($action == 'add_payment') } } + if (!$error) { + $payment->fetch($paymentid); + if ($expensereport->total_ttc - $payment->amount == 0) { + $result = $expensereport->set_paid($expensereport->id, $user); + if (!$result > 0) { + $errmsg = $payment->error; + $error++; + } + } + + } + if (! $error) { $db->commit(); From dae08285433bd6170f883565723c03b82970e388 Mon Sep 17 00:00:00 2001 From: delcroix Patrick Date: Wed, 5 Apr 2017 20:50:18 +0200 Subject: [PATCH 091/233] NEW : show files in the bank statement + download --- htdocs/compta/bank/releve.php | 134 +++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index ffadceafb2e..2ab6df9047f 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2017 Patrick Delcroix * * This 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,6 +35,9 @@ require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php'; +//show files +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; $langs->load("banks"); $langs->load("categories"); @@ -88,7 +92,36 @@ if ($id > 0 || ! empty($ref)) // Initialize technical object to manage context to save list fields $contextpage='banktransactionlist'.(empty($object->ref)?'':'-'.$object->id); +/* +*ZIP creation +*/ +if($action=="dl" && $num>0 && isset($_SESSION["releve"][$num])){ + unset($zip); + $log=''; + $filearray=$_SESSION["releve"][$num]; + $zipname = $num.'.zip'; + $zip = new ZipArchive; + $zip->open($zipname, ZipArchive::OVERWRITE); + foreach ($filearray as $key=> $files) { + if(is_array($files)){ + foreach ($files as $file) { + $zip->addFile($file["fullname"],$file["name"]);// + $log.=$key.','.$file["name"]."\n"; + } + }else{ + $log.=$key.','.$langs->trans("Nofile")."\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); +} +unset($_SESSION["releve"][$num]); /* * View @@ -519,7 +552,7 @@ else dol_print_error($db); } } - + print Get_attach_files($db,$objp->rowid,$objp->label); print "
    "; - print $memberstatic->getNomUrl(1); + print $memberstatic->getNomUrl(-1); print "
    '; @@ -146,7 +147,8 @@ if ($object->id) print ''; print "
    \n"; - + print '
    '; + print dol_fiche_end(); @@ -198,7 +200,7 @@ if ($object->id) $dir = $upload_dir.'/'.$pdir; print '
    '; - print ''; + print '
    '; foreach ($object->liste_photos($dir) as $key => $obj) { @@ -255,14 +257,12 @@ if ($object->id) $nbphoto++; } + print '
    '; + if ($nbphoto < 1) { - print '
    '; - print "
    ".$langs->trans("NoPhotoYet")."

    "; - print '
    '; } } else diff --git a/htdocs/categories/traduction.php b/htdocs/categories/traduction.php index a239b357045..7dbe6325e1d 100644 --- a/htdocs/categories/traduction.php +++ b/htdocs/categories/traduction.php @@ -167,7 +167,7 @@ if (! empty($object->multilangs)) } } -dol_fiche_head($head, 'translation', $title, 0, 'category'); +dol_fiche_head($head, 'translation', $title, -1, 'category'); $linkback = ''.$langs->trans("BackToList").''; @@ -184,6 +184,7 @@ dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref', 'ref', print '
    '; +print '
    '; print '
    '; print ''; @@ -201,6 +202,7 @@ print $formother->showColor($object->color); print ''; print '
    '; +print '
    '; dol_fiche_end(); diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index a1c33c568f3..a256b362361 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -192,7 +192,7 @@ else $title=$langs->trans("Category"); $head = categories_prepare_head($object,$type); -dol_fiche_head($head, 'card', $title, 0, 'category'); +dol_fiche_head($head, 'card', $title, -1, 'category'); $linkback = ''.$langs->trans("BackToList").''; @@ -219,6 +219,7 @@ if ($action == 'delete') print '
    '; +print '
    '; print '
    '; print ''; @@ -241,6 +242,7 @@ if (empty($reshook) && ! empty($extrafields->attribute_label)) } print '
    '; +print '
    '; dol_fiche_end(); diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index f403f676f07..f77ac86af7f 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -228,7 +228,6 @@ $tabs = array( ) ); -dol_fiche_head($tabs, 0, $langs->trans('LineRecord'), 0, 'account'); $sql = "SELECT b.rowid,b.dateo as do,b.datev as dv, b.amount, b.label, b.rappro,"; $sql.= " b.num_releve, b.fk_user_author, b.num_chq, b.fk_type, b.fk_account, b.fk_bordereau as receiptid,"; @@ -269,11 +268,14 @@ if ($result) print ''; print ''; + dol_fiche_head($tabs, 0, $langs->trans('LineRecord'), 0, 'account'); + $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($bankline, 'rowid', $linkback); + print '
    '; print ''; @@ -542,8 +544,10 @@ if ($result) print ""; print "
    "; - - print '
    '; + + dol_fiche_end(); + + print '

    '; print ""; @@ -596,7 +600,7 @@ if ($result) print ''; print ''; - print '
    '; + print '

    '; print ''; } @@ -606,7 +610,6 @@ if ($result) $db->free($result); } else dol_print_error($db); -print '
    '; @@ -641,8 +644,7 @@ if ($result) { $objp = $db->fetch_object($result); - $var=!$var; - print ""; + print ''; print "".$objp->label.""; print "rowid."\">".$langs->trans("ListBankTransactions").""; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index e6a5b5d6b92..634f27b1985 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -781,7 +781,7 @@ abstract class CommonObject $tab=array(); $sql = "SELECT ec.rowid, ec.statut as statuslink, ec.fk_socpeople as id, ec.fk_c_type_contact"; // This field contains id of llx_socpeople or id of llx_user - if ($source == 'internal') $sql.=", '-1' as socid, t.statut as statuscontact"; + if ($source == 'internal') $sql.=", '-1' as socid, t.statut as statuscontact, t.login, t.photo"; if ($source == 'external' || $source == 'thirdparty') $sql.=", t.fk_soc as socid, t.statut as statuscontact"; $sql.= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email"; $sql.= ", tc.source, tc.element, tc.code, tc.libelle"; @@ -815,7 +815,7 @@ abstract class CommonObject $libelle_type=($langs->trans($transkey)!=$transkey ? $langs->trans($transkey) : $obj->libelle); $tab[$i]=array('source'=>$obj->source,'socid'=>$obj->socid,'id'=>$obj->id, 'nom'=>$obj->lastname, // For backward compatibility - 'civility'=>$obj->civility, 'lastname'=>$obj->lastname, 'firstname'=>$obj->firstname, 'email'=>$obj->email, 'statuscontact'=>$obj->statuscontact, + 'civility'=>$obj->civility, 'lastname'=>$obj->lastname, 'firstname'=>$obj->firstname, 'email'=>$obj->email, 'login'=>$obj->login, 'photo'=>$obj->photo, 'statuscontact'=>$obj->statuscontact, 'rowid'=>$obj->rowid, 'code'=>$obj->code, 'libelle'=>$libelle_type, 'status'=>$obj->statuslink, 'fk_c_type_contact'=>$obj->fk_c_type_contact); } else diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 06405f28b01..eba2fda5049 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4920,7 +4920,7 @@ class Form } elseif ($typehour=='text' || $typehour=='textselect') { - $retstring.=''; + $retstring.=''; } else return 'BadValueForParameterTypeHour'; @@ -4944,7 +4944,7 @@ class Form } elseif ($typehour=='text' ) { - $retstring.=''; + $retstring.=''; } if ($typehour!='text') $retstring.=' '.$langs->trans('MinuteShort'); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 258c2c9c962..3eef315d48a 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1103,19 +1103,16 @@ class FormFile // Do we have entry into database ? print ''."\n"; print ''; - print ''; + print ''; + + $filepath=$relativepath.$file['name']; + + if (! $editline) print $this->showPreview($file,$modulepart,$filepath); //print "XX".$file['name']; //$file['name'] must be utf8 - print ''; @@ -1135,10 +1132,10 @@ class FormFile print ''; } - if (! $editline) print $this->showPreview($file,$modulepart,$filepath); - print "\n"; + print ''.dol_print_size($file['size'],1,1).''; + print ''.dol_print_date($file['date'],"dayhour","tzuser").''; // Preview diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 67713d7bd2c..66eca2409f3 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1176,7 +1176,8 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r } if (! empty($object->name_alias)) $morehtmlref.='
    '.$object->name_alias.'
    '; // For thirdparty - if ($object->element == 'product' || $object->element == 'bank_account') + // Add label + if ($object->element == 'product' || $object->element == 'bank_account' || $object->element == 'project_task') { if (! empty($object->label)) $morehtmlref.='
    '.$object->label.'
    '; } diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php index 0a17a8c07c2..3077e49bf89 100644 --- a/htdocs/core/tpl/contacts.tpl.php +++ b/htdocs/core/tpl/contacts.tpl.php @@ -196,7 +196,9 @@ if ($permission) { $userstatic->id=$tab[$i]['id']; $userstatic->lastname=$tab[$i]['lastname']; $userstatic->firstname=$tab[$i]['firstname']; - echo $userstatic->getNomUrl(1); + $userstatic->photo=$tab[$i]['photo']; + $userstatic->login=$tab[$i]['login']; + echo $userstatic->getNomUrl(-1); } if ($tab[$i]['source']=='external') { diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 074f626f299..f44f2f70acf 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -848,7 +848,7 @@ if (! defined('NOREQUIRETRAN')) // Define some constants used for style of arrays $bc=array(0=>'class="impair"',1=>'class="pair"'); -$bcdd=array(0=>'class="drag drop"',1=>'class="drag drop"'); +$bcdd=array(0=>'class="drag drop oddeven"',1=>'class="drag drop oddeven"'); $bcnd=array(0=>'class="nodrag nodrop nohover"',1=>'class="nodrag nodrop nohoverpair"'); // Used for tr to add new lines $bctag=array(0=>'class="tagtr"',1=>'class="pair tagtr"'); diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 9407fc716c1..791cd6855f0 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -892,13 +892,12 @@ elseif ($object->id > 0) // Date start - end print ''.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_start,'day'); - $end=dol_print_date($object->date_end,'day'); - if ($end) - { - print ' - '.$end; - if ($object->hasDelay()) print img_warning($langs->trans('Late')); - } + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print ''; // Budget diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 7c986e4d9a2..a5e4cb69492 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -1635,6 +1635,17 @@ class Task extends CommonObject 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'); } + if ($mode == 6) + { + /*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]),'statut4'); + 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');*/ + //return $this->progress.' %'; + return ' '; + } } /** diff --git a/htdocs/projet/contact.php b/htdocs/projet/contact.php index e9de1f7f787..e843d4951e4 100644 --- a/htdocs/projet/contact.php +++ b/htdocs/projet/contact.php @@ -146,7 +146,7 @@ if ($id > 0 || ! empty($ref)) //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete; $head = project_prepare_head($object); - dol_fiche_head($head, 'contact', $langs->trans("Project"), 0, ($object->public?'projectpub':'project')); + dol_fiche_head($head, 'contact', $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); // Project card @@ -206,9 +206,12 @@ if ($id > 0 || ! empty($ref)) // Date start - end print ''.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_start,'day'); - $end=dol_print_date($object->date_end,'day'); - if ($end) print ' - '.$end; + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print ''; // Budget @@ -235,7 +238,7 @@ if ($id > 0 || ! empty($ref)) print ''; // Categories - if($conf->categorie->enabled) { + if ($conf->categorie->enabled) { print ''.$langs->trans("Categories").''; print $form->showCategories($object->id,'project',1); print ""; diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 1efc4465d81..7be3cebd46c 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -183,9 +183,12 @@ if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) // Date start - end print ''.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; -print dol_print_date($object->date_start,'day'); -$end=dol_print_date($object->date_end,'day'); -if ($end) print ' - '.$end; +$start = dol_print_date($object->date_start,'dayhour'); +print ($start?$start:'?'); +$end = dol_print_date($object->date_end,'dayhour'); +print ' - '; +print ($end?$end:'?'); +if ($object->hasDelay()) print img_warning("Late"); print ''; // Budget @@ -770,7 +773,6 @@ foreach ($listofreferent as $key => $value) $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee); if (is_array($elementarray) && count($elementarray)>0) { - $var=true; $total_ht = 0; $total_ttc = 0; @@ -813,7 +815,6 @@ foreach ($listofreferent as $key => $value) if ($breakline && $saved_third_id != $element->thirdparty->id) { print $breakline; - $var = true; $saved_third_id = $element->thirdparty->id; $breakline = ''; @@ -829,8 +830,7 @@ foreach ($listofreferent as $key => $value) if (! empty($element->close_code) && $element->close_code == 'replaced') $qualifiedfortotal=false; // Replacement invoice, do not include into total } - $var=!$var; - print ""; + print ''; // Remove link print ''; if ($tablename != 'projet_task' && $tablename != 'stock_mouvement') @@ -909,7 +909,9 @@ foreach ($listofreferent as $key => $value) else if (in_array($tablename, array('projet_task'))) { $tmpprojtime = $element->getSumOfAmount($elementuser, $dates, $datee); // $element is a task. $elementuser may be empty + print ''; print convertSecondToTime($tmpprojtime['nbseconds'], 'allhourmin'); + print ''; $total_time_by_line = $tmpprojtime['nbseconds']; } else print dol_print_date($date,'day'); @@ -935,7 +937,7 @@ foreach ($listofreferent as $key => $value) } else if ($tablename == 'projet_task' && $key == 'project_task_time') // if $key == 'project_task', we don't want details per user { - print $elementuser->getNomUrl(1); + print $elementuser->getNomUrl(1); } print ''; diff --git a/htdocs/projet/ganttchart.inc.php b/htdocs/projet/ganttchart.inc.php index f60ada41bb1..4e1b53d3f24 100644 --- a/htdocs/projet/ganttchart.inc.php +++ b/htdocs/projet/ganttchart.inc.php @@ -167,8 +167,8 @@ function constructGanttLine($tarr,$task,$project_dependencies,$level=0,$project_ $parent = $task["task_parent"]; // Define percent $percent = $task['task_percent_complete']?$task['task_percent_complete']:0; - // Link - $link=DOL_URL_ROOT.'/projet/tasks/task.php?withproject=1&id='.$task["task_id"]; + // Link (more information) + $link=DOL_URL_ROOT.'/projet/tasks/contact.php?withproject=1&id='.$task["task_id"]; // Name $name=$task['task_name']; diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index d96e21cf194..36fbfccca77 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -94,7 +94,7 @@ if ($id > 0 || ! empty($ref)) $tab='gantt'; $head=project_prepare_head($object); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($object->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); @@ -138,9 +138,12 @@ if ($id > 0 || ! empty($ref)) // Date start - end print ''.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_start,'day'); - $end=dol_print_date($object->date_end,'day'); - if ($end) print ' - '.$end; + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print ''; // Budget @@ -253,7 +256,7 @@ if (count($tasksarray)>0) $tasks[$taskcursor]['task_percent_complete']=$val->progress; //$tasks[$taskcursor]['task_name']=$task->getNomUrl(1); //print dol_print_date($val->date_start).dol_print_date($val->date_end).'
    '."\n"; - $tasks[$taskcursor]['task_name']=$val->label; + $tasks[$taskcursor]['task_name']=$val->ref.' - '.$val->label; $tasks[$taskcursor]['task_start_date']=$val->date_start; $tasks[$taskcursor]['task_end_date']=$val->date_end; $tasks[$taskcursor]['task_color']='b4d1ea'; diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index b742b5a3acb..8b72a6448ec 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -207,7 +207,7 @@ if ($id > 0 || ! empty($ref)) $tab=GETPOST('tab')?GETPOST('tab'):'tasks'; $head=project_prepare_head($object); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($object->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); @@ -268,9 +268,12 @@ if ($id > 0 || ! empty($ref)) // Date start - end print ''.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_start,'day'); - $end=dol_print_date($object->date_end,'day'); - if ($end) print ' - '.$end; + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print ''; // Budget diff --git a/htdocs/projet/tasks/contact.php b/htdocs/projet/tasks/contact.php index 060155d6507..02b31ea83ff 100644 --- a/htdocs/projet/tasks/contact.php +++ b/htdocs/projet/tasks/contact.php @@ -279,35 +279,31 @@ if ($id > 0 || ! empty($ref)) //$arrayofuseridoftask=$object->getListContactId('internal'); $head = task_prepare_head($object); - dol_fiche_head($head, 'task_contact', $langs->trans("Task"), 0, 'projecttask'); + dol_fiche_head($head, 'task_contact', $langs->trans("Task"), -1, 'projecttask'); - /* - * Projet synthese pour rappel - */ - print ''; - $param=(GETPOST('withproject')?'&withproject=1':''); $linkback=GETPOST('withproject')?''.$langs->trans("BackToList").'':''; - - // Ref - print ''; - - // Label - print ''; - - // Project - if (empty($withproject)) + + $morehtmlref=''; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param, 0, '', '', 1); + + if (empty($withproject)) { - print '
    '.$langs->trans('Ref').''; + if (! GETPOST('withproject') || empty($projectstatic->id)) { $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); $object->next_prev_filter=" fk_projet in (".$projectsListId.")"; } else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; - print $form->showrefnav($object,'ref',$linkback,1,'ref','ref','',$param); - print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("Project").''; + print '
    '; + + print '
    '; + print ''; + + // Project + print ''; @@ -317,16 +313,18 @@ if ($id > 0 || ! empty($ref)) if ($projectstatic->thirdparty->id > 0) print $projectstatic->thirdparty->getNomUrl(1); else print ' '; print ''; + + print "
    '.$langs->trans("Project").''; print $projectstatic->getNomUrl(1); print '
    "; + + print '
    '; } - print "
    "; - + dol_fiche_end(); /* * Lignes de contacts */ - print '
    '; /* // Contacts lines (modules that overwrite templates must declare this into descriptor) $dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl')); @@ -481,7 +479,9 @@ if ($id > 0 || ! empty($ref)) $userstatic->id=$tab[$i]['id']; $userstatic->lastname=$tab[$i]['lastname']; $userstatic->firstname=$tab[$i]['firstname']; - print $userstatic->getNomUrl(1); + $userstatic->photo=$tab[$i]['photo']; + $userstatic->login=$tab[$i]['login']; + print $userstatic->getNomUrl(-1); } if ($tab[$i]['source']=='external') { diff --git a/htdocs/projet/tasks/document.php b/htdocs/projet/tasks/document.php index d985454119d..af7d35ab378 100644 --- a/htdocs/projet/tasks/document.php +++ b/htdocs/projet/tasks/document.php @@ -218,10 +218,7 @@ if ($object->id > 0) } $head = task_prepare_head($object); - dol_fiche_head($head, 'task_document', $langs->trans("Task"), 0, 'projecttask'); - - $param=(GETPOST('withproject')?'&withproject=1':''); - $linkback=GETPOST('withproject')?''.$langs->trans("BackToList").'':''; + dol_fiche_head($head, 'task_document', $langs->trans("Task"), -1, 'projecttask'); // Files list constructor $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); @@ -230,10 +227,27 @@ if ($object->id > 0) { $totalsize+=$file['size']; } + + $param=(GETPOST('withproject')?'&withproject=1':''); + $linkback=GETPOST('withproject')?''.$langs->trans("BackToList").'':''; + if (! GETPOST('withproject') || empty($projectstatic->id)) + { + $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); + $object->next_prev_filter=" fk_projet in (".$projectsListId.")"; + } + else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; + + $morehtmlref=''; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param); + + print '
    '; + + print '
    '; print ''; // Ref + /* print ''; - + */ + // Project if (empty($withproject)) { - print ''; @@ -265,11 +280,13 @@ if ($object->id > 0) } // Files infos - print ''; + print ''; print ''; print "
    '; print $langs->trans("Ref"); print ''; @@ -249,11 +263,12 @@ if ($object->id > 0) // Label print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("Project").''; + print '
    '.$langs->trans("Project").''; print $projectstatic->getNomUrl(1); print '
    '.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
    '.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
    '.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
    \n"; + print '
    '; + dol_fiche_end(); print '
    '; diff --git a/htdocs/projet/tasks/note.php b/htdocs/projet/tasks/note.php index f595f43bc2b..ebdd3d0c5a3 100644 --- a/htdocs/projet/tasks/note.php +++ b/htdocs/projet/tasks/note.php @@ -110,7 +110,7 @@ if ($object->id > 0) // Tabs for project $tab='tasks'; $head=project_prepare_head($projectstatic); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($projectstatic->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), 0, ($projectstatic->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); // Project card @@ -197,13 +197,27 @@ if ($object->id > 0) } $head = task_prepare_head($object); - dol_fiche_head($head, 'task_notes', $langs->trans('Task'), 0, 'projecttask'); - - print ''; + dol_fiche_head($head, 'task_notes', $langs->trans('Task'), -1, 'projecttask'); + $param=(GETPOST('withproject')?'&withproject=1':''); $linkback=GETPOST('withproject')?''.$langs->trans("BackToList").'':''; - + + if (! GETPOST('withproject') || empty($projectstatic->id)) + { + $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); + $object->next_prev_filter=" fk_projet in (".$projectsListId.")"; + } + else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; + + $morehtmlref=''; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param); + + print '
    '; + + print '
    '; + print '
    '; + /* // Ref print ''; - + */ + // Project if (empty($withproject)) { @@ -234,12 +249,12 @@ if ($object->id > 0) print "
    '.$langs->trans("Ref").''; if (empty($withproject) || empty($projectstatic->id)) @@ -217,7 +231,8 @@ if ($object->id > 0) // Label print '
    '.$langs->trans("Label").''.$object->label.'
    "; - print '
    '; - $cssclass='titlefield'; $moreparam=$param; include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + print ''; + dol_fiche_end(); } diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 2665b0b33b5..3e6d658bcc1 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -221,7 +221,7 @@ if ($id > 0 || ! empty($ref)) // Tabs for project $tab='tasks'; $head=project_prepare_head($projectstatic); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($projectstatic->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), -1, ($projectstatic->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); @@ -306,6 +306,8 @@ if ($id > 0 || ! empty($ref)) print '
    '; dol_fiche_end(); + + print '
    '; } /* @@ -437,9 +439,22 @@ if ($id > 0 || ! empty($ref)) print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$_GET["id"].'&withproject='.$withproject,$langs->trans("DeleteATask"),$langs->trans("ConfirmDeleteATask"),"confirm_delete"); } + if (! GETPOST('withproject') || empty($projectstatic->id)) + { + $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); + $object->next_prev_filter=" fk_projet in (".$projectsListId.")"; + } + else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; + + $morehtmlref=''; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param); + print '
    '; + + print '
    '; print ''; + /* // Ref print ''; - + */ + // Project if (empty($withproject)) { - print ''; @@ -471,15 +487,14 @@ if ($id > 0 || ! empty($ref)) print ''; } - // Date start - print ''; - - // Date end - print ''; // Planned workload @@ -523,7 +538,8 @@ if ($id > 0 || ! empty($ref)) } print '
    '; print $langs->trans("Ref"); @@ -456,11 +471,12 @@ if ($id > 0 || ! empty($ref)) // Label print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("Project").''; + print '
    '.$langs->trans("Project").''; print $projectstatic->getNomUrl(1); print '
    '.$langs->trans("DateStart").''; - print dol_print_date($object->date_start,'dayhour'); - print '
    '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_end,'dayhour'); - if ($object->hasDelay()) print img_warning("Late"); + // Date start - Date end + print '
    '.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print '
    '; - print '
    '; + + print ''; dol_fiche_end(); } diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 4b2b0b4c21e..73aba634c4d 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -49,6 +49,9 @@ $search_datewithhour=''; $search_note=GETPOST('search_note','alpha'); $search_duration=GETPOST('search_duration','int'); $search_value=GETPOST('search_value','int'); +$search_task_ref=GETPOST('search_task_ref','alpha'); +$search_task_label=GETPOST('search_task_label','alpha'); +$search_user=GETPOST('search_user','int'); // Security check $socid=0; @@ -103,6 +106,9 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") ||GETPO $search_value=''; $search_date_creation=''; $search_date_update=''; + $search_task_ref=''; + $search_task_label=''; + $search_user=0; $toselect=''; $search_array_options=array(); $action=''; @@ -299,7 +305,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) // Tabs for project $tab='tasks'; $head=project_prepare_head($projectstatic); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($projectstatic->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), 0, ($projectstatic->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); @@ -418,43 +424,51 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) if (empty($projectidforalltimes)) { $head=task_prepare_head($object); - dol_fiche_head($head, 'task_time', $langs->trans("Task"),0,'projecttask'); + dol_fiche_head($head, 'task_time', $langs->trans("Task"), -1, 'projecttask'); if ($action == 'deleteline') { print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id.'&lineid='.$_GET["lineid"].($withproject?'&withproject=1':''),$langs->trans("DeleteATimeSpent"),$langs->trans("ConfirmDeleteATimeSpent"),"confirm_delete",'','',1); } - print '
    '; - print ''; - $param=($withproject?'&withproject=1':''); $linkback=$withproject?''.$langs->trans("BackToList").'':''; - // Ref - print '
    '; - print $langs->trans("Ref"); - print ''; if (! GETPOST('withproject') || empty($projectstatic->id)) { $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); $object->next_prev_filter=" fk_projet in (".$projectsListId.")"; } else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; + + $morehtmlref=''; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param); + + print '
    '; + + print '
    '; + print ''; + + // Ref + /* + print ''; // Label print ''; - - // Date start - print ''; - - // Date end - print ''; // Planned workload @@ -517,11 +531,12 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print ''; print ''; print ''; + print ''; print ''; - print ''; + print ''; print "\n"; - print ''; + print ''; // Date print ''; + // Duration - Time spent + print ''; + // Progress declared print ''; - // Duration - Time spent - print ''; - print ''; @@ -609,13 +624,16 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) $sql = "SELECT t.rowid, t.fk_task, t.task_date, t.task_datehour, t.task_date_withhour, t.task_duration, t.fk_user, t.note, t.thm,"; $sql .= " pt.ref, pt.label,"; - $sql .= " u.lastname, u.firstname"; + $sql .= " u.lastname, u.firstname, u.login, u.photo"; $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u"; $sql .= " WHERE t.fk_user = u.rowid AND t.fk_task = pt.rowid"; if (empty($projectidforalltimes)) $sql .= " AND t.fk_task =".$object->id; else $sql.= " AND pt.fk_projet IN (".$projectidforalltimes.")"; if ($search_ref) $sql .= natural_search('c.ref', $search_ref); if ($search_note) $sql .= natural_search('t.note', $search_note); + if ($search_task_ref) $sql .= natural_search('pt.ref', $search_task_ref); + if ($search_task_label) $sql .= natural_search('pt.label', $search_task_label); + if ($search_user > 0) $sql .= natural_search('t.fk_user', $search_user); $sql .= $db->order($sortfield, $sortorder); $var=true; @@ -711,50 +729,23 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print '
    '; print '
    '; + print $langs->trans("Ref"); + print ''; print $form->showrefnav($object,'ref',$linkback,1,'ref','ref','',$param); print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("DateStart").''; - print dol_print_date($object->date_start,'dayhour'); - print '
    '.$langs->trans("DateEnd").''; - print dol_print_date($object->date_end,'dayhour'); + */ + + // Date start - Date end + print '
    '.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; + $start = dol_print_date($object->date_start,'dayhour'); + print ($start?$start:'?'); + $end = dol_print_date($object->date_end,'dayhour'); + print ' - '; + print ($end?$end:'?'); + if ($object->hasDelay()) print img_warning("Late"); print '
    '.$langs->trans("Date").''.$langs->trans("By").''.$langs->trans("Note").''.$langs->trans("NewTimeSpent").''.$langs->trans("ProgressDeclared").''.$langs->trans("NewTimeSpent").'
    '; @@ -550,16 +565,16 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print ''; print ''; + print $form->select_duration('timespent_duration', ($_POST['timespent_duration']?$_POST['timespent_duration']:''), 0, 'text'); + print ''; print $formother->select_percent(GETPOST('progress')?GETPOST('progress'):$object->progress,'progress'); print ''; - print $form->select_duration('timespent_duration', ($_POST['timespent_duration']?$_POST['timespent_duration']:''), 0, 'text'); - print ''; print ''; print '
    '."\n"; - print ''; - if (! empty($arrayfields['t.task_date']['checked'])) print_liste_field_titre($arrayfields['t.task_date']['label'],$_SERVER['PHP_SELF'],'t.task_date,t.task_datehour,t.rowid','',$params,'',$sortfield,$sortorder); - if ((empty($id) && empty($ref)) || ! empty($projectidforalltimes)) // Not a dedicated task - { - if (! empty($arrayfields['t.task_ref']['checked'])) print_liste_field_titre($arrayfields['t.task_ref']['label'],$_SERVER['PHP_SELF'],'pt.ref','',$params,'',$sortfield,$sortorder); - if (! empty($arrayfields['t.task_label']['checked'])) print_liste_field_titre($arrayfields['t.task_label']['label'],$_SERVER['PHP_SELF'],'pt.label','',$params,'',$sortfield,$sortorder); - } - if (! empty($arrayfields['author']['checked'])) print_liste_field_titre($arrayfields['author']['label'],$_SERVER['PHP_SELF'],'','',$params,'',$sortfield,$sortorder); - if (! empty($arrayfields['t.note']['checked'])) print_liste_field_titre($arrayfields['t.note']['label'],$_SERVER['PHP_SELF'],'t.note','',$params,'',$sortfield,$sortorder); - if (! empty($arrayfields['t.task_duration']['checked'])) print_liste_field_titre($arrayfields['t.task_duration']['label'],$_SERVER['PHP_SELF'],'t.task_duration','',$params,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['value']['checked'])) print_liste_field_titre($arrayfields['value']['label'],$_SERVER['PHP_SELF'],'','',$params,'align="right"',$sortfield,$sortorder); - // Extra fields - /* - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - }*/ - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - // Fields title search - print ''; - // LIST_OF_TD_TITLE_SEARCH + print ''; + // Date if (! empty($arrayfields['t.task_date']['checked'])) print ''; if ((empty($id) && empty($ref)) || ! empty($projectidforalltimes)) // Not a dedicated task { - if (! empty($arrayfields['t.task_ref']['checked'])) print ''; - if (! empty($arrayfields['t.task_label']['checked'])) print ''; + if (! empty($arrayfields['t.task_ref']['checked'])) print ''; + if (! empty($arrayfields['t.task_label']['checked'])) print ''; } - if (! empty($arrayfields['author']['checked'])) print ''; - if (! empty($arrayfields['t.note']['checked'])) print ''; - if (! empty($arrayfields['t.task_duration']['checked'])) print ''; - if (! empty($arrayfields['value']['checked'])) print ''; + // Author + if (! empty($arrayfields['author']['checked'])) print ''; + // Note + if (! empty($arrayfields['t.note']['checked'])) print ''; + // Duration + if (! empty($arrayfields['t.task_duration']['checked'])) print ''; + // Value in currency + if (! empty($arrayfields['value']['checked'])) print ''; // Extra fields /* if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) @@ -784,11 +775,42 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column - print ''; - print ''."\n"; + print ''."\n"; + + print ''; + if (! empty($arrayfields['t.task_date']['checked'])) print_liste_field_titre($arrayfields['t.task_date']['label'],$_SERVER['PHP_SELF'],'t.task_date,t.task_datehour,t.rowid','',$params,'',$sortfield,$sortorder); + if ((empty($id) && empty($ref)) || ! empty($projectidforalltimes)) // Not a dedicated task + { + if (! empty($arrayfields['t.task_ref']['checked'])) print_liste_field_titre($arrayfields['t.task_ref']['label'],$_SERVER['PHP_SELF'],'pt.ref','',$params,'',$sortfield,$sortorder); + if (! empty($arrayfields['t.task_label']['checked'])) print_liste_field_titre($arrayfields['t.task_label']['label'],$_SERVER['PHP_SELF'],'pt.label','',$params,'',$sortfield,$sortorder); + } + if (! empty($arrayfields['author']['checked'])) print_liste_field_titre($arrayfields['author']['label'],$_SERVER['PHP_SELF'],'','',$params,'',$sortfield,$sortorder); + if (! empty($arrayfields['t.note']['checked'])) print_liste_field_titre($arrayfields['t.note']['label'],$_SERVER['PHP_SELF'],'t.note','',$params,'',$sortfield,$sortorder); + if (! empty($arrayfields['t.task_duration']['checked'])) print_liste_field_titre($arrayfields['t.task_duration']['label'],$_SERVER['PHP_SELF'],'t.task_duration','',$params,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['value']['checked'])) print_liste_field_titre($arrayfields['value']['label'],$_SERVER['PHP_SELF'],'','',$params,'align="right"',$sortfield,$sortorder); + // Extra fields + /* + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + }*/ + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center" width="80"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; $tasktmp = new Task($db); @@ -802,7 +824,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) foreach ($tasks as $task_time) { $var=!$var; - print ""; + print ''; $date1=$db->jdate($task_time->task_date); $date2=$db->jdate($task_time->task_datehour); @@ -873,7 +895,8 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) $userstatic->id = $task_time->fk_user; $userstatic->lastname = $task_time->lastname; $userstatic->firstname = $task_time->firstname; - print $userstatic->getNomUrl(1); + $userstatic->photo = $task_time->photo; + print $userstatic->getNomUrl(-1); } print ''; if (! $i) $totalarray['nbfield']++; @@ -932,7 +955,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print $hookmanager->resPrint; // Action column - print ''; print ''; print ''; diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index ffadceafb2e..cfe05e28ec3 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -44,7 +44,7 @@ $action=GETPOST('action', 'alpha'); $id=GETPOST('account'); $ref=GETPOST('ref'); $dvid=GETPOST('dvid'); -$num=GETPOST('num'); +$numref=GETPOST('num'); // Security check $fieldid = (! empty($ref)?$ref:$id); @@ -116,7 +116,7 @@ if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; if ($id > 0) $param.='&id='.urlencode($id); -if (empty($num)) +if (empty($numref)) { /* * Vue liste tous releves confondus @@ -176,14 +176,14 @@ if (empty($num)) while ($i < min($numrows,$conf->liste_limit)) { $objp = $db->fetch_object($result); - $var=!$var; + if (! isset($objp->numr)) { // } else { - print ''; + print ''; // Calculate start amount $sql = "SELECT sum(b.amount) as amount"; @@ -240,7 +240,7 @@ else // Recherche valeur pour num = numero releve precedent $sql = "SELECT DISTINCT(b.num_releve) as num"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; - $sql.= " WHERE b.num_releve < '".$db->escape($num)."'"; + $sql.= " WHERE b.num_releve < '".$db->escape($numref)."'"; $sql.= " AND b.fk_account = ".$object->id; $sql.= " ORDER BY b.num_releve DESC"; @@ -252,7 +252,7 @@ else if ($numrows > 0) { $obj = $db->fetch_object($resql); - $num = $obj->num; + $numref = $obj->num; $found=true; } } @@ -262,7 +262,7 @@ else // Recherche valeur pour num = numero releve precedent $sql = "SELECT DISTINCT(b.num_releve) as num"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; - $sql.= " WHERE b.num_releve > '".$db->escape($num)."'"; + $sql.= " WHERE b.num_releve > '".$db->escape($numref)."'"; $sql.= " AND b.fk_account = ".$object->id; $sql.= " ORDER BY b.num_releve ASC"; @@ -274,7 +274,7 @@ else if ($numrows > 0) { $obj = $db->fetch_object($resql); - $num = $obj->num; + $numref = $obj->num; $found=true; } } @@ -286,13 +286,16 @@ else $mesprevnext=''; $mesprevnext.=''; - print load_fiche_titre($langs->trans("AccountStatement").' '.$num.', '.$langs->trans("BankAccount").' : '.$object->getNomUrl(0, 'receipts'), $mesprevnext, 'title_bank.png'); + + $title=$langs->trans("AccountStatement").' '.$numref.', '.$langs->trans("BankAccount").' : '.$object->getNomUrl(0, 'receipts'); + print load_fiche_titre($title, $mesprevnext, 'title_bank.png'); + //print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, 0, $nbtotalofrecords, 'title_bank.png', 0, '', '', 0, 1); print '
    '; print ""; @@ -315,7 +318,7 @@ else // Calcul du solde de depart du releve $sql = "SELECT sum(b.amount) as amount"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; - $sql.= " WHERE b.num_releve < '".$db->escape($num)."'"; + $sql.= " WHERE b.num_releve < '".$db->escape($numref)."'"; $sql.= " AND b.fk_account = ".$object->id; $resql=$db->query($sql); @@ -335,8 +338,8 @@ else $sql.= " FROM ".MAIN_DB_PREFIX."bank_account as ba"; $sql.= ", ".MAIN_DB_PREFIX."bank as b"; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bordereau_cheque as bc ON bc.rowid=b.fk_bordereau'; - $sql.= " WHERE b.num_releve='".$db->escape($num)."'"; - if (!isset($num)) $sql.= " OR b.num_releve is null"; + $sql.= " WHERE b.num_releve='".$db->escape($numref)."'"; + if (!isset($numref)) $sql.= " OR b.num_releve is null"; $sql.= " AND b.fk_account = ".$object->id; $sql.= " AND b.fk_account = ba.rowid"; $sql.= $db->order("b.datev, b.datec", "ASC"); // We add date of creation to have correct order when everything is done the same day @@ -368,9 +371,9 @@ else // Date de valeur print '\n"; print ''; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 66eca2409f3..7c428968c34 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3347,20 +3347,20 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so if ($cpt>=1) { - $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'':'data-role="button" ').'href="'.$file.'?page=0'.$options.'">1'; - if ($cpt > 2) $pagelist.='dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="inactive"':'data-role="button"').'>...'; - else if ($cpt == 2) $pagelist.='dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'':'data-role="button" ').'href="'.$file.'?page=1'.$options.'">2'; + $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>1'; + if ($cpt > 2) $pagelist.='dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="inactive"':'').'>...'; + else if ($cpt == 2) $pagelist.='dol_use_jmobile != 4)?' class="pagination"':'').'>2'; } do { if ($cpt==$page) { - $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="active"':'data-role="button"').'>'.($page+1).''; + $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="active"':'').'>'.($page+1).''; } else { - $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'':'data-role="button" ').'href="'.$file.'?page='.$cpt.$options.'">'.($cpt+1).''; + $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>'.($cpt+1).''; } $cpt++; } @@ -3368,14 +3368,14 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so if ($cpt<$nbpages) { - if ($cpt<$nbpages-2) $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="inactive"':'data-role="button"').'>...'; - else if ($cpt == $nbpages-2) $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'':'data-role="button" ').'href="'.$file.'?page='.($nbpages-2).$options.'">'.($nbpages - 1).''; - $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'':'data-role="button" ').'href="'.$file.'?page='.($nbpages-1).$options.'">'.$nbpages.''; + if ($cpt<$nbpages-2) $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="inactive"':'').'>...'; + else if ($cpt == $nbpages-2) $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>'.($nbpages - 1).''; + $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>'.$nbpages.''; } } else { - $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="active"':'data-role="button"').'>'.($page+1).""; + $pagelist.= 'dol_use_jmobile != 4)?' class="pagination"':'').'>dol_use_jmobile != 4)?'class="active"':'').'>'.($page+1).""; } } print_fleche_navigation($page, $file, $options, $nextpage, $pagelist, $morehtml, $savlimit, $totalnboflines, $hideselectlimit); // output the div and ul for previous/last completed with page numbers into $pagelist diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index a63593292b6..77c779b268e 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2469,6 +2469,7 @@ div.pagination .disabled a:focus { } div.pagination li.pagination .active { text-decoration: underline; + box-shadow: none; } div.pagination li.paginationafterarrows { margin-left: 10px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 26c4c4d0a93..553d2560790 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2533,6 +2533,7 @@ div.pagination .disabled a:focus { } div.pagination li.pagination .active { text-decoration: underline; + box-shadow: none; } div.pagination li.paginationafterarrows { margin-left: 10px; From 216bce608d38fa3c88ab1341e714c08dc43ccf4c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Apr 2017 23:28:06 +0200 Subject: [PATCH 099/233] Work on v6 look and feel --- htdocs/compta/bank/releve.php | 268 ++++++++++-------- .../compta/paiement/class/paiement.class.php | 12 +- htdocs/compta/salaries/card.php | 26 +- .../salaries/class/paymentsalary.class.php | 91 +++++- htdocs/fourn/class/paiementfourn.class.php | 12 +- htdocs/fourn/paiement/card.php | 18 +- 6 files changed, 268 insertions(+), 159 deletions(-) diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index fdf1ac27e7a..9d9826d0729 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -92,36 +92,46 @@ if ($id > 0 || ! empty($ref)) // Initialize technical object to manage context to save list fields $contextpage='banktransactionlist'.(empty($object->ref)?'':'-'.$object->id); -/* -*ZIP creation -*/ -if($action=="dl" && $num>0 && isset($_SESSION["releve"][$num])){ - unset($zip); - $log=''; - $filearray=$_SESSION["releve"][$num]; - $zipname = $num.'.zip'; - $zip = new ZipArchive; - $zip->open($zipname, ZipArchive::OVERWRITE); - foreach ($filearray as $key=> $files) { - if(is_array($files)){ - foreach ($files as $file) { - $zip->addFile($file["fullname"],$file["name"]);// - $log.=$key.','.$file["name"]."\n"; - } - }else{ - $log.=$key.','.$langs->trans("Nofile")."\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); + +// ZIP creation +if ($action=="dl" && $numref > 0) +{ + // TODO Replace this with a standard builddoc action that use a document generation module to build the ZIP + $log = ''; + + getAttachedFiles($db, $numref); // Build array $_SESSION["releve"][$numref] with all files to includes + + $filearray = $_SESSION["releve"][$numref]; + $zipname = $numref . '.zip'; + + $zip = new ZipArchive(); + $zip->open($zipname, ZipArchive::OVERWRITE); + foreach ($filearray as $key => $files) { + if (is_array($files)) { + foreach ($files as $file) { + $zip->addFile($file["fullname"], $file["name"]); // + $log .= $key . ',' . $file["name"] . "\n"; + } + } else { + $log .= $key . ',' . $langs->trans("Nofile") . "\n"; + } + } + $zip->addFromString('log '.$numref.'.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); + + unset($_SESSION["releve"][$numref]); + + exit; } -unset($_SESSION["releve"][$num]); + /* * View @@ -151,9 +161,7 @@ if ($id > 0) $param.='&id='.urlencode($id); if (empty($numref)) { - /* - * Vue liste tous releves confondus - */ + // List of all standing receipts $sql = "SELECT DISTINCT(b.num_releve) as numr"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; $sql.= " WHERE b.fk_account = ".$object->id; @@ -470,6 +478,14 @@ else $paymentvatstatic->ref=$langs->trans("Payment"); print ' '.$paymentvatstatic->getNomUrl(1); } + elseif ($links[$key]['type']=='payment_salary') + { + print ''; + print ' '.img_object($langs->trans('ShowPayment'),'payment').' '; + print $langs->trans("Payment"); + print ''; + $newline=0; + } elseif ($links[$key]['type']=='banktransfert') { // Do not show link to transfer since there is no transfer card (avoid confusion). Can already be accessed from transaction detail. if ($objp->amount > 0) @@ -512,6 +528,13 @@ else print ''; $newline=0; } + elseif ($links[$key]['type']=='user') { + print ''; + print img_object($langs->trans('ShowUser'),'user').' '; + print $links[$key]['label']; + print ''; + $newline=0; + } elseif ($links[$key]['type']=='sc') { print ''; print img_object($langs->trans('ShowBill'),'bill').' '; @@ -555,7 +578,6 @@ else dol_print_error($db); } } - print Get_attach_files($db,$objp->rowid,$num,$objp->label); print ""; if ($objp->amount < 0) @@ -598,9 +620,13 @@ else print ""; print "\n"; - // download button - echo ''.$langs->trans('DownloadFile')." \n"; - + + // Add a download button + if ($conf->global->MAIN_FEATURES_LEVEL >= 2) // Started a rewrite to make this feature more Dolibarr compliant. Still need dev to be completed. + { + // TODO Replace this with standard box to generate document. + print ''.$langs->trans('DownloadPackageWithAllDocuments')." \n"; + } } @@ -608,102 +634,102 @@ llxFooter(); $db->close(); -/*Function to generate the HTML code used to show the file name & download link attached to the Item covered by the bank line - * @param $db Object database object - * @param $bankId int bank line id - * @param $num int bank statement - * @param $label string label used to optimise the sql querry + + + +/** + * Function to generate the HTML code used to show the file name & download link attached to the Item covered by the bank line * + * @param DoliDB $db database object + * @param int $bankId bank line id + * @param int $num bank statement + * @param string $label label used to optimise the sql querry */ -function Get_attach_files($db, $bankId,$num,$label=''){ - $out=''; - global$conf; - $sql='SELECT u.url_id, u.type,ff.rowid as id , ff.`ref` AS reff, f.facnumber AS `ref`,'; - $sql.=' e.`ref` AS refe, sp.rowid AS ids, d.rowid AS idd'; - $sql.=' FROM '.MAIN_DB_PREFIX.'bank_url AS u'; - if ( !empty($label) || $label=='(CustomerInvoicePayment)'){ - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiement AS p ON p.fk_bank = u.fk_bank'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiement_facture AS pf ON pf.fk_paiement = p.rowid'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'facture AS f ON f.rowid = pf.fk_facture'; +function getAttachedFiles($db, $numref, $label='') +{ + $out = ''; + global $conf; + $sql = 'SELECT u.url_id, u.type,ff.rowid as id , ff.`ref` AS reff, f.facnumber AS `ref`,'; + $sql .= ' e.`ref` AS refe, sp.rowid AS ids, d.rowid AS idd'; + $sql .= ' FROM ' . MAIN_DB_PREFIX . 'bank_url AS u, ' . MAIN_DB_PREFIX . 'bank AS b'; + if (! empty($label) || $label == '(CustomerInvoicePayment)') { + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'paiement AS p ON p.fk_bank = u.fk_bank'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'paiement_facture AS pf ON pf.fk_paiement = p.rowid'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'facture AS f ON f.rowid = pf.fk_facture'; } - if( !empty($label) || $label=='(SupplierInvoicePayment)'){ - //invoice suplier (SupplierInvoicePayment) - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn AS fp ON fp.fk_bank = u.fk_bank'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn AS fpf ON fpf.fk_paiementfourn = fp.rowid'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn AS ff ON ff.rowid = fpf.fk_facturefourn'; + if (! empty($label) || $label == '(SupplierInvoicePayment)') { + // invoice suplier (SupplierInvoicePayment) + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'paiementfourn AS fp ON fp.fk_bank = u.fk_bank'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'paiementfourn_facturefourn AS fpf ON fpf.fk_paiementfourn = fp.rowid'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'facture_fourn AS ff ON ff.rowid = fpf.fk_facturefourn'; } - if( !empty($label) || $label=='(ExpenseReportPayment)'){ - //EXPENSEs (ExpenseReportPayment) - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_expensereport AS ep ON ep.fk_bank = u.fk_bank'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport AS e ON e.rowid = ep.fk_expensereport'; + if (! empty($label) || $label == '(ExpenseReportPayment)') { + // EXPENSEs (ExpenseReportPayment) + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'payment_expensereport AS ep ON ep.fk_bank = u.fk_bank'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'expensereport AS e ON e.rowid = ep.fk_expensereport'; } - if( !empty($label) || $label=='(DonationPayment)'){ - //donation - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_donation AS dp ON dp.fk_bank = u.fk_bank'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'don AS d ON d.rowid = dp.fk_donation'; + if (! empty($label) || $label == '(DonationPayment)') { + // donation + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'payment_donation AS dp ON dp.fk_bank = u.fk_bank'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'don AS d ON d.rowid = dp.fk_donation'; } - if( !empty($label) || $label=='(SalaryPayment)'){ - //loan -// $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_loan AS lp ON lp.fk_bank = u.fk_bank'; - //salary - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_salary AS sp ON sp.fk_bank = u.fk_bank'; + if (! empty($label) || $label == '(SalaryPayment)') { + // loan + // $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_loan AS lp ON lp.fk_bank = u.fk_bank'; + // salary + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'payment_salary AS sp ON sp.fk_bank = u.fk_bank'; } - //END SQL - $sql.=" WHERE u.fk_bank in('".$bankId."')AND u.type in ('payment','payment_supplier','payment_expensereport','payment_salary','payment_donation' )"; + // END SQL + $sql .= " WHERE u.fk_bank = b.rowid AND u.type in ('payment','payment_supplier','payment_expensereport','payment_salary','payment_donation' )"; $resd = $db->query($sql); - $files=array(); - $link=''; - if ($resd) - { - $numd = $db->num_rows($resd); - $upload_dir =''; - $i=0; - if($numd>0) - { - - + $files = array(); + $link = ''; + if ($resd) { + $numd = $db->num_rows($resd); + $upload_dir = ''; + $i = 0; + if ($numd > 0) + { $objd = $db->fetch_object($resd); - - switch($objd->type){ - case "payment": - $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 "payment_supplier": - $subdir=get_exdir($objd->id,2,0,0,$objd,'invoice_supplier').$objd->reff; - $upload_dir = $conf->fournisseur->facture->dir_output.'/'.$subdir; - $link="../../document.php?modulepart=facture_fournisseur&file=".str_replace('/','%2F',$subdir).'%2F'; - break; - case "payment_expensereport": - $subdir=dol_sanitizeFileName($objd->refe); - $upload_dir = $conf->expensereport->dir_output.'/'.$subdir; - $link="../../document.php?modulepart=expensereport&file=".str_replace('/','%2F',$subdir).'%2F'; - break; - case "payment_salary": - $subdir=dol_sanitizeFileName($objd->ids); - $upload_dir = $conf->salaries->dir_output.'/'.$subdir; - $link="../../document.php?modulepart=salaries&file=".str_replace('/','%2F',$subdir).'%2F'; - break; - case "payment_donation": - $subdir=get_exdir(null,2,0,1,$objd,'donation'). '/'. dol_sanitizeFileName($objd->idd); - $upload_dir = $conf->don->dir_output . '/' . $subdir; - $link="../../document.php?modulepart=don&file=".str_replace('/','%2F',$subdir).'%2F'; - break; - default: - break; + + switch ($objd->type) { + case "payment": + $subdir = dol_sanitizeFileName($objd->ref); + $upload_dir = $conf->facture->dir_output . '/' . $subdir; + $link = DOL_URL_ROOT."/document.php?modulepart=facture&file=" . str_replace('/', '%2F', $subdir) . '%2F'; + break; + case "payment_supplier": + $subdir = get_exdir($objd->id, 2, 0, 0, $objd, 'invoice_supplier') . $objd->reff; + $upload_dir = $conf->fournisseur->facture->dir_output . '/' . $subdir; + $link = DOL_URL_ROOT."/document.php?modulepart=facture_fournisseur&file=" . str_replace('/', '%2F', $subdir) . '%2F'; + break; + case "payment_expensereport": + $subdir = dol_sanitizeFileName($objd->refe); + $upload_dir = $conf->expensereport->dir_output . '/' . $subdir; + $link = DOL_URL_ROOT."/document.php?modulepart=expensereport&file=" . str_replace('/', '%2F', $subdir) . '%2F'; + break; + case "payment_salary": + $subdir = dol_sanitizeFileName($objd->ids); + $upload_dir = $conf->salaries->dir_output . '/' . $subdir; + $link = DOL_URL_ROOT."/document.php?modulepart=salaries&file=" . str_replace('/', '%2F', $subdir) . '%2F'; + break; + case "payment_donation": + $subdir = get_exdir(null, 2, 0, 1, $objd, 'donation') . '/' . dol_sanitizeFileName($objd->idd); + $upload_dir = $conf->don->dir_output . '/' . $subdir; + $link = DOL_URL_ROOT."/document.php?modulepart=don&file=" . str_replace('/', '%2F', $subdir) . '%2F'; + break; + default: + break; } - if(!empty($upload_dir)){ - $files=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$','',SORT_ASC,1); - foreach ($files as $key => $file){ - $out.= '
    '.$file['name'].''; - } - $_SESSION["releve"][$num][]=$files; + if (! empty($upload_dir)) + { + $files = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview\.png)$', '', SORT_ASC, 1); + $_SESSION["releve"][$numref][] = $files; } - } - } - $db->free($resd); - return $out; + } + } + + $db->free($resd); + return $out; } diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 099d05cfa84..61d2b5a3b8a 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -37,7 +37,8 @@ class Paiement extends CommonObject { public $element='payment'; public $table_element='paiement'; - + public $picto = 'payment'; + var $facid; var $datepaye; /** @@ -1016,7 +1017,7 @@ class Paiement extends CommonObject global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage $langs->load('compta'); - if ($mode == 0) + /*if ($mode == 0) { if ($status == 0) return $langs->trans('ToValidate'); if ($status == 1) return $langs->trans('Validated'); @@ -1046,7 +1047,12 @@ class Paiement extends CommonObject if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); } - return $langs->trans('Unknown'); + if ($mode == 6) + { + if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); + if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); + }*/ + return ''; } } diff --git a/htdocs/compta/salaries/card.php b/htdocs/compta/salaries/card.php index df83f5b9958..569aa81629e 100644 --- a/htdocs/compta/salaries/card.php +++ b/htdocs/compta/salaries/card.php @@ -202,11 +202,7 @@ if ($id) } } -/* ************************************************************************** */ -/* */ -/* create mode */ -/* */ -/* ************************************************************************** */ +// Create if ($action == 'create') { $year_current = strftime("%Y",dol_now()); @@ -332,19 +328,19 @@ if ($id) $head=salaries_prepare_head($object); - dol_fiche_head($head, 'card', $langs->trans("SalaryPayment"), 0, 'payment'); - - print '
    '.$form->select_dolusers($search_user > 0 ? $search_user : -1, 'search_user', 1).''; + print ''; $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); print $searchpitco; print '
    '; + print ''; if ($action == 'editline' && $_GET['lineid'] == $task_time->rowid) { print ''; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 112609ce521..8529a0c0cfc 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1987,7 +1987,7 @@ class User extends CommonObject if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0; $result=''; $label=''; - $linkstart=''; $linkend=''; + $link=''; $linkstart=''; $linkend=''; if (! empty($this->photo)) { @@ -2086,7 +2086,9 @@ class User extends CommonObject } $result.=$linkend; //if ($withpictoimg == -1) $result.=''; + $result.=$companylink; + return $result; } From fe4f71296f13a2231bfbe603d8ed9dd256026cfd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Apr 2017 21:55:23 +0200 Subject: [PATCH 097/233] FIX #6636 Complete fix --- htdocs/compta/bank/categ.php | 2 +- htdocs/core/menus/standard/eldy.lib.php | 4 ++-- htdocs/langs/en_US/categories.lang | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/bank/categ.php b/htdocs/compta/bank/categ.php index 51030242fce..ae35eee80fa 100644 --- a/htdocs/compta/bank/categ.php +++ b/htdocs/compta/bank/categ.php @@ -80,7 +80,7 @@ if ($categid) { llxHeader(); -print load_fiche_titre($langs->trans("Rubriques"), '', 'title_bank.png'); +print load_fiche_titre($langs->trans("RubriquesTransactions"), '', 'title_bank.png'); print '
    '; print ''; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index eab8f5a8c19..aa98f23b2ad 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1073,8 +1073,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $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&type=5",$langs->trans("NewCategory"),1,$user->rights->categorie->creer); - $newmenu->add("/compta/bank/categ.php",$langs->trans("RubriquesTransactions"),1,$user->rights->banque->configurer); - + $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'); } // Prelevements diff --git a/htdocs/langs/en_US/categories.lang b/htdocs/langs/en_US/categories.lang index 976c8a50d93..b8a1e5ef58b 100644 --- a/htdocs/langs/en_US/categories.lang +++ b/htdocs/langs/en_US/categories.lang @@ -1,6 +1,7 @@ # Dolibarr language file - Source file is en_US - categories Rubrique=Tag/Category Rubriques=Tags/Categories +RubriquesTransactions=Tags/Categories of transactions categories=tags/categories NoCategoryYet=No tag/category of this type created In=In From a99a4be9e01594d075216d767edf2e6f7177215d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Apr 2017 22:31:45 +0200 Subject: [PATCH 098/233] Work on 6.0 look and feel --- htdocs/compta/bank/class/account.class.php | 5 +-- htdocs/compta/bank/ligne.php | 2 +- htdocs/compta/bank/releve.php | 37 ++++++++++++---------- htdocs/core/lib/functions.lib.php | 18 +++++------ htdocs/theme/eldy/style.css.php | 1 + htdocs/theme/md/style.css.php | 1 + 6 files changed, 35 insertions(+), 29 deletions(-) diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 8925a67d593..d360dc5207e 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1243,9 +1243,10 @@ class Account extends CommonObject * * @param int $withpicto Include picto into link * @param string $mode ''=Link to card, 'transactions'=Link to transactions card + * @param string $option ''=Show ref, 'reflabel'=Show ref+label * @return string Chaine avec URL */ - function getNomUrl($withpicto=0, $mode='') + function getNomUrl($withpicto=0, $mode='', $option='') { global $conf, $langs; @@ -1279,7 +1280,7 @@ class Account extends CommonObject } if ($withpicto) $result.=($link.img_object($label, 'account', 'class="classfortooltip"').$linkend.' '); - $result.=$link.$this->ref.$linkend; + $result.=$link.$this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '').$linkend; return $result; } diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index f77ac86af7f..360a0d15a00 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -293,7 +293,7 @@ if ($result) // Bank account print '
    '.$langs->trans("Account").''; - print $acct->getNomUrl(1,'transactions'); + print $acct->getNomUrl(1,'transactions','reflabel'); print '
    '.$objp->numr.'
    '.$objp->numr.''; print dol_print_date($db->jdate($objp->dv),"day") .' '; - print ''; + print ''; print img_edit_remove() . " "; - print ''; + print ''; print img_edit_add() .""; print "
    '; + dol_fiche_head($head, 'card', $langs->trans("SalaryPayment"), -1, 'payment'); $linkback = ''.$langs->trans("BackToList").''; - print ""; - print ''; + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', ''); + + print '
    '; + print '
    '; + + print '
    '.$langs->trans("Ref").''; - print $form->showrefnav($object, 'id', $linkback, 1, 'rowid', 'ref', ''); - print '
    '; // Employee - print '
    '.$langs->trans("Employee").''; + print '
    '.$langs->trans("Employee").''; $usersal=new User($db); $usersal->fetch($object->fk_user); print $usersal->getNomUrl(1); @@ -394,7 +390,9 @@ if ($id) $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook print '
    '; - + + print '
    '; + dol_fiche_end(); diff --git a/htdocs/compta/salaries/class/paymentsalary.class.php b/htdocs/compta/salaries/class/paymentsalary.class.php index a4bee09d7de..6c151272035 100644 --- a/htdocs/compta/salaries/class/paymentsalary.class.php +++ b/htdocs/compta/salaries/class/paymentsalary.class.php @@ -33,20 +33,21 @@ 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 $tms; - var $fk_user; - var $datep; - var $datev; - var $amount; - var $type_payment; - var $num_payment; - var $label; - var $datesp; - var $dateep; - var $fk_bank; - var $fk_user_author; - var $fk_user_modif; + public $picto='payment'; + + public $tms; + public $fk_user; + public $datep; + public $datev; + public $amount; + public $type_payment; + public $num_payment; + public $label; + public $datesp; + public $dateep; + public $fk_bank; + public $fk_user_author; + public $fk_user_modif; /** @@ -547,4 +548,66 @@ class PaymentSalary extends CommonObject } } + + /** + * Retourne le libelle du statut d'une facture (brouillon, validee, abandonnee, payee) + * + * @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 + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->statut,$mode); + } + + /** + * 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 + */ + function LibStatut($status,$mode=0) + { + global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage + + $langs->load('compta'); + /*if ($mode == 0) + { + if ($status == 0) return $langs->trans('ToValidate'); + if ($status == 1) return $langs->trans('Validated'); + } + if ($mode == 1) + { + if ($status == 0) return $langs->trans('ToValidate'); + if ($status == 1) return $langs->trans('Validated'); + } + if ($mode == 2) + { + if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate'); + if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated'); + } + if ($mode == 3) + { + if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1'); + if ($status == 1) return img_picto($langs->trans('Validated'),'statut4'); + } + if ($mode == 4) + { + if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate'); + if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated'); + } + if ($mode == 5) + { + if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); + if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); + } + if ($mode == 6) + { + if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); + if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); + }*/ + return ''; + } + } diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php index 5d8279b1c54..be87fbc7512 100644 --- a/htdocs/fourn/class/paiementfourn.class.php +++ b/htdocs/fourn/class/paiementfourn.class.php @@ -36,7 +36,8 @@ class PaiementFourn extends Paiement { public $element='payment_supplier'; public $table_element='paiementfourn'; - + public $picto = 'payment'; + var $statut; //Status of payment. 0 = unvalidated; 1 = validated // 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 @@ -486,7 +487,7 @@ class PaiementFourn extends Paiement global $langs; $langs->load('compta'); - if ($mode == 0) + /*if ($mode == 0) { if ($status == 0) return $langs->trans('ToValidate'); if ($status == 1) return $langs->trans('Validated'); @@ -516,7 +517,12 @@ class PaiementFourn extends Paiement if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); } - return $langs->trans('Unknown'); + if ($mode == 6) + { + if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); + if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); + }*/ + return ''; } diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index 9cb44a92bb8..c8e882e5003 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -179,7 +179,7 @@ $formfile = new FormFile($db); $head = payment_supplier_prepare_head($object); -dol_fiche_head($head, 'payment', $langs->trans('SupplierPayment'), 0, 'payment'); +dol_fiche_head($head, 'payment', $langs->trans('SupplierPayment'), -1, 'payment'); if ($result > 0) { @@ -201,15 +201,23 @@ if ($result > 0) } + $linkback = '' . $langs->trans("BackToList") . ''; + + + dol_banner_tab($object,'id',$linkback,1,'rowid','ref'); + + print '
    '; + print '
    '; + print ''; - print ''; + /*print ''; print ''; + print '';*/ // Date payment - print ''; @@ -270,6 +278,8 @@ if ($result > 0) print '
    '.$langs->trans('Ref').''; print $form->showrefnav($object,'id','',1,'rowid','ref'); - print '
    '.$form->editfieldkey("Date",'datep',$object->date,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).''; + print '
    '.$form->editfieldkey("Date",'datep',$object->date,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).''; print $form->editfieldval("Date",'datep',$object->date,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer,'datepicker','',null,$langs->trans('PaymentDateUpdateSucceeded')); print '
    '; + print '
    '; + print '
    '; /** From 76687028063578ceae53b626d93348bbeee32161 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 7 Apr 2017 08:56:10 +0200 Subject: [PATCH 100/233] fix: missing attribute update --- htdocs/fourn/class/fournisseur.commande.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 98939ee01f2..70c3f1a831a 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1503,6 +1503,7 @@ class CommandeFournisseur extends CommonOrder $this->line->product_type=$product_type; $this->line->remise_percent=$remise_percent; $this->line->subprice=$pu_ht; + $this->line->rang=$this->rang; $this->line->info_bits=$info_bits; $this->line->vat_src_code=$vat_src_code; From ea44e14b605725457bf6cf5f6293c9acf47184e3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Apr 2017 11:01:12 +0200 Subject: [PATCH 101/233] Start debug the variant module --- htdocs/compta/index.php | 12 +- htdocs/core/class/html.formfile.class.php | 2 + htdocs/langs/en_US/products.lang | 3 + htdocs/product/card.php | 1 + htdocs/product/class/product.class.php | 5 + htdocs/product/index.php | 16 +-- htdocs/variants/combinations.php | 162 ++++++++++++++-------- htdocs/variants/generator.php | 46 +++--- 8 files changed, 143 insertions(+), 104 deletions(-) diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index ea8d47b264e..736d5696c3e 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -233,7 +233,6 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- if ( $resql ) { - $var = false; $num = $db->num_rows($resql); print ''; @@ -248,7 +247,7 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- while ($i < $num) { $obj = $db->fetch_object($resql); - print ''; $tot_ttc+=$obj->total_ttc; $i++; - $var=!$var; } print ''; @@ -278,7 +276,7 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- } else { - print ''; + print ''; } print "
    '; + print '
    '; $facturesupplierstatic->ref=$obj->ref; $facturesupplierstatic->id=$obj->rowid; $facturesupplierstatic->total_ht=$obj->total_ht; @@ -269,7 +268,6 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- print '
    '.$langs->trans("Total").'
    '.$langs->trans("NoInvoice").'
    '.$langs->trans("NoInvoice").'

    "; $db->free($resql); @@ -768,6 +766,7 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire) $num = $db->num_rows($resql); $i = 0; + print '
    '; print ''; print ''; print ''; @@ -848,7 +847,7 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire) if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) $colspan++; print ''; } - print '
    '.$langs->trans("BillsCustomersUnpaid",$num).' '.$num.''.$langs->trans("DateDue").'
    '.$langs->trans("NoInvoice").'

    '; + print '

    '; $db->free($resql); } else @@ -890,6 +889,7 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- $var=false; $num = $db->num_rows($resql); + print '
    '; print ''; print ''; print ''; @@ -948,7 +948,7 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- if (! empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) $colspan++; print ''; } - print '
    '.$langs->trans("BillsSuppliersUnpaid",$num).' '.$num.''.$langs->trans("DateDue").'
    '.$langs->trans("NoInvoice").'

    '; + print '

    '; } else { diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 1e2dc1c4938..647d0cf6a76 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -593,6 +593,7 @@ class FormFile $out.= ''; $out.= load_fiche_titre($titletoshow, '', ''); + $out.= '
    '; $out.= ''; $out.= ''; @@ -802,6 +803,7 @@ class FormFile { // Affiche pied du tableau $out.= "
    \n"; + $out.= "
    \n"; if ($genallowed) { if (empty($noform)) $out.= ''."\n"; diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 046521e398e..ef4c13c89cc 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -287,6 +287,9 @@ HideProductCombinations=Hide products variant in the products selector ProductCombination=Variant NewProductCombination=New variant EditProductCombination=Editing variant +NewProductCombinations=New variants +EditProductCombinations=Editing variants +SelectCombination=Select combination ProductCombinationGenerator=Variants generator Features=Features PriceImpact=Price impact diff --git a/htdocs/product/card.php b/htdocs/product/card.php index ac260fc99fb..0c6109ba64a 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -2015,6 +2015,7 @@ if (! empty($conf->global->PRODUCT_ADD_FORM_ADD_TO) && $object->id && ($action = /* * Documents generes */ + if ($action != 'edit' && $action != 'delete') { print '
    '; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 23be6de5111..5f5b6f6eae9 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3559,6 +3559,11 @@ class Product extends CommonObject 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"'); } + if ($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"'); + } return $langs->trans('Unknown'); } diff --git a/htdocs/product/index.php b/htdocs/product/index.php index 355e0d2757f..73447e456e6 100644 --- a/htdocs/product/index.php +++ b/htdocs/product/index.php @@ -130,26 +130,26 @@ print ''; print ''; if (! empty($conf->product->enabled)) { - $statProducts = ""; + $statProducts = ''; $statProducts.= ''; $statProducts.= ""; - $statProducts.= ""; + $statProducts.= ''; $statProducts.= ''; $statProducts.= ""; - $statProducts.= ""; + $statProducts.= ''; $statProducts.= ''; $statProducts.= ""; } if (! empty($conf->service->enabled)) { - $statServices = ""; + $statServices = ''; $statServices.= ''; $statServices.= ""; - $statServices.= ""; + $statServices.= ''; $statServices.= ''; $statServices.= ""; - $statServices.= ""; + $statServices.= ''; $statServices.= ''; $statServices.= ""; @@ -325,10 +325,10 @@ if ($result) print ''; } print '"; print '"; print "\n"; $i++; diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index dabace75ac0..cfbec4a8016 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -36,6 +36,7 @@ $price_impact = (float) GETPOST('price_impact'); $price_impact_percent = (bool) GETPOST('price_impact_percent'); $form = new Form($db); $action = GETPOST('action'); +$cancel = GETPOST('cancel'); // Security check $fieldvalue = (! empty($id) ? $id : $ref); @@ -57,6 +58,10 @@ if ($id > 0 || $ref) * Actions */ +if ($cancel) { + $action=''; +} + if (! $object->isProduct()) { header('Location: '.dol_buildpath('/product/card.php?id='.$object->id, 2)); exit(); @@ -107,7 +112,7 @@ if ($_POST) { $db->begin(); if (!$prodcomb->fetchByProductCombination2ValuePairs($id, $sanit_features)) { - if (ProductCombination::createProductCombination($product, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact)) { + if (ProductCombination::createProductCombination($object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact)) { $db->commit(); setEventMessage($langs->trans('RecordSaved')); header('Location: '.dol_buildpath('/variants/combinations.php?id='.$id, 2)); @@ -175,7 +180,7 @@ if ($_POST) { setEventMessage($langs->trans('RecordSaved')); } - } else { + } elseif ($valueid > 0) { if ($prodcomb->fetch($valueid) < 0) { dol_print_error($db, $langs->trans('ErrorRecordNotFound')); @@ -256,6 +261,9 @@ if ($action === 'confirm_deletecombination') { * View */ +$form = new Form($db); + + if (! empty($id) || ! empty($ref)) { llxHeader("", "", $langs->trans("CardProduct".$object->type)); @@ -342,6 +350,7 @@ if (! empty($id) || ! empty($ref)) { var select = jQuery("select#features"); select.empty(); + jQuery("form#combinationform input[type=hidden]").detach(); jQuery.each(variants_selected.index, function (key, val) { @@ -359,11 +368,12 @@ if (! empty($id) || ! empty($ref)) { jQuery(document).ready(function() { jQuery("select#attribute").change(function () { - console.log("Change of field attribute"); + console.log("Change of field variant attribute"); var select = jQuery("select#value"); if (!jQuery(this).val().length || jQuery(this).val() == '-1') { select.empty(); + select.append(''); return; } @@ -373,22 +383,27 @@ if (! empty($id) || ! empty($ref)) { id: jQuery(this).val() }, function(data) { if (data.error) { - jQuery("select#value").empty(); + select.empty(); + select.append(''); return alert(data.error); } select.empty(); - /* console.log(data.length); */ + select.append(''); jQuery(data).each(function (key, val) { keyforoption = val.id valforoption = val.value - jQuery("select#value").append(''); + select.append(''); }); }); }); + /* Click on button Add combination + @FIXME Not compatible with all browsers. + */ jQuery("#addfeature").click(function () { + console.log("Click on add"); var selectedattr = jQuery("select[name=attribute] option:selected"); var selectedvalu = jQuery("select[name=value] option:selected"); @@ -438,54 +453,69 @@ if (! empty($id) || ! empty($ref)) { '; + print ''; + print ''; + print dol_fiche_head(); ?>
    '.$langs->trans("Statistics").'
    '.$langs->trans("ProductsNotOnSell").''.round($prodser[0][0]).'
    '.$langs->trans("ProductsOnSell").''.round($prodser[0][1]).'
    '.$langs->trans("ProductsOnSellAndOnBuy").''.round($prodser[0][2]).'
    '.$langs->trans("ServicesNotOnSell").''.round($prodser[1][0]).'
    '.$langs->trans("ServicesOnSell").''.round($prodser[1][1]).'
    '.$langs->trans("ServicesOnSellAndOnBuy").''.round($prodser[1][2]).'
    '; - print $product_static->LibStatut($objp->tosell,5,0); + print $product_static->LibStatut($objp->tosell,3,0); print "'; - print $product_static->LibStatut($objp->tobuy,5,1); + print $product_static->LibStatut($objp->tobuy,3,1); print "
    + - + - - - - + +
    +
    + trans("SelectCombination"); ?> +
    +
    + + + + + + +
    + +
    + - - +
    +
    +
    - -

    - -
    + >
    @@ -494,8 +524,10 @@ if (! empty($id) || ! empty($ref)) { ?>
    - -
    + +   + +
    @@ -509,7 +541,6 @@ if (! empty($id) || ! empty($ref)) { if ($action === 'delete') { if ($prodcomb->fetch($valueid) > 0) { - $form = new Form($db); $prodstatic->fetch($prodcomb->fk_product_child); print $form->formconfirm( @@ -524,8 +555,6 @@ if (! empty($id) || ! empty($ref)) { } } elseif ($action === 'copy') { - $form = new Form($db); - print $form->formconfirm( 'combinations.php?id='.$id, $langs->trans('CloneCombinationsProduct'), @@ -570,50 +599,64 @@ if (! empty($id) || ! empty($ref)) { }); - - - - - " class="button"> -
    -
    '; + print '
    '; if ($productCombinations) { print ''.$langs->trans('Copy').''; } + print ''.$langs->trans('NewProductCombination').''; - print ''.$langs->trans('ProductCombinationGenerator').''; + + if (empty($conf->dol_optimize_smallscreen) && $conf->use_javascript_ajax) // Bugged page. Too much useless javascript. + { + print ''.$langs->trans('ProductCombinationGenerator').''; + } + print '
    '; + print '
    '; + print ''; + $aaa=''; + if (count($productCombinations)) + { + $aaa = ''; + $aaa .= ''; + $aaa .= ''; + $aaa .= ''; + } + $title = $langs->trans("ProductCombinations"); + + print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $aaa, 0); + + print '
    '; ?> - - + + + + + + + - - - - - - - fetch($currcomb->fk_product_child); ?> - > - + - - + + - +
    + trans('Product') ?>trans('Combination') ?>trans('PriceImpact') ?>trans('WeightImpact') ?>trans('OnSell') ?>trans('OnBuy') ?> trans('Product') ?>trans('Combination') ?>trans('PriceImpact') ?>trans('WeightImpact') ?>trans('OnSell') ?>trans('OnBuy') ?>
    getNomUrl(1) ?> variation_price >= 0 ? '+' : '').price($currcomb->variation_price).($currcomb->variation_price_percentage ? ' %' : '') ?>variation_weight >= 0 ? '+' : '').price($currcomb->variation_weight).' '.measuring_units_string($prodstatic->weight_units, 'weight') ?>variation_price >= 0 ? '+' : '').price($currcomb->variation_price).($currcomb->variation_price_percentage ? ' %' : '') ?>variation_weight >= 0 ? '+' : '').price($currcomb->variation_weight).' '.measuring_units_string($prodstatic->weight_units, 'weight') ?> getLibStatut(2, 0) ?> getLibStatut(2, 1) ?> - - + + +
    - - - - '; + print ''; } } llxFooter(); + +$db->close(); diff --git a/htdocs/variants/generator.php b/htdocs/variants/generator.php index b709f240551..7b0358fd176 100644 --- a/htdocs/variants/generator.php +++ b/htdocs/variants/generator.php @@ -130,6 +130,8 @@ if ($_POST) { } } + + /* * View */ @@ -140,37 +142,21 @@ if (! empty($id) || ! empty($ref)) { llxHeader("", "", $langs->trans("CardProduct".$object->type)); - if ($result) { - $head = product_prepare_head($object); - $titre = $langs->trans("CardProduct".$object->type); - $picto = ($object->type == Product::TYPE_SERVICE ? 'service' : 'product'); - + if ($result > 0) + { + $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); - - print ''; - - // Reference - print ''; - print ''; - print ''; - - // Label - print ''; - - // Status (to sell) - print ''; - - // Status (to buy) - print ''; - - print '
    '.$langs->trans("Ref").''; - print $form->showrefnav($object, 'id', '', 0); - print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("Status").' ('.$langs->trans("Sell").')'; - print $object->getLibStatut(2, 0); - print '
    '.$langs->trans("Status").' ('.$langs->trans("Buy").')'; - print $object->getLibStatut(2, 1); - print '
    '; - + + $linkback = ''.$langs->trans("BackToList").''; + $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(); } From a6ec22d7fee41c954b37249909271c6370047eff Mon Sep 17 00:00:00 2001 From: altatof Date: Fri, 7 Apr 2017 12:06:15 +0200 Subject: [PATCH 102/233] FIX: dont lose supplier ref if no supplier price in database --- htdocs/fourn/class/fournisseur.commande.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index b2f2d3dc3c3..44364a884eb 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1373,7 +1373,7 @@ class CommandeFournisseur extends CommonOrder if ($result > 0) { $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice - $ref = $prod->ref_fourn; // Ref supplier price set by get_buyprice + $fourn_ref = $prod->ref_fourn; // Ref supplier price set by get_buyprice } if ($result == 0) // If result == 0, we failed to found the supplier reference price { @@ -1457,7 +1457,7 @@ class CommandeFournisseur extends CommonOrder $sql.= ", '".$localtax1_type."',"; $sql.= " '".$localtax2_type."'"; - $sql.= ", ".$remise_percent.",'".price2num($subprice,'MU')."','".$ref."',"; + $sql.= ", ".$remise_percent.",'".price2num($subprice,'MU')."','".$fourn_ref."',"; $sql.= "'".price2num($total_ht)."',"; $sql.= "'".price2num($total_tva)."',"; $sql.= "'".price2num($total_localtax1)."',"; From 919633b2beb65208d4b9c309b3dbf28a4ffd8d36 Mon Sep 17 00:00:00 2001 From: altatof Date: Fri, 7 Apr 2017 12:10:01 +0200 Subject: [PATCH 103/233] escape supplier ref --- htdocs/fourn/class/fournisseur.commande.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 44364a884eb..99babcda7fe 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1457,7 +1457,7 @@ class CommandeFournisseur extends CommonOrder $sql.= ", '".$localtax1_type."',"; $sql.= " '".$localtax2_type."'"; - $sql.= ", ".$remise_percent.",'".price2num($subprice,'MU')."','".$fourn_ref."',"; + $sql.= ", ".$remise_percent.",'".price2num($subprice,'MU')."','".$this->db->escape($fourn_ref)."',"; $sql.= "'".price2num($total_ht)."',"; $sql.= "'".price2num($total_tva)."',"; $sql.= "'".price2num($total_localtax1)."',"; From aa47575b13f64e2b062a796168be7feb2fd8252c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Apr 2017 12:22:59 +0200 Subject: [PATCH 104/233] Serious debug of variant module. No more fu.. js errors on smarpthone. --- htdocs/langs/en_US/products.lang | 3 +- htdocs/variants/combinations.php | 282 +++++++++++++++---------------- 2 files changed, 140 insertions(+), 145 deletions(-) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index ef4c13c89cc..72ec89c55d3 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -283,6 +283,7 @@ ProductAttributeValueDeleteDialog=Are you sure you want to delete the value "%s" ProductCombinationDeleteDialog=Are you sure want to delete the variant of the product "%s"? ProductCombinationAlreadyUsed=There was an error while deleting the variant. Please check it is not being used in any object ProductCombinations=Variants +PropagateVariant=Propagate variants HideProductCombinations=Hide products variant in the products selector ProductCombination=Variant NewProductCombination=New variant @@ -307,7 +308,7 @@ NbOfDifferentValues=Nb of different values NbProducts=Nb. of products ParentProduct=Parent product HideChildProducts=Hide variant products -ConfirmCloneProductCombinations=Would you like to copy all the product variant to the product with the given reference? +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 ErrorDestinationProductNotFound=Destination product not found diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index cfbec4a8016..4342b352478 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -1,6 +1,6 @@ +/* Copyright (C) 2016 Marcos García + * Copyright (C) 2017 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,7 +35,12 @@ $weight_impact = (float) GETPOST('weight_impact'); $price_impact = (float) GETPOST('price_impact'); $price_impact_percent = (bool) GETPOST('price_impact_percent'); $form = new Form($db); -$action = GETPOST('action'); + +$action=GETPOST('action','alpha'); +$massaction=GETPOST('massaction','alpha'); +$show_files=GETPOST('show_files','int'); +$confirm=GETPOST('confirm','alpha'); +$toselect = GETPOST('toselect', 'array'); $cancel = GETPOST('cancel'); // Security check @@ -53,6 +58,8 @@ if ($id > 0 || $ref) $object->fetch($id, $ref); } +$selectedvariant = $_SESSION['addvariant_'.$object->id]; + /* * Actions @@ -60,13 +67,25 @@ if ($id > 0 || $ref) if ($cancel) { $action=''; + $massactions=''; + unset($_SESSION['addvariant_'.$object->id]); } - + if (! $object->isProduct()) { header('Location: '.dol_buildpath('/product/card.php?id='.$object->id, 2)); exit(); } +if (GETPOST('selectvariant')) +{ + $action = 'add'; + if (GETPOST('attribute') != '-1' && GETPOST('value') != '-1') + { + $selectedvariant[GETPOST('attribute').':'.GETPOST('value')]=GETPOST('attribute').':'.GETPOST('value'); + $_SESSION['addvariant_'.$object->id]=$selectedvariant; + } +} + $prodcomb = new ProductCombination($db); $prodcomb2val = new ProductCombination2ValuePair($db); @@ -75,13 +94,16 @@ $productCombination2ValuePairs1 = array(); if ($_POST) { - if ($action == 'add') { + if (($action == 'add' || $action == 'create') && empty($massaction) && ! GETPOST('selectvariant')) { - $features = GETPOST('features', 'array'); + //$features = GETPOST('features', 'array'); + $features = $_SESSION['addvariant_'.$object->id]; if (!$features) { setEventMessage($langs->trans('ErrorFieldsRequired'), 'errors'); - } else { + } + else + { $weight_impact = price2num($weight_impact); $price_impact = price2num($price_impact); $sanit_features = array(); @@ -115,6 +137,7 @@ if ($_POST) { if (ProductCombination::createProductCombination($object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact)) { $db->commit(); setEventMessage($langs->trans('RecordSaved')); + unset($_SESSION['addvariant_'.$object->id]); header('Location: '.dol_buildpath('/variants/combinations.php?id='.$id, 2)); exit(); } else { @@ -126,17 +149,17 @@ if ($_POST) { $db->rollback(); } - } elseif ($action == 'bulk_actions') { - - $prodarray = array_keys(GETPOST('select', 'array')); - $bulkaction = GETPOST('bulk_action'); + } + elseif (! empty($massaction)) + { + $bulkaction = $massaction; $error = 0; $prodstatic = new Product($db); $db->begin(); - foreach ($prodarray as $prodid) { + foreach ($toselect as $prodid) { if ($prodstatic->fetch($prodid) < 0) { continue; @@ -180,7 +203,8 @@ if ($_POST) { setEventMessage($langs->trans('RecordSaved')); } - } elseif ($valueid > 0) { + } + elseif ($valueid > 0) { if ($prodcomb->fetch($valueid) < 0) { dol_print_error($db, $langs->trans('ErrorRecordNotFound')); @@ -201,6 +225,7 @@ if ($_POST) { } } +// Reload variants $productCombinations = $prodcomb->fetchAllByFkProductParent($object->id); if ($action === 'confirm_deletecombination') { @@ -263,29 +288,26 @@ if ($action === 'confirm_deletecombination') { $form = new Form($db); - -if (! empty($id) || ! empty($ref)) { - +if (! empty($id) || ! empty($ref)) +{ llxHeader("", "", $langs->trans("CardProduct".$object->type)); - if ($result) - { - $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 = ''.$langs->trans("BackToList").''; - $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(); - } + $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 = ''.$langs->trans("BackToList").''; + $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(); + // Create or edit a varian if ($action == 'add' || ($action == 'edit')) { @@ -295,6 +317,7 @@ if (! empty($id) || ! empty($ref)) { $title = $langs->trans('EditProductCombination'); } + print '
    '; print_fiche_titre($title); if ($action == 'add') { @@ -312,7 +335,7 @@ if (! empty($id) || ! empty($ref)) { ?> - + '; - print ''; + print '
    '."\n"; + print ''."\n"; + print ''."\n"; print dol_fiche_head(); @@ -483,7 +439,8 @@ if (! empty($id) || ! empty($ref)) { - trans("SelectCombination"); ?> + "> + @@ -493,17 +450,27 @@ if (! empty($id) || ! empty($ref)) { - @@ -524,15 +491,12 @@ if (! empty($id) || ! empty($ref)) { ?>
    - + value="trans('Create') : $langs->trans('Save') ?>" class="button">  
    - - - -'; } @@ -606,36 +570,56 @@ if (! empty($id) || ! empty($ref)) { print '
    '; if ($productCombinations) { - print ''.$langs->trans('Copy').''; + print ''.$langs->trans('PropagateVariant').''; } - print ''.$langs->trans('NewProductCombination').''; + print ''.$langs->trans('NewProductCombination').''; // NewVariant - if (empty($conf->dol_optimize_smallscreen) && $conf->use_javascript_ajax) // Bugged page. Too much useless javascript. - { - print ''.$langs->trans('ProductCombinationGenerator').''; - } + // Too much bugged page. + /* + print ''.$langs->trans('ProductCombinationGenerator').''; + */ print '
    '; print ''; - print ''; + + + $arrayofselected=is_array($toselect)?$toselect:array(); + + + // List of variants + print ''; + + + // List of mass actions available + /* + $arrayofmassactions = array( + 'presend'=>$langs->trans("SendByMail"), + 'builddoc'=>$langs->trans("PDFMerge"), + ); + if ($user->rights->product->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); + if ($massaction == 'presend' || $massaction == 'createbills') $arrayofmassactions=array(); + $massactionbutton=$form->selectMassAction('', $arrayofmassactions); + */ $aaa=''; if (count($productCombinations)) { - $aaa = ''; - $aaa .= ''; + $aaa .= ' '; $aaa .= ' '; $aaa .= ' '; $aaa .= ' '; $aaa .= ' '; $aaa .= ' '; $aaa .= ''; - $aaa .= ''; + $aaa .= ''; $aaa .= ''; } + $massactionbutton = $aaa; $title = $langs->trans("ProductCombinations"); @@ -645,18 +629,19 @@ if (! empty($id) || ! empty($ref)) { ?>
    +
    -
    -
    - + $val) { + $tmp = explode(':',$val); + $result1 = $prodattr->fetch($tmp[0]); + $result2 = $prodattr_val->fetch($tmp[1]); + if ($result1 > 0 && $result2 > 0) + { + print $prodattr->label . ' - '.$prodattr_val->value.'
    '; + // TODO Add delete link + } + } + } + ?>
    +
    - - - - - - - - + + + + + + + + '; + $searchpitco=$form->showCheckAddButtons('checkforselect', 1); + print $searchpitco; + print ''; + ?> id, 2) ?>"> - + '; + if ($productCombinations || $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($prodstatic->id, $arrayofselected)) $selected=1; + print ''; + } + print ''; + ?> Date: Fri, 7 Apr 2017 13:56:41 +0200 Subject: [PATCH 105/233] Update code using new css class --- dev/skeletons/skeleton_list.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dev/skeletons/skeleton_list.php b/dev/skeletons/skeleton_list.php index ca66990a9f7..e5e0f925a9c 100644 --- a/dev/skeletons/skeleton_list.php +++ b/dev/skeletons/skeleton_list.php @@ -435,10 +435,8 @@ while ($i < min($num, $limit)) $obj = $db->fetch_object($resql); if ($obj) { - $var = !$var; - // Show here line of result - print ''; + print ''; // LIST_OF_TD_FIELDS_LIST /* if (! empty($arrayfields['t.field1']['checked'])) From 60a54041c20f8ac0cb5c7822a1cc0e4f0a105985 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Apr 2017 14:09:19 +0200 Subject: [PATCH 106/233] NEW Enable bulk actions delete on supplier invoices --- htdocs/comm/propal/list.php | 7 +- htdocs/commande/list.php | 8 +- htdocs/compta/facture/list.php | 33 +-- htdocs/core/class/html.formfile.class.php | 8 +- htdocs/core/lib/functions.lib.php | 2 +- .../class/api_supplier_invoices.class.php | 2 +- .../class/fournisseur.commande.class.php | 27 +- .../fourn/class/fournisseur.facture.class.php | 62 ++-- htdocs/fourn/class/paiementfourn.class.php | 2 +- htdocs/fourn/facture/list.php | 274 ++++++++++++++---- htdocs/main.inc.php | 2 +- htdocs/theme/eldy/style.css.php | 6 + htdocs/theme/md/style.css.php | 6 + 13 files changed, 305 insertions(+), 134 deletions(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index d1ccf6547ce..c06ea117d01 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -556,7 +556,8 @@ if ($resql) $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 '
    '; print '
    trans('Product') ?>trans('Combination') ?>trans('PriceImpact') ?>trans('WeightImpact') ?>trans('OnSell') ?>trans('OnBuy') ?> - - - - trans('Product') ?>trans('Combination') ?>trans('PriceImpact') ?>trans('WeightImpact') ?>trans('OnSell') ?>trans('OnBuy') ?>
    '."\n"; @@ -695,7 +696,7 @@ if ($resql) } // Action column print ''; @@ -807,7 +808,7 @@ if ($resql) // Thirdparty if (! empty($arrayfields['s.nom']['checked'])) { - print ''; if (! $i) $totalarray['nbfield']++; diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index fa94541cdbf..27033254dba 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -789,7 +789,6 @@ if ($resql) print ''; print ''; print '
    '; - } if ($sall) @@ -841,7 +840,8 @@ if ($resql) $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 '
    '; print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpitco=$form->showFilterButtons(); print $searchpitco; print ''; + print ''; print $companystatic->getNomUrl(1,'customer'); print '
    '."\n"; @@ -992,7 +992,7 @@ if ($resql) } // Action column print ''; @@ -1222,7 +1222,7 @@ if ($resql) // Third party if (! empty($arrayfields['s.nom']['checked'])) { - print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpitco=$form->showFilterButtons(); print $searchpitco; print ''; + print ''; print $companystatic->getNomUrl(1,'customer'); // If module invoices enabled and user with invoice creation permissions diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 03612cbb932..92fcf4fc511 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -738,7 +738,8 @@ if ($resql) $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 '
    '; print ''."\n"; @@ -748,14 +749,14 @@ if ($resql) if (! empty($arrayfields['f.facnumber']['checked'])) { print ''; } // Ref customer if (! empty($arrayfields['f.ref_client']['checked'])) { print ''; } // Type @@ -776,8 +777,8 @@ if ($resql) if (! empty($arrayfields['f.date']['checked'])) { print ''; } @@ -785,8 +786,8 @@ if ($resql) if (! empty($arrayfields['f.date_lim_reglement']['checked'])) { print ''; @@ -797,9 +798,9 @@ if ($resql) print ''; } // Town - if (! empty($arrayfields['s.town']['checked'])) print ''; + if (! empty($arrayfields['s.town']['checked'])) print ''; // Zip - if (! empty($arrayfields['s.zip']['checked'])) print ''; + if (! empty($arrayfields['s.zip']['checked'])) print ''; // State if (! empty($arrayfields['state.nom']['checked'])) { @@ -832,21 +833,21 @@ if ($resql) { // Amount print ''; } if (! empty($arrayfields['f.total_vat']['checked'])) { // Amount print ''; } if (! empty($arrayfields['f.total_ttc']['checked'])) { // Amount print ''; } if (! empty($arrayfields['dynamount_payed']['checked'])) @@ -908,7 +909,7 @@ if ($resql) } // Action column print ''; print "\n"; @@ -956,12 +957,10 @@ if ($resql) if ($num > 0) { $i=0; - $var=true; $totalarray=array(); while ($i < min($num,$limit)) { $obj = $db->fetch_object($resql); - $var=!$var; $datelimit=$db->jdate($obj->datelimite); $facturestatic->id=$obj->facid; @@ -978,7 +977,7 @@ if ($resql) $totalpay = $paiement + $totalcreditnotes + $totaldeposits; $remaintopay = $obj->total_ttc - $totalpay; - print ''; + print ''; if (! empty($arrayfields['f.facnumber']['checked'])) { print '\n"; $accountstatic = new AccountingAccount($db); diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 4589cdc754f..bf3d61cd6f2 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -594,7 +594,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['d.statut']['checked'])) print_liste_field_titre($arrayfields['d.statut']['label'],$_SERVER["PHP_SELF"],"d.statut","",$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; $i = 0; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index c06ea117d01..ba01033eee5 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -738,7 +738,7 @@ if ($resql) 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.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print ''."\n"; $now = dol_now(); @@ -780,7 +780,7 @@ if ($resql) print ''; } // Other picto tool - print ''."\n"; $total=0; diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index ca786c1e3e0..44ff8934831 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -835,7 +835,7 @@ if ($resql) $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print_liste_field_titre('', $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index e67441036c4..0f4e8b825b2 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -415,7 +415,7 @@ if (! empty($arrayfields['b.datec']['checked'])) print_liste_field_titr if (! empty($arrayfields['b.tms']['checked'])) print_liste_field_titre($arrayfields['b.tms']['label'],$_SERVER["PHP_SELF"],"b.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['b.clos']['checked'])) print_liste_field_titre($arrayfields['b.clos']['label'],$_SERVER["PHP_SELF"],'b.clos','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['balance']['checked'])) print_liste_field_titre($arrayfields['balance']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 92fcf4fc511..a8cd12c1884 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -951,7 +951,7 @@ if ($resql) if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye,type,dynamount_payed","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; if ($num > 0) diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php index 8a58b842ab6..3c651ec7eb3 100644 --- a/htdocs/compta/paiement/card.php +++ b/htdocs/compta/paiement/card.php @@ -38,10 +38,12 @@ $langs->load('bills'); $langs->load('banks'); $langs->load('companies'); -// Security check $id=GETPOST('id','int'); +$ref=GETPOST('ref', 'alpha'); $action=GETPOST('action','alpha'); $confirm=GETPOST('confirm','alpha'); + +// Security check if ($user->societe_id) $socid=$user->societe_id; // TODO ajouter regle pour restreindre acces paiement //$result = restrictedArea($user, 'facture', $id,''); @@ -163,11 +165,11 @@ if ($action == 'setdatep' && ! empty($_POST['datepday'])) * View */ -llxHeader(); +llxHeader('', $langs->trans("Payment")); $thirdpartystatic=new Societe($db); -$result=$object->fetch($id); +$result=$object->fetch($id, $ref); if ($result <= 0) { dol_print_error($db,'Payement '.$id.' not found in database'); @@ -178,7 +180,7 @@ $form = new Form($db); $head = payment_prepare_head($object); -dol_fiche_head($head, 'payment', $langs->trans("PaymentCustomerInvoice"), 0, 'payment'); +dol_fiche_head($head, 'payment', $langs->trans("PaymentCustomerInvoice"), -1, 'payment'); /* * Confirmation de la suppression du paiement @@ -199,19 +201,18 @@ if ($action == 'valide') } - $linkback = '' . $langs->trans("BackToList") . ''; +dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', ''); + + +print '
    '; +print '
    '; print '
    '; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; - print ''; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; + print ''; $formother->select_year($year?$year:-1,'year',1, 20, 5); print ''; - if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; - print ''; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; + print ''; $formother->select_year($year_lim?$year_lim:-1,'year_lim',1, 20, 5); print '
    '.$langs->trans("Late"); print '
    '; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpitco=$form->showFilterButtons(); print $searchpitco; print '
    '; @@ -1045,7 +1044,7 @@ if ($resql) // Third party if (! empty($arrayfields['s.nom']['checked'])) { - print ''; + print ''; $thirdparty=new Societe($db); $thirdparty->id=$obj->socid; $thirdparty->name=$obj->name; diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 647d0cf6a76..73e854248fe 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -871,8 +871,12 @@ class FormFile else $this->infofiles['extensions'][$ext]++; // Preview - $urladvanced = getAdvancedPreviewUrl($modulepart, $relativepath); - if ($urladvanced) $tmpout.= '
  • '.img_picto('','detail').' '.$langs->trans("Preview").' '.$ext.'
  • '; + if (! empty($conf->use_javascript_ajax) && ! empty($conf->browser->layout != 'phone')) + { + $tmparray = getAdvancedPreviewUrl($modulepart, $relativepath, 1); + if ($tmparray && $tmparray['url']) $tmpout.= '
  • '.img_picto('','detail').' '.$langs->trans("Preview").' '.$ext.'
  • '; + } + // Download $tmpout.= '
  • login); } - if( $this->invoice->delete($id) < 0) + if( $this->invoice->delete(DolibarrApiAccess::$user) < 0) { throw new RestException(500); } diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 1da9854791b..7b732dd05a6 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1724,28 +1724,31 @@ class CommandeFournisseur extends CommonOrder * Delete an order * * @param User $user Object user + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int <0 if KO, >0 if OK */ - public function delete($user='') + public function delete(User $user, $notrigger=0) { global $langs,$conf; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $error = 0; - // Call trigger - $result=$this->call_trigger('ORDER_SUPPLIER_DELETE',$user); - if ($result < 0) - { - $this->errors[]='ErrorWhenRunningTrigger'; - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - return -1; - } - // End call triggers - - $this->db->begin(); + if (empty($notrigger)) + { + // Call trigger + $result=$this->call_trigger('ORDER_SUPPLIER_DELETE',$user); + if ($result < 0) + { + $this->errors[]='ErrorWhenRunningTrigger'; + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + return -1; + } + // End call triggers + } + $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseurdet WHERE fk_commande =". $this->id ; dol_syslog(get_class($this)."::delete", LOG_DEBUG); if (! $this->db->query($sql) ) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 5f435da9daf..42daafe9c2d 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -849,14 +849,15 @@ class FactureFournisseur extends CommonInvoice /** * Delete invoice from database * - * @param int $rowid Id of invoice to delete + * @param User $user User object + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int <0 if KO, >0 if OK */ - public function delete($rowid) + public function delete(User $user, $notrigger=0) { - global $user,$langs,$conf; + global $langs,$conf; - if (! $rowid) $rowid=$this->id; + $rowid=$this->id; dol_syslog("FactureFournisseur::delete rowid=".$rowid, LOG_DEBUG); @@ -865,22 +866,37 @@ class FactureFournisseur extends CommonInvoice $error=0; $this->db->begin(); - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det WHERE fk_facture_fourn = '.$rowid.';'; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) + if (! $error && ! $notrigger) { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn WHERE rowid = '.$rowid; + // Call trigger + $result=$this->call_trigger('BILL_SUPPLIER_DELETE',$user); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + // Fin appel triggers + } + + if (! $error) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det WHERE fk_facture_fourn = '.$rowid.';'; dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql2 = $this->db->query($sql); - if (! $resql2) { + $resql = $this->db->query($sql); + if ($resql) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn WHERE rowid = '.$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql2 = $this->db->query($sql); + if (! $resql2) { + $error++; + } + } + else { $error++; } } - else { - $error++; - } - + if (! $error) { // Delete linked object @@ -888,18 +904,6 @@ class FactureFournisseur extends CommonInvoice if ($res < 0) $error++; } - if (! $error) - { - // Call trigger - $result=$this->call_trigger('BILL_SUPPLIER_DELETE',$user); - if ($result < 0) - { - $this->db->rollback(); - return -1; - } - // Fin appel triggers - } - if (! $error) { // Delete linked object @@ -2452,13 +2456,11 @@ class SupplierInvoiceLine extends CommonObjectLine /** * Deletes a line * - * @param bool|int $notrigger 1=Does not execute triggers, 0= execute triggers + * @param bool|int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int 0 if KO, 1 if OK */ public function delete($notrigger = 0) { - global $user; - dol_syslog(get_class($this)."::deleteline rowid=".$this->id, LOG_DEBUG); $error = 0; diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php index be87fbc7512..12fccab91d8 100644 --- a/htdocs/fourn/class/paiementfourn.class.php +++ b/htdocs/fourn/class/paiementfourn.class.php @@ -349,7 +349,7 @@ class PaiementFourn extends Paiement $result=$accline->fetch($bank_line_id); if ($result > 0) // If result = 0, record not found, we don't try to delete { - $result=$accline->delete(); + $result=$accline->delete($user); } if ($result < 0) { diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 52320ec9580..1eb2dfaeb4a 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -48,6 +48,12 @@ $langs->load("companies"); $langs->load('products'); $langs->load('projects'); +$action=GETPOST('action','alpha'); +$massaction=GETPOST('massaction','alpha'); +$show_files=GETPOST('show_files','int'); +$confirm=GETPOST('confirm','alpha'); +$toselect = GETPOST('toselect', 'array'); + $socid = GETPOST('socid','int'); // Security check @@ -110,7 +116,7 @@ if (! $sortfield) $sortfield="f.datef,f.rowid"; // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array $contextpage='supplierinvoicelist'; -$diroutputmassaction=$conf->facture->dir_output . '/temp/massgeneration/'.$user->id; +$diroutputmassaction=$conf->fournisseur->facture->dir_output . '/temp/massgeneration/'.$user->id; $object=new FactureFournisseur($db); @@ -171,67 +177,62 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab */ if (GETPOST('cancel')) { $action='list'; $massaction=''; } -if (! GETPOST('confirmmassaction')) { $massaction=''; } +if (! GETPOST('confirmmassaction') && $massaction != 'presend' && $massaction != 'confirm_presend' && $massaction != 'confirm_createbills') { $massaction=''; } $parameters=array('socid'=>$socid); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; - -if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter") || GETPOST("button_removefilter.x")) // All test must be present to be compatible with all browsers -{ - $search_all=""; - $search_user=''; - $search_sale=''; - $search_product_category=''; - $search_ref=""; - $search_refsupplier=""; - $search_label=""; - $search_project=''; - $search_societe=""; - $search_company=""; - $search_amount_no_tax=""; - $search_amount_all_tax=""; - $search_montant_ht=''; - $search_montant_vat=''; - $search_montant_ttc=''; - $search_status=''; - $search_paymentmode=''; - $search_town=''; - $search_zip=""; - $search_state=""; - $search_type=''; - $search_country=''; - $search_type_thirdparty=''; - $year=""; - $month=""; - $day=""; - $year_lim=""; - $month_lim=""; - $day_lim=""; - $search_array_options=array(); - $filter=''; - $option=''; -} - if (empty($reshook)) { - // Mass actions. Controls on number of lines checked - $maxformassaction=1000; - if (! empty($massaction) && count($toselect) < 1) + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + + if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter") || GETPOST("button_removefilter.x")) // All test must be present to be compatible with all browsers { - $error++; - setEventMessages($langs->trans("NoLineChecked"), null, "warnings"); + $search_all=""; + $search_user=''; + $search_sale=''; + $search_product_category=''; + $search_ref=""; + $search_refsupplier=""; + $search_label=""; + $search_project=''; + $search_societe=""; + $search_company=""; + $search_amount_no_tax=""; + $search_amount_all_tax=""; + $search_montant_ht=''; + $search_montant_vat=''; + $search_montant_ttc=''; + $search_status=''; + $search_paymentmode=''; + $search_town=''; + $search_zip=""; + $search_state=""; + $search_type=''; + $search_country=''; + $search_type_thirdparty=''; + $year=""; + $month=""; + $day=""; + $year_lim=""; + $month_lim=""; + $day_lim=""; + $toselect=''; + $search_array_options=array(); + $filter=''; + $option=''; } - if (! $error && count($toselect) > $maxformassaction) - { - setEventMessages($langs->trans('TooManyRecordForMassAction',$maxformassaction), null, 'errors'); - $error++; - } - - + + // Mass actions + $objectclass='FactureFournisseur'; + $objectlabel='SupplierInvoices'; + $permtoread = $user->rights->fournisseur->facture->lire; + $permtodelete = $user->rights->fournisseur->facture->supprimer; + $uploaddir = $conf->fournisseur->facture->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } + /* * View @@ -424,7 +425,15 @@ if ($resql) if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); } - $massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"))); + // List of mass actions available + $arrayofmassactions = array( + //'presend'=>$langs->trans("SendByMail"), + //'builddoc'=>$langs->trans("PDFMerge"), + ); + //if($user->rights->fournisseur->facture->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer"); + if ($user->rights->fournisseur->facture->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); + //if ($massaction == 'presend' || $massaction == 'createbills') $arrayofmassactions=array(); + $massactionbutton=$form->selectMassAction('', $arrayofmassactions); $i = 0; print ''."\n"; @@ -437,7 +446,144 @@ if ($resql) print ''; print ''; - print_barre_liste($langs->trans("BillsSuppliers").($socid?" - $soc->name":""), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit); + print_barre_liste($langs->trans("BillsSuppliers").($socid?" - $soc->name":""), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit); + + if ($massaction == 'presend') + { + $langs->load("mails"); + + if (! GETPOST('cancel')) + { + $objecttmp=new Commande($db); + $listofselectedid=array(); + $listofselectedthirdparties=array(); + $listofselectedref=array(); + foreach($arrayofselected as $toselectid) + { + $result=$objecttmp->fetch($toselectid); + if ($result > 0) + { + $listofselectedid[$toselectid]=$toselectid; + $thirdpartyid=$objecttmp->fk_soc?$objecttmp->fk_soc:$objecttmp->socid; + $listofselectedthirdparties[$thirdpartyid]=$thirdpartyid; + $listofselectedref[$thirdpartyid][$toselectid]=$objecttmp->ref; + } + } + } + + print ''; + + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + dol_fiche_head(null, '', ''); + + $topicmail="SendOrderRef"; + $modelmail="order_send"; + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->withform=-1; + $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); + + if($formmail->fromtype === 'user'){ + $formmail->fromid = $user->id; + + } + if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1)) // If bit 1 is set + { + $formmail->trackid='ord'.$object->id; + } + if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set + { + include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'ord'.$object->id); + } + $formmail->withfrom=1; + $liste=$langs->trans("AllRecipientSelected"); + if (count($listofselectedthirdparties) == 1) + { + $liste=array(); + $thirdpartyid=array_shift($listofselectedthirdparties); + $soc=new Societe($db); + $soc->fetch($thirdpartyid); + foreach ($soc->thirdparty_and_contact_email_array(1) as $key=>$value) + { + $liste[$key]=$value; + } + $formmail->withtoreadonly=0; + } + else + { + $formmail->withtoreadonly=1; + } + $formmail->withto=$liste; + $formmail->withtofree=0; + $formmail->withtocc=1; + $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; + $formmail->withtopic=$langs->transnoentities($topicmail, '__REF__', '__REFCLIENT__'); + $formmail->withfile=$langs->trans("OnlyPDFattachmentSupported"); + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + // Tableau des substitutions + $formmail->substit['__REF__']='__REF__'; // We want to keep the tag + $formmail->substit['__SIGNATURE__']=$user->signature; + $formmail->substit['__REFCLIENT__']='__REFCLIENT__'; // We want to keep the tag + $formmail->substit['__PERSONALIZED__']=''; + $formmail->substit['__CONTACTCIVNAME__']=''; + + // Tableau des parametres complementaires du post + $formmail->param['action']=$action; + $formmail->param['models']=$modelmail; + $formmail->param['models_id']=GETPOST('modelmailselected','int'); + $formmail->param['id']=join(',',$arrayofselected); + //$formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; + + print $formmail->get_form(); + + dol_fiche_end(); + } + elseif ($massaction == 'createbills') + { + //var_dump($_REQUEST); + print ''; + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
    '; + print $langs->trans('DateInvoice'); + print ''; + print $form->select_date('', '', '', '', '', '', 1, 1); + print '
    '; + print $langs->trans('CreateOneBillByThird'); + print ''; + print $form->selectyesno('createbills_onebythird', '', 1); + print '
    '; + print $langs->trans('ValidateInvoices'); + print ''; + print $form->selectyesno('valdate_invoices', 1, 1); + print '
    '; + + print '
    '; + print '
    '; + print ' '; + print ''; + print '
    '; + print '
    '; + } if ($search_all) { @@ -487,11 +633,11 @@ if ($resql) $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 '
    '; print ''."\n"; - // Line for filters print ''; // Ref @@ -646,7 +792,7 @@ if ($resql) } // Action column print ''; @@ -688,7 +834,7 @@ if ($resql) if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; $facturestatic=new FactureFournisseur($db); @@ -944,11 +1090,15 @@ if ($resql) } // Action column + // Action column print '' ; + if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + { + $selected=0; + if (in_array($obj->facid, $arrayofselected)) $selected=1; + print ''; + } + print ''; if (! $i) $totalarray['nbfield']++; print "\n"; diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index f44f2f70acf..8fe2125251c 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1922,7 +1922,7 @@ if (! function_exists("llxFooter")) } // Wrapper to manage document_preview - if (! empty($conf->use_javascript_ajax)) + if (! empty($conf->use_javascript_ajax) && ! empty($conf->browser->layout != 'phone')) { print "\n\n"; print ''; - - -// Part to create -if ($action == 'create') -{ - print load_fiche_titre($langs->trans("NewMyModule")); - - print ''; - print ''; - print ''; - - dol_fiche_head(); - - print '
    '; - $searchpitco=$form->showFilterAndCheckAddButtons(0, 'checkforselect', 0); + $searchpitco=$form->showFilterButtons('checkforselect', 0); print $searchpitco; print '
    '; - $selected=0; - if (in_array($obj->facid, $arrayofselected)) $selected=1; - //print ''; - print '
    '."\n"; - // print ''; - // LIST_OF_TD_LABEL_FIELDS_CREATE - print '
    '.$langs->trans("Label").'
    '."\n"; - - dol_fiche_end(); - - print '
     
    '; - - print ''; -} - - - -// Part to edit record -if (($id || $ref) && $action == 'edit') -{ - print load_fiche_titre($langs->trans("MyModule")); - - print '
    '; - print ''; - print ''; - print ''; - - dol_fiche_head(); - - print ''."\n"; - // print ''; - // LIST_OF_TD_LABEL_FIELDS_EDIT - print '
    '.$langs->trans("Label").'
    '; - - dol_fiche_end(); - - print '
    '; - print '   '; - print '
    '; - - print '
    '; -} - - - -// Part to show record -if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) -{ - $res = $object->fetch_optionals($object->id, $extralabels); - - $head = commande_prepare_head($object); - dol_fiche_head($head, 'order', $langs->trans("CustomerOrder"), 0, 'order'); - - print load_fiche_titre($langs->trans("MyModule")); - - dol_fiche_head(); - - if ($action == 'delete') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteMyOjbect'), $langs->trans('ConfirmDeleteMyObject'), 'confirm_delete', '', 0, 1); - print $formconfirm; - } - - print ''."\n"; - // print ''; - // LIST_OF_TD_LABEL_FIELDS_VIEW - print '
    '.$langs->trans("Label").''.$object->label.'
    '; - - dol_fiche_end(); - - - // Buttons - print '
    '."\n"; - - - // Example 2 : Adding links to objects - // Show links to link elements - //$linktoelem = $form->showLinkToObjectBlock($object, null, array('skeleton')); - //$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - -} - - -// End of page -llxFooter(); -$db->close(); diff --git a/dev/skeletons/skeleton_class.class.php b/dev/skeletons/skeleton_class.class.php deleted file mode 100644 index 01b48c35f75..00000000000 --- a/dev/skeletons/skeleton_class.class.php +++ /dev/null @@ -1,593 +0,0 @@ - - * Copyright (C) 2014-2016 Juanjo Menent - * Copyright (C) 2015 Florian Henry - * Copyright (C) 2015 Raphaël Doursenaud - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file 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 - */ - -// 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'; - -/** - * Class Skeleton_Class - * - * Put here description of your class - * - * @see CommonObject - */ -class Skeleton_Class extends CommonObject -{ - /** - * @var string Id to identify managed objects - */ - public $element = 'skeleton'; - /** - * @var string Name of table without prefix where object is stored - */ - public $table_element = 'skeleton'; - - /** - * @var Skeleton_ClassLine[] Lines - */ - public $lines = array(); - - /** - * @var mixed Sample property 1 - */ - public $prop1; - /** - * @var mixed Sample property 2 - */ - public $prop2; - //... - - /** - * Constructor - * - * @param DoliDb $db Database handler - */ - public function __construct(DoliDB $db) - { - $this->db = $db; - } - - /** - * Create object into database - * - * @param User $user User that creates - * @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) - { - dol_syslog(__METHOD__, LOG_DEBUG); - - $error = 0; - - // Clean parameters - if (isset($this->prop1)) { - $this->prop1 = trim($this->prop1); - } - if (isset($this->prop2)) { - $this->prop2 = trim($this->prop2); - } - //... - - // Check parameters - // Put here code to add control on parameters values - - // Insert request - $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '('; - $sql .= ' field1,'; - $sql .= ' field2'; - //... - $sql .= ') VALUES ('; - $sql .= ' \'' . $this->prop1 . '\','; - $sql .= ' \'' . $this->prop2 . '\''; - //... - $sql .= ')'; - - $this->db->begin(); - - $resql = $this->db->query($sql); - if (!$resql) { - $error ++; - $this->errors[] = 'Error ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); - } - - 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. - - //// Call triggers - //$result=$this->call_trigger('MYOBJECT_CREATE',$user); - //if ($result < 0) $error++; - //// End call triggers - } - } - - // Commit or rollback - if ($error) { - $this->db->rollback(); - - return - 1 * $error; - } else { - $this->db->commit(); - - return $this->id; - } - } - - /** - * Load object in memory from the database - * - * @param int $id Id object - * @param string $ref Ref - * - * @return int <0 if KO, 0 if not found, >0 if OK - */ - public function fetch($id, $ref = null) - { - dol_syslog(__METHOD__, LOG_DEBUG); - - $sql = 'SELECT'; - $sql .= ' t.rowid,'; - $sql .= ' t.field1,'; - $sql .= ' t.field2'; - //... - $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t'; - $sql.= ' WHERE 1 = 1'; - if (! empty($conf->multicompany->enabled)) { - $sql .= " AND entity IN (" . getEntity("skeleton", 1) . ")"; - } - if (null !== $ref) { - $sql .= ' AND t.ref = ' . '\'' . $ref . '\''; - } else { - $sql .= ' AND t.rowid = ' . $id; - } - - $resql = $this->db->query($sql); - if ($resql) { - $numrows = $this->db->num_rows($resql); - if ($numrows) { - $obj = $this->db->fetch_object($resql); - - $this->id = $obj->rowid; - $this->prop1 = $obj->field1; - $this->prop2 = $obj->field2; - //... - } - - // Retrieve all extrafields for invoice - // fetch optionals attributes and labels - /* - 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); - $this->fetch_optionals($this->id,$extralabels); - */ - - // $this->fetch_lines(); - - $this->db->free($resql); - - if ($numrows) { - return 1; - } else { - return 0; - } - } else { - $this->errors[] = 'Error ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); - - return - 1; - } - } - - /** - * Load object in memory from the database - * - * @param string $sortorder Sort Order - * @param string $sortfield Sort field - * @param int $limit offset limit - * @param int $offset offset limit - * @param array $filter filter array - * @param string $filtermode filter mode (AND or OR) - * - * @return int <0 if KO, >0 if OK - */ - public function fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter = array(), $filtermode='AND') - { - dol_syslog(__METHOD__, LOG_DEBUG); - - $sql = 'SELECT'; - $sql .= ' t.rowid,'; - $sql .= ' t.field1,'; - $sql .= ' t.field2'; - //... - $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element. ' as t'; - - // Manage filter - $sqlwhere = array(); - if (count($filter) > 0) { - foreach ($filter as $key => $value) { - $sqlwhere [] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\''; - } - } - $sql.= ' WHERE 1 = 1'; - if (! empty($conf->multicompany->enabled)) { - $sql .= " AND entity IN (" . getEntity("skeleton", 1) . ")"; - } - if (count($sqlwhere) > 0) { - $sql .= ' AND ' . implode(' '.$filtermode.' ', $sqlwhere); - } - if (!empty($sortfield)) { - $sql .= $this->db->order($sortfield,$sortorder); - } - if (!empty($limit)) { - $sql .= ' ' . $this->db->plimit($limit, $offset); - } - - $resql = $this->db->query($sql); - if ($resql) { - $num = $this->db->num_rows($resql); - - while ($obj = $this->db->fetch_object($resql)) { - $line = new self($this->db); - - $line->id = $obj->rowid; - $line->prop1 = $obj->field1; - $line->prop2 = $obj->field2; - //... - } - $this->db->free($resql); - - return $num; - } else { - $this->errors[] = 'Error ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); - - return - 1; - } - } - - /** - * Update object into database - * - * @param User $user User that modifies - * @param bool $notrigger false=launch triggers after, true=disable triggers - * - * @return int <0 if KO, >0 if OK - */ - public function update(User $user, $notrigger = false) - { - $error = 0; - - dol_syslog(__METHOD__, LOG_DEBUG); - - // Clean parameters - if (isset($this->prop1)) { - $this->prop1 = trim($this->prop1); - } - if (isset($this->prop2)) { - $this->prop2 = trim($this->prop2); - } - //... - - // Check parameters - // Put here code to add a control on parameters values - - // Update request - $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET'; - $sql .= " field1=".(isset($this->field1)?"'".$this->db->escape($this->field1)."'":"null").","; - $sql .= " field2=".(isset($this->field2)?"'".$this->db->escape($this->field2)."'":"null").""; - //... - $sql .= ' WHERE rowid=' . $this->id; - - $this->db->begin(); - - $resql = $this->db->query($sql); - if (!$resql) { - $error ++; - $this->errors[] = 'Error ' . $this->db->lasterror(); - 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. - - //// 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) { - $this->db->rollback(); - - return - 1 * $error; - } else { - $this->db->commit(); - - return 1; - } - } - - /** - * Delete object in database - * - * @param User $user User that deletes - * @param bool $notrigger false=launch triggers after, true=disable triggers - * - * @return int <0 if KO, >0 if OK - */ - public function delete(User $user, $notrigger = false) - { - 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. - - //// 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 - - if (!$error) { - $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element; - $sql .= ' WHERE rowid=' . $this->id; - - $resql = $this->db->query($sql); - if (!$resql) { - $error ++; - $this->errors[] = 'Error ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); - } - } - - // Commit or rollback - if ($error) { - $this->db->rollback(); - - return - 1 * $error; - } else { - $this->db->commit(); - - return 1; - } - } - - /** - * Load an object from its id and create a new one in database - * - * @param int $fromid Id of object to clone - * - * @return int New id of clone - */ - public function createFromClone($fromid) - { - dol_syslog(__METHOD__, LOG_DEBUG); - - global $user; - $error = 0; - $object = new Skeleton_Class($this->db); - - $this->db->begin(); - - // Load source object - $object->fetch($fromid); - // Reset object - $object->id = 0; - - // Clear fields - // ... - - // Create clone - $result = $object->create($user); - - // Other options - if ($result < 0) { - $error ++; - $this->errors = $object->errors; - dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); - } - - // End - if (!$error) { - $this->db->commit(); - - return $object->id; - } else { - $this->db->rollback(); - - return - 1; - } - } - - /** - * 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 - * @param int $notooltip 1=Disable tooltip - * @param int $maxlen Max length of visible user name - * @param string $morecss Add more css on link - * @return string String with URL - */ - function getNomUrl($withpicto=0, $option='', $notooltip=0, $maxlen=24, $morecss='') - { - global $db, $conf, $langs; - global $dolibarr_main_authentication, $dolibarr_main_demo; - global $menumanager; - - if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips - - $result = ''; - $companylink = ''; - - $label = '' . $langs->trans("MyModule") . ''; - $label.= '
    '; - $label.= '' . $langs->trans('Ref') . ': ' . $this->ref; - - $url = DOL_URL_ROOT.'/mymodule/'.$this->table_name.'_card.php?id='.$this->id; - - $linkclose=''; - if (empty($notooltip)) - { - if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { - $label=$langs->trans("ShowProject"); - $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; - } - $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; - } - else $linkclose = ($morecss?' class="'.$morecss.'"':''); - - $linkstart = ''; - $linkend=''; - - if ($withpicto) - { - $result.=($linkstart.img_object(($notooltip?'':$label), 'label', ($notooltip?'':'class="classfortooltip"')).$linkend); - if ($withpicto != 2) $result.=' '; - } - $result.= $linkstart . $this->ref . $linkend; - return $result; - } - - /** - * Retourne le libelle du status d'un user (actif, inactif) - * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label of status - */ - function getLibStatut($mode=0) - { - return $this->LibStatut($this->status,$mode); - } - - /** - * Return the status - * - * @param int $status Id status - * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 5=Long label + Picto - * @return string Label of status - */ - static function LibStatut($status,$mode=0) - { - global $langs; - - if ($mode == 0) - { - $prefix=''; - if ($status == 1) return $langs->trans('Enabled'); - if ($status == 0) return $langs->trans('Disabled'); - } - if ($mode == 1) - { - if ($status == 1) return $langs->trans('Enabled'); - if ($status == 0) return $langs->trans('Disabled'); - } - if ($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) - { - if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4'); - if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5'); - } - if ($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) - { - 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) - { - 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'); - } - } - - - /** - * Initialise object with example values - * Id must be 0 if object instance is a specimen - * - * @return void - */ - public function initAsSpecimen() - { - $this->id = 0; - $this->prop1 = 'prop1'; - $this->prop2 = 'prop2'; - } - -} - -/** - * Class Skeleton_ClassLine - */ -class Skeleton_ClassLine -{ - /** - * @var int ID - */ - public $id; - /** - * @var mixed Sample line property 1 - */ - public $prop1; - /** - * @var mixed Sample line property 2 - */ - public $prop2; -} diff --git a/dev/skeletons/skeleton_list.php b/dev/skeletons/skeleton_list.php deleted file mode 100644 index ca66990a9f7..00000000000 --- a/dev/skeletons/skeleton_list.php +++ /dev/null @@ -1,569 +0,0 @@ - - * Copyright (C) 2014-2016 Juanjo Menent - * Copyright (C) 2016 Jean-François Ferry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file dev/skeletons/skeleton_list.php - * \ingroup mymodule othermodule1 othermodule2 - * \brief This file is an example of a php page - * Put here some comments - */ - -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); -//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) - -// Change this following line to use the correct relative path (../, ../../, etc) -$res=0; -if (! $res && file_exists("../main.inc.php")) $res=@include '../main.inc.php'; // to work if your module directory is into dolibarr root htdocs directory -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 && 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"); -// Change this following line to use the correct relative path from htdocs -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/skeleton_class.class.php'); - -// Load traductions files requiredby by page -$langs->load("mymodule"); -$langs->load("other"); - -$action=GETPOST('action','alpha'); -$massaction=GETPOST('massaction','alpha'); -$show_files=GETPOST('show_files','int'); -$confirm=GETPOST('confirm','alpha'); -$toselect = GETPOST('toselect', 'array'); - -$id = GETPOST('id','int'); -$backtopage = GETPOST('backtopage'); -$myparam = GETPOST('myparam','alpha'); - -$search_all=trim(GETPOST("sall")); -$search_field1=GETPOST("search_field1"); -$search_field2=GETPOST("search_field2"); -$search_myfield=GETPOST('search_myfield'); -$optioncss = GETPOST('optioncss','alpha'); - -// Load variable for pagination -$limit = GETPOST("limit")?GETPOST("limit","int"):$conf->liste_limit; -$sortfield = GETPOST('sortfield','alpha'); -$sortorder = GETPOST('sortorder','alpha'); -$page = GETPOST('page','int'); -if ($page == -1) { $page = 0; } -$offset = $limit * $page; -$pageprev = $page - 1; -$pagenext = $page + 1; -if (! $sortfield) $sortfield="t.rowid"; // Set here default search field -if (! $sortorder) $sortorder="ASC"; - -// Protection if external user -$socid=0; -if ($user->societe_id > 0) -{ - $socid = $user->societe_id; - //accessforbidden(); -} - -// Initialize technical object to manage context to save list fields -$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'mymodulelist'; - -// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array -$hookmanager->initHooks(array('mymodulelist')); -$extrafields = new ExtraFields($db); - -// fetch optionals attributes and labels -$extralabels = $extrafields->fetch_name_optionals_label('mymodule'); -$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_'); - -// List of fields to search into when doing a "search in all" -$fieldstosearchall = array( - 't.ref'=>'Ref', - 't.note_public'=>'NotePublic', -); -if (empty($user->socid)) $fieldstosearchall["t.note_private"]="NotePrivate"; - -// Definition of fields for list -$arrayfields=array( - 't.field1'=>array('label'=>$langs->trans("Field1"), 'checked'=>1), - 't.field2'=>array('label'=>$langs->trans("Field2"), 'checked'=>1), - //'t.entity'=>array('label'=>$langs->trans("Entity"), 'checked'=>1, 'enabled'=>(! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode))), - 't.datec'=>array('label'=>$langs->trans("DateCreationShort"), 'checked'=>0, 'position'=>500), - 't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), - //'t.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), -); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); - } -} - - -// Load object if id or ref is provided as parameter -$object=new Skeleton_Class($db); -if (($id > 0 || ! empty($ref)) && $action != 'add') -{ - $result=$object->fetch($id,$ref); - if ($result < 0) dol_print_error($db); -} - - - - -/******************************************************************* -* ACTIONS -* -* Put here all code to do according to value of "action" parameter -********************************************************************/ - -if (GETPOST('cancel')) { $action='list'; $massaction=''; } -if (! GETPOST('confirmmassaction') && $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") || GETPOST("button_removefilter.x") ||GETPOST("button_removefilter")) // All tests are required to be compatible with all browsers - { - $search_field1=''; - $search_field2=''; - $search_date_creation=''; - $search_date_update=''; - $toselect=''; - $search_array_options=array(); - } - - // Mass actions - $objectclass='Skeleton'; - $objectlabel='Skeleton'; - $permtoread = $user->rights->skeleton->read; - $permtodelete = $user->rights->skeleton->delete; - $uploaddir = $conf->skeleton->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; -} - - - -/*************************************************** -* VIEW -* -* Put here all code to build page -****************************************************/ - -$now=dol_now(); - -$form=new Form($db); - -//$help_url="EN:Module_Customers_Orders|FR:Module_Commandes_Clients|ES:Módulo_Pedidos_de_clientes"; -$help_url=''; -$title = $langs->trans('MyModuleListTitle'); - -// Put here content of your page - -// Example : Adding jquery code -print ''; - - -$sql = "SELECT"; -$sql.= " t.rowid,"; -$sql.= " t.field1,"; -$sql.= " t.field2"; -// 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."mytable as t"; -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."mytable_extrafields as ef on (t.rowid = ef.fk_object)"; -$sql.= " WHERE 1 = 1"; -//$sql.= " WHERE u.entity IN (".getEntity('mytable',1).")"; -if ($search_field1) $sql.= natural_search("field1",$search_field1); -if ($search_field2) $sql.= natural_search("field2",$search_field2); -if ($sall) $sql.= natural_search(array_keys($fieldstosearchall), $sall); -// Add where from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode=0; - if (in_array($typ, array('int','double'))) $mode=1; // Search on a numeric - if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit))) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); - } -} -// 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); -//$sql.= $db->plimit($conf->liste_limit+1, $offset); - -// 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); - -dol_syslog($script_file, LOG_DEBUG); -$resql=$db->query($sql); -if (! $resql) -{ - dol_print_error($db); - exit; -} - -$num = $db->num_rows($resql); - -// Direct jump if only one record found -if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all) -{ - $obj = $db->fetch_object($resql); - $id = $obj->rowid; - header("Location: ".DOL_URL_ROOT.'/skeleton/card.php?id='.$id); - exit; -} - -llxHeader('', $title, $help_url); - -$arrayofselected=is_array($toselect)?$toselect:array(); - -$param=''; -if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; -if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; -if ($search_field1 != '') $param.= '&search_field1='.urlencode($search_field1); -if ($search_field2 != '') $param.= '&search_field2='.urlencode($search_field2); -if ($optioncss != '') $param.='&optioncss='.$optioncss; -// Add $param from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); -} - -$arrayofmassactions = array( - 'presend'=>$langs->trans("SendByMail"), - 'builddoc'=>$langs->trans("PDFMerge"), -); -if ($user->rights->mymodule->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); -if ($massaction == 'presend') $arrayofmassactions=array(); -$massactionbutton=$form->selectMassAction('', $arrayofmassactions); - -print '
    '; -if ($optioncss != '') print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; - -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit); - -if ($sall) -{ - foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); - print $langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall); -} - -$moreforfilter = ''; -$moreforfilter.='
    '; -$moreforfilter.= $langs->trans('MyFilter') . ': '; -$moreforfilter.= '
    '; - -$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 (! empty($moreforfilter)) -{ - print '
    '; - print $moreforfilter; - print '
    '; -} - -$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; -$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields - -print '
    '; -print ''."\n"; - -// Fields title -print ''; -// LIST_OF_TD_TITLE_FIELDS -//if (! empty($arrayfields['t.field1']['checked'])) print_liste_field_titre($arrayfields['t.field1']['label'],$_SERVER['PHP_SELF'],'t.field1','',$param,'',$sortfield,$sortorder); -//if (! empty($arrayfields['t.field2']['checked'])) print_liste_field_titre($arrayfields['t.field2']['label'],$_SERVER['PHP_SELF'],'t.field2','',$param,'',$sortfield,$sortorder); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} -// Hook fields -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -//if (! empty($arrayfields['t.status']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"t.status","",$param,'align="center"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); -print ''."\n"; - -// Fields title search -print ''; -// LIST_OF_TD_TITLE_SEARCH -//if (! empty($arrayfields['t.field1']['checked'])) print ''; -//if (! empty($arrayfields['t.field2']['checked'])) print ''; -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } -} -// Fields from hook -$parameters=array('arrayfields'=>$arrayfields); -$reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -if (! empty($arrayfields['t.datec']['checked'])) -{ - // Date creation - print ''; -} -if (! empty($arrayfields['t.tms']['checked'])) -{ - // Date modification - print ''; -} -/*if (! empty($arrayfields['u.statut']['checked'])) -{ - // Status - print ''; -}*/ -// Action column -print ''; -print ''."\n"; - - -$i=0; -$var=true; -$totalarray=array(); -while ($i < min($num, $limit)) -{ - $obj = $db->fetch_object($resql); - if ($obj) - { - $var = !$var; - - // Show here line of result - print ''; - // LIST_OF_TD_FIELDS_LIST - /* - if (! empty($arrayfields['t.field1']['checked'])) - { - print ''; - if (! $i) $totalarray['nbfield']++; - } - if (! empty($arrayfields['t.field2']['checked'])) - { - print ''; - if (! $i) $totalarray['nbfield']++; - }*/ - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print 'getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print ''; - if (! $i) $totalarray['nbfield']++; - } - } - } - // 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['t.datec']['checked'])) - { - print ''; - if (! $i) $totalarray['nbfield']++; - } - // Date modification - if (! empty($arrayfields['t.tms']['checked'])) - { - print ''; - if (! $i) $totalarray['nbfield']++; - } - // Status - /* - if (! empty($arrayfields['u.statut']['checked'])) - { - $userstatic->statut=$obj->statut; - print ''; - }*/ - - // Action column - print ''; - if (! $i) $totalarray['nbfield']++; - - print ''; - } - $i++; -} - -// Show total line -if (isset($totalarray['totalhtfield'])) -{ - print ''; - $i=0; - while ($i < $totalarray['nbfield']) - { - $i++; - if ($i == 1) - { - if ($num < $limit) print ''; - else print ''; - } - elseif ($totalarray['totalhtfield'] == $i) print ''; - elseif ($totalarray['totalvatfield'] == $i) print ''; - elseif ($totalarray['totalttcfield'] == $i) print ''; - else print ''; - } - print ''; -} - -$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 '
    '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print ''; - print ''; - print ''; - print $form->selectarray('search_statut', array('-1'=>'','0'=>$langs->trans('Disabled'),'1'=>$langs->trans('Enabled')),$search_statut); - print ''; -$searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); -print $searchpitco; -print '
    '.$obj->field1.''.$obj->field2.''; - print dol_print_date($db->jdate($obj->date_creation), 'dayhour'); - print ''; - print dol_print_date($db->jdate($obj->date_update), 'dayhour'); - print ''.$userstatic->getLibStatut(3).''; - 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 ''; - } - print '
    '.$langs->trans("Total").''.$langs->trans("Totalforthispage").''.price($totalarray['totalht']).''.price($totalarray['totalvat']).''.price($totalarray['totalttc']).'
    '."\n"; -print '
    '."\n"; - -print '
    '."\n"; - - -if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) -{ - // Show list of available documents - $urlsource=$_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder; - $urlsource.=str_replace('&','&',$param); - - $filedir=$diroutputmassaction; - $genallowed=$user->rights->facture->lire; - $delallowed=$user->rights->facture->lire; - - print $formfile->showdocuments('massfilesarea_mymodule','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,''); -} -else -{ - print '
    '.$langs->trans("ShowTempMassFilesArea").''; -} - - -// End of page -llxFooter(); -$db->close(); diff --git a/dev/skeletons/skeleton_script.php b/dev/skeletons/skeleton_script.php deleted file mode 100644 index 5eb1565d4a3..00000000000 --- a/dev/skeletons/skeleton_script.php +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env php - - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file dev/skeletons/skeleton_script.php - * \ingroup mymodule - * \brief This file is an example for a command line script - * Put here some comments - */ - -$sapi_type = php_sapi_name(); -$script_file = basename(__FILE__); -$path=dirname(__FILE__).'/'; - -// Test if batch mode -if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; - exit(-1); -} - -// Global variables -$version='1.0'; -$error=0; - - -// -------------------- START OF YOUR CODE HERE -------------------- -@set_time_limit(0); // No timeout for this script -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"); -// 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. - -//$langs->setDefaultLang('en_US'); // To change default language of $langs -$langs->load("main"); // To load language file for default language - -// Load user and its permissions -$result=$user->fetch('','admin'); // Load user for login 'admin'. Comment line to run as anonymous user. -if (! $result > 0) { dol_print_error('',$user->error); exit; } -$user->getrights(); - - -print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; -if (! isset($argv[1])) { // Check parameters - print "Usage: ".$script_file." param1 param2 ...\n"; - exit(-1); -} -print '--- start'."\n"; -print 'Argument 1='.$argv[1]."\n"; -print 'Argument 2='.$argv[2]."\n"; - - -// Start of transaction -$db->begin(); - - -// Examples for manipulating class skeleton_class -require_once(DOL_DOCUMENT_ROOT."/../dev/skeletons/skeleton_class.class.php"); -$myobject=new Skeleton_Class($db); - -// Example for inserting creating object in database -/* -dol_syslog($script_file." CREATE", LOG_DEBUG); -$myobject->prop1='value_prop1'; -$myobject->prop2='value_prop2'; -$id=$myobject->create($user); -if ($id < 0) { $error++; dol_print_error($db,$myobject->error); } -else print "Object created with id=".$id."\n"; -*/ - -// Example for reading object from database -/* -dol_syslog($script_file." FETCH", LOG_DEBUG); -$result=$myobject->fetch($id); -if ($result < 0) { $error; dol_print_error($db,$myobject->error); } -else print "Object with id=".$id." loaded\n"; -*/ - -// Example for updating object in database ($myobject must have been loaded by a fetch before) -/* -dol_syslog($script_file." UPDATE", LOG_DEBUG); -$myobject->prop1='newvalue_prop1'; -$myobject->prop2='newvalue_prop2'; -$result=$myobject->update($user); -if ($result < 0) { $error++; dol_print_error($db,$myobject->error); } -else print "Object with id ".$myobject->id." updated\n"; -*/ - -// Example for deleting object in database ($myobject must have been loaded by a fetch before) -/* -dol_syslog($script_file." DELETE", LOG_DEBUG); -$result=$myobject->delete($user); -if ($result < 0) { $error++; dol_print_error($db,$myobject->error); } -else print "Object with id ".$myobject->id." deleted\n"; -*/ - - -// An example of a direct SQL read without using the fetch method -/* -$sql = "SELECT field1, field2"; -$sql.= " FROM ".MAIN_DB_PREFIX."skeleton"; -$sql.= " WHERE field3 = 'xxx'"; -$sql.= " ORDER BY field1 ASC"; - -dol_syslog($script_file, LOG_DEBUG); -$resql=$db->query($sql); -if ($resql) -{ - $num = $db->num_rows($resql); - $i = 0; - if ($num) - { - while ($i < $num) - { - $obj = $db->fetch_object($resql); - if ($obj) - { - // You can use here results - print $obj->field1; - print $obj->field2; - } - $i++; - } - } -} -else -{ - $error++; - dol_print_error($db); -} -*/ - - -// -------------------- END OF YOUR CODE -------------------- - -if (! $error) -{ - $db->commit(); - print '--- end ok'."\n"; -} -else -{ - print '--- end error code='.$error."\n"; - $db->rollback(); -} - -$db->close(); // Close $db database opened handler - -exit($error); diff --git a/dev/skeletons/skeleton_webservice_server.php b/dev/skeletons/skeleton_webservice_server.php deleted file mode 100644 index 54a050ff9da..00000000000 --- a/dev/skeletons/skeleton_webservice_server.php +++ /dev/null @@ -1,272 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/webservices/server_skeleton.php - * \brief File that is entry point to call Dolibarr WebServices - * \version $Id: server_skeleton.php,v 1.7 2010/12/19 11:49:37 eldy Exp $ - */ - -// This is to make Dolibarr working with Plesk -set_include_path($_SERVER['DOCUMENT_ROOT'].'/htdocs'); - -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."/skeleton/class/skeleton.class.php"); - - -dol_syslog("Call Skeleton webservices interfaces"); - -// Enable and test if module web services is enabled -if (empty($conf->global->MAIN_MODULE_WEBSERVICES)) -{ - $langs->load("admin"); - dol_syslog("Call Dolibarr webservices interfaces with module webservices disabled"); - print $langs->trans("WarningModuleNotActive",'WebServices').'.

    '; - print $langs->trans("ToActivateModule"); - exit; -} - -// Create the soap Object -$server = new nusoap_server(); -$server->soap_defencoding='UTF-8'; -$server->decode_utf8=false; -$ns='http://www.dolibarr.org/ns/'; -$server->configureWSDL('WebServicesDolibarrSkeleton',$ns); -$server->wsdl->schemaTargetNamespace=$ns; - - -// Define WSDL Authentication object -$server->wsdl->addComplexType( - 'authentication', - 'complexType', - 'struct', - 'all', - '', - array( - 'dolibarrkey' => array('name'=>'dolibarrkey','type'=>'xsd:string'), - 'sourceapplication' => array('name'=>'sourceapplication','type'=>'xsd:string'), - 'login' => array('name'=>'login','type'=>'xsd:string'), - 'password' => array('name'=>'password','type'=>'xsd:string'), - 'entity' => array('name'=>'entity','type'=>'xsd:string'), - ) -); - -// Define WSDL Return object -$server->wsdl->addComplexType( - 'result', - 'complexType', - 'struct', - 'all', - '', - array( - 'result_code' => array('name'=>'result_code','type'=>'xsd:string'), - 'result_label' => array('name'=>'result_label','type'=>'xsd:string'), - ) -); - -// Define other specific objects -$server->wsdl->addComplexType( - 'skeleton', - 'complexType', - 'struct', - 'all', - '', - array( - 'prop1'=>'xxx', - 'prop2'=>'xxx', - //... - ) -); - - - -// 5 styles: RPC/encoded, RPC/literal, Document/encoded (not WS-I compliant), Document/literal, Document/literal wrapped -// Style merely dictates how to translate a WSDL binding to a SOAP message. Nothing more. You can use either style with any programming model. -// http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/ -$styledoc='rpc'; // rpc/document (document is an extend into SOAP 1.0 to support unstructured messages) -$styleuse='encoded'; // encoded/literal/literal wrapped -// Better choice is document/literal wrapped but literal wrapped not supported by nusoap. - - -// Register WSDL -$server->register( - 'getSkeleton', - // Entry values - array('authentication'=>'tns:authentication','id'=>'xsd:string','ref'=>'xsd:string','ref_ext'=>'xsd:string'), - // Exit values - array('result'=>'tns:result','skeleton'=>'tns:skeleton'), - $ns, - $ns.'#getSkeleton', - $styledoc, - $styleuse, - 'WS to get skeleton' -); - -// Register WSDL -$server->register( - 'createSkeleton', - // Entry values - array('authentication'=>'tns:authentication','skeleton'=>'tns:skeleton'), - // Exit values - array('result'=>'tns:result','id'=>'xsd:string'), - $ns, - $ns.'#createSkeleton', - $styledoc, - $styleuse, - 'WS to create a skeleton' -); - - - - -/** - * Get Skeleton - * - * @param array $authentication Array of authentication information - * @param int $id Id of object - * @param string $ref Ref of object - * @param string $ref_ext Ref external of object - * @return mixed - */ -function getSkeleton($authentication,$id,$ref='',$ref_ext='') -{ - global $db,$conf,$langs; - - dol_syslog("Function: getSkeleton login=".$authentication['login']." id=".$id." ref=".$ref." ref_ext=".$ref_ext); - - if ($authentication['entity']) $conf->entity=$authentication['entity']; - - // Init and check authentication - $objectresp=array(); - $errorcode='';$errorlabel=''; - $error=0; - $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); - // Check parameters - if (! $error && (($id && $ref) || ($id && $ref_ext) || ($ref && $ref_ext))) - { - $error++; - $errorcode='BAD_PARAMETERS'; $errorlabel="Parameter id, ref and ref_ext can't be both provided. You must choose one or other but not both."; - } - - if (! $error) - { - $fuser->getrights(); - - if ($fuser->rights->skeleton->read) - { - $skeleton=new Skeleton($db); - $result=$skeleton->fetch($id,$ref,$ref_ext); - if ($result > 0) - { - // Create - $objectresp = array( - 'result'=>array('result_code'=>'OK', 'result_label'=>''), - 'skeleton'=>array( - 'prop1'=>$skeleton->prop1, - 'prop2'=>$skeleton->prop2, - //... - ) - ); - } - else - { - $error++; - $errorcode='NOT_FOUND'; $errorlabel='Object not found for id='.$id.' nor ref='.$ref.' nor ref_ext='.$ref_ext; - } - } - else - { - $error++; - $errorcode='PERMISSION_DENIED'; $errorlabel='User does not have permission for this request'; - } - } - - if ($error) - { - $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel)); - } - - return $objectresp; -} - - -/** - * Create Skeleton - * - * @param array $authentication Array of authentication information - * @param Skeleton $skeleton $skeleton - * @return array Array result - */ -function createSkeleton($authentication,$skeleton) -{ - global $db,$conf,$langs; - - $now=dol_now(); - - dol_syslog("Function: createSkeleton login=".$authentication['login']); - - if ($authentication['entity']) $conf->entity=$authentication['entity']; - - // Init and check authentication - $objectresp=array(); - $errorcode='';$errorlabel=''; - $error=0; - $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); - // Check parameters - - - if (! $error) - { - $newobject=new Skeleton($db); - $newobject->prop1=$skeleton->prop1; - $newobject->prop2=$skeleton->prop2; - //... - - $db->begin(); - - $result=$newobject->create($fuser); - if ($result <= 0) - { - $error++; - } - - if (! $error) - { - $db->commit(); - $objectresp=array('result'=>array('result_code'=>'OK', 'result_label'=>''),'id'=>$newobject->id,'ref'=>$newobject->ref); - } - else - { - $db->rollback(); - $error++; - $errorcode='KO'; - $errorlabel=$newobject->error; - } - } - - if ($error) - { - $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel)); - } - - return $objectresp; -} - -// Return the results. -$server->service(file_get_contents("php://input")); diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index b10463361f8..7f909cd2f13 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -263,7 +263,7 @@ if ($resql) if (! empty($arrayfields['aa.pcg_type']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_type']['label'],$_SERVER["PHP_SELF"],'aa.pcg_type','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['aa.pcg_subtype']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_subtype']['label'],$_SERVER["PHP_SELF"],'aa.pcg_subtype','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['aa.active']['checked'])) print_liste_field_titre($arrayfields['aa.active']['label'],$_SERVER["PHP_SELF"],'aa.active','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "
  • '; + print ''; $filename=dol_sanitizeFileName($obj->ref); $filedir=$conf->propal->dir_output . '/' . dol_sanitizeFileName($obj->ref); $urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->rowid; diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 27033254dba..fcd68992b38 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1033,7 +1033,7 @@ if ($resql) if (! empty($arrayfields['c.tms']['checked'])) print_liste_field_titre($arrayfields['c.tms']['label'],$_SERVER["PHP_SELF"],"c.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['c.fk_statut']['checked'])) print_liste_field_titre($arrayfields['c.fk_statut']['label'],$_SERVER["PHP_SELF"],"c.fk_statut","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['c.facture']['checked'])) print_liste_field_titre($arrayfields['c.facture']['label'],$_SERVER["PHP_SELF"],'c.facture','',$param,'align="center"',$sortfield,$sortorder,''); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print '
    '."\n"; -// Ref -print ''; - // Date payment -print ''; @@ -280,6 +281,8 @@ if (! empty($conf->banque->enabled)) print '
    '.$langs->trans('Ref').''; -print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', ''); -print '
    '.$form->editfieldkey("Date",'datep',$object->date,$object,$user->rights->facture->paiement).''; +print '
    '.$form->editfieldkey("Date",'datep',$object->date,$object,$user->rights->facture->paiement).''; print $form->editfieldval("Date",'datep',$object->date,$object,$user->rights->facture->paiement,'datepicker','',null,$langs->trans('PaymentDateUpdateSucceeded')); print '
    '; +print '
    '; + dol_fiche_end(); diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 61d2b5a3b8a..b229f756b25 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -96,7 +96,7 @@ class Paiement extends CommonObject if ($id > 0) $sql.= ' AND p.rowid = '.$id; else if ($ref) - $sql.= ' AND p.rowid = '.$ref; + $sql.= " AND p.ref = '".$ref."'"; else if ($fk_bank) $sql.= ' AND p.fk_bank = '.$fk_bank; diff --git a/htdocs/compta/paiement/info.php b/htdocs/compta/paiement/info.php index e1b12225aad..d0bda152b21 100644 --- a/htdocs/compta/paiement/info.php +++ b/htdocs/compta/paiement/info.php @@ -32,33 +32,39 @@ $langs->load("bills"); $langs->load("companies"); $id=GETPOST('id'); +$ref=GETPOST('ref', 'alpha'); +$action=GETPOST('action','alpha'); +$confirm=GETPOST('confirm','alpha'); + +/* + * Actions + */ + +// None /* * View */ -llxHeader(); +llxHeader('', $langs->trans("Payment")); $object = new Paiement($db); -$object->fetch($id); -$object->info($id); +$object->fetch($id, $ref); +$object->info($object->id); $head = payment_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans("PaymentCustomerInvoice"), 0, 'payment'); +dol_fiche_head($head, 'info', $langs->trans("PaymentCustomerInvoice"), -1, 'payment'); -print ''; $linkback = '' . $langs->trans("BackToList") . ''; +dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', ''); -// Ref -print ''; -print '
    '.$langs->trans('Ref').''; -print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', ''); -print '
    '; +print '
    '; +print '
    '; print '
    '; @@ -68,5 +74,7 @@ print '
    '; print '
    '; +dol_fiche_end(); + llxFooter(); $db->close(); diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 917c59006f2..ef26c9c80e2 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -642,7 +642,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['p.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['p.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['p.statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"p.statut","",$param,'align="center"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index af68e789da2..be1b2e5fccf 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -551,7 +551,7 @@ if ($resql) print_liste_field_titre($staticcontratligne->LibStatut(4,3,1), '', '', '', '', 'width="16"'); print_liste_field_titre($staticcontratligne->LibStatut(5,3), '', '', '', '', 'width="16"'); } - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; while ($i < min($num,$limit)) diff --git a/htdocs/contrat/services.php b/htdocs/contrat/services.php index 62b9fddf743..1e2820f10e0 100644 --- a/htdocs/contrat/services.php +++ b/htdocs/contrat/services.php @@ -382,7 +382,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['cd.datec']['checked'])) print_liste_field_titre($arrayfields['cd.datec']['label'],$_SERVER["PHP_SELF"],"cd.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['cd.tms']['checked'])) print_liste_field_titre($arrayfields['cd.tms']['label'],$_SERVER["PHP_SELF"],"cd.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['status']['checked'])) print_liste_field_titre($arrayfields['status']['label'],$_SERVER["PHP_SELF"],"cd.statut,c.statut","",$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; print ''; diff --git a/htdocs/core/boxes/box_commandes.php b/htdocs/core/boxes/box_commandes.php index fe460f7d512..be9a868109d 100644 --- a/htdocs/core/boxes/box_commandes.php +++ b/htdocs/core/boxes/box_commandes.php @@ -121,7 +121,7 @@ class box_commandes extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => '', + 'td' => 'class="tdoverflowmax100"', 'text' => $societestatic->getNomUrl(1), 'asis' => 1, ); diff --git a/htdocs/core/boxes/box_propales.php b/htdocs/core/boxes/box_propales.php index d3945ddb940..3f7b37f186a 100644 --- a/htdocs/core/boxes/box_propales.php +++ b/htdocs/core/boxes/box_propales.php @@ -116,8 +116,8 @@ class box_propales extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => '', - 'text' => $societestatic->getNomUrl(1,'',40), + 'td' => 'class="tdoverflowmax100"', + 'text' => $societestatic->getNomUrl(1), 'asis' => 1, ); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 73e854248fe..7dc69a82b23 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -834,8 +834,8 @@ class FormFile $out=''; $this->infofiles=array('nboffiles'=>0,'extensions'=>array(),'files'=>array()); - if (! empty($conf->dol_use_jmobile)) return ''; - + //if (! empty($conf->dol_use_jmobile)) return ''; + $file_list=dol_dir_list($filedir, 'files', 0, preg_quote(basename($modulesubdir),'/').'[^\-]+', '\.meta$|\.png$'); // Get list of files starting with name of ref (but not followed by "-" to discard uploaded files) // For ajax treatment diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index ed6bb2c9979..178a3629d23 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -57,7 +57,10 @@ $nolinesbefore=(count($this->lines) == 0 || $forcetoshowtitlelines); if ($nolinesbefore) { ?> - global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="2"' : ''); ?>> + global->MAIN_VIEW_LINE_NUMBER)) { ?> + + +
    trans('AddNewLine'); ?>trans("FreeZone"); ?> element == 'supplier_proposal') { ?> @@ -114,12 +117,17 @@ if ($nolinesbefore) { global->MAIN_VIEW_LINE_NUMBER)) { - $coldisplay=2; } + $coldisplay=2; + ?> + + - global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="2"' : ''); ?>> + global->MAIN_VIEW_LINE_NUMBER)) { ?> -
    +
    info_bits & 2) == 2) { ?> diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 29f6978b24e..853c047b23c 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -458,7 +458,7 @@ if ($resql) if (! empty($arrayfields['e.tms']['checked'])) print_liste_field_titre($arrayfields['e.tms']['label'],$_SERVER["PHP_SELF"],"e.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['e.fk_statut']['checked'])) print_liste_field_titre($arrayfields['e.fk_statut']['label'],$_SERVER["PHP_SELF"],"e.fk_statut","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['l.fk_statut']['checked'])) print_liste_field_titre($arrayfields['l.fk_statut']['label'], $_SERVER["PHP_SELF"],"l.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; $i=0; diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index 9339b33ee7f..c04a2fc3b61 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -342,43 +342,13 @@ if ($resql) $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 '
    '; print ''."\n"; - print ""; - if (! empty($arrayfields['d.ref']['checked'])) print_liste_field_titre($arrayfields['d.ref']['label'],$_SERVER["PHP_SELF"],"d.ref","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['user']['checked'])) print_liste_field_titre($arrayfields['user']['label'],$_SERVER["PHP_SELF"],"u.lastname","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['d.date_debut']['checked'])) print_liste_field_titre($arrayfields['d.date_debut']['label'],$_SERVER["PHP_SELF"],"d.date_debut","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['d.date_fin']['checked'])) print_liste_field_titre($arrayfields['d.date_fin']['label'],$_SERVER["PHP_SELF"],"d.date_fin","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['d.date_valid']['checked'])) print_liste_field_titre($arrayfields['d.date_valid']['label'],$_SERVER["PHP_SELF"],"d.date_valid","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['d.date_approve']['checked'])) print_liste_field_titre($arrayfields['d.date_approve']['label'],$_SERVER["PHP_SELF"],"d.date_approve","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['d.total_ht']['checked'])) print_liste_field_titre($arrayfields['d.total_ht']['label'],$_SERVER["PHP_SELF"],"d.total_ht","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['d.total_vat']['checked'])) print_liste_field_titre($arrayfields['d.total_vat']['label'],$_SERVER["PHP_SELF"],"d.total_tva","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['d.total_ttc']['checked'])) print_liste_field_titre($arrayfields['d.total_ttc']['label'],$_SERVER["PHP_SELF"],"d.total_ttc","",$param,'align="right"',$sortfield,$sortorder); - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } - // Hook fields - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['d.fk_statut']['checked'])) print_liste_field_titre($arrayfields['d.fk_statut']['label'],$_SERVER["PHP_SELF"],"d.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); - print "\n"; - + // Filters - print ''; + print ''; if (! empty($arrayfields['d.ref']['checked'])) { print ''; print "\n"; - $var=true; + print ''; + if (! empty($arrayfields['d.ref']['checked'])) print_liste_field_titre($arrayfields['d.ref']['label'],$_SERVER["PHP_SELF"],"d.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['user']['checked'])) print_liste_field_titre($arrayfields['user']['label'],$_SERVER["PHP_SELF"],"u.lastname","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['d.date_debut']['checked'])) print_liste_field_titre($arrayfields['d.date_debut']['label'],$_SERVER["PHP_SELF"],"d.date_debut","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['d.date_fin']['checked'])) print_liste_field_titre($arrayfields['d.date_fin']['label'],$_SERVER["PHP_SELF"],"d.date_fin","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['d.date_valid']['checked'])) print_liste_field_titre($arrayfields['d.date_valid']['label'],$_SERVER["PHP_SELF"],"d.date_valid","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['d.date_approve']['checked'])) print_liste_field_titre($arrayfields['d.date_approve']['label'],$_SERVER["PHP_SELF"],"d.date_approve","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['d.total_ht']['checked'])) print_liste_field_titre($arrayfields['d.total_ht']['label'],$_SERVER["PHP_SELF"],"d.total_ht","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['d.total_vat']['checked'])) print_liste_field_titre($arrayfields['d.total_vat']['label'],$_SERVER["PHP_SELF"],"d.total_tva","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['d.total_ttc']['checked'])) print_liste_field_titre($arrayfields['d.total_ttc']['label'],$_SERVER["PHP_SELF"],"d.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($langs->trans($extralabels[$key]),$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['d.fk_statut']['checked'])) print_liste_field_titre($arrayfields['d.fk_statut']['label'],$_SERVER["PHP_SELF"],"d.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; $total_total_ht = 0; $total_total_ttc = 0; @@ -528,7 +528,7 @@ if ($resql) $expensereportstatic->note_public=$obj->note_public; $var=!$var; - print ""; + print ''; // Ref if (! empty($arrayfields['d.ref']['checked'])) { print '\n"; $total = 0; diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index be3cb384e96..5c4c8aae11c 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -684,7 +684,7 @@ if ($resql) if (! empty($arrayfields['cf.tms']['checked'])) print_liste_field_titre($arrayfields['cf.tms']['label'],$_SERVER["PHP_SELF"],"cf.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['cf.fk_statut']['checked'])) print_liste_field_titre($arrayfields['cf.fk_statut']['label'],$_SERVER["PHP_SELF"],"cf.fk_statut","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['cf.billed']['checked'])) print_liste_field_titre($arrayfields['cf.billed']['label'],$_SERVER["PHP_SELF"],'cf.billed','',$param,'align="center"',$sortfield,$sortorder,''); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index 131dcc3651b..d9c5fdf43c0 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -1,6 +1,6 @@ - * Copyright (C) 2013-2016 Laurent Destailleur + * Copyright (C) 2013-2017 Laurent Destailleur * Copyright (C) 2012-2016 Regis Houssin * * This program is free software; you can redistribute it and/or modify @@ -82,7 +82,7 @@ $fieldstosearchall = array( * Actions */ -if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // All tests are required to be compatible with all browsers { $search_ref=""; $month_create=""; @@ -292,21 +292,8 @@ if ($sall) print '
    '; print '
    '; @@ -491,13 +461,43 @@ if ($resql) } // Action column print ''; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + $searchpitco=$form->showFilterButtons(); print $searchpitco; print '
    '; diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 4a24f0d0c6d..88584a4f954 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -367,7 +367,7 @@ if ($result) if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"f.fk_statut","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "
    '."\n"; -print ''; -print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"cp.rowid","",'','',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("DateCreateCP"),$_SERVER["PHP_SELF"],"cp.date_create","",'','align="center"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Employee"),$_SERVER["PHP_SELF"],"cp.fk_user","",'','',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("ValidatorCP"),$_SERVER["PHP_SELF"],"cp.fk_validator","",'','',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],'','','','',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Duration"),$_SERVER["PHP_SELF"],'','','','align="right"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("DateDebCP"),$_SERVER["PHP_SELF"],"cp.date_debut","",'','align="center"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("DateFinCP"),$_SERVER["PHP_SELF"],"cp.date_fin","",'','align="center"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"cp.statut","",'','align="right"',$sortfield,$sortorder); -print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); -print "\n"; - // FILTRES -print ''; +print ''; print ''; @@ -391,6 +378,18 @@ print ''; print "\n"; +print ''; +print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"cp.rowid","",'','',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("DateCreateCP"),$_SERVER["PHP_SELF"],"cp.date_create","",'','align="center"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Employee"),$_SERVER["PHP_SELF"],"cp.fk_user","",'','',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("ValidatorCP"),$_SERVER["PHP_SELF"],"cp.fk_validator","",'','',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],'','','','',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Duration"),$_SERVER["PHP_SELF"],'','','','align="right"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("DateDebCP"),$_SERVER["PHP_SELF"],"cp.date_debut","",'','align="center"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("DateFinCP"),$_SERVER["PHP_SELF"],"cp.date_fin","",'','align="center"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"cp.statut","",'','align="right"',$sortfield,$sortorder); +print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); +print "\n"; // Lines if (! empty($holiday->holiday)) @@ -400,8 +399,6 @@ if (! empty($holiday->holiday)) foreach($holiday->holiday as $infos_CP) { - $var=!$var; - // Utilisateur $userstatic->id=$infos_CP['fk_user']; $userstatic->lastname=$infos_CP['user_lastname']; @@ -420,7 +417,7 @@ if (! empty($holiday->holiday)) $date = $infos_CP['date_create']; - print ''; + print ''; print ''."\n"; // Fields title search diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 2e651398766..7789849da99 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -622,7 +622,7 @@ else 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($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"],"p.tosell","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['p.tobuy']['checked'])) print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"],"p.tobuy","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php index 45ace2031cb..bc4099f66ec 100644 --- a/htdocs/product/stock/mouvement.php +++ b/htdocs/product/stock/mouvement.php @@ -898,7 +898,7 @@ if ($resql) print $hookmanager->resPrint; if (! empty($arrayfields['m.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['m.tms']['checked'])) print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index ac6bc7b9948..b6a51233fa2 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -433,7 +433,7 @@ if ($resql) if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); //if (! empty($arrayfields['t.status']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"t.status","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print ''."\n"; $productlot = new Productlot($db); diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 790dde6e1aa..fb6453e8159 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -614,7 +614,7 @@ 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.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'],$_SERVER["PHP_SELF"],"p.fk_statut","",$param,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; $i=0; diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 13e15eb7eb6..ca7cff35a0a 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -585,7 +585,7 @@ $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // No print $hookmanager->resPrint; if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 2d93a0ab2df..e1047d22981 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -252,7 +252,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab } } } -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 5c5f6f8e1c8..88e7a7a631e 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -886,7 +886,7 @@ 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); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index 09dd0eb240c..3624101d7cf 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -568,7 +568,7 @@ if ($result) print_liste_field_titre($langs->trans('AmountHT'),$_SERVER["PHP_SELF"],'sp.total_ht','',$param, 'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans('Author'),$_SERVER["PHP_SELF"],'u.login','',$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre($langs->trans('Status'),$_SERVER["PHP_SELF"],'sp.fk_statut','',$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; $now = dol_now(); diff --git a/htdocs/theme/eldy/ckeditor/config.js b/htdocs/theme/eldy/ckeditor/config.js index a1bb5fdcf0b..eabd0c58bd3 100644 --- a/htdocs/theme/eldy/ckeditor/config.js +++ b/htdocs/theme/eldy/ckeditor/config.js @@ -31,7 +31,7 @@ CKEDITOR.editorConfig = function( config ) ['Templates','NewPage'], ['Save'], ['Source','Maximize','Preview'], - ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], + ['PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], ['CreateDiv','ShowBlocks'], ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], @@ -42,14 +42,14 @@ CKEDITOR.editorConfig = function( config ) ['Link','Unlink','Anchor'], ['Image','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'], ['Styles','Format','Font','FontSize'], - ['TextColor','BGColor'], + ['TextColor','BGColor'] ]; // Used for mailing fields config.toolbar_dolibarr_mailings = [ ['Source','Maximize','Preview'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], ['Undo','Redo','-','Find','Replace'], ['CreateDiv','ShowBlocks'], ['Format','Font','FontSize'], @@ -63,7 +63,7 @@ CKEDITOR.editorConfig = function( config ) config.toolbar_dolibarr_notes = [ ['Source','Maximize'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Undo','Redo','-','Find','Replace'], ['Format','Font','FontSize'], ['Bold','Italic','Underline','Strike','Subscript','Superscript','-','TextColor','RemoveFormat'], @@ -76,9 +76,9 @@ CKEDITOR.editorConfig = function( config ) config.toolbar_dolibarr_details = [ ['Source','Maximize'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Format','Font','FontSize'], - ['Bold','Italic','Underline','Strike','Subscript','Superscript','-','TextColor','RemoveFormat'], + ['Bold','Italic','Underline','Strike','-','TextColor','RemoveFormat'], // ,'Subscript','Superscript' useless ['NumberedList','BulletedList','Outdent','Indent'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['Link','Unlink','SpecialChar'] diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 38d50962086..793e17c8f72 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -411,7 +411,6 @@ hr { border: 0; border-top: 1px solid #ccc; } margin-top: 0; text-align: center; cursor: pointer; - color: #333333 !important; text-decoration: none !important; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); background-color: #f5f5f5; @@ -430,9 +429,6 @@ hr { border: 0; border-top: 1px solid #ccc; } -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); } .button:focus, .buttonDelete:focus { -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 60, 0.2), 0px 0px 0px rgba(60,60,60,0.1); @@ -775,8 +771,8 @@ div.fiche>form>div.div-table-responsive { .minwidth100imp { min-width: 80px !important; } .minwidth200imp { min-width: 100px !important; } .minwidth300imp { min-width: 100px !important; } - .minwidth400imp { min-width: 100px !important; } - .minwidth500imp { min-width: 100px !important; } + .minwidth400imp { min-width: 150px !important; } + .minwidth500imp { min-width: 250px !important; } } /* Force values for small screen 570 */ @@ -826,9 +822,9 @@ div.fiche>form>div.div-table-responsive { .minwidth75imp { min-width: 60px !important; } .minwidth100imp { min-width: 60px !important; } .minwidth200imp { min-width: 60px !important; } - .minwidth300imp { min-width: 60px !important; } - .minwidth400imp { min-width: 60px !important; } - .minwidth500imp { min-width: 60px !important; } + .minwidth300imp { min-width: 100px !important; } + .minwidth400imp { min-width: 150px !important; } + .minwidth500imp { min-width: 250px !important; } .titlefield { width: auto; } .titlefieldcreate { width: auto; } @@ -2115,6 +2111,7 @@ span.butAction, span.butActionDelete { .butActionDelete, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active, .buttonDelete { background: #633; border: 1px solid #633; + color: #FFF; } .butActionDelete:hover { diff --git a/htdocs/theme/md/ckeditor/config.js b/htdocs/theme/md/ckeditor/config.js index eb88af48a04..6f1bbe7fb30 100644 --- a/htdocs/theme/md/ckeditor/config.js +++ b/htdocs/theme/md/ckeditor/config.js @@ -31,25 +31,25 @@ CKEDITOR.editorConfig = function( config ) ['Templates','NewPage'], ['Save'], ['Source','Maximize','Preview'], - ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], + ['PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], + ['CreateDiv','ShowBlocks'], ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], - ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], + ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['BidiLtr', 'BidiRtl'], ['Link','Unlink','Anchor'], ['Image','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'], ['Styles','Format','Font','FontSize'], - ['TextColor','BGColor'], - ['Maximize', 'ShowBlocks'] + ['TextColor','BGColor'] ]; // Used for mailing fields config.toolbar_dolibarr_mailings = [ ['Source','Maximize','Preview'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Undo','Redo','-','Find','Replace'], ['Format','Font','FontSize'], ['Bold','Italic','Underline','Strike','Subscript','Superscript','-','TextColor','RemoveFormat'], @@ -62,7 +62,7 @@ CKEDITOR.editorConfig = function( config ) config.toolbar_dolibarr_notes = [ ['Source','Maximize'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Undo','Redo','-','Find','Replace'], ['Format','Font','FontSize'], ['Bold','Italic','Underline','Strike','Subscript','Superscript','-','TextColor','RemoveFormat'], @@ -75,9 +75,9 @@ CKEDITOR.editorConfig = function( config ) config.toolbar_dolibarr_details = [ ['Source','Maximize'], - ['Cut','Copy','Paste','-','SpellChecker', 'Scayt'], + ['SpellChecker', 'Scayt'], // 'Cut','Copy','Paste','-', are useless, can be done with right click, even on smarpthone ['Format','Font','FontSize'], - ['Bold','Italic','Underline','Strike','Subscript','Superscript','-','TextColor','RemoveFormat'], + ['Bold','Italic','Underline','Strike','-','TextColor','RemoveFormat'], // ,'Subscript','Superscript' useless ['NumberedList','BulletedList','Outdent','Indent'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['Link','Unlink','SpecialChar'] diff --git a/htdocs/user/index.php b/htdocs/user/index.php index 312416afa29..c3a32ae02fc 100644 --- a/htdocs/user/index.php +++ b/htdocs/user/index.php @@ -458,7 +458,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['u.datec']['checked'])) print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"u.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['u.tms']['checked'])) print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"u.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['u.statut']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"u.statut","",$param,'align="center"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; From 1ab3086fcafa9cd342a3ea6d5ad6343db2ece6ed Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Apr 2017 16:44:43 +0200 Subject: [PATCH 113/233] Work on website module --- htdocs/websites/index.php | 225 ++++++++++++++++++++------------------ 1 file changed, 120 insertions(+), 105 deletions(-) diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index e6bfec0d84a..b55f81f5b7f 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2016-2017 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -143,6 +143,8 @@ $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain */ if (GETPOST('refreshsite')) $pageid=0; // If we change the site, we reset the pageid. +if (GETPOST('refreshpage')) $action='preview'; + // Add page if ($action == 'add') @@ -434,7 +436,7 @@ if ($action == 'updatemeta') } // Update page -if ($action == 'updatecontent') +if ($action == 'updatecontent' || GETPOST('refreshsite') || GETPOST('refreshpage') || GETPOST('preview')) { $db->begin(); $object->fetch(0, $website); @@ -444,110 +446,123 @@ if ($action == 'updatecontent') $res = $objectpage->fetch($pageid, $object->fk_website); if ($res > 0) { - $objectpage->content = GETPOST('PAGE_CONTENT'); - - // Clean data. We remove all the head section. - $objectpage->content = preg_replace('//s', '', $objectpage->content); - /* $objectpage->content = preg_replace('//s', '', $objectpage->content); */ - - $res = $objectpage->update($user); - if ($res < 0) + if ($action == 'updatecontent') { - $error++; - setEventMessages($objectpage->error, $objectpage->errors, 'errors'); - } - - if (! $error) - { - $db->commit(); - - $filemaster=$pathofwebsite.'/master.inc.php'; - //$fileoldalias=$pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php'; - $filealias=$pathofwebsite.'/'.$objectpage->pageurl.'.php'; - - dol_mkdir($pathofwebsite); - - - // Now generate the master.inc.php page - dol_syslog("We regenerate the master file"); - dol_delete_file($filemaster); - - $mastercontent = ''."\n"; - $result = file_put_contents($filemaster, $mastercontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filemaster, octdec($conf->global->MAIN_UMASK)); - - if (! $result) setEventMessages('Failed to write file '.$filemaster, null, 'errors'); - - - // Now generate the alias.php page - if (! empty($fileoldalias)) - { - dol_syslog("We regenerate alias page new name=".$filealias.", old name=".$fileoldalias); - dol_delete_file($fileoldalias); - } + $objectpage->content = GETPOST('PAGE_CONTENT'); + + // Clean data. We remove all the head section. + $objectpage->content = preg_replace('//s', '', $objectpage->content); + /* $objectpage->content = preg_replace('//s', '', $objectpage->content); */ - $aliascontent = '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 (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); - - - // Now create the .tpl file with code to be able to make dynamic changes - dol_delete_file($filetpl); - - $tplcontent =''; - $tplcontent.= "\n"; - $tplcontent.= ''."\n"; - $tplcontent.= '
    '."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''.dol_escape_htmltag($objectpage->title).''."\n"; - $tplcontent.= '
    '."\n"; - - $tplcontent.= ''."\n"; - $tplcontent.= $objectpage->content."\n"; - $tplcontent.= ''."\n"; - - $tplcontent.= '"."\n"; - - //var_dump($filetpl);exit; - $result = file_put_contents($filetpl, $tplcontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); - - if ($result) - { - setEventMessages($langs->trans("Saved"), null, 'mesgs'); - header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); - exit; - } - else setEventMessages('Failed to write file '.$filetpl, null, 'errors'); - } - else - { - $db->rollback(); - } + $res = $objectpage->update($user); + if ($res < 0) + { + $error++; + setEventMessages($objectpage->error, $objectpage->errors, 'errors'); + } + + if (! $error) + { + $db->commit(); + + $filemaster=$pathofwebsite.'/master.inc.php'; + //$fileoldalias=$pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php'; + $filealias=$pathofwebsite.'/'.$objectpage->pageurl.'.php'; + + dol_mkdir($pathofwebsite); + + + // Now generate the master.inc.php page + dol_syslog("We regenerate the master file"); + dol_delete_file($filemaster); + + $mastercontent = ''."\n"; + $result = file_put_contents($filemaster, $mastercontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filemaster, octdec($conf->global->MAIN_UMASK)); + + if (! $result) setEventMessages('Failed to write file '.$filemaster, null, 'errors'); + + + // Now generate the alias.php page + if (! empty($fileoldalias)) + { + dol_syslog("We regenerate alias page new name=".$filealias.", old name=".$fileoldalias); + dol_delete_file($fileoldalias); + } + + $aliascontent = '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 (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); + + + // Now create the .tpl file with code to be able to make dynamic changes + dol_delete_file($filetpl); + + $tplcontent =''; + $tplcontent.= "\n"; + $tplcontent.= ''."\n"; + $tplcontent.= '
    '."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''.dol_escape_htmltag($objectpage->title).''."\n"; + $tplcontent.= '
    '."\n"; + + $tplcontent.= ''."\n"; + $tplcontent.= $objectpage->content."\n"; + $tplcontent.= ''."\n"; + + $tplcontent.= '"."\n"; + + //var_dump($filetpl);exit; + $result = file_put_contents($filetpl, $tplcontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); + + if ($result) + { + setEventMessages($langs->trans("Saved"), null, 'mesgs'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + exit; + } + else + { + setEventMessages('Failed to write file '.$filetpl, null, 'errors'); + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + exit; + } + } + else + { + $db->rollback(); + } + } + else + { + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + exit; + } } else { @@ -603,7 +618,7 @@ if ($action == 'edit') $style=''; if ($action != 'preview' && $action != 'editcontent') $style=' margin-bottom: 5px;'; - +//var_dump($objectpage);exit; print '
    '; if (count($object->records) > 0) From a0e75d0af053851c08c6efa2bd266e6a6ddbd9b4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Apr 2017 16:44:43 +0200 Subject: [PATCH 114/233] Work on look and feel v6 --- htdocs/categories/class/categorie.class.php | 93 +++++--- htdocs/compta/bank/ligne.php | 169 +++++++-------- htdocs/compta/bank/releve.php | 7 +- htdocs/core/class/html.form.class.php | 34 ++- htdocs/websites/index.php | 225 +++++++++++--------- 5 files changed, 299 insertions(+), 229 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 0263395ec50..b2cd3d3dd31 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -49,9 +49,10 @@ class Categorie extends CommonObject const TYPE_MEMBER = 3; // TODO Replace this value with 'member' const TYPE_CONTACT = 4; // TODO Replace this value with 'contact' const TYPE_USER = 4; // categorie contact and user are same ! TODO Replace this value with 'user' - const TYPE_ACCOUNT = 5; // for bank account TODO Replace this value with 'account' - const TYPE_PROJECT = 6; - public $picto = 'category'; + const TYPE_ACCOUNT = 5; // TODO Replace this value with 'bank_account' + const TYPE_PROJECT = 6; + const TYPE_BANK_LINE = 'bank_line'; + public $picto = 'category'; /** @@ -1337,34 +1338,68 @@ class Categorie extends CommonObject $type = $map_type[$type]; } - $sql = "SELECT ct.fk_categorie, c.label, c.rowid"; - $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type] . " as ct, " . MAIN_DB_PREFIX . "categorie as c"; - $sql .= " WHERE ct.fk_categorie = c.rowid AND ct.fk_" . $this->MAP_CAT_FK[$type] . " = " . (int) $id . " AND c.type = " . $this->MAP_ID[$type]; - $sql .= " AND c.entity IN (" . getEntity( 'category', 1 ) . ")"; - - $res = $this->db->query($sql); - if ($res) + if ($type == Categorie::TYPE_BANK_LINE) // TODO Remove this with standard category code { - while ($obj = $this->db->fetch_object($res)) - { - if ($mode == 'id') { - $cats[] = $obj->rowid; - } else if ($mode == 'label') { - $cats[] = $obj->label; - } else { - $cat = new Categorie($this->db); - $cat->fetch($obj->fk_categorie); - $cats[] = $cat; - } - } - - return $cats; - } - else - { - dol_print_error($this->db); - return -1; + // Load bank groups + $sql = "SELECT c.label, c.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."bank_class as a, ".MAIN_DB_PREFIX."bank_categ as c"; + $sql.= " WHERE a.lineid=".$id." AND a.fk_categ = c.rowid"; + $sql.= " ORDER BY c.label"; + + $res = $this->db->query($sql); + if ($res) + { + while ($obj = $this->db->fetch_object($res)) + { + if ($mode == 'id') { + $cats[] = $obj->rowid; + } else if ($mode == 'label') { + $cats[] = $obj->label; + } else { + $cat = new Categorie($this->db); + $cat->id = $obj->rowid; + $cat->label = $obj->label; + $cats[] = $cat; + } + } + } + else + { + dol_print_error($this->db); + return -1; + } } + else + { + $sql = "SELECT ct.fk_categorie, c.label, c.rowid"; + $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type] . " as ct, " . MAIN_DB_PREFIX . "categorie as c"; + $sql .= " WHERE ct.fk_categorie = c.rowid AND ct.fk_" . $this->MAP_CAT_FK[$type] . " = " . (int) $id . " AND c.type = " . $this->MAP_ID[$type]; + $sql .= " AND c.entity IN (" . getEntity( 'category', 1 ) . ")"; + + $res = $this->db->query($sql); + if ($res) + { + while ($obj = $this->db->fetch_object($res)) + { + if ($mode == 'id') { + $cats[] = $obj->rowid; + } else if ($mode == 'label') { + $cats[] = $obj->label; + } else { + $cat = new Categorie($this->db); + $cat->fetch($obj->fk_categorie); + $cats[] = $cat; + } + } + } + else + { + dol_print_error($this->db); + return -1; + } + } + + return $cats; } diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index 360a0d15a00..b50bf07d31a 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -1,7 +1,7 @@ * Copyright (C) 2003 Xavier DUTOIT - * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2004 Christophe Combelles * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2015-2017 Alexandre Spangaro @@ -30,6 +30,7 @@ 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'; $langs->load("banks"); $langs->load("categories"); @@ -47,6 +48,8 @@ $action=GETPOST('action','alpha'); $confirm=GETPOST('confirm','alpha'); $rowid=GETPOST("rowid",'int'); $orig_account=GETPOST("orig_account"); +$backtopage=GETPOST('backtopage'); +$cancel=GETPOSt('cancel'); // Security check $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref :'')); @@ -59,6 +62,14 @@ if (! $user->rights->banque->lire && ! $user->rights->banque->consolidate) acces /* * Actions */ +if ($cancel) +{ + if ($backtopage) + { + header("Location: ".$backtopage); + exit; + } +} if ($user->rights->banque->consolidate && $action == 'dvnext') { @@ -81,21 +92,6 @@ if ($action == 'confirm_delete_categ' && $confirm == "yes" && $user->rights->ban } } -if ($user->rights->banque->modifier && $action == 'class') -{ - $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class WHERE lineid = ".$rowid." AND fk_categ = ".GETPOST('cat1', 'int'); - if (! $db->query($sql)) - { - dol_print_error($db); - } - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (lineid, fk_categ) VALUES (".$rowid.", ".GETPOST('cat1', 'int').")"; - if (! $db->query($sql)) - { - dol_print_error($db); - } -} - if ($user->rights->banque->modifier && $action == "update") { $error=0; @@ -145,7 +141,36 @@ if ($user->rights->banque->modifier && $action == "update") $sql.= " WHERE rowid = ".$rowid; $result = $db->query($sql); - if ($result) + if (! $result) + { + $error++; + } + + if (! $error) + { + $arrayofcategs=GETPOST('custcats', 'array'); + $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class WHERE lineid = ".$rowid; + if (! $db->query($sql)) + { + $error++; + dol_print_error($db); + } + if (count($arrayofcategs)) + { + foreach($arrayofcategs as $val) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (lineid, fk_categ) VALUES (".$rowid.", ".$val.")"; + if (! $db->query($sql)) + { + $error++; + dol_print_error($db); + } + } + // $arrayselected will be loaded after in page output + } + } + + if (! $error) { setEventMessages($langs->trans("RecordSaved"), null, 'mesgs'); $db->commit(); @@ -204,19 +229,14 @@ if ($user->rights->banque->consolidate && ($action == 'num_releve' || $action == $form = new Form($db); -llxHeader(); +llxHeader('', $langs->trans("BankTransaction")); -// Load bank groups -require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/bankcateg.class.php'; -$bankcateg = new BankCateg($db); -$options = array(); - -foreach ($bankcateg->fetchAll() as $bankcategory) { - $options[$bankcategory->id] = $bankcategory->label; +$c = new Categorie($db); +$cats = $c->containing($rowid, Categorie::TYPE_BANK_LINE); +foreach ($cats as $cat) { + $arrayselected[] = $cat->id; } -$var=false; - $tabs = array( array( DOL_URL_ROOT.'/compta/bank/ligne.php?rowid='.$rowid, @@ -300,7 +320,7 @@ if ($result) // Show links of bank transactions if (count($links)) { - print "
    "; + print ''; print ''; } else @@ -444,7 +464,7 @@ if ($result) if ($user->rights->banque->modifier || $user->rights->banque->consolidate) { print ''; } else @@ -498,7 +518,7 @@ if ($result) if ($user->rights->banque->modifier || $user->rights->banque->consolidate) { print ''; } else @@ -532,7 +552,7 @@ if ($result) if ($user->rights->banque->modifier) { print ''; } else @@ -543,25 +563,41 @@ if ($result) } print ""; + // Categories + if (! empty($conf->categorie->enabled) && ! empty($user->rights->categorie->lire)) + { + $langs->load('categories'); + + // Bank line + print '"; + } + print "
    '; print ''; print '
    '; $holidaystatic->id=$infos_CP['rowid']; $holidaystatic->ref=$infos_CP['rowid']; diff --git a/htdocs/modulebuilder/skeletons/skeleton_list.php b/htdocs/modulebuilder/skeletons/skeleton_list.php index 561dc98da35..fb2ec136bbe 100644 --- a/htdocs/modulebuilder/skeletons/skeleton_list.php +++ b/htdocs/modulebuilder/skeletons/skeleton_list.php @@ -365,7 +365,7 @@ print $hookmanager->resPrint; if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); //if (! empty($arrayfields['t.status']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"t.status","",$param,'align="center"',$sortfield,$sortorder); -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print '
    ".$langs->trans("Links")."
    '.$langs->trans("Links").''; foreach($links as $key=>$val) { @@ -430,7 +450,7 @@ if ($result) if ($user->rights->banque->modifier || $user->rights->banque->consolidate) { print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - print 'rappro?' disabled':'').' value="'; + print 'rappro?' disabled':'').' value="'; if (preg_match('/^\((.*)\)$/i',$objp->label,$reg)) { // Label generique car entre parentheses. On l'affiche en le traduisant @@ -508,7 +528,7 @@ if ($result) { print $objp->label; } - print '" size="50">'; + print '">'; print ''; - print 'rappro?' disabled':'').' value="'.price($objp->amount).'"> '.$langs->trans("Currency".$acct->currency_code); + print 'rappro?' disabled':'').' value="'.price($objp->amount).'"> '.$langs->trans("Currency".$acct->currency_code); print '
    ' . fieldLabel('RubriquesTransactions', 'custcats') . ''; + $cate_arbo = $form->select_all_categories(Categorie::TYPE_BANK_LINE, null, 'parent', null, null, 1); + print $form->multiselectarray('custcats', $cate_arbo, $arrayselected, null, null, null, null, "90%"); + print "
    "; dol_fiche_end(); + print '

    '; - + print ""; + + // Releve rappro if ($acct->canBeConciliated() > 0) // Si compte rapprochable { - print '

    '."\n"; - print load_fiche_titre($langs->trans("Reconciliation"), '', 'title_bank.png'); + print '
    '."\n"; + print '
    '; print ''; print ''; print ''; - + print ''; + print ''; print '"; @@ -600,7 +636,15 @@ if ($result) print ''; print '
    '.$langs->trans("Conciliation")."
    '; - print '

    '; + print '
    '; + + print ''; + if ($backtopage) + { + print '   '; + print ''; + } + print '
    '; print '
    '; } @@ -611,55 +655,6 @@ if ($result) } else dol_print_error($db); - - -// List of bank categories -print '
    '; - -print '
    '; -print ''; -print ''; -print ''; - -print ''; -print ''; -} -print ''; - -$sql = "SELECT c.label, c.rowid"; -$sql.= " FROM ".MAIN_DB_PREFIX."bank_class as a, ".MAIN_DB_PREFIX."bank_categ as c"; -$sql.= " WHERE a.lineid=".$rowid." AND a.fk_categ = c.rowid"; -$sql.= " ORDER BY c.label"; -$result = $db->query($sql); -if ($result) -{ - $var=True; - $num = $db->num_rows($result); - $i = 0; $total = 0; - while ($i < $num) - { - $objp = $db->fetch_object($result); - - print ''; - - print ""; - print ""; - if ($user->rights->banque->modifier) - { - print ''; - } - print ''; - - $i++; - } - $db->free($result); -} -print '
    '.$langs->trans("Rubriques").''; -if ($user->rights->banque->modifier) -{ - print Form::selectarray('cat1', $options, '', 1).' '; - print '
    ".$objp->label."rowid."\">".$langs->trans("ListBankTransactions")."'.img_delete($langs->trans("Remove")).'
    '; - llxFooter(); $db->close(); diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index 9d9826d0729..5abbcb2512e 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2017 Patrick Delcroix @@ -403,8 +403,7 @@ else $objp = $db->fetch_object($result); $total = $total + $objp->amount; - $var=!$var; - print ""; + print ''; // Date operation print ''.dol_print_date($db->jdate($objp->do),"day").''; @@ -595,7 +594,7 @@ else if ($user->rights->banque->modifier || $user->rights->banque->consolidate) { - print "rowid&account=".$object->id."\">"; + print ''; print img_edit(); print ""; } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index eba2fda5049..6bd2d3036b9 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3395,7 +3395,7 @@ class Form */ function select_all_categories($type, $selected='', $htmlname="parent", $maxlength=64, $excludeafterid=0, $outputmode=0) { - global $langs; + global $conf, $langs; $langs->load("categories"); include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; @@ -3406,9 +3406,35 @@ class Form dol_syslog(__METHOD__ . ': using numeric value for parameter type is deprecated. Use string code instead.', LOG_WARNING); } - $cat = new Categorie($this->db); - $cate_arbo = $cat->get_full_arbo($type,$excludeafterid); - + if ($type == Categorie::TYPE_BANK_LINE) + { + // TODO Move this into common category feature + $categids=array(); + $sql = "SELECT c.label, c.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."bank_categ as c"; + $sql.= " WHERE entity = ".$conf->entity; + $sql.= " ORDER BY c.label"; + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + while ($i < $num) + { + $objp = $this->db->fetch_object($result); + if ($objp) $cate_arbo[$objp->rowid]=array('id'=>$objp->rowid, 'fulllabel'=>$objp->label); + $i++; + } + $this->db->free($result); + } + else dol_print_error($this->db); + } + else + { + $cat = new Categorie($this->db); + $cate_arbo = $cat->get_full_arbo($type,$excludeafterid); + } + $output = ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +$head=defaultvalues_prepare_head(); + +dol_fiche_head($head, 'overwrite', '', -1, ''); + + +print ''; +print ''; +print ''; + +print ''; +print ''; +print_liste_field_titre($langs->trans("Language").' (en_US, es_MX, ...)',$_SERVER["PHP_SELF"],'lang,transkey','',$param,'',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("Key"),$_SERVER["PHP_SELF"],'transkey','',$param,'',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("NewTranslationStringToShow"),$_SERVER["PHP_SELF"],'transvalue','',$param,'',$sortfield,$sortorder); +//if (! empty($conf->multicompany->enabled) && !$user->entity) print_liste_field_titre($langs->trans("Entity"),$_SERVER["PHP_SELF"],'entity,transkey','',$param,'',$sortfield,$sortorder); +print ''; +print "\n"; + + +// Line to add new record +print "\n"; + +print ''."\n"; +print ''; +// Limit to superadmin +/*if (! empty($conf->multicompany->enabled) && !$user->entity) +{ + print ''; + print '\n"; +print ''; + + +// Show constants +$sql = "SELECT"; +$sql.= " rowid"; +$sql.= ", lang"; +$sql.= ", transkey"; +$sql.= ", transvalue"; +$sql.= " FROM ".MAIN_DB_PREFIX."overwrite_trans"; +$sql.= " WHERE 1 = 1"; +//$sql.= " AND entity IN (".$user->entity.",".$conf->entity.")"; +//if ((empty($user->entity) || $user->admin) && $debug) {} // to force for superadmin to debug +//else if (! GETPOST('visible') || GETPOST('visible') != 'all') $sql.= " AND visible = 1"; // We must always have this. Otherwise, array is too large and submitting data fails due to apache POST or GET limits +//if (GETPOST('name')) $sql.=natural_search("name", GETPOST('name')); +//$sql.= " ORDER BY entity, name ASC"; +$sql.= $db->order($sortfield, $sortorder); + +dol_syslog("translation::select from table", LOG_DEBUG); +$result = $db->query($sql); +if ($result) +{ + $num = $db->num_rows($result); + $i = 0; + $var=false; + + while ($i < $num) + { + $obj = $db->fetch_object($result); + $var=!$var; + + print "\n"; + + print ''; + + print ''."\n"; + print ''."\n"; + + // Value + print ''; + + print ''; + + print "\n"; + print "\n"; + $i++; + } +} + + +print '
    '; +print $formadmin->select_language(GETPOST('langcode'), 'langcode', 0, null, 1, 0, 0, 'maxwidthonsmartphone', 1); +print ''; +print ''; +print ''; +print ''; +print ''; + print ''; + print ''; +} +else +{*/ + print ''; + print ''; +//} +print ''; +print "
    '.$obj->lang.''.$obj->transkey.''; + /*print ''; + print ''; + print ''; + print ''; + */ + print $obj->transvalue; + print ''; + print ''.img_delete().''; + print '
    '; + +dol_fiche_end(); + +print "\n"; + + +llxFooter(); + +$db->close(); diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php index 4dbfc53c821..bb485c41999 100644 --- a/htdocs/admin/translation.php +++ b/htdocs/admin/translation.php @@ -57,10 +57,6 @@ if (! $sortfield) $sortfield='lang,transkey'; if (! $sortorder) $sortorder='ASC'; -/* - * Actions - */ - /* * Actions */ diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index edfeef064f2..5c4df1bcd91 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -598,6 +598,35 @@ function translation_prepare_head() } +/** + * Prepare array with list of tabs + * + * @return array Array of tabs to show + */ +function defaultvalues_prepare_head() +{ + global $langs, $conf, $user; + $h = 0; + $head = array(); + + $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=overwrite"; + $head[$h][1] = $langs->trans("DefaultValuesOverwriteKey"); + $head[$h][2] = 'overwrite'; + $h++; + + /*$head[$h][0] = DOL_URL_ROOT."/admin/translation.php?mode=searchkey"; + $head[$h][1] = $langs->trans("TranslationKeySearch"); + $head[$h][2] = 'searchkey'; + $h++;*/ + + complete_head_from_modules($conf,$langs,null,$head,$h,'defaultvalues_admin'); + + complete_head_from_modules($conf,$langs,null,$head,$h,'defaultvalues_admin','remove'); + + + return $head; +} + /** * Return list of session diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index c0da3e8af0e..f85885def1d 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -545,6 +545,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/admin/ihm.php?mainmenu=home", $langs->trans("GUISetup"),1); $newmenu->add("/admin/translation.php?mainmenu=home", $langs->trans("Translation"),1); + $newmenu->add("/admin/defaultvalues.php?mainmenu=home", $langs->trans("DefaultValues"),1, $conf->global->MAIN_FEATURES_LEVEL); $newmenu->add("/admin/boxes.php?mainmenu=home", $langs->trans("Boxes"),1); $newmenu->add("/admin/delais.php?mainmenu=home",$langs->trans("MenuWarnings"),1); $newmenu->add("/admin/security_other.php?mainmenu=home", $langs->trans("Security"),1); From ff75077b340888a079b1a61c541b1c90bb83d03b Mon Sep 17 00:00:00 2001 From: vvnt Date: Sat, 8 Apr 2017 20:15:14 +0200 Subject: [PATCH 119/233] Fix: bug #6653 situation invoice miscalculation Bug (#6653) In price.lib.php (htdocs\core\lib\price.lib.php), the function calcul_price_total() is defined (line 76). The 7th parameter is **$remise_percent_global**. However, this function is called on facture.class.php (htdocs\compta\facture\class\facture.class.php) and the 7th parameter used is **$line->product_type**. Consequently, invoice situation is correct when user sells a product (product_type = 0) and is wrong when user sells a service (product_type = 1). Effectively, in the latter case, the total situation invoice will be wrong by 1%. In order to correct this, we can add 0 as the 7th parameter and move **$line->product_type** to the 10th parameter. --- htdocs/compta/facture/class/facture.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 963534da934..5838bb9bcf3 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2872,7 +2872,7 @@ class Facture extends CommonInvoice // Cap percentages to 100 if ($percent > 100) $percent = 100; $line->situation_percent = $percent; - $tabprice = calcul_price_total($line->qty, $line->subprice, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->product_type, 'HT', 0, 0, $mysoc, '', $percent); + $tabprice = calcul_price_total($line->qty, $line->subprice, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 0, 'HT', 0, $line->product_type, $mysoc, '', $percent); $line->total_ht = $tabprice[0]; $line->total_tva = $tabprice[1]; $line->total_ttc = $tabprice[2]; From feebd4252a0d364f18cfcbb520d8e4c3248d74f8 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sun, 9 Apr 2017 11:29:54 +0200 Subject: [PATCH 120/233] add invoice_rec_prepare_head for reccuring invoice --- htdocs/core/lib/invoice.lib.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index 6e5640d1e0a..453b27aefee 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -3,6 +3,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2015 Juanjo Menent + * Copyright (C) 2017 Charlie Benke * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -157,4 +158,27 @@ function invoice_admin_prepare_head() } +function invoice_rec_prepare_head($object) +{ + global $db, $langs, $conf; + + $h = 0; + $head = array(); + + $head[$h][0] = DOL_URL_ROOT.'/compta/facture/fiche-rec.php?facid='.$object->id; + $head[$h][1] = $langs->trans('Card'); + $head[$h][2] = 'compta'; + $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,$object,$head,$h,'invoice-rec'); + + complete_head_from_modules($conf,$langs,$object,$head,$h,'invoice-rec','remove'); + + return $head; +} + From 54780ff205b5ab18b8a25b11318c08b8cb50c788 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sun, 9 Apr 2017 11:33:09 +0200 Subject: [PATCH 121/233] Update fiche-rec.php --- htdocs/compta/facture/fiche-rec.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index 88cb39bd7a9..90938242f5f 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -38,6 +38,7 @@ if (! empty($conf->projet->enabled)) { require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php'; } require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php'; $langs->load('bills'); $langs->load('compta'); @@ -1109,11 +1110,7 @@ else $author = new User($db); $author->fetch($object->user_author); - $head=array(); - $h=0; - $head[$h][0] = $_SERVER["PHP_SELF"].'?id='.$object->id; - $head[$h][1] = $langs->trans("CardBill"); - $head[$h][2] = 'card'; + $head=invoice_rec_prepare_head($object); dol_fiche_head($head, 'card', $langs->trans("RepeatableInvoice"),0,'bill'); // Add a div From a0a9c8fa0c35e5c122fa5ee5a3c4c077cdcee77a Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sun, 9 Apr 2017 11:33:56 +0200 Subject: [PATCH 122/233] Update invoice.lib.php --- htdocs/core/lib/invoice.lib.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index 453b27aefee..564e909a2da 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -165,9 +165,9 @@ function invoice_rec_prepare_head($object) $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/compta/facture/fiche-rec.php?facid='.$object->id; - $head[$h][1] = $langs->trans('Card'); - $head[$h][2] = 'compta'; + $head[$h][0] = DOL_URL_ROOT.'/compta/facture/fiche-rec.php?id='.$object->id; + $head[$h][1] = $langs->trans("CardBill"); + $head[$h][2] = 'card'; $h++; // Show more tabs from modules From e4ed626912dcd6d070eeb286e15a124d94d110c8 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Sun, 9 Apr 2017 12:50:09 +0200 Subject: [PATCH 123/233] Fix: Travis error --- test/phpunit/FactureFournisseurTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/phpunit/FactureFournisseurTest.php b/test/phpunit/FactureFournisseurTest.php index 199d397f50d..7985e8f0931 100644 --- a/test/phpunit/FactureFournisseurTest.php +++ b/test/phpunit/FactureFournisseurTest.php @@ -1,5 +1,6 @@ + * Copyright (C) 2017 Juanjo Menent * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -259,7 +260,7 @@ class FactureFournisseurTest extends PHPUnit_Framework_TestCase $localobject=new FactureFournisseur($this->savdb); $result=$localobject->fetch($id); - $result=$localobject->delete($id); + $result=$localobject->delete($user); print __METHOD__." id=".$id." result=".$result."\n"; $this->assertLessThan($result, 0); From 52c86cb3f5af57c26e691241adf9bfde3e1bd2ae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 9 Apr 2017 13:12:25 +0200 Subject: [PATCH 124/233] NEW Bulk actions available on supplier orders --- htdocs/comm/card.php | 2 +- htdocs/comm/remise.php | 38 +- htdocs/comm/remx.php | 262 ++++++----- htdocs/commande/list.php | 449 ++++++++++--------- htdocs/core/class/html.form.class.php | 2 +- htdocs/core/class/html.formfile.class.php | 10 +- htdocs/core/lib/files.lib.php | 24 + htdocs/core/lib/functions.lib.php | 16 + htdocs/fourn/commande/list.php | 517 +++++++++++++++++++--- htdocs/societe/class/societe.class.php | 2 +- htdocs/theme/eldy/style.css.php | 23 +- htdocs/theme/md/style.css.php | 14 +- 12 files changed, 913 insertions(+), 446 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index aa6c2729745..52fdaa6eceb 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -460,7 +460,7 @@ if ($id > 0) } else { - print $langs->trans("ThirdpartyNotLinkedToMember"); + print ''.$langs->trans("ThirdpartyNotLinkedToMember").''; } print ''; print "\n"; diff --git a/htdocs/comm/remise.php b/htdocs/comm/remise.php index cf93c87dabb..2be1981c5ae 100644 --- a/htdocs/comm/remise.php +++ b/htdocs/comm/remise.php @@ -107,7 +107,7 @@ if ($socid > 0) print ''; print ''; - dol_fiche_head($head, 'relativediscount', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'relativediscount', $langs->trans("ThirdParty"), 0, 'company'); dol_banner_tab($object, 'socid', '', ($user->societe_id?0:1), 'rowid', 'nom'); @@ -119,7 +119,6 @@ if ($socid > 0) // Discount print ''; print $langs->trans("CustomerRelativeDiscount").''.price2num($object->remise_percent)."%"; - print ''; print '
    '; @@ -130,11 +129,11 @@ if ($socid > 0) print ''; // New value - print ''; // Motif/Note - print ''; print "
    '; + print '
    '; print $langs->trans("NewValue").'%
    '; + print '
    '; print $langs->trans("NoteReason").'
    "; @@ -179,21 +178,26 @@ if ($socid > 0) print ''.$langs->trans("NoteReason").''; print ''.$langs->trans("User").''; print ''; - $i = 0 ; $num = $db->num_rows($resql); - - while ($i < $num ) - { - $obj = $db->fetch_object($resql); - $tag = !$tag; - print ''; - print ''.dol_print_date($db->jdate($obj->dc),"dayhour").''; - print ''.price2num($obj->remise_percent).'%'; - print ''.$obj->note.''; - print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; - print ''; - $i++; + if ($num > 0) + { + $i = 0; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + print ''; + print ''.dol_print_date($db->jdate($obj->dc),"dayhour").''; + print ''.price2num($obj->remise_percent).'%'; + print ''.$obj->note.''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; + print ''; + $i++; + } } + else + { + print ''.$langs->trans("None").''; + } $db->free($resql); print ""; } diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 6481c891d45..375b4d0ecb8 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -235,7 +235,7 @@ if ($socid > 0) print ''; print ''; - dol_fiche_head($head, 'absolutediscount', $langs->trans("ThirdParty"),0,'company'); + dol_fiche_head($head, 'absolutediscount', $langs->trans("ThirdParty"), 0, 'company'); dol_banner_tab($object, 'socid', '', ($user->societe_id?0:1), 'rowid', 'nom'); @@ -274,6 +274,8 @@ if ($socid > 0) } print ''; + print '
    '; + if ($user->rights->societe->creer) { print '
    '; @@ -294,7 +296,6 @@ if ($socid > 0) print ""; } - print ''; dol_fiche_end(); @@ -342,8 +343,8 @@ if ($socid > 0) print load_fiche_titre($langs->trans("DiscountStillRemaining")); print ''; print ''; - print ''; // Need 120+ for format with AM/PM - print ''; + print ''; // Need 120+ for format with AM/PM + print ''; print ''; print ''; print ''; @@ -354,73 +355,79 @@ if ($socid > 0) $showconfirminfo=array(); - $var = true; $i = 0; $num = $db->num_rows($resql); - while ($i < $num) + if ($num > 0) { - $obj = $db->fetch_object($resql); - $var = !$var; - print ""; - print ''; - if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) - { - print ''; - } - elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) - { - print ''; - } - elseif (preg_match('/\(EXCESS RECEIVED\)/',$obj->description)) - { - print ''; - } - else - { - print ''; - } - print ''; - print ''; - print ''; - print ''; - print ''; - if ($user->rights->societe->creer || $user->rights->facture->creer) - { - print ''; - } - else print ''; - print ''; - - if ($_GET["action"]=='split' && GETPOST('remid') == $obj->rowid) - { - $showconfirminfo['rowid']=$obj->rowid; - $showconfirminfo['amount_ttc']=$obj->amount_ttc; - } - $i++; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + print ''; + print ''; + if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(EXCESS RECEIVED\)/',$obj->description)) + { + print ''; + } + else + { + print ''; + } + print ''; + print ''; + print ''; + print ''; + print ''; + if ($user->rights->societe->creer || $user->rights->facture->creer) + { + print ''; + } + else print ''; + print ''; + + if ($_GET["action"]=='split' && GETPOST('remid') == $obj->rowid) + { + $showconfirminfo['rowid']=$obj->rowid; + $showconfirminfo['amount_ttc']=$obj->amount_ttc; + } + $i++; + } } + else + { + print ''; + } $db->free($resql); print "
    '.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("ConsumedBy").''.$langs->trans("AmountHT").''.$langs->trans("VATRate").'
    '.dol_print_date($db->jdate($obj->dc),'dayhour').''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(EXCESS RECEIVED\)/',$langs->trans("Invoice"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - print $obj->description; - print ''.$langs->trans("NotConsumed").''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; - print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; - print ''; - print 'rowid.'">'.img_picto($langs->trans("SplitDiscount"),'split').''; - print '   '; - print 'rowid.'">'.img_delete($langs->trans("RemoveDiscount")).''; - print ' 
    '.dol_print_date($db->jdate($obj->dc),'dayhour').''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(EXCESS RECEIVED\)/',$langs->trans("Invoice"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + print $obj->description; + print ''.$langs->trans("NotConsumed").''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; + print ''; + print 'rowid.'">'.img_split($langs->trans("SplitDiscount")).''; + print '   '; + print 'rowid.'">'.img_delete($langs->trans("RemoveDiscount")).''; + print ' 
    '.$langs->trans("None").'
    "; @@ -491,8 +498,8 @@ if ($socid > 0) print load_fiche_titre($langs->trans("DiscountAlreadyCounted")); print ''; print ''; - print ''; // Need 120+ for format with AM/PM - print ''; + print ''; // Need 120+ for format with AM/PM + print ''; print ''; print ''; print ''; @@ -501,15 +508,17 @@ if ($socid > 0) print ''; print ''; - $var = true; $tab_sqlobj=array(); $tab_sqlobjOrder=array(); $num = $db->num_rows($resql); - for ($i = 0;$i < $num;$i++) + if ($num > 0) { - $sqlobj = $db->fetch_object($resql); - $tab_sqlobj[] = $sqlobj; - $tab_sqlobjOrder[]=$db->jdate($sqlobj->dc); + for ($i = 0;$i < $num; $i++) + { + $sqlobj = $db->fetch_object($resql); + $tab_sqlobj[] = $sqlobj; + $tab_sqlobjOrder[]=$db->jdate($sqlobj->dc); + } } $db->free($resql); @@ -524,57 +533,64 @@ if ($socid > 0) array_multisort($tab_sqlobjOrder,SORT_DESC,$tab_sqlobj); $num = count($tab_sqlobj); - $i = 0 ; - while ($i < $num ) + if ($num > 0) { - $obj = array_shift($tab_sqlobj); - $var = !$var; - print ""; - print ''; - if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) - { - print ''; - } - elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) - { - print ''; - } - elseif (preg_match('/\(EXCESS RECEIVED\)/',$obj->description)) - { - print ''; - } - else - { - print ''; - } - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - $i++; + $i = 0 ; + while ($i < $num ) + { + $obj = array_shift($tab_sqlobj); + print ''; + print ''; + if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(EXCESS RECEIVED\)/',$obj->description)) + { + print ''; + } + else + { + print ''; + } + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + $i++; + } } + else + { + print ''; + } + print "
    '.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("ConsumedBy").''.$langs->trans("AmountHT").''.$langs->trans("VATRate").' 
    '.dol_print_date($db->jdate($obj->dc),'dayhour').''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - $facturestatic->id=$obj->fk_facture_source; - $facturestatic->ref=$obj->ref; - $facturestatic->type=$obj->type; - print preg_replace('/\(EXCESS RECEIVED\)/',$langs->trans("Invoice"),$obj->description).' '.$facturestatic->getNomURl(1); - print ''; - print $obj->description; - print ''.img_object($langs->trans("ShowBill"),'bill').' '.$obj->facnumber.''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; - print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; - print ' 
    '.dol_print_date($db->jdate($obj->dc),'dayhour').''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + $facturestatic->id=$obj->fk_facture_source; + $facturestatic->ref=$obj->ref; + $facturestatic->type=$obj->type; + print preg_replace('/\(EXCESS RECEIVED\)/',$langs->trans("Invoice"),$obj->description).' '.$facturestatic->getNomURl(1); + print ''; + print $obj->description; + print ''.img_object($langs->trans("ShowBill"),'bill').' '.$obj->facnumber.''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; + print ' 
    '.$langs->trans("None").'
    "; } else diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index fcd68992b38..6d8f42edffb 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -199,227 +199,226 @@ if (empty($reshook)) $permtodelete = $user->rights->commande->supprimer; $uploaddir = $conf->commande->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; -} - -if ($massaction == 'confirm_createbills') { - - $orders = GETPOST('toselect'); - $createbills_onebythird = GETPOST('createbills_onebythird', 'int'); - $validate_invoices = GETPOST('valdate_invoices', 'int'); - - $TFact = array(); - $TFactThird = array(); - - $nb_bills_created = 0; - - $db->begin(); - - foreach($orders as $id_order) { - - $cmd = new Commande($db); - if($cmd->fetch($id_order) <= 0) continue; - - $object = new Facture($db); - if(!empty($createbills_onebythird) && !empty($TFactThird[$cmd->socid])) $object = $TFactThird[$cmd->socid]; // If option "one bill per third" is set, we use already created order. - else { - - $object->socid = $cmd->socid; - $object->type = Facture::TYPE_STANDARD; - $object->cond_reglement_id = $cmd->cond_reglement_id; - $object->mode_reglement_id = $cmd->mode_reglement_id; - $object->fk_project = $cmd->fk_project; - - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) - { - $datefacture = dol_mktime(date("h"), date("M"), 0, date("m"), date("d"), date("Y")); - } - - $object->date = $datefacture; - $object->origin = 'commande'; - $object->origin_id = $id_order; - - $res = $object->create($user); - - if($res > 0) $nb_bills_created++; - - } - - if($object->id > 0) { - - $db->begin(); - $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_element ("; - $sql.= "fk_source"; - $sql.= ", sourcetype"; - $sql.= ", fk_target"; - $sql.= ", targettype"; - $sql.= ") VALUES ("; - $sql.= $id_order; - $sql.= ", '".$object->origin."'"; - $sql.= ", ".$object->id; - $sql.= ", '".$object->element."'"; - $sql.= ")"; - - if ($db->query($sql)) - { - $db->commit(); - } - else - { - $db->rollback(); - } - - $lines = $cmd->lines; - if (empty($lines) && method_exists($cmd, 'fetch_lines')) - { - $cmd->fetch_lines(); - $lines = $cmd->lines; - } - - $fk_parent_line=0; - $num=count($lines); - - for ($i=0;$i<$num;$i++) - { - $desc=($lines[$i]->desc?$lines[$i]->desc:$lines[$i]->libelle); - if ($lines[$i]->subprice < 0) - { - // Negative line, we create a discount line - $discount = new DiscountAbsolute($db); - $discount->fk_soc=$object->socid; - $discount->amount_ht=abs($lines[$i]->total_ht); - $discount->amount_tva=abs($lines[$i]->total_tva); - $discount->amount_ttc=abs($lines[$i]->total_ttc); - $discount->tva_tx=$lines[$i]->tva_tx; - $discount->fk_user=$user->id; - $discount->description=$desc; - $discountid=$discount->create($user); - if ($discountid > 0) - { - $result=$object->insert_discount($discountid); - //$result=$discount->link_to_invoice($lineid,$id); - } - else - { - setEventMessages($discount->error, $discount->errors, 'errors'); - $error++; - break; - } - } - else - { - // Positive line - $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); - // Date start - $date_start=false; - if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; - if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; - if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; - //Date end - $date_end=false; - if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; - if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; - if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; - // Reset fk_parent_line for no child products and special product - if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) - { - $fk_parent_line = 0; - } - $result = $object->addline( - $desc, - $lines[$i]->subprice, - $lines[$i]->qty, - $lines[$i]->tva_tx, - $lines[$i]->localtax1_tx, - $lines[$i]->localtax2_tx, - $lines[$i]->fk_product, - $lines[$i]->remise_percent, - $date_start, - $date_end, - 0, - $lines[$i]->info_bits, - $lines[$i]->fk_remise_except, - 'HT', - 0, - $product_type, - $ii, - $lines[$i]->special_code, - $object->origin, - $lines[$i]->rowid, - $fk_parent_line, - $lines[$i]->fk_fournprice, - $lines[$i]->pa_ht, - $lines[$i]->label - ); - if ($result > 0) - { - $lineid=$result; - } - else - { - $lineid=0; - $error++; - break; - } - // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) - { - $fk_parent_line = $result; - } - } - } - - } - - $cmd->classifyBilled($user); - - if(!empty($createbills_onebythird) && empty($TFactThird[$cmd->socid])) $TFactThird[$cmd->socid] = $object; - else $TFact[$object->id] = $object; - } - - // Build doc with all invoices - $TAllFact = empty($createbills_onebythird) ? $TFact : $TFactThird; - $toselect = array(); - - if(!empty($validate_invoices)) { - - $massaction = $action = 'builddoc'; - - foreach($TAllFact as &$object) { - $object->validate($user); - $toselect[] = $object->id; // For builddoc action - - // Fac builddoc - $upload_dir = $conf->facture->dir_output; - $permissioncreate=$user->rights->facture->creer; - include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; - } - - $objectclass='Facture'; - $objectlabel='Invoice'; - $permtoread = $user->rights->facture->lire; - $permtodelete = $user->rights->facture->supprimer; - $uploaddir = $conf->facture->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; - - } - - if (! $error) - { - $db->commit(); - setEventMessage($langs->trans('BillCreated', $nb_bills_created)); - } - else - { - $db->rollback(); - $action='create'; - $_GET["origin"]=$_POST["origin"]; - $_GET["originid"]=$_POST["originid"]; - setEventMessages($object->error, $object->errors, 'errors'); - $error++; - } - + // TODO Move this into mass action include + if ($massaction == 'confirm_createbills') { + + $orders = GETPOST('toselect'); + $createbills_onebythird = GETPOST('createbills_onebythird', 'int'); + $validate_invoices = GETPOST('valdate_invoices', 'int'); + + $TFact = array(); + $TFactThird = array(); + + $nb_bills_created = 0; + + $db->begin(); + + foreach($orders as $id_order) { + + $cmd = new Commande($db); + if($cmd->fetch($id_order) <= 0) continue; + + $object = new Facture($db); + if(!empty($createbills_onebythird) && !empty($TFactThird[$cmd->socid])) $object = $TFactThird[$cmd->socid]; // If option "one bill per third" is set, we use already created order. + else { + + $object->socid = $cmd->socid; + $object->type = Facture::TYPE_STANDARD; + $object->cond_reglement_id = $cmd->cond_reglement_id; + $object->mode_reglement_id = $cmd->mode_reglement_id; + $object->fk_project = $cmd->fk_project; + + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) + { + $datefacture = dol_mktime(date("h"), date("M"), 0, date("m"), date("d"), date("Y")); + } + + $object->date = $datefacture; + $object->origin = 'commande'; + $object->origin_id = $id_order; + + $res = $object->create($user); + + if($res > 0) $nb_bills_created++; + + } + + if($object->id > 0) { + + $db->begin(); + $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_element ("; + $sql.= "fk_source"; + $sql.= ", sourcetype"; + $sql.= ", fk_target"; + $sql.= ", targettype"; + $sql.= ") VALUES ("; + $sql.= $id_order; + $sql.= ", '".$object->origin."'"; + $sql.= ", ".$object->id; + $sql.= ", '".$object->element."'"; + $sql.= ")"; + + if ($db->query($sql)) + { + $db->commit(); + } + else + { + $db->rollback(); + } + + $lines = $cmd->lines; + if (empty($lines) && method_exists($cmd, 'fetch_lines')) + { + $cmd->fetch_lines(); + $lines = $cmd->lines; + } + + $fk_parent_line=0; + $num=count($lines); + + for ($i=0;$i<$num;$i++) + { + $desc=($lines[$i]->desc?$lines[$i]->desc:$lines[$i]->libelle); + if ($lines[$i]->subprice < 0) + { + // Negative line, we create a discount line + $discount = new DiscountAbsolute($db); + $discount->fk_soc=$object->socid; + $discount->amount_ht=abs($lines[$i]->total_ht); + $discount->amount_tva=abs($lines[$i]->total_tva); + $discount->amount_ttc=abs($lines[$i]->total_ttc); + $discount->tva_tx=$lines[$i]->tva_tx; + $discount->fk_user=$user->id; + $discount->description=$desc; + $discountid=$discount->create($user); + if ($discountid > 0) + { + $result=$object->insert_discount($discountid); + //$result=$discount->link_to_invoice($lineid,$id); + } + else + { + setEventMessages($discount->error, $discount->errors, 'errors'); + $error++; + break; + } + } + else + { + // Positive line + $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); + // Date start + $date_start=false; + if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; + if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; + if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; + //Date end + $date_end=false; + if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; + if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; + if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; + // Reset fk_parent_line for no child products and special product + if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) + { + $fk_parent_line = 0; + } + $result = $object->addline( + $desc, + $lines[$i]->subprice, + $lines[$i]->qty, + $lines[$i]->tva_tx, + $lines[$i]->localtax1_tx, + $lines[$i]->localtax2_tx, + $lines[$i]->fk_product, + $lines[$i]->remise_percent, + $date_start, + $date_end, + 0, + $lines[$i]->info_bits, + $lines[$i]->fk_remise_except, + 'HT', + 0, + $product_type, + $ii, + $lines[$i]->special_code, + $object->origin, + $lines[$i]->rowid, + $fk_parent_line, + $lines[$i]->fk_fournprice, + $lines[$i]->pa_ht, + $lines[$i]->label + ); + if ($result > 0) + { + $lineid=$result; + } + else + { + $lineid=0; + $error++; + break; + } + // Defined the new fk_parent_line + if ($result > 0 && $lines[$i]->product_type == 9) + { + $fk_parent_line = $result; + } + } + } + + } + + $cmd->classifyBilled($user); + + if(!empty($createbills_onebythird) && empty($TFactThird[$cmd->socid])) $TFactThird[$cmd->socid] = $object; + else $TFact[$object->id] = $object; + } + + // Build doc with all invoices + $TAllFact = empty($createbills_onebythird) ? $TFact : $TFactThird; + $toselect = array(); + + if(!empty($validate_invoices)) { + + $massaction = $action = 'builddoc'; + + foreach($TAllFact as &$object) { + $object->validate($user); + $toselect[] = $object->id; // For builddoc action + + // Fac builddoc + $upload_dir = $conf->facture->dir_output; + $permissioncreate=$user->rights->facture->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; + } + + $objectclass='Facture'; + $objectlabel='Invoice'; + $permtoread = $user->rights->facture->lire; + $permtodelete = $user->rights->facture->supprimer; + $uploaddir = $conf->facture->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + + } + + if (! $error) + { + $db->commit(); + setEventMessage($langs->trans('BillCreated', $nb_bills_created)); + } + else + { + $db->rollback(); + $action='create'; + $_GET["origin"]=$_POST["origin"]; + $_GET["originid"]=$_POST["originid"]; + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } } @@ -435,8 +434,9 @@ $formfile = new FormFile($db); $companystatic = new Societe($db); $formcompany=new FormCompany($db); +$title=$langs->trans("Orders"); $help_url="EN:Module_Customers_Orders|FR:Module_Commandes_Clients|ES:Módulo_Pedidos_de_clientes"; -llxHeader('',$langs->trans("Orders"),$help_url); +llxHeader('',$title,$help_url); $sql = 'SELECT'; if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT'; @@ -622,7 +622,6 @@ if ($resql) if ($show_files) $param.='&show_files=' .$show_files; if ($optioncss != '') $param.='&optioncss='.$optioncss; if ($billed != '') $param.='&billed='.$billed; - // Add $param from extra fields foreach ($search_array_options as $key => $val) { @@ -654,6 +653,7 @@ if ($resql) print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_commercial.png', 0, '', '', $limit); + // TODO Move this into an invluce if ($massaction == 'presend') { $langs->load("mails"); @@ -679,9 +679,6 @@ if ($resql) print ''; - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - dol_fiche_head(null, '', ''); $topicmail="SendOrderRef"; @@ -1428,8 +1425,6 @@ if ($resql) print ''."\n"; - //print '
    '.img_help(1,'').' '.$langs->trans("ToBillSeveralOrderSelectCustomer", $langs->transnoentitiesnoconv("CreateInvoiceForThisCustomer")).'
    '; - if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) { /* diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 6bd2d3036b9..9ee36f783d2 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6218,7 +6218,7 @@ class Form global $conf, $langs; $out=''; - if (! empty($conf->use_javascript_ajax)) $out.=''; + if (! empty($conf->use_javascript_ajax)) $out.='
    '; $out.='