Explorar o código

Merge branch 'develop' into 10.0_accounting6

Laurent Destailleur %!s(int64=6) %!d(string=hai) anos
pai
achega
229dd4d3f5
Modificáronse 100 ficheiros con 1871 adicións e 968 borrados
  1. 4 2
      .editorconfig
  2. 3 0
      .scrutinizer.yml
  3. 3 6
      .travis.yml
  4. 6 7
      COPYRIGHT
  5. 282 5
      ChangeLog
  6. 9 9
      build/debian/copyright
  7. 1 1
      build/generate_filelist_xml.php
  8. 3 3
      build/makepack-dolibarr.pl
  9. 3 2
      build/perl/virtualmin/dolibarr.pl
  10. 14 0
      build/phpstan/bootstrap.php
  11. 4 1
      build/rpm/dolibarr_fedora.spec
  12. 4 1
      build/rpm/dolibarr_generic.spec
  13. 4 1
      build/rpm/dolibarr_mandriva.spec
  14. 4 1
      build/rpm/dolibarr_opensuse.spec
  15. 1 1
      dev/examples/code/create_invoice.php
  16. 1 1
      dev/examples/code/create_order.php
  17. 1 1
      dev/examples/code/create_product.php
  18. 1 1
      dev/examples/code/create_user.php
  19. 1 1
      dev/examples/code/get_contracts.php
  20. 1 1
      dev/initdata/generate-invoice.php
  21. 1 1
      dev/initdata/generate-order.php
  22. 1 1
      dev/initdata/generate-product.php
  23. 1 1
      dev/initdata/generate-proposal.php
  24. 1 1
      dev/initdata/generate-thirdparty.php
  25. 1 1
      dev/initdata/import-products.php
  26. 1 1
      dev/initdata/import-thirdparties.php
  27. 1 1
      dev/initdata/import-users.php
  28. 1 1
      dev/initdata/purge-data.php
  29. 56 0
      dev/initdemo/mysqldump_dolibarr_10.0.0.sql
  30. 68 1
      dev/initdemo/savedemo.sh
  31. 1 1
      dev/initdemo/sftpget_and_loaddump.php
  32. 1 1
      dev/initdemo/updatedemo.php
  33. 3 3
      dev/resources/licence/Links on GPL.txt
  34. 39 7
      dev/setup/codesniffer/ruleset.xml
  35. 1 1
      dev/translation/autotranslator.class.php
  36. 1 1
      dev/translation/autotranslator.php
  37. 1 1
      dev/translation/sanity_check_en_langfiles.php
  38. 1 1
      dev/translation/strip_language_file.php
  39. 8 9
      htdocs/accountancy/admin/account.php
  40. 3 11
      htdocs/accountancy/admin/accountmodel.php
  41. 1 1
      htdocs/accountancy/admin/card.php
  42. 1 1
      htdocs/accountancy/admin/categories.php
  43. 1 1
      htdocs/accountancy/admin/categories_list.php
  44. 3 4
      htdocs/accountancy/admin/closure.php
  45. 2 3
      htdocs/accountancy/admin/defaultaccounts.php
  46. 4 3
      htdocs/accountancy/admin/export.php
  47. 5 10
      htdocs/accountancy/admin/fiscalyear.php
  48. 1 1
      htdocs/accountancy/admin/fiscalyear_card.php
  49. 2 2
      htdocs/accountancy/admin/fiscalyear_info.php
  50. 0 187
      htdocs/accountancy/admin/importaccounts.php
  51. 13 13
      htdocs/accountancy/admin/index.php
  52. 1 1
      htdocs/accountancy/admin/journals_list.php
  53. 117 40
      htdocs/accountancy/admin/productaccount.php
  54. 1 1
      htdocs/accountancy/bookkeeping/balance.php
  55. 1 1
      htdocs/accountancy/bookkeeping/balancebymonth.php
  56. 14 14
      htdocs/accountancy/bookkeeping/card.php
  57. 123 44
      htdocs/accountancy/bookkeeping/list.php
  58. 4 6
      htdocs/accountancy/bookkeeping/listbyaccount.php
  59. 97 60
      htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
  60. 93 59
      htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
  61. 1 1
      htdocs/accountancy/class/accountancycategory.class.php
  62. 247 34
      htdocs/accountancy/class/accountancyexport.class.php
  63. 3 3
      htdocs/accountancy/class/accountancysystem.class.php
  64. 10 14
      htdocs/accountancy/class/accountingaccount.class.php
  65. 1 1
      htdocs/accountancy/class/accountingjournal.class.php
  66. 22 26
      htdocs/accountancy/class/bookkeeping.class.php
  67. 26 26
      htdocs/accountancy/class/lettering.class.php
  68. 1 1
      htdocs/accountancy/customer/card.php
  69. 13 13
      htdocs/accountancy/customer/index.php
  70. 5 5
      htdocs/accountancy/customer/lines.php
  71. 70 35
      htdocs/accountancy/customer/list.php
  72. 1 1
      htdocs/accountancy/expensereport/card.php
  73. 11 11
      htdocs/accountancy/expensereport/index.php
  74. 5 5
      htdocs/accountancy/expensereport/lines.php
  75. 7 7
      htdocs/accountancy/expensereport/list.php
  76. 1 1
      htdocs/accountancy/index.php
  77. 79 44
      htdocs/accountancy/journal/bankjournal.php
  78. 23 27
      htdocs/accountancy/journal/expensereportsjournal.php
  79. 20 22
      htdocs/accountancy/journal/purchasesjournal.php
  80. 23 25
      htdocs/accountancy/journal/sellsjournal.php
  81. 1 1
      htdocs/accountancy/supplier/card.php
  82. 11 11
      htdocs/accountancy/supplier/index.php
  83. 5 5
      htdocs/accountancy/supplier/lines.php
  84. 40 24
      htdocs/accountancy/supplier/list.php
  85. 2 4
      htdocs/adherents/agenda.php
  86. 36 24
      htdocs/adherents/card.php
  87. 18 10
      htdocs/adherents/class/adherent.class.php
  88. 29 4
      htdocs/adherents/class/adherent_type.class.php
  89. 1 1
      htdocs/adherents/document.php
  90. 3 3
      htdocs/adherents/htpasswd.php
  91. 12 3
      htdocs/adherents/index.php
  92. 57 7
      htdocs/adherents/list.php
  93. 1 1
      htdocs/adherents/note.php
  94. 1 1
      htdocs/adherents/stats/geo.php
  95. 1 6
      htdocs/adherents/stats/index.php
  96. 16 2
      htdocs/adherents/subscription.php
  97. 3 5
      htdocs/adherents/subscription/list.php
  98. 4 4
      htdocs/adherents/tpl/linkedobjectblock.tpl.php
  99. 35 7
      htdocs/adherents/type.php
  100. 1 1
      htdocs/admin/agenda.php

+ 4 - 2
.editorconfig

@@ -1,7 +1,8 @@
-# EditorConfig is awesome: http://EditorConfig.org
+# EditorConfig is awesome: https://editorconfig.org
 
 # top-most EditorConfig file
 root = true
+
 # Unix-style newlines with a newline ending every file
 [*]
 charset = utf-8
@@ -11,9 +12,10 @@ insert_final_newline = true
 # PHP PSR-2 Coding Standards
 # http://www.php-fig.org/psr/psr-2/
 [*.php]
-indent_style = space
+indent_style = tab
 indent_size = 4
 trim_trailing_whitespace = true
+insert_final_newline = true
 [*.js]
 indent_style = tab
 [*.css]

+ 3 - 0
.scrutinizer.yml

@@ -1,4 +1,7 @@
 # .scrutinizer.yml
+build:
+    - php-scrutinizer-run
+          
 imports:
     - javascript
     - php

+ 3 - 6
.travis.yml

@@ -164,12 +164,6 @@ before_script:
     echo
     echo "Set timezone"
     echo 'date.timezone = "Europe/Paris"' >> ~/.phpenv/versions/$PHP_VERSION_NAME/etc/php.ini
-    if [ "$TRAVIS_PHP_VERSION" = '5.4' ]; then
-      # Documentation says it should be available for all PHP versions but it's not for 5.5 and 5.6, 7.0, 7.1, 7.2 and nightly!
-      echo
-      echo "Enabling Memcached for PHP <= 5.4"
-      echo 'extension = memcached.so' >> ~/.phpenv/versions/$PHP_VERSION_NAME/etc/php.ini
-    fi
     phpenv rehash
     echo
 
@@ -350,6 +344,9 @@ script:
   php upgrade.php 9.0.0 10.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade9001000.log
   php upgrade2.php 9.0.0 10.0.0 > $TRAVIS_BUILD_DIR/upgrade9001000-2.log
   php step5.php 9.0.0 10.0.0 > $TRAVIS_BUILD_DIR/upgrade9001000-3.log
+  php upgrade.php 10.0.0 11.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade9001000.log
+  php upgrade2.php 10.0.0 11.0.0 > $TRAVIS_BUILD_DIR/upgrade9001000-2.log
+  php step5.php 10.0.0 11.0.0 > $TRAVIS_BUILD_DIR/upgrade9001000-3.log
   # Enable modules not enabled into original dump
   php upgrade2.php 0.0.0 0.0.0 MAIN_MODULE_API,MAIN_MODULE_SUPPLIERPROPOSAL,MAIN_MODULE_WEBSITE,MAIN_MODULE_TICKETSUP,MAIN_MODULE_ACCOUNTING > $TRAVIS_BUILD_DIR/enablemodule.log
   echo $?

+ 6 - 7
COPYRIGHT

@@ -13,29 +13,28 @@ 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.11.4        LGPL-2.1+                   Yes             Editor WYSIWYG
-PHPDebugBar			   1.15.0		 MIT License	             Yes             Used only by the module "debugbar" for developers
 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
 GeoIP                  1.4           LGPL-2.1+                   Yes             Sample code to make geoip convert (not into deb package)
-Mobiledetect           2.8.17        MIT License                 Yes             Detect mobile devices browsers
+Mobiledetect           2.8.83        MIT License                 Yes             Detect mobile devices browsers
 NuSoap                 0.9.5         LGPL 2.1+                   Yes             Library to develop SOAP Web services (not into rpm and deb package)
 PEAR Mail_MIME         1.8.9         BSD                         Yes             NuSoap dependency
-odtPHP                 1.0.1         GPL-2+                      Yes             Library to build/edit ODT files
 ParseDown              1.6           MIT License                 Yes             Markdown parser
+PHPDebugBar			   1.15.0		 MIT License	             Yes             Used only by the module "debugbar" for developers
 PHPExcel               1.8.1         LGPL-2.1+                   Yes             Read/Write XLS files, read ODS files
 PHPSpreadSheet         ?             LGPL-2.1+                   Yes             Read/Write XLS files, read ODS files
 php-iban               1.4.7         LGPL-3+                     Yes             Parse and validate IBAN (and IIBAN) bank account information in PHP
 PHPoAuthLib            0.8.2         MIT License                 Yes             Library to provide oauth1 and oauth2 to different service
 PHPPrintIPP            1.3           GPL-2+                      Yes             Library to send print IPP requests
 PSR/Logs			   1.0										                 Library for logs (used by DebugBar)
-PSR/simple-cache												                 Library for cache (used by PHPSpreadSheet)
+PSR/simple-cache	   ?										                 Library for cache (used by PHPSpreadSheet)
 Restler                3.0.0RC6      LGPL-3+                     Yes             Library to develop REST Web services (+ swagger-ui js lib into dir explorer)
+Sabre                  3.2.2         BSD                         Yes             DAV support
+Swift Mailer           5.4.2-DEV     MIT license                 Yes             Comprehensive mailing tools for PHP
+Stripe                 6.35          MIT licence                 Yes             Library for Stripe module
 TCPDF                  6.2.25        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
-Stripe                 4.7.0         MIT licence                 Yes             Library for Stripe module
 
 JS libraries:
 jQuery                 3.3.1         MIT License                 Yes             JS library

+ 282 - 5
ChangeLog

@@ -3,31 +3,186 @@ English Dolibarr ChangeLog
 --------------------------------------------------------------
 
 
+***** ChangeLog for 11.0.0 compared to 10.0.0 *****
+For Users:
+
+
+For Developers:
+
+
+WARNING:
+
+Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
+...
+
 
 ***** ChangeLog for 10.0.0 compared to 9.0.0 *****
 For Users:
 NEW: Module "Ticket" is available as a stable module.
-NEW: module "Email Collector" is available as a stable module.
-NEW: module "TakePOS" is available as a stable module.
+NEW: Module "Email Collector" is available as a stable module.
+NEW: Module "TakePOS" is available as a stable module.
 NEW: Experimental module "Vendor receptions".
 NEW: Experimental module "BOM".
-FIX: Disallow line start date if after end date.
+NEW: Accounting - Add default accounting account for member subcriptions.
+NEW: Accounting - More comprehensive menu.
+NEW: Agenda/event - add description column available in list (hidden by default).
+NEW: Add accounting account for result.
+NEW: Add accounting code for EEC sales and export sales on products.
+NEW: Add a security permission to edit php dynamic content on the WebSite module.
+NEW: Attached document on bank account are now visible in automatic ECM.
+NEW: Add Autofill Remainder Amount picto on the Expense Report Payment Page.
+NEW: Add contact status in category export
+NEW: Add Default Warehouse to user record (if module stock is on)
+NEW: Add employee/user to subledger account list
+NEW: Add gender in member card
+NEW: Add getFormatedCustomerRef and getFormatedSupplierRef methods
+NEW: Add history to view and print previous sales on TakePos.
+NEW: Add import of accounting account for intra/export selling on product card
+NEW: Adding code to show update date of supplier price shown
+NEW: Add line total on list of payments
+NEW: Add LinkedIn field in social network module
+NEW: Add more complete error messages in log on stripe payments
+NEW: Add no_email field in contact list
+NEW: Add notes are show in tooltips
+NEW: Add option DONATION_USE_THIRDPARTIES in admin of membership module
+NEW: Add option STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO
+NEW: add page to setup opening hours of the company
+NEW: add payments table to pdf of expense report
+NEW: add payment terms to invoices list
+NEW: Add picto of deletion on mass action combo lists
+NEW: add product extrafields available into shipping export
+NEW: add ref supplier on supplier invoice
+NEW: Add stats on entries & movements by fiscal year
+NEW: Add subledger in various payment module
+NEW: Add tag for ODT generation for localtax rates
+NEW: Add the now link when creating expense report
+NEW: Ask date of invoice when using the Clone feature.
+NEW: auto event msg
+NEW: Automatically binding for intra/export accountancy code in customer list
+NEW: automatic / manual selector form
+NEW: Better explanation for setup of WebDav module
+NEW: Can add more lines on situation invoices at end of project when there is extra to add.
+NEW: Can change the customer account of an instance
+NEW: Can choose the root category to show products for TakePOS module
+NEW: Can edit supplier on draft order supplier
+NEW: Can enter price with or without tax when entering expense repor line
+NEW: Can filter on the date of period for social contributions
+NEW: Can generate invoices from the timespent entered on a project
+NEW: Can update product supplier price ref
+NEW: Can upload files from the edit page of expense report
+NEW: Color for hover and for checked line is on by default
+NEW: Column of parent company is available in list of third parties
+NEW: conditionnal add member button by statut
+NEW: constant KEEP_DISCOUNT_LINES_FROM_ORIGIN
+NEW: Contact related items tab
+NEW: Can create of supplier invoice from a reception
+NEW: Ensure External RSS Links Open in New Window
+NEW: Export available for reception module
+NEW: Extend import option to Order's card and Propal's card
+NEW: filter by thirdparty on report CA by prod/serv
+NEW: Save space by moving the meteo on the title line
+NEW: Get the list of groups of a user with the REST API.
+NEW: Hidden option MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER to edit supplier on draft supplier order
+NEW: Improve Displaying Shortcut Access Keys in Navigation.
+NEW: Improve Expensereport, Inverse Receiver.
+NEW: Improve pdf description item visibitity.
+NEW: Introduce a config parameter $dolibarr_main_instance_unique_id
+NEW: Introduce css "nobottomiftotal"
+NEW: Introduce PhpSpreadsheet for export (need php5.6+)
+NEW: Invoice creation from the timesheet
+NEW: Can list remote stripe's payout in a dedicated page.
+NEW: Manage account sell_intra & sell_export in page accoutancy admin default product
+NEW: Manage loan schedule.
+NEW: Manage status of member types.
+NEW: Mass action "create bills" for validated reception
+NEW: Measuring unit are now defined into an editable dictionary. Add product size/unit into product import. 
+NEW: Template pdf 'canelle_reception' displays linked reception lines.
+NEW: Moral/physic status can be defined at member type level
+NEW: Pagination into list of time spent.
+NEW: Performance enhancement (Replace dirname(__FILE__) with __DIR__)
+NEW: POS support in order (ex: online cart).
+NEW: Preview of images into the filemanager component.
+NEW: Resource module can be used in products/services (in a dedicated tab)
+NEW: Retrieve invoice infos from order when billing shipment
+NEW: Save and display type of membership in subscription table for more explicit historic
+NEW: Setup default thirdparty type (customer or prospect/customer)
+NEW: Add shipping "set draft" button and can update lines.
+NEW: show in blod, the invoice amount where we came from, when making payment
+NEW: Show product dimensions in product tooltips.
+NEW: Show the latest date of subscription in member statistics reports.
+NEW: Sort list of templates alphabetically
+NEW: Stripe Payment Intent (need option to use this new Stripe api method)
+NEW: Can support barcode on supplier price references.
+NEW: Support tag {ccc} on payment ref
+NEW: The preview of PDF files generates only 1 png file, even if several pages.
+NEW: Can select a Thirdparty object in donation module if option ON.
+NEW: Tooltip with VAT amount and price incl tax on lines of objects.
+NEW: Unsubscribed emails are now stored in a dedicated table.
+NEW: Update working chkbxlst filter for lists.
+NEW: Use ajax switch into setup of donation.php and multi-currency module.
+NEW: use recipient language when generating the fullname for emails.
+NEW: When you create product or service, sell accountancy account by default is suggested.
+NEW: Widget birthdays of the month.
+NEW: Option in workflow module to set a reception billed on validate supplier bill.
+NEW: Autocompletion on lists should be available on mobile applications.
+NEW: Add mass action to close several members.
+NEW: Add hidden option ADD_UNSPLASH_LOGIN_BACKGROUND for random background
+NEW: Add hidden option to be ready for BREXIT
 
 For Developers:
 NEW: Module "DebugBar" is available as a stable module.
+NEW: Add API REST for donations
+NEW: Add a script 'purge-data.php' to purge data older than a defined creation date
+NEW: Add constant XFRAMEOPTIONS_ALLOWALL
+NEW: Add function isValidVATID() to heck syntax of a VAT ID/number.
+NEW: Add document's product support in APIs
+NEW: Add REST API: get the list of objects in a category.
+NEW: Update Stripe library to 6.35
+NEW: Upgrade jquery lib to 3.3.1
+NEW: Add hook 'addHtmlHeader()'
+NEW: Add hook 'createRecurringInvoices()'
+NEW: Add hook 'afterSelectContactOptions'
+NEW: Add hook 'getAccessForbiddenMessage'
+NEW: Add hook support in accountancy index
+NEW: Add hook support in list of template invoices
+NEW: Add parameter 'replaceambiguouschars' on getRandomPassword function
+NEW: Add property 'noteditable' in modulebuilder
+NEW: Add the current modulepart into the Conf class object
+NEW: Add trigger FICHINTER_UNVALIDATE
+NEW: Add visibility with value 4 in framework to define fields to show
+NEW: More option to tune initialization of a new module with modulebuilder.
+NEW: Add REST API to list currencies
+NEW: REST API Proposal, Orders, Invoices: Add contact details
+NEW: hidden option to change concat order of description/product label.
+NEW: Enhance management of webhooks
+NEW: Generation of doc by modulebuilder can include README and CHANGELOG
+NEW: massfilesarea feature is possible for external modules
+NEW: Show list of enabled modules in dol_print_error().
+NEW: Simplification of CSS styles of default themes. 
+NEW: Clean code of a lot of deprecated code.
+NEW: Add hidden option to set a search entry to the top
+NEW: add hidden option DISPLAY_DISCOUNTED_SUPPLIER_PRICE
+NEW: add hidden option MAIN_DEFAULT_LANGUAGE_FILTER
+NEW: add hidden option NO_CONCAT_DESCRIPTION
+NEW: Add hidden option ACCOUNTANCY_COMBO_FOR_AUX
+NEW: Add Hidden option OVERRIDE_VAT_FOR_EXPENSE_REPORT
+NEW: add hidden option MAIN_DOC_UPLOAD_NOT_RENAME_BY_DEFAULT
+NEW: Hidden conf to improve pdf desc item visibitity
+NEW: Look and feel v10 - Add CSS 'tabBarNoTop'
 
 
 WARNING:
 
 Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
 * PHP 5.4 is no more supported. Minimum PHP is now 5.5+.
-* The PHP extension php-intl is not mandatory but should be installed to have new features working correctly.
+* The PHP extension php-intl is not mandatory and must be installed to have new features working correctly.
 * Method GetUrlTrackingStatus were renamed into getUrlTrackingStatus for consistency with naming rules.
 * API getListOfCivility has been renamed into getListOfCivilities for consistency with naming rules.
 * Deprecated function img_phone as been removed. You can use img_picto(..., 'call|call_out') instead.; 
 * Files for variables of themes were renamed from graph-color.php into theme_vars.inc.php to match naming 
   convention of extension .inc.php for files to be included.
 * All methods set_draft() were renamed into setDraft().
+* Signatures of methods createFromClone() has been standardized. All methods requires the object User as first parameter.
 * Removed deprecated function function test_sql_and_script_inject that was replaced with testSqlAndScriptInject.
 * Method load_measuring_units were renamed into selectMeasuringUnits and select_measuring_units was deprecated.
 * Hidden option CHANGE_ORDER_CONCAT_DESCRIPTION were renamed into MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION.
@@ -35,7 +190,45 @@ Following changes may create regressions for some external modules, but were nec
 * Removed deprecated use of string in dol_print_date(). Only date allowed.
 * Deprecated property ->fk_departement is now ->state_id everywhere.
 * Removed the method 4 of GETPOST (to get $_COOKIE). It was not used and not recommanded to use in Dolibarr.
-
+* Column llx_facture.facnumber change to llx_facture.ref
+* Variable $dolibarr_main_cookie_cryptkey is no more created at install (it was not used by Dolibarr). A new variable 
+  called $dolibarr_main_instance_unique_id is now generated at each installation. It will be used by some future features.
+
+
+
+***** ChangeLog for 9.0.3 compared to 9.0.2 *****
+FIX: #11013
+FIX: #11041
+FIX: actioncomm: sort events by date after external calendars and hook (into 7.0)
+FIX: better test
+FIX: Combo list was limited to 20 in stock correction
+FIX: Confusion between expired and late
+FIX: Cursor pointer in payment screen for autofill
+FIX: CVE-2019-11199
+FIX: CVE-2019-11200
+FIX: CVE-2019-11201
+FIX: Default value on form to send email
+FIX: error messages not displayed
+FIX: Massive debug in lettering function
+FIX: missing compatibility with multicompany
+FIX: missing global $user
+FIX: missing situation invoice in list
+FIX: MultiEntity in lettering functionality
+FIX: Product accountancey sell intra code must be visible if main feature level 1
+FIX: ref for table without ref manager are set to NULL.
+FIX: Sending email to mass actions send same email on same customer
+FIX: Several fixes on import of services/products
+FIX: shipping default warehouse if only one warehouse
+FIX: sortfield on lettering function
+FIX: Status of opportunity should never be -1
+FIX: test to display create invoice button on supplier_order card
+FIX: The autocopy feature was ko for suppliers
+FIX: Total per day in timespent per week
+FIX: Total per day shows 00:00 if the total time spent is equal to 12:00
+FIX: Update/delete currency on same languages
+FIX: Wrong variable name make contact of supplier order not used on PDF.
+FIX: Add hidden option MAIN_PDF_HIDE_SITUATION to hide situation (quick hack to fix output pb).
+FIX: attached files list with link file was broked
 
 ***** ChangeLog for 9.0.2 compared to 9.0.1 *****
 FIX: #10822
@@ -256,6 +449,90 @@ Following changes may create regressions for some external modules, but were nec
 * Remove the no more used and deprecated dol_print_graph function
 
 
+***** ChangeLog for 8.0.5 compared to 8.0.4 *****
+FIX: #10381
+FIX: #10460 compatibility with MariaDB 10.4
+FIX: #11025
+FIX: Accountancy - Add transaction with multicompany use all the time 1st entity
+FIX: Accountancy - Format EBP import
+FIX: actioncomm export: ORDER BY clause is in wrong export property + event type filter does not work
+FIX: actioncomm: sort events by date after external calendars and hook
+FIX: action list: add printFieldListSelect and printFieldListWhere hooks
+FIX: add fk_unit on addline action
+FIX: avoid php warning
+FIX: bad sql request
+FIX: better method
+FIX: better test
+FIX: better test on fetch
+FIX: broken external authentication module feature and avoid warning
+FIX: Can not create contract with numbering module without autogen rule
+FIX: can't add lines on invoices
+FIX: Can't generate invoice pdf
+FIX: Can't insert if there is extrafields mandatory on another entity.
+FIX: Can't insert if there is extrafields mandatory on another entity. FIX: Can't set default value of extrafield of type varchar
+FIX: Check for old picture name if the new one was not found
+FIX: Civility not saved when creating a member.
+FIX: $conf->fournisseur->commande->enabled doesn't exist, we must use $conf->fournisseur->enabled
+FIX: could not create several superadmin in transversal mode
+FIX: credit note can have negative value
+FIX: Default value on sales representative on third party creation
+FIX: Don't show journal:getNomUrl without data
+FIX: Erreur dans le Total
+FIX: error messages not displayed
+FIX: expedition: reset status on rollback + replace hardcoded status with const
+FIX: Fix PHP warning "count(): Parameter must be an array..."
+FIX: fk_default_warehouse missing in group by
+FIX: function sendEmailsReminder isn't completely developed, then MAIN_FEATURES_LEVEL must be 2 to "use" it
+FIX: holidays get natural_search if search params are set only
+FIX: if empty error message, we just see "error" displayed
+FIX: if(!method_exists(dol_loginfunction))
+FIX: If we build one invoice for several orders, we must put the ref of order on the line to not lose information.
+FIX: in fact expensereport must be in $check array
+FIX: Interface regression for bind people. Fix option MAIN_OPTIMIZEFORTEXTBROWSER
+FIX: line edit template: keep fk_parent_line
+FIX: Loan impossible to account
+FIX: Mark credit note as available for credit note in other currency
+FIX: missing access security checking with multicompany
+FIX: missing entity filter and wrong var name
+FIX: missing entity filter in function "build_filterField()" (export)
+FIX: Missing field in import/export of users
+FIX: missing hook completeTabsHead in margins module
+FIX: missing $ismultientitymanaged for previous/next ref
+FIX: Missing province in export of invoice
+FIX: multicompany compatibility
+FIX: must fetch member in current entity
+FIX: need an order by in case we found other invoice with same number but not same date
+FIX: need to round with 2 decimals to avoid movements not correctly balanced
+FIX: no need to test anything to display documents tabs on expense report
+FIX: positive values creating diff on addline rounding
+FIX: problem with multicompany transverse mode
+FIX: Product accountancey sell intra code must be visible if main feature level 1
+FIX: project_title for display of getNomUrl()
+FIX: quick search for supplier orders
+FIX: Remane of project
+FIX: same thing here
+FIX: Selection of email recipient with option MAIN_OPTIMIZEFORTEXTBROWSER
+FIX: several hooks in shipping/delivery cards
+FIX: shipping default warehouse if only one warehouse
+FIX: SQL injection on rowid of dict.php
+FIX: 'statut' is ignored when updating a user with the REST API.
+FIX: supplier invoice payment total dont care about deposit or credit
+FIX: supplier invoice product stats total ht is line total not invoice total
+FIX: The minimum amount filter does not work in the VAT report per customer
+FIX: Total per day shows 00:00 if the total time spent is equal to 12:00
+FIX: Update/delete currency on same languages
+FIX: [URGENT] broken feature, "$usercancreate" is for Dolibarr 9
+FIX: useless join
+FIX: we need to keep originline special_code
+FIX: we want to be able to reopen fourn credit note
+FIX: when 2 extra fields are mandatory in 2 different entities
+FIX: when we add a payment on an invoice which already has payments with credit note or deposit amount, and then we get an excess received, discount amount must be $total_paiements + $total_creditnote_and_deposit - $object->total_ttc;
+FIX: when we create deposit with multi tva, we mustn't add line if amount = 0 (example when we have a 100% reduc on one of origin invoice line)
+FIX: wrong redirect link on holiday refuse
+FIX: wrong test enabled
+FIX: Wrong variable name
+FIX: XSS
+
 ***** ChangeLog for 8.0.4 compared to 8.0.3 *****
 FIX: #10030 better german chart
 FIX: #10036

+ 9 - 9
build/debian/copyright

@@ -52,7 +52,7 @@ License: GPL-3+
  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/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
  .
  On Debian systems, the full text of the GNU General Public
  License version 3 can be found in the file
@@ -98,7 +98,7 @@ License: GPL-2+
  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/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
  .
  On Debian systems, the complete text of the GNU General Public License
  can be found in /usr/share/common-licenses/GPL-2 file.
@@ -192,7 +192,7 @@ License: GPL-2+
  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/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
  .
  On Debian systems, the full text of the GNU General Public
  License version 2 can be found in the file
@@ -212,7 +212,7 @@ License: LGPL-2.1+
  Lesser General Public License for more details.
  .
  You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
  .
  On Debian systems, the full text of the GNU Lesser General Public
  License version 2.1 can be found in the file
@@ -236,7 +236,7 @@ License: GPL-2+ or MIT
  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/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
  .
  On Debian systems, the full text of the GNU General Public
  License version 2 can be found in the file
@@ -291,7 +291,7 @@ License: GPL-2+
  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/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
  .
  On Debian systems, the full text of the GNU General Public
  License version 2 can be found in the file
@@ -311,7 +311,7 @@ License: LGPL-2.1+
  Lesser General Public License for more details.
  .
  You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
  .
  On Debian systems, the full text of the GNU Lesser General Public
  License version 2.1 can be found in the file
@@ -358,7 +358,7 @@ License: LGPL-2.1+
  Lesser General Public License for more details.
  .
  You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
  .
  On Debian systems, the full text of the GNU Lesser General Public
  License version 2.1 can be found in the file
@@ -378,7 +378,7 @@ License: LGPL-3.0+
  See the GNU Lesser General Public License for more details.
  .
  You should have received a copy of the GNU Lesser General Public License
- along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
+ along with TCPDF. If not, see <https://www.gnu.org/licenses/>.
  .
  On Debian systems, the complete text of the GNU Lesser General
  Public License version 3 can be found in "/usr/share/common-licenses/LGPL-3".

+ 1 - 1
build/generate_filelist_xml.php

@@ -13,7 +13,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
 /**

+ 3 - 3
build/makepack-dolibarr.pl

@@ -129,7 +129,7 @@ $BUILDROOT="$TEMP/buildroot";
 $result = open( IN, "<" . $SOURCE . "/htdocs/filefunc.inc.php" );
 if ( !$result ) { die "Error: Can't open descriptor file " . $SOURCE . "/htdocs/filefunc.inc.php\n"; }
 while (<IN>) {
-	if ( $_ =~ /define\('DOL_VERSION','([\d\.a-z\-]+)'\)/ ) { $PROJVERSION = $1; break; }
+	if ( $_ =~ /define\('DOL_VERSION',\s*'([\d\.a-z\-]+)'\)/ ) { $PROJVERSION = $1; break; }
 }
 close IN;
 ($MAJOR,$MINOR,$BUILD)=split(/\./,$PROJVERSION,3);
@@ -357,7 +357,7 @@ if ($nboftargetok) {
 		}
 		else
 		{
-			print "ChangeLog for $MAJOR.$MINOR\.$BUILD was found into '$SOURCE/ChangeLog. But you can regenerate it with command:'\n";
+			print "ChangeLog for $MAJOR.$MINOR\.$BUILD was found into '$SOURCE/ChangeLog'. But you can regenerate it with command:\n";
 		}
 		if (! $BUILD || $BUILD eq '0-rc')	# For a major version
 		{
@@ -1002,7 +1002,7 @@ if ($nboftargetok) {
 			$ret=`chmod -R 644 $BUILDROOT/$PROJECT.tmp/htdocs/modulebuilder/template/mymoduleindex.php`;
 			$ret=`chmod -R 644 $BUILDROOT/$PROJECT.tmp/htdocs/modulebuilder/template/myobject_card.php`;
 			$ret=`chmod -R 644 $BUILDROOT/$PROJECT.tmp/htdocs/modulebuilder/template/myobject_list.php`;
-			$ret=`chmod -R 755 $BUILDROOT/$PROJECT.tmp/htdocs/modulebuilder/template/scripts/myobject.php`;
+			$ret=`chmod -R 755 $BUILDROOT/$PROJECT.tmp/htdocs/modulebuilder/template/scripts/mymodule.php`;
 			$cmd="find $BUILDROOT/$PROJECT.tmp/scripts -name '*.php' -type f -exec chmod 755 {} \\; ";
 			$ret=`$cmd`;
 			$cmd="find $BUILDROOT/$PROJECT.tmp/scripts -name '*.sh' -type f -exec chmod 755 {} \\; ";

+ 3 - 2
build/perl/virtualmin/dolibarr.pl

@@ -1,7 +1,7 @@
 #----------------------------------------------------------------------------
 # \file         dolibarr.pl
 # \brief        Dolibarr script install for Virtualmin Pro
-# \author       (c)2009-2018 Regis Houssin  <regis.houssin@inodbox.com>
+# \author       (c)2009-2019 Regis Houssin  <regis.houssin@inodbox.com>
 #----------------------------------------------------------------------------
 
 
@@ -30,7 +30,7 @@ return "Regis Houssin";
 # script_dolibarr_versions()
 sub script_dolibarr_versions
 {
-return ( "9.0.0", "8.0.3", "7.0.4", "6.0.8", "5.0.7" );
+return ( "10.0.0", "9.0.3", "8.0.5", "7.0.5", "6.0.8" );
 }
 
 sub script_dolibarr_release
@@ -390,6 +390,7 @@ sub script_dolibarr_check_latest
 {
 local ($ver) = @_;
 local @vers = &osdn_package_versions("dolibarr",
+				$ver >= 10.0 ? "dolibarr\\-(10\\.0\\.[0-9\\.]+)\\.tgz" :
 				$ver >= 9.0 ? "dolibarr\\-(9\\.0\\.[0-9\\.]+)\\.tgz" :
 				$ver >= 8.0 ? "dolibarr\\-(8\\.0\\.[0-9\\.]+)\\.tgz" :
 				$ver >= 7.0 ? "dolibarr\\-(7\\.0\\.[0-9\\.]+)\\.tgz" :

+ 14 - 0
build/phpstan/bootstrap.php

@@ -0,0 +1,14 @@
+<?php
+// Example to use PHPStan
+// cd git/dolibarr
+// /usr/bin/php7.2 ../phpstan.phar -l1 analyze htdocs/societe/website.php --memory-limit 2G
+
+// Defined some constants and load Dolibarr env to reduce PHPStan bootstrap that fails to load a lot of things.
+define('DOL_DOCUMENT_ROOT', __DIR__ . '/../../htdocs');
+define('DOL_DATA_ROOT', __DIR__ . '/../../documents');
+define('DOL_URL_ROOT', '/');
+
+// Load the main.inc.php file to have finctions llx_Header and llx_Footer defined
+if (! defined("NOLOGIN")) define("NOLOGIN", '1');
+global $conf, $langs, $user, $db;
+include_once __DIR__ . '/../../htdocs/main.inc.php';

+ 4 - 1
build/rpm/dolibarr_fedora.spec

@@ -165,6 +165,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/barcode
 %_datadir/dolibarr/htdocs/blockedlog
 %_datadir/dolibarr/htdocs/bookmarks
+%_datadir/dolibarr/htdocs/bom
 %_datadir/dolibarr/htdocs/cashdesk
 %_datadir/dolibarr/htdocs/categories
 %_datadir/dolibarr/htdocs/collab
@@ -179,6 +180,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/custom
 %_datadir/dolibarr/htdocs/datapolicy
 %_datadir/dolibarr/htdocs/dav
+%_datadir/dolibarr/htdocs/debugbar
 %_datadir/dolibarr/htdocs/don
 %_datadir/dolibarr/htdocs/ecm
 %_datadir/dolibarr/htdocs/emailcollector
@@ -191,7 +193,6 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/ftp
 %_datadir/dolibarr/htdocs/holiday
 %_datadir/dolibarr/htdocs/hrm
-%_datadir/dolibarr/htdocs/ifttt
 %_datadir/dolibarr/htdocs/imports
 %_datadir/dolibarr/htdocs/includes
 %_datadir/dolibarr/htdocs/install
@@ -201,6 +202,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/mailmanspip
 %_datadir/dolibarr/htdocs/margin
 %_datadir/dolibarr/htdocs/modulebuilder
+%_datadir/dolibarr/htdocs/mrp
 %_datadir/dolibarr/htdocs/multicurrency
 %_datadir/dolibarr/htdocs/opensurvey
 %_datadir/dolibarr/htdocs/paybox
@@ -209,6 +211,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/product
 %_datadir/dolibarr/htdocs/projet
 %_datadir/dolibarr/htdocs/public
+%_datadir/dolibarr/htdocs/reception
 %_datadir/dolibarr/htdocs/resource
 %_datadir/dolibarr/htdocs/societe
 %_datadir/dolibarr/htdocs/stripe

+ 4 - 1
build/rpm/dolibarr_generic.spec

@@ -245,6 +245,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/barcode
 %_datadir/dolibarr/htdocs/blockedlog
 %_datadir/dolibarr/htdocs/bookmarks
+%_datadir/dolibarr/htdocs/bom
 %_datadir/dolibarr/htdocs/cashdesk
 %_datadir/dolibarr/htdocs/categories
 %_datadir/dolibarr/htdocs/collab
@@ -259,6 +260,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/custom
 %_datadir/dolibarr/htdocs/datapolicy
 %_datadir/dolibarr/htdocs/dav
+%_datadir/dolibarr/htdocs/debugbar
 %_datadir/dolibarr/htdocs/don
 %_datadir/dolibarr/htdocs/ecm
 %_datadir/dolibarr/htdocs/emailcollector
@@ -271,7 +273,6 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/ftp
 %_datadir/dolibarr/htdocs/holiday
 %_datadir/dolibarr/htdocs/hrm
-%_datadir/dolibarr/htdocs/ifttt
 %_datadir/dolibarr/htdocs/imports
 %_datadir/dolibarr/htdocs/includes
 %_datadir/dolibarr/htdocs/install
@@ -281,6 +282,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/mailmanspip
 %_datadir/dolibarr/htdocs/margin
 %_datadir/dolibarr/htdocs/modulebuilder
+%_datadir/dolibarr/htdocs/mrp
 %_datadir/dolibarr/htdocs/multicurrency
 %_datadir/dolibarr/htdocs/opensurvey
 %_datadir/dolibarr/htdocs/paybox
@@ -289,6 +291,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/product
 %_datadir/dolibarr/htdocs/projet
 %_datadir/dolibarr/htdocs/public
+%_datadir/dolibarr/htdocs/reception
 %_datadir/dolibarr/htdocs/resource
 %_datadir/dolibarr/htdocs/societe
 %_datadir/dolibarr/htdocs/stripe

+ 4 - 1
build/rpm/dolibarr_mandriva.spec

@@ -162,6 +162,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/barcode
 %_datadir/dolibarr/htdocs/blockedlog
 %_datadir/dolibarr/htdocs/bookmarks
+%_datadir/dolibarr/htdocs/bom
 %_datadir/dolibarr/htdocs/cashdesk
 %_datadir/dolibarr/htdocs/categories
 %_datadir/dolibarr/htdocs/collab
@@ -176,6 +177,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/custom
 %_datadir/dolibarr/htdocs/datapolicy
 %_datadir/dolibarr/htdocs/dav
+%_datadir/dolibarr/htdocs/debugbar
 %_datadir/dolibarr/htdocs/don
 %_datadir/dolibarr/htdocs/ecm
 %_datadir/dolibarr/htdocs/emailcollector
@@ -188,7 +190,6 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/ftp
 %_datadir/dolibarr/htdocs/holiday
 %_datadir/dolibarr/htdocs/hrm
-%_datadir/dolibarr/htdocs/ifttt
 %_datadir/dolibarr/htdocs/imports
 %_datadir/dolibarr/htdocs/includes
 %_datadir/dolibarr/htdocs/install
@@ -198,6 +199,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/mailmanspip
 %_datadir/dolibarr/htdocs/margin
 %_datadir/dolibarr/htdocs/modulebuilder
+%_datadir/dolibarr/htdocs/mrp
 %_datadir/dolibarr/htdocs/multicurrency
 %_datadir/dolibarr/htdocs/opensurvey
 %_datadir/dolibarr/htdocs/paybox
@@ -206,6 +208,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/product
 %_datadir/dolibarr/htdocs/projet
 %_datadir/dolibarr/htdocs/public
+%_datadir/dolibarr/htdocs/reception
 %_datadir/dolibarr/htdocs/resource
 %_datadir/dolibarr/htdocs/societe
 %_datadir/dolibarr/htdocs/stripe

+ 4 - 1
build/rpm/dolibarr_opensuse.spec

@@ -173,6 +173,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/barcode
 %_datadir/dolibarr/htdocs/blockedlog
 %_datadir/dolibarr/htdocs/bookmarks
+%_datadir/dolibarr/htdocs/bom
 %_datadir/dolibarr/htdocs/cashdesk
 %_datadir/dolibarr/htdocs/categories
 %_datadir/dolibarr/htdocs/collab
@@ -187,6 +188,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/custom
 %_datadir/dolibarr/htdocs/datapolicy
 %_datadir/dolibarr/htdocs/dav
+%_datadir/dolibarr/htdocs/debugbar
 %_datadir/dolibarr/htdocs/don
 %_datadir/dolibarr/htdocs/ecm
 %_datadir/dolibarr/htdocs/emailcollector
@@ -199,7 +201,6 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/ftp
 %_datadir/dolibarr/htdocs/holiday
 %_datadir/dolibarr/htdocs/hrm
-%_datadir/dolibarr/htdocs/ifttt
 %_datadir/dolibarr/htdocs/imports
 %_datadir/dolibarr/htdocs/includes
 %_datadir/dolibarr/htdocs/install
@@ -209,6 +210,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/mailmanspip
 %_datadir/dolibarr/htdocs/margin
 %_datadir/dolibarr/htdocs/modulebuilder
+%_datadir/dolibarr/htdocs/mrp
 %_datadir/dolibarr/htdocs/multicurrency
 %_datadir/dolibarr/htdocs/opensurvey
 %_datadir/dolibarr/htdocs/paybox
@@ -217,6 +219,7 @@ done >>%{name}.lang
 %_datadir/dolibarr/htdocs/product
 %_datadir/dolibarr/htdocs/projet
 %_datadir/dolibarr/htdocs/public
+%_datadir/dolibarr/htdocs/reception
 %_datadir/dolibarr/htdocs/resource
 %_datadir/dolibarr/htdocs/societe
 %_datadir/dolibarr/htdocs/stripe

+ 1 - 1
dev/examples/code/create_invoice.php

@@ -13,7 +13,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
 /**

+ 1 - 1
dev/examples/code/create_order.php

@@ -13,7 +13,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
 /**

+ 1 - 1
dev/examples/code/create_product.php

@@ -13,7 +13,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
 /**

+ 1 - 1
dev/examples/code/create_user.php

@@ -13,7 +13,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
 /**

+ 1 - 1
dev/examples/code/get_contracts.php

@@ -13,7 +13,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
 /**

+ 1 - 1
dev/initdata/generate-invoice.php

@@ -13,7 +13,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  *
  * ATTENTION DE PAS EXECUTER CE SCRIPT SUR UNE INSTALLATION DE PRODUCTION
  */

+ 1 - 1
dev/initdata/generate-order.php

@@ -14,7 +14,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  *
  * ATTENTION DE PAS EXECUTER CE SCRIPT SUR UNE INSTALLATION DE PRODUCTION
  */

+ 1 - 1
dev/initdata/generate-product.php

@@ -14,7 +14,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  *
  * ATTENTION DE PAS EXECUTER CE SCRIPT SUR UNE INSTALLATION DE PRODUCTION
  */

+ 1 - 1
dev/initdata/generate-proposal.php

@@ -14,7 +14,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  *
  * ATTENTION DE PAS EXECUTER CE SCRIPT SUR UNE INSTALLATION DE PRODUCTION
  */

+ 1 - 1
dev/initdata/generate-thirdparty.php

@@ -14,7 +14,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  *
  * ATTENTION DE PAS EXECUTER CE SCRIPT SUR UNE INSTALLATION DE PRODUCTION
  */

+ 1 - 1
dev/initdata/import-products.php

@@ -14,7 +14,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  *
  * WARNING, THIS WILL LOAD MASS DATA ON YOUR INSTANCE
  */

+ 1 - 1
dev/initdata/import-thirdparties.php

@@ -14,7 +14,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  *
  * WARNING, THIS WILL LOAD MASS DATA ON YOUR INSTANCE
  */

+ 1 - 1
dev/initdata/import-users.php

@@ -14,7 +14,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  *
  * WARNING, THIS WILL LOAD MASS DATA ON YOUR INSTANCE
  */

+ 1 - 1
dev/initdata/purge-data.php

@@ -13,7 +13,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  *
  * THIS SCRIPT DELETE ALL MAIN TABLE CONTENT
  * WARNING, DO NOT USE ON A PRODUCTION INSTANCE

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 56 - 0
dev/initdemo/mysqldump_dolibarr_10.0.0.sql


+ 68 - 1
dev/initdemo/savedemo.sh

@@ -176,10 +176,61 @@ 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_agefodd_calendrier
+    --ignore-table=$base.llx_agefodd_certif_state
+    --ignore-table=$base.llx_agefodd_certificate_type
+    --ignore-table=$base.llx_agefodd_contact
+    --ignore-table=$base.llx_agefodd_convention
+    --ignore-table=$base.llx_agefodd_convention_stagiaire
+    --ignore-table=$base.llx_agefodd_cursus
+    --ignore-table=$base.llx_agefodd_cursus_extrafields
+    --ignore-table=$base.llx_agefodd_formateur
+    --ignore-table=$base.llx_agefodd_formateur_category
+    --ignore-table=$base.llx_agefodd_formateur_category_dict
+    --ignore-table=$base.llx_agefodd_formateur_training
+    --ignore-table=$base.llx_agefodd_formateur_type
+    --ignore-table=$base.llx_agefodd_formation_catalogue
+    --ignore-table=$base.llx_agefodd_formation_catalogue_extrafields
+    --ignore-table=$base.llx_agefodd_formation_catalogue_modules
+    --ignore-table=$base.llx_agefodd_formation_catalogue_type
+    --ignore-table=$base.llx_agefodd_formation_catalogue_type_bpf
+    --ignore-table=$base.llx_agefodd_formation_cursus
+    --ignore-table=$base.llx_agefodd_formation_objectifs_peda
+    --ignore-table=$base.llx_agefodd_opca
+    --ignore-table=$base.llx_agefodd_place
+    --ignore-table=$base.llx_agefodd_reg_interieur
+    --ignore-table=$base.llx_agefodd_session
+    --ignore-table=$base.llx_agefodd_session_adminsitu
+    --ignore-table=$base.llx_agefodd_session_admlevel
+    --ignore-table=$base.llx_agefodd_session_calendrier
+    --ignore-table=$base.llx_agefodd_session_commercial
+    --ignore-table=$base.llx_agefodd_session_contact
+    --ignore-table=$base.llx_agefodd_session_element
+    --ignore-table=$base.llx_agefodd_session_extrafields
+    --ignore-table=$base.llx_agefodd_session_formateur
+    --ignore-table=$base.llx_agefodd_session_formateur_calendrier
+    --ignore-table=$base.llx_agefodd_session_stagiaire
+    --ignore-table=$base.llx_agefodd_session_stagiaire_heures
+    --ignore-table=$base.llx_agefodd_session_status_type
+    --ignore-table=$base.llx_agefodd_stagiaire
+    --ignore-table=$base.llx_agefodd_stagiaire_certif
+    --ignore-table=$base.llx_agefodd_stagiaire_cursus
+    --ignore-table=$base.llx_agefodd_stagiaire_extrafields
+    --ignore-table=$base.llx_agefodd_stagiaire_type
+    --ignore-table=$base.llx_agefodd_training_admlevel
     --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_assetOf
+    --ignore-table=$base.llx_assetOf_line
+    --ignore-table=$base.llx_asset_workstation_of
+    --ignore-table=$base.llx_asset_workstation_product
+    --ignore-table=$base.llx_asset_workstation_task
+    --ignore-table=$base.llx_assetof_amounts
+    --ignore-table=$base.llx_asset_workstation_of
+    --ignore-table=$base.llx_asset_workstation_of
+    --ignore-table=$base.llx_asset_workstation_of
     --ignore-table=$base.llx_bookkeeping
 	--ignore-table=$base.llx_bootstrap
 	--ignore-table=$base.llx_bt_namemap
@@ -226,15 +277,28 @@ export list="
 	--ignore-table=$base.llx_ecommerce_site
 	--ignore-table=$base.llx_ecommerce_societe
 	--ignore-table=$base.llx_ecommerce_socpeople
-	--ignore-table=$base.llx_element_rang
+    --ignore-table=$base.llx_element_rang
+	--ignore-table=$base.llx_element_tag
+    --ignore-table=$base.llx_eleves
+    --ignore-table=$base.llx_eleves_extrafields
 	--ignore-table=$base.llx_entity
+    --ignore-table=$base.llx_entity_extrafields
+    --ignore-table=$base.llx_entity_thirdparty
+    --ignore-table=$base.llx_equipement_factory
+    --ignore-table=$base.llx_factory
+    --ignore-table=$base.llx_factory_extrafields
+    --ignore-table=$base.llx_factorydet
 	--ignore-table=$base.llx_filemanager_roots
 	--ignore-table=$base.llx_fournisseur_ca
 	--ignore-table=$base.llx_google_maps
+    --ignore-table=$base.llx_lead
+    --ignore-table=$base.llx_lead_extrafields
+    --ignore-table=$base.llx_milestone
 	--ignore-table=$base.llx_milestone
 	--ignore-table=$base.llx_monitoring_probes
 	--ignore-table=$base.llx_m
 	--ignore-table=$base.llx_m_extrafields
+	--ignore-table=$base.llx_monmodule_abcdef
 	--ignore-table=$base.llx_notes
 	--ignore-table=$base.llx_pos_cash
 	--ignore-table=$base.llx_pos_control_cash
@@ -256,6 +320,9 @@ export list="
 	--ignore-table=$base.llx_ultimatepdf
 	--ignore-table=$base.llx_update_modules
 	--ignore-table=$base.llx_ventilation_achat
+    --ignore-table=$base.tmp_llx_accouting_account
+    --ignore-table=$base.tmp_llx_product_batch
+    --ignore-table=$base.tmp_llx_product_batch2
 	" 
 echo "mysqldump -P$port -u$admin -p***** $list $base > $mydir/$dumpfile"
 mysqldump -P$port -u$admin $passwd $list $base > $mydir/$dumpfile

+ 1 - 1
dev/initdemo/sftpget_and_loaddump.php

@@ -13,7 +13,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  * or see http://www.gnu.org/
  *
  * Get a distant dump file and load it into a mysql database

+ 1 - 1
dev/initdemo/updatedemo.php

@@ -13,7 +13,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  * or see http://www.gnu.org/
  *
  * Get a distant dump file and load it into a mysql database

+ 3 - 3
dev/resources/licence/Links on GPL.txt

@@ -1,8 +1,8 @@
 * Page with licence compatibility
-http://www.gnu.org/licenses/quick-guide-gplv3.fr.html
+https://www.gnu.org/licenses/quick-guide-gplv3.fr.html
 
 * FAQ on GPL licence
-http://www.fsf.org/licensing/licenses/gpl-faq.html
+https://www.fsf.org/licensing/licenses/gpl-faq.html
 
 * Questions/Answers on Fork for using Dolibarr as a SaaS
-http://stackoverflow.com/questions/539291/rebranding-a-gpld-app-as-saas
+https://stackoverflow.com/questions/539291/rebranding-a-gpld-app-as-saas

+ 39 - 7
dev/setup/codesniffer/ruleset.xml

@@ -75,10 +75,13 @@
 	<!-- Warning if action on same line than if -->
 	<!--
 		<rule ref="Generic.ControlStructures.InlineControlStructure">
-		<properties> <property name="error" value="false"/> </properties>
+		<properties>
+			<property name="error" value="false"/>
+		</properties>
 		</rule>
 	-->
 
+
     <!-- PHP code MUST use only UTF-8 without BOM. -->
     <rule ref="Generic.Files.ByteOrderMark"/>
 
@@ -97,8 +100,11 @@
 		</properties>
 	</rule>
 
-    <!-- To disallow several statements on same line -->
-	<!-- <rule ref="Generic.Formatting.DisallowMultipleStatements" /> -->
+    <!-- Disallow several statements on same line -->
+	<!--  We want to allow 'if () { ...small code... }' on same line for better code compacity and readability -->
+	<rule ref="Generic.Formatting.DisallowMultipleStatements">
+		<severity>0</severity>
+	</rule>
 
 	<!-- Have 2 chars padding maximum and always show as errors -->
 	<!--
@@ -112,13 +118,17 @@
     <rule ref="Generic.Functions.CallTimePassByReference" />
 
 	<rule ref="Generic.Functions.FunctionCallArgumentSpacing" />
+	
 	<rule ref="Generic.Functions.FunctionCallArgumentSpacing.NoSpaceBeforeEquals">
 		<severity>0</severity>
 	</rule>
 	<rule ref="Generic.Functions.FunctionCallArgumentSpacing.NoSpaceBeforeEquals">
 		<severity>0</severity>
 	</rule>
-	<rule ref="Generic.Functions.FunctionCallArgumentSpacing.TooMuchSpaceAfterComma">	<!-- We don't want this rule, we want to be able to align params on several similare functions on different lines -->
+	
+    <!-- Disallow several spaces after comma -->
+	<!-- We want to allow this because we want to be able to align params on several similare functions on different lines -->
+	<rule ref="Generic.Functions.FunctionCallArgumentSpacing.TooMuchSpaceAfterComma">
 		<severity>0</severity>
 	</rule>
 
@@ -152,7 +162,10 @@
     <rule ref="Generic.PHP.ForbiddenFunctions" />
 
     <!-- Warning when using @ before functions -->
-    <!-- <rule ref="Generic.PHP.NoSilencedErrors" /> -->
+    <!-- We want this. Some features need this -->
+    <rule ref="Generic.PHP.NoSilencedErrors">
+        <severity>0</severity>
+    </rule>
 
 	<!-- Say if null, true, false must be uppercase (Rule 2.5 of PSR2 https://www.php-fig.org/psr/psr-2/) -->
 	<rule ref="Generic.PHP.LowerCaseConstant" />
@@ -169,7 +182,16 @@
 	<!-- Check indent are done with spaces and with correct number -->
 	<!-- Disabled as this does not support tab -->
 	<!-- <rule ref="Generic.WhiteSpace.ScopeIndent" /> -->
-
+ 	<!-- TODO Enable this
+	<arg name="tab-width" value="4"/>
+	<rule ref="Generic.WhiteSpace.ScopeIndent">
+	  <properties>
+	    <property name="indent" value="4"/>
+	    <property name="tabIndent" value="true"/>
+	  </properties>
+	</rule>
+	-->
+	
     <rule ref="Squiz.WhiteSpace.ScopeClosingBrace.Indent" />
 
     <!-- There MUST NOT be trailing whitespace at the end of non-blank lines. -->
@@ -310,22 +332,29 @@
 
     <rule ref="PEAR.Commenting.InlineComment" />
 
-	<!-- <rule ref="PEAR.ControlStructures.ControlSignature" /> -->
+	<!-- Check position of { after a control structure like if (), while (), etc... -->
+	<!-- 
+	<rule ref="PEAR.ControlStructures.ControlSignature" />
+	-->
 
 	<!-- <rule ref="PEAR.ControlStructures.MultiLineCondition" /> -->
 
 	<!-- Test if () are removed for includes -->
 	<rule ref="PEAR.Files.IncludingFile" />
+
     <!-- Disable some error messages that we do not want. -->
+
     <rule ref="PEAR.Files.IncludingFile.UseInclude">
         <severity>0</severity>
     </rule>
+    <!-- TODO Enable this test. We should use require for include in prior of include when out of if -->
     <rule ref="PEAR.Files.IncludingFile.UseIncludeOnce">
         <severity>0</severity>
     </rule>
     <rule ref="PEAR.Files.IncludingFile.UseRequire">
         <severity>0</severity>
     </rule>
+    <!-- TODO Enable this test. We should use require for include in prior of include when out of if -->
     <rule ref="PEAR.Files.IncludingFile.UseRequireOnce">
         <severity>0</severity>
     </rule>
@@ -334,12 +363,15 @@
 
 	<rule ref="PEAR.Functions.FunctionCallSignature" />
 
+    <!-- TODO Enable this test. -->
     <rule ref="PEAR.Functions.FunctionCallSignature.CloseBracketLine">
         <severity>0</severity>
     </rule>
+    <!-- TODO Enable this test. -->
     <rule ref="PEAR.Functions.FunctionCallSignature.ContentAfterOpenBracket">
         <severity>0</severity>
     </rule>
+   
 	<rule ref="PEAR.Functions.FunctionCallSignature.EmptyLine">
 	    <severity>0</severity>
 	</rule>

+ 1 - 1
dev/translation/autotranslator.class.php

@@ -12,7 +12,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
 /**

+ 1 - 1
dev/translation/autotranslator.php

@@ -13,7 +13,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
 /**

+ 1 - 1
dev/translation/sanity_check_en_langfiles.php

@@ -15,7 +15,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
 $sapi_type = php_sapi_name();

+ 1 - 1
dev/translation/strip_language_file.php

@@ -14,7 +14,7 @@
  * 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/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
  *
  * -----
  *

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

@@ -19,7 +19,7 @@
 
 /**
  * \file 		htdocs/accountancy/admin/account.php
- * \ingroup     Advanced accountancy
+ * \ingroup     Accountancy (Double entries)
  * \brief		List accounting account
  */
 
@@ -247,18 +247,17 @@ if ($resql)
 	print '<input type="hidden" name="page" value="'.$page.'">';
 	print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
 
-	$newcardbutton = '<a class="butActionNew" href="./card.php?action=create"><span class="valignmiddle text-plus-circle">' . $langs->trans("Addanaccount").'</span>';
-	$newcardbutton.= '<span class="fa fa-plus-circle valignmiddle"></span>';
-	$newcardbutton.= '</a>';
+    $newcardbutton.= dolGetButtonTitle($langs->trans("New"), $langs->trans("Addanaccount"), 'fa fa-plus-circle', './card.php?action=create');
 
-	print_barre_liste($langs->trans('ListAccounts'), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit);
+
+    print_barre_liste($langs->trans('ListAccounts'), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit);
 
 	// Box to select active chart of account
     print $langs->trans("Selectchartofaccounts") . " : ";
     print '<select class="flat" name="chartofaccounts" id="chartofaccounts">';
     $sql = "SELECT a.rowid, a.pcg_version, a.label, a.active, c.code as country_code";
     $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_system as a";
-    $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_country as c ON a.fk_country = c.rowid";
+    $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_country as c ON a.fk_country = c.rowid AND c.active = 1";
     $sql .= " WHERE a.active = 1";
     dol_syslog('accountancy/admin/account.php $sql='.$sql);
     print $sql;
@@ -298,7 +297,7 @@ if ($resql)
 	if (! empty($arrayfields['aa.pcg_type']['checked']))		print '<td class="liste_titre"><input type="text" class="flat" size="6" name="search_pcgtype" value="' . $search_pcgtype . '"></td>';
 	if (! empty($arrayfields['aa.pcg_subtype']['checked']))		print '<td class="liste_titre"><input type="text" class="flat" size="6" name="search_pcgsubtype" value="' . $search_pcgsubtype . '"></td>';
 	if (! empty($arrayfields['aa.active']['checked']))			print '<td class="liste_titre">&nbsp;</td>';
-	print '<td class="liste_titre right">';
+	print '<td class="liste_titre maxwidthsearch">';
 	$searchpicto=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1);
 	print $searchpicto;
 	print '</td>';
@@ -390,11 +389,11 @@ if ($resql)
 		{
 			print '<td>';
 			if (empty($obj->active)) {
-				print '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $obj->rowid . '&action=enable">';
+				print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?id=' . $obj->rowid . '&action=enable">';
 				print img_picto($langs->trans("Disabled"), 'switch_off');
 				print '</a>';
 			} else {
-				print '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $obj->rowid . '&action=disable">';
+				print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?id=' . $obj->rowid . '&action=disable">';
 				print img_picto($langs->trans("Activated"), 'switch_on');
 				print '</a>';
 			}

+ 3 - 11
htdocs/accountancy/admin/accountmodel.php

@@ -1,10 +1,10 @@
 <?php
 /* Copyright (C) 2004       Rodolphe Quiedeville    <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2015  Laurent Destailleur     <eldy@users.sourceforge.net>
+ * Copyright (C) 2004-2019  Laurent Destailleur     <eldy@users.sourceforge.net>
  * Copyright (C) 2004       Benoit Mortier          <benoit.mortier@opensides.be>
  * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@inodbox.com>
  * Copyright (C) 2010-2016  Juanjo Menent           <jmenent@2byte.es>
- * Copyright (C) 2011-2018  Philippe Grand          <philippe.grand@atoo-net.com>
+ * Copyright (C) 2011-2019  Philippe Grand          <philippe.grand@atoo-net.com>
  * 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>
@@ -28,7 +28,7 @@
 
 /**
  *	    \file       htdocs/accountancy/admin/accountmodel.php
- *		\ingroup    Advanced accountancy
+ *		\ingroup    Accountancy (Double entries)
  *		\brief      Page to administer model of chart of accounts
  */
 
@@ -462,8 +462,6 @@ $linkback='';
 
 print load_fiche_titre($titre, $linkback, 'title_accountancy');
 
-print "<br>\n";
-
 
 // Confirmation de la suppression de la ligne
 if ($action == 'delete')
@@ -522,7 +520,6 @@ if ($id)
 			if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label')
 			{
 				$valuetoshow=$langs->trans("Label");
-				if ($id != 25) $valuetoshow.="*";
 			}
 			if ($fieldlist[$field]=='country')         {
 				if (in_array('region_id', $fieldlist)) { print '<td>&nbsp;</td>'; continue; }		// For region page, we do not show the country input
@@ -583,10 +580,6 @@ if ($id)
 
 		$colspan=count($fieldlist)+3;
 
-		if (! empty($alabelisused))  // If there is one label among fields, we show legend of *
-		{
-			print '<tr><td colspan="'.$colspan.'">* '.$langs->trans("LabelUsedByDefault").'.</td></tr>';
-		}
 		print '<tr><td colspan="'.$colspan.'">&nbsp;</td></tr>';	// Keep &nbsp; to have a line with enough height
 	}
 
@@ -667,7 +660,6 @@ if ($id)
             }
             if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') {
                 $valuetoshow=$langs->trans("Label");
-                if ($id != 25) $valuetoshow.="*";
             }
             if ($fieldlist[$field]=='country') {
                 $valuetoshow=$langs->trans("Country");

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

@@ -19,7 +19,7 @@
 
 /**
  *  \file       htdocs/accountancy/admin/card.php
- *  \ingroup    Advanced accountancy
+ *  \ingroup    Accountancy (Double entries)
  *  \brief      Card of accounting account
  */
 

+ 1 - 1
htdocs/accountancy/admin/categories.php

@@ -18,7 +18,7 @@
 
 /**
  * \file	htdocs/accountancy/admin/categories.php
- * \ingroup Advanced accountancy
+ * \ingroup Accountancy (Double entries)
  * \brief	Page to assign mass categories to accounts
  */
 

+ 1 - 1
htdocs/accountancy/admin/categories_list.php

@@ -412,7 +412,7 @@ $titlepicto='title_setup';
 
 print load_fiche_titre($titre, $linkback, $titlepicto);
 
-print $langs->trans("AccountingAccountGroupsDesc", $langs->transnoentitiesnoconv("ByPersonalizedAccountGroups")).'<br><br>';
+print '<span class="opacitymedium">'.$langs->trans("AccountingAccountGroupsDesc", $langs->transnoentitiesnoconv("ByPersonalizedAccountGroups")).'</span><br><br>';
 
 // Confirmation de la suppression de la ligne
 if ($action == 'delete')

+ 3 - 4
htdocs/accountancy/admin/closure.php

@@ -18,12 +18,11 @@
 
 /**
  * \file		htdocs/accountancy/admin/closure.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Setup page to configure accounting expert module
  */
-require '../../main.inc.php';
 
-// Class
+require '../../main.inc.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
@@ -89,7 +88,7 @@ llxHeader();
 $linkback = '';
 print load_fiche_titre($langs->trans('MenuClosureAccounts'), $linkback, 'title_accountancy');
 
-print $langs->trans("DefaultClosureDesc").'<br>';
+print '<span class="opacitymedium">'.$langs->trans("DefaultClosureDesc").'</span><br>';
 print '<br>';
 
 print '<form action="' . $_SERVER["PHP_SELF"] . '" method="post">';

+ 2 - 3
htdocs/accountancy/admin/defaultaccounts.php

@@ -24,7 +24,7 @@
 
 /**
  * \file		htdocs/accountancy/admin/defaultaccounts.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Setup page to configure accounting expert module
  */
 require '../../main.inc.php';
@@ -78,7 +78,6 @@ $list_account = array (
 
 $accounting_mode = empty($conf->global->ACCOUNTING_MODE) ? 'RECETTES-DEPENSES' : $conf->global->ACCOUNTING_MODE;
 
-
 if (GETPOST('change_chart', 'alpha'))
 {
     $chartofaccounts = GETPOST('chartofaccounts', 'int');
@@ -132,7 +131,7 @@ llxHeader();
 $linkback = '';
 print load_fiche_titre($langs->trans('MenuDefaultAccounts'), $linkback, 'title_accountancy');
 
-print $langs->trans("DefaultBindingDesc").'<br>';
+print '<span class="opacitymedium">'.$langs->trans("DefaultBindingDesc").'</span><br>';
 print '<br>';
 
 print '<form action="' . $_SERVER["PHP_SELF"] . '" method="post">';

+ 4 - 3
htdocs/accountancy/admin/export.php

@@ -23,7 +23,7 @@
 
 /**
  * \file 		htdocs/accountancy/admin/export.php
- * \ingroup 	Advanced accountancy
+ * \ingroup 	Accountancy (Double entries)
  * \brief 		Setup page to configure accounting expert module
  */
 require '../../main.inc.php';
@@ -76,6 +76,7 @@ $model_option = array (
     ),
 );
 
+
 /*
  * Actions
  */
@@ -138,6 +139,7 @@ $form = new Form($db);
 // $linkback = '<a href="' . DOL_URL_ROOT . '/admin/modules.php?restore_lastsearch_values=1">' . $langs->trans("BackToModuleList") . '</a>';
 print load_fiche_titre($langs->trans('ConfigAccountingExpert'), $linkback, 'title_setup');
 
+
 print "\n".'<script type="text/javascript" language="javascript">'."\n";
 print 'jQuery(document).ready(function () {'."\n";
 print '    function initfields()'."\n";
@@ -195,7 +197,6 @@ print '<tr class="liste_titre">';
 print '<td colspan="3">' . $langs->trans('Options') . '</td>';
 print "</tr>\n";
 
-
 $num = count($main_option);
 if ($num) {
 	foreach ($main_option as $key) {
@@ -236,7 +237,7 @@ if (! $conf->use_javascript_ajax) {
 } else {
 	print '<td>';
 	$listmodelcsv = AccountancyExport::getType();
-	print $form->selectarray("ACCOUNTING_EXPORT_MODELCSV", $listmodelcsv, $conf->global->ACCOUNTING_EXPORT_MODELCSV, 0);
+	print $form->selectarray("ACCOUNTING_EXPORT_MODELCSV", $listmodelcsv, $conf->global->ACCOUNTING_EXPORT_MODELCSV, 0, 0, 0, '', 0, 0, 0, '', '', 1);
 
 	print '</td>';
 }

+ 5 - 10
htdocs/accountancy/admin/fiscalyear.php

@@ -17,7 +17,7 @@
 
 /**
  *  \file       htdocs/accountancy/admin/fiscalyear.php
- *  \ingroup    Advanced accountancy
+ *  \ingroup    Accountancy (Double entries)
  *  \brief      Setup page to configure fiscal year
  */
 
@@ -111,14 +111,9 @@ if ($result)
 
 	$i = 0;
 
-	if (! empty($user->rights->accounting->fiscalyear))
-	{
-		$addbutton = '<a class="butActionNew" href="fiscalyear_card.php?action=create"><span class="valignmiddle text-plus-circle">' . $langs->trans("NewFiscalYear") .'</span><span class="fa fa-plus-circle valignmiddle"></span></a>';
-	}
-	else
-	{
-		$addbutton = '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'"><span class="valignmiddle text-plus-circle">' . $langs->trans("NewFiscalYear") .'</span><span class="fa fa-plus-circle valignmiddle"></span></a>';
-	}
+
+    $addbutton.= dolGetButtonTitle($langs->trans('NewFiscalYear'), '', 'fa fa-plus-circle', 'fiscalyear_card.php?action=create', '', $user->rights->accounting->fiscalyear);
+
 
 	$title = $langs->trans('AccountingPeriods');
 	print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $params, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, $addbutton, '', $limit, 1);
@@ -154,7 +149,7 @@ if ($result)
 			$i++;
 		}
 	} else {
-		print '<tr class="oddeven"><td colspan="5" class="opacitymedium">' . $langs->trans("None") . '</td></tr>';
+		print '<tr class="oddeven"><td colspan="7" class="opacitymedium">' . $langs->trans("None") . '</td></tr>';
 	}
 	print '</table>';
 	print '</div>';

+ 1 - 1
htdocs/accountancy/admin/fiscalyear_card.php

@@ -18,7 +18,7 @@
 
 /**
  * \file        htdocs/accountancy/admin/fiscalyear_card.php
- * \ingroup     Advanced accountancy
+ * \ingroup     Accountancy (Double entries)
  * \brief       Page to show a fiscal year
  */
 

+ 2 - 2
htdocs/accountancy/admin/fiscalyear_info.php

@@ -12,12 +12,12 @@
  * 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, seehttp://www.gnu.org/licenses/>.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /**
  * \file	    htdocs/accountancy/admin/fiscalyear_info.php
- * \ingroup     Advanced accountancy
+ * \ingroup     Accountancy (Double entries)
  * \brief	    Page to show info of a fiscal year
  */
 

+ 0 - 187
htdocs/accountancy/admin/importaccounts.php

@@ -1,187 +0,0 @@
-<?php
-/* Copyright (C) 2013-2014 Olivier Geffroy      <jeff@jeffinfo.com>
- * Copyright (C) 2013-2017 Alexandre Spangaro   <aspangaro@open-dsi.fr>
- * Copyright (C) 2014      Florian Henry        <florian.henry@open-concept.pro>
- * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * 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/admin/importaccounts.php
- * \ingroup		Advanced accountancy
- * \brief 		Page import accounting account
- */
-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 . '/core/class/html.formaccounting.class.php';
-
-// Load translation files required by the page
-$langs->loadLangs(array("compta","bills","accountancy"));
-
-// Security check
-if (! $user->admin)
-	accessforbidden();
-
-$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):(empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION)?$conf->liste_limit:$conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
-$sortfield = GETPOST("sortfield", 'alpha');
-$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
-if (empty($page) || $page == -1) { $page = 0; }     // If $page is not defined, or '' or -1
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-
-
-
-
-/*
- * View
- */
-
-llxHeader('', $langs->trans("ImportAccount"));
-
-$to_import = GETPOST("mesCasesCochees");
-
-if ($_POST["action"] == 'import') {
-	print '<div><font color="red">' . $langs->trans("Processing") . '...</font></div>';
-	if (is_array($to_import) && count($to_import) > 0) {
-		print '<div><font color="red">' . count($to_import) . ' ' . $langs->trans("SelectedLines") . '</font></div>';
-		$sql = 'SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid=' . $conf->global->CHARTOFACCOUNTS;
-
-		$result = $db->query($sql);
-		if ($result && ($db->num_rows($result) > 0)) {
-
-			$obj = $db->fetch_object($result);
-
-			$cpt = 0;
-			foreach ($to_import as $maLigneCochee) {
-
-				$accounting = new AccountingAccount($db);
-
-				$monLabel = (string) GETPOST('label' . $maLigneCochee);
-				$monParentAccount = (string) GETPOST('AccountParent' . $maLigneCochee);
-				$monType = (string) GETPOST('pcgType' . $maLigneCochee);
-				$monSubType = (string) GETPOST('pcgSubType' . $maLigneCochee);
-
-				$accounting->fk_pcg_version = $obj->pcg_version;
-				$accounting->account_number = $maLigneCochee;
-				$accounting->label = $monLabel;
-				$accounting->account_parent = $monParentAccount;
-				$accounting->pcg_type = $monType;
-				$accounting->pcg_subtype = $monSubType;
-				$accounting->active = 1;
-
-				$result = $accounting->create($user);
-				if ($result > 0) {
-					setEventMessages($langs->trans("AccountingAccountAdd"), null, 'mesgs');
-				} else {
-					setEventMessages($accounting->error, $accounting->errors, 'errors');
-				}
-				$cpt ++;
-			}
-		} else {
-			setEventMessages($langs->trans('AccountPlanNotFoundCheckSetting'), null, 'errors');
-		}
-	} else {
-		print '<div><font color="red">' . $langs->trans("AnyLineImport") . '</font></div>';
-	}
-	print '<div><font color="red">' . $langs->trans("EndProcessing") . '</font></div>';
-}
-
-// list accounting account from product
-
-$sql = "(SELECT p.rowid as product_id, p.accountancy_code_sell as accounting ";
-$sql .= " FROM  " . MAIN_DB_PREFIX . "product as p ";
-$sql .= " WHERE p.accountancy_code_sell >=0";
-$sql .= " GROUP BY accounting ";
-$sql .= ")";
-$sql .= "UNION ALL(SELECT p.rowid as product_id, p.accountancy_code_buy as accounting ";
-$sql .= " FROM  " . MAIN_DB_PREFIX . "product as p ";
-$sql .= " WHERE p.accountancy_code_buy >=0";
-$sql .= " GROUP BY accounting ";
-$sql .= ") ";
-$sql .= " ORDER BY accounting DESC " . $db->plimit($limit + 1, $offset);
-
-dol_syslog('accountancy/admin/importaccounts.php:: $sql=' . $sql);
-$result = $db->query($sql);
-if ($result) {
-	$num_lines = $db->num_rows($result);
-	$i = 0;
-	print_barre_liste($langs->trans("ImportAccount"), $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, '', $num_lines);
-
-	print '<form action="' . $_SERVER["PHP_SELF"] . '" method="POST">' . "\n";
-	print '<input type="hidden" name="action" value="import">';
-
-	print '<table class="noborder" width="100%">';
-	print '<tr class="liste_titre"><td>' . $langs->trans("AccountAccouting") . '</td>';
-	print '<td>' . $langs->trans("label") . '</td>';
-	print '<td>' . $langs->trans("Accountparent") . '</td>';
-	print '<td>' . $langs->trans("Pcgtype") . '</td>';
-	print '<td>' . $langs->trans("Pcgsubtype") . '</td>';
-	print '<td class="center">' . $langs->trans("Import") . '</td>';
-	print '</tr>';
-
-	$form = new Form($db);
-	$formaccounting = new FormAccounting($db);
-
-	while ( $i < min($num_lines, $limit) ) {
-		$objp = $db->fetch_object($result);
-		print '<tr class="oddeven">';
-
-		print '<td class="left">';
-		print $objp->accounting;
-		print '</td>';
-
-		print '<td class="left">';
-		print '<input name="label" size="30" value="">';
-		print '</td>';
-
-		// Colonne choix du compte
-		print '<td>';
-		print $formaccounting->select_account($accounting->account_parent, 'AccountParent');
-		print '</td>';
-
-		print '<td>';
-		print '<input type="text" name="pcgType" value="'.dol_escape_htmltag(isset($_POST['pcg_subtype'])?GETPOST('pcg_subtype', 'alpha'):$accounting->pcg_type).'">';
-		print '</td>';
-
-		print '<td>';
-		print '<input type="text" name="pcgSubType" value="'.dol_escape_htmltag(isset($_POST['pcg_subtype'])?GETPOST('pcg_subtype', 'alpha'):$accounting->pcg_subtype).'">';
-		print '</td>';
-
-		// Colonne choix ligne a ventiler
-		$checked = ('label' == 'O') ? ' checked' : '';
-
-		print '<td class="center">';
-		print '<input type="checkbox" name="mesCasesCochees[]" ' . $checked . ' value="' . $objp->accounting . '"/>';
-		print '</td>';
-
-		print '</tr>';
-		$i ++;
-	}
-
-	print '<tr><td colspan="8">&nbsp;</td></tr><tr><td colspan="8" class="center"><input type="submit" class="butAction" value="' . $langs->trans("Import") . '"></td></tr>';
-
-	print '</table>';
-	print '</form>';
-} else {
-	print $db->error();
-}
-
-// End of page
-llxFooter();
-$db->close();

+ 13 - 13
htdocs/accountancy/admin/index.php

@@ -24,7 +24,7 @@
 
 /**
  * \file		htdocs/accountancy/admin/index.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Setup page to configure accounting expert module
  */
 
@@ -214,11 +214,11 @@ if (! empty($user->admin))
     print '<tr class="oddeven">';
     print '<td>' . $langs->trans("ACCOUNTING_LIST_SORT_VENTILATION_TODO") . '</td>';
     if (! empty($conf->global->ACCOUNTING_LIST_SORT_VENTILATION_TODO)) {
-        print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setlistsorttodo&value=0">';
+        print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setlistsorttodo&value=0">';
         print img_picto($langs->trans("Activated"), 'switch_on');
         print '</a></td>';
     } else {
-        print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setlistsorttodo&value=1">';
+        print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setlistsorttodo&value=1">';
         print img_picto($langs->trans("Disabled"), 'switch_off');
         print '</a></td>';
     }
@@ -227,11 +227,11 @@ if (! empty($user->admin))
     print '<tr class="oddeven">';
     print '<td>' . $langs->trans("ACCOUNTING_LIST_SORT_VENTILATION_DONE") . '</td>';
     if (! empty($conf->global->ACCOUNTING_LIST_SORT_VENTILATION_DONE)) {
-        print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setlistsortdone&value=0">';
+        print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setlistsortdone&value=0">';
         print img_picto($langs->trans("Activated"), 'switch_on');
         print '</a></td>';
     } else {
-        print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setlistsortdone&value=1">';
+        print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setlistsortdone&value=1">';
         print img_picto($langs->trans("Disabled"), 'switch_off');
         print '</a></td>';
     }
@@ -240,11 +240,11 @@ if (! empty($user->admin))
 	print '<tr class="oddeven">';
 	print '<td>' . $langs->trans("ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL") . '</td>';
 	if (! empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL)) {
-		print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setenabledraftexport&value=0">';
+		print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setenabledraftexport&value=0">';
 		print img_picto($langs->trans("Activated"), 'switch_on');
 		print '</a></td>';
 	} else {
-		print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setenabledraftexport&value=1">';
+		print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setenabledraftexport&value=1">';
 		print img_picto($langs->trans("Disabled"), 'switch_off');
 		print '</a></td>';
 	}
@@ -253,11 +253,11 @@ if (! empty($user->admin))
 	print '<tr class="oddeven">';
 	print '<td>' . $langs->trans("BANK_DISABLE_DIRECT_INPUT") . '</td>';
 	if (! empty($conf->global->BANK_DISABLE_DIRECT_INPUT)) {
-		print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setdisabledirectinput&value=0">';
+		print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setdisabledirectinput&value=0">';
 		print img_picto($langs->trans("Activated"), 'switch_on');
 		print '</a></td>';
 	} else {
-		print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setdisabledirectinput&value=1">';
+		print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setdisabledirectinput&value=1">';
 		print img_picto($langs->trans("Disabled"), 'switch_off');
 		print '</a></td>';
 	}
@@ -266,11 +266,11 @@ if (! empty($user->admin))
     print '<tr class="oddeven">';
     print '<td>' . $langs->trans("ACCOUNTANCY_COMBO_FOR_AUX") . '</td>';
     if (! empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) {
-        print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setenablesubsidiarylist&value=0">';
+        print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setenablesubsidiarylist&value=0">';
         print img_picto($langs->trans("Activated"), 'switch_on');
         print '</a></td>';
     } else {
-        print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setenablesubsidiarylist&value=1">';
+        print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setenablesubsidiarylist&value=1">';
         print img_picto($langs->trans("Disabled"), 'switch_off');
         print '</a></td>';
     }
@@ -279,11 +279,11 @@ if (! empty($user->admin))
     print '<tr class="oddeven">';
     print '<td>' . $langs->trans("ACCOUNTING_MANAGE_ZERO") . '</td>';
     if (! empty($conf->global->ACCOUNTING_MANAGE_ZERO)) {
-        print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setmanagezero&value=0">';
+        print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setmanagezero&value=0">';
         print img_picto($langs->trans("Activated"), 'switch_on');
         print '</a></td>';
     } else {
-        print '<td class="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=setmanagezero&value=1">';
+        print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?action=setmanagezero&value=1">';
         print img_picto($langs->trans("Disabled"), 'switch_off');
         print '</a></td>';
     }

+ 1 - 1
htdocs/accountancy/admin/journals_list.php

@@ -18,7 +18,7 @@
 
 /**
  * \file		htdocs/accountancy/admin/journals_list.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Setup page to configure journals
  */
 

+ 117 - 40
htdocs/accountancy/admin/productaccount.php

@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2013-2014 Olivier Geffroy      <jeff@jeffinfo.com>
- * Copyright (C) 2013-2016 Alexandre Spangaro   <aspangaro@open-dsi.fr>
+ * Copyright (C) 2013-2019 Alexandre Spangaro   <aspangaro@open-dsi.fr>
  * Copyright (C) 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>
@@ -21,7 +21,7 @@
 
 /**
  * \file		htdocs/accountancy/admin/productaccount.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		To define accounting account on product / service
  */
 require '../../main.inc.php';
@@ -111,6 +111,8 @@ if ($action == 'update') {
 
 		$accounting_product_modes = array (
 				'ACCOUNTANCY_SELL',
+                'ACCOUNTANCY_SELL_INTRA',
+                'ACCOUNTANCY_SELL_EXPORT',
 				'ACCOUNTANCY_BUY'
 		);
 
@@ -158,6 +160,12 @@ if ($action == 'update') {
 					if ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
 						$sql .= " SET accountancy_code_sell = " . $accounting->account_number;
 					}
+                    if ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
+                        $sql .= " SET accountancy_code_sell_intra = " . $accounting->account_number;
+                    }
+                    if ($accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') {
+                        $sql .= " SET accountancy_code_sell_export = " . $accounting->account_number;
+                    }
 					$sql .= " WHERE rowid = " . $productid;
 
 					dol_syslog("/accountancy/admin/productaccount.php sql=" . $sql, LOG_DEBUG);
@@ -192,16 +200,20 @@ $form = new FormAccounting($db);
 // at this time ACCOUNTING_SERVICE_SOLD_ACCOUNT & ACCOUNTING_PRODUCT_SOLD_ACCOUNT are account number not accountingacount rowid
 // so we need to get those default value rowid first
 $accounting = new AccountingAccount($db);
-// TODO: we should need to check if result is a really exist accountaccount rowid.....
-$aarowid_servbuy = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT, 1);
-$aarowid_prodbuy = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT, 1);
-$aarowid_servsell = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT, 1);
-$aarowid_prodsell = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT, 1);
-
-$aacompta_servbuy = (! empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : $langs->trans("CodeNotDef"));
-$aacompta_prodbuy = (! empty($conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT : $langs->trans("CodeNotDef"));
-$aacompta_servsell = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans("CodeNotDef"));
-$aacompta_prodsell = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : $langs->trans("CodeNotDef"));
+// TODO: we should need to check if result is already exists accountaccount rowid.....
+$aarowid_servbuy            = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT, 1);
+$aarowid_prodbuy            = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT, 1);
+$aarowid_servsell           = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT, 1);
+$aarowid_prodsell           = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT, 1);
+$aarowid_prodsell_intra     = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT, 1);
+$aarowid_prodsell_export    = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT, 1);
+
+$aacompta_servbuy           = (! empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : $langs->trans("CodeNotDef"));
+$aacompta_prodbuy           = (! empty($conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT : $langs->trans("CodeNotDef"));
+$aacompta_servsell          = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans("CodeNotDef"));
+$aacompta_prodsell          = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : $langs->trans("CodeNotDef"));
+$aacompta_prodsell_intra    = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT : $langs->trans("CodeNotDef"));
+$aacompta_prodsell_export   = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT : $langs->trans("CodeNotDef"));
 
 llxHeader('', $langs->trans("ProductsBinding"));
 
@@ -209,27 +221,45 @@ $pcgverid = $conf->global->CHARTOFACCOUNTS;
 $pcgvercode = dol_getIdFromCode($db, $pcgverid, 'accounting_system', 'rowid', 'pcg_version');
 if (empty($pcgvercode)) $pcgvercode=$pcgverid;
 
-$sql = "SELECT p.rowid, p.ref, p.label, p.description, p.tosell, p.tobuy, p.accountancy_code_sell, p.accountancy_code_buy, p.tms, p.fk_product_type as product_type,";
+$sql = "SELECT p.rowid, p.ref, p.label, p.description, p.tosell, p.tobuy, p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy, p.tms, p.fk_product_type as product_type,";
 $sql.= " aa.rowid as aaid";
 $sql.= " FROM " . MAIN_DB_PREFIX . "product as p";
 $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON";
 if ($accounting_product_mode == 'ACCOUNTANCY_BUY') {
     $sql.=" p.accountancy_code_buy = aa.account_number AND aa.fk_pcg_version = '" . $pcgvercode . "'";
 }
-else
+elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL')
 {
     $sql.=" p.accountancy_code_sell = aa.account_number AND aa.fk_pcg_version = '" . $pcgvercode . "'";
 }
+elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA')
+{
+    $sql.=" p.accountancy_code_sell_intra = aa.account_number AND aa.fk_pcg_version = '" . $pcgvercode . "'";
+}
+else
+{
+    $sql.=" p.accountancy_code_sell_intra = aa.account_number AND aa.fk_pcg_version = '" . $pcgvercode . "'";
+}
 $sql.= ' WHERE p.entity IN ('.getEntity('product').')';
 if ($accounting_product_mode == 'ACCOUNTANCY_BUY') {
     if (strlen(trim($search_current_account))) {
         $sql .= natural_search("p.accountancy_code_buy", $search_current_account);
     }
-} else {
+} elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
     if (strlen(trim($search_current_account))) {
         $sql .= natural_search("p.accountancy_code_sell", $search_current_account);
     }
 }
+elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
+    if (strlen(trim($search_current_account))) {
+        $sql .= natural_search("p.accountancy_code_sell_intra", $search_current_account);
+    }
+}
+else {
+    if (strlen(trim($search_current_account))) {
+        $sql .= natural_search("p.accountancy_code_sell_export", $search_current_account);
+    }
+}
 if ($search_current_account_valid == 'withoutvalidaccount')
 {
 	$sql .= " AND aa.account_number IS NULL";
@@ -279,6 +309,7 @@ if ($result)
     if ($search_desc > 0) $param.="&search_desc=".urlencode($search_desc);
     if ($search_current_account > 0) $param.="&search_current_account=".urlencode($search_current_account);
     if ($search_current_account_valid && $search_current_account_valid != '-1') $param.="&search_current_account_valid=".urlencode($search_current_account_valid);
+    if ($accounting_product_mode) $param.='&accounting_product_mode='.urlencode($accounting_product_mode);
 
     print '<form action="' . $_SERVER["PHP_SELF"] . '" method="post">';
     if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
@@ -292,7 +323,7 @@ if ($result)
     print load_fiche_titre($langs->trans("ProductsBinding"), '', 'title_accountancy');
 	print '<br>';
 
-	print $langs->trans("InitAccountancyDesc") . '<br>';
+	print '<span class="opacitymedium">'.$langs->trans("InitAccountancyDesc") . '</span><br>';
 	print '<br>';
 
     // Select mode
@@ -300,9 +331,18 @@ if ($result)
 	print '<tr class="liste_titre">';
 	print '<td>' . $langs->trans('Options') . '</td><td>' . $langs->trans('Description') . '</td>';
 	print "</tr>\n";
-	print '<tr class="oddeven"><td class="titlefield"><input type="radio" name="accounting_product_mode" value="ACCOUNTANCY_SELL"' . ($accounting_product_mode != 'ACCOUNTANCY_BUY' ? ' checked' : '') . '> ' . $langs->trans('OptionModeProductSell') . '</td>';
+	print '<tr class="oddeven"><td class="titlefield"><input type="radio" name="accounting_product_mode" value="ACCOUNTANCY_SELL"' . ($accounting_product_mode == 'ACCOUNTANCY_SELL' ? ' checked' : '') . '> ' . $langs->trans('OptionModeProductSell') . '</td>';
 	print '<td>'.$langs->trans('OptionModeProductSellDesc');
 	print "</td></tr>\n";
+	if ($mysoc->isInEEC())
+	{
+        print '<tr class="oddeven"><td class="titlefield"><input type="radio" name="accounting_product_mode" value="ACCOUNTANCY_SELL_INTRA"' . ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA' ? ' checked' : '') . '> ' . $langs->trans('OptionModeProductSellIntra') . '</td>';
+        print '<td>'.$langs->trans('OptionModeProductSellIntraDesc');
+        print "</td></tr>\n";
+	}
+    print '<tr class="oddeven"><td class="titlefield"><input type="radio" name="accounting_product_mode" value="ACCOUNTANCY_SELL_EXPORT"' . ($accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT' ? ' checked' : '') . '> ' . $langs->trans('OptionModeProductSellExport') . '</td>';
+    print '<td>'.$langs->trans('OptionModeProductSellExportDesc');
+    print "</td></tr>\n";
 	print '<tr class="oddeven"><td class="titlefield"><input type="radio" name="accounting_product_mode" value="ACCOUNTANCY_BUY"' . ($accounting_product_mode == 'ACCOUNTANCY_BUY' ? ' checked' : '') . '> ' . $langs->trans('OptionModeProductBuy') . '</td>';
 	print '<td>'.$langs->trans('OptionModeProductBuyDesc')."</td></tr>\n";
 	print "</table>\n";
@@ -317,8 +357,11 @@ if ($result)
 	$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
 	$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);	// This also change content of $arrayfields
 
+    $buttonsave = '<input type="submit" class="button" id="changeaccount" name="changeaccount" value="' . $langs->trans("Save") . '">';
+    //print '<br><div class="center">'.$buttonsave.'</div>';
+
 	$texte=$langs->trans("ListOfProductsServices");
-	print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, '', 0, '', '', $limit);
+	print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $buttonsave, $num, $nbtotalofrecords, '', 0, '', '', $limit);
 
 	print '<div class="div-table-responsive">';
 	print '<table class="liste '.($moreforfilter?"listwithfilterbefore":"").'">';
@@ -328,7 +371,7 @@ if ($result)
 	print '<td class="liste_titre"><input type="text" class="flat" size="10" name="search_label" value="' . dol_escape_htmltag($search_label) . '"></td>';
 	if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC)) print '<td class="liste_titre"><input type="text" class="flat" size="20" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
 	// On sell
-	if ($accounting_product_mode == 'ACCOUNTANCY_SELL') print '<td class="liste_titre"></td>';
+	if ($accounting_product_mode == 'ACCOUNTANCY_SELL' || $accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA' || $accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') print '<td class="liste_titre"></td>';
 	// On buy
 	if ($accounting_product_mode == 'ACCOUNTANCY_BUY') print '<td class="liste_titre"></td>';
 	// Current account
@@ -348,10 +391,19 @@ if ($result)
 	print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder);
 	print_liste_field_titre("Label", $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder);
     if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC)) print_liste_field_titre("Description", $_SERVER["PHP_SELF"], "p.description", "", $param, '', $sortfield, $sortorder);
-    if ($accounting_product_mode == 'ACCOUNTANCY_SELL') print_liste_field_titre("OnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'center ');
-    if ($accounting_product_mode == 'ACCOUNTANCY_BUY')  print_liste_field_titre("OnBuy", $_SERVER["PHP_SELF"], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'center ');
-   	if ($accounting_product_mode == 'ACCOUNTANCY_BUY') $fieldtosortaccount="p.accountancy_code_buy";
-   	else $fieldtosortaccount="p.accountancy_code_sell";
+    if ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
+        print_liste_field_titre("OnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'center ');
+        $fieldtosortaccount="p.accountancy_code_sell";
+    } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
+        print_liste_field_titre("OnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'center ');
+        $fieldtosortaccount="p.accountancy_code_sell_intra";
+    } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') {
+        print_liste_field_titre("OnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'center ');
+        $fieldtosortaccount="p.accountancy_code_sell_export";
+    } else {
+        if ($accounting_product_mode == 'ACCOUNTANCY_BUY')  print_liste_field_titre("OnBuy", $_SERVER["PHP_SELF"], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'center ');
+        $fieldtosortaccount="p.accountancy_code_buy";
+    }
    	print_liste_field_titre("CurrentDedicatedAccountingAccount", $_SERVER["PHP_SELF"], $fieldtosortaccount, "", $param, '', $sortfield, $sortorder);
 	print_liste_field_titre("AssignDedicatedAccountingAccount");
 	$clickpitco=$form->showCheckAddButtons('checkforselect', 1);
@@ -374,10 +426,16 @@ if ($result)
 		$product_static->status = $obj->tosell;
 		$product_static->status_buy = $obj->tobuy;
 
-		if ($obj->product_type == 0) {
+		if ($obj->product_type == 0 && $accounting_product_mode == 'ACCOUNTANCY_SELL') {
 			$compta_prodsell = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : $langs->trans("CodeNotDef"));
 			$compta_prodsell_id = $aarowid_prodsell;
-		} else {
+		} elseif ($obj->product_type == 0 && $accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
+            $compta_prodsell = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT : $langs->trans("CodeNotDef"));
+            $compta_prodsell_id = $aarowid_prodsell_intra;
+        } elseif ($obj->product_type == 0 && $accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') {
+            $compta_prodsell = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT : $langs->trans("CodeNotDef"));
+            $compta_prodsell_id = $aarowid_prodsell_export;
+        } else {
 			$compta_prodsell = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans("CodeNotDef"));
 			$compta_prodsell_id = $aarowid_servsell;
 		}
@@ -407,7 +465,7 @@ if ($result)
     		print '<td style="' . $code_sell_p_l_differ . '">' . nl2br(dol_trunc($obj->description, $trunclengh)) . '</td>';
 		}
 
-		if ($accounting_product_mode == 'ACCOUNTANCY_SELL')
+		if ($accounting_product_mode == 'ACCOUNTANCY_SELL' || $accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA' || $accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT')
 			print '<td class="center">'.$product_static->getLibStatut(3, 0).'</td>';
 
 		if ($accounting_product_mode == 'ACCOUNTANCY_BUY')
@@ -418,12 +476,16 @@ if ($result)
 		if ($accounting_product_mode == 'ACCOUNTANCY_BUY') {
 		    print length_accountg($obj->accountancy_code_buy);
 		    if ($obj->accountancy_code_buy && empty($obj->aaid)) print ' '.img_warning($langs->trans("ValueNotIntoChartOfAccount"));
-		}
-		else
-		{
-		    print length_accountg($obj->accountancy_code_sell);
-		    if ($obj->accountancy_code_sell && empty($obj->aaid)) print ' '.img_warning($langs->trans("ValueNotIntoChartOfAccount"));
-		}
+		} elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
+            print length_accountg($obj->accountancy_code_sell);
+            if ($obj->accountancy_code_sell && empty($obj->aaid)) print ' '.img_warning($langs->trans("ValueNotIntoChartOfAccount"));
+        } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
+		    print length_accountg($obj->accountancy_code_sell_intra);
+		    if ($obj->accountancy_code_sell_intra && empty($obj->aaid)) print ' '.img_warning($langs->trans("ValueNotIntoChartOfAccount"));
+		} else {
+            print length_accountg($obj->accountancy_code_sell_export);
+            if ($obj->accountancy_code_sell_export && empty($obj->aaid)) print ' '.img_warning($langs->trans("ValueNotIntoChartOfAccount"));
+        }
 		print '</td>';
 
 		// Dedicated account
@@ -437,7 +499,7 @@ if ($result)
 			if (! empty($obj->aaid)) $defaultvalue = '';     // Do not suggest default new value is code is already valid
 			print $form->select_account($defaultvalue, 'codeventil_' . $product_static->id, 1, array(), 1);
 			print '</td>';
-		} else {
+		} elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
 			// Accounting account sell
 			print '<td class="left">';
 			//$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha');        This is id and we need a code
@@ -447,7 +509,26 @@ if ($result)
 			if (! empty($obj->aaid)) $defaultvalue = '';     // Do not suggest default new value is code is already valid
 			print $form->select_account($defaultvalue, 'codeventil_' . $product_static->id, 1, array(), 1);
 			print '</td>';
-		}
+		} elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
+            // Accounting account sell intra (In EEC)
+            print '<td class="left">';
+            //$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha');        This is id and we need a code
+            if (empty($defaultvalue)) $defaultvalue=$compta_prodsell;
+            $codesell=length_accountg($obj->accountancy_code_sell_intra);
+            //var_dump($defaultvalue.' - '.$codesell.' - '.$compta_prodsell);
+            if (! empty($obj->aaid)) $defaultvalue = '';     // Do not suggest default new value is code is already valid
+            print $form->select_account($defaultvalue, 'codeventil_' . $product_static->id, 1, array(), 1);
+            print '</td>';
+        } else {
+            // Accounting account sell export (Out of EEC)
+            print '<td class="left">';
+            //$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha');        This is id and we need a code
+            if (empty($defaultvalue)) $defaultvalue=$compta_prodsell;
+            $codesell=length_accountg($obj->accountancy_code_sell_export);
+            if (! empty($obj->aaid)) $defaultvalue = '';     // Do not suggest default new value is code is already valid
+            print $form->select_account($defaultvalue, 'codeventil_' . $product_static->id, 1, array(), 1);
+            print '</td>';
+        }
 
 		// Checkbox select
 		print '<td class="center">';
@@ -458,7 +539,6 @@ if ($result)
 	print '</table>';
 	print '</div>';
 
-	// Example : Adding jquery code
 	print '<script type="text/javascript" language="javascript">
         jQuery(document).ready(function() {
         	function init_savebutton()
@@ -473,8 +553,8 @@ if ($result)
 
 	            if (atleastoneselected) jQuery("#changeaccount").removeAttr(\'disabled\');
 	            else jQuery("#changeaccount").attr(\'disabled\',\'disabled\');
-	            if (atleastoneselected) jQuery("#changeaccount").attr(\'class\',\'butAction\');
-	            else jQuery("#changeaccount").attr(\'class\',\'butActionRefused\');
+	            if (atleastoneselected) jQuery("#changeaccount").attr(\'class\',\'button\');
+	            else jQuery("#changeaccount").attr(\'class\',\'button\');
         	}
         	jQuery(".checkforselect, #checkallactions").click(function() {
         		init_savebutton();
@@ -492,9 +572,6 @@ if ($result)
         });
         </script>';
 
-
-	print '<br><div class="center"><input type="submit" class="butAction" id="changeaccount" name="changeaccount" value="' . $langs->trans("Save") . '"></div>';
-
 	print '</form>';
 
 	$db->free($result);

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

@@ -21,7 +21,7 @@
 
 /**
  *  \file 		htdocs/accountancy/bookkeeping/balance.php
- *  \ingroup 	Advanced accountancy
+ *  \ingroup 	Accountancy (Double entries)
  *  \brief 		Balance of book keeping
  */
 

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

@@ -21,7 +21,7 @@
 
 /**
  * \file		htdocs/accountancy/bookkeeping/balancebymonth.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Balance by month
  */
 require '../../main.inc.php';

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

@@ -21,7 +21,7 @@
 
 /**
  * \file		htdocs/accountancy/bookkeeping/card.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Page to show book-entry
  */
 
@@ -373,7 +373,7 @@ if ($action == 'create')
 
 	print '<tr>';
 	print '<td>' . $langs->trans("Piece") . '</td>';
-	print '<td><input type="text" class="minwidth200" name="doc_ref" value=""/></td>';
+	print '<td><input type="text" class="minwidth200" name="doc_ref" value="'.GETPOST('doc_ref', 'alpha').'"></td>';
 	print '</tr>';
 
 	/*
@@ -531,11 +531,11 @@ if ($action == 'create')
 		print '<td class="titlefield">' . $langs->trans("Status") . '</td>';
 		print '<td>';
 			if (empty($object->validated)) {
-				print '<a href="' . $_SERVER["PHP_SELF"] . '?piece_num=' . $line->rowid . '&action=enable">';
+				print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?piece_num=' . $line->rowid . '&action=enable">';
 				print img_picto($langs->trans("Disabled"), 'switch_off');
 				print '</a>';
 			} else {
-				print '<a href="' . $_SERVER["PHP_SELF"] . '?piece_num=' . $line->rowid . '&action=disable">';
+				print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?piece_num=' . $line->rowid . '&action=disable">';
 				print img_picto($langs->trans("Activated"), 'switch_on');
 				print '</a>';
 			}
@@ -615,23 +615,23 @@ if ($action == 'create')
 
 					if ($action == 'update' && $line->id == $id) {
 						print '<td>';
-						print $formaccounting->select_account($line->numero_compte, 'accountingaccount_number', 1, array (), 1, 1, '');
+						print $formaccounting->select_account((GETPOSTISSET("accountingaccount_number") ? GETPOST("accountingaccount_number", "alpha") : $line->numero_compte), 'accountingaccount_number', 1, array (), 1, 1, '');
 						print '</td>';
 						print '<td>';
 						// TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because it does not
 						// use setup of keypress to select thirdparty and this hang browser on large database.
 						if (! empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX))
 						{
-							print $formaccounting->select_auxaccount($line->subledger_account, 'subledger_account', 1);
+							print $formaccounting->select_auxaccount((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1);
 						}
 						else
 						{
-							print '<input type="text" name="subledger_account" value="'.$line->subledger_account.'">';
+							print '<input type="text" class="maxwidth150" name="subledger_account" value="'.(GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account).'">';
 						}
 						print '</td>';
-						print '<td><input type="text" class="minwidth200" name="label_operation" value="' . $line->label_operation. '"/></td>';
-						print '<td class="right"><input type="text" size="6" class="right" name="debit" value="' . price($line->debit) . '"/></td>';
-						print '<td class="right"><input type="text" size="6" class="right" name="credit" value="' . price($line->credit) . '"/></td>';
+						print '<td><input type="text" class="minwidth200" name="label_operation" value="' . (GETPOSTISSET("label_operation") ? GETPOST("label_operation", "alpha") : $line->label_operation). '"></td>';
+						print '<td class="right"><input type="text" size="6" class="right" name="debit" value="' . (GETPOSTISSET("debit") ? GETPOST("debit", "alpha") : price($line->debit)) . '"></td>';
+						print '<td class="right"><input type="text" size="6" class="right" name="credit" value="' . (GETPOSTISSET("credit") ? GETPOST("credit", "alpha") : price($line->credit)) . '"></td>';
 						print '<td>';
 						print '<input type="hidden" name="id" value="' . $line->id . '">' . "\n";
 						print '<input type="submit" class="button" name="update" value="' . $langs->trans("Update") . '">';
@@ -672,21 +672,21 @@ if ($action == 'create')
 				if ($action == "" || $action == 'add') {
 					print '<tr class="oddeven">';
 					print '<td>';
-					print $formaccounting->select_account($accountingaccount_number, 'accountingaccount_number', 1, array (), 1, 1, '');
+					print $formaccounting->select_account('', 'accountingaccount_number', 1, array (), 1, 1, '');
 					print '</td>';
 					print '<td>';
 					// TODO For the moment we keep a fre input text instead of a combo. The select_auxaccount has problem because it does not
 					// use setup of keypress to select thirdparty and this hang browser on large database.
 					if (! empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX))
 					{
-						print $formaccounting->select_auxaccount($subledger_account, 'subledger_account', 1);
+						print $formaccounting->select_auxaccount('', 'subledger_account', 1);
 					}
 					else
 					{
-						print '<input type="text" name="subledger_account" value="">';
+						print '<input type="text" class="maxwidth150" name="subledger_account" value="">';
 					}
 					print '</td>';
-					print '<td><input type="text" class="minwidth200" name="label_operation" value=""/></td>';
+					print '<td><input type="text" class="minwidth200" name="label_operation" value="'.$label_operation.'"/></td>';
 					print '<td class="right"><input type="text" size="6" class="right" name="debit" value=""/></td>';
 					print '<td class="right"><input type="text" size="6" class="right" name="credit" value=""/></td>';
 					print '<td><input type="submit" class="button" name="save" value="' . $langs->trans("Add") . '"></td>';

+ 123 - 44
htdocs/accountancy/bookkeeping/list.php

@@ -21,7 +21,7 @@
 
 /**
  * \file		htdocs/accountancy/bookkeeping/list.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief 		List operation of book keeping
  */
 require '../../main.inc.php';
@@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php
 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
+require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php';
 
 // Load translation files required by the page
 $langs->loadLangs(array("accountancy"));
@@ -47,6 +48,9 @@ $search_date_creation_start = dol_mktime(0, 0, 0, GETPOST('date_creation_startmo
 $search_date_creation_end = dol_mktime(0, 0, 0, GETPOST('date_creation_endmonth', 'int'), GETPOST('date_creation_endday', 'int'), GETPOST('date_creation_endyear', 'int'));
 $search_date_modification_start = dol_mktime(0, 0, 0, GETPOST('date_modification_startmonth', 'int'), GETPOST('date_modification_startday', 'int'), GETPOST('date_modification_startyear', 'int'));
 $search_date_modification_end = dol_mktime(0, 0, 0, GETPOST('date_modification_endmonth', 'int'), GETPOST('date_modification_endday', 'int'), GETPOST('date_modification_endyear', 'int'));
+$search_date_export_start = dol_mktime(0, 0, 0, GETPOST('date_export_startmonth', 'int'), GETPOST('date_export_startday', 'int'), GETPOST('date_export_startyear', 'int'));
+$search_date_export_end = dol_mktime(0, 0, 0, GETPOST('date_export_endmonth', 'int'), GETPOST('date_export_endday', 'int'), GETPOST('date_export_endyear', 'int'));
+
 //var_dump($search_date_start);exit;
 if (GETPOST("button_delmvt_x") || GETPOST("button_delmvt.x") || GETPOST("button_delmvt")) {
 	$action = 'delbookkeepingyear';
@@ -143,6 +147,7 @@ $arrayfields=array(
 	't.code_journal'=>array('label'=>$langs->trans("Codejournal"), 'checked'=>1),
 	't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0),
 	't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0),
+    't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1),
 );
 
 if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) unset($arrayfields['t.lettering_code']);
@@ -178,6 +183,8 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
 	$search_date_creation_end = '';
 	$search_date_modification_start = '';
 	$search_date_modification_end = '';
+    $search_date_export_start = '';
+    $search_date_export_end = '';
 	$search_debit = '';
 	$search_credit = '';
 	$search_lettering_code = '';
@@ -269,6 +276,16 @@ if (! empty($search_date_modification_end)) {
 	$tmp=dol_getdate($search_date_modification_end);
 	$param .= '&date_modification_endmonth=' . $tmp['mon'] . '&date_modification_endday=' . $tmp['mday'] . '&date_modification_endyear=' . $tmp['year'];
 }
+if (! empty($search_date_export_start)) {
+    $filter['t.date_export>='] = $search_date_export_start;
+    $tmp=dol_getdate($search_date_export_start);
+    $param .= '&date_export_startmonth=' . $tmp['mon'] . '&date_export_startday=' . $tmp['mday'] . '&date_export_startyear=' . $tmp['year'];
+}
+if (! empty($search_date_export_end)) {
+    $filter['t.date_export<='] = $search_date_export_end;
+    $tmp=dol_getdate($search_date_export_end);
+    $param .= '&date_export_endmonth=' . $tmp['mon'] . '&date_export_endday=' . $tmp['mday'] . '&date_export_endyear=' . $tmp['year'];
+}
 if (! empty($search_debit)) {
 	$filter['t.debit'] = $search_debit;
 	$param .= '&search_debit=' . urlencode($search_debit);
@@ -292,8 +309,10 @@ if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->suppri
 		if ($result < 0) {
 			setEventMessages($object->error, $object->errors, 'errors');
 		}
-		Header("Location: list.php");
-		exit();
+
+		// Make a redirect to avoid to launch the delete later after a back button
+		header("Location: list.php".($param?'?'.$param:''));
+		exit;
 	}
 }
 if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) {
@@ -317,14 +336,14 @@ if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouveme
 		{
 			setEventMessages("RecordDeleted", null, 'mesgs');
 		}
-		Header("Location: list.php");
+
+		// Make a redirect to avoid to launch the delete later after a back button
+		header("Location: list.php".($param?'?'.$param:''));
 		exit;
 	}
 	else
 	{
 		setEventMessages("NoRecordDeleted", null, 'warnings');
-		Header("Location: list.php");
-		exit;
 	}
 }
 if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->supprimer) {
@@ -341,7 +360,7 @@ if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->suppri
 			setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
 		}
 
-		Header("Location: list.php?noreset=1".($param?'&'.$param:''));
+		header("Location: list.php?noreset=1".($param?'&'.$param:''));
 		exit;
 	}
 }
@@ -349,7 +368,7 @@ if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->suppri
 // Export into a file with format defined into setup (FEC, CSV, ...)
 if ($action == 'export_file' && $user->rights->accounting->mouvements->export) {
 
-	$result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter);
+	$result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter, 'AND', $conf->global->ACCOUNTING_REEXPORT);
 
 	if ($result < 0)
 	{
@@ -357,17 +376,57 @@ if ($action == 'export_file' && $user->rights->accounting->mouvements->export) {
 	}
 	else
 	{
+	    // Export files
 		$accountancyexport = new AccountancyExport($db);
 		$accountancyexport->export($object->lines);
 
-		if (!empty($accountancyexport->errors))
-		{
-			setEventMessages('', $accountancyexport->errors, 'errors');
-		}
+        if (! empty($accountancyexport->errors))
+        {
+            setEventMessages('', $accountancyexport->errors, 'errors');
+        } else {
+            // Specify as export : update field date_export
+            // TODO Move in class bookKeeping
+            $error=0;
+            $db->begin();
+
+            if (is_array($object->lines)) {
+                foreach ($object->lines as $movement) {
+                    $now = dol_now();
+                    $sql = " UPDATE " . MAIN_DB_PREFIX . "accounting_bookkeeping";
+                    $sql .= " SET date_export = '" . $db->idate($now) . "'";
+                    $sql .= " WHERE rowid = " . $movement->id;
+
+                    dol_syslog("/accountancy/bookeeping/list.php Function export_file Specify movements as exported sql=" . $sql, LOG_DEBUG);
+                    $result = $db->query($sql);
+                    if ($result) {
+                        $db->commit();
+                        // setEventMessages($langs->trans("AllExportedMovementsWereRecordedAsExported"), null, 'mesgs');
+                    } else {
+                        $db->rollback();
+                        // setEventMessages($langs->trans("NotAllExportedMovementsCouldBeRecordedAsExported"), null, 'errors');
+                    }
+                }
+            }
+        }
 		exit;
 	}
 }
 
+if ($action == 'setreexport') {
+    $export = 0;
+    $setreexport = GETPOST('value', 'int');
+    if (! dolibarr_set_const($db, "ACCOUNTING_REEXPORT", $setreexport, 'yesno', 0, '', $conf->entity)) $error++;
+
+    if (! $error) {
+        if ($conf->global->ACCOUNTING_REEXPORT == 1) {
+            setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsEnable"), null, 'mesgs');
+        } else {
+            setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsDisable"), null, 'mesgs');
+        }
+    } else {
+        setEventMessages($langs->trans("Error"), null, 'errors');
+    }
+}
 
 /*
  * View
@@ -380,14 +439,14 @@ llxHeader('', $title_page);
 // List
 $nbtotalofrecords = '';
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
-	$nbtotalofrecords = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter);
+	$nbtotalofrecords = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter, 'AND', $conf->global->ACCOUNTING_REEXPORT);
 	if ($nbtotalofrecords < 0) {
 		setEventMessages($object->error, $object->errors, 'errors');
 	}
 }
 
 // TODO Do not use this
-$result = $object->fetchAll($sortorder, $sortfield, $limit, $offset, $filter);
+$result = $object->fetchAll($sortorder, $sortfield, $limit, $offset, $filter, 'AND', $conf->global->ACCOUNTING_REEXPORT);
 if ($result < 0) {
 	setEventMessages($object->error, $object->errors, 'errors');
 }
@@ -425,7 +484,7 @@ if ($action == 'delbookkeepingyear') {
 			'default' => $deljournal
 	);
 
-	$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt'), 'delbookkeepingyearconfirm', $form_question, 0, 1, 250);
+	$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt'), 'delbookkeepingyearconfirm', $form_question, 0, 1, 250);
 	print $formconfirm;
 }
 
@@ -442,32 +501,27 @@ print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
 print '<input type="hidden" name="page" value="'.$page.'">';
 
-if ($user->rights->accounting->mouvements->export) {
-    $listofformat=AccountancyExport::getType();
-    $button = '<a class="butAction" name="button_export_file" href="'.$_SERVER["PHP_SELF"].'?action=export_file'.($param?'&'.$param:'').'" title="'.$listofformat[$conf->global->ACCOUNTING_EXPORT_MODELCSV].'">';
-    if (count($filter)) $button.= $langs->trans("ExportFilteredList");
-    else $button.= $langs->trans("ExportList");
-    $button.= '</a>';
-} else {
-    $button = '<span class="butActionRefused" title="' . $langs->trans("NotEnoughPermissions") . '">';
-    if (count($filter)) $button.= $langs->trans("ExportFilteredList");
-    else $button.= $langs->trans("ExportList");
-    $button.= '</span>';
-}
+$button .= '<a class="butAction" title="" name="button_export_file" href="'.$_SERVER["PHP_SELF"].'?action=export_file'.($param?'&'.$param:'').'">';
 
-$groupby = ' <a class="nohover marginrightonly" href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param.'">' . $langs->trans("GroupByAccountAccounting") . '</a>';
+$listofformat=AccountancyExport::getType();
+if (count($filter)) $buttonLabel = $langs->trans("ExportFilteredList");
+else $buttonLabel = $langs->trans("ExportList");
 
-if ($user->rights->accounting->mouvements->creer) {
-    $newcardbutton = '<a class="butActionNew" href="./card.php?action=create"><span class="valignmiddle text-plus-circle">'.$langs->trans("NewAccountingMvt").'</span>';
-    $newcardbutton.= '<span class="fa fa-plus-circle valignmiddle"></span>';
-    $newcardbutton.= '</a>';
+// Button re-export
+if (! empty($conf->global->ACCOUNTING_REEXPORT)) {
+    $newcardbutton ='<a href="'.$_SERVER['PHP_SELF'].'?action=setreexport&value=0'.($param?'&'.$param:'').'">'.img_picto($langs->trans("Activated"), 'switch_on').'</a> ';
 } else {
-    $newcardbutton = '<span class="butActionRefused" title="' . $langs->trans("NotEnoughPermissions") . '"><span class="valignmiddle text-plus-circle">' . $langs->trans("NewAccountingMvt") . '</span>';
-    $newcardbutton.= '<span class="fa fa-plus-circle valignmiddle"></span>';
-    $newcardbutton.= '</span>';
+    $newcardbutton ='<a href="'.$_SERVER['PHP_SELF'].'?action=setreexport&value=1'.($param?'&'.$param:'').'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a> ';
 }
+$newcardbutton.= '<span class="valignmiddle marginrightonly">'.$langs->trans("IncludeDocsAlreadyExported").'</span>';
+
+$newcardbutton.= dolGetButtonTitle($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$conf->global->ACCOUNTING_EXPORT_MODELCSV].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file'.($param?'&'.$param:''), $user->rights->accounting->mouvements->export);
+
+$newcardbutton.= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param);
 
-print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $button, $result, $nbtotalofrecords, 'title_accountancy', 0, $groupby.$newcardbutton, '', $limit);
+$newcardbutton.= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', './card.php?action=create', '', $user->rights->accounting->mouvements->creer);
+
+print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit);
 
 $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
 $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);	// This also change content of $arrayfields
@@ -530,7 +584,7 @@ if (! empty($arrayfields['t.subledger_account']['checked']))
 	}
 	else
 	{
-		print '<input type="text" name="search_accountancy_aux_code_start" value="'.$search_accountancy_aux_code_start.'">';
+		print '<input type="text" class="maxwidth100" name="search_accountancy_aux_code_start" value="'.$search_accountancy_aux_code_start.'">';
 	}
 	print '</div>';
 	print '<div class="nowrap">';
@@ -543,7 +597,7 @@ if (! empty($arrayfields['t.subledger_account']['checked']))
 	}
 	else
 	{
-		print '<input type="text" name="search_accountancy_aux_code_end" value="'.$search_accountancy_aux_code_end.'">';
+		print '<input type="text" class="maxwidth100" name="search_accountancy_aux_code_end" value="'.$search_accountancy_aux_code_end.'">';
 	}
 	print '</div>';
 	print '</td>';
@@ -609,6 +663,20 @@ if (! empty($arrayfields['t.tms']['checked']))
 	print '</div>';
 	print '</td>';
 }
+// Date export
+if (! empty($arrayfields['t.date_export']['checked']))
+{
+    print '<td class="liste_titre center">';
+    print '<div class="nowrap">';
+    print $langs->trans('From') . ' ';
+    print $form->selectDate($search_date_export_start, 'date_export_start', 0, 0, 1);
+    print '</div>';
+    print '<div class="nowrap">';
+    print $langs->trans('to') . ' ';
+    print $form->selectDate($search_date_export_end, 'date_export_end', 0, 0, 1);
+    print '</div>';
+    print '</td>';
+}
 // Action column
 print '<td class="liste_titre center">';
 $searchpicto=$form->showFilterButtons();
@@ -629,6 +697,7 @@ if (! empty($arrayfields['t.lettering_code']['checked']))		print_liste_field_tit
 if (! empty($arrayfields['t.code_journal']['checked']))			print_liste_field_titre($arrayfields['t.code_journal']['label'], $_SERVER['PHP_SELF'], "t.code_journal", "", $param, '', $sortfield, $sortorder, 'center ');
 if (! empty($arrayfields['t.date_creation']['checked']))		print_liste_field_titre($arrayfields['t.date_creation']['label'], $_SERVER['PHP_SELF'], "t.date_creation", "", $param, '', $sortfield, $sortorder, 'center ');
 if (! empty($arrayfields['t.tms']['checked']))					print_liste_field_titre($arrayfields['t.tms']['label'], $_SERVER['PHP_SELF'], "t.tms", "", $param, '', $sortfield, $sortorder, 'center ');
+if (! empty($arrayfields['t.date_export']['checked']))          print_liste_field_titre($arrayfields['t.date_export']['label'], $_SERVER['PHP_SELF'], "t.date_export", "", $param, '', $sortfield, $sortorder, 'center ');
 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
 print "</tr>\n";
 
@@ -741,16 +810,26 @@ if ($num > 0)
 			if (! $i) $totalarray['nbfield']++;
 		}
 
+        // Exported operation date
+        if (! empty($arrayfields['t.date_export']['checked']))
+        {
+            print '<td align="center">' . dol_print_date($line->date_export, 'dayhour') . '</td>';
+            if (! $i) $totalarray['nbfield']++;
+        }
+
 		// Action column
 		print '<td class="nowraponall center">';
-        if ($user->rights->accounting->mouvements->creer) {
-            print '<a href="' . DOL_URL_ROOT . '/accountancy/bookkeeping/card.php?piece_num=' . $line->piece_num . $param . '&page=' . $page . ($sortfield ? '&sortfield=' . $sortfield : '') . ($sortorder ? '&sortorder=' . $sortorder : '') . '">' . img_edit() . '</a>';
-        }
-		if ($user->rights->accounting->mouvements->supprimer) {
-            print '&nbsp;<a href="' . $_SERVER['PHP_SELF'] . '?action=delmouv&mvt_num=' . $line->piece_num . $param . '&page=' . $page . ($sortfield ? '&sortfield=' . $sortfield : '') . ($sortorder ? '&sortorder=' . $sortorder : '') . '">' . img_delete() . '</a>';
+        if (empty($line->date_export)) {
+          if ($user->rights->accounting->mouvements->creer) {
+              print '<a href="' . DOL_URL_ROOT . '/accountancy/bookkeeping/card.php?piece_num=' . $line->piece_num . $param . '&page=' . $page . ($sortfield ? '&sortfield=' . $sortfield : '') . ($sortorder ? '&sortorder=' . $sortorder : '') . '">' . img_edit() . '</a>';
+          }
+          if ($user->rights->accounting->mouvements->supprimer) {
+              print '&nbsp;<a href="' . $_SERVER['PHP_SELF'] . '?action=delmouv&mvt_num=' . $line->piece_num . $param . '&page=' . $page . ($sortfield ? '&sortfield=' . $sortfield : '') . ($sortorder ? '&sortorder=' . $sortorder : '') . '">' . img_delete() . '</a>';
+          }
         }
 		print '</td>';
-		if (! $i) $totalarray['nbfield']++;
+
+    if (! $i) $totalarray['nbfield']++;
 
 		print "</tr>\n";
 

+ 4 - 6
htdocs/accountancy/bookkeeping/listbyaccount.php

@@ -21,7 +21,7 @@
 
 /**
  * \file 		htdocs/accountancy/bookkeeping/listbyaccount.php
- * \ingroup 	Advanced accountancy
+ * \ingroup 	Accountancy (Double entries)
  * \brief 		List operation of book keeping ordered by account number
  */
 
@@ -256,10 +256,8 @@ if ($action == 'delbookkeepingyear') {
 
 print '<form method="POST" id="searchFormList" action="' . $_SERVER["PHP_SELF"] . '">';
 
-$viewflat = ' <a class="nohover marginrightonly" href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param.'">' . $langs->trans("ViewFlatList") . '</a>';
-$newcardbutton = '<a class="butActionNew" href="./card.php?action=create"><span class="valignmiddle text-plus-circle">'.$langs->trans("NewAccountingMvt").'</span>';
-$newcardbutton.= '<span class="fa fa-plus-circle valignmiddle"></span>';
-$newcardbutton.= '</a>';
+$newcardbutton.= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param);
+$newcardbutton.= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', './card.php?action=create');
 
 if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage);
 if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit);
@@ -350,7 +348,7 @@ while ($i < min($num, $limit))
 		$colspan = 9;
 		print "<tr>";
 		print '<td colspan="'.$colspan.'" style="font-weight:bold; border-bottom: 1pt solid black;">';
-		if (! empty($line->numero_compte) && $line->numero_compte != '-1') print length_accountg($line->numero_compte) . ' : ' . $object->get_compte_desc($line->numero_compte);
+		if ($line->numero_compte != "" && $line->numero_compte != '-1') print length_accountg($line->numero_compte) . ' : ' . $object->get_compte_desc($line->numero_compte);
 		else print '<span class="error">'.$langs->trans("Unknown").'</span>';
 		print '</td>';
 		print '</tr>';

+ 97 - 60
htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php

@@ -3,8 +3,8 @@
  * Copyright (C) 2005      Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2013      Olivier Geffroy      <jeff@jeffinfo.com>
  * Copyright (C) 2013      Florian Henry	    <florian.henry@open-concept.pro>
- * Copyright (C) 2013-2018 Alexandre Spangaro      <aspangaro@open-dsi.fr>
- * Copyright (C) 2018      Frédéric France         <frederic.france@netlogic.fr>
+ * Copyright (C) 2013-2019 Alexandre Spangaro   <aspangaro@open-dsi.fr>
+ * Copyright (C) 2018-2019 Frédéric France      <frederic.france@netlogic.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,17 +30,19 @@ require '../../main.inc.php';
 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php';
 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
+require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php';
 require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
 
 // Load translation files required by the page
 $langs->loadLangs(array("compta","accountancy"));
 
-$action = GETPOST('action', 'aZ09');
+$action     = GETPOST('action', 'aZ09');
 $massaction = GETPOST('massaction', 'alpha');
 $show_files = GETPOST('show_files', 'int');
-$confirm = GETPOST('confirm', 'alpha');
-$toselect = GETPOST('toselect', 'array');
+$confirm    = GETPOST('confirm', 'alpha');
+$toselect   = GETPOST('toselect', 'array');
+$socid      = GETPOST('socid', 'int')?GETPOST('socid', 'int'):GETPOST('id', 'int');
 
 $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
 $sortfield = GETPOST("sortfield", 'alpha');
@@ -53,26 +55,31 @@ $offset = $limit * $page;
 $pageprev = $page - 1;
 $pagenext = $page + 1;
 if ($sortorder == "")
-	$sortorder = "DESC";
+	$sortorder = "ASC";
 if ($sortfield == "")
 	$sortfield = "bk.doc_date";
 
-$search_year = GETPOST("search_year", 'int');
-$search_doc_type = GETPOST("search_doc_type", 'alpha');
+/*
+$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
+$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
+//$search_doc_type = GETPOST("search_doc_type", 'alpha');
 $search_doc_ref = GETPOST("search_doc_ref", 'alpha');
+*/
 
 $lettering = GETPOST('lettering', 'alpha');
 if (! empty($lettering)) {
 	$action = $lettering;
 }
 
-// Did we click on purge search criteria ?
-// All tests are required to be compatible with all browsers
-if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
-	$search_year = '';
-	$search_doc_type = '';
+/*
+if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers
+{
+    $search_date_start = '';
+    $search_date_end = '';
+	//$search_doc_type = '';
 	$search_doc_ref = '';
 }
+*/
 
 // Security check
 $socid = GETPOST("socid", 'int');
@@ -102,6 +109,7 @@ if ($action == 'lettering') {
 	}
 }
 
+/*
 if ($action == 'autolettrage') {
 
 	$result = $lettering->letteringThirdparty($socid);
@@ -111,9 +119,9 @@ if ($action == 'autolettrage') {
 		$error++;
 	}
 }
+*/
 
-
-	/*
+/*
  * View
  */
 
@@ -136,19 +144,17 @@ dol_banner_tab($object, 'socid', $linkback, ($user->societe_id?0:1), 'rowid', 'n
 
 dol_fiche_end();
 
-print '<br>';
-
 $sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, ";
 $sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, ";
 $sql .= " bk.credit, bk.montant , bk.sens , bk.code_journal , bk.piece_num, bk.lettering_code ";
 $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as bk";
 $sql .= " WHERE (bk.subledger_account =  '" . $object->code_compta . "' AND bk.numero_compte = '" . $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER . "' )";
 
-if (dol_strlen($search_year)) {
-	$date_start = dol_mktime(0, 0, 0, 1, 1, $search_year);
-	$date_end = dol_mktime(23, 59, 59, 12, 31, $search_year);
-	$sql .= " AND ( bk.doc_date BETWEEN  '" . $db->idate($date_start) . "' AND  '" . $db->idate($date_end) . "' )";
+/*
+if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) {
+	$sql .= " AND ( bk.doc_date BETWEEN  '" . $db->idate($search_date_start) . "' AND  '" . $db->idate($search_date_end) . "' )";
 }
+*/
 
 $sql.= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')';
 $sql .= $db->order($sortfield, $sortorder);
@@ -181,92 +187,123 @@ if (! $resql) {
 	exit();
 }
 
+$param='';
+$param.="&socid=".urlencode($socid);
+
 $num = $db->num_rows($resql);
 
 dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG);
 if ($resql) {
 	$i = 0;
 
+    $param="&socid=".$socid;
 	print '<form name="add" action="' . $_SERVER["PHP_SELF"] . '?socid=' . $object->id . '" method="POST">';
 	print '<input type="hidden" name="socid" value="' . $object->id . '">';
 
-	print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit);
+    $letteringbutton = '<a class="divButAction"><span class="valignmiddle"><input class="butAction" type="submit" value="lettering" name="lettering" id="lettering"></span></a>';
+
+	print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit);
+
+    print '<div class="div-table-responsive-no-min">';
+    print '<table class="liste" width="100%">'."\n";
+
+	/*
+    print '<tr class="liste_titre">';
+    //print '<td><input type="text" name="search_doc_type" value="' . $search_doc_type . '"></td>';
+
+    // Date
+    print '<td class="liste_titre center">';
+    print '<div class="nowrap">';
+    print $langs->trans('From') . ' ';
+    print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1);
+    print '</div>';
+    print '<div class="nowrap">';
+    print $langs->trans('to') . ' ';
+    print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1);
+    print '</div>';
+    print '</td>';
+
+    // Piece
+    print '<td><input type="text" name="search_doc_ref" value="' . $search_doc_ref . '"></td>';
+
+    print '<td colspan="6">&nbsp;</td>';
+    print '<td class="right">';
+    $searchpicto = $form->showFilterButtons();
+    print $searchpicto;
+    print '</td>';
+    print '</tr>';
+	*/
 
-	print "<table class=\"noborder\" width=\"100%\">";
 	print '<tr class="liste_titre">';
-	print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder);
-	print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder);
-	print_liste_field_titre("Docref", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder);
+	//print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder);
+	print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center ');
+	print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder);
 	print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder);
 	print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder);
 	print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder);
 	print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder);
-	print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder);
-	print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder);
+	print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center ');
+	print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center ');
+    print_liste_field_titre("", "", "", '', '', "", $sortfield, $sortorder, 'maxwidthsearch center ');
 	print "</tr>\n";
 
-	print '<tr class="liste_titre">';
-	print '<td><input type="text" name="search_doc_type" value="' . $search_doc_type . '"></td>';
-	print '<td><input type="text" name="search_year" value="' . $search_year . '"></td>';
-	print '<td><input type="text" name="search_doc_refe" value="' . $search_doc_ref . '"></td>';
-	print '<td colspan="5">&nbsp;</td>';
-	print '<td class="right">';
-	$searchpicto = $form->showFilterButtons();
-	print $searchpicto;
-	print '</td>';
-	print '</tr>';
-
 	$solde = 0;
 	$tmp = '';
-	while ( $obj = $db->fetch_object($resql) ) {
+
+    while ( $obj = $db->fetch_object($resql) ) {
 
 		if ($tmp != $obj->lettering_code || empty($tmp))						$tmp = $obj->lettering_code;
 		/*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/	$solde += ($obj->credit - $obj->debit);
 
 		print '<tr class="oddeven">';
 
-		if (empty($obj->lettering_code)) {
-			print '<td><a href="' . dol_buildpath('/accountancy/bookkeeping/card.php', 1) . '?piece_num=' . $obj->piece_num . '">';
-			print img_edit();
-			print '</a>&nbsp;' . $obj->doc_type . '</td>' . "\n";
-		} else {
-			print '<td>' . $obj->doc_type . '</td>' . "\n";
-		}
-
-		print '<td>' . dol_print_date($db->jdate($obj->doc_date), 'day') . '</td>';
+		//print '<td>' . $obj->doc_type . '</td>' . "\n";
+		print '<td class="center">' . dol_print_date($db->jdate($obj->doc_date), 'day') . '</td>';
 		print '<td>' . $obj->doc_ref . '</td>';
 		print '<td>' . $obj->label_compte . '</td>';
 		print '<td class="right">' . price($obj->debit) . '</td>';
 		print '<td class="right">' . price($obj->credit) . '</td>';
 		print '<td class="right">' . price(round($solde, 2)) . '</td>';
-		print '<td class="center">' . $obj->code_journal . '</td>';
 
-		if (empty($obj->lettering_code)) {
-			print '<td class="nowrap center"><input type="checkbox" class="flat checkforselect" name="toselect[]" id="toselect[]" value="' . $obj->rowid . '" /></td>';
-		} else
-			print '<td class="center">' . $obj->lettering_code . '</td>';
+		// Journal
+        $accountingjournal = new AccountingJournal($db);
+        $result = $accountingjournal->fetch('', $obj->code_journal);
+        $journaltoshow = (($result > 0)?$accountingjournal->getNomUrl(0, 0, 0, '', 0) : $obj->code_journal);
+        print '<td class="center">' . $journaltoshow . '</td>';
+
+        if (empty($obj->lettering_code)) {
+            print '<td class="nowrap center"><input type="checkbox" class="flat checkforselect" name="toselect[]" id="toselect[]" value="' . $obj->rowid . '" /></td>';
+            print '<td><a href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?piece_num=' . $obj->piece_num . '">';
+            print img_edit();
+            print '</a></td>' . "\n";
+        } else {
+            print '<td class="center">' . $obj->lettering_code . '</td>';
+            print '<td></td>';
+        }
 
 		print "</tr>\n";
 	}
 
 	print '<tr class="oddeven">';
-	print '<td class="right" colspan="4">'.$langs->trans("Total").':</td>' . "\n";
+	print '<td class="right" colspan="3">'.$langs->trans("Total").':</td>' . "\n";
 	print '<td class="right"><strong>' . price($debit) . '</strong></td>';
 	print '<td class="right"><strong>' . price($credit) . '</strong></td>';
-	print '<td colspan="5"></td>';
+	print '<td colspan="4"></td>';
 	print "</tr>\n";
 
 	print '<tr class="oddeven">';
-	print '<td class="right" colspan="4">'.$langs->trans("Balancing").':</td>' . "\n";
+	print '<td class="right" colspan="3">'.$langs->trans("Balancing").':</td>' . "\n";
 	print '<td colspan="2">&nbsp;</td>';
 	print '<td class="right"><strong>' . price($credit - $debit) . '</strong></td>';
-	print '<td colspan="3"></td>';
+	print '<td colspan="6"></td>';
 	print "</tr>\n";
 
 	print "</table>";
 
-	print '<input class="butAction" type="submit" value="lettering" name="lettering" id="lettering">';
-	//print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?socid=' . $object->id . '&action=autolettering">' . $langs->trans('AccountancyAutoLettering') . '</a>';
+    print '<div class="tabsAction tabsActionNoBottom">'."\n";
+    print $letteringbutton;
+    print '</div>';
+
 	print "</form>";
 	$db->free($resql);
 } else {

+ 93 - 59
htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php

@@ -3,8 +3,8 @@
  * Copyright (C) 2005      Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2013      Olivier Geffroy      <jeff@jeffinfo.com>
  * Copyright (C) 2013      Florian Henry	    <florian.henry@open-concept.pro>
- * Copyright (C) 2013-2018 Alexandre Spangaro      <aspangaro@open-dsi.fr>
- * Copyright (C) 2018      Frédéric France         <frederic.france@netlogic.fr>
+ * Copyright (C) 2013-2019 Alexandre Spangaro   <aspangaro@open-dsi.fr>
+ * Copyright (C) 2018-2019 Frédéric France      <frederic.france@netlogic.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,29 +18,30 @@
  *
  * 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/bookkeeping/thirdparty_lettrage_supplier.php
- * \ingroup 	Advanced accountancy
+ * \ingroup 	Accountancy (Double entries)
  * \brief 		Tab to setup lettering
  */
 require '../../main.inc.php';
 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php';
 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
+require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php';
 require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
 
 // Load translation files required by the page
 $langs->loadLangs(array("compta","accountancy"));
 
-$action = GETPOST('action', 'aZ09');
+$action     = GETPOST('action', 'aZ09');
 $massaction = GETPOST('massaction', 'alpha');
 $show_files = GETPOST('show_files', 'int');
-$confirm = GETPOST('confirm', 'alpha');
-$toselect = GETPOST('toselect', 'array');
+$confirm    = GETPOST('confirm', 'alpha');
+$toselect   = GETPOST('toselect', 'array');
+$socid      = GETPOST('socid', 'int')?GETPOST('socid', 'int'):GETPOST('id', 'int');
 
 $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
 $sortfield = GETPOST("sortfield", 'alpha');
@@ -53,27 +54,31 @@ $offset = $limit * $page;
 $pageprev = $page - 1;
 $pagenext = $page + 1;
 if ($sortorder == "")
-	$sortorder = "DESC";
+	$sortorder = "ASC";
 if ($sortfield == "")
 	$sortfield = "bk.doc_date";
 
-$search_year = GETPOST("search_year", 'int');
-$search_doc_type = GETPOST("search_doc_type", 'alpha');
-$search_doc_ref = GETPOST("search_doc_ref", 'alpha');
+/*
+$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
+$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
+//$search_doc_type = GETPOST("search_doc_type",'alpha');
+$search_doc_ref = GETPOST("search_doc_ref",'alpha');
+*/
 
 $lettering = GETPOST('lettering', 'alpha');
 if (!empty($lettering)) {
 	$action=$lettering;
 }
 
-// Did we click on purge search criteria ?
-// All tests are required to be compatible with all browsers
-if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha'))
+/*
+if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers
 {
-	$search_year='';
-	$search_doc_type='';
+    $search_date_start = '';
+    $search_date_end = '';
+	//$search_doc_type='';
 	$search_doc_ref='';
 }
+*/
 
 
 // Security check
@@ -103,6 +108,7 @@ if ($action == 'lettering') {
 	}
 }
 
+/*
 if ($action == 'autolettrage') {
 
 	$result = $lettering->letteringThirdparty($socid);
@@ -112,7 +118,7 @@ if ($action == 'autolettrage') {
 		$error++;
 	}
 }
-
+*/
 
 /*
  * View
@@ -142,10 +148,8 @@ $sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, ";
 $sql .= " bk.credit, bk.montant , bk.sens , bk.code_journal , bk.piece_num, bk.lettering_code ";
 $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as bk";
 $sql .= " WHERE (bk.subledger_account =  '" . $object->code_compta_fournisseur . "' AND bk.numero_compte = '" . $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER . "' )";
-if (dol_strlen($search_year)) {
-	$date_start = dol_mktime(0, 0, 0, 1, 1, $search_year);
-	$date_end = dol_mktime(23, 59, 59, 12, 31, $search_year);
-	$sql .= " AND ( bk.doc_date BETWEEN  '".$db->idate($date_start)."' AND  '".$db->idate($date_end)."' )";
+if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) {
+	$sql .= " AND (bk.doc_date BETWEEN '".$db->idate($search_date_start)."' AND  '".$db->idate($search_date_end)."' )";
 }
 $sql.= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')';
 $sql.= $db->order($sortfield, $sortorder);
@@ -172,50 +176,75 @@ while ($obj = $db->fetch_object($resql)) {
 
 $sql.= $db->plimit($limit+1, $offset);
 
-dol_syslog("/accountancy/bookkeeping/thirdparty_lettrage_supplier.php", LOG_DEBUG);
+dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_supplier.php", LOG_DEBUG);
 $resql = $db->query($sql);
 if (! $resql) {
 		dol_print_error($db);
 		exit;
 }
 
+$param='';
+$param.="&socid=".urlencode($socid);
+
 $num = $db->num_rows($resql);
 
-dol_syslog("/accountancy/bookkeeping/thirdparty_lettrage_supplier.php", LOG_DEBUG);
+dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_supplier.php", LOG_DEBUG);
 $resql = $db->query($sql);
 if ($resql) {
 	$num = $db->num_rows($resql);
 	$i = 0;
 
+    $param="&socid=".$socid;
 	print '<form name="add" action="'.$_SERVER["PHP_SELF"].'?socid=' . $object->id . '" method="POST">';
 	print '<input type="hidden" name="socid" value="' . $object->id . '">';
 
-	print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit);
+    $letteringbutton = '<a class="divButAction"><span class="valignmiddle"><input class="butAction" type="submit" value="lettering" name="lettering" id="lettering"></span></a>';
+
+    print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit);
+
+    print '<div class="div-table-responsive-no-min">';
+    print '<table class="liste" width="100%">'."\n";
+
+	/*
+    print '<tr class="liste_titre">';
+    //print '<td><input type="text" name="search_doc_type" value="' . $search_doc_type . '"></td>';
+
+    // Date
+    print '<td class="liste_titre center">';
+    print '<div class="nowrap">';
+    print $langs->trans('From') . ' ';
+    print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1);
+    print '</div>';
+    print '<div class="nowrap">';
+    print $langs->trans('to') . ' ';
+    print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1);
+    print '</div>';
+    print '</td>';
+
+    // Piece
+    print '<td><input type="text" name="search_doc_ref" value="' . $search_doc_ref . '"></td>';
+
+    print '<td colspan="6">&nbsp;</td>';
+    print '<td class="right">';
+    $searchpicto = $form->showFilterButtons();
+    print $searchpicto;
+    print '</td>';
+    print '</tr>';
+	*/
 
-	print "<table class=\"noborder\" width=\"100%\">";
 	print '<tr class="liste_titre">';
-	print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder);
-	print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder);
-	print_liste_field_titre("Docref", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder);
+	//print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder);
+	print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center ');
+	print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder);
 	print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder);
 	print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder);
 	print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder);
 	print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder);
-	print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder);
-	print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder);
+	print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center ');
+	print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center ');
+    print_liste_field_titre("", "", "", '', '', "", $sortfield, $sortorder, 'maxwidthsearch center ');
 	print "</tr>\n";
 
-	print '<tr class="liste_titre">';
-	print '<td><input type="text" name="search_doc_type" value="' . $search_doc_type . '"></td>';
-	print '<td><input type="text" name="search_year" value="' . $search_year . '"></td>';
-	print '<td><input type="text" name="search_doc_refe" value="' . $search_doc_ref . '"></td>';
-	print '<td colspan="6">&nbsp;</td>';
-	print '<td class="right">';
-	$searchpicto=$form->showFilterButtons();
-	print $searchpicto;
-	print '</td>';
-	print '</tr>';
-
 	$solde = 0;
 	$tmp = '';
 	while ($obj = $db->fetch_object($resql)) {
@@ -225,48 +254,53 @@ if ($resql) {
 
 		print '<tr class="oddeven">';
 
-		if (empty($obj->lettering_code)) {
-			print '<td><a href="' . dol_buildpath('/accountancy/bookkeeping/card.php', 1) . '?piece_num=' . $obj->piece_num . '">';
-			print img_edit();
-			print '</a>&nbsp;' . $obj->doc_type . '</td>' . "\n";
-		} else {
-			print '<td>' . $obj->doc_type . '</td>' . "\n";
-		}
-
-		print '<td>' . dol_print_date($db->jdate($obj->doc_date), 'day') . '</td>';
+		//print '<td>' . $obj->doc_type . '</td>' . "\n";
+		print '<td class="center">' . dol_print_date($db->jdate($obj->doc_date), 'day') . '</td>';
 		print '<td>' . $obj->doc_ref . '</td>';
 		print '<td>' . $obj->label_compte . '</td>';
 		print '<td class="right">' . price($obj->debit) . '</td>';
 		print '<td class="right">' . price($obj->credit) . '</td>';
 		print '<td class="right">' . price(round($solde, 2)) . '</td>';
-		print '<td class="center">' . $obj->code_journal . '</td>';
+
+        // Journal
+        $accountingjournal = new AccountingJournal($db);
+        $result = $accountingjournal->fetch('', $obj->code_journal);
+        $journaltoshow = (($result > 0)?$accountingjournal->getNomUrl(0, 0, 0, '', 0) : $obj->code_journal);
+        print '<td class="center">' . $journaltoshow . '</td>';
 
 		if (empty($obj->lettering_code)) {
 			print '<td class="nowrap center"><input type="checkbox" class="flat checkforselect" name="toselect[]" id="toselect[]" value="' . $obj->rowid . '" /></td>';
-		} else
-			print '<td class="center">' . $obj->lettering_code . '</td>';
+		    print '<td><a href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?piece_num=' . $obj->piece_num . '">';
+		    print img_edit();
+            print '</a></td>' . "\n";
+		} else {
+            print '<td class="center">' . $obj->lettering_code . '</td>';
+            print '<td></td>';
+        }
 
 		print "</tr>\n";
 	}
 
 	print '<tr class="oddeven">';
-	print '<td class="right" colspan="4">'.$langs->trans("Total").':</td>' . "\n";
+	print '<td class="right" colspan="3">'.$langs->trans("Total").':</td>' . "\n";
 	print '<td class="right"><strong>' . price($debit) . '</strong></td>';
 	print '<td class="right"><strong>' . price($credit) . '</strong></td>';
-	print '<td colspan="5"></td>';
+	print '<td colspan="6"></td>';
 	print "</tr>\n";
 
 	print '<tr class="oddeven">';
-	print '<td class="right" colspan="4">'.$langs->trans("Balancing").':</td>' . "\n";
+	print '<td class="right" colspan="3">'.$langs->trans("Balancing").':</td>' . "\n";
 	print '<td colspan="2">&nbsp;</td>';
 	print '<td class="right"><strong>' . price($credit - $debit) . '</strong></td>';
-	print '<td colspan="3"></td>';
+	print '<td colspan="4"></td>';
 	print "</tr>\n";
 
 	print "</table>";
 
-	print '<input class="butAction" type="submit" value="' . $langs->trans('AccountancyLettering') . '" name="lettering" id="lettering">';
-	//print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?socid=' . $object->id . '&action=autolettrage">'.$langs->trans('AccountancyAutoLettering').'</a>';
+    print '<div class="tabsAction tabsActionNoBottom">'."\n";
+	print $letteringbutton;
+    print '</div>';
+
 	print "</form>";
 	$db->free($resql);
 } else {

+ 1 - 1
htdocs/accountancy/class/accountancycategory.class.php

@@ -19,7 +19,7 @@
 
 /**
  * \file	htdocs/accountancy/class/accountancycategory.class.php
- * \ingroup Advanced accountancy
+ * \ingroup Accountancy (Double entries)
  * \brief	File of class to manage categories of an accounting category_type
  */
 

+ 247 - 34
htdocs/accountancy/class/accountancyexport.class.php

@@ -9,7 +9,7 @@
  * Copyright (C) 2013-2017  Olivier Geffroy     <jeff@jeffinfo.com>
  * Copyright (C) 2017       Elarifr. Ari Elbaz  <github@accedinfo.com>
  * Copyright (C) 2017-2019  Frédéric France     <frederic.france@netlogic.fr>
-
+ * Copyright (C) 2017       André Schild        <a.schild@aarboard.ch>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@
 
 /**
  * \file		htdocs/accountancy/class/accountancyexport.class.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief 		Class accountancy export
  */
 
@@ -39,17 +39,18 @@ require_once DOL_DOCUMENT_ROOT . '/core/lib/functions.lib.php';
 class AccountancyExport
 {
 	// Type of export. Used into $conf->global->ACCOUNTING_EXPORT_MODELCSV
-    public static $EXPORT_TYPE_NORMAL = 1;	 			// CSV
-	public static $EXPORT_TYPE_CONFIGURABLE = 10;		// CSV
-	public static $EXPORT_TYPE_CEGID = 2;
-	public static $EXPORT_TYPE_COALA = 3;
-	public static $EXPORT_TYPE_BOB50 = 4;
-	public static $EXPORT_TYPE_CIEL = 5;
-	public static $EXPORT_TYPE_QUADRATUS = 6;
-	public static $EXPORT_TYPE_EBP = 7;
-	public static $EXPORT_TYPE_COGILOG = 8;
-	public static $EXPORT_TYPE_AGIRIS = 9;
-	public static $EXPORT_TYPE_FEC = 11;
+	public static $EXPORT_TYPE_CONFIGURABLE = 1;		// CSV
+	public static $EXPORT_TYPE_AGIRIS = 10;
+	public static $EXPORT_TYPE_EBP = 15;
+	public static $EXPORT_TYPE_CEGID = 20;
+	public static $EXPORT_TYPE_COGILOG = 25;
+	public static $EXPORT_TYPE_COALA = 30;
+	public static $EXPORT_TYPE_BOB50 = 35;
+	public static $EXPORT_TYPE_CIEL = 40;
+	public static $EXPORT_TYPE_SAGE50_SWISS = 45;
+	public static $EXPORT_TYPE_QUADRATUS = 60;
+	public static $EXPORT_TYPE_OPENCONCERTO = 100;
+	public static $EXPORT_TYPE_FEC = 1000;
 
 
 	/**
@@ -92,8 +93,7 @@ class AccountancyExport
 	{
 		global $langs;
 
-		return array (
-			//self::$EXPORT_TYPE_NORMAL => $langs->trans('Modelcsv_normal'),
+		$listofexporttypes = array(
 			self::$EXPORT_TYPE_CONFIGURABLE => $langs->trans('Modelcsv_configurable'),
 			self::$EXPORT_TYPE_CEGID => $langs->trans('Modelcsv_CEGID'),
 			self::$EXPORT_TYPE_COALA => $langs->trans('Modelcsv_COALA'),
@@ -103,8 +103,14 @@ class AccountancyExport
 			self::$EXPORT_TYPE_EBP => $langs->trans('Modelcsv_ebp'),
 			self::$EXPORT_TYPE_COGILOG => $langs->trans('Modelcsv_cogilog'),
 			self::$EXPORT_TYPE_AGIRIS => $langs->trans('Modelcsv_agiris'),
+            self::$EXPORT_TYPE_OPENCONCERTO => $langs->trans('Modelcsv_openconcerto'),
+			self::$EXPORT_TYPE_SAGE50_SWISS => $langs->trans('Modelcsv_Sage50_Swiss'),
 			self::$EXPORT_TYPE_FEC => $langs->trans('Modelcsv_FEC'),
 		);
+
+		ksort($listofexporttypes, SORT_NUMERIC);
+
+		return $listofexporttypes;
 	}
 
 	/**
@@ -116,7 +122,6 @@ class AccountancyExport
 	private static function getFormatCode($type)
 	{
 		$formatcode = array (
-			//self::$EXPORT_TYPE_NORMAL => 'csv',
 			self::$EXPORT_TYPE_CONFIGURABLE => 'csv',
 			self::$EXPORT_TYPE_CEGID => 'cegid',
 			self::$EXPORT_TYPE_COALA => 'coala',
@@ -126,6 +131,8 @@ class AccountancyExport
 			self::$EXPORT_TYPE_EBP => 'ebp',
 			self::$EXPORT_TYPE_COGILOG => 'cogilog',
 			self::$EXPORT_TYPE_AGIRIS => 'agiris',
+			self::$EXPORT_TYPE_OPENCONCERTO => 'openconcerto',
+            self::$EXPORT_TYPE_SAGE50_SWISS => 'sage50ch',
 			self::$EXPORT_TYPE_FEC => 'fec',
 		);
 
@@ -143,13 +150,13 @@ class AccountancyExport
 
 		return array (
 			'param' => array(
-				/*self::$EXPORT_TYPE_NORMAL => array(
-					'label' => $langs->trans('Modelcsv_normal'),
+				self::$EXPORT_TYPE_CONFIGURABLE => array(
+					'label' => $langs->trans('Modelcsv_configurable'),
 					'ACCOUNTING_EXPORT_FORMAT' => empty($conf->global->ACCOUNTING_EXPORT_FORMAT)?'txt':$conf->global->ACCOUNTING_EXPORT_FORMAT,
 					'ACCOUNTING_EXPORT_SEPARATORCSV' => empty($conf->global->ACCOUNTING_EXPORT_SEPARATORCSV)?',':$conf->global->ACCOUNTING_EXPORT_SEPARATORCSV,
 					'ACCOUNTING_EXPORT_ENDLINE' => empty($conf->global->ACCOUNTING_EXPORT_ENDLINE)?1:$conf->global->ACCOUNTING_EXPORT_ENDLINE,
 					'ACCOUNTING_EXPORT_DATE' => empty($conf->global->ACCOUNTING_EXPORT_DATE)?'%d%m%Y':$conf->global->ACCOUNTING_EXPORT_DATE,
-				),*/
+				),
 				self::$EXPORT_TYPE_CEGID => array(
 					'label' => $langs->trans('Modelcsv_CEGID'),
 				),
@@ -176,12 +183,13 @@ class AccountancyExport
 				self::$EXPORT_TYPE_AGIRIS => array(
 					'label' => $langs->trans('Modelcsv_agiris'),
 				),
-				self::$EXPORT_TYPE_CONFIGURABLE => array(
-					'label' => $langs->trans('Modelcsv_configurable'),
-					'ACCOUNTING_EXPORT_FORMAT' => empty($conf->global->ACCOUNTING_EXPORT_FORMAT)?'txt':$conf->global->ACCOUNTING_EXPORT_FORMAT,
-					'ACCOUNTING_EXPORT_SEPARATORCSV' => empty($conf->global->ACCOUNTING_EXPORT_SEPARATORCSV)?',':$conf->global->ACCOUNTING_EXPORT_SEPARATORCSV,
-					'ACCOUNTING_EXPORT_ENDLINE' => empty($conf->global->ACCOUNTING_EXPORT_ENDLINE)?1:$conf->global->ACCOUNTING_EXPORT_ENDLINE,
-					'ACCOUNTING_EXPORT_DATE' => empty($conf->global->ACCOUNTING_EXPORT_DATE)?'%d%m%Y':$conf->global->ACCOUNTING_EXPORT_DATE,
+                self::$EXPORT_TYPE_OPENCONCERTO => array(
+                    'label' => $langs->trans('Modelcsv_openconcerto'),
+                    'ACCOUNTING_EXPORT_FORMAT' => 'csv',
+                ),
+				self::$EXPORT_TYPE_SAGE50_SWISS => array(
+					'label' => $langs->trans('Modelcsv_Sage50_Swiss'),
+					'ACCOUNTING_EXPORT_FORMAT' => 'csv',
 				),
 				self::$EXPORT_TYPE_FEC => array(
 					'label' => $langs->trans('Modelcsv_FEC'),
@@ -219,11 +227,9 @@ class AccountancyExport
 
 
 		switch ($conf->global->ACCOUNTING_EXPORT_MODELCSV) {
-			case self::$EXPORT_TYPE_NORMAL :
 			case self::$EXPORT_TYPE_CONFIGURABLE :
 				$this->exportConfigurable($TData);
 				break;
-			case self::$EXPORT_TYPE_NORMAL :
 			case self::$EXPORT_TYPE_CEGID :
 				$this->exportCegid($TData);
 				break;
@@ -248,9 +254,15 @@ class AccountancyExport
 			case self::$EXPORT_TYPE_AGIRIS :
 				$this->exportAgiris($TData);
 				break;
+            case self::$EXPORT_TYPE_OPENCONCERTO :
+                $this->exportOpenConcerto($TData);
+                break;
 			case self::$EXPORT_TYPE_FEC :
 				$this->exportFEC($TData);
 				break;
+			case self::$EXPORT_TYPE_SAGE50_SWISS :
+				$this->exportSAGE50SWISS($TData);
+				break;
 			default:
 				$this->errors[] = $langs->trans('accountancy_error_modelnotfound');
 				break;
@@ -565,19 +577,19 @@ class AccountancyExport
 			$date = dol_print_date($line->doc_date, '%d%m%Y');
 
 			print $line->piece_num . $separator;
-			print $line->label_operation . $separator;
+			print self::toAnsi($line->label_operation) . $separator;
 			print $date . $separator;
-			print $line->label_operation . $separator;
+			print self::toAnsi($line->label_operation) . $separator;
 
 			if (empty($line->subledger_account)) {
 				print length_accountg($line->numero_compte) . $separator;
-				print $line->label_compte . $separator;
+				print self::toAnsi($line->label_compte) . $separator;
 			} else {
 				print length_accounta($line->subledger_account) . $separator;
-				print $line->subledger_label . $separator;
+				print self::toAnsi($line->subledger_label) . $separator;
 			}
 
-			print $line->doc_ref . $separator;
+			print self::toAnsi($line->doc_ref) . $separator;
 			print price($line->debit) . $separator;
 			print price($line->credit) . $separator;
 			print price($line->montant) . $separator;
@@ -588,6 +600,39 @@ class AccountancyExport
 		}
 	}
 
+    /**
+     * Export format : OpenConcerto
+     *
+     * @param array $objectLines data
+     *
+     * @return void
+     */
+    public function exportOpenConcerto($objectLines)
+    {
+
+        $separator = ';';
+        $end_line = "\n";
+
+        foreach ($objectLines as $line) {
+
+            $date = dol_print_date($line->doc_date, '%d/%m/%Y');
+
+            print $date . $separator;
+            print $line->code_journal . $separator;
+            if (empty($line->subledger_account)) {
+                print length_accountg($line->numero_compte) . $separator;
+            } else {
+                print length_accounta($line->subledger_account) . $separator;
+            }
+            print $line->doc_ref . $separator;
+            print $line->label_operation . $separator;
+            print price($line->debit) . $separator;
+            print price($line->credit) . $separator;
+
+            print $end_line;
+        }
+    }
+
 	/**
 	 * Export format : Configurable
 	 *
@@ -714,14 +759,182 @@ class AccountancyExport
 		}
 	}
 
+    /**
+     * Export format : SAGE50SWISS
+     *
+     * https://onlinehelp.sageschweiz.ch/default.aspx?tabid=19984
+     * http://media.topal.ch/Public/Schnittstellen/TAF/Specification/Sage50-TAF-format.pdf
+     *
+     * @param array $objectLines data
+     *
+     * @return void
+     */
+    public function exportSAGE50SWISS($objectLines)
+    {
+        // SAGE50SWISS
+        $this->separator = ',';
+        $this->end_line = "\r\n";
+
+        // Print header line
+        print "Blg,Datum,Kto,S/H,Grp,GKto,SId,SIdx,KIdx,BTyp,MTyp,Code,Netto,Steuer,FW-Betrag,Tx1,Tx2,PkKey,OpId,Flag";
+        print $this->end_line;
+        $thisPieceNum= "";
+        $thisPieceAccountNr= "";
+        $aSize= count($objectLines);
+        foreach ($objectLines as $aIndex=>$line)
+		{
+            $sammelBuchung= false;
+            if ($aIndex-2 >= 0 && $objectLines[$aIndex-2]->piece_num == $line->piece_num)
+            {
+                $sammelBuchung= true;
+            }
+            elseif ($aIndex+2 < $aSize && $objectLines[$aIndex+2]->piece_num == $line->piece_num)
+            {
+                $sammelBuchung= true;
+            }
+            elseif ($aIndex+1 < $aSize
+                    && $objectLines[$aIndex+1]->piece_num == $line->piece_num
+                    && $aIndex-1 < $aSize
+                    && $objectLines[$aIndex-1]->piece_num == $line->piece_num
+                    )
+            {
+                $sammelBuchung= true;
+            }
+
+            //Blg
+            print $line->piece_num . $this->separator;
+
+            // Datum
+            $date = dol_print_date($line->doc_date, '%d.%m.%Y');
+            print $date . $this->separator;
+
+            // Kto
+            print length_accountg($line->numero_compte) . $this->separator;
+            // S/H
+            if ($line->sens == 'D')
+            {
+                print 'S' . $this->separator;
+            }
+            else
+            {
+                print 'H' . $this->separator;
+            }
+            //Grp
+            print self::trunc($line->code_journal, 1) . $this->separator;
+            // GKto
+            if (empty($line->code_tiers))
+            {
+                if ($line->piece_num == $thisPieceNum)
+                {
+                    print length_accounta($thisPieceAccountNr) . $this->separator;
+                }
+                else
+                {
+                    print "div" . $this->separator;
+                }
+            }
+            else
+            {
+                print length_accounta($line->code_tiers) . $this->separator;
+            }
+            //SId
+            print $this->separator;
+            //SIdx
+            print "0" . $this->separator;
+            //KIdx
+            print "0" . $this->separator;
+            //BTyp
+            print "0" . $this->separator;
+
+            //MTyp 1=Fibu Einzelbuchung 2=Sammebuchung
+            if ($sammelBuchung)
+            {
+                print "2" . $this->separator;
+            }
+            else
+            {
+                print "1" . $this->separator;
+            }
+            // Code
+            print '""' . $this->separator;
+            // Netto
+            if ($line->montant >= 0)
+            {
+                print $line->montant . $this->separator;
+            }
+            else
+            {
+                print $line->montant*-1 . $this->separator;
+            }
+            // Steuer
+            print "0.00" . $this->separator;
+            // FW-Betrag
+            print "0.00" . $this->separator;
+            // Tx1
+            $line1= self::toAnsi($line->label_compte, 29);
+            if ($line1 == "LIQ" || $line1 == "LIQ Beleg ok" || strlen($line1) <= 3)
+            {
+                $line1= "";
+            }
+            $line2= self::toAnsi($line->doc_ref, 29);
+            if (strlen($line1) == 0)
+            {
+                $line1= $line2;
+                $line2= "";
+            }
+            if (strlen($line1) > 0 && strlen($line2) > 0 && (strlen($line1) + strlen($line2)) < 27)
+            {
+                $line1= $line1 . ' / ' . $line2;
+                $line2= "";
+            }
+
+            print '"' . self::toAnsi($line1). '"' . $this->separator;
+            // Tx2
+            print '"' . self::toAnsi($line2). '"' . $this->separator;
+            //PkKey
+            print "0" . $this->separator;
+            //OpId
+            print $this->separator;
+
+            // Flag
+            print "0";
+
+            print $this->end_line;
+
+            if ($line->piece_num !== $thisPieceNum)
+            {
+                $thisPieceNum= $line->piece_num;
+                $thisPieceAccountNr= $line->numero_compte;
+            }
+        }
+    }
+
 	/**
+	 * trunc
 	 *
-	 * @param string	$str 	data
-	 * @param integer 	$size 	data
+	 * @param string	$str 	String
+	 * @param integer 	$size 	Data to trunc
 	 * @return string
 	 */
 	public static function trunc($str, $size)
 	{
 		return dol_trunc($str, $size, 'right', 'UTF-8', 1);
 	}
+
+	/**
+	 * toAnsi
+	 *
+	 * @param string	$str 		Original string to encode and optionaly truncate
+	 * @param integer 	$size 		Truncate string after $size characters
+     * @return string 				String encoded in Windows-1251 charset
+	 */
+	public static function toAnsi($str, $size = -1)
+    {
+		$retVal= dol_string_nohtmltag($str, 1, 'Windows-1251');
+        if ($retVal >= 0 && $size >= 0)
+        {
+            $retVal= mb_substr($retVal, 0, $size, 'Windows-1251');
+        }
+        return $retVal;
+	}
 }

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

@@ -19,7 +19,7 @@
 
 /**
  * \file		htdocs/accountancy/class/accountancysystem.class.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		File of class to manage accountancy systems
  */
 
@@ -83,13 +83,13 @@ class AccountancySystem
 
 	    if ($rowid > 0 || $ref)
 	    {
-	        $sql  = "SELECT a.pcg_version, a.label, a.active";
+	        $sql  = "SELECT a.rowid, a.pcg_version, a.label, a.active";
 	        $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_system as a";
 	        $sql .= " WHERE";
 	        if ($rowid) {
 	            $sql .= " a.rowid = '" . $rowid . "'";
 	        } elseif ($ref) {
-	            $sql .= " a.pcg_version = '" . $ref . "'";
+	            $sql .= " a.pcg_version = '" . $this->db->escape($ref) . "'";
 	        }
 
 	        dol_syslog(get_class($this) . "::fetch sql=" . $sql, LOG_DEBUG);

+ 10 - 14
htdocs/accountancy/class/accountingaccount.class.php

@@ -22,7 +22,7 @@
 
 /**
  *  \file       htdocs/accountancy/class/accountingaccount.class.php
- *  \ingroup    Advanced accountancy
+ *  \ingroup    Accountancy (Double entries)
  *  \brief      File of class to manage accounting accounts
  */
 
@@ -151,12 +151,13 @@ class AccountingAccount extends CommonObject
 	/**
 	 * Load record in memory
 	 *
-	 * @param 	int 	$rowid 				   Id
-	 * @param 	string 	$account_number 	   Account number
-	 * @param 	int 	$limittocurrentchart   1=Do not load record if it is into another accounting system
-	 * @return 	int                            <0 if KO, 0 if not found, Id of record if OK and found
+	 * @param 	int 	       $rowid 				    Id
+	 * @param 	string 	       $account_number 	        Account number
+	 * @param 	int|boolean    $limittocurrentchart     1 or true=Load record only if it is into current active char of account
+	 * @param   string         $limittoachartaccount    'ABC'=Load record only if it is into chart account with code 'ABC'.
+	 * @return 	int                                     <0 if KO, 0 if not found, Id of record if OK and found
 	 */
-	public function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0)
+    public function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0, $limittoachartaccount = '')
 	{
 		global $conf;
 
@@ -174,6 +175,9 @@ class AccountingAccount extends CommonObject
 			if (! empty($limittocurrentchart)) {
 				$sql .= ' AND a.fk_pcg_version IN (SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid=' . $this->db->escape($conf->global->CHARTOFACCOUNTS) . ')';
 			}
+			if (! empty($limittoachartaccount)) {
+			    $sql .= " AND a.fk_pcg_version = '".$this->db->escape($limittoachartaccount)."'";
+			}
 
 			dol_syslog(get_class($this) . "::fetch sql=" . $sql, LOG_DEBUG);
 			$result = $this->db->query($sql);
@@ -233,16 +237,8 @@ class AccountingAccount extends CommonObject
 			$this->pcg_subtype = trim($this->pcg_subtype);
 		if (isset($this->account_number))
 			$this->account_number = trim($this->account_number);
-		if (isset($this->account_parent))
-			$this->account_parent = trim($this->account_parent);
 		if (isset($this->label))
 			$this->label = trim($this->label);
-		if (isset($this->account_category))
-			$this->account_category = trim($this->account_category);
-		if (isset($this->fk_user_author))
-			$this->fk_user_author = trim($this->fk_user_author);
-		if (isset($this->active))
-			$this->active = trim($this->active);
 
 		if (empty($this->pcg_type) || $this->pcg_type == '-1')
 		{

+ 1 - 1
htdocs/accountancy/class/accountingjournal.class.php

@@ -17,7 +17,7 @@
 
 /**
  * \file		htdocs/accountancy/class/accountingjournal.class.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		File of class to manage accounting journals
  */
 

+ 22 - 26
htdocs/accountancy/class/bookkeeping.class.php

@@ -20,7 +20,7 @@
 
 /**
  * \file        htdocs/accountancy/class/bookkeeping.class.php
- * \ingroup     Advanced accountancy
+ * \ingroup     Accountancy (Double entries)
  * \brief       File of class to manage Ledger (General Ledger and Subledger)
  */
 
@@ -202,9 +202,6 @@ class BookKeeping extends CommonObject
 		if (isset($this->sens)) {
 			$this->sens = trim($this->sens);
 		}
-		if (isset($this->fk_user_author)) {
-			$this->fk_user_author = trim($this->fk_user_author);
-		}
 		if (isset($this->import_key)) {
 			$this->import_key = trim($this->import_key);
 		}
@@ -522,9 +519,6 @@ class BookKeeping extends CommonObject
 		if (isset($this->sens)) {
 			$this->sens = trim($this->sens);
 		}
-		if (isset($this->fk_user_author)) {
-			$this->fk_user_author = trim($this->fk_user_author);
-		}
 		if (isset($this->import_key)) {
 			$this->import_key = trim($this->import_key);
 		}
@@ -866,15 +860,16 @@ class BookKeeping extends CommonObject
 	/**
 	 * Load object in memory from the database
 	 *
-	 * @param string 		$sortorder 		Sort Order
-	 * @param string 		$sortfield 		Sort field
-	 * @param int 			$limit 			Offset limit
-	 * @param int 			$offset 		Offset limit
-	 * @param array 		$filter 		Filter array
-	 * @param string 		$filtermode 	Filter mode (AND or OR)
-	 * @return int 							<0 if KO, >0 if OK
+	 * @param string 		$sortorder                      Sort Order
+	 * @param string 		$sortfield                      Sort field
+	 * @param int 			$limit                          Offset limit
+	 * @param int 			$offset                         Offset limit
+	 * @param array 		$filter                         Filter array
+	 * @param string 		$filtermode                     Filter mode (AND or OR)
+     * @param int           $showAlreadyExportMovements     Show movements when field 'date_export' is not empty (0:No / 1:Yes (Default))
+	 * @return int                                          <0 if KO, >0 if OK
 	 */
-    public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
+    public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND', $showAlreadyExportMovements = 1)
     {
 		global $conf;
 
@@ -904,7 +899,8 @@ class BookKeeping extends CommonObject
 		$sql .= " t.journal_label,";
 		$sql .= " t.piece_num,";
 		$sql .= " t.date_creation,";
-		$sql .= " t.tms as date_modification";
+		$sql .= " t.tms as date_modification,";
+        $sql .= " t.date_export";
 		$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
 		// Manage filter
 		$sqlwhere = array ();
@@ -924,6 +920,8 @@ class BookKeeping extends CommonObject
 					$sqlwhere[] = $key . '\'' . $this->db->idate($value) . '\'';
 				} elseif ($key == 't.tms>=' || $key == 't.tms<=') {
 					$sqlwhere[] = $key . '\'' . $this->db->idate($value) . '\'';
+                } elseif ($key == 't.date_export>=' || $key == 't.date_export<=') {
+                    $sqlwhere[] = $key . '\'' . $this->db->idate($value) . '\'';
 				} elseif ($key == 't.credit' || $key == 't.debit') {
 					$sqlwhere[] = natural_search($key, $value, 1, 1);
 				} else {
@@ -932,10 +930,12 @@ class BookKeeping extends CommonObject
 			}
 		}
 		$sql.= ' WHERE t.entity IN (' . getEntity('accountancy') . ')';
+        if ($showAlreadyExportMovements == 0) {
+            $sql .= " AND t.date_export IS NULL";
+        }
 		if (count($sqlwhere) > 0) {
 			$sql .= ' AND ' . implode(' ' . $filtermode . ' ', $sqlwhere);
 		}
-
 		if (! empty($sortfield)) {
 			$sql .= $this->db->order($sortfield, $sortorder);
 		}
@@ -978,6 +978,7 @@ class BookKeeping extends CommonObject
 				$line->piece_num = $obj->piece_num;
 				$line->date_creation = $this->db->jdate($obj->date_creation);
 				$line->date_modification = $this->db->jdate($obj->date_modification);
+                $line->date_export = $this->db->jdate($obj->date_export);
 
 				$this->lines[] = $line;
 
@@ -1139,9 +1140,6 @@ class BookKeeping extends CommonObject
 		if (isset($this->sens)) {
 			$this->sens = trim($this->sens);
 		}
-		if (isset($this->fk_user_author)) {
-			$this->fk_user_author = trim($this->fk_user_author);
-		}
 		if (isset($this->import_key)) {
 			$this->import_key = trim($this->import_key);
 		}
@@ -1409,16 +1407,14 @@ class BookKeeping extends CommonObject
 	/**
 	 * Load an object from its id and create a new one in database
 	 *
-	 * @param int $fromid Id of object to clone
-	 *
-	 * @return int New id of clone
+	 * @param	User	$user		User making the clone
+	 * @param   int     $fromid     Id of object to clone
+	 * @return  int                 New id of clone
 	 */
-    public function createFromClone($fromid)
+    public function createFromClone(User $user, $fromid)
     {
 		dol_syslog(__METHOD__, LOG_DEBUG);
 
-		global $user;
-
 		$error = 0;
 		$object = new BookKeeping($this->db);
 

+ 26 - 26
htdocs/accountancy/class/lettering.class.php

@@ -1,7 +1,7 @@
 <?php
 /* Copyright (C) 2004-2005  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
  * Copyright (C) 2013       Olivier Geffroy         <jeff@jeffinfo.com>
- * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@open-dsi.fr>
+ * Copyright (C) 2013-2019  Alexandre Spangaro      <aspangaro@open-dsi.fr>
  * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -20,7 +20,7 @@
 
 /**
  * \file      	htdocs/accountancy/class/lettering.class.php
- * \ingroup 	Advanced accountancy
+ * \ingroup 	Accountancy (Double entries)
  * \brief 		File of class for lettering
  */
 
@@ -66,13 +66,13 @@ class Lettering extends BookKeeping
 		$sql .= " , bk.sens , bk.code_journal , bk.piece_num, bk.date_lettering, bu.url_id , bu.type ";
 		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as bk";
 		$sql .= " LEFT JOIN  " . MAIN_DB_PREFIX . "bank_url as bu ON(bk.fk_doc = bu.fk_bank AND bu.type IN ('payment', 'payment_supplier') ) ";
-		$sql .= " WHERE   ( ";
-		if (! empty($object->code_compta))
-			$sql .= "  bk.subledger_account = '" . $object->code_compta . "'  ";
-		if (! empty($object->code_compta) && ! empty($object->code_compta_fournisseur))
-			$sql .= "  OR  ";
-		if (! empty($object->code_compta_fournisseur))
-			$sql .= "   bk.subledger_account = '" . $object->code_compta_fournisseur . "' ";
+		$sql .= " WHERE ( ";
+		if ($object->code_compta != "")
+			$sql .= " bk.subledger_account = '" . $object->code_compta . "'  ";
+		if ($object->code_compta != "" && $object->code_compta_fournisseur != "")
+			$sql .= " OR ";
+		if ($object->code_compta_fournisseur != "")
+			$sql .= " bk.subledger_account = '" . $object->code_compta_fournisseur . "' ";
 
 		$sql .= " ) AND (bk.date_lettering ='' OR bk.date_lettering IS NULL) ";
 		$sql .= "  AND (bk.lettering_code != '' OR bk.lettering_code IS NULL) ";
@@ -99,13 +99,13 @@ class Lettering extends BookKeeping
 					$sql .= " AND facf.entity = ".$conf->entity;
 					$sql .= " AND code_journal IN (SELECT code FROM " . MAIN_DB_PREFIX . "accounting_journal WHERE nature=4 AND entity=".$conf->entity.") ";
 					$sql .= " AND ( ";
-					if (! empty($object->code_compta)) {
+					if ($object->code_compta != "") {
 						$sql .= "  bk.subledger_account = '" . $object->code_compta . "'  ";
 					}
-					if (! empty($object->code_compta) && ! empty($object->code_compta_fournisseur)) {
+					if ($object->code_compta != "" && $object->code_compta_fournisseur != "") {
 						$sql .= "  OR  ";
 					}
-					if (! empty($object->code_compta_fournisseur)) {
+					if ($object->code_compta_fournisseur != "") {
 						$sql .= "   bk.subledger_account = '" . $object->code_compta_fournisseur . "' ";
 					}
 					$sql .= " )  ";
@@ -127,16 +127,16 @@ class Lettering extends BookKeeping
 						$sql .= " WHERE bk.code_journal IN (SELECT code FROM " . MAIN_DB_PREFIX . "accounting_journal WHERE nature=3 AND entity=".$conf->entity.") ";
 						$sql .= " AND facf.entity = ".$conf->entity;
 						$sql .= " AND ( ";
-						if (! empty($object->code_compta)) {
-							$sql .= "  bk.subledger_account = '" . $object->code_compta . "'  ";
+						if ($object->code_compta != "") {
+							$sql .= " bk.subledger_account = '" . $object->code_compta . "'  ";
 						}
-						if (! empty($object->code_compta) && ! empty($object->code_compta_fournisseur)) {
-							$sql .= "  OR  ";
+						if ($object->code_compta != "" && $object->code_compta_fournisseur != "") {
+							$sql .= " OR ";
 						}
-						if (! empty($object->code_compta_fournisseur)) {
-							$sql .= "   bk.subledger_account = '" . $object->code_compta_fournisseur . "' ";
+						if ($object->code_compta_fournisseur != "") {
+							$sql .= " bk.subledger_account = '" . $object->code_compta_fournisseur . "' ";
 						}
-						$sql .= " )  ";
+						$sql .= ") ";
 
 						$resql2 = $this->db->query($sql);
 						if ($resql2) {
@@ -159,13 +159,13 @@ class Lettering extends BookKeeping
 					$sql .= " AND bk.code_journal IN (SELECT code FROM " . MAIN_DB_PREFIX . "accounting_journal WHERE nature=4 AND entity=".$conf->entity.") ";
 					$sql .= " AND fac.entity IN (".getEntity('invoice', 0).")";// We don't share object for accountancy
 					$sql .= " AND ( ";
-					if (! empty($object->code_compta)) {
+					if ($object->code_compta != "") {
 						$sql .= "  bk.subledger_account = '" . $object->code_compta . "'  ";
 					}
-					if (! empty($object->code_compta) && ! empty($object->code_compta_fournisseur)) {
+					if ($object->code_compta != "" && $object->code_compta_fournisseur != "") {
 						$sql .= "  OR  ";
 					}
-					if (! empty($object->code_compta_fournisseur)) {
+					if ($object->code_compta_fournisseur != "") {
 						$sql .= "   bk.subledger_account = '" . $object->code_compta_fournisseur . "' ";
 					}
 					$sql .= " )  ";
@@ -187,13 +187,13 @@ class Lettering extends BookKeeping
 						$sql .= " WHERE code_journal IN (SELECT code FROM " . MAIN_DB_PREFIX . "accounting_journal WHERE nature=2 AND entity=".$conf->entity.") ";
 						$sql .= " AND fac.entity IN (".getEntity('invoice', 0).")";// We don't share object for accountancy
 						$sql .= " AND ( ";
-						if (! empty($object->code_compta)) {
+						if ($object->code_compta != "") {
 							$sql .= "  bk.subledger_account = '" . $object->code_compta . "'  ";
 						}
-						if (! empty($object->code_compta) && ! empty($object->code_compta_fournisseur)) {
+						if ($object->code_compta != "" && $object->code_compta_fournisseur != "") {
 							$sql .= "  OR  ";
 						}
-						if (! empty($object->code_compta_fournisseur)) {
+						if ($object->code_compta_fournisseur != "") {
 							$sql .= "   bk.subledger_account = '" . $object->code_compta_fournisseur . "' ";
 						}
 						$sql .= " )  ";
@@ -253,7 +253,7 @@ class Lettering extends BookKeeping
 			$error++;
 		}
 
-		$sql = "SELECT SUM(ABS(debit)) as deb, SUM(ABS(credit)) as cred   FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping WHERE ";
+		$sql = "SELECT SUM(ABS(debit)) as deb, SUM(ABS(credit)) as cred FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping WHERE ";
 		$sql .= " rowid IN (" . implode(',', $ids) . ") ";
 		$result = $this->db->query($sql);
 		if ($result) {

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

@@ -19,7 +19,7 @@
 
 /**
  * \file 	htdocs/accountancy/customer/card.php
- * \ingroup Advanced accountancy
+ * \ingroup Accountancy (Double entries)
  * \brief 	Card customer ventilation
  */
 require '../../main.inc.php';

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

@@ -22,7 +22,7 @@
 
 /**
  * \file 	htdocs/accountancy/customer/index.php
- * \ingroup Advanced accountancy
+ * \ingroup Accountancy (Double entries)
  * \brief 	Home customer journalization page
  */
 
@@ -143,9 +143,9 @@ $textnextyear = '&nbsp;<a href="' . $_SERVER["PHP_SELF"] . '?year=' . ($year_cur
 
 print load_fiche_titre($langs->trans("CustomersVentilation") . " " . $textprevyear . " " . $langs->trans("Year") . " " . $year_start . " " . $textnextyear, '', 'title_accountancy');
 
-print $langs->trans("DescVentilCustomer") . '<br>';
+print '<span class="opacitymedium">'.$langs->trans("DescVentilCustomer") . '<br>';
 print $langs->trans("DescVentilMore", $langs->transnoentitiesnoconv("ValidateHistory"), $langs->transnoentitiesnoconv("ToBind")) . '<br>';
-print '<br>';
+print '</span><br>';
 
 
 $y = $year_current;
@@ -211,10 +211,10 @@ if ($resql) {
 		else print $row[1];
 		print '</td>';
 		for($i = 2; $i <= 12; $i ++) {
-			print '<td class="right">' . price($row[$i]) . '</td>';
+			print '<td class="nowrap right">' . price($row[$i]) . '</td>';
 		}
-		print '<td class="right">' . price($row[13]) . '</td>';
-		print '<td class="right"><b>' . price($row[14]) . '</b></td>';
+		print '<td class="nowrap right">' . price($row[13]) . '</td>';
+		print '<td class="nowrap right"><b>' . price($row[14]) . '</b></td>';
 		print '</tr>';
 	}
 	$db->free($resql);
@@ -289,10 +289,10 @@ if ($resql) {
 		print '</td>';
 
 		for($i = 2; $i <= 12; $i++) {
-			print '<td class="right">' . price($row[$i]) . '</td>';
+			print '<td class="nowrap right">' . price($row[$i]) . '</td>';
 		}
-		print '<td class="right">' . price($row[13]) . '</td>';
-		print '<td class="right"><b>' . price($row[14]) . '</b></td>';
+		print '<td class="nowrap right">' . price($row[13]) . '</td>';
+		print '<td class="nowrap right"><b>' . price($row[14]) . '</b></td>';
 		print '</tr>';
 	}
 	$db->free($resql);
@@ -348,9 +348,9 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
 		while ($row = $db->fetch_row($resql)) {
 			print '<tr><td>' . $row[0] . '</td>';
 			for($i = 1; $i <= 12; $i ++) {
-				print '<td class="right">' . price($row[$i]) . '</td>';
+				print '<td class="nowrap right">' . price($row[$i]) . '</td>';
 			}
-			print '<td class="right"><b>' . price($row[13]) . '</b></td>';
+			print '<td class="nowrap right"><b>' . price($row[13]) . '</b></td>';
 			print '</tr>';
 		}
 		$db->free($resql);
@@ -401,9 +401,9 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
 
 				print '<tr><td>' . $row[0] . '</td>';
 				for($i = 1; $i <= 12; $i ++) {
-					print '<td class="right">' . price(price2num($row[$i])) . '</td>';
+					print '<td class="nowrap right">' . price(price2num($row[$i])) . '</td>';
 				}
-				print '<td class="right"><b>' . price(price2num($row[13])) . '</b></td>';
+				print '<td class="nowrap right"><b>' . price(price2num($row[13])) . '</b></td>';
 				print '</tr>';
 			}
 			$db->free($resql);

+ 5 - 5
htdocs/accountancy/customer/lines.php

@@ -21,7 +21,7 @@
 
 /**
  * \file 		htdocs/accountancy/customer/lines.php
- * \ingroup 	Advanced accountancy
+ * \ingroup 	Accountancy (Double entries)
  * \brief 		Page of detail of the lines of ventilation of invoices customers
  */
 require '../../main.inc.php';
@@ -294,7 +294,7 @@ if ($result) {
 	print '<input type="hidden" name="page" value="'.$page.'">';
 
 	print_barre_liste($langs->trans("InvoiceLinesDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
-	print $langs->trans("DescVentilDoneCustomer") . '<br>';
+	print '<span class="opacitymedium">'.$langs->trans("DescVentilDoneCustomer") . '</span><br>';
 
 	print '<br><div class="inline-block divButAction">' . $langs->trans("ChangeAccount") . '<br>';
 	print $formaccounting->select_account($account_parent, 'account_parent', 2, array(), 0, 0, 'maxwidth300 maxwidthonsmartphone valignmiddle');
@@ -310,9 +310,9 @@ if ($result) {
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="' . dol_escape_htmltag($search_invoice) . '"></td>';
 	print '<td class="liste_titre center nowraponall">';
     if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) {
-        print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_day" value="'.dol_escape_htmltag($search_day).'">';
+        print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_day" value="'.dol_escape_htmltag($search_day).'">';
     }
-   	print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_month" value="'.dol_escape_htmltag($search_month).'">';
+   	print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_month" value="'.dol_escape_htmltag($search_month).'">';
    	$formother->select_year($search_year, 'search_year', 1, 20, 5);
 	print '</td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="' . dol_escape_htmltag($search_ref) . '"></td>';
@@ -385,7 +385,7 @@ if ($result) {
 		print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description);
 		print '</td>';
 
-		print '<td class="right">' . price($objp->total_ht) . '</td>';
+		print '<td class="nowrap right">' . price($objp->total_ht) . '</td>';
 
 		print '<td class="right">' . vatrate($objp->tva_tx.($objp->vat_src_code?' ('.$objp->vat_src_code.')':'')) . '</td>';
 

+ 70 - 35
htdocs/accountancy/customer/list.php

@@ -22,7 +22,7 @@
 
 /**
  * \file 		htdocs/accountancy/customer/list.php
- * \ingroup 	Advanced accountancy
+ * \ingroup 	Accountancy (Double entries)
  * \brief 		Ventilation page from customers invoices
  */
 require '../../main.inc.php';
@@ -92,9 +92,6 @@ if (! $user->rights->accounting->bind->write)
 $hookmanager->initHooks(array('accountancycustomerlist'));
 
 $formaccounting = new FormAccounting($db);
-$accounting = new AccountingAccount($db);
-$aarowid_s = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT, 1);
-$aarowid_p = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT, 1);
 
 $chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
 
@@ -214,7 +211,7 @@ $sql.= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation
 $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.accountancy_code_sell as code_sell, p.tva_tx as tva_tx_prod,";
 $sql.= " p.accountancy_code_sell_intra as code_sell_intra, p.accountancy_code_sell_export as code_sell_export,";
 $sql.= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export,";
-$sql.= " co.code as country_code, co.label as country,";
+$sql.= " co.code as country_code, co.label as country_label,";
 $sql.= " s.tva_intra";
 $parameters=array();
 $reshook=$hookmanager->executeHooks('printFieldListSelect', $parameters);    // Note that $action and $object may have been modified by hook
@@ -356,7 +353,7 @@ if ($result) {
 
 	print_barre_liste($langs->trans("InvoiceLines"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
 
-	print $langs->trans("DescVentilTodoCustomer") . '</br><br>';
+	print '<span class="opacitymedium">'.$langs->trans("DescVentilTodoCustomer") . '</span></br><br>';
 
 	/*$topicmail="Information";
 	 $modelmail="project";
@@ -377,18 +374,18 @@ if ($result) {
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="' . dol_escape_htmltag($search_invoice) . '"></td>';
 	print '<td class="liste_titre center nowraponall">';
    	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) {
-        print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_day" value="'.$search_day.'">';
+        print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_day" value="'.$search_day.'">';
     }
-   	print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_month" value="'.$search_month.'">';
+   	print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_month" value="'.$search_month.'">';
    	$formother->select_year($search_year, 'search_year', 1, 20, 5);
 	print '</td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="' . dol_escape_htmltag($search_ref) . '"></td>';
 	//print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="' . dol_escape_htmltag($search_label) . '"></td>';
-	print '<td class="liste_titre"><input type="text" class="flat maxwidthonsmartphone" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
+	print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
 	print '<td class="liste_titre right"><input type="text" class="flat maxwidth50 right" name="search_amount" value="' . dol_escape_htmltag($search_amount) . '"></td>';
 	print '<td class="liste_titre right"><input type="text" class="flat maxwidth50 right" name="search_vat" placeholder="%" size="1" value="' . dol_escape_htmltag($search_vat) . '"></td>';
 	print '<td class="liste_titre">';
-	print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth200', 'code2', 1, 0, 1);
+	print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth150', 'code2', 1, 0, 1);
 	//print '<input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '">';
 	print '</td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_tvaintra" value="' . dol_escape_htmltag($search_tvaintra) . '"></td>';
@@ -407,10 +404,10 @@ if ($result) {
 	print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder);
 	//print_liste_field_titre("ProductLabel", $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder);
 	print_liste_field_titre("Description", $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder);
-	print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "l.total_ht", "", $param, '', $sortfield, $sortorder, 'right ');
+	print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "l.total_ht", "", $param, '', $sortfield, $sortorder, 'right maxwidth50 ');
 	print_liste_field_titre("VATRate", $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, '', $sortfield, $sortorder, 'right ');
 	print_liste_field_titre("Country", $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder);
-	print_liste_field_titre("VATIntra", $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder, 'center ');
+	print_liste_field_titre("VATIntra", $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder);
 	print_liste_field_titre("AccountAccountingSuggest", '', '', '', '', '', '', '', 'center ');
 	print_liste_field_titre("IntoAccount", '', '', '', '', '', '', '', 'center ');
 	$checkpicto='';
@@ -421,6 +418,8 @@ if ($result) {
 	$facture_static = new Facture($db);
 	$product_static = new Product($db);
 
+    $isSellerInEEC = isInEEC($mysoc);
+
 	while ( $i < min($num_lines, $limit) ) {
 		$objp = $db->fetch_object($result);
 
@@ -440,30 +439,53 @@ if ($result) {
 		$code_sell_p_notset = '';
 		$objp->aarowid_suggest = $objp->aarowid;
 
-        $isinEEC = isInEEC($objp->country_code);
+        $isBuyerInEEC = isInEEC($objp);
 
+        $suggestedaccountingaccountbydefaultfor = '';
     	if ($objp->type_l == 1) {
-			$objp->code_sell_l = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : '');
-			if ($objp->aarowid == '') {
-				$objp->aarowid_suggest = $aarowid_s;
-			}
+    		if ($objp->country_code == $mysoc->country_code || empty($objp->country_code)) {  // If buyer in same country than seller (if not defined, we assume it is same country)
+    			$objp->code_sell_l = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : '');
+    			$suggestedaccountingaccountbydefaultfor = '';
+    		} else {
+    			if ($isSellerInEEC && $isBuyerInEEC) {          // European intravat sale
+    				$objp->code_sell_l = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT : '');
+    				$suggestedaccountingaccountbydefaultfor = 'eec';
+	    		} else {                                        // Foreign sale
+	    			$objp->code_sell_l = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT : '');
+	    			$suggestedaccountingaccountbydefaultfor = 'export';
+	    		}
+    		}
 		} elseif ($objp->type_l == 0) {
-			$objp->code_sell_l = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : '');
-			if ($objp->aarowid == '') {
-				$objp->aarowid_suggest = $aarowid_p;
+			if ($objp->country_code == $mysoc->country_code || empty($objp->country_code)) {  // If buyer in same country than seller (if not defined, we assume it is same country)
+				$objp->code_sell_l = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : '');
+				$suggestedaccountingaccountbydefaultfor = '';
+			} else {
+				if ($isSellerInEEC && $isBuyerInEEC) {          // European intravat sale
+					$objp->code_sell_l = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT : '');
+					$suggestedaccountingaccountbydefaultfor = 'eec';
+				} else {
+					$objp->code_sell_l = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT : '');
+					$suggestedaccountingaccountbydefaultfor = 'export';
+				}
 			}
 		}
 		if ($objp->code_sell_l == -1) $objp->code_sell_l='';
 
-        if ($objp->country_sell == '1') {
+		$suggestedaccountingaccountfor = '';
+		if ($objp->country_code == $mysoc->country_code || empty($objp->country_code)) {  // If buyer in same country than seller (if not defined, we assume it is same country)
             $objp->code_sell_p = $objp->code_sell;
             $objp->aarowid_suggest = $objp->aarowid;
-        } elseif ($isinEEC === true) {
-            $objp->code_sell_p = $objp->code_sell_intra;
-            $objp->aarowid_suggest = $objp->aarowid_intra;
+            $suggestedaccountingaccountfor = '';
         } else {
-            $objp->code_sell_p = $objp->code_sell_export;
-            $objp->aarowid_suggest = $objp->aarowid_export;
+            if ($isSellerInEEC && $isBuyerInEEC) {          // European intravat sale
+                $objp->code_sell_p = $objp->code_sell_intra;
+                $objp->aarowid_suggest = $objp->aarowid_intra;
+                $suggestedaccountingaccountfor = 'eec';
+            } else {                                        // Foreign sale
+                $objp->code_sell_p = $objp->code_sell_export;
+                $objp->aarowid_suggest = $objp->aarowid_export;
+                $suggestedaccountingaccountfor = 'export';
+            }
         }
 
 		if (! empty($objp->code_sell)) {
@@ -473,8 +495,8 @@ if ($result) {
 		}
 		if (empty($objp->code_sell_l) && empty($objp->code_sell_p)) $code_sell_p_notset = 'color:red';
 
-		// $objp->code_sell_p is now code of product/service
 		// $objp->code_sell_l is now default code of product/service
+		// $objp->code_sell_p is now code of product/service
 
 		print '<tr class="oddeven">';
 
@@ -488,7 +510,7 @@ if ($result) {
 
 		// Ref Product
 		print '<td>';
-		if ($product_static->id)
+		if ($product_static->id > 0)
 			print $product_static->getNomUrl(1);
 		if ($objp->product_label) print '<br>'.$objp->product_label;
 		print '</td>';
@@ -499,7 +521,7 @@ if ($result) {
 		print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description);
 		print '</td>';
 
-		print '<td class="right">';
+		print '<td class="nowrap right">';
 		print price($objp->total_ht);
 		print '</td>';
 
@@ -510,23 +532,36 @@ if ($result) {
 		print vatrate($objp->tva_tx_line.($objp->vat_src_code?' ('.$objp->vat_src_code.')':''));
 		print '</td>';
 
-		print '<td>' . $objp->country .'</td>';
+        print '<td>';
+        $labelcountry=($objp->country_code && ($langs->trans("Country".$objp->country_code)!="Country".$objp->country_code))?$langs->trans("Country".$objp->country_code):$objp->country_label;
+        print $labelcountry;
+        print '</td>';
 
 		print '<td>' . $objp->tva_intra . '</td>';
 
 		// Current account
 		print '<td class="center" style="' . $code_sell_p_notset . '">';
-	    print (($objp->type_l == 1)?$langs->trans("DefaultForService"):$langs->trans("DefaultForProduct")) . ' = ' . ($objp->code_sell_l > 0 ? length_accountg($objp->code_sell_l) : $langs->trans("Unknown"));
-		if ($objp->product_id > 0)
+	    $s = (($objp->type_l == 1)?$langs->trans("DefaultForService"):$langs->trans("DefaultForProduct")).': ';
+	    $shelp = '';
+	    if ($suggestedaccountingaccountbydefaultfor == 'eec') $shelp.= $langs->trans("SaleEEC");
+	    elseif ($suggestedaccountingaccountbydefaultfor == 'export') $shelp.= $langs->trans("SaleExport");
+	    $s.= ($objp->code_sell_l > 0 ? length_accountg($objp->code_sell_l) : $langs->trans("NotDefined"));
+	    print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
+	    if ($objp->product_id > 0)
 		{
 		    print '<br>';
-		    print (($objp->type_l == 1)?$langs->trans("ThisService"):$langs->trans("ThisProduct")) . ' = ' . (empty($objp->code_sell_p) ? $langs->trans("Unknown") : length_accountg($objp->code_sell_p));
+		    $s = (($objp->type_l == 1)?$langs->trans("ThisService"):$langs->trans("ThisProduct")).': ';
+		    $shelp = '';
+		    if ($suggestedaccountingaccountfor == 'eec') $shelp = $langs->trans("SaleEEC");
+		    elseif ($suggestedaccountingaccountfor == 'export') $shelp = $langs->trans("SaleExport");
+		    $s.= (empty($objp->code_sell_p) ? $langs->trans("NotDefined") : length_accountg($objp->code_sell_p));
+		    print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
 		}
 		print '</td>';
 
 		// Suggested accounting account
-		print '<td class="center">';
-		print $formaccounting->select_account($objp->aarowid_suggest, 'codeventil'.$objp->rowid, 1, array(), 0, 0, 'codeventil maxwidth300 maxwidthonsmartphone', 'cachewithshowemptyone');
+		print '<td>';
+		print $formaccounting->select_account($objp->aarowid_suggest, 'codeventil'.$objp->rowid, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone');
 		print '</td>';
 
 		// Column with checkbox

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

@@ -23,7 +23,7 @@
  */
 /**
  * \file		htdocs/accountancy/supplier/card.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Card expense report ventilation
  */
 require '../../main.inc.php';

+ 11 - 11
htdocs/accountancy/expensereport/index.php

@@ -20,7 +20,7 @@
 
 /**
  * \file		htdocs/accountancy/expensereport/index.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Home expense report ventilation
  */
 
@@ -139,9 +139,9 @@ $textnextyear = '&nbsp;<a href="' . $_SERVER["PHP_SELF"] . '?year=' . ($year_cur
 
 print load_fiche_titre($langs->trans("ExpenseReportsVentilation") . "&nbsp;" . $textprevyear . "&nbsp;" . $langs->trans("Year") . "&nbsp;" . $year_start . "&nbsp;" . $textnextyear, '', 'title_accountancy');
 
-print $langs->trans("DescVentilExpenseReport") . '<br>';
+print '<span class="opacitymedium">'.$langs->trans("DescVentilExpenseReport") . '<br>';
 print $langs->trans("DescVentilExpenseReportMore", $langs->transnoentitiesnoconv("ValidateHistory"), $langs->transnoentitiesnoconv("ToBind")) . '<br>';
-print '<br>';
+print '</span><br>';
 
 
 $y = $year_current;
@@ -203,10 +203,10 @@ if ($resql) {
 		else print $row[1];
 		print '</td>';
     	for($i = 2; $i <= 12; $i ++) {
-            print '<td class="right">' . price($row[$i]) . '</td>';
+            print '<td class="nowrap right">' . price($row[$i]) . '</td>';
         }
-        print '<td class="right">' . price($row[13]) . '</td>';
-        print '<td class="right"><b>' . price($row[14]) . '</b></td>';
+        print '<td class="nowrap right">' . price($row[13]) . '</td>';
+        print '<td class="nowrap right"><b>' . price($row[14]) . '</b></td>';
         print '</tr>';
     }
     $db->free($resql);
@@ -276,10 +276,10 @@ if ($resql) {
 		else print $row[1];
 		print '</td>';
     	for($i = 2; $i <= 12; $i ++) {
-            print '<td class="right">' . price($row[$i]) . '</td>';
+            print '<td class="nowrap right">' . price($row[$i]) . '</td>';
         }
-        print '<td class="right">' . price($row[13]) . '</td>';
-        print '<td class="right"><b>' . price($row[14]) . '</b></td>';
+        print '<td class="nowrap right">' . price($row[13]) . '</td>';
+        print '<td class="nowrap right"><b>' . price($row[14]) . '</b></td>';
         print '</tr>';
     }
     $db->free($resql);
@@ -331,9 +331,9 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
     	while ($row = $db->fetch_row($resql)) {
     		print '<tr><td>' . $row[0] . '</td>';
             for($i = 1; $i <= 12; $i ++) {
-    			print '<td class="right">' . price($row[$i]) . '</td>';
+    			print '<td class="nowrap right">' . price($row[$i]) . '</td>';
     		}
-    		print '<td class="right"><b>' . price($row[13]) . '</b></td>';
+    		print '<td class="nowrap right"><b>' . price($row[13]) . '</b></td>';
     		print '</tr>';
     	}
 

+ 5 - 5
htdocs/accountancy/expensereport/lines.php

@@ -21,7 +21,7 @@
 
 /**
  * \file 		htdocs/accountancy/expensereport/lines.php
- * \ingroup 	Advanced accountancy
+ * \ingroup 	Accountancy (Double entries)
  * \brief 		Page of detail of the lines of ventilation of expense reports
  */
 require '../../main.inc.php';
@@ -248,7 +248,7 @@ if ($result) {
 
 	print_barre_liste($langs->trans("ExpenseReportLinesDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
 
-	print $langs->trans("DescVentilDoneExpenseReport") . '<br>';
+	print '<span class="opacitymedium">'.$langs->trans("DescVentilDoneExpenseReport") . '</span><br>';
 
 	print '<br><div class="inline-block divButAction">' . $langs->trans("ChangeAccount") . '<br>';
 	print $formaccounting->select_account($account_parent, 'account_parent', 2, array(), 0, 0, 'maxwidth300 maxwidthonsmartphone valignmiddle');
@@ -263,8 +263,8 @@ if ($result) {
 	print '<td class="liste_titre"></td>';
 	print '<td><input type="text" class="flat maxwidth50" name="search_expensereport" value="' . dol_escape_htmltag($search_expensereport) . '"></td>';
 	print '<td class="liste_titre center">';
-   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="search_day" value="'.$search_day.'">';
-   	print '<input class="flat" type="text" size="1" maxlength="2" name="search_month" value="'.$search_month.'">';
+   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_day" value="'.$search_day.'">';
+   	print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_month" value="'.$search_month.'">';
    	$formother->select_year($search_year, 'search_year', 1, 20, 5);
 	print '</td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="' . dol_escape_htmltag($search_label) . '"></td>';
@@ -319,7 +319,7 @@ if ($result) {
 		print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments);
 		print '</td>';
 
-		print '<td class="right">' . price($objp->total_ht) . '</td>';
+		print '<td class="nowrap right">' . price($objp->total_ht) . '</td>';
 
 		print '<td class="center">' . vatrate($objp->tva_tx.($objp->vat_src_code?' ('.$objp->vat_src_code.')':'')) . '</td>';
 

+ 7 - 7
htdocs/accountancy/expensereport/list.php

@@ -22,7 +22,7 @@
 
 /**
  * \file 		htdocs/accountancy/expensereport/list.php
- * \ingroup 	Advanced accountancy
+ * \ingroup 	Accountancy (Double entries)
  * \brief 		Ventilation page from expense reports
  */
 require '../../main.inc.php';
@@ -289,7 +289,7 @@ if ($result) {
 
 	print_barre_liste($langs->trans("ExpenseReportLines"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
 
-	print $langs->trans("DescVentilTodoExpenseReport") . '</br><br>';
+	print '<span class="opacitymedium">'.$langs->trans("DescVentilTodoExpenseReport") . '</span></br><br>';
 
 	/*$topicmail="Information";
 	$modelmail="project";
@@ -309,8 +309,8 @@ if ($result) {
 	print '<td class="liste_titre"></td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_expensereport" value="' . dol_escape_htmltag($search_expensereport) . '"></td>';
 	print '<td class="liste_titre center">';
-   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_day" value="'.$search_day.'">';
-   	print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_month" value="'.$search_month.'">';
+   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_day" value="'.$search_day.'">';
+   	print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_month" value="'.$search_month.'">';
    	$formother->select_year($search_year, 'search_year', 1, 20, 5);
 	print '</td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="' . dol_escape_htmltag($search_label) . '"></td>';
@@ -331,7 +331,7 @@ if ($result) {
 	print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "erd.date, erd.rowid", "", $param, '', $sortfield, $sortorder, 'center ');
 	print_liste_field_titre("TypeFees", $_SERVER["PHP_SELF"], "f.label", "", $param, '', $sortfield, $sortorder);
 	print_liste_field_titre("Description", $_SERVER["PHP_SELF"], "erd.comments", "", $param, '', $sortfield, $sortorder);
-	print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "erd.total_ht", "", $param, '', $sortfield, $sortorder, 'right ');
+	print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "erd.total_ht", "", $param, '', $sortfield, $sortorder, 'right maxwidth50 ');
 	print_liste_field_titre("VATRate", $_SERVER["PHP_SELF"], "erd.tva_tx", "", $param, '', $sortfield, $sortorder, 'right ');
 	print_liste_field_titre("AccountAccountingSuggest", '', '', '', '', '', $sortfield, $sortorder, 'center ');
 	print_liste_field_titre("IntoAccount", '', '', '', '', '', $sortfield, $sortorder, 'center ');
@@ -376,7 +376,7 @@ if ($result) {
 		print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments);
 		print '</td>';
 
-		print '<td class="right">';
+		print '<td class="nowrap right">';
 		print price($objp->price);
 		print '</td>';
 
@@ -386,7 +386,7 @@ if ($result) {
 		print '</td>';
 
 		// Current account
-		print '<td class="center">';
+		print '<td>';
 		print length_accountg(html_entity_decode($objp->code_buy));
 		print '</td>';
 

+ 1 - 1
htdocs/accountancy/index.php

@@ -18,7 +18,7 @@
 
 /**
  * \file    htdocs/accountancy/index.php
- * \ingroup Advanced accountancy
+ * \ingroup Accountancy (Double entries)
  * \brief   Home accounting module
  */
 

+ 79 - 44
htdocs/accountancy/journal/bankjournal.php

@@ -8,8 +8,8 @@
  * Copyright (C) 2013-2014  Florian Henry           <florian.henry@open-concept.pro>
  * Copyright (C) 2013-2014  Olivier Geffroy         <jeff@jeffinfo.com>
  * Copyright (C) 2017-2018  Frédéric France         <frederic.france@netlogic.fr>
- * Copyright (C) 2018		Ferran Marcet	    <fmarcet@2byte.es>
- * Copyright (C) 2018		Eric Seigne	    <eric.seigne@cap-rel.fr>
+ * Copyright (C) 2018		Ferran Marcet	        <fmarcet@2byte.es>
+ * Copyright (C) 2018		Eric Seigne	            <eric.seigne@cap-rel.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@
 
 /**
  *  \file       htdocs/accountancy/journal/bankjournal.php
- *  \ingroup    Advanced accountancy
+ *  \ingroup    Accountancy (Double entries)
  *  \brief      Page with bank journal
  */
 require '../../main.inc.php';
@@ -107,8 +107,6 @@ if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end)
 	$date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
 }
 
-$idpays = $mysoc->country_id;
-
 $sql  = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.label, b.rappro, b.num_releve, b.num_chq, b.fk_type, b.fk_account,";
 $sql .= " ba.courant, ba.ref as baref, ba.account_number, ba.fk_accountancy_journal,";
 $sql .= " soc.code_compta, soc.code_compta_fournisseur, soc.rowid as socid, soc.nom as name, soc.email as email, bu1.type as typeop_company,";
@@ -154,6 +152,9 @@ $paymentloanstatic = new PaymentLoan($db);
 $accountLinestatic=new AccountLine($db);
 $paymentsubscriptionstatic = new Subscription($db);
 
+$tmppayment = new Paiement($db);
+$tmpinvoice = new Facture($db);
+
 $accountingaccount = new AccountingAccount($db);
 
 // Get code of finance journal
@@ -171,8 +172,8 @@ if ($result) {
 	//print $sql;
 
 	// Variables
-	$account_supplier			= (! empty($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) ? $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER : 'NotDefined');	// NotDefined is a reserved word
-	$account_customer			= (! empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) ? $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER : 'NotDefined');	// NotDefined is a reserved word
+	$account_supplier			= (($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER != "") ? $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER : 'NotDefined');	// NotDefined is a reserved word
+	$account_customer			= (($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER != "") ? $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER : 'NotDefined');	// NotDefined is a reserved word
 	$account_employee			= (! empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) ? $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT : 'NotDefined');	// NotDefined is a reserved word
 	$account_pay_vat			= (! empty($conf->global->ACCOUNTING_VAT_PAY_ACCOUNT) ? $conf->global->ACCOUNTING_VAT_PAY_ACCOUNT : 'NotDefined');	// NotDefined is a reserved word
 	$account_pay_donation		= (! empty($conf->global->DONATION_ACCOUNTINGACCOUNT) ? $conf->global->DONATION_ACCOUNTINGACCOUNT : 'NotDefined');	// NotDefined is a reserved word
@@ -185,13 +186,14 @@ if ($result) {
 	$tabbq = array ();
 	$tabtp = array ();
 	$tabtype = array ();
+	$tabmoreinfo = array();
 
 	// Loop on each line into llx_bank table. For each line, we should get:
 	// one line tabpay = line into bank
 	// one line for bank record = tabbq
 	// one line for thirdparty record = tabtp
 	$i = 0;
-	while ( $i < $num )
+	while ($i < $num)
 	{
 		$obj = $db->fetch_object($result);
 
@@ -215,10 +217,10 @@ if ($result) {
 		// Set accountancy code for bank
 		$compta_bank = $obj->account_number;
 
-		// Set accountancy code for thirdparty
+		// Set accountancy code for thirdparty (example: '411CU...' or '411' if no subledger account defined on customer)
 		$compta_soc = 'NotDefined';
 		if ($lineisapurchase > 0)
-			$compta_soc = (! empty($obj->code_compta_fournisseur) ? $obj->code_compta_fournisseur : $account_supplier);
+			$compta_soc = (($obj->code_compta_fournisseur != "") ? $obj->code_compta_fournisseur : $account_supplier);
 		if ($lineisasale > 0)
 			$compta_soc = (! empty($obj->code_compta) ? $obj->code_compta : $account_customer);
 
@@ -257,10 +259,12 @@ if ($result) {
 
 		//var_dump($i);
 		//var_dump($tabpay);
+		//var_dump($tabcompany);
 
 		// By default
 		$tabpay[$obj->rowid]['type'] = 'unknown';	// Can be SOLD, miscellaneous entry, payment of patient, or any old record with no links in bank_url.
 		$tabtype[$obj->rowid] = 'unknown';
+		$tabmoreinfo[$obj->rowid] = array();
 
 		// get_url may return -1 which is not traversable
 		if (is_array($links) && count($links) > 0) {
@@ -285,6 +289,10 @@ if ($result) {
 					}
 				}
 
+				if ($links[$key]['type'] == 'withdraw') {
+					$tabmoreinfo[$obj->rowid]['withdraw']=1;
+				}
+
 				if ($links[$key]['type'] == 'payment') {
 					$paymentstatic->id = $links[$key]['url_id'];
 					$paymentstatic->ref = $links[$key]['url_id'];
@@ -411,8 +419,30 @@ if ($result) {
 
 		$tabbq[$obj->rowid][$compta_bank] += $obj->amount;
 
-		// If not links were found to know amount on thirdparty, we init it.
-		if (empty($tabtp[$obj->rowid])) $tabtp[$obj->rowid]['NotDefined']= $tabbq[$obj->rowid][$compta_bank];
+		// If no links were found to know the amount on thirdparty, we try to guess it.
+		// This may happens on bank entries without the links lines to 'company'.
+		if (empty($tabtp[$obj->rowid]) && ! empty($tabmoreinfo[$obj->rowid]['withdraw']))	// If we dont find 'company' link because it is an old 'withdraw' record
+		{
+			foreach ($links as $key => $val) {
+				if ($links[$key]['type'] == 'payment') {
+					// Get thirdparty
+					$tmppayment->fetch($links[$key]['url_id']);
+					$arrayofamounts = $tmppayment->getAmountsArray();
+					foreach($arrayofamounts as $invoiceid => $amount)
+					{
+						$tmpinvoice->fetch($invoiceid);
+						$tmpinvoice->fetch_thirdparty();
+						if ($tmpinvoice->thirdparty->code_compta)
+						{
+							$tabtp[$obj->rowid][$tmpinvoice->thirdparty->code_compta] += $amount;
+						}
+					}
+				}
+			}
+		}
+
+		// If no links were found to know the amount on thirdparty, we init it to account 'NotDefined'.
+		if (empty($tabtp[$obj->rowid])) $tabtp[$obj->rowid]['NotDefined'] = $tabbq[$obj->rowid][$compta_bank];
 
 		// Check account number is ok
 		/*if ($action == 'writebookkeeping')		// Make test now in such a case
@@ -441,11 +471,12 @@ if ($result) {
 	dol_print_error($db);
 }
 
-/*
-var_dump($tabpay);
+
+/*var_dump($tabpay);
+var_dump($tabcompany);
 var_dump($tabbq);
 var_dump($tabtp);
-*/
+var_dump($tabtype);*/
 
 // Write bookkeeping
 if (! $error && $action == 'writebookkeeping') {
@@ -561,15 +592,15 @@ if (! $error && $action == 'writebookkeeping') {
 						$bookkeeping->date_create = $now;
 
 						if ($tabtype[$key] == 'payment') {	// If payment is payment of customer invoice, we get ref of invoice
-							$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
-							$bookkeeping->subledger_label = $tabcompany[$key]['name'];
+							$bookkeeping->subledger_account = $k;							// For payment, the subledger account is stored as $key of $tabtp
+							$bookkeeping->subledger_label = $tabcompany[$key]['name'];		// $tabcompany is defined only if we are sure there is 1 thirdparty for the bank transaction
 							$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
 
 							$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER, true);
 							$bookkeeping->label_compte = $accountingaccount->label;
-						} elseif ($tabtype[$key] == 'payment_supplier') {		   // If payment is payment of supplier invoice, we get ref of invoice
-							$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
-							$bookkeeping->subledger_label = $tabcompany[$key]['name'];
+						} elseif ($tabtype[$key] == 'payment_supplier') {	// If payment is payment of supplier invoice, we get ref of invoice
+							$bookkeeping->subledger_account = $k;				   			// For payment, the subledger account is stored as $key of $tabtp
+							$bookkeeping->subledger_label = $tabcompany[$key]['name'];		// $tabcompany is defined only if we are sure there is 1 thirdparty for the bank transaction
 							$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER;
 
 							$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER, true);
@@ -701,6 +732,7 @@ if (! $error && $action == 'writebookkeeping') {
 						$totalcredit += $bookkeeping->credit;
 
 						$result = $bookkeeping->create($user);
+
 						if ($result < 0) {
 							if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists')	// Already exists
 							{
@@ -931,18 +963,18 @@ if (empty($action) || $action == 'view') {
 		if ($obj->nb > 0)
 		{
 			print '<br>'.img_warning().' '.$langs->trans("TheJournalCodeIsNotDefinedOnSomeBankAccount");
-			print ' : '.$langs->trans("AccountancyAreaDescBank", 9, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("BankAccounts").'</strong>');
+			print ' : '.$langs->trans("AccountancyAreaDescBank", 9, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("BankAccounts").'</strong>');
 		}
 	}
 	else dol_print_error($db);
 
 
 	// Button to write into Ledger
-	if (empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1'
-		|| empty($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1'
+	if (($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "") || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1'
+		|| ($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "") || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1'
 		|| empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1') {
 		print '<br>'.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
-		print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
+		print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
 	}
 
 
@@ -950,8 +982,8 @@ if (empty($action) || $action == 'view') {
 
 	if (! empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL)) print '<input type="button" class="butAction" name="exportcsv" value="' . $langs->trans("ExportDraftJournal") . '" onclick="launch_export();" />';
 
-	if (empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1'
-	    || empty($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1') {
+	if (($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "") || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1'
+	    || ($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "") || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1') {
 	   print '<input type="button" class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")).'" value="' . $langs->trans("WriteBookKeeping") . '" />';
 	}
 	else {
@@ -987,15 +1019,14 @@ if (empty($action) || $action == 'view') {
 	print '<div class="div-table-responsive">';
 	print "<table class=\"noborder\" width=\"100%\">";
 	print "<tr class=\"liste_titre\">";
-	print "<td></td>";
 	print "<td>" . $langs->trans("Date") . "</td>";
 	print "<td>" . $langs->trans("Piece") . ' (' . $langs->trans("ObjectsRef") . ")</td>";
 	print "<td>" . $langs->trans("AccountAccounting") . "</td>";
 	print "<td>" . $langs->trans("SubledgerAccount") . "</td>";
 	print "<td>" . $langs->trans("LabelOperation") . "</td>";
-	print "<td>" . $langs->trans("PaymentMode") . "</td>";
-	print "<td class='right'>" . $langs->trans("Debit") . "</td>";
-	print "<td class='right'>" . $langs->trans("Credit") . "</td>";
+	print '<td class="center">' . $langs->trans("PaymentMode") . "</td>";
+	print '<td class="right">' . $langs->trans("Debit") . "</td>";
+	print '<td class="right">' . $langs->trans("Credit") . "</td>";
 	print "</tr>\n";
 
 	$r = '';
@@ -1019,7 +1050,6 @@ if (empty($action) || $action == 'view') {
 				//var_dump($tabpay[$key]);
 				print '<!-- Bank bank.rowid='.$key.' type='.$tabpay[$key]['type'].' ref='.$tabpay[$key]['ref'].'-->';
 				print '<tr class="oddeven">';
-				print "<td></td>";
 				print "<td>" . $date . "</td>";
 				print "<td>" . $ref . "</td>";
 				// Ledger account
@@ -1043,9 +1073,9 @@ if (empty($action) || $action == 'view') {
 				print "<td>";
 				print $reflabel;
 				print "</td>";
-				print "<td>" . $val["type_payment"] . "</td>";
-				print "<td class='right'>" . ($mt >= 0 ? price($mt) : '') . "</td>";
-				print "<td class='right'>" . ($mt < 0 ? price(- $mt) : '') . "</td>";
+				print '<td class="center">' . $val["type_payment"] . "</td>";
+				print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
 				print "</tr>";
 			}
 		}
@@ -1061,7 +1091,6 @@ if (empty($action) || $action == 'view') {
 
 					print '<!-- Thirdparty bank.rowid='.$key.' -->';
 					print '<tr class="oddeven">';
-					print "<td></td>";
 					print "<td>" . $date . "</td>";
 					print "<td>" . $ref . "</td>";
 					// Ledger account
@@ -1074,7 +1103,6 @@ if (empty($action) || $action == 'view') {
 					if ($tabtype[$key] == 'payment_salary')			$account_ledger = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
 					if ($tabtype[$key] == 'payment_vat')			$account_ledger = $conf->global->ACCOUNTING_VAT_PAY_ACCOUNT;
 					if ($tabtype[$key] == 'member')					$account_ledger = $conf->global->ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT;
-
 					$accounttoshow = length_accounta($account_ledger);
 					if (empty($accounttoshow) || $accounttoshow == 'NotDefined')
 					{
@@ -1107,6 +1135,7 @@ if (empty($action) || $action == 'view') {
 					print "</td>";
 					// Subledger account
 					print "<td>";
+
 					if (in_array($tabtype[$key], array('payment', 'payment_supplier', 'payment_expensereport', 'payment_salary')))	// Type of payment with subledger
 					{
 						$accounttoshowsubledger = length_accounta($k);
@@ -1118,16 +1147,23 @@ if (empty($action) || $action == 'view') {
 								var_dump($tabtype[$key]);
 								var_dump($tabbq[$key]);*/
 								//print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefined").'</span>';
-								print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown").'</span>';
+								if (! empty($tabcompany[$key]['code_compta']))
+								{
+									print '<span class="warning">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown", $tabcompany[$key]['code_compta']).'</span>';
+								}
+								else
+								{
+									print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking").'</span>';
+								}
 							}
 							else print $accounttoshowsubledger;
 						}
 					}
 					print "</td>";
 					print "<td>" . $reflabel . "</td>";
-					print "<td>" . $val["type_payment"] . "</td>";
-					print "<td class='right'>" . ($mt < 0 ? price(- $mt) : '') . "</td>";
-					print "<td class='right'>" . ($mt >= 0 ? price($mt) : '') . "</td>";
+					print '<td class="center">' . $val["type_payment"] . "</td>";
+					print '<td class="right nowraponall">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
+					print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
 					print "</tr>";
 				}
 			}
@@ -1141,7 +1177,6 @@ if (empty($action) || $action == 'view') {
 
 					print '<!-- Wait bank.rowid='.$key.' -->';
 					print '<tr class="oddeven">';
-					print "<td></td>";
 					print "<td>" . $date . "</td>";
 					print "<td>" . $ref . "</td>";
 					// Ledger account
@@ -1162,9 +1197,9 @@ if (empty($action) || $action == 'view') {
 					*/
 					print "</td>";
 					print "<td>" . $reflabel . "</td>";
-					print "<td>" . $val["type_payment"] . "</td>";
-					print "<td class='right'>" . ($mt < 0 ? price(- $mt) : '') . "</td>";
-					print "<td class='right'>" . ($mt >= 0 ? price($mt) : '') . "</td>";
+					print '<td class="center">' . $val["type_payment"] . "</td>";
+					print '<td class="right nowraponall">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
+					print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
 					print "</tr>";
 				}
 			}

+ 23 - 27
htdocs/accountancy/journal/expensereportsjournal.php

@@ -25,7 +25,7 @@
 
 /**
  * \file		htdocs/accountancy/journal/expensereportsjournal.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Page with expense reports journal
  */
 require '../../main.inc.php';
@@ -87,15 +87,11 @@ if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end)
 	$date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
 }
 
-$idpays = $mysoc->country_id;
-
 $sql = "SELECT er.rowid, er.ref, er.date_debut as de,";
 $sql .= " erd.rowid as erdid, erd.comments, erd.total_ht, erd.total_tva, erd.total_localtax1, erd.total_localtax2, erd.tva_tx, erd.total_ttc, erd.fk_code_ventilation, erd.vat_src_code, ";
 $sql .= " u.rowid as uid, u.firstname, u.lastname, u.accountancy_code as user_accountancy_account,";
 $sql .= " f.accountancy_code, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte";
-//$sql .= " ct.accountancy_code_buy as account_tva";
 $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
-//$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_tva as ct ON erd.tva_tx = ct.taux AND ct.fk_pays = '" . $idpays . "'";
 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as f ON f.id = erd.fk_c_type_fees";
 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = erd.fk_code_ventilation";
 $sql .= " JOIN " . MAIN_DB_PREFIX . "expensereport as er ON er.rowid = erd.fk_expensereport";
@@ -444,10 +440,10 @@ if ($action == 'exportcsv') {		// ISO and not UTF8 !
 
 	foreach ($taber as $key => $val) {
 	  $date = dol_print_date($val["date"], 'day');
-	  
+
 	  $userstatic->id = $tabuser[$key]['id'];
 	  $userstatic->name = $tabuser[$key]['name'];
-	  
+
 	  // Fees
 	  foreach ($tabht[$key] as $k => $mt) {
 	    $accountingaccount = new AccountingAccount($db);
@@ -474,7 +470,7 @@ if ($action == 'exportcsv') {		// ISO and not UTF8 !
 	      print "\n";
 	    }
 	  }
-	  
+
 	  // Third party
 	  foreach ($tabttc[$key] as $k => $mt) {
 	    print '"' . $date . '"' . $sep;
@@ -510,7 +506,7 @@ if (empty($action) || $action == 'view') {
 	// Button to write into Ledger
 	if (empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1') {
 		print '<br>'.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
-		print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
+		print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
 	}
 	print '<div class="tabsAction tabsActionNoBottom">';
 
@@ -549,14 +545,13 @@ if (empty($action) || $action == 'view') {
 	print '<div class="div-table-responsive">';
 	print "<table class=\"noborder\" width=\"100%\">";
 	print "<tr class=\"liste_titre\">";
-	print "<td></td>";
 	print "<td>" . $langs->trans("Date") . "</td>";
 	print "<td>" . $langs->trans("Piece") . ' (' . $langs->trans("ExpenseReportRef") . ")</td>";
 	print "<td>" . $langs->trans("AccountAccounting") . "</td>";
 	print "<td>" . $langs->trans("SubledgerAccount") . "</td>";
 	print "<td>" . $langs->trans("LabelOperation") . "</td>";
-	print "<td class='right'>" . $langs->trans("Debit") . "</td>";
-	print "<td class='right'>" . $langs->trans("Credit") . "</td>";
+	print '<td class="right">' . $langs->trans("Debit") . "</td>";
+	print '<td class="right">' . $langs->trans("Credit") . "</td>";
 	print "</tr>\n";
 
 	$r = '';
@@ -578,7 +573,7 @@ if (empty($action) || $action == 'view') {
 
 			if ($mt) {
 				print '<tr class="oddeven">';
-				print "<td><!-- Fees --></td>";
+				print "<!-- Fees -->";
 				print "<td>" . $date . "</td>";
 				print "<td>" . $expensereportstatic->getNomUrl(1) . "</td>";
 				$userstatic->id = $tabuser[$key]['id'];
@@ -586,7 +581,7 @@ if (empty($action) || $action == 'view') {
 				// Account
 				print "<td>";
 				$accountoshow = length_accountg($k);
-				if (empty($accountoshow) || $accountoshow == 'NotDefined')
+				if (($accountoshow == "") || $accountoshow == 'NotDefined')
 				{
 					print '<span class="error">'.$langs->trans("FeeAccountNotDefined").'</span>';
 				}
@@ -598,24 +593,25 @@ if (empty($action) || $action == 'view') {
 				$userstatic->id = $tabuser[$key]['id'];
 				$userstatic->name = $tabuser[$key]['name'];
 				print "<td>" . $userstatic->getNomUrl(0, 'user', 16) . ' - ' . $accountingaccount->label . "</td>";
-				print '<td class="right">' . ($mt >= 0 ? price($mt) : '') . "</td>";
-				print '<td class="right">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
 				print "</tr>";
 			}
 		}
 
 		// Third party
 		foreach ($tabttc[$key] as $k => $mt) {
+			$userstatic->id = $tabuser[$key]['id'];
+			$userstatic->name = $tabuser[$key]['name'];
+
 			print '<tr class="oddeven">';
-			print "<td><!-- Thirdparty --></td>";
+			print "<!-- Thirdparty -->";
 			print "<td>" . $date . "</td>";
 			print "<td>" . $expensereportstatic->getNomUrl(1) . "</td>";
-			$userstatic->id = $tabuser[$key]['id'];
-			$userstatic->name = $tabuser[$key]['name'];
 			// Account
 			print "<td>";
 			$accountoshow = length_accounta($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT);
-			if (empty($accountoshow) || $accountoshow == 'NotDefined')
+			if (($accountoshow == "") || $accountoshow == 'NotDefined')
 			{
 				print '<span class="error">'.$langs->trans("MainAccountForUsersNotDefined").'</span>';
 			}
@@ -624,15 +620,15 @@ if (empty($action) || $action == 'view') {
 			// Subledger account
 			print "<td>";
 			$accountoshow = length_accounta($k);
-			if (empty($accountoshow) || $accountoshow == 'NotDefined')
+			if (($accountoshow == "") || $accountoshow == 'NotDefined')
 			{
 				print '<span class="error">'.$langs->trans("UserAccountNotDefined").'</span>';
 			}
 			else print $accountoshow;
 			print '</td>';
 			print "<td>" . $userstatic->getNomUrl(0, 'user', 16) . ' - ' . $langs->trans("SubledgerAccount") . "</td>";
-			print '<td class="right">' . ($mt < 0 ? - price(- $mt) : '') . "</td>";
-			print '<td class="right">' . ($mt >= 0 ? price($mt) : '') . "</td>";
+			print '<td class="right nowraponall">' . ($mt < 0 ? - price(- $mt) : '') . "</td>";
+			print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
 			print "</tr>";
 		}
 
@@ -646,13 +642,13 @@ if (empty($action) || $action == 'view') {
 			foreach ($arrayofvat[$key] as $k => $mt) {
 			if ($mt) {
 				print '<tr class="oddeven">';
-				print "<td><!-- VAT --></td>";
+				print "<!-- VAT -->";
 				print "<td>" . $date . "</td>";
 				print "<td>" . $expensereportstatic->getNomUrl(1) . "</td>";
 				// Account
 				print "<td>";
 				$accountoshow = length_accountg($k);
-				if (empty($accountoshow) || $accountoshow == 'NotDefined')
+				if (($accountoshow == "") || $accountoshow == 'NotDefined')
 				{
 					print '<span class="error">'.$langs->trans("VATAccountNotDefined").'</span>';
 				}
@@ -663,8 +659,8 @@ if (empty($action) || $action == 'view') {
 				print '</td>';
 				print "<td>" . $userstatic->getNomUrl(0, 'user', 16) . ' - ' . $langs->trans("VAT"). ' '.join(', ', $def_tva[$key][$k]).' %'.($numtax?' - Localtax '.$numtax:'');
 				print "</td>";
-				print '<td class="right">' . ($mt >= 0 ? price($mt) : '') . "</td>";
-				print '<td class="right">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
 				print "</tr>";
 			}
 			}

+ 20 - 22
htdocs/accountancy/journal/purchasesjournal.php

@@ -25,7 +25,7 @@
 
 /**
  * \file		htdocs/accountancy/journal/purchasesjournal.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Page with purchases journal
  */
 require '../../main.inc.php';
@@ -92,8 +92,6 @@ if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end)
 	$date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
 }
 
-$idpays = $mysoc->country_id;
-
 $sql = "SELECT f.rowid, f.ref as ref, f.type, f.datef as df, f.libelle,f.ref_supplier, f.date_lim_reglement as dlf, f.close_code,";
 $sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.tva as total_tva, fd.total_localtax1, fd.total_localtax2, fd.tva_tx, fd.total_ttc, fd.vat_src_code,";
 $sql .= " s.rowid as socid, s.nom as name, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
@@ -743,12 +741,13 @@ if (empty($action) || $action == 'view') {
 
 	// Button to write into Ledger
 	if (($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "") || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1') {
+		print '<br>';
 		print img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
-		print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
+		print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
 	}
 	print '<div class="tabsAction tabsActionNoBottom">';
 	if (! empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL)) print '<input type="button" class="butAction" name="exportcsv" value="' . $langs->trans("ExportDraftJournal") . '" onclick="launch_export();" />';
-	if (empty($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1') {
+	if (($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "") || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1') {
 		print '<input type="button" class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")).'" value="' . $langs->trans("WriteBookKeeping") . '" />';
 	}
 	else {
@@ -782,14 +781,13 @@ if (empty($action) || $action == 'view') {
 	print '<div class="div-table-responsive">';
 	print "<table class=\"noborder\" width=\"100%\">";
 	print "<tr class=\"liste_titre\">";
-	print "<td></td>";
 	print "<td>" . $langs->trans("Date") . "</td>";
 	print "<td>" . $langs->trans("Piece") . ' (' . $langs->trans("InvoiceRef") . ")</td>";
 	print "<td>" . $langs->trans("AccountAccounting") . "</td>";
 	print "<td>" . $langs->trans("SubledgerAccount") . "</td>";
 	print "<td>" . $langs->trans("LabelOperation") . "</td>";
-	print "<td class='right'>" . $langs->trans("Debit") . "</td>";
-	print "<td class='right'>" . $langs->trans("Credit") . "</td>";
+	print '<td class="center">' . $langs->trans("Debit") . "</td>";
+	print '<td class="center">' . $langs->trans("Credit") . "</td>";
 	print "</tr>\n";
 
 	$r = '';
@@ -829,7 +827,7 @@ if (empty($action) || $action == 'view') {
 		if ($replacedinvoice == 1)
 		{
 			print '<tr class="oddeven">';
-			print "<td><!-- Replaced invoice --></td>";
+			print "<!-- Replaced invoice -->";
 			print "<td>" . $date . "</td>";
 			print "<td><strike>" . $invoicestatic->getNomUrl(1) . "</strike></td>";
 			// Account
@@ -850,7 +848,7 @@ if (empty($action) || $action == 'view') {
 		if ($errorforinvoice[$key] == 'somelinesarenotbound')
 		{
 			print '<tr class="oddeven">';
-			print "<td><!-- Some lines are not bound --></td>";
+			print "<!-- Some lines are not bound -->";
 			print "<td>" . $date . "</td>";
 			print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
 			// Account
@@ -871,7 +869,7 @@ if (empty($action) || $action == 'view') {
 		foreach ($tabttc[$key] as $k => $mt) {
 			//if ($mt) {
 				print '<tr class="oddeven">';
-				print "<td><!-- Thirdparty --></td>";
+				print "<!-- Thirdparty -->";
 				print "<td>" . $date . "</td>";
 				print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
 				// Account
@@ -893,8 +891,8 @@ if (empty($action) || $action == 'view') {
 				else print $accountoshow;
 				print '</td>';
 				print "<td>" . $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("SubledgerAccount") . "</td>";
-				print '<td class="right">'. ($mt < 0 ? price(- $mt) : '') . "</td>";
-				print '<td class="right">' . ($mt >= 0 ? price($mt) : '') . "</td>";
+				print '<td class="right nowraponall">'. ($mt < 0 ? price(- $mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
 				print "</tr>";
 			//}
 		}
@@ -906,7 +904,7 @@ if (empty($action) || $action == 'view') {
 
 			//if ($mt) {
 				print '<tr class="oddeven">';
-				print "<td><!-- Product --></td>";
+				print "<!-- Product -->";
 				print "<td>" . $date . "</td>";
 				print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
 				// Account
@@ -924,8 +922,8 @@ if (empty($action) || $action == 'view') {
 				$companystatic->id = $tabcompany[$key]['id'];
 				$companystatic->name = $tabcompany[$key]['name'];
 				print "<td>" . $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $accountingaccount->label . "</td>";
-				print '<td class="right">' . ($mt >= 0 ? price($mt) : '') . "</td>";
-				print '<td class="right">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
 				print "</tr>";
 			//}
 		}
@@ -940,7 +938,7 @@ if (empty($action) || $action == 'view') {
 			foreach ($arrayofvat[$key] as $k => $mt) {
 				if ($mt) {
 					print '<tr class="oddeven">';
-					print "<td><!-- VAT --></td>";
+					print "<!-- VAT -->";
 					print "<td>" . $date . "</td>";
 					print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
 					// Account
@@ -958,8 +956,8 @@ if (empty($action) || $action == 'view') {
 					print "<td>";
 					print $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("VAT"). ' '.join(', ', $def_tva[$key][$k]).' %'.($numtax?' - Localtax '.$numtax:'');
 					print "</td>";
-					print '<td class="right">' . ($mt >= 0 ? price($mt) : '') . "</td>";
-					print '<td class="right">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
+					print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
+					print '<td class="right nowraponall">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
 					print "</tr>";
 				}
 			}
@@ -971,7 +969,7 @@ if (empty($action) || $action == 'view') {
 			foreach ($tabother[$key] as $k => $mt) {
 				if ($mt) {
 					print '<tr class="oddeven">';
-					print "<td><!-- VAT counterpart NPR --></td>";
+					print "<!-- VAT counterpart NPR -->";
 					print "<td>" . $date . "</td>";
 					print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
 					// Account
@@ -987,8 +985,8 @@ if (empty($action) || $action == 'view') {
 					print "<td>";
 					print '</td>';
 					print "<td>" . $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("VAT") . " NPR (counterpart)</td>";
-					print '<td class="right">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
-					print '<td class="right">' . ($mt >= 0 ? price($mt) : '') . "</td>";
+					print '<td class="right nowraponall">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
+					print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
 					print "</tr>";
 				}
 			}

+ 23 - 25
htdocs/accountancy/journal/sellsjournal.php

@@ -26,7 +26,7 @@
 
 /**
  * \file		htdocs/accountancy/journal/sellsjournal.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Page with sells journal
  */
 
@@ -95,8 +95,6 @@ if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end)
 	$date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
 }
 
-$idpays = $mysoc->country_id;
-
 $sql = "SELECT f.rowid, f.ref, f.type, f.datef as df, f.ref_client, f.date_lim_reglement as dlr, f.close_code,";
 $sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.total_tva, fd.total_localtax1, fd.total_localtax2, fd.tva_tx, fd.total_ttc, fd.situation_percent, fd.vat_src_code,";
 $sql .= " s.rowid as socid, s.nom as name, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
@@ -146,7 +144,7 @@ if ($result) {
 	$num = $db->num_rows($result);
 
 	// Variables
-	$cptcli = (! empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER)) ? $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER : 'NotDefined';
+	$cptcli = (($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER != "")) ? $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER : 'NotDefined';
 	$cpttva = (! empty($conf->global->ACCOUNTING_VAT_SOLD_ACCOUNT)) ? $conf->global->ACCOUNTING_VAT_SOLD_ACCOUNT : 'NotDefined';
 
 	$i = 0;
@@ -679,13 +677,14 @@ if (empty($action) || $action == 'view') {
 	journalHead($nom, $nomlink, $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink);
 
 	// Button to write into Ledger
-	if (empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1') {
+	if (($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "") || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1') {
+		print '<br>';
 		print img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
-		print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
+		print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
 	}
 	print '<div class="tabsAction tabsActionNoBottom">';
 	if (! empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL)) print '<input type="button" class="butAction" name="exportcsv" value="' . $langs->trans("ExportDraftJournal") . '" onclick="launch_export();" />';
-	if (empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1') {
+	if (($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "") || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1') {
 		print '<input type="button" class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")).'" value="' . $langs->trans("WriteBookKeeping") . '" />';
 	}
 	else {
@@ -719,14 +718,13 @@ if (empty($action) || $action == 'view') {
 	print '<div class="div-table-responsive">';
 	print "<table class=\"noborder\" width=\"100%\">";
 	print "<tr class=\"liste_titre\">";
-	print "<td></td>";
 	print "<td>" . $langs->trans("Date") . "</td>";
 	print "<td>" . $langs->trans("Piece") . ' (' . $langs->trans("InvoiceRef") . ")</td>";
 	print "<td>" . $langs->trans("AccountAccounting") . "</td>";
 	print "<td>" . $langs->trans("SubledgerAccount") . "</td>";
 	print "<td>" . $langs->trans("LabelOperation") . "</td>";
-	print "<td class='right'>" . $langs->trans("Debit") . "</td>";
-	print "<td class='right'>" . $langs->trans("Credit") . "</td>";
+	print '<td class="center">' . $langs->trans("Debit") . "</td>";
+	print '<td class="center">' . $langs->trans("Credit") . "</td>";
 	print "</tr>\n";
 
 	$r = '';
@@ -764,7 +762,7 @@ if (empty($action) || $action == 'view') {
 		if ($replacedinvoice == 1)
 		{
 			print '<tr class="oddeven">';
-			print "<td><!-- Replaced invoice --></td>";
+			print "<!-- Replaced invoice -->";
 			print "<td>" . $date . "</td>";
 			print "<td><strike>" . $invoicestatic->getNomUrl(1) . "</strike></td>";
 			// Account
@@ -785,7 +783,7 @@ if (empty($action) || $action == 'view') {
 		if ($errorforinvoice[$key] == 'somelinesarenotbound')
 		{
 			print '<tr class="oddeven">';
-			print "<td><!-- Some lines are not bound --></td>";
+			print "<!-- Some lines are not bound -->";
 			print "<td>" . $date . "</td>";
 			print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
 			// Account
@@ -807,13 +805,13 @@ if (empty($action) || $action == 'view') {
 		{
 			//if ($mt) {
 				print '<tr class="oddeven">';
-				print "<td><!-- Thirdparty --></td>";
+				print "<!-- Thirdparty -->";
 				print "<td>" . $date . "</td>";
 				print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
 				// Account
 				print "<td>";
 				$accountoshow = length_accounta($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER);
-				if (empty($accountoshow) || $accountoshow == 'NotDefined')
+				if (($accountoshow == "") || $accountoshow == 'NotDefined')
 				{
 					print '<span class="error">'.$langs->trans("MainAccountForCustomersNotDefined").'</span>';
 				}
@@ -822,15 +820,15 @@ if (empty($action) || $action == 'view') {
 				// Subledger account
 				print "<td>";
 				$accountoshow = length_accounta($k);
-				if (empty($accountoshow) || $accountoshow == 'NotDefined')
+				if (($accountoshow == "") || $accountoshow == 'NotDefined')
 				{
 					print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefined").'</span>';
 				}
 				else print $accountoshow;
 				print '</td>';
 				print "<td>" . $companystatic->getNomUrl(0, 'customer', 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("SubledgerAccount") . "</td>";
-				print '<td class="right">' . ($mt >= 0 ? price($mt) : '') . "</td>";
-				print '<td class="right">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
 				print "</tr>";
 			//}
 		}
@@ -843,13 +841,13 @@ if (empty($action) || $action == 'view') {
 
 			//if ($mt) {
 				print '<tr class="oddeven">';
-				print "<td><!-- Product --></td>";
+				print "<!-- Product -->";
 				print "<td>" . $date . "</td>";
 				print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
 				// Account
 				print "<td>";
 				$accountoshow = length_accountg($k);
-				if (empty($accountoshow) || $accountoshow == 'NotDefined')
+				if (($accountoshow == "") || $accountoshow == 'NotDefined')
 				{
 					print '<span class="error">'.$langs->trans("ProductNotDefined").'</span>';
 				}
@@ -861,8 +859,8 @@ if (empty($action) || $action == 'view') {
 				$companystatic->id = $tabcompany[$key]['id'];
 				$companystatic->name = $tabcompany[$key]['name'];
 				print "<td>" . $companystatic->getNomUrl(0, 'customer', 16) . ' - ' . $invoicestatic->ref . ' - ' . $accountingaccount->label . "</td>";
-				print "<td class='right'>" . ($mt < 0 ? price(- $mt) : '') . "</td>";
-				print "<td class='right'>" . ($mt >= 0 ? price($mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
+				print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
 				print "</tr>";
 			//}
 		}
@@ -878,13 +876,13 @@ if (empty($action) || $action == 'view') {
 			foreach ($arrayofvat[$key] as $k => $mt) {
 				if ($mt) {
 					print '<tr class="oddeven">';
-					print "<td><!-- VAT --></td>";
+					print "<!-- VAT -->";
 					print "<td>" . $date . "</td>";
 					print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
 					// Account
 					print "<td>";
 					$accountoshow = length_accountg($k);
-					if (empty($accountoshow) || $accountoshow == 'NotDefined')
+					if (($accountoshow == "") || $accountoshow == 'NotDefined')
 					{
 						print '<span class="error">'.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("Sale").')'.'</span>';
 					}
@@ -895,8 +893,8 @@ if (empty($action) || $action == 'view') {
 					print '</td>';
 					print "<td>" . $companystatic->getNomUrl(0, 'customer', 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("VAT"). ' '.join(', ', $def_tva[$key][$k]).' %'.($numtax?' - Localtax '.$numtax:'');
 					print "</td>";
-					print '<td class="right">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
-					print '<td class="right">' . ($mt >= 0 ? price($mt) : '') . "</td>";
+					print '<td class="right nowraponall">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
+					print '<td class="right nowraponall">' . ($mt >= 0 ? price($mt) : '') . "</td>";
 					print "</tr>";
 				}
 			}

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

@@ -23,7 +23,7 @@
  */
 /**
  * \file 	htdocs/accountancy/supplier/card.php
- * \ingroup Advanced accountancy
+ * \ingroup Accountancy (Double entries)
  * \brief 	Card supplier ventilation
  */
 require '../../main.inc.php';

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

@@ -20,7 +20,7 @@
 
 /**
  * \file		htdocs/accountancy/supplier/index.php
- * \ingroup		Advanced accountancy
+ * \ingroup		Accountancy (Double entries)
  * \brief		Home supplier journalization page
  */
 
@@ -140,9 +140,9 @@ $textnextyear = '&nbsp;<a href="' . $_SERVER["PHP_SELF"] . '?year=' . ($year_cur
 
 print load_fiche_titre($langs->trans("SuppliersVentilation") . " " . $textprevyear . "&nbsp;" . $langs->trans("Year") . "&nbsp;" . $year_start . "&nbsp;" . $textnextyear, '', 'title_accountancy');
 
-print $langs->trans("DescVentilSupplier") . '<br>';
+print '<span class="opacitymedium">'.$langs->trans("DescVentilSupplier") . '<br>';
 print $langs->trans("DescVentilMore", $langs->transnoentitiesnoconv("ValidateHistory"), $langs->transnoentitiesnoconv("ToBind")) . '<br>';
-print '<br>';
+print '</span><br>';
 
 $y = $year_current;
 
@@ -203,10 +203,10 @@ if ($resql) {
 		else print $row[1];
 		print '</td>';
 		for($i = 2; $i <= 12; $i ++) {
-			print '<td class="right">' . price($row[$i]) . '</td>';
+			print '<td class="nowrap right">' . price($row[$i]) . '</td>';
 		}
-		print '<td class="right">' . price($row[13]) . '</td>';
-		print '<td class="right"><b>' . price($row[14]) . '</b></td>';
+		print '<td class="nowrap right">' . price($row[13]) . '</td>';
+		print '<td class="nowrap right"><b>' . price($row[14]) . '</b></td>';
 		print '</tr>';
 	}
 	$db->free($resql);
@@ -274,10 +274,10 @@ if ($resql) {
 		else print $row[1];
 		print '</td>';
     	for($i = 2; $i <= 12; $i++) {
-            print '<td class="right">' . price($row[$i]) . '</td>';
+            print '<td class="nowrap right">' . price($row[$i]) . '</td>';
         }
-        print '<td class="right">' . price($row[13]) . '</td>';
-        print '<td class="right"><b>' . price($row[14]) . '</b></td>';
+        print '<td class="nowrap right">' . price($row[13]) . '</td>';
+        print '<td class="nowrap right"><b>' . price($row[14]) . '</b></td>';
         print '</tr>';
     }
     $db->free($resql);
@@ -329,9 +329,9 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
     	while ($row = $db->fetch_row($resql)) {
     		print '<tr><td>' . $row[0] . '</td>';
             for($i = 1; $i <= 12; $i ++) {
-    			print '<td class="right">' . price($row[$i]) . '</td>';
+    			print '<td class="nowrap right">' . price($row[$i]) . '</td>';
     		}
-    		print '<td class="right"><b>' . price($row[13]) . '</b></td>';
+    		print '<td class="nowrap right"><b>' . price($row[13]) . '</b></td>';
     		print '</tr>';
     	}
         $db->free($resql);

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

@@ -21,7 +21,7 @@
 
 /**
  * \file 		htdocs/accountancy/supplier/lines.php
- * \ingroup 	Advanced accountancy
+ * \ingroup 	Accountancy (Double entries)
  * \brief 		Page of detail of the lines of ventilation of invoices suppliers
  */
 require '../../main.inc.php';
@@ -297,7 +297,7 @@ if ($result) {
 
 	print_barre_liste($langs->trans("InvoiceLinesDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
 
-	print $langs->trans("DescVentilDoneSupplier") . '<br>';
+	print '<span class="opacitymedium">'.$langs->trans("DescVentilDoneSupplier") . '</span><br>';
 
 	print '<br><div class="inline-block divButAction">' . $langs->trans("ChangeAccount") . '<br>';
 	print $formaccounting->select_account($account_parent, 'account_parent', 2, array(), 0, 0, 'maxwidth300 maxwidthonsmartphone valignmiddle');
@@ -314,8 +314,8 @@ if ($result) {
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="' . dol_escape_htmltag($search_invoice) . '"></td>';
 	print '<td class="liste_titre"></td>';
 	print '<td class="liste_titre center nowraponall">';
-   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_day" value="'.$search_day.'">';
-   	print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_month" value="'.$search_month.'">';
+   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_day" value="'.$search_day.'">';
+   	print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_month" value="'.$search_month.'">';
    	$formother->select_year($search_year, 'search_year', 1, 20, 5);
 	print '</td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="' . dol_escape_htmltag($search_ref) . '"></td>';
@@ -396,7 +396,7 @@ if ($result) {
 		print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description);
 		print '</td>';
 
-		print '<td class="right">' . price($objp->total_ht) . '</td>';
+		print '<td class="nowrap right">' . price($objp->total_ht) . '</td>';
 
 		print '<td class="right">' . vatrate($objp->tva_tx.($objp->vat_src_code?' ('.$objp->vat_src_code.')':'')) . '</td>';
 

+ 40 - 24
htdocs/accountancy/supplier/list.php

@@ -22,7 +22,7 @@
 
 /**
  * \file 		htdocs/accountancy/supplier/list.php
- * \ingroup 	Advanced accountancy
+ * \ingroup 	Accountancy (Double entries)
  * \brief 		Ventilation page from suppliers invoices
  */
 require '../../main.inc.php';
@@ -214,7 +214,7 @@ $sql = "SELECT f.rowid as facid, f.ref, f.ref_supplier, f.libelle as invoice_lab
 $sql.= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,";
 $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.accountancy_code_buy as code_buy, p.tva_tx as tva_tx_prod,";
 $sql.= " aa.rowid as aarowid,";
-$sql.= " co.code as country_code, co.label as country,";
+$sql.= " co.code as country_code, co.label as country_label,";
 $sql.= " s.tva_intra";
 $parameters=array();
 $reshook=$hookmanager->executeHooks('printFieldListSelect', $parameters);    // Note that $action and $object may have been modified by hook
@@ -332,8 +332,8 @@ if ($result) {
 	if ($search_desc)        $param.='&search_desc='.urlencode($search_desc);
 	if ($search_amount)      $param.='&search_amount='.urlencode($search_amount);
 	if ($search_vat)         $param.='&search_vat='.urlencode($search_vat);
-	if ($search_country) 	$param .= "&search_country=" . urlencode($search_country);
-	if ($search_tvaintra)	$param .= "&search_tvaintra=" . urlencode($search_tvaintra);
+	if ($search_country) 	 $param.="&search_country=".urlencode($search_country);
+	if ($search_tvaintra)	 $param.="&search_tvaintra=".urlencode($search_tvaintra);
 
 	$arrayofmassactions =  array(
 	    'ventil'=>$langs->trans("Ventilate")
@@ -355,7 +355,7 @@ if ($result) {
 
 	print_barre_liste($langs->trans("InvoiceLines"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
 
-	print $langs->trans("DescVentilTodoCustomer") . '</br><br>';
+	print '<span class="opacitymedium">'.$langs->trans("DescVentilTodoCustomer") . '</span></br><br>';
 
 	/*$topicmail="Information";
 	 $modelmail="project";
@@ -376,17 +376,17 @@ if ($result) {
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="' . dol_escape_htmltag($search_invoice) . '"></td>';
 	print '<td class="liste_titre"></td>';
 	print '<td class="liste_titre center nowraponall">';
-   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_day" value="'.$search_day.'">';
-   	print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_month" value="'.$search_month.'">';
+   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_day" value="'.$search_day.'">';
+   	print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_month" value="'.$search_month.'">';
    	$formother->select_year($search_year, 'search_year', 1, 20, 5);
 	print '</td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="' . dol_escape_htmltag($search_ref) . '"></td>';
 	//print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="' . dol_escape_htmltag($search_label) . '"></td>';
-	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
+	print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
 	print '<td class="liste_titre right"><input type="text" class="right flat maxwidth50" name="search_amount" value="' . dol_escape_htmltag($search_amount) . '"></td>';
 	print '<td class="liste_titre right"><input type="text" class="right flat maxwidth50" name="search_vat" placeholder="%" size="1" value="' . dol_escape_htmltag($search_vat) . '"></td>';
 	print '<td class="liste_titre">';
-	print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth200', 'code2', 1, 0, 1);
+	print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth150', 'code2', 1, 0, 1);
 	//print '<input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '">';
 	print '</td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_tvaintra" value="' . dol_escape_htmltag($search_tvaintra) . '"></td>';
@@ -406,7 +406,7 @@ if ($result) {
 	print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder);
 	//print_liste_field_titre("ProductLabel", $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder);
 	print_liste_field_titre("Description", $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder);
-	print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "l.total_ht", "", $param, '', $sortfield, $sortorder, 'right ');
+	print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "l.total_ht", "", $param, '', $sortfield, $sortorder, 'right maxwidth50 ');
 	print_liste_field_titre("VATRate", $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, '', $sortfield, $sortorder, 'right ');
 	print_liste_field_titre("Country", $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder);
 	print_liste_field_titre("VATIntra", $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder);
@@ -418,7 +418,7 @@ if ($result) {
 	print "</tr>\n";
 
 	$facturefourn_static = new FactureFournisseur($db);
-	$productfourn_static = new ProductFournisseur($db);
+	$product_static = new Product($db);
 
 	while ($i < min($num_lines, $limit)) {
 		$objp = $db->fetch_object($result);
@@ -430,10 +430,10 @@ if ($result) {
 		$objp->code_buy_p = '';
 		$objp->aarowid_suggest = '';
 
-		$productfourn_static->ref = $objp->product_ref;
-		$productfourn_static->id = $objp->product_id;
-		$productfourn_static->type = $objp->type;
-		$productfourn_static->label = $objp->product_label;
+		$product_static->ref = $objp->product_ref;
+		$product_static->id = $objp->product_id;
+		$product_static->type = $objp->type;
+		$product_static->label = $objp->product_label;
 
 		$facturefourn_static->ref = $objp->ref;
 		$facturefourn_static->id = $objp->facid;
@@ -479,8 +479,8 @@ if ($result) {
 
 		// Ref product
 		print '<td>';
-		if ($productfourn_static->id)
-			print $productfourn_static->getNomUrl(1);
+		if ($product_static->id > 0)
+			print $product_static->getNomUrl(1);
 		if ($objp->product_label) print '<br>'.$objp->product_label;
 		print '</td>';
 
@@ -491,7 +491,7 @@ if ($result) {
 		print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description);
 		print '</td>';
 
-		print '<td class="right">';
+		print '<td class="nowrap right">';
 		print price($objp->total_ht);
 		print '</td>';
 
@@ -502,22 +502,38 @@ if ($result) {
 		print vatrate($objp->tva_tx_line.($objp->vat_src_code?' ('.$objp->vat_src_code.')':''));
 		print '</td>';
 
-		print '<td>' . $objp->country .'</td>';
+		// Country
+        print '<td>';
+        $labelcountry=($objp->country_code && ($langs->trans("Country".$objp->country_code)!="Country".$objp->country_code))?$langs->trans("Country".$objp->country_code):$objp->country_label;
+        print $labelcountry;
+        print '</td>';
+
+        // VAT Num
 		print '<td>' . $objp->tva_intra . '</td>';
 
 		// Current account
 		print '<td class="center" style="' . $code_buy_p_notset . '">';
-		print (($objp->type_l == 1)?$langs->trans("DefaultForService"):$langs->trans("DefaultForProduct")) . ' = ' . ($objp->code_buy_l > 0 ? length_accountg($objp->code_buy_l) : $langs->trans("Unknown"));
+		$s = (($objp->type_l == 1)?$langs->trans("DefaultForService"):$langs->trans("DefaultForProduct")).': ';
+		$shelp = '';
+		if ($suggestedaccountingaccountbydefaultfor == 'eec') $shelp.= $langs->trans("SaleEEC");
+		elseif ($suggestedaccountingaccountbydefaultfor == 'export') $shelp.= $langs->trans("SaleExport");
+		$s.= ($objp->code_buy_l > 0 ? length_accountg($objp->code_buy_l) : $langs->trans("NotDefined"));
+		print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
 		if ($objp->product_id > 0)
 		{
-		    print '<br>';
-		    print (($objp->type_l == 1)?$langs->trans("ThisService"):$langs->trans("ThisProduct")) . ' = ' . (empty($objp->code_buy_p) ? $langs->trans("Unknown") : length_accountg($objp->code_buy_p));
+			print '<br>';
+			$s = (($objp->type_l == 1)?$langs->trans("ThisService"):$langs->trans("ThisProduct")).': ';
+			$shelp = '';
+			if ($suggestedaccountingaccountfor == 'eec') $shelp = $langs->trans("SaleEEC");
+			elseif ($suggestedaccountingaccountfor == 'export') $shelp = $langs->trans("SaleExport");
+			$s.= (empty($objp->code_buy_p) ? $langs->trans("NotDefined") : length_accountg($objp->code_buy_p));
+			print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
 		}
 		print '</td>';
 
 		// Suggested accounting account
-		print '<td class="center">';
-		print $formaccounting->select_account($objp->aarowid_suggest, 'codeventil'.$objp->rowid, 1, array(), 0, 0, 'codeventil maxwidth300 maxwidthonsmartphone', 'cachewithshowemptyone');
+		print '<td>';
+		print $formaccounting->select_account($objp->aarowid_suggest, 'codeventil'.$objp->rowid, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone');
 		print '</td>';
 
 		// Column with checkbox

+ 2 - 4
htdocs/adherents/agenda.php

@@ -137,7 +137,7 @@ if ($object->id > 0)
 	print '<div class="underbanner clearboth"></div>';
 
 	$object->info($id);
-	print dol_print_object_info($object, 1);
+	dol_print_object_info($object, 1);
 
 	print '</div>';
 
@@ -151,9 +151,7 @@ if ($object->id > 0)
 	$newcardbutton = '';
     if (! empty($conf->agenda->enabled))
     {
-    	$newcardbutton.='<a class="butActionNew" href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&backtopage=1&origin=member&originid='.$id.'"><span class="valignmiddle text-plus-circle">'.$langs->trans("AddAction").'</span>';
-    	$newcardbutton.= '<span class="fa fa-plus-circle valignmiddle"></span>';
-    	$newcardbutton.= '</a>';
+        $newcardbutton.= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create&backtopage=1&origin=member&originid='.$id);
     }
 
     if (! empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read) ))

+ 36 - 24
htdocs/adherents/card.php

@@ -82,7 +82,7 @@ if (! empty($canvas))
 }
 
 // Security check
-$result=restrictedArea($user, 'adherent', $id, '', '', 'fk_soc', 'rowid', $objcanvas);
+$result=restrictedArea($user, 'adherent', $id, '', '', 'socid', 'rowid', $objcanvas);
 
 if ($id > 0)
 {
@@ -163,10 +163,10 @@ if (empty($reshook))
 		$error=0;
 		if (! $error)
 		{
-			if ($socid != $object->fk_soc)	// If link differs from currently in database
+			if ($socid != $object->socid)	// If link differs from currently in database
 			{
 				$sql ="SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
-				$sql.=" WHERE fk_soc = '".$socid."'";
+				$sql.=" WHERE socid = '".$socid."'";
 				$sql.=" AND entity = ".$conf->entity;
 				$resql = $db->query($sql);
 				if ($resql)
@@ -273,7 +273,7 @@ if (empty($reshook))
 		{
 			if (empty($login)) {
 				$error++;
-				setEventMessages($langs->trans("ErrorFieldRequired", $langs->trans("Login")), null, 'errors');
+				setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Login")), null, 'errors');
 			}
 		}
 		// Create new object
@@ -492,7 +492,7 @@ if (empty($reshook))
 		//$object->note        = $comment;
 		$object->morphy      = $morphy;
 		$object->user_id     = $userid;
-		$object->fk_soc      = $socid;
+		$object->socid      = $socid;
 		$object->public      = $public;
 
 		// Fill array 'array_options' with data from add form
@@ -502,14 +502,14 @@ if (empty($reshook))
 		// Check parameters
 		if (empty($morphy) || $morphy == "-1") {
 			$error++;
-			setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Nature")), null, 'errors');
+			setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("MemberNature")), null, 'errors');
 		}
 		// Tests if the login already exists
 		if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
 		{
 			if (empty($login)) {
 				$error++;
-				setEventMessages($langs->trans("ErrorFieldRequired", $langs->trans("Login")), null, 'errors');
+				setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Login")), null, 'errors');
 			}
 			else {
 				$sql = "SELECT login FROM ".MAIN_DB_PREFIX."adherent WHERE login='".$db->escape($login)."'";
@@ -941,7 +941,7 @@ else
 		// Morphy
 		$morphys["phy"] = $langs->trans("Physical");
 		$morphys["mor"] = $langs->trans("Moral");
-		print '<tr><td class="fieldrequired">'.$langs->trans("Nature")."</td><td>\n";
+		print '<tr><td class="fieldrequired">'.$langs->trans("MemberNature")."</td><td>\n";
 		print $form->selectarray("morphy", $morphys, GETPOST('morphy', 'alpha')?GETPOST('morphy', 'alpha'):$object->morphy, 1);
 		print "</td>\n";
 
@@ -1059,11 +1059,17 @@ else
 
 		// Other attributes
 		include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
-
-        print '<tbody>';
+		//Hooks here
+		$reshook=$hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action);    // Note that $action and $object may have been modified by hook
+		print $hookmanager->resPrint;
+		if (empty($reshook))
+		{
+      	    print $object->showOptionals($extrafields, 'edit');
+		}
+			
+		print '<tbody>';
 		print "</table>\n";
-
-        dol_fiche_end();
+		dol_fiche_end();
 
 		print '<div class="center">';
 		print '<input type="submit" name="button" class="button" value="'.$langs->trans("AddMember").'">';
@@ -1182,7 +1188,7 @@ else
 		// Morphy
 		$morphys["phy"] = $langs->trans("Physical");
 		$morphys["mor"] = $langs->trans("Morale");
-		print '<tr><td><span class="fieldrequired">'.$langs->trans("Nature").'</span></td><td>';
+		print '<tr><td><span class="fieldrequired">'.$langs->trans("MemberNature").'</span></td><td>';
 		print $form->selectarray("morphy", $morphys, (GETPOSTISSET("morphy")?GETPOST("morphy", 'alpha'):$object->morphy));
 		print "</td></tr>";
 
@@ -1333,10 +1339,10 @@ else
 		if (! empty($conf->societe->enabled))
 		{
 			print '<tr><td>'.$langs->trans("LinkedToDolibarrThirdParty").'</td><td colspan="2" class="valeur">';
-			if ($object->fk_soc)
+			if ($object->socid)
 			{
 				$company=new Societe($db);
-				$result=$company->fetch($object->fk_soc);
+				$result=$company->fetch($object->socid);
 				print $company->getNomUrl(1);
 			}
 			else
@@ -1357,9 +1363,15 @@ else
 
 		// Other attributes
 		include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
-
+		//Hooks here
+		$reshook=$hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action);    // Note that $action and $object may have been modified by hook
+		print $hookmanager->resPrint;
+		if (empty($reshook))
+		{
+      	    print $object->showOptionals($extrafields, 'edit');
+		}
+      
 		print '</table>';
-
 		dol_fiche_end();
 
 		print '<div class="center">';
@@ -1421,7 +1433,7 @@ else
 			$text=$langs->trans("ConfirmCreateLogin").'<br>';
 			if (! empty($conf->societe->enabled))
 			{
-				if ($object->fk_soc > 0) $text.=$langs->trans("UserWillBeExternalUser");
+				if ($object->socid > 0) $text.=$langs->trans("UserWillBeExternalUser");
 				else $text.=$langs->trans("UserWillBeInternalUser");
 			}
 			print $form->formconfirm($_SERVER["PHP_SELF"]."?rowid=".$object->id, $langs->trans("CreateDolibarrLogin"), $text, "confirm_create_user", $formquestion, 'yes');
@@ -1567,7 +1579,7 @@ else
 			$formquestion=array();
 			if ($object->email) $formquestion[]=array('type' => 'checkbox', 'name' => 'send_mail', 'label' => $label, 'value' => (! empty($conf->global->ADHERENT_DEFAULT_SENDINFOBYMAIL)?'true':'false'));
 			if ($backtopage)    $formquestion[]=array('type' => 'hidden', 'name' => 'backtopage', 'value' => ($backtopage != '1' ? $backtopage : $_SERVER["HTTP_REFERER"]));
-			print $form->formconfirm("card.php?rowid=".$id, $langs->trans("ResiliateMember"), $langs->trans("ConfirmResiliateMember"), "confirm_resign", $formquestion, 'no', 1, 220);
+			print $form->formconfirm("card.php?rowid=".$id, $langs->trans("ResiliateMember"), $langs->trans("ConfirmResiliateMember"), "confirm_resign", $formquestion, 'no', 1, 240);
 		}
 
 		// Confirm remove member
@@ -1613,7 +1625,7 @@ else
 		print '<tr><td class="titlefield">'.$langs->trans("Type").'</td><td class="valeur">'.$adht->getNomUrl(1)."</td></tr>\n";
 
 		// Morphy
-		print '<tr><td>'.$langs->trans("Nature").'</td><td class="valeur" >'.$object->getmorphylib().'</td>';
+		print '<tr><td>'.$langs->trans("MemberNature").'</td><td class="valeur" >'.$object->getmorphylib().'</td>';
 		print '</tr>';
 
 		// Gender
@@ -1688,17 +1700,17 @@ else
 				print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
 				print '<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
 				print '<tr><td>';
-				print $form->select_company($object->fk_soc, 'socid', '', 1);
+				print $form->select_company($object->socid, 'socid', '', 1);
 				print '</td>';
 				print '<td class="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>';
 				print '</tr></table></form>';
 			}
 			else
 			{
-				if ($object->fk_soc)
+				if ($object->socid)
 				{
 					$company=new Societe($db);
-					$result=$company->fetch($object->fk_soc);
+					$result=$company->fetch($object->socid);
 					print $company->getNomUrl(1);
 				}
 				else
@@ -1848,7 +1860,7 @@ else
 				}
 
 				// Create third party
-				if (! empty($conf->societe->enabled) && ! $object->fk_soc)
+				if (! empty($conf->societe->enabled) && ! $object->socid)
 				{
 					if ($user->rights->societe->creer)
 					{

+ 18 - 10
htdocs/adherents/class/adherent.class.php

@@ -10,6 +10,8 @@
  * Copyright (C) 2015-2018  Frédéric France			<frederic.france@netlogic.fr>
  * Copyright (C) 2015		Raphaël Doursenaud		<rdoursenaud@gpcsolutions.fr>
  * Copyright (C) 2016		Juanjo Menent			<jmenent@2byte.es>
+ * Copyright (C) 2018-2019  Thibault FOUCART		<support@ptibogxiv.net>
+ * Copyright (C) 2019       Nicolas ZABOURI 		<info@inovea-conseil.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -182,14 +184,14 @@ class Adherent extends CommonObject
      * @var integer
      */
     public $datec;
-    
+
 	/**
      * Date modification record (tms)
      *
      * @var integer
      */
     public $datem;
-    
+
 	public $datevalid;
 
 	public $gender;
@@ -557,7 +559,7 @@ class Adherent extends CommonObject
 		$sql.= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null");	// 'man' or 'woman'
 		$sql.= ", login = ".($this->login?"'".$this->db->escape($this->login)."'":"null");
 		$sql.= ", societe = ".($this->societe?"'".$this->db->escape($this->societe)."'":"null");
-		$sql.= ", fk_soc = ".($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null");
+		$sql.= ", fk_soc = ".($this->socid > 0?$this->db->escape($this->socid):"null");
 		$sql.= ", address = ".($this->address?"'".$this->db->escape($this->address)."'":"null");
 		$sql.= ", zip = ".($this->zip?"'".$this->db->escape($this->zip)."'":"null");
 		$sql.= ", town = ".($this->town?"'".$this->db->escape($this->town)."'":"null");
@@ -595,7 +597,7 @@ class Adherent extends CommonObject
 			{
 			    while ($obj=$this->db->fetch_object($resql2))
 			    {
-				$this->type=$obj->label;
+					$this->type=$obj->label;
 			    }
 			}
 		}
@@ -1223,7 +1225,7 @@ class Adherent extends CommonObject
 	{
 		global $langs;
 
-		$sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_id, d.gender, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
+		$sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_code, d.gender, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
 		$sql.= " d.note_public,";
 		$sql.= " d.email, d.skype, d.twitter, d.facebook, d.linkedin, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
 		$sql.= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
@@ -1267,14 +1269,19 @@ class Adherent extends CommonObject
 				$this->ref				= $obj->rowid;
 				$this->id				= $obj->rowid;
 				$this->ref_ext			= $obj->ref_ext;
-				$this->civility_id		= $obj->civility_id;
+
+				$this->civility_id      = $obj->civility_code;  // Bad. Kept for backard compatibility
+				$this->civility_code    = $obj->civility_code;
+				$this->civility	        = $obj->civility_code?($langs->trans("Civility".$obj->civility_code) != ("Civility".$obj->civility_code) ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code):'';
+
 				$this->firstname		= $obj->firstname;
 				$this->lastname			= $obj->lastname;
 				$this->gender			= $obj->gender;
 				$this->login			= $obj->login;
 				$this->societe			= $obj->company;
 				$this->company			= $obj->company;
-				$this->fk_soc			= $obj->fk_soc;
+				$this->socid			= $obj->fk_soc;
+				$this->fk_soc			= $obj->fk_soc;     // For backward comaptibility
 				$this->address			= $obj->address;
 				$this->zip				= $obj->zip;
 				$this->town				= $obj->town;
@@ -2397,7 +2404,7 @@ class Adherent extends CommonObject
 		$this->country_id = 1;
 		$this->country_code = 'FR';
 		$this->country = 'France';
-		$this->morphy = 1;
+		$this->morphy = 'mor';
 		$this->email = 'specimen@specimen.com';
 		$this->skype = 'skypepseudo';
 		$this->twitter = 'twitterpseudo';
@@ -2454,12 +2461,13 @@ class Adherent extends CommonObject
 
 
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-	/**
+    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
+   /**
 	 *	Initialise tableau info (tableau des attributs LDAP)
 	 *
 	 *	@return		array		Tableau info des attributs
 	 */
-	private function _load_ldap_info()
+	public function _load_ldap_info()
 	{
         // phpcs:enable
 		global $conf,$langs;

+ 29 - 4
htdocs/adherents/class/adherent_type.class.php

@@ -1,8 +1,9 @@
 <?php
-/* Copyright (C) 2002		Rodolphe Quiedeville		<rodolphe@quiedeville.org>
+/* Copyright (C) 2002		Rodolphe Quiedeville	<rodolphe@quiedeville.org>
  * Copyright (C) 2004-2008	Laurent Destailleur		<eldy@users.sourceforge.net>
  * Copyright (C) 2009-2017	Regis Houssin			<regis.houssin@inodbox.com>
  * Copyright (C) 2016		Charlie Benke			<charlie@patas-monkey.com>
+ * Copyright (C) 2018-2019  Thibault Foucart		<support@ptibogxiv.net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -65,6 +66,11 @@ class AdherentType extends CommonObject
      */
     public $label;
 
+    /**
+     * @var string Adherent type nature
+     */
+    public $morphy;
+
 	/**
 	 * @var int Subsription required (0 or 1)
 	 * @since 5.0
@@ -184,6 +190,7 @@ class AdherentType extends CommonObject
 		$sql.= "SET ";
 		$sql.= "statut = ".$this->statut.",";
 		$sql.= "libelle = '".$this->db->escape($this->label) ."',";
+        $sql.= "morphy = '".$this->db->escape($this->morphy) ."',";
 		$sql.= "subscription = '".$this->db->escape($this->subscription)."',";
 		$sql.= "note = '".$this->db->escape($this->note)."',";
 		$sql.= "vote = ".(integer) $this->db->escape($this->vote).",";
@@ -274,7 +281,7 @@ class AdherentType extends CommonObject
 	 */
 	public function fetch($rowid)
 	{
-		$sql = "SELECT d.rowid, d.libelle as label, d.statut, d.subscription, d.mail_valid, d.note, d.vote";
+		$sql = "SELECT d.rowid, d.libelle as label, d.morphy, d.statut, d.subscription, d.mail_valid, d.note, d.vote";
 		$sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d";
 		$sql .= " WHERE d.rowid = ".(int) $rowid;
 
@@ -290,6 +297,7 @@ class AdherentType extends CommonObject
 				$this->id             = $obj->rowid;
 				$this->ref            = $obj->rowid;
 				$this->label          = $obj->label;
+                $this->morphy         = $obj->morphy;
 				$this->statut         = $obj->statut;
 				$this->subscription   = $obj->subscription;
 				$this->mail_valid     = $obj->mail_valid;
@@ -403,6 +411,21 @@ class AdherentType extends CommonObject
 		}
 	}
 
+	/**
+	 *	Return translated label by the nature of a adherent (physical or moral)
+	 *
+	 *	@param	string		$morphy		Nature of the adherent (physical or moral)
+	 *	@return	string					Label
+	 */
+	public function getmorphylib($morphy = '')
+	{
+		global $langs;
+		if ($morphy == 'phy') { return $langs->trans("Physical"); }
+		elseif ($morphy == 'mor') { return $langs->trans("Moral"); }
+        else return $langs->trans("Physical & Morale");
+		//return $morphy;
+	}
+
     /**
      *  Return clicable name (with picto eventually)
      *
@@ -440,6 +463,7 @@ class AdherentType extends CommonObject
     }
 
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
 	/**
 	 *	Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
 	 *
@@ -449,7 +473,7 @@ class AdherentType extends CommonObject
 	 *									2=Return key only (uid=qqq)
 	 *	@return		string				DN
 	 */
-	private function _load_ldap_dn($info, $mode = 0)
+	public function _load_ldap_dn($info, $mode = 0)
 	{
         // phpcs:enable
 		global $conf;
@@ -462,12 +486,13 @@ class AdherentType extends CommonObject
 
 
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
 	/**
 	 *	Initialize the info array (array of LDAP values) that will be used to call LDAP functions
 	 *
 	 *	@return		array		Tableau info des attributs
 	 */
-	private function _load_ldap_info()
+	public function _load_ldap_info()
 	{
         // phpcs:enable
 		global $conf,$langs;

+ 1 - 1
htdocs/adherents/document.php

@@ -127,7 +127,7 @@ if ($id > 0)
         print '<tr><td>'.$langs->trans("Type").'</td><td class="valeur">'.$membert->getNomUrl(1)."</td></tr>\n";
 
         // Morphy
-        print '<tr><td class="titlefield">'.$langs->trans("Nature").'</td><td class="valeur" >'.$object->getmorphylib().'</td>';
+        print '<tr><td class="titlefield">'.$langs->trans("MemberNature").'</td><td class="valeur" >'.$object->getmorphylib().'</td>';
         /*print '<td rowspan="'.$rowspan.'" class="center" valign="middle" width="25%">';
         print $form->showphoto('memberphoto',$object);
         print '</td>';*/

+ 3 - 3
htdocs/adherents/htpasswd.php

@@ -43,13 +43,13 @@ if (empty($sortorder)) {  $sortorder="ASC"; }
 if (empty($sortfield)) {  $sortfield="d.login"; }
 if (! isset($statut))
 {
-  $statut = 1 ;
+	$statut = 1 ;
 }
 
 if (! isset($cotis))
 {
-  // by default, members must be up to date of subscription
-  $cotis=1;
+	// by default, members must be up to date of subscription
+	$cotis=1;
 }
 
 

+ 12 - 3
htdocs/adherents/index.php

@@ -1,8 +1,9 @@
 <?php
 /* Copyright (C) 2001-2002	Rodolphe Quiedeville	<rodolphe@quiedeville.org>
- * Copyright (C) 2003		Jean-Louis Bergamo		<jlb@j1b.org>
- * Copyright (C) 2004-2017	Laurent Destailleur		<eldy@users.sourceforge.net>
- * Copyright (C) 2005-2012	Regis Houssin			<regis.houssin@inodbox.com>
+ * Copyright (C) 2003		Jean-Louis Bergamo	<jlb@j1b.org>
+ * Copyright (C) 2004-2017	Laurent Destailleur	<eldy@users.sourceforge.net>
+ * Copyright (C) 2005-2012	Regis Houssin		<regis.houssin@inodbox.com>
+ * Copyright (C) 2019           Nicolas ZABOURI         <info@inovea-conseil.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,6 +30,11 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
 require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
 
+$hookmanager = new HookManager($db);
+
+// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
+$hookmanager->initHooks(array('membersindex'));
+
 // Load translation files required by the page
 $langs->loadLangs(array("companies","members"));
 
@@ -435,6 +441,9 @@ print "</div>";
 
 print '</div></div></div>';
 
+$parameters = array('user' => $user);
+$reshook = $hookmanager->executeHooks('dashboardMembers', $parameters, $object); // Note that $action and $object may have been modified by hook
+
 // End of page
 llxFooter();
 $db->close();

+ 57 - 7
htdocs/adherents/list.php

@@ -130,6 +130,7 @@ $arrayfields=array(
 	'd.note_private'=>array('label'=>$langs->trans("NotePrivate"), 'checked'=>0),*/
 	'd.datefin'=>array('label'=>$langs->trans("EndSubscription"), 'checked'=>1, 'position'=>500),
 	'd.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
+	'd.birth'=>array('label'=>$langs->trans("Birthday"), 'checked'=>0, 'position'=>500),
 	'd.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
 	'd.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000)
 );
@@ -189,6 +190,42 @@ if (empty($reshook))
 		$search_array_options=array();
 	}
 
+	// Close
+	if ($massaction == 'close' && $user->rights->adherent->creer)
+	{
+	    $tmpmember = new Adherent($db);
+	    $error=0;
+	    $nbclose=0;
+
+	    $db->begin();
+
+        foreach($toselect as $idtoclose)
+        {
+            $tmpmember->fetch($idtoclose);
+            $result=$tmpmember->resiliate($user);
+
+            if ($result < 0 && ! count($tmpmember->errors))
+    	    {
+    	        setEventMessages($tmpmember->error, $tmpmember->errors, 'errors');
+    	    }
+    	    else
+    	    {
+    	        if ($result > 0) $nbclose++;
+    	    }
+        }
+
+        if (! $error)
+        {
+            setEventMessages($langs->trans("XMembersClosed", $nbclose), null, 'mesgs');
+
+            $db->commit();
+        }
+        else
+        {
+            $db->rollback();
+        }
+	}
+
 	// Mass actions
 	$objectclass='Adherent';
 	$objectlabel='Members';
@@ -326,12 +363,11 @@ if ($search_type > 0)
 }
 
 $param='';
-if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage;
-if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
+if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage);
+if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit);
 if ($sall != "") $param.="&sall=".urlencode($sall);
 if ($statut != "") $param.="&statut=".urlencode($statut);
 if ($search_ref)   $param.="&search_ref=".urlencode($search_ref);
-if ($search_nom)   $param.="&search_nom=".urlencode($search_nom);
 if ($search_civility) $param.="&search_civility=".urlencode($search_civility);
 if ($search_firstname) $param.="&search_firstname=".urlencode($search_firstname);
 if ($search_lastname)  $param.="&search_lastname=".urlencode($search_lastname);
@@ -358,6 +394,7 @@ $arrayofmassactions =  array(
 	//'presend'=>$langs->trans("SendByMail"),
 	//'builddoc'=>$langs->trans("PDFMerge"),
 );
+if ($user->rights->adherent->creer) $arrayofmassactions['close']=$langs->trans("Resiliate");
 if ($user->rights->adherent->supprimer) $arrayofmassactions['predelete']='<span class="fa fa-trash paddingrightonly"></span>'.$langs->trans("Delete");
 if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
 $massactionbutton=$form->selectMassAction('', $arrayofmassactions);
@@ -365,9 +402,7 @@ $massactionbutton=$form->selectMassAction('', $arrayofmassactions);
 $newcardbutton='';
 if ($user->rights->adherent->creer)
 {
-	$newcardbutton='<a class="butActionNew" href="'.DOL_URL_ROOT.'/adherents/card.php?action=create"><span class="valignmiddle text-plus-circle">'.$langs->trans('NewMember').'</span>';
-	$newcardbutton.= '<span class="fa fa-plus-circle valignmiddle"></span>';
-	$newcardbutton.= '</a>';
+    $newcardbutton.= dolGetButtonTitle($langs->trans('NewMember'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/adherents/card.php?action=create');
 }
 
 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
@@ -457,7 +492,7 @@ if (! empty($arrayfields['d.lastname']['checked']))
 if (! empty($arrayfields['d.gender']['checked']))
 {
 	print '<td class="liste_titre">';
-	$arraygender=array('man'=>$langs->trans("Genderman"),'woman'=>$langs->trans("Genderwoman"));
+	$arraygender=array('man'=>$langs->trans("Genderman"), 'woman'=>$langs->trans("Genderwoman"));
 	print $form->selectarray('search_gender', $arraygender, $search_gender, 1);
 	print '</td>';
 }
@@ -557,6 +592,12 @@ if (! empty($arrayfields['d.datec']['checked']))
 	print '<td class="liste_titre">';
 	print '</td>';
 }
+//Birthday
+if (! empty($arrayfields['d.birth']['checked']))
+{
+	print '<td class="liste_titre">';
+	print '</td>';
+}
 // Date modification
 if (! empty($arrayfields['d.tms']['checked']))
 {
@@ -612,6 +653,7 @@ $parameters=array('arrayfields'=>$arrayfields,'param'=>$param,'sortfield'=>$sort
 $reshook=$hookmanager->executeHooks('printFieldListTitle', $parameters);    // Note that $action and $object may have been modified by hook
 print $hookmanager->resPrint;
 if (! empty($arrayfields['d.datec']['checked']))     print_liste_field_titre($arrayfields['d.datec']['label'], $_SERVER["PHP_SELF"], "d.datec", "", $param, 'align="center" class="nowrap"', $sortfield, $sortorder);
+if (! empty($arrayfields['d.birth']['checked']))     print_liste_field_titre($arrayfields['d.birth']['label'], $_SERVER["PHP_SELF"], "d.birth", "", $param, 'align="center" class="nowrap"', $sortfield, $sortorder);
 if (! empty($arrayfields['d.tms']['checked']))       print_liste_field_titre($arrayfields['d.tms']['label'], $_SERVER["PHP_SELF"], "d.tms", "", $param, 'align="center" class="nowrap"', $sortfield, $sortorder);
 if (! empty($arrayfields['d.statut']['checked']))    print_liste_field_titre($arrayfields['d.statut']['label'], $_SERVER["PHP_SELF"], "d.statut", "", $param, 'class="right"', $sortfield, $sortorder);
 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch ');
@@ -831,6 +873,14 @@ while ($i < min($num, $limit))
 		print '</td>';
 		if (! $i) $totalarray['nbfield']++;
 	}
+	// Birth
+	if (! empty($arrayfields['d.birth']['checked']))
+	{
+		print '<td class="nowrap center">';
+		print dol_print_date($db->jdate($obj->birth), 'day', 'tzuser');
+		print '</td>';
+		if (! $i) $totalarray['nbfield']++;
+	}
 	// Date modification
 	if (! empty($arrayfields['d.tms']['checked']))
 	{

+ 1 - 1
htdocs/adherents/note.php

@@ -92,7 +92,7 @@ if ($id)
     print '<tr><td>'.$langs->trans("Type").'</td><td class="valeur">'.$adht->getNomUrl(1)."</td></tr>\n";
 
     // Morphy
-    print '<tr><td class="titlefield">'.$langs->trans("Nature").'</td><td class="valeur" >'.$object->getmorphylib().'</td>';
+    print '<tr><td class="titlefield">'.$langs->trans("MemberNature").'</td><td class="valeur" >'.$object->getmorphylib().'</td>';
     /*print '<td rowspan="'.$rowspan.'" class="center" valign="middle" width="25%">';
     print $form->showphoto('memberphoto',$member);
     print '</td>';*/

+ 1 - 1
htdocs/adherents/stats/geo.php

@@ -235,7 +235,7 @@ else
         print '<br>';
         print '<a href="'.$_SERVER["PHP_SELF"].'?mode=memberbytown">'.$langs->trans("MembersStatisticsByTown").'</a><br>';
         print '<br>';//+
-	print '<a href="'.$_SERVER["PHP_SELF"].'?mode=memberbyregion">'.$langs->trans("MembersStatisticsByRegion").'</a><br>';//+
+		print '<a href="'.$_SERVER["PHP_SELF"].'?mode=memberbyregion">'.$langs->trans("MembersStatisticsByRegion").'</a><br>';//+
     }
     print '<br>';
 }

+ 1 - 6
htdocs/adherents/stats/index.php

@@ -81,7 +81,6 @@ $mesg = $px1->isGraphKo();
 if (! $mesg)
 {
     $px1->SetData($data);
-    $px1->SetPrecisionY(0);
     $i=$startyear;
     while ($i <= $endyear)
     {
@@ -96,7 +95,6 @@ if (! $mesg)
     $px1->SetYLabel($langs->trans("NbOfSubscriptions"));
     $px1->SetShading(3);
     $px1->SetHorizTickIncrement(1);
-    $px1->SetPrecisionY(0);
     $px1->mode='depth';
     $px1->SetTitle($langs->trans("NbOfSubscriptions"));
 
@@ -116,7 +114,6 @@ $mesg = $px2->isGraphKo();
 if (! $mesg)
 {
     $px2->SetData($data);
-    $px2->SetPrecisionY(0);
     $i=$startyear;
     while ($i <= $endyear)
     {
@@ -131,7 +128,6 @@ if (! $mesg)
     $px2->SetYLabel($langs->trans("AmountOfSubscriptions"));
     $px2->SetShading(3);
     $px2->SetHorizTickIncrement(1);
-    $px2->SetPrecisionY(0);
     $px2->mode='depth';
     $px2->SetTitle($langs->trans("AmountOfSubscriptions"));
 
@@ -151,8 +147,7 @@ print '<div class="fichecenter"><div class="fichethirdleft">';
 print '<table class="border" width="100%">';
 print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>';
 print '<tr><td>'.$langs->trans("Member").'</td><td>';
-$filter='s.client in (1,2,3)';
-print $form->select_company($id,'memberid',$filter,1);
+print $form->select_company($id,'memberid','',1);
 print '</td></tr>';
 print '<tr><td>'.$langs->trans("User").'</td><td>';
 print $form->select_dolusers($userid, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300');

+ 16 - 2
htdocs/adherents/subscription.php

@@ -5,6 +5,7 @@
  * Copyright (C) 2012-2017  Regis Houssin           <regis.houssin@inodbox.com>
  * Copyright (C) 2015-2016  Alexandre Spangaro      <aspangaro@open-dsi.fr>
  * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
+ * Copyright (C) 2019       Thibault FOUCART        <support@ptibogxiv.net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -489,7 +490,7 @@ if ($rowid > 0)
 	print '<tr><td class="titlefield">'.$langs->trans("Type").'</td><td class="valeur">'.$adht->getNomUrl(1)."</td></tr>\n";
 
 	// Morphy
-	print '<tr><td>'.$langs->trans("Nature").'</td><td class="valeur" >'.$object->getmorphylib().'</td>';
+	print '<tr><td>'.$langs->trans("MemberNature").'</td><td class="valeur" >'.$object->getmorphylib().'</td>';
 	print '</tr>';
 
 	// Company
@@ -668,7 +669,7 @@ if ($rowid > 0)
     {
         $sql = "SELECT d.rowid, d.firstname, d.lastname, d.societe,";
         $sql.= " c.rowid as crowid, c.subscription,";
-        $sql.= " c.datec,";
+        $sql.= " c.datec, c.fk_type as cfk_type,";
         $sql.= " c.dateadh as dateh,";
         $sql.= " c.datef,";
         $sql.= " c.fk_bank,";
@@ -693,6 +694,7 @@ if ($rowid > 0)
             print '<tr class="liste_titre">';
             print_liste_field_titre('Ref', $_SERVER["PHP_SELF"], 'c.rowid', '', $param, '', $sortfield, $sortorder);
             print '<td class="center">'.$langs->trans("DateCreation").'</td>';
+            print '<td align="center">'.$langs->trans("Type").'</td>';
             print '<td class="center">'.$langs->trans("DateStart").'</td>';
             print '<td class="center">'.$langs->trans("DateEnd").'</td>';
             print '<td class="right">'.$langs->trans("Amount").'</td>';
@@ -703,6 +705,7 @@ if ($rowid > 0)
             print "</tr>\n";
 
             $accountstatic=new Account($db);
+            $adht = new AdherentType($db);
 
             while ($i < $num)
             {
@@ -711,9 +714,20 @@ if ($rowid > 0)
                 $subscriptionstatic->ref=$objp->crowid;
                 $subscriptionstatic->id=$objp->crowid;
 
+                if ($objp->cfk_type > 0)
+                {
+                    $adht->fetch($objp->cfk_type);
+                }
+
                 print '<tr class="oddeven">';
                 print '<td>'.$subscriptionstatic->getNomUrl(1).'</td>';
                 print '<td class="center">'.dol_print_date($db->jdate($objp->datec), 'dayhour')."</td>\n";
+                print '<td class="center">';
+                if ($objp->cfk_type > 0)
+                {
+                    print $adht->getNomUrl(1);
+                }
+                print '</td>';
                 print '<td class="center">'.dol_print_date($db->jdate($objp->dateh), 'day')."</td>\n";
                 print '<td class="center">'.dol_print_date($db->jdate($objp->datef), 'day')."</td>\n";
                 print '<td class="right">'.price($objp->subscription).'</td>';

+ 3 - 5
htdocs/adherents/subscription/list.php

@@ -247,9 +247,7 @@ $massactionbutton=$form->selectMassAction('', $arrayofmassactions);
 $newcardbutton='';
 if ($user->rights->adherent->cotisation->creer)
 {
-	$newcardbutton='<a class="butActionNew" href="'.DOL_URL_ROOT.'/adherents/list.php?status=-1,1"><span class="valignmiddle text-plus-circle">'.$langs->trans('NewSubscription').'</span>';
-	$newcardbutton.= '<span class="fa fa-plus-circle valignmiddle"></span>';
-	$newcardbutton.= '</a>';
+    $newcardbutton.= dolGetButtonTitle($langs->trans('NewSubscription'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/adherents/list.php?status=-1,1');
 }
 
 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
@@ -308,7 +306,7 @@ if (! empty($arrayfields['d.fk_type']['checked']))
 {
 	print '<td class="liste_titre left">';
 	print '<input class="flat" type="text" name="search_type" value="'.dol_escape_htmltag($search_type).'" size="7">';
-  print'</td>';
+	print'</td>';
 }
 
 if (! empty($arrayfields['d.lastname']['checked']))
@@ -419,7 +417,7 @@ if (! empty($arrayfields['d.bank']['checked']))
 }
 if (! empty($arrayfields['c.dateadh']['checked']))
 {
-	print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "c.dateadh", $param, "", 'align="center"', $sortfield, $sortorder);
+	print_liste_field_titre("DateStart", $_SERVER["PHP_SELF"], "c.dateadh", $param, "", 'align="center"', $sortfield, $sortorder);
 }
 if (! empty($arrayfields['c.datef']['checked']))
 {

+ 4 - 4
htdocs/adherents/tpl/linkedobjectblock.tpl.php

@@ -47,10 +47,10 @@ foreach($linkedObjectBlock as $key => $objectlink)
 	<td class="center"></td>
 	<td class="center"><?php echo dol_print_date($objectlink->dateh, 'day'); ?></td>
 	<td class="right"><?php
-		if ($user->rights->adherent->lire) {
-			$total = $total + $objectlink->amount;
-			echo price($objectlink->amount);
-		} ?></td>
+	if ($user->rights->adherent->lire) {
+		$total = $total + $objectlink->amount;
+		echo price($objectlink->amount);
+	} ?></td>
 	<td class="right"></td>
 	<td class="right"><a href="<?php echo $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=dellink&dellinkid='.$key; ?>"><?php echo img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink'); ?></a></td>
 </tr>

+ 35 - 7
htdocs/adherents/type.php

@@ -1,10 +1,11 @@
 <?php
-/* Copyright (C) 2001-2002	Rodolphe Quiedeville		<rodolphe@quiedeville.org>
+/* Copyright (C) 2001-2002	Rodolphe Quiedeville	<rodolphe@quiedeville.org>
  * Copyright (C) 2003		Jean-Louis Bergamo		<jlb@j1b.org>
  * Copyright (C) 2004-2011	Laurent Destailleur		<eldy@users.sourceforge.net>
  * Copyright (C) 2005-2017	Regis Houssin			<regis.houssin@inodbox.com>
  * Copyright (C) 2013		Florian Henry			<florian.henry@open-concept.pro>
  * Copyright (C) 2015		Alexandre Spangaro		<aspangaro@open-dsi.fr>
+ * Copyright (C) 2019		Thibault Foucart		<support@ptibogxiv.net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -57,6 +58,7 @@ if (! $sortorder) {  $sortorder="DESC"; }
 if (! $sortfield) {  $sortfield="d.lastname"; }
 
 $label=GETPOST("label", "alpha");
+$morphy=GETPOST("morphy", "alpha");
 $statut=GETPOST("statut", "int");
 $subscription=GETPOST("subscription", "int");
 $vote=GETPOST("vote", "int");
@@ -103,6 +105,7 @@ if ($cancel) {
 
 if ($action == 'add' && $user->rights->adherent->configurer) {
 	$object->label			= trim($label);
+    $object->morphy         = trim($morphy);
 	$object->statut = (int) $statut;
 	$object->subscription = (int) $subscription;
 	$object->note			= trim($comment);
@@ -157,6 +160,7 @@ if ($action == 'update' && $user->rights->adherent->configurer)
 	$object->oldcopy = clone $object;
 
 	$object->label			= trim($label);
+    $object->morphy         = trim($morphy);
 	$object->statut = (int) $statut;
 	$object->subscription = (int) $subscription;
 	$object->note			= trim($comment);
@@ -215,7 +219,7 @@ if (! $rowid && $action != 'create' && $action != 'edit')
 {
 	//dol_fiche_head('');
 
-	$sql = "SELECT d.rowid, d.libelle as label, d.subscription, d.vote, d.statut";
+	$sql = "SELECT d.rowid, d.libelle as label, d.subscription, d.vote, d.statut, d.morphy";
 	$sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as d";
 	$sql.= " WHERE d.entity IN (".getEntity('member_type').")";
 
@@ -232,10 +236,8 @@ if (! $rowid && $action != 'create' && $action != 'edit')
 		$newcardbutton='';
 		if ($user->rights->adherent->configurer)
 		{
-			$newcardbutton='<a class="butActionNew" href="'.DOL_URL_ROOT.'/adherents/type.php?action=create"><span class="valignmiddle text-plus-circle">'.$langs->trans('NewMemberType').'</span>';
-			$newcardbutton.= '<span class="fa fa-plus-circle valignmiddle"></span>';
-			$newcardbutton.= '</a>';
-		}
+            $newcardbutton.= dolGetButtonTitle($langs->trans('NewMemberType'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/adherents/type.php?action=create');
+        }
 
 		print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
 		if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
@@ -256,6 +258,7 @@ if (! $rowid && $action != 'create' && $action != 'edit')
 		print '<tr class="liste_titre">';
 		print '<th>'.$langs->trans("Ref").'</th>';
 		print '<th>'.$langs->trans("Label").'</th>';
+        print '<th class="center">'.$langs->trans("MemberNature").'</th>';
 		print '<th class="center">'.$langs->trans("SubscriptionRequired").'</th>';
 		print '<th class="center">'.$langs->trans("VoteAllowed").'</th>';
 		print '<th class="center">'.$langs->trans("Status").'</th>';
@@ -277,6 +280,11 @@ if (! $rowid && $action != 'create' && $action != 'edit')
 			//<a href="'.$_SERVER["PHP_SELF"].'?rowid='.$objp->rowid.'">'.img_object($langs->trans("ShowType"),'group').' '.$objp->rowid.'</a>
 			print '</td>';
 			print '<td>'.dol_escape_htmltag($objp->label).'</td>';
+            print '<td class="center">';
+			if ($objp->morphy == 'phy') { print $langs->trans("Physical"); }
+			elseif ($objp->morphy == 'mor') { print $langs->trans("Moral"); }
+			else print $langs->trans("Physical & Morale");
+            print '</td>';
 			print '<td class="center">'.yn($objp->subscription).'</td>';
 			print '<td class="center">'.yn($objp->vote).'</td>';
 			print '<td class="center">';
@@ -331,6 +339,14 @@ if ($action == 'create')
   	print $form->selectarray('statut', array('0'=>$langs->trans('ActivityCeased'),'1'=>$langs->trans('InActivity')), 1);
   	print '</td></tr>';
 
+    // Morphy
+    $morphys[""] = $langs->trans("MorPhy");
+    $morphys["phy"] = $langs->trans("Physical");
+	$morphys["mor"] = $langs->trans("Morale");
+	print '<tr><td><span>'.$langs->trans("MemberNature").'</span></td><td>';
+	print $form->selectarray("morphy", $morphys, isset($_POST["morphy"])?$_POST["morphy"]:$object->morphy);
+	print "</td></tr>";
+
   	print '<tr><td>'.$langs->trans("SubscriptionRequired").'</td><td>';
 	print $form->selectyesno("subscription", 1, 1);
 	print '</td></tr>';
@@ -412,6 +428,10 @@ if ($rowid > 0)
         }
 		print '</tr>';
 
+        // Morphy
+		print '<tr><td>'.$langs->trans("MemberNature").'</td><td class="valeur" >'.$object->getmorphylib($object->morphy).'</td>';
+		print '</tr>';
+
 		print '<tr><td class="titlefield">'.$langs->trans("SubscriptionRequired").'</td><td>';
 		print yn($object->subscription);
 		print '</tr>';
@@ -610,7 +630,7 @@ if ($rowid > 0)
 			print '<tr class="liste_titre">';
             print_liste_field_titre("NameSlashCompany", $_SERVER["PHP_SELF"], "d.lastname", $param, "", "", $sortfield, $sortorder);
 		    print_liste_field_titre("Login", $_SERVER["PHP_SELF"], "d.login", $param, "", "", $sortfield, $sortorder);
-		    print_liste_field_titre("Nature", $_SERVER["PHP_SELF"], "d.morphy", $param, "", "", $sortfield, $sortorder);
+		    print_liste_field_titre("MemberNature", $_SERVER["PHP_SELF"], "d.morphy", $param, "", "", $sortfield, $sortorder);
 		    print_liste_field_titre("EMail", $_SERVER["PHP_SELF"], "d.email", $param, "", "", $sortfield, $sortorder);
 		    print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "d.statut,d.datefin", $param, "", "", $sortfield, $sortorder);
 		    print_liste_field_titre("EndSubscription", $_SERVER["PHP_SELF"], "d.datefin", $param, "", 'align="center"', $sortfield, $sortorder);
@@ -752,6 +772,14 @@ if ($rowid > 0)
     	print $form->selectarray('statut', array('0'=>$langs->trans('ActivityCeased'),'1'=>$langs->trans('InActivity')), $object->statut);
     	print '</td></tr>';
 
+        // Morphy
+        $morphys[""] = $langs->trans("MorPhy");
+        $morphys["phy"] = $langs->trans("Physical");
+        $morphys["mor"] = $langs->trans("Morale");
+        print '<tr><td><span>'.$langs->trans("MemberNature").'</span></td><td>';
+        print $form->selectarray("morphy", $morphys, isset($_POST["morphy"])?$_POST["morphy"]:$object->morphy);
+        print "</td></tr>";
+
     	print '<tr><td>'.$langs->trans("SubscriptionRequired").'</td><td>';
 		print $form->selectyesno("subscription", $object->subscription, 1);
 		print '</td></tr>';

+ 1 - 1
htdocs/admin/agenda.php

@@ -143,7 +143,7 @@ print '<tr class="liste_titre">';
 print '<td class="liste_titre"><input type="text" name="search_event" value="'.dol_escape_htmltag($search_event).'"></td>';
 print '<td class="liste_titre"></td>';
 // Action column
-print '<td class="liste_titre right">';
+print '<td class="liste_titre maxwidthsearch">';
 $searchpicto=$form->showFilterButtons();
 print $searchpicto;
 print '</td>';

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio