diff --git a/ChangeLog b/ChangeLog index 9b561820629..d8387c6a0e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -150,6 +150,7 @@ Dolibarr better: - A new paramater sqlfilters was introduced to allow filter on any fields int the REST API. Few old parameters, no more required, were also removed. Use this new one if you were using one of them. - The trigger that activate or close a contract line is run on a contract line, not on contract. +- Method commande->set_availability(user, availability_id) removed from commande class, use method commande->availability(availability_id, notrigger). Dolibarr 5.0 was frozen before PHP 7.1 was released. Unit tests are successful on PHP 7.1 but we don't have enough feedback to confirm all application is compatible. Current officiel supported PHP versions are PHP 5.3 to 7.0. diff --git a/build/generate_filelist_xml.php b/build/generate_filelist_xml.php index 07e87dd86bb..ff580fad58c 100755 --- a/build/generate_filelist_xml.php +++ b/build/generate_filelist_xml.php @@ -1,6 +1,6 @@ #!/usr/bin/env php +/* Copyright (C) 2015-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 @@ -40,55 +40,113 @@ require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); * Main */ +$includeconstants=array(); + if (empty($argv[1])) { - print "Usage: ".$script_file." release=x.y.z\n"; + print "Usage: ".$script_file." release=x.y.z[-...] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n"; + print "Example: ".$script_file." release=6.0.0 includecustom=1 includeconstant=FR:INVOICE_CAN_ALWAYS_BE_REMOVED:0 includeconstant=all:MAILING_NO_USING_PHPMAIL:1\n"; exit -1; } -parse_str($argv[1]); - -if ($release != DOL_VERSION) +$i=0; +while ($i < $argc) { - print 'Error: release is not version declared into filefunc.in.php.'."\n"; - exit -1; + if (! empty($argv[$i])) parse_str($argv[$i]); + if (preg_match('/includeconstant=/',$argv[$i])) + { + $tmp=explode(':', $includeconstant, 3); + if (count($tmp) != 3) + { + print "Error: Bad parameter includeconstant ".$includeconstant."\n"; + exit -1; + } + $includeconstants[$tmp[0]][$tmp[1]] = $tmp[2]; + } + $i++; } +if (empty($includecustom)) +{ + $includecustom=0; + + if (DOL_VERSION != $release) + { + print 'Error: When parameter "includecustom" is not set, version declared into filefunc.in.php ('.DOL_VERSION.') must be exact same value than "release" parameter ('.$release.')'."\n"; + print "Usage: ".$script_file." release=x.y.z[-...] [includecustom=1]\n"; + exit -1; + } +} +else +{ + if (! preg_match('/'.preg_quote(DOL_VERSION,'/').'-/',$release)) + { + print 'Error: When parameter "includecustom" is not set, version declared into ('.DOL_VERSION.') must be used with a suffix into "release" parmater (ex: '.DOL_VERSION.'-mydistrib).'."\n"; + print "Usage: ".$script_file." release=x.y.z[-...] [includecustom=1]\n"; + exit -1; + } +} + +print "Release : ".$release."\n"; +print "Include custom : ".$includecustom."\n"; +print "Include constants: "; +foreach ($includeconstants as $countrycode => $tmp) +{ + foreach($tmp as $constname => $constvalue) + { + print $constname.'='.$constvalue." "; + } +} +print "\n"; + //$outputfile=dirname(__FILE__).'/../htdocs/install/filelist-'.$release.'.xml'; $outputdir=dirname(__FILE__).'/../htdocs/install'; -print 'Delete current files '.$outputdir.'/filelist*.xml'."\n"; -dol_delete_file($outputdir.'/filelist*.xml',0,1,1); +print 'Delete current files '.$outputdir.'/filelist-'.$release.'.xml'."\n"; +dol_delete_file($outputdir.'/filelist-'.$release.'.xml',0,1,1); + +$checksumconcat=array(); $outputfile=$outputdir.'/filelist-'.$release.'.xml'; $fp = fopen($outputfile,'w'); fputs($fp, ''."\n"); -fputs($fp, ''."\n"); +fputs($fp, ''."\n"); -fputs($fp, ''."\n"); +foreach ($includeconstants as $countrycode => $tmp) +{ + fputs($fp, ''."\n"); + foreach($tmp as $constname => $constvalue) + { + $valueforchecksum=(empty($constvalue)?'0':$constvalue); + $checksumconcat[]=$valueforchecksum; + fputs($fp, ' '.$valueforchecksum.''."\n"); + } + fputs($fp, ''."\n"); +} -$checksumconcat=array(); +fputs($fp, ''."\n"); +// TODO Replace RecursiveDirectoryIterator with dol_dir_list $dir_iterator1 = new RecursiveDirectoryIterator(dirname(__FILE__).'/../htdocs/'); $iterator1 = new RecursiveIteratorIterator($dir_iterator1); -// need to ignore document custom etc -$files = new RegexIterator($iterator1, '#^(?:[A-Z]:)?(?:/(?!(?:custom|documents|conf|install|nltechno))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i'); +// Need to ignore document custom etc. Note: this also ignore natively symbolic links. +$files = new RegexIterator($iterator1, '#^(?:[A-Z]:)?(?:/(?!(?:'.($includecustom?'':'custom\/|').'documents\/|conf\/|install\/))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i'); $dir=''; $needtoclose=0; foreach ($files as $file) { $newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file)); if ($newdir!=$dir) { if ($needtoclose) - fputs($fp, ''."\n"); - fputs($fp, ''."\n"); + fputs($fp, ' '."\n"); + fputs($fp, ' '."\n"); $dir = $newdir; $needtoclose=1; } if (filetype($file)=="file") { $md5=md5_file($file); $checksumconcat[]=$md5; - fputs($fp, ''.$md5.''."\n"); + fputs($fp, ' '.$md5.''."\n"); } } -fputs($fp, ''."\n"); +fputs($fp, ' '."\n"); fputs($fp, ''."\n"); asort($checksumconcat); // Sort list of checksum @@ -102,28 +160,29 @@ $checksumconcat=array(); fputs($fp, ''."\n"); +// TODO Replace RecursiveDirectoryIterator with dol_dir_list $dir_iterator2 = new RecursiveDirectoryIterator(dirname(__FILE__).'/../scripts/'); $iterator2 = new RecursiveIteratorIterator($dir_iterator2); -// need to ignore document custom etc -$files = new RegexIterator($iterator2, '#^(?:[A-Z]:)?(?:/(?!(?:custom|documents|conf|install|nltechno))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i'); +// Need to ignore document custom etc. Note: this also ignore natively symbolic links. +$files = new RegexIterator($iterator2, '#^(?:[A-Z]:)?(?:/(?!(?:custom|documents|conf|install))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i'); $dir=''; $needtoclose=0; foreach ($files as $file) { $newdir = str_replace(dirname(__FILE__).'/../scripts', '', dirname($file)); if ($newdir!=$dir) { if ($needtoclose) - fputs($fp, ''."\n"); - fputs($fp, ''."\n"); + fputs($fp, ' '."\n"); + fputs($fp, ' '."\n"); $dir = $newdir; $needtoclose=1; } if (filetype($file)=="file") { $md5=md5_file($file); $checksumconcat[]=$md5; - fputs($fp, ''.$md5.''."\n"); + fputs($fp, ' '.$md5.''."\n"); } } -fputs($fp, ''."\n"); +fputs($fp, ' '."\n"); fputs($fp, ''."\n"); asort($checksumconcat); // Sort list of checksum diff --git a/build/pad/pad_dolibarr.xml b/build/pad/pad_dolibarr.xml index 0920a19311d..77318eeb2d2 100644 --- a/build/pad/pad_dolibarr.xml +++ b/build/pad/pad_dolibarr.xml @@ -7,20 +7,20 @@ Dolibarr team - 11 rue raymond Queneau + 20 rue camponac - Rueil Malmaison + Pessac - 92500 + 33600 FRANCE - http://www.dolibarr.org + https://www.dolibarr.org Dolibarr team Dolibarr team - dolibarr-dev@nongnu.org + contact@dolibarr.org Dolibarr team Dolibarr team - dolibarr-dev@nongnu.org + contact@dolibarr.org dolibarr-dev@nongnu.org @@ -34,10 +34,10 @@ Dolibarr - 3.5 - 01 + 5.0 + 02 01 - 2014 + 2017 @@ -71,8 +71,8 @@ Dolibarr ERP & CRM 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: + Dolibarr ERP & CRM is a software package 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 package 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, Odoo, Neogia, Compiere, etc) because everything was made to be more simple: Simple to install Simple to use Simple to develop @@ -101,14 +101,14 @@ Dolibarr intègre en effet sa propre architecture (design patterns) permettant - http://www.dolibarr.org - http://www.dolibarr.org - http://www.dolibarr.org/images/dolibarr_screenshot1.png - http://www.dolibarr.org/images/dolibarr.gif - http://www.dolibarr.org/files/pad_dolibarr.xml + https://www.dolibarr.org + https://www.dolibarr.org + https://www.dolibarr.org/images/dolibarr_screenshot1.png + https://www.dolibarr.org/images/dolibarr.gif + https://www.dolibarr.org/files/pad_dolibarr.xml - http://www.dolibarr.org/files/dolibarr.tgz + https://www.dolibarr.org/files/dolibarr.tgz http://www.dolibarr.org/files/dolibarr.tgz diff --git a/build/pad/pad_dolibarr_nos.xml b/build/pad/pad_dolibarr_nos.xml new file mode 100644 index 00000000000..6d81793de79 --- /dev/null +++ b/build/pad/pad_dolibarr_nos.xml @@ -0,0 +1,232 @@ + + + + 3.11 + PADGen 3.1.1.47 http://www.padgen.org + Portable Application Description, or PAD for short, is a data set that is used by shareware authors to disseminate information to anyone interested in their software products. To find out more go to http://pad.asp-software.org + + + Dolibarr team + 20 rue camponac + + Pessac + + 33600 + FRANCE + https://www.dolibarr.org + + Dolibarr team + Dolibarr team + contact@dolibarr.org + Dolibarr team + Dolibarr team + contact@dolibarr.org + + + dolibarr-dev@nongnu.org + dolibarr-dev@nongnu.org + dolibarr-dev@nongnu.org + + + + + + + + Dolibarr + 5.0 + 02 + 01 + 2017 + + + + Freeware + Major Update + No Install Support + Linux,Mac OS X,Mac Other,Unix,Win2000,Win7 x32,Win7 x64,Win98,WinOther,WinServer,WinVista,WinVista x64,WinXP,Other + English,Arabic,Catalan,Chinese,Danish,Dutch,Finnish,French,German,Greek,Icelandic,Italian,Norwegian,Polish,Portuguese,Romanian,Russian,Slovenian,Spanish,Swedish,Turkish + Increase performances, Setup process is easier, Reduce number of clicks required to use software + Business + Business::Accounting & Finance + None + + 18037439 + 18037 + 18.03 + + + N + + Days + + + + + + + + + dolibarr, erp, crm, invoices, commercial proposals, orders, accounting, stock, products, agenda, bank, business, company, foundation, management, sme, doliwamp + Dolibarr ERP & CRM + 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 package 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 package 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). + + + dolibarr, erp, crm, invoices, commercial proposals, orders, accounting, stock, products, agenda, bank, business, company, foundation, management, sme, doliwamp + Dolibarr ERP & CRM + 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 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. + + + erp, crm, gestionale, medie imprese, fondazioni + Gestionale open source e gratuito + Gestionale open source e gratuito per piccole e medie imprese, fondazioni + Dolibarr è un a gestionale open source e gratuito per piccole e medie imprese, fondazioni e liberi professionisti. Include varie funzionalità per Enterprise Resource Planning e gestione dei clienti (CRM), ma anche ulteriori attività. + Dolibarr è un programma gestionale open source e gratuito per piccole e medie imprese, fondazioni e liberi professionisti. Include varie funzionalità per Enterprise Resource Planning e gestione dei clienti (CRM), ma anche ulteriori attività. Dolibar è progettato per poter fornire solo ciò di cui hai bisogno ed essere facile da usare. + Dolibarr è un programma gestionale open source e gratuito per piccole e medie imprese, fondazioni e liberi professionisti. Include varie funzionalità per Enterprise Resource Planning e gestione dei clienti (CRM), ma anche ulteriori attività. Dolibar è progettato per poter fornire solo ciò di cui hai bisogno ed essere facile da usare. Dolibar è completamente web-based, progettato per poter fornire solo ciò di cui hai bisogno ed essere facile da usare. + + + + + https://www.dolibarr.org + https://www.dolibarr.org + http://www.dolibarr.org/images/dolibarr_screenshot1.png + http://www.dolibarr.org/images/dolibarr.gif + https://www.dolibarr.org/files/pad_dolibarr.xml + + + https://www.dolibarr.org/files/dolibarr.zip + http://www.dolibarr.org/files/dolibarr.zip + + + + + + GNU GPL + GNU GPL + + + Y + 1.4 + http://pad.asp-software.org/extensions/Affiliates.htm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Y + N + + + diff --git a/build/pad/pad_doliwamp.xml b/build/pad/pad_doliwamp.xml index 8abf126d5f7..842d746dbcc 100644 --- a/build/pad/pad_doliwamp.xml +++ b/build/pad/pad_doliwamp.xml @@ -7,13 +7,13 @@ NLTechno - 11 Rue raymond Queneau + 20 Rue Camponac - Rueil Malmaison + Pessac - 92500 + 33600 FRANCE - http://www.nltechno.com + https://www.dolibarr.org NLTechno NLTechno @@ -34,10 +34,10 @@ DoliWamp - 3.5 - 01 + 5.0 + 02 01 - 2014 + 2017 @@ -53,7 +53,7 @@ 26048004 25437 - 24.84 + 45.84 N @@ -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 package 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. @@ -96,12 +96,12 @@ DoliWamp is the auto-installer for Windows users with no technical knowledge to http://www.nltechno.com/doliwamp/ http://www.nltechno.com/doliwamp/ - http://www.dolibarr.org/images/dolibarr_screenshot1.png - http://www.dolibarr.org/images/dolibarr.gif - http://www.dolibarr.org/files/pad_doliwamp.xml + https://www.dolibarr.org/images/dolibarr_screenshot1.png + https://www.dolibarr.org/images/dolibarr.gif + https://www.dolibarr.org/files/pad_doliwamp.xml - http://www.dolibarr.org/files/doliwamp.exe + https://www.dolibarr.org/files/doliwamp.exe http://www.dolibarr.org/files/doliwamp.exe diff --git a/build/pad/pad_doliwamp_nos.xml b/build/pad/pad_doliwamp_nos.xml new file mode 100644 index 00000000000..61c739daff0 --- /dev/null +++ b/build/pad/pad_doliwamp_nos.xml @@ -0,0 +1,225 @@ + + + + 3.11 + PADGen 3.1.1.47 http://www.padgen.org + Portable Application Description, or PAD for short, is a data set that is used by shareware authors to disseminate information to anyone interested in their software products. To find out more go to http://pad.asp-software.org + + + NLTechno + 20 Rue Camponac + + Pessac + + 33600 + FRANCE + https://www.dolibarr.org + + NLTechno + NLTechno + contact@nltechno.com + NLTechno + NLTechno + contact@nltechno.com + + + support@nltechno.com + support@nltechno.com + support@nltechno.com + + + + + + + + DoliWamp + 5.0 + 02 + 01 + 2017 + + + + Freeware + Major Update + Install and Uninstall + Win2000,Win7 x32,Win7 x64,Win98,WinOther,WinServer,WinVista,WinVista x64,WinXP,Other + English,Arabic,Catalan,Chinese,Dutch,Finnish,French,German,Icelandic,Italian,Norwegian,Polish,Portuguese,Romanian,Russian,Slovenian,Spanish,Swedish,Turkish + Increase performances, Setup process is easier, Reduce number of clicks required to use software + Business + Business::Accounting & Finance + None + + 26048004 + 25437 + 45.84 + + + N + + Days + + + + + + + + + doliwamp, dolibarr, erp, crm, invoices, commercial proposals, orders, accounting, stock, products, agenda, bank, business, company, foundation, management + DoliWamp, Dolibarr ERP/CRM for Windows + 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 package 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. + + + doliwamp, dolibarr, erp, crm, factures, devis, facturation, commandes, compta, trésorerie, stocks, produits, agenda, comptes bancaires, associations, entreprises, PME, TPE + DoliWamp, Dolibarr ERP/CRM pour Windows + DoliWamp, la distribution de Dolibarr pour gérer votre entreprise ou association + DoliWamp est la version spécialisée pour Windows de 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) + DoliWamp est la version spécialisée pour Windows de 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) + DoliWamp est la version spécialisée pour Windows de 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) + + + doliwamp, dolibarr, erp, crm, gestionale, medie imprese, fondazioni + DoliWamp, Dolibarr ERP/CRM per Windows + Gestionale open source e gratuito per piccole e medie imprese, fondazioni + Dolibarr è un a gestionale open source e gratuito per piccole e medie imprese, fondazioni e liberi professionisti. Include varie funzionalità per Enterprise Resource Planning e gestione dei clienti (CRM), ma anche ulteriori attività. + Dolibarr è un programma gestionale open source e gratuito per piccole e medie imprese, fondazioni e liberi professionisti. Include varie funzionalità per Enterprise Resource Planning e gestione dei clienti (CRM), ma anche ulteriori attività. Dolibar è progettato per poter fornire solo ciò di cui hai bisogno ed essere facile da usare. + Dolibarr è un programma gestionale open source e gratuito per piccole e medie imprese, fondazioni e liberi professionisti. Include varie funzionalità per Enterprise Resource Planning e gestione dei clienti (CRM), ma anche ulteriori attività. Dolibar è progettato per poter fornire solo ciò di cui hai bisogno ed essere facile da usare. Dolibar è completamente web-based, progettato per poter fornire solo ciò di cui hai bisogno ed essere facile da usare. + + + + + http://www.nltechno.com/doliwamp/ + http://www.nltechno.com/doliwamp/ + http://www.dolibarr.org/images/dolibarr_screenshot1.png + http://www.dolibarr.org/images/dolibarr.gif + https://www.dolibarr.org/files/pad_doliwamp.xml + + + https://www.dolibarr.org/files/doliwamp.exe + http://www.dolibarr.org/files/doliwamp.exe + + + + + + GNU GPL + GNU GPL + + + Y + 1.4 + http://pad.asp-software.org/extensions/Affiliates.htm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Y + N + + + diff --git a/dev/resources/iso-normes/sample_FEC_file.txt b/dev/resources/iso-normes/sample_FEC_file.txt new file mode 100644 index 00000000000..5ca795af5c2 --- /dev/null +++ b/dev/resources/iso-normes/sample_FEC_file.txt @@ -0,0 +1,13 @@ +JOURNALCODE JOURNALLIB ECRITURENUM ECRITUREDATE COMPTENUM COMPTELIB COMPAUXNUM COMPAUXLIB PIECEREF PIECEDATE ECRITURELIB DEBIT CREDIT ECRITURELET DATELET VALIDDATE MONTANTDEVISE IDEVISE +Banque Banque 17293 20170109 401PPRO PUBLI-PROV L08 20170109 PPRO domiciliation 1TR 187,20 0,00 20170109 +Banque Banque 17293 20170109 5121CRA CR AGRICOLE L08 20170109 PPRO domiciliation 1TR 0,00 187,20 20170109 +Banque Banque 17295 20170109 401ORPA ORANGE PARIS Report 20170109 ORPA adsl par 12 96,00 0,00 20170109 +Banque Banque 17295 20170109 5121CRA CR AGRICOLE Report 20170109 ORPA adsl par 12 0,00 96,00 20170109 +Banque Banque 17302 20170105 401ORVI ORANGE VEBRON INTERNET Report 20170105 ORVI adsl veb 12 26,00 0,00 20170109 +Banque Banque 17302 20170105 5121CRA CR AGRICOLE Report 20170105 ORVI adsl veb 12 0,00 26,00 20170109 +Fournisseurs Fournisseurs 17305 20170119 401ZDAV SANDRA DAVILA A01 20170119 ZDAV courtage s/ ventes 0,00 508,00 20170119 +Fournisseurs Fournisseurs 17305 20170119 622200 Courtages s/ ventes A01 20170119 ZDAV courtage s/ ventes 508,00 0,00 20170119 +Banque Banque 17306 20170119 5121CRA CR AGRICOLE A01 20170119 ZDAV courtage s/ ventes 0,00 508,00 20170119 +Banque Banque 17306 20170119 401ZDAV SANDRA DAVILA A01 20170119 ZDAV courtage s/ ventes 508,00 0,00 20170119 +Banque Banque 17307 20170119 401ZDAV SANDRA DAVILA A01 20170119 ZDAV courtage s/ ventes 508,00 0,00 20170131 +Banque Banque 17307 20170119 5121CRA CR AGRICOLE A01 20170119 ZDAV courtage s/ ventes 0,00 508,00 20170131 diff --git a/dev/skeletons/build_class_from_table.php b/dev/skeletons/build_class_from_table.php index d9e30b23501..0e5a6d82a82 100755 --- a/dev/skeletons/build_class_from_table.php +++ b/dev/skeletons/build_class_from_table.php @@ -636,7 +636,8 @@ foreach ($skeletonfiles as $skeletonfile => $outfile) { if ($prop['field'] != 'rowid' && $prop['field'] != 'id' && ! $prop['istime']) { - $varprop.="print ''.\$langs->trans(\"Field".$prop['field']."\").'".$prop['field'].".'\">';\n"; + $baseString = 'print "".\$langs->trans("Field%s")."%s."\">";'; + $varprop.= sprintf("\t ".$baseString." \n", $prop['field'], $prop['field'], $prop['field']); } } $targetcontent=preg_replace('/LIST_OF_TD_LABEL_FIELDS_EDIT/', $varprop, $targetcontent); @@ -648,7 +649,7 @@ foreach ($skeletonfiles as $skeletonfile => $outfile) { if ($prop['field'] != 'rowid' && $prop['field'] != 'id' && ! $prop['istime']) { - $varprop.="print ''.\$langs->trans(\"Field".$prop['field']."\").'\$object->".$prop['field']."';\n"; + $varprop.=sprintf("\t print ''.\$langs->trans(\"Field%s\").''.\$object->%s.'';\n",$prop['field'],$prop['field']); } } $targetcontent=preg_replace('/LIST_OF_TD_LABEL_FIELDS_VIEW/', $varprop, $targetcontent); diff --git a/doc/images/dolibarr_screenshot5_1280x800.png b/doc/images/dolibarr_screenshot5_1280x800.png index 96700f89bd5..92f6dfa521d 100644 Binary files a/doc/images/dolibarr_screenshot5_1280x800.png and b/doc/images/dolibarr_screenshot5_1280x800.png differ diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index e82522df26f..a7ad5d14e90 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -1,6 +1,6 @@ - * Copyright (C) 2013-2016 Alexandre Spangaro + * Copyright (C) 2013-2017 Alexandre Spangaro * Copyright (C) 2016 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify @@ -41,6 +41,7 @@ $action = GETPOST('action'); $cancel = GETPOST('cancel'); $id = GETPOST('id', 'int'); $rowid = GETPOST('rowid', 'int'); + $search_account = GETPOST("search_account"); $search_label = GETPOST("search_label"); $search_accountparent = GETPOST("search_accountparent"); @@ -68,6 +69,15 @@ if (! $sortfield) if (! $sortorder) $sortorder = "ASC"; +$arrayfields=array( + 'aa.account_number'=>array('label'=>$langs->trans("AccountNumber"), 'checked'=>1), + 'aa.label'=>array('label'=>$langs->trans("Label"), 'checked'=>1), + 'aa.account_parent'=>array('label'=>$langs->trans("Accountparent"), 'checked'=>0), + 'aa.pcg_type'=>array('label'=>$langs->trans("Pcgtype"), 'checked'=>0), + 'aa.pcg_subtype'=>array('label'=>$langs->trans("Pcgsubtype"), 'checked'=>0), + 'aa.active'=>array('label'=>$langs->trans("Activated"), 'checked'=>1) +); + $accounting = new AccountingAccount($db); @@ -95,6 +105,7 @@ if (empty($reshook)) $search_accountparent = ""; $search_pcgtype = ""; $search_pcgsubtype = ""; + $search_array_options=array(); } if (GETPOST('change_chart')) @@ -135,6 +146,7 @@ if (empty($reshook)) /* * View */ +$form=new Form($db); llxHeader('', $langs->trans("ListAccounts")); @@ -145,8 +157,6 @@ if ($action == 'delete') { $pcgver = $conf->global->CHARTOFACCOUNTS; - - $sql = "SELECT aa.rowid, aa.fk_pcg_version, aa.pcg_type, aa.pcg_subtype, aa.account_number, aa.account_parent , aa.label, aa.active, "; $sql .= " a2.rowid as rowid2, a2.label as label2, a2.account_number as account_number2"; $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa"; @@ -154,21 +164,12 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_vers $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as a2 ON aa.account_parent = a2.rowid"; $sql .= " WHERE asy.rowid = " . $pcgver; -if (strlen(trim($search_account))) { - $sql .= natural_search("aa.account_number", $search_account); -} -if (strlen(trim($search_label))) { - $sql .= natural_search("aa.label", $search_label); -} -if (strlen(trim($search_accountparent))) { - $sql .= natural_search("aa.account_parent", $search_accountparent); -} -if (strlen(trim($search_pcgtype))) { - $sql .= natural_search("aa.pcg_type", $search_pcgtype); -} -if (strlen(trim($search_pcgsubtype))) { - $sql .= natural_search("aa.pcg_subtype", $search_pcgsubtype); -} +if (strlen(trim($search_account))) $sql .= natural_search("aa.account_number", $search_account); +if (strlen(trim($search_label))) $sql .= natural_search("aa.label", $search_label); +if (strlen(trim($search_accountparent))) $sql .= natural_search("aa.account_parent", $search_accountparent); +if (strlen(trim($search_pcgtype))) $sql .= natural_search("aa.pcg_type", $search_pcgtype); +if (strlen(trim($search_pcgsubtype))) $sql .= natural_search("aa.pcg_subtype", $search_pcgsubtype); + $sql .= $db->order($sortfield, $sortorder); // Count total nb of records @@ -184,18 +185,19 @@ $sql .= $db->plimit($limit + 1, $offset); dol_syslog('accountancy/admin/account.php:: $sql=' . $sql); $resql = $db->query($sql); -if ($resql) { - +if ($resql) +{ $num = $db->num_rows($resql); - + $params=''; - if ($search_account != "") $params.= '&search_account='.urlencode($search_account); - if ($search_label != "") $params.= '&search_label='.urlencode($search_label); - if ($search_accountparent != "") $params.= '&search_accountparent='.urlencode($search_accountparent); - if ($search_pcgtype != "") $params.= '&search_pcgtype='.urlencode($search_pcgtype); - if ($search_pcgsubtype != "") $params.= '&search_pcgsubtype='.urlencode($search_pcgsubtype); - if ($optioncss != '') $param.='&optioncss='.$optioncss; - + if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; + if ($search_account) $params.= '&search_account='.urlencode($search_account); + if ($search_label) $params.= '&search_label='.urlencode($search_label); + if ($search_accountparent) $params.= '&search_accountparent='.urlencode($search_accountparent); + if ($search_pcgtype) $params.= '&search_pcgtype='.urlencode($search_pcgtype); + if ($search_pcgsubtype) $params.= '&search_pcgsubtype='.urlencode($search_pcgsubtype); + if ($optioncss) $param.='&optioncss='.$optioncss; + print_barre_liste($langs->trans('ListAccounts'), $page, $_SERVER["PHP_SELF"], $params, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy'); print '
'; @@ -207,7 +209,7 @@ if ($resql) { $sql = "SELECT rowid, pcg_version, label, active"; $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_system"; $sql .= " WHERE active = 1"; - dol_syslog('accountancy/admin/index.php:: $sql=' . $sql); + dol_syslog('accountancy/admin/account.php:: $sql=' . $sql); $resqlchart = $db->query($sql); $var = true; if ($resqlchart) { @@ -228,34 +230,53 @@ if ($resql) { print ''; print '
'; print "
\n"; + + print '
'; + $i = 0; + print '
'."\n"; + if ($optioncss != '') print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '' . $langs->trans("Addanaccount") . ''; print '' . $langs->trans("ApplyMassCategories") . ''; // print '' . $langs->trans("ImportAccount") . ''; // print '' . $langs->trans("CheckProductAccountancyCode") . ''; print '

'; - print ''; - print ''; - print_liste_field_titre($langs->trans("AccountNumber"), $_SERVER["PHP_SELF"], "aa.account_number", "", $params, "", $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Label"), $_SERVER["PHP_SELF"], "aa.label", "", $params, "", $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Accountparent"), $_SERVER["PHP_SELF"], "aa.account_parent", "", $params, "", $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Pcgtype"), $_SERVER["PHP_SELF"], "aa.pcg_type", "", $params, "", $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Pcgsubtype"), $_SERVER["PHP_SELF"], "aa.pcg_subtype", "", $params, "", $sortfield, $sortorder); - print_liste_field_titre($langs->trans("Activated"), $_SERVER["PHP_SELF"], "aa.active", "", $params, "", $sortfield, $sortorder); - print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $params, "", 'width="60" align="center"', $sortfield, $sortorder); - print ''; + $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; + $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields + print '
'; + print '
'."\n"; + print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - 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 ''; + if (! empty($arrayfields['aa.account_number']['checked'])) print ''; + if (! empty($arrayfields['aa.label']['checked'])) print ''; + if (! empty($arrayfields['aa.account_parent']['checked'])) print ''; + if (! empty($arrayfields['aa.pcg_type']['checked'])) print ''; + if (! empty($arrayfields['aa.pcg_subtype']['checked'])) print ''; + if (! empty($arrayfields['aa.active']['checked'])) print ''; print ''; print ''; @@ -263,8 +284,7 @@ if ($resql) { $accountstatic = new AccountingAccount($db); $accountparent = new AccountingAccount($db); - - $i = 0; + while ( $i < min($num, $limit) ) { $obj = $db->fetch_object($resql); @@ -274,35 +294,81 @@ if ($resql) { $accountstatic->account_number = $obj->account_number; print ''; - print ''; - print ''; - if (! empty($obj->account_parent)) - { - $accountparent->id = $obj->rowid2; - $accountparent->label = $obj->label2; - $accountparent->account_number = $obj->account_number2; - - print ''; - } - else + // Account number + if (! empty($arrayfields['aa.account_number']['checked'])) { - print ''; + print "\n"; + if (! $i) $totalarray['nbfield']++; } - print ''; - print ''; - print '\n"; + if (! $i) $totalarray['nbfield']++; } - print ''; - + + // Account parent + if (! empty($arrayfields['aa.account_parent']['checked'])) + { + if (! empty($obj->account_parent)) + { + $accountparent->id = $obj->rowid2; + $accountparent->label = $obj->label2; + $accountparent->account_number = $obj->account_number2; + + print "\n"; + if (! $i) $totalarray['nbfield']++; + } + else + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + } + + // Chart of accounts type + if (! empty($arrayfields['aa.pcg_type']['checked'])) + { + print "\n"; + if (! $i) $totalarray['nbfield']++; + } + + // Chart of accounts subtype + if (! empty($arrayfields['aa.pcg_subtype']['checked'])) + { + print "\n"; + if (! $i) $totalarray['nbfield']++; + } + + // Activated or not + if (! empty($arrayfields['aa.active']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Action print '' . "\n"; + if (! $i) $totalarray['nbfield']++; print "\n"; $var = ! $var; @@ -322,6 +389,7 @@ if ($resql) { } print "
 
 '; - $searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); - print $searchpitco; + $searchpicto=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); + print $searchpicto; print '
' . $accountstatic->getNomUrl(1) . '' . $obj->label . '' . $accountparent->getNomUrl(1) . ' "; + print $accountstatic->getNomUrl(1); + print "' . $obj->pcg_type . '' . $obj->pcg_subtype . ''; - if (empty($obj->active)) { - print ''; - print img_picto($langs->trans("Disabled"), 'switch_off'); - print ''; - } else { - print ''; - print img_picto($langs->trans("Activated"), 'switch_on'); - print ''; + + // Account label + if (! empty($arrayfields['aa.label']['checked'])) + { + print ""; + print $obj->label; + print ""; + print $accountparent->getNomUrl(1); + print " "; + print $obj->pcg_type; + print ""; + print $obj->pcg_subtype; + print "'; + if (empty($obj->active)) { + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print ''; + } else { + print ''; + print img_picto($langs->trans("Activated"), 'switch_on'); + print ''; + } + print ''; if ($user->admin) { @@ -315,6 +381,7 @@ if ($resql) { print ''; } print '
"; + print ""; print '
'; } else { dol_print_error($db); diff --git a/htdocs/accountancy/admin/categories.php b/htdocs/accountancy/admin/categories.php index 12d9a707cbd..d052b4312a7 100644 --- a/htdocs/accountancy/admin/categories.php +++ b/htdocs/accountancy/admin/categories.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2016 Jamal Elbaz + * Copyright (C) 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 @@ -16,24 +17,24 @@ */ /** - * \file htdocs/accountancy/admin/categories.php + * \file htdocs/accountancy/admin/categories.php * \ingroup Advanced accountancy - * \brief Page to assign mass categories to accounts + * \brief Page to assign mass categories to accounts */ require '../../main.inc.php'; - -// Class require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountancycategory.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php'; $error = 0; -// Langs $langs->load("bills"); $langs->load("accountancy"); $mesg = ''; +$id = GETPOST('id', 'int'); +$rowid = GETPOST('rowid', 'int'); +$cancel = GETPOST('cancel'); $action = GETPOST('action'); $cat_id = GETPOST('account_category'); $selectcpt = GETPOST('cpt_bk', 'array'); @@ -43,36 +44,31 @@ if ($cat_id == 0) { $cat_id = null; } -$id = GETPOST('id', 'int'); -$rowid = GETPOST('rowid', 'int'); -$cancel = GETPOST('cancel'); - // Security check -if (! $user->admin) - accessforbidden(); +if (! $user->admin) accessforbidden(); -$AccCat = new AccountancyCategory($db); +$accountingcategory = new AccountancyCategory($db); // si ajout de comptes if (! empty($selectcpt)) { $cpts = array (); - foreach ( $selectcpt as $selectedOption ) { - if (! array_key_exists($selectedOption, $cpts)) - $cpts[$selectedOption] = "'" . $selectedOption . "'"; + foreach ( $selectcpt as $selectedoption ) { + if (! array_key_exists($selectedoption, $cpts)) + $cpts[$selectedoption] = "'" . $selectedoption . "'"; } - $return= $AccCat->updateAccAcc($cat_id, $cpts); + $return= $accountingcategory->updateAccAcc($cat_id, $cpts); if ($return<0) { - setEventMessages($langs->trans('errors'), $AccCat->errors, 'errors'); + setEventMessages($langs->trans('errors'), $accountingcategory->errors, 'errors'); } else { setEventMessages($langs->trans('Saved'), null, 'mesgs'); } } if ($action == 'delete') { if ($cpt_id) { - if ($AccCat->deleteCptCat($cpt_id)) { - setEventMessages($langs->trans('Deleted'), null, 'mesgs'); + if ($accountingcategory->deleteCptCat($cpt_id)) { + setEventMessages($langs->trans('CategoryDeleted'), null, 'mesgs'); } else { setEventMessages($langs->trans('errors'), null, 'errors'); } @@ -83,12 +79,11 @@ if ($action == 'delete') { /* * View */ +$form = new Form($db); +$formaccounting = new FormAccounting($db); llxheader('', $langs->trans('AccountAccounting')); -$formaccounting = new FormAccounting($db); -$form = new Form($db); - print load_fiche_titre($langs->trans('Categories')); print '
' . "\n"; @@ -102,22 +97,23 @@ print ''; print ''; print ''; if (! empty($cat_id)) { - $return = $AccCat->getCptBK($cat_id); + $return = $accountingcategory->getCptBK($cat_id); if ($return < 0) { - setEventMessages(null, $AccCat->errors, 'errors'); + setEventMessages(null, $accountingcategory->errors, 'errors'); } - print ''; + print ''; print ''; } @@ -131,26 +127,30 @@ print ''; if ($action == 'display' || $action == 'delete') { - print '
' . $langs->trans("AccountingCategory") . ''; $formaccounting->select_accounting_category($cat_id, 'account_category', 1); -print ''; +print ''; print '
' . $langs->trans("AddCompteFromBK") . '
' . $langs->trans("AddAccountFromBookKeepingWithNoCategories") . ''; - if (is_array($AccCat->lines_cptbk) && count($AccCat->lines_cptbk) > 0) { + if (is_array($accountingcategory->lines_cptbk) && count($accountingcategory->lines_cptbk) > 0) { print ' - '; + print ''; + print ' '; } print '
'; - - print ''; + print "
' . $langs->trans("Numerocompte") . '' . $langs->trans("Description") . 'Action
\n"; + print ''; + print '"; + print '"; + print "\n"; if (! empty($cat_id)) { - $return = $AccCat->display($cat_id); + $return = $accountingcategory->display($cat_id); if ($return < 0) { - setEventMessages(null, $AccCat->errors, 'errors'); + setEventMessages(null, $accountingcategory->errors, 'errors'); } - $j = 1; - if (is_array($AccCat->lines_display) && count($AccCat->lines_display) > 0) { - foreach ( $AccCat->lines_display as $cpt ) { + + if (is_array($accountingcategory->lines_display) && count($accountingcategory->lines_display) > 0) { + foreach ( $accountingcategory->lines_display as $cpt ) { $var = ! $var; print ''; print ''; print ''; - print $form->formconfirm($_SERVER["PHP_SELF"] . "?account_category=$cat_id&cptid=" . $cpt->rowid, $langs->trans("DeleteCptCategory"), $langs->trans("ConfirmDeleteCptCategory"), "delete", '', 0, "action-delete" . $j); - print ''; + print '"; print "\n"; - $j ++; } } } diff --git a/htdocs/accountancy/admin/fiscalyear.php b/htdocs/accountancy/admin/fiscalyear.php index 817905f7b56..4b2b57ee7db 100644 --- a/htdocs/accountancy/admin/fiscalyear.php +++ b/htdocs/accountancy/admin/fiscalyear.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2013-2016 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 diff --git a/htdocs/accountancy/admin/fiscalyear_card.php b/htdocs/accountancy/admin/fiscalyear_card.php index 2c22d8f191a..7a8ab0673a7 100644 --- a/htdocs/accountancy/admin/fiscalyear_card.php +++ b/htdocs/accountancy/admin/fiscalyear_card.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2014-2016 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 @@ -176,13 +176,15 @@ if ($action == 'create') print $form->select_date(($date_end ? $date_end : - 1), 'fiscalyearend'); print ''; + /* // Statut print ''; print ''; print ''; - + */ + print '
'.$langs->trans("AccountAccounting")."'.$langs->trans("Label")."
' . length_accountg($cpt->account_number) . '' . $cpt->label . ''; + print ""; + print img_delete($langs->trans("DeleteFromCat")).' '; + print $langs->trans("DeleteFromCat").""; + print "
' . $langs->trans("Status") . ''; print $form->selectarray('statut', $statut2label, GETPOST('statut')); print '
'; dol_fiche_end(); @@ -232,7 +234,8 @@ if ($action == 'create') // Statut print '' . $langs->trans("Statut") . ''; - print $form->selectarray('statut', $statut2label, $object->statut); + // print $form->selectarray('statut', $statut2label, $object->statut); + print $object->getLibStatut(4); print ''; print ''; @@ -304,7 +307,7 @@ if ($action == 'create') print '' . $langs->trans('Modify') . ''; - print '' . $langs->trans('Delete') . ''; + // print '' . $langs->trans('Delete') . ''; print ''; } diff --git a/htdocs/accountancy/admin/journal.php b/htdocs/accountancy/admin/journal.php index 0487538a906..2a868969c3d 100644 --- a/htdocs/accountancy/admin/journal.php +++ b/htdocs/accountancy/admin/journal.php @@ -1,26 +1,26 @@ - * Copyright (C) 2013-2015 Alexandre Spangaro -* Copyright (C) 2014 Florian Henry -* Copyright (C) 2014 Marcos García -* Copyright (C) 2014 Juanjo Menent -* Copyright (C) 2015 Jean-François Ferry -* Copyright (C) 2016 Laurent Destailleur -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -*/ + * Copyright (C) 2013-2017 Alexandre Spangaro + * Copyright (C) 2014 Florian Henry + * Copyright (C) 2014 Marcos García + * Copyright (C) 2014 Juanjo Menent + * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2016 Laurent Destailleur + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ /** * \file htdocs/accountancy/admin/journal.php @@ -121,7 +121,7 @@ dol_fiche_head($head, 'journal', $langs->trans("Configuration"), 0, 'cron'); print ''; print ''; -print ''; +print ''; print "\n"; foreach ( $list as $key ) { @@ -145,11 +145,11 @@ print '
'; print '
' . $langs->trans('Journaux') . '' . $langs->trans('Journaux') . '
'; print ''; -print ''; +print ''; print "\n"; // Bank account -$sql = "SELECT rowid, label, number, accountancy_journal"; +$sql = "SELECT rowid, ref, label, number, account_number, accountancy_journal"; $sql .= " FROM " . MAIN_DB_PREFIX . "bank_account"; $sql .= " WHERE entity = " . $conf->entity; $sql .= " AND clos = 0"; @@ -162,30 +162,33 @@ if ($resql) { if ($numr > 0) - $bankaccountstatic=new Account($db); + $bankaccountstatic = new Account($db); while ( $i < $numr ) { $objp = $db->fetch_object($resql); - + $var = ! $var; - + + $bankaccountstatic->rowid = $objp->rowid; $bankaccountstatic->id = $objp->rowid; + $bankaccountstatic->ref = $objp->ref; $bankaccountstatic->label = $objp->label; $bankaccountstatic->number = $objp->number; + $bankaccountstatic->account_number = $objp->account_number; $bankaccountstatic->accountancy_journal = $objp->accountancy_journal; - + print ''; - + // Param print ''; - + // Value print ''; - + $i ++; } $db->free($resql); diff --git a/htdocs/accountancy/class/accountancycategory.class.php b/htdocs/accountancy/class/accountancycategory.class.php index 40290bd845b..b2564c342e5 100644 --- a/htdocs/accountancy/class/accountancycategory.class.php +++ b/htdocs/accountancy/class/accountancycategory.class.php @@ -1,6 +1,6 @@ - * 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 @@ -17,9 +17,9 @@ */ /** - * \file htdocs/accountancy/class/accountancycategory.class.php + * \file htdocs/accountancy/class/accountancycategory.class.php * \ingroup Advanced accountancy - * \brief File of class to manage categories of an accounting category_type + * \brief File of class to manage categories of an accounting category_type */ // Class @@ -72,7 +72,6 @@ class AccountancyCategory $this->lines_display[] = $obj; } } - return $num; } else { $this->error = "Error " . $this->db->lasterror(); @@ -84,7 +83,7 @@ class AccountancyCategory } /** - * Function to select accountiing category of an accounting account present in chart of accounts + * Function to select accounting category of an accounting account present in chart of accounts * * @param int $id Id category * diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php index ce1c632e85b..8bc62c27ef6 100644 --- a/htdocs/accountancy/journal/expensereportsjournal.php +++ b/htdocs/accountancy/journal/expensereportsjournal.php @@ -86,14 +86,14 @@ $idpays = $p[0]; $sql = "SELECT er.rowid, er.ref, er.date_debut as de,"; $sql .= " erd.rowid as erdid, erd.comments, erd.total_ttc, erd.tva_tx, erd.total_ht, erd.total_tva, erd.fk_code_ventilation,"; -$sql .= " u.rowid as uid, u.firstname, u.lastname, u.accountancy_code as user_accountancy_code,"; +$sql .= " u.rowid as uid, u.firstname, u.lastname, u.accountancy_code as user_accountancy_account,"; $sql .= " f.accountancy_code, ct.accountancy_code_buy as account_tva, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte"; $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_tva as ct ON erd.tva_tx = ct.taux AND ct.fk_pays = '" . $idpays . "'"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as f ON f.id = erd.fk_c_type_fees"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = erd.fk_code_ventilation"; $sql .= " JOIN " . MAIN_DB_PREFIX . "expensereport as er ON er.rowid = erd.fk_expensereport"; -$sql .= " JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = er.fk_user_valid"; +$sql .= " JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = er.fk_user_author"; $sql .= " WHERE er.fk_statut > 0 "; $sql .= " AND erd.fk_code_ventilation > 0 "; $sql .= " AND er.entity IN (" . getEntity("expensereport", 0) . ")"; // We don't share object for accountancy diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 28968a849fc..b8776a8e98e 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -749,7 +749,8 @@ while ($i < min($num, $limit)) print ''; } diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index b92549d8489..3ad6120be02 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -44,11 +44,12 @@ $search_email = GETPOST('search_email','alpha'); $type = GETPOST('type','alpha'); $status = GETPOST('status','alpha'); -$sortfield = GETPOST('sortfield','alpha'); -$sortorder = GETPOST('sortorder','alpha'); -$page = GETPOST('page','int'); -if ($page == -1) { $page = 0 ; } -$offset = $conf->liste_limit * $page ; +$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 (! $sortorder) { $sortorder="DESC"; } @@ -166,9 +167,6 @@ $form=new Form($db); // List of members type if (! $rowid && $action != 'create' && $action != 'edit') { - - print load_fiche_titre($langs->trans("MembersTypes")); - //dol_fiche_head(''); $sql = "SELECT d.rowid, d.libelle, d.subscription, d.vote"; @@ -179,8 +177,22 @@ if (! $rowid && $action != 'create' && $action != 'edit') if ($result) { $num = $db->num_rows($result); + $nbtotalofrecords = $num; + $i = 0; + $param = ''; + + print ''; + if ($optioncss != '') print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + print_barre_liste($langs->trans("MembersTypes"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_generic.png', 0, '', '', $limit); + $moreforfilter = ''; print '
'; @@ -213,6 +225,8 @@ if (! $rowid && $action != 'create' && $action != 'edit') } print "
' . $langs->trans('JournalFinancial') . ' ('.$langs->trans('Opened').')' . $langs->trans('JournalFinancial') . ' ('.$langs->trans('Opened').')
'; print ''; print '
'; print dol_print_date($datefin,'day'); if ($memberstatic->hasDelay()) { - print " ".img_warning($langs->trans("SubscriptionLate")); + $textlate .= ' ('.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($conf->adherent->subscription->warning_delay/60/60/24) >= 0 ? '+' : '').ceil($conf->adherent->subscription->warning_delay/60/60/24).' '.$langs->trans("days").')'; + print " ".img_warning($langs->trans("SubscriptionLate").$textlate); } print '
"; print ''; + + print ''; } else { diff --git a/htdocs/admin/commande.php b/htdocs/admin/commande.php index c2f8cf2d4d6..a9041f5272b 100644 --- a/htdocs/admin/commande.php +++ b/htdocs/admin/commande.php @@ -570,7 +570,7 @@ print '
'; print ''; print ''; print ''; -print $langs->trans("FreeLegalTextOnOrders").' ('.$langs->trans("AddCRIfTooLong").')
'; +print $langs->trans("FreeLegalTextOnOrders").' '.img_info($langs->trans("AddCRIfTooLong")).'
'; $variablename='ORDER_FREE_TEXT'; if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { @@ -592,8 +592,8 @@ $var=!$var; print ""; print ''; print ""; -print ''; -print $langs->trans("WatermarkOnDraftOrders").'
'; +print ''; +print $langs->trans("WatermarkOnDraftOrders").''; print ''; print ''; print ''; diff --git a/htdocs/admin/contract.php b/htdocs/admin/contract.php index acfe7de156f..487203c9f4d 100644 --- a/htdocs/admin/contract.php +++ b/htdocs/admin/contract.php @@ -504,7 +504,7 @@ $var=true; $var=! $var; print ''; -print $langs->trans("FreeLegalTextOnContracts").' ('.$langs->trans("AddCRIfTooLong").')
'; +print $langs->trans("FreeLegalTextOnContracts").' '.img_info($langs->trans("AddCRIfTooLong")).'
'; $variablename='CONTRACT_FREE_TEXT'; if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { @@ -520,8 +520,8 @@ print ''."\n"; //Use draft Watermark $var=!$var; -print ''; -print $langs->trans("WatermarkOnDraftContractCards").'
'; +print ''; +print $langs->trans("WatermarkOnDraftContractCards").''; print ''; print ''."\n"; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 09ee313e487..b5d15e07833 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -86,7 +86,7 @@ $hookmanager->initHooks(array('admin')); // Put here declaration of dictionaries properties // Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this. -$taborder=array(9,0,4,3,2,0,1,8,19,16,27,0,5,11,0,33,34,0,6,0,29,0,7,17,24,28,0,10,23,12,13,0,14,0,22,20,18,21,0,15,30,0,25,0,26,0,32,0); +$taborder=array(9,0,4,3,2,0,1,8,19,16,27,0,5,11,0,33,34,0,6,0,29,0,7,17,24,28,0,10,23,12,13,0,14,0,22,20,18,21,0,15,30,0,26,0,32,0); // Name of SQL tables of dictionaries $tabname=array(); @@ -114,7 +114,7 @@ $tabname[21]= MAIN_DB_PREFIX."c_availability"; $tabname[22]= MAIN_DB_PREFIX."c_input_reason"; $tabname[23]= MAIN_DB_PREFIX."c_revenuestamp"; $tabname[24]= MAIN_DB_PREFIX."c_type_resource"; -$tabname[25]= MAIN_DB_PREFIX."c_email_templates"; +//$tabname[25]= MAIN_DB_PREFIX."c_email_templates"; $tabname[26]= MAIN_DB_PREFIX."c_units"; $tabname[27]= MAIN_DB_PREFIX."c_stcomm"; $tabname[28]= MAIN_DB_PREFIX."c_holiday_types"; @@ -151,7 +151,7 @@ $tablib[21]= "DictionaryAvailability"; $tablib[22]= "DictionarySource"; $tablib[23]= "DictionaryRevenueStamp"; $tablib[24]= "DictionaryResourceType"; -$tablib[25]= "DictionaryEMailTemplates"; +//$tablib[25]= "DictionaryEMailTemplates"; $tablib[26]= "DictionaryUnits"; $tablib[27]= "DictionaryProspectStatus"; $tablib[28]= "DictionaryHolidayTypes"; @@ -188,7 +188,7 @@ $tabsql[21]= "SELECT c.rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX $tabsql[22]= "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_input_reason"; $tabsql[23]= "SELECT t.rowid as rowid, t.taux, c.label as country, c.code as country_code, t.fk_pays as country_id, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_revenuestamp as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid"; $tabsql[24]= "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_type_resource"; -$tabsql[25]= "SELECT rowid as rowid, label, type_template, private, position, topic, content_lines, content, active FROM ".MAIN_DB_PREFIX."c_email_templates WHERE entity IN (".getEntity('email_template',1).")"; +//$tabsql[25]= "SELECT rowid as rowid, label, type_template, private, position, topic, content_lines, content, active FROM ".MAIN_DB_PREFIX."c_email_templates WHERE entity IN (".getEntity('email_template',1).")"; $tabsql[26]= "SELECT rowid as rowid, code, label, short_label, active FROM ".MAIN_DB_PREFIX."c_units"; $tabsql[27]= "SELECT id as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_stcomm"; $tabsql[28]= "SELECT h.rowid as rowid, h.code, h.label, h.affect, h.delay, h.newbymonth, h.fk_country as country_id, c.code as country_code, c.label as country, h.active FROM ".MAIN_DB_PREFIX."c_holiday_types as h LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON h.fk_country=c.rowid"; @@ -225,7 +225,7 @@ $tabsqlsort[21]="code ASC, label ASC"; $tabsqlsort[22]="code ASC, label ASC"; $tabsqlsort[23]="country ASC, taux ASC"; $tabsqlsort[24]="code ASC,label ASC"; -$tabsqlsort[25]="label ASC"; +//$tabsqlsort[25]="label ASC"; $tabsqlsort[26]="code ASC"; $tabsqlsort[27]="code ASC"; $tabsqlsort[28]="country ASC, code ASC"; @@ -262,7 +262,7 @@ $tabfield[21]= "code,label"; $tabfield[22]= "code,label"; $tabfield[23]= "country_id,country,taux,accountancy_code_sell,accountancy_code_buy,note"; $tabfield[24]= "code,label"; -$tabfield[25]= "label,type_template,private,position,topic,content_lines,content"; +//$tabfield[25]= "label,type_template,private,position,topic,content_lines,content"; $tabfield[26]= "code,label,short_label"; $tabfield[27]= "code,libelle"; $tabfield[28]= "code,label,affect,delay,newbymonth,country_id,country"; @@ -299,7 +299,7 @@ $tabfieldvalue[21]= "code,label"; $tabfieldvalue[22]= "code,label"; $tabfieldvalue[23]= "country,taux,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldvalue[24]= "code,label"; -$tabfieldvalue[25]= "label,type_template,private,position,topic,content_lines,content"; +//$tabfieldvalue[25]= "label,type_template,private,position,topic,content_lines,content"; $tabfieldvalue[26]= "code,label,short_label"; $tabfieldvalue[27]= "code,libelle"; $tabfieldvalue[28]= "code,label,affect,delay,newbymonth,country"; @@ -336,7 +336,7 @@ $tabfieldinsert[21]= "code,label"; $tabfieldinsert[22]= "code,label"; $tabfieldinsert[23]= "fk_pays,taux,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldinsert[24]= "code,label"; -$tabfieldinsert[25]= "label,type_template,private,position,topic,content_lines,content,entity"; +//$tabfieldinsert[25]= "label,type_template,private,position,topic,content_lines,content,entity"; $tabfieldinsert[26]= "code,label,short_label"; $tabfieldinsert[27]= "code,libelle"; $tabfieldinsert[28]= "code,label,affect,delay,newbymonth,fk_country"; @@ -375,7 +375,7 @@ $tabrowid[21]= "rowid"; $tabrowid[22]= "rowid"; $tabrowid[23]= ""; $tabrowid[24]= ""; -$tabrowid[25]= ""; +//$tabrowid[25]= ""; $tabrowid[26]= ""; $tabrowid[27]= "id"; $tabrowid[28]= ""; @@ -412,7 +412,7 @@ $tabcond[21]= ! empty($conf->propal->enabled); $tabcond[22]= (! empty($conf->commande->enabled) || ! empty($conf->propal->enabled)); $tabcond[23]= true; $tabcond[24]= ! empty($conf->resource->enabled); -$tabcond[25]= true; // && ! empty($conf->global->MAIN_EMAIL_EDIT_TEMPLATE_FROM_DIC); +//$tabcond[25]= true; // && ! empty($conf->global->MAIN_EMAIL_EDIT_TEMPLATE_FROM_DIC); $tabcond[26]= ! empty($conf->product->enabled); $tabcond[27]= ! empty($conf->societe->enabled); $tabcond[28]= ! empty($conf->holiday->enabled); @@ -449,7 +449,7 @@ $tabhelp[21] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[22] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[23] = array(); $tabhelp[24] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[25] = array('topic'=>$langs->trans('SeeSubstitutionVars'),'content'=>$langs->trans('SeeSubstitutionVars'),'content_lines'=>$langs->trans('SeeSubstitutionVars'),'type_template'=>$langs->trans("TemplateForElement"),'private'=>$langs->trans("TemplateIsVisibleByOwnerOnly"), 'position'=>$langs->trans("PositionIntoComboList")); +//$tabhelp[25] = array('topic'=>$langs->trans('SeeSubstitutionVars'),'content'=>$langs->trans('SeeSubstitutionVars'),'content_lines'=>$langs->trans('SeeSubstitutionVars'),'type_template'=>$langs->trans("TemplateForElement"),'private'=>$langs->trans("TemplateIsVisibleByOwnerOnly"), 'position'=>$langs->trans("PositionIntoComboList")); $tabhelp[26] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[27] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[28] = array('affect'=>$langs->trans("FollowedByACounter"),'delay'=>$langs->trans("MinimumNoticePeriod"), 'newbymonth'=>$langs->trans("NbAddedAutomatically")); @@ -486,7 +486,7 @@ $tabfieldcheck[21] = array(); $tabfieldcheck[22] = array(); $tabfieldcheck[23] = array(); $tabfieldcheck[24] = array(); -$tabfieldcheck[25] = array(); +//$tabfieldcheck[25] = array(); $tabfieldcheck[26] = array(); $tabfieldcheck[27] = array(); $tabfieldcheck[28] = array(); @@ -544,29 +544,6 @@ if ($id == 11) 'external' => $langs->trans('External') ); } -if ($id == 25) -{ - // We save list of template email Dolibarr can manage. This list can found by a grep into code on "->param['models']" - $elementList = array(); - if ($conf->propal->enabled) $elementList['propal_send']=$langs->trans('MailToSendProposal'); - if ($conf->commande->enabled) $elementList['order_send']=$langs->trans('MailToSendOrder'); - if ($conf->facture->enabled) $elementList['facture_send']=$langs->trans('MailToSendInvoice'); - if ($conf->expedition->enabled) $elementList['shipping_send']=$langs->trans('MailToSendShipment'); - if ($conf->ficheinter->enabled) $elementList['fichinter_send']=$langs->trans('MailToSendIntervention'); - if ($conf->supplier_proposal->enabled) $elementList['supplier_proposal_send']=$langs->trans('MailToSendSupplierRequestForQuotation'); - if ($conf->fournisseur->enabled) $elementList['order_supplier_send']=$langs->trans('MailToSendSupplierOrder'); - if ($conf->fournisseur->enabled) $elementList['invoice_supplier_send']=$langs->trans('MailToSendSupplierInvoice'); - if ($conf->societe->enabled) $elementList['thirdparty']=$langs->trans('MailToThirdparty'); - if ($conf->contrat->enabled) $elementList['contract']=$langs->trans('MailToSendContract'); - - $parameters=array('elementList'=>$elementList); - $reshook=$hookmanager->executeHooks('emailElementlist',$parameters); // Note that $action and $object may have been modified by some hooks - if ($reshook == 0) { - foreach ($hookmanager->resArray as $item => $value) { - $elementList[$item] = $value; - } - } -} // Define localtax_typeList (used for dictionary "llx_c_tva") $localtax_typeList = array(); @@ -1048,7 +1025,6 @@ if ($id) if ($fieldlist[$field]=='pcg_subtype') { $valuetoshow=$langs->trans("Pcg_subtype"); } if ($fieldlist[$field]=='sortorder') { $valuetoshow=$langs->trans("SortOrder"); } if ($fieldlist[$field]=='short_label') { $valuetoshow=$langs->trans("ShortLabel"); } - if ($fieldlist[$field]=='type_template') { $valuetoshow=$langs->trans("TypeOfTemplate"); } if ($fieldlist[$field]=='range_account') { $valuetoshow=$langs->trans("Range"); } if ($fieldlist[$field]=='sens') { $valuetoshow=$langs->trans("Sens"); } if ($fieldlist[$field]=='category_type') { $valuetoshow=$langs->trans("Calculated"); } @@ -1062,8 +1038,6 @@ if ($id) if ($fieldlist[$field]=='font_size') { $valuetoshow=$langs->trans("FontSize"); } if ($fieldlist[$field]=='custom_x') { $valuetoshow=$langs->trans("CustomX"); } if ($fieldlist[$field]=='custom_y') { $valuetoshow=$langs->trans("CustomY"); } - if ($fieldlist[$field]=='content') { $valuetoshow=$langs->trans("Content"); } - if ($fieldlist[$field]=='content_lines') { $valuetoshow=$langs->trans("ContentLines"); } if ($fieldlist[$field]=='percent') { $valuetoshow=$langs->trans("Percentage"); } if ($fieldlist[$field]=='affect') { $valuetoshow=$langs->trans("Info"); } if ($fieldlist[$field]=='delay') { $valuetoshow=$langs->trans("NoticePeriod"); } @@ -1117,35 +1091,18 @@ if ($id) if (empty($reshook)) { - if ($tabname[$id] == MAIN_DB_PREFIX.'c_email_templates' && $action == 'edit') - { - fieldList($fieldlist,$obj,$tabname[$id],'hide'); - } - else - { - fieldList($fieldlist,$obj,$tabname[$id],'add'); - } + fieldList($fieldlist,$obj,$tabname[$id],'add'); } if ($id == 4) print ''; print ''; - if ($tabname[$id] != MAIN_DB_PREFIX.'c_email_templates' || $action != 'edit') + if ($action != 'edit') { print ''; } print ''; print ""; - if ($tabname[$id] == MAIN_DB_PREFIX.'c_email_templates') - { - print '* '.$langs->trans("AvailableVariables").": "; - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail=new FormMail($db); - $tmp=$formmail->getAvailableSubstitKey('form'); - print implode(', ', $tmp); - print ''; - } - $colspan=count($fieldlist)+3; if ($id == 4) $colspan++; @@ -1240,7 +1197,6 @@ if ($id) if ($fieldlist[$field]=='pcg_subtype') { $valuetoshow=$langs->trans("Pcg_subtype"); } if ($fieldlist[$field]=='sortorder') { $valuetoshow=$langs->trans("SortOrder"); } if ($fieldlist[$field]=='short_label') { $valuetoshow=$langs->trans("ShortLabel"); } - if ($fieldlist[$field]=='type_template') { $valuetoshow=$langs->trans("TypeOfTemplate"); } if ($fieldlist[$field]=='range_account') { $valuetoshow=$langs->trans("Range"); } if ($fieldlist[$field]=='sens') { $valuetoshow=$langs->trans("Sens"); } if ($fieldlist[$field]=='category_type') { $valuetoshow=$langs->trans("Calculated"); } @@ -1254,8 +1210,6 @@ if ($id) if ($fieldlist[$field]=='font_size') { $valuetoshow=$langs->trans("FontSize"); } if ($fieldlist[$field]=='custom_x') { $valuetoshow=$langs->trans("CustomX"); } if ($fieldlist[$field]=='custom_y') { $valuetoshow=$langs->trans("CustomY"); } - if ($fieldlist[$field]=='content') { $valuetoshow=$langs->trans("Content"); } - if ($fieldlist[$field]=='content_lines') { $valuetoshow=$langs->trans("ContentLines"); } if ($fieldlist[$field]=='percent') { $valuetoshow=$langs->trans("Percentage"); } if ($fieldlist[$field]=='affect') { $valuetoshow=$langs->trans("Info"); } if ($fieldlist[$field]=='delay') { $valuetoshow=$langs->trans("NoticePeriod"); } @@ -1354,10 +1308,6 @@ if ($id) $showfield=1; $align="left"; $valuetoshow=$obj->{$fieldlist[$field]}; - if ($value == 'type_template') - { - $valuetoshow = isset($elementList[$valuetoshow])?$elementList[$valuetoshow]:$valuetoshow; - } if ($value == 'element') { $valuetoshow = isset($elementList[$valuetoshow])?$elementList[$valuetoshow]:$valuetoshow; @@ -1537,7 +1487,8 @@ if ($id) $canbemodified=$iserasable; if ($obj->code == 'RECEP') $canbemodified=1; - $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?urlencode($obj->code):''); + $rowidcol=$tabrowid[$id]; + $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->{$rowidcol})?$obj->{$rowidcol}:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?urlencode($obj->code):''); if ($param) $url .= '&'.$param; $url.='&'; @@ -1726,13 +1677,6 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT,'lang'); print ''; } - // Le type de template - elseif ($fieldlist[$field] == 'type_template') - { - print ''; - print $form->selectarray('type_template', $elementList,(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'')); - print ''; - } // Le type de l'element (pour les type de contact) elseif ($fieldlist[$field] == 'element') { @@ -1773,42 +1717,6 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') elseif (in_array($fieldlist[$field], array('libelle_facture'))) { print ''; } - elseif (in_array($fieldlist[$field], array('content_lines'))) - { - if ($tabname == MAIN_DB_PREFIX.'c_email_templates') - { - print ''; // To create an artificial CR for the current tr we are on - } - else print ''; - if ($context != 'hide') - { - //print ''; - $okforextended=true; - if ($tabname == MAIN_DB_PREFIX.'c_email_templates' && empty($conf->global->FCKEDITOR_ENABLE_MAIL)) $okforextended=false; - $doleditor = new DolEditor($fieldlist[$field], (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''), '', 100, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_1, '90%'); - print $doleditor->Create(1); - } - else print ' '; - print ''; - } - elseif (in_array($fieldlist[$field], array('content'))) - { - if ($tabname == MAIN_DB_PREFIX.'c_email_templates') - { - print ''; // To create an artificial CR for the current tr we are on - } - else print ''; - if ($context != 'hide') - { - //print ''; - $okforextended=true; - if ($tabname == MAIN_DB_PREFIX.'c_email_templates' && empty($conf->global->FCKEDITOR_ENABLE_MAIL)) $okforextended=false; - $doleditor = new DolEditor($fieldlist[$field], (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''), '', 140, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_8, '90%'); - print $doleditor->Create(1); - } - else print ' '; - print ''; - } elseif ($fieldlist[$field] == 'price' || preg_match('/^amount/i',$fieldlist[$field])) { print ''; } diff --git a/htdocs/admin/external_rss.php b/htdocs/admin/external_rss.php index f18a3fe86b6..8e550f98c99 100644 --- a/htdocs/admin/external_rss.php +++ b/htdocs/admin/external_rss.php @@ -46,14 +46,17 @@ $action=GETPOST('action'); */ // positionne la variable pour le nombre de rss externes -$sql ="SELECT MAX(".$db->decrypt('name').") as name FROM ".MAIN_DB_PREFIX."const"; +$sql ="SELECT ".$db->decrypt('name')." as name FROM ".MAIN_DB_PREFIX."const"; $sql.=" WHERE ".$db->decrypt('name')." LIKE 'EXTERNAL_RSS_URLRSS_%'"; -$result=$db->query($sql); +//print $sql; +$result=$db->query($sql); // We can't use SELECT MAX() because EXTERNAL_RSS_URLRSS_10 is lower than EXTERNAL_RSS_URLRSS_9 if ($result) { - $obj = $db->fetch_object($result); - preg_match('/([0-9]+)$/i',$obj->name,$reg); - if ($reg[1]) $lastexternalrss = $reg[1]; + while ($obj = $db->fetch_object($result)) + { + preg_match('/([0-9]+)$/i',$obj->name,$reg); + if ($reg[1] && $reg[1] > $lastexternalrss) $lastexternalrss = $reg[1]; + } } else { diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php index 21ddabc1b65..42000e7176d 100644 --- a/htdocs/admin/facture.php +++ b/htdocs/admin/facture.php @@ -738,7 +738,7 @@ print ''; print ''; print ''; print ''; -print $langs->trans("FreeLegalTextOnInvoices").' ('.$langs->trans("AddCRIfTooLong").')
'; +print $langs->trans("FreeLegalTextOnInvoices").' '.img_info($langs->trans("AddCRIfTooLong")).'
'; $variablename='INVOICE_FREE_TEXT'; if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { @@ -759,9 +759,9 @@ $var=!$var; print ''; print ''; print ''; -print ''; -print $langs->trans("WatermarkOnDraftBill").'
'; -print ''; +print ''; +print $langs->trans("WatermarkOnDraftBill").''; +print ''; print ''; print ''; print "\n"; diff --git a/htdocs/admin/fichinter.php b/htdocs/admin/fichinter.php index a67407b818c..8d31db0d3af 100644 --- a/htdocs/admin/fichinter.php +++ b/htdocs/admin/fichinter.php @@ -539,7 +539,7 @@ print ''; print ''; print ''; print ''; -print $langs->trans("FreeLegalTextOnInterventions").' ('.$langs->trans("AddCRIfTooLong").')
'; +print $langs->trans("FreeLegalTextOnInterventions").' '.img_info($langs->trans("AddCRIfTooLong")).'
'; $variablename='FICHINTER_FREE_TEXT'; if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { @@ -561,8 +561,8 @@ $var=!$var; print ""; print ''; print ""; -print ''; -print $langs->trans("WatermarkOnDraftInterventionCards").'
'; +print ''; +print $langs->trans("WatermarkOnDraftInterventionCards").''; print ''; print ''; print ''; diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index ed290060370..e0e23f75d18 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -114,17 +114,24 @@ $server=! empty($conf->global->MAIN_MAIL_SMTP_SERVER)?$conf->global->MAIN_MAIL_S if (! $server) $server='127.0.0.1'; -/* - * View - */ - $wikihelp='EN:Setup EMails|FR:Paramétrage EMails|ES:Configuración EMails'; llxHeader('',$langs->trans("Setup"),$wikihelp); print load_fiche_titre($langs->trans("EMailsSetup"),'','title_setup'); -print $langs->trans("EMailsDesc")."
\n"; -print "
\n"; + +$h = 0; + +$head[$h][0] = DOL_URL_ROOT."/admin/mails.php"; +$head[$h][1] = $langs->trans("OutGoingEmailSetup"); +$head[$h][2] = 'common'; +$h++; + +$head[$h][0] = DOL_URL_ROOT."/admin/mails_templates.php"; +$head[$h][1] = $langs->trans("DictionaryEMailTemplates"); +$head[$h][2] = 'templates'; +$h++; + // List of sending methods $listofmethods=array(); @@ -221,6 +228,12 @@ if ($action == 'edit') print ''; print ''; + dol_fiche_head($head, 'common', ''); + + print $langs->trans("EMailsDesc")."
\n"; + print "
\n"; + + clearstatcache(); $var=true; @@ -428,6 +441,8 @@ if ($action == 'edit') print ''; + dol_fiche_end(); + print '
'; print ''; print '     '; @@ -438,6 +453,12 @@ if ($action == 'edit') } else { + dol_fiche_head($head, 'common', ''); + + print $langs->trans("EMailsDesc")."
\n"; + print "
\n"; + + $var=true; print ''; @@ -570,10 +591,12 @@ else print ' '; } print ''; - print '
'; + dol_fiche_end(); + + if ($conf->global->MAIN_MAIL_SENDMODE == 'mail' && empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA)) { print '
'; @@ -619,7 +642,7 @@ else print '
'; - if ($conf->global->MAIN_MAIL_SENDMODE == 'mail') + if ($conf->global->MAIN_MAIL_SENDMODE == 'mail' && ! in_array($action, array('testconnect', 'test', 'testhtml'))) { $text = $langs->trans("WarningPHPMail"); print info_admin($text); diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php new file mode 100644 index 00000000000..150f288e45d --- /dev/null +++ b/htdocs/admin/mails_templates.php @@ -0,0 +1,868 @@ + + * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2010-2016 Juanjo Menent + * Copyright (C) 2011-2015 Philippe Grand + * Copyright (C) 2011 Remy Younes + * Copyright (C) 2012-2015 Marcos García + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2011-2016 Alexandre Spangaro + * Copyright (C) 2015 Ferran Marcet + * Copyright (C) 2016 Raphaël Doursenaud + * + * This 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/admin/dict.php + * \ingroup setup + * \brief Page to administer data tables + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/html.formventilation.class.php'; + +$langs->load("errors"); +$langs->load("admin"); +$langs->load("main"); +$langs->load("mails"); + +$action=GETPOST('action','alpha')?GETPOST('action','alpha'):'view'; +$confirm=GETPOST('confirm','alpha'); +$id=GETPOST('id','int'); +$rowid=GETPOST('rowid','alpha'); + +$allowed=$user->admin; +if (! $allowed) accessforbidden(); + +$acts[0] = "activate"; +$acts[1] = "disable"; +$actl[0] = img_picto($langs->trans("Disabled"),'switch_off'); +$actl[1] = img_picto($langs->trans("Activated"),'switch_on'); + +$listoffset=GETPOST('listoffset'); +$listlimit=GETPOST('listlimit')>0?GETPOST('listlimit'):1000; +$active = 1; + +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { $page = 0 ; } +$offset = $listlimit * $page ; +$pageprev = $page - 1; +$pagenext = $page + 1; + +// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array +$hookmanager->initHooks(array('emailtemplates')); + +// Name of SQL tables of dictionaries +$tabname=array(); +$tabname[25]= MAIN_DB_PREFIX."c_email_templates"; + +// Requests to extract data +$tabsql=array(); +$tabsql[25]= "SELECT rowid as rowid, label, type_template, private, position, topic, content_lines, content, active FROM ".MAIN_DB_PREFIX."c_email_templates WHERE entity IN (".getEntity('email_template',1).")"; + +// Criteria to sort dictionaries +$tabsqlsort=array(); +$tabsqlsort[25]="label ASC"; + +// Nom des champs en resultat de select pour affichage du dictionnaire +$tabfield=array(); +$tabfield[25]= "label,type_template,private,position,topic,content"; +if (! empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) $tabfield[25].=',content_lines'; + +// Nom des champs d'edition pour modification d'un enregistrement +$tabfieldvalue=array(); +$tabfieldvalue[25]= "label,type_template,private,position,topic,content"; +if (! empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) $tabfieldvalue[25].=',content_lines'; + +// Nom des champs dans la table pour insertion d'un enregistrement +$tabfieldinsert=array(); +$tabfieldinsert[25]= "label,type_template,private,position,topic,content"; +if (! empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) $tabfieldinsert[25].=',content_lines'; +$tabfieldinsert[25].=',entity'; // Must be at end because not into other arrays + +// Nom du rowid si le champ n'est pas de type autoincrement +// Example: "" if id field is "rowid" and has autoincrement on +// "nameoffield" if id field is not "rowid" or has not autoincrement on +$tabrowid=array(); +$tabrowid[25]= ""; + +// Condition to show dictionary in setup page +$tabcond=array(); +$tabcond[25]= true; + +// List of help for fields +// Set MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES to allow edit of template for lines +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; +$formmail=new FormMail($db); +if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) +{ + $tmp=$formmail->getAvailableSubstitKey('form'); + $helpsubstit = $langs->trans("AvailableVariables").':
'.implode('
', $tmp); + $helpsubstitforlines = $langs->trans("AvailableVariables").':
'.implode('
', $tmp); +} +else +{ + $tmp=$formmail->getAvailableSubstitKey('formwithlines'); + $helpsubstit = $langs->trans("AvailableVariables").':
'.implode('
', $tmp); + $tmp=$formmail->getAvailableSubstitKey('formforlines'); + $helpsubstitforlines = $langs->trans("AvailableVariables").':
'.implode('
', $tmp); +} + + +$tabhelp=array(); +$tabhelp[25] = array('topic'=>$helpsubstit,'content'=>$helpsubstit,'content_lines'=>$helpsubstitforlines,'type_template'=>$langs->trans("TemplateForElement"),'private'=>$langs->trans("TemplateIsVisibleByOwnerOnly"), 'position'=>$langs->trans("PositionIntoComboList")); + +// List of check for fields (NOT USED YET) +$tabfieldcheck=array(); +$tabfieldcheck[25] = array(); + + +// Define elementList and sourceList (used for dictionary type of contacts "llx_c_type_contact") +$elementList = array(); +$sourceList=array(); + +// We save list of template email Dolibarr can manage. This list can found by a grep into code on "->param['models']" +$elementList = array(); +if ($conf->propal->enabled) $elementList['propal_send']=$langs->trans('MailToSendProposal'); +if ($conf->commande->enabled) $elementList['order_send']=$langs->trans('MailToSendOrder'); +if ($conf->facture->enabled) $elementList['facture_send']=$langs->trans('MailToSendInvoice'); +if ($conf->expedition->enabled) $elementList['shipping_send']=$langs->trans('MailToSendShipment'); +if ($conf->ficheinter->enabled) $elementList['fichinter_send']=$langs->trans('MailToSendIntervention'); +if ($conf->supplier_proposal->enabled) $elementList['supplier_proposal_send']=$langs->trans('MailToSendSupplierRequestForQuotation'); +if ($conf->fournisseur->enabled) $elementList['order_supplier_send']=$langs->trans('MailToSendSupplierOrder'); +if ($conf->fournisseur->enabled) $elementList['invoice_supplier_send']=$langs->trans('MailToSendSupplierInvoice'); +if ($conf->societe->enabled) $elementList['thirdparty']=$langs->trans('MailToThirdparty'); +if ($conf->contrat->enabled) $elementList['contract']=$langs->trans('MailToSendContract'); + +$parameters=array('elementList'=>$elementList); +$reshook=$hookmanager->executeHooks('emailElementlist',$parameters); // Note that $action and $object may have been modified by some hooks +if ($reshook == 0) { + foreach ($hookmanager->resArray as $item => $value) { + $elementList[$item] = $value; + } +} + +$id = 25; + + +/* + * Actions + */ + +if (GETPOST('button_removefilter') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter_x')) +{ + //$search_country_id = ''; +} + +// Actions add or modify an entry into a dictionary +if (GETPOST('actionadd') || GETPOST('actionmodify')) +{ + $listfield=explode(',', str_replace(' ', '',$tabfield[$id])); + $listfieldinsert=explode(',',$tabfieldinsert[$id]); + $listfieldmodify=explode(',',$tabfieldinsert[$id]); + $listfieldvalue=explode(',',$tabfieldvalue[$id]); + + // Check that all fields are filled + $ok=1; + foreach ($listfield as $f => $value) + { + if ($value == 'content') continue; + if ($value == 'content_lines') continue; + if ($value == 'content') $value='content-'.$rowid; + if ($value == 'content_lines') $value='content_lines-'.$rowid; + + if (! isset($_POST[$value]) || $_POST[$value]=='') + { + $ok=0; + $fieldnamekey=$listfield[$f]; + // We take translate key of field + if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) $fieldnamekey='Label'; + if ($fieldnamekey == 'libelle_facture') $fieldnamekey = 'LabelOnDocuments'; + if ($fieldnamekey == 'code') $fieldnamekey = 'Code'; + if ($fieldnamekey == 'note') $fieldnamekey = 'Note'; + if ($fieldnamekey == 'type') $fieldnamekey = 'Type'; + + setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); + } + } + + // Si verif ok et action add, on ajoute la ligne + if ($ok && GETPOST('actionadd')) + { + if ($tabrowid[$id]) + { + // Recupere id libre pour insertion + $newid=0; + $sql = "SELECT max(".$tabrowid[$id].") newid from ".$tabname[$id]; + $result = $db->query($sql); + if ($result) + { + $obj = $db->fetch_object($result); + $newid=($obj->newid + 1); + + } else { + dol_print_error($db); + } + } + + // Add new entry + $sql = "INSERT INTO ".$tabname[$id]." ("; + // List of fields + if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldinsert)) + $sql.= $tabrowid[$id].","; + $sql.= $tabfieldinsert[$id]; + $sql.=",active)"; + $sql.= " VALUES("; + + // List of values + if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldinsert)) + $sql.= $newid.","; + $i=0; + foreach ($listfieldinsert as $f => $value) + { + //var_dump($i.' - '.$listfieldvalue[$i].' - '.$_POST[$listfieldvalue[$i]].' - '.$value); + if ($value == 'entity') { + $_POST[$listfieldvalue[$i]] = $conf->entity; + } + if ($i) $sql.=","; + if ($value == 'private' && ! is_numeric($_POST[$listfieldvalue[$i]])) $_POST[$listfieldvalue[$i]]='0'; + if ($value == 'position' && ! is_numeric($_POST[$listfieldvalue[$i]])) $_POST[$listfieldvalue[$i]]='1'; + if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; // For vat, we want/accept code = '' + else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $i++; + } + $sql.=",1)"; + + dol_syslog("actionadd", LOG_DEBUG); + $result = $db->query($sql); + if ($result) // Add is ok + { + setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); + $_POST=array('id'=>$id); // Clean $_POST array, we keep only + } + else + { + if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); + } + else { + dol_print_error($db); + } + } + } + + // Si verif ok et action modify, on modifie la ligne + if ($ok && GETPOST('actionmodify')) + { + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + // Modify entry + $sql = "UPDATE ".$tabname[$id]." SET "; + // Modifie valeur des champs + if ($tabrowid[$id] && ! in_array($tabrowid[$id],$listfieldmodify)) + { + $sql.= $tabrowid[$id]."="; + $sql.= "'".$db->escape($rowid)."', "; + } + $i = 0; + foreach ($listfieldmodify as $field) + { + if ($field == 'content') $_POST['content']=$_POST['content-'.$rowid]; + if ($field == 'content_lines') $_POST['content_lines']=$_POST['content_lines-'.$rowid]; + if ($field == 'entity') { + $_POST[$listfieldvalue[$i]] = $conf->entity; + } + if ($i) $sql.=","; + $sql.= $field."="; + if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; // For vat, we want/accept code = '' + else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $i++; + } + $sql.= " WHERE ".$rowidcol." = '".$rowid."'"; + + dol_syslog("actionmodify", LOG_DEBUG); + //print $sql; + $resql = $db->query($sql); + if (! $resql) + { + setEventMessages($db->error(), null, 'errors'); + } + } +} + +if ($action == 'confirm_delete' && $confirm == 'yes') // delete +{ + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol."='".$rowid."'"; + + dol_syslog("delete", LOG_DEBUG); + $result = $db->query($sql); + if (! $result) + { + if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') + { + setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors'); + } + else + { + dol_print_error($db); + } + } +} + +// activate +if ($action == $acts[0]) +{ + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE ".$rowidcol."='".$rowid."'"; + } + elseif ($_GET["code"]) { + $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE code='".$_GET["code"]."'"; + } + + $result = $db->query($sql); + if (!$result) + { + dol_print_error($db); + } +} + +// disable +if ($action == $acts[1]) +{ + if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } + else { $rowidcol="rowid"; } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE ".$rowidcol."='".$rowid."'"; + } + elseif ($_GET["code"]) { + $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE code='".$_GET["code"]."'"; + } + + $result = $db->query($sql); + if (!$result) + { + dol_print_error($db); + } +} + + + +/* + * View + */ + +$form = new Form($db); +$formadmin=new FormAdmin($db); + +llxHeader(); + +$titre=$langs->trans("EMailsSetup"); +$linkback=''; +$titlepicto='title_setup'; + +print load_fiche_titre($titre,$linkback,$titlepicto); + +$h = 0; + +$head[$h][0] = DOL_URL_ROOT."/admin/mails.php"; +$head[$h][1] = $langs->trans("OutGoingEmailSetup"); +$head[$h][2] = 'common'; +$h++; + +$head[$h][0] = DOL_URL_ROOT."/admin/mails_templates.php"; +$head[$h][1] = $langs->trans("DictionaryEMailTemplates"); +$head[$h][2] = 'templates'; +$h++; + + +dol_fiche_head($head, 'templates', ''); + +// Confirmation de la suppression de la ligne +if ($action == 'delete') +{ + print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid.'&code='.$_GET["code"].'&id='.$id, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete','',0,1); +} +//var_dump($elementList); + +// Complete requete recherche valeurs avec critere de tri +$sql=$tabsql[$id]; + +if ($search_country_id > 0) +{ + if (preg_match('/ WHERE /',$sql)) $sql.= " AND "; + else $sql.=" WHERE "; + $sql.= " c.rowid = ".$search_country_id; +} + +if ($sortfield) +{ + // If sort order is "country", we use country_code instead + if ($sortfield == 'country') $sortfield='country_code'; + $sql.= " ORDER BY ".$sortfield; + if ($sortorder) + { + $sql.=" ".strtoupper($sortorder); + } + $sql.=", "; + // Clear the required sort criteria for the tabsqlsort to be able to force it with selected value + $tabsqlsort[$id]=preg_replace('/([a-z]+\.)?'.$sortfield.' '.$sortorder.',/i','',$tabsqlsort[$id]); + $tabsqlsort[$id]=preg_replace('/([a-z]+\.)?'.$sortfield.',/i','',$tabsqlsort[$id]); +} +else { + $sql.=" ORDER BY "; +} +$sql.=$tabsqlsort[$id]; +$sql.=$db->plimit($listlimit+1,$offset); +//print $sql; + +$fieldlist=explode(',',$tabfield[$id]); + +print ''; +print ''; +print ''; + +print ''; + +// Form to add a new line +$alabelisused=0; +$var=false; + +$fieldlist=explode(',',$tabfield[$id]); + +if ($action != 'edit') +{ + // Line for title + print ''; + foreach ($fieldlist as $field => $value) + { + // Determine le nom du champ par rapport aux noms possibles + // dans les dictionnaires de donnees + $valuetoshow=ucfirst($fieldlist[$field]); // Par defaut + $valuetoshow=$langs->trans($valuetoshow); // try to translate + $align="left"; + if ($fieldlist[$field]=='lang') { $valuetoshow=$langs->trans("Language"); } + if ($fieldlist[$field]=='type') { $valuetoshow=$langs->trans("Type"); } + if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } + if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') { $valuetoshow=$langs->trans("Label"); } + if ($fieldlist[$field]=='type_template') { $valuetoshow=$langs->trans("TypeOfTemplate"); } + if ($fieldlist[$field]=='content') { $valuetoshow=''; } + if ($fieldlist[$field]=='content_lines') { $valuetoshow=''; } + + if ($valuetoshow != '') + { + print ''; + } + if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') $alabelisused=1; + } + + print ''; + print ''; + + // Line to enter new values + print ""; + + $obj = new stdClass(); + // If data was already input, we define them in obj to populate input fields. + if (GETPOST('actionadd')) + { + foreach ($fieldlist as $key=>$val) + { + if (GETPOST($val) != '') + $obj->$val=GETPOST($val); + } + } + + $tmpaction = 'create'; + $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook=$hookmanager->executeHooks('createDictionaryFieldlist',$parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + $error=$hookmanager->error; $errors=$hookmanager->errors; + + if (empty($reshook)) + { + if ($tabname[$id] == MAIN_DB_PREFIX.'c_email_templates' && $action == 'edit') + { + fieldList($fieldlist,$obj,$tabname[$id],'hide'); + } + else + { + fieldList($fieldlist,$obj,$tabname[$id],'add'); + } + } + + print ''; + print ""; + + $fieldsforcontent = array('content'); + if (! empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) + { + $fieldsforcontent = array('content', 'content_lines'); + } + foreach ($fieldsforcontent as $tmpfieldlist) + { + print ''; + if ($tmpfieldlist == 'content') + { + print ''; + } + //else print ''; + print ''; + } + + + + $colspan=count($fieldlist)+1; + print ''; // Keep   to have a line with enough height +} + + +// List of available record in database +dol_syslog("htdocs/admin/dict", LOG_DEBUG); +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + $i = 0; + $var=true; + + $param = '&id='.$id; + $paramwithsearch = $param; + if ($sortorder) $paramwithsearch.= '&sortorder='.$sortorder; + if ($sortfield) $paramwithsearch.= '&sortfield='.$sortfield; + if (GETPOST('from')) $paramwithsearch.= '&from='.GETPOST('from','alpha'); + + // There is several pages + if ($num > $listlimit) + { + print ''; + } + + // Title of lines + print ''; + foreach ($fieldlist as $field => $value) + { + // Determine le nom du champ par rapport aux noms possibles + // dans les dictionnaires de donnees + $showfield=1; // By defaut + $align="left"; + $sortable=1; + $valuetoshow=''; + /* + $tmparray=getLabelOfField($fieldlist[$field]); + $showfield=$tmp['showfield']; + $valuetoshow=$tmp['valuetoshow']; + $align=$tmp['align']; + $sortable=$tmp['sortable']; + */ + $valuetoshow=ucfirst($fieldlist[$field]); // By defaut + $valuetoshow=$langs->trans($valuetoshow); // try to translate + if ($fieldlist[$field]=='lang') { $valuetoshow=$langs->trans("Language"); } + if ($fieldlist[$field]=='type') { $valuetoshow=$langs->trans("Type"); } + if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') { $valuetoshow=$langs->trans("Label"); } + if ($fieldlist[$field]=='type_template') { $valuetoshow=$langs->trans("TypeOfTemplate"); } + if ($fieldlist[$field]=='content') { $valuetoshow=$langs->trans("Content"); $showfield=0;} + if ($fieldlist[$field]=='content_lines') { $valuetoshow=$langs->trans("ContentLines"); $showfield=0; } + + // Affiche nom du champ + if ($showfield) + { + if (! empty($tabhelp[$id][$value])) $valuetoshow = $form->textwithpicto($valuetoshow,$tabhelp[$id][$value]); + print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable?$fieldlist[$field]:''), ($page?'page='.$page.'&':''), $param, "align=".$align, $sortfield, $sortorder); + } + } + + print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page?'page='.$page.'&':''), $param, 'align="center"', $sortfield, $sortorder); + print getTitleFieldOfList(''); + print getTitleFieldOfList(''); + print ''; + + // Title line with search boxes + print ''; + $filterfound=0; + foreach ($fieldlist as $field => $value) + { + if (! in_array($field, array('content', 'content_lines'))) print ''; + } + if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) print ''; + print ''; + print ''; + print ''; + + if ($num) + { + // Lines with values + while ($i < $num) + { + $var = ! $var; + + $obj = $db->fetch_object($resql); + //print_r($obj); + print ''; + if ($action == 'edit' && ($rowid == (! empty($obj->rowid)?$obj->rowid:$obj->code))) + { + $tmpaction='edit'; + $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook=$hookmanager->executeHooks('editDictionaryFieldlist',$parameters,$obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + $error=$hookmanager->error; $errors=$hookmanager->errors; + + // Show fields + if (empty($reshook)) fieldList($fieldlist,$obj,$tabname[$id],'edit'); + + print ''; + + $fieldsforcontent = array('content'); + if (! empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) + { + $fieldsforcontent = array('content', 'content_lines'); + } + foreach ($fieldsforcontent as $tmpfieldlist) + { + $showfield = 1; + $align = "left"; + $valuetoshow = $obj->{$tmpfieldlist}; + + $class = 'tddict'; + // Show value for field + if ($showfield) { + + print ''; + print ''; + + } + } + } + else + { + $tmpaction = 'view'; + $parameters=array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook=$hookmanager->executeHooks('viewDictionaryFieldlist',$parameters,$obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + + $error=$hookmanager->error; $errors=$hookmanager->errors; + + if (empty($reshook)) + { + foreach ($fieldlist as $field => $value) + { + if (in_array($fieldlist[$field], array('content','content_lines'))) continue; + $showfield=1; + $align="left"; + $valuetoshow=$obj->{$fieldlist[$field]}; + if ($value == 'type_template') + { + $valuetoshow = isset($elementList[$valuetoshow])?$elementList[$valuetoshow]:$valuetoshow; + } + + $class='tddict'; + // Show value for field + if ($showfield) + { + print ''; + } + } + } + + // Can an entry be erased or disabled ? + $iserasable=1;$canbedisabled=1;$canbemodified=1; // true by default + $canbemodified=$iserasable; + + $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?urlencode($obj->code):''); + if ($param) $url .= '&'.$param; + $url.='&'; + + // Active + print '"; + + // Modify link + if ($canbemodified) print ''; + else print ''; + + // Delete link + if ($iserasable) + { + print ''; + } + else print ''; + + /* + $fieldsforcontent = array('content'); + if (! empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) + { + $fieldsforcontent = array('content', 'content_lines'); + } + foreach ($fieldsforcontent as $tmpfieldlist) + { + $showfield = 1; + $align = "left"; + $valuetoshow = $obj->{$tmpfieldlist}; + + $class = 'tddict'; + // Show value for field + if ($showfield) { + + print ''; + print ''; + + } + }*/ + } + print "\n"; + + + $i++; + } + } +} +else { + dol_print_error($db); +} + +print '
'; + if (! empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i',$tabhelp[$id][$value])) print ''.$valuetoshow.' '.img_help(1,$valuetoshow).''; + else if (! empty($tabhelp[$id][$value])) print $form->textwithpicto($valuetoshow,$tabhelp[$id][$value]); + else print $valuetoshow; + print ''; + print ''; + print '
'; + print '
'; + if ($tmpfieldlist == 'content') print ''.$form->textwithpicto($langs->trans("Content"),$tabhelp[$id][$tmpfieldlist]).'
'; + if ($tmpfieldlist == 'content_lines') print ''.$form->textwithpicto($langs->trans("ContentForLines"),$tabhelp[$id][$tmpfieldlist]).'
'; + + if ($context != 'hide') + { + //print ''; + $okforextended=true; + if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) $okforextended=false; + $doleditor = new DolEditor($tmpfieldlist, (! empty($obj->{$tmpfieldlist})?$obj->{$tmpfieldlist}:''), '', 120, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_4, '90%'); + print $doleditor->Create(1); + } + else print ' '; + print '
'; + if ($action != 'edit') + { + print ''; + } + print '
 
'; + print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), ''); + print '
'; + print ''; + print ''; + print ''; + print '
'; + print ''; + print '
'; // To create an artificial CR for the current tr we are on + $okforextended = true; + if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) + $okforextended = false; + $doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (! empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 140, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_6, '90%'); + print $doleditor->Create(1); + print ''.$valuetoshow.''; + if ($canbedisabled) print ''.$actl[$obj->active].''; + else + { + if (in_array($obj->code, array('AC_OTH','AC_OTH_AUTO'))) print $langs->trans("AlwaysActive"); + else if (isset($obj->type) && in_array($obj->type, array('systemauto')) && empty($obj->active)) print $langs->trans("Deprecated"); + else if (isset($obj->type) && in_array($obj->type, array('system')) && ! empty($obj->active) && $obj->code != 'AC_OTH') print $langs->trans("UsedOnlyWithTypeOption"); + else print $langs->trans("AlwaysActive"); + } + print "'.img_edit().' '; + if ($user->admin) print ''.img_delete().''; + //else print ''.img_delete().''; // Some dictionnary can be edited by other profile than admin + print ' 
'; // To create an artificial CR for the current tr we are on + $okforextended = true; + if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) + $okforextended = false; + $doleditor = new DolEditor($tmpfieldlist.'-'.$i, (! empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 140, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_6, '90%', 1); + print $doleditor->Create(1); + print '
'; + +print ''; + + +dol_fiche_end(); + +llxFooter(); +$db->close(); + + +/** + * Show fields in insert/edit mode + * + * @param array $fieldlist Array of fields + * @param Object $obj If we show a particular record, obj is filled with record fields + * @param string $tabname Name of SQL table + * @param string $context 'add'=Output field for the "add form", 'edit'=Output field for the "edit form", 'hide'=Output field for the "add form" but we dont want it to be rendered + * @return void + */ +function fieldList($fieldlist, $obj='', $tabname='', $context='') +{ + global $conf,$langs,$db; + global $form; + global $region_id; + global $elementList,$sourceList,$localtax_typeList; + global $bc; + + $formadmin = new FormAdmin($db); + $formcompany = new FormCompany($db); + if (! empty($conf->accounting->enabled)) $formaccountancy = new FormVentilation($db); + + foreach ($fieldlist as $field => $value) + { + if ($fieldlist[$field] == 'lang') + { + print ''; + print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT,'lang'); + print ''; + } + // Le type de template + elseif ($fieldlist[$field] == 'type_template') + { + print ''; + print $form->selectarray('type_template', $elementList,(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'')); + print ''; + } + elseif (in_array($fieldlist[$field], array('content','content_lines'))) continue; + else + { + print ''; + $size=''; $class=''; + if ($fieldlist[$field]=='code') $class='maxwidth100'; + if ($fieldlist[$field]=='private') $class='maxwidth50'; + if ($fieldlist[$field]=='position') $class='maxwidth50'; + if ($fieldlist[$field]=='libelle') $class='quatrevingtpercent'; + if ($fieldlist[$field]=='topic') $class='quatrevingtpercent'; + if ($fieldlist[$field]=='sortorder' || $fieldlist[$field]=='sens' || $fieldlist[$field]=='category_type') $size='size="2" '; + print ''; + print ''; + } + } +} + diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php new file mode 100644 index 00000000000..9ff7a4478ff --- /dev/null +++ b/htdocs/admin/modulehelp.php @@ -0,0 +1,490 @@ + + * 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 + * + * This 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/admin/modules.php + * \brief Page to activate/disable all modules + */ + +//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) + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; + +$langs->load("errors"); +$langs->load("admin"); + +$mode=GETPOST('mode', 'alpha'); +$action=GETPOST('action','alpha'); +$id = GETPOST('id', 'int'); +if (empty($mode)) $mode='desc'; + +if (! $user->admin) + accessforbidden(); + + + +/* + * Actions + */ + +// Nothing + + +/* + * View + */ + +$form = new Form($db); + +$help_url='EN:First_setup|FR:Premiers_paramétrages|ES:Primeras_configuraciones'; +llxHeader('',$langs->trans("Setup"),$help_url); + +print ''."\n".''; + +$arrayofnatures=array('core'=>$langs->transnoentitiesnoconv("Core"), 'external'=>$langs->transnoentitiesnoconv("External").' - '.$langs->trans("AllPublishers")); + +// Search modules dirs +$modulesdir = dolGetModulesDirs(); + + +$filename = array(); +$modules = array(); +$orders = array(); +$categ = array(); +$dirmod = array(); +$i = 0; // is a sequencer of modules found +$j = 0; // j is module number. Automatically affected if module number not defined. +$modNameLoaded=array(); + +foreach ($modulesdir as $dir) +{ + // Load modules attributes in arrays (name, numero, orders) from dir directory + //print $dir."\n
"; + dol_syslog("Scan directory ".$dir." for module descriptor files (modXXX.class.php)"); + $handle=@opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + //print "$i ".$file."\n
"; + if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php') + { + $modName = substr($file, 0, dol_strlen($file) - 10); + + if ($modName) + { + if (! empty($modNameLoaded[$modName])) + { + $mesg="Error: Module ".$modName." was found twice: Into ".$modNameLoaded[$modName]." and ".$dir.". You probably have an old file on your disk.
"; + setEventMessages($mesg, null, 'warnings'); + dol_syslog($mesg, LOG_ERR); + continue; + } + + try + { + $res=include_once $dir.$file; + 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); + } + $j = $objMod->numero; + + $modulequalified=1; + + // We discard modules according to features level (PS: if module is activated we always show it) + $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod))); + if ($objMod->version == 'development' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 2))) $modulequalified=0; + if ($objMod->version == 'experimental' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 1))) $modulequalified=0; + if (preg_match('/deprecated/', $objMod->version) && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL >= 0))) $modulequalified=0; + + // We discard modules according to property disabled + if (! empty($objMod->hidden)) $modulequalified=0; + + if ($modulequalified > 0) + { + $publisher=dol_escape_htmltag($objMod->getPublisher()); + $external=($objMod->isCoreOrExternalModule() == 'external'); + if ($external) + { + if ($publisher) + { + $arrayofnatures['external_'.$publisher]=$langs->trans("External").' - '.$publisher; + } + else + { + $arrayofnatures['external_']=$langs->trans("External").' - '.$langs->trans("UnknownPublishers"); + } + } + ksort($arrayofnatures); + } + + // Define array $categ with categ with at least one qualified module + if ($modulequalified > 0) + { + $modules[$i] = $objMod; + $filename[$i]= $modName; + + $special = $objMod->special; + + // Gives the possibility to the module, to provide his own family info and position of this family + if (is_array($objMod->familyinfo) && !empty($objMod->familyinfo)) { + $familyinfo = array_merge($familyinfo, $objMod->familyinfo); + $familykey = key($objMod->familyinfo); + } else { + $familykey = $objMod->family; + } + + $moduleposition = ($objMod->module_position?$objMod->module_position:'500'); + if ($moduleposition == 500 && ($objMod->isCoreOrExternalModule() == 'external')) + { + $moduleposition = 800; + } + + if ($special == 1) $familykey='interface'; + + $orders[$i] = $familyinfo[$familykey]['position']."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number + $dirmod[$i] = $dir; + //print $i.'-'.$dirmod[$i].'
'; + // Set categ[$i] + $specialstring = isset($specialtostring[$special])?$specialtostring[$special]:'unknown'; + if ($objMod->version == 'development' || $objMod->version == 'experimental') $specialstring='expdev'; + if (isset($categ[$specialstring])) $categ[$specialstring]++; // Array of all different modules categories + else $categ[$specialstring]=1; + $j++; + $i++; + } + else dol_syslog("Module ".get_class($objMod)." not qualified"); + } + catch(Exception $e) + { + dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR); + } + } + else + { + print "Warning bad descriptor file : ".$dir.$file." (Class ".$modName." not found into file)
"; + } + } + catch(Exception $e) + { + dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR); + } + } + } + } + closedir($handle); + } + else + { + dol_syslog("htdocs/admin/modulehelp.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING); + } +} + +asort($orders); +//var_dump($orders); +//var_dump($categ); +//var_dump($modules); + + + +$h = 0; + +$head[$h][0] = DOL_URL_ROOT."/admin/modulehelp.php?id=".$id.'&mode=desc'; +$head[$h][1] = $langs->trans("Description"); +$head[$h][2] = 'desc'; +$h++; + +$head[$h][0] = DOL_URL_ROOT."/admin/modulehelp.php?id=".$id.'&mode=feature'; +$head[$h][1] = $langs->trans("Features"); +$head[$h][2] = 'feature'; +$h++; + + +$i=0; +foreach($orders as $tmpkey => $tmpvalue) +{ + $objMod = $modules[$tmpkey]; + if ($objMod->numero == $id) + { + $key = $i; + break; + } + $i++; +} +$value = $orders[$key]; + + +print '
'; + + +print load_fiche_titre($objMod->getDesc(),$moreinfo,'object_'.$objMod->picto); +print '
'; + +dol_fiche_head($head, $mode, $title); + + + +$tab=explode('_',$value); +$familyposition=$tab[0]; $familykey=$tab[1]; $module_position=$tab[2]; $numero=$tab[3]; + +$modName = $filename[$key]; +$objMod = $modules[$key]; +$dirofmodule = $dirmod[$key]; + +$special = $objMod->special; + +if (! $objMod->getName()) +{ + dol_syslog("Error for module ".$key." - Property name of module looks empty", LOG_WARNING); +} + +$const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod))); + +// Check filters +$modulename=$objMod->getName(); +$moduledesc=$objMod->getDesc(); +$moduledesclong=$objMod->getDescLong(); +$moduleauthor=$objMod->getPublisher(); + +// Load all lang files of module +if (isset($objMod->langfiles) && is_array($objMod->langfiles)) +{ + foreach($objMod->langfiles as $domain) + { + $langs->load($domain); + } +} + +$var=!$var; + + +// Version (with picto warning or not) +$version=$objMod->getVersion(0); +$versiontrans=''; +if (preg_match('/development/i', $version)) $versiontrans.=img_warning($langs->trans("Development"), 'style="float: left"'); +if (preg_match('/experimental/i', $version)) $versiontrans.=img_warning($langs->trans("Experimental"), 'style="float: left"'); +if (preg_match('/deprecated/i', $version)) $versiontrans.=img_warning($langs->trans("Deprecated"), 'style="float: left"'); +$versiontrans.=$objMod->getVersion(1); + +// Define imginfo +$imginfo="info"; +if ($objMod->isCoreOrExternalModule() == 'external') +{ + $imginfo="info_black"; +} + +// Define text of description of module +$text=''; + +if ($mode == 'desc') +{ + $text.=''.$langs->trans("Version").': '.$version; + + $textexternal=''; + if ($objMod->isCoreOrExternalModule() == 'external') + { + $textexternal.='
'.$langs->trans("Origin").': '.$langs->trans("ExternalModule",$dirofmodule); + if ($objMod->editor_name != 'dolibarr') $textexternal.='
'.$langs->trans("Publisher").': '.(empty($objMod->editor_name)?$langs->trans("Unknown"):$objMod->editor_name); + if (! empty($objMod->editor_url) && ! preg_match('/dolibarr\.org/i',$objMod->editor_url)) $textexternal.='
'.$langs->trans("Url").': '.$objMod->editor_url; + $text.=$textexternal; + $text.='
'; + } + else + { + $text.='
'.$langs->trans("Origin").': '.$langs->trans("Core").'
'; + } + $text.='
'.$langs->trans("LastActivationDate").': '; + if (! empty($conf->global->$const_name)) $text.=dol_print_date($objMod->getLastActivationDate(), 'dayhour'); + else $text.=$langs->trans("Disabled"); + $text.='
'; + + if ($objMod->getDescLong()) $text.=$objMod->getDesc().'
'; +} + +if ($mode == 'feature') +{ + $text.=''.$langs->trans("AddRemoveTabs").': '; + if (isset($objMod->tabs) && is_array($objMod->tabs) && count($objMod->tabs)) + { + $i=0; + foreach($objMod->tabs as $val) + { + $tmp=explode(':',$val,3); + $text.=($i?', ':'').$tmp[0].':'.$tmp[1]; + $i++; + } + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddDictionaries").': '; + if (isset($objMod->dictionaries) && isset($objMod->dictionaries['tablib']) && is_array($objMod->dictionaries['tablib']) && count($objMod->dictionaries['tablib'])) + { + $i=0; + foreach($objMod->dictionaries['tablib'] as $val) + { + $text.=($i?', ':'').$val; + $i++; + } + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddBoxes").': '; + if (isset($objMod->boxes) && is_array($objMod->boxes) && count($objMod->boxes)) + { + $i=0; + foreach($objMod->boxes as $val) + { + $text.=($i?', ':'').($val['file']?$val['file']:$val[0]); + $i++; + } + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddModels").': '; + if (isset($objMod->module_parts) && isset($objMod->module_parts['models']) && $objMod->module_parts['models']) + { + $text.=$langs->trans("Yes"); + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddSubstitutions").': '; + if (isset($objMod->module_parts) && isset($objMod->module_parts['substitutions']) && $objMod->module_parts['substitutions']) + { + $text.=$langs->trans("Yes"); + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddSheduledJobs").': '; + if (isset($objMod->cronjobs) && is_array($objMod->cronjobs) && count($objMod->cronjobs)) + { + $i=0; + foreach($objMod->cronjobs as $val) + { + $text.=($i?', ':'').($val['label']); + $i++; + } + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddTriggers").': '; + if (isset($objMod->module_parts) && isset($objMod->module_parts['triggers']) && $objMod->module_parts['triggers']) + { + $text.=$langs->trans("Yes"); + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddHooks").': '; + if (isset($objMod->module_parts) && is_array($objMod->module_parts['hooks']) && count($objMod->module_parts['hooks'])) + { + $i=0; + foreach($objMod->module_parts['hooks'] as $val) + { + $text.=($i?', ':'').($val); + $i++; + } + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddPermissions").': '; + if (isset($objMod->rights) && is_array($objMod->rights) && count($objMod->rights)) + { + $i=0; + foreach($objMod->rights as $val) + { + $text.=($i?', ':'').($val[1]); + $i++; + } + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddMenus").': '; + if (isset($objMod->menu) && ! empty($objMod->menu)) // objMod can be an array or just an int 1 + { + $text.=$langs->trans("Yes"); + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddExportProfiles").': '; + if (isset($objMod->export_label) && is_array($objMod->export_label) && count($objMod->export_label)) + { + $i=0; + foreach($objMod->export_label as $val) + { + $text.=($i?', ':'').($val); + $i++; + } + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddImportProfiles").': '; + if (isset($objMod->import_label) && is_array($objMod->import_label) && count($objMod->import_label)) + { + $i=0; + foreach($objMod->import_label as $val) + { + $text.=($i?', ':'').($val); + $i++; + } + } + else $text.=$langs->trans("No"); + + $text.='
'.$langs->trans("AddOtherPagesOrServices").': '; + $text.=$langs->trans("DetectionNotPossible"); +} + + +print $text; + + +dol_fiche_end(); + +print '
'; + + +llxFooter(); + +$db->close(); diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index ad33b4ce619..596aefa803e 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -1,7 +1,7 @@ * Copyright (C) 2003 Jean-Louis Bergamo - * Copyright (C) 2004-2016 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2011 Juanjo Menent @@ -29,12 +29,15 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; $langs->load("errors"); $langs->load("admin"); -$mode=GETPOST('mode', 'alpha')?GETPOST('mode', 'alpha'):0; +$mode=GETPOST('mode', 'alpha'); +if (empty($mode)) $mode='common'; $action=GETPOST('action','alpha'); $value=GETPOST('value', 'alpha'); $page_y=GETPOST('page_y','int'); @@ -69,13 +72,14 @@ if ($search_status) $param.='&search_status='.urlencode($search_status); if ($search_nature) $param.='&search_nature='.urlencode($search_nature); if ($search_version) $param.='&search_version='.urlencode($search_version); +$dirins=DOL_DOCUMENT_ROOT.'/custom'; +$urldolibarrmodules='https://www.dolistore.com/'; /* * Actions */ - if (GETPOST('buttonreset')) { $search_keyword=''; @@ -84,6 +88,109 @@ if (GETPOST('buttonreset')) $search_version=''; } +if ($action=='install') +{ + $error=0; + + // $original_file should match format module_modulename-x.y[.z].zip + $original_file=basename($_FILES["fileinstall"]["name"]); + $newfile=$conf->admin->dir_temp.'/'.$original_file.'/'.$original_file; + + if (! $original_file) + { + $langs->load("Error"); + setEventMessages($langs->trans("ErrorModuleFileRequired"), null, 'warnings'); + $error++; + } + else + { + if (! preg_match('/\.zip$/i',$original_file)) + { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorFileMustBeADolibarrPackage",$original_file), null, 'errors'); + $error++; + } + if (! preg_match('/module_.*\-[\d]+\.[\d]+.*$/i',$original_file)) + { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorFilenameDosNotMatchDolibarrPackageRules",$original_file, 'module_*-x.y*.zip'), null, 'errors'); + $error++; + } + } + + if (! $error) + { + if ($original_file) + { + @dol_delete_dir_recursive($conf->admin->dir_temp.'/'.$original_file); + dol_mkdir($conf->admin->dir_temp.'/'.$original_file); + } + + $tmpdir=preg_replace('/\.zip$/','',$original_file).'.dir'; + if ($tmpdir) + { + @dol_delete_dir_recursive($conf->admin->dir_temp.'/'.$tmpdir); + dol_mkdir($conf->admin->dir_temp.'/'.$tmpdir); + } + + $result=dol_move_uploaded_file($_FILES['fileinstall']['tmp_name'],$newfile,1,0,$_FILES['fileinstall']['error']); + if ($result > 0) + { + $result=dol_uncompress($newfile,$conf->admin->dir_temp.'/'.$tmpdir); + + if (! empty($result['error'])) + { + $langs->load("errors"); + setEventMessages($langs->trans($result['error'],$original_file), null, 'errors'); + $error++; + } + else + { + // Now we move the dir of the module + $modulename=preg_replace('/module_/', '', $original_file); + $modulename=preg_replace('/\-[\d]+\.[\d]+.*$/', '', $modulename); + // Search dir $modulename + $modulenamedir=$conf->admin->dir_temp.'/'.$tmpdir.'/'.$modulename; + //var_dump($modulenamedir); + if (! dol_is_dir($modulenamedir)) + { + $modulenamedir=$conf->admin->dir_temp.'/'.$tmpdir.'/htdocs/'.$modulename; + //var_dump($modulenamedir); + if (! dol_is_dir($modulenamedir)) + { + setEventMessages($langs->trans("ErrorModuleFileSeemsToHaveAWrongFormat").'
Dir not found: '.$conf->admin->dir_temp.'/'.$tmpdir.'/'.$modulename.'
'.$conf->admin->dir_temp.'/'.$tmpdir.'/htdocs/'.$modulename, null, 'errors'); + $error++; + } + } + + if (! $error) + { + //var_dump($dirins); + @dol_delete_dir_recursive($dirins.'/'.$modulename); + dol_syslog("Uncompress of module file is a success. We copy it from ".$modulenamedir." into target dir ".$dirins.'/'.$modulename); + $result=dolCopyDir($modulenamedir, $dirins.'/'.$modulename, '0444', 1); + if ($result <= 0) + { + dol_syslog('Failed to call dolCopyDir result='.$result." with param ".$modulenamedir." and ".$dirins.'/'.$modulename, LOG_WARNING); + $langs->load("errors"); + setEventMessages($langs->trans("ErrorFailToCopyDir", $modulenamedir, $dirins.'/'.$modulename), null, 'errors'); + $error++; + } + } + } + } + else + { + $error++; + } + } + + if (! $error) + { + setEventMessages($langs->trans("SetupIsReadyForUse", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentitiesnoconv("Home").' - '.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Modules")), null, 'warnings'); + } +} + if ($action == 'set' && $user->admin) { $resarray = activateModule($value); @@ -115,6 +222,13 @@ if ($action == 'reset' && $user->admin) * View */ +// Set dir where external modules are installed +if (! dol_is_dir($dirins)) +{ + dol_mkdir($dirins); +} +$dirins_ok=(dol_is_dir($dirins)); + $form = new Form($db); $help_url='EN:First_setup|FR:Premiers_paramétrages|ES:Primeras_configuraciones'; @@ -277,33 +391,35 @@ if ($nbofactivatedmodules <= 1) $moreinfo .= ' '.img_warning($langs->trans("YouM print load_fiche_titre($langs->trans("ModulesSetup"),$moreinfo,'title_setup'); // Start to show page -if (empty($mode)) $mode='common'; -if ($mode==='common') print $langs->trans("ModulesDesc")."
\n"; -if ($mode==='marketplace') print $langs->trans("ModulesMarketPlaceDesc")."
\n"; -if ($mode==='expdev') print $langs->trans("ModuleFamilyExperimental")."
\n"; +if ($mode=='common') print $langs->trans("ModulesDesc")."
\n"; +if ($mode=='marketplace') print $langs->trans("ModulesMarketPlaceDesc")."
\n"; +if ($mode=='deploy') print $langs->trans("ModulesDeployDesc", $langs->transnoentitiesnoconv("AvailableModules"))."
\n"; $h = 0; -$categidx='common'; // Main -$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=".$categidx; +$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=common"; $head[$h][1] = $langs->trans("AvailableModules"); $head[$h][2] = 'common'; $h++; -$categidx='marketplace'; -$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=".$categidx; +$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=marketplace"; $head[$h][1] = $langs->trans("ModulesMarketPlaces"); $head[$h][2] = 'marketplace'; $h++; +$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=deploy"; +$head[$h][1] = $langs->trans("AddExtensionThemeModuleOrOther"); +$head[$h][2] = 'deploy'; +$h++; + print "
\n"; $var=true; -if ($mode != 'marketplace') +if ($mode == 'common') { print '
'; @@ -313,7 +429,7 @@ if ($mode != 'marketplace') print ''; dol_fiche_head($head, $mode, ''); - + $moreforfilter = ''; $moreforfilter.='
'; $moreforfilter.= $langs->trans('Keyword') . ': '; @@ -351,10 +467,8 @@ if ($mode != 'marketplace') //print '
'; } - //dol_fiche_end(); print '

'; - //print '



'; $moreforfilter=''; @@ -440,8 +554,6 @@ if ($mode != 'marketplace') } // Print a separator if we change family - //print "xx".$oldfamily."-".$familykey."-".$atleastoneforfamily."
"; - //if ($oldfamily && $familykey!=$oldfamily && $atleastoneforfamily) { if ($familykey!=$oldfamily) { print ''."\n"; @@ -452,7 +564,6 @@ if ($mode != 'marketplace') print ''.$langs->trans("SetupShort").''."\n"; print "\n"; $atleastoneforfamily=0; - //print "yy".$oldfamily."-".$familykey."-".$atleastoneforfamily."
"; } $atleastoneforfamily++; @@ -465,7 +576,22 @@ if ($mode != 'marketplace') $var=!$var; - //print "\n\n"; + + // Version (with picto warning or not) + $version=$objMod->getVersion(0); + $versiontrans=''; + if (preg_match('/development/i', $version)) $versiontrans.=img_warning($langs->trans("Development"), 'style="float: left"'); + if (preg_match('/experimental/i', $version)) $versiontrans.=img_warning($langs->trans("Experimental"), 'style="float: left"'); + if (preg_match('/deprecated/i', $version)) $versiontrans.=img_warning($langs->trans("Deprecated"), 'style="float: left"'); + $versiontrans.=$objMod->getVersion(1); + + // Define imginfo + $imginfo="info"; + if ($objMod->isCoreOrExternalModule() == 'external') + { + $imginfo="info_black"; + } + print '\n"; // Picto @@ -495,177 +621,15 @@ if ($mode != 'marketplace') // Help print ''; - $text=''; - - if ($objMod->getDescLong()) $text.='
'.$objMod->getDesc().'

'.$objMod->getDescLong().'
'; - else $text.='
'.$objMod->getDesc().'

'; - - $textexternal=''; - $imginfo="info"; - if ($objMod->isCoreOrExternalModule() == 'external') - { - $imginfo="info_black"; - $textexternal.='
'.$langs->trans("Origin").': '.$langs->trans("ExternalModule",$dirofmodule); - if ($objMod->editor_name != 'dolibarr') $textexternal.='
'.$langs->trans("Publisher").': '.(empty($objMod->editor_name)?$langs->trans("Unknown"):$objMod->editor_name); - if (! empty($objMod->editor_url) && ! preg_match('/dolibarr\.org/i',$objMod->editor_url)) $textexternal.='
'.$langs->trans("Url").': '.$objMod->editor_url; - $text.=$textexternal; - $text.='
'; - } - else - { - $text.='
'.$langs->trans("Origin").': '.$langs->trans("Core").'
'; - } - $text.='
'.$langs->trans("LastActivationDate").': '; - if (! empty($conf->global->$const_name)) $text.=dol_print_date($objMod->getLastActivationDate(), 'dayhour'); - else $text.=$langs->trans("Disabled"); - $text.='
'; - - $text.='
'.$langs->trans("AddRemoveTabs").': '; - if (isset($objMod->tabs) && is_array($objMod->tabs) && count($objMod->tabs)) - { - $i=0; - foreach($objMod->tabs as $val) - { - $tmp=explode(':',$val,3); - $text.=($i?', ':'').$tmp[0].':'.$tmp[1]; - $i++; - } - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddDictionaries").': '; - if (isset($objMod->dictionaries) && isset($objMod->dictionaries['tablib']) && is_array($objMod->dictionaries['tablib']) && count($objMod->dictionaries['tablib'])) - { - $i=0; - foreach($objMod->dictionaries['tablib'] as $val) - { - $text.=($i?', ':'').$val; - $i++; - } - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddBoxes").': '; - if (isset($objMod->boxes) && is_array($objMod->boxes) && count($objMod->boxes)) - { - $i=0; - foreach($objMod->boxes as $val) - { - $text.=($i?', ':'').($val['file']?$val['file']:$val[0]); - $i++; - } - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddModels").': '; - if (isset($objMod->module_parts) && isset($objMod->module_parts['models']) && $objMod->module_parts['models']) - { - $text.=$langs->trans("Yes"); - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddSubstitutions").': '; - if (isset($objMod->module_parts) && isset($objMod->module_parts['substitutions']) && $objMod->module_parts['substitutions']) - { - $text.=$langs->trans("Yes"); - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddSheduledJobs").': '; - if (isset($objMod->cronjobs) && is_array($objMod->cronjobs) && count($objMod->cronjobs)) - { - $i=0; - foreach($objMod->cronjobs as $val) - { - $text.=($i?', ':'').($val['label']); - $i++; - } - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddTriggers").': '; - if (isset($objMod->module_parts) && isset($objMod->module_parts['triggers']) && $objMod->module_parts['triggers']) - { - $text.=$langs->trans("Yes"); - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddHooks").': '; - if (isset($objMod->module_parts) && is_array($objMod->module_parts['hooks']) && count($objMod->module_parts['hooks'])) - { - $i=0; - foreach($objMod->module_parts['hooks'] as $val) - { - $text.=($i?', ':'').($val); - $i++; - } - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddPermissions").': '; - if (isset($objMod->rights) && is_array($objMod->rights) && count($objMod->rights)) - { - $i=0; - foreach($objMod->rights as $val) - { - $text.=($i?', ':'').($val[1]); - $i++; - } - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddMenus").': '; - if (isset($objMod->menu) && ! empty($objMod->menu)) // objMod can be an array or just an int 1 - { - $text.=$langs->trans("Yes"); - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddExportProfiles").': '; - if (isset($objMod->export_label) && is_array($objMod->export_label) && count($objMod->export_label)) - { - $i=0; - foreach($objMod->export_label as $val) - { - $text.=($i?', ':'').($val); - $i++; - } - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddImportProfiles").': '; - if (isset($objMod->import_label) && is_array($objMod->import_label) && count($objMod->import_label)) - { - $i=0; - foreach($objMod->import_label as $val) - { - $text.=($i?', ':'').($val); - $i++; - } - } - else $text.=$langs->trans("No"); - - $text.='
'.$langs->trans("AddOtherPagesOrServices").': '; - $text.=$langs->trans("DetectionNotPossible"); - - - print $form->textwithpicto('', $text, 1, $imginfo, 'minheight20'); - + + //print $form->textwithpicto('', $text, 1, $imginfo, 'minheight20', 0, 2, 1); + print ''.img_picto($langs->trans("ClickToShowDescription"), $imginfo).''; + print ''; // Version print ''; - - // Picto warning - $version=$objMod->getVersion(0); - $versiontrans=$objMod->getVersion(1); - if (preg_match('/development/i', $version)) print img_warning($langs->trans("Development"), 'style="float: left"'); - if (preg_match('/experimental/i', $version)) print img_warning($langs->trans("Experimental"), 'style="float: left"'); - if (preg_match('/deprecated/i', $version)) print img_warning($langs->trans("Deprecated"), 'style="float: left"'); - - print $versiontrans; - print "\n"; // Activate/Disable and Setup (2 columns) @@ -762,8 +726,11 @@ if ($mode != 'marketplace') } print "\n"; print ''; + + dol_fiche_end(); } -else + +if ($mode == 'marketplace') { dol_fiche_head($head, $mode, ''); @@ -793,13 +760,115 @@ else print "\n"; - //dol_fiche_end(); + dol_fiche_end(); +} + + +// Install external module + +if ($mode == 'deploy') +{ + dol_fiche_head($head, $mode, ''); + + + $allowonlineinstall=true; + $allowfromweb=1; + if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) $allowonlineinstall=false; + + $fullurl=''.$urldolibarrmodules.''; + $message=''; + if (! empty($allowonlineinstall)) + { + if (! in_array('/custom',explode(',',$dolibarr_main_url_root_alt))) + { + $message=info_admin($langs->trans("ConfFileMuseContainCustom", DOL_DOCUMENT_ROOT.'/custom', DOL_DOCUMENT_ROOT)); + $allowfromweb=-1; + } + else + { + if ($dirins_ok) + { + if (! is_writable(dol_osencode($dirins))) + { + $langs->load("errors"); + $message=info_admin($langs->trans("ErrorFailedToWriteInDir",$dirins)); + $allowfromweb=0; + } + } + else + { + + $message=info_admin($langs->trans("NotExistsDirect",$dirins).$langs->trans("InfDirAlt").$langs->trans("InfDirExample")); + $allowfromweb=0; + } + } + } + else + { + $message=info_admin($langs->trans("InstallModuleFromWebHasBeenDisabledByFile",$dolibarrdataroot.'/installmodules.lock')); + $allowfromweb=0; + } + + if ($allowfromweb < 1) + { + print $langs->trans("SomethingMakeInstallFromWebNotPossible"); + print $message; + //print $langs->trans("SomethingMakeInstallFromWebNotPossible2"); + print '
'; + } + + + if ($allowfromweb >= 0) + { + if ($allowfromweb == 1) + { + //print $langs->trans("ThisIsProcessToFollow").'
'; + } + else + { + print $langs->trans("ThisIsAlternativeProcessToFollow").'
'; + print ''.$langs->trans("StepNb",1).': '; + print $langs->trans("FindPackageFromWebSite",$fullurl).'
'; + print ''.$langs->trans("StepNb",2).': '; + print $langs->trans("DownloadPackageFromWebSite",$fullurl).'
'; + print ''.$langs->trans("StepNb",3).': '; + } + + if ($allowfromweb == 1) + { + print $langs->trans("UnpackPackageInModulesRoot",$dirins).'
'; + print ''; + print ''; + print ''; + print $langs->trans("YouCanSubmitFile").' '; + print ''; + print '
'; + } + else + { + print $langs->trans("UnpackPackageInModulesRoot",$dirins).'
'; + print ''.$langs->trans("StepNb",4).': '; + print $langs->trans("SetupIsReadyForUse").'
'; + } + } + + + if (! empty($result['return'])) + { + print '
'; + + foreach($result['return'] as $value) + { + echo $value.'
'; + } + } + + dol_fiche_end(); } -dol_fiche_end(); // Show warning about external users -if ($mode != 'marketplace') print info_admin(showModulesExludedForExternal($modules))."\n"; +if ($mode == 'common') print info_admin(showModulesExludedForExternal($modules))."\n"; llxFooter(); diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php index 57c5560a185..c6ccb4f639c 100644 --- a/htdocs/admin/propal.php +++ b/htdocs/admin/propal.php @@ -577,7 +577,7 @@ print '
'; print ''; print ''; print ''; -print $langs->trans("FreeLegalTextOnProposal").' ('.$langs->trans("AddCRIfTooLong").')
'; +print $langs->trans("FreeLegalTextOnProposal").' '.img_info($langs->trans("AddCRIfTooLong")).'
'; $variablename='PROPOSAL_FREE_TEXT'; if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { @@ -598,8 +598,8 @@ $var=!$var; print ""; print ''; print ""; -print ''; -print $langs->trans("WatermarkOnDraftProposal").'
'; +print ''; +print $langs->trans("WatermarkOnDraftProposal").''; print ''; print ''; print ''; diff --git a/htdocs/admin/supplier_invoice.php b/htdocs/admin/supplier_invoice.php index 540cd4a4b98..7510bfe37ef 100644 --- a/htdocs/admin/supplier_invoice.php +++ b/htdocs/admin/supplier_invoice.php @@ -472,7 +472,7 @@ print ' '; print "\n"; print ''; -print $langs->trans("FreeLegalTextOnInvoices").' ('.$langs->trans("AddCRIfTooLong").')
'; +print $langs->trans("FreeLegalTextOnInvoices").' '.img_info($langs->trans("AddCRIfTooLong")).'
'; $variablename='SUPPLIER_INVOICE_FREE_TEXT'; if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php index 5c288b9e78a..1ac6ae86989 100644 --- a/htdocs/admin/supplier_order.php +++ b/htdocs/admin/supplier_order.php @@ -537,7 +537,7 @@ else */ print ''; -print $langs->trans("FreeLegalTextOnOrders").' ('.$langs->trans("AddCRIfTooLong").')
'; +print $langs->trans("FreeLegalTextOnOrders").' '.img_info($langs->trans("AddCRIfTooLong")).'
'; $variablename='SUPPLIER_ORDER_FREE_TEXT'; if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php index 069c90ead8a..7963aa7fabc 100644 --- a/htdocs/admin/supplier_proposal.php +++ b/htdocs/admin/supplier_proposal.php @@ -528,7 +528,7 @@ print ''; print ''; print ''; print ''; -print $langs->trans("FreeLegalTextOnSupplierProposal").' ('.$langs->trans("AddCRIfTooLong").')
'; +print $langs->trans("FreeLegalTextOnSupplierProposal").' '.img_info($langs->trans("AddCRIfTooLong")).'
'; $variablename='SUPPLIER_PROPOSAL_FREE_TEXT'; if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { @@ -549,8 +549,8 @@ $var=!$var; print ""; print ''; print ""; -print ''; -print $langs->trans("WatermarkOnDraftSupplierProposal").'
'; +print ''; +print $langs->trans("WatermarkOnDraftSupplierProposal").''; print ''; print ''; print ''; diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php index c0ff5d75819..498e1ec54f0 100644 --- a/htdocs/admin/system/filecheck.php +++ b/htdocs/admin/system/filecheck.php @@ -73,11 +73,15 @@ print '
'; // Modified or missing files $file_list = array('missing' => array(), 'updated' => array()); -// File to analyze -//$xmlfile = DOL_DOCUMENT_ROOT.'/install/filelist-'.DOL_VERSION.'.xml'; +// Local file to compare to $xmlshortfile = GETPOST('xmlshortfile')?GETPOST('xmlshortfile'):'/install/filelist-'.DOL_VERSION.'.xml'; $xmlfile = DOL_DOCUMENT_ROOT.$xmlshortfile; -$xmlremote = GETPOST('xmlremote')?GETPOST('xmlremote'):'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml'; +// Remote file to compare to +$xmlremote = GETPOST('xmlremote'); +if (empty($xmlremote) && ! empty($conf->global->MAIN_FILECHECK_URL)) $xmlremote = $conf->global->MAIN_FILECHECK_URL; +$param='MAIN_FILECHECK_URL_'.DOL_VERSION; +if (empty($xmlremote) && ! empty($conf->global->$param)) $xmlremote = $conf->global->$param; +if (empty($xmlremote)) $xmlremote = 'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml'; // Test if remote test is ok @@ -90,19 +94,22 @@ print $langs->trans("MakeIntegrityAnalysisFrom").':
'; print ''."\n"; if (dol_is_file($xmlfile)) { - print ' '.$langs->trans("LocalSignature").' = '.$xmlshortfile.'
'; + print ' '.$langs->trans("LocalSignature").' = '; + print ''; + print '
'; } else { - print ' '.$langs->trans("LocalSignature").' = '.$xmlshortfile; - if (! GETPOST('xmlshortfile')) print ' ('.$langs->trans("AvailableOnlyOnPackagedVersions").')'; + print ' '.$langs->trans("LocalSignature").' = '; + print ''; + print ' ('.$langs->trans("AvailableOnlyOnPackagedVersions").')'; print '
'; } print ''."\n"; if ($enableremotecheck) { print ' '.$langs->trans("RemoteSignature").' = '; - print '
'; + print '
'; } else { @@ -150,21 +157,88 @@ if (GETPOST('target') == 'remote') if ($xml) { $checksumconcat = array(); + $file_list = array(); + $out = ''; + + // Forced constants + if (is_object($xml->dolibarr_constants[0])) + { + $out.=load_fiche_titre($langs->trans("ForcedConstants")); + + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''."\n"; + $var = true; + $i = 0; + foreach ($xml->dolibarr_constants[0]->constant as $constant) // $constant is a simpleXMLElement + { + $constname=$constant['name']; + $constvalue=(string) $constant; + $constvalue = (empty($constvalue)?'0':$constvalue); + // Value found + $value=''; + if ($constname && $conf->global->$constname != '') $value=$conf->global->$constname; + $valueforchecksum=(empty($value)?'0':$value); + + $checksumconcat[]=$valueforchecksum; + + $i++; + $var = !$var; + $out.=''; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.="\n"; + } + + if ($i==0) + { + $out.=''; + } + $out.='
#' . $langs->trans("Constant") . '' . $langs->trans("ExpectedValue") . '' . $langs->trans("Value") . '
'.$i.''.$constname.''.$constvalue.''.$valueforchecksum.'
'.$langs->trans("None").'
'; + + $out.='
'; + } + // Scan htdocs if (is_object($xml->dolibarr_htdocs_dir[0])) { - $file_list = array(); - $ret = getFilesUpdated($file_list, $xml->dolibarr_htdocs_dir[0], '', DOL_DOCUMENT_ROOT, $checksumconcat); // Fill array $file_list - - print_fiche_titre($langs->trans("FilesMissing")); + //var_dump($xml->dolibarr_htdocs_dir[0]['includecustom']);exit; + $includecustom=(empty($xml->dolibarr_htdocs_dir[0]['includecustom'])?0:$xml->dolibarr_htdocs_dir[0]['includecustom']); + + // Defined qualified files (must be same than into generate_filelist_xml.php) + $regextoinclude='\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$'; + $regextoexclude='('.($includecustom?'':'custom|').'documents|conf|install)$'; // Exclude dirs + $scanfiles = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude); + + // Fill file_list with files in signature, new files, modified files + $ret = getFilesUpdated($file_list, $xml->dolibarr_htdocs_dir[0], '', DOL_DOCUMENT_ROOT, $checksumconcat, $scanfiles); // Fill array $file_list + // Complete with list of new files + foreach ($scanfiles as $keyfile => $valfile) + { + $tmprelativefilename=preg_replace('/^'.preg_quote(DOL_DOCUMENT_ROOT,'/').'/','', $valfile['fullname']); + if (! in_array($tmprelativefilename, $file_list['insignature'])) + { + $md5newfile=@md5_file($valfile['fullname']); // Can fails if we don't have permission to open/read file + $file_list['added'][]=array('filename'=>$tmprelativefilename, 'md5'=>$md5newfile); + } + } - print ''; - print ''; - print ''; - print ''; - print ''; - print ''."\n"; + // Files missings + $out.=load_fiche_titre($langs->trans("FilesMissing")); + + $out.='
#' . $langs->trans("Filename") . '' . $langs->trans("ExpectedChecksum") . '
'; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''."\n"; $var = true; $tmpfilelist = dol_sort_array($file_list['missing'], 'filename'); if (is_array($tmpfilelist) && count($tmpfilelist)) @@ -174,32 +248,34 @@ if ($xml) { $i++; $var = !$var; - print ''; - print '' . "\n"; - print '' . "\n"; - print '' . "\n"; - print "\n"; + $out.=''; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.="\n"; } } else { - print ''; + $out.=''; } - print '
#' . $langs->trans("Filename") . '' . $langs->trans("ExpectedChecksum") . '
'.$i.''.$file['filename'].''.$file['expectedmd5'].'
'.$i.''.$file['filename'].''.$file['expectedmd5'].'
'.$langs->trans("None").'
'.$langs->trans("None").'
'; + $out.=''; - print '
'; + $out.='
'; - print_fiche_titre($langs->trans("FilesUpdated")); + // Files modified + $out.=load_fiche_titre($langs->trans("FilesModified")); - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''."\n"; + $totalsize=0; + $out.='
#' . $langs->trans("Filename") . '' . $langs->trans("ExpectedChecksum") . '' . $langs->trans("CurrentChecksum") . '' . $langs->trans("Size") . '' . $langs->trans("DateModification") . '
'; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''."\n"; $var = true; $tmpfilelist2 = dol_sort_array($file_list['updated'], 'filename'); if (is_array($tmpfilelist2) && count($tmpfilelist2)) @@ -209,30 +285,92 @@ if ($xml) { $i++; $var = !$var; - print ''; - print '' . "\n"; - print '' . "\n"; - print '' . "\n"; - print '' . "\n"; - print '' . "\n"; - print '' . "\n"; - print "\n"; + $out.=''; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']); + $totalsize += $size; + $out.='' . "\n"; + $out.='' . "\n"; + $out.="\n"; } + $out.=''; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.="\n"; } else { - print ''; + $out.=''; } - print '
#' . $langs->trans("Filename") . '' . $langs->trans("ExpectedChecksum") . '' . $langs->trans("CurrentChecksum") . '' . $langs->trans("Size") . '' . $langs->trans("DateModification") . '
'.$i.''.$file['filename'].''.$file['expectedmd5'].''.$file['md5'].''.dol_print_size(dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename'])).''.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']),'dayhour').'
'.$i.''.$file['filename'].''.$file['expectedmd5'].''.$file['md5'].''.dol_print_size($size).''.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']),'dayhour').'
'.$langs->trans("Total").''.dol_print_size($totalsize).'
'.$langs->trans("None").'
'.$langs->trans("None").'
'; + $out.=''; - if (empty($tmpfilelist) && empty($tmpfilelist2)) + $out.='
'; + + // Files added + $out.=load_fiche_titre($langs->trans("FilesAdded")); + + $totalsize = 0; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''; + $out.=''."\n"; + $var = true; + $tmpfilelist3 = dol_sort_array($file_list['added'], 'filename'); + if (is_array($tmpfilelist3) && count($tmpfilelist3)) + { + $i = 0; + foreach ($tmpfilelist3 as $file) + { + $i++; + $var = !$var; + $out.=''; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']); + $totalsize += $size; + $out.='' . "\n"; + $out.='' . "\n"; + $out.="\n"; + } + $out.=''; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.='' . "\n"; + $out.="\n"; + } + else + { + $out.=''; + } + $out.='
#' . $langs->trans("Filename") . '' . $langs->trans("ExpectedChecksum") . '' . $langs->trans("CurrentChecksum") . '' . $langs->trans("Size") . '' . $langs->trans("DateModification") . '
'.$i.''.$file['filename'].''.$file['expectedmd5'].''.$file['md5'].''.dol_print_size($size).''.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']),'dayhour').'
'.$langs->trans("Total").''.dol_print_size($totalsize).'
'.$langs->trans("None").'
'; + + + // Show warning + if (empty($tmpfilelist) && empty($tmpfilelist2) && empty($tmpfilelist3)) { setEventMessage($langs->trans("FileIntegrityIsStrictlyConformedWithReference")); } else { setEventMessage($langs->trans("FileIntegritySomeFilesWereRemovedOrModified"), 'warnings'); - } + } } else { @@ -253,13 +391,30 @@ if ($xml) asort($checksumconcat); // Sort list of checksum //var_dump($checksumconcat); $checksumget = md5(join(',',$checksumconcat)); - $checksumtoget = $xml->dolibarr_htdocs_dir_checksum; - - print '
'; + $checksumtoget = trim((string) $xml->dolibarr_htdocs_dir_checksum); + /*var_dump(count($file_list['added'])); + var_dump($checksumget); + var_dump($checksumtoget); + var_dump($checksumget == $checksumtoget);*/ print_fiche_titre($langs->trans("GlobalChecksum")).'
'; print $langs->trans("ExpectedChecksum").' = '. ($checksumtoget ? $checksumtoget : $langs->trans("Unknown")) .'
'; - print $langs->trans("CurrentChecksum").' = '.$checksumget; + print $langs->trans("CurrentChecksum").' = '; + if ($checksumget == $checksumtoget) + { + if (count($file_list['added'])) print $checksumget.' - '.$langs->trans("FileIntegrityIsOkButFilesWereAdded").''; + else print ''.$checksumget.''; + } + else + { + print ''.$checksumget.''; + } + + print '
'; + print '
'; + + // Output detail + print $out; } @@ -287,10 +442,11 @@ function getFilesUpdated(&$file_list, SimpleXMLElement $dir, $path = '', $pathre { $exclude = 'install'; - foreach ($dir->md5file as $file) + foreach ($dir->md5file as $file) // $file is a simpleXMLElement { $filename = $path.$file['name']; - + $file_list['insignature'][] = $filename; + //if (preg_match('#'.$exclude.'#', $filename)) continue; if (!file_exists($pathref.'/'.$filename)) @@ -309,3 +465,4 @@ function getFilesUpdated(&$file_list, SimpleXMLElement $dir, $path = '', $pathre return $file_list; } + diff --git a/htdocs/admin/tools/update.php b/htdocs/admin/tools/update.php index 5cebb1dac4e..d8b17ab989b 100644 --- a/htdocs/admin/tools/update.php +++ b/htdocs/admin/tools/update.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2007-2017 Laurent Destailleur * Copyright (C) 2009-2012 Regis Houssin * Copyright (C) 2012 Juanjo Menent * @@ -23,9 +23,9 @@ */ require '../../main.inc.php'; -include_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php'; -include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; -include_once DOL_DOCUMENT_ROOT . '/core/lib/geturl.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/geturl.lib.php'; $langs->load("admin"); $langs->load("other"); @@ -40,111 +40,23 @@ if (GETPOST('msg','alpha')) { $urldolibarr='https://www.dolibarr.org/downloads/'; -$urldolibarrmodules='https://www.dolistore.com/'; -$urldolibarrthemes='https://www.dolistore.com/'; $dolibarrroot=preg_replace('/([\\/]+)$/i','',DOL_DOCUMENT_ROOT); $dolibarrroot=preg_replace('/([^\\/]+)$/i','',$dolibarrroot); $dolibarrdataroot=preg_replace('/([\\/]+)$/i','',DOL_DATA_ROOT); -$dirins=DOL_DOCUMENT_ROOT.'/custom'; +$sfurl = ''; +$version='0.0'; /* * Actions */ -if ($action=='install') +if ($action == 'getlastversion') { - $error=0; - - // $original_file should match format module_modulename-x.y[.z].zip - $original_file=basename($_FILES["fileinstall"]["name"]); - $newfile=$conf->admin->dir_temp.'/'.$original_file.'/'.$original_file; - - if (! $original_file) - { - $langs->load("Error"); - setEventMessages($langs->trans("ErrorFileRequired"), null, 'warnings'); - $error++; - } - else - { - if (! preg_match('/\.zip/i',$original_file)) - { - $langs->load("errors"); - setEventMessages($langs->trans("ErrorFileMustBeADolibarrPackage",$original_file), null, 'errors'); - $error++; - } - } - - if (! $error) - { - if ($original_file) - { - @dol_delete_dir_recursive($conf->admin->dir_temp.'/'.$original_file); - dol_mkdir($conf->admin->dir_temp.'/'.$original_file); - } - - $tmpdir=preg_replace('/\.zip$/','',$original_file).'.dir'; - if ($tmpdir) - { - @dol_delete_dir_recursive($conf->admin->dir_temp.'/'.$tmpdir); - dol_mkdir($conf->admin->dir_temp.'/'.$tmpdir); - } - - $result=dol_move_uploaded_file($_FILES['fileinstall']['tmp_name'],$newfile,1,0,$_FILES['fileinstall']['error']); - if ($result > 0) - { - $result=dol_uncompress($newfile,$conf->admin->dir_temp.'/'.$tmpdir); - - if (! empty($result['error'])) - { - $langs->load("errors"); - setEventMessages($langs->trans($result['error'],$original_file), null, 'errors'); - $error++; - } - else - { - // Now we move the dir of the module - $modulename=preg_replace('/module_/', '', $original_file); - $modulename=preg_replace('/\-[\d]+\.[\d]+.*$/', '', $modulename); - // Search dir $modulename - $modulenamedir=$conf->admin->dir_temp.'/'.$tmpdir.'/'.$modulename; - //var_dump($modulenamedir); - if (! dol_is_dir($modulenamedir)) - { - $modulenamedir=$conf->admin->dir_temp.'/'.$tmpdir.'/htdocs/'.$modulename; - //var_dump($modulenamedir); - if (! dol_is_dir($modulenamedir)) - { - setEventMessages($langs->trans("ErrorModuleFileSeemsToHaveAWrongFormat"), null, 'errors'); - $error++; - } - } - - if (! $error) - { - //var_dump($dirins); - @dol_delete_dir_recursive($dirins.'/'.$modulename); - $result=dolCopyDir($modulenamedir, $dirins.'/'.$modulename, '0444', 1); - if ($result <= 0) - { - setEventMessages($langs->trans("ErrorFailedToCopy"), null, 'errors'); - $error++; - } - } - } - } - else - { - $error++; - } - } - - if (! $error) - { - setEventMessages($langs->trans("SetupIsReadyForUse"), null, 'mesgs'); - } + $result = getURLContent('http://sourceforge.net/projects/dolibarr/rss'); + //var_dump($result['content']); + $sfurl = simplexml_load_string($result['content']); } @@ -152,15 +64,6 @@ if ($action=='install') * View */ - - -// Set dir where external modules are installed -if (! dol_is_dir($dirins)) -{ - dol_mkdir($dirins); -} -$dirins_ok=(dol_is_dir($dirins)); - $wikihelp='EN:Installation_-_Upgrade|FR:Installation_-_Mise_à_jour|ES:Instalación_-_Actualización'; llxHeader('',$langs->trans("Upgrade"),$wikihelp); @@ -170,36 +73,42 @@ print $langs->trans("CurrentVersion").' : '.DOL_VERSION.'
'; if (function_exists('curl_init')) { - $result = getURLContent('http://sourceforge.net/projects/dolibarr/rss'); - //var_dump($result['content']); - $sfurl = simplexml_load_string($result['content']); - if ($sfurl) + $conf->global->MAIN_USE_RESPONSE_TIMEOUT = 10; + + if ($action == 'getlastversion') { - $i=0; - $version='0.0'; - while (! empty($sfurl->channel[0]->item[$i]->title) && $i < 10000) + if ($sfurl) { - $title=$sfurl->channel[0]->item[$i]->title; - if (preg_match('/([0-9]+\.([0-9\.]+))/', $title, $reg)) + $i=0; + while (! empty($sfurl->channel[0]->item[$i]->title) && $i < 10000) { - $newversion=$reg[1]; - $newversionarray=explode('.',$newversion); - $versionarray=explode('.',$version); - //var_dump($newversionarray);var_dump($versionarray); - if (versioncompare($newversionarray, $versionarray) > 0) $version=$newversion; + $title=$sfurl->channel[0]->item[$i]->title; + if (preg_match('/([0-9]+\.([0-9\.]+))/', $title, $reg)) + { + $newversion=$reg[1]; + $newversionarray=explode('.',$newversion); + $versionarray=explode('.',$version); + //var_dump($newversionarray);var_dump($versionarray); + if (versioncompare($newversionarray, $versionarray) > 0) $version=$newversion; + } + $i++; } - $i++; + + // Show version + print $langs->trans("LastStableVersion").' : '. (($version != '0.0')?$version:$langs->trans("Unknown")) .'
'; + } + else + { + print $langs->trans("LastStableVersion").' : ' .$langs->trans("UpdateServerOffline").'
'; } - - // Show version - print $langs->trans("LastStableVersion").' : '. (($version != '0.0')?$version:$langs->trans("Unknown")) .'
'; } else { - print $langs->trans("LastStableVersion").' : ' .$langs->trans("UpdateServerOffline").'
'; + print $langs->trans("LastStableVersion").' : ' .$langs->trans("Check").'
'; } } +print '
'; print '
'; // Upgrade @@ -223,100 +132,15 @@ print '
'; print '
'; -// Install external module - -$allowonlineinstall=true; -$allowfromweb=1; -if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) $allowonlineinstall=false; - -$fullurl=''.$urldolibarrmodules.''; -$message=''; -if (! empty($allowonlineinstall)) -{ - if (! in_array('/custom',explode(',',$dolibarr_main_url_root_alt))) - { - $message=info_admin($langs->trans("ConfFileMuseContainCustom", DOL_DOCUMENT_ROOT.'/custom', DOL_DOCUMENT_ROOT)); - $allowfromweb=-1; - } - else - { - if ($dirins_ok) - { - if (! is_writable(dol_osencode($dirins))) - { - $langs->load("errors"); - $message=info_admin($langs->trans("ErrorFailedToWriteInDir",$dirins)); - $allowfromweb=0; - } - } - else - { - - $message=info_admin($langs->trans("NotExistsDirect",$dirins).$langs->trans("InfDirAlt").$langs->trans("InfDirExample")); - $allowfromweb=0; - } - } -} -else -{ - $message=info_admin($langs->trans("InstallModuleFromWebHasBeenDisabledByFile",$dolibarrdataroot.'/installmodules.lock')); - $allowfromweb=0; -} - - print $langs->trans("AddExtensionThemeModuleOrOther").'
'; print '
'; -if ($allowfromweb < 1) -{ - print $langs->trans("SomethingMakeInstallFromWebNotPossible"); - print $message; - //print $langs->trans("SomethingMakeInstallFromWebNotPossible2"); - print '
'; -} +print $langs->trans("GoModuleSetupArea", DOL_URL_ROOT.'/admin/modules.php?mode=deploy', $langs->transnoentities("Home").' - '.$langs->transnoentities("Setup").' - '.$langs->transnoentities("Modules")); -if ($allowfromweb >= 0) -{ - if ($allowfromweb == 1) print $langs->trans("ThisIsProcessToFollow").'
'; - else print $langs->trans("ThisIsAlternativeProcessToFollow").'
'; - print ''.$langs->trans("StepNb",1).': '; - print $langs->trans("FindPackageFromWebSite",$fullurl).'
'; - print ''.$langs->trans("StepNb",2).': '; - print $langs->trans("DownloadPackageFromWebSite",$fullurl).'
'; - print ''.$langs->trans("StepNb",3).': '; - - if ($allowfromweb == 1) - { - print $langs->trans("UnpackPackageInDolibarrRoot",$dirins).'
'; - print ''; - print ''; - print $langs->trans("YouCanSubmitFile").' '; - print ''; - print ''; - } - else - { - print $langs->trans("UnpackPackageInDolibarrRoot",$dirins).'
'; - print ''.$langs->trans("StepNb",4).': '; - print $langs->trans("SetupIsReadyForUse").'
'; - } -} - - -if (! empty($result['return'])) -{ - print '
'; - - foreach($result['return'] as $value) - { - echo $value.'
'; - } -} - llxFooter(); $db->close(); diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 5ffae225df1..1204fded0aa 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -170,7 +170,7 @@ class DolibarrApi * @throws RestException */ static function _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid') { - + // Features/modules to check $featuresarray = array($resource); if (preg_match('/&/', $resource)) { @@ -185,7 +185,7 @@ class DolibarrApi $feature2 = explode("|", $feature2); } - return checkUserAccessToObject(DolibarrApiAccess::$user, $featuresarray,$resource_id,$dbtablename,$feature2,$dbt_keyfield,$dbt_select); + return checkUserAccessToObject(DolibarrApiAccess::$user, $featuresarray, $resource_id, $dbtablename, $feature2, $dbt_keyfield, $dbt_select); } /** diff --git a/htdocs/cashdesk/class/Auth.class.php b/htdocs/cashdesk/class/Auth.class.php index 33bbd094050..5e431514d1c 100644 --- a/htdocs/cashdesk/class/Auth.class.php +++ b/htdocs/cashdesk/class/Auth.class.php @@ -22,14 +22,14 @@ */ class Auth { - var $db; + protected $db; - var $login; - var $passwd; + private $login; + private $passwd; - var $reponse; + private $reponse; - var $sqlQuery; + public $sqlQuery; /** * Enter description here ... @@ -37,7 +37,7 @@ class Auth * @param DoliDB $db Database handler * @return void */ - function __construct($db) + public function __construct($db) { $this->db = $db; $this->reponse(null); @@ -49,7 +49,7 @@ class Auth * @param string $aLogin Login * @return void */ - function login($aLogin) + public function login($aLogin) { $this->login = $aLogin; } @@ -71,7 +71,7 @@ class Auth * @param string $aReponse Response * @return void */ - function reponse($aReponse) + public function reponse($aReponse) { $this->reponse = $aReponse; } @@ -83,7 +83,7 @@ class Auth * @param string $aPasswd Password * @return int 0 or 1 */ - function verif($aLogin, $aPasswd) + public function verif($aLogin, $aPasswd) { global $conf,$langs; global $dolibarr_main_authentication,$dolibarr_auto_user; diff --git a/htdocs/cashdesk/tpl/validation2.tpl.php b/htdocs/cashdesk/tpl/validation2.tpl.php index 844522f55e0..8f24e2069aa 100644 --- a/htdocs/cashdesk/tpl/validation2.tpl.php +++ b/htdocs/cashdesk/tpl/validation2.tpl.php @@ -29,15 +29,15 @@ $langs->load("bills"); diff --git a/htdocs/cashdesk/validation_verif.php b/htdocs/cashdesk/validation_verif.php index 5775a3c9388..3328fa52886 100644 --- a/htdocs/cashdesk/validation_verif.php +++ b/htdocs/cashdesk/validation_verif.php @@ -57,14 +57,29 @@ switch ($action) $invoice->date=dol_now(); $invoice->type= Facture::TYPE_STANDARD; - // TODO // To use a specific numbering module for POS, reset $conf->global->FACTURE_ADDON and other vars here - // and restore after values just after + // and restore values just after + $sav_FACTURE_ADDON=''; + if (! empty($conf->global->POS_ADDON)) + { + $sav_FACTURE_ADDON = $conf->global->FACTURE_ADDON; + $conf->global->FACTURE_ADDON = $conf->global->POS_ADDON; + + // To force prefix only for POS with terre module + if (! empty($conf->global->POS_NUMBERING_TERRE_FORCE_PREFIX)) $conf->global->INVOICE_NUMBERING_TERRE_FORCE_PREFIX = $conf->global->POS_NUMBERING_TERRE_FORCE_PREFIX; + // To force prefix only for POS with mars module + if (! empty($conf->global->POS_NUMBERING_MARS_FORCE_PREFIX)) $conf->global->INVOICE_NUMBERING_MARS_FORCE_PREFIX = $conf->global->POS_NUMBERING_MARS_FORCE_PREFIX; + // To force rule only for POS with mercure + //... + } $num=$invoice->getNextNumRef($company); - // TODO Restore save values - + // Restore save values + if (! empty($sav_FACTURE_ADDON)) + { + $conf->global->FACTURE_ADDON = $sav_FACTURE_ADDON; + } $obj_facturation->numInvoice($num); diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index aeaf19f8471..b7f2a002105 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -602,6 +602,29 @@ if (empty($reshook)) } } + // Action confirmation validation + if ($action == 'confirm_settodraft' && $confirm == 'yes') + { + if ($object->id > 0) + { + $result = $object->setStatut(0); + if ($result > 0) + { + //setEventMessages($langs->trans("MailingSuccessfullyValidated"), null, 'mesgs'); + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + else + { + dol_print_error($db); + } + } + // Resend if ($action == 'confirm_reset' && $confirm == 'yes') { @@ -707,7 +730,7 @@ if ($action == 'create') print '
'; // Editeur wysiwyg require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('body',$_POST['body'],'',320,'dolibarr_mailings','',true,true,$conf->global->FCKEDITOR_ENABLE_MAILING,20,'90%'); + $doleditor=new DolEditor('body',$_POST['body'],'',600,'dolibarr_mailings','',true,true,$conf->global->FCKEDITOR_ENABLE_MAILING,20,'90%'); $doleditor->Create(); print '
'; @@ -727,7 +750,12 @@ else dol_fiche_head($head, 'card', $langs->trans("Mailing"), 0, 'email'); - // Confirmation de la validation du mailing + // Confirmation back to draft + if ($action == 'settodraft') + { + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("SetToDraft"),$langs->trans("ConfirmUnvalidateEmailing"),"confirm_settodraft",'','',1); + } + // Confirmation validation of mailing if ($action == 'valid') { print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("ValidMailing"),$langs->trans("ConfirmValidMailing"),"confirm_valid",'','',1); @@ -900,10 +928,15 @@ else * Boutons d'action */ - if (GETPOST("cancel") || $confirm=='no' || $action == '' || in_array($action,array('valid','delete','sendall','clone'))) + if (GETPOST("cancel") || $confirm=='no' || $action == '' || in_array($action,array('settodraft', 'valid','delete','sendall','clone'))) { print "\n\n
\n"; + if (($object->statut == 1) && ($user->rights->mailing->valider || $object->fk_user_valid == $user->id)) + { + print ''.$langs->trans("SetToDraft").''; + } + if (($object->statut == 0 || $object->statut == 1) && $user->rights->mailing->creer) { print ''.$langs->trans("EditMailing").''; @@ -1065,7 +1098,7 @@ else $readonly=1; // Editeur wysiwyg require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('body',$object->body,'',320,'dolibarr_mailings','',false,true,empty($conf->global->FCKEDITOR_ENABLE_MAILING)?0:1,20,120,$readonly); + $doleditor=new DolEditor('body',$object->body,'',600,'dolibarr_mailings','',false,true,empty($conf->global->FCKEDITOR_ENABLE_MAILING)?0:1,20,120,$readonly); $doleditor->Create(); } else print dol_htmlentitiesbr($object->body); @@ -1212,7 +1245,7 @@ else print '
'; // Editeur wysiwyg require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('body',$object->body,'',320,'dolibarr_mailings','',true,true,$conf->global->FCKEDITOR_ENABLE_MAILING,20,'90%'); + $doleditor=new DolEditor('body',$object->body,'',600,'dolibarr_mailings','',true,true,$conf->global->FCKEDITOR_ENABLE_MAILING,20,'90%'); $doleditor->Create(); print '
'; diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index e104db4dcda..470ee2a4ec1 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -533,7 +533,7 @@ if ($object->fetch($id) >= 0) print ''; if (empty($obj->source_id) || empty($obj->source_type)) { - print $obj->source_url; // For backward compatibility + print empty($obj->source_url)?'':$obj->source_url; // For backward compatibility } else { diff --git a/htdocs/comm/mailing/class/mailing.class.php b/htdocs/comm/mailing/class/mailing.class.php index dc39c2e9399..b0dff81332c 100644 --- a/htdocs/comm/mailing/class/mailing.class.php +++ b/htdocs/comm/mailing/class/mailing.class.php @@ -601,35 +601,38 @@ class Mailing extends CommonObject if ($mode == 2) { if ($statut==-1) return $langs->trans("MailingStatusError").' '.img_error($desc); - if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut4'); - if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut6'); - if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut8'); + if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut6'); + if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut4'); + if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut3'); } if ($mode == 3) { if ($statut==-1) return $langs->trans("MailingStatusError").' '.img_error($desc); - if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut4'); - if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut6'); - if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut8'); + if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut6'); + if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut4'); + if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut3'); } if ($mode == 4) { if ($statut==-1) return $langs->trans("MailingStatusError").' '.img_error($desc); - if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut4'); - if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut6'); - if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut8'); + if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut6'); + if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut4'); + if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut3'); } if ($mode == 5) { - if ($statut==-1) return $langs->trans("MailingStatusError").' '.img_error($desc); - if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut4'); - if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut6'); - if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut8'); + if ($statut==-1) return $langs->trans("MailingStatusError").' '.img_error($desc); + if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut6'); + if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut4'); + if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut3'); + } + if ($mode == 6) + { + if ($statut==-1) return $langs->trans("MailingStatusError").' '.img_error($desc); + if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut6'); + if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut4'); + if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut3'); } - - - - } } diff --git a/htdocs/comm/mailing/list.php b/htdocs/comm/mailing/list.php index b0801c817aa..2d6fae37b98 100644 --- a/htdocs/comm/mailing/list.php +++ b/htdocs/comm/mailing/list.php @@ -174,7 +174,7 @@ if ($result) { print ''; $nbemail = $obj->nbemail; - if ($obj->statut != 3 && !empty($conf->global->MAILING_LIMIT_SENDBYWEB) && $conf->global->MAILING_LIMIT_SENDBYWEB < $nbemail) + /*if ($obj->statut != 3 && !empty($conf->global->MAILING_LIMIT_SENDBYWEB) && $conf->global->MAILING_LIMIT_SENDBYWEB < $nbemail) { $text=$langs->trans('LimitSendingEmailing',$conf->global->MAILING_LIMIT_SENDBYWEB); print $form->textwithpicto($nbemail,$text,1,'warning'); @@ -182,7 +182,8 @@ if ($result) else { print $nbemail; - } + }*/ + print $nbemail; print ''; } // Last send diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 9b416fd1457..6139d54c799 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -11,6 +11,7 @@ * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2014 Ferran Marcet + * Copyright (C) 2016 Marcos García * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -50,6 +51,10 @@ if (! empty($conf->projet->enabled)) { require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php'; } +if (!empty($conf->variants->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php'; +} + $langs->load('companies'); $langs->load('propal'); $langs->load('compta'); @@ -682,7 +687,8 @@ if (empty($reshook)) $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); $price_ht = GETPOST('price_ht'); $price_ht_devise = GETPOST('multicurrency_price_ht'); - if (GETPOST('prod_entry_mode') == 'free') + $prod_entry_mode = GETPOST('prod_entry_mode'); + if ($prod_entry_mode == 'free') { $idprod=0; $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); @@ -708,21 +714,35 @@ if (empty($reshook)) } } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { + if ($prod_entry_mode == 'free' && empty($idprod) && GETPOST('type') < 0) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors'); $error ++; } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && $price_ht == '' && $price_ht_devise == '') // Unit price can be 0 but not ''. Also price can be negative for proposal. + if ($prod_entry_mode == 'free' && empty($idprod) && $price_ht == '' && $price_ht_devise == '') // Unit price can be 0 but not ''. Also price can be negative for proposal. { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors'); $error ++; } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { + if ($prod_entry_mode == 'free' && empty($idprod) && empty($product_desc)) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), null, 'errors'); $error ++; } + if (!$error && !empty($conf->variants->enabled) && $prod_entry_mode != 'free') { + if ($combinations = GETPOST('combinations', 'array')) { + //Check if there is a product with the given combination + $prodcomb = new ProductCombination($db); + + if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) { + $idprod = $res->fk_product_child; + } else { + setEventMessage($langs->trans('ErrorProductCombinationNotFound'), 'errors'); + $error ++; + } + } + } + if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { $pu_ht = 0; $pu_ttc = 0; @@ -961,7 +981,7 @@ if (empty($reshook)) // Add buying price $fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : ''); $buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we muste keep this value - + $pu_ht_devise = GETPOST('multicurrency_subprice'); $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); @@ -2398,7 +2418,7 @@ if ($action == 'create') if ($action != 'presend') { print '
'; - + print ''; // ancre /* * Documents generes */ diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 2111886a517..96dfee663da 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -2764,6 +2764,8 @@ class Propal extends CommonObject */ function availability($availability_id, $notrigger=0) { + global $user; + if ($this->statut >= self::STATUS_DRAFT) { $error=0; @@ -3035,6 +3037,7 @@ class Propal extends CommonObject $response->warning_delay = $delay_warning/60/60/24; $response->label = $label; $response->url = DOL_URL_ROOT.'/comm/propal/list.php?viewstatut='.$statut.'&mainmenu=commercial&leftmenu=propals'; + $response->url_late = DOL_URL_ROOT.'/comm/propal/list.php?viewstatut='.$statut.'&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc'; $response->img = img_object($langs->trans("Propals"),"propal"); // This assignment in condition is not a bug. It allows walking the results. diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 575a55e435f..9e781139723 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -114,7 +114,7 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes') $newdiscount2->amount_ttc=price2num($discount->amount_ttc-$newdiscount1->amount_ttc); $newdiscount1->amount_ht=price2num($newdiscount1->amount_ttc/(1+$newdiscount1->tva_tx/100),'MT'); $newdiscount2->amount_ht=price2num($newdiscount2->amount_ttc/(1+$newdiscount2->tva_tx/100),'MT'); - $newdiscount1->amount_tva=price2num($newdiscount1->amount_ttc-$newdiscount2->amount_ht); + $newdiscount1->amount_tva=price2num($newdiscount1->amount_ttc-$newdiscount1->amount_ht); $newdiscount2->amount_tva=price2num($newdiscount2->amount_ttc-$newdiscount2->amount_ht); $db->begin(); @@ -381,6 +381,15 @@ if ($socid > 0) print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturestatic->getNomURl(1); print ''; } + elseif (preg_match('/\(EXCESS RECEIVED\)/',$obj->description)) + { + 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 ''; + } else { print ''; @@ -540,6 +549,15 @@ if ($socid > 0) print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturestatic->getNomURl(1); print ''; } + elseif (preg_match('/\(EXCESS RECEIVED\)/',$obj->description)) + { + 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 ''; + } else { print ''; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 26d4d4822e2..497dd6292f2 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -7,7 +7,7 @@ * Copyright (C) 2010-2013 Juanjo Menent * Copyright (C) 2011-2016 Philippe Grand * Copyright (C) 2012-2013 Christophe Battarel - * Copyright (C) 2012 Marcos García + * Copyright (C) 2012-2016 Marcos García * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013 Florian Henry * Copyright (C) 2014 Ferran Marcet @@ -51,6 +51,10 @@ if (! empty($conf->projet->enabled)) { } require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; +if (!empty($conf->variants->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php'; +} + $langs->load('orders'); $langs->load('sendings'); $langs->load('companies'); @@ -640,7 +644,8 @@ if (empty($reshook)) $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); $price_ht = GETPOST('price_ht'); $price_ht_devise = GETPOST('multicurrency_price_ht'); - if (GETPOST('prod_entry_mode') == 'free') + $prod_entry_mode = GETPOST('prod_entry_mode'); + if ($prod_entry_mode == 'free') { $idprod=0; $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); @@ -670,11 +675,11 @@ if (empty($reshook)) setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { + if ($prod_entry_mode == 'free' && empty($idprod) && GETPOST('type') < 0) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors'); $error++; } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '') && (! ($price_ht_devise >= 0) || $price_ht_devise == '')) // Unit price can be 0 but not '' + if ($prod_entry_mode == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '') && (! ($price_ht_devise >= 0) || $price_ht_devise == '')) // Unit price can be 0 but not '' { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors'); $error++; @@ -683,11 +688,25 @@ if (empty($reshook)) setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { + if ($prod_entry_mode == 'free' && empty($idprod) && empty($product_desc)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors'); $error++; } + if (!$error && !empty($conf->variants->enabled) && $prod_entry_mode != 'free') { + if ($combinations = GETPOST('combinations', 'array')) { + //Check if there is a product with the given combination + $prodcomb = new ProductCombination($db); + + if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) { + $idprod = $res->fk_product_child; + } else { + setEventMessage($langs->trans('ErrorProductCombinationNotFound'), 'errors'); + $error ++; + } + } + } + if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { // Clean parameters $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); @@ -1187,54 +1206,10 @@ if (empty($reshook)) } } - if ($action == 'builddoc') // In get or post - { - // Save last template used to generate document - if (GETPOST('model')) - $object->setDocModel($user, GETPOST('model', 'alpha')); - if (GETPOST('fk_bank')) { // this field may come from an external module - $object->fk_bank = GETPOST('fk_bank'); - } else { - $object->fk_bank = $object->fk_account; - } - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - $action=''; - } - } - - // Remove file in doc form - if ($action == 'remove_file') - { - if ($object->id > 0) - { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - $langs->load("other"); - $upload_dir = $conf->commande->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret = dol_delete_file($file, 0, 0, 0, $object); - if ($ret) - setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs'); - else - setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors'); - $action = ''; - } - } + // Actions to build doc + $upload_dir = $conf->commande->dir_output; + $permissioncreate = $user->rights->commande->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; if ($action == 'update_extras') { @@ -2463,7 +2438,7 @@ if ($action == 'create' && $user->rights->commande->creer) } print ''; print '
'; - + print "\n"; dol_fiche_end(); @@ -2606,7 +2581,7 @@ if ($action == 'create' && $user->rights->commande->creer) if ($action != 'presend') { print '
'; - + print ''; // ancre // Documents $comref = dol_sanitizeFileName($object->ref); $file = $conf->commande->dir_output . '/' . $comref . '/' . $comref . '.pdf'; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 50bb9e6a009..7bad08b2f84 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -242,7 +242,8 @@ class Commande extends CommonOrder } else { - dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); + $this->error=$obj->error; + //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); return ""; } } diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index 54c77ed6e73..ad3817f28cd 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -5,6 +5,7 @@ * Copyright (C) 2012 Vinícius Nogueira * Copyright (C) 2014 Florian Henry * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2016 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 @@ -773,7 +774,7 @@ if ($resql) 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'],'balance','',$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); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index f332cb65203..29cbe624fca 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -13,7 +13,7 @@ * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2014 Ferran Marcet - * Copyright (C) 2015 Marcos García + * Copyright (C) 2015-2016 Marcos García * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -56,6 +56,10 @@ if (! empty($conf->projet->enabled)) { } require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; +if (!empty($conf->variants->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php'; +} + $langs->load('bills'); $langs->load('companies'); $langs->load('compta'); @@ -602,7 +606,7 @@ if (empty($reshook)) $canconvert=0; if ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 1 && empty($discountcheck->id)) $canconvert=1; // we can convert deposit into discount if deposit is payed completely and not already converted (see real condition into condition used to show button converttoreduc) - if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) + if (($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) if ($canconvert) { $db->begin(); @@ -626,6 +630,8 @@ if (empty($reshook)) $discount->description = '(CREDIT_NOTE)'; elseif ($object->type == Facture::TYPE_DEPOSIT) $discount->description = '(DEPOSIT)'; + elseif ($object->type == Facture::TYPE_STANDARD) + $discount->description = '(EXCESS RECEIVED)'; else { setEventMessages($langs->trans('CantConvertToReducAnInvoiceOfThisType'), null, 'errors'); } @@ -634,20 +640,46 @@ if (empty($reshook)) $discount->fk_facture_source = $object->id; $error = 0; - - foreach ($amount_ht as $tva_tx => $xxx) - { - $discount->amount_ht = abs($amount_ht[$tva_tx]); - $discount->amount_tva = abs($amount_tva[$tva_tx]); - $discount->amount_ttc = abs($amount_ttc[$tva_tx]); - $discount->tva_tx = abs($tva_tx); + + if ($object->type == Facture::TYPE_STANDARD) { + + // If we're on a standard invoice, we have to get excess received to create it in TTC wuthout VAT + + $sql = 'SELECT SUM(pf.amount) as total_paiements + FROM llx_c_paiement as c, llx_paiement_facture as pf, llx_paiement as p + WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid ORDER BY p.datep, p.tms'; + + $resql = $db->query($sql); + $res = $db->fetch_object($resql); + $total_paiements = $res->total_paiements; + + $discount->amount_ht = $discount->amount_ttc = $total_paiements - $object->total_ttc; + $discount->amount_tva = 0; + $discount->tva_tx = 0; $result = $discount->create($user); if ($result < 0) { $error++; - break; } + + } else { + + foreach ($amount_ht as $tva_tx => $xxx) + { + $discount->amount_ht = abs($amount_ht[$tva_tx]); + $discount->amount_tva = abs($amount_tva[$tva_tx]); + $discount->amount_ttc = abs($amount_ttc[$tva_tx]); + $discount->tva_tx = abs($tva_tx); + + $result = $discount->create($user); + if ($result < 0) + { + $error++; + break; + } + } + } if (empty($error)) @@ -804,14 +836,14 @@ if (empty($reshook)) $line->fk_parent_line = $fk_parent_line; $line->subprice =-$line->subprice; // invert price for object - $line->pa_ht = -$line->pa_ht; + $line->pa_ht = $line->pa_ht; // we choosed to have buy/cost price always positive, so no revert of sign here $line->total_ht=-$line->total_ht; $line->total_tva=-$line->total_tva; $line->total_ttc=-$line->total_ttc; $line->total_localtax1=-$line->total_localtax1; $line->total_localtax2=-$line->total_localtax2; - $result = $line->insert(); + $result = $line->insert(0, 1); // When creating credit note with same lines than source, we must ignore error if discount alreayd linked $object->lines[] = $line; // insert new line in current object @@ -1334,7 +1366,8 @@ if (empty($reshook)) $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); $price_ht = GETPOST('price_ht'); $price_ht_devise = GETPOST('multicurrency_price_ht'); - if (GETPOST('prod_entry_mode') == 'free') + $prod_entry_mode = GETPOST('prod_entry_mode'); + if ($prod_entry_mode == 'free') { $idprod=0; $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); @@ -1364,7 +1397,7 @@ if (empty($reshook)) setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error ++; } - if (! GETPOST('prod_entry_mode')) + if (!$prod_entry_mode) { if (GETPOST('type') < 0 && ! GETPOST('search_idprod')) { @@ -1372,11 +1405,11 @@ if (empty($reshook)) $error ++; } } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { + if ($prod_entry_mode == 'free' && empty($idprod) && GETPOST('type') < 0) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors'); $error ++; } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '') && $price_ht_devise == '') // Unit price can be 0 but not '' + if ($prod_entry_mode == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '') && $price_ht_devise == '') // Unit price can be 0 but not '' { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors'); $error ++; @@ -1385,7 +1418,7 @@ if (empty($reshook)) setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error ++; } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { + if ($prod_entry_mode == 'free' && empty($idprod) && empty($product_desc)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors'); $error ++; } @@ -1394,7 +1427,23 @@ if (empty($reshook)) setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors'); $error ++; } + + if (!$error && !empty($conf->variants->enabled) && $prod_entry_mode != 'free') { + if ($combinations = GETPOST('combinations', 'array')) { + //Check if there is a product with the given combination + $prodcomb = new ProductCombination($db); + + if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) { + $idprod = $res->fk_product_child; + } else { + setEventMessage($langs->trans('ErrorProductCombinationNotFound'), 'errors'); + $error ++; + } + } + } + if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { + $ret = $object->fetch($id); if ($ret < 0) { dol_print_error($db, $object->error); @@ -1727,7 +1776,7 @@ if (empty($reshook)) } } } - + $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $qty, GETPOST('remise_percent'), $date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOST('progress'), @@ -2119,7 +2168,7 @@ if ($action == 'create') print '' . "\n"; $exampletemplateinvoice=new FactureRec($db); - + // Overwrite value if creation of invoice is from a predefined invoice if (empty($origin) && empty($originid) && GETPOST('fac_rec','int') > 0) { @@ -2436,7 +2485,7 @@ if ($action == 'create') } $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - + // Date invoice print '' . $langs->trans('DateInvoice') . ''; print $form->select_date($datefacture?$datefacture:$dateinvoice, '', '', '', '', "add", 1, 1, 1); @@ -2542,15 +2591,15 @@ if ($action == 'create') '__INVOICE_YEAR__' => $langs->trans("PreviousYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample,'%Y').')', '__INVOICE_NEXT_YEAR__' => $langs->trans("NextYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'y'),'%Y').')' ); - + $htmltext = ''.$langs->trans("FollowingConstantsWillBeSubstituted").':
'; foreach($substitutionarray as $key => $val) { $htmltext.=$key.' = '.$langs->trans($val).'
'; } - $htmltext.='
'; + $htmltext.=''; } - + // Public note print ''; print ''; @@ -2718,8 +2767,8 @@ else if ($id > 0 || ! empty($ref)) $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice } else { - $filterabsolutediscount = "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description LIKE '(DEPOSIT)%')"; - $filtercreditnote = "fk_facture_source IS NOT NULL AND description NOT LIKE '(DEPOSIT)%'"; + $filterabsolutediscount = "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND (description LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%'))"; + $filtercreditnote = "fk_facture_source IS NOT NULL AND description NOT LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%'"; } $absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount); @@ -2742,7 +2791,10 @@ else if ($id > 0 || ! empty($ref)) // Confirmation de la conversion de l'avoir en reduc if ($action == 'converttoreduc') { - $text = $langs->trans('ConfirmConvertToReduc'); + if($object->type == 0) $type_fac = 'ExcessReceived'; + elseif($object->type == 2) $type_fac = 'CreditNote'; + elseif($object->type == 3) $type_fac = 'Deposit'; + $text = $langs->trans('ConfirmConvertToReduc', strtolower($langs->transnoentities($type_fac))); $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('ConvertToReduc'), $text, 'confirm_converttoreduc', '', "yes", 2); } @@ -3470,7 +3522,7 @@ else if ($id > 0 || ! empty($ref)) print ''; - + // List of previous situation invoices $sign = 1; @@ -3582,9 +3634,9 @@ else if ($id > 0 || ! empty($ref)) print ''; } - + // List of payments already done - + print ''; print ''; @@ -3893,7 +3945,7 @@ else if ($id > 0 || ! empty($ref)) print "
\n"; print "
"; - + print "\n"; dol_fiche_end(); @@ -3932,7 +3984,10 @@ else if ($id > 0 || ! empty($ref)) } } } - + + $discount = new DiscountAbsolute($db); + $result = $discount->fetch(0, $object->id); + // Reopen a standard paid invoice if ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) || ($object->type == Facture::TYPE_CREDIT_NOTE && empty($discount->id)) @@ -3958,7 +4013,7 @@ else if ($id > 0 || ! empty($ref)) } // Send by mail - if (($object->statut == 1 || $object->statut == 2) || ! empty($conf->global->FACTURE_SENDBYEMAIL_FOR_ALL_STATUS)) { + if (($object->statut == Facture::STATUS_VALIDATED || $object->statut == Facture::STATUS_CLOSED) || ! empty($conf->global->FACTURE_SENDBYEMAIL_FOR_ALL_STATUS)) { if ($objectidnext) { print '
' . $langs->trans('SendByMail') . '
'; } else { @@ -3969,21 +4024,27 @@ else if ($id > 0 || ! empty($ref)) } } - // deprecated. Useless because now we can use templates - if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) // For backward compatibility + // Request a direct debit order + if ($object->statut > Facture::STATUS_DRAFT && $object->paye == 0 && $num == 0) { - if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0) { - if ($objectidnext) { - print '
' . $langs->trans('SendRemindByMail') . '
'; - } else { - if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) { - print ''; - } else - print ''; - } - } + if ($resteapayer > 0) + { + if ($user->rights->prelevement->bons->creer) + { + $langs->load("withdrawals"); + print ''.$langs->trans("MakeWithdrawRequest").''; + } + else + { + //print ''.$langs->trans("MakeWithdrawRequest").''; + } + } + else + { + //print ''.$langs->trans("MakeWithdrawRequest").''; + } } - + // Create payment if ($object->type != Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) { if ($objectidnext) { @@ -3998,7 +4059,7 @@ else if ($id > 0 || ! empty($ref)) } // Reverse back money or convert to reduction - if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT) { + if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_STANDARD) { // For credit note only if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) { @@ -4012,6 +4073,11 @@ else if ($id > 0 || ! empty($ref)) } } + // For standard invoice with excess received + if ($object->type == Facture::TYPE_STANDARD && empty($object->paye) && ($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits) < 0 && $user->rights->facture->creer && empty($discount->id)) + { + print ''; + } // For credit note if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0) { print ''; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 72e81fd252e..305b8a7e1c0 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1277,7 +1277,7 @@ class Facture extends CommonInvoice { $this->lines=array(); - $sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx,'; + $sql = 'SELECT l.rowid, l.fk_facture, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx,'; $sql.= ' l.situation_percent, l.fk_prev_id,'; $sql.= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise_percent, l.fk_remise_except, l.subprice,'; $sql.= ' l.rang, l.special_code,'; @@ -1304,6 +1304,7 @@ class Facture extends CommonInvoice $line->id = $objp->rowid; $line->rowid = $objp->rowid; // deprecated + $line->fk_facture = $objp->fk_facture; $line->label = $objp->custom_label; // deprecated $line->desc = $objp->description; // Description line $line->description = $objp->description; // Description line @@ -1558,6 +1559,18 @@ class Facture extends CommonInvoice $facligne->rang=-1; $facligne->info_bits=2; + // Get buy/cost price of invoice that is source of discount + if ($remise->fk_facture_source > 0) + { + $srcinvoice=new Facture($this->db); + $srcinvoice->fetch($remise->fk_facture_source); + $totalcostpriceofinvoice=0; + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php'; // TODO Move this into commonobject + $formmargin=new FormMargin($this->db); + $arraytmp=$formmargin->getMarginInfosArray($srcinvoice, false); + $facligne->pa_ht = $arraytmp['pa_total']; + } + $facligne->total_ht = -$remise->amount_ht; $facligne->total_tva = -$remise->amount_tva; $facligne->total_ttc = -$remise->amount_ttc; @@ -3192,7 +3205,8 @@ class Facture extends CommonInvoice * set up mask. */ if ($mode != 'last' && !$numref) { - dol_print_error($this->db,"Facture::getNextNumRef ".$obj->error); + $this->error=$obj->error; + //dol_print_error($this->db,"Facture::getNextNumRef ".$obj->error); return ""; } @@ -4295,10 +4309,11 @@ class FactureLigne extends CommonInvoiceLine /** * Insert line into database * - * @param int $notrigger 1 no triggers - * @return int <0 if KO, >0 if OK + * @param int $notrigger 1 no triggers + * @param int $noerrorifdiscountalreadylinked 1=Do not make error if lines is linked to a discount and discount already linked to another + * @return int <0 if KO, >0 if OK */ - function insert($notrigger=0) + function insert($notrigger=0, $noerrorifdiscountalreadylinked=0) { global $langs,$user,$conf; @@ -4445,13 +4460,16 @@ class FactureLigne extends CommonInvoiceLine // Check if discount was found if ($result > 0) { - // Check if discount not already affected to another invoice - if ($discount->fk_facture) + // Check if discount not already affected to another invoice + if ($discount->fk_facture_line > 0) { - $this->error=$langs->trans("ErrorDiscountAlreadyUsed",$discount->id); - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -3; + if (empty($noerrorifdiscountalreadylinked)) + { + $this->error=$langs->trans("ErrorDiscountAlreadyUsed",$discount->id); + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -3; + } } else { diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 01620bc3c40..aad49656e2e 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -414,7 +414,7 @@ if ($search_country) $sql .= " AND s.fk_pays IN (".$search_country.')'; if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$search_type_thirdparty.')'; if ($search_company) $sql .= natural_search('s.nom', $search_company); if ($search_montant_ht != '') $sql.= natural_search('f.total', $search_montant_ht, 1); -if ($search_montant_vat != '') $sql.= natural_search('f.total_vat', $search_montant_vat, 1); +if ($search_montant_vat != '') $sql.= natural_search('f.tva', $search_montant_vat, 1); if ($search_montant_ttc != '') $sql.= natural_search('f.total_ttc', $search_montant_ttc, 1); if ($search_status != '' && $search_status >= 0) { diff --git a/htdocs/compta/paiement/rapport.php b/htdocs/compta/paiement/rapport.php index b8bcf030729..27f34bef269 100644 --- a/htdocs/compta/paiement/rapport.php +++ b/htdocs/compta/paiement/rapport.php @@ -128,7 +128,7 @@ if (is_dir($dir)) asort($linkforyear); foreach($linkforyear as $cursoryear) { - print ''.$cursoryear.'  '; + print ''.$cursoryear.'  '; } if ($year) diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index 8a6f4bb7ecc..a0b8e67365f 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -124,24 +124,16 @@ if ($nb < 0 || $nb1 < 0 || $nb11 < 0) print ''; print ''; -print ''; print ''; -print ''; print ''; -//print ''; - -//print ''; - print '
'.$langs->trans("NbOfInvoiceToWithdraw").''; +print ''; print $nb; print '
'.$langs->trans("AmountToWithdraw").''; +print ''; print price($pricetowithdraw); print '
'.$langs->trans("NbOfInvoiceToWithdraw").' + '.$langs->trans("ThirdPartyBankCode").'='.$conf->global->PRELEVEMENT_CODE_BANQUE.''; -//print $nb1; -//print '
'.$langs->trans("NbOfInvoiceToWithdrawWithInfo").''; -//print $nb11; -//print '
'; print '
'; @@ -158,8 +150,6 @@ else { print ''.$langs->trans("CreateAll")."\n"; } - //if ($nb11) print ''.$langs->trans("CreateBanque")."\n"; - //if ($nb1) print ''.$langs->trans("CreateGuichet")."\n"; print "
\n"; print '
'; @@ -247,7 +237,7 @@ else /* - * List of last withdraws + * List of latest withdraws */ $limit=5; diff --git a/htdocs/compta/prelevement/index.php b/htdocs/compta/prelevement/index.php index e00de804f93..9e766e937e2 100644 --- a/htdocs/compta/prelevement/index.php +++ b/htdocs/compta/prelevement/index.php @@ -59,9 +59,7 @@ llxHeader('',$langs->trans("CustomersStandingOrdersArea")); if (prelevement_check_config() < 0) { $langs->load("errors"); - print '
'; - print $langs->trans("ErrorModuleSetupNotComplete"); - print '
'; + setEventMessages($langs->trans("ErrorModuleSetupNotComplete"), null, 'errors'); } print load_fiche_titre($langs->trans("CustomersStandingOrdersArea")); diff --git a/htdocs/contact/agenda.php b/htdocs/contact/agenda.php index 3882d2ebca3..e97263ebf00 100644 --- a/htdocs/contact/agenda.php +++ b/htdocs/contact/agenda.php @@ -81,7 +81,7 @@ if (GETPOST('actioncode','array')) } else { - $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE)); + $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)); } $search_agenda_label=GETPOST('search_agenda_label'); diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 37bd3078c7d..7d95da69aef 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -714,6 +714,11 @@ else print '     '; print ''; } + else + { + print '     '; + print ''; + } print '
'; print ""; @@ -997,7 +1002,7 @@ else print '
'; print ''; - print '     '; + print '     '; print ''; print '
'; @@ -1229,33 +1234,7 @@ else } print ""; - //print "
"; - /* - if (! empty($conf->agenda->enabled)) - { - $objthirdparty=$objsoc; - $objcon=$object; - - $out=''; - $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("TasksHistoryForThisContact"),$out,''); - - //print show_actions_todo($conf,$langs,$db,$objsoc,$object); - - print show_actions_done($conf,$langs,$db,$objsoc,$object,0,'',''); - } - */ } } diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 3b4fa942f81..40051753252 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -41,61 +41,61 @@ class Contact extends CommonObject public $table_element='socpeople'; protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - var $civility_id; // In fact we store civility_code - var $civility_code; - var $address; - var $zip; - var $town; + public $civility_id; // In fact we store civility_code + public $civility_code; + public $address; + public $zip; + public $town; /** * @deprecated * @see state_id */ - var $fk_departement; + public $fk_departement; /** * @deprecated * @see state_code */ - var $departement_code; + public $departement_code; /** * @deprecated * @see state */ - var $departement; - var $state_id; // Id of department - var $state_code; // Code of department - var $state; // Label of department + public $departement; + public $state_id; // Id of department + public $state_code; // Code of department + public $state; // Label of department - var $poste; // Position + public $poste; // Position - var $socid; // fk_soc - var $statut; // 0=inactif, 1=actif + public $socid; // fk_soc + public $statut; // 0=inactif, 1=actif - var $code; - var $email; - var $skype; - var $photo; - var $jabberid; - var $phone_pro; - var $phone_perso; - var $phone_mobile; - var $fax; + public $code; + public $email; + public $skype; + public $photo; + public $jabberid; + public $phone_pro; + public $phone_perso; + public $phone_mobile; + public $fax; - var $priv; + public $priv; - var $birthday; - var $default_lang; - var $no_email; // 1=Don't send e-mail to this contact, 0=do + public $birthday; + public $default_lang; + public $no_email; // 1=Don't send e-mail to this contact, 0=do - var $ref_facturation; // Nb de reference facture pour lequel il est contact - var $ref_contrat; // Nb de reference contrat pour lequel il est contact - var $ref_commande; // Nb de reference commande pour lequel il est contact - var $ref_propal; // Nb de reference propal pour lequel il est contact + public $ref_facturation; // Reference number of invoice for which it is contact + public $ref_contrat; // Nb de reference contrat pour lequel il est contact + public $ref_commande; // Nb de reference commande pour lequel il est contact + public $ref_propal; // Nb de reference propal pour lequel il est contact - var $user_id; - var $user_login; + public $user_id; + public $user_login; - var $oldcopy; // To contains a clone of this when we need to save old properties of object + public $oldcopy; // To contains a clone of this when we need to save old properties of object /** diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 3c88eb64e26..bea5af7e795 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -7,7 +7,7 @@ * Copyright (C) 2013 Christophe Battarel * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2014-2016 Ferran Marcet - * Copyright (C) 2014 Marcos García + * Copyright (C) 2014-2016 Marcos García * Copyright (C) 2015 Jean-François Ferry * * This program is free software; you can redistribute it and/or modify @@ -446,7 +446,7 @@ if (empty($reshook)) unset($_POST["options_" . $key]); } } - + if (! $error) { // Clean parameters diff --git a/htdocs/core/actions_builddoc.inc.php b/htdocs/core/actions_builddoc.inc.php index 5984283b996..adbc17a4161 100644 --- a/htdocs/core/actions_builddoc.inc.php +++ b/htdocs/core/actions_builddoc.inc.php @@ -91,6 +91,9 @@ if ($action == 'builddoc' && $permissioncreate) else { setEventMessages($langs->trans("FileGenerated"), null); + + header('Location: '.$_SERVER['REQUEST_URI'].'#builddoc'); + exit; } } } diff --git a/htdocs/core/ajax/check_notifications.php b/htdocs/core/ajax/check_notifications.php index af56cb23700..4db67aef939 100644 --- a/htdocs/core/ajax/check_notifications.php +++ b/htdocs/core/ajax/check_notifications.php @@ -24,31 +24,57 @@ if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; global $user, $db, $langs, $conf; -$time = GETPOST('time'); +$time = (int) GETPOST('time'); // Use the time parameter that is always increased by time_update, even if call is late //$time=dol_now(); -session_start(); -$time_update = (empty($conf->global->MAIN_BROWSER_NOTIFICATION_FREQUENCY)?'3':(int) $conf->global->MAIN_BROWSER_NOTIFICATION_FREQUENCY); +$eventfound = array(); +//Uncomment this to force a test +//$eventfound[]=array('type'=>'agenda', 'id'=>1, 'tipo'=>'eee', 'location'=>'aaa'); -$eventos = array(); -//$eventos[]=array('type'=>'agenda', 'id'=>1, 'tipo'=>'eee', 'location'=>'aaa'); +//dol_syslog('time='.$time.' $_SESSION[auto_ck_events_not_before]='.$_SESSION['auto_check_events_not_before']); -// TODO Remove test on session. Timer should be managed by a javascript timer -if ($_SESSION['auto_check_events'] <= (int) $time) +// TODO Try to make a solution with only a javascript timer that is easier. Difficulty is to avoid notification twice when several tabs are opened. +if ($time >= $_SESSION['auto_check_events_not_before']) { - $_SESSION['auto_check_events'] = $time + $time_update; - + $time_update = (int) $conf->global->MAIN_BROWSER_NOTIFICATION_FREQUENCY; // Always defined + if (! empty($_SESSION['auto_check_events_not_before'])) + { + // We start scan from the not before so if two tabs were opend at differents seconds and we close one (so the js timer), + // then we are not losing periods + $starttime = $_SESSION['auto_check_events_not_before']; + // Protection to avoid too long sessions + if ($starttime < ($time - (int) $conf->global->MAIN_SESSION_TIMEOUT)) + { + dol_syslog("We ask to check browser notification on a too large period. We fix this with current date."); + $starttime = $time; + } + } + else + { + $starttime = $time; + } + + $_SESSION['auto_check_events_not_before'] = $time + $time_update; + + // Force save of session change we did. + // WARNING: Any change in sessions after that will not be saved ! + session_write_close(); + + require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; + + + dol_syslog('NEW $_SESSION[auto_check_events_not_before]='.$_SESSION['auto_check_events_not_before']); + $sql = 'SELECT id'; $sql .= ' FROM ' . MAIN_DB_PREFIX . 'actioncomm a, ' . MAIN_DB_PREFIX . 'actioncomm_resources ar'; $sql .= ' WHERE a.id = ar.fk_actioncomm'; - // TODO Try to make a solution with only a javascript timer that is easier. Difficulty is to avoid notification twice when. - // This need to extend period to be sure to not miss and save what we notified to avoid duplicate (save is not done yet). - $sql .= " AND datep BETWEEN '" . $db->idate($time + 1) . "' AND '" . $db->idate($time + $time_update) . "'"; + // TODO Try to make a solution with only a javascript timer that is easier. Difficulty is to avoid notification twice when several tabs are opened. + // This need to extend period to be sure to not miss and save in session what we notified to avoid duplicate (save is not done yet). + $sql .= " AND datep BETWEEN '" . $db->idate($starttime) . "' AND '" . $db->idate($time + $time_update - 1) . "'"; $sql .= ' AND a.code <> "AC_OTH_AUTO"'; $sql .= ' AND ar.element_type = "user"'; $sql .= ' AND ar.fk_element = ' . $user->id; @@ -59,8 +85,10 @@ if ($_SESSION['auto_check_events'] <= (int) $time) $actionmod = new ActionComm($db); - while ($obj = $db->fetch_object($resql)) { - + while ($obj = $db->fetch_object($resql)) + { + $langs->load("agenda"); + $actionmod->fetch($obj->id); $event = array(); @@ -68,13 +96,13 @@ if ($_SESSION['auto_check_events'] <= (int) $time) $event['id'] = $actionmod->id; $event['tipo'] = $langs->transnoentities('Action' . $actionmod->code); $event['titulo'] = $actionmod->label; - $event['location'] = $actionmod->location; + $event['location'] = $langs->transnoentities('Location').': '.$actionmod->location; - $eventos[] = $event; + $eventfound[] = $event; } } } -print json_encode($eventos); +print json_encode($eventfound); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 7aa8249f1b7..8bfda274d80 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2785,6 +2785,7 @@ abstract class CommonObject $this->db->begin(); $fieldstatus="fk_statut"; + if ($elementTable == 'mailing') $fieldstatus="statut"; if ($elementTable == 'user') $fieldstatus="statut"; if ($elementTable == 'expensereport') $fieldstatus="fk_statut"; if ($elementTable == 'commande_fournisseur_dispatch') $fieldstatus="status"; @@ -3698,6 +3699,12 @@ abstract class CommonObject $discount->fetch($line->fk_remise_except); $this->tpl['description'] = $langs->transnoentities("DiscountFromDeposit",$discount->getNomUrl(0)); } + elseif ($line->desc == '(EXCESS RECEIVED)') + { + $discount=new DiscountAbsolute($this->db); + $discount->fetch($line->fk_remise_except); + $this->tpl['description'] = $langs->transnoentities("DiscountFromExcessReceived",$discount->getNomUrl(0)); + } else { $this->tpl['description'] = dol_trunc($line->desc,60); @@ -4549,7 +4556,7 @@ abstract class CommonObject var parent = $(this).find("option[parent]:first").attr("parent"); var infos = parent.split(":"); var parent_list = infos[0]; - $("select[name=\"options_"+parent_list+"\"]").change(function() { + $("select[name=\""+parent_list+"\"]").change(function() { showOptions(child_list, parent_list); }); }); diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 064beaa8226..bb63e4c3560 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -420,6 +420,8 @@ class Conf if (empty($this->global->MAIN_MONNAIE)) $this->global->MAIN_MONNAIE='EUR'; $this->currency=$this->global->MAIN_MONNAIE; + if (empty($conf->global->MAIN_BROWSER_NOTIFICATION_FREQUENCY)) $conf->global->MAIN_BROWSER_NOTIFICATION_FREQUENCY = 30; // Less than 1 minutes to be sure + // conf->global->ACCOUNTING_MODE = Option des modules Comptabilites (simple ou expert). Defini le mode de calcul des etats comptables (CA,...) if (empty($this->global->ACCOUNTING_MODE)) $this->global->ACCOUNTING_MODE='RECETTES-DEPENSES'; // By default. Can be 'RECETTES-DEPENSES' ou 'CREANCES-DETTES' diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index 2295a301e03..5ea11cba680 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -41,10 +41,10 @@ class DiscountAbsolute public $fk_user; // Id utilisateur qui accorde la remise public $description; // Description libre public $datec; // Date creation - public $fk_facture_line; // Id invoice line when a discount linked to invoice line (for absolute discounts) - public $fk_facture; // Id invoice when a discoutn linked to invoice (for credit note) + public $fk_facture_line; // Id invoice line when a discount is used into an invoice line (for absolute discounts) + public $fk_facture; // Id invoice when a discount line is used into an invoice (for credit note) public $fk_facture_source; // Id facture avoir a l'origine de la remise - public $ref_facture_source; // Ref facture avoir a l'origine de la remise + public $ref_facture_source; // Ref facture avoir a l'origine de la remise /** * Constructor @@ -296,7 +296,7 @@ class DiscountAbsolute $resql = $this->db->query($sql); if ($resql) { - $this->fk_facture_source=$rowidline; + $this->fk_facture_line=$rowidline; $this->fk_facture=$rowidinvoice; return 1; } diff --git a/htdocs/core/class/fiscalyear.class.php b/htdocs/core/class/fiscalyear.class.php index ef990d8edf3..912c1e34879 100644 --- a/htdocs/core/class/fiscalyear.class.php +++ b/htdocs/core/class/fiscalyear.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2014-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 @@ -89,7 +89,7 @@ class Fiscalyear extends CommonObject $sql.= " '".$this->label."'"; $sql.= ", '".$this->db->idate($this->date_start)."'"; $sql.= ", ".($this->date_end ? "'".$this->db->idate($this->date_end)."'":"null"); - $sql.= ", ".$this->statut; + $sql.= ", 0"; $sql.= ", ".$conf->entity; $sql.= ", '".$this->db->idate($now)."'"; $sql.= ", ". $user->id; diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index cc221393a42..2456005428e 100644 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -231,15 +231,15 @@ class HookManager if (is_array($parameters) && ! empty($parameters['special_code']) && $parameters['special_code'] > 3 && $parameters['special_code'] != $actionclassinstance->module_number) continue; //dol_syslog("Call method ".$method." of class ".get_class($actionclassinstance).", module=".$module.", hooktype=".$hooktype, LOG_DEBUG); - $result = $actionclassinstance->$method($parameters, $object, $action, $this); // $object and $action can be changed by method ($object->id during creation for example or $action to go back to other action for example) + $resaction = $actionclassinstance->$method($parameters, $object, $action, $this); // $object and $action can be changed by method ($object->id during creation for example or $action to go back to other action for example) if (! empty($actionclassinstance->results) && is_array($actionclassinstance->results)) $this->resArray =array_merge($this->resArray, $actionclassinstance->results); if (! empty($actionclassinstance->resprints)) $this->resPrint.=$actionclassinstance->resprints; // TODO dead code to remove (do not enable this, but fix hook instead): result must not be a string. we must use $actionclassinstance->resprints to return a string - if (! is_array($result) && ! is_numeric($result)) + if (! is_array($resaction) && ! is_numeric($resaction)) { dol_syslog('Error: Bug into hook '.$method.' of module class '.get_class($actionclassinstance).'. Method must not return a string but an int (0=OK, 1=Replace, -1=KO) and set string into ->resprints', LOG_ERR); - if (empty($actionclassinstance->resprints)) { $this->resPrint.=$result; $result=0; } + if (empty($actionclassinstance->resprints)) { $this->resPrint.=$resaction; $resaction=0; } } } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 6cf24b2e38f..5637d52ace7 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -12,7 +12,7 @@ * Copyright (C) 2010 Juanjo Menent * Copyright (C) 2010-2014 Philippe Grand * Copyright (C) 2011 Herve Prot - * Copyright (C) 2012-2014 Marcos García + * Copyright (C) 2012-2016 Marcos García * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2012-2015 Raphaël Doursenaud * Copyright (C) 2014 Alexandre Spangaro @@ -80,7 +80,7 @@ class Form * @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'ckeditor:dolibarr_zzz:width:height:savemethod:1:rows:cols', 'select;xxx[:class]'...) * @param string $moreparam More param to add on a href URL. * @param int $fieldrequired 1 if we want to show field as mandatory using the "fieldrequired" CSS. - * @param int $notabletag 1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' ' + * @param int $notabletag 1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' ' * @return string HTML edit field */ function editfieldkey($text, $htmlname, $preselected, $object, $perm, $typeofdata='string', $moreparam='', $fieldrequired=0, $notabletag=0) @@ -464,8 +464,8 @@ class Form * @param string $text Text to show * @param string $htmltext Content of tooltip * @param int $direction 1=Icon is after text, -1=Icon is before text, 0=no icon - * @param string $type Type of picto (info, help, warning, superadmin...) OR image filepath (mypicto@mymodule) - * @param string $extracss Add a CSS style to td tags + * @param string $type Type of picto ('info', 'help', 'warning', 'superadmin', 'mypicto@mymodule', ...) or image filepath + * @param string $extracss Add a CSS style to td, div or span tag * @param int $noencodehtmltext Do not encode into html entity the htmltext * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span * @return string HTML code of text, picto, tooltip @@ -512,7 +512,7 @@ class Form * * @param string $selected Value auto selected when at least one record is selected. Not a preselected value. Use '0' by default. * @param int $arrayofaction array('code'=>'label', ...). The code is the key stored into the GETPOST('massaction') when submitting action. - * @param int $alwaysvisible 1=select button always visible + * @param int $alwaysvisible 1=select button always visible * @return string Select list */ function selectMassAction($selected, $arrayofaction, $alwaysvisible=0) @@ -586,7 +586,7 @@ class Form '; } - + return $ret; } @@ -1171,6 +1171,7 @@ class Form $desc=dol_trunc($obj->description,40); if (preg_match('/\(CREDIT_NOTE\)/', $desc)) $desc=preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $desc); if (preg_match('/\(DEPOSIT\)/', $desc)) $desc=preg_replace('/\(DEPOSIT\)/', $langs->trans("Deposit"), $desc); + if (preg_match('/\(EXCESS RECEIVED\)/', $desc)) $desc=preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("ExcessReceived"), $desc); $selectstring=''; if ($selected > 0 && $selected == $obj->rowid) $selectstring=' selected'; @@ -1409,7 +1410,7 @@ class Form // Build list includeUsers to have only hierarchy and current user $includeUsers = implode(",",$user->getAllChildIds(1)); } - + $out=''; // On recherche les utilisateurs @@ -1615,7 +1616,7 @@ class Form $i++; } if ($nbassignetouser) $out.=''; - + //$out.=''; return $out; } @@ -1641,11 +1642,12 @@ class Form * @param int $hidepriceinlabel 1=Hide prices in label * @param string $warehouseStatus warehouse status filter, following comma separated filter options can be used * 'warehouseopen' = select products from open warehouses, - * 'warehouseclosed' = select products from closed warehouses, + * 'warehouseclosed' = select products from closed warehouses, * 'warehouseinternal' = select products from warehouses for internal correct/transfer only + * @param array $selected_combinations Selected combinations. Format: array([attrid] => attrval, [...]) * @return void */ - function select_produits($selected='', $htmlname='productid', $filtertype='', $limit=20, $price_level=0, $status=1, $finished=2, $selected_input_value='', $hidelabel=0, $ajaxoptions=array(), $socid=0, $showempty='1', $forcecombo=0, $morecss='', $hidepriceinlabel=0, $warehouseStatus='') + function select_produits($selected='', $htmlname='productid', $filtertype='', $limit=20, $price_level=0, $status=1, $finished=2, $selected_input_value='', $hidelabel=0, $ajaxoptions=array(), $socid=0, $showempty='1', $forcecombo=0, $morecss='', $hidepriceinlabel=0, $warehouseStatus='', $selected_combinations = array()) { global $langs,$conf; @@ -1670,6 +1672,80 @@ class Form $urloption.='&socid='.$socid; } print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); + + if (!empty($conf->variants->enabled)) { + ?> + + trans("RefOrLabel").' : '; else if ($hidelabel > 1) { if (! empty($conf->global->MAIN_HTML5_PLACEHOLDER)) $placeholder=' placeholder="'.$langs->trans("RefOrLabel").'"'; @@ -1708,7 +1784,7 @@ class Form * @param int $hidepriceinlabel 1=Hide prices in label * @param string $warehouseStatus warehouse status filter, following comma separated filter options can be used * 'warehouseopen' = select products from open warehouses, - * 'warehouseclosed' = select products from closed warehouses, + * 'warehouseclosed' = select products from closed warehouses, * 'warehouseinternal' = select products from warehouses for internal correct/transfer only * @return array Array of keys for json */ @@ -1723,19 +1799,19 @@ class Form if (! empty($warehouseStatus)) { require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; - if (preg_match('/warehouseclosed/', $warehouseStatus)) + if (preg_match('/warehouseclosed/', $warehouseStatus)) { $warehouseStatusArray[] = Entrepot::STATUS_CLOSED; } - if (preg_match('/warehouseopen/', $warehouseStatus)) + if (preg_match('/warehouseopen/', $warehouseStatus)) { $warehouseStatusArray[] = Entrepot::STATUS_OPEN_ALL; } - if (preg_match('/warehouseinternal/', $warehouseStatus)) + if (preg_match('/warehouseinternal/', $warehouseStatus)) { $warehouseStatusArray[] = Entrepot::STATUS_OPEN_INTERNAL; } - } + } $selectFields = " p.rowid, p.label, p.ref, p.description, p.barcode, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.fk_price_expression"; (count($warehouseStatusArray)) ? $selectFieldsGrouped = ", sum(ps.reel) as stock" : $selectFieldsGrouped = ", p.stock"; @@ -1774,7 +1850,7 @@ class Form $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps on ps.fk_product = p.rowid"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e on ps.fk_entrepot = e.rowid"; } - + //Price by customer if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) { $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."product_customer_price as pcp ON pcp.fk_soc=".$socid." AND pcp.fk_product=p.rowid"; @@ -1784,11 +1860,21 @@ class Form { $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang='". $langs->getDefaultLang() ."'"; } + + if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { + $sql .= " LEFT JOIN llx_product_attribute_combination pac ON pac.fk_product_child = p.rowid"; + } + $sql.= ' WHERE p.entity IN ('.getEntity('product', 1).')'; if (count($warehouseStatusArray)) { $sql.= ' AND (p.fk_product_type = 1 OR e.statut IN ('.implode(',',$warehouseStatusArray).'))'; } + + if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { + $sql .= " AND pac.rowid IS NULL"; + } + if ($finished == 0) { $sql.= " AND p.finished = ".$finished; @@ -1841,7 +1927,7 @@ class Form $num = $this->db->num_rows($result); $events=null; - + if ($conf->use_javascript_ajax && ! $forcecombo) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; @@ -1849,9 +1935,9 @@ class Form $out.= $comboenhancement; $nodatarole=($comboenhancement?' data-role="none"':''); } - + $out.=''; if ($addempty) print ''; foreach($this->cache_conditions_paiements as $id => $arrayconditions) @@ -3384,7 +3470,7 @@ class Form // Clean parameters $newselectedchoice=empty($selectedchoice)?"no":$selectedchoice; if ($conf->browser->layout == 'phone') $width='95%'; - + if (is_array($formquestion) && ! empty($formquestion)) { // First add hidden fields and value @@ -3650,7 +3736,7 @@ class Form require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; $out=''; - + $formproject=new FormProjets($this->db); $langs->load("project"); @@ -3678,8 +3764,8 @@ class Form $out.=" "; } } - - if (empty($nooutput)) + + if (empty($nooutput)) { print $out; return ''; @@ -4005,7 +4091,7 @@ class Form } else { - if (! $filter || $filter=="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description LIKE '(DEPOSIT)%')") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency)); + if (! $filter || $filter=="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND (description LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%'))") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency)); else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency)); } if (empty($hidelist)) print ': '; @@ -4234,7 +4320,7 @@ class Form // Make select dynamic include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $out.= ajax_combobox($htmlname); - + return $out; } @@ -4429,13 +4515,13 @@ class Form $key.= $rate['nprtva'] ? '*': ''; if ($mode > 0 && $rate['code']) $key.=' ('.$rate['code'].')'; if ($mode < 0) $key = $rate['rowid']; - + $return.= '