Browse Source

conflict solved Merge branch 'develop' into abb-14

Conflicts:
	htdocs/langs/en_US/companies.lang
abb 9 years ago
parent
commit
23c0a0a64e
100 changed files with 3114 additions and 2426 deletions
  1. 3 3
      .travis.yml
  2. 4 1
      COPYRIGHT
  3. 111 7
      ChangeLog
  4. 1 1
      README.md
  5. BIN
      build/exe/doliwamp/doliwamp.bmp
  6. 6 3
      build/makepack-dolibarr.pl
  7. 17 1124
      composer.lock
  8. 25 16
      dev/dolibarr_changes.txt
  9. 3 3
      dev/fixdosfiles.sh
  10. 0 0
      dev/initdemo/mysqldump_dolibarr_3.0.0.sql
  11. 0 0
      dev/initdemo/mysqldump_dolibarr_3.1.0.sql
  12. 0 0
      dev/initdemo/mysqldump_dolibarr_3.2.0.sql
  13. 0 0
      dev/initdemo/mysqldump_dolibarr_3.4.0.sql
  14. 0 0
      dev/initdemo/mysqldump_dolibarr_3.5.0.sql
  15. 0 0
      dev/initdemo/mysqldump_dolibarr_3.6.0.sql
  16. 0 0
      dev/initdemo/mysqldump_dolibarr_3.7.0.sql
  17. 0 0
      dev/initdemo/mysqldump_dolibarr_3.8.0.sql
  18. 51 0
      dev/initdemo/mysqldump_dolibarr_3.9.0.sql
  19. 10 0
      dev/initdemo/savedemo.sh
  20. 7 6
      dev/skeletons/modMyModule.class.php
  21. 1 2
      dev/skeletons/skeleton_class.class.php
  22. 60 16
      dev/skeletons/skeleton_list.php
  23. BIN
      doc/images/dolibarr_screenshot1_1280x800.png
  24. BIN
      doc/images/dolibarr_screenshot1_300x188.png
  25. BIN
      doc/images/dolibarr_screenshot1_640x400.png
  26. 11 9
      htdocs/accountancy/admin/account.php
  27. 118 61
      htdocs/accountancy/admin/card.php
  28. 9 11
      htdocs/accountancy/admin/export.php
  29. 3 3
      htdocs/accountancy/admin/importaccounts.php
  30. 10 6
      htdocs/accountancy/admin/index.php
  31. 3 3
      htdocs/accountancy/admin/journal.php
  32. 7 7
      htdocs/accountancy/admin/productaccount.php
  33. 24 20
      htdocs/accountancy/bookkeeping/balance.php
  34. 3 3
      htdocs/accountancy/bookkeeping/balancebymonth.php
  35. 1 1
      htdocs/accountancy/bookkeeping/card.php
  36. 25 10
      htdocs/accountancy/bookkeeping/list.php
  37. 386 0
      htdocs/accountancy/class/accountancycategory.class.php
  38. 286 0
      htdocs/accountancy/class/accountancyexport.class.php
  39. 3 3
      htdocs/accountancy/class/accountancysystem.class.php
  40. 28 16
      htdocs/accountancy/class/accountingaccount.class.php
  41. 54 18
      htdocs/accountancy/class/bookkeeping.class.php
  42. 125 225
      htdocs/accountancy/class/html.formventilation.class.php
  43. 0 0
      htdocs/accountancy/customer/index.html
  44. 6 6
      htdocs/accountancy/customer/index.php
  45. 15 14
      htdocs/accountancy/customer/lines.php
  46. 89 66
      htdocs/accountancy/journal/bankjournal.php
  47. 0 45
      htdocs/accountancy/journal/index.php
  48. 24 10
      htdocs/accountancy/journal/purchasesjournal.php
  49. 39 21
      htdocs/accountancy/journal/sellsjournal.php
  50. 0 0
      htdocs/accountancy/report/index.html
  51. 240 0
      htdocs/accountancy/report/result.php
  52. 5 5
      htdocs/accountancy/supplier/index.php
  53. 11 10
      htdocs/accountancy/supplier/lines.php
  54. 2 2
      htdocs/accountancy/supplier/list.php
  55. 2 7
      htdocs/adherents/card.php
  56. 15 11
      htdocs/adherents/class/adherent_type.class.php
  57. 4 2
      htdocs/adherents/cotisations.php
  58. 1 1
      htdocs/adherents/document.php
  59. 1 1
      htdocs/adherents/index.php
  60. 8 4
      htdocs/adherents/type.php
  61. 3 68
      htdocs/admin/bank.php
  62. 287 0
      htdocs/admin/chequereceipts.php
  63. 15 9
      htdocs/admin/company.php
  64. 4 3
      htdocs/admin/confexped.php
  65. 81 22
      htdocs/admin/dict.php
  66. 5 5
      htdocs/admin/facture.php
  67. 13 1
      htdocs/admin/fckeditor.php
  68. 11 2
      htdocs/admin/loan.php
  69. 64 10
      htdocs/admin/mails.php
  70. 12 3
      htdocs/admin/menus/edit.php
  71. 1 1
      htdocs/admin/menus/index.php
  72. 0 33
      htdocs/admin/menus/other.php
  73. 317 80
      htdocs/admin/modules.php
  74. 79 12
      htdocs/admin/multicurrency.php
  75. 3 0
      htdocs/admin/notification.php
  76. 2 3
      htdocs/admin/security_file.php
  77. 22 214
      htdocs/admin/tools/export.php
  78. 1 1
      htdocs/admin/tools/index.php
  79. 35 21
      htdocs/admin/tools/listevents.php
  80. 2 2
      htdocs/admin/tools/update.php
  81. 9 3
      htdocs/admin/translation.php
  82. 5 5
      htdocs/admin/websites.php
  83. 19 1
      htdocs/api/admin/explorer.php
  84. 5 5
      htdocs/api/class/api_access.class.php
  85. 2 0
      htdocs/api/index.php
  86. 2 2
      htdocs/barcode/printsheet.php
  87. 1 1
      htdocs/cashdesk/affContenu.php
  88. 1 3
      htdocs/cashdesk/affIndex.php
  89. 25 25
      htdocs/cashdesk/class/Facturation.class.php
  90. 11 31
      htdocs/cashdesk/css/style.css
  91. 52 27
      htdocs/cashdesk/facturation_verif.php
  92. 1 2
      htdocs/cashdesk/index.php
  93. 1 1
      htdocs/cashdesk/index_verif.php
  94. 8 7
      htdocs/cashdesk/tpl/facturation1.tpl.php
  95. 1 1
      htdocs/cashdesk/tpl/menu.tpl.php
  96. 1 1
      htdocs/cashdesk/tpl/validation1.tpl.php
  97. 19 34
      htdocs/cashdesk/validation_verif.php
  98. 133 0
      htdocs/categories/class/api_category.class.php
  99. 3 3
      htdocs/categories/class/categorie.class.php
  100. 1 1
      htdocs/categories/index.php

+ 3 - 3
.travis.yml

@@ -266,7 +266,7 @@ script:
 - |
   echo "Upgrading Dolibarr"
   # Ensure we catch errors
-  set -e
+  set +e
   cd htdocs/install
   php upgrade.php 3.5.0 3.6.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade350360.log
   php upgrade2.php 3.5.0 3.6.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade350360-2.log
@@ -289,9 +289,9 @@ script:
 
 - |
   echo "Unit testing"
-  # Ensure we catch errors. Set this to +e if you want to go to this end to see log file.
+  # Ensure we catch errors. Set this to +e if you want to go to the end to see log file.
   set -e
-  phpunit -d memory_limit=-1 -c test/phpunit/phpunittest.xml test/phpunit/AllTests.php
+  #phpunit -d memory_limit=-1 -c test/phpunit/phpunittest.xml test/phpunit/AllTests.php
   set +e
 
 - |

+ 4 - 1
COPYRIGHT

@@ -14,7 +14,7 @@ Component              Version       License                     GPL Compatible
 PHP libraries:
 AdoDb-Date             0.36          Modified BSD License        Yes             Date convertion (not into rpm package)
 ChromePHP              4.1.0         Apache Software License 2.0 Yes             Return server log to chrome browser console
-CKEditor               4.5.6         LGPL-2.1+                   Yes             Editor WYSIWYG
+CKEditor               4.5.8         LGPL-2.1+                   Yes             Editor WYSIWYG
 EvalMath               1.0           BSD                         Yes             Safe math expressions evaluation
 Escpos-php                           MIT License                 Yes             Thermal receipt printer library, for use with ESC/POS compatible printers
 FPDI                   1.5.2         Apache Software License 2.0 Yes             PDF templates management
@@ -30,6 +30,7 @@ PHPPrintIPP            1.3           GPL-2+                      Yes
 Restler                3.0           LGPL-3+                     Yes             Library to develop REST Web services
 TCPDF                  6.2.12        LGPL-3+                     Yes             PDF generation
 TCPDI                  1.0.0         LGPL-3+ / Apache 2.0        Yes             FPDI replacement
+Swift Mailer           5.4.2-DEV     MIT license                 Yes             Comprehensive mailing tools for PHP
 
 JS libraries:
 jQuery                 1.11.3        MIT License                 Yes             JS library
@@ -61,6 +62,8 @@ http://www.gnu.org/licenses/licenses.en.html
 Copyright
 ---------
 
+Copyright (C) 2016
+
 Copyright (C) 2015
 - Laurent Destailleur <eldy@users.sourceforge.net>
 - Marcos García <marcosgdf@gmail.com>

+ 111 - 7
ChangeLog

@@ -6,8 +6,8 @@ WARNING:
 
 Do not try to make any Dolibarr upgrade if you are running Mysql version 5.5.40.
 Mysql version 5.5.40 has a very critical bug making your data beeing definitely lost.
-You may also experience troubles with Mysql 5.5.41/42/43 with error "Lost connection"
-during migration.
+You may also experience troubles with Mysql 5.5.41/42/43 with error "Lost connection" during
+migration.
 Upgrading to any other version or any other database system is abolutely required BEFORE trying
 make a Dolibarr upgrade.
 
@@ -24,9 +24,80 @@ Dolibarr 4.0 should be compatible with PHP 7 but more feedbacks are still expect
 
 Following changes may create regression for some external modules, but were necessary to make
 Dolibarr better:
+- Function log() of class CommandeFournisseur has been removed. Using it is no more required.
+- Class Resource was renamed into DolResource to avoid conflict with a reserved PHP word.
+- Method commonobject->add_thumb() has been renamed into commonobject->addThumbs().
 - Method select_type_comptes_financiers() has been renamed into selectTypeOfBankAccount() 
-
-
+- Property ->client that was deprecated 6 years ago, is replaced in all core code with ->thirdparty.
+- File '/core/tpl/document_actions_pre_headers.tpl.php' were renamed into '/core/actions_linkedfiles.inc.php'.
+So if you included it into your module, change your code like this to be compatible with all version:
+  $res=@include_once DOL_DOCUMENT_ROOT . '/core/actions_linkedfiles.inc.php';
+  if (! $res) include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php';
+
+
+***** ChangeLog for 3.9.1 compared to 3.9.* *****
+FIX: #3815 Call to undefined function local_by_date()
+FIX: #4424 Missing email of user popup in supplier orders area
+FIX: #4442 Missing translation in Banks menu
+FIX: #4737 Bank transacion type selector translation is cropped
+FIX: #4742 Able to delete a supplier invoice with a registered payment
+FIX: #4743 UI glitch in project summary page
+FIX: #4747 Missing UI background when registering a supplier invoice payment
+FIX: #4748 Supplier invoice payment confirmation amount is not translated
+FIX: #4766 VAT not shown in supplier invoice popup
+FIX: #4784
+FIX: #4809 Duplicate functions with different content
+FIX: #4812
+FIX: #4839
+FIX: #4851 Project selector in supplier invoices shows the project label twice
+FIX: #4870
+FIX: #4874 SQL error when listing users
+FIX: #4880
+FIX: #4961
+FIX: #4989
+FIX: If oauth has never been activated two tables are missing and printing is not working
+FIX: A not enabled field for list must not into fields to add
+FIX: Bad color of message password changed
+FIX: Bad error and style message when changing its own login
+FIX: Bad function name call on delete
+FIX: Bad include and param for project numbering module call
+FIX: bad translation language loaded FIX: When changing thirdparty on event card, the showempty option of contact was lost. FIX: Bad placeholder shown on combo to select a thirdparty.
+FIX: Bad vat definition when using POS module
+FIX: Box disabled because bugged
+FIX: Can not select a commercial on the creation of a third
+FIX: Check of EAN13 barcode when mask was set to use 13 digits instead of 12
+FIX: correct display of minimum buying price
+FIX: Creation of thumb image for size "small" was not done.
+FIX: Damn, where was the project ref ?
+FIX: Default vat is not set correctly when an error occured and we use VAT identified by a code.
+FIX: dont retrieve new buying price on margin display
+FIX: Duplicate records into export
+FIX: Each time we edit a line, we loose the unit price.
+FIX: Email templates not compatible with Multicompany
+FIX: Export must use a left join to not loose lines
+FIX: fetchAllEMailTemplate
+FIX: Filter/search on extrafields on lists
+FIX: finished parameters not used
+FIX: Generated thumbs must always use the png format so using thumbs can work.
+FIX: Hook resprint  be printed
+FIX: image extension must be in lower case
+FIX: Missing clean of criteria
+FIX: Missing database escaping on supplier price insert/update
+FIX: Missing function
+FIX: Multiprice generator didn't recalculate prices if only the price_base_type property changes
+FIX: Not removing code into vatrate.
+FIX: Not showing sellprice properly on product list
+FIX: Parsing of amount to pay vat
+FIX: PHPCS
+FIX: PMP is deprecated at warehouse level
+FIX: real min buying price
+FIX: Same term to create than other objects
+FIX: Some records were lost into margin per product report
+FIX: systematic rounding causes prices to be updated without reason
+FIX: Template email must take care of positino column
+FIX: VAT rate can be negative. Example spain selling to morroco.
+FIX: When cloning an order the order result from clone must be now
+FIX: When using option Price per level, when adding a predefined product, the vat for customer was not correctly set.
 
 ***** ChangeLog for 3.9.0 compared to 3.8.* *****
 For users:
@@ -712,6 +783,23 @@ Dolibarr better:
 - Function get_exdir require now 6 parameters. This is to prepare a future feature.
 
 
+***** ChangeLog for 3.7.4 compared to 3.7.3 *****
+FIX: #3694
+FIX: #4239
+FIX: #4291 Correctly filter external calendar GETPOSTs
+FIX: #4341
+FIX: #4414 Supplier invoices use FAC_FORCE_DATE_VALIDATION client invoices property
+FIX: #4440 Wrong price is filled by Product::fetch into multiprices arrays
+FIX: add missing global def for ttc column
+FIX: Contrat card don't consider user permissions to show active/unactive service button
+FIX: CVE CVE-2015-8685
+FIX: Email templates not compatible with Multicompany
+Fix: for avoid division by 0
+FIX: ISSUE #4506 : make working the PROPAL_CLONE_ON_CREATE_PAGE hidden constant
+FIX: $outputlangs is not defined (dolibarr 3.7, 3.8, 3.9)
+FIX: sql injection even when code is on several lines
+FIX: The third dashboard don't consider user permissions
+
 ***** ChangeLog for 3.7.3 compared to 3.7.2 *****
 FIX: #3734 Do not show empty links of deleted source objects in stock movement list
 FIX: #3890 Expected transactions bank account page, shows negative numbers
@@ -1044,6 +1132,11 @@ Dolibarr better:
 - Replaced USER_UPDATE_SESSION trigger with an updateSession hook may break modules using it.
 
 
+
+***** ChangeLog for 3.6.7 compared to 3.6.6 *****
+FIX: #4291 Correctly filter external calendar GETPOSTs
+FIX: CVE CVE-2015-8685
+
 ***** ChangeLog for 3.6.6 compared to 3.6.5 *****
 FIX: #3734 Do not show empty links of deleted source objects in stock movement list
 FIX: #4081 Added missing translation
@@ -1296,6 +1389,17 @@ removed. You must now use the 6 parameters way. See file modMyModule.class.php f
 - Remove add_photo_web() that is not used anymore by core code.
 
 
+***** ChangeLog for 3.5.8 compared to 3.5.7 *****
+FIX: #4291 Correctly filter external calendar GETPOSTs
+FIX: bad calculation for stock value
+FIX: bad stock valo
+FIX: change order date on clone (as everywhere else)
+FIX: CVE CVE-2015-8685
+FIX: The hours of date filter aren't correct
+FIX: #3442 Remove useless syslog
+FIX: #3448 Pass expected date format
+FIX: #3471 3.5 Rounding issue when dispatching non-integer
+
 ***** ChangeLog for 3.5.7 compared to 3.5.6 *****
 Fix: Paypal link were broken due to SSL v3 closed.
 Fix: [ bug #1769 ] Error when installing to a PostgreSQL DB that contains numbers
@@ -1861,7 +1965,7 @@ backport commit 384e3812eb73a15adafb472cacfb93397a54459b to fix W3C/edit contrac
 - Fix: [ bug #810 ] Cannot update ODT template path
 - Fix: [ bug #816 ] Sales journal does not reflect localtaxes
 - Fix: [ bug #817 ] Purchases journal does not reflect localtaxes
-- Fix: [ bug #824 ] MAIN_DB_PREFIX not use into dictionnary
+- Fix: [ bug #824 ] MAIN_DB_PREFIX not use into dictionary
 - Fix: [ bug #828 ] Error when code_region is not a number in llx_c_regions (with postgres)
 - Fix: [ bug #855 ] Holiday approval email in French
 - Fix: [ bug #856 ] (Holidays module) Mail error if destination user doesn't have an email
@@ -1880,7 +1984,7 @@ backport commit 384e3812eb73a15adafb472cacfb93397a54459b to fix W3C/edit contrac
 - Fix: [ bug #736 ] Missing column in llx_c_chargesociales  
 - Fix: Localtax2 for Spain must be based into buyer
 - Fix: [ bug #762 ] Bad profit calculation in Reporting
-- Fix: bug dictionnary with wrong prefix table
+- Fix: bug dictionary with wrong prefix table
 
 ***** ChangeLog for 3.3 compared to 3.2.* *****
 For users:
@@ -1968,7 +2072,7 @@ New experimental module:
 For developers:
 - New: Add webservice for thirdparty creation and list.
 - New: A module can overwrite templates parts.
-- New: Can add a link on title field of added dictionnary.
+- New: Can add a link on title field of added dictionary.
 - New: Uniformize code.
 - New: Add option WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER and 
        WORKFLOW_DISABLE_CLASSIFY_BILLED_FROM_ORDER.

+ 1 - 1
README.md

@@ -6,7 +6,7 @@ Dolibarr ERP & CRM is a modern software to manage your organization's activity (
 
 It's an Open Source software (wrote in PHP language) designed for small and medium companies, foundation and freelances.
 
-You can freely use, study, modify or distribute it according to it's Free Software licence.
+You can freely use, study, modify or distribute it according to its Free Software licence.
 
 You can use it as a standalone application or as a web application to be able to access it from the Internet or a LAN.
 

BIN
build/exe/doliwamp/doliwamp.bmp


+ 6 - 3
build/makepack-dolibarr.pl

@@ -379,7 +379,7 @@ if ($nboftargetok) {
 			
 		print 'Run git tag -a -m "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'" "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'"'."\n";
 		$ret=`git tag -a -m "$MAJOR.$MINOR.$BUILD" "$MAJOR.$MINOR.$BUILD" 2>&1`;
-		if ($ret =~ /already exists/)
+		if ($ret =~ /(already exists|existe déjà)/)
 		{
 			print "WARNING: Tag ".$MAJOR.'.'.$MINOR.'.'.$BUILD." already exists. Overwrite (y/N) ? ";
 			$QUESTIONOVERWRITETAG=<STDIN>; 
@@ -1159,10 +1159,13 @@ if ($nboftargetok) {
 	    		if ($target eq 'SF') { 
 	    			$destFolder="$NEWPUBLISH/$filestoscan{$file}/".$MAJOR.'.'.$MINOR.'.'.$BUILD;
 	    		}
-	    		elsif ($target eq 'ASSO' && $NEWPUBLISH =~ /stable/) {
+	    		elsif ($target eq 'ASSO' and $NEWPUBLISH =~ /stable/) {
 	    			$destFolder="$NEWPUBLISH/$filestoscanstableasso{$file}";
 	    		} 
-	    		else
+	    		elsif ($target eq 'ASSO' and $NEWPUBLISH !~ /stable/) {
+	    			$destFolder="$NEWPUBLISH";
+	    		} 
+	    		else	# No more used
 	    		{
 	    			$dirnameonly=$file;
 	    			$dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/;  

+ 17 - 1124
composer.lock

@@ -4,8 +4,8 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "4a06567f53c5f081f9c961a0b3093da3",
-    "content-hash": "265061f1a1056df2e8c5184841993d0f",
+    "hash": "c2b53c577364dbe3a56137043081b511",
+    "content-hash": "8f7a86cfbc13f45e13b73c49531818cb",
     "packages": [
         {
             "name": "ccampbell/chromephp",
@@ -56,12 +56,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/ckeditor/ckeditor-releases.git",
-                "reference": "c1cefe7341e6910a1e6cb2f3f024bbdaf6cd1d4d"
+                "reference": "e3eb254641c4c349ffc19e49bd4a1a6831b5b6d0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/ckeditor/ckeditor-releases/zipball/c1cefe7341e6910a1e6cb2f3f024bbdaf6cd1d4d",
-                "reference": "c1cefe7341e6910a1e6cb2f3f024bbdaf6cd1d4d",
+                "url": "https://api.github.com/repos/ckeditor/ckeditor-releases/zipball/e3eb254641c4c349ffc19e49bd4a1a6831b5b6d0",
+                "reference": "e3eb254641c4c349ffc19e49bd4a1a6831b5b6d0",
                 "shasum": ""
             },
             "type": "library",
@@ -73,7 +73,7 @@
             ],
             "authors": [
                 {
-                    "name": "CKSource - Frederico Knabben",
+                    "name": "CKSource",
                     "homepage": "http://cksource.com"
                 }
             ],
@@ -89,7 +89,7 @@
                 "text",
                 "wysiwyg"
             ],
-            "time": "2015-12-09 15:49:34"
+            "time": "2016-03-31 16:19:25"
         },
         {
             "name": "mike42/escpos-php",
@@ -97,12 +97,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/mike42/escpos-php.git",
-                "reference": "63648d03d47b81e8f6c1020ac92f051a3f3b5793"
+                "reference": "96f05cbf460f5b67c2184ee4e91aedfbcedeb788"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mike42/escpos-php/zipball/63648d03d47b81e8f6c1020ac92f051a3f3b5793",
-                "reference": "63648d03d47b81e8f6c1020ac92f051a3f3b5793",
+                "url": "https://api.github.com/repos/mike42/escpos-php/zipball/96f05cbf460f5b67c2184ee4e91aedfbcedeb788",
+                "reference": "96f05cbf460f5b67c2184ee4e91aedfbcedeb788",
                 "shasum": ""
             },
             "require": {
@@ -112,6 +112,11 @@
                 "phpunit/phpunit": "4.5.*"
             },
             "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Mike42\\": "src/Mike42"
+                }
+            },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
@@ -147,7 +152,7 @@
                 "print",
                 "receipt"
             ],
-            "time": "2015-12-04 10:23:55"
+            "time": "2016-03-27 23:08:27"
         },
         {
             "name": "mobiledetect/mobiledetectlib",
@@ -398,1119 +403,7 @@
             "time": "2015-09-12 10:08:34"
         }
     ],
-    "packages-dev": [
-        {
-            "name": "doctrine/instantiator",
-            "version": "1.0.5",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/doctrine/instantiator.git",
-                "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
-                "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3,<8.0-DEV"
-            },
-            "require-dev": {
-                "athletic/athletic": "~0.1.8",
-                "ext-pdo": "*",
-                "ext-phar": "*",
-                "phpunit/phpunit": "~4.0",
-                "squizlabs/php_codesniffer": "~2.0"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.0.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Marco Pivetta",
-                    "email": "ocramius@gmail.com",
-                    "homepage": "http://ocramius.github.com/"
-                }
-            ],
-            "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
-            "homepage": "https://github.com/doctrine/instantiator",
-            "keywords": [
-                "constructor",
-                "instantiate"
-            ],
-            "time": "2015-06-14 21:17:01"
-        },
-        {
-            "name": "myclabs/deep-copy",
-            "version": "1.5.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/myclabs/DeepCopy.git",
-                "reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e3abefcd7f106677fd352cd7c187d6c969aa9ddc",
-                "reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.4.0"
-            },
-            "require-dev": {
-                "doctrine/collections": "1.*",
-                "phpunit/phpunit": "~4.1"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-4": {
-                    "DeepCopy\\": "src/DeepCopy/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "description": "Create deep copies (clones) of your objects",
-            "homepage": "https://github.com/myclabs/DeepCopy",
-            "keywords": [
-                "clone",
-                "copy",
-                "duplicate",
-                "object",
-                "object graph"
-            ],
-            "time": "2015-11-07 22:20:37"
-        },
-        {
-            "name": "phpdocumentor/reflection-docblock",
-            "version": "2.0.4",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
-                "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
-                "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "~4.0"
-            },
-            "suggest": {
-                "dflydev/markdown": "~1.0",
-                "erusev/parsedown": "~1.0"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "2.0.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-0": {
-                    "phpDocumentor": [
-                        "src/"
-                    ]
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Mike van Riel",
-                    "email": "mike.vanriel@naenius.com"
-                }
-            ],
-            "time": "2015-02-03 12:10:50"
-        },
-        {
-            "name": "phpspec/prophecy",
-            "version": "v1.5.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/phpspec/prophecy.git",
-                "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7",
-                "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7",
-                "shasum": ""
-            },
-            "require": {
-                "doctrine/instantiator": "^1.0.2",
-                "phpdocumentor/reflection-docblock": "~2.0",
-                "sebastian/comparator": "~1.1"
-            },
-            "require-dev": {
-                "phpspec/phpspec": "~2.0"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.4.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-0": {
-                    "Prophecy\\": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Konstantin Kudryashov",
-                    "email": "ever.zet@gmail.com",
-                    "homepage": "http://everzet.com"
-                },
-                {
-                    "name": "Marcello Duarte",
-                    "email": "marcello.duarte@gmail.com"
-                }
-            ],
-            "description": "Highly opinionated mocking framework for PHP 5.3+",
-            "homepage": "https://github.com/phpspec/prophecy",
-            "keywords": [
-                "Double",
-                "Dummy",
-                "fake",
-                "mock",
-                "spy",
-                "stub"
-            ],
-            "time": "2015-08-13 10:07:40"
-        },
-        {
-            "name": "phpunit/php-code-coverage",
-            "version": "3.0.2",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "f7bb5cddf4ffe113eeb737b05241adb947b43f9d"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f7bb5cddf4ffe113eeb737b05241adb947b43f9d",
-                "reference": "f7bb5cddf4ffe113eeb737b05241adb947b43f9d",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.6",
-                "phpunit/php-file-iterator": "~1.3",
-                "phpunit/php-text-template": "~1.2",
-                "phpunit/php-token-stream": "~1.3",
-                "sebastian/environment": "^1.3.2",
-                "sebastian/version": "~1.0"
-            },
-            "require-dev": {
-                "ext-xdebug": ">=2.1.4",
-                "phpunit/phpunit": "~5"
-            },
-            "suggest": {
-                "ext-dom": "*",
-                "ext-xdebug": ">=2.2.1",
-                "ext-xmlwriter": "*"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "3.0.x-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sb@sebastian-bergmann.de",
-                    "role": "lead"
-                }
-            ],
-            "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
-            "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
-            "keywords": [
-                "coverage",
-                "testing",
-                "xunit"
-            ],
-            "time": "2015-11-12 21:08:20"
-        },
-        {
-            "name": "phpunit/php-file-iterator",
-            "version": "1.4.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
-                "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
-                "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.4.x-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sb@sebastian-bergmann.de",
-                    "role": "lead"
-                }
-            ],
-            "description": "FilterIterator implementation that filters files based on a list of suffixes.",
-            "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
-            "keywords": [
-                "filesystem",
-                "iterator"
-            ],
-            "time": "2015-06-21 13:08:43"
-        },
-        {
-            "name": "phpunit/php-text-template",
-            "version": "1.2.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/php-text-template.git",
-                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
-                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "type": "library",
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de",
-                    "role": "lead"
-                }
-            ],
-            "description": "Simple template engine.",
-            "homepage": "https://github.com/sebastianbergmann/php-text-template/",
-            "keywords": [
-                "template"
-            ],
-            "time": "2015-06-21 13:50:34"
-        },
-        {
-            "name": "phpunit/php-timer",
-            "version": "1.0.7",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/php-timer.git",
-                "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
-                "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "type": "library",
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sb@sebastian-bergmann.de",
-                    "role": "lead"
-                }
-            ],
-            "description": "Utility class for timing",
-            "homepage": "https://github.com/sebastianbergmann/php-timer/",
-            "keywords": [
-                "timer"
-            ],
-            "time": "2015-06-21 08:01:12"
-        },
-        {
-            "name": "phpunit/php-token-stream",
-            "version": "1.4.8",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/php-token-stream.git",
-                "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
-                "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
-                "shasum": ""
-            },
-            "require": {
-                "ext-tokenizer": "*",
-                "php": ">=5.3.3"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "~4.2"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.4-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de"
-                }
-            ],
-            "description": "Wrapper around PHP's tokenizer extension.",
-            "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
-            "keywords": [
-                "tokenizer"
-            ],
-            "time": "2015-09-15 10:49:45"
-        },
-        {
-            "name": "phpunit/phpunit",
-            "version": "5.1.3",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "c047ff05d2279404af9a7e89e2a7151c32c88022"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c047ff05d2279404af9a7e89e2a7151c32c88022",
-                "reference": "c047ff05d2279404af9a7e89e2a7151c32c88022",
-                "shasum": ""
-            },
-            "require": {
-                "ext-dom": "*",
-                "ext-json": "*",
-                "ext-pcre": "*",
-                "ext-reflection": "*",
-                "ext-spl": "*",
-                "myclabs/deep-copy": "~1.3",
-                "php": ">=5.6",
-                "phpspec/prophecy": "^1.3.1",
-                "phpunit/php-code-coverage": "~3.0",
-                "phpunit/php-file-iterator": "~1.4",
-                "phpunit/php-text-template": "~1.2",
-                "phpunit/php-timer": ">=1.0.6",
-                "phpunit/phpunit-mock-objects": ">=3.0.5",
-                "sebastian/comparator": "~1.1",
-                "sebastian/diff": "~1.2",
-                "sebastian/environment": "~1.3",
-                "sebastian/exporter": "~1.2",
-                "sebastian/global-state": "~1.0",
-                "sebastian/resource-operations": "~1.0",
-                "sebastian/version": "~1.0",
-                "symfony/yaml": "~2.1|~3.0"
-            },
-            "suggest": {
-                "phpunit/php-invoker": "~1.1"
-            },
-            "bin": [
-                "phpunit"
-            ],
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "5.1.x-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de",
-                    "role": "lead"
-                }
-            ],
-            "description": "The PHP Unit Testing framework.",
-            "homepage": "https://phpunit.de/",
-            "keywords": [
-                "phpunit",
-                "testing",
-                "xunit"
-            ],
-            "time": "2015-12-10 07:54:54"
-        },
-        {
-            "name": "phpunit/phpunit-mock-objects",
-            "version": "3.0.6",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
-                "reference": "49bc700750196c04dd6bc2c4c99cb632b893836b"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/49bc700750196c04dd6bc2c4c99cb632b893836b",
-                "reference": "49bc700750196c04dd6bc2c4c99cb632b893836b",
-                "shasum": ""
-            },
-            "require": {
-                "doctrine/instantiator": "^1.0.2",
-                "php": ">=5.6",
-                "phpunit/php-text-template": "~1.2",
-                "sebastian/exporter": "~1.2"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "~5"
-            },
-            "suggest": {
-                "ext-soap": "*"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "3.0.x-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sb@sebastian-bergmann.de",
-                    "role": "lead"
-                }
-            ],
-            "description": "Mock Object library for PHPUnit",
-            "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
-            "keywords": [
-                "mock",
-                "xunit"
-            ],
-            "time": "2015-12-08 08:47:06"
-        },
-        {
-            "name": "sebastian/comparator",
-            "version": "1.2.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/comparator.git",
-                "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
-                "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3",
-                "sebastian/diff": "~1.2",
-                "sebastian/exporter": "~1.2"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "~4.4"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.2.x-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Jeff Welch",
-                    "email": "whatthejeff@gmail.com"
-                },
-                {
-                    "name": "Volker Dusch",
-                    "email": "github@wallbash.com"
-                },
-                {
-                    "name": "Bernhard Schussek",
-                    "email": "bschussek@2bepublished.at"
-                },
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de"
-                }
-            ],
-            "description": "Provides the functionality to compare PHP values for equality",
-            "homepage": "http://www.github.com/sebastianbergmann/comparator",
-            "keywords": [
-                "comparator",
-                "compare",
-                "equality"
-            ],
-            "time": "2015-07-26 15:48:44"
-        },
-        {
-            "name": "sebastian/diff",
-            "version": "1.4.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/diff.git",
-                "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
-                "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "~4.8"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.4-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Kore Nordmann",
-                    "email": "mail@kore-nordmann.de"
-                },
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de"
-                }
-            ],
-            "description": "Diff implementation",
-            "homepage": "https://github.com/sebastianbergmann/diff",
-            "keywords": [
-                "diff"
-            ],
-            "time": "2015-12-08 07:14:41"
-        },
-        {
-            "name": "sebastian/environment",
-            "version": "1.3.3",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/environment.git",
-                "reference": "6e7133793a8e5a5714a551a8324337374be209df"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e7133793a8e5a5714a551a8324337374be209df",
-                "reference": "6e7133793a8e5a5714a551a8324337374be209df",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "~4.4"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.3.x-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de"
-                }
-            ],
-            "description": "Provides functionality to handle HHVM/PHP environments",
-            "homepage": "http://www.github.com/sebastianbergmann/environment",
-            "keywords": [
-                "Xdebug",
-                "environment",
-                "hhvm"
-            ],
-            "time": "2015-12-02 08:37:27"
-        },
-        {
-            "name": "sebastian/exporter",
-            "version": "1.2.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/exporter.git",
-                "reference": "7ae5513327cb536431847bcc0c10edba2701064e"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
-                "reference": "7ae5513327cb536431847bcc0c10edba2701064e",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3",
-                "sebastian/recursion-context": "~1.0"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "~4.4"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.2.x-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Jeff Welch",
-                    "email": "whatthejeff@gmail.com"
-                },
-                {
-                    "name": "Volker Dusch",
-                    "email": "github@wallbash.com"
-                },
-                {
-                    "name": "Bernhard Schussek",
-                    "email": "bschussek@2bepublished.at"
-                },
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de"
-                },
-                {
-                    "name": "Adam Harvey",
-                    "email": "aharvey@php.net"
-                }
-            ],
-            "description": "Provides the functionality to export PHP variables for visualization",
-            "homepage": "http://www.github.com/sebastianbergmann/exporter",
-            "keywords": [
-                "export",
-                "exporter"
-            ],
-            "time": "2015-06-21 07:55:53"
-        },
-        {
-            "name": "sebastian/global-state",
-            "version": "1.1.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/global-state.git",
-                "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
-                "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "~4.2"
-            },
-            "suggest": {
-                "ext-uopz": "*"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.0-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de"
-                }
-            ],
-            "description": "Snapshotting of global state",
-            "homepage": "http://www.github.com/sebastianbergmann/global-state",
-            "keywords": [
-                "global state"
-            ],
-            "time": "2015-10-12 03:26:01"
-        },
-        {
-            "name": "sebastian/recursion-context",
-            "version": "1.0.2",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/recursion-context.git",
-                "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
-                "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "~4.4"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.0.x-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Jeff Welch",
-                    "email": "whatthejeff@gmail.com"
-                },
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de"
-                },
-                {
-                    "name": "Adam Harvey",
-                    "email": "aharvey@php.net"
-                }
-            ],
-            "description": "Provides functionality to recursively process PHP variables",
-            "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
-            "time": "2015-11-11 19:50:13"
-        },
-        {
-            "name": "sebastian/resource-operations",
-            "version": "1.0.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/resource-operations.git",
-                "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
-                "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.6.0"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.0.x-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de"
-                }
-            ],
-            "description": "Provides a list of PHP built-in functions that operate on resources",
-            "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
-            "time": "2015-07-28 20:34:47"
-        },
-        {
-            "name": "sebastian/version",
-            "version": "1.0.6",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/sebastianbergmann/version.git",
-                "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
-                "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
-                "shasum": ""
-            },
-            "type": "library",
-            "autoload": {
-                "classmap": [
-                    "src/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Sebastian Bergmann",
-                    "email": "sebastian@phpunit.de",
-                    "role": "lead"
-                }
-            ],
-            "description": "Library that helps with managing the version number of Git-hosted PHP projects",
-            "homepage": "https://github.com/sebastianbergmann/version",
-            "time": "2015-06-21 13:59:46"
-        },
-        {
-            "name": "squizlabs/php_codesniffer",
-            "version": "2.4.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
-                "reference": "32a879f4f35019d78d568db2885d7779ca084a33"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/32a879f4f35019d78d568db2885d7779ca084a33",
-                "reference": "32a879f4f35019d78d568db2885d7779ca084a33",
-                "shasum": ""
-            },
-            "require": {
-                "ext-tokenizer": "*",
-                "ext-xmlwriter": "*",
-                "php": ">=5.1.2"
-            },
-            "bin": [
-                "scripts/phpcs",
-                "scripts/phpcbf"
-            ],
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "2.0.x-dev"
-                }
-            },
-            "autoload": {
-                "classmap": [
-                    "CodeSniffer.php",
-                    "CodeSniffer/CLI.php",
-                    "CodeSniffer/Exception.php",
-                    "CodeSniffer/File.php",
-                    "CodeSniffer/Fixer.php",
-                    "CodeSniffer/Report.php",
-                    "CodeSniffer/Reporting.php",
-                    "CodeSniffer/Sniff.php",
-                    "CodeSniffer/Tokens.php",
-                    "CodeSniffer/Reports/",
-                    "CodeSniffer/Tokenizers/",
-                    "CodeSniffer/DocGenerators/",
-                    "CodeSniffer/Standards/AbstractPatternSniff.php",
-                    "CodeSniffer/Standards/AbstractScopeSniff.php",
-                    "CodeSniffer/Standards/AbstractVariableSniff.php",
-                    "CodeSniffer/Standards/IncorrectPatternException.php",
-                    "CodeSniffer/Standards/Generic/Sniffs/",
-                    "CodeSniffer/Standards/MySource/Sniffs/",
-                    "CodeSniffer/Standards/PEAR/Sniffs/",
-                    "CodeSniffer/Standards/PSR1/Sniffs/",
-                    "CodeSniffer/Standards/PSR2/Sniffs/",
-                    "CodeSniffer/Standards/Squiz/Sniffs/",
-                    "CodeSniffer/Standards/Zend/Sniffs/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "BSD-3-Clause"
-            ],
-            "authors": [
-                {
-                    "name": "Greg Sherwood",
-                    "role": "lead"
-                }
-            ],
-            "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
-            "homepage": "http://www.squizlabs.com/php-codesniffer",
-            "keywords": [
-                "phpcs",
-                "standards"
-            ],
-            "time": "2015-11-23 21:30:59"
-        },
-        {
-            "name": "symfony/yaml",
-            "version": "v3.0.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/yaml.git",
-                "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002",
-                "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.5.9"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "3.0-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Symfony\\Component\\Yaml\\": ""
-                },
-                "exclude-from-classmap": [
-                    "/Tests/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Fabien Potencier",
-                    "email": "fabien@symfony.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Symfony Yaml Component",
-            "homepage": "https://symfony.com",
-            "time": "2015-11-30 12:36:17"
-        }
-    ],
+    "packages-dev": [],
     "aliases": [],
     "minimum-stability": "stable",
     "stability-flags": {

+ 25 - 16
dev/dolibarr_changes.txt

@@ -10,6 +10,16 @@ Replace "& new" by "new"
 
 
 
+CKEDITOR:
+---------
+* In ckeditor/ckeditor/contents.css
+Replace:
+	margin: 20px;
+With
+	margin: 5px;
+
+
+
 NUSOAP:
 -------
 * In file nusoap.php, to avoid a warning,
@@ -38,15 +48,16 @@ with:
     }
 
 
+
 TCPDF:
 ------
-* Removed all fonts except 
-    dejavusans* (used by greek, arab, persan, romanian, turkish), 
-    freemono* (russian), 
-    cid*+msungstdlight+stsongstdlight+uni2cid* (chinese), 
-    helvetica* (all other languages),
-    zapfdingbats.php (for special chars like form checkboxes)
+* To avoid to have QRcode changed because generated with a random mask, replace
+define('QR_FIND_FROM_RANDOM', 2);
+with
+define('QR_FIND_FROM_RANDOM', false);
+
 * Removed useless directories (examples, tools)
+
 * Fix
  	// initialize subsetchars
 	$subsetchars = array();
@@ -54,19 +65,18 @@ into
 	// initialize subsetchars
 	$subsetchars = array_fill(0, 256, true);
 
-* Made freemono the default monotype font because we removed courier
+* Optionnaly, removed all fonts except 
+    dejavusans* (used by greek, arab, persan, romanian, turkish), 
+    freemono* (russian), 
+    cid*+msungstdlight+stsongstdlight+uni2cid* (chinese), 
+    helvetica* (all other languages),
+    zapfdingbats.php (for special chars like form checkboxes)
+
+* Optionnaly, made freemono the default monotype font because we removed courier
 In htdocs/includes/tcpdf/tcpdf.php
 -       protected $default_monospaced_font = 'courier';
 +       protected $default_monospaced_font = 'freemono';
 
-* Renamed getmypid into dol_getmypid().
-
-
-To avoid to have QRcode changed because generated with a random mask, replace
-define('QR_FIND_FROM_RANDOM', 2);
-with
-define('QR_FIND_FROM_RANDOM', false);
-
 
 
 TCPDI:
@@ -81,7 +91,6 @@ require_once(dirname(__FILE__).'/../tecnickcom/tcpdf/include/tcpdf_filters.php')
 
 
 
-
 JSGANTT:
 --------
 * Replace in function JSGantt.taskLink

+ 3 - 3
dev/fixdosfiles.sh

@@ -17,16 +17,16 @@ fi
 # To detec
 if [ "x$1" = "xlist" ]
 then
-	find . \( -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.txt" -o -iname "*.xml" \) -exec file "{}" + | grep CRLF
+	find . \( -iname "functions" -o -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.txt" -o -iname "*.xml" \) -exec file "{}" + | grep CRLF
 #	find . \( -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.txt" -o -iname "*.xml" \) -exec file "{}" + | grep -v 'htdocs\/includes' | grep CRLF
 fi
 
 # To convert
 if [ "x$1" = "xfix" ]
 then
-	for fic in `find . \( -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.txt" -o -iname "*.xml" \) -exec file "{}" + | grep CRLF | awk -F':' '{ print $1 }' `
+	for fic in `find . \( -iname "functions" -o -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.txt" -o -iname "*.xml" \) -exec file "{}" + | grep CRLF | awk -F':' '{ print $1 }' `
 	do
 		echo "Fix file $fic"
-		dos2unix $fic
+		dos2unix "$fic"
 	done;
 fi

File diff suppressed because it is too large
+ 0 - 0
dev/initdemo/mysqldump_dolibarr_3.0.0.sql


File diff suppressed because it is too large
+ 0 - 0
dev/initdemo/mysqldump_dolibarr_3.1.0.sql


File diff suppressed because it is too large
+ 0 - 0
dev/initdemo/mysqldump_dolibarr_3.2.0.sql


File diff suppressed because it is too large
+ 0 - 0
dev/initdemo/mysqldump_dolibarr_3.4.0.sql


File diff suppressed because it is too large
+ 0 - 0
dev/initdemo/mysqldump_dolibarr_3.5.0.sql


File diff suppressed because it is too large
+ 0 - 0
dev/initdemo/mysqldump_dolibarr_3.6.0.sql


File diff suppressed because it is too large
+ 0 - 0
dev/initdemo/mysqldump_dolibarr_3.7.0.sql


File diff suppressed because it is too large
+ 0 - 0
dev/initdemo/mysqldump_dolibarr_3.8.0.sql


File diff suppressed because it is too large
+ 51 - 0
dev/initdemo/mysqldump_dolibarr_3.9.0.sql


+ 10 - 0
dev/initdemo/savedemo.sh

@@ -174,6 +174,10 @@ export list="
     --ignore-table=$base.llx_advanced_extrafields 
     --ignore-table=$base.llx_advanced_extrafields_options 
     --ignore-table=$base.llx_advanced_extrafields_values
+    --ignore-table=$base.llx_askpricesupplier
+    --ignore-table=$base.llx_askpricesupplier_extrafields
+    --ignore-table=$base.llx_askpricesupplierdet
+    --ignore-table=$base.llx_askpricesupplierdet_extrafields
     --ignore-table=$base.llx_bookkeeping
 	--ignore-table=$base.llx_bootstrap
 	--ignore-table=$base.llx_bt_namemap
@@ -196,6 +200,11 @@ export list="
 	--ignore-table=$base.llx_cabinetmed_motifcons
 	--ignore-table=$base.llx_cabinetmed_patient
 	--ignore-table=$base.llx_cabinetmed_societe
+	--ignore-table=$base.llx_congespayes
+	--ignore-table=$base.llx_congespayes_config
+	--ignore-table=$base.llx_congespayes_events
+	--ignore-table=$base.llx_congespayes_logs
+	--ignore-table=$base.llx_congespayes_users
 	--ignore-table=$base.llx_dolicloud_customers
 	--ignore-table=$base.llx_dolicloud_stats
 	--ignore-table=$base.llx_dolicloud_emailstemplates
@@ -205,6 +214,7 @@ export list="
 	--ignore-table=$base.llx_filemanager_roots
 	--ignore-table=$base.llx_fournisseur_ca
 	--ignore-table=$base.llx_google_maps
+	--ignore-table=$base.llx_milestone
 	--ignore-table=$base.llx_monitoring_probes
 	--ignore-table=$base.llx_notes
 	--ignore-table=$base.llx_pos_cash

+ 7 - 6
dev/skeletons/modMyModule.class.php

@@ -50,25 +50,26 @@ class modMyModule extends DolibarrModules
 		// Key text used to identify module (for permissions, menus, etc...)
 		$this->rights_class = 'mymodule';
 
-		// Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
-		// It is used to group modules in module setup page
+		// Family can be 'crm','financial','hr','projects','products','ecm','technic','interface','other'
+		// It is used to group modules by family in module setup page
 		$this->family = "other";
 		// Module position in the family
 		$this->module_position = 500;
 		// Gives the possibility to the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
-		$this->familyinfo = array('myownfamily' => array('position' => '001', 'label' => $langs->trans("MyOwnFamily")));
+		//$this->familyinfo = array('myownfamily' => array('position' => '001', 'label' => $langs->trans("MyOwnFamily")));
 
 		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
 		$this->name = preg_replace('/^mod/i','',get_class($this));
 		// Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
 		$this->description = "Description of module MyModule";
+		$this->descriptionlong = "A very lon description. Can be a full HTML content";
+		$this->editor_name = 'Editor name';
+		$this->editor_url = 'http://www.dolibarr.org';
 		
-		// Possible values for version are: 'development', 'experimental', 'dolibarr' or 'dolibarr_deprecated' or version
+		// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
 		$this->version = '1.0';
 		// Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase)
 		$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
-		// Where to store the module in setup page (0=common,1=interface,2=others,3=very specific)
-		$this->special = 0;
 		// Name of image file used for this module.
 		// If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
 		// If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'

+ 1 - 2
dev/skeletons/skeleton_class.class.php

@@ -71,7 +71,6 @@ class Skeleton_Class extends CommonObject
 	public function __construct(DoliDB $db)
 	{
 		$this->db = $db;
-		return 1;
 	}
 
 	/**
@@ -249,7 +248,7 @@ class Skeleton_Class extends CommonObject
 				$line->prop1 = $obj->field1;
 				$line->prop2 = $obj->field2;
 
-				$this->lines[] = $line;
+				$this->lines[$line->id] = $line;
 				//...
 			}
 			$this->db->free($resql);

+ 60 - 16
dev/skeletons/skeleton_list.php

@@ -43,7 +43,9 @@ if (! $res && file_exists("../../../dolibarr/htdocs/main.inc.php")) $res=@includ
 if (! $res && file_exists("../../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../../dolibarr/htdocs/main.inc.php';   // Used on dev env only
 if (! $res) die("Include of main fails");
 // Change this following line to use the correct relative path from htdocs
-include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php');
+require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php');
+require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
 dol_include_once('/mymodule/class/skeleton_class.class.php');
 
 // Load traductions files requiredby by page
@@ -58,6 +60,7 @@ $myparam	= GETPOST('myparam','alpha');
 
 $search_field1=GETPOST("search_field1");
 $search_field2=GETPOST("search_field2");
+$search_myfield=GETPOST('search_myfield');
 $optioncss = GETPOST('optioncss','alpha');
 
 // Load variable for pagination
@@ -123,6 +126,9 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab
 * Put here all code to do according to value of "action" parameter
 ********************************************************************/
 
+if (GETPOST('cancel')) { $action='list'; $massaction=''; }
+if (! GETPOST('confirmmassaction')) { $massaction=''; }
+
 $parameters=array();
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
@@ -141,6 +147,19 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") ||GETPO
 
 if (empty($reshook))
 {
+    // Mass actions. Controls on number of lines checked
+    $maxformassaction=1000;
+    if (! empty($massaction) && count($toselect) < 1)
+    {
+        $error++;
+        setEventMessages($langs->trans("NoLineChecked"), null, "warnings");
+    }
+    if (! $error && count($toselect) > $maxformassaction)
+    {
+        setEventMessages($langs->trans('TooManyRecordForMassAction',$maxformassaction), null, 'errors');
+        $error++;
+    }
+    
 	// Action to delete
 	if ($action == 'confirm_delete')
 	{
@@ -216,7 +235,7 @@ foreach ($search_array_options as $key => $val)
     $tmpkey=preg_replace('/search_options_/','',$key);
     $typ=$extrafields->attribute_type[$tmpkey];
     $mode=0;
-    if (in_array($typ, array('int'))) $mode=1;    // Search on a numeric
+    if (in_array($typ, array('int','double'))) $mode=1;    // Search on a numeric
     if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit))) 
     {
         $sql .= natural_search('ef.'.$tmpkey, $crit, $mode);
@@ -265,6 +284,7 @@ if ($resql)
     if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
 	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
 	print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
+    print '<input type="hidden" name="action" value="list">';
 	print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
 	print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
 	
@@ -274,6 +294,11 @@ if ($resql)
         print $langs->trans("FilterOnInto", $all) . join(', ',$fieldstosearchall);
     }
     
+    $moreforfilter = '';
+    $moreforfilter.='<div class="divsearchfield">';
+    $moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escpae_htmltag($search_myfield).'">';
+    $moreforfilter.= '</div>';
+    
 	if (! empty($moreforfilter))
 	{
 		print '<div class="liste_titre liste_titre_bydiv centpercent">';
@@ -291,8 +316,8 @@ if ($resql)
 
     // Fields title
     print '<tr class="liste_titre">';
-    if (! empty($arrayfields['t.field1']['checked'])) print_liste_field_titre($langs->trans('field1'),$_SERVER['PHP_SELF'],'t.field1','',$param,'',$sortfield,$sortorder);
-    if (! empty($arrayfields['t.field2']['checked'])) print_liste_field_titre($langs->trans('field2'),$_SERVER['PHP_SELF'],'t.field2','',$param,'',$sortfield,$sortorder);
+    if (! empty($arrayfields['t.field1']['checked'])) print_liste_field_titre($arrayfields['t.field1']['label'],$_SERVER['PHP_SELF'],'t.field1','',$param,'',$sortfield,$sortorder);
+    if (! empty($arrayfields['t.field2']['checked'])) print_liste_field_titre($arrayfields['t.field2']['label'],$_SERVER['PHP_SELF'],'t.field2','',$param,'',$sortfield,$sortorder);
 	// Extra fields
 	if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
 	{
@@ -309,8 +334,8 @@ if ($resql)
 	$parameters=array('arrayfields'=>$arrayfields);
     $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters);    // Note that $action and $object may have been modified by hook
     print $hookmanager->resPrint;
-	if (! empty($arrayfields['t.datec']['checked']))  print_liste_field_titre($langs->trans("DateCreationShort"),$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
-	if (! empty($arrayfields['t.tms']['checked']))    print_liste_field_titre($langs->trans("DateModificationShort"),$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
+	if (! empty($arrayfields['t.datec']['checked']))  print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
+	if (! empty($arrayfields['t.tms']['checked']))    print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
 	//if (! empty($arrayfields['t.status']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"t.status","",$param,'align="center"',$sortfield,$sortorder);
 	print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch ');
     print '</tr>'."\n";
@@ -329,12 +354,15 @@ if ($resql)
                 $align=$extrafields->getAlignFlag($key);
                 $typeofextrafield=$extrafields->attribute_type[$key];
                 print '<td class="liste_titre'.($align?' '.$align:'').'">';
-                if (in_array($typeofextrafield, array('varchar', 'int', 'select')))
-                {
-                   $crit=$val;
-                			$tmpkey=preg_replace('/search_options_/','',$key);
-                			print '<input class="flat" size="4" type="text" name="search_options_'.$tmpkey.'" value="'.dol_escape_htmltag($search_array_options['search_options_'.$tmpkey]).'">';
-                }
+            	if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select')))
+				{
+				    $crit=$val;
+    				$tmpkey=preg_replace('/search_options_/','',$key);
+    				$searchclass='';
+    				if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring';
+    				if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum';
+    				print '<input class="flat'.($searchclass?' '.$searchclass:'').'" size="4" type="text" name="search_options_'.$tmpkey.'" value="'.dol_escape_htmltag($search_array_options['search_options_'.$tmpkey]).'">';
+				}
                 print '</td>';
             }
         }
@@ -370,7 +398,9 @@ if ($resql)
 	print '</tr>'."\n";
         
     
-    $i = 0;
+	$i=0;
+	$var=true;
+	$totalarray=array();
     while ($i < min($num, $limit))
     {
         $obj = $db->fetch_object($resql);
@@ -378,8 +408,16 @@ if ($resql)
         {
             // You can use here results
             print '<tr>';
-            if (! empty($arrayfields['t.field1']['checked'])) print '<td>'.$obj->field1.'</td>';
-            if (! empty($arrayfields['t.field2']['checked'])) print '<td>'.$obj->field2.'</td>';
+            if (! empty($arrayfields['t.field1']['checked'])) 
+            {
+                print '<td>'.$obj->field1.'</td>';
+    		    if (! $i) $totalarray['nbfield']++;
+            }
+            if (! empty($arrayfields['t.field2']['checked'])) 
+            {
+                print '<td>'.$obj->field2.'</td>';
+    		    if (! $i) $totalarray['nbfield']++;
+            }
         	// Extra fields
     		if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
     		{
@@ -394,6 +432,7 @@ if ($resql)
     					$tmpkey='options_'.$key;
     					print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1);
     					print '</td>';
+    		            if (! $i) $totalarray['nbfield']++;
     				}
     		   }
     		}
@@ -407,6 +446,7 @@ if ($resql)
                 print '<td align="center">';
                 print dol_print_date($db->jdate($obj->date_creation), 'dayhour');
                 print '</td>';
+    		    if (! $i) $totalarray['nbfield']++;
             }
             // Date modification
             if (! empty($arrayfields['t.tms']['checked']))
@@ -414,6 +454,7 @@ if ($resql)
                 print '<td align="center">';
                 print dol_print_date($db->jdate($obj->date_update), 'dayhour');
                 print '</td>';
+    		    if (! $i) $totalarray['nbfield']++;
             }
             // Status
             /*
@@ -422,9 +463,12 @@ if ($resql)
     		  $userstatic->statut=$obj->statut;
               print '<td align="center">'.$userstatic->getLibStatut(3).'</td>';
             }*/
+
             // Action column
             print '<td></td>';
-    		print '</tr>';
+            if (! $i) $totalarray['nbfield']++;
+
+            print '</tr>';
         }
         $i++;
     }

BIN
doc/images/dolibarr_screenshot1_1280x800.png


BIN
doc/images/dolibarr_screenshot1_300x188.png


BIN
doc/images/dolibarr_screenshot1_640x400.png


+ 11 - 9
htdocs/accountancy/admin/account.php

@@ -43,7 +43,9 @@ $search_pcgtype = GETPOST("search_pcgtype");
 $search_pcgsubtype = GETPOST("search_pcgsubtype");
 
 // Security check
-if (! $user->admin)
+if ($user->societe_id > 0)
+	accessforbidden();
+if (! $user->rights->accounting->chartofaccount)
 	accessforbidden();
 
 $sortfield = GETPOST("sortfield", 'alpha');
@@ -145,8 +147,8 @@ if ($result) {
 	print '<br/>';
 	
 	print '<a class="butAction" href="./card.php?action=create">' . $langs->trans("Addanaccount") . '</a>';
-	print '<a class="butAction" href="./importaccounts.php">' . $langs->trans("ImportAccount") . '</a>';
-	print '<a class="butAction" href="./productaccount.php">' . $langs->trans("CheckProductAccountancyCode") . '</a>';
+	// print '<a class="butAction" href="./importaccounts.php">' . $langs->trans("ImportAccount") . '</a>';
+	// print '<a class="butAction" href="./productaccount.php">' . $langs->trans("CheckProductAccountancyCode") . '</a>';
 	print '<br/><br/>';
 	
 	print '<table class="noborder" width="100%">';
@@ -161,11 +163,11 @@ if ($result) {
 	print '</tr>';
 	
 	print '<tr class="liste_titre">';
-	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_account" value="' . $search_account . '"></td>';
-	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_label" value="' . $search_label . '"></td>';
-	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_accountparent" value="' . $search_accountparent . '"></td>';
-	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_pcgtype" value="' . $search_pcgtype . '"></td>';
-	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_pcgsubtype" value="' . $search_pcgsubtype . '"></td>';
+	print '<td class="liste_titre"><input type="text" class="flat" size="10" name="search_account" value="' . $search_account . '"></td>';
+	print '<td class="liste_titre"><input type="text" class="flat" size="20" name="search_label" value="' . $search_label . '"></td>';
+	print '<td class="liste_titre"><input type="text" class="flat" size="10" name="search_accountparent" value="' . $search_accountparent . '"></td>';
+	print '<td class="liste_titre"><input type="text" class="flat" size="6" name="search_pcgtype" value="' . $search_pcgtype . '"></td>';
+	print '<td class="liste_titre"><input type="text" class="flat" size="6" name="search_pcgsubtype" value="' . $search_pcgsubtype . '"></td>';
 	print '<td class="liste_titre">&nbsp;</td>';
 	print '<td align="right" colspan="2" class="liste_titre">';
 	print '<input type="image" class="liste_titre" src="' . img_picto($langs->trans("Search"), 'search.png', '', '', 1) . '" name="button_search" value="' . dol_escape_htmltag($langs->trans("Search")) . '" title="' . dol_escape_htmltag($langs->trans("Search")) . '">';
@@ -190,7 +192,7 @@ if ($result) {
 		print '<td>' . $accountstatic->getNomUrl(1) . '</td>';
 		print '<td>' . $obj->label . '</td>';
 
-		if ($obj->account_parent)
+		if (! empty($obj->account_parent))
         {
 			$accountparent->id = $obj->rowid2;
 			$accountparent->label = $obj->label2;

+ 118 - 61
htdocs/accountancy/admin/card.php

@@ -1,6 +1,6 @@
-<?PHP
+<?php
 /* Copyright (C) 2013-2014 Olivier Geffroy      <jeff@jeffinfo.com>
- * Copyright (C) 2013-2015 Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2013-2016 Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2014	   Florian Henry		<florian.henry@open-concept.pro>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -18,9 +18,9 @@
  */
 
 /**
- * \file htdocs/accountancy/admin/card.php
- * \ingroup Accounting Expert
- * \brief Card accounting account
+ * \file 		htdocs/accountancy/admin/card.php
+ * \ingroup 	Advanced accountancy
+ * \brief 		Card of accounting account
  */
 require '../../main.inc.php';
 
@@ -28,6 +28,7 @@ require '../../main.inc.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php';
 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/html.formventilation.class.php';
+require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
 
 $error = 0;
 
@@ -45,7 +46,7 @@ $cancel = GETPOST('cancel');
 if (! $user->admin)
 	accessforbidden();
 
-$accounting = new AccountingAccount($db);
+$object = new AccountingAccount($db);
 
 // Action
 if ($action == 'add') {
@@ -55,16 +56,25 @@ if ($action == 'add') {
 		dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
 		$result = $db->query($sql);
 		$obj = $db->fetch_object($result);
+
+		// Clean code
+		$account_number = clean_account(GETPOST('account_number')); // Accounting account without zero on the right
+		if (GETPOST('account_category') <= 0) {
+			$account_parent = '';
+		} else {
+			$account_parent = GETPOST('account_category','int');
+		}
 		
-		$accounting->fk_pcg_version = $obj->pcg_version;
-		$accounting->pcg_type = GETPOST('pcg_type');
-		$accounting->pcg_subtype = GETPOST('pcg_subtype');
-		$accounting->account_number = GETPOST('account_number');
-		$accounting->account_parent = GETPOST('account_parent', 'int');
-		$accounting->label = GETPOST('label', 'alpha');
-		$accounting->active = 1;
+		$object->fk_pcg_version = $obj->pcg_version;
+		$object->pcg_type = GETPOST('pcg_type');
+		$object->pcg_subtype = GETPOST('pcg_subtype');
+		$object->account_number = $account_number;
+		$object->account_parent = $account_parent;
+		$object->account_category = GETPOST('account_category');
+		$object->label = GETPOST('label', 'alpha');
+		$object->active = 1;
 		
-		$res = $accounting->create($user);
+		$res = $object->create($user);
 		
 		if ($res == 0) {
 		} else {
@@ -81,22 +91,31 @@ if ($action == 'add') {
 	Header("Location: account.php");
 } else if ($action == 'edit') {
 	if (! GETPOST('cancel', 'alpha')) {
-		$result = $accounting->fetch($id);
+		$result = $object->fetch($id);
 		
 		$sql = 'SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid=' . $conf->global->CHARTOFACCOUNTS;
 		
 		dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
 		$result2 = $db->query($sql);
 		$obj = $db->fetch_object($result2);
+
+		// Clean code
+		$account_number = clean_account(GETPOST('account_number')); // Accounting account without zero on the right
+		if (GETPOST('account_category') <= 0) {
+			$account_parent = '';
+		} else {
+			$account_parent = GETPOST('account_category','int');
+		}
+
+		$object->fk_pcg_version = $obj->pcg_version;
+		$object->pcg_type = GETPOST('pcg_type');
+		$object->pcg_subtype = GETPOST('pcg_subtype');
+		$object->account_number = $account_number;
+		$object->account_parent = $account_parent;
+		$object->account_category = GETPOST('account_category');
+		$object->label = GETPOST('label', 'alpha');
 		
-		$accounting->fk_pcg_version = $obj->pcg_version;
-		$accounting->pcg_type = GETPOST('pcg_type');
-		$accounting->pcg_subtype = GETPOST('pcg_subtype');
-		$accounting->account_number = GETPOST('account_number');
-		$accounting->account_parent = GETPOST('account_parent', 'int');
-		$accounting->label = GETPOST('label', 'alpha');
-		
-		$result = $accounting->update($user);
+		$result = $object->update($user);
 		
 		if ($result > 0) {
 			header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id);
@@ -109,10 +128,10 @@ if ($action == 'add') {
 		exit();
 	}
 } else if ($action == 'delete') {
-	$result = $accounting->fetch($id);
+	$result = $object->fetch($id);
 	
-	if (! empty($accounting->id)) {
-		$result = $accounting->delete($user);
+	if (! empty($object->id)) {
+		$result = $object->delete($user);
 		
 		if ($result > 0) {
 			Header("Location: account.php");
@@ -120,7 +139,7 @@ if ($action == 'add') {
 	}
 	
 	if ($result < 0) {
-		setEventMessages($accounting->error, $accounting->errors, 'errors');
+		setEventMessages($object->error, $object->errors, 'errors');
 	}
 }
 
@@ -131,7 +150,9 @@ llxheader('', $langs->trans('AccountAccounting'));
 
 $form = new Form($db);
 $htmlacc = new FormVentilation($db);
+$formaccounting = new FormAccounting($db);
 
+// Create mode
 if ($action == 'create') {
 	print load_fiche_titre($langs->trans('NewAccount'));
 	
@@ -142,22 +163,37 @@ if ($action == 'create') {
 	dol_fiche_head();
 	
 	print '<table class="border" width="100%">';
-	
+
+	// Account number
 	print '<tr><td width="25%"><span class="fieldrequired">' . $langs->trans("AccountNumber") . '</span></td>';
-	print '<td><input name="account_number" size="30" value="' . $accounting->account_number . '"</td></tr>';
+	print '<td><input name="account_number" size="30" value="' . $object->account_number . '"</td></tr>';
+
+	// Label
 	print '<tr><td><span class="fieldrequired">' . $langs->trans("Label") . '</span></td>';
-	print '<td><input name="label" size="70" value="' . $accounting->label . '"</td></tr>';
+	print '<td><input name="label" size="70" value="' . $object->label . '"</td></tr>';
+
+	// Account parent
 	print '<tr><td>' . $langs->trans("Accountparent") . '</td>';
 	print '<td>';
-	print $htmlacc->select_account($accounting->account_parent, 'account_parent', 1);
+	print $htmlacc->select_account($object->account_parent, 'account_parent', 1);
+	print '</td></tr>';
+
+	// Category
+	print '<tr><td>' . $langs->trans("AccountingCategory") . '</td>';
+	print '<td>';
+	$formaccounting->select_accounting_category($object->account_category, 'account_category', 1);
 	print '</td></tr>';
+
+	// Chart of accounts type
 	print '<tr><td>' . $langs->trans("Pcgtype") . '</td>';
 	print '<td>';
-	print $htmlacc->select_pcgtype($accounting->pcg_type, 'pcg_type');
+	print $htmlacc->select_pcgtype($object->pcg_type, 'pcg_type');
 	print '</td></tr>';
+
+	// Chart of acounts subtype
 	print '<tr><td>' . $langs->trans("Pcgsubtype") . '</td>';
 	print '<td>';
-	print $htmlacc->select_pcgsubtype($accounting->pcg_subtype, 'pcg_subtype');
+	print $htmlacc->select_pcgsubtype($object->pcg_subtype, 'pcg_subtype');
 	print '</td></tr>';
 	
 	print '</table>';
@@ -172,20 +208,16 @@ if ($action == 'create') {
 	
 	print '</form>';
 } else if ($id) {
-	$rowid = $id;
-	$account = $accounting->fetch($rowid);
+	$result = $object->fetch($id);
 	
-	if ($account > 0) {
+	if ($result > 0) {
 		dol_htmloutput_mesg($mesg);
 		
-		$head = accounting_prepare_head($accounting);
+		$head = accounting_prepare_head($object);
 		
-		if ($action == 'update') {
-			$soc = new Societe($db);
-			if ($object->socid) {
-				$soc->fetch($object->socid);
-			}
-			
+		// Edit mode
+		if ($action == 'update') 
+		{
 			dol_fiche_head($head, 'card', $langs->trans('AccountAccounting'), 0, 'billr');
 			
 			print '<form name="update" action="' . $_SERVER["PHP_SELF"] . '" method="POST">' . "\n";
@@ -195,21 +227,36 @@ if ($action == 'create') {
 			
 			print '<table class="border" width="100%">';
 			
+			// Account number
 			print '<tr><td width="25%"><span class="fieldrequired">' . $langs->trans("AccountNumber") . '</span></td>';
-			print '<td><input name="account_number" size="30" value="' . $accounting->account_number . '"</td></tr>';
+			print '<td><input name="account_number" size="30" value="' . $object->account_number . '"</td></tr>';
+			
+			// Label
 			print '<tr><td><span class="fieldrequired">' . $langs->trans("Label") . '</span></td>';
-			print '<td><input name="label" size="70" value="' . $accounting->label . '"</td></tr>';
+			print '<td><input name="label" size="70" value="' . $object->label . '"</td></tr>';
+			
+			// Account parent
 			print '<tr><td>' . $langs->trans("Accountparent") . '</td>';
 			print '<td>';
-			print $htmlacc->select_account($accounting->account_parent, 'account_parent', 1);
+			print $htmlacc->select_account($object->account_parent, 'account_parent', 1);
 			print '</td></tr>';
+
+			// Category
+            print '<tr><td>'.$langs->trans("AccountingCategory").'</td>';
+			print '<td>';
+            $formaccounting->select_accounting_category($object->account_category, 'account_category', 1);
+            print '</td></tr>';
+
+			// Chart of accounts type
 			print '<tr><td>' . $langs->trans("Pcgtype") . '</td>';
 			print '<td>';
-			print $htmlacc->select_pcgtype($accounting->pcg_type, 'pcg_type');
+			print $htmlacc->select_pcgtype($object->pcg_type, 'pcg_type');
 			print '</td></tr>';
+
+			// Chart of accounts subtype
 			print '<tr><td>' . $langs->trans("Pcgsubtype") . '</td>';
 			print '<td>';
-			print $htmlacc->select_pcgsubtype($accounting->pcg_subtype, 'pcg_subtype');
+			print $htmlacc->select_pcgsubtype($object->pcg_subtype, 'pcg_subtype');
 			print '</td></tr>';
 			
 			print '</table>';
@@ -224,6 +271,8 @@ if ($action == 'create') {
 			
 			print '</form>';
 		} else {
+			
+			// View mode
 			$linkback = '<a href="../admin/account.php">' . $langs->trans("BackToChartofaccounts") . '</a>';
 			
 			dol_fiche_head($head, 'card', $langs->trans('AccountAccounting'), 0, 'billr');
@@ -232,29 +281,37 @@ if ($action == 'create') {
 			
 			// Account number
 			print '<tr><td width="25%">' . $langs->trans("AccountNumber") . '</td>';
-			print '<td>' . $accounting->account_number . '</td>';
+			print '<td>' . $object->account_number . '</td>';
 			print '<td align="right" width="25%">' . $linkback . '</td></tr>';
-			
+
+			// Label
 			print '<tr><td>' . $langs->trans("Label") . '</td>';
-			print '<td colspan="2">' . $accounting->label . '</td></tr>';
-			
+			print '<td colspan="2">' . $object->label . '</td></tr>';
+
+			// Account parent
 			$accp = new AccountingAccount($db);
-			if (! empty($accounting->account_parent)) {
-				$accp->fetch($accounting->account_parent, '');
+			if (! empty($object->account_parent)) {
+				$accp->fetch($object->account_parent, '');
 			}
 			print '<tr><td>' . $langs->trans("Accountparent") . '</td>';
 			print '<td colspan="2">' . $accp->account_number . ' - ' . $accp->label . '</td></tr>';
-			
+
+			// Category
+			print "<tr><td>".$langs->trans("AccountingCategory")."</td><td colspan='2'>".$object->account_category_label."</td>";
+
+			// Chart of accounts type
 			print '<tr><td>' . $langs->trans("Pcgtype") . '</td>';
-			print '<td colspan="2">' . $accounting->pcg_type . '</td></tr>';
-			
+			print '<td colspan="2">' . $object->pcg_type . '</td></tr>';
+
+			// Chart of accounts subtype
 			print '<tr><td>' . $langs->trans("Pcgsubtype") . '</td>';
-			print '<td colspan="2">' . $accounting->pcg_subtype . '</td></tr>';
-			
+			print '<td colspan="2">' . $object->pcg_subtype . '</td></tr>';
+
+			// Active
 			print '<tr><td>' . $langs->trans("Activated") . '</td>';
 			print '<td colspan="2">';
 			
-			if (empty($accounting->active)) {
+			if (empty($object->active)) {
 				print img_picto($langs->trans("Disabled"), 'switch_off');
 			} else {
 				print img_picto($langs->trans("Activated"), 'switch_on');
@@ -267,7 +324,7 @@ if ($action == 'create') {
 			dol_fiche_end();
 			
 			/*
-			 * Barre d'actions
+			 * Actions buttons
 			 */
 			
 			print '<div class="tabsAction">';

+ 9 - 11
htdocs/accountancy/admin/export.php

@@ -21,15 +21,16 @@
  */
 
 /**
- * \file htdocs/accountancy/admin/export.php
- * \ingroup Accounting Expert
- * \brief Setup page to configure accounting expert module
+ * \file 		htdocs/accountancy/admin/export.php
+ * \ingroup 	Advanced accountancy
+ * \brief 		Setup page to configure accounting expert module
  */
 require '../../main.inc.php';
 
 // Class
 require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
+require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountancyexport.class.php';
 
 $langs->load("compta");
 $langs->load("bills");
@@ -49,12 +50,14 @@ $main_option = array (
 
 $model_option = array (
 		'ACCOUNTING_EXPORT_SEPARATORCSV',
-		'ACCOUNTING_EXPORT_DATE',
+		'ACCOUNTING_EXPORT_DATE'
+		/*
 		'ACCOUNTING_EXPORT_PIECE',
 		'ACCOUNTING_EXPORT_GLOBAL_ACCOUNT',
 		'ACCOUNTING_EXPORT_LABEL',
 		'ACCOUNTING_EXPORT_AMOUNT',
-		'ACCOUNTING_EXPORT_DEVISE' 
+		'ACCOUNTING_EXPORT_DEVISE'
+		*/
 );
 
 /*
@@ -195,12 +198,7 @@ if (! $conf->use_javascript_ajax) {
 	print "</td>";
 } else {
 	print '<td>';
-	$listmodelcsv = array (
-			'1' => $langs->trans("Modelcsv_normal"),
-			'2' => $langs->trans("Modelcsv_CEGID"),
-			'3' => $langs->trans("Modelcsv_COALA"),
-			'4' => $langs->trans("Modelcsv_bob50") 			
-	);
+	$listmodelcsv = AccountancyExport::getType();
 	print $form->selectarray("modelcsv", $listmodelcsv, $conf->global->ACCOUNTING_EXPORT_MODELCSV, 0);
 	
 	print '</td>';

+ 3 - 3
htdocs/accountancy/admin/importaccounts.php

@@ -19,9 +19,9 @@
  */
 
 /**
- * \file htdocs/accountancy/admin/importaccounts.php
- * \ingroup Accounting Expert
- * \brief Page import accounting account
+ * \file 		htdocs/accountancy/admin/importaccounts.php
+ * \ingroup		Advanced accountancy
+ * \brief 		Page import accounting account
  */
 require '../../main.inc.php';
 

+ 10 - 6
htdocs/accountancy/admin/index.php

@@ -1,7 +1,7 @@
 <?php
 /* Copyright (C) 2013-2014 Olivier Geffroy		<jeff@jeffinfo.com>
  * Copyright (C) 2013-2014 Florian Henry		<florian.henry@open-concept.pro>
- * Copyright (C) 2013-2015 Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2013-2016 Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2014-2015 Ari Elbaz (elarifr)	<github@accedinfo.com>
  * Copyright (C) 2014      Marcos García        <marcosgdf@gmail.com>
  * Copyright (C) 2014	   Juanjo Menent		<jmenent@2byte.es>
@@ -23,9 +23,9 @@
  */
 
 /**
- * \file htdocs/accountancy/admin/index.php
- * \ingroup Accounting Expert
- * \brief Setup page to configure accounting expert module
+ * \file		htdocs/accountancy/admin/index.php
+ * \ingroup		Advanced accountancy
+ * \brief		Setup page to configure accounting expert module
  */
 require '../../main.inc.php';
 
@@ -38,6 +38,7 @@ $langs->load("compta");
 $langs->load("bills");
 $langs->load("admin");
 $langs->load("accountancy");
+$langs->load("salaries");
 
 // Security check
 if (! $user->admin)
@@ -45,7 +46,7 @@ if (! $user->admin)
 
 $action = GETPOST('action', 'alpha');
 
-// Other parameters ACCOUNTING_*
+// Parameters ACCOUNTING_* and others
 $list = array (
 		'ACCOUNTING_LIMIT_LIST_VENTILATION',
 		'ACCOUNTING_LENGTH_DESCRIPTION', // adjust size displayed for lines description for dol_trunc
@@ -63,8 +64,11 @@ $list_account = array (
 		'ACCOUNTING_SERVICE_SOLD_ACCOUNT',
 		'ACCOUNTING_VAT_BUY_ACCOUNT',
 		'ACCOUNTING_VAT_SOLD_ACCOUNT',
+		'ACCOUNTING_VAT_PAY_ACCOUNT',
 		'ACCOUNTING_ACCOUNT_SUSPENSE',
-		'ACCOUNTING_ACCOUNT_TRANSFER_CASH' 
+		'ACCOUNTING_ACCOUNT_TRANSFER_CASH',
+		'SALARIES_ACCOUNTING_ACCOUNT_PAYMENT',
+		'DONATION_ACCOUNTINGACCOUNT'
 );
 
 /*

+ 3 - 3
htdocs/accountancy/admin/journal.php

@@ -22,9 +22,9 @@
  */
 
 /**
- * \file htdocs/accountancy/admin/journal.php
- * \ingroup Accounting Expert
- * \brief Setup page to configure accounting expert module
+ * \file		htdocs/accountancy/admin/journal.php
+ * \ingroup		Advanced accountancy
+ * \brief		Setup page to configure accounting expert module
  */
 require '../../main.inc.php';
 

+ 7 - 7
htdocs/accountancy/admin/productaccount.php

@@ -20,9 +20,9 @@
  */
 
 /**
- * \file 	htdocs/accountancy/admin/productaccount.php
- * \ingroup Accounting Expert
- * \brief 	To define accounting account on product / service
+ * \file		htdocs/accountancy/admin/productaccount.php
+ * \ingroup		Advanced accountancy
+ * \brief		To define accounting account on product / service
  */
 require '../../main.inc.php';
 
@@ -184,7 +184,7 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both
  * View
  */
 
-llxHeader('', $langs->trans("Accounts"));
+llxHeader('', $langs->trans("InitAccountancy"));
 
 print '<script type="text/javascript">
 			$(function () {
@@ -241,7 +241,7 @@ if ($result) {
 	$num_lines = $db->num_rows($result);
 	$i = 0;
 	
-	print_barre_liste($langs->trans("ProductAccountingAccountSelect"), $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, '', $num_lines);
+	print_barre_liste($langs->trans("ModulesSystemTools"), $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, '', $num_lines);
 	print '<br>';
 	
 	print $langs->trans("InitAccountancyDesc") . '<br>';
@@ -263,9 +263,9 @@ if ($result) {
 	
 	print "</table>\n";
 	
-	print '<br /><div align="right"><input type="submit" class="button" value="' . $langs->trans('Modify') . '" name="changetype"></div>';
+	print '<div align="center"><input type="submit" class="button" value="' . $langs->trans('Refresh') . '" name="changetype"></div>';
 	
-	print "<br>\n";
+	print "<br><br>\n";
 	
 	if (! empty($msg)) {
 		print $msg;

+ 24 - 20
htdocs/accountancy/bookkeeping/balance.php

@@ -1,7 +1,7 @@
 <?php
-/* Copyright (C) 2013-2014 Olivier Geffroy		<jeff@jeffinfo.com>
- * Copyright (C) 2013-2016 Florian Henry		<florian.henry@open-concept.pro>
- * Copyright (C) 2013-2015 Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
+/* Copyright (C) 2016 		Olivier Geffroy		<jeff@jeffinfo.com>
+ * Copyright (C) 2016 		Florian Henry		<florian.henry@open-concept.pro>
+ * Copyright (C) 2016 		Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,9 +19,9 @@
  */
 
 /**
- * \file htdocs/accountancy/bookkeeping/balance.php
- * \ingroup Accounting Expert
- * \brief Balance of book keeping
+ *  \file 		htdocs/accountancy/bookkeeping/balance.php
+ *  \ingroup 	Advanced accountancy
+ *  \brief 		Balance of book keeping
  */
 require '../../main.inc.php';
 
@@ -137,7 +137,6 @@ else {
 	/*
 	 * List
 	 */
-
 	$nbtotalofrecords = 0;
 	if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
 		$nbtotalofrecords = $object->fetchAllBalance($sortorder, $sortfield, 0, 0, $filter);
@@ -150,13 +149,12 @@ else {
 	if ($result < 0) {
 		setEventMessages($object->error, $object->errors, 'errors');
 	}
-
-	print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $options, $sortfield, $sortorder, '', $result, $nbtotalofrecords);
-
+	
+	print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $options, $sortfield, $sortorder, '', $result);
+	
 	print '<form method="GET" id="searchFormList" action="' . $_SERVER["PHP_SELF"] . '">';
 	print '<div class="tabsAction">' . "\n";
 	print '<div class="inline-block divButAction"><input type="submit" name="button_export_csv" class="butAction" value="' . $langs->trans("Export") . '" /></div>';
-
 	print '</div>';
 
 	print '<div class="liste_titre">';
@@ -168,7 +166,8 @@ else {
 
 	print '<table class="noborder" width="100%">';
 	print '<tr class="liste_titre">';
-	print_liste_field_titre($langs->trans("Numerocompte"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("AccountAccountingShort"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Labelcompte"), $_SERVER['PHP_SELF'], "t.label_compte", "", $options, "", $sortfield, $sortorder);
 	print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "t.debit", "", $options, 'align="right"', $sortfield, $sortorder);
 	print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "t.credit", "", $options, 'align="right"', $sortfield, $sortorder);
 	print_liste_field_titre($langs->trans("Solde"), $_SERVER["PHP_SELF"], "", $options, "", 'width="60" align="center"', $sortfield, $sortorder);
@@ -176,11 +175,11 @@ else {
 	print "</tr>\n";
 
 	print '<tr class="liste_titre">';
-	print '<td>';
+	print '<td colspan="2">';
 	print $langs->trans('From');
 	print $formventilation->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array (), 1, 1, '');
 	print '<br>';
-	print $langs->trans('To');
+	print $langs->trans('to');
 	print $formventilation->select_account($search_accountancy_code_end, 'search_accountancy_code_end', 1, array (), 1, 1, '');
 	print '</td>';
 
@@ -203,23 +202,28 @@ else {
 
 	foreach ( $object->lines as $line ) {
 		$var = ! $var;
-
+		$link = '';
 		$total_debit += $line->debit;
 		$total_credit += $line->credit;
-
+		$description = $object->get_compte_desc($line->numero_compte); // Search description of the account
+		if(empty($description)){
+			$link = '<a href="../admin/card.php?action=create&compte=' . length_accountg($line->numero_compte) . '">' . img_edit_add() .'</a>';
+		}
 		print "<tr $bc[$var]>";
 
 		print '<td>' . length_accountg($line->numero_compte) . '</td>';
-		print '<td align="right">' . price($line->debit) . '</td>';
-		print '<td align="right">' . price($line->credit) . '</td>';
-		print '<td align="right">' . price($line->credit - $line->debit) . '</td>';
-		print '<td align="center">';
+		print '<td>' . $description . '</td>';
+		print '<td align="right">' .  number_format($line->debit, 2, ',', ' ') . '</td>';
+        print '<td align="right">' . number_format($line->credit, 2, ',', ' ') . '</td>';
+        print '<td align="right">' . number_format($line->credit - $line->debit, 2, ',', ' ') . '</td>';
+		print '<td align="center">' . $link;
 		print '</td>';
 		print "</tr>\n";
 	}
 
 	print '<tr class="liste_total">';
 	print '<td></td>';
+	print '<td></td>';
 	print '<td  align="right">';
 	print price($total_debit);
 	print '</td>';

+ 3 - 3
htdocs/accountancy/bookkeeping/balancebymonth.php

@@ -20,9 +20,9 @@
  */
 
 /**
- * \file htdocs/accountancy/bookkeeping/balancebymonth.php
- * \ingroup Accounting Expert
- * \brief Balance by month
+ * \file		htdocs/accountancy/bookkeeping/balancebymonth.php
+ * \ingroup		Advanced accountancy
+ * \brief		Balance by month
  */
 require '../../main.inc.php';
 

+ 1 - 1
htdocs/accountancy/bookkeeping/card.php

@@ -333,7 +333,7 @@ if ($action == 'create') {
 				
 				print '<tr class="liste_titre">';
 				
-				print_liste_field_titre($langs->trans("Numerocompte"));
+				print_liste_field_titre($langs->trans("AccountAccountingShort"));
 				print_liste_field_titre($langs->trans("Code_tiers"));
 				print_liste_field_titre($langs->trans("Labelcompte"));
 				print_liste_field_titre($langs->trans("Debit"), "", "", "", "", 'align="center"');

+ 25 - 10
htdocs/accountancy/bookkeeping/list.php

@@ -218,16 +218,31 @@ if ($action == 'delbookkeeping') {
 		exit();
 	}
 } elseif ($action == 'export_csv') {
-	$sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
-	$journal = 'bookkepping';
 
-	include DOL_DOCUMENT_ROOT . '/accountancy/tpl/export_journal.tpl.php';
+	include DOL_DOCUMENT_ROOT . '/accountancy/class/accountancyexport.class.php';
 
 	$result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter);
-	if ($result < 0) {
+	if ($result < 0)
+	{
 		setEventMessages($object->error, $object->errors, 'errors');
 	}
+	else
+	{
+		if (in_array($conf->global->ACCOUNTING_EXPORT_MODELCSV, array(5,6))) // TODO remove the conditional and keep the code in the "else"
+		{
+			$accountancyexport = new AccountancyExport($db);
+			$accountancyexport->export($object->lines);
+			if (!empty($accountancyexport->errors)) setEventMessages('', $accountancyexport->errors, 'errors');
+			else exit;
+		}
+	}
+
 
+	// TODO remove next 3 lines and foreach to implement the AccountancyExport method for each model
+	$sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
+	$journal = 'bookkepping';
+	include DOL_DOCUMENT_ROOT . '/accountancy/tpl/export_journal.tpl.php';
+	
 	foreach ( $object->lines as $line ) {
 
 		if ($conf->global->ACCOUNTING_EXPORT_MODELCSV == 2) {
@@ -365,12 +380,12 @@ else {
 	print_liste_field_titre($langs->trans("NumPiece"), $_SERVER['PHP_SELF'], "t.piece_num", "", $options, "", $sortfield, $sortorder);
 	print_liste_field_titre($langs->trans("Docdate"), $_SERVER['PHP_SELF'], "t.doc_date", "", $options, "", $sortfield, $sortorder);
 	print_liste_field_titre($langs->trans("Docref"), $_SERVER['PHP_SELF'], "t.doc_ref", "", $options, "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Numerocompte"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("AccountAccountingShort"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder);
 	print_liste_field_titre($langs->trans("Code_tiers"), $_SERVER['PHP_SELF'], "t.code_tiers", "", $options, "", $sortfield, $sortorder);
 	print_liste_field_titre($langs->trans("Labelcompte"), $_SERVER['PHP_SELF'], "bk_label_compte", "", $options, "", $sortfield, $sortorder);
 	print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "t.debit", "", $options, 'align="right"', $sortfield, $sortorder);
 	print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "t.credit", "", $options, 'align="right"', $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Codejournal"), $_SERVER['PHP_SELF'], "t.code_journal", "", $options, 'align="right"', $sortfield, $sortorder);
+	print_liste_field_titre($langs->trans("Codejournal"), $_SERVER['PHP_SELF'], "t.code_journal", "", $options, 'align="center"', $sortfield, $sortorder);
 	print_liste_field_titre($langs->trans("Action"), $_SERVER["PHP_SELF"], "", $options, "", 'width="60" align="center"', $sortfield, $sortorder);
 	print "</tr>\n";
 
@@ -381,7 +396,7 @@ else {
 	print $langs->trans('From') . ': ';
 	print $form->select_date($search_date_start, 'date_start', 0, 0, 1);
 	print '<br>';
-	print $langs->trans('To') . ': ';
+	print $langs->trans('to') . ': ';
 	print $form->select_date($search_date_end, 'date_end', 0, 0, 1);
 	print '</td>';
 	print '<td><input type="text" name="search_doc_ref" size="8" value="' . $search_doc_ref . '"></td>';
@@ -389,14 +404,14 @@ else {
 	print $langs->trans('From');
 	print $formventilation->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array (), 1, 1, '');
 	print '<br>';
-	print $langs->trans('To');
+	print $langs->trans('to');
 	print $formventilation->select_account($search_accountancy_code_end, 'search_accountancy_code_end', 1, array (), 1, 1, '');
 	print '</td>';
 	print '<td>';
 	print $langs->trans('From');
 	print $formventilation->select_auxaccount($search_accountancy_aux_code_start, 'search_accountancy_aux_code_start', 1);
 	print '<br>';
-	print $langs->trans('To');
+	print $langs->trans('to');
 	print $formventilation->select_auxaccount($search_accountancy_aux_code_end, 'search_accountancy_aux_code_end', 1);
 	print '</td>';
 
@@ -435,7 +450,7 @@ else {
 		print '<td>' . $line->label_compte . '</td>';
 		print '<td align="right">' . price($line->debit) . '</td>';
 		print '<td align="right">' . price($line->credit) . '</td>';
-		print '<td align="right">' . $line->code_journal . '</td>';
+		print '<td align="center">' . $line->code_journal . '</td>';
 		print '<td align="center">';
 		print '<a href="./card.php?piece_num=' . $line->piece_num . '">' . img_edit() . '</a>&nbsp;';
 		print '<a href="' . $_SERVER['PHP_SELF'] . '?action=delmouv&mvt_num=' . $line->piece_num . $options . '&page=' . $page . '">' . img_delete() . '</a>';

+ 386 - 0
htdocs/accountancy/class/accountancycategory.class.php

@@ -0,0 +1,386 @@
+<?php
+/* Copyright (C) 2016		Jamal Elbaz			<jamelbaz@gmail.pro>
+ * Copyright (C) 2016 		Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *	\file       htdocs/accountancy/class/accountancycategory.class.php
+ *	\ingroup    Advanced accountancy
+ *	\brief      File of class to manage categories of an accounting account_category
+ */
+
+// Class
+require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
+
+/**
+ * Class to manage categories of an accounting account
+ */
+class AccountancyCategory
+{
+	private $db;
+	public $error;
+	public $errors = array();
+	//public $element='accounting_category';
+	//public $table_element='c_accounting_category';
+	public $id;
+
+	/**
+	 *	Constructor
+	 *
+	 *	@param 		DoliDB		$db		Database handler
+	 */
+	public function __construct($db)
+	{
+		$this->db = $db;
+
+		return 1;
+	}
+
+	/**
+	 * Function to select all accounting accounts from an accounting category
+	 *
+	 * @param 	int 	$id 		Id
+	 *
+	 * @return int <0 if KO, 0 if not found, >0 if OK
+	 */ 
+	public function display($id)
+	{
+		$sql = "SELECT t.rowid, t.account_number, t.label";
+		$sql.= " FROM " . MAIN_DB_PREFIX . "accounting_account as t";
+		$sql.= " WHERE t.fk_accounting_category = " . $id;
+
+		dol_syslog(__METHOD__ . " sql=" . $sql, LOG_DEBUG);
+		$resql = $this->db->query($sql);
+		if ($resql) {
+			$i = 0;
+			$obj = '';
+			$num = $this->db->num_rows($resql);
+			if ($num) {
+				while ( $i < $num ) {
+					$obj[$i] = $this->db->fetch_object($resql);
+					$i ++;
+				}
+			}
+
+			return $obj;
+		} else {
+			$this->error = "Error " . $this->db->lasterror();
+			dol_syslog(__METHOD__ . " " . $this->error, LOG_ERR);
+
+			return -1;
+		}
+	}
+
+	/**
+	 * Function to select accountiing category of an accounting account present in chart of accounts
+	 *
+	 * @param 	int 	$id 		Id category
+	 *
+	 * @return int <0 if KO, 0 if not found, >0 if OK
+	 */
+	public function getCptBK($id)
+	{
+		global $conf;
+
+		$sql = "SELECT t.numero_compte, t.label_compte, t.doc_ref";
+		$sql.= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as t";
+		$sql.= " WHERE t.numero_compte NOT IN (";
+		$sql.= " SELECT t.account_number";		
+		$sql.= " FROM " . MAIN_DB_PREFIX . "accounting_account as t";
+		$sql.= " WHERE t.fk_accounting_category = " . $id .")";
+		$sql.= " AND t.numero_compte IN (";
+		$sql.= " SELECT DISTINCT aa.account_number";
+		$sql.= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa";
+		$sql.= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
+		$sql.= " AND asy.rowid = " . $conf->global->CHARTOFACCOUNTS;
+		$sql.= " AND aa.active = 1)";
+		$sql.= " GROUP BY t.numero_compte";
+
+		dol_syslog(__METHOD__ . " sql=" . $sql, LOG_DEBUG);
+		$resql = $this->db->query($sql);
+		if ($resql) {
+			$i = 0;
+			$obj = '';
+			$num = $this->db->num_rows($resql);
+			if ($num) {
+				while ( $i < $num ) {
+					$obj[$i] = $this->db->fetch_object($resql);
+					$i ++;
+				}
+			}
+
+			return $obj;
+		} else {
+			$this->error = "Error " . $this->db->lasterror();
+			dol_syslog(__METHOD__ . " " . $this->error, LOG_ERR);
+
+			return -1;
+		}
+	}
+	
+	/**
+	 * Function to add an accounting account in an accounting category
+	 *
+	 * @param	int		$id_cat		Id category
+	 * @param 	array	$cpts		list of accounts array
+	 *
+	 * @return int <0 if KO, >0 if OK
+	 */
+	public function updateAccAcc($id_cat, $cpts = array())
+	{
+		global $conf;
+		$error = 0;
+
+		$sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account as aa";
+		$sql.= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
+		$sql.= " AND asy.rowid = " . $conf->global->CHARTOFACCOUNTS;
+		$sql.= " AND aa.active = 1";
+		$sql.= " SET fk_accounting_category=" . $id_cat;
+		$sql.= " WHERE aa.account_number IN (" . join(',',$cpts) .")";
+		$this->db->begin();
+
+		dol_syslog(__METHOD__ . " sql=" . $sql, LOG_DEBUG);
+		$resql = $this->db->query($sql);
+		if (! $resql) {
+			$error ++;
+			$this->errors[] = "Error " . $this->db->lasterror();
+		}
+
+		// Commit or rollback
+		if ($error) {
+			foreach ($this->errors as $errmsg) {
+				dol_syslog(__METHOD__ . " " . $errmsg, LOG_ERR);
+				$this->error.=($this->error ? ', ' . $errmsg : $errmsg);
+			}
+			$this->db->rollback();
+
+			return -1 * $error;
+		} else {
+			$this->db->commit();
+
+			return 1;
+		}
+	}
+
+	/**
+	 * Function to delete an accounting account from an accounting category
+	 *
+	 * @param	int		$cpt_id		Id of accounting account
+	 *
+	 * @return int <0 if KO, >0 if OK
+	 */
+	public function deleteCptCat($cpt_id)
+	{
+		$error = 0;
+
+		$sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account as aa";
+		$sql.= " SET fk_accounting_category= 0";
+		$sql.= " WHERE aa.rowid= " . $cpt_id;
+		$this->db->begin();
+
+		dol_syslog(__METHOD__ . " sql=" . $sql, LOG_DEBUG);
+		$resql = $this->db->query($sql);
+		if (! $resql) {
+			$error ++;
+			$this->errors[] = "Error " . $this->db->lasterror();
+		}
+
+		// Commit or rollback
+		if ($error) {
+			foreach ($this->errors as $errmsg) {
+				dol_syslog(__METHOD__ . " " . $errmsg, LOG_ERR);
+				$this->error.=($this->error ? ', ' . $errmsg : $errmsg);
+			}
+			$this->db->rollback();
+
+			return -1 * $error;
+		} else {
+			$this->db->commit();
+
+			return 1;
+		}
+	}
+
+	/**
+	 * Function to know all category from accounting account
+	 *
+	 * @return		array		Result in table
+	 */
+	public function getCatsCpts()
+	{
+		global $mysoc;
+		$sql = "";
+
+		if (empty($mysoc->country_id) && empty($mysoc->country_code))
+        {
+            dol_print_error('','Call to select_accounting_account with mysoc country not yet defined');
+            exit;
+        }
+
+        if (! empty($mysoc->country_id))
+        {
+			$sql = "SELECT t.rowid, t.account_number, t.label as name_cpt, cat.code, cat.position, cat.label as name_cat, cat.sens ";			
+			$sql.= " FROM " . MAIN_DB_PREFIX . "accounting_account as t, ".MAIN_DB_PREFIX."c_accounting_category as cat";
+			$sql.= " WHERE t.fk_accounting_category IN ( SELECT c.rowid ";
+            $sql.= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c";
+            $sql.= " WHERE c.active = 1";
+            $sql.= " AND c.fk_country = ".$mysoc->country_id.")";
+			$sql.= " AND cat.rowid = t.fk_accounting_category";
+			$sql.= " ORDER BY cat.position ASC";
+        }
+        else
+        {
+            $sql = "SELECT c.rowid, c.code, c.label, c.account_category ";
+            $sql.= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c, ".MAIN_DB_PREFIX."c_country as co";
+            $sql.= " WHERE c.active = 1 AND c.fk_country = co.rowid";
+            $sql.= " AND co.code = '".$mysoc->country_code."'";
+            $sql.= " ORDER BY c.position ASC";
+        }
+		
+        $resql = $this->db->query($sql);
+		if ($resql) {
+			$i = 0;
+			$obj = '';
+			$num = $this->db->num_rows($resql);
+			$data = array();
+			if ($num) {
+				while ( $i < $num ) {
+					$obj = $this->db->fetch_object($resql);
+					$name_cat = $obj->name_cat;
+					$data[$name_cat][$i] =	array(
+											'id' => $obj->rowid,
+											'code' => $obj->code,
+											'position' => $obj->position,
+											'account_number' => $obj->account_number,
+											'name_cpt' => $obj->name_cpt,
+											'sens' => $obj->sens,
+											);
+					$i ++;
+				}
+			}
+			return $data;
+		} else {
+			$this->error = "Error " . $this->db->lasterror();
+			dol_syslog(__METHOD__ . " " . $this->error, LOG_ERR);
+
+			return -1;
+		}
+	}		
+
+	/**
+	 * Function to show result of an accounting account from the general ledger with a sens and a period
+	 * 
+	 * @param	int		$cpt	Id accounting account
+	 * @param	string	$month	Specifig month - Can be empty
+	 * @param	string	$year	Specific year
+	 * @param	int		$sens	Sens of the account 0: credit - debit 1: debit - credit
+	 *
+	 * @return		array		Result in table
+	 */
+	public function getResult($cpt, $month, $year, $sens)
+	{
+		$sql = "SELECT SUM(t.debit) as debit, SUM(t.credit) as credit";		
+		$sql.= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as t";
+		$sql.= " WHERE t.numero_compte = " . $cpt;
+		$sql.= " AND YEAR(t.doc_date) = " . $year;
+
+		if(! empty($month)){
+			$sql.= " AND MONTH(t.doc_date) = " . $month;
+		}
+
+		dol_syslog(__METHOD__ . " sql=" . $sql, LOG_DEBUG);
+		$resql = $this->db->query($sql);
+
+		if ($resql) {
+			$num = $this->db->num_rows($resql);
+			$sdc = 0;
+			if ($num) {
+				$obj = $this->db->fetch_object($resql);
+				if($sens == 1){
+					$sdc = $obj->debit - $obj->credit;					
+				}else{					
+					$sdc = $obj->credit - $obj->debit;
+				}
+			}
+			return $sdc;
+		} else {
+			$this->error = "Error " . $this->db->lasterror();
+			dol_syslog(__METHOD__ . " " . $this->error, LOG_ERR);
+
+			return -1;
+		}
+	}
+
+	/**
+	 * Function to call category from a specific country
+	 *
+	 * @return		array		Result in table
+	 */
+	public function getCatsCal()
+	{
+		global $db,$langs,$user,$mysoc;
+
+        if (empty($mysoc->country_id) && empty($mysoc->country_code))
+        {
+            dol_print_error('','Call to select_accounting_account with mysoc country not yet defined');
+            exit;
+        }
+
+        if (! empty($mysoc->country_id))
+        {
+            $sql = "SELECT c.rowid, c.code, c.label, c.formula, c.position";
+            $sql.= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c";
+            $sql.= " WHERE c.active = 1 AND c.account_category = 1 ";
+            $sql.= " AND c.fk_country = ".$mysoc->country_id;
+            $sql.= " ORDER BY c.position ASC";
+        }
+        else
+        {
+            $sql = "SELECT c.rowid, c.code, c.label, c.formula, c.position";
+            $sql.= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c, ".MAIN_DB_PREFIX."c_country as co";
+            $sql.= " WHERE c.active = 1 AND c.account_category = 1 AND c.fk_country = co.rowid";
+            $sql.= " AND co.code = '".$mysoc->country_code."'";
+			$sql.= " ORDER BY c.position ASC";
+        }
+
+        dol_syslog(__METHOD__ . " sql=" . $sql, LOG_DEBUG);
+		$resql = $this->db->query($sql);
+		if ($resql) {
+			$i = 0;
+			$obj = '';
+			$num = $this->db->num_rows($resql);
+			$data = array();
+			if ($num) {
+				while ( $i < $num ) {
+					$obj = $this->db->fetch_object($resql);
+					$position = $obj->position;
+					$data[$position] = array(
+										'code' => $obj->code,
+										'label' => $obj->label,
+										'formula' => $obj->formula
+										);
+					$i ++;
+				}
+			}
+			return $data;
+		} else {
+			$this->error = "Error " . $this->db->lasterror();
+			dol_syslog(__METHOD__ . " " . $this->error, LOG_ERR);
+
+			return -1;
+		}
+	}
+}

+ 286 - 0
htdocs/accountancy/class/accountancyexport.class.php

@@ -0,0 +1,286 @@
+<?php
+/* Copyright (C) 2007-2012  Laurent Destailleur <eldy@users.sourceforge.net>
+ * Copyright (C) 2014       Juanjo Menent       <jmenent@2byte.es>
+ * Copyright (C) 2015       Florian Henry       <florian.henry@open-concept.pro>
+ * Copyright (C) 2015       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
+ * Copyright (C) 2016		Pierre-Henry Favre	<phf@atm-consulting.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file    htdocs/accountancy/class/accountancyexport.class.php
+ */
+
+/**
+ * Class AccountancyExport
+ *
+ * Manage the different format accountancy export
+ */
+require_once DOL_DOCUMENT_ROOT . '/core/lib/functions.lib.php';
+
+class AccountancyExport
+{
+	/**
+	 * @var Type of export
+	 */
+	public static $EXPORT_TYPE_NORMAL		= 1;
+	public static $EXPORT_TYPE_CEGID	 	= 2;
+	public static $EXPORT_TYPE_COALA		= 3;
+	public static $EXPORT_TYPE_BOB50		= 4;
+	public static $EXPORT_TYPE_CIEL			= 5;
+	public static $EXPORT_TYPE_QUADRATUS	= 6;
+
+	/**
+	 * @var string[] Error codes (or messages)
+	 */
+	public $errors = array();
+
+	/**
+	 * @var string Separator
+	 */
+	public $separator = '';
+
+	/**
+	 * @var string End of line
+	 */
+	public $end_line = '';
+
+	/**
+	 * Constructor
+	 *
+	 * @param DoliDb $db Database handler
+	 */
+	public function __construct(DoliDB &$db)
+	{
+		global $conf;
+
+		$this->db = &$db;
+		$this->separator = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
+		$this->end_line = "\n";
+	}
+
+	/**
+	 * Get all export type are available
+	 *
+	 * @return array of type
+	 */
+	public static function getType()
+	{
+		global $langs;
+
+		return array (
+			self::$EXPORT_TYPE_NORMAL 		=> $langs->trans('Modelcsv_normal'),
+			self::$EXPORT_TYPE_CEGID 		=> $langs->trans('Modelcsv_CEGID'),
+			self::$EXPORT_TYPE_COALA 		=> $langs->trans('Modelcsv_COALA'),
+			self::$EXPORT_TYPE_BOB50 		=> $langs->trans('Modelcsv_bob50'),
+			self::$EXPORT_TYPE_CIEL 		=> $langs->trans('Modelcsv_ciel'),
+			self::$EXPORT_TYPE_QUADRATUS 	=> $langs->trans('Modelcsv_quadratus')
+		);
+	}
+
+	/**
+	 * Download the export
+	 *
+	 * @return void
+	 */
+	public static function downloadFile()
+	{
+		global $conf;
+		$journal = 'bookkepping';
+		include DOL_DOCUMENT_ROOT . '/accountancy/tpl/export_journal.tpl.php';
+	}
+
+	/**
+	 * Function who chose which export to use with the default config
+	 *
+	 * @param unknown $TData data
+	 */
+	public function export(&$TData)
+	{
+		global $conf, $langs;
+
+		switch ($conf->global->ACCOUNTING_EXPORT_MODELCSV) {
+			case self::$EXPORT_TYPE_NORMAL:
+				$this->exportNormal($TData);
+				break;
+			case self::$EXPORT_TYPE_CEGID:
+				$this->exportCegid($TData);
+				break;
+			case self::$EXPORT_TYPE_COALA:
+				$this->exportCoala($TData);
+				break;
+			case self::$EXPORT_TYPE_BOB50:
+				$this->exportBob50($TData);
+				break;
+			case self::$EXPORT_TYPE_CIEL:
+				$this->exportCiel($TData);
+				break;
+			case self::$EXPORT_TYPE_QUADRATUS:
+				$this->exportQuadratus($TData);
+				break;
+			default:
+				$this->errors[] = $langs->trans('accountancy_error_modelnotfound');
+				break;
+		}
+
+		if (empty($this->errors)) self::downloadFile();
+	}
+
+	/**
+	 * Export format : Normal
+	 *
+	 * @param unknown $TData data
+	 *
+	 * @return void
+	 */
+	public function exportNormal(&$TData)
+	{
+
+	}
+
+	/**
+	 * Export format : CEGID
+	 *
+	 * @param unknown $TData data
+	 *
+	 * @return void
+	 */
+	public function exportCegid(&$TData)
+	{
+
+	}
+
+	/**
+	 * Export format : COALA
+	 *
+	 * @param unknown $TData data
+	 *
+	 * @return void
+	 */
+	public function exportCoala(&$TData)
+	{
+
+	}
+
+	/**
+	 * Export format : BOB50
+	 *
+	 * @param unknown $TData data
+	 *
+	 * @return void
+	 */
+	public function exportBob50(&$TData)
+	{
+
+	}
+
+	/**
+	 * Export format : CIEL
+	 *
+	 * @param unknown $TData data
+	 *
+	 * @return void
+	 */
+	public function exportCiel(&$TData)
+	{
+		global $conf;
+
+		$i=1;
+		$date_ecriture = dol_print_date(time(), $conf->global->ACCOUNTING_EXPORT_DATE); // format must be yyyymmdd
+		foreach ($TData as $data)
+		{
+			$code_compta = $data->numero_compte;
+			if (!empty($data->code_tiers)) $code_compta = $data->code_tiers;
+
+			$Tab = array();
+			$Tab['num_ecriture'] = str_pad($i, 5);
+			$Tab['code_journal'] = str_pad($data->code_journal, 2);
+			$Tab['date_ecriture'] = $date_ecriture;
+			$Tab['date_ope'] = dol_print_date($data->doc_date, $conf->global->ACCOUNTING_EXPORT_DATE);
+			$Tab['num_piece'] = str_pad(self::trunc($data->piece_num, 12), 12);
+			$Tab['num_compte'] = str_pad(self::trunc($code_compta, 11), 11);
+			$Tab['libelle_ecriture'] = str_pad(self::trunc($data->doc_ref.$data->label_compte, 25), 25);
+			$Tab['montant'] = str_pad(abs($data->montant), 13, ' ', STR_PAD_LEFT);
+			$Tab['type_montant'] = str_pad($data->sens, 1);
+			$Tab['vide'] = str_repeat(' ', 18);
+			$Tab['intitule_compte'] = str_pad(self::trunc($data->label_compte, 34), 34);
+			$Tab['end'] = 'O2003';
+
+			$Tab['end_line'] = $this->end_line;
+
+			print implode($Tab);
+			$i++;
+		}
+	}
+
+	/**
+	 * Export format : Quadratus
+	 *
+	 * @param unknown $TData data
+	 *
+	 * @return void
+	 */
+	public function exportQuadratus(&$TData)
+	{
+		global $conf;
+
+		$date_ecriture = dol_print_date(time(), $conf->global->ACCOUNTING_EXPORT_DATE); // format must be ddmmyy
+		foreach ($TData as $data)
+		{
+			$code_compta = $data->numero_compte;
+			if (!empty($data->code_tiers)) $code_compta = $data->code_tiers;
+
+			$Tab = array();
+			$Tab['type_ligne'] = 'M';
+			$Tab['num_compte'] = str_pad(self::trunc($code_compta, 8), 8);
+			$Tab['code_journal'] = str_pad(self::trunc($data->code_journal, 2), 2);
+			$Tab['folio'] = '000';
+			$Tab['date_ecriture'] = $date_ecriture;
+			$Tab['filler'] = ' ';
+			$Tab['libelle_ecriture'] = str_pad(self::trunc($data->doc_ref.' '.$data->label_compte, 20), 20);
+			$Tab['sens'] = $data->sens; // C or D
+			$Tab['signe_montant'] = '+';
+			$Tab['montant'] = str_pad(abs($data->montant)*100, 12, '0', STR_PAD_LEFT); // TODO manage negative amount
+			$Tab['contrepartie'] = str_repeat(' ', 8);
+			if (!empty($data->date_echeance)) $Tab['date_echeance'] = dol_print_date($data->date_echeance, $conf->global->ACCOUNTING_EXPORT_DATE);
+			else $Tab['date_echeance'] = '000000';
+			$Tab['lettrage'] = str_repeat(' ', 5);
+			$Tab['num_piece'] = str_pad(self::trunc($data->piece_num, 5), 5);
+			$Tab['filler2'] = str_repeat(' ', 20);
+			$Tab['num_piece2'] = str_pad(self::trunc($data->piece_num, 8), 8);
+			$Tab['devis'] = str_pad($conf->currency, 3);
+			$Tab['code_journal2'] = str_pad(self::trunc($data->code_journal, 3), 3);
+			$Tab['filler3'] = str_repeat(' ', 3);
+			$Tab['libelle_ecriture2'] = str_pad(self::trunc($data->doc_ref.' '.$data->label_compte, 32), 32);
+			$Tab['num_piece3'] = str_pad(self::trunc($data->piece_num, 10), 10);
+			$Tab['filler4'] = str_repeat(' ', 73);
+
+			$Tab['end_line'] = $this->end_line;
+
+			print implode($Tab);
+		}
+	}
+
+	/**
+	 *
+	 * @param unknown $str data
+	 * @param integer $size data
+	 */
+	public static function trunc($str, $size)
+	{
+		return dol_trunc($str, $size, 'right', 'UTF-8', 1);
+	}
+
+}

+ 3 - 3
htdocs/accountancy/class/accountancysystem.class.php

@@ -18,9 +18,9 @@
  */
 
 /**
- * \file htdocs/accountancy/class/accountancysystem.class.php
- * \ingroup Accounting Expert
- * \brief File of class to manage accountancy systems
+ * \file		htdocs/accountancy/class/accountancysystem.class.php
+ * \ingroup		Advanced accountancy
+ * \brief		File of class to manage accountancy systems
  */
 
 /**

+ 28 - 16
htdocs/accountancy/class/accountingaccount.class.php

@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2013-2014 Olivier Geffroy      <jeff@jeffinfo.com>
- * Copyright (C) 2013-2015 Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2013-2016 Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2013-2014 Florian Henry		<florian.henry@open-concept.pro>
  * Copyright (C) 2014 	   Juanjo Menent		<jmenent@2byte.es>
  * Copyright (C) 2015      Ari Elbaz (elarifr)  <github@accedinfo.com>
@@ -20,9 +20,9 @@
  */
 
 /**
- * \file htdocs/accountancy/class/accountingaccount.class.php
- * \ingroup Accounting Expert
- * \brief Fichier de la classe des comptes comptable
+ * \file		htdocs/accountancy/class/accountingaccount.class.php
+ * \ingroup		Advanced accountancy
+ * \brief		File of class to manage accounting accounts
  */
 
 /**
@@ -41,6 +41,7 @@ class AccountingAccount extends CommonObject
 	var $pcg_subtype;
 	var $account_number;
 	var $account_parent;
+	var $account_category;
 	var $label;
 	var $fk_user_author;
 	var $fk_user_modif;
@@ -58,25 +59,29 @@ class AccountingAccount extends CommonObject
 	/**
 	 * Load record in memory
 	 *
-	 * @param int $rowid Id
-	 * @param string $account_number Account number
-	 * @param int $limittocurentchart 1=Do not load record if it is into another accounting system
-	 * @return int <0 if KO, >0 if OK
+	 * @param 	int 	$rowid 				Id
+	 * @param 	string 	$account_number 	Account number
+	 * @param 	int 	$limittocurrentchart 1=Do not load record if it is into another accounting system
+	 * @return 	int <0 if KO, >0 if OK
 	 */
-	function fetch($rowid = null, $account_number = null, $limittocurentchart = 0) {
+	function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0) {
 		global $conf;
 		
 		if ($rowid || $account_number) {
-			$sql = "SELECT rowid, datec, tms, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, fk_user_author, fk_user_modif, active";
-			$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account WHERE";
+			$sql  = "SELECT a.rowid as rowid, a.datec, a.tms, a.fk_pcg_version, a.pcg_type, a.pcg_subtype, a.account_number, a.account_parent, a.label, a.fk_accounting_category, a.fk_user_author, a.fk_user_modif, a.active";
+			$sql .= ", ca.label as category_label";
+			$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as a";
+			$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as ca ON a.fk_accounting_category = ca.rowid";
+			$sql .= " WHERE";
 			if ($rowid) {
-				$sql .= " rowid = '" . $rowid . "'";
+				$sql .= " a.rowid = '" . $rowid . "'";
 			} elseif ($account_number) {
-				$sql .= " account_number = '" . $account_number . "'";
+				$sql .= " a.account_number = '" . $account_number . "'";
 			}
-			if (! empty($limittocurentchart)) {
-				$sql .= ' AND fk_pcg_version IN (SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid=' . $conf->global->CHARTOFACCOUNTS . ')';
+			if (! empty($limittocurrentchart)) {
+				$sql .= ' AND a.fk_pcg_version IN (SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid=' . $conf->global->CHARTOFACCOUNTS . ')';
 			}
+
 			dol_syslog(get_class($this) . "::fetch sql=" . $sql, LOG_DEBUG);
 			$result = $this->db->query($sql);
 			if ($result) {
@@ -93,6 +98,8 @@ class AccountingAccount extends CommonObject
 					$this->account_number = $obj->account_number;
 					$this->account_parent = $obj->account_parent;
 					$this->label = $obj->label;
+					$this->account_category = $obj->fk_accounting_category;
+					$this->account_category_label = $obj->category_label;
 					$this->fk_user_author = $obj->fk_user_author;
 					$this->fk_user_modif = $obj->fk_user_modif;
 					$this->active = $obj->active;
@@ -110,7 +117,7 @@ class AccountingAccount extends CommonObject
 	}
 	
 	/**
-	 * Insert line in accounting_account
+	 * Insert new accounting account in chart of accounts
 	 *
 	 * @param User $user Use making action
 	 * @param int $notrigger Disable triggers
@@ -134,6 +141,8 @@ class AccountingAccount extends CommonObject
 			$this->account_parent = trim($this->account_parent);
 		if (isset($this->label))
 			$this->label = trim($this->label);
+		if (isset($this->account_category))
+			$this->account_category = trim($this->account_category);
 		if (isset($this->fk_user_author))
 			$this->fk_user_author = trim($this->fk_user_author);
 		if (isset($this->active))
@@ -153,6 +162,7 @@ class AccountingAccount extends CommonObject
 		$sql .= ", account_number";
 		$sql .= ", account_parent";
 		$sql .= ", label";
+		$sql .= ", fk_accounting_category";
 		$sql .= ", fk_user_author";
 		$sql .= ", active";
 		
@@ -166,6 +176,7 @@ class AccountingAccount extends CommonObject
 		$sql .= ", " . (! isset($this->account_number) ? 'NULL' : "'" . $this->account_number . "'");
 		$sql .= ", " . (! isset($this->account_parent) ? 'NULL' : "'" . $this->db->escape($this->account_parent) . "'");
 		$sql .= ", " . (! isset($this->label) ? 'NULL' : "'" . $this->db->escape($this->label) . "'");
+		$sql .= ", " . (! isset($this->account_category) ? 'NULL' : "'" . $this->db->escape($this->account_category) . "'");
 		$sql .= ", " . $user->id;
 		$sql .= ", " . (! isset($this->active) ? 'NULL' : "'" . $this->db->escape($this->active) . "'");
 		
@@ -226,6 +237,7 @@ class AccountingAccount extends CommonObject
 		$sql .= " , account_number = '" . $this->account_number . "'";
 		$sql .= " , account_parent = '" . $this->account_parent . "'";
 		$sql .= " , label = " . ($this->label ? "'" . $this->db->escape($this->label) . "'" : "null");
+		$sql .= " , fk_accounting_category = '" . $this->account_category . "'";
 		$sql .= " , fk_user_modif = " . $user->id;
 		$sql .= " , active = '" . $this->active . "'";
 		

+ 54 - 18
htdocs/accountancy/class/bookkeeping.class.php

@@ -1,8 +1,7 @@
 <?php
-/* Copyright (C) 2007-2012  Laurent Destailleur <eldy@users.sourceforge.net>
- * Copyright (C) 2014       Juanjo Menent       <jmenent@2byte.es>
- * Copyright (C) 2015-2016 Florian Henry       <florian.henry@open-concept.pro>
- * Copyright (C) 2015       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
+/* Copyright (C) 2014-2016 Olivier Geffroy      <jeff@jeffinfo.com>
+ * Copyright (C) 2015-2016 Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2015-2016 Florian Henry		<florian.henry@open-concept.pro>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,21 +18,16 @@
  */
 
 /**
- * \file accountancy/bookkeeping.class.php
- * \ingroup accountancy
- * \brief This file is an example for a CRUD class file (Create/Read/Update/Delete)
- * Put some comments here
+ *	\file       htdocs/accountancy/class/bookkeeping.class.php
+ *	\ingroup    Advanced accountancy
+ *	\brief      File of class to manage general ledger
  */
 
-// Put here all includes required by your class file
+// Class
 require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
-// require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
-// require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
 
 /**
- * Class Accountingbookkeeping
- *
- * Put here description of your class
+ * Class to manage general ledger
  */
 class BookKeeping extends CommonObject
 {
@@ -170,7 +164,7 @@ class BookKeeping extends CommonObject
 		$this->piece_num = 0;
 		
 		// first check if line not yet in bookkeeping
-		$sql = "SELECT count(*)";
+		$sql = "SELECT count(*) as nb";
 		$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
 		$sql .= " WHERE doc_type = '" . $this->doc_type . "'";
 		$sql .= " AND fk_docdet = " . $this->fk_docdet;
@@ -180,8 +174,8 @@ class BookKeeping extends CommonObject
 		$resql = $this->db->query($sql);
 		
 		if ($resql) {
-			$row = $this->db->fetch_array($resql);
-			if ($row[0] == 0) {
+			$row = $this->db->fetch_object($resql);
+			if ($row->nb == 0) {
 				
 				// Determine piece_num
 				$sqlnum = "SELECT piece_num";
@@ -461,7 +455,7 @@ class BookKeeping extends CommonObject
 	 *
 	 * @param int $id Id object
 	 * @param string $ref Ref
-	 *       
+	 * 
 	 * @return int <0 if KO, 0 if not found, >0 if OK
 	 */
 	public function fetch($id, $ref = null) {
@@ -1207,6 +1201,48 @@ class BookKeeping extends CommonObject
 			return - 1;
 		}
 	}
+	
+	/**
+	* Description of accounting account
+	*
+	* @param 	string 	$account	Accounting account
+	* @return 	string 	
+	*/
+	function get_compte_desc($account = null)
+	{	
+		global $conf;
+		$pcgver = $conf->global->CHARTOFACCOUNTS;
+
+		$sql  = "SELECT aa.account_number, aa.label, aa.rowid, aa.fk_pcg_version, cat.label as category";
+		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa ";
+		$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
+		$sql .= " AND aa.account_number = '" . $account . "'";
+		$sql .= " AND asy.rowid = " . $pcgver;
+		$sql .= " AND aa.active = 1";
+		$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_accounting_category as cat ON aa.fk_accounting_category = cat.rowid";
+
+		dol_syslog(get_class($this) . "::select_account sql=" . $sql, LOG_DEBUG);
+		$resql = $this->db->query($sql);
+		if ($resql) {
+			$obj = '';
+			if ($this->db->num_rows($resql)) {
+				$obj = $this->db->fetch_object($resql);	
+			}
+			
+			if(empty($obj->category)){				
+				return $obj->label;
+			}else{
+				return $obj->label.' ('.$obj->category.')';
+				
+			}
+		} else {
+			$this->error = "Error " . $this->db->lasterror();
+			dol_syslog(__METHOD__ . " " . $this->error, LOG_ERR);
+
+			return -1;
+		}
+	}
+	
 }
 
 /**

+ 125 - 225
htdocs/accountancy/class/html.formventilation.class.php

@@ -3,6 +3,7 @@
  * Copyright (C) 2013-2014 Olivier Geffroy      <jeff@jeffinfo.com>
  * Copyright (C) 2013-2016 Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2015      Ari Elbaz (elarifr)  <github@accedinfo.com>
+ * Copyright (C) 2016      Marcos García        <marcosgdf@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,9 +20,9 @@
  */
 
 /**
- * \file htdocs/accountancy/class/html.formventilation.class.php
- * \ingroup Accounting Expert
- * \brief File of class with all html predefined components
+ * \file		htdocs/accountancy/class/html.formventilation.class.php
+ * \ingroup		Advanced accountancy
+ * \brief		File of class with all html predefined components
  */
 
 /**
@@ -29,18 +30,6 @@
  */
 class FormVentilation extends Form
 {
-	var $db;
-	var $error;
-	
-	/**
-	 * Constructor
-	 *
-	 * @param DoliDB $db Database handler
-	 */
-	public function __construct($db) {
-		$this->db = $db;
-	}
-	
 	/**
 	 * Return select filter with date of transaction
 	 *
@@ -49,38 +38,25 @@ class FormVentilation extends Form
 	 * @return string HTML edit field
 	 */
 	function select_bookkeeping_importkey($htmlname = 'importkey', $selectedkey = '') {
+		$options = array();
+
 		$sql = 'SELECT DISTINCT import_key from ' . MAIN_DB_PREFIX . 'accounting_bookkeeping';
 		$sql .= ' ORDER BY import_key DESC';
-		
-		$out = '<SELECT name="' . $htmlname . '">';
-		
-		dol_syslog(get_class($this) . "::select_bookkeeping_importkey sql=" . $sql, LOG_DEBUG);
+
+		dol_syslog(get_class($this) . "::select_bookkeeping_importkey", LOG_DEBUG);
 		$resql = $this->db->query($sql);
-		if ($resql) {
-			$i = 0;
-			$num = $this->db->num_rows($resql);
-			
-			while ( $i < $num ) {
-				$obj = $this->db->fetch_object($resql);
-				
-				$selected = '';
-				if ($selectedkey == $obj->import_key) {
-					$selected = ' selected ';
-				}
-				
-				$out .= '<OPTION value="' . $obj->import_key . '"' . $selected . '>' . dol_print_date($obj->import_key, 'dayhourtext') . '</OPTION>';
-				
-				$i ++;
-			}
-		} else {
+
+		if (!$resql) {
 			$this->error = "Error " . $this->db->lasterror();
 			dol_syslog(get_class($this) . "::select_bookkeeping_importkey " . $this->error, LOG_ERR);
 			return - 1;
 		}
-		
-		$out .= '</SELECT>';
-		
-		return $out;
+
+		while ($obj = $this->db->fetch_object($resql)) {
+			$options[$obj->import_key] = dol_print_date($obj->import_key, 'dayhourtext');
+		}
+
+		return Form::selectarray($htmlname, $options, $selectedkey);
 	}
 	
 	/**
@@ -100,8 +76,8 @@ class FormVentilation extends Form
 		global $conf;
 		
 		require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
-		
-		$out = '';
+
+		$trunclength = defined('ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT') ? $conf->global->ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT : 50;
 		
 		$sql = "SELECT DISTINCT aa.account_number, aa.label, aa.rowid, aa.fk_pcg_version";
 		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa";
@@ -110,49 +86,44 @@ class FormVentilation extends Form
 		$sql .= " AND aa.active = 1";
 		$sql .= " ORDER BY aa.account_number";
 		
-		dol_syslog(get_class($this) . "::select_account sql=" . $sql, LOG_DEBUG);
+		dol_syslog(get_class($this) . "::select_account", LOG_DEBUG);
 		$resql = $this->db->query($sql);
-		if ($resql) {
-			
-			$out .= ajax_combobox($htmlname, $event);
-			$out .= '<select id="' . $htmlname . '" class="flat" name="' . $htmlname . '">';
-			if ($showempty)
-				$out .= '<option value="-1"></option>';
-			$num = $this->db->num_rows($resql);
-			$trunclength = defined('ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT') ? $conf->global->ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT : '50';
-			
-			$i = 0;
-			if ($num) {
-				while ( $i < $num ) {
-					$obj = $this->db->fetch_object($resql);
-					$label = length_accountg($obj->account_number) . ' - ' . $obj->label;
-					$label = dol_trunc($label, $trunclength);
-					if ($select_in == 0)
-						$select_value_in = $obj->rowid;
-					if ($select_in == 1)
-						$select_value_in = $obj->account_number;
-					if ($select_out == 0)
-						$select_value_out = $obj->rowid;
-					if ($select_out == 1)
-						$select_value_out = $obj->account_number;
-						// Remember guy's we store in database llx_facturedet the rowid of accounting_account and not the account_number
-						// Because same account_number can be share between different accounting_system and do have the same meaning
-					if (($selectid != '') && $selectid == $select_value_in) {
-						// $out .= '<option value="' . $obj->account_number . '" selected>' . $label . '</option>';
-						$out .= '<option value="' . $select_value_out . '" selected>' . $label . '</option>';
-					} else {
-						// $out .= '<option value="' . $obj->account_number . '">' . $label . '</option>';
-						$out .= '<option value="' . $select_value_out . '">' . $label . '</option>';
-					}
-					$i ++;
-				}
-			}
-			$out .= '</select>';
-		} else {
+
+		if (!$resql) {
 			$this->error = "Error " . $this->db->lasterror();
 			dol_syslog(get_class($this) . "::select_account " . $this->error, LOG_ERR);
-			return - 1;
+			return -1;
+		}
+
+		$out = ajax_combobox($htmlname, $event);
+
+		$options = array();
+		$selected = null;
+
+		while ($obj = $this->db->fetch_object($resql)) {
+			$label = length_accountg($obj->account_number) . ' - ' . $obj->label;
+			$label = dol_trunc($label, $trunclength);
+
+			$select_value_in = $obj->rowid;
+			$select_value_out = $obj->rowid;
+
+			if ($select_in == 1) {
+				$select_value_in = $obj->account_number;
+			}
+			if ($select_out == 1) {
+				$select_value_out = $obj->account_number;
+			}
+
+			// Remember guy's we store in database llx_facturedet the rowid of accounting_account and not the account_number
+			// Because same account_number can be share between different accounting_system and do have the same meaning
+			if (($selectid != '') && $selectid == $select_value_in) {
+				$selected = $select_value_out;
+			}
+
+			$options[$select_value_out] = $label;
 		}
+
+		$out .= Form::selectarray($htmlname, $options, $selected, $showempty);
 		$this->db->free($resql);
 		return $out;
 	}
@@ -170,44 +141,30 @@ class FormVentilation extends Form
 	function select_pcgtype($selectid, $htmlname = 'pcg_type', $showempty = 0, $event = array()) {
 		global $conf;
 		
-		$out = '';
-		
 		$sql = "SELECT DISTINCT pcg_type ";
 		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa";
 		$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
 		$sql .= " AND asy.rowid = " . $conf->global->CHARTOFACCOUNTS;
 		$sql .= " ORDER BY pcg_type";
 		
-		dol_syslog(get_class($this) . "::select_pcgtype sql=" . $sql, LOG_DEBUG);
+		dol_syslog(get_class($this) . "::select_pcgtype", LOG_DEBUG);
 		$resql = $this->db->query($sql);
-		if ($resql) {
-			
-			$out .= ajax_combobox($htmlname, $event);
-			
-			$out .= '<select id="' . $htmlname . '" class="flat" name="' . $htmlname . '">';
-			if ($showempty)
-				$out .= '<option value="-1"></option>';
-			$num = $this->db->num_rows($resql);
-			$i = 0;
-			if ($num) {
-				while ( $i < $num ) {
-					$obj = $this->db->fetch_object($resql);
-					$label = $obj->pcg_type;
-					
-					if (($selectid != '') && $selectid == $obj->pcg_type) {
-						$out .= '<option value="' . $obj->pcg_type . '" selected>' . $label . '</option>';
-					} else {
-						$out .= '<option value="' . $obj->pcg_type . '">' . $label . '</option>';
-					}
-					$i ++;
-				}
-			}
-			$out .= '</select>';
-		} else {
-			$this->error = "Error " . $this->db->lasterror();
-			dol_syslog(get_class($this) . "::select_pcgtype " . $this->error, LOG_ERR);
-			return - 1;
+
+		if (!$resql) {
+			$this->error = "Error ".$this->db->lasterror();
+			dol_syslog(get_class($this)."::select_pcgtype ".$this->error, LOG_ERR);
+			return -1;
+		}
+
+		$options = array();
+		$out = ajax_combobox($htmlname, $event);
+
+		while ($obj = $this->db->fetch_object($resql)) {
+			$options[$obj->pcg_type] = $obj->pcg_type;
 		}
+
+		$out .= Form::selectarray($htmlname, $options, $selectid, $showempty);
+
 		$this->db->free($resql);
 		return $out;
 	}
@@ -225,44 +182,30 @@ class FormVentilation extends Form
 	function select_pcgsubtype($selectid, $htmlname = 'pcg_subtype', $showempty = 0, $event = array()) {
 		global $conf;
 		
-		$out = '';
-		
 		$sql = "SELECT DISTINCT pcg_subtype ";
 		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa";
 		$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
 		$sql .= " AND asy.rowid = " . $conf->global->CHARTOFACCOUNTS;
 		$sql .= " ORDER BY pcg_subtype";
 		
-		dol_syslog(get_class($this) . "::select_pcgsubtype sql=" . $sql, LOG_DEBUG);
+		dol_syslog(get_class($this) . "::select_pcgsubtype", LOG_DEBUG);
 		$resql = $this->db->query($sql);
-		if ($resql) {
-			
-			$out .= ajax_combobox($htmlname, $event);
-			
-			$out .= '<select id="' . $htmlname . '" class="flat" name="' . $htmlname . '">';
-			if ($showempty)
-				$out .= '<option value="-1"></option>';
-			$num = $this->db->num_rows($resql);
-			$i = 0;
-			if ($num) {
-				while ( $i < $num ) {
-					$obj = $this->db->fetch_object($resql);
-					$label = $obj->pcg_subtype;
-					
-					if (($selectid != '') && $selectid == $obj->pcg_subtype) {
-						$out .= '<option value="' . $obj->pcg_subtype . '" selected>' . $label . '</option>';
-					} else {
-						$out .= '<option value="' . $obj->pcg_subtype . '">' . $label . '</option>';
-					}
-					$i ++;
-				}
-			}
-			$out .= '</select>';
-		} else {
-			$this->error = "Error " . $this->db->lasterror();
-			dol_syslog(get_class($this) . "::select_pcgsubtype " . $this->error, LOG_ERR);
-			return - 1;
+
+		if (!$resql) {
+			$this->error = "Error ".$this->db->lasterror();
+			dol_syslog(get_class($this)."::select_pcgsubtype ".$this->error, LOG_ERR);
+			return -1;
+		}
+
+		$options = array();
+		$out = ajax_combobox($htmlname, $event);
+
+		while ($obj = $this->db->fetch_object($resql)) {
+			$options[$obj->pcg_subtype] = $obj->pcg_subtype;
 		}
+
+		$out .= Form::selectarray($htmlname, $options, $selectid, $showempty);
+
 		$this->db->free($resql);
 		return $out;
 	}
@@ -278,68 +221,51 @@ class FormVentilation extends Form
 	 * @return string String with HTML select
 	 */
 	function select_auxaccount($selectid, $htmlname = 'account_num_aux', $showempty = 0, $event = array()) {
-		global $conf;
-		
-		$out = '';
-		
-		$aux_account = array ();
-		
+
+		$aux_account = array();
+
 		// Auxiliary customer account
 		$sql = "SELECT DISTINCT code_compta, nom ";
-		$sql .= " FROM " . MAIN_DB_PREFIX . "societe";
+		$sql .= " FROM ".MAIN_DB_PREFIX."societe";
 		$sql .= " ORDER BY code_compta";
-		dol_syslog(get_class($this) . "::select_auxaccount", LOG_DEBUG);
+		dol_syslog(get_class($this)."::select_auxaccount", LOG_DEBUG);
 		$resql = $this->db->query($sql);
 		if ($resql) {
-			while ( $obj = $this->db->fetch_object($resql) ) {
-				if (! empty($obj->code_compta)) {
-					$aux_account[$obj->code_compta] = $obj->code_compta . ' (' . $obj->nom . ')';
+			while ($obj = $this->db->fetch_object($resql)) {
+				if (!empty($obj->code_compta)) {
+					$aux_account[$obj->code_compta] = $obj->code_compta.' ('.$obj->nom.')';
 				}
 			}
 		} else {
-			$this->error = "Error " . $this->db->lasterror();
-			dol_syslog(get_class($this) . "::select_pcgsubtype " . $this->error, LOG_ERR);
-			return - 1;
+			$this->error = "Error ".$this->db->lasterror();
+			dol_syslog(get_class($this)."::select_pcgsubtype ".$this->error, LOG_ERR);
+			return -1;
 		}
 		$this->db->free($resql);
-		
+
 		// Auxiliary supplier account
 		$sql = "SELECT DISTINCT code_compta_fournisseur, nom ";
-		$sql .= " FROM " . MAIN_DB_PREFIX . "societe";
+		$sql .= " FROM ".MAIN_DB_PREFIX."societe";
 		$sql .= " ORDER BY code_compta";
-		dol_syslog(get_class($this) . "::select_auxaccount", LOG_DEBUG);
+		dol_syslog(get_class($this)."::select_auxaccount", LOG_DEBUG);
 		$resql = $this->db->query($sql);
 		if ($resql) {
-			while ( $obj = $this->db->fetch_object($resql) ) {
-				if (! empty($obj->code_compta_fournisseur)) {
-					$aux_account[$obj->code_compta_fournisseur] = $obj->code_compta_fournisseur . ' (' . $obj->nom . ')';
+			while ($obj = $this->db->fetch_object($resql)) {
+				if (!empty($obj->code_compta_fournisseur)) {
+					$aux_account[$obj->code_compta_fournisseur] = $obj->code_compta_fournisseur.' ('.$obj->nom.')';
 				}
 			}
 		} else {
-			$this->error = "Error " . $this->db->lasterror();
-			dol_syslog(get_class($this) . "::select_pcgsubtype " . $this->error, LOG_ERR);
-			return - 1;
+			$this->error = "Error ".$this->db->lasterror();
+			dol_syslog(get_class($this)."::select_pcgsubtype ".$this->error, LOG_ERR);
+			return -1;
 		}
 		$this->db->free($resql);
-		
+
 		// Build select
-		if (count($aux_account) > 0) {
-			
-			$out .= ajax_combobox($htmlname, $event);
-			
-			$out .= '<select id="' . $htmlname . '" class="flat" name="' . $htmlname . '">';
-			if ($showempty)
-				$out .= '<option value="-1"></option>';
-			foreach ( $aux_account as $key => $val ) {
-				if (($selectid != '') && $selectid == $key) {
-					$out .= '<option value="' . $key . '" selected>' . $val . '</option>';
-				} else {
-					$out .= '<option value="' . $key . '">' . $val . '</option>';
-				}
-			}
-			$out .= '</select>';
-		}
-		
+		$out = ajax_combobox($htmlname, $event);
+		$out .= Form::selectarray($htmlname, $aux_account, $selectid, $showempty);
+
 		return $out;
 	}
 	
@@ -352,55 +278,29 @@ class FormVentilation extends Form
 	 * @param string $output_format (html/opton (for option html only)/array (to return options arrays
 	 * @return string/array
 	 */
-	function selectyear_accountancy_bookkepping($selected = '', $htmlname = 'yearid', $useempty = 0, $output_format = 'html') {
-		$out = '';
-		$out_array = array ();
-		
-		if ($output_format == 'html') {
-			$out .= '<select class="flat" placeholder="aa" id="' . $htmlname . '" name="' . $htmlname . '"' . $option . ' >';
-		}
-		if ($useempty) {
-			$selected_html = '';
-			if ($selected == '') {
-				$selected_html = ' selected';
-			}
-			if ($output_format == 'html' || $output_format == 'options') {
-				$out .= '<option value=""' . $selected_html . '>&nbsp;</option>';
-			} elseif ($output_format == 'array') {
-				$out_array[''] = '';
-			}
-		}
-		
+	function selectyear_accountancy_bookkepping($selected = '', $htmlname = 'yearid', $useempty = 0, $output_format = 'html')
+	{
+		$out_array = array();
+
 		$sql = "SELECT DISTINCT date_format(doc_date,'%Y') as dtyear";
-		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
+		$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
 		$sql .= " ORDER BY doc_date";
-		dol_syslog(get_class($this) . "::" . __METHOD__, LOG_DEBUG);
+		dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
 		$resql = $this->db->query($sql);
-		if ($resql) {
-			while ( $obj = $this->db->fetch_object($resql) ) {
-				$selected_html = '';
-				if ($selected > 0 && $obj->dtyear == $selected)
-					$selected_html = ' selected';
-				if ($output_format == 'html' || $output_format == 'options') {
-					$out .= '<option value="' . $obj->dtyear . '"' . $selected_html . ' >' . $obj->dtyear . '</option>';
-				} elseif ($output_format == 'array') {
-					$out_array[$obj->dtyear] = $obj->dtyear;
-				}
-			}
-		} else {
-			$this->error = "Error " . $this->db->lasterror();
-			dol_syslog(get_class($this) . "::" . __METHOD__ . $this->error, LOG_ERR);
-			return - 1;
+
+		if (!$resql) {
+			$this->error = "Error ".$this->db->lasterror();
+			dol_syslog(get_class($this)."::".__METHOD__.$this->error, LOG_ERR);
+			return -1;
+		}
+		while ($obj = $this->db->fetch_object($resql)) {
+			$out_array[$obj->dtyear] = $obj->dtyear;
 		}
 		$this->db->free($resql);
-		
+
 		if ($output_format == 'html') {
-			$out .= "</select>\n";
-		}
-		
-		if ($output_format == 'html' || $output_format == 'options') {
-			return $out;
-		} elseif ($output_format == 'array') {
+			return Form::selectarray($htmlname, $out_array, $selected, $useempty, 0, 0, 'placeholder="aa"');
+		} else {
 			return $out_array;
 		}
 	}

+ 0 - 0
htdocs/core/modules/cheque/pdf/index.html → htdocs/accountancy/customer/index.html


+ 6 - 6
htdocs/accountancy/customer/index.php

@@ -1,7 +1,7 @@
 <?php
 /* Copyright (C) 2013      Olivier Geffroy		<jeff@jeffinfo.com>
  * Copyright (C) 2013-2014 Florian Henry		<florian.henry@open-concept.pro>
- * Copyright (C) 2013-2015 Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2013-2016 Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2014	   Juanjo Menent		<jmenent@2byte.es>
  * Copyright (C) 2015      Jean-François Ferry  <jfefe@aternatik.fr>
  *
@@ -21,9 +21,9 @@
  */
 
 /**
- * \file htdocs/accountancy/customer/index.php
- * \ingroup Accounting Expert
- * \brief Home customer ventilation
+ * \file		htdocs/accountancy/customer/index.php
+ * \ingroup 	Advanced accountancy
+ * \brief 		Home customer ventilation
  */
 require '../../main.inc.php';
 
@@ -44,7 +44,7 @@ if ($user->societe_id > 0)
 if (! $user->rights->accounting->ventilation->read)
 	accessforbidden();
 	
-	// Filter
+// Filter
 $year = $_GET["year"];
 if ($year == 0) {
 	$year_current = strftime("%Y", time());
@@ -95,7 +95,7 @@ if ($action == 'validatehistory') {
 	$sql1 .= " SET fd.fk_code_ventilation = 0";
 	$sql1 .= ' WHERE fd.fk_code_ventilation NOT IN ';
 	$sql1 .= '	(SELECT accnt.rowid ';
-	$sql1 .= '	FROM ' . MAIN_DB_PREFIX . 'accountingaccount as accnt';
+	$sql1 .= '	FROM ' . MAIN_DB_PREFIX . 'accounting_account as accnt';
 	$sql1 .= '	INNER JOIN ' . MAIN_DB_PREFIX . 'accounting_system as syst';
 	$sql1 .= '	ON accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=' . $conf->global->CHARTOFACCOUNTS . ')';
 	

+ 15 - 14
htdocs/accountancy/customer/lines.php

@@ -1,8 +1,8 @@
 <?php
-/* Copyright (C) 2013-2014 Olivier Geffroy		<jeff@jeffinfo.com>
- * Copyright (C) 2013-2015 Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
+/* Copyright (C) 2013-2016 Olivier Geffroy		<jeff@jeffinfo.com>
+ * Copyright (C) 2013-2016 Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2014-2015 Ari Elbaz (elarifr)	<github@accedinfo.com>
- * Copyright (C) 2014      Florian Henry		<florian.henry@open-concept.pro>
+ * Copyright (C) 2014-2016 Florian Henry		<florian.henry@open-concept.pro>
  * Copyright (C) 2014	   Juanjo Menent		<jmenent@2byte.es>   
  *
  * This program is free software; you can redistribute it and/or modify
@@ -21,9 +21,9 @@
  */
 
 /**
- * \file htdocs/accountancy/customer/lines.php
- * \ingroup Accounting Expert
- * \brief Page of detail of the lines of ventilation of invoices customers
+ * \file 		htdocs/accountancy/customer/lines.php
+ * \ingroup 	Advanced accountancy
+ * \brief 		Page of detail of the lines of ventilation of invoices customers
  */
 require '../../main.inc.php';
 
@@ -31,6 +31,7 @@ require '../../main.inc.php';
 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/html.formventilation.class.php';
 require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
+require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
 
 // Langs
 $langs->load("bills");
@@ -267,14 +268,14 @@ if ($result) {
 	
 	print '<tr class="liste_titre">';
 	print '<td class="liste_titre"><input type="text" class="flat" name="search_invoice" size="10" value="' . $search_invoice . '"></td>';
-	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_ref" value="' . $search_ref . '"></td>';
-	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_label" value="' . $search_label . '"></td>';
+	print '<td class="liste_titre"><input type="text" class="flat" size="10" name="search_ref" value="' . $search_ref . '"></td>';
+	print '<td class="liste_titre"><input type="text" class="flat" size="10" name="search_label" value="' . $search_label . '"></td>';
 	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_desc" value="' . $search_desc . '"></td>';
 	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="8" name="search_amount" value="' . $search_amount . '"></td>';
-	print '<td class="liste_titre" align="center">%<input type="text" class="flat" size="5" name="search_vat" value="' . $search_vat . '"></td>';
-	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="15" name="search_account" value="' . $search_account . '"></td>';
-	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="15" name="search_country" value="' . $search_country . '"></td>';
-	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="15" name="search_tavintra" value="' . $search_tavintra . '"></td>';
+	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="5" name="search_vat" value="' . $search_vat . '">%</td>';
+	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="10" name="search_account" value="' . $search_account . '"></td>';
+	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="10" name="search_country" value="' . $search_country . '"></td>';
+	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="10" name="search_tavintra" value="' . $search_tavintra . '"></td>';
 	print '<td class="liste_titre" align="center"><input type="image" class="liste_titre" name="button_search" src="' . img_picto($langs->trans("Search"), 'search.png', '', '', 1) . '" value="' . dol_escape_htmltag($langs->trans("Search")) . '" title="' . dol_escape_htmltag($langs->trans("Search")) . '">';
 	print '<input type="image" class="liste_titre" name="button_removefilter" src="' . img_picto($langs->trans("Search"), 'searchclear.png', '', '', 1) . '" value="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '" title="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '">';
 	print "</td></tr>\n";
@@ -285,7 +286,7 @@ if ($result) {
 	$var = True;
 	while ( $objp = $db->fetch_object($result) ) {
 		$var = ! $var;
-		$codecompta = $objp->account_number . ' - ' . $objp->label_compte;
+		$codecompta = length_accountg($objp->account_number) . ' - ' . $objp->label_compte;
 		
 		print "<tr $bc[$var]>";
 		
@@ -309,7 +310,7 @@ if ($result) {
 		print '<td>' . nl2br(dol_trunc($objp->description, 32)) . '</td>';
 		print '<td align="right">' . price($objp->total_ht) . '</td>';
 		print '<td align="center">' . price($objp->tva_tx) . '</td>';
-		print '<td align="center">' . $codecompta . '<a href="./card.php?id=' . $objp->fdid . '">';
+		print '<td>' . $codecompta . '<a href="./card.php?id=' . $objp->fdid . '">';
 		print img_edit();
 		print '</a></td>';
 		print '<td align="right">' . $objp->country .'</td>';

+ 89 - 66
htdocs/accountancy/journal/bankjournal.php

@@ -52,8 +52,9 @@ require_once DOL_DOCUMENT_ROOT . '/societe/class/client.class.php';
 $langs->load("companies");
 $langs->load("other");
 $langs->load("compta");
-$langs->load("bank");
+$langs->load("banks");
 $langs->load('bills');
+$langs->load('donations');
 $langs->load("accountancy");
 
 $id_bank_account = GETPOST('id_account', 'int');
@@ -130,11 +131,12 @@ if ($result) {
 
 	$num = $db->num_rows($result);
 	// Variables
-	$cptfour = (! empty($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) ? $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER : $langs->trans("CodeNotDef"));
-	$cptcli = (! empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) ? $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER : $langs->trans("CodeNotDef"));
-	$accountancy_account_salary = (! empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) ? $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT : $langs->trans("CodeNotDef"));
-	$accountancy_account_pay_vat = (! empty($conf->global->ACCOUNTING_VAT_PAY_ACCOUNT) ? $conf->global->ACCOUNTING_VAT_PAY_ACCOUNT : $langs->trans("CodeNotDef"));
-	$accountancy_account_pay_donation = (! empty($conf->global->DONATION_ACCOUNTINGACCOUNT) ? $conf->global->DONATION_ACCOUNTINGACCOUNT : $langs->trans("CodeNotDef"));
+	$account_supplier = (! empty($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) ? $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER : $langs->trans("CodeNotDef"));
+	$account_customer = (! empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) ? $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER : $langs->trans("CodeNotDef"));
+	$account_employee = (! empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) ? $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT : $langs->trans("CodeNotDef"));
+	$account_pay_vat = (! empty($conf->global->ACCOUNTING_VAT_PAY_ACCOUNT) ? $conf->global->ACCOUNTING_VAT_PAY_ACCOUNT : $langs->trans("CodeNotDef"));
+	$account_pay_donation = (! empty($conf->global->DONATION_ACCOUNTINGACCOUNT) ? $conf->global->DONATION_ACCOUNTINGACCOUNT : $langs->trans("CodeNotDef"));
+	$account_transfer = (! empty($conf->global->ACCOUNTING_ACCOUNT_TRANSFER_CASH) ? $conf->global->ACCOUNTING_ACCOUNT_TRANSFER_CASH : $langs->trans("CodeNotDef"));
 
 	$tabpay = array ();
 	$tabbq = array ();
@@ -154,11 +156,9 @@ if ($result) {
 		// Controls
 		$compta_bank = $obj->account_number;
 		if ($obj->label == '(SupplierInvoicePayment)')
-			$compta_soc = (! empty($obj->code_compta_fournisseur) ? $obj->code_compta_fournisseur : $cptfour);
+			$compta_soc = (! empty($obj->code_compta_fournisseur) ? $obj->code_compta_fournisseur : $account_supplier);
 		if ($obj->label == '(CustomerInvoicePayment)')
-			$compta_soc = (! empty($obj->code_compta) ? $obj->code_compta : $cptcli);
-		if ($obj->typeop == '(BankTransfert)')
-			$compta_soc = $conf->global->ACCOUNTING_ACCOUNT_TRANSFER_CASH;
+			$compta_soc = (! empty($obj->code_compta) ? $obj->code_compta : $account_customer);
 
 		// Variable bookkeeping
 		$tabpay[$obj->rowid]["date"] = $obj->do;
@@ -226,25 +226,23 @@ if ($result) {
 					$paymentdonstatic->id = $links[$key]['url_id'];
 					$paymentdonstatic->fk_donation = $links[$key]['url_id'];
 					$tabpay[$obj->rowid]["lib"] .= ' ' . $langs->trans("PaymentDonation");
-					$tabtp[$obj->rowid][$accountancy_account_pay_donation] += $obj->amount;
+					$tabtp[$obj->rowid][$account_pay_donation] += $obj->amount;
 				} else if ($links[$key]['type'] == 'payment_vat') {
 					$paymentvatstatic->id = $links[$key]['url_id'];
 					$paymentvatstatic->ref = $links[$key]['url_id'];
+					$paymentvatstatic->label = $links[$key]['label'];
 					$tabpay[$obj->rowid]["lib"] .= ' ' . $langs->trans("PaymentVat");
-					$tabtp[$obj->rowid][$accountancy_account_pay_vat] += $obj->amount;
+					$tabtp[$obj->rowid][$account_pay_vat] += $obj->amount;
 				} else if ($links[$key]['type'] == 'payment_salary') {
 					$paymentsalstatic->id = $links[$key]['url_id'];
 					$paymentsalstatic->ref = $links[$key]['url_id'];
 					$paymentsalstatic->label = $links[$key]['label'];
 					$tabpay[$obj->rowid]["lib"] .= ' ' . $paymentsalstatic->getNomUrl(2);
-					$tabtp[$obj->rowid][$accountancy_account_salary] += $obj->amount;
+					$tabtp[$obj->rowid][$account_employee] += $obj->amount;
 				} else if ($links[$key]['type'] == 'banktransfert') {
-					$tabpay[$obj->rowid]["lib"] .= ' ' . $paymentvatstatic->getNomUrl(2);
-					$tabtp[$obj->rowid][$cpttva] += $obj->amount;
+					$tabpay[$obj->rowid]["lib"] .= ' ' . $langs->trans("BankTransfer");
+					$tabtp[$obj->rowid][$account_transfer] += $obj->amount;
 				}
-				/*else {
-				 $tabtp [$obj->rowid] [$accountancy_account_salary] += $obj->amount;
-				 }*/
 			}
 		}
 
@@ -420,12 +418,27 @@ if ($action == 'export_csv') {
 		foreach ( $tabpay as $key => $val ) {
 			$date = dol_print_date($db->jdate($val["date"]), '%d%m%Y');
 
+			$reflabel = $val["ref"];
+			if ($reflabel == '(SupplierInvoicePayment)') {
+				$reflabel = $langs->trans('Supplier');
+			}
+			if ($reflabel == '(CustomerInvoicePayment)') {
+				$reflabel = $langs->trans('Customer');
+			}		
+			if ($reflabel == '(SocialContributionPayment)') {
+				$reflabel = $langs->trans('SocialContribution');
+			}
+			if ($reflabel == '(DonationPayment)') {
+				$reflabel = $langs->trans('Donation');
+			}
+			if ($reflabel == '(SubscriptionPayment)') {
+				$reflabel = $langs->trans('Donation');
+			}
+			
 			$companystatic->id = $tabcompany[$key]['id'];
 			$companystatic->name = $tabcompany[$key]['name'];
 			$companystatic->client = $tabcompany[$key]['code_client'];
 
-			$date = dol_print_date($db->jdate($val["date"]), '%d%m%Y');
-
 			// Bank
 			foreach ( $tabbq[$key] as $k => $mt ) {
 				print $date . $sep;
@@ -434,8 +447,12 @@ if ($action == 'export_csv') {
 				print $sep;
 				print ($mt < 0 ? 'C' : 'D') . $sep;
 				print ($mt <= 0 ? price(- $mt) : $mt) . $sep;
-				print $val["type_payment"] . $sep;
-				print utf8_decode($val["ref"]) . $sep;
+				if ($companystatic->name == '') {
+					print $langs->trans('Bank')." - ". utf8_decode($val["ref"]) . $sep;
+				} else {
+					print $langs->trans("Bank") .' - '.utf8_decode($companystatic->name) . $sep;
+				}
+				print utf8_decode($reflabel) . $sep;
 				print "\n";
 			}
 
@@ -445,33 +462,45 @@ if ($action == 'export_csv') {
 					if ($mt) {
 						print $date . $sep;
 						print $journal . $sep;
-						if ($val["lib"] == '(SupplierInvoicePayment)') {
+						if ($tabtype[$key] == 'payment') {
+							print length_accountg($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) . $sep;
+							print length_accounta(html_entity_decode($k)) . $sep;
+						} else if ($tabtype[$key] == 'payment_supplier') {
 							print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) . $sep;
+							print length_accounta(html_entity_decode($k)) . $sep;
 						} else {
-							print length_accountg($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) . $sep;
+							print length_accountg(html_entity_decode($k)) . $sep;
+							print $sep;
 						}
-						print length_accounta(html_entity_decode($k)) . $sep;
 						print ($mt < 0 ? 'D' : 'C') . $sep;
 						print ($mt <= 0 ? price(- $mt) : $mt) . $sep;
-						print $val["type_payment"] . $sep;
-						print utf8_decode($val["ref"]) . $sep;
+						if ($companystatic->name == '') {
+							print $langs->trans('ThirdParty')." - ". utf8_decode($val["ref"]) . $sep;
+						} else {
+							print $langs->trans('ThirdParty')." - ". utf8_decode($companystatic->name) . $sep;
+						}
+						print utf8_decode($reflabel) . $sep;
 						print "\n";
 					}
 				}
 			} else {
 				foreach ( $tabbq[$key] as $k => $mt ) {
-						print $date . $sep;
-						print $journal . $sep;
-						print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . $sep;
-						print $sep;
-						print ($mt < 0 ? 'D' : 'C') . $sep;
-						print ($mt <= 0 ? price(- $mt) : $mt) . $sep;
-						print $val["type_payment"] . $sep;
-					print utf8_decode($val["ref"]) . $sep;
-						print "\n";
+					print $date . $sep;
+					print $journal . $sep;
+					print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . $sep;
+					print $sep;
+					print ($mt < 0 ? 'D' : 'C') . $sep;
+					print ($mt <= 0 ? price(- $mt) : $mt) . $sep;
+					if ($companystatic->name == '') {
+						print $langs->trans('ThirdParty')." - ". utf8_decode($val["ref"]) . $sep;
+					} else {
+						print $langs->trans('ThirdParty')." - ". utf8_decode($companystatic->name) . $sep;
 					}
+					print utf8_decode($reflabel) . $sep;
+					print "\n";
 				}
 			}
+		}
 	} else {
 		// Model Classic Export
 		foreach ( $tabpay as $key => $val ) {
@@ -482,6 +511,7 @@ if ($action == 'export_csv') {
 
 			// Bank
 			foreach ( $tabbq[$key] as $k => $mt ) {
+				print '"' . $journal . '"' . $sep;
 				print '"' . $date . '"' . $sep;
 				print '"' . $val["type_payment"] . '"' . $sep;
 				print '"' . length_accountg(html_entity_decode($k)) . '"' . $sep;
@@ -490,7 +520,6 @@ if ($action == 'export_csv') {
 				} else {
 					print '"' . $langs->trans("Bank") . ' - ' . utf8_decode($companystatic->name) . '"' . $sep;
 				}
-				// print '"' . $langs->trans("Bank") . '"' . $sep;
 				print '"' . ($mt >= 0 ? price($mt) : '') . '"' . $sep;
 				print '"' . ($mt < 0 ? price(- $mt) : '') . '"';
 				print "\n";
@@ -500,10 +529,10 @@ if ($action == 'export_csv') {
 			if (is_array($tabtp[$key])) {
 				foreach ( $tabtp[$key] as $k => $mt ) {
 					if ($mt) {
+						print '"' . $journal . '"' . $sep;
 						print '"' . $date . '"' . $sep;
 						print '"' . $val["type_payment"] . '"' . $sep;
 						print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep;
-						// print '"' . $companystatic->name . '"' . $sep;
 						if ($companystatic->name == '') {
 							print '"' . $langs->trans('ThirdParty') . " - " . utf8_decode($val["ref"]) . '"' . $sep;
 						} else {
@@ -516,10 +545,10 @@ if ($action == 'export_csv') {
 				}
 			} else {
 				foreach ( $tabbq[$key] as $k => $mt ) {
+					print '"' . $journal . '"' . $sep;
 					print '"' . $date . '"' . $sep;
 					print '"' . $val["ref"] . '"' . $sep;
 					print '"' . length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . '"' . $sep;
-					// print '"' . $langs->trans("Bank") . '"' . $sep;
 					if ($companystatic->name == '') {
 						print '"' . $langs->trans("Bank") . ' - ' . utf8_decode($val["ref"]) . '"' . $sep;
 					} else {
@@ -588,24 +617,33 @@ else {
 	foreach ( $tabpay as $key => $val ) {
 		$date = dol_print_date($db->jdate($val["date"]), 'day');
 
-		if ($val["lib"] == '(SupplierInvoicePayment)') {
-			$reflabel = $langs->trans('SupplierInvoicePayment');
+		$reflabel = $val["ref"];
+		if ($reflabel == '(SupplierInvoicePayment)') {
+			$reflabel = $langs->trans('Supplier');
+		}
+		if ($reflabel == '(CustomerInvoicePayment)') {
+			$reflabel = $langs->trans('Customer');
+		}		
+		if ($reflabel == '(SocialContributionPayment)') {
+			$reflabel = $langs->trans('SocialContribution');
+		}
+		if ($reflabel == '(DonationPayment)') {
+			$reflabel = $langs->trans('Donation');
 		}
-		if ($val["lib"] == '(CustomerInvoicePayment)') {
-			$reflabel = $langs->trans('CustomerInvoicePayment');
+		if ($reflabel == '(SubscriptionPayment)') {
+			$reflabel = $langs->trans('SubscriptionPayment');
 		}
 
 		// Bank
 		foreach ( $tabbq[$key] as $k => $mt ) {
 			print "<tr " . $bc[$var] . ">";
 			print "<td>" . $date . "</td>";
-			print "<td>" . $reflabel . "</td>";
+			print "<td>" . $ref . "</td>";
 			print "<td>" . length_accountg($k) . "</td>";
-			// print "<td>" . $langs->trans('Bank') . "</td>";
 			if ($val['soclib'] == '') {
-				print "<td>" . $langs->trans('Bank') . " - " . $val["ref"] . "</td>";
+				print "<td>" . $bank_code_journal->label . " - " . $val["ref"] . "</td>";
 			} else {
-				print "<td>" . $langs->trans("Bank") . " - " . $val['soclib'] . "</td>";
+				print "<td>" . $bank_code_journal->label . " - " . $val['soclib'] . "</td>";
 			}
 			print "<td>" . $val["type_payment"] . "</td>";
 			print "<td align='right'>" . ($mt >= 0 ? price($mt) : '') . "</td>";
@@ -619,19 +657,9 @@ else {
 				if ($k != 'type') {
 					print "<tr " . $bc[$var] . ">";
 					print "<td>" . $date . "</td>";
-					print "<td>" . $val["soclib"] . "</td>";
-					// print "<td>" . length_accounta($k) . "</td>";
-					if (length_accounta($k) == '') {
-						print "<td>" . length_accounta($conf->global->ACCOUNTING_ACCOUNT_TRANSFER_CASH) . "</td>";
-					} else {
+					print "<td>" . $ref . "</td>";
 					print "<td>" . length_accounta($k) . "</td>";
-					}
-					// print "<td>" . $langs->trans('ThirdParty') . " (" . $val['soclib'] . ")</td>";
-					if ($val['soclib'] == '') {
-						print "<td>" . $langs->trans('ThirdParty') . " - " . $val["ref"] . "</td>";
-					} else {
-						print "<td>" . $langs->trans("ThirdParty") . ' - ' . $val['soclib'] . "</td>";
-					}
+					print "<td>" . $reflabel . ' ' . $val['soclib'] . "</td>";
 					print "<td>" . $val["type_payment"] . "</td>";
 					print "<td align='right'>" . ($mt < 0 ? price(- $mt) : '') . "</td>";
 					print "<td align='right'>" . ($mt >= 0 ? price($mt) : '') . "</td>";
@@ -642,14 +670,9 @@ else {
 			foreach ( $tabbq[$key] as $k => $mt ) {
 				print "<tr " . $bc[$var] . ">";
 				print "<td>" . $date . "</td>";
-				print "<td>" . $reflabel . "</td>";
+				print "<td>" . $ref . "</td>";
 				print "<td>" . length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . "</td>";
-				// print "<td>" . $langs->trans('ThirdParty') . "</td>";
-				if ($val['soclib'] == '') {
-					print "<td>" . $langs->trans('ThirdParty') . " - " . $val["ref"] . "</td>";
-				} else {
-					print "<td>" . $langs->trans("ThirdParty") . ' - ' . $val['soclib'] . "</td>";
-				}
+				print "<td>" . $reflabel . "</td>";
 				print "<td>&nbsp;</td>";
 				print "<td align='right'>" . ($mt < 0 ? price(- $mt) : '') . "</td>";
 				print "<td align='right'>" . ($mt >= 0 ? price($mt) : '') . "</td>";

+ 0 - 45
htdocs/accountancy/journal/index.php

@@ -1,45 +0,0 @@
-<?php
-/* Copyright (C) 2013-2014 Olivier Geffroy      <jeff@jeffinfo.com>
- * Copyright (C) 2013-2014 Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
- * Copyright (C) 2013-2014  Florian Henry	    <florian.henry@open-concept.pro>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/**
- * \file htdocs/accountancy/journal/index.php
- * \ingroup Accounting Expert
- * \brief Index
- */
-require '../../main.inc.php';
-
-// Langs
-$langs->load("compta");
-$langs->load("bills");
-$langs->load("other");
-$langs->load("main");
-$langs->load("accountancy");
-
-// Security check
-if ($user->societe_id > 0)
-	accessforbidden();
-
-llxHeader('', 'Journaux', '');
-
-$form = new Form($db);
-
-// End of page
-llxFooter();
-$db->close();

+ 24 - 10
htdocs/accountancy/journal/purchasesjournal.php

@@ -4,7 +4,7 @@
  * Copyright (C) 2011		Juanjo Menent		<jmenent@2byte.es>
  * Copyright (C) 2012		Regis Houssin		<regis@dolibarr.fr>
  * Copyright (C) 2013-2015  Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
- * Copyright (C) 2013-2014  Olivier Geffroy		<jeff@jeffinfo.com>
+ * Copyright (C) 2013-2016  Olivier Geffroy		<jeff@jeffinfo.com>
  * Copyright (C) 2013-2016  Florian Henry	    <florian.henry@open-concept.pro>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -22,9 +22,9 @@
  */
 
 /**
- * \file htdocs/accountancy/journal/purchasesjournal.php
- * \ingroup Accounting Expert
- * \brief Page with purchases journal
+ * \file		htdocs/accountancy/journal/purchasesjournal.php
+ * \ingroup		Advanced accountancy
+ * \brief		Page with purchases journal
  */
 require '../../main.inc.php';
 
@@ -123,7 +123,7 @@ if ($result) {
 	$i = 0;
 	while ( $i < $num ) {
 		$obj = $db->fetch_object($result);
-		// contrôles
+		// contrôles
 		$compta_soc = (! empty($obj->code_compta_fournisseur)) ? $obj->code_compta_fournisseur : $cptfour;
 		$compta_prod = $obj->compte;
 		if (empty($compta_prod)) {
@@ -164,6 +164,19 @@ if ($action == 'writebookkeeping') {
 	$error = 0;
 
 	foreach ( $tabfac as $key => $val ) {
+	
+	$invoicestatic->id = $key;
+			$invoicestatic->ref = $val["ref"];
+			$invoicestatic->ref = $val["refsologest"];
+			$invoicestatic->refsupplier = $val["refsuppliersologest"];
+			$invoicestatic->type = $val["type"];
+			$invoicestatic->description = html_entity_decode(dol_trunc($val["description"], 32));
+	
+	$companystatic->id = $tabcompany[$key]['id'];
+			$companystatic->name = $tabcompany[$key]['name'];
+			$companystatic->client = $tabcompany[$key]['code_client'];
+	
+	
 		foreach ( $tabttc[$key] as $k => $mt ) {
 			// get compte id and label
 
@@ -175,7 +188,7 @@ if ($action == 'writebookkeeping') {
 			$bookkeeping->fk_doc = $key;
 			$bookkeeping->fk_docdet = $val["fk_facturefourndet"];
 			$bookkeeping->code_tiers = $tabcompany[$key]['code_fournisseur'];
-			$bookkeeping->label_compte = $tabcompany[$key]['name'];
+			$bookkeeping->label_compte = utf8_decode(dol_trunc($companystatic->name,16)).' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("Code_tiers");
 			$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER;
 			$bookkeeping->montant = $mt;
 			$bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
@@ -193,6 +206,8 @@ if ($action == 'writebookkeeping') {
 
 		// Product / Service
 		foreach ( $tabht[$key] as $k => $mt ) {
+		$accountingaccount = new AccountingAccount($db);
+			$accountingaccount->fetch(null, $k);
 			if ($mt) {
 				// get compte id and label
 				$accountingaccount = new AccountingAccount($db);
@@ -205,7 +220,7 @@ if ($action == 'writebookkeeping') {
 					$bookkeeping->fk_doc = $key;
 					$bookkeeping->fk_docdet = $val["fk_facturefourndet"];
 					$bookkeeping->code_tiers = '';
-					$bookkeeping->label_compte = $accountingaccount->label;
+					$bookkeeping->label_compte = utf8_decode(dol_trunc($companystatic->name,16)). ' - ' . $invoicestatic->refsupplier  . ' - ' . utf8_decode($accountingaccount->label);
 					$bookkeeping->numero_compte = $k;
 					$bookkeeping->montant = $mt;
 					$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
@@ -236,7 +251,7 @@ if ($action == 'writebookkeeping') {
 				$bookkeeping->fk_doc = $key;
 				$bookkeeping->fk_docdet = $val["fk_facturefourndet"];
 				$bookkeeping->code_tiers = '';
-				$bookkeeping->label_compte = $langs->trans("VAT");
+				$bookkeeping->label_compte = utf8_decode(dol_trunc($companystatic->name,16)).' - ' . $invoicestatic->refsupplier .' - '. $langs->trans("VAT");
 				$bookkeeping->numero_compte = $k;
 				$bookkeeping->montant = $mt;
 				$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
@@ -248,7 +263,7 @@ if ($action == 'writebookkeeping') {
 				$result = $bookkeeping->create($user);
 				if ($result < 0) {
 					$error ++;
-					setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
+					setEventMessages($object->error, $object->errors, 'errors');
 				}
 			}
 		}
@@ -517,5 +532,4 @@ if ($action == 'export_csv') {
 	// End of page
 	llxFooter();
 }
-
 $db->close();

+ 39 - 21
htdocs/accountancy/journal/sellsjournal.php

@@ -7,7 +7,7 @@
  * Copyright (C) 2013-2016	Alexandre Spangaro		<aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2013-2016	Florian Henry			<florian.henry@open-concept.pro>
  * Copyright (C) 2013-2016	Olivier Geffroy			<jeff@jeffinfo.com>
- * Copyright (C) 2014       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
+ * Copyright (C) 2014       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,9 +24,9 @@
  */
 
 /**
- * \file 		htdocs/accountancy/journal/sellsjournal.php
- * \ingroup 	Advanced accountancy
- * \brief 		Page with sells journal
+ * \file		htdocs/accountancy/journal/sellsjournal.php
+ * \ingroup		Advanced accountancy
+ * \brief		Page with sells journal
  */
 require '../../main.inc.php';
 
@@ -40,6 +40,7 @@ require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php';
 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php';
 
 // Langs
+$langs->load("commercial");
 $langs->load("compta");
 $langs->load("bills");
 $langs->load("other");
@@ -141,15 +142,14 @@ if ($result) {
 
 		// Situation invoices handling
 		$line = new FactureLigne($db);
-		$line->fetch($obj->fdid); // id of line
-		$prev_progress = 0;
+		$line->fetch($obj->rowid);
+		$prev_progress = $line->get_prev_progress();
 		if ($obj->type == Facture::TYPE_SITUATION) {
-		    // Avoid divide by 0
+			// Avoid divide by 0
 			if ($obj->situation_percent == 0) {
 				$situation_ratio = 0;
 			} else {
-		        $prev_progress = $line->get_prev_progress($obj->rowid);   // id of invoice
-			    $situation_ratio = ($obj->situation_percent - $prev_progress) / $obj->situation_percent;
+				$situation_ratio = ($obj->situation_percent - $prev_progress) / $obj->situation_percent;
 			}
 		} else {
 			$situation_ratio = 1;
@@ -193,6 +193,14 @@ if ($action == 'writebookkeeping') {
 	$error = 0;
 
 	foreach ( $tabfac as $key => $val ) {
+			$companystatic->id = $tabcompany[$key]['id'];
+			$companystatic->name = $tabcompany[$key]['name'];
+			$companystatic->client = $tabcompany[$key]['code_client'];
+
+$invoicestatic->id = $key;
+		$invoicestatic->ref = $val["ref"];
+	
+	
 		foreach ( $tabttc[$key] as $k => $mt ) {
 			$bookkeeping = new BookKeeping($db);
 			$bookkeeping->doc_date = $val["date"];
@@ -203,7 +211,8 @@ if ($action == 'writebookkeeping') {
 			$bookkeeping->fk_docdet = $val["fk_facturedet"];
 			$bookkeeping->code_tiers = $tabcompany[$key]['code_client'];
 			$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
-			$bookkeeping->label_compte = $tabcompany[$key]['name'];
+			//$bookkeeping->label_compte = $tabcompany[$key]['name'];
+			$bookkeeping->label_compte = utf8_decode(dol_trunc($companystatic->name,16)).' - ' . $invoicestatic->ref . ' - ' . $langs->trans("Code_tiers");
 			$bookkeeping->montant = $mt;
 			$bookkeeping->sens = ($mt >= 0) ? 'D' : 'C';
 			$bookkeeping->debit = ($mt >= 0) ? $mt : 0;
@@ -233,7 +242,7 @@ if ($action == 'writebookkeeping') {
 					$bookkeeping->fk_docdet = $val["fk_facturedet"];
 					$bookkeeping->code_tiers = '';
 					$bookkeeping->numero_compte = $k;
-					$bookkeeping->label_compte = $accountingaccount->label;
+					$bookkeeping->label_compte = utf8_decode(dol_trunc($companystatic->name,16)). ' - ' . $invoicestatic->ref  . ' - ' . utf8_decode($accountingaccount->label);
 					$bookkeeping->montant = $mt;
 					$bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
 					$bookkeeping->debit = ($mt < 0) ? $mt : 0;
@@ -263,7 +272,7 @@ if ($action == 'writebookkeeping') {
 				$bookkeeping->fk_docdet = $val["fk_facturedet"];
 				$bookkeeping->code_tiers = '';
 				$bookkeeping->numero_compte = $k;
-				$bookkeeping->label_compte = $langs->trans("VAT");
+				$bookkeeping->label_compte = utf8_decode(dol_trunc($companystatic->name,16)).' - ' . $invoicestatic->ref .' - '. $langs->trans("VAT");
 				$bookkeeping->montant = $mt;
 				$bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
 				$bookkeeping->debit = ($mt < 0) ? $mt : 0;
@@ -274,7 +283,7 @@ if ($action == 'writebookkeeping') {
 				$result = $bookkeeping->create($user);
 				if ($result < 0) {
 					$error ++;
-					setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
+					setEventMessages($object->error, $object->errors, 'errors');
 				}
 			}
 		}
@@ -304,6 +313,9 @@ if ($action == 'export_csv') {
 			$companystatic->name = $tabcompany[$key]['name'];
 			$companystatic->client = $tabcompany[$key]['code_client'];
 
+$invoicestatic->id = $key;
+		$invoicestatic->ref = $val["ref"];
+		
 			$date = dol_print_date($db->jdate($val["date"]), '%d%m%Y');
 
 			foreach ( $tabttc[$key] as $k => $mt ) {
@@ -313,7 +325,8 @@ if ($action == 'export_csv') {
 				print length_accounta(html_entity_decode($k)) . $sep;
 				print ($mt < 0 ? 'C' : 'D') . $sep;
 				print ($mt <= 0 ? price(- $mt) : $mt) . $sep;
-				print utf8_decode($companystatic->name) . $sep;
+				print utf8_decode(dol_trunc($companystatic->name,16)).' - ' . $invoicestatic->ref . ' - ' . $langs->trans("Code_tiers")  . $sep;
+				//print utf8_decode($companystatic->name) . $sep;
 				print $val["ref"];
 				print "\n";
 			}
@@ -328,7 +341,8 @@ if ($action == 'export_csv') {
 					print $sep;
 					print ($mt < 0 ? 'D' : 'C') . $sep;
 					print ($mt <= 0 ? price(- $mt) : $mt) . $sep;
-					print dol_trunc($accountingaccount_static->label, 32) . $sep;
+					print utf8_decode(dol_trunc($companystatic->name,16)). ' - ' . $invoicestatic->ref  . ' - ' . utf8_decode ( utf8_decode ( $accountingaccount_static->label)) . $sep;
+					//print dol_trunc($accountingaccount_static->label, 32) . $sep;
 					print $val["ref"];
 					print "\n";
 				}
@@ -343,7 +357,8 @@ if ($action == 'export_csv') {
 					print $sep;
 					print ($mt < 0 ? 'D' : 'C') . $sep;
 					print ($mt <= 0 ? price(- $mt) : $mt) . $sep;
-					print $langs->trans("VAT") . $sep;
+					print utf8_decode(dol_trunc($companystatic->name,16)).' - ' . $invoicestatic->ref .' - '. $langs->trans("VAT") . $sep;
+					//print $langs->trans("VAT") . $sep;
 					print $val["ref"];
 					print "\n";
 				}
@@ -355,6 +370,9 @@ if ($action == 'export_csv') {
 			$companystatic->id = $tabcompany[$key]['id'];
 			$companystatic->name = $tabcompany[$key]['name'];
 			$companystatic->client = $tabcompany[$key]['code_client'];
+			
+			$invoicestatic->id = $key;
+		$invoicestatic->ref = $val["ref"];
 
 			$date = dol_print_date($db->jdate($val["date"]), 'day');
 
@@ -362,7 +380,7 @@ if ($action == 'export_csv') {
 				print '"' . $date . '"' . $sep;
 				print '"' . $val["ref"] . '"' . $sep;
 				print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep;
-				print '"' . utf8_decode(dol_trunc($companystatic->name,16)).' - ' . $companystatic->ref_client . ' - ' . $langs->trans("Code_tiers") . '"' . $sep;
+				print '"' . utf8_decode(dol_trunc($companystatic->name,16)).' - ' . $invoicestatic->ref . ' - ' . $langs->trans("Code_tiers") . '"' . $sep;
 				//print '"' . utf8_decode($companystatic->name) . '"' . $sep;
 				print '"' . ($mt >= 0 ? price($mt) : '') . '"' . $sep;
 				print '"' . ($mt < 0 ? price(- $mt) : '') . '"';
@@ -392,7 +410,7 @@ if ($action == 'export_csv') {
 					print '"' . $date . '"' . $sep;
 					print '"' . $val["ref"] . '"' . $sep;
 					print '"' . length_accountg(html_entity_decode($k)) . '"' . $sep;
-					print '"' . utf8_decode(dol_trunc($companystatic->name,16)).' - '. $langs->trans("VAT") . '"' . $sep;
+					print '"' . utf8_decode(dol_trunc($companystatic->name,16)).' - ' . $invoicestatic->ref .' - '. $langs->trans("VAT") . '"' . $sep;
 					//print '"' . $langs->trans("VAT") . '"' . $sep;
 					print '"' . ($mt < 0 ? price(- $mt) : '') . '"' . $sep;
 					print '"' . ($mt >= 0 ? price($mt) : '') . '"';
@@ -480,7 +498,7 @@ if ($action == 'export_csv') {
 			print "<td>" . length_accounta($k);
 			//print "</td><td>" . $langs->trans("ThirdParty");
 			//print ' (' . $companystatic->getNomUrl(0, 'customer', 16) . ')';
-			print "<td>" . $companystatic->getNomUrl(0, 'customer', 16) . ' - ' . $invoicestatic->ref_client . ' - ' . $langs->trans("Code_tiers"). "</td>";
+			print "<td>" . $companystatic->getNomUrl(0, 'customer', 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("Code_tiers"). "</td>";
 			print "</td><td align='right'>" . ($mt >= 0 ? price($mt) : '') . "</td>";
 			print "<td align='right'>" . ($mt < 0 ? price(- $mt) : '') . "</td>";
 		}
@@ -497,7 +515,7 @@ if ($action == 'export_csv') {
 				print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
 				print "<td>" . length_accountg($k) . "</td>";
 				//print "<td>" . $accountingaccount->label . "</td>";
-				print "<td>" . $companystatic->getNomUrl(0, 'customer', 16). ' - ' . $invoicestatic->ref_client  . ' - ' . utf8_decode ( utf8_decode ( $accountingaccount->label)) . "</td>";
+				print "<td>" . $companystatic->getNomUrl(0, 'customer', 16). ' - ' . $invoicestatic->ref  . ' - ' . utf8_decode ( utf8_decode ( $accountingaccount->label)) . "</td>";
 				print "<td align='right'>" . ($mt < 0 ? price(- $mt) : '') . "</td>";
 				print "<td align='right'>" . ($mt >= 0 ? price($mt) : '') . "</td>";
 				print "</tr>";
@@ -511,7 +529,7 @@ if ($action == 'export_csv') {
 				print "<td>" . $date . "</td>";
 				print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
 				print "<td>" . length_accountg($k) . "</td>";
-				print "<td>" . $companystatic->getNomUrl(0, 'customer', 16). ' - ' . $invoicestatic->ref_client .' - '. $langs->trans("VAT")  . "</td>";
+				print "<td>" . $companystatic->getNomUrl(0, 'customer', 16). ' - ' . $invoicestatic->ref .' - '. $langs->trans("VAT")  . "</td>";
 				//print "<td>" . $langs->trans("VAT") . "</td>";
 				print "<td align='right'>" . ($mt < 0 ? price(- $mt) : '') . "</td>";
 				print "<td align='right'>" . ($mt >= 0 ? price($mt) : '') . "</td>";

+ 0 - 0
htdocs/accountancy/report/index.html


+ 240 - 0
htdocs/accountancy/report/result.php

@@ -0,0 +1,240 @@
+<?php
+/* Copyright (C) 2016		Jamal Elbaz			<jamelbaz@gmail.pro>
+ * Copyright (C) 2016 		Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file 		htdocs/accountancy/report/result.php
+ * \ingroup 	Advanced accountancy
+ * \brief 		Page for accounting result
+ */
+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("accountancy");
+$langs->load("compta");
+
+$mesg = '';
+$action = GETPOST('action');
+$cat_id = GETPOST('account_category');
+$selectcpt = GETPOST('cpt_bk');
+$id = GETPOST('id', 'int');
+$rowid = GETPOST('rowid', 'int');
+$cancel = GETPOST('cancel');
+
+// Filter
+$year = $_GET["year"];
+if ($year == 0) {
+	$year_current = strftime("%Y", time());
+	$year_start = $year_current;
+} else {
+	$year_current = $year;
+	$year_start = $year;
+}
+
+if($cat_id == 0){
+	$cat_id = null;	
+}
+
+// Security check
+if ($user->societe_id > 0)
+	accessforbidden();
+if (! $user->rights->accounting->comptarapport->lire)
+	accessforbidden();
+
+$AccCat = new AccountancyCategory($db);
+
+/*
+ * View
+ */
+llxheader('', $langs->trans('ReportInOut'));
+
+$formaccounting = new FormAccounting($db);
+$form = new Form($db);
+
+$textprevyear = '<a href="' . $_SERVER["PHP_SELF"] . '?year=' . ($year_current - 1) . '">' . img_previous() . '</a>';
+$textnextyear = '&nbsp;<a href="' . $_SERVER["PHP_SELF"] . '?year=' . ($year_current + 1) . '">' . img_next() . '</a>';
+
+print load_fiche_titre($langs->trans('ReportInOut') . " " . $textprevyear . " " . $langs->trans("Year") . " " . $year_start . " " . $textnextyear);
+	
+print '<table class="border" width="100%">';
+	
+$months = array( $langs->trans("JanuaryMin"), 
+				$langs->trans("FebruaryMin"), 
+				$langs->trans("MarchMin"), 
+				$langs->trans("AprilMin"), 
+				$langs->trans("MayMin"), 
+				$langs->trans("JuneMin"), 
+				$langs->trans("JulyMin"), 
+				$langs->trans("AugustMin"), 
+				$langs->trans("SeptemberMin"), 
+				$langs->trans("OctoberMin"), 
+				$langs->trans("NovemberMin"), 
+				$langs->trans("DecemberMin"),
+			);
+
+print '<tr class="liste_titre"><th class="liste_titre">'.$langs->trans("Account").'</th>';
+print '<th class="liste_titre">'.$langs->trans("Description").'</th>';
+print '<th class="liste_titre" align="center">N-1</th>';		
+print '<th class="liste_titre" align="center">'.$langs->trans("NReal").'</th>';
+foreach($months as $k => $v){
+	print '<th class="liste_titre"  align="center">'.$langs->trans($v).'</th>';
+}
+print	'</tr>';			
+
+$cats = $AccCat->getCatsCpts();
+$catsCalcule = $AccCat->getCatsCal();
+
+$j=1;
+$sommes = array();
+
+if(!empty($cats))
+{
+	foreach ( $cats as $name_cat => $cpts )
+	{
+		print "<tr class='liste_titre'>";
+		print '<td colspan="17">' . $name_cat . '</td>';
+		print "</tr>\n";
+		$position = -1;
+		$code = -1;
+		foreach($cpts as $i => $cpt){
+			$var = ! $var;
+
+			$position = $cpt['position'];
+			$code = $cpt['code'];
+
+			$resultNP = $AccCat->getResult($cpt['account_number'], 0, $year_current -1, $cpt['dc']);
+			$resultN = $AccCat->getResult($cpt['account_number'], 0, $year_current, $cpt['dc']);
+			$sommes[$code]['NP'] += $resultNP;
+			$sommes[$code]['N'] += $resultN; 
+			print "<tr $bc[$var]>";
+			print '<td>' . $cpt['account_number'] . '</td>';
+			print '<td>' . $cpt['name_cpt'] . '</td>';
+			print '<td>' . price($resultNP)  . '</td>';
+			print '<td>' . price($resultN) . '</td>';
+				
+			foreach($months as $k => $v){
+				$resultM = $AccCat->getResult($cpt['account_number'], $k+1, $year_current, $cpt['dc']);
+				$sommes[$code]['M'][$k] += $resultM;
+				print '<td align="right">' . price($resultM) . '</td>';
+			}
+				
+			print "</tr>\n";
+		}
+
+		// If it's a calculated catgory
+		$p = $position + 1;
+		if(array_key_exists($p, $catsCalcule)){
+			$formula = $catsCalcule[$p]['formula'];
+
+			print "<tr class='liste_titre'>";
+			print '<td colspan="2">' . $catsCalcule[$p]['label'] . '</td>';
+
+			$vars = array();
+
+			// Previous Fiscal year (N-1)
+			foreach($sommes as $code => $det){
+				$vars[$code] = $det['NP'];
+			}
+			$result = strtr($formula, $vars);
+			eval( '$result = (' . $result . ');' );
+			print '<td align="right">' . price($result) . '</td>';
+			$code = $catsCalcule[$p]['code']; // code categorie de calcule
+			$sommes[$code]['NP'] += $result;
+
+			// Current fiscal year (N)
+			foreach($sommes as $code => $det){
+				$vars[$code] = $det['N'];
+			}
+			$result = strtr($formula, $vars);
+			eval( '$result = (' . $result . ');' );
+			print '<td align="right">' . price($result) . '</td>';	
+			$sommes[$code]['N'] += $result;
+				
+			// Detail by month
+			foreach($months as $k => $v){
+				foreach($sommes as $code => $det){
+					$vars[$code] = $det['M'][$k];
+				}
+				$result = strtr($formula, $vars);
+				eval( '$result = (' . $result . ');' );
+				print '<td align="right">' . price($result) . '</td>';
+				$sommes[$code]['M'][$k] += $result;
+			}
+	
+			//print '<td colspan="15">' . $catsCalcule[$p]['formula'] . '</td>';
+			print "</tr>\n";
+			unset($catsCalcule[$p]); // j'élimine la catégorie calculée après affichage
+		}
+		$j++;
+	}
+		
+	// Others calculed category
+	foreach($catsCalcule as $p => $catc)
+	{
+		$formula = $catsCalcule[$p]['formula'];
+
+		print "<tr class='liste_titre'>";
+		print '<td colspan="2">' . $catsCalcule[$p]['label'] . '</td>';
+
+		$vars = array();
+
+		// Previous Fiscal year (N-1)
+		foreach($sommes as $code => $det){
+			$vars[$code] = $det['NP'];
+		}
+		$result = strtr($formula, $vars);
+		eval( '$result = (' . $result . ');' );
+		print '<td align="right">' . price($result) . '</td>';
+		$code = $catsCalcule[$p]['code']; // code categorie de calcule
+		$sommes[$code]['NP'] += $result;
+
+		// Current fiscal year (N)
+		foreach($sommes as $code => $det){
+			$vars[$code] = $det['N'];
+		}
+		$result = strtr($formula, $vars);
+		eval( '$result = (' . $result . ');' );
+		print '<td align="right">' . price($result) . '</td>';	
+		$sommes[$code]['N'] += $result;
+
+		// Detail by month
+		foreach($months as $k => $v){
+			foreach($sommes as $code => $det){
+				$vars[$code] = $det['M'][$k];
+			}
+			$result = strtr($formula, $vars);
+			eval( '$result = (' . $result . ');' );
+			print '<td align="right">' . price($result) . '</td>';
+			$sommes[$code]['M'][$k] += $result;
+		}
+
+		//print '<td colspan="15">' . $catsCalcule[$p]['formula'] . '</td>';
+		print "</tr>\n";
+	}
+}
+
+print "</table>";
+
+llxFooter();
+$db->close();

+ 5 - 5
htdocs/accountancy/supplier/index.php

@@ -19,9 +19,9 @@
  */
 
 /**
- * \file htdocs/accountancy/supplier/index.php
- * \ingroup Accounting Expert
- * \brief Home supplier ventilation
+ * \file		htdocs/accountancy/supplier/index.php
+ * \ingroup		Advanced accountancy
+ * \brief		Home supplier ventilation
  */
 require '../../main.inc.php';
 
@@ -42,7 +42,7 @@ if ($user->societe_id > 0)
 if (! $user->rights->accounting->ventilation->read)
 	accessforbidden();
 	
-	// Filter
+// Filter
 $year = $_GET["year"];
 if ($year == 0) {
 	$year_current = strftime("%Y", time());
@@ -91,7 +91,7 @@ if ($action == 'validatehistory') {
 	$sql1 .= " SET fd.fk_code_ventilation = 0";
 	$sql1 .= ' WHERE fd.fk_code_ventilation NOT IN ';
 	$sql1 .= '	(SELECT accnt.rowid ';
-	$sql1 .= '	FROM ' . MAIN_DB_PREFIX . 'accountingaccount as accnt';
+	$sql1 .= '	FROM ' . MAIN_DB_PREFIX . 'accounting_account as accnt';
 	$sql1 .= '	INNER JOIN ' . MAIN_DB_PREFIX . 'accounting_system as syst';
 	$sql1 .= '	ON accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=' . $conf->global->CHARTOFACCOUNTS . ')';
 	

+ 11 - 10
htdocs/accountancy/supplier/lines.php

@@ -1,8 +1,8 @@
 <?php
-/* Copyright (C) 2013-2014 Olivier Geffroy		<jeff@jeffinfo.com>
+/* Copyright (C) 2013-2016 Olivier Geffroy		<jeff@jeffinfo.com>
  * Copyright (C) 2013-2016 Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2014-2015 Ari Elbaz (elarifr)	<github@accedinfo.com>  
- * Copyright (C) 2013-2014 Florian Henry		<florian.henry@open-concept.pro>
+ * Copyright (C) 2013-2016 Florian Henry		<florian.henry@open-concept.pro>
  * Copyright (C) 2014	   Juanjo Menent		<jmenent@2byte.es>
  *   
  * This program is free software; you can redistribute it and/or modify
@@ -20,9 +20,9 @@
  */
 
 /**
- * \file htdocs/accountancy/supplier/lines.php
- * \ingroup Accounting Expert
- * \brief Page of detail of the lines of ventilation of invoices suppliers
+ * \file 		htdocs/accountancy/supplier/lines.php
+ * \ingroup 	Advanced accountancy
+ * \brief 		Page of detail of the lines of ventilation of invoices suppliers
  */
 require '../../main.inc.php';
 
@@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT . '/accountancy/class/html.formventilation.class.
 require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture.class.php';
 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
+require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
 
 // Langs
 $langs->load("compta");
@@ -213,11 +214,11 @@ if ($result) {
 	print "</tr>\n";
 	
 	print '<tr class="liste_titre"><td><input type="text" class="flat" name="search_invoice" size="10" value="' . $search_invoice . '"></td>';
-	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_ref" value="' . $search_ref . '"></td>';
-	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_label" value="' . $search_label . '"></td>';
+	print '<td class="liste_titre"><input type="text" class="flat" size="10" name="search_ref" value="' . $search_ref . '"></td>';
+	print '<td class="liste_titre"><input type="text" class="flat" size="10" name="search_label" value="' . $search_label . '"></td>';
 	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_desc" value="' . $search_desc . '"></td>';
 	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="8" name="search_amount" value="' . $search_amount . '"></td>';
-	print '<td class="liste_titre" align="center">%<input type="text" class="flat" size="5" name="search_vat" value="' . $search_vat . '"></td>';
+	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="5" name="search_vat" value="' . $search_vat . '">%</td>';
 	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="15" name="search_account" value="' . $search_account . '"></td>';
 	print '<td class="liste_titre" colspan="2">&nbsp;</td>';
     print '<td class="liste_titre" align="right">';
@@ -233,7 +234,7 @@ if ($result) {
 	while ( $i < min($num_lines, $limit) ) {
 		$objp = $db->fetch_object($result);
 		$var = ! $var;
-		$codeCompta = $objp->account_number . ' - ' . $objp->label;
+		$codeCompta = length_accountg($objp->account_number) . ' - ' . $objp->label;
 		
 		print "<tr $bc[$var]>";
 		
@@ -257,7 +258,7 @@ if ($result) {
 		print '<td>' . nl2br(dol_trunc($objp->description, 32)) . '</td>';
 		print '<td align="right">' . price($objp->total_ht) . '</td>';
 		print '<td align="center">' . price($objp->tva_tx) . '</td>';
-		print '<td align="center">' . $codeCompta . '</td>';
+		print '<td>' . $codeCompta . '</td>';
 		print '<td align="right">' . $objp->rowid . '</td>';
 		print '<td align="left"><a href="./card.php?id=' . $objp->rowid . '">';
 		print img_edit();

+ 2 - 2
htdocs/accountancy/supplier/list.php

@@ -254,11 +254,11 @@ if ($result) {
 
 	print '<tr class="liste_titre">';
 	print '<td class="liste_titre"><input type="text" class="flat" size="10" name="search_invoice" value="' . $search_invoice . '"></td>';
-	print '<td class="liste_titre"><input type="text" class="flat" size="15" name="search_ref" value="' . $search_ref . '"></td>';
+	print '<td class="liste_titre">%<input type="text" class="flat" size="15" name="search_ref" value="' . $search_ref . '"></td>';
 	print '<td class="liste_titre"><input type="text" class="flat" size="20" name="search_label" value="' . $search_label . '"></td>';
 	print '<td class="liste_titre"><input type="text" class="flat" size="20" name="search_desc" value="' . $search_desc . '"></td>';
 	print '<td class="liste_titre" align="right"><input type="text" class="flat" size="10" name="search_amount" value="' . $search_amount . '"></td>';
-	print '<td class="liste_titre" align="center"><input type="text" class="flat" size="3" name="search_vat" value="' . $search_vat . '">%</td>';
+	print '<td class="liste_titre" align="center">%<input type="text" class="flat" size="5" name="search_vat" value="' . $search_vat . '"></td>';
 	print '<td class="liste_titre" align="center">&nbsp;</td>';
 	print '<td class="liste_titre">&nbsp;</td>';
 	print '<td align="right" colspan="2" class="liste_titre">';

+ 2 - 7
htdocs/adherents/card.php

@@ -356,13 +356,8 @@ if (empty($reshook))
 							}
 							else
 							{
-								// Create small thumbs for company (Ratio is near 16/9)
-								// Used on logon for example
-								$imgThumbSmall = vignette($newfile, $maxwidthsmall, $maxheightsmall, '_small', $quality);
-
-								// Create mini thumbs for company (Ratio is near 16/9)
-								// Used on menu or for setup page for example
-								$imgThumbMini = vignette($newfile, $maxwidthmini, $maxheightmini, '_mini', $quality);
+							    // Create thumbs
+							    $object->addThumbs($newfile);
 							}
 						}
 					}

+ 15 - 11
htdocs/adherents/class/adherent_type.class.php

@@ -2,6 +2,7 @@
 /* Copyright (C) 2002      Rodolphe Quiedeville <rodolphe@quiedeville.org>
  * Copyright (C) 2004-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2009      Regis Houssin        <regis.houssin@capnetworks.com>
+ * Copyright (C) 2016      Charlie Benke	<charlie@patas-monkey.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,10 +36,14 @@ class AdherentType extends CommonObject
     public $table_element = 'adherent_type';
     public $element = 'adherent_type';
 
+    var $id;
+    var $ref;
     var $libelle;
-    var $cotisation;  // Soumis a la cotisation
-    var $vote;		  // droit de vote
-    var $mail_valid;  //mail envoye lors de la validation
+    var $cotisation;  	// Soumis a la cotisation
+    var $note;		
+    var $vote;		// droit de vote
+    var $mail_valid;  	//mail envoye lors de la validation
+    var $statut;
 
 
     /**
@@ -110,7 +115,7 @@ class AdherentType extends CommonObject
         $sql.= "note = '".$this->db->escape($this->note)."',";
         $sql.= "vote = '".$this->vote."',";
         $sql.= "mail_valid = '".$this->db->escape($this->mail_valid)."'";
-        $sql .= " WHERE rowid = $this->id";
+        $sql .= " WHERE rowid =".$this->id;
 
         $result = $this->db->query($sql);
         if ($result)
@@ -164,7 +169,7 @@ class AdherentType extends CommonObject
                 return 1;
             }
             else
-			{
+            {
                 return 0;
             }
         }
@@ -223,7 +228,7 @@ class AdherentType extends CommonObject
     {
         global $conf,$langs;
 
-        $projets = array();
+        $adherenttypes = array();
 
         $sql = "SELECT rowid, libelle";
         $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type";
@@ -241,7 +246,7 @@ class AdherentType extends CommonObject
                 {
                     $obj = $this->db->fetch_object($resql);
 
-                    $projets[$obj->rowid] = $langs->trans($obj->libelle);
+                    $adherenttypes[$obj->rowid] = $langs->trans($obj->libelle);
                     $i++;
                 }
             }
@@ -250,8 +255,7 @@ class AdherentType extends CommonObject
         {
             print $this->db->error();
         }
-
-        return $projets;
+        return $adherenttypes;
     }
 
 
@@ -308,7 +312,7 @@ class AdherentType extends CommonObject
     function getMailOnSubscription()
     {
         global $conf;
-
+	// mail_subscription not  defined so never used
         if (! empty($this->mail_subscription) && trim(dol_htmlentitiesbr_decode($this->mail_subscription)))  // Property not yet defined
         {
             return $this->mail_subscription;
@@ -327,7 +331,7 @@ class AdherentType extends CommonObject
     function getMailOnResiliate()
     {
         global $conf;
-
+	// NOTE mail_resiliate not defined so never used
         if (! empty($this->mail_resiliate) && trim(dol_htmlentitiesbr_decode($this->mail_resiliate)))  // Property not yet defined
         {
             return $this->mail_resiliate;

+ 4 - 2
htdocs/adherents/cotisations.php

@@ -128,7 +128,9 @@ if ($result)
     if (! empty($date_select)) $title.=' ('.$langs->trans("Year").' '.$date_select.')';
 
     $param='';
-    $param.="&statut=$statut&date_select=$date_select";
+    if ($statut != '')    $param.="&statut=".$statut;
+    if ($date_select)     $param.="&date_select=".$date_select;
+    if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
     if ($search_lastname) $param.="&search_lastname=".$search_lastname;
 	if ($search_login)    $param.="&search_login=".$search_login;
 	if ($search_acount)   $param.="&search_account=".$search_account;
@@ -214,7 +216,7 @@ if ($result)
 
     $var=true;
     $total=0;
-    while ($i < $num && $i < $conf->liste_limit)
+    while ($i < min($num, $limit))
     {
         $objp = $db->fetch_object($result);
         $total+=$objp->cotisation;

+ 1 - 1
htdocs/adherents/document.php

@@ -76,7 +76,7 @@ $upload_dir = $conf->adherent->dir_output . "/" . get_exdir($object->id,2,0,1,$o
  * Actions
  */
 
-include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php';
+include_once DOL_DOCUMENT_ROOT . '/core/actions_linkedfiles.inc.php';
 
 
 /*

+ 1 - 1
htdocs/adherents/index.php

@@ -141,7 +141,7 @@ if (count($listofsearchfields))
 	{
 		if ($i == 0) print '<tr class="liste_titre"><td colspan="3">'.$langs->trans("Search").'</td></tr>';
 		print '<tr '.$bc[false].'>';
-		print '<td class="nowrap"><label for="'.$key.'">'.$langs->trans($value["text"]).'</label>:</td><td><input type="text" class="flat" name="'.$key.'" id="'.$key.'" size="18"></td>';
+		print '<td class="nowrap"><label for="'.$key.'">'.$langs->trans($value["text"]).'</label>:</td><td><input type="text" class="flat inputsearch" name="'.$key.'" id="'.$key.'" size="18"></td>';
 		if ($i == 0) print '<td rowspan="'.count($listofsearchfields).'"><input type="submit" value="'.$langs->trans("Search").'" class="button"></td>';
 		print '</tr>';
 		$i++;

+ 8 - 4
htdocs/adherents/type.php

@@ -153,6 +153,7 @@ if ($action == 'delete' && $user->rights->adherent->configurer)
 	exit;
 }
 
+
 /*
  * View
  */
@@ -200,7 +201,10 @@ if (! $rowid && $action != 'create' && $action != 'edit')
 			print '<td>'.dol_escape_htmltag($objp->libelle).'</td>';
 			print '<td align="center">'.yn($objp->cotisation).'</td>';
 			print '<td align="center">'.yn($objp->vote).'</td>';
-			print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=edit&rowid='.$objp->rowid.'">'.img_edit().'</a></td>';
+			if ($user->rights->adherent->configurer)
+				print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=edit&rowid='.$objp->rowid.'">'.img_edit().'</a></td>';
+			else
+				print '<td align="right">&nbsp;</td>';
 			print "</tr>";
 			$i++;
 		}
@@ -233,7 +237,7 @@ if ($action == 'create')
 	print '<table class="border" width="100%">';
 	print '<tbody>';
 
-	print '<tr><td width="25%" class="fieldrequired">'.$langs->trans("Label").'</td><td><input type="text" name="libelle" size="40"></td></tr>';
+	print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Label").'</td><td><input type="text" name="libelle" size="40"></td></tr>';
 
 	print '<tr><td>'.$langs->trans("SubscriptionRequired").'</td><td>';
 	print $form->selectyesno("cotisation",1,1);
@@ -244,7 +248,7 @@ if ($action == 'create')
 	print '</td></tr>';
 
 	print '<tr><td valign="top">'.$langs->trans("Description").'</td><td>';
-	print '<textarea name="comment" wrap="soft" cols="60" rows="3"></textarea></td></tr>';
+	print '<textarea name="comment" wrap="soft" class="centpercent" rows="3"></textarea></td></tr>';
 
 	print '<tr><td valign="top">'.$langs->trans("WelcomeEMail").'</td><td>';
 	require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
@@ -642,7 +646,7 @@ if ($rowid > 0)
 		print '</td></tr>';
 
 		print '<tr><td valign="top">'.$langs->trans("Description").'</td><td>';
-		print '<textarea name="comment" wrap="soft" cols="90" rows="3">'.$object->note.'</textarea></td></tr>';
+		print '<textarea name="comment" wrap="soft" class="centpercent" rows="3">'.$object->note.'</textarea></td></tr>';
 
 		print '<tr><td valign="top">'.$langs->trans("WelcomeEMail").'</td><td>';
 		require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';

+ 3 - 68
htdocs/admin/bank.php

@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2009       Laurent Destailleur        <eldy@users.sourceforge.net>
- * Copyright (C) 2010-2013  Juanjo Menent	       <jmenent@2byte.es>
+ * Copyright (C) 2010-2016  Juanjo Menent	       <jmenent@2byte.es>
  * Copyright (C) 2013-2014  Philippe Grand             <philippe.grand@atoo-net.com>
  * Copyright (C) 2015       Jean-François Ferry         <jfefe@aternatik.fr>
  *
@@ -46,24 +46,6 @@ $action = GETPOST('action','alpha');
  * Actions
  */
 
-if ($action == 'set_BANK_CHEQUERECEIPT_FREE_TEXT')
-{
-	$freetext = GETPOST('BANK_CHEQUERECEIPT_FREE_TEXT');	// No alpha here, we want exact string
-
-    $res = dolibarr_set_const($db, "BANK_CHEQUERECEIPT_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity);
-
-	if (! $res > 0) $error++;
-
- 	if (! $error)
-    {
-        setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
-    }
-    else
-    {
-        setEventMessages($langs->trans("Error"), null, 'errors');
-    }
-}
-
 //Order display of bank account
 if ($action == 'setbankorder')
 {
@@ -89,58 +71,13 @@ $form=new Form($db);
 $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
 print load_fiche_titre($langs->trans("BankSetupModule"),$linkback,'title_setup');
 
-
-print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
-print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-print '<input type="hidden" name="action" value="set_BANK_CHEQUERECEIPT_FREE_TEXT">';
-
 $head = bank_admin_prepare_head(null);
 dol_fiche_head($head, 'general', $langs->trans("BankSetupModule"), 0, 'account');
 
-print '<table class="noborder" width="100%">';
-print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("Parameters").'</td>';
-print '<td align="center" width="60">&nbsp;</td>';
-print '<td width="80">&nbsp;</td>';
-print "</tr>\n";
 $var=true;
 
 $var=! $var;
 
-print '<tr '.$bc[$var].'><td colspan="2">';
-print $langs->trans("FreeLegalTextOnChequeReceipts").' ('.$langs->trans("AddCRIfTooLong").')<br>';
-$variablename='BANK_CHEQUERECEIPT_FREE_TEXT';
-if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT))
-{
-    print '<textarea name="'.$variablename.'" class="flat" cols="120">'.$conf->global->$variablename.'</textarea>';
-}
-else
-{
-    include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-    $doleditor=new DolEditor($variablename, $conf->global->$variablename,'',80,'dolibarr_details');
-    print $doleditor->Create();
-}
-print '</td><td align="right">';
-print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
-print "</td></tr>\n";
-print '</table>';
-print "<br>";
-
-/*
-$var=!$var;
-print "<form method=\"post\" action=\"".$_SERVER["PHP_SELF"]."\">";
-print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-print "<input type=\"hidden\" name=\"action\" value=\"set_BANK_CHEQUERECEIPT_DRAFT_WATERMARK\">";
-print '<tr '.$bc[$var].'><td colspan="2">';
-print $langs->trans("WatermarkOnDraftChequeReceipt").'<br>';
-print '<input size="50" class="flat" type="text" name="BANK_CHEQUERECEIPT_DRAFT_WATERMARK" value="'.$conf->global->BANK_CHEQUERECEIPT_DRAFT_WATERMARK.'">';
-print '</td><td align="right">';
-print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
-print "</td></tr>\n";
-print '</form>';
-*/
-
-
 //Show bank account order
 print load_fiche_titre($langs->trans("BankOrderShow"));
 
@@ -155,10 +92,10 @@ print "</tr>\n";
 
 $bankorder[0][0]=$langs->trans("BankOrderGlobal");
 $bankorder[0][1]=$langs->trans("BankOrderGlobalDesc");
-$bankorder[0][2]='BankCode DeskCode AccountNumber BankAccountNumberKey';
+$bankorder[0][2]='BankCode DeskCode BankAccountNumber BankAccountNumberKey';
 $bankorder[1][0]=$langs->trans("BankOrderES");
 $bankorder[1][1]=$langs->trans("BankOrderESDesc");
-$bankorder[1][2]='BankCode DeskCode BankAccountNumberKey AccountNumber';
+$bankorder[1][2]='BankCode DeskCode BankAccountNumberKey BankAccountNumber';
 
 $var = true;
 $i=0;
@@ -202,8 +139,6 @@ print '</table>'."\n";
 
 dol_fiche_end();
 
-print '</form>';
-
 llxFooter();
 
 $db->close();

+ 287 - 0
htdocs/admin/chequereceipts.php

@@ -0,0 +1,287 @@
+<?php
+/* Copyright (C) 2009       Laurent Destailleur        <eldy@users.sourceforge.net>
+ * Copyright (C) 2010-2016  Juanjo Menent	       <jmenent@2byte.es>
+ * Copyright (C) 2013-2014  Philippe Grand             <philippe.grand@atoo-net.com>
+ * Copyright (C) 2015       Jean-François Ferry         <jfefe@aternatik.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/**
+ *      \file       htdocs/admin/bank.php
+ *		\ingroup    bank
+ *		\brief      Page to setup the bank module
+ */
+
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php';
+
+$langs->load("admin");
+$langs->load("companies");
+$langs->load("bills");
+$langs->load("other");
+$langs->load("banks");
+
+if (!$user->admin)
+  accessforbidden();
+
+$action = GETPOST('action','alpha');
+$value = GETPOST('value','alpha');
+
+
+if (empty($conf->global->CHEQUERECEIPTS_ADDON)) $conf->global->CHEQUERECEIPTS_ADDON = 'mod_chequereceipts_mint.php';
+
+
+
+/*
+ * Actions
+ */
+
+if ($action == 'updateMask')
+{
+	$maskconstchequereceipts=GETPOST('maskconstchequereceipts','alpha');
+	$maskchequereceipts=GETPOST('maskchequereceipts','alpha');
+	if ($maskconstchequereceipts) $res = dolibarr_set_const($db,$maskconstchequereceipts,$maskchequereceipts,'chaine',0,'',$conf->entity);
+
+	if (! $res > 0) $error++;
+
+	if (! $error)
+	{
+		setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
+	}
+	else
+	{
+		setEventMessages($langs->trans("Error"), null, 'errors');
+	}
+}
+
+if ($action == 'setmod')
+{
+	dolibarr_set_const($db, "CHEQUERECEIPTS_ADDON",$value,'chaine',0,'',$conf->entity);
+}
+
+if ($action == 'set_BANK_CHEQUERECEIPT_FREE_TEXT')
+{
+	$freetext = GETPOST('BANK_CHEQUERECEIPT_FREE_TEXT');	// No alpha here, we want exact string
+
+    $res = dolibarr_set_const($db, "BANK_CHEQUERECEIPT_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity);
+
+	if (! $res > 0) $error++;
+
+ 	if (! $error)
+    {
+        setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
+    }
+    else
+    {
+        setEventMessages($langs->trans("Error"), null, 'errors');
+    }
+}
+
+/*
+ * view
+ */
+
+$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
+llxHeader("",$langs->trans("BankSetupModule"));
+
+$form=new Form($db);
+
+$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
+print load_fiche_titre($langs->trans("BankSetupModule"),$linkback,'title_setup');
+
+$head = bank_admin_prepare_head(null);
+dol_fiche_head($head, 'checkreceipts', $langs->trans("BankSetupModule"), 0, 'account');
+
+/*
+ *  Numbering module
+ */
+
+print load_fiche_titre($langs->trans("ChequeReceiptsNumberingModule"), '', '');
+
+print '<table class="noborder" width="100%">';
+print '<tr class="liste_titre">';
+print '<td>'.$langs->trans("Name").'</td>';
+print '<td>'.$langs->trans("Description").'</td>';
+print '<td class="nowrap">'.$langs->trans("Example").'</td>';
+print '<td align="center" width="60">'.$langs->trans("Status").'</td>';
+print '<td align="center" width="16">'.$langs->trans("ShortInfo").'</td>';
+print '</tr>'."\n";
+
+clearstatcache();
+
+foreach ($dirmodels as $reldir)
+{
+	$dir = dol_buildpath($reldir."core/modules/cheque/");
+	if (is_dir($dir))
+	{
+		$handle = opendir($dir);
+		if (is_resource($handle))
+		{
+			$var=true;
+
+			while (($file = readdir($handle))!==false)
+			{
+				if (! is_dir($dir.$file) || (substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS'))
+				{
+					$filebis = $file;
+					$name = substr($file, 4, dol_strlen($file) -16);
+					$classname = preg_replace('/\.php$/','',$file);
+					// For compatibility
+					if (! is_file($dir.$filebis))
+					{
+						$filebis = $file."/".$file.".modules.php";
+						$classname = "mod_chequereceipt_".$file;
+					}
+					// Check if there is a filter on country
+					preg_match('/\-(.*)_(.*)$/',$classname,$reg);
+					if (! empty($reg[2]) && $reg[2] != strtoupper($mysoc->country_code)) continue;
+
+					$classname = preg_replace('/\-.*$/','',$classname);
+					if (! class_exists($classname) && is_readable($dir.$filebis) && (preg_match('/mod_/',$filebis) || preg_match('/mod_/',$classname)) && substr($filebis, dol_strlen($filebis)-3, 3) == 'php')
+					{
+						// Charging the numbering class
+						require_once $dir.$filebis;
+
+						$module = new $classname($db);
+
+						// Show modules according to features level
+						if ($module->version == 'development'  && $conf->global->MAIN_FEATURES_LEVEL < 2) continue;
+						if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue;
+
+						if ($module->isEnabled())
+						{
+							$var = !$var;
+							print '<tr '.$bc[$var].'><td width="100">';
+							print (empty($module->name)?$name:$module->name);
+							print "</td><td>\n";
+
+							print $module->info();
+
+							print '</td>';
+
+							// Show example of numbering module
+							print '<td class="nowrap">';
+							$tmp=$module->getExample();
+							if (preg_match('/^Error/',$tmp)) print '<div class="error">'.$langs->trans($tmp).'</div>';
+							elseif ($tmp=='NotConfigured') print $langs->trans($tmp);
+							else print $tmp;
+							print '</td>'."\n";
+
+							print '<td align="center">';
+							if ($conf->global->CHEQUERECEIPTS_ADDON == $file || $conf->global->CHEQUERECEIPTS_ADDON.'.php' == $file)
+							{
+								print img_picto($langs->trans("Activated"),'switch_on');
+							}
+							else
+							{
+								print '<a href="'.$_SERVER["PHP_SELF"].'?action=setmod&value='.preg_replace('/\.php$/','',$file).'&scandir='.$module->scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>';
+							}
+							print '</td>';
+
+							$chequereceipts=new RemiseCheque($db);
+							$chequereceipts->initAsSpecimen();
+
+							// Example
+							$htmltooltip='';
+							$htmltooltip.=''.$langs->trans("Version").': <b>'.$module->getVersion().'</b><br>';
+							$nextval=$module->getNextValue($mysoc,$chequereceipts);
+							if ("$nextval" != $langs->trans("NotAvailable")) {  // Keep " on nextval
+								$htmltooltip.=$langs->trans("NextValue").': ';
+								if ($nextval) {
+									if (preg_match('/^Error/',$nextval) || $nextval=='NotConfigured')
+										$nextval = $langs->trans($nextval);
+									$htmltooltip.=$nextval.'<br>';
+								} else {
+									$htmltooltip.=$langs->trans($module->error).'<br>';
+								}
+							}
+
+							print '<td align="center">';
+							print $form->textwithpicto('',$htmltooltip,1,0);
+
+							if ($conf->global->CHEQUERECEIPTS_ADDON.'.php' == $file)  // If module is the one used, we show existing errors
+							{
+								if (! empty($module->error)) dol_htmloutput_mesg($module->error,'','error',1);
+							}
+
+							print '</td>';
+
+							print "</tr>\n";
+
+						}
+					}
+				}
+			}
+			closedir($handle);
+		}
+	}
+}
+
+print '</table>';
+
+print '<br>';
+
+
+/*
+ * Other options
+ *
+ */
+print load_fiche_titre($langs->trans("OtherOptions"),'','');
+
+print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
+print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+print '<input type="hidden" name="action" value="set_BANK_CHEQUERECEIPT_FREE_TEXT">';
+
+print '<table class="noborder" width="100%">';
+print '<tr class="liste_titre">';
+print '<td>'.$langs->trans("Parameters").'</td>';
+print '<td align="center" width="60">&nbsp;</td>';
+print '<td width="80">&nbsp;</td>';
+print "</tr>\n";
+$var=true;
+
+$var=! $var;
+
+print '<tr '.$bc[$var].'><td colspan="2">';
+print $langs->trans("FreeLegalTextOnChequeReceipts").' ('.$langs->trans("AddCRIfTooLong").')<br>';
+$variablename='BANK_CHEQUERECEIPT_FREE_TEXT';
+if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT))
+{
+    print '<textarea name="'.$variablename.'" class="flat" cols="120">'.$conf->global->$variablename.'</textarea>';
+}
+else
+{
+    include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
+    $doleditor=new DolEditor($variablename, $conf->global->$variablename,'',80,'dolibarr_details');
+    print $doleditor->Create();
+}
+print '</td><td align="right">';
+print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
+print "</td></tr>\n";
+print '</table>';
+print "<br>";
+
+print '</table>'."\n";
+
+dol_fiche_end();
+
+print '</form>';
+
+llxFooter();
+
+$db->close();

+ 15 - 9
htdocs/admin/company.php

@@ -98,12 +98,14 @@ if ( ($action == 'update' && empty($_POST["cancel"]))
 					// Create thumbs of logo (Note that PDF use original file and not thumbs)
 					if ($isimage > 0)
 					{
-						// Create small thumbs for company (Ratio is near 16/9)
+					    // Create thumbs
+					    //$object->addThumbs($newfile);    // We can't use addThumbs here yet because we need name of generated thumbs to add them into constants. TODO Check if need such constants. We should be able to retreive value with get... 
+					    	
 						// Used on logon for example
 						$imgThumbSmall = vignette($conf->mycompany->dir_output.'/logos/'.$original_file, $maxwidthsmall, $maxheightsmall, '_small', $quality);
-						if (preg_match('/([^\\/:]+)$/i',$imgThumbSmall,$reg))
+						if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbSmall,$reg))
 						{
-							$imgThumbSmall = $reg[1];
+							$imgThumbSmall = $reg[1];    // Save only basename
 							dolibarr_set_const($db, "MAIN_INFO_SOCIETE_LOGO_SMALL",$imgThumbSmall,'chaine',0,'',$conf->entity);
 						}
 						else dol_syslog($imgThumbSmall);
@@ -111,9 +113,9 @@ if ( ($action == 'update' && empty($_POST["cancel"]))
 						// Create mini thumbs for company (Ratio is near 16/9)
 						// Used on menu or for setup page for example
 						$imgThumbMini = vignette($conf->mycompany->dir_output.'/logos/'.$original_file, $maxwidthmini, $maxheightmini, '_mini', $quality);
-						if (preg_match('/([^\\/:]+)$/i',$imgThumbMini,$reg))
+						if (image_format_supported($imgThumbMini) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbMini,$reg))
 						{
-							$imgThumbMini = $reg[1];
+							$imgThumbMini = $reg[1];     // Save only basename
 							dolibarr_set_const($db, "MAIN_INFO_SOCIETE_LOGO_MINI",$imgThumbMini,'chaine',0,'',$conf->entity);
 						}
 						else dol_syslog($imgThumbMini);
@@ -203,12 +205,14 @@ if ($action == 'addthumb')
 		// Create thumbs of logo
 		if ($isimage > 0)
 		{
-			// Create small thumbs for company (Ratio is near 16/9)
+		    // Create thumbs
+		    //$object->addThumbs($newfile);    // We can't use addThumbs here yet because we need name of generated thumbs to add them into constants. TODO Check if need such constants. We should be able to retreive value with get... 
+
 			// Used on logon for example
 			$imgThumbSmall = vignette($conf->mycompany->dir_output.'/logos/'.$_GET["file"], $maxwidthsmall, $maxheightsmall, '_small',$quality);
 			if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbSmall,$reg))
 			{
-				$imgThumbSmall = $reg[1];
+				$imgThumbSmall = $reg[1];   // Save only basename
 				dolibarr_set_const($db, "MAIN_INFO_SOCIETE_LOGO_SMALL",$imgThumbSmall,'chaine',0,'',$conf->entity);
 			}
 			else dol_syslog($imgThumbSmall);
@@ -218,7 +222,7 @@ if ($action == 'addthumb')
 			$imgThumbMini = vignette($conf->mycompany->dir_output.'/logos/'.$_GET["file"], $maxwidthmini, $maxheightmini, '_mini',$quality);
 			if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i',$imgThumbMini,$reg))
 			{
-				$imgThumbMini = $reg[1];
+				$imgThumbMini = $reg[1];   // Save only basename
 				dolibarr_set_const($db, "MAIN_INFO_SOCIETE_LOGO_MINI",$imgThumbMini,'chaine',0,'',$conf->entity);
 			}
 			else dol_syslog($imgThumbMini);
@@ -727,7 +731,9 @@ else
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("CompanyCurrency").'</td><td>';
 	print currency_name($conf->currency,1);
-	print ' ('.$langs->getCurrencySymbol($conf->currency).')';
+	print ' ('.$conf->currency;
+	print ($conf->currency != $langs->getCurrencySymbol($conf->currency) ? ' - '.$langs->getCurrencySymbol($conf->currency) : '');
+	print ')';
 	print '</td></tr>';
 
 	$var=!$var;

+ 4 - 3
htdocs/admin/confexped.php

@@ -131,7 +131,10 @@ print '</tr>';
 // Bon de livraison activation/desactivation
 $var=!$var;
 print '<tr '.$bc[$var].'>';
-print '<td>'.$langs->trans("DeliveriesOrderAbility").'</td>';
+print '<td>';
+print $langs->trans("DeliveriesOrderAbility");
+print '<br>'.info_admin($langs->trans("NoNeedForDeliveryReceipts"), 0, 1);
+print '</td>';
 print '<td align="center" width="20">';
 print '</td>';
 print '<td align="center" width="100">';
@@ -151,7 +154,5 @@ print '</table>';
 
 print '</div>';
 
-print info_admin($langs->trans("NoNeedForDeliveryReceipts"));
-
 llxFooter();
 $db->close();

+ 81 - 22
htdocs/admin/dict.php

@@ -8,7 +8,7 @@
  * Copyright (C) 2011       Remy Younes             <ryounes@gmail.com>
  * Copyright (C) 2012-2015  Marcos García           <marcosgdf@gmail.com>
  * Copyright (C) 2012       Christophe Battarel     <christophe.battarel@ltairis.fr>
- * Copyright (C) 2011-2015  Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2011-2016  Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2015       Ferran Marcet           <fmarcet@2byte.es>
  * Copyright (C) 2016       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
  *
@@ -46,6 +46,8 @@ $langs->load("admin");
 $langs->load("companies");
 $langs->load("resource");
 $langs->load("holiday");
+$langs->load("accountancy");
+$langs->load("hrm");
 
 $action=GETPOST('action','alpha')?GETPOST('action','alpha'):'view';
 $confirm=GETPOST('confirm','alpha');
@@ -78,7 +80,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,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);
+$taborder=array(9,0,4,3,2,0,1,8,19,16,27,0,5,11,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,31,32,0);
 
 // Name of SQL tables of dictionaries
 $tabname=array();
@@ -112,6 +114,10 @@ $tabname[27]= MAIN_DB_PREFIX."c_stcomm";
 $tabname[28]= MAIN_DB_PREFIX."c_holiday_types";
 $tabname[29]= MAIN_DB_PREFIX."c_lead_status";
 $tabname[30]= MAIN_DB_PREFIX."c_format_cards";
+$tabname[31]= MAIN_DB_PREFIX."accounting_system";
+$tabname[32]= MAIN_DB_PREFIX."c_accounting_category";
+$tabname[33]= MAIN_DB_PREFIX."c_hrm_department";
+$tabname[34]= MAIN_DB_PREFIX."c_hrm_function";
 
 // Dictionary labels
 $tablib=array();
@@ -145,6 +151,10 @@ $tablib[27]= "DictionaryProspectStatus";
 $tablib[28]= "DictionaryHolidayTypes";
 $tablib[29]= "DictionaryOpportunityStatus";
 $tablib[30]= "DictionaryFormatCards";
+$tablib[31]= "DictionaryAccountancysystem";
+$tablib[32]= "DictionaryAccountancyCategory";
+$tablib[33]= "DictionaryDepartment";
+$tablib[34]= "DictionaryFunction";
 
 // Requests to extract data
 $tabsql=array();
@@ -172,12 +182,16 @@ $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, active FROM ".MAIN_DB_PREFIX."c_email_templates";
+$tabsql[25]= "SELECT rowid   as rowid, label, type_template, private, position, topic, 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";
+$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";
 $tabsql[29]= "SELECT rowid   as rowid, code, label, percent, position, active FROM ".MAIN_DB_PREFIX."c_lead_status";
 $tabsql[30]= "SELECT rowid, code, name, paper_size, orientation, metric, leftmargin, topmargin, nx, ny, spacex, spacey, width, height, font_size, custom_x, custom_y, active FROM ".MAIN_DB_PREFIX."c_format_cards";
+$tabsql[31]= "SELECT s.rowid as rowid, pcg_version, s.fk_pays as country_id, c.code as country_code, c.label as country, s.label, s.active FROM ".MAIN_DB_PREFIX."accounting_system as s, ".MAIN_DB_PREFIX."c_country as c WHERE s.fk_pays=c.rowid and c.active=1";
+$tabsql[32]= "SELECT a.rowid as rowid, a.code as code, a.label, a.range_account, a.sens, a.category_type, a.formula, a.position as position, a.fk_country as country_id, c.code as country_code, c.label as country, a.active FROM ".MAIN_DB_PREFIX."c_accounting_category as a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_country=c.rowid and c.active=1";
+$tabsql[33]= "SELECT rowid, pos, code, label, active FROM ".MAIN_DB_PREFIX."c_hrm_department";
+$tabsql[34]= "SELECT rowid, pos, code, label, c_level, active FROM ".MAIN_DB_PREFIX."c_hrm_function";
 
 // Criteria to sort dictionaries
 $tabsqlsort=array();
@@ -211,6 +225,10 @@ $tabsqlsort[27]="code ASC";
 $tabsqlsort[28]="country ASC, code ASC";
 $tabsqlsort[29]="position ASC";
 $tabsqlsort[30]="code ASC";
+$tabsqlsort[31]="pcg_version ASC";
+$tabsqlsort[32]="position ASC";
+$tabsqlsort[33]="code ASC";
+$tabsqlsort[34]="code ASC";
 
 // Nom des champs en resultat de select pour affichage du dictionnaire
 $tabfield=array();
@@ -238,12 +256,16 @@ $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,position,topic,content";
+$tabfield[25]= "label,type_template,private,position,topic,content";
 $tabfield[26]= "code,label,short_label";
 $tabfield[27]= "code,libelle";
-$tabfield[28]= "code,label,affect,delay,newByMonth,country_id,country";
+$tabfield[28]= "code,label,affect,delay,newbymonth,country_id,country";
 $tabfield[29]= "code,label,percent,position";
 $tabfield[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y";
+$tabfield[31]= "pcg_version,country_id,country,label";
+$tabfield[32]= "code,label,range_account,sens,category_type,formula,position,country_id,country";
+$tabfield[33]= "code,label";
+$tabfield[34]= "code,label";
 
 // Nom des champs d'edition pour modification d'un enregistrement
 $tabfieldvalue=array();
@@ -271,12 +293,16 @@ $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,position,topic,content";
+$tabfieldvalue[25]= "label,type_template,private,position,topic,content";
 $tabfieldvalue[26]= "code,label,short_label";
 $tabfieldvalue[27]= "code,libelle";
-$tabfieldvalue[28]= "code,label,affect,delay,newByMonth,country";
+$tabfieldvalue[28]= "code,label,affect,delay,newbymonth,country";
 $tabfieldvalue[29]= "code,label,percent,position";
 $tabfieldvalue[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y";
+$tabfieldvalue[31]= "pcg_version,country,label";
+$tabfieldvalue[32]= "code,label,range_account,sens,category_type,formula,position,country";
+$tabfieldvalue[33]= "code,label";
+$tabfieldvalue[34]= "code,label";
 
 // Nom des champs dans la table pour insertion d'un enregistrement
 $tabfieldinsert=array();
@@ -304,12 +330,16 @@ $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,position,topic,content";
+$tabfieldinsert[25]= "label,type_template,private,position,topic,content,entity";
 $tabfieldinsert[26]= "code,label,short_label";
 $tabfieldinsert[27]= "code,libelle";
-$tabfieldinsert[28]= "code,label,affect,delay,newByMonth,fk_country";
+$tabfieldinsert[28]= "code,label,affect,delay,newbymonth,fk_country";
 $tabfieldinsert[29]= "code,label,percent,position";
 $tabfieldinsert[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y";
+$tabfieldinsert[31]= "pcg_version,fk_pays,label";
+$tabfieldinsert[32]= "code,label,range_account,sens,category_type,formula,position,fk_country";
+$tabfieldinsert[33]= "code,label";
+$tabfieldinsert[34]= "code,label";
 
 // Nom du rowid si le champ n'est pas de type autoincrement
 // Example: "" if id field is "rowid" and has autoincrement on
@@ -345,6 +375,10 @@ $tabrowid[27]= "id";
 $tabrowid[28]= "";
 $tabrowid[29]= "";
 $tabrowid[30]= "";
+$tabrowid[31]= "";
+$tabrowid[32]= "";
+$tabrowid[33]= "rowid";
+$tabrowid[34]= "rowid";
 
 // Condition to show dictionary in setup page
 $tabcond=array();
@@ -378,6 +412,10 @@ $tabcond[27]= ! empty($conf->societe->enabled);
 $tabcond[28]= ! empty($conf->holiday->enabled);
 $tabcond[29]= ! empty($conf->projet->enabled);
 $tabcond[30]= ! empty($conf->label->enabled);
+$tabcond[31]= ! empty($conf->accounting->enabled);
+$tabcond[32]= ! empty($conf->accounting->enabled);
+$tabcond[33]= ! empty($conf->hrm->enabled);
+$tabcond[34]= ! empty($conf->hrm->enabled);
 
 // List of help for fields
 $tabhelp=array();
@@ -408,9 +446,13 @@ $tabhelp[24] = array('code'=>$langs->trans("EnterAnyCode"));
 $tabhelp[25] = array('topic'=>$langs->trans('SeeSubstitutionVars'),'content'=>$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"));
+$tabhelp[28] = array('affect'=>$langs->trans("FollowedByACounter"),'delay'=>$langs->trans("MinimumNoticePeriod"), 'newbymonth'=>$langs->trans("NbAddedAutomatically"));
 $tabhelp[29] = array('code'=>$langs->trans("EnterAnyCode"), 'percent'=>$langs->trans("OpportunityPercent"), 'position'=>$langs->trans("PositionIntoComboList"));
 $tabhelp[30] = array('code'=>$langs->trans("EnterAnyCode"), 'name'=>$langs->trans("LabelName"), 'paper_size'=>$langs->trans("LabelPaperSize"));
+$tabhelp[31] = array('pcg_version'=>$langs->trans("EnterAnyCode"));
+$tabhelp[32] = array('code'=>$langs->trans("EnterAnyCode"));
+$tabhelp[33] = array('code'=>$langs->trans("EnterAnyCode"));
+$tabhelp[34] = array('code'=>$langs->trans("EnterAnyCode"));
 
 // List of check for fields (NOT USED YET)
 $tabfieldcheck=array();
@@ -444,6 +486,10 @@ $tabfieldcheck[27] = array();
 $tabfieldcheck[28] = array();
 $tabfieldcheck[29] = array();
 $tabfieldcheck[30] = array();
+$tabfieldcheck[31] = array();
+$tabfieldcheck[32] = array();
+$tabfieldcheck[33] = array();
+$tabfieldcheck[34] = array();
 
 // Complete all arrays with entries found into modules
 complete_dictionary_with_modules($taborder,$tabname,$tablib,$tabsql,$tabsqlsort,$tabfield,$tabfieldvalue,$tabfieldinsert,$tabrowid,$tabcond,$tabhelp,$tabfieldcheck);
@@ -478,6 +524,7 @@ if ($id == 11)
 			'propal'            => $langs->trans('Proposal'),
 			'commande'          => $langs->trans('Order'),
 			'facture'           => $langs->trans('Bill'),
+			'resource'           => $langs->trans('Resource'),
 //			'facture_fourn'     => $langs->trans('SupplierBill'),
 			'fichinter'         => $langs->trans('InterventionCard')
 	);
@@ -534,11 +581,12 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     $ok=1;
     foreach ($listfield as $f => $value)
     {
-        if ($value == 'country_id' && in_array($tablib[$id],array('DictionaryVAT','DictionaryRegion','DictionaryCompanyType','DictionaryHolidayTypes','DictionaryRevenueStamp'))) continue;		// For some pages, country is not mandatory
+        if ($value == 'country_id' && in_array($tablib[$id],array('DictionaryVAT','DictionaryRegion','DictionaryCompanyType','DictionaryHolidayTypes','DictionaryRevenueStamp','DictionaryAccountancysystem','DictionaryAccountancyCategory'))) continue;		// For some pages, country is not mandatory
     	if ($value == 'country' && in_array($tablib[$id],array('DictionaryCanton','DictionaryCompanyType','DictionaryRevenueStamp'))) continue;		// For some pages, country is not mandatory
         if ($value == 'localtax1' && empty($_POST['localtax1_type'])) continue;
         if ($value == 'localtax2' && empty($_POST['localtax2_type'])) continue;
         if ($value == 'color' && empty($_POST['color'])) continue;
+		if ($value == 'formula' && empty($_POST['formula'])) continue;
         if ((! isset($_POST[$value]) || $_POST[$value]=='')
         	&& (! in_array($listfield[$f], array('decalage','module','accountancy_code','accountancy_code_sell','accountancy_code_buy')))  // Fields that are not mandatory
 		)
@@ -559,6 +607,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
             if ($fieldnamekey == 'unicode') $fieldnamekey = 'Unicode';
             if ($fieldnamekey == 'deductible') $fieldnamekey = 'Deductible';
             if ($fieldnamekey == 'sortorder') $fieldnamekey = 'SortOrder';
+			if ($fieldnamekey == 'category_type') $fieldnamekey = 'Calculated';
 
             setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors');
         }
@@ -598,7 +647,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
        	$ok=0;
        	setEventMessages($langs->transnoentities("ErrorFieldMustBeANumeric",$langs->transnoentities("Code")), null, 'errors');
     }
-    
+
 	// Clean some parameters
     if (isset($_POST["localtax1"]) && empty($_POST["localtax1"])) $_POST["localtax1"]='0';	// If empty, we force to 0
     if (isset($_POST["localtax2"]) && empty($_POST["localtax2"])) $_POST["localtax2"]='0';	// If empty, we force to 0
@@ -952,6 +1001,10 @@ if ($id)
             if ($fieldlist[$field]=='sortorder')       { $valuetoshow=$langs->trans("SortOrder"); }
 	        if ($fieldlist[$field]=='short_label')     { $valuetoshow=$langs->trans("ShortLabel"); }
             if ($fieldlist[$field]=='type_template')   { $valuetoshow=$langs->trans("TypeOfTemplate"); }
+			if ($fieldlist[$field]=='range_account')   { $valuetoshow=$langs->trans("Range"); }
+			if ($fieldlist[$field]=='sens')            { $valuetoshow=$langs->trans("Sens"); }
+			if ($fieldlist[$field]=='category_type')   { $valuetoshow=$langs->trans("Calculated"); }
+			if ($fieldlist[$field]=='formula')         { $valuetoshow=$langs->trans("Formula"); }
 
             if ($id == 2)	// Special cas for state page
             {
@@ -1119,6 +1172,10 @@ if ($id)
                 if ($fieldlist[$field]=='sortorder')       { $valuetoshow=$langs->trans("SortOrder"); }
 	            if ($fieldlist[$field]=='short_label')     { $valuetoshow=$langs->trans("ShortLabel"); }
             	if ($fieldlist[$field]=='type_template')   { $valuetoshow=$langs->trans("TypeOfTemplate"); }
+				if ($fieldlist[$field]=='range_account')   { $valuetoshow=$langs->trans("Range"); }
+				if ($fieldlist[$field]=='sens')            { $valuetoshow=$langs->trans("Sens"); }
+				if ($fieldlist[$field]=='category_type')   { $valuetoshow=$langs->trans("Calculated"); }
+				if ($fieldlist[$field]=='formula')         { $valuetoshow=$langs->trans("Formula"); }
 
                 // Affiche nom du champ
                 if ($showfield)
@@ -1200,7 +1257,7 @@ if ($id)
                                     $valuetoshow=($key != "Country".strtoupper($obj->country_code)?$obj->country_code." - ".$key:$obj->country);
                                 }
                             }
-                            else if ($fieldlist[$field]=='recuperableonly' || $fieldlist[$field]=='fdm' || $fieldlist[$field] == 'deductible') {
+                            else if ($fieldlist[$field]=='recuperableonly' || $fieldlist[$field]=='fdm' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') {
                                 $valuetoshow=yn($valuetoshow);
                                 $align="center";
                             }
@@ -1341,8 +1398,10 @@ if ($id)
                                 $valuetoshow = length_accountg($valuetoshow);
                             }
 
+                            $class='tddict';
+                            if ($fieldlist[$field] == 'tracking') $class.=' tdoverflowauto';
 							// Show value for field
-							if ($showfield) print '<td align="'.$align.'">'.$valuetoshow.'</td>';
+							if ($showfield) print '<!-- '.$fieldlist[$field].' --><td align="'.$align.'" class="'.$class.'">'.$valuetoshow.'</td>';
                         }
                     }
 
@@ -1359,7 +1418,7 @@ if ($id)
                     if (in_array($obj->code, array('AC_OTH','AC_OTH_AUTO')) || in_array($obj->type, array('systemauto'))) { $canbedisabled=0; $canbedisabled = 0; }
                     $canbemodified=$iserasable;
                     if ($obj->code == 'RECEP') $canbemodified=1;
-                        
+
                     $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&amp;code='.(! empty($obj->code)?urlencode($obj->code):'').'&amp;id='.$id.'&amp;';
 
 					// Favorite
@@ -1568,7 +1627,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 			print 'user<input type="hidden" name="type" value="user">';
 			print '</td>';
 		}
-		elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'fdm' || $fieldlist[$field] == 'deductible') {
+		elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'fdm' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') {
 			print '<td>';
 			print $form->selectyesno($fieldlist[$field],(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''),1);
 			print '</td>';
@@ -1642,13 +1701,13 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 		else
 		{
 			print '<td>';
-			$size='';
+			$size=''; $class='';
 			if ($fieldlist[$field]=='code') $size='size="8" ';
 			if ($fieldlist[$field]=='position') $size='size="4" ';
-			if ($fieldlist[$field]=='libelle') $size='size="32" ';
-			if ($fieldlist[$field]=='tracking') $size='size="92" ';
-			if ($fieldlist[$field]=='sortorder') $size='size="2" ';
-			print '<input type="text" '.$size.' class="flat" value="'.(isset($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" name="'.$fieldlist[$field].'">';
+			if ($fieldlist[$field]=='libelle') $size='centpercent';
+			if ($fieldlist[$field]=='tracking') $class='centpercent';
+			if ($fieldlist[$field]=='sortorder' || $fieldlist[$field]=='sens' || $fieldlist[$field]=='category_type') $size='size="2" ';
+			print '<input type="text" '.$size.' class="flat'.($class?' '.$class:'').'" value="'.(isset($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" name="'.$fieldlist[$field].'">';
 			print '</td>';
 		}
 	}

+ 5 - 5
htdocs/admin/facture.php

@@ -262,11 +262,11 @@ if ($action == 'setforcedate')
     }
 }
 
-if ($action == 'set_FAC_AUTO_FILLJS')
+if ($action == 'set_INVOICE_AUTO_FILLJS')
 {
-	$freetext = GETPOST('FAC_AUTO_FILLJS');	// No alpha here, we want exact string
+	$freetext = GETPOST('INVOICE_AUTO_FILLJS');	// No alpha here, we want exact string
 
-	$res = dolibarr_set_const($db, "FAC_AUTO_FILLJS",$freetext,'chaine',0,'',$conf->entity);
+	$res = dolibarr_set_const($db, "INVOICE_AUTO_FILLJS",$freetext,'chaine',0,'',$conf->entity);
 
 	if (! $res > 0) $error++;
 
@@ -754,11 +754,11 @@ print '</form>';
 $var=! $var;
 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
 print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />';
-print '<input type="hidden" name="action" value="set_FAC_AUTO_FILLJS" />';
+print '<input type="hidden" name="action" value="set_INVOICE_AUTO_FILLJS" />';
 print '<tr '.$bc[$var].'><td>';
 print $langs->trans("JSOnPaimentBill");
 print '</td><td width="60" align="center">';
-print $form->selectyesno("FAC_AUTO_FILLJS",$conf->global->FAC_AUTO_FILLJS,1);
+print $form->selectyesno("INVOICE_AUTO_FILLJS",$conf->global->INVOICE_AUTO_FILLJS,1);
 print '</td><td align="right">';
 print '<input type="submit" class="button" value="'.$langs->trans("Modify").'" />';
 print "</td></tr>\n";

+ 13 - 1
htdocs/admin/fckeditor.php

@@ -189,7 +189,19 @@ else
     show_skin(null,1);
     print '<br>'."\n";
     
-	print load_fiche_titre($langs->trans("TestSubmitForm"),'(mode='.$mode.')','');
+    $listofmodes=array('dolibarr_mailings','dolibarr_notes','dolibarr_details','Full');
+    $linkstomode='';
+    foreach($listofmodes as $newmode)
+    {
+        if ($linkstomode) $linkstomode.=' - ';
+        $linkstomode.='<a href="'.$_SERVER["PHP_SELF"].'?mode='.$newmode.'">';
+        if ($mode == $newmode) $linkstomode.='<strong>';
+        $linkstomode.=$newmode;
+        if ($mode == $newmode) $linkstomode.='</strong>';
+        $linkstomode.='</a>';
+    }
+    $linkstomode.='';
+	print load_fiche_titre($langs->trans("TestSubmitForm"),$linkstomode,'');
     print '<input type="hidden" name="mode" value="'.dol_escape_htmltag($mode).'">';
     $uselocalbrowser=true;
     $readonly=($mode=='dolibarr_readonly'?1:0);

+ 11 - 2
htdocs/admin/loan.php

@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) 2014		Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
+/* Copyright (C) 2014-2016	Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@ require '../main.inc.php';
 	
 // Class
 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/html.formventilation.class.php';
 
 $langs->load("admin");
 $langs->load("loan");
@@ -76,6 +77,7 @@ if ($action == 'update')
 llxHeader();
 
 $form = new Form($db);
+if (! empty($conf->accounting->enabled)) $formaccountancy = New FormVentilation($db);
 
 $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
 print load_fiche_titre($langs->trans('ConfigLoan'),$linkback,'title_setup');
@@ -104,7 +106,14 @@ foreach ($list as $key)
 
 	// Value
 	print '<td>';
-	print '<input type="text" size="20" id="'.$key.'" name="'.$key.'" value="'.$conf->global->$key.'">';
+	if (! empty($conf->accounting->enabled))
+	{
+		print $formaccountancy->select_account($conf->global->$key, $key, 1, '', 1, 1);
+	}
+	else
+	{
+		print '<input type="text" size="20" id="'.$key.'" name="'.$key.'" value="'.$conf->global->$key.'">';
+	}
 	print '</td></tr>';
 }
 

+ 64 - 10
htdocs/admin/mails.php

@@ -2,6 +2,7 @@
 /* Copyright (C) 2007-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2009-2012 Regis Houssin        <regis.houssin@capnetworks.com>
  * Copyright (C) 2013	   Juanjo Menent		<jmenent@2byte.es>
+ * Copyright (C) 2016      Jonathan TISSEAU     <jonathan.tisseau@86dev.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -71,6 +72,7 @@ if ($action == 'update' && empty($_POST["cancel"]))
 	dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID",       GETPOST("MAIN_MAIL_SMTPS_ID"), 'chaine',0,'',$conf->entity);
 	dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW",       GETPOST("MAIN_MAIL_SMTPS_PW"), 'chaine',0,'',$conf->entity);
 	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS",      GETPOST("MAIN_MAIL_EMAIL_TLS"),'chaine',0,'',$conf->entity);
+	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_STARTTLS", GETPOST("MAIN_MAIL_EMAIL_STARTTLS"),'chaine',0,'',$conf->entity);
     // Content parameters
 	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_FROM",     GETPOST("MAIN_MAIL_EMAIL_FROM"), 'chaine',0,'',$conf->entity);
 	dolibarr_set_const($db, "MAIN_MAIL_ERRORS_TO",		GETPOST("MAIN_MAIL_ERRORS_TO"),  'chaine',0,'',$conf->entity);
@@ -205,7 +207,7 @@ if (($action == 'send' || $action == 'sendhtml') && ! GETPOST('addfile') && ! GE
             $msgishtml,
             $errors_to,
         	'',
-        	$trackid	
+        	$trackid
         );
 
 		$result=$mailfile->sendfile();
@@ -257,6 +259,7 @@ $listofmethods=array();
 $listofmethods['mail']='PHP mail function';
 //$listofmethods['simplemail']='Simplemail class';
 $listofmethods['smtps']='SMTP/SMTPS socket library';
+$listofmethods['swiftmailer']='Swift Mailer socket library';
 
 
 if ($action == 'edit')
@@ -274,6 +277,8 @@ if ($action == 'edit')
                             jQuery(".drag").hide();
                             jQuery("#MAIN_MAIL_EMAIL_TLS").val(0);
                             jQuery("#MAIN_MAIL_EMAIL_TLS").prop("disabled", true);
+                            jQuery("#MAIN_MAIL_EMAIL_STARTTLS").val(0);
+                            jQuery("#MAIN_MAIL_EMAIL_STARTTLS").prop("disabled", true);
                             ';
 		if ($linuxlike)
 		{
@@ -300,6 +305,8 @@ if ($action == 'edit')
                             jQuery(".drag").show();
                             jQuery("#MAIN_MAIL_EMAIL_TLS").val('.$conf->global->MAIN_MAIL_EMAIL_TLS.');
                             jQuery("#MAIN_MAIL_EMAIL_TLS").removeAttr("disabled");
+                            jQuery("#MAIN_MAIL_EMAIL_STARTTLS").val('.$conf->global->MAIN_MAIL_EMAIL_STARTTLS.');
+                            jQuery("#MAIN_MAIL_EMAIL_STARTTLS").removeAttr("disabled");
                             jQuery("#MAIN_MAIL_SMTP_SERVER").removeAttr("disabled");
                             jQuery("#MAIN_MAIL_SMTP_PORT").removeAttr("disabled");
                             jQuery("#MAIN_MAIL_SMTP_SERVER").show();
@@ -307,11 +314,33 @@ if ($action == 'edit')
                             jQuery("#smtp_server_mess").hide();
 			                jQuery("#smtp_port_mess").hide();
 						}
+                        if (jQuery("#MAIN_MAIL_SENDMODE").val()==\'swiftmailer\')
+                        {
+                            jQuery(".drag").show();
+                            jQuery("#MAIN_MAIL_EMAIL_TLS").val('.$conf->global->MAIN_MAIL_EMAIL_TLS.');
+                            jQuery("#MAIN_MAIL_EMAIL_TLS").removeAttr("disabled");
+                            jQuery("#MAIN_MAIL_EMAIL_STARTTLS").val('.$conf->global->MAIN_MAIL_EMAIL_STARTTLS.');
+                            jQuery("#MAIN_MAIL_EMAIL_STARTTLS").removeAttr("disabled");
+                            jQuery("#MAIN_MAIL_SMTP_SERVER").removeAttr("disabled");
+                            jQuery("#MAIN_MAIL_SMTP_PORT").removeAttr("disabled");
+                            jQuery("#MAIN_MAIL_SMTP_SERVER").show();
+                            jQuery("#MAIN_MAIL_SMTP_PORT").show();
+                            jQuery("#smtp_server_mess").hide();
+                            jQuery("#smtp_port_mess").hide();
+                        }
                     }
                     initfields();
                     jQuery("#MAIN_MAIL_SENDMODE").change(function() {
                         initfields();
                     });
+					jQuery("#MAIN_MAIL_EMAIL_TLS").change(function() {
+						if (jQuery("#MAIN_MAIL_EMAIL_STARTTLS").val() == 1)
+							jQuery("#MAIN_MAIL_EMAIL_STARTTLS").val(0);
+					});
+					jQuery("#MAIN_MAIL_EMAIL_STARTTLS").change(function() {
+						if (jQuery("#MAIN_MAIL_EMAIL_TLS").val() == 1)
+							jQuery("#MAIN_MAIL_EMAIL_TLS").val(0);
+					});
                })';
 		print '</script>'."\n";
 	}
@@ -422,7 +451,7 @@ if ($action == 'edit')
 	print '</td></tr>';
 
 	// ID
-	if (! empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'smtps'))
+	if (! empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer'))))
 	{
 		$var=!$var;
 		$mainstmpid=(! empty($conf->global->MAIN_MAIL_SMTPS_ID)?$conf->global->MAIN_MAIL_SMTPS_ID:'');
@@ -442,7 +471,7 @@ if ($action == 'edit')
 	}
 
 	// PW
-	if (! empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'smtps'))
+	if (! empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer'))))
 	{
 		$var=!$var;
 		$mainsmtppw=(! empty($conf->global->MAIN_MAIL_SMTPS_PW)?$conf->global->MAIN_MAIL_SMTPS_PW:'');
@@ -464,7 +493,7 @@ if ($action == 'edit')
 	// TLS
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td>'.$langs->trans("MAIN_MAIL_EMAIL_TLS").'</td><td>';
-	if (! empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'smtps'))
+	if (! empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer'))))
 	{
 		if (function_exists('openssl_open'))
 		{
@@ -475,6 +504,20 @@ if ($action == 'edit')
 	else print yn(0).' ('.$langs->trans("NotSupported").')';
 	print '</td></tr>';
 
+	// STARTTLS
+	$var=!$var;
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("MAIN_MAIL_EMAIL_STARTTLS").'</td><td>';
+	if (! empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer'))))
+	{
+		if (function_exists('openssl_open'))
+		{
+			print $form->selectyesno('MAIN_MAIL_EMAIL_STARTTLS',(! empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS)?$conf->global->MAIN_MAIL_EMAIL_STARTTLS:0),1);
+		}
+		else print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')';
+	}
+	else print yn(0).' ('.$langs->trans("NotSupported").')';
+	print '</td></tr>';
+
 	// Separator
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td colspan="2">&nbsp;</td></tr>';
@@ -553,14 +596,14 @@ else
 
 	// SMTPS ID
 	$var=!$var;
-	if (isset($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'smtps')
+	if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer')))
 	{
 		print '<tr '.$bc[$var].'><td>'.$langs->trans("MAIN_MAIL_SMTPS_ID").'</td><td>'.$conf->global->MAIN_MAIL_SMTPS_ID.'</td></tr>';
 	}
 
 	// SMTPS PW
 	$var=!$var;
-	if (isset($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'smtps')
+	if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer')))
 	{
 		print '<tr '.$bc[$var].'><td>'.$langs->trans("MAIN_MAIL_SMTPS_PW").'</td><td>'.preg_replace('/./','*',$conf->global->MAIN_MAIL_SMTPS_PW).'</td></tr>';
 	}
@@ -568,7 +611,7 @@ else
 	// TLS
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td>'.$langs->trans("MAIN_MAIL_EMAIL_TLS").'</td><td>';
-	if (isset($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'smtps')
+	if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer')))
 	{
 		if (function_exists('openssl_open'))
 		{
@@ -579,6 +622,20 @@ else
 	else print yn(0).' ('.$langs->trans("NotSupported").')';
 	print '</td></tr>';
 
+	// STARTTLS
+	$var=!$var;
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("MAIN_MAIL_EMAIL_STARTTLS").'</td><td>';
+	if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer')))
+	{
+		if (function_exists('openssl_open'))
+		{
+			print yn($conf->global->MAIN_MAIL_EMAIL_STARTTLS);
+		}
+		else print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')';
+	}
+	else print yn(0).' ('.$langs->trans("NotSupported").')';
+	print '</td></tr>';
+
 	// Separator
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td colspan="2">&nbsp;</td></tr>';
@@ -663,9 +720,6 @@ else
 	{
 		print load_fiche_titre($langs->trans("DoTestServerAvailability"));
 
-		// If we use SSL/TLS
-		if (! empty($conf->global->MAIN_MAIL_EMAIL_TLS) && function_exists('openssl_open')) $server='ssl://'.$server;
-
 		include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
 		$mail = new CMailFile('','','','');
 		$result=$mail->check_server_port($server,$port);

+ 12 - 3
htdocs/admin/menus/edit.php

@@ -75,6 +75,7 @@ if ($action == 'update')
             $menu->perms=$_POST['perms'];
             $menu->target=$_POST['target'];
             $menu->user=$_POST['user'];
+            $menu->fk_menu=$_POST['fk_menu'];
             $result=$menu->update($user);
             if ($result > 0)
             {
@@ -275,6 +276,8 @@ if ($action == 'create')
     print '<form action="./edit.php?action=add&menuId='.$_GET['menuId'].'" method="post" name="formmenucreate">';
     print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
 
+    dol_fiche_head();
+    
     print '<table class="border" width="100%">';
 
     // Id
@@ -368,8 +371,10 @@ if ($action == 'create')
 
     print '</table>';
 
+    dol_fiche_end();
+    
     // Boutons
-    print '<br><div class="center">';
+    print '<div class="center">';
 	print '<input type="submit" class="button" name="save" value="'.$langs->trans("Save").'">';
     print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
     print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
@@ -387,6 +392,8 @@ elseif ($action == 'edit')
     print '<input type="hidden" name="handler_origine" value="'.$menu_handler.'">';
     print '<input type="hidden" name="menuId" value="'.$_GET['menuId'].'">';
 
+    dol_fiche_head();
+    
     print '<table class="border" width="100%">';
 
     $menu = new Menubase($db);
@@ -416,9 +423,9 @@ elseif ($action == 'edit')
 
     // MenuId Parent
     print '<tr><td class="fieldrequired">'.$langs->trans('MenuIdParent').'</td>';
+    print '<td><input type="text" name="fk_menu" value="'.$menu->fk_menu.'" size=10></td>';
     //$menu_handler
     //print '<td><input type="text" size="50" name="handler" value="all"></td>';
-    print '<td>'.$menu->fk_menu.'</td>';
     print '<td>'.$langs->trans('DetailMenuIdParent').'</td></tr>';
 
     // Niveau
@@ -454,8 +461,10 @@ elseif ($action == 'edit')
 
     print '</table>';
 
+    dol_fiche_end();
+    
     // Bouton
-    print '<br><div class="center">';
+    print '<div class="center">';
 	print '<input type="submit" class="button" name="save" value="'.$langs->trans("Save").'">';
     print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
     print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';

+ 1 - 1
htdocs/admin/menus/index.php

@@ -262,7 +262,7 @@ print '</form>';
 
 print '<br>';
 
-print '<table class="border" width="100%">';
+print '<table class="noborder centpercent">';
 
 print '<tr class="liste_titre">';
 print '<td>'.$langs->trans("TreeMenuPersonalized").'</td>';

+ 0 - 33
htdocs/admin/menus/other.php

@@ -50,25 +50,11 @@ else if ($action == 'disable_hidemenu')
 	exit;
 }
 
-if ($action == 'activate_layoutmenu')
-{
-	dolibarr_set_const($db, "MAIN_MENU_USE_JQUERY_LAYOUT", '1','chaine',0,'',$conf->entity);
-	header("Location: ".$_SERVER["PHP_SELF"]);
-	exit;
-}
-else if ($action == 'disable_layoutmenu')
-{
-	dolibarr_del_const($db, "MAIN_MENU_USE_JQUERY_LAYOUT",$conf->entity);
-	header("Location: ".$_SERVER["PHP_SELF"]);
-	exit;
-}
-
 
 /*
  * View
  */
 
-
 llxHeader('',$langs->trans("Setup"));
 
 print load_fiche_titre($langs->trans("Menus"),'','title_setup');
@@ -119,25 +105,6 @@ else
 print "</td>";
 print '</tr>';
 
-// Use a flip-hide menu
-if (isset($conf->global->MAIN_FEATURES_LEVEL) && $conf->global->MAIN_FEATURES_LEVEL > 1)
-{
-	$var=!$var;
-	print "<tr ".$bc[$var].">";
-	print '<td colspan="3">'.$langs->trans("MenuUseLayout").'</td>';
-	print '<td align="center">';
-	if (empty($conf->global->MAIN_MENU_USE_JQUERY_LAYOUT))
-	{
-		print '<a href="'.$_SERVER["PHP_SELF"].'?action=activate_layoutmenu">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>';
-	}
-	else
-	{
-		print '<a href="'.$_SERVER["PHP_SELF"].'?action=disable_layoutmenu">'.img_picto($langs->trans("Enabled"),'switch_on').'</a>';
-	}
-	print "</td>";
-	print '</tr>';
-}
-
 print '</table>';
 
 

+ 317 - 80
htdocs/admin/modules.php

@@ -38,6 +38,10 @@ $mode=GETPOST('mode', 'alpha')?GETPOST('mode', 'alpha'):(isset($_SESSION['mode']
 $action=GETPOST('action','alpha');
 $value=GETPOST('value', 'alpha');
 $page_y=GETPOST('page_y','int');
+$search_keyword=GETPOST('search_keyword','alpha');
+$search_status=GETPOST('search_status','alpha');
+$search_nature=GETPOST('search_nature','alpha');
+$search_version=GETPOST('search_version','alpha');
 
 if (! $user->admin)
 	accessforbidden();
@@ -59,6 +63,12 @@ $familyinfo=array(
 	'other'=>array('position'=>'100', 'label'=>$langs->trans("ModuleFamilyOther")),
 );
 
+$param='';
+if ($search_keyword) $param.='&search_keyword='.urlencode($search_keyword);
+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);
+
 
 
 /*
@@ -69,7 +79,7 @@ if ($action == 'set' && $user->admin)
 {
     $result=activateModule($value);
     if ($result) setEventMessages($result, null, 'errors');
-    header("Location: modules.php?mode=".$mode.($page_y?'&page_y='.$page_y:''));
+    header("Location: modules.php?mode=".$mode.$param.($page_y?'&page_y='.$page_y:''));
 	exit;
 }
 
@@ -77,10 +87,19 @@ if ($action == 'reset' && $user->admin)
 {
     $result=unActivateModule($value);
     if ($result) setEventMessages($result, null, 'errors');
-    header("Location: modules.php?mode=".$mode.($page_y?'&page_y='.$page_y:''));
+    header("Location: modules.php?mode=".$mode.$param.($page_y?'&page_y='.$page_y:''));
 	exit;
 }
 
+if (GETPOST('buttonreset'))
+{
+    $search_keyword='';
+    $search_status='';
+    $search_nature='';
+    $search_version='';
+}
+
+
 
 /*
  * View
@@ -93,6 +112,7 @@ $_SESSION["mode"]=$mode;
 $help_url='EN:First_setup|FR:Premiers_paramétrages|ES:Primeras_configuraciones';
 llxHeader('',$langs->trans("Setup"),$help_url);
 
+$arrayofnatures=array('core'=>$langs->transnoentitiesnoconv("Core"), 'external'=>$langs->transnoentitiesnoconv("External").' - '.$langs->trans("AllPublishers"));
 
 // Search modules dirs
 $modulesdir = dolGetModulesDirs();
@@ -154,11 +174,30 @@ foreach ($modulesdir as $dir)
 		    					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=false;
+		    					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)
+		    					if ($modulequalified > 0)
 		    					{
 		    						$modules[$i] = $objMod;
 		    			            $filename[$i]= $modName;
@@ -183,6 +222,7 @@ foreach ($modulesdir as $dir)
 
 		    			            $orders[$i]  = $familyinfo[$familykey]['position']."_".$familykey."_".$moduleposition."_".$j;   // Sort by family, then by module position then number
 		    						$dirmod[$i]  = $dir;
+		    						//print $i.'-'.$dirmod[$i].'<br>';
 		    			            // Set categ[$i]
 		    						$specialstring = isset($specialtostring[$special])?$specialtostring[$special]:'unknown';
 		    			            if ($objMod->version == 'development' || $objMod->version == 'experimental') $specialstring='expdev';
@@ -231,57 +271,22 @@ 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")."<br>\n";
-//if ($mode==='other')       print $langs->trans("ModulesSpecialDesc")."<br>\n";
-//if ($mode==='interfaces')  print $langs->trans("ModulesInterfaceDesc")."<br>\n";
-//if ($mode==='functional')  print $langs->trans("ModulesJobDesc")."<br>\n";
 if ($mode==='marketplace') print $langs->trans("ModulesMarketPlaceDesc")."<br>\n";
 if ($mode==='expdev')      print $langs->trans("ModuleFamilyExperimental")."<br>\n";
 
 
-//print '<br>'."\n";
-
-
 $h = 0;
 
 $categidx='common';    // Main
-if (! empty($categ[$categidx]))
-{
+//if (! empty($categ[$categidx]))
+//{
 	$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=".$categidx;
 	$head[$h][1] = $langs->trans("AvailableModules");
 	$head[$h][2] = 'common';
 	$h++;
-}
-
-/*
-$categidx='other';    // Other
-if (! empty($categ[$categidx]))
-{
-	$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=".$categidx;
-	$head[$h][1] = $langs->trans("ModulesOther");
-	$head[$h][2] = 'other';
-	$h++;
-}
-
-$categidx='interfaces';    // Interfaces
-if (! empty($categ[$categidx]))
-{
-	$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=".$categidx;
-	$head[$h][1] = $langs->trans("ModulesInterfaces");
-	$head[$h][2] = 'interfaces';
-	$h++;
-}
-
-$categidx='functional';    // Not used
-if (! empty($categ[$categidx]))
-{
-	$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=".$categidx;
-	$head[$h][1] = $langs->trans("ModulesSpecial");
-	$head[$h][2] = 'functional';
-	$h++;
-}
-*/
+//}
 
-$categidx='expdev';
+/*$categidx='expdev';
 if (! empty($categ[$categidx]))
 {
 	$categidx='expdev';
@@ -289,7 +294,7 @@ if (! empty($categ[$categidx]))
     $head[$h][1] = $form->textwithpicto($langs->trans("ModuleFamilyExperimental"), $langs->trans('DoNotUseInProduction'), 1, 'warning', '', 0, 3);
     $head[$h][2] = 'expdev';
     $h++;
-}
+}*/
 
 $categidx='marketplace';
 $head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=".$categidx;
@@ -307,20 +312,56 @@ $var=true;
 
 if ($mode != 'marketplace')
 {
-    print "<table summary=\"list_of_modules\" class=\"noborder\" width=\"100%\">\n";
-
-    /*
-    print '<tr class="liste_titre">'."\n";
-    print "  <td colspan=\"2\">".$langs->trans("Module")."</td>\n";
-    print "  <td>".$langs->trans("Description")."</td>\n";
-    print "  <td align=\"center\">".$langs->trans("Version")."</td>\n";
-    print '  <td align="center">'.$langs->trans("Status").'</td>'."\n";
-    print '  <td align="right">'.$langs->trans("SetupShort").'</td>'."\n";
-    print "</tr>\n";
-	*/
-
+    print '<form method="GET" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
+    if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
+    print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+    print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
+    print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
+    
+    $moreforfilter = '';
+    $moreforfilter.='<div class="divsearchfield">';
+    $moreforfilter.= $langs->trans('Keyword') . ': <input type="text" name="search_keyword" value="'.dol_escape_htmltag($search_keyword).'">';
+    $moreforfilter.= '</div>';
+    $moreforfilter.='<div class="divsearchfield">';
+    $moreforfilter.= $langs->trans('Origin') . ': '.$form->selectarray('search_nature', $arrayofnatures, $search_nature, 1);
+    $moreforfilter.= '</div>';
+    if (! empty($conf->global->MAIN_FEATURES_LEVEL))
+    {
+        $array_version = array('stable'=>$langs->transnoentitiesnoconv("Stable"));
+        if ($conf->global->MAIN_FEATURES_LEVEL < 0) $array_version['deprecated']=$langs->trans("Deprecated");
+        if ($conf->global->MAIN_FEATURES_LEVEL > 0) $array_version['experimental']=$langs->trans("Experimental");
+        if ($conf->global->MAIN_FEATURES_LEVEL > 1) $array_version['development']=$langs->trans("Development");
+        $moreforfilter.='<div class="divsearchfield">';
+        $moreforfilter.= $langs->trans('Version') . ': '.$form->selectarray('search_version', $array_version, $search_version, 1);
+        $moreforfilter.= '</div>';
+    }
+    $moreforfilter.='<div class="divsearchfield">';
+    $moreforfilter.= $langs->trans('Status') . ': '.$form->selectarray('search_status', array('active'=>$langs->transnoentitiesnoconv("Enabled"), 'disabled'=>$langs->transnoentitiesnoconv("Disabled")), $search_status, 1);
+    $moreforfilter.= '</div>';
+    $moreforfilter.=' ';
+    $moreforfilter.='<div class="divsearchfield">';
+    $moreforfilter.='<input type="submit" name="buttonsubmit" class="button" value="'.dol_escape_htmltag($langs->trans("Refresh")).'">';
+    $moreforfilter.=' ';
+    $moreforfilter.='<input type="submit" name="buttonreset" class="button" value="'.dol_escape_htmltag($langs->trans("Reset")).'">';
+    $moreforfilter.= '</div>';
+    
+    if (! empty($moreforfilter))
+    {
+        //print '<div class="liste_titre liste_titre_bydiv centpercent">';
+        print $moreforfilter;
+        $parameters=array();
+        $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters);    // Note that $action and $object may have been modified by hook
+        print $hookmanager->resPrint;
+        //print '</div>';
+    }    
+    
+    print '<br><br><br>';
+    
+    
     // Show list of modules
 
+    print '<table summary="list_of_modules" id="list_of_modules" class="liste" width="100%">'."\n";
+
     $oldfamily='';
 
     foreach ($orders as $key => $value)
@@ -330,7 +371,8 @@ if ($mode != 'marketplace')
 
         $modName = $filename[$key];
     	$objMod  = $modules[$key];
-
+    	$dirofmodule = $dirmod[$key];
+    	 
     	$special = $objMod->special;
 
     	//print $objMod->name." - ".$key." - ".$objMod->special.' - '.$objMod->version."<br>";
@@ -343,8 +385,50 @@ if ($mode != 'marketplace')
         	dol_syslog("Error for module ".$key." - Property name of module looks empty", LOG_WARNING);
       		continue;
         }
-
+        
         $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();
+
+        // We discard showing according to filters
+        if ($search_keyword)
+        {
+            $qualified=0;
+            if (preg_match('/'.preg_quote($search_keyword).'/i', $modulename) 
+                || preg_match('/'.preg_quote($search_keyword).'/i', $moduledesc)
+                || preg_match('/'.preg_quote($search_keyword).'/i', $moduledesclong)
+                || preg_match('/'.preg_quote($search_keyword).'/i', $moduleauthor)
+                ) $qualified=1;
+            if (! $qualified) continue;
+        }
+        if ($search_status)
+        {
+            if ($search_status == 'active' && empty($conf->global->$const_name)) continue;
+            if ($search_status == 'disabled' && ! empty($conf->global->$const_name)) continue;
+        }
+        if ($search_nature)
+        {
+            if (preg_match('/^external/',$search_nature) && $objMod->isCoreOrExternalModule() != 'external') continue;
+            if (preg_match('/^external_(.*)$/',$search_nature, $reg))
+            {
+                //print $reg[1].'-'.dol_escape_htmltag($objMod->getPublisher());
+                $publisher=dol_escape_htmltag($objMod->getPublisher());
+                if ($reg[1] && $reg[1] != $publisher) continue;
+                if (! $reg[1] && ! empty($publisher)) continue;
+            }
+            if ($search_nature == 'core' && $objMod->isCoreOrExternalModule() == 'external') continue;
+        }
+        if ($search_version)
+        {
+            if (($objMod->version == 'development' || $objMod->version == 'experimental' || preg_match('/deprecated/', $objMod->version)) && $search_version == 'stable') continue;
+            if ($objMod->version != 'development'  && ($search_version == 'development')) continue;
+            if ($objMod->version != 'experimental' && ($search_version == 'experimental')) continue;
+            if (! preg_match('/deprecated/', $objMod->version) && ($search_version == 'deprecated')) continue;
+        }
 
         // Load all lang files of module
         if (isset($objMod->langfiles) && is_array($objMod->langfiles))
@@ -361,7 +445,7 @@ if ($mode != 'marketplace')
         if ($familykey!=$oldfamily)
         {
             print '<tr class="liste_titre">'."\n";
-            print '<td colspan="5">';
+            print '<td colspan="6">';
             $familytext=empty($familyinfo[$familykey]['label'])?$familykey:$familyinfo[$familykey]['label'];
             print $familytext;
             print "</td>\n";
@@ -409,18 +493,171 @@ if ($mode != 'marketplace')
         print nl2br($objMod->getDesc());
         print "</td>\n";
 
-        // Version
-        print '<td align="center" valign="top" class="nowrap">';
-        $version=$objMod->getVersion();
-        $dirofmodule=$dirmod[$key];
+        // Help
+        print '<td align="center" valign="top" class="nowrap" style="width: 82px;">';
+        $text='';
+        if ($objMod->getDescLong()) $text.=$objMod->getDesc().'<br>'.$objMod->getDescLong().'<br>';
+        else $text.=$objMod->getDesc().'<br>';
+        
+        $textexternal='';
         if ($objMod->isCoreOrExternalModule() == 'external')
         {
-        	$text=$langs->trans("ExternalModule",$dirofmodule);
-        	if (! empty($objMod->editor_name) && $objMod->editor_name != 'dolibarr') $text.=' - '.$objMod->editor_name;
-        	if (! empty($objMod->editor_web) && $objMod->editor_web != 'www.dolibarr.org') $text.=' - '.$objMod->editor_web;
-        	print $form->textwithpicto($version, $text, 1, 'help');
+            $textexternal.='<br><strong>'.$langs->trans("Origin").':</strong> '.$langs->trans("ExternalModule",$dirofmodule);
+            if ($objMod->editor_name != 'dolibarr') $textexternal.='<br><strong>'.$langs->trans("Publisher").':</strong> '.(empty($objMod->editor_name)?$langs->trans("Unknown"):$objMod->editor_name);
+            if (! empty($objMod->editor_url) && ! preg_match('/dolibarr\.org/i',$objMod->editor_url)) $textexternal.='<br><strong>'.$langs->trans("Url").':</strong> '.$objMod->editor_url;
+            $text.=$textexternal;
+            $text.='<br>';
+        }
+        else
+        {
+            $text.='<br><strong>'.$langs->trans("Origin").':</strong> '.$langs->trans("Core").'<br>';
+        }
+        $text.='<br><strong>'.$langs->trans("AddRemoveTabs").':</strong> ';
+        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.='<br><strong>'.$langs->trans("AddDictionaries").':</strong> ';
+        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.='<br><strong>'.$langs->trans("AddBoxes").':</strong> ';
+        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.='<br><strong>'.$langs->trans("AddModels").':</strong> ';
+        if (isset($objMod->module_parts) && isset($objMod->module_parts['models']) && $objMod->module_parts['models'])
+        {
+            $text.=$langs->trans("Yes");
+        }
+        else $text.=$langs->trans("No");
+        
+        $text.='<br><strong>'.$langs->trans("AddSubstitutions").':</strong> ';
+        if (isset($objMod->module_parts) && isset($objMod->module_parts['substitutions']) && $objMod->module_parts['substitutions'])
+        {
+            $text.=$langs->trans("Yes");
         }
-        else print $version;
+        else $text.=$langs->trans("No");
+        
+        $text.='<br><strong>'.$langs->trans("AddSheduledJobs").':</strong> ';
+        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.='<br><strong>'.$langs->trans("AddTriggers").':</strong> ';
+        if (isset($objMod->module_parts) && isset($objMod->module_parts['triggers']) && $objMod->module_parts['triggers'])
+        {
+            $text.=$langs->trans("Yes");
+        }
+        else $text.=$langs->trans("No");
+        
+        $text.='<br><strong>'.$langs->trans("AddHooks").':</strong> ';
+        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.='<br><strong>'.$langs->trans("AddPermissions").':</strong> ';
+        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.='<br><strong>'.$langs->trans("AddMenus").':</strong> ';
+        if (isset($objMod->menu) && is_array($objMod->menu) && $objMod->menu)
+        {
+            $text.=$langs->trans("Yes");
+        }
+        else $text.=$langs->trans("No");
+        
+        $text.='<br><strong>'.$langs->trans("AddExportProfiles").':</strong> ';
+        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.='<br><strong>'.$langs->trans("AddImportProfiles").':</strong> ';
+        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.='<br><strong>'.$langs->trans("AddOtherPagesOrServices").':</strong> ';
+        $text.=$langs->trans("DetectionNotPossible");
+        
+        print $form->textwithpicto('', $text, 1, 'help', 'minheight20');
+
+        // Picto warning 
+        $version=$objMod->getVersion(0);
+        $versiontrans=$objMod->getVersion(1);
+        if (preg_match('/development/i', $version))  print img_warning($langs->trans("Development"), 'style="float: right"');
+        if (preg_match('/experimental/i', $version)) print img_warning($langs->trans("Experimental"), 'style="float: right"');
+        if (preg_match('/deprecated/i', $version))   print img_warning($langs->trans("Deprecated"), 'style="float: right"');
+        
+        // Picto external
+        if ($textexternal) print img_picto($langs->trans("ExternalModule",$dirofmodule), 'external', 'style="float: right"');
+        
+        
+        print '</td>';
+        
+        // Version
+        print '<td align="center" valign="top" class="nowrap">';
+        print $versiontrans;
         print "</td>\n";
 
         // Activate/Disable and Setup (2 columns)
@@ -440,7 +677,7 @@ if ($mode != 'marketplace')
         	}
         	else
         	{
-        		print '<a class="reposition" href="modules.php?id='.$objMod->numero.'&amp;module_position='.$module_position.'&amp;action=reset&amp;value=' . $modName . '&amp;mode=' . $mode . '">';
+        		print '<a class="reposition" href="modules.php?id='.$objMod->numero.'&amp;module_position='.$module_position.'&amp;action=reset&amp;value=' . $modName . '&amp;mode=' . $mode . $param . '">';
         		print img_picto($langs->trans("Activated"),'switch_on');
         		print '</a>';
         	}
@@ -451,25 +688,25 @@ if ($mode != 'marketplace')
         	{
         		if (is_array($objMod->config_page_url))
         		{
-        			print '  <td align="right" valign="top">';
+        			print '<td class="tdsetuppicto" align="right" valign="top">';
         			$i=0;
         			foreach ($objMod->config_page_url as $page)
         			{
         				$urlpage=$page;
         				if ($i++)
         				{
-        					print '<a href="'.$urlpage.'" title="'.$langs->trans($page).'">'.img_picto(ucfirst($page),"setup").'</a>&nbsp;';
+        					print '<a href="'.$urlpage.'" title="'.$langs->trans($page).'">'.img_picto(ucfirst($page),"setup").'</a>';
         					//    print '<a href="'.$page.'">'.ucfirst($page).'</a>&nbsp;';
         				}
         				else
         				{
         					if (preg_match('/^([^@]+)@([^@]+)$/i',$urlpage,$regs))
         					{
-        						print '<a href="'.dol_buildpath('/'.$regs[2].'/admin/'.$regs[1],1).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup").'</a>&nbsp;';
+        						print '<a href="'.dol_buildpath('/'.$regs[2].'/admin/'.$regs[1],1).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').'</a>';
         					}
         					else
         					{
-        						print '<a href="'.$urlpage.'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup").'</a>&nbsp;';
+        						print '<a href="'.$urlpage.'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').'</a>';
         					}
         				}
         			}
@@ -477,16 +714,16 @@ if ($mode != 'marketplace')
         		}
         		else if (preg_match('/^([^@]+)@([^@]+)$/i',$objMod->config_page_url,$regs))
         		{
-        			print '<td align="right" valign="middle"><a href="'.dol_buildpath('/'.$regs[2].'/admin/'.$regs[1],1).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup").'</a></td>';
+        			print '<td class="tdsetuppicto" align="right" valign="middle"><a href="'.dol_buildpath('/'.$regs[2].'/admin/'.$regs[1],1).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').'</a></td>';
         		}
         		else
         		{
-        			print '<td align="right" valign="middle"><a href="'.$objMod->config_page_url.'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup").'</a></td>';
+        			print '<td class="tdsetuppicto" align="right" valign="middle"><a href="'.$objMod->config_page_url.'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').'</a></td>';
         		}
         	}
         	else
         	{
-        		print "<td>&nbsp;</td>";
+        		print '<td class="tdsetuppicto" align="right" valign="middle">'.img_picto($langs->trans("NothingToSetup"),"setup",'class="opacitytransp" style="padding-right: 6px"').'</td>';
         	}
 
         }
@@ -504,12 +741,12 @@ if ($mode != 'marketplace')
         	else
         	{
 	        	// Module non actif
-	        	print '<a class="reposition" href="modules.php?id='.$objMod->numero.'&amp;module_position='.$module_position.'&amp;action=set&amp;value=' . $modName . '&amp;mode=' . $mode . '">';
+	        	print '<a class="reposition" href="modules.php?id='.$objMod->numero.'&amp;module_position='.$module_position.'&amp;action=set&amp;value=' . $modName . '&amp;mode=' . $mode . $param . '">';
 	        	print img_picto($langs->trans("Disabled"),'switch_off');
 	        	print "</a>\n";
         	}
         	print "</td>\n";
-        	print "<td>&nbsp;</td>";
+        	print '<td class="tdsetuppicto" align="right" valign="middle">'.img_picto($langs->trans("NothingToSetup"),"setup",'class="opacitytransp" style="padding-right: 6px"').'</td>';
         }
 
         print "</tr>\n";
@@ -529,7 +766,7 @@ else
 
     $var=!$var;
     print "<tr ".$bc[$var].">\n";
-    $url='http://www.dolistore.com';
+    $url='https://www.dolistore.com';
     print '<td align="left"><a href="'.$url.'" target="_blank" rel="external"><img border="0" width="180" src="'.DOL_URL_ROOT.'/theme/dolistore_logo.png"></a></td>';
     print '<td>'.$langs->trans("DoliStoreDesc").'</td>';
     print '<td><a href="'.$url.'" target="_blank" rel="external">'.$url.'</a></td>';
@@ -537,7 +774,7 @@ else
 
     $var=!$var;
     print "<tr ".$bc[$var].">\n";
-    $url='http://partners.dolibarr.org';
+    $url='https://partners.dolibarr.org';
     print '<td align="left"><a href="'.$url.'" target="_blank" rel="external"><img border="0" width="180" src="'.DOL_URL_ROOT.'/theme/dolibarr_preferred_partner_int.png"></a></td>';
     print '<td>'.$langs->trans("DoliPartnersDesc").'</td>';
     print '<td><a href="'.$url.'" target="_blank" rel="external">'.$url.'</a></td>';

+ 79 - 12
htdocs/admin/multicurrency.php

@@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/multicurrency.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
 
+
 // Translations
 $langs->load("multicurrency");
 
@@ -41,10 +42,11 @@ if (! $user->admin) {
 
 // Parameters
 $action = GETPOST('action', 'alpha');
-
 /*
  * Actions
  */
+
+
 if (preg_match('/set_(.*)/',$action,$reg))
 {
 	$code=$reg[1];
@@ -64,7 +66,7 @@ if (preg_match('/del_(.*)/',$action,$reg))
 	$code=$reg[1];
 	if (dolibarr_del_const($db, $code, 0) > 0)
 	{
-		Header("Location: ".$_SERVER["PHP_SELF"]);
+		header("Location: ".$_SERVER["PHP_SELF"]);
 		exit;
 	}
 	else
@@ -117,6 +119,21 @@ elseif ($action == 'update_currency')
 		}
 	}
 }
+elseif ($action == 'synchronize') 
+{
+	$response = GETPOST('response');
+	$response = json_decode($response);
+	
+	if ($response->success)
+	{
+		MultiCurrency::syncRates($response);	
+	}
+	else
+	{
+		setEventMessages($langs->trans('multicurrency_syncronize_error', $reponse->error->info), null, 'errors');
+	}
+}
+
 
 $TCurrency = array();
 $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'multicurrency WHERE entity = '.$conf->entity;
@@ -136,7 +153,7 @@ if ($resql)
  * View
  */
 
-$page_name = "MultiCurrency";
+$page_name = "MultiCurrencySetup";
 
 llxHeader('', $langs->trans($page_name));
 
@@ -212,42 +229,72 @@ print '<td align="right" width="400">';
 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
 print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
 print '<input type="hidden" name="action" value="set_MULTICURRENCY_MODIFY_RATE_APPLICATION">';
-print $form->selectarray('MULTICURRENCY_MODIFY_RATE_APPLICATION', array('PU_DOLIBARR' => 'PU_DOLIBARR', 'PU_CURRENCY' => 'PU_CURRENCY'));
+print $form->selectarray('MULTICURRENCY_MODIFY_RATE_APPLICATION', array('PU_DOLIBARR' => 'PU_DOLIBARR', 'PU_CURRENCY' => 'PU_CURRENCY'), $conf->global->MULTICURRENCY_MODIFY_RATE_APPLICATION);
 print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
 print '</form>';
 print '</td></tr>';
 
+print '</table>';
+print '<br />';
+
+$var=false;
+print '<table class="noborder" width="100%">';
+print '<tr class="liste_titre">';
+print '<td>'.$langs->trans("CurrencyLayerAccount").'</td>'."\n";
+print '<td align="center" width="20">&nbsp;</td>';
+print '<td align="right" width="100">';
+print '<form id="form_sync" action="" method="POST">';
+print '<input type="hidden" name="action" value="synchronize" />';
+print '<textarea id="response" class="hideobject" name="response"></textarea>';
+print $langs->trans("Value").'&nbsp;<input type="button" id="bt_sync" class="button" onclick="javascript:getRates();" value="'.$langs->trans('Synchronize').'" />';
+print '</form>';
+print '</td></tr>';
+
+
 $var=!$var;
 print '<tr '.$bc[$var].'>';
-print '<td>'.$langs->transnoentitiesnoconv("multicurrency_appId").'</td>';
+print '<td><a target="_blank" href="https://currencylayer.com">'.$langs->transnoentitiesnoconv("multicurrency_appId").'</a></td>';
 print '<td align="center" width="20">&nbsp;</td>';
 print '<td align="right" width="400">';
 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
 print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-print '<input type="hidden" name="action" value="set_CURRENCY_APP_ID">';
-print '<input type="text" name="CURRENCY_APP_ID" value="'.$conf->global->MULTICURRENCY_APP_ID.'" size="28" />&nbsp;';
+print '<input type="hidden" name="action" value="set_MULTICURRENCY_APP_ID">';
+print '<input type="text" name="MULTICURRENCY_APP_ID" value="'.$conf->global->MULTICURRENCY_APP_ID.'" size="28" />&nbsp;';
 print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
 print '</form>';
 print '</td></tr>';
 
+/* This property seems not used in code, so i comment it
 $var=!$var;
 print '<tr '.$bc[$var].'>';
-print '<td>'.$langs->transnoentitiesnoconv("multicurrency_currencyFromToRate").'</td>';
+print '<td>'.$langs->transnoentitiesnoconv("multicurrency_appCurrencySource").'</td>';
 print '<td align="center" width="20">&nbsp;</td>';
 print '<td align="right" width="400">';
 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
 print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-print '<input type="hidden" name="action" value="set_MULTICURRENCY_FROM_TO_RATE">';
-print '<input type="text" name="MULTICURRENCY_FROM_TO_RATE" value="'.$conf->global->MULTICURRENCY_FROM_TO_RATE.'" size="10" placeholder="USD-EUR-1" />&nbsp;'; // CURRENCY_BASE - CURRENCY_ENTITY - ID_ENTITY
+print '<input type="hidden" name="action" value="set_MULTICURRENCY_APP_SOURCE">';
+print '<input type="text" name="MULTICURRENCY_APP_SOURCE" value="'.$conf->global->MULTICURRENCY_APP_SOURCE.'" size="10" placeholder="USD" />&nbsp;'; // Default: USD
 print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
 print '</form>';
 print '</td></tr>';
 
-print '</table>';
-
+$var=!$var;
+print '<tr '.$bc[$var].'>';
+print '<td>'.$langs->transnoentitiesnoconv("multicurrency_alternateCurrencySource").'</td>';
+print '<td align="center" width="20">&nbsp;</td>';
+print '<td align="right" width="400">';
+print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
+print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+print '<input type="hidden" name="action" value="set_MULTICURRENCY_ALTERNATE_SOURCE">';
+print '<input type="text" name="MULTICURRENCY_ALTERNATE_SOURCE" value="'.$conf->global->MULTICURRENCY_ALTERNATE_SOURCE.'" size="10" placeholder="EUR" />&nbsp;'; // Example: EUR
+print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
 print '</form>';
+print '</td></tr>';
+*/
 
+print '</table>';
 print '<br />';
+
 print '<table class="noborder" width="100%">';
 
 print '<tr class="liste_titre">';
@@ -287,6 +334,26 @@ foreach ($TCurrency as &$currency)
 
 print '</table>';
 
+
+
+print '
+	<script type="text/javascript">
+ 		function getRates()
+		{
+			$("#bt_sync").attr("disabled", true);
+			var url_sync = "http://apilayer.net/api/live?access_key='.$conf->global->MULTICURRENCY_APP_ID.'&format=1'.(!empty($conf->global->MULTICURRENCY_APP_SOURCE) ? '&source='.$conf->global->MULTICURRENCY_APP_SOURCE : '').'";
+			
+			$.ajax({
+				url: url_sync,
+				dataType: "jsonp"
+			}).done(function(response) {
+				$("#response").val(JSON.stringify(response));
+				$("#form_sync").submit();
+			});
+		}
+	</script>
+';
+
 llxFooter();
 
 $db->close();

+ 3 - 0
htdocs/admin/notification.php

@@ -2,6 +2,7 @@
 /* Copyright (C) 2004      Rodolphe Quiedeville <rodolphe@quiedeville.org>
  * Copyright (C) 2005-2015 Laurent Destailleur  <eldy@users.sourceforge.org>
  * Copyright (C) 2013      Juanjo Menent		<jmenent@2byte.es>
+ * Copyright (C) 2015      Bahfir Abbes         <contact@dolibarrpar.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -169,6 +170,7 @@ if ($conf->societe->enabled)
 	    elseif ($notifiedevent['elementtype'] == 'propal') $elementLabel = $langs->trans('Proposal');
 	    elseif ($notifiedevent['elementtype'] == 'facture') $elementLabel = $langs->trans('Bill');
 	    elseif ($notifiedevent['elementtype'] == 'commande') $elementLabel = $langs->trans('Order');
+	    elseif ($notifiedevent['elementtype'] == 'ficheinter') $elementLabel = $langs->trans('Intervention');
 
 	    print '<tr '.$bc[$var].'>';
 	    print '<td>'.$elementLabel.'</td>';
@@ -213,6 +215,7 @@ foreach($listofnotifiedevents as $notifiedevent)
     elseif ($notifiedevent['elementtype'] == 'propal') $elementLabel = $langs->trans('Proposal');
     elseif ($notifiedevent['elementtype'] == 'facture') $elementLabel = $langs->trans('Bill');
     elseif ($notifiedevent['elementtype'] == 'commande') $elementLabel = $langs->trans('Order');
+	elseif ($notifiedevent['elementtype'] == 'ficheinter') $elementLabel = $langs->trans('Intervention');
 
     print '<tr '.$bc[$var].'>';
     print '<td>'.$elementLabel.'</td>';

+ 2 - 3
htdocs/admin/security_file.php

@@ -114,9 +114,8 @@ llxHeader('',$langs->trans("Files"),$wikihelp);
 
 print load_fiche_titre($langs->trans("SecuritySetup"),'','title_setup');
 
-//print $langs->trans("FilesDesc")."<br>\n";
-//print "<br>\n";
-
+print $langs->trans("SecurityFilesDesc")."<br>\n";
+print "<br>\n";
 
 
 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';

+ 22 - 214
htdocs/admin/tools/export.php

@@ -25,6 +25,7 @@
 require '../../main.inc.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
 
 $langs->load("admin");
@@ -111,175 +112,34 @@ $outputdir  = $conf->admin->dir_output.'/backup';
 $result=dol_mkdir($outputdir);
 
 
+$utils = new Utils($db);
+
+
 // MYSQL
 if ($what == 'mysql')
 {
+    
     $cmddump=GETPOST("mysqldump");	// Do not sanitize here with 'alpha', will be sanitize later by escapeshellarg
     if ($cmddump)
     {
         dolibarr_set_const($db, 'SYSTEMTOOLS_MYSQLDUMP', $cmddump,'chaine',0,'',$conf->entity);
     }
 
-    $outputfile = $outputdir.'/'.$file;
-    // for compression format, we add extension
-    $compression=GETPOST('compression') ? GETPOST('compression','alpha') : 'none';
-    if ($compression == 'gz') $outputfile.='.gz';
-    if ($compression == 'bz') $outputfile.='.bz2';
-    $outputerror = $outputfile.'.err';
-    dol_mkdir($conf->admin->dir_output.'/backup');
-
-    // Parameteres execution
-    $command=$cmddump;
-    if (preg_match("/\s/",$command)) $command=escapeshellarg($command);	// Use quotes on command
-
-    //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass);
-    $param=$dolibarr_main_db_name." -h ".$dolibarr_main_db_host;
-    $param.=" -u ".$dolibarr_main_db_user;
-    if (! empty($dolibarr_main_db_port)) $param.=" -P ".$dolibarr_main_db_port;
-    if (! GETPOST("use_transaction"))    $param.=" -l --single-transaction";
-    if (GETPOST("disable_fk"))           $param.=" -K";
-    if (GETPOST("sql_compat") && GETPOST("sql_compat") != 'NONE') $param.=" --compatible=".escapeshellarg(GETPOST("sql_compat","alpha"));
-    if (GETPOST("drop_database"))        $param.=" --add-drop-database";
-    if (GETPOST("sql_structure"))
-    {
-        if (GETPOST("drop"))			$param.=" --add-drop-table=TRUE";
-        else 							$param.=" --add-drop-table=FALSE";
-    }
-    else
-    {
-        $param.=" -t";
-    }
-    if (GETPOST("disable-add-locks")) $param.=" --add-locks=FALSE";
-    if (GETPOST("sql_data"))
-    {
-        $param.=" --tables";
-        if (GETPOST("showcolumns"))	 $param.=" -c";
-        if (GETPOST("extended_ins")) $param.=" -e";
-        else $param.=" --skip-extended-insert";
-        if (GETPOST("delayed"))	 	 $param.=" --delayed-insert";
-        if (GETPOST("sql_ignore"))	 $param.=" --insert-ignore";
-        if (GETPOST("hexforbinary")) $param.=" --hex-blob";
-    }
-    else
-    {
-        $param.=" -d";    // No row information (no data)
-    }
-    $param.=" --default-character-set=utf8";    // We always save output into utf8 charset
-    $paramcrypted=$param;
-    $paramclear=$param;
-    if (! empty($dolibarr_main_db_pass))
-    {
-        $paramcrypted.=' -p"'.preg_replace('/./i','*',$dolibarr_main_db_pass).'"';
-        $paramclear.=' -p"'.str_replace(array('"','`'),array('\"','\`'),$dolibarr_main_db_pass).'"';
-    }
-
-    $_SESSION["commandbackuplastdone"]=$command." ".$paramcrypted;
-    $_SESSION["commandbackuptorun"]="";
-    /*
-    print '<b>'.$langs->trans("RunCommandSummary").':</b><br>'."\n";
-    print '<textarea rows="'.ROWS_2.'" cols="120">'.$command." ".$paramcrypted.'</textarea><br>'."\n";
-    print '<br>';
-
-    //print $paramclear;
-
-    // Now run command and show result
-    print '<b>'.$langs->trans("BackupResult").':</b> ';
-	*/
-
-    $errormsg='';
-
-    // Debut appel methode execution
-    $fullcommandcrypted=$command." ".$paramcrypted." 2>&1";
-    $fullcommandclear=$command." ".$paramclear." 2>&1";
-    if ($compression == 'none') $handle = fopen($outputfile, 'w');
-    if ($compression == 'gz')   $handle = gzopen($outputfile, 'w');
-    if ($compression == 'bz')   $handle = bzopen($outputfile, 'w');
-
-    if ($handle)
-    {
-        $ok=0;
-        dol_syslog("Run command ".$fullcommandcrypted);
-        $handlein = popen($fullcommandclear, 'r');
-        $i=0;
-        while (!feof($handlein))
-        {
-            $i++;   // output line number
-            $read = fgets($handlein);
-            if ($i == 1 && preg_match('/'.preg_quote('Warning: Using a password').'/i', $read)) continue;
-            fwrite($handle,$read);
-            if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1;
-            elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1;
-        }
-        pclose($handlein);
-
-        if ($compression == 'none') fclose($handle);
-        if ($compression == 'gz')   gzclose($handle);
-        if ($compression == 'bz')   bzclose($handle);
-
-        if (! empty($conf->global->MAIN_UMASK))
-        @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
-    }
-    else
-    {
-        $langs->load("errors");
-        dol_syslog("Failed to open file ".$outputfile,LOG_ERR);
-        $errormsg=$langs->trans("ErrorFailedToWriteInDir");
-    }
-
-    // Get errorstring
-    if ($compression == 'none') $handle = fopen($outputfile, 'r');
-    if ($compression == 'gz')   $handle = gzopen($outputfile, 'r');
-    if ($compression == 'bz')   $handle = bzopen($outputfile, 'r');
-    if ($handle)
-    {
-        // Get 2048 first chars of error message.
-        $errormsg = fgets($handle,2048);
-        // Close file
-        if ($compression == 'none') fclose($handle);
-        if ($compression == 'gz')   gzclose($handle);
-        if ($compression == 'bz')   bzclose($handle);
-        if ($ok && preg_match('/^-- MySql/i',$errormsg)) $errormsg='';	// Pas erreur
-        else
-        {
-            // Renommer fichier sortie en fichier erreur
-            //print "$outputfile -> $outputerror";
-            @dol_delete_file($outputerror,1);
-            @rename($outputfile,$outputerror);
-            // Si safe_mode on et command hors du parametre exec, on a un fichier out vide donc errormsg vide
-            if (! $errormsg)
-            {
-            	$langs->load("errors");
-            	$errormsg=$langs->trans("ErrorFailedToRunExternalCommand");
-            }
-        }
-    }
-    // Fin execution commande
+    $utils->dumpDatabase(GETPOST('compression','alpha'), $what, 0, $file);
+    
+    $errormsg=$utils->error;
+    $_SESSION["commandbackuplastdone"]=$utils->result['commandbackuplastdone'];
+    $_SESSION["commandbackuptorun"]=$utils->result['commandbackuptorun'];
 }
 
+// MYSQL NO BIN
 if ($what == 'mysqlnobin')
 {
-    $outputfile = $outputdir.'/'.$file;
-    $outputfiletemp = $outputfile.'-TMP.sql';
-    // for compression format, we add extension
-    $compression=GETPOST('compression') ? GETPOST('compression','alpha') : 'none';
-    if ($compression == 'gz') $outputfile.='.gz';
-    if ($compression == 'bz') $outputfile.='.bz2';
-    $outputerror = $outputfile.'.err';
-    dol_mkdir($conf->admin->dir_output.'/backup');
-
-    if ($compression == 'gz' or $compression == 'bz')
-    {
-        backup_tables($outputfiletemp);
-        dol_compress_file($outputfiletemp, $outputfile, $compression);
-        unlink($outputfiletemp);
-    }
-    else
-    {
-        backup_tables($outputfile);
-    }
+    $utils->dumpDatabase(GETPOST('compression','alpha'), $what, 0, $file);
 
-    $_SESSION["commandbackuplastdone"]="";
-    $_SESSION["commandbackuptorun"]="";
+    $errormsg=$utils->error;
+    $_SESSION["commandbackuplastdone"]=$utils->result['commandbackuplastdone'];
+    $_SESSION["commandbackuptorun"]=$utils->result['commandbackuptorun'];
 }
 
 // POSTGRESQL
@@ -291,65 +151,13 @@ if ($what == 'postgresql')
         dolibarr_set_const($db, 'SYSTEMTOOLS_POSTGRESQLDUMP', $cmddump,'chaine',0,'',$conf->entity);
     }
 
-    $outputfile = $outputdir.'/'.$file;
-    // for compression format, we add extension
-    $compression=GETPOST('compression') ? GETPOST('compression','alpha') : 'none';
-    if ($compression == 'gz') $outputfile.='.gz';
-    if ($compression == 'bz') $outputfile.='.bz2';
-    $outputerror = $outputfile.'.err';
-    dol_mkdir($conf->admin->dir_output.'/backup');
-
-    // Parameteres execution
-    $command=$cmddump;
-    if (preg_match("/\s/",$command)) $command=escapeshellarg($command);	// Use quotes on command
-
-    //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass);
-    //$param="-F c";
-    $param="-F p";
-    $param.=" --no-tablespaces --inserts -h ".$dolibarr_main_db_host;
-    $param.=" -U ".$dolibarr_main_db_user;
-    if (! empty($dolibarr_main_db_port)) $param.=" -p ".$dolibarr_main_db_port;
-    if (GETPOST("sql_compat") && GETPOST("sql_compat") == 'ANSI') $param.="  --disable-dollar-quoting";
-    if (GETPOST("drop_database"))        $param.=" -c -C";
-    if (GETPOST("sql_structure"))
-    {
-        if (GETPOST("drop"))			 $param.=" --add-drop-table";
-        if (! GETPOST("sql_data"))       $param.=" -s";
-    }
-    if (GETPOST("sql_data"))
-    {
-        if (! GETPOST("sql_structure"))	 $param.=" -a";
-        if (GETPOST("showcolumns"))	     $param.=" -c";
-    }
-    $param.=' -f "'.$outputfile.'"';
-    //if ($compression == 'none')
-    if ($compression == 'gz')   $param.=' -Z 9';
-    //if ($compression == 'bz')
-    $paramcrypted=$param;
-    $paramclear=$param;
-    /*if (! empty($dolibarr_main_db_pass))
-     {
-    $paramcrypted.=" -W".preg_replace('/./i','*',$dolibarr_main_db_pass);
-    $paramclear.=" -W".$dolibarr_main_db_pass;
-    }*/
-    $paramcrypted.=" -w ".$dolibarr_main_db_name;
-    $paramclear.=" -w ".$dolibarr_main_db_name;
-
-    $_SESSION["commandbackuplastdone"]="";
-    $_SESSION["commandbackuptorun"]=$command." ".$paramcrypted;
-    /*print $langs->trans("RunCommandSummaryToLaunch").':<br>'."\n";
-    print '<textarea rows="'.ROWS_3.'" cols="120">'.$command." ".$paramcrypted.'</textarea><br>'."\n";
-
-    print '<br>';
-
-
-    // Now show to ask to run command
-    print $langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser",$dolibarr_main_db_user,$dolibarr_main_db_user);
-
-    print '<br>';
-    print '<br>';*/
-
-    $what='';
+    $utils->dumpDatabase(GETPOST('compression','alpha'), $what, 0, $file);
+    
+    $errormsg=$utils->error;
+    $_SESSION["commandbackuplastdone"]=$utils->result['commandbackuplastdone'];
+    $_SESSION["commandbackuptorun"]=$utils->result['commandbackuptorun'];
+
+    $what='';   // Clear to show message to run command
 }
 
 

+ 1 - 1
htdocs/admin/tools/index.php

@@ -40,7 +40,7 @@ $form = new Form($db);
 $title=$langs->trans("SystemToolsArea");
 if (GETPOST('leftmenu') == 'admintools') $title=$langs->trans("ModulesSystemTools");
 
-llxHeader(array(),$title);
+llxHeader('', $title);
 
 print load_fiche_titre($title,'','title_setup');
 

+ 35 - 21
htdocs/admin/tools/listevents.php

@@ -61,11 +61,13 @@ $search_user = GETPOST("search_user");
 $search_desc = GETPOST("search_desc");
 $search_ua   = GETPOST("search_ua");
 
-$date_start=dol_mktime(0,0,0,$_REQUEST["date_startmonth"],$_REQUEST["date_startday"],$_REQUEST["date_startyear"]);
-$date_end=dol_mktime(23,59,59,$_REQUEST["date_endmonth"],$_REQUEST["date_endday"],$_REQUEST["date_endyear"]);
+if (!isset($_REQUEST["date_startmonth"]) || $_REQUEST["date_startmonth"] > 0) $date_start=dol_mktime(0,0,0,$_REQUEST["date_startmonth"],$_REQUEST["date_startday"],$_REQUEST["date_startyear"]);
+else $date_start=-1;
+if (!isset($_REQUEST["date_endmonth"]) || $_REQUEST["date_endmonth"] > 0) $date_end=dol_mktime(23,59,59,$_REQUEST["date_endmonth"],$_REQUEST["date_endday"],$_REQUEST["date_endyear"]);
+else $date_end=-1;
 
 // checks:if date_start>date_end  then date_end=date_start + 24 hours
-if ($date_start > $date_end) $date_end=$date_start+86400;
+if ($date_start > 0 && $date_end > 0 && $date_start > $date_end) $date_end=$date_start+86400;
 
 $now = dol_now();
 $nowarray = dol_getdate($now);
@@ -94,6 +96,18 @@ if (empty($date_end))
 
 $now=dol_now();
 
+// Purge search criteria
+if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers
+{
+    $date_start=-1;
+    $date_end=-1;
+    $search_code='';
+    $search_ip='';
+    $search_user='';
+    $search_desc='';
+    $search_ua='';
+}
+
 // Purge audit events
 if ($action == 'confirm_purge' && $confirm == 'yes' && $user->admin)
 {
@@ -152,12 +166,13 @@ $sql.= " u.login";
 $sql.= " FROM ".MAIN_DB_PREFIX."events as e";
 $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = e.fk_user";
 $sql.= " WHERE e.entity IN (".getEntity('actioncomm', 1).")";
-$sql.= " AND e.dateevent >= '".$db->idate($date_start)."' AND e.dateevent <= '".$db->idate($date_end)."'";
-if ($search_code) { $usefilter++; $sql.=" AND e.type LIKE '%".$db->escape($search_code)."%'"; }
-if ($search_ip)   { $usefilter++; $sql.=" AND e.ip LIKE '%".$db->escape($search_ip)."%'"; }
-if ($search_user) { $usefilter++; $sql.=" AND u.login LIKE '%".$db->escape($search_user)."%'"; }
-if ($search_desc) { $usefilter++; $sql.=" AND e.description LIKE '%".$db->escape($search_desc)."%'"; }
-if ($search_ua)   { $usefilter++; $sql.=" AND e.user_agent LIKE '%".$db->escape($search_ua)."%'"; }
+if ($date_start > 0) $sql.= " AND e.dateevent >= '".$db->idate($date_start)."'";
+if ($date_end > 0)   $sql.= " AND e.dateevent <= '".$db->idate($date_end)."'";
+if ($search_code) { $usefilter++; $sql.=natural_search("e.type", $search_code, 0); }
+if ($search_ip)   { $usefilter++; $sql.=natural_search("e.ip", $search_ip, 0); }
+if ($search_user) { $usefilter++; $sql.=natural_search("u.login", $search_user, 0); }
+if ($search_desc) { $usefilter++; $sql.=natural_search("e.description", $search_desc, 0); }
+if ($search_ua)   { $usefilter++; $sql.=natural_search("e.user_agent", $search_ua, 0); }
 $sql.= $db->order($sortfield,$sortorder);
 $sql.= $db->plimit($conf->liste_limit+1, $offset);
 //print $sql;
@@ -169,13 +184,18 @@ if ($result)
 
 	$param='';
 	if ($search_code) $param.='&search_code='.$search_code;
-	if ($search_ip) $param.='&search_ip='.$search_ip;
+	if ($search_ip)   $param.='&search_ip='.$search_ip;
 	if ($search_user) $param.='&search_user='.$search_user;
 	if ($search_desc) $param.='&search_desc='.$search_desc;
-	if ($search_ua) $param.='&search_ua='.$search_ua;
+	if ($search_ua)   $param.='&search_ua='.$search_ua;
 
-        $langs->load('withdrawals');
-	print_barre_liste($langs->trans("ListOfSecurityEvents").' : '.$num.' '.strtolower($langs->trans("Lines")), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, 0, 'setup');
+    $langs->load('withdrawals');
+    if ($num)
+    {
+        $center='<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=purge">'.$langs->trans("Purge").'</a>';
+    }
+    
+	print_barre_liste($langs->trans("ListOfSecurityEvents").' ('.$num.')', $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $center, $num, 0, 'setup');
 
 	if ($action == 'purge')
 	{
@@ -218,7 +238,8 @@ if ($result)
 	print '</td>';
 
 	print '<td align="right" class="liste_titre">';
-	print '<input type="image" class="liste_titre" src="'.img_picto($langs->trans("Search"),'search.png','','',1).'" name="button_search" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
+	$searchpitco=$form->showFilterAndCheckAddButtons(0);
+	print $searchpitco;
 	print '</td>';
 
 	print "</tr>\n";
@@ -284,13 +305,6 @@ if ($result)
 	}
 	print "</table></form>";
 	$db->free($result);
-
-	if ($num)
-	{
-		print '<div class="tabsAction">';
-		print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=purge">'.$langs->trans("Purge").'</a>';
-		print '</div>';
-	}
 }
 else
 {

+ 2 - 2
htdocs/admin/tools/update.php

@@ -40,8 +40,8 @@ if (GETPOST('msg','alpha')) {
 
 
 $urldolibarr='http://www.dolibarr.org/downloads/';
-$urldolibarrmodules='http://www.dolistore.com/';
-$urldolibarrthemes='http://www.dolistore.com/';
+$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);

+ 9 - 3
htdocs/admin/translation.php

@@ -23,6 +23,7 @@
 
 require '../main.inc.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
 
 $langs->load("companies");
 $langs->load("products");
@@ -107,6 +108,8 @@ if ($action == 'delete')
  * View
  */
 
+$formadmin = new FormAdmin($db);
+
 $wikihelp='EN:Setup|FR:Paramétrage|ES:Configuración';
 llxHeader('',$langs->trans("Setup"),$wikihelp);
 
@@ -118,7 +121,7 @@ print "<br>\n";
 print $langs->trans("CurrentUserLanguage").': <strong>'.$langs->defaultlang.'</strong><br>';
 print '<br>';
 
-print img_warning().' '.$langs->trans("SomeTranslationAreUncomplete").'<br>';
+print img_info().' '.$langs->trans("SomeTranslationAreUncomplete").'<br>';
 $urlwikitranslatordoc='http://wiki.dolibarr.org/index.php/Translator_documentation';
 print $langs->trans("SeeAlso").': <a href="'.$urlwikitranslatordoc.'" target="_blank">'.$urlwikitranslatordoc.'</a><br>';
 
@@ -134,7 +137,7 @@ print '<input type="hidden" id="action" name="action" value="">';
 
 print '<table class="noborder" width="100%">';
 print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("Language").'</td>';
+print '<td>'.$langs->trans("Language").' (en_US, es_MX, ...)</td>';
 print '<td>'.$langs->trans("Key").'</td>';
 print '<td>'.$langs->trans("Value").'</td>';
 if (! empty($conf->multicompany->enabled) && !$user->entity) print '<td>'.$langs->trans("Entity").'</td>';
@@ -146,7 +149,10 @@ print "</tr>\n";
 $var=false;
 print "\n";
 
-print '<tr '.$bc[$var].'><td><input type="text" class="flat" size="24" name="langcode" value="'.GETPOST('langcode').'"></td>'."\n";
+print '<tr '.$bc[$var].'><td>';
+print $formadmin->select_language(GETPOST('langcode'),'langcode',0,null,1,0,0,'',1);
+//print '<input type="text" class="flat" size="24" name="langcode" value="'.GETPOST('langcode').'">';
+print '</td>'."\n";
 print '<td>';
 print '<input type="text" class="flat" size="30" name="transkey" value="">';
 print '</td><td>';

+ 5 - 5
htdocs/admin/websites.php

@@ -75,23 +75,23 @@ $tablib[1] = "Websites";
 
 // Requests to extract data
 $tabsql=array();
-$tabsql[1] = "SELECT f.rowid as rowid, f.entity, f.shortname, f.description, f.status FROM ".MAIN_DB_PREFIX."website as f";
+$tabsql[1] = "SELECT f.rowid as rowid, f.entity, f.ref, f.description, f.status FROM ".MAIN_DB_PREFIX."website as f";
 
 // Criteria to sort dictionaries
 $tabsqlsort=array();
-$tabsqlsort[1] ="shortname ASC";
+$tabsqlsort[1] ="ref ASC";
 
 // Nom des champs en resultat de select pour affichage du dictionnaire
 $tabfield=array();
-$tabfield[1] = "shortname,description";
+$tabfield[1] = "ref,description";
 
 // Nom des champs d'edition pour modification d'un enregistrement
 $tabfieldvalue=array();
-$tabfieldvalue[1] = "shortname,description";
+$tabfieldvalue[1] = "ref,description";
 
 // Nom des champs dans la table pour insertion d'un enregistrement
 $tabfieldinsert=array();
-$tabfieldinsert[1] = "shortname,description,entity";
+$tabfieldinsert[1] = "ref,description,entity";
 
 // Nom du rowid si le champ n'est pas de type autoincrement
 // Example: "" if id field is "rowid" and has autoincrement on

+ 19 - 1
htdocs/api/admin/explorer.php

@@ -150,12 +150,30 @@ $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToM
 print load_fiche_titre($langs->trans("ApiSetup"),$linkback,'title_setup');
 
 
+// Define $urlwithroot
+$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
+$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;		// This is to use external domain name found into config file
+//$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
+
+// Show message
+print '<br>';
+$message='';
+$url='<a href="'.$urlwithroot.'/api/index.php/login?login='.urlencode($user->login).'&password=yourpassword" target="_blank">'.$urlwithroot.'/api/index.php/login?login='.urlencode($user->login).'&password=yourpassword</a>';
+$message.=$langs->trans("UrlToGetKeyToUseAPIs").':<br>';
+$message.=img_picto('','object_globe.png').' '.$url;
+print $message;
+print '<br>';
+print '<br>';
+
+print $langs->trans("ListOfAvailableAPIs").':<br>';
 foreach($listofapis['v1'] as $key => $val)
 {
+    if ($key == 'login') continue;
     if ($key)
     {
         //print $key.' - '.$val['classname'].' - '.$val['fullpath']." - ".DOL_MAIN_URL_ROOT.'/api/index.php/'.strtolower(preg_replace('/Api$/','',$val['classname']))."/xxx<br>\n";
-        $url=DOL_MAIN_URL_ROOT.'/api/index.php/'.$key;
+        $url=$urlwithroot.'/api/index.php/'.$key;
+        $url.='?api_key=token';
         print img_picto('','object_globe.png').' <a href="'.$url.'" target="_blank">'.$url."</a><br>\n";
         
     }

+ 5 - 5
htdocs/api/class/api_access.class.php

@@ -116,13 +116,13 @@ class DolibarrApiAccess implements iAuthenticate
 		else
 		{
 		    throw new RestException(401, "Failed to login to API. No parameter 'api_key' provided");
-		    //dol_syslog("Failed to login to API. No parameter key provided", LOG_DEBUG);
-			//return false;
 		}
 
-        $userClass::setCacheIdentifier(static::$role);
-        Resources::$accessControlFunction = 'DolibarrApiAccess::verifyAccess';
-        return in_array(static::$role, (array) static::$requires) || static::$role == 'admin';
+    $userClass::setCacheIdentifier(static::$role);
+    Resources::$accessControlFunction = 'DolibarrApiAccess::verifyAccess';
+    $requirefortest = static::$requires;
+    if (! is_array($requirefortest)) $requirefortest=explode(',',$requirefortest);
+    return in_array(static::$role, (array) $requirefortest) || static::$role == 'admin';
 	}
 
 	/**

+ 2 - 0
htdocs/api/index.php

@@ -141,6 +141,8 @@ foreach ($modulesdir as $dir)
 
 // TODO If not found, redirect to explorer
 
+
+// Call API (we suppose we found it)
 $api->r->handle();
 
 

+ 2 - 2
htdocs/barcode/printsheet.php

@@ -62,7 +62,7 @@ if (GETPOST('submitproduct') && GETPOST('submitproduct'))
 	{
 		$producttmp->fetch(GETPOST('productid'));
 		$forbarcode=$producttmp->barcode;
-		$fk_barcode_type=$thirdpartytmp->barcode_type_code;
+		$fk_barcode_type=$producttmp->barcode_type;
 
 		if (empty($fk_barcode_type) && ! empty($conf->global->PRODUIT_DEFAULT_BARCODE_TYPE)) $fk_barcode_type = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE;
 
@@ -384,7 +384,7 @@ print '</div>';
 print '<input id="fillfromthirdparty" type="radio" '.((GETPOST("selectorforbarcode")=='fillfromthirdparty')?'checked ':'').'name="selectorforbarcode" value="fillfromthirdparty" class="radiobarcodeselect"> '.$langs->trans("FillBarCodeTypeAndValueFromThirdParty").' &nbsp; ';
 print '<br>';
 print '<div class="showforthirdpartyselector">';
-print $form->select_company(GETPOST('socid'), 'socid', '', 1, 0, 0, array(), 0, 'minwidth300');
+print $form->select_company(GETPOST('socid'), 'socid', '', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300');
 print ' &nbsp; <input type="submit" id="submitthirdparty" name="submitthirdparty" class="button showforthirdpartyselector" value="'.(dol_escape_htmltag($langs->trans("GetBarCode"))).'">';
 print '</div>';
 

+ 1 - 1
htdocs/cashdesk/affContenu.php

@@ -59,7 +59,7 @@ exit;*/
 print '<div class="inline-block" style="vertical-align: top">';
 print '<div class="principal">';
 
-$page=GETPOST('menu','alpha');
+$page=GETPOST('menutpl','alpha');
 if (empty($page)) $page='facturation';
 
 if (in_array(

+ 1 - 3
htdocs/cashdesk/affIndex.php

@@ -42,7 +42,7 @@ $langs->load("cashdesk");
  */
 
 //header("Content-type: text/html; charset=UTF-8");
-header("Content-type: text/html; charset=".$conf->file->character_set_client);
+//header("Content-type: text/html; charset=".$conf->file->character_set_client);
 
 $arrayofjs=array();
 $arrayofcss=array('/cashdesk/css/style.css');
@@ -62,8 +62,6 @@ print '<div class="conteneur">'."\n";
 print '<div class="conteneur_img_gauche">'."\n";
 print '<div class="conteneur_img_droite">'."\n";
 
-print '<h1 class="entete"><span>POINT OF SALE</span></h1>'."\n";
-
 print '<div class="menu_principal">'."\n";
 include_once 'tpl/menu.tpl.php';
 print '</div>'."\n";

+ 25 - 25
htdocs/cashdesk/class/Facturation.class.php

@@ -99,31 +99,24 @@ class Facturation
         $product = new Product($db);
         $product->fetch($this->id);
 
-        $sql = "SELECT taux";
-        $sql.= " FROM ".MAIN_DB_PREFIX."c_tva";
-        $sql.= " WHERE rowid = ".$this->tva();
-
-        dol_syslog("ajoutArticle", LOG_DEBUG);
-        $resql = $db->query($sql);
-
-        if ($resql)
-        {
-            $obj = $db->fetch_object($resql);
-            $vat_rate=$obj->taux;
-            //var_dump($vat_rate);exit;
-        }
-        else
-       {
-            dol_print_error($db);
-        }
-
+        
+        $vatrowid = $this->tva();
+        
+        $tmp = getTaxesFromId($vatrowid);
+        $vat_rate = $tmp['rate'];
+        $vat_npr = $tmp['npr'];
+        
+        $localtaxarray = getLocalTaxesFromRate($vatrowid, 0, $societe, $mysoc, 1);
+        
         // Define part of HT, VAT, TTC
-        $resultarray=calcul_price_total($this->qte,$this->prix(),$this->remisePercent(),$vat_rate,0,0,0,'HT',0,$product->type,$mysoc);
+        $resultarray=calcul_price_total($this->qte, $this->prix(), $this->remisePercent(), $vat_rate, -1, -1, 0, 'HT', $use_npr, $product->type, $mysoc, $localtaxarray);
 
         // Calcul du total ht sans remise
         $total_ht = $resultarray[0];
         $total_vat = $resultarray[1];
         $total_ttc = $resultarray[2];
+        $total_localtax1 = $resultarray[9];
+        $total_localtax2 = $resultarray[10];
 
         // Calcul du montant de la remise
         if ($this->remisePercent())
@@ -143,7 +136,7 @@ class Facturation
         $newcartarray[$i]['label']=$product->label;
         $newcartarray[$i]['price']=$product->price;
         $newcartarray[$i]['price_ttc']=$product->price_ttc;
-
+        
         if (! empty($conf->global->PRODUIT_MULTIPRICES))
         {
             if (isset($product->multiprices[$societe->price_level]))
@@ -160,6 +153,9 @@ class Facturation
         $newcartarray[$i]['remise']=price2num($montant_remise_ht);
         $newcartarray[$i]['total_ht']=price2num($total_ht,'MT');
         $newcartarray[$i]['total_ttc']=price2num($total_ttc,'MT');
+        $newcartarray[$i]['total_vat']=price2num($total_vat, 'MT');
+        $newcartarray[$i]['total_localtax1']=price2num($total_localtax1, 'MT');
+        $newcartarray[$i]['total_localtax2']=price2num($total_localtax2, 'MT');
         $_SESSION['poscart']=$newcartarray;
 
         $this->raz();
@@ -213,12 +209,18 @@ class Facturation
             // Total HT
             $remise = $tab[$i]['remise'];
             $total_ht += ($tab[$i]['total_ht']);
+            $total_vat += ($tab[$i]['total_vat']);
             $total_ttc += ($tab[$i]['total_ttc']);
+            $total_localtax1 += ($tab[$i]['total_localtax1']);
+            $total_localtax2 += ($tab[$i]['total_localtax2']);
         }
 
         $this->prix_total_ttc = $total_ttc;
         $this->prix_total_ht = $total_ht;
-
+        $this->prix_total_vat = $total_vat;
+        $this->prix_total_localtax1 = $total_localtax1;
+        $this->prix_total_localtax2 = $total_localtax2;
+        
         $this->montant_tva = $total_ttc - $total_ht;
         //print $this->prix_total_ttc.'eeee'; exit;
     }
@@ -442,9 +444,8 @@ class Facturation
      * @param	int		$aTva		Vat
      * @return	int					Vat
      */
-    public function tva ( $aTva=null )
+    public function tva($aTva=null)
     {
-
         if ( !$aTva ) {
 
             return $this->tva;
@@ -467,9 +468,8 @@ class Facturation
      * @param string	$aNumFacture		Invoice ref
      * @return	string						Invoice ref
      */
-    public function numInvoice( $aNumFacture=null )
+    public function numInvoice($aNumFacture=null)
     {
-
         if ( !$aNumFacture ) {
 
             return $this->num_facture;

+ 11 - 31
htdocs/cashdesk/css/style.css

@@ -20,7 +20,6 @@ body {
 	margin: 0;
 	padding: 0;
 	text-align: center;
-	font: 0.7em verdana, arial, helvetica;
 }
 
 p {
@@ -46,6 +45,15 @@ p {
 .contenu {
 	width: 100%;
 	text-align: center;
+	padding-top: 20px;
+}
+
+.logo {
+    text-align: center;
+}
+.logopos {
+	padding-top: 20px;
+	max-height: 40px;	
 }
 
 /* ------------------- Header ------------------- */
@@ -61,7 +69,7 @@ p {
 
 /* ------------------- Menu ------------------- */
 .menu_principal {
-    margin: 0 20px 20px 15px;
+    margin: 0;
     font-size: 14px;
 	height: 84px;
 	background: #CCCCCC;
@@ -80,7 +88,7 @@ p {
 .menu {
 	margin: 0;
     list-style-type: none;
-    padding: 10px 0 0;
+    padding: 8px 0 0;
 }
 
 .menu li {
@@ -88,34 +96,6 @@ p {
 	padding-right: 10px;
 }
 
-.menu_choix1,.menu_choix2 {
-	font-size: 1.4em;
-	text-align: left;
-}
-
-.menu_choix1 a,.menu_choix2 a {
-	display: block;
-	color: #fff;
-	text-decoration: none;
-	padding-top: 18px;
-	padding-left: 54px;
-	font-size: 14px;
-	height: 48px;
-	background: url('../img/new.png') top left no-repeat;
-}
-
-.menu_choix1 a {
-	background: url('../img/new.png') top left no-repeat;
-}
-
-.menu_choix2 a {
-	background: url('../img/gescom.png') top left no-repeat;
-}
-
-.menu_choix1 a:hover,.menu_choix2 a:hover {
-	color: #6d3f6d;
-}
-
 .menu_choix0 {
 	font-size: 10px;
 	text-align: right;

+ 52 - 27
htdocs/cashdesk/facturation_verif.php

@@ -37,7 +37,7 @@ switch ( $_GET['action'] )
 	default:
 		if ( $_POST['hdnSource'] != 'NULL' )
 		{
-			$sql = "SELECT p.rowid, p.ref, p.price, p.tva_tx";
+			$sql = "SELECT p.rowid, p.ref, p.price, p.tva_tx, p.recuperableonly";
 			if (! empty($conf->stock->enabled) && !empty($conf_fkentrepot)) $sql.= ", ps.reel";
 			$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
 			if (! empty($conf->stock->enabled) && !empty($conf_fkentrepot)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps ON p.rowid = ps.fk_product AND ps.fk_entrepot = ".$conf_fkentrepot;
@@ -66,19 +66,23 @@ switch ( $_GET['action'] )
 					{
 						$ret[$key] = $value;
 					}
-
-					/** add Ditto for MultiPrix*/
-					if (! empty($conf->global->PRODUIT_MULTIPRICES))
+                    // Here $ret['tva_tx'] is vat rate of product but we want to not use the one into table but found by function
+                    
+					$productid = $ret['rowid'];
+					$product = new Product($db);
+                    $product->fetch($productid);
+
+					$thirdpartyid = $_SESSION['CASHDESK_ID_THIRDPARTY'];
+                    $societe = new Societe($db);
+					$societe->fetch($thirdpartyid);
+
+					$tva_tx = get_default_tva($mysoc,$societe,$productid);
+					$tva_npr = get_default_npr($mysoc,$societe,$productid);
+					if (empty($tva_tx)) $tva_npr=0;
+					dol_syslog('tva_tx='.$tva_tx.'-tva_npr='.$tva_npr);
+					
+					if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($societe->price_level))
 					{
-						$thirdpartyid = $_SESSION['CASHDESK_ID_THIRDPARTY'];
-						$productid = $ret['rowid'];
-
-						$societe = new Societe($db);
-						$societe->fetch($thirdpartyid);
-
-						$product = new Product($db);
-                        $product->fetch($productid);
-
 						if(isset($product->multiprices[$societe->price_level]))
 						{
 							$ret['price'] = $product->multiprices[$societe->price_level];
@@ -86,16 +90,39 @@ switch ( $_GET['action'] )
 							// $product->multiprices_min[$societe->price_level];
 							// $product->multiprices_min_ttc[$societe->price_level];
 							// $product->multiprices_base_type[$societe->price_level];
-							$ret['tva_tx'] = $product->multiprices_tva_tx[$societe->price_level];
+							if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL))  // using this option is a bug. kept for backward compatibility
+							{
+							    if (isset($prod->multiprices_tva_tx[$societe->price_level])) $tva_tx=$prod->multiprices_tva_tx[$societe->price_level];
+							    if (isset($prod->multiprices_recuperableonly[$societe->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$societe->price_level];
+							    if (empty($tva_tx)) $tva_npr=0;
+							}
 						}
 					}
-					/** end add Ditto */
 
+					$ret['tva_tx'] = $tva_tx;
+					$ret['tva_npr'] = $tva_npr;
+                    //var_dump('tva_tx='.$ret['tva_tx'].'-tva_npr='.$ret['tva_npr'].'-'.$conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL);exit;
+                    
 					$obj_facturation->id($ret['rowid']);
 					$obj_facturation->ref($ret['ref']);
 					$obj_facturation->stock($ret['reel']);
 					$obj_facturation->prix($ret['price']);
-					$obj_facturation->tva($ret['tva_tx']);
+					
+					// Use $ret['tva_tx'] / ret['tva_npr'] to find vat id
+					$vatrowid = null;
+					$sqlfindvatid = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'c_tva';
+					$sqlfindvatid.= ' WHERE taux = '.$ret['tva_tx'].' AND recuperableonly = '.(int) $ret['tva_npr'];
+					$sqlfindvatid.= ' AND fk_pays = '.$mysoc->country_id;
+					$resqlfindvatid=$db->query($sqlfindvatid);
+					if ($resqlfindvatid)
+					{
+					    $obj = $db->fetch_object($resqlfindvatid);
+					    if ($obj) $vatrowid = $obj->rowid;
+					}
+					else dol_print_error($db);
+					
+					dol_syslog("save vatrowid=".$vatrowid);
+					$obj_facturation->tva($vatrowid);     // Save vat it for next use
 
 					// Definition du filtre pour n'afficher que le produit concerne
 					if ( $_POST['hdnSource'] == 'LISTE' )
@@ -107,7 +134,7 @@ switch ( $_GET['action'] )
 						$filtre = $_POST['txtRef'];
 					}
 
-					$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menu=facturation&filtre='.$filtre;
+					$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menutpl=facturation&filtre='.$filtre;
 				}
 				else
 				{
@@ -115,11 +142,11 @@ switch ( $_GET['action'] )
 
 					if ( $_POST['hdnSource'] == 'REF' )
 					{
-						$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menu=facturation&filtre='.$_POST['txtRef'];
+						$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menutpl=facturation&filtre='.$_POST['txtRef'];
 					}
 					else
 					{
-						$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menu=facturation';
+						$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menutpl=facturation';
 					}
 				}
 			}
@@ -130,40 +157,38 @@ switch ( $_GET['action'] )
 		}
 		else
 		{
-			$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menu=facturation';
+			$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menutpl=facturation';
 		}
 
 		break;
 
 	case 'ajout_article':	// We have clicked on button "Add product"
 
-		//var_dump('ajout_article');
-		//exit;
-
 		if (! empty($obj_facturation->id))	// A product was previously selected and stored in session, so we can add it
 		{
+		    dol_syslog("facturation_verif save vat ".$_POST['selTva']);
 			$obj_facturation->qte($_POST['txtQte']);
-			$obj_facturation->tva($_POST['selTva']);
+			$obj_facturation->tva($_POST['selTva']);                 // Save VAT selected so we can use it for next product
 			$obj_facturation->remisePercent($_POST['txtRemise']);
 			$obj_facturation->ajoutArticle();	// This add an entry into $_SESSION['poscart']
 			// We update prixTotalTtc
 			 
 		}
 
-		$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menu=facturation';
+		$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menutpl=facturation';
 		break;
 
 	case 'suppr_article':
 		$obj_facturation->supprArticle($_GET['suppr_id']);
 
-		$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menu=facturation';
+		$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menutpl=facturation';
 		break;
 
 }
 
 // We saved object obj_facturation
 $_SESSION['serObjFacturation'] = serialize($obj_facturation);
-
+//var_dump($_SESSION['serObjFacturation']);
 header('Location: '.$redirection);
 exit;
 

+ 1 - 2
htdocs/cashdesk/index.php

@@ -58,9 +58,8 @@ top_htmlhead('','',0,0,'',$arrayofcss);
 <div class="conteneur_img_gauche">
 <div class="conteneur_img_droite">
 
-<h1 class="entete"></h1>
-
 <div class="menu_principal hideonsmartphone">
+<div class="logo"><?php print '<img class="logopos" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=companylogo&amp;file='.urlencode('/thumbs/'.$mysoc->logo_small).'">'; ?></div>
 </div>
 
 <div class="contenu">

+ 1 - 1
htdocs/cashdesk/index_verif.php

@@ -125,7 +125,7 @@ if ( $retour >= 0 )
         $_SESSION['CASHDESK_ID_BANKACCOUNT_CB'] = ($bankid_cb > 0 ? $bankid_cb : '');
         //var_dump($_SESSION);exit;
 
-		header('Location: '.DOL_URL_ROOT.'/cashdesk/affIndex.php?menu=facturation&id=NOUV');
+		header('Location: '.DOL_URL_ROOT.'/cashdesk/affIndex.php?menutpl=facturation&id=NOUV');
 		exit;
 	}
 	else

+ 8 - 7
htdocs/cashdesk/tpl/facturation1.tpl.php

@@ -119,7 +119,7 @@ $langs->load("cashdesk");
 				<td></td>
     			<!-- Choix de la remise -->
     			<td><input class="texte1" type="text" id="txtRemise" name="txtRemise" value="0" onkeyup="javascript: modif();" onfocus="javascript: this.select();"/>
-<?php print genkeypad("txtRemise", "frmQte");?>
+					<?php print genkeypad("txtRemise", "frmQte");?>
     			</td>
     			<!-- Affichage du total HT -->
     			<td><input class="texte1_off" type="text" name="txtTotal" value="" disabled /></td><td></td>
@@ -128,16 +128,17 @@ $langs->load("cashdesk");
                 <?php //var_dump($tab_tva); ?>
                 <select name="selTva" onchange="javascript: modif();" >
                     <?php
-                        $tva_tx = $obj_facturation->tva();
-                        $tab_tva_size=count($tab_tva);
-                        for($i=0;$i < $tab_tva_size;$i++) {
+                        $tva_tx = $obj_facturation->tva();  // Try to get a previously entered VAT rowid. First time, this will return empty.
 
-                            if ( $tva_tx == $tab_tva[$i]['taux'] )
+                        $tab_tva_size=count($tab_tva);      // $tab_tva contains list of possible vat array('rowid'=> , 'taux'=> ) 
+                        for ($i=0;$i < $tab_tva_size;$i++) 
+                        {
+                            if ($tva_tx == $tab_tva[$i]['rowid'])
                                 $selected = 'selected';
                             else
-                            $selected = '';
+                                $selected = '';
 
-                            echo ('<option '.$selected.' value="'.$tab_tva[$i]['rowid'].'">'.$tab_tva[$i]['taux'].'</option>'."\n               ");
+                            echo '<option '.$selected.' value="'.$tab_tva[$i]['rowid'].'">'.$tab_tva[$i]['taux'].'</option>'."\n               ";
                         }
                     ?>
                 </select>

+ 1 - 1
htdocs/cashdesk/tpl/menu.tpl.php

@@ -62,7 +62,7 @@ $langs->load("main");
 print '<div class="menu_bloc">';
 print '<ul class="menu">';
 // Link to new sell
-print '<li class="menu_choix1"><a href="affIndex.php?menu=facturation&id=NOUV"><span>'.$langs->trans("NewSell").'</span></a></li>';
+print '<li class="menu_choix1"><a href="affIndex.php?menutpl=facturation&id=NOUV"><span>'.$langs->trans("NewSell").'</span></a></li>';
 // Open new tab on backoffice (this is not a disconnect from POS)
 print '<li class="menu_choix2"><a href=".." target="backoffice"><span>'.$langs->trans("BackOffice").'</span></a></li>';
 // Disconnect

+ 1 - 1
htdocs/cashdesk/tpl/validation1.tpl.php

@@ -113,7 +113,7 @@ $langs->load("bills");
 		<p class="note_label"><?php echo $langs->trans("Notes"); ?><br><textarea class="textarea_note" name="txtaNotes"></textarea></p>
 
 		<div class="center"><input class="button" type="submit" name="btnValider" value="<?php echo $langs->trans("ValidateInvoice"); ?>" /><br>
-		<br><a class="lien1" href="affIndex.php?menu=facturation"><?php echo $langs->trans("RestartSelling"); ?></a>
+		<br><a class="lien1" href="affIndex.php?menutpl=facturation"><?php echo $langs->trans("RestartSelling"); ?></a>
 		</div>
 	</form>
 

+ 19 - 34
htdocs/cashdesk/validation_verif.php

@@ -42,7 +42,7 @@ switch ($action)
 
 	default:
 
-		$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menu=validation';
+		$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menutpl=validation';
 		break;
 
 
@@ -85,13 +85,13 @@ switch ($action)
 			$obj_facturation->paiementLe($txtDatePaiement);
 		}
 
-		$redirection = 'affIndex.php?menu=validation';
+		$redirection = 'affIndex.php?menutpl=validation';
 		break;
 
 
 	case 'retour':
 
-		$redirection = 'affIndex.php?menu=facturation';
+		$redirection = 'affIndex.php?menutpl=facturation';
 		break;
 
 
@@ -158,45 +158,30 @@ switch ($action)
 		// Get content of cart
 		$tab_liste = $_SESSION['poscart'];
 
-		// Loop on each product
+		// Loop on each line into cart
 		$tab_liste_size=count($tab_liste);
-		for ($i=0;$i < $tab_liste_size;$i++)
+		for ($i=0; $i < $tab_liste_size; $i++)
 		{
-			// Recuperation de l'article
-			$product = new Product($db);
-			$product->fetch($tab_liste[$i]['fk_article']);
-			$ret=array('label'=>$product->label,'tva_tx'=>$product->tva_tx,'price'=>$product->price);
-
-	        if (! empty($conf->global->PRODUIT_MULTIPRICES))
-	        {
-	            if (isset($product->multiprices[$societe->price_level]))
-	            {
-	                $ret['price'] = $product->multiprices[$societe->price_level];
-	            }
-	        }
-			$tab_article = $ret;
-
-			$res = $db->query('SELECT taux FROM '.MAIN_DB_PREFIX.'c_tva WHERE rowid = '.$tab_liste[$i]['fk_tva']);
-			$ret=array();
-			$tab = $db->fetch_array($res);
-			foreach ( $tab as $cle => $valeur )
-			{
-				$ret[$cle] = $valeur;
-			}
-			$tab_tva = $ret;
+			$tmp = getTaxesFromId($tab_liste[$i]['fk_tva']);
+			$vat_rate = $tmp['rate'];
+			$vat_npr = $tmp['npr'];
 
 			$invoiceline=new FactureLigne($db);
 			$invoiceline->fk_product=$tab_liste[$i]['fk_article'];
-			$invoiceline->desc=$tab_article['label'];
-			$invoiceline->tva_tx=empty($tab_tva['taux'])?0:$tab_tva['taux'];	// works even if vat_rate is ''
-			//$invoiceline->tva_tx=$tab_tva['taux'];
+			$invoiceline->desc=$tab_liste[$i]['label'];
 			$invoiceline->qty=$tab_liste[$i]['qte'];
 			$invoiceline->remise_percent=$tab_liste[$i]['remise_percent'];
-			$invoiceline->price=$tab_article['price'];
-			$invoiceline->subprice=$tab_article['price'];
+			$invoiceline->price=$tab_liste[$i]['price'];
+			$invoiceline->subprice=$tab_liste[$i]['price'];
+			
+			$invoiceline->tva_tx=empty($vat_rate)?0:$vat_rate;	// works even if vat_rate is ''
+			$invoiceline->info_bits=empty($vat_npr)?0:$vat_npr;
+				
 			$invoiceline->total_ht=$tab_liste[$i]['total_ht'];
 			$invoiceline->total_ttc=$tab_liste[$i]['total_ttc'];
-			$invoiceline->total_tva=($tab_liste[$i]['total_ttc']-$tab_liste[$i]['total_ht']);
+			$invoiceline->total_tva=$tab_liste[$i]['total_vat'];
+			$invoiceline->total_localtax1=$tab_liste[$i]['total_localtax1'];
+			$invoiceline->total_localtax2=$tab_liste[$i]['total_localtax2'];
 			$invoice->lines[]=$invoiceline;
 		}
 
@@ -336,7 +321,7 @@ switch ($action)
 		if (! $error)
 		{
 			$db->commit();
-			$redirection = 'affIndex.php?menu=validation_ok&facid='.$id;	// Ajout de l'id de la facture, pour l'inclure dans un lien pointant directement vers celle-ci dans Dolibarr
+			$redirection = 'affIndex.php?menutpl=validation_ok&facid='.$id;	// Ajout de l'id de la facture, pour l'inclure dans un lien pointant directement vers celle-ci dans Dolibarr
 		}
 		else
 		{

+ 133 - 0
htdocs/categories/class/api_category.class.php

@@ -18,6 +18,7 @@
  use Luracast\Restler\RestException;
 
  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+ require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php';
 
 /**
  * API class for category object
@@ -143,6 +144,88 @@ class CategoryApi extends DolibarrApi
         $result = $db->query($sql);
         if ($result)
         {
+        	$i=0;
+            $num = $db->num_rows($result);
+            while ($i < $num)
+            {
+                $obj = $db->fetch_object($result);
+                $category_static = new Categorie($db);
+                if($category_static->fetch($obj->rowid)) {
+                    $obj_ret[] = parent::_cleanObjectDatas($category_static);
+                }
+                $i++;
+            }
+        }
+        else {
+            throw new RestException(503, 'Error when retrieve category list : '.$category_static->error);
+        }
+        if( ! count($obj_ret)) {
+            throw new RestException(404, 'No category found');
+        }
+		return $obj_ret;
+    }
+    /**
+     * List categories of an entity
+     * 
+     * Get a list of categories
+     *
+     * @param string	$type		Type of category ('member', 'customer', 'supplier', 'product', 'contact')
+     * @param string	$sortfield	Sort field
+     * @param string	$sortorder	Sort order
+     * @param int		$limit		Limit for list
+     * @param int		$page		Page number
+     * @param int		$item		Id of the item to get categories for
+     * @return array Array of category objects
+     *
+     * @url	GET /product/{item}/categories
+     */
+    function getListForItem($type='product', $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $item = 0) {
+        global $db, $conf;
+        
+        $obj_ret = array();
+        
+         if(! DolibarrApiAccess::$user->rights->categorie->lire) {
+			    throw new RestException(401);
+         }
+        //if ($type == "") {
+          //$type="product";
+        //}
+        $sub_type = $type;
+        $subcol_name = "fk_".$type;
+        if ($type=="customer" || $type=="supplier") {
+          $sub_type="societe";
+          $subcol_name="fk_soc";
+        }
+        $sql = "SELECT s.rowid";
+        $sql.= " FROM ".MAIN_DB_PREFIX."categorie as s";
+        $sql.= " , ".MAIN_DB_PREFIX."categorie_".$sub_type." as sub ";
+        $sql.= ' WHERE s.entity IN ('.getEntity('categorie', 1).')';
+        $sql.= ' AND s.type='.array_search($type,CategoryApi::$TYPES);
+        $sql.= ' AND s.rowid = sub.fk_categorie';
+        $sql.= ' AND sub.'.$subcol_name.' = '.$item;
+
+        $nbtotalofrecords = 0;
+        if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
+        {
+            $result = $db->query($sql);
+            $nbtotalofrecords = $db->num_rows($result);
+        }
+
+        $sql.= $db->order($sortfield, $sortorder);
+        if ($limit)	{
+            if ($page < 0)
+            {
+                $page = 0;
+            }
+            $offset = $limit * $page;
+
+            $sql.= $db->plimit($limit + 1, $offset);
+        }
+
+        $result = $db->query($sql);
+        if ($result)
+        {
+        	$i=0;
             $num = $db->num_rows($result);
             while ($i < $num)
             {
@@ -193,6 +276,56 @@ class CategoryApi extends DolibarrApi
     function getListCategoryCustomer($sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0) {
         return $this->getList('customer', $sortfield, $sortorder, $limit, $page);  
     }
+    /**
+     * Get categories for a customer
+     * 
+     * @param int		$cusid  Customer id filter
+     * @param string	$sortfield	Sort field
+     * @param string	$sortorder	Sort order
+     * @param int		$limit		Limit for list
+     * @param int		$page		Page number
+     * 
+     * @return mixed
+     * 
+     * @url GET /customer/{cusid}/categories
+     */
+    function getListCustomerCategories($cusid, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0) {
+        return $this->getListForItem('customer', $sortfield, $sortorder, $limit, $page, $cusid);  
+    }
+
+    /**
+     * Add category to customer
+     * 
+     * @param int		$cusid	Id of customer
+     * @param int		$catid  Id of category
+     * 
+     * @return mixed
+     * 
+     * @url GET /customer/{cusid}/addCategory/{catid}
+     */
+    function addCustomerCategory($cusid,$catid) {
+      if(! DolibarrApiAccess::$user->rights->societe->creer) {
+			  throw new RestException(401);
+      }
+      $customer = new Client($this->db);
+      $customer->fetch($cusid);
+      if( ! $customer ) {
+        throw new RestException(404, 'customer not found');
+      }
+      $result = $this->category->fetch($catid);
+      if( ! $result ) {
+        throw new RestException(404, 'category not found');
+      }
+      
+      if( ! DolibarrApi::_checkAccessToResource('societe',$customer->id)) {
+        throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+      }
+      if( ! DolibarrApi::_checkAccessToResource('category',$this->category->id)) {
+        throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+      }
+      $this->category->add_type($customer,'customer');
+      return $customer;
+    }
     
     /**
      * Get supplier categories list

+ 3 - 3
htdocs/categories/class/categorie.class.php

@@ -1451,8 +1451,8 @@ class Categorie extends CommonObject
 
 			if (file_exists($originImage))
 			{
-				// Cree fichier en taille vignette
-				$this->add_thumb($originImage);
+			    // Create thumbs
+				$this->addThumbs($originImage);
 			}
 		}
 	}
@@ -1478,7 +1478,7 @@ class Categorie extends CommonObject
 			$handle=opendir($dir);
             if (is_resource($handle))
             {
-    			while (($file = readdir($handle)) != false)
+    			while (($file = readdir($handle)) !== false)
     			{
     				if (dol_is_file($dir.$file) && preg_match('/(\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$dir.$file))
     				{

+ 1 - 1
htdocs/categories/index.php

@@ -79,7 +79,7 @@ print '<tr class="liste_titre">';
 print '<td colspan="3">'.$langs->trans("Search").'</td>';
 print '</tr>';
 print '<tr '.$bc[0].'><td>';
-print $langs->trans("Name").':</td><td><input class="flat" type="text" size="20" name="catname" value="' . $catname . '"/></td><td><input type="submit" class="button" value="'.$langs->trans("Search").'"></td></tr>';
+print $langs->trans("Name").':</td><td><input class="flat inputsearch" type="text" name="catname" value="' . $catname . '"/></td><td><input type="submit" class="button" value="'.$langs->trans("Search").'"></td></tr>';
 /*
 // faire une rech dans une sous categorie uniquement
 print '<tr '.$bc[0].'><td>';

Some files were not shown because too many files changed in this diff