Browse Source

Merge branch 'develop' into prod-attr

# Conflicts:
#	htdocs/comm/propal/card.php
#	htdocs/commande/card.php
#	htdocs/compta/facture.php
#	htdocs/core/class/html.form.class.php
#	htdocs/core/tpl/objectline_create.tpl.php
#	htdocs/fourn/commande/card.php
#	htdocs/fourn/facture/card.php
#	htdocs/install/mysql/migration/4.0.0-5.0.0.sql
Marcos García de La Fuente 8 năm trước cách đây
mục cha
commit
5669f734b8
100 tập tin đã thay đổi với 1492 bổ sung856 xóa
  1. 126 16
      ChangeLog
  2. 7 1
      build/debian/conf.php.install
  3. 2 0
      build/makepack-howto.txt
  4. 52 0
      dev/initdemo/mysqldump_dolibarr_5.0.0.sql
  5. 28 0
      dev/setup/nginx/dolibarr
  6. 1 1
      dev/skeletons/modMyModule.class.php
  7. 8 3
      dev/skeletons/skeleton_list.php
  8. 2 2
      dev/tools/fixdosfiles.sh
  9. 1 1
      htdocs/accountancy/admin/account.php
  10. 5 2
      htdocs/accountancy/admin/defaultaccounts.php
  11. 1 1
      htdocs/accountancy/admin/fiscalyear.php
  12. 1 1
      htdocs/accountancy/admin/productaccount.php
  13. 154 157
      htdocs/accountancy/bookkeeping/balance.php
  14. 3 1
      htdocs/accountancy/bookkeeping/balancebymonth.php
  15. 18 17
      htdocs/accountancy/bookkeeping/list.php
  16. 8 7
      htdocs/accountancy/bookkeeping/listbyaccount.php
  17. 1 1
      htdocs/accountancy/bookkeeping/listbyyear.php
  18. 4 4
      htdocs/accountancy/class/accountingaccount.class.php
  19. 11 13
      htdocs/accountancy/class/bookkeeping.class.php
  20. 19 18
      htdocs/accountancy/class/html.formventilation.class.php
  21. 2 2
      htdocs/accountancy/customer/index.php
  22. 1 1
      htdocs/accountancy/customer/lines.php
  23. 1 1
      htdocs/accountancy/customer/list.php
  24. 33 32
      htdocs/accountancy/expensereport/index.php
  25. 1 1
      htdocs/accountancy/expensereport/lines.php
  26. 1 1
      htdocs/accountancy/expensereport/list.php
  27. 21 16
      htdocs/accountancy/index.php
  28. 34 23
      htdocs/accountancy/journal/bankjournal.php
  29. 4 4
      htdocs/accountancy/journal/expensereportsjournal.php
  30. 4 4
      htdocs/accountancy/journal/purchasesjournal.php
  31. 4 4
      htdocs/accountancy/journal/sellsjournal.php
  32. 11 4
      htdocs/accountancy/report/result.php
  33. 2 2
      htdocs/accountancy/supplier/index.php
  34. 1 1
      htdocs/accountancy/supplier/lines.php
  35. 1 1
      htdocs/accountancy/supplier/list.php
  36. 16 16
      htdocs/adherents/card.php
  37. 9 4
      htdocs/adherents/class/adherent.class.php
  38. 16 4
      htdocs/adherents/class/adherent_type.class.php
  39. 3 6
      htdocs/adherents/class/api_members.class.php
  40. 3 3
      htdocs/adherents/class/api_subscriptions.class.php
  41. 26 1
      htdocs/adherents/class/subscription.class.php
  42. 17 17
      htdocs/adherents/list.php
  43. 6 2
      htdocs/adherents/subscription.php
  44. 24 20
      htdocs/adherents/subscription/card.php
  45. 1 1
      htdocs/adherents/subscription/list.php
  46. 15 22
      htdocs/adherents/type.php
  47. 1 1
      htdocs/admin/agenda_other.php
  48. 64 62
      htdocs/admin/company.php
  49. 6 1
      htdocs/admin/delais.php
  50. 9 7
      htdocs/admin/dict.php
  51. 4 4
      htdocs/admin/fckeditor.php
  52. 1 0
      htdocs/admin/ihm.php
  53. 1 1
      htdocs/admin/mails.php
  54. 14 14
      htdocs/admin/menus/index.php
  55. 3 3
      htdocs/admin/modules.php
  56. 13 1
      htdocs/admin/multicurrency.php
  57. 2 2
      htdocs/admin/perms.php
  58. 2 1
      htdocs/admin/system/constall.php
  59. 2 1
      htdocs/admin/system/dolibarr.php
  60. 0 3
      htdocs/api/class/api.class.php
  61. 1 1
      htdocs/api/class/api_dictionnarycountries.class.php
  62. 1 1
      htdocs/api/class/api_dictionnarytowns.class.php
  63. 17 2
      htdocs/api/index.php
  64. 4 4
      htdocs/asterisk/wrapper.php
  65. 5 3
      htdocs/bookmarks/card.php
  66. 2 2
      htdocs/cache.manifest
  67. 1 1
      htdocs/cashdesk/tpl/validation2.tpl.php
  68. 5 8
      htdocs/categories/class/api_categories.class.php
  69. 7 7
      htdocs/categories/class/api_deprecated_category.class.php
  70. 10 10
      htdocs/categories/class/categorie.class.php
  71. 1 1
      htdocs/categories/traduction.php
  72. 14 9
      htdocs/comm/action/class/api_agendaevents.class.php
  73. 2 2
      htdocs/comm/action/listactions.php
  74. 2 1
      htdocs/comm/action/peruser.php
  75. 1 1
      htdocs/comm/action/rapport/index.php
  76. 1 7
      htdocs/comm/card.php
  77. 6 3
      htdocs/comm/contact.php
  78. 1 1
      htdocs/comm/index.php
  79. 13 10
      htdocs/comm/mailing/advtargetemailing.php
  80. 22 12
      htdocs/comm/mailing/card.php
  81. 1 1
      htdocs/comm/mailing/cibles.php
  82. 117 15
      htdocs/comm/mailing/class/advtargetemailing.class.php
  83. 57 31
      htdocs/comm/propal/card.php
  84. 8 7
      htdocs/comm/propal/class/api_proposals.class.php
  85. 57 27
      htdocs/comm/propal/class/propal.class.php
  86. 1 0
      htdocs/comm/propal/contact.php
  87. 11 3
      htdocs/comm/propal/info.php
  88. 3 3
      htdocs/comm/propal/list.php
  89. 1 1
      htdocs/comm/propal/note.php
  90. 4 4
      htdocs/comm/remise.php
  91. 2 2
      htdocs/comm/remx.php
  92. 37 8
      htdocs/commande/card.php
  93. 4 3
      htdocs/commande/class/api_deprecated_commande.class.php
  94. 9 6
      htdocs/commande/class/api_orders.class.php
  95. 22 14
      htdocs/commande/class/commande.class.php
  96. 2 1
      htdocs/commande/class/commandestats.class.php
  97. 54 61
      htdocs/commande/contact.php
  98. 24 21
      htdocs/commande/customer.php
  99. 63 14
      htdocs/commande/document.php
  100. 68 8
      htdocs/commande/info.php

+ 126 - 16
ChangeLog

@@ -2,20 +2,130 @@
 English Dolibarr ChangeLog
 --------------------------------------------------------------
 
-WARNING: 
-
-Do not try to make any Dolibarr upgrade if you are running Mysql version 5.5.40.
-Mysql version 5.5.40 has a very critical bug making your data beeing definitely lost.
-You may also experience troubles with Mysql 5.5.41/42/43 with error "Lost connection" during
-migration.
-Upgrading to any other version or any other database system is abolutely required BEFORE trying
-make a Dolibarr upgrade.
-
 
 
 ***** ChangeLog for 5.0.0 compared to 4.0.* *****
 For users:
-...
+NEW: Add module mulicurrency.
+NEW: Add module accoutancy expert (double party accountancy). 
+NEW: Better responsive design, above all on smartphone.
+NEW: #5801 More complete change to allow to disable supplier invoice document generation.
+NEW: #5830 Can choose a generic email or use remail in the mail from field.
+NEW: #5896 More complete data on event sent by email (name in title, emails list in details)
+NEW: Add a better icon to show when "run" in cron jobs is disabled.
+NEW: Add account statement into fields of bank account transaction list.
+NEW: Add a direct debit mandate PDF template.
+NEW: add clone contract feature.
+NEW: Add color regarding stock even on ajax autocompleter product selector.
+NEW: Add date into list of print jobs for Google Print.
+NEW: add field and filters on turnover by third party report.
+NEW: Add last activation date as info in module list.
+NEW: add option to limit stock product by warehouse.
+NEW: Add missing unique key on table llx_links.
+NEW: Add option "Hide images in Top menu".
+NEW: Add option PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY to show thirdparty on page to submit time.
+NEW: Add option "Stock can be negative". Off by default.
+NEW: Add option SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED.
+NEW: Add hidden option to include parent products too in stats of orders (not supported in rest of app yet).
+NEW: Add Panama datas.
+NEW: Add ressource extrafields.
+NEW: add restrictions on standard exports (agenda, order, deplacement, facture, fournisseur, societe, propal, expedition)
+NEW: Add substitution keys __SHIPPINGTRACKNUM__, __SHIPPINGTRACKNUMURL__ into shipping email template.
+NEW: Add status Done on interventions.
+NEW: Add system tool "Files integrity checker" to detect modified files for packaged versions.
+NEW: Add tooltip in payment term edition in dictionnary.
+NEW: Add type "url" as possible extrafield.
+NEW: Add workflow to calculated supplier order status on stock dispatch.
+NEW: Add workflow to classifed propal bill on invoice validation.
+NEW: allow to save a parent warehouse.
+NEW: Better filtering of automatic/manually inserted events.
+NEW: Bill orders from order list.
+NEW: Can add event from the card listing events.
+NEW: Can change thirdparty when cloning a project.
+NEW: Can create expense report for someone else (advanced permission). 
+NEW: Can clone an expense report.
+NEW: Can edit a label for each price segment when using several segment prices for products.
+NEW: Can filter on fields on admin translation page.
+NEW: Can filter on project/task ref/label on the "new time consumed" page.
+NEW: Can filter on status on objects on the "statistics" pages.
+NEW: Can filter on type of leave requests in list.
+NEW: Can generate SEPA mandate for each bank account of your customers.
+NEW: Can see/make bank conciliation from bank transaction list.
+NEW: Can edit RUM number of a customer bank account.
+NEW: Can link template invoice to other objects. Generated invoices will be linked to same objects (example: contracts).
+NEW: Can renamed attached files on some documents tabs (like products and expense reports).
+NEW: Can see/edit the customer ref of a shipment.
+NEW: Can select fields/extrafields on contract list + Mass delete action.
+NEW: Can select fields on expense report list. Can make mass delete.
+NEW: Can select fields to show on list of bank transaction.
+NEW: Can set to paid automatically social or fiscal taxes after a payment was recorded.
+NEW: Can sort on status of recurring invoice in list of template invoices.
+NEW: Can use native php and dolibarr object on pages of module website.
+NEW: Checkbox 'close order to "Everything received" automatically if all products are received' is visible on supplier orders.
+NEW: conf to allow payments on different thirdparties bills but same parent company.
+NEW: Consumption view on thirdparty total line and total HT by element.
+NEW: Display bookkeeping by accounting account - Bookkeeping ordered by accounting account - Link with customers and suppliers invoices - Sub Total by accounting account - Ability to display more than 25 lines and filter by customer/supplier, invoice and accounting account
+NEW: Each user can select its landing page (on tab "user display setup").
+NEW: Editing translation GUI become easier with tool to search existing translation.
+NEW: Error code of each email sent is visible in list of email targets
+NEW: Export thirdparty with payment terms and mode.
+NEW: filter actiontype on thirdparty tab.
+NEW: filter by supplier and fk_warehouse on replenishment page.
+NEW: Filters can accept generic search key like __DAY__, __MONTH__, __YEAR__ replaced with current day, month year before making the search.
+NEW: Function "crop" images available on project, product and holiday attachment tab.
+NEW: function to display full path to current warehouse.
+NEW: Generation of document is available on member card.
+NEW: Introduce mass action "delete" on sales orders.
+NEW: Introduce option MAIN_DEFAULT_PAYMENT_TERM_ID to set default payment term on company level.
+NEW: introduce option PROJECT_DISABLE_PRIVATE_PROJECT and PROJECT_DISABLE_PUBLIC_PROJECT.
+NEW: Link between objects can be done on both side and on all objects.
+NEW: More filter on bank transaction list.
+NEW: Mutualize mass action. So "Send by email" is also available on orders.
+NEW: New set of icon for status easier to understand.
+NEW: option "Current/Next" for limit payment date (in payment term dictionary setup) to use a specific day of current month or jump to same day of next month.
+NEW: Option DOC_SHOW_FIRST_SALES_REP shows name of "user buyer or saler" on PDF.
+NEW: Option MAIN_INFO_SOCIETE_MAIL_ALIASES to be able to use several identities into the "email from".
+NEW: Pagination available on list of users.
+NEW: Phone formatting for Canada. Add dol_print_phone into phpunit tests.
+NEW: Reduce nb of picto visible after reference of an object into lists, merging preview and download.
+NEW: Reduce space lost on EDM module.
+NEW: Reopen a paid bill is a user advanced permission.
+NEW: can set a default bank account on thirdparty card.
+NEW: Show photo of contacts on thirdparty card.
+NEW: Show subtotal into list of linked elements.
+NEW: Show total line (planned workload and time spent) on list of tasks.
+NEW: Start to introduce search filters on dictionnaries for vat list.
+NEW: Support extrafields for expense reports.
+NEW: Support extrafields on product lot.
+NEW: Support free bottom text and watermark on expense report template.
+NEW: Support mass actions for proposals
+NEW: Table with list of lots/serial can be viewed (module product batch).
+NEW: The autofill zip/town table option is on by default.
+NEW: the count of linked files on card includes external links.
+NEW: Usage of vat code seems ok everywhere.
+NEW: User date of employment added.
+NEW: Use small photo of user on all user links.
+NEW: Use new archi to select fields into list of time spent.
+NEW: Available substitution key (__INVOICE_MONTH__, __INVOICE_PREVIOUS_MONTH__, ...) to use into note text of recurring invoices.
+
+For developers:
+NEW: Add ORDER_MODIFY trigger on each order modification.
+NEW: Trigger on delete stock
+NEW: The getURLContent return more information on success and error.
+NEW: Uniformize code and correct deal with triggers
+NEW: REST API explorer. Can create invoice and orders with lines.
+NEW: Add a lot of API REST: expense reports, orders, commercial proposals, projects, agenda events, users, invoices, ...
+NEW: Default collation for mysql is now utf8_unicode_ci
+NEW: Can use any filter on all REST API to list.
+NEW: ckeditor accept a parameter to disable all html filtering.
+NEW: Complete table llx_ecm_files with field generated_or_uploaded
+NEW: Enhance function setValueFrom so we can use it for "edit in form" feature.
+NEW: getNomUrl displays full path to warehouse
+NEW: Hook formObjectOptions
+NEW: hook in element overview
+NEW: Hook on stock product card
+NEW: param socid find_min_price_product_fournisseur() function
+NEW: More phpunit tests
 
 WARNING: 
 
@@ -139,12 +249,12 @@ NEW: Add the admin info on combo of type of contact
 NEW: Add the event BILL_PAYED to the list of supported events for module notification.
 NEW: Add total weight and volume on PDF. 
 NEW: Add hidden option to hide column qty ordered on shipments.
-NEW: Add view of virtual stock into product list (when appropriate).
-NEW: Add warning on tasks when they are late (add also the warning tolerance parameter).
-NEW: Add weight/volume for one product into shipment export.
-NEW: Add width and height on product card
-NEW: allow a document to be linked to project of another customer by config setup.
-NEW: allow project to be shared across entities (for multicompany module).
+NEW: Add view of virtual stock into product list (when appropriate)
+NEW: Add warning on tasks when they are late (add also the warning tolerance parameter)
+NEW: Add weight/volume for one product into shipment export
+NEW: Add width and height on product table
+NEW: allow a document to be linked to project from another customer on config
+NEW: allow project to be shared across entities (for multicompany module)
 NEW: All variant of ckeditor config can be tested into the setup page of module.
 NEW: Can change dynamically number of records visible into lists.
 NEW: Can change type of extrafields (for some combinations only).

+ 7 - 1
build/debian/conf.php.install

@@ -221,7 +221,13 @@ $dolibarr_main_prod='0';
 # $dolibarr_main_limit_users='0';
 
 # dolibarr_mailing_limit_sendbyweb
-# Can set a limit for mailing send by web, can be used for a restricted mode.
+# Can set a limit for mailing send by web. This overwrite database value. Can be used to restrict on OS level.
 # Default value: 0 (use database value if exist)
 # Examples:
 # $dolibarr_mailing_limit_sendbyweb='0';
+
+# dolibarr_mailing_limit_sendbycli
+# Can set a limit for mailing send by cli. This overwrite database value. Can be used to restrict on OS level.
+# Default value: 0 (use database value if exist)
+# Examples:
+# $dolibarr_mailing_limit_sendbycli='0';

+ 2 - 0
build/makepack-howto.txt

@@ -12,6 +12,7 @@ beta version of Dolibarr, step by step.
 To generate a changelog of a major new version x.y.0 (from develop repo), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0)  <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
 To generate a changelog of a major new version x.y.0 (from x.y repo), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0)  <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
 To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
+- To know number of lines changes: git diff --shortstat A B
 - Update version number with x.y.z-w in htdocs/filefunc.inc.php
 - Commit all changes.
 
@@ -35,6 +36,7 @@ complete release of Dolibarr, step by step.
 To generate a changelog of a major new version x.y.0 (from develop repo), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0)  <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
 To generate a changelog of a major new version x.y.0 (from x.y repo), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0)  <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
 To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
+- To know number of lines changes: git diff --shortstat A B
 - Update version number with x.y.z in htdocs/filefunc.inc.php
 - Commit all changes.
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 52 - 0
dev/initdemo/mysqldump_dolibarr_5.0.0.sql


+ 28 - 0
dev/setup/nginx/dolibarr

@@ -0,0 +1,28 @@
+# Dolibarr server configuration sample for NGinx
+server {
+        listen 80;
+        listen [::]:80;
+
+        root /path/to/your/htdocs;
+
+        # Optionnal
+        error_log /path/to/your/log/directory/nginx.error.log;
+	    access_log /path/to/your/log/directory/nginx.access.log;
+
+        index index.php index.html index.htm;
+
+        # Optionnal
+        server_name your-fqdn.tld;
+
+        location / {
+                try_files $uri $uri/ /index.php;
+        }
+
+        location ~ [^/]\.php(/|$) {
+                try_files $uri =404;
+                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+                fastcgi_read_timeout 600;
+                include fastcgi_params;
+                fastcgi_pass unix:/var/run/php5-fpm.sock;
+        }
+}

+ 1 - 1
dev/skeletons/modMyModule.class.php

@@ -64,7 +64,7 @@ class modMyModule extends DolibarrModules
 		$this->description = "Description of module MyModule";
 		$this->descriptionlong = "A very long description. Can be a full HTML content";
 		$this->editor_name = 'Editor name';
-		$this->editor_url = 'http://www.dolibarr.org';
+		$this->editor_url = 'https://www.dolibarr.org';
 		
 		// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
 		$this->version = '1.0';

+ 8 - 3
dev/skeletons/skeleton_list.php

@@ -1,6 +1,7 @@
 <?php
 /* Copyright (C) 2007-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2014-2016  Juanjo Menent       <jmenent@2byte.es>
+ * Copyright (C) 2014-2016 Juanjo Menent        <jmenent@2byte.es>
+ * Copyright (C) 2016      Jean-François Ferry	<jfefe@aternatik.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -88,8 +89,11 @@ if ($user->societe_id > 0)
 	//accessforbidden();
 }
 
+// Initialize technical object to manage context to save list fields
+$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'mymodulelist';
+
 // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
-$hookmanager->initHooks(array('skeletonlist'));
+$hookmanager->initHooks(array('mymodulelist'));
 $extrafields = new ExtraFields($db);
 
 // fetch optionals attributes and labels
@@ -243,7 +247,7 @@ $sql.=$db->order($sortfield,$sortorder);
 //$sql.= $db->plimit($conf->liste_limit+1, $offset);
 
 // Count total nb of records
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
 	$result = $db->query($sql);
@@ -304,6 +308,7 @@ print '<input type="hidden" name="formfilteraction" id="formfilteraction" value=
 print '<input type="hidden" name="action" value="list">';
 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
+print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
 
 print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit);
 

+ 2 - 2
dev/tools/fixdosfiles.sh

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

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

@@ -172,7 +172,7 @@ if (strlen(trim($search_pcgsubtype))) {
 $sql .= $db->order($sortfield, $sortorder);
 
 // Count total nb of records
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
 	$resql = $db->query($sql);

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

@@ -1,7 +1,7 @@
 <?php
 /* Copyright (C) 2013-2014 Olivier Geffroy		<jeff@jeffinfo.com>
  * Copyright (C) 2013-2014 Florian Henry		<florian.henry@open-concept.pro>
- * Copyright (C) 2013-2016 Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2013-2016 Alexandre Spangaro	<aspangaro@zendsi.com>
  * Copyright (C) 2014-2015 Ari Elbaz (elarifr)	<github@accedinfo.com>
  * Copyright (C) 2014      Marcos García        <marcosgdf@gmail.com>
  * Copyright (C) 2014	   Juanjo Menent		<jmenent@2byte.es>
@@ -62,7 +62,10 @@ $list_account = array (
 		'ACCOUNTING_VAT_PAY_ACCOUNT',
 		'ACCOUNTING_ACCOUNT_SUSPENSE',
 		'ACCOUNTING_ACCOUNT_TRANSFER_CASH',
-		'DONATION_ACCOUNTINGACCOUNT'
+		'DONATION_ACCOUNTINGACCOUNT',
+		'LOAN_ACCOUNTING_ACCOUNT_CAPITAL',
+		'LOAN_ACCOUNTING_ACCOUNT_INTEREST',
+		'LOAN_ACCOUNTING_ACCOUNT_INSURANCE'
 );
 
 

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

@@ -90,7 +90,7 @@ $sql .= " WHERE f.entity = " . $conf->entity;
 $sql.=$db->order($sortfield,$sortorder);
 
 // Count total nb of records
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
 	$result = $db->query($sql);

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

@@ -248,7 +248,7 @@ if (strlen(trim($search_desc))) {
 }
 $sql .= $db->order($sortfield, $sortorder);
 
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
     $result = $db->query($sql);

+ 154 - 157
htdocs/accountancy/bookkeeping/balance.php

@@ -65,14 +65,6 @@ $formventilation = new FormVentilation($db);
 $formother = new FormOther($db);
 $form = new Form($db);
 
-if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers
-{
-	$search_accountancy_code_start = '';
-	$search_accountancy_code_end = '';
-	$search_date_start = '';
-	$search_date_end = '';
-}
-
 if (empty($search_date_start)) {
 	$search_date_start = dol_mktime(0, 0, 0, 1, 1, dol_print_date(dol_now(), '%Y'));
 	$search_date_end = dol_mktime(0, 0, 0, 12, 31, dol_print_date(dol_now(), '%Y'));
@@ -106,6 +98,19 @@ if (! empty($search_accountancy_code_end)) {
  * Action
  */
 
+if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers
+{
+    $search_accountancy_code_start = '';
+    $search_accountancy_code_end = '';
+    $search_date_start = '';
+    $search_date_end = '';
+}
+
+
+/*
+ * View
+ */
+
 if ($action == 'export_csv') {
 	$sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
 	$journal = 'bookkepping';
@@ -132,155 +137,147 @@ if ($action == 'export_csv') {
 }
 
 else {
-
-	$title_page = $langs->trans("AccountBalance") . ' ' . dol_print_date($search_date_start) . '-' . dol_print_date($search_date_end);
-
-	llxHeader('', $title_page);
-
-	/*
-	 * List
-	 */
-	$nbtotalofrecords = 0;
-	if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
-		$nbtotalofrecords = $object->fetchAllBalance($sortorder, $sortfield, 0, 0, $filter);
-		if ($nbtotalofrecords < 0) {
-			setEventMessages($object->error, $object->errors, 'errors');
-		}
-	}
-
-	$result = $object->fetchAllBalance($sortorder, $sortfield, $limit, $offset, $filter);
-	if ($result < 0) {
-		setEventMessages($object->error, $object->errors, 'errors');
-	}
-
-	print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $options, $sortfield, $sortorder, '', $result, 0, 'title_accountancy');
-
-	print '<form method="GET" id="searchFormList" action="' . $_SERVER["PHP_SELF"] . '">';
-	print '<div class="tabsAction">' . "\n";
-	print '<div class="inline-block divButAction"><input type="submit" name="button_export_csv" class="butAction" value="' . $langs->trans("Export") . '" /></div>';
-	print '</div>';
-
-	$moreforfilter='';
-
-	$moreforfilter.='<div class="divsearchfield">';
-	$moreforfilter.=$langs->trans('DateStart') . ': ';
-	$moreforfilter.=$form->select_date($search_date_start, 'date_start', 0, 0, 1, '', 1, 0, 1);
-	$moreforfilter.=$langs->trans('DateEnd') . ': ';
-	$moreforfilter.=$form->select_date($search_date_end, 'date_end', 0, 0, 1, '', 1, 0, 1);
-	$moreforfilter.='</div>';
-
-	if (! empty($moreforfilter))
-	{
-		print '<div class="liste_titre liste_titre_bydiv centpercent">';
-		print $moreforfilter;
-    	$parameters=array();
-    	$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters);    // Note that $action and $object may have been modified by hook
-	    print $hookmanager->resPrint;
-	    print '</div>';
-	}
-
-	print '<table class="liste '.($moreforfilter?"listwithfilterbefore":"").'">';
-	print '<tr class="liste_titre">';
-	print_liste_field_titre($langs->trans("AccountAccounting"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Labelcompte"), $_SERVER['PHP_SELF'], "t.label_compte", "", $options, "", $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "t.debit", "", $options, 'align="right"', $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "t.credit", "", $options, 'align="right"', $sortfield, $sortorder);
-	print_liste_field_titre($langs->trans("Solde"), $_SERVER["PHP_SELF"], "", $options, "", 'align="right"', $sortfield, $sortorder);
-	print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $options, "", 'width="60" align="center"', $sortfield, $sortorder);
-	print "</tr>\n";
-
-	print '<tr class="liste_titre">';
-	print '<td colspan="2">';
-	print $langs->trans('From');
-	print $formventilation->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array (), 1, 1, '');
-	print '<br>';
-	print $langs->trans('to');
-	print $formventilation->select_account($search_accountancy_code_end, 'search_accountancy_code_end', 1, array (), 1, 1, '');
-	print '</td>';
-
-	print '<td>&nbsp;</td>';
-	print '<td>&nbsp;</td>';
-	print '<td>&nbsp;</td>';
-
-	print '<td align="right" class="liste_titre">';
-	print '<input type="image" class="liste_titre" src="' . img_picto($langs->trans("Search"), 'search.png', '', '', 1) . '" name="button_search" value="' . dol_escape_htmltag($langs->trans("Search")) . '" title="' . dol_escape_htmltag($langs->trans("Search")) . '">';
-	print '&nbsp;';
-	print '<input type="image" class="liste_titre" src="' . img_picto($langs->trans("Search"), 'searchclear.png', '', '', 1) . '" name="button_removefilter" value="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '" title="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '">';
-	print '</td>';
-
-	print '</tr>';
-
-	$var = True;
-
-	$total_debit = 0;
-	$total_credit = 0;
-  $sous_total_debit = 0;
-  $sous_total_credit = 0;
-  $displayed_account = "";
-
-	foreach ( $object->lines as $line ) {
-		$var = ! $var;
-		$link = '';
-		$total_debit += $line->debit;
-		$total_credit += $line->credit;
-		$description = $object->get_compte_desc($line->numero_compte); // Search description of the account
-    $root_account_description = $object->get_compte_racine($line->numero_compte);
-		if(empty($description)){
-			$link = '<a href="../admin/card.php?action=create&compte=' . length_accountg($line->numero_compte) . '">' . img_edit_add() .'</a>';
-		}
-		print '<tr'. $bc[$var].'>';
-
-
-    // Permet d'afficher le compte comptable
-    if ($root_account_description != $displayed_account) {
-
-      // Affiche un Sous-Total par compte comptable
-      if ($displayed_account != "") {
-        print '<tr class="liste_total"><td align="right" colspan="2">'.$langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">'.price($sous_total_debit).'</td><td class="nowrap" align="right">'.price($sous_total_credit).'</td><td class="nowrap" align="right">'.price($sous_total_credit-$sous_total_debit).'</td>';
-        print "<td>&nbsp;</td>\n";
-        print '</tr>';
-      }
-
-      // Affiche le compte comptable en d�but de ligne
-      print "<tr>";
-    	print '<td colspan="6" style="font-weight:bold; border-bottom: 1pt solid black;">'. $root_account_description .'</td>';
-    	print '</tr>';
-
-      $displayed_account = $root_account_description;
-      $sous_total_debit = 0;
-      $sous_total_credit = 0;
+    $title_page = $langs->trans("AccountBalance") . ' ' . dol_print_date($search_date_start) . '-' . dol_print_date($search_date_end);
+    
+    llxHeader('', $title_page);
+    
+    // List
+
+    $nbtotalofrecords = -1;
+    if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
+        $nbtotalofrecords = $object->fetchAllBalance($sortorder, $sortfield, 0, 0, $filter);
+        if ($nbtotalofrecords < 0) {
+            setEventMessages($object->error, $object->errors, 'errors');
+        }
     }
-
-    // $object->get_compte_racine($line->numero_compte);
-
-
-		print '<td>' . length_accountg($line->numero_compte) . '</td>';
-		print '<td>' . $description . '</td>';
-		print '<td align="right">' .  number_format($line->debit, 2, ',', ' ') . '</td>';
-    print '<td align="right">' . number_format($line->credit, 2, ',', ' ') . '</td>';
-    print '<td align="right">' . number_format($line->credit - $line->debit, 2, ',', ' ') . '</td>';
-		print '<td align="center">' . $link;
-		print '</td>';
-		print "</tr>\n";
-
-    // Comptabilise le sous-total
-    $sous_total_debit += $line->debit;
-    $sous_total_credit += $line->credit;
-
-	}
-
-  print '<tr class="liste_total"><td align="right" colspan="2">'.$langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">'.price($sous_total_debit).'</td><td class="nowrap" align="right">'.price($sous_total_credit).'</td><td class="nowrap" align="right">'.price($sous_total_credit-$sous_total_debit).'</td>';
-  print "<td>&nbsp;</td>\n";
-  print '</tr>';
-
-  print '<tr class="liste_total"><td align="right" colspan="2">'.$langs->trans("AccountBalance") . ':</td><td class="nowrap" align="right">'.price($total_debit).'</td><td class="nowrap" align="right">'.price($total_credit).'</td><td class="nowrap" align="right">'.price($total_credit-$total_debit).'</td>';
-  print "<td>&nbsp;</td>\n";
-  print '</tr>';
-
-
-	print "</table>";
-	print '</form>';
-
-	llxFooter();
+    
+    $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, $offset, $filter);
+    if ($result < 0) {
+        setEventMessages($object->error, $object->errors, 'errors');
+    }
+    
+    
+    print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
+    
+    $button = '<input type="submit" name="button_export_csv" class="butAction" value="' . $langs->trans("Export") . '" />';
+    print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $options, $sortfield, $sortorder, '', $result, 0, 'title_accountancy', 0, $button);
+    
+    
+    $moreforfilter = '';
+    
+    $moreforfilter .= '<div class="divsearchfield">';
+    $moreforfilter .= $langs->trans('DateStart') . ': ';
+    $moreforfilter .= $form->select_date($search_date_start, 'date_start', 0, 0, 1, '', 1, 0, 1);
+    $moreforfilter .= $langs->trans('DateEnd') . ': ';
+    $moreforfilter .= $form->select_date($search_date_end, 'date_end', 0, 0, 1, '', 1, 0, 1);
+    $moreforfilter .= '</div>';
+    
+    if (! empty($moreforfilter)) {
+        print '<div class="liste_titre liste_titre_bydiv centpercent">';
+        print $moreforfilter;
+        $parameters = array();
+        $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
+        print $hookmanager->resPrint;
+        print '</div>';
+    }
+    
+    print '<table class="liste ' . ($moreforfilter ? "listwithfilterbefore" : "") . '">';
+    print '<tr class="liste_titre">';
+    print_liste_field_titre($langs->trans("AccountAccounting"), $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder);
+    print_liste_field_titre($langs->trans("Labelcompte"), $_SERVER['PHP_SELF'], "t.label_compte", "", $options, "", $sortfield, $sortorder);
+    print_liste_field_titre($langs->trans("Debit"), $_SERVER['PHP_SELF'], "t.debit", "", $options, 'align="right"', $sortfield, $sortorder);
+    print_liste_field_titre($langs->trans("Credit"), $_SERVER['PHP_SELF'], "t.credit", "", $options, 'align="right"', $sortfield, $sortorder);
+    print_liste_field_titre($langs->trans("Solde"), $_SERVER["PHP_SELF"], "", $options, "", 'align="right"', $sortfield, $sortorder);
+    print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $options, "", 'width="60" align="center"', $sortfield, $sortorder);
+    print "</tr>\n";
+    
+    print '<tr class="liste_titre">';
+    print '<td class="liste_titre center" colspan="2">';
+    print $langs->trans('From');
+    print $formventilation->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array(), 1, 1, '');
+    print '<br>';
+    print $langs->trans('to');
+    print $formventilation->select_account($search_accountancy_code_end, 'search_accountancy_code_end', 1, array(), 1, 1, '');
+    print '</td>';
+    
+    print '<td class="liste_titre center">&nbsp;</td>';
+    print '<td class="liste_titre center">&nbsp;</td>';
+    print '<td class="liste_titre center">&nbsp;</td>';
+    
+    print '<td align="right" class="liste_titre">';
+	$searchpitco=$form->showFilterAndCheckAddButtons(0);
+	print $searchpitco;
+    print '</td>';
+    
+    print '</tr>';
+    
+    $var = True;
+    
+    $total_debit = 0;
+    $total_credit = 0;
+    $sous_total_debit = 0;
+    $sous_total_credit = 0;
+    $displayed_account = "";
+    
+    foreach ($object->lines as $line) {
+        $var = ! $var;
+        $link = '';
+        $total_debit += $line->debit;
+        $total_credit += $line->credit;
+        $description = $object->get_compte_desc($line->numero_compte); // Search description of the account
+        $root_account_description = $object->get_compte_racine($line->numero_compte);
+        if (empty($description)) {
+            $link = '<a href="../admin/card.php?action=create&compte=' . length_accountg($line->numero_compte) . '">' . img_edit_add() . '</a>';
+        }
+        print '<tr' . $bc[$var] . '>';
+        
+        // Permet d'afficher le compte comptable
+        if ($root_account_description != $displayed_account) {
+            
+            // Affiche un Sous-Total par compte comptable
+            if ($displayed_account != "") {
+                print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">' . price($sous_total_debit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit - $sous_total_debit) . '</td>';
+                print "<td>&nbsp;</td>\n";
+                print '</tr>';
+            }
+            
+            // Affiche le compte comptable en d�but de ligne
+            print "<tr>";
+            print '<td colspan="6" style="font-weight:bold; border-bottom: 1pt solid black;">' . $root_account_description . '</td>';
+            print '</tr>';
+            
+            $displayed_account = $root_account_description;
+            $sous_total_debit = 0;
+            $sous_total_credit = 0;
+        }
+        
+        // $object->get_compte_racine($line->numero_compte);
+        
+        print '<td>' . length_accountg($line->numero_compte) . '</td>';
+        print '<td>' . $description . '</td>';
+        print '<td align="right">' . number_format($line->debit, 2, ',', ' ') . '</td>';
+        print '<td align="right">' . number_format($line->credit, 2, ',', ' ') . '</td>';
+        print '<td align="right">' . number_format($line->credit - $line->debit, 2, ',', ' ') . '</td>';
+        print '<td align="center">' . $link;
+        print '</td>';
+        print "</tr>\n";
+        
+        // Comptabilise le sous-total
+        $sous_total_debit += $line->debit;
+        $sous_total_credit += $line->credit;
+    }
+    
+    print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">' . price($sous_total_debit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit - $sous_total_debit) . '</td>';
+    print "<td>&nbsp;</td>\n";
+    print '</tr>';
+    
+    print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("AccountBalance") . ':</td><td class="nowrap" align="right">' . price($total_debit) . '</td><td class="nowrap" align="right">' . price($total_credit) . '</td><td class="nowrap" align="right">' . price($total_credit - $total_debit) . '</td>';
+    print "<td>&nbsp;</td>\n";
+    print '</tr>';
+    
+    print "</table>";
+    print '</form>';
+    
+    llxFooter();
 }
 $db->close();

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

@@ -38,7 +38,7 @@ $langs->load("other");
 $langs->load("accountancy");
 
 // Filter
-$year = $_GET["year"];
+$year = GETPOST("year",'int');
 if ($year == 0) {
 	$year_current = strftime("%Y", time());
 	$year_start = $year_current;
@@ -47,9 +47,11 @@ if ($year == 0) {
 	$year_start = $year;
 }
 
+
 /*
  * View
  */
+
 llxHeader('', $langs->trans("Bookkeeping"));
 
 $textprevyear = '<a href="' . $_SERVER["PHP_SELF"] . '?year=' . ($year_current - 1) . '">' . img_previous() . '</a>';

+ 18 - 17
htdocs/accountancy/bookkeeping/list.php

@@ -288,12 +288,12 @@ if ($action == 'export_csv') {
 }
 
 $title_page = $langs->trans("Bookkeeping");
-if ($search_date_start || $search_date_end) $title_page .= ' ' . dol_print_date($search_date_start, 'day') . ' - ' . dol_print_date($search_date_end, 'day');
+
 llxHeader('', $title_page);
 
 // List
 
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
 	$nbtotalofrecords = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter);
 	if ($nbtotalofrecords < 0) {
@@ -356,20 +356,21 @@ print '<input type="hidden" name="formfilteraction" id="formfilteraction" value=
 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
 
-print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
+$button = '<a class="butAction" name="button_export_csv" href="'.$_SERVER["PHP_SELF"].'?action=export_csv'.($param?'&'.$param:'').'">';
+if (count($filter)) $button.= $langs->trans("ExportFilteredList");
+else $button.= $langs->trans("ExportList");
+$button.= '</a>';
+
+$groupby = ' <a href="./listbyaccount.php">' . $langs->trans("GroupByAccountAccounting") . '</a>';
+
+print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $button, $result, $nbtotalofrecords, 'title_accountancy', 0, $groupby, '', $limit);
 
 print '<div class="tabsAction">' . "\n";
 print '<div class="inline-block divButAction"><a class="butAction" href="./card.php?action=create">' . $langs->trans("NewAccountingMvt") . '</a></div>';
-print '<div class="inline-block divButAction"><a class="butAction" name="button_export_csv" href="'.$_SERVER["PHP_SELF"].'?action=export_csv'.($param?'&'.$param:'').'">';
-if (count($filter)) print $langs->trans("ExportFilteredList");
-else print $langs->trans("ExportList");
-print '</a></div>';
 print '<div class="inline-block divButAction"><a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear'.($param?'&'.$param:'').'">' . $langs->trans("DelBookKeeping") . '</a></div>';
 
 print '</div>';
 
-print ' <a href="./listbyaccount.php">' . $langs->trans("GroupByAccountAccounting") . '</a><br><br>';
-
 print '<table class="noborder" width="100%">';
 print '<tr class="liste_titre">';
 print_liste_field_titre($langs->trans("TransactionNumShort"), $_SERVER['PHP_SELF'], "t.piece_num", "", $param, "", $sortfield, $sortorder);
@@ -385,7 +386,7 @@ print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $param, "", 'width="60" al
 print "</tr>\n";
 
 print '<tr class="liste_titre">';
-print '<td><input type="text" name="search_mvt_num" size="6" value="' . $search_mvt_num . '"></td>';
+print '<td class="liste_titre center"><input type="text" name="search_mvt_num" size="6" value="' . $search_mvt_num . '"></td>';
 print '<td class="liste_titre center">';
 print $langs->trans('From') . ': ';
 print $form->select_date($search_date_start, 'date_start', 0, 0, 1);
@@ -393,15 +394,15 @@ print '<br>';
 print $langs->trans('to') . ': ';
 print $form->select_date($search_date_end, 'date_end', 0, 0, 1);
 print '</td>';
-print '<td><input type="text" name="search_doc_ref" size="8" value="' . $search_doc_ref . '"></td>';
-print '<td>';
+print '<td class="liste_titre center"><input type="text" name="search_doc_ref" size="8" value="' . $search_doc_ref . '"></td>';
+print '<td class="liste_titre center">';
 print $langs->trans('From');
 print $formventilation->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array (), 1, 1, '');
 print '<br>';
 print $langs->trans('to');
 print $formventilation->select_account($search_accountancy_code_end, 'search_accountancy_code_end', 1, array (), 1, 1, '');
 print '</td>';
-print '<td>';
+print '<td class="liste_titre center">';
 print $langs->trans('From');
 print $formventilation->select_auxaccount($search_accountancy_aux_code_start, 'search_accountancy_aux_code_start', 1);
 print '<br>';
@@ -411,10 +412,10 @@ print '</td>';
 print '<td class="liste_titre">';
 print '<input type="text" size="7" class="flat" name="search_mvt_label" value="' . $search_mvt_label . '"/>';
 print '</td>';
-print '<td>&nbsp;</td>';
-print '<td>&nbsp;</td>';
-print '<td  align="right"><input type="text" name="search_ledger_code" size="3" value="' . $search_ledger_code . '"></td>';
-print '<td align="right" class="liste_titre">';
+print '<td class="liste_titre center">&nbsp;</td>';
+print '<td class="liste_titre center">&nbsp;</td>';
+print '<td class="liste_titre center" align="right"><input type="text" name="search_ledger_code" size="3" value="' . $search_ledger_code . '"></td>';
+print '<td class="liste_titre center" align="right">';
 $searchpitco=$form->showFilterAndCheckAddButtons(0);
 print $searchpitco;
 print '</td>';

+ 8 - 7
htdocs/accountancy/bookkeeping/listbyaccount.php

@@ -156,13 +156,13 @@ if ($action == 'delmouvconfirm') {
  * View
  */
 
-$title_page = $langs->trans("Bookkeeping") . ' ' . strtolower($langs->trans("By")) . ' ' . $langs->trans("AccountAccounting") . ' ' . dol_print_date($search_date_start) . '-' . dol_print_date($search_date_end);
+$title_page = $langs->trans("Bookkeeping") . ' ' . strtolower($langs->trans("By")) . ' ' . $langs->trans("AccountAccounting");
 
 llxHeader('', $title_page);
 
 // List
 
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
 	$nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter);
 	if ($nbtotalofrecords < 0) {
@@ -207,7 +207,9 @@ if ($action == 'delbookkeepingyear') {
 
 print '<form method="GET" id="searchFormList" action="' . $_SERVER["PHP_SELF"] . '">';
 
-print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $options, $sortfield, $sortorder, '', $result, $nbtotalofrecords,'title_accountancy',0,'','',$limit);
+$viewflat = ' <a href="./list.php">' . $langs->trans("ViewFlatList") . '</a>';
+
+print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $options, $sortfield, $sortorder, '', $result, $nbtotalofrecords,'title_accountancy',0,$viewflat,'',$limit);
 
 // Reverse sort order
 if ( preg_match('/^asc/i', $sortorder) )
@@ -219,8 +221,6 @@ print '<div class="tabsAction">' . "\n";
 print '<div class="inline-block divButAction"><a class="butAction" href="./card.php?action=create">' . $langs->trans("NewAccountingMvt") . '</a></div>';
 print '</div>';
 
-print ' <a href="./list.php">' . $langs->trans("ViewFlatList") . '</a><br><br>';
-
 print '<table class="noborder" width="100%">';
 print '<tr class="liste_titre">';
 print '<td>' . $langs->trans("AccountAccounting") . '</td>';
@@ -331,14 +331,15 @@ foreach ( $object->lines as $line ) {
 }
 
 // Affiche un Sous-Total du dernier compte comptable affiché
-print '<tr class="liste_total"><td align="right" colspan="4">'.$langs->trans("SubTotal").':</td><td class="nowrap" align="right">'.price($sous_total_debit).'</td><td class="nowrap" align="right">'.price($sous_total_credit).'</td>';
+print '<tr class="liste_total">';
+print '<td align="right" colspan="5">'.$langs->trans("SubTotal").':</td><td class="nowrap" align="right">'.price($sous_total_debit).'</td><td class="nowrap" align="right">'.price($sous_total_credit).'</td>';
 print "<td>&nbsp;</td>\n";
 print '</tr>';
 
 
 // Affiche le Total
 print '<tr class="liste_total">';
-print '<td align="right" colspan="4">'.$langs->trans("Total").':</td>';
+print '<td align="right" colspan="5">'.$langs->trans("Total").':</td>';
 print '<td  align="right">';
 print price($total_debit);
 print '</td>';

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

@@ -158,7 +158,7 @@ if (! empty($search_code_journal)) {
  * Mode List
  */
 
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
 	$nbtotalofrecords = $object->fetchAll($sortorder, $sortfield, 0, 0);
 	if ($nbtotalofrecords < 0) {

+ 4 - 4
htdocs/accountancy/class/accountingaccount.class.php

@@ -60,10 +60,10 @@ 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 OK
+	 * @param 	int 	$rowid 				   Id
+	 * @param 	string 	$account_number 	   Account number
+	 * @param 	int 	$limittocurrentchart   1=Do not load record if it is into another accounting system
+	 * @return 	int                            <0 if KO, Id of record if OK and found
 	 */
 	function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0) {
 		global $conf;

+ 11 - 13
htdocs/accountancy/class/bookkeeping.class.php

@@ -190,14 +190,14 @@ class BookKeeping extends CommonObject
 		
 		if ($resql) {
 			$row = $this->db->fetch_object($resql);
-			if ($row->nb == 0) {
-				
+			if ($row->nb == 0) 
+			{
 				// Determine piece_num
 				$sqlnum = "SELECT piece_num";
 				$sqlnum .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
-				$sqlnum .= " WHERE doc_type = '" . $this->doc_type . "'";
-				$sqlnum .= " AND fk_docdet = '" . $this->fk_docdet . "'";
-				$sqlnum .= " AND doc_ref = '" . $this->doc_ref . "'";
+				$sqlnum .= " WHERE doc_type = '" . $this->doc_type . "'";		// For example doc_type = 'bank' 
+				$sqlnum .= " AND fk_docdet = '" . $this->fk_docdet . "'";		// fk_docdet is rowid into llx_bank or llx_facturedet or llx_facturefourndet, or ...
+				$sqlnum .= " AND doc_ref = '" . $this->doc_ref . "'";			// ref of source object
 			    $sqlnum .= " AND entity IN (" . getEntity("accountancy", 1) . ")";
 				
 				dol_syslog(get_class($this) . ":: create sqlnum=" . $sqlnum, LOG_DEBUG);
@@ -276,13 +276,13 @@ class BookKeeping extends CommonObject
 						$this->id = $id;
 						$result = 0;
 					} else {
-						$result = - 2;
+						$result = -2;
 						$error ++;
 						$this->errors[] = 'Error Create Error ' . $result . ' lecture ID';
 						dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
 					}
 				} else {
-					$result = - 1;
+					$result = -1;
 					$error ++;
 					$this->errors[] = 'Error ' . $this->db->lasterror();
 					dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
@@ -290,11 +290,11 @@ class BookKeeping extends CommonObject
 			} else {     // Already exists
 				$result = -3;
 				$error++;
-				$this->errors[] = 'Error Transaction for ('.$this->doc_type.', '.$this->doc_ref.', '.$this->fk_docdet.') were already recorded';
-				dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_WARNING);
+				$this->error='BookkeepingRecordAlreadyExists';
+				dol_syslog(__METHOD__ . ' ' . $this->error, LOG_WARNING);
 			}
 		} else {
-			$result = - 5;
+			$result = -5;
 			$error ++;
 			$this->errors[] = 'Error ' . $this->db->lasterror();
 			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
@@ -316,11 +316,9 @@ class BookKeeping extends CommonObject
 		// Commit or rollback
 		if ($error) {
 			$this->db->rollback();
-			
-			return - 1 * $error;
+			return -1 * $error;
 		} else {
 			$this->db->commit();
-			
 			return $result;
 		}
 	}

+ 19 - 18
htdocs/accountancy/class/html.formventilation.class.php

@@ -30,10 +30,10 @@
  */
 class FormVentilation extends Form
 {
-    
+
     private $options_cache = array();
-    
-    
+
+
 	/**
 	 * Return select filter with date of transaction
 	 *
@@ -71,8 +71,8 @@ class FormVentilation extends Form
 	 * @param string   $htmlname           Name of field in html form
 	 * @param int      $showempty          Add an empty field
 	 * @param array    $event              Event options
-	 * @param int      $select_in          selectid value is a aa.rowid (0 default) or aa.account_number (1)
-	 * @param int      $select_out         set value returned by select 0=rowid (default), 1=account_number
+	 * @param int      $select_in          0=selectid value is a aa.rowid (default) or 1=selectid is aa.account_number
+	 * @param int      $select_out         Set value returned by select. 0=rowid (default), 1=account_number
 	 * @param string   $morecss            More css non HTML object
 	 * @param string   $usecache           Key to use to store result into a cache. Next call with same key will reuse the cache.
 	 * @return string                      String with HTML select
@@ -87,21 +87,22 @@ class FormVentilation extends Form
 		if ($usecache && ! empty($this->options_cache[$usecache]))
 		{
 		    $options = $this->options_cache[$usecache];
+		    $selected=$selectid;
 		}
 		else
 		{
     		$trunclength = defined('ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT') ? $conf->global->ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT : 50;
-    
+
     		$sql = "SELECT DISTINCT aa.account_number, aa.label, aa.rowid, aa.fk_pcg_version";
     		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa";
     		$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
     		$sql .= " AND asy.rowid = " . $conf->global->CHARTOFACCOUNTS;
     		$sql .= " AND aa.active = 1";
     		$sql .= " ORDER BY aa.account_number";
-    
+
     		dol_syslog(get_class($this) . "::select_account", LOG_DEBUG);
     		$resql = $this->db->query($sql);
-    
+
     		if (!$resql) {
     			$this->error = "Error " . $this->db->lasterror();
     			dol_syslog(get_class($this) . "::select_account " . $this->error, LOG_ERR);
@@ -109,16 +110,16 @@ class FormVentilation extends Form
     		}
 
     		$out = ajax_combobox($htmlname, $event);
-    
+
     		$selected = 0;
-    		while ($obj = $this->db->fetch_object($resql)) 
+    		while ($obj = $this->db->fetch_object($resql))
     		{
     			$label = length_accountg($obj->account_number) . ' - ' . $obj->label;
     			$label = dol_trunc($label, $trunclength);
-    
+
     			$select_value_in = $obj->rowid;
     			$select_value_out = $obj->rowid;
-    
+
     			// Try to guess if we have found default value
     			if ($select_in == 1) {
     				$select_value_in = $obj->account_number;
@@ -132,19 +133,19 @@ class FormVentilation extends Form
     			    //var_dump("Found ".$selectid." ".$select_value_in);
     				$selected = $select_value_out;
     			}
-    
+
     			$options[$select_value_out] = $label;
     		}
     		$this->db->free($resql);
-    		
+
     		if ($usecache)
     		{
                 $this->options_cache[$usecache] = $options;
     		}
 		}
-		
+
 		$out .= Form::selectarray($htmlname, $options, $selected, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, 1);
-		
+
 		return $out;
 	}
 
@@ -303,7 +304,7 @@ class FormVentilation extends Form
 	function selectyear_accountancy_bookkepping($selected = '', $htmlname = 'yearid', $useempty = 0, $output_format = 'html')
 	{
 	    global $conf;
-	    
+
 		$out_array = array();
 
 		$sql = "SELECT DISTINCT date_format(doc_date,'%Y') as dtyear";
@@ -342,7 +343,7 @@ class FormVentilation extends Form
 	function selectjournal_accountancy_bookkepping($selected = '', $htmlname = 'journalid', $useempty = 0, $output_format = 'html')
 	{
 	    global $conf,$langs;
-	    
+
 		$out_array = array();
 
 		$sql = "SELECT DISTINCT code_journal";

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

@@ -47,7 +47,7 @@ if (! $user->rights->accounting->bind->write)
 	accessforbidden();
 
 // Filter
-$year = $_GET["year"];
+$year = GETPOST("year",'int');
 if ($year == 0) {
 	$year_current = strftime("%Y", time());
 	$year_start = $year_current;
@@ -57,7 +57,7 @@ if ($year == 0) {
 }
 
 // Validate History
-$action = GETPOST('action');
+$action = GETPOST('action','alpha');
 
 
 

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

@@ -200,7 +200,7 @@ $sql .= " AND f.entity IN (" . getEntity("facture", 0) . ")";    // We don't sha
 $sql .= $db->order($sortfield, $sortorder);
 
 // Count total nb of records
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
     $result = $db->query($sql);

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

@@ -215,7 +215,7 @@ $sql .= " AND f.entity IN (" . getEntity("facture", 0) . ")";    // We don't sha
 $sql .= $db->order($sortfield, $sortorder);
 
 // Count total nb of records
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
     $result = $db->query($sql);

+ 33 - 32
htdocs/accountancy/expensereport/index.php

@@ -45,7 +45,7 @@ if (! $user->rights->accounting->bind->write)
 	accessforbidden();
 
 // Filter
-$year = $_GET["year"];
+$year = GETPOST('year', 'int');
 if ($year == 0) {
 	$year_current = strftime("%Y", time());
 	$year_start = $year_current;
@@ -68,9 +68,9 @@ if ($action == 'validatehistory') {
 	$db->begin();
 
 	// First clean corrupted data
-	$sqlclean = "UPDATE " . MAIN_DB_PREFIX . "facturedet as fd";
-	$sqlclean .= " SET fd.fk_code_ventilation = 0";
-	$sqlclean .= ' WHERE fd.fk_code_ventilation NOT IN ';
+	$sqlclean = "UPDATE " . MAIN_DB_PREFIX . "expensereport_det as erd";
+	$sqlclean .= " SET erd.fk_code_ventilation = 0";
+	$sqlclean .= ' WHERE erd.fk_code_ventilation NOT IN ';
 	$sqlclean .= '	(SELECT accnt.rowid ';
 	$sqlclean .= '	FROM ' . MAIN_DB_PREFIX . 'accounting_account as accnt';
 	$sqlclean .= '	INNER JOIN ' . MAIN_DB_PREFIX . 'accounting_system as syst';
@@ -79,18 +79,18 @@ if ($action == 'validatehistory') {
 
 	// Now make the binding
 	if ($db->type == 'pgsql') {
-		$sql1 = "UPDATE " . MAIN_DB_PREFIX . "facture_fourn_det";
+		$sql1 = "UPDATE " . MAIN_DB_PREFIX . "expensereport_det";
 		$sql1 .= " SET fk_code_ventilation = accnt.rowid";
-		$sql1 .= " FROM " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst";
-		$sql1 .= " WHERE " . MAIN_DB_PREFIX . "facture_fourn_det.fk_product = p.rowid  AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=" . $conf->global->CHARTOFACCOUNTS;
-		$sql1 .= " AND accnt.active = 1 AND p.accountancy_code_buy=accnt.account_number";
-		$sql1 .= " AND " . MAIN_DB_PREFIX . "facture_fourn_det.fk_code_ventilation = 0";
+		$sql1 .= " FROM " . MAIN_DB_PREFIX . "c_type_fees as t, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst";
+		$sql1 .= " WHERE " . MAIN_DB_PREFIX . "expensereport_det.fk_c_type_fees = t.id  AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=" . $conf->global->CHARTOFACCOUNTS;
+		$sql1 .= " AND accnt.active = 1 AND t.accountancy_code = accnt.account_number";
+		$sql1 .= " AND " . MAIN_DB_PREFIX . "expensereport_det.fk_code_ventilation = 0";
 	} else {
-		$sql1 = "UPDATE " . MAIN_DB_PREFIX . "facture_fourn_det as fd, " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst";
-		$sql1 .= " SET fd.fk_code_ventilation = accnt.rowid";
-		$sql1 .= " WHERE fd.fk_product = p.rowid AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=" . $conf->global->CHARTOFACCOUNTS;
-		$sql1 .= " AND accnt.active = 1 AND p.accountancy_code_buy=accnt.account_number";
-		$sql1 .= " AND fd.fk_code_ventilation = 0";
+		$sql1 = "UPDATE " . MAIN_DB_PREFIX . "expensereport_det as erd, " . MAIN_DB_PREFIX . "c_type_fees as t, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst";
+		$sql1 .= " SET erd.fk_code_ventilation = accnt.rowid";
+		$sql1 .= " WHERE erd.fk_c_type_fees = t.id AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=" . $conf->global->CHARTOFACCOUNTS;
+		$sql1 .= " AND accnt.active = 1 AND t.accountancy_code=accnt.account_number";
+		$sql1 .= " AND erd.fk_code_ventilation = 0";
 	}
 
 	$resql1 = $db->query($sql1);
@@ -106,9 +106,9 @@ if ($action == 'validatehistory') {
 	$error = 0;
 	$db->begin();
 
-	$sql1 = "UPDATE " . MAIN_DB_PREFIX . "facture_fourn_det as fd";
-	$sql1 .= " SET fd.fk_code_ventilation = 0";
-	$sql1 .= ' WHERE fd.fk_code_ventilation NOT IN ';
+	$sql1 = "UPDATE " . MAIN_DB_PREFIX . "expensereport_det as erd";
+	$sql1 .= " SET erd.fk_code_ventilation = 0";
+	$sql1 .= ' WHERE erd.fk_code_ventilation NOT IN ';
 	$sql1 .= '	(SELECT accnt.rowid ';
 	$sql1 .= '	FROM ' . MAIN_DB_PREFIX . 'accounting_account as accnt';
 	$sql1 .= '	INNER JOIN ' . MAIN_DB_PREFIX . 'accounting_system as syst';
@@ -129,12 +129,12 @@ if ($action == 'validatehistory') {
 	$error = 0;
 	$db->begin();
 
-	$sql1 = "UPDATE " . MAIN_DB_PREFIX . "facture_fourn_det as fd";
-	$sql1.= " SET fd.fk_code_ventilation = 0";
-	$sql1.= " WHERE fd.fk_facture_fourn IN ( SELECT f.rowid FROM " . MAIN_DB_PREFIX . "facture_fourn as f";
-	$sql1.= " WHERE f.datef >= '" . $db->idate(dol_get_first_day($year_current, 1, false)) . "'";
-	$sql1.= " AND f.datef <= '" . $db->idate(dol_get_last_day($year_current, 12, false)) . "'";
-	$sql1.= " AND f.entity IN (" . getEntity("accountancy", 1) . ")";
+	$sql1 = "UPDATE " . MAIN_DB_PREFIX . "expensereport_det as erd";
+	$sql1.= " SET erd.fk_code_ventilation = 0";
+	$sql1.= " WHERE erd.fk_expensereport IN ( SELECT er.rowid FROM " . MAIN_DB_PREFIX . "expensereport as er";
+	$sql1.= " WHERE er.date_debut >= '" . $db->idate(dol_get_first_day($year_current, 1, false)) . "'";
+	$sql1.= " AND er.date_debut <= '" . $db->idate(dol_get_last_day($year_current, 12, false)) . "'";
+	$sql1.= " AND er.entity IN (" . getEntity("accountancy", 1) . ")";
 	$sql1.=")";
 	
 	dol_syslog("htdocs/accountancy/customer/index.php fixaccountancycode", LOG_DEBUG);
@@ -197,16 +197,17 @@ print '<td width="60" align="right"><b>' . $langs->trans("Total") . '</b></td></
 $sql = "SELECT  ".$db->ifsql('aa.account_number IS NULL', "'".$langs->trans('NotMatch')."'", 'aa.account_number') ." AS codecomptable,";
 $sql .= "  " . $db->ifsql('aa.label IS NULL', "'".$langs->trans('NotMatch')."'", 'aa.label') . " AS intitule,";
 for($i = 1; $i <= 12; $i ++) {
-    $sql .= "  SUM(" . $db->ifsql('MONTH(er.date_create)=' . $i, 'erd.total_ht', '0') . ") AS month" . str_pad($i, 2, '0', STR_PAD_LEFT) . ",";
+    $sql .= "  SUM(" . $db->ifsql('MONTH(er.date_debut)=' . $i, 'erd.total_ht', '0') . ") AS month" . str_pad($i, 2, '0', STR_PAD_LEFT) . ",";
 }
 $sql .= " ROUND(SUM(erd.total_ht),2) as total";
 $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "expensereport as er ON er.rowid = erd.fk_expensereport";
 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = erd.fk_code_ventilation";
-$sql .= " WHERE er.date_create >= '" . $db->idate(dol_get_first_day($y, 1, false)) . "'";
-$sql .= " AND er.date_create <= '" . $db->idate(dol_get_last_day($y, 12, false)) . "'";
+$sql .= " WHERE er.date_debut >= '" . $db->idate(dol_get_first_day($y, 1, false)) . "'";
+$sql .= " AND er.date_debut <= '" . $db->idate(dol_get_last_day($y, 12, false)) . "'";
 $sql .= " AND er.fk_statut > 0 ";
 $sql .= " AND er.entity IN (" . getEntity("expensereport", 0) . ")";     // We don't share object for accountancy
+$sql .= " AND aa.account_number IS NULL";
 $sql .= " GROUP BY erd.fk_code_ventilation,aa.account_number,aa.label";
 
 dol_syslog('/accountancy/expensereport/index.php:: sql=' . $sql);
@@ -250,17 +251,17 @@ print '<td width="60" align="right"><b>' . $langs->trans("Total") . '</b></td></
 $sql = "SELECT  ".$db->ifsql('aa.account_number IS NULL', "'".$langs->trans('NotMatch')."'", 'aa.account_number') ." AS codecomptable,";
 $sql .= "  " . $db->ifsql('aa.label IS NULL', "'".$langs->trans('NotMatch')."'", 'aa.label') . " AS intitule,";
 for($i = 1; $i <= 12; $i ++) {
-    $sql .= "  SUM(" . $db->ifsql('MONTH(er.date_create)=' . $i, 'erd.total_ht', '0') . ") AS month" . str_pad($i, 2, '0', STR_PAD_LEFT) . ",";
+    $sql .= "  SUM(" . $db->ifsql('MONTH(er.date_debut)=' . $i, 'erd.total_ht', '0') . ") AS month" . str_pad($i, 2, '0', STR_PAD_LEFT) . ",";
 }
 $sql .= " ROUND(SUM(erd.total_ht),2) as total";
 $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "expensereport as er ON er.rowid = erd.fk_expensereport";
 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = erd.fk_code_ventilation";
-$sql .= " WHERE er.date_create >= '" . $db->idate(dol_get_first_day($y, 1, false)) . "'";
-$sql .= " AND er.date_create <= '" . $db->idate(dol_get_last_day($y, 12, false)) . "'";
+$sql .= " WHERE er.date_debut >= '" . $db->idate(dol_get_first_day($y, 1, false)) . "'";
+$sql .= " AND er.date_debut <= '" . $db->idate(dol_get_last_day($y, 12, false)) . "'";
 $sql .= " AND er.fk_statut > 0 ";
 $sql .= " AND er.entity IN (" . getEntity("expensereport", 0) . ")";     // We don't share object for accountancy
-$sql .= " AND aa.account_number IS NULL";
+$sql .= " AND aa.account_number IS NOT NULL";
 $sql .= " GROUP BY erd.fk_code_ventilation,aa.account_number,aa.label";
 
 dol_syslog('/accountancy/expensereport/index.php:: sql=' . $sql);
@@ -312,8 +313,8 @@ for($i = 1; $i <= 12; $i ++) {
 $sql .= " ROUND(SUM(erd.total_ht),2) as total";
 $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "expensereport as er ON er.rowid = erd.fk_expensereport";
-$sql .= " WHERE er.date_create >= '" . $db->idate(dol_get_first_day($y, 1, false)) . "'";
-$sql .= " AND er.date_create <= '" . $db->idate(dol_get_last_day($y, 12, false)) . "'";
+$sql .= " WHERE er.date_debut >= '" . $db->idate(dol_get_first_day($y, 1, false)) . "'";
+$sql .= " AND er.date_debut <= '" . $db->idate(dol_get_last_day($y, 12, false)) . "'";
 $sql .= " AND er.fk_statut > 0 ";
 $sql .= " AND er.entity IN (" . getEntity("expensereport", 0) . ")";     // We don't share object for accountancy
 

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

@@ -178,7 +178,7 @@ $sql .= " AND er.entity IN (" . getEntity("expensereport", 0) . ")";  // We don'
 $sql .= $db->order($sortfield, $sortorder);
 
 // Count total nb of records
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
     $result = $db->query($sql);

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

@@ -208,7 +208,7 @@ $sql .= " AND er.entity IN (" . getEntity("expensereport", 0) . ")";  // We don'
 $sql .= $db->order($sortfield, $sortorder);
 
 // Count total nb of records
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
     $result = $db->query($sql);

+ 21 - 16
htdocs/accountancy/index.php

@@ -1,5 +1,6 @@
 <?php
 /* Copyright (C) 2016     Laurent Destailleur      <eldy@users.sourceforge.net>
+ * Copyright (C) 2016     Alexandre Spangaro       <aspangaro@zendsi.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,9 +37,6 @@ $langs->load("accountancy");
 if ($user->societe_id > 0)
 	accessforbidden();
 
-// Validate History
-$action = GETPOST('action');
-
 $langs->load("admin");
 $langs->load("dict");
 $langs->load("bills");
@@ -73,11 +71,11 @@ print "<br>\n";
 
 // STEPS
 $step++;
-print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Pcg_version").'</strong>');
+print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Pcg_version").'</strong>');
 print "<br>\n";
 print "<br>\n";
 $step++;
-print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Chartofaccounts").'</strong>');
+print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Chartofaccounts").'</strong>');
 print "<br>\n";
 print "<br>\n";
 
@@ -86,16 +84,16 @@ print "<br>\n";
 print "<br>\n";
 
 $step++;
-print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescMisc", $step, '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>')."<br>\n";
+print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescMisc", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>')."<br>\n";
 print "<br>\n";
 $step++;
-$textlink = '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuVatAccounts").'</strong>';
+$textlink = '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuVatAccounts").'</strong>';
 print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescVat", $step, $textlink);
 print "<br>\n";
 print "<br>\n";
 if (! empty($conf->tax->enabled))
 {
-    $textlink = '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuTaxAccounts").'</strong>';
+    $textlink = '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuTaxAccounts").'</strong>';
     $step++;
     print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescContrib", $step, $textlink);
     print "<br>\n";
@@ -104,7 +102,7 @@ if (! empty($conf->tax->enabled))
 /*if (! empty($conf->salaries->enabled))
 {
     $step++;
-    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescSal", $step, '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
+    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescSal", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
     // htdocs/admin/salaries.php
     print "<br>\n";
     print "<br>\n";
@@ -112,14 +110,14 @@ if (! empty($conf->tax->enabled))
 if (! empty($conf->expensereport->enabled))  // TODO Move this in the default account page because this is only one accounting account per purpose, not several.
 {
     $step++;
-    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'</strong>');
+    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'</strong>');
     print "<br>\n";
     print "<br>\n";
 }
 if (! empty($conf->loan->enabled))  // TODO Move this in the default account page because this is only one accounting account per purpose, not several.
 {
     $step++;
-    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescLoan", $step, '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuLoanAccounts").'</strong>');
+    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescLoan", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuSpecialExpenses").'-'.$langs->transnoentitiesnoconv("Loans").'</strong> '.$langs->transnoentitiesnoconv("or").' <strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
     print "<br>\n";
     print "<br>\n";
 }
@@ -127,7 +125,7 @@ if (! empty($conf->loan->enabled))  // TODO Move this in the default account pag
 if (! empty($conf->don->enabled))
 {
     $step++;
-    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDonation", $step, '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDonationAccounts").'</strong>');
+    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDonation", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDonationAccounts").'</strong>');
     print "<br>\n";
     print "<br>\n";
 }*/
@@ -138,7 +136,7 @@ print "<br>\n";
 print "<br>\n";
 
 $step++;
-print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("ProductsBinding").'</strong>')."<br>\n";
+print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("ProductsBinding").'</strong>')."<br>\n";
 print "<br>\n";
 
 print "<br>\n";
@@ -148,14 +146,21 @@ print "<br>\n";
 $step = 0;
 
 $step++;
-print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescCustomer", $step, '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy")."-".$langs->transnoentitiesnoconv("CustomersVentilation").'</strong>')."<br>\n";
+print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescCustomer", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("CustomersVentilation").'</strong>')."<br>\n";
 print "<br>\n";
+
 $step++;
-print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescSupplier", $step, '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy")."-".$langs->transnoentitiesnoconv("SuppliersVentilation").'</strong>')."<br>\n";
+print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescSupplier", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("SuppliersVentilation").'</strong>')."<br>\n";
 print "<br>\n";
+
 $step++;
-print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescWriteRecords", $step, '<strong>'.$langs->transnoentitiesnoconv("Financial").'-'.$langs->transnoentitiesnoconv("Accountancy")."-".$langs->transnoentitiesnoconv("SuppliersVentilation").'</strong>')."<br>\n";
+print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</strong>')."<br>\n";
 print "<br>\n";
+
+$step++;
+print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescWriteRecords", $step)."<br>\n";
+print "<br>\n";
+
 $step++;
 print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescAnalyze", $step)."<br>\n";
 print "<br>\n";

+ 34 - 23
htdocs/accountancy/journal/bankjournal.php

@@ -153,7 +153,8 @@ if ($result) {
 	// one line for bank jounral = tabbq
 	// one line for thirdparty journal = tabtp
 	$i = 0;
-	while ( $i < $num ) {
+	while ( $i < $num ) 
+	{
 		$obj = $db->fetch_object($result);
 
 		// Set accountancy code (for bank and thirdparty)
@@ -314,7 +315,8 @@ if (! $error && $action == 'writebookkeeping') {
 		if (! $errorforline)
 		{
 		    // Line into bank account
-    		foreach ( $tabbq[$key] as $k => $mt ) {
+    		foreach ( $tabbq[$key] as $k => $mt ) 
+    		{
     			$bookkeeping = new BookKeeping($db);
     			$bookkeeping->doc_date = $val["date"];
     			$bookkeeping->doc_ref = $val["ref"];
@@ -363,9 +365,18 @@ if (! $error && $action == 'writebookkeeping') {
     
     			$result = $bookkeeping->create($user);
     			if ($result < 0) {
-    				$error++;
-    				$errorforline++;
-    				setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
+    				if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists')	// Already exists
+    				{
+    					$error++;
+    					$errorforline++;
+    					//setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->doc_ref.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
+    				}
+    				else
+    				{
+	    				$error++;
+	    				$errorforline++;
+	    				setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
+    				}
     			}
     		}
 		}
@@ -463,16 +474,6 @@ if (! $error && $action == 'writebookkeeping') {
 	$action = '';
 }
 
-
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-
 // Export
 if ($action == 'export_csv') {
 	$sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
@@ -633,6 +634,15 @@ if ($action == 'export_csv') {
 	}
 }
 
+
+
+
+/*
+ * View
+ */
+
+$form = new Form($db);
+
 if (empty($action) || $action == 'view') {
 	$invoicestatic = new Facture($db);
 	$invoicesupplierstatic = new FactureFournisseur($db);
@@ -689,7 +699,8 @@ if (empty($action) || $action == 'view') {
 	print "<td>" . $langs->trans("AccountAccounting") . "</td>";
 	print "<td>" . $langs->trans("Type") . "</td>";
 	print "<td>" . $langs->trans("PaymentMode") . "</td>";
-	print "<td align='right'>" . $langs->trans("Debit") . "</td><td align='right'>" . $langs->trans("Credit") . "</td>";
+	print "<td align='right'>" . $langs->trans("Debit") . "</td>";
+	print "<td align='right'>" . $langs->trans("Credit") . "</td>";
 	print "</tr>\n";
 
 	$var = true;
@@ -697,7 +708,7 @@ if (empty($action) || $action == 'view') {
 
 	foreach ( $tabpay as $key => $val ) {      // $key is rowid in llx_bank
 		$date = dol_print_date($db->jdate($val["date"]), 'day');
-		
+
 		$reflabel = $val["ref"];
 		if ($reflabel == '(SupplierInvoicePayment)') {
 			$reflabel = $langs->trans('Supplier');
@@ -721,7 +732,7 @@ if (empty($action) || $action == 'view') {
 		    $sqlmid = 'SELECT payfac.fk_facture as id';
 		    $sqlmid .= " FROM ".MAIN_DB_PREFIX."paiement_facture as payfac";
 		    $sqlmid .= " WHERE payfac.fk_paiement=" . $val["paymentid"];
-		    dol_syslog("accountancy/journal/bankjournal.php:: sqlmid=" . $sqlmid, LOG_DEBUG);
+		    dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG);
 		    $resultmid = $db->query($sqlmid);
 		    if ($resultmid) {
 		        $objmid = $db->fetch_object($resultmid);
@@ -735,7 +746,7 @@ if (empty($action) || $action == 'view') {
 		    $sqlmid = 'SELECT payfac.fk_facturefourn as id';
 		    $sqlmid .= " FROM " . MAIN_DB_PREFIX . "paiementfourn_facturefourn as payfac";
 		    $sqlmid .= " WHERE payfac.fk_paiementfourn=" . $val["paymentsupplierid"];
-		    dol_syslog("accountancy/journal/bankjournal.php:: sqlmid=" . $sqlmid, LOG_DEBUG);
+		    dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG);
 		    $resultmid = $db->query($sqlmid);
 		    if ($resultmid) {
 		        $objmid = $db->fetch_object($resultmid);
@@ -744,14 +755,14 @@ if (empty($action) || $action == 'view') {
 		    }
 		    else dol_print_error($db);
 		}
-		
+
 
 		/*$invoicestatic->id = $key;
 		$invoicestatic->ref = $val["ref"];
 		$invoicestatic->type = $val["type"];*/
 		// Bank
-		foreach ( $tabbq[$key] as $k => $mt ) {
-
+		foreach ( $tabbq[$key] as $k => $mt ) 
+		{
 		    print "<tr " . $bc[$var] . ">";
 		    print "<td><!-- Bank bank.rowid=".$key."--></td>";
 		    print "<td>" . $date . "</td>";
@@ -809,7 +820,7 @@ if (empty($action) || $action == 'view') {
         		{
         		    print '<span class="error">'.$langs->trans("WaitAccountNotDefined").'</span>';
         		}
-				else print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . 
+				else print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE); 
 				print "</td>";
 				print "<td>" . $reflabel . "</td>";
 				print "<td>&nbsp;</td>";

+ 4 - 4
htdocs/accountancy/journal/expensereportsjournal.php

@@ -187,11 +187,11 @@ if ($action == 'writebookkeeping') {
 		// Fees
 		foreach ( $tabht[$key] as $k => $mt ) {
 			$accountingaccount = new AccountingAccount($db);
-			$accountingaccount->fetch(null, $k);
+			$accountingaccount->fetch(null, $k, true);
 			if ($mt) {
 				// get compte id and label
 				$accountingaccount = new AccountingAccount($db);
-				if ($accountingaccount->fetch(null, $k)) {
+				if ($accountingaccount->fetch(null, $k, true)) {
 					$bookkeeping = new BookKeeping($db);
 					$bookkeeping->doc_date = $val["date"];
 					$bookkeeping->doc_ref = $val["ref"];
@@ -355,7 +355,7 @@ if ($action == 'export_csv') {
 			// Fees
 			foreach ( $tabht[$key] as $k => $mt ) {
 				$accountingaccount = new AccountingAccount($db);
-				$accountingaccount->fetch(null, $k);
+				$accountingaccount->fetch(null, $k, true);
 				if ($mt) {
 					print '"' . $date . '"' . $sep;
 					print '"' . $val["ref"] . '"' . $sep;
@@ -464,7 +464,7 @@ if (empty($action) || $action == 'view') {
 		// Fees
 		foreach ( $tabht[$key] as $k => $mt ) {
 			$accountingaccount = new AccountingAccount($db);
-			$accountingaccount->fetch(null, $k);
+			$accountingaccount->fetch(null, $k, true);
 
 			if ($mt) {
 				print "<tr " . $bc[$var] . " >";

+ 4 - 4
htdocs/accountancy/journal/purchasesjournal.php

@@ -219,11 +219,11 @@ if ($action == 'writebookkeeping') {
 		// Product / Service
 		foreach ( $tabht[$key] as $k => $mt ) {
 			$accountingaccount = new AccountingAccount($db);
-			$accountingaccount->fetch(null, $k);
+			$accountingaccount->fetch(null, $k, true);
 			if ($mt) {
 				// get compte id and label
 				$accountingaccount = new AccountingAccount($db);
-				if ($accountingaccount->fetch(null, $k)) {
+				if ($accountingaccount->fetch(null, $k, true)) {
 					$bookkeeping = new BookKeeping($db);
 					$bookkeeping->doc_date = $val["date"];
 					$bookkeeping->doc_ref = $val["ref"];
@@ -398,7 +398,7 @@ if ($action == 'export_csv') {
 			// Product / Service
 			foreach ( $tabht[$key] as $k => $mt ) {
 				$accountingaccount = new AccountingAccount($db);
-				$accountingaccount->fetch(null, $k);
+				$accountingaccount->fetch(null, $k, true);
 				if ($mt) {
 					print '"' . $date . '"' . $sep;
 					print '"' . $val["ref"] . '"' . $sep;
@@ -518,7 +518,7 @@ if (empty($action) || $action == 'view') {
 		// Product / Service
 		foreach ( $tabht[$key] as $k => $mt ) {
 			$accountingaccount = new AccountingAccount($db);
-			$accountingaccount->fetch(null, $k);
+			$accountingaccount->fetch(null, $k, true);
 
 			if ($mt) {
 				print "<tr " . $bc[$var] . " >";

+ 4 - 4
htdocs/accountancy/journal/sellsjournal.php

@@ -243,7 +243,7 @@ if ($action == 'writebookkeeping') {
             if ($mt) {
                 // get compte id and label
                 $accountingaccount = new AccountingAccount($db);
-                if ($accountingaccount->fetch(null, $k)) {
+                if ($accountingaccount->fetch(null, $k, true)) {
                     $bookkeeping = new BookKeeping($db);
                     $bookkeeping->doc_date = $val["date"];
                     $bookkeeping->doc_ref = $val["ref"];
@@ -375,7 +375,7 @@ if ($action == 'export_csv') {
             // Product / Service
             foreach ( $tabht[$key] as $k => $mt ) {
                 $accountingaccount_static = new AccountingAccount($db);
-                if ($accountingaccount_static->fetch(null, $k)) {
+                if ($accountingaccount_static->fetch(null, $k, true)) {
                     print $date . $sep;
                     print $sell_journal . $sep;
                     print length_accountg(html_entity_decode($k)) . $sep;
@@ -429,7 +429,7 @@ if ($action == 'export_csv') {
             // Product / Service
             foreach ( $tabht[$key] as $k => $mt ) {
                 $accountingaccount = new AccountingAccount($db);
-                $accountingaccount->fetch(null, $k);
+                $accountingaccount->fetch(null, $k, true);
 
                 if ($mt) {
                     print '"' . $date . '"' . $sep;
@@ -559,7 +559,7 @@ if (empty($action) || $action == 'view') {
 		// Product / Service
 		foreach ( $tabht[$key] as $k => $mt ) {
 			$accountingaccount = new AccountingAccount($db);
-			$accountingaccount->fetch(null, $k);
+			$accountingaccount->fetch(null, $k, true);
 
 			if ($mt) {
 				print "<tr " . $bc[$var] . ">";

+ 11 - 4
htdocs/accountancy/report/result.php

@@ -43,7 +43,7 @@ $rowid = GETPOST('rowid', 'int');
 $cancel = GETPOST('cancel');
 
 // Filter
-$year = $_GET["year"];
+$year = GETPOST('year','int');
 if ($year == 0) {
 	$year_current = strftime("%Y", time());
 	$year_start = $year_current;
@@ -64,9 +64,11 @@ if (! $user->rights->accounting->comptarapport->lire)
 
 $AccCat = new AccountancyCategory($db);
 
+
 /*
  * View
  */
+
 llxheader('', $langs->trans('ReportInOut'));
 
 $formaccounting = new FormAccounting($db);
@@ -75,9 +77,12 @@ $form = new Form($db);
 $textprevyear = '<a href="' . $_SERVER["PHP_SELF"] . '?year=' . ($year_current - 1) . '">' . img_previous() . '</a>';
 $textnextyear = '&nbsp;<a href="' . $_SERVER["PHP_SELF"] . '?year=' . ($year_current + 1) . '">' . img_next() . '</a>';
 
-print load_fiche_titre($langs->trans('ReportInOut') . " " . $textprevyear . " " . $langs->trans("Year") . " " . $year_start . " " . $textnextyear, '', 'title_accountancy');
+print load_fiche_titre($langs->trans('ReportInOut'), $textprevyear . " " . $langs->trans("Year") . " " . $year_start . " " . $textnextyear, 'title_accountancy');
+
+$moreforfilter='';
 
-print '<table class="border" width="100%">';
+print '<div class="div-table-responsive">';
+print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
 
 $months = array( $langs->trans("JanuaryMin"),
 				$langs->trans("FebruaryMin"),
@@ -93,7 +98,8 @@ $months = array( $langs->trans("JanuaryMin"),
 				$langs->trans("DecemberMin"),
 			);
 
-print '<tr class="liste_titre"><th class="liste_titre">'.$langs->trans("Account").'</th>';
+print '<tr class="liste_titre">';
+print '<th class="liste_titre">'.$langs->trans("Account").'</th>';
 print '<th class="liste_titre">'.$langs->trans("Description").'</th>';
 print '<th class="liste_titre" align="center">N-1</th>';
 print '<th class="liste_titre" align="center">'.$langs->trans("NReal").'</th>';
@@ -257,6 +263,7 @@ if (!empty($cats))
 }
 
 print "</table>";
+print '</div>';
 
 llxFooter();
 $db->close();

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

@@ -45,7 +45,7 @@ if (! $user->rights->accounting->bind->write)
 	accessforbidden();
 
 // Filter
-$year = $_GET["year"];
+$year = GETPOST("year",'int');
 if ($year == 0) {
 	$year_current = strftime("%Y", time());
 	$year_start = $year_current;
@@ -55,7 +55,7 @@ if ($year == 0) {
 }
 
 // Validate History
-$action = GETPOST('action');
+$action = GETPOST('action', 'alpha');
 
 
 /*

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

@@ -182,7 +182,7 @@ $sql .= " AND f.entity IN (" . getEntity("facture_fourn", 0) . ")";  // We don't
 $sql .= $db->order($sortfield, $sortorder);
 
 // Count total nb of records
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
     $result = $db->query($sql);

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

@@ -217,7 +217,7 @@ $sql .= " AND f.entity IN (" . getEntity("facture_fourn", 0) . ")";  // We don't
 $sql .= $db->order($sortfield, $sortorder);
 
 // Count total nb of records
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
     $result = $db->query($sql);

+ 16 - 16
htdocs/adherents/card.php

@@ -822,7 +822,7 @@ else
 		// Login
 		if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
 		{
-			print '<tr><td><span class="fieldrequired">'.$langs->trans("Login").' / '.$langs->trans("Id").'</span></td><td><input type="text" name="member_login" size="40" value="'.(isset($_POST["member_login"])?$_POST["member_login"]:$object->login).'"></td></tr>';
+			print '<tr><td><span class="fieldrequired">'.$langs->trans("Login").' / '.$langs->trans("Id").'</span></td><td><input type="text" name="member_login" class="maxwidth200" value="'.(isset($_POST["member_login"])?GETPOST("member_login", 'alpha', 2):$object->login).'"></td></tr>';
 		}
 
 		// Type
@@ -1066,7 +1066,7 @@ else
 		// Login
 		if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
 		{
-			print '<tr><td><span class="fieldrequired">'.$langs->trans("Login").' / '.$langs->trans("Id").'</span></td><td colspan="2"><input type="text" name="login" size="30" value="'.(isset($_POST["login"])?$_POST["login"]:$object->login).'"></td></tr>';
+			print '<tr><td><span class="fieldrequired">'.$langs->trans("Login").' / '.$langs->trans("Id").'</span></td><td colspan="2"><input type="text" name="login" class="maxwidth200" value="'.(isset($_POST["login"])?GETPOST("login",'alpha',2):$object->login).'"></td></tr>';
 		}
 
 		// Morphy
@@ -1090,7 +1090,7 @@ else
 		print "</td></tr>";
 
 		// Company
-		print '<tr><td id="tdcompany">'.$langs->trans("Company").'</td><td><input type="text" name="societe" size="40" value="'.(isset($_POST["societe"])?$_POST["societe"]:$object->societe).'"></td></tr>';
+		print '<tr><td id="tdcompany">'.$langs->trans("Company").'</td><td><input type="text" name="societe" size="40" value="'.(isset($_POST["societe"])?GETPOST("societe",'',2):$object->societe).'"></td></tr>';
 
 		// Civility
 		print '<tr><td>'.$langs->trans("UserTitle").'</td><td>';
@@ -1099,11 +1099,11 @@ else
 		print '</tr>';
 
 		// Lastname
-		print '<tr><td id="tdlastname">'.$langs->trans("Lastname").'</td><td><input type="text" name="lastname" size="40" value="'.(isset($_POST["lastname"])?$_POST["lastname"]:$object->lastname).'"></td>';
+		print '<tr><td id="tdlastname">'.$langs->trans("Lastname").'</td><td><input type="text" name="lastname" size="40" value="'.(isset($_POST["lastname"])?GETPOST("lastname",'',2):$object->lastname).'"></td>';
 		print '</tr>';
 
 		// Firstname
-		print '<tr><td id="tdfirstname">'.$langs->trans("Firstname").'</td><td><input type="text" name="firstname" size="40" value="'.(isset($_POST["firstname"])?$_POST["firstname"]:$object->firstname).'"></td>';
+		print '<tr><td id="tdfirstname">'.$langs->trans("Firstname").'</td><td><input type="text" name="firstname" size="40" value="'.(isset($_POST["firstname"])?GETPOST("firstname",'',3):$object->firstname).'"></td>';
 		print '</tr>';
 
 		// Photo
@@ -1122,24 +1122,24 @@ else
 		print '</td></tr>';
 
 		// EMail
-		print '<tr><td>'.($conf->global->ADHERENT_MAIL_REQUIRED?'<span class="fieldrequired">':'').$langs->trans("EMail").($conf->global->ADHERENT_MAIL_REQUIRED?'</span>':'').'</td><td><input type="text" name="email" size="40" value="'.(isset($_POST["email"])?$_POST["email"]:$object->email).'"></td></tr>';
+		print '<tr><td>'.($conf->global->ADHERENT_MAIL_REQUIRED?'<span class="fieldrequired">':'').$langs->trans("EMail").($conf->global->ADHERENT_MAIL_REQUIRED?'</span>':'').'</td><td><input type="text" name="email" size="40" value="'.(isset($_POST["email"])?GETPOST("email",'',2):$object->email).'"></td></tr>';
 
 		// Password
 		if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
 		{
-			print '<tr><td class="fieldrequired">'.$langs->trans("Password").'</td><td><input type="password" name="pass" size="30" value="'.(isset($_POST["pass"])?$_POST["pass"]:$object->pass).'"></td></tr>';
+			print '<tr><td class="fieldrequired">'.$langs->trans("Password").'</td><td><input type="password" name="pass" class="maxwdith200" value="'.(isset($_POST["pass"])?GETPOST("pass",'',2):$object->pass).'"></td></tr>';
 		}
 
 		// Address
 		print '<tr><td>'.$langs->trans("Address").'</td><td>';
-		print '<textarea name="address" wrap="soft" class="quatrevingtpercent" rows="2">'.(isset($_POST["address"])?$_POST["address"]:$object->address).'</textarea>';
+		print '<textarea name="address" wrap="soft" class="quatrevingtpercent" rows="2">'.(isset($_POST["address"])?GETPOST("address",'',2):$object->address).'</textarea>';
 		print '</td></tr>';
 
 		// Zip / Town
 		print '<tr><td>'.$langs->trans("Zip").' / '.$langs->trans("Town").'</td><td>';
-		print $formcompany->select_ziptown((isset($_POST["zipcode"])?$_POST["zipcode"]:$object->zip),'zipcode',array('town','selectcountry_id','state_id'),6);
+		print $formcompany->select_ziptown((isset($_POST["zipcode"])?GETPOST("zipcode",'',2):$object->zip),'zipcode',array('town','selectcountry_id','state_id'),6);
 		print ' ';
-		print $formcompany->select_ziptown((isset($_POST["town"])?$_POST["town"]:$object->town),'town',array('zipcode','selectcountry_id','state_id'));
+		print $formcompany->select_ziptown((isset($_POST["town"])?GETPOST("town",'',2):$object->town),'town',array('zipcode','selectcountry_id','state_id'));
 		print '</td></tr>';
 
 		// Country
@@ -1153,23 +1153,23 @@ else
 		if (empty($conf->global->MEMBER_DISABLE_STATE))
 		{
 			print '<tr><td>'.$langs->trans('State').'</td><td>';
-			print $formcompany->select_state($object->state_id,isset($_POST["country_id"])?$_POST["country_id"]:$object->country_id);
+			print $formcompany->select_state($object->state_id,isset($_POST["country_id"])?GETPOST("country_id"):$object->country_id);
 			print '</td></tr>';
 		}
 
 		// Pro phone
-		print '<tr><td>'.$langs->trans("PhonePro").'</td><td><input type="text" name="phone" size="20" value="'.(isset($_POST["phone"])?$_POST["phone"]:$object->phone).'"></td></tr>';
+		print '<tr><td>'.$langs->trans("PhonePro").'</td><td><input type="text" name="phone" size="20" value="'.(isset($_POST["phone"])?GETPOST("phone"):$object->phone).'"></td></tr>';
 
 		// Personal phone
-		print '<tr><td>'.$langs->trans("PhonePerso").'</td><td><input type="text" name="phone_perso" size="20" value="'.(isset($_POST["phone_perso"])?$_POST["phone_perso"]:$object->phone_perso).'"></td></tr>';
+		print '<tr><td>'.$langs->trans("PhonePerso").'</td><td><input type="text" name="phone_perso" size="20" value="'.(isset($_POST["phone_perso"])?GETPOST("phone_perso"):$object->phone_perso).'"></td></tr>';
 
 		// Mobile phone
-		print '<tr><td>'.$langs->trans("PhoneMobile").'</td><td><input type="text" name="phone_mobile" size="20" value="'.(isset($_POST["phone_mobile"])?$_POST["phone_mobile"]:$object->phone_mobile).'"></td></tr>';
+		print '<tr><td>'.$langs->trans("PhoneMobile").'</td><td><input type="text" name="phone_mobile" size="20" value="'.(isset($_POST["phone_mobile"])?GETPOST("phone_mobile"):$object->phone_mobile).'"></td></tr>';
 
 	    // Skype
 	    if (! empty($conf->skype->enabled))
 	    {
-			    print '<tr><td>'.$langs->trans("Skype").'</td><td><input type="text" name="skype" size="40" value="'.(isset($_POST["skype"])?$_POST["skype"]:$object->skype).'"></td></tr>';
+			    print '<tr><td>'.$langs->trans("Skype").'</td><td><input type="text" name="skype" size="40" value="'.(isset($_POST["skype"])?GETPOST("skype"):$object->skype).'"></td></tr>';
 	    }
 
 		// Birthday
@@ -1179,7 +1179,7 @@ else
 
 		// Public profil
 		print "<tr><td>".$langs->trans("Public")."</td><td>\n";
-		print $form->selectyesno("public",(isset($_POST["public"])?$_POST["public"]:$object->public),1);
+		print $form->selectyesno("public",(isset($_POST["public"])?GETPOST("public",'',2):$object->public),1);
 		print "</td></tr>\n";
 
 		// Categories

+ 9 - 4
htdocs/adherents/class/adherent.class.php

@@ -83,6 +83,9 @@ class Adherent extends CommonObject
     var $datevalid;
     var $birth;
 
+    var $note_public;
+    var $note_private;
+
     var $typeid;			// Id type adherent
     var $type;				// Libelle type adherent
     var $need_subscription;
@@ -410,7 +413,9 @@ class Adherent extends CommonObject
 		$this->country_id=($this->country_id > 0?$this->country_id:$this->country_id);
 		$this->state_id=($this->state_id > 0?$this->state_id:$this->state_id);
 		if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname=ucwords(trim($this->lastname));
-        if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname=ucwords(trim($this->firstname));
+		if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname=ucwords(trim($this->firstname));
+		$this->note_public=($this->note_public?$this->note_public:$this->note_public);
+		$this->note_private=($this->note_private?$this->note_private:$this->note_private);
 
         // Check parameters
         if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email))
@@ -440,7 +445,7 @@ class Adherent extends CommonObject
         $sql.= ", phone_perso=" .($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null");
         $sql.= ", phone_mobile=" .($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null");
         $sql.= ", note_private=" .($this->note_private?"'".$this->db->escape($this->note_private)."'":"null");
-        $sql.= ", note_public=" .($this->note_private?"'".$this->db->escape($this->note_public)."'":"null");
+        $sql.= ", note_public=" .($this->note_public?"'".$this->db->escape($this->note_public)."'":"null");
         $sql.= ", photo="   .($this->photo?"'".$this->photo."'":"null");
         $sql.= ", public='".$this->public."'";
         $sql.= ", statut="  .$this->statut;
@@ -1146,11 +1151,11 @@ class Adherent extends CommonObject
                 $this->birth			= $this->db->jdate($obj->birthday);
 
                 $this->note_private		= $obj->note_private;
-                $this->note_public      	= $obj->note_public;
+                $this->note_public		= $obj->note_public;
                 $this->morphy			= $obj->morphy;
 
                 $this->typeid			= $obj->fk_adherent_type;
-                $this->type			= $obj->type;
+                $this->type				= $obj->type;
                 $this->need_subscription 	= $obj->subscription;
 
                 $this->user_id			= $obj->user_id;

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

@@ -35,9 +35,10 @@ class AdherentType extends CommonObject
 {
 	public $table_element = 'adherent_type';
 	public $element = 'adherent_type';
-
+	public $picto = 'group';
+	
 	/** @var string Label */
-	public $libelle;
+	public $label;
 	/**
 	 * @var bool
 	 * @deprecated Use subscription
@@ -199,7 +200,7 @@ class AdherentType extends CommonObject
      */
     function fetch($rowid)
     {
-        $sql = "SELECT d.rowid, d.libelle, d.statut, d.subscription, d.mail_valid, d.note, d.vote";
+        $sql = "SELECT d.rowid, d.libelle as label, d.statut, d.subscription, d.mail_valid, d.note, d.vote";
         $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d";
         $sql .= " WHERE d.rowid = ".$rowid;
 
@@ -214,7 +215,8 @@ class AdherentType extends CommonObject
 
                 $this->id             = $obj->rowid;
                 $this->ref            = $obj->rowid;
-                $this->libelle        = $obj->libelle;
+                $this->label          = $obj->label;
+                $this->libelle        = $obj->label;	// For backward compatibility
                 $this->statut         = $obj->statut;
                 $this->subscription   = $obj->subscription;
                 $this->mail_valid     = $obj->mail_valid;
@@ -296,6 +298,16 @@ class AdherentType extends CommonObject
     }
 
 
+    /**
+     *     getLibStatut
+     *
+     *     @return string     Return status of a type of member
+     */
+    function getLibStatut()
+    {
+    	return '';
+    }
+    
     /**
      *     getMailOnValid
      *

+ 3 - 6
htdocs/adherents/class/api_members.class.php

@@ -143,7 +143,7 @@ class Members extends DolibarrApi
             }
         }
         else {
-            throw new RestException(503, 'Error when retrieve member list : '.$member->error);
+            throw new RestException(503, 'Error when retrieve member list : '.$db->lasterror());
         }
         if( ! count($obj_ret)) {
             throw new RestException(404, 'No member found');
@@ -170,8 +170,8 @@ class Members extends DolibarrApi
         foreach($request_data as $field => $value) {
             $member->$field = $value;
         }
-        if($member->create(DolibarrApiAccess::$user) < 0) {
-            throw new RestException(503, 'Error when create member : '.$member->error);
+        if ($member->create(DolibarrApiAccess::$user) < 0) {
+            throw new RestException(500, 'Error creating member', array_merge(array($member->error), $member->errors));
         }
         return $member->id;
     }
@@ -289,9 +289,6 @@ class Members extends DolibarrApi
      *
      * @param   object  $object    Object to clean
      * @return    array    Array of cleaned object properties
-     *
-     * @todo use an array for properties to clean
-     *
      */
     function _cleanObjectDatas($object) {
 

+ 3 - 3
htdocs/adherents/class/api_subscriptions.class.php

@@ -135,7 +135,7 @@ class Subscriptions extends DolibarrApi
             }
         }
         else {
-            throw new RestException(503, 'Error when retrieve subscription list : '.$subscription->error);
+            throw new RestException(503, 'Error when retrieve subscription list : '.$db->lasterror());
         }
         if( ! count($obj_ret)) {
             throw new RestException(404, 'No Subscription found');
@@ -162,8 +162,8 @@ class Subscriptions extends DolibarrApi
         foreach($request_data as $field => $value) {
             $subscription->$field = $value;
         }
-        if($subscription->create(DolibarrApiAccess::$user) < 0) {
-            throw new RestException(503, 'Error when create subscription : '.$subscription->error);
+        if ($subscription->create(DolibarrApiAccess::$user) < 0) {
+            throw new RestException(500, 'Error when creating subscription', array_merge(array($subscription->error), $subscription->errors));
         }
         return $subscription->id;
     }

+ 26 - 1
htdocs/adherents/class/subscription.class.php

@@ -32,7 +32,8 @@ class Subscription extends CommonObject
 {
 	public $element='subscription';
 	public $table_element='subscription';
-
+    public $picto='payment';
+    
 	var $datec;				// Date creation
 	var $datem;				// Date modification
 	var $dateh;				// Subscription start date (date subscription)
@@ -277,6 +278,30 @@ class Subscription extends CommonObject
 	}
 
 
+	/**
+	 *  Retourne le libelle du statut d'une adhesion
+	 *
+	 *  @param	int		$mode       0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
+	 *  @return string				Label
+	 */
+	function getLibStatut($mode=0)
+	{
+	    return '';
+	}
+	
+	/**
+	 *  Renvoi le libelle d'un statut donne
+	 *
+	 *  @param	int			$statut      			Id statut
+	 *  @return string      						Label
+	 */
+	function LibStatut($statut)
+	{
+	    global $langs;
+	    $langs->load("members");
+	    return '';
+	}
+	
     /**
      *  Load information of the subscription object
 	 *

+ 17 - 17
htdocs/adherents/list.php

@@ -250,7 +250,7 @@ $sql.=$hookmanager->resPrint;
 $sql.= $db->order($sortfield,$sortorder);
 
 // Count total nb of records with no order and no limits
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
 	$resql = $db->query($sql);
@@ -395,8 +395,8 @@ if (! empty($arrayfields['d.town']['checked']))           print_liste_field_titr
 if (! empty($arrayfields['state.nom']['checked']))        print_liste_field_titre($langs->trans("StateShort"),$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder);
 if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($langs->trans("Country"),$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder);
 if (! empty($arrayfields['d.phone']['checked']))          print_liste_field_titre($arrayfields['d.phone']['label'],$_SERVER["PHP_SELF"],'d.phone','',$param,'',$sortfield,$sortorder);
-if (! empty($arrayfields['d.phone_perso']['checked']))          print_liste_field_titre($arrayfields['d.phone_perso']['label'],$_SERVER["PHP_SELF"],'d.phone_perso','',$param,'',$sortfield,$sortorder);
-if (! empty($arrayfields['d.phone_mobile']['checked']))          print_liste_field_titre($arrayfields['d.phone_mobile']['label'],$_SERVER["PHP_SELF"],'d.phone_mobile','',$param,'',$sortfield,$sortorder);
+if (! empty($arrayfields['d.phone_perso']['checked']))    print_liste_field_titre($arrayfields['d.phone_perso']['label'],$_SERVER["PHP_SELF"],'d.phone_perso','',$param,'',$sortfield,$sortorder);
+if (! empty($arrayfields['d.phone_mobile']['checked']))   print_liste_field_titre($arrayfields['d.phone_mobile']['label'],$_SERVER["PHP_SELF"],'d.phone_mobile','',$param,'',$sortfield,$sortorder);
 if (! empty($arrayfields['d.email']['checked']))          print_liste_field_titre($arrayfields['d.email']['label'],$_SERVER["PHP_SELF"],'d.email','',$param,'',$sortfield,$sortorder);
 if (! empty($arrayfields['d.datefin']['checked']))        print_liste_field_titre($arrayfields['d.datefin']['label'],$_SERVER["PHP_SELF"],'d.datefin','',$param,'align="center"',$sortfield,$sortorder);
 // Extra fields
@@ -434,32 +434,32 @@ if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER))
 if (! empty($arrayfields['d.ref']['checked'])) 
 {
     print '<td class="liste_titre">';
-	print '<input class="flat" size="6" type="text" name="search_ref" value="'.$search_ref.'">';
+	print '<input class="flat maxwidth50" type="text" name="search_ref" value="'.dol_escape_htmltag($search_ref).'">';
     print '</td>';
 }
 
 if (! empty($arrayfields['d.firstname']['checked'])) 
 {
 	print '<td class="liste_titre" align="left">';
-	print '<input class="flat" type="text" name="search_firstname" value="'.$search_firstname.'" size="6"></td>';
+	print '<input class="flat maxwidth50" type="text" name="search_firstname" value="'.dol_escape_htmltag($search_firstname).'"></td>';
 }
 
 if (! empty($arrayfields['d.lastname']['checked'])) 
 {
 	print '<td class="liste_titre" align="left">';
-	print '<input class="flat" type="text" name="search_lastname" value="'.$search_lastname.'" size="6"></td>';
+	print '<input class="flat maxwidth50" type="text" name="search_lastname" value="'.dol_escape_htmltag($search_lastname).'"></td>';
 }
 
 if (! empty($arrayfields['d.company']['checked'])) 
 {
 	print '<td class="liste_titre" align="left">';
-	print '<input class="flat" type="text" name="search_company" value="'.$search_company.'" size="6"></td>';
+	print '<input class="flat maxwidth50" type="text" name="search_company" value="'.dol_escape_htmltag($search_company).'"></td>';
 }
 
 if (! empty($arrayfields['d.login']['checked'])) 
 {
 	print '<td class="liste_titre" align="left">';
-	print '<input class="flat" type="text" name="search_login" value="'.$search_login.'" size="6"></td>';
+	print '<input class="flat maxwidth50" type="text" name="search_login" value="'.dol_escape_htmltag($search_login).'"></td>';
 }
 
 if (! empty($arrayfields['d.morphy']['checked']))
@@ -479,24 +479,24 @@ if (! empty($arrayfields['t.libelle']['checked']))
 if (! empty($arrayfields['d.address']['checked'])) 
 {
 	print '<td class="liste_titre" align="left">';
-	print '<input class="flat" type="text" name="search_address" value="'.$search_address.'" size="5"></td>';
+	print '<input class="flat maxwidth50" type="text" name="search_address" value="'.$search_address.'"></td>';
 }
 
 if (! empty($arrayfields['d.zip']['checked'])) 
 {
 	print '<td class="liste_titre" align="left">';
-	print '<input class="flat" type="text" name="search_zip" value="'.$search_zip.'" size="5"></td>';
+	print '<input class="flat maxwidth50" type="text" name="search_zip" value="'.$search_zip.'"></td>';
 }
 if (! empty($arrayfields['d.town']['checked'])) 
 {
 	print '<td class="liste_titre" align="left">';
-	print '<input class="flat" type="text" name="search_town" value="'.$search_town.'" size="5"></td>';
+	print '<input class="flat maxwidth50" type="text" name="search_town" value="'.$search_town.'"></td>';
 }
 // State
 if (! empty($arrayfields['state.nom']['checked']))
 {
     print '<td class="liste_titre">';
-    print '<input class="flat searchstring" size="4" type="text" name="search_state" value="'.dol_escape_htmltag($search_state).'">';
+    print '<input class="flat searchstring maxwidth50" type="text" name="search_state" value="'.dol_escape_htmltag($search_state).'">';
     print '</td>';
 }
 // Country
@@ -510,25 +510,25 @@ if (! empty($arrayfields['country.code_iso']['checked']))
 if (! empty($arrayfields['d.phone']['checked'])) 
 {
 	print '<td class="liste_titre" align="left">';
-	print '<input class="flat" type="text" name="search_phone" value="'.$search_phone.'" size="5"></td>';
+	print '<input class="flat maxwidth50" type="text" name="search_phone" value="'.$search_phone.'"></td>';
 }
 // Phone perso
 if (! empty($arrayfields['d.phone_perso']['checked'])) 
 {
 	print '<td class="liste_titre" align="left">';
-	print '<input class="flat" type="text" name="search_phone_perso" value="'.$search_phone_perso.'" size="5"></td>';
+	print '<input class="flat maxwidth50" type="text" name="search_phone_perso" value="'.$search_phone_perso.'"></td>';
 }
 // Phone mobile
 if (! empty($arrayfields['d.phone_mobile']['checked'])) 
 {
 	print '<td class="liste_titre" align="left">';
-	print '<input class="flat" type="text" name="search_phone_mobile" value="'.$search_phone_mobile.'" size="5"></td>';
+	print '<input class="flat maxwidth50" type="text" name="search_phone_mobile" value="'.$search_phone_mobile.'"></td>';
 }
 // Email
 if (! empty($arrayfields['d.email']['checked'])) 
 {
 	print '<td class="liste_titre" align="left">';
-	print '<input class="flat" type="text" name="search_email" value="'.$search_email.'" size="5"></td>';
+	print '<input class="flat maxwidth50" type="text" name="search_email" value="'.$search_email.'"></td>';
 }
 
 if (! empty($arrayfields['d.datefin']['checked'])) 
@@ -597,7 +597,7 @@ print "</tr>\n";
 
 $var=True;
 $i = 0;
-while ($i < $num && $i < $conf->liste_limit)
+while ($i < min($num, $limit))
 {
 	$obj = $db->fetch_object($resql);
 

+ 6 - 2
htdocs/adherents/subscription.php

@@ -792,7 +792,7 @@ if ($rowid > 0)
         $sql.= " c.datef,";
         $sql.= " c.fk_bank,";
         $sql.= " b.rowid as bid,";
-        $sql.= " ba.rowid as baid, ba.label, ba.bank";
+        $sql.= " ba.rowid as baid, ba.label, ba.bank, ba.ref, ba.account_number, ba.accountancy_journal, ba.number";
         $sql.= " FROM ".MAIN_DB_PREFIX."adherent as d, ".MAIN_DB_PREFIX."subscription as c";
         $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."bank as b ON c.fk_bank = b.rowid";
         $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."bank_account as ba ON b.fk_account = ba.rowid";
@@ -807,7 +807,7 @@ if ($rowid > 0)
             $num = $db->num_rows($result);
             $i = 0;
 
-            print "<table class=\"noborder\" width=\"100%\">\n";
+            print '<table class="noborder" width="100%">'."\n";
 
             print '<tr class="liste_titre">';
             print '<td>'.$langs->trans("Ref").'</td>';
@@ -841,6 +841,10 @@ if ($rowid > 0)
                     {
                         $accountstatic->label=$objp->label;
                         $accountstatic->id=$objp->baid;
+                        $accountstatic->number=$objp->number;
+                        $accountstatic->account_number=$objp->account_number;
+                        $accountstatic->accountancy_journal=$objp->accountancy_journal;
+                        $accountstatic->ref=$objp->ref;
                         print $accountstatic->getNomUrl(1);
                     }
                     else

+ 24 - 20
htdocs/adherents/subscription/card.php

@@ -40,6 +40,7 @@ $action=GETPOST("action",'alpha');
 $rowid=GETPOST("rowid","int")?GETPOST("rowid","int"):GETPOST("id","int");
 $typeid=GETPOST("typeid","int");
 $cancel=GETPOST('cancel');
+$confirm=GETPOST('confirm');
 
 if (! $user->rights->adherent->cotisation->lire)
 	 accessforbidden();
@@ -62,10 +63,10 @@ include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';		// Must be include,
 //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php';	// Must be include, not include_once
 
 
-if ($user->rights->adherent->cotisation->creer && $_REQUEST["action"] == 'update' && ! $_POST["cancel"])
+if ($user->rights->adherent->cotisation->creer && $action == 'update' && ! $cancel)
 {
 	// Charge objet actuel
-	$result=$object->fetch($_POST["rowid"]);
+	$result=$object->fetch($rowid);
 	if ($result > 0)
 	{
 		$db->begin();
@@ -138,7 +139,7 @@ if ($user->rights->adherent->cotisation->creer && $_REQUEST["action"] == 'update
 	}
 }
 
-if ($_REQUEST["action"] == 'confirm_delete' && $_REQUEST["confirm"] == 'yes' && $user->rights->adherent->cotisation->creer)
+if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->adherent->cotisation->creer)
 {
 	$result=$object->fetch($rowid);
     $result=$object->delete($user);
@@ -189,11 +190,11 @@ if ($user->rights->adherent->cotisation->creer && $action == 'edit')
 	
 	dol_fiche_head($head, 'general', $langs->trans("Subscription"), 0, 'payment');
 
-	print "\n";
-	print '<table class="border" width="100%">';
-
     $linkback = '<a href="'.DOL_URL_ROOT.'/adherents/subscription/list.php">'.$langs->trans("BackToList").'</a>';
 
+    print "\n";
+	print '<table class="border" width="100%">';
+
     // Ref
     print '<tr><td class="titlefieldcreate">'.$langs->trans("Ref").'</td>';
 	print '<td class="valeur" colspan="3">';
@@ -287,49 +288,50 @@ if ($rowid && $action != 'edit')
 
     print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
     print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-    print '<table class="border" width="100%">';
 
     $linkback = '<a href="'.DOL_URL_ROOT.'/adherents/subscription/list.php">'.$langs->trans("BackToList").'</a>';
 
-    // Ref
-    print '<tr><td class="titlefield">'.$langs->trans("Ref").'</td>';
-	print '<td class="valeur" colspan="3">';
-	print $form->showrefnav($object, 'rowid', $linkback, 1);
-	print '</td></tr>';
-
+    dol_banner_tab($object, 'rowid', $linkback, 1);
+    
+    print '<div class="fichecenter">';
+    
+    print '<div class="underbanner clearboth"></div>';
+    
+    print '<table class="border" width="100%">';
+    
     // Member
 	$adh->ref=$adh->getFullName($langs);
     print '<tr>';
-	print '<td>'.$langs->trans("Member").'</td><td class="valeur" colspan="3">'.$adh->getNomUrl(1,0,'subscription').'</td>';
+	print '<td class="titlefield">'.$langs->trans("Member").'</td><td class="valeur">'.$adh->getNomUrl(1,0,'subscription').'</td>';
     print '</tr>';
 
     // Date record
     /*print '<tr>';
-	print '<td>'.$langs->trans("DateSubscription").'</td><td class="valeur" colspan="3">'.dol_print_date($object->datec,'dayhour').'</td>';
+	print '<td>'.$langs->trans("DateSubscription").'</td><td class="valeur">'.dol_print_date($object->datec,'dayhour').'</td>';
     print '</tr>';*/
 
     // Date subscription
     print '<tr>';
-	print '<td>'.$langs->trans("DateSubscription").'</td><td class="valeur" colspan="3">'.dol_print_date($object->dateh,'day').'</td>';
+	print '<td>'.$langs->trans("DateSubscription").'</td><td class="valeur">'.dol_print_date($object->dateh,'day').'</td>';
     print '</tr>';
 
     // Date end subscription
     print '<tr>';
-	print '<td>'.$langs->trans("DateEndSubscription").'</td><td class="valeur" colspan="3">'.dol_print_date($object->datef,'day').'</td>';
+	print '<td>'.$langs->trans("DateEndSubscription").'</td><td class="valeur">'.dol_print_date($object->datef,'day').'</td>';
     print '</tr>';
 
     // Amount
-    print '<tr><td>'.$langs->trans("Amount").'</td><td class="valeur" colspan="3">'.price($object->amount).'</td></tr>';
+    print '<tr><td>'.$langs->trans("Amount").'</td><td class="valeur">'.price($object->amount).'</td></tr>';
 
     // Amount
-    print '<tr><td>'.$langs->trans("Label").'</td><td class="valeur" colspan="3">'.$object->note.'</td></tr>';
+    print '<tr><td>'.$langs->trans("Label").'</td><td class="valeur">'.$object->note.'</td></tr>';
 
     // Bank line
 	if (! empty($conf->banque->enabled))
 	{
 		if ($conf->global->ADHERENT_BANK_USE || $object->fk_bank)
 	    {
-    		print '<tr><td>'.$langs->trans("BankTransactionLine").'</td><td class="valeur" colspan="3">';
+    		print '<tr><td>'.$langs->trans("BankTransactionLine").'</td><td class="valeur">';
 			if ($object->fk_bank)
 			{
 	    		$bankline=new AccountLine($db);
@@ -346,6 +348,8 @@ if ($rowid && $action != 'edit')
 
 
     print "</table>\n";
+    print '</div>';
+    
     print '</form>';
 
     dol_fiche_end();

+ 1 - 1
htdocs/adherents/subscription/list.php

@@ -110,7 +110,7 @@ if ($search_account > 0) $sql.= " AND b.fk_account = ".$search_account;
 if ($search_amount) $sql.= natural_search('c.subscription', $search_amount, 1);
 $sql.= $db->order($sortfield,$sortorder);
 
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
     $result = $db->query($sql);

+ 15 - 22
htdocs/adherents/type.php

@@ -298,20 +298,15 @@ if ($rowid > 0)
 
 		dol_fiche_head($head, 'card', $langs->trans("MemberType"), 0, 'group');
 
-		print '<table class="border" width="100%">';
-
 		$linkback = '<a href="'.DOL_URL_ROOT.'/adherents/type.php">'.$langs->trans("BackToList").'</a>';
 
-		// Ref
-		print '<tr><td class="titlefield">'.$langs->trans("Ref").'</td>';
-		print '<td>';
-		print $form->showrefnav($object, 'rowid', $linkback);
-		print '</td></tr>';
-
-		// Label
-		print '<tr><td>'.$langs->trans("Label").'</td><td>'.dol_escape_htmltag($object->libelle).'</td></tr>';
+		dol_banner_tab($object, 'rowid', $linkback);
+		
+		print '<div class="underbanner clearboth"></div>';
+		
+		print '<table class="border" width="100%">';
 
-		print '<tr><td>'.$langs->trans("SubscriptionRequired").'</td><td>';
+		print '<tr><td class="titlefield">'.$langs->trans("SubscriptionRequired").'</td><td>';
 		print yn($object->subscription);
 		print '</tr>';
 
@@ -378,9 +373,7 @@ if ($rowid > 0)
 		$sql.= " AND t.rowid = ".$object->id;
 		if ($sall)
 		{
-		    $sql.= " AND (d.firstname LIKE '%".$sall."%' OR d.lastname LIKE '%".$sall."%' OR d.societe LIKE '%".$sall."%'";
-		    $sql.= " OR d.email LIKE '%".$sall."%' OR d.login LIKE '%".$sall."%' OR d.address LIKE '%".$sall."%'";
-		    $sql.= " OR d.town LIKE '%".$sall."%' OR d.note_public LIKE '%".$sall."%' OR d.note_private LIKE '%".$sall."%')";
+			$sql.=natural_search(array("f.firstname","d.lastname","d.societe","d.email","d.login","d.address","d.town","d.note_public","d.note_private"), $sall);
 		}
 		if ($status != '')
 		{
@@ -388,22 +381,22 @@ if ($rowid > 0)
 		}
 		if ($action == 'search')
 		{
-		  if (isset($_POST['search']) && $_POST['search'] != '')
-		  {
-		    $sql.= " AND (d.firstname LIKE '%".$_POST['search']."%' OR d.lastname LIKE '%".$_POST['search']."%')";
-		  }
+			if (GETPOST('search'))
+			{
+		  		$sql.= natural_search(array("d.firstname","d.lastname"), GETPOST('search'));
+		  	}
 		}
 		if (! empty($search_lastname))
 		{
-			$sql.= " AND (d.firstname LIKE '%".$search_lastname."%' OR d.lastname LIKE '%".$search_lastname."%')";
+			$sql.= natural_search(array("d.firstname","d.lastname"), $search_lastname);
 		}
 		if (! empty($search_login))
 		{
-		    $sql.= " AND d.login LIKE '%".$search_login."%'";
+			$sql.= natural_search("d.login", $search_login);
 		}
 		if (! empty($search_email))
 		{
-		    $sql.= " AND d.email LIKE '%".$search_email."%'";
+			$sql.= natural_search("d.email", $search_email);
 		}
 		if ($filter == 'uptodate')
 		{
@@ -414,7 +407,7 @@ if ($rowid > 0)
 		    $sql.=" AND datefin < '".$db->idate($now)."'";
 		}
 		// Count total nb of records
-		$nbtotalofrecords = 0;
+		$nbtotalofrecords = -1;
 		if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 		{
 			$resql = $db->query($sql);

+ 1 - 1
htdocs/admin/agenda_other.php

@@ -375,7 +375,7 @@ if (! empty($conf->global->AGENDA_USE_EVENT_TYPE))
     print '<td>'.$langs->trans("AGENDA_USE_EVENT_TYPE_DEFAULT").'</td>'."\n";
     print '<td align="center">&nbsp;</td>'."\n";
     print '<td align="right" class="nowrap">'."\n";
-    $formactions->select_type_actions($conf->global->AGENDA_USE_EVENT_TYPE_DEFAULT, "AGENDA_USE_EVENT_TYPE_DEFAULT", '', 0, 1);
+    $formactions->select_type_actions($conf->global->AGENDA_USE_EVENT_TYPE_DEFAULT, "AGENDA_USE_EVENT_TYPE_DEFAULT", 'systemauto', 0, 1);
     print '</td></tr>'."\n";
 }
 

+ 64 - 62
htdocs/admin/company.php

@@ -306,12 +306,12 @@ if ($action == 'edit' || $action == 'updateedit')
 	$var=true;
 
 	print '<table class="noborder" width="100%">';
-	print '<tr class="liste_titre"><th width="35%">'.$langs->trans("CompanyInfo").'</th><th>'.$langs->trans("Value").'</th></tr>'."\n";
+	print '<tr class="liste_titre"><th class="titlefield">'.$langs->trans("CompanyInfo").'</th><th>'.$langs->trans("Value").'</th></tr>'."\n";
 
 	// Name
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td class="fieldrequired"><label for="name">'.$langs->trans("CompanyName").'</label></td><td>';
-	print '<input name="nom" id="name" size="30" value="'. ($conf->global->MAIN_INFO_SOCIETE_NOM?$conf->global->MAIN_INFO_SOCIETE_NOM:$_POST["nom"]) . '" autofocus="autofocus"></td></tr>'."\n";
+	print '<input name="nom" id="name" class="minwidth200" value="'. ($conf->global->MAIN_INFO_SOCIETE_NOM?$conf->global->MAIN_INFO_SOCIETE_NOM:$_POST["nom"]) . '" autofocus="autofocus"></td></tr>'."\n";
 
 	// Addresse
 	$var=!$var;
@@ -320,11 +320,11 @@ if ($action == 'edit' || $action == 'updateedit')
 
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td><label for="zipcode">'.$langs->trans("CompanyZip").'</label></td><td>';
-	print '<input name="zipcode" id="zipcode" value="'. ($conf->global->MAIN_INFO_SOCIETE_ZIP?$conf->global->MAIN_INFO_SOCIETE_ZIP:$_POST["zipcode"]) . '" size="10"></td></tr>'."\n";
+	print '<input class="minwidth100" name="zipcode" id="zipcode" value="'. ($conf->global->MAIN_INFO_SOCIETE_ZIP?$conf->global->MAIN_INFO_SOCIETE_ZIP:$_POST["zipcode"]) . '"></td></tr>'."\n";
 
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td><label for="town">'.$langs->trans("CompanyTown").'</label></td><td>';
-	print '<input name="town" id="town" size="30" value="'. ($conf->global->MAIN_INFO_SOCIETE_TOWN?$conf->global->MAIN_INFO_SOCIETE_TOWN:$_POST["town"]) . '"></td></tr>'."\n";
+	print '<input name="town" class="minwidth100" id="town" value="'. ($conf->global->MAIN_INFO_SOCIETE_TOWN?$conf->global->MAIN_INFO_SOCIETE_TOWN:$_POST["town"]) . '"></td></tr>'."\n";
 
 	// Country
 	$var=!$var;
@@ -356,20 +356,20 @@ if ($action == 'edit' || $action == 'updateedit')
 
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td><label for="email">'.$langs->trans("EMail").'</label></td><td>';
-	print '<input name="mail" id="email" size="60" value="'. $conf->global->MAIN_INFO_SOCIETE_MAIL . '"></td></tr>';
+	print '<input name="mail" id="email" class="minwidth200" value="'. $conf->global->MAIN_INFO_SOCIETE_MAIL . '"></td></tr>';
 	print '</td></tr>'."\n";
 
 	// Web
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td><label for="web">'.$langs->trans("Web").'</label></td><td>';
-	print '<input name="web" id="web" size="60" value="'. $conf->global->MAIN_INFO_SOCIETE_WEB . '"></td></tr>';
+	print '<input name="web" id="web" class="minwidth300" value="'. $conf->global->MAIN_INFO_SOCIETE_WEB . '"></td></tr>';
 	print '</td></tr>'."\n";
 
 	// Barcode
 	if (! empty($conf->barcode->enabled)) {
 		$var=!$var;
 		print '<tr '.$bc[$var].'><td><label for="barcode">'.$langs->trans("Gencod").'</label></td><td>';
-		print '<input name="barcode" id="barcode" size="40" value="'. $conf->global->MAIN_INFO_SOCIETE_GENCOD . '"></td></tr>';
+		print '<input name="barcode" id="barcode" class="minwidth150" value="'. $conf->global->MAIN_INFO_SOCIETE_GENCOD . '"></td></tr>';
 		print '</td></tr>';
 	}
 
@@ -377,7 +377,7 @@ if ($action == 'edit' || $action == 'updateedit')
 	$var=!$var;
 	print '<tr'.dol_bc($var,'hideonsmartphone').'><td><label for="logo">'.$langs->trans("Logo").' (png,jpg)</label></td><td>';
 	print '<table width="100%" class="nobordernopadding"><tr class="nocellnopadd"><td valign="middle" class="nocellnopadd">';
-	print '<input type="file" class="flat" name="logo" id="logo" size="50">';
+	print '<input type="file" class="flat class=minwidth200" name="logo" id="logo">';
 	print '</td><td class="nocellnopadd" valign="middle" align="right">';
 	if (! empty($mysoc->logo_mini)) {
 		print '<a href="'.$_SERVER["PHP_SELF"].'?action=removelogo">'.img_delete($langs->trans("Delete")).'</a>';
@@ -393,7 +393,7 @@ if ($action == 'edit' || $action == 'updateedit')
 
 	// Note
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td valign="top"><label for="note">'.$langs->trans("Note").'</label></td><td>';
+	print '<tr '.$bc[$var].'><td class="tdtop"><label for="note">'.$langs->trans("Note").'</label></td><td>';
 	print '<textarea class="flat quatrevingtpercent" name="note" id="note" rows="'.ROWS_5.'">'.(! empty($conf->global->MAIN_INFO_SOCIETE_NOTE) ? $conf->global->MAIN_INFO_SOCIETE_NOTE : '').'</textarea></td></tr>';
 	print '</td></tr>';
 
@@ -410,13 +410,13 @@ if ($action == 'edit' || $action == 'updateedit')
 
 	// Managing Director(s)
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%"><label for="director">'.$langs->trans("ManagingDirectors").'</label></td><td>';
-	print '<input name="MAIN_INFO_SOCIETE_MANAGERS" id="director" size="80" value="' . $conf->global->MAIN_INFO_SOCIETE_MANAGERS . '"></td></tr>';
+	print '<tr '.$bc[$var].'><td><label for="director">'.$langs->trans("ManagingDirectors").'</label></td><td>';
+	print '<input name="MAIN_INFO_SOCIETE_MANAGERS" id="director" class="minwidth200" value="' . $conf->global->MAIN_INFO_SOCIETE_MANAGERS . '"></td></tr>';
 
 	// Capital
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%"><label for="capital">'.$langs->trans("Capital").'</label></td><td>';
-	print '<input name="capital" id="capital" size="20" value="' . $conf->global->MAIN_INFO_CAPITAL . '"></td></tr>';
+	print '<tr '.$bc[$var].'><td><label for="capital">'.$langs->trans("Capital").'</label></td><td>';
+	print '<input name="capital" id="capital" class="minwidth100" value="' . $conf->global->MAIN_INFO_CAPITAL . '"></td></tr>';
 
 	// Juridical Status
 	$var=!$var;
@@ -432,10 +432,10 @@ if ($action == 'edit' || $action == 'updateedit')
 	if ($langs->transcountry("ProfId1",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%"><label for="profid1">'.$langs->transcountry("ProfId1",$mysoc->country_code).'</label></td><td>';
+		print '<tr '.$bc[$var].'><td><label for="profid1">'.$langs->transcountry("ProfId1",$mysoc->country_code).'</label></td><td>';
 		if (! empty($mysoc->country_code))
 		{
-			print '<input name="siren" id="profid1" size="20" value="' . (! empty($conf->global->MAIN_INFO_SIREN) ? $conf->global->MAIN_INFO_SIREN : '') . '">';
+			print '<input name="siren" id="profid1" class="minwidth200" value="' . (! empty($conf->global->MAIN_INFO_SIREN) ? $conf->global->MAIN_INFO_SIREN : '') . '">';
 		}
 		else
 		{
@@ -448,10 +448,10 @@ if ($action == 'edit' || $action == 'updateedit')
 	if ($langs->transcountry("ProfId2",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%"><label for="profid2">'.$langs->transcountry("ProfId2",$mysoc->country_code).'</label></td><td>';
+		print '<tr '.$bc[$var].'><td><label for="profid2">'.$langs->transcountry("ProfId2",$mysoc->country_code).'</label></td><td>';
 		if (! empty($mysoc->country_code))
 		{
-			print '<input name="siret" id="profid2" size="20" value="' . (! empty($conf->global->MAIN_INFO_SIRET) ? $conf->global->MAIN_INFO_SIRET : '' ) . '">';
+			print '<input name="siret" id="profid2" class="minwidth200" value="' . (! empty($conf->global->MAIN_INFO_SIRET) ? $conf->global->MAIN_INFO_SIRET : '' ) . '">';
 		}
 		else
 		{
@@ -464,10 +464,10 @@ if ($action == 'edit' || $action == 'updateedit')
 	if ($langs->transcountry("ProfId3",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%"><label for="profid3">'.$langs->transcountry("ProfId3",$mysoc->country_code).'</label></td><td>';
+		print '<tr '.$bc[$var].'><td><label for="profid3">'.$langs->transcountry("ProfId3",$mysoc->country_code).'</label></td><td>';
 		if (! empty($mysoc->country_code))
 		{
-			print '<input name="ape" id="profid3" size="20" value="' . (! empty($conf->global->MAIN_INFO_APE) ? $conf->global->MAIN_INFO_APE : '') . '">';
+			print '<input name="ape" id="profid3" class="minwidth200" value="' . (! empty($conf->global->MAIN_INFO_APE) ? $conf->global->MAIN_INFO_APE : '') . '">';
 		}
 		else
 		{
@@ -480,10 +480,10 @@ if ($action == 'edit' || $action == 'updateedit')
 	if ($langs->transcountry("ProfId4",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%"><label for="profid4">'.$langs->transcountry("ProfId4",$mysoc->country_code).'</label></td><td>';
+		print '<tr '.$bc[$var].'><td><label for="profid4">'.$langs->transcountry("ProfId4",$mysoc->country_code).'</label></td><td>';
 		if (! empty($mysoc->country_code))
 		{
-			print '<input name="rcs" id="profid4" size="20" value="' . (! empty($conf->global->MAIN_INFO_RCS) ? $conf->global->MAIN_INFO_RCS : '') . '">';
+			print '<input name="rcs" id="profid4" class="minwidth200" value="' . (! empty($conf->global->MAIN_INFO_RCS) ? $conf->global->MAIN_INFO_RCS : '') . '">';
 		}
 		else
 		{
@@ -496,10 +496,10 @@ if ($action == 'edit' || $action == 'updateedit')
 	if ($langs->transcountry("ProfId5",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%"><label for="profid5">'.$langs->transcountry("ProfId5",$mysoc->country_code).'</label></td><td>';
+		print '<tr '.$bc[$var].'><td><label for="profid5">'.$langs->transcountry("ProfId5",$mysoc->country_code).'</label></td><td>';
 		if (! empty($mysoc->country_code))
 		{
-			print '<input name="MAIN_INFO_PROFID5" id="profid5" size="20" value="' . (! empty($conf->global->MAIN_INFO_PROFID5) ? $conf->global->MAIN_INFO_PROFID5 : '') . '">';
+			print '<input name="MAIN_INFO_PROFID5" id="profid5" class="minwidth200" value="' . (! empty($conf->global->MAIN_INFO_PROFID5) ? $conf->global->MAIN_INFO_PROFID5 : '') . '">';
 		}
 		else
 		{
@@ -512,10 +512,10 @@ if ($action == 'edit' || $action == 'updateedit')
 	if ($langs->transcountry("ProfId6",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%"><label for="profid6">'.$langs->transcountry("ProfId6",$mysoc->country_code).'</label></td><td>';
+		print '<tr '.$bc[$var].'><td><label for="profid6">'.$langs->transcountry("ProfId6",$mysoc->country_code).'</label></td><td>';
 		if (! empty($mysoc->country_code))
 		{
-			print '<input name="MAIN_INFO_PROFID6" id="profid6" size="20" value="' . (! empty($conf->global->MAIN_INFO_PROFID6) ? $conf->global->MAIN_INFO_PROFID6 : '') . '">';
+			print '<input name="MAIN_INFO_PROFID6" id="profid6" class="minwidth200" value="' . (! empty($conf->global->MAIN_INFO_PROFID6) ? $conf->global->MAIN_INFO_PROFID6 : '') . '">';
 		}
 		else
 		{
@@ -526,13 +526,13 @@ if ($action == 'edit' || $action == 'updateedit')
 
 	// TVA Intra
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%"><label for="intra_vat">'.$langs->trans("VATIntra").'</label></td><td>';
-	print '<input name="tva" id="intra_vat" size="20" value="' . (! empty($conf->global->MAIN_INFO_TVAINTRA) ? $conf->global->MAIN_INFO_TVAINTRA : '') . '">';
+	print '<tr '.$bc[$var].'><td><label for="intra_vat">'.$langs->trans("VATIntra").'</label></td><td>';
+	print '<input name="tva" id="intra_vat" class="minwidth200" value="' . (! empty($conf->global->MAIN_INFO_TVAINTRA) ? $conf->global->MAIN_INFO_TVAINTRA : '') . '">';
 	print '</td></tr>';
 	
 	// Object of the company
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%"><label for="object">'.$langs->trans("CompanyObject").'</label></td><td>';
+	print '<tr '.$bc[$var].'><td><label for="object">'.$langs->trans("CompanyObject").'</label></td><td>';
 	print '<textarea class="flat quatrevingtpercent" name="object" id="object" rows="'.ROWS_5.'">'.(! empty($conf->global->MAIN_INFO_SOCIETE_OBJECT) ? $conf->global->MAIN_INFO_SOCIETE_OBJECT : '').'</textarea></td></tr>';
 	print '</td></tr>';
 
@@ -543,12 +543,12 @@ if ($action == 'edit' || $action == 'updateedit')
 	print '<br>';
 	print '<table class="noborder" width="100%">';
 	print '<tr class="liste_titre">';
-	print '<td>'.$langs->trans("FiscalYearInformation").'</td><td>'.$langs->trans("Value").'</td>';
+	print '<td class="titlefield">'.$langs->trans("FiscalYearInformation").'</td><td>'.$langs->trans("Value").'</td>';
 	print "</tr>\n";
 	$var=true;
 
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%"><label for="fiscalmonthstart">'.$langs->trans("FiscalMonthStart").'</label></td><td>';
+	print '<tr '.$bc[$var].'><td><label for="fiscalmonthstart">'.$langs->trans("FiscalMonthStart").'</label></td><td>';
 	print $formother->select_month($conf->global->SOCIETE_FISCAL_MONTH_START,'fiscalmonthstart',0,1) . '</td></tr>';
 
 	print "</table>";
@@ -558,7 +558,7 @@ if ($action == 'edit' || $action == 'updateedit')
 	print '<br>';
 	print '<table class="noborder" width="100%">';
 	print '<tr class="liste_titre">';
-	print '<td>'.$langs->trans("VATManagement").'</td><td>'.$langs->trans("Description").'</td>';
+	print '<td class="titlefield">'.$langs->trans("VATManagement").'</td><td>'.$langs->trans("Description").'</td>';
 	print '<td align="right">&nbsp;</td>';
 	print "</tr>\n";
 	$var=true;
@@ -699,19 +699,19 @@ else
 	$var=true;
 
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("CompanyName").'</td><td>';
+	print '<tr '.$bc[$var].'><td class="titlefield">'.$langs->trans("CompanyName").'</td><td>';
 	if (! empty($conf->global->MAIN_INFO_SOCIETE_NOM)) print $conf->global->MAIN_INFO_SOCIETE_NOM;
 	else print img_warning().' <font class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CompanyName")).'</font>';
 	print '</td></tr>';
 
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("CompanyAddress").'</td><td>' . nl2br(empty($conf->global->MAIN_INFO_SOCIETE_ADDRESS)?'':$conf->global->MAIN_INFO_SOCIETE_ADDRESS) . '</td></tr>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("CompanyAddress").'</td><td>' . nl2br(empty($conf->global->MAIN_INFO_SOCIETE_ADDRESS)?'':$conf->global->MAIN_INFO_SOCIETE_ADDRESS) . '</td></tr>';
 
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("CompanyZip").'</td><td>' . (empty($conf->global->MAIN_INFO_SOCIETE_ZIP)?'':$conf->global->MAIN_INFO_SOCIETE_ZIP) . '</td></tr>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("CompanyZip").'</td><td>' . (empty($conf->global->MAIN_INFO_SOCIETE_ZIP)?'':$conf->global->MAIN_INFO_SOCIETE_ZIP) . '</td></tr>';
 
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("CompanyTown").'</td><td>' . (empty($conf->global->MAIN_INFO_SOCIETE_TOWN)?'':$conf->global->MAIN_INFO_SOCIETE_TOWN) . '</td></tr>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("CompanyTown").'</td><td>' . (empty($conf->global->MAIN_INFO_SOCIETE_TOWN)?'':$conf->global->MAIN_INFO_SOCIETE_TOWN) . '</td></tr>';
 
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td>'.$langs->trans("CompanyCountry").'</td><td>';
@@ -731,7 +731,7 @@ else
 	print '</td></tr>';
 
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("CompanyCurrency").'</td><td>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("CompanyCurrency").'</td><td>';
 	print currency_name($conf->currency,1);
 	print ' ('.$conf->currency;
 	print ($conf->currency != $langs->getCurrencySymbol($conf->currency) ? ' - '.$langs->getCurrencySymbol($conf->currency) : '');
@@ -739,52 +739,54 @@ else
 	print '</td></tr>';
 
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("Phone").'</td><td>' . dol_print_phone($conf->global->MAIN_INFO_SOCIETE_TEL,$mysoc->country_code) . '</td></tr>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("Phone").'</td><td>' . dol_print_phone($conf->global->MAIN_INFO_SOCIETE_TEL,$mysoc->country_code) . '</td></tr>';
 
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("Fax").'</td><td>' . dol_print_phone($conf->global->MAIN_INFO_SOCIETE_FAX,$mysoc->country_code) . '</td></tr>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("Fax").'</td><td>' . dol_print_phone($conf->global->MAIN_INFO_SOCIETE_FAX,$mysoc->country_code) . '</td></tr>';
 
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("Mail").'</td><td>' . dol_print_email($conf->global->MAIN_INFO_SOCIETE_MAIL,0,0,0,80) . '</td></tr>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("Mail").'</td><td>' . dol_print_email($conf->global->MAIN_INFO_SOCIETE_MAIL,0,0,0,80) . '</td></tr>';
 
 	// Web
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("Web").'</td><td>' . dol_print_url($conf->global->MAIN_INFO_SOCIETE_WEB,'_blank',80) . '</td></tr>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("Web").'</td><td>' . dol_print_url($conf->global->MAIN_INFO_SOCIETE_WEB,'_blank',80) . '</td></tr>';
 
 	// Barcode
 	if (! empty($conf->barcode->enabled))
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("Gencod").'</td><td>' . $conf->global->MAIN_INFO_SOCIETE_GENCOD . '</td></tr>';
+		print '<tr '.$bc[$var].'><td>'.$langs->trans("Gencod").'</td><td>' . $conf->global->MAIN_INFO_SOCIETE_GENCOD . '</td></tr>';
 	}
 
 	// Logo
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("Logo").'</td><td>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("Logo").'</td><td>';
 
-	print '<table width="100%" class="nobordernopadding"><tr class="nocellnopadd"><td valign="middle" class="nocellnopadd">';
+	$tagtd='tagtd ';
+	if ($conf->browser->layout == 'phone') $tagtd='';
+	print '<div class="tagtable centpercent"><div class="tagtr inline-block centpercent valignmiddle"><div class="'.$tagtd.'inline-block valignmiddle left">';
 	print $mysoc->logo;
-	print '</td><td class="nocellnopadd" valign="center" align="right">';
+	print '</div><div class="'.$tagtd.'inline-block valignmiddle left">';
 
 	// It offers the generation of the thumbnail if it does not exist
 	if (!is_file($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini) && preg_match('/(\.jpg|\.jpeg|\.png)$/i',$mysoc->logo))
 	{
-		print '<a href="'.$_SERVER["PHP_SELF"].'?action=addthumb&amp;file='.urlencode($mysoc->logo).'">'.img_picto($langs->trans('GenerateThumb'),'refresh').'</a>&nbsp;&nbsp;';
+		print '<a class="img_logo" href="'.$_SERVER["PHP_SELF"].'?action=addthumb&amp;file='.urlencode($mysoc->logo).'">'.img_picto($langs->trans('GenerateThumb'),'refresh').'</a>&nbsp;&nbsp;';
 	}
 	else if ($mysoc->logo_mini && is_file($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini))
 	{
-		print '<img src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=companylogo&amp;file='.urlencode('/thumbs/'.$mysoc->logo_mini).'">';
+		print '<img class="img_logo" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=companylogo&amp;file='.urlencode('/thumbs/'.$mysoc->logo_mini).'">';
 	}
 	else
 	{
-		print '<img height="30" src="'.DOL_URL_ROOT.'/public/theme/common/nophoto.png">';
+		print '<img class="img_logo" src="'.DOL_URL_ROOT.'/public/theme/common/nophoto.png">';
 	}
-	print '</td></tr></table>';
+	print '</div></div></div>';
 
 	print '</td></tr>';
 
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%" valign="top">'.$langs->trans("Note").'</td><td>' . (! empty($conf->global->MAIN_INFO_SOCIETE_NOTE) ? nl2br($conf->global->MAIN_INFO_SOCIETE_NOTE) : '') . '</td></tr>';
+	print '<tr '.$bc[$var].'><td valign="top">'.$langs->trans("Note").'</td><td>' . (! empty($conf->global->MAIN_INFO_SOCIETE_NOTE) ? nl2br($conf->global->MAIN_INFO_SOCIETE_NOTE) : '') . '</td></tr>';
 
 	print '</table>';
 
@@ -796,22 +798,22 @@ else
 	print '<form name="formsoc" method="post">';
 	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
 	print '<table class="noborder" width="100%">';
-	print '<tr class="liste_titre"><td>'.$langs->trans("CompanyIds").'</td><td>'.$langs->trans("Value").'</td></tr>';
+	print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("CompanyIds").'</td><td>'.$langs->trans("Value").'</td></tr>';
 	$var=true;
 
 	// Managing Director(s)
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("ManagingDirectors").'</td><td>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("ManagingDirectors").'</td><td>';
 	print $conf->global->MAIN_INFO_SOCIETE_MANAGERS . '</td></tr>';
 
 	// Capital
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("Capital").'</td><td>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("Capital").'</td><td>';
 	print $conf->global->MAIN_INFO_CAPITAL . '</td></tr>';
 
 	// Juridical Status
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("JuridicalStatus").'</td><td>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("JuridicalStatus").'</td><td>';
 	print getFormeJuridiqueLabel($conf->global->MAIN_INFO_SOCIETE_FORME_JURIDIQUE);
 	print '</td></tr>';
 
@@ -819,7 +821,7 @@ else
 	if ($langs->transcountry("ProfId1",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%">'.$langs->transcountry("ProfId1",$mysoc->country_code).'</td><td>';
+		print '<tr '.$bc[$var].'><td>'.$langs->transcountry("ProfId1",$mysoc->country_code).'</td><td>';
 		if (! empty($conf->global->MAIN_INFO_SIREN))
 		{
 			print $conf->global->MAIN_INFO_SIREN;
@@ -835,7 +837,7 @@ else
 	if ($langs->transcountry("ProfId2",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%">'.$langs->transcountry("ProfId2",$mysoc->country_code).'</td><td>';
+		print '<tr '.$bc[$var].'><td>'.$langs->transcountry("ProfId2",$mysoc->country_code).'</td><td>';
 		if (! empty($conf->global->MAIN_INFO_SIRET))
 		{
 			print $conf->global->MAIN_INFO_SIRET;
@@ -851,7 +853,7 @@ else
 	if ($langs->transcountry("ProfId3",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%">'.$langs->transcountry("ProfId3",$mysoc->country_code).'</td><td>';
+		print '<tr '.$bc[$var].'><td>'.$langs->transcountry("ProfId3",$mysoc->country_code).'</td><td>';
 		if (! empty($conf->global->MAIN_INFO_APE))
 		{
 			print $conf->global->MAIN_INFO_APE;
@@ -867,7 +869,7 @@ else
 	if ($langs->transcountry("ProfId4",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%">'.$langs->transcountry("ProfId4",$mysoc->country_code).'</td><td>';
+		print '<tr '.$bc[$var].'><td>'.$langs->transcountry("ProfId4",$mysoc->country_code).'</td><td>';
 		if (! empty($conf->global->MAIN_INFO_RCS))
 		{
 			print $conf->global->MAIN_INFO_RCS;
@@ -883,7 +885,7 @@ else
 	if ($langs->transcountry("ProfId5",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%">'.$langs->transcountry("ProfId5",$mysoc->country_code).'</td><td>';
+		print '<tr '.$bc[$var].'><td>'.$langs->transcountry("ProfId5",$mysoc->country_code).'</td><td>';
 		if (! empty($conf->global->MAIN_INFO_PROFID5))
 		{
 			print $conf->global->MAIN_INFO_PROFID5;
@@ -899,7 +901,7 @@ else
 	if ($langs->transcountry("ProfId6",$mysoc->country_code) != '-')
 	{
 		$var=!$var;
-		print '<tr '.$bc[$var].'><td width="35%">'.$langs->transcountry("ProfId6",$mysoc->country_code).'</td><td>';
+		print '<tr '.$bc[$var].'><td>'.$langs->transcountry("ProfId6",$mysoc->country_code).'</td><td>';
 		if (! empty($conf->global->MAIN_INFO_PROFID6))
 		{
 			print $conf->global->MAIN_INFO_PROFID6;
@@ -950,7 +952,7 @@ else
 	print '</tr>';
 	
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%" valign="top">'.$langs->trans("CompanyObject").'</td><td>' . (! empty($conf->global->MAIN_INFO_SOCIETE_OBJECT) ? nl2br($conf->global->MAIN_INFO_SOCIETE_OBJECT) : '') . '</td></tr>';
+	print '<tr '.$bc[$var].'><td valign="top">'.$langs->trans("CompanyObject").'</td><td>' . (! empty($conf->global->MAIN_INFO_SOCIETE_OBJECT) ? nl2br($conf->global->MAIN_INFO_SOCIETE_OBJECT) : '') . '</td></tr>';
 
 	print '</table>';
 	print '</form>';
@@ -961,12 +963,12 @@ else
 	print '<br>';
 	print '<table class="noborder" width="100%">';
 	print '<tr class="liste_titre">';
-	print '<td>'.$langs->trans("FiscalYearInformation").'</td><td>'.$langs->trans("Value").'</td>';
+	print '<td class="titlefield">'.$langs->trans("FiscalYearInformation").'</td><td>'.$langs->trans("Value").'</td>';
 	print "</tr>\n";
 	$var=true;
 
 	$var=!$var;
-	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("FiscalMonthStart").'</td><td>';
+	print '<tr '.$bc[$var].'><td>'.$langs->trans("FiscalMonthStart").'</td><td>';
 	$monthstart=(! empty($conf->global->SOCIETE_FISCAL_MONTH_START)) ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1;
 	print dol_print_date(dol_mktime(12,0,0,$monthstart,1,2000,1),'%B','gm') . '</td></tr>';
 

+ 6 - 1
htdocs/admin/delais.php

@@ -112,7 +112,12 @@ $modules=array(
 				array(
 						'code' => 'MAIN_DELAY_EXPENSEREPORTS',
 						'img' => 'trip'
-				)
+				),
+    		    /* TODO Enable this
+		        array(
+    		        'code' => 'MAIN_DELAY_EXPENSEREPORTS_TO_PAY',
+    		        'img' => 'trip'
+    		    )*/
 		),
 );
 

+ 9 - 7
htdocs/admin/dict.php

@@ -675,8 +675,8 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     }
 
 	// Clean some parameters
-    if (! empty($_POST["localtax1_type"]) && empty($_POST["localtax1"])) $_POST["localtax1"]='0';	// If empty, we force to 0
-    if (! empty($_POST["localtax2_type"]) && empty($_POST["localtax2"])) $_POST["localtax2"]='0';	// If empty, we force to 0
+    if ((! empty($_POST["localtax1_type"]) || ($_POST['localtax1_type'] == '0')) && empty($_POST["localtax1"])) $_POST["localtax1"]='0';	// If empty, we force to 0
+    if ((! empty($_POST["localtax2_type"]) || ($_POST['localtax2_type'] == '0')) && empty($_POST["localtax2"])) $_POST["localtax2"]='0';	// If empty, we force to 0
 	if ($_POST["accountancy_code"] <= 0) $_POST["accountancy_code"]='';	// If empty, we force to null
 	if ($_POST["accountancy_code_sell"] <= 0) $_POST["accountancy_code_sell"]='';	// If empty, we force to null
 	if ($_POST["accountancy_code_buy"] <= 0) $_POST["accountancy_code_buy"]='';	// If empty, we force to null
@@ -1064,7 +1064,9 @@ if ($id)
 			if ($fieldlist[$field]=='content')         { $valuetoshow=$langs->trans("Content"); }
 			if ($fieldlist[$field]=='percent')         { $valuetoshow=$langs->trans("Percentage"); }
 			if ($fieldlist[$field]=='affect')          { $valuetoshow=$langs->trans("Info"); }
-
+			if ($fieldlist[$field]=='delay')           { $valuetoshow=$langs->trans("NoticePeriod"); }
+			if ($fieldlist[$field]=='newbymonth')      { $valuetoshow=$langs->trans("NewByMonth"); }
+				
             if ($id == 2)	// Special cas for state page
             {
             	if ($fieldlist[$field]=='region_id') { $valuetoshow='&nbsp;'; $showfield=1; }
@@ -1784,10 +1786,10 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 			print '</td>';
 		}
 		elseif ($fieldlist[$field] == 'price' || preg_match('/^amount/i',$fieldlist[$field])) {
-			print '<td><input type="text" class="flat" value="'.price((! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'')).'" size="8" name="'.$fieldlist[$field].'"></td>';
+			print '<td><input type="text" class="flat minwidth75" value="'.price((! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'')).'" name="'.$fieldlist[$field].'"></td>';
 		}
 		elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) {
-			print '<td><input type="text" class="flat" value="'.(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" size="10" name="'.$fieldlist[$field].'"></td>';
+			print '<td><input type="text" class="flat minwidth100" value="'.(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" name="'.$fieldlist[$field].'"></td>';
 		}
 		elseif ($fieldlist[$field]=='unit') {
 			print '<td>';
@@ -1827,8 +1829,8 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 		{
 			print '<td>';
 			$size=''; $class='';
-			if ($fieldlist[$field]=='code') $size='size="8" ';
-			if ($fieldlist[$field]=='position') $size='size="4" ';
+			if ($fieldlist[$field]=='code') $class='maxwidth100';
+			if ($fieldlist[$field]=='position') $class='maxwidth50';
 			if ($fieldlist[$field]=='libelle') $class='quatrevingtpercent';
 			if ($fieldlist[$field]=='tracking') $class='quatrevingtpercent';
 			if ($fieldlist[$field]=='sortorder' || $fieldlist[$field]=='sens' || $fieldlist[$field]=='category_type') $size='size="2" ';

+ 4 - 4
htdocs/admin/fckeditor.php

@@ -46,27 +46,27 @@ if (!$user->admin) accessforbidden();
 $modules = array(
 'SOCIETE' => 'FCKeditorForCompany',
 'PRODUCTDESC' => 'FCKeditorForProduct',
-'MAILING' => 'FCKeditorForMailing',
 'DETAILS' => 'FCKeditorForProductDetails',
 'USERSIGN' => 'FCKeditorForUserSignature',
+'MAILING' => 'FCKeditorForMailing',
 'MAIL' => 'FCKeditorForMail'
 );
 // Conditions pour que l'option soit proposee
 $conditions = array(
 'SOCIETE' => 1,
 'PRODUCTDESC' => (! empty($conf->product->enabled) || ! empty($conf->service->enabled)),
-'MAILING' => ! empty($conf->mailing->enabled),
 'DETAILS' => (! empty($conf->facture->enabled) || ! empty($conf->propal->enabled) || ! empty($conf->commande->enabled) || ! empty($conf->supplier_proposal->enabled) || ! empty($conf->fournisseur->enabled)),
 'USERSIGN' => 1,
+'MAILING' => ! empty($conf->mailing->enabled),
 'MAIL' => (! empty($conf->facture->enabled) || ! empty($conf->propal->enabled) || ! empty($conf->commande->enabled))
 );
 // Picto
 $picto = array(
 'SOCIETE' => 'generic',
 'PRODUCTDESC' => 'product',
-'MAILING' => 'email',
-'DETAILS' => 'generic',
+'DETAILS' => 'product',
 'USERSIGN' => 'user',
+'MAILING' => 'email',
 'MAIL' => 'email'
 );
 

+ 1 - 0
htdocs/admin/ihm.php

@@ -39,6 +39,7 @@ $langs->load("products");
 $langs->load("members");
 $langs->load("projects");
 $langs->load("hrm");
+$langs->load("agenda");
 
 if (! $user->admin) accessforbidden();
 

+ 1 - 1
htdocs/admin/mails.php

@@ -404,7 +404,7 @@ if ($action == 'edit')
     $var=!$var;
     $liste = array();
     $liste['user'] = $langs->trans('UserEmail');
-    $liste['company'] = $langs->trans('CompanyEmail');
+    $liste['company'] = $langs->trans('CompanyEmail').' ('.(empty($conf->global->MAIN_INFO_SOCIETE_MAIL)?$langs->trans("NotDefined"):$conf->global->MAIN_INFO_SOCIETE_MAIL).')';
 
     print '<tr '.$bc[$var?1:0].'><td>'.$langs->trans('MAIN_MAIL_DEFAULT_FROMTYPE').'</td><td>';
     print $form->selectarray('MAIN_MAIL_DEFAULT_FROMTYPE',$liste,$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE,0);

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

@@ -71,7 +71,7 @@ if ($action == 'up')
 	// Get current position
 	$sql = "SELECT m.rowid, m.position, m.type, m.fk_menu";
 	$sql.= " FROM ".MAIN_DB_PREFIX."menu as m";
-	$sql.= " WHERE m.rowid = ".$_GET["menuId"];
+	$sql.= " WHERE m.rowid = ".GETPOST("menuId","int");
 	dol_syslog("admin/menus/index.php ".$sql);
 	$result = $db->query($sql);
 	$num = $db->num_rows($result);
@@ -89,11 +89,11 @@ if ($action == 'up')
 	// Menu before
 	$sql = "SELECT m.rowid, m.position";
 	$sql.= " FROM ".MAIN_DB_PREFIX."menu as m";
-	$sql.= " WHERE (m.position < ".($current['order'])." OR (m.position = ".($current['order'])." AND rowid < ".$_GET["menuId"]."))";
-	$sql.= " AND m.menu_handler='".$menu_handler_to_search."'";
+	$sql.= " WHERE (m.position < ".($current['order'])." OR (m.position = ".($current['order'])." AND rowid < ".GETPOST("menuId","int")."))";
+	$sql.= " AND m.menu_handler='".$db->escape($menu_handler_to_search)."'";
 	$sql.= " AND m.entity = ".$conf->entity;
-	$sql.= " AND m.type = '".$current['type']."'";
-	$sql.= " AND m.fk_menu = '".$current['fk_menu']."'";
+	$sql.= " AND m.type = '".$db->escape($current['type'])."'";
+	$sql.= " AND m.fk_menu = '".$db->escape($current['fk_menu'])."'";
 	$sql.= " ORDER BY m.position, m.rowid";
 	dol_syslog("admin/menus/index.php ".$sql);
 	$result = $db->query($sql);
@@ -127,7 +127,7 @@ elseif ($action == 'down')
 	// Get current position
 	$sql = "SELECT m.rowid, m.position, m.type, m.fk_menu";
 	$sql.= " FROM ".MAIN_DB_PREFIX."menu as m";
-	$sql.= " WHERE m.rowid = ".$_GET["menuId"];
+	$sql.= " WHERE m.rowid = ".GETPOST("menuId","int");
 	dol_syslog("admin/menus/index.php ".$sql);
 	$result = $db->query($sql);
 	$num = $db->num_rows($result);
@@ -145,11 +145,11 @@ elseif ($action == 'down')
 	// Menu after
 	$sql = "SELECT m.rowid, m.position";
 	$sql.= " FROM ".MAIN_DB_PREFIX."menu as m";
-	$sql.= " WHERE (m.position > ".($current['order'])." OR (m.position = ".($current['order'])." AND rowid > ".$_GET["menuId"]."))";
-	$sql.= " AND m.menu_handler='".$menu_handler_to_search."'";
+	$sql.= " WHERE (m.position > ".($current['order'])." OR (m.position = ".($current['order'])." AND rowid > ".GETPOST("menuId","int")."))";
+	$sql.= " AND m.menu_handler='".$db->escape($menu_handler_to_search)."'";
 	$sql.= " AND m.entity = ".$conf->entity;
-	$sql.= " AND m.type = '".$current['type']."'";
-	$sql.= " AND m.fk_menu = '".$current['fk_menu']."'";
+	$sql.= " AND m.type = '".$db->escape($current['type'])."'";
+	$sql.= " AND m.fk_menu = '".$db->escape($current['fk_menu'])."'";
 	$sql.= " ORDER BY m.position, m.rowid";
 	dol_syslog("admin/menus/index.php ".$sql);
 	$result = $db->query($sql);
@@ -180,7 +180,7 @@ elseif ($action == 'confirm_delete' && $confirm == 'yes')
 	$db->begin();
 
 	$sql = "DELETE FROM ".MAIN_DB_PREFIX."menu";
-	$sql.= " WHERE rowid = ".$_GET['menuId'];
+	$sql.= " WHERE rowid = ".GETPOST('menuId','int');
 	$resql=$db->query($sql);
 	if ($resql)
 	{
@@ -245,11 +245,11 @@ if ($action == 'delete')
 {
 	$sql = "SELECT m.titre";
 	$sql.= " FROM ".MAIN_DB_PREFIX."menu as m";
-	$sql.= " WHERE m.rowid = ".$_GET['menuId'];
+	$sql.= " WHERE m.rowid = ".GETPOST('menuId','int');
 	$result = $db->query($sql);
 	$obj = $db->fetch_object($result);
 
-    print $form->formconfirm("index.php?menu_handler=".$menu_handler."&menuId=".$_GET['menuId'],$langs->trans("DeleteMenu"),$langs->trans("ConfirmDeleteMenu",$obj->titre),"confirm_delete");
+    print $form->formconfirm("index.php?menu_handler=".$menu_handler."&menuId=".GETPOST('menuId','int'),$langs->trans("DeleteMenu"),$langs->trans("ConfirmDeleteMenu",$obj->titre),"confirm_delete");
 }
 
 
@@ -298,7 +298,7 @@ if ($conf->use_javascript_ajax)
 
 	$sql = "SELECT m.rowid, m.titre, m.langs, m.mainmenu, m.leftmenu, m.fk_menu, m.fk_mainmenu, m.fk_leftmenu, m.module";
 	$sql.= " FROM ".MAIN_DB_PREFIX."menu as m";
-	$sql.= " WHERE menu_handler = '".$menu_handler_to_search."'";
+	$sql.= " WHERE menu_handler = '".$db->escape($menu_handler_to_search)."'";
 	$sql.= " AND entity = ".$conf->entity;
 	//$sql.= " AND fk_menu >= 0";
 	$sql.= " ORDER BY m.position, m.rowid";		// Order is position then rowid (because we need a sort criteria when position is same)

+ 3 - 3
htdocs/admin/modules.php

@@ -500,8 +500,10 @@ if ($mode != 'marketplace')
         else $text.='<div class="titre">'.$objMod->getDesc().'</div><br>';
 
         $textexternal='';
+	$imginfo="info";
         if ($objMod->isCoreOrExternalModule() == 'external')
         {
+ 	    $imginfo="info_black";
             $textexternal.='<br><strong>'.$langs->trans("Origin").':</strong> '.$langs->trans("ExternalModule",$dirofmodule);
             if ($objMod->editor_name != 'dolibarr') $textexternal.='<br><strong>'.$langs->trans("Publisher").':</strong> '.(empty($objMod->editor_name)?$langs->trans("Unknown"):$objMod->editor_name);
             if (! empty($objMod->editor_url) && ! preg_match('/dolibarr\.org/i',$objMod->editor_url)) $textexternal.='<br><strong>'.$langs->trans("Url").':</strong> '.$objMod->editor_url;
@@ -645,7 +647,7 @@ if ($mode != 'marketplace')
         $text.='<br><strong>'.$langs->trans("AddOtherPagesOrServices").':</strong> ';
         $text.=$langs->trans("DetectionNotPossible");
 
-        print $form->textwithpicto('', $text, 1, 'help', 'minheight20');
+        print $form->textwithpicto('', $text, 1, $imginfo, 'minheight20');
 
         print '</td>';
 
@@ -659,8 +661,6 @@ if ($mode != 'marketplace')
         if (preg_match('/experimental/i', $version)) print img_warning($langs->trans("Experimental"), 'style="float: left"');
         if (preg_match('/deprecated/i', $version))   print img_warning($langs->trans("Deprecated"), 'style="float: left"');
 
-        // Picto external
-        if ($textexternal) print img_picto($langs->trans("ExternalModule",$dirofmodule), 'external', 'style="float: left"');
 
         print $versiontrans;
 

+ 13 - 1
htdocs/admin/multicurrency.php

@@ -33,6 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
 
 
 // Translations
+$langs->load("admin");
 $langs->load("multicurrency");
 
 // Access control
@@ -323,8 +324,17 @@ print '<input type="text" name="rate" value="" size="13" placeholder="'.$langs->
 print '<input type="submit" class="button" value="'.$langs->trans("Add").'">';
 print '</td></form></tr>';
 
+$var=!$var;
+print '<tr '.$bc[$var].'>';
+print '<td>'.$conf->currency.$form->textwithpicto(' ', $langs->trans("BaseCurrency")).'</td>';
+print '<td align="center" width="20">&nbsp;</td>';
+print '<td align="right" width="300">1';
+print '</td></form></tr>';
+
 foreach ($TCurrency as &$currency)
 {
+	if($currency->code == $conf->currency) continue;
+	
 	$var=!$var;
 	print '<tr '.$bc[$var].'>';
 	print '<td>'.$currency->code.' - '.$currency->name.'</td>';
@@ -334,10 +344,12 @@ foreach ($TCurrency as &$currency)
 	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
 	print '<input type="hidden" name="action" value="update_currency">';
 	print '<input type="hidden" name="fk_multicurrency" value="'.$currency->id.'">';
-	print '<input type="text" name="rate" value="'.($currency->rate->rate ? $currency->rate->rate : '').'" size="13" />&nbsp;';
+	print '1 '.$conf->currency.' = ';
+	print '<input type="text" name="rate" value="'.($currency->rate->rate ? $currency->rate->rate : '').'" size="13" />&nbsp;'.$currency->code.'&nbsp;';
 	print '<input type="submit" name="submit" class="button" value="'.$langs->trans("Modify").'">&nbsp;';
 	print '<input type="submit" name="submit" class="button" value="'.$langs->trans("Delete").'">';
 	print '</form>';
+
 	print '</td></tr>';
 }
 

+ 2 - 2
htdocs/admin/perms.php

@@ -44,7 +44,7 @@ if (!$user->admin) accessforbidden();
 if ($action == 'add')
 {
     $sql = "UPDATE ".MAIN_DB_PREFIX."rights_def SET bydefault=1";
-    $sql.= " WHERE id = ".$_GET["pid"];
+    $sql.= " WHERE id = ".GETPOST("pid",'int');
     $sql.= " AND entity = ".$conf->entity;
     $db->query($sql);
 }
@@ -52,7 +52,7 @@ if ($action == 'add')
 if ($action == 'remove')
 {
     $sql = "UPDATE ".MAIN_DB_PREFIX."rights_def SET bydefault=0";
-    $sql.= " WHERE id = ".$_GET["pid"];
+    $sql.= " WHERE id = ".GETPOST('pid','int');
     $sql.= " AND entity = ".$conf->entity;
     $db->query($sql);
 }

+ 2 - 1
htdocs/admin/system/constall.php

@@ -90,7 +90,8 @@ $configfileparameters=array(
                             '?dolibarr_font_DOL_DEFAULT_TTF_BOLD',
 							'separator',
 							'?dolibarr_mailing_limit_sendbyweb',
-							'?dolibarr_strict_mode'
+							'?dolibarr_mailing_limit_sendbycli',
+                            '?dolibarr_strict_mode'
 						);
 $configfilelib=array(
 //					'separator',

+ 2 - 1
htdocs/admin/system/dolibarr.php

@@ -286,7 +286,8 @@ $configfileparameters=array(
 		'separator4' => '',
 		'dolibarr_main_prod' => 'Production mode (Hide all error messages)',
 		'?dolibarr_mailing_limit_sendbyweb' => 'Limit nb of email sent by page',
-		'?dolibarr_strict_mode' => 'Strict mode is on/off',
+		'?dolibarr_mailing_limit_sendbycli' => 'Limit nb of email sent by cli',
+        '?dolibarr_strict_mode' => 'Strict mode is on/off',
 		'?dolibarr_pdf_force_fpdf' => 'Force fpdf usage to generate PDF'
 );
 

+ 0 - 3
htdocs/api/class/api.class.php

@@ -81,9 +81,6 @@ class DolibarrApi
      *
      * @param   object  $object	Object to clean
      * @return	array	Array of cleaned object properties
-     *
-     * @todo use an array for properties to clean
-     *
      */
     function _cleanObjectDatas($object) {
 

+ 1 - 1
htdocs/api/class/api_dictionnarycountries.class.php

@@ -54,7 +54,7 @@ class DictionnaryCountries extends DolibarrApi
      * @param int       $page       Page number (starting from zero)
      * @param string    $filter     To filter the countries by name
      * @param string    $lang       Code of the language the label of the countries must be translated to
-     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
+     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
      * @return List of countries
      *            
      * @throws RestException

+ 1 - 1
htdocs/api/class/api_dictionnarytowns.class.php

@@ -47,7 +47,7 @@ class DictionnaryTowns extends DolibarrApi
      * @param int       $page       Page number (starting from zero)
      * @param string    $zipcode    To filter on zipcode
      * @param string    $town       To filter on city name
-     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
+     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
      * @return List of towns
      *            
      * @throws RestException

+ 17 - 2
htdocs/api/index.php

@@ -115,6 +115,10 @@ foreach ($modulesdir as $dir)
                 elseif ($module == 'stock') {
                     $moduledirforclass = 'product/stock';
                 }
+                elseif ($module == 'fournisseur') {
+                    $moduledirforclass = 'fourn';
+                }
+                //dol_syslog("Found module file ".$file." - module=".$module." - moduledirforclass=".$moduledirforclass);
                 
                 // Defined if module is enabled
                 $enabled=true;
@@ -137,6 +141,8 @@ foreach ($modulesdir as $dir)
                     {
                         while (($file_searched = readdir($handle_part))!==false)
                         {
+                            if ($file_searched == 'api_access.class.php') continue;
+                            
                             // Support of the deprecated API.
                             if (is_readable($dir_part.$file_searched) && preg_match("/^api_deprecated_(.*)\.class\.php$/i",$file_searched,$reg))
                             {
@@ -144,19 +150,28 @@ foreach ($modulesdir as $dir)
                                 require_once $dir_part.$file_searched;
                                 if (class_exists($classname))
                                 {
-                                    dol_syslog("Found deprecated API by index.php: classname=".$classname." into ".$dir." - ".$dir_part.$file_searched);
+                                    //dol_syslog("Found deprecated API by index.php: classname=".$classname." for module ".$dir." into ".$dir_part.$file_searched);
                                     $api->r->addAPIClass($classname, '/');
                                 }
+                                else
+                                {
+                                    dol_syslog("We found an api_xxx file (".$file_searched.") but class ".$classname." does not exists after loading file", LOG_WARNING);
+                                }
                             }
                             elseif (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$reg))
                             {
                                 $classname = ucwords($reg[1]);
+                                $classname = str_replace('_', '', $classname);
                                 require_once $dir_part.$file_searched;
                                 if (class_exists($classname))
                                 {
-                                    dol_syslog("Found API by index.php: classname=".$classname." into ".$dir." - ".$dir_part.$file_searched);
+                                    //dol_syslog("Found API by index.php: classname=".$classname." for module ".$dir." into ".$dir_part.$file_searched);
                                     $listofapis[] = $classname;
                                 }
+                                else
+                                {
+                                    dol_syslog("We found an api_xxx file (".$file_searched.") but class ".$classname." does not exists after loading file", LOG_WARNING);
+                                }
                             }
                         }
                     }

+ 4 - 4
htdocs/asterisk/wrapper.php

@@ -85,10 +85,10 @@ if (! isset($conf->global->ASTERISK_PRIORITY))  $conf->global->ASTERISK_PRIORITY
 if (! isset($conf->global->ASTERISK_MAX_RETRY)) $conf->global->ASTERISK_MAX_RETRY="2";
 
 
-$login = $_GET['login'];
-$password = $_GET['password'];
-$caller = $_GET['caller'];
-$called = $_GET['called'];
+$login = GETPOST('login');
+$password = GETPOST('password');
+$caller = GETPOST('caller');
+$called = GETPOST('called');
 
 // IP address of Asterisk server
 $strHost = $conf->global->ASTERISK_HOST;

+ 5 - 3
htdocs/bookmarks/card.php

@@ -69,7 +69,7 @@ if ($action == 'add' || $action == 'addproduct' || $action == 'update')
 		exit;
 	}
 
-	if ($action == 'update') $bookmark->fetch($_POST["id"]);
+	if ($action == 'update') $bookmark->fetch(GETPOST("id",'int'));
 	// Check if null because user not admin can't set an user and send empty value here.
 	if(!empty($userid))
 		$bookmark->fk_user=$userid;
@@ -217,7 +217,7 @@ if ($id > 0 && ! preg_match('/^add/i',$action))
 
 	print '<table class="border" width="100%">';
 
-	print '<tr><td width="25%">'.$langs->trans("Ref").'</td><td>'.$bookmark->ref.'</td></tr>';
+	print '<tr><td class="titlefield">'.$langs->trans("Ref").'</td><td>'.$bookmark->ref.'</td></tr>';
 
 	print '<tr><td>';
 	if ($action == 'edit') {
@@ -231,7 +231,7 @@ if ($id > 0 && ! preg_match('/^add/i',$action))
 	}
 
 	print '</td><td>';
-	if ($action == 'edit') print '<input class="flat" name="title" size="30" value="'.(isset($_POST["title"])?$_POST["title"]:$bookmark->title).'">';
+	if ($action == 'edit') print '<input class="flat minwidth200" name="title" value="'.(isset($_POST["title"])?GETPOST("title",'',2):$bookmark->title).'">';
 	else print $bookmark->title;
 	print '</td></tr>';
 
@@ -301,6 +301,8 @@ if ($id > 0 && ! preg_match('/^add/i',$action))
 	}
 
 
+	// Buttons
+	
 	print "<div class=\"tabsAction\">\n";
 
 	// Edit

+ 2 - 2
htdocs/cache.manifest

@@ -33,5 +33,5 @@ NETWORK:
 # If the browser is unable to retrieve the original content, the fallback resource will be used.
 # In the example above, we display a static image in case the dynamic one is unavailable.
 FALLBACK: 
-#/ public/offline.php
-#theme/amarok/img/* theme/eldy/img/
+#/ public/notice.php
+#theme/eldy/img/* theme/md/img/*

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

@@ -33,7 +33,7 @@ $langs->load("bills");
 		largeur = 600;
 		hauteur = 500;
 		opt = 'width='+largeur+', height='+hauteur+', left='+(screen.width - largeur)/2+', top='+(screen.height-hauteur)/2+'';
-		window.open('validation_ticket.php?facid=<?php echo $_GET['facid']; ?>', '<?php echo $langs->trans('PrintTicket') ?>', opt);
+		window.open('validation_ticket.php?facid=<?php echo GETPOST('facid','int'); ?>', '<?php echo $langs->trans('PrintTicket') ?>', opt);
 	}
 
 	popupTicket();

+ 5 - 8
htdocs/categories/class/api_categories.class.php

@@ -157,7 +157,7 @@ class Categories extends DolibarrApi
             }
         }
         else {
-            throw new RestException(503, 'Error when retrieve category list : '.$category_static->error);
+            throw new RestException(503, 'Error when retrieve category list : '.$db->lasterror());
         }
         if( ! count($obj_ret)) {
             throw new RestException(404, 'No category found');
@@ -209,7 +209,7 @@ class Categories extends DolibarrApi
         $sql.= ' AND s.rowid = sub.fk_categorie';
         $sql.= ' AND sub.'.$subcol_name.' = '.$item;
 
-        $nbtotalofrecords = 0;
+        $nbtotalofrecords = -1;
         if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
         {
             $result = $db->query($sql);
@@ -243,7 +243,7 @@ class Categories extends DolibarrApi
             }
         }
         else {
-            throw new RestException(503, 'Error when retrieve category list : '.$category_static->error);
+            throw new RestException(503, 'Error when retrieve category list : '.$db->lasterror());
         }
         if( ! count($obj_ret)) {
             throw new RestException(404, 'No category found');
@@ -269,8 +269,8 @@ class Categories extends DolibarrApi
         foreach($request_data as $field => $value) {
             $this->category->$field = $value;
         }
-        if($this->category->create(DolibarrApiAccess::$user) < 0) {
-            throw new RestException(503, 'Error when create category : '.$this->category->error);
+        if ($this->category->create(DolibarrApiAccess::$user) < 0) {
+            throw new RestException(500, 'Error when creating category', array_merge(array($this->category->error), $this->category->errors));
         }
         return $this->category->id;
     }
@@ -346,9 +346,6 @@ class Categories extends DolibarrApi
      *
      * @param   Categorie  $object    Object to clean
      * @return    array    Array of cleaned object properties
-     *
-     * @todo use an array for properties to clean
-     *
      */
     function _cleanObjectDatas($object) {
     

+ 7 - 7
htdocs/categories/class/api_deprecated_category.class.php

@@ -124,7 +124,7 @@ class CategoryApi extends DolibarrApi
         $sql.= ' WHERE s.entity IN ('.getEntity('category', 1).')';
         $sql.= ' AND s.type='.array_search($type,CategoryApi::$TYPES);
 
-        $nbtotalofrecords = 0;
+        $nbtotalofrecords = -1;
         if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
         {
             $result = $db->query($sql);
@@ -152,13 +152,13 @@ class CategoryApi extends DolibarrApi
                 $obj = $db->fetch_object($result);
                 $category_static = new Categorie($db);
                 if($category_static->fetch($obj->rowid)) {
-                    $obj_ret[] = parent::_cleanObjectDatas($category_static);
+                    $obj_ret[] = $this->_cleanObjectDatas($category_static);
                 }
                 $i++;
             }
         }
         else {
-            throw new RestException(503, 'Error when retrieve category list : '.$category_static->error);
+            throw new RestException(503, 'Error when retrieve category list : '.$db->lasterror());
         }
         if( ! count($obj_ret)) {
             throw new RestException(404, 'No category found');
@@ -205,7 +205,7 @@ class CategoryApi extends DolibarrApi
         $sql.= ' AND s.rowid = sub.fk_categorie';
         $sql.= ' AND sub.'.$subcol_name.' = '.$item;
 
-        $nbtotalofrecords = 0;
+        $nbtotalofrecords = -1;
         if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
         {
             $result = $db->query($sql);
@@ -233,13 +233,13 @@ class CategoryApi extends DolibarrApi
                 $obj = $db->fetch_object($result);
                 $category_static = new Categorie($db);
                 if($category_static->fetch($obj->rowid)) {
-                    $obj_ret[] = parent::_cleanObjectDatas($category_static);
+                    $obj_ret[] = $this->_cleanObjectDatas($category_static);
                 }
                 $i++;
             }
         }
         else {
-            throw new RestException(503, 'Error when retrieve category list : '.$category_static->error);
+            throw new RestException(503, 'Error when retrieve category list : '.$db->lasterror());
         }
         if( ! count($obj_ret)) {
             throw new RestException(404, 'No category found');
@@ -395,7 +395,7 @@ class CategoryApi extends DolibarrApi
             $this->category->$field = $value;
         }
         if($this->category->create(DolibarrApiAccess::$user) < 0) {
-            throw new RestException(503, 'Error when create category : '.$this->category->error);
+            throw new RestException(500, 'Error when create category : '.$this->category->error);
         }
         return $this->category->id;
     }

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

@@ -49,8 +49,8 @@ class Categorie extends CommonObject
 	const TYPE_MEMBER = 3;     // TODO Replace this value with 'member'
 	const TYPE_CONTACT = 4;    // TODO Replace this value with 'contact'
 	const TYPE_USER = 4;       // categorie contact and user are same !   TODO Replace this value with 'user'
-    const TYPE_ACCOUNT = 5;    // for bank account TODO Replace this value with 'account'
-    const TYPE_PROJECT = 6;
+    	const TYPE_ACCOUNT = 5;    // for bank account TODO Replace this value with 'account'
+    	const TYPE_PROJECT = 6;
 
 	/**
 	 * @var array ID mapping from type string
@@ -131,17 +131,17 @@ class Categorie extends CommonObject
 	public $element='category';
 	public $table_element='categories';
 
-	var $fk_parent;
-	var $label;
-	var $description;
+	public $fk_parent;
+	public $label;
+	public $description;
 	/**
 	 * @var string     Color
 	 */
-	var $color;
+	public $color;
 	/**
 	 * @var ???
 	 */
-	var $socid;
+	public $socid;
 	/**
 	 * @var int Category type
 	 *
@@ -154,10 +154,10 @@ class Categorie extends CommonObject
 	 * @see Categorie::TYPE_ACCOUNT
 	 * @see Categorie::TYPE_PROJECT
 	 */
-	var $type;
+	public $type;
 
-	var $cats=array();			// Categories table in memory
-	var $motherof=array();
+	public $cats = array();			// Categories table in memory
+	public $motherof = array();
 
 	/**
 	 *	Constructor

+ 1 - 1
htdocs/categories/traduction.php

@@ -277,7 +277,7 @@ if ($action == 'add' && ($user->rights->produit->creer || $user->rights->service
 	print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
 	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
 	print '<input type="hidden" name="action" value="vadd">';
-	print '<input type="hidden" name="id" value="'.$_GET["id"].'">';
+	print '<input type="hidden" name="id" value="'.$id.'">';
 
 	print '<table class="border" width="100%">';
 	print '<tr><td class="fieldtitlecreate fieldrequired">'.$langs->trans('Translation').'</td><td>';

+ 14 - 9
htdocs/comm/action/class/api_agendaevents.class.php

@@ -94,7 +94,7 @@ class AgendaEvents extends DolibarrApi
      * @param int		$limit		Limit for list
      * @param int		$page		Page number
      * @param string   	$user_ids   User ids filter field (owners of event). Example: '1' or '1,2,3'          {@pattern /^[0-9,]*$/i}
-     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
+     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'%dol%') and (t.date_creation:<:'20160101')"
      * @return  array               Array of Agenda Events objects
      */
     function index($sortfield = "t.id", $sortorder = 'ASC', $limit = 0, $page = 0, $user_ids = 0, $sqlfilters = '') {
@@ -102,13 +102,19 @@ class AgendaEvents extends DolibarrApi
         
         $obj_ret = array();
 
-        // case of external user, $societe param is ignored and replaced by user's socid
-        //$socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $societe;
-            
+        // case of external user
+        $socid = 0;
+        if (! empty(DolibarrApiAccess::$user->societe_id)) $socid = DolibarrApiAccess::$user->societe_id;
+        
+        // If the internal user must only see his customers, force searching by him
+        $search_sale = 0;
+        if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id;
+        
         $sql = "SELECT t.id as rowid";
         $sql.= " FROM ".MAIN_DB_PREFIX."actioncomm as t";
         $sql.= ' WHERE t.entity IN ('.getEntity('agenda', 1).')';
         if ($user_ids) $sql.=" AND t.fk_user_action IN (".$user_ids.")";
+        if ($socid > 0) $sql.= " AND t.fk_soc = ".$socid;
         // Insert sale filter
         if ($search_sale > 0)
         {
@@ -146,13 +152,13 @@ class AgendaEvents extends DolibarrApi
                 $obj = $db->fetch_object($result);
                 $actioncomm_static = new ActionComm($db);
                 if($actioncomm_static->fetch($obj->rowid)) {
-                    $obj_ret[] = parent::_cleanObjectDatas($actioncomm_static);
+                    $obj_ret[] = $this->_cleanObjectDatas($actioncomm_static);
                 }
                 $i++;
             }
         }
         else {
-            throw new RestException(503, 'Error when retrieve Agenda Event list');
+            throw new RestException(503, 'Error when retrieve Agenda Event list : '.$db->lasterror());
         }
         if( ! count($obj_ret)) {
             throw new RestException(404, 'No Agenda Event found');
@@ -188,9 +194,8 @@ class AgendaEvents extends DolibarrApi
           }
           $this->expensereport->lines = $lines;
         }*/
-        if ($this->actioncomm->create(DolibarrApiAccess::$user) <= 0) {
-            $errormsg = $this->actioncomm->error;
-            throw new RestException(500, $errormsg ? $errormsg : "Error while creating actioncomm");
+        if ($this->actioncomm->create(DolibarrApiAccess::$user) < 0) {
+            throw new RestException(500, "Error creating event", array_merge(array($this->actioncomm->error), $this->actioncomm->errors));
         }
         
         return $this->actioncomm->id;

+ 2 - 2
htdocs/comm/action/listactions.php

@@ -245,7 +245,7 @@ if ($datestart > 0) $sql.= " AND a.datep BETWEEN '".$db->idate($datestart)."' AN
 if ($dateend > 0) $sql.= " AND a.datep2 BETWEEN '".$db->idate($dateend)."' AND '".$db->idate($dateend+3600*24-1)."'";
 $sql.= $db->order($sortfield,$sortorder);
 
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
     $result = $db->query($sql);
@@ -368,7 +368,7 @@ if ($resql)
 	print '<td class="liste_titre"></td>';
 	print '<td class="liste_titre"></td>';
 	print '<td class="liste_titre"></td>';
-    print '<td></td>';
+    print '<td class="liste_titre"></td>';
 	// Action column
 	print '<td class="liste_titre" align="middle">';
 	$searchpitco=$form->showFilterAndCheckAddButtons(0);

+ 2 - 1
htdocs/comm/action/peruser.php

@@ -590,6 +590,7 @@ echo '</form>';
 //print "begin_d=".$begin_d." end_d=".$end_d;
 
 
+echo '<div class="div-table-responsive">';
 echo '<table width="100%" class="noborder nocellnopadd cal_month">';
 
 echo '<tr class="liste_titre">';
@@ -766,7 +767,7 @@ foreach ($usernames as $username)
 }
 
 echo "</table>\n";
-
+echo '</div>';
 
 if (! empty($conf->global->AGENDA_USE_EVENT_TYPE))
 {

+ 1 - 1
htdocs/comm/action/rapport/index.php

@@ -85,7 +85,7 @@ $sql.= ' AND a.entity IN ('.getEntity('agenda', 1).')';
 $sql.= " GROUP BY year, month, df";
 $sql.= " ORDER BY year DESC, month DESC, df DESC";
 
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
     $result = $db->query($sql);

+ 1 - 7
htdocs/comm/card.php

@@ -247,12 +247,6 @@ if ($id > 0)
 		print '</tr>';
 	}
 
-	// Skype
-  	if (! empty($conf->skype->enabled))
-  	{
-		print '<td>'.$langs->trans('Skype').'</td><td>'.dol_print_skype($object->skype,0,$object->id,'AC_SKYPE').'</td></tr>';
-  	}
-
 	// Assujeti a TVA ou pas
 	print '<tr>';
 	print '<td class="nowrap">'.$langs->trans('VATIsUsed').'</td><td>';
@@ -592,7 +586,7 @@ if ($id > 0)
                 $propal_static->total_tva = $objp->total_tva;
                 $propal_static->total_ttc = $objp->total_ttc;
                 print $propal_static->getNomUrl(1);
-                if ( ($db->jdate($objp->dp) < ($now - $conf->propal->cloture->warning_delay)) && $objp->fk_statut == 1 ) {
+                if ( ($db->jdate($objp->datelimite) < ($now - $conf->propal->cloture->warning_delay)) && $objp->fk_statut == 1 ) {
                     print " ".img_warning();
                 }
 				print '</td><td align="right" width="80px">'.dol_print_date($db->jdate($objp->dp),'day')."</td>\n";

+ 6 - 3
htdocs/comm/contact.php

@@ -125,6 +125,8 @@ if ($resql)
 	$title = (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("ListOfContacts") : $langs->trans("ListOfContactsAddresses"));
 	print_barre_liste($title.($label?" (".$label.")":""),$page, $_SERVER["PHP_SELF"], $param,$sortfield,$sortorder,"",$num);
 
+	print '<form action="'.$_SERVER["PHP_SELF"].'?type='.GETPOST("type", "alpha").'" method="GET">';
+	
 	print '<table class="liste" width="100%">';
 	print '<tr class="liste_titre">';
 	print_liste_field_titre($langs->trans("Lastname"),$_SERVER["PHP_SELF"],"p.name", $begin, $param,"",$sortfield,$sortorder);
@@ -134,7 +136,6 @@ if ($resql)
 	print_liste_field_titre($langs->trans("Phone"));
 	print "</tr>\n";
 
-	print '<form action="'.$_SERVER["PHP_SELF"].'?type='.$_GET["type"].'" method="GET">';
 	print '<tr class="liste_titre">';
 	print '<td class="liste_titre"><input class="flat" name="search_lastname" size="12" value="'.$search_lastname.'"></td>';
 	print '<td class="liste_titre"><input class="flat" name="search_firstname" size="12"  value="'.$search_firstname.'"></td>';
@@ -142,7 +143,6 @@ if ($resql)
 	print '<td class="liste_titre">&nbsp;</td>';
 	print '<td class="liste_titre" align="right"><input type="image" class="liste_titre" src="'.img_picto($langs->trans("Search"),'search.png','','',1).'" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'"></td>';
 	print "</tr>\n";
-	print '</form>';
 
 	$var=True;
 	$i = 0;
@@ -167,7 +167,10 @@ if ($resql)
 		print "</tr>\n";
 		$i++;
 	}
-	print "</table></p>";
+	print "</table>";
+	
+	print '</form>';
+	
 	$db->free($resql);
 }
 else

+ 1 - 1
htdocs/comm/index.php

@@ -385,7 +385,7 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande
     if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
     $sql.= " WHERE cf.fk_soc = s.rowid";
     $sql.= " AND cf.fk_statut = 0";
-    $sql.= " AND cf.entity IN (".getEntity('commande_fournisseur', 1).")";
+    $sql.= " AND cf.entity IN (".getEntity('supplier_order', 1).")";
     if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
     if ($socid)	$sql.= " AND cf.fk_soc = ".$socid;
 

+ 13 - 10
htdocs/comm/mailing/advtargetemailing.php

@@ -189,6 +189,10 @@ if ($action == 'add') {
 			}
 		}
 
+		if ($array_query['type_of_target'] == 2 || $array_query['type_of_target'] == 4) {
+			$user_contact_query = true;
+		}
+
 		if (preg_match("/^type_of_target/", $key)) {
 			$array_query[$key] = GETPOST($key);
 		}
@@ -203,8 +207,8 @@ if ($action == 'add') {
 		$advTarget->thirdparty_lines = array ();
 	}*/
 
-	if ($user_contact_query && ($array_query['type_of_target'] == 1 || $array_query['type_of_target'] == 2)) {
-		$result = $advTarget->query_contact($array_query);
+	if ($user_contact_query && ($array_query['type_of_target'] == 1 || $array_query['type_of_target'] == 2 || $array_query['type_of_target'] == 4)) {
+		$result = $advTarget->query_contact($array_query, 1);
 		if ($result < 0) {
 			setEventMessage($advTarget->error, 'errors');
 		}
@@ -889,6 +893,11 @@ if ($object->fetch($id) >= 0) {
 			dol_include_once('/core/class/extrafields.class.php');
 			$extrafields = new ExtraFields($db);
 			$extralabels = $extrafields->fetch_name_optionals_label('socpeople');
+            foreach($extrafields->attribute_type as $key=>&$value) {
+                if($value == 'radio')$value = 'select';
+            }
+
+
 			foreach ( $extralabels as $key => $val ) {
 
 				print '<tr><td>' . $extrafields->attribute_label[$key];
@@ -900,8 +909,8 @@ if ($object->fetch($id) >= 0) {
 					print '<input type="text" name="options_' . $key . '_cnct"/></td><td>' . "\n";
 					print $form->textwithpicto('', $langs->trans("AdvTgtSearchTextHelp"), 1, 'help');
 				} elseif (($extrafields->attribute_type[$key] == 'int') || ($extrafields->attribute_type[$key] == 'double')) {
-					print $langs->trans("AdvTgtMinVal") . '<input type="text" name="options' . $key . '_min_cnct"/>';
-					print $langs->trans("AdvTgtMaxVal") . '<input type="text" name="options' . $key . '_max_cnct"/>';
+					print $langs->trans("AdvTgtMinVal") . '<input type="text" name="options_' . $key . '_min_cnct"/>';
+					print $langs->trans("AdvTgtMaxVal") . '<input type="text" name="options_' . $key . '_max_cnct"/>';
 					print '</td><td>' . "\n";
 					print $form->textwithpicto('', $langs->trans("AdvTgtSearchIntHelp"), 1, 'help');
 				} elseif (($extrafields->attribute_type[$key] == 'date') || ($extrafields->attribute_type[$key] == 'datetime')) {
@@ -967,12 +976,6 @@ if ($object->fetch($id) >= 0) {
 		print '</form>';
 		print '<br>';
 	}
-
-
-	if (empty($conf->mailchimp->enabled) || (! empty($conf->mailchimp->enabled) && $object->statut != 3))
-	{
-	    // List of recipients (TODO Move code of page cibles.php into a .tpl.php file and make an include here to avoid duplicate content)
-	}
 }
 
 llxFooter();

+ 22 - 12
htdocs/comm/mailing/card.php

@@ -681,9 +681,9 @@ if ($action == 'create')
 	dol_fiche_head();
 
 	print '<table class="border" width="100%">';
-	print '<tr><td class="fieldrequired titlefieldcreate">'.$langs->trans("MailTitle").'</td><td><input class="flat" name="titre" size="40" value="'.$_POST['titre'].'"></td></tr>';
-	print '<tr><td class="fieldrequired">'.$langs->trans("MailFrom").'</td><td><input class="flat" name="from" size="40" value="'.$conf->global->MAILING_EMAIL_FROM.'"></td></tr>';
-	print '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td><input class="flat" name="errorsto" size="40" value="'.(!empty($conf->global->MAILING_EMAIL_ERRORSTO)?$conf->global->MAILING_EMAIL_ERRORSTO:$conf->global->MAIN_MAIL_ERRORS_TO).'"></td></tr>';
+	print '<tr><td class="fieldrequired titlefieldcreate">'.$langs->trans("MailTitle").'</td><td><input class="flat minwidth200" name="titre" value="'.dol_escape_htmltag(GETPOST('titre')).'"></td></tr>';
+	print '<tr><td class="fieldrequired">'.$langs->trans("MailFrom").'</td><td><input class="flat minwidth200" name="from" value="'.$conf->global->MAILING_EMAIL_FROM.'"></td></tr>';
+	print '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td><input class="flat minwidth200" name="errorsto" value="'.(!empty($conf->global->MAILING_EMAIL_ERRORSTO)?$conf->global->MAILING_EMAIL_ERRORSTO:$conf->global->MAIN_MAIL_ERRORS_TO).'"></td></tr>';
 
 	// Other attributes
 	$parameters=array();
@@ -697,7 +697,7 @@ if ($action == 'create')
 	print '</br><br>';
 
 	print '<table class="border" width="100%">';
-	print '<tr><td class="fieldrequired titlefieldcreate">'.$langs->trans("MailTopic").'</td><td><input class="flat" name="sujet" size="60" value="'.$_POST['sujet'].'"></td></tr>';
+	print '<tr><td class="fieldrequired titlefieldcreate">'.$langs->trans("MailTopic").'</td><td><input class="flat minwidth200" name="sujet" value="'.dol_escape_htmltag(GETPOST('sujet')).'"></td></tr>';
 	print '<tr><td>'.$langs->trans("BackgroundColorByDefault").'</td><td colspan="3">';
 	print $htmlother->selectColor($_POST['bgcolor'],'bgcolor','new_mailing',0);
 	print '</td></tr>';
@@ -756,10 +756,12 @@ else
 				$sendingmode=$conf->global->MAIN_MAIL_SENDMODE;
 				if (empty($sendingmode)) $sendingmode='mail';	// If not defined, we use php mail function
 
+				// MAILING_NO_USING_PHPMAIL may be defined or not
+				// MAILING_LIMIT_SENDBYWEB is always defined to something != 0, MAILING_LIMIT_SENDBYCLI may be defined ot not.
 				if (! empty($conf->global->MAILING_NO_USING_PHPMAIL) && $sendingmode == 'mail')
 				{
 					// EMailing feature may be a spam problem, so when you host several users/instance, having this option may force each user to use their own SMTP agent.
-					// You ensure that every user is using its own SMTP server.
+					// You ensure that every user is using its own SMTP server when using the mass emailing module.
 					$linktoadminemailbefore='<a href="'.DOL_URL_ROOT.'/admin/mails.php">';
 					$linktoadminemailend='</a>';
 					setEventMessages($langs->trans("MailSendSetupIs", $listofmethods[$sendingmode]), null, 'warnings');
@@ -767,19 +769,27 @@ else
 					if (! empty($conf->global->MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS)) setEventMessages($langs->trans("MailSendSetupIs3", $conf->global->MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS), null, 'warnings');
 					$_GET["action"]='';
 				}
-				else if (empty($conf->global->MAILING_LIMIT_SENDBYWEB))
+				else if ($conf->global->MAILING_LIMIT_SENDBYWEB == '-1')
 				{
-					// Pour des raisons de securite, on ne permet pas cette fonction via l'IHM,
-					// on affiche donc juste un message
-					setEventMessages($langs->trans("MailingNeedCommand"), null, 'warnings');
+				    if (! empty($conf->global->MAILING_LIMIT_WARNING_PHPMAIL) && $sendingmode == 'mail') setEventMessages($conf->global->MAILING_LIMIT_WARNING_PHPMAIL, null, 'warnings');
+				    if (! empty($conf->global->MAILING_LIMIT_WARNING_NOPHPMAIL) && $sendingmode != 'mail') setEventMessages($conf->global->MAILING_LIMIT_WARNING_NOPHPMAIL, null, 'warnings');
+				    
+					// The feature is forbidden from GUI, we show just message to use from command line.
+				    setEventMessages($langs->trans("MailingNeedCommand"), null, 'warnings');
 					setEventMessages('<textarea cols="60" rows="'.ROWS_1.'" wrap="soft">php ./scripts/emailings/mailing-send.php '.$object->id.'</textarea>', null, 'warnings');
-					setEventMessages($langs->trans("MailingNeedCommand2"), null, 'warnings');
+					if ($conf->file->mailing_limit_sendbyweb != '-1')  // MAILING_LIMIT_SENDBYWEB was set to -1 in database, but it is allowed ot increase it.
+					{
+					   setEventMessages($langs->trans("MailingNeedCommand2"), null, 'warnings');  // You can send online with constant...
+					}
 					$_GET["action"]='';
 				}
 				else
 				{
-					$text='';
-                    if ($conf->file->mailing_limit_sendbyweb == 0)
+				    if (! empty($conf->global->MAILING_LIMIT_WARNING_PHPMAIL) && $sendingmode == 'mail') setEventMessages($conf->global->MAILING_LIMIT_WARNING_PHPMAIL, null, 'warnings');
+				    if (! empty($conf->global->MAILING_LIMIT_WARNING_NOPHPMAIL) && $sendingmode != 'mail') setEventMessages($conf->global->MAILING_LIMIT_WARNING_NOPHPMAIL, null, 'warnings');
+				    
+				    $text='';
+				    if ($conf->global->MAILING_LIMIT_SENDBYCLI >= 0)
                     {
                     	$text.=$langs->trans("MailingNeedCommand");
                     	$text.='<br><textarea cols="60" rows="'.ROWS_2.'" wrap="soft">php ./scripts/emailings/mailing-send.php '.$object->id.' '.$user->login.'</textarea>';

+ 1 - 1
htdocs/comm/mailing/cibles.php

@@ -412,7 +412,7 @@ if ($object->fetch($id) >= 0)
 	$sql .= $db->order($sortfield,$sortorder);
 
 	// Count total nb of records
-	$nbtotalofrecords = 0;
+	$nbtotalofrecords = -1;
 	if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 	{
 	    $result = $db->query($sql);

+ 117 - 15
htdocs/comm/mailing/class/advtargetemailing.class.php

@@ -64,16 +64,19 @@ class AdvanceTargetingMailing extends CommonObject
 
 		$this->db = $db;
 
-		$this->select_target_type = array('2'=>$langs->trans('Contacts'),'1'=>$langs->trans('Contacts').'+'.$langs->trans('ThirdParty'),
-			'3'=>$langs->trans('ThirdParty'),
-			);
-		$this->type_statuscommprospect=array(
-			-1=>$langs->trans("StatusProspect-1"),
-			0=>$langs->trans("StatusProspect0"),
-			1=>$langs->trans("StatusProspect1"),
-			2=>$langs->trans("StatusProspect2"),
-			3=>$langs->trans("StatusProspect3"));
-
+		$this->select_target_type = array(
+				'2' => $langs->trans('Contacts'),
+				'1' => $langs->trans('Contacts') . '+' . $langs->trans('ThirdParty'),
+				'3' => $langs->trans('ThirdParty'),
+				'4' => $langs->trans('ContactsWithThirdpartyFilter')
+		);
+		$this->type_statuscommprospect = array(
+				- 1 => $langs->trans("StatusProspect-1"),
+				0 => $langs->trans("StatusProspect0"),
+				1 => $langs->trans("StatusProspect1"),
+				2 => $langs->trans("StatusProspect2"),
+				3 => $langs->trans("StatusProspect3")
+		);
 
 		return 1;
 	}
@@ -492,7 +495,7 @@ class AdvanceTargetingMailing extends CommonObject
 			}
 			if (!empty($arrayquery['cust_mothercompany'])) {
 				$str=$this->transformToSQL('nom',$arrayquery['cust_mothercompany']);
-				$sqlwhere[]= " (t.parent IN (SELECT rowid FROM " . MAIN_DB_PREFIX . "societe WHERE ('.$str.')))";
+				$sqlwhere[]= " (t.parent IN (SELECT rowid FROM " . MAIN_DB_PREFIX . "societe WHERE (".$str.")))";
 			}
 			if (!empty($arrayquery['cust_status']) && count($arrayquery['cust_status'])>0) {
 				$sqlwhere[]= " (t.status IN (".implode(',',$arrayquery['cust_status'])."))";
@@ -603,9 +606,10 @@ class AdvanceTargetingMailing extends CommonObject
 	 * Load object in memory from database
 	 *
 	 * 	@param		array		$arrayquery	All element to Query
+	 * 	@param		int			$withThirdpartyFilter	add contact with tridparty filter
 	 * 	@return		int			<0 if KO, >0 if OK
 	 */
-	function query_contact($arrayquery)
+	function query_contact($arrayquery, $withThirdpartyFilter = 0)
 	{
 		global $langs,$conf;
 
@@ -614,6 +618,11 @@ class AdvanceTargetingMailing extends CommonObject
 		$sql.= " FROM " . MAIN_DB_PREFIX . "socpeople as t";
 		$sql.= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "socpeople_extrafields as te ON te.fk_object=t.rowid ";
 
+		if (! empty($withThirdpartyFilter)) {
+			$sql .= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "societe as ts ON ts.rowid=t.fk_soc";
+			$sql .= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "societe_extrafields as tse ON tse.fk_object=ts.rowid ";
+		}
+
 		$sqlwhere=array();
 
 		$sqlwhere[]= 't.entity IN ('.getEntity('socpeople',1).')';
@@ -694,14 +703,107 @@ class AdvanceTargetingMailing extends CommonObject
 
 				}
 
+				if (! empty($withThirdpartyFilter)) {
+					if (array_key_exists('cust_saleman', $arrayquery)) {
+						$sql.= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as saleman ON saleman.fk_soc=ts.rowid ";
+					}
+					if (array_key_exists('cust_categ', $arrayquery)) {
+						$sql.= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "categorie_societe as custcateg ON custcateg.fk_soc=ts.rowid ";
+					}
 
-			}
+					if (!empty($arrayquery['cust_name'])) {
 
-			if (count($sqlwhere)>0)	$sql.= " WHERE ".implode(" AND ",$sqlwhere);
+						$sqlwhere[]= $this->transformToSQL('ts.nom',$arrayquery['cust_name']);
+					}
+					if (!empty($arrayquery['cust_code'])) {
+						$sqlwhere[]= $this->transformToSQL('ts.code_client',$arrayquery['cust_code']);
+					}
+					if (!empty($arrayquery['cust_adress'])) {
+						$sqlwhere[]= $this->transformToSQL('ts.address',$arrayquery['cust_adress']);
+					}
+					if (!empty($arrayquery['cust_zip'])) {
+						$sqlwhere[]= $this->transformToSQL('ts.zip',$arrayquery['cust_zip']);
+					}
+					if (!empty($arrayquery['cust_city'])) {
+						$sqlwhere[]= $this->transformToSQL('ts.town',$arrayquery['cust_city']);
+					}
+					if (!empty($arrayquery['cust_mothercompany'])) {
+						$str=$this->transformToSQL('nom',$arrayquery['cust_mothercompany']);
+						$sqlwhere[]= " (ts.parent IN (SELECT rowid FROM " . MAIN_DB_PREFIX . "societe WHERE (".$str.")))";
+					}
+					if (!empty($arrayquery['cust_status']) && count($arrayquery['cust_status'])>0) {
+						$sqlwhere[]= " (ts.status IN (".implode(',',$arrayquery['cust_status'])."))";
+					}
+					if (!empty($arrayquery['cust_typecust']) && count($arrayquery['cust_typecust'])>0) {
+						$sqlwhere[]= " (ts.client IN (".implode(',',$arrayquery['cust_typecust'])."))";
+					}
+					if (!empty($arrayquery['cust_comm_status']) && count($arrayquery['cust_comm_status']>0)) {
+						$sqlwhere[]= " (ts.fk_stcomm IN (".implode(',',$arrayquery['cust_comm_status'])."))";
+					}
+					if (!empty($arrayquery['cust_prospect_status']) && count($arrayquery['cust_prospect_status'])>0) {
+						$sqlwhere[]= " (ts.fk_prospectlevel IN ('".implode("','",$arrayquery['cust_prospect_status'])."'))";
+					}
+					if (!empty($arrayquery['cust_typeent']) && count($arrayquery['cust_typeent'])>0) {
+						$sqlwhere[]= " (ts.fk_typent IN (".implode(',',$arrayquery['cust_typeent'])."))";
+					}
+					if (!empty($arrayquery['cust_saleman']) && count($arrayquery['cust_saleman'])>0) {
+						$sqlwhere[]= " (saleman.fk_user IN (".implode(',',$arrayquery['cust_saleman'])."))";
+					}
+					if (!empty($arrayquery['cust_country']) && count($arrayquery['cust_country'])>0) {
+						$sqlwhere[]= " (ts.fk_pays IN (".implode(',',$arrayquery['cust_country'])."))";
+					}
+					if (!empty($arrayquery['cust_effectif_id']) && count($arrayquery['cust_effectif_id'])>0) {
+						$sqlwhere[]= " (ts.fk_effectif IN (".implode(',',$arrayquery['cust_effectif_id'])."))";
+					}
+					if (!empty($arrayquery['cust_categ']) && count($arrayquery['cust_categ'])>0) {
+						$sqlwhere[]= " (custcateg.fk_categorie IN (".implode(',',$arrayquery['cust_categ'])."))";
+					}
+					if (!empty($arrayquery['cust_language']) && count($arrayquery['cust_language'])>0) {
+						$sqlwhere[]= " (ts.default_lang IN ('".implode("','",$arrayquery['cust_language'])."'))";
+					}
 
+					//Standard Extrafield feature
+					if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) {
+						// fetch optionals attributes and labels
+						dol_include_once('/core/class/extrafields.class.php');
+						$extrafields = new ExtraFields($this->db);
+						$extralabels=$extrafields->fetch_name_optionals_label('societe');
+
+						foreach($extralabels as $key=>$val) {
+
+							if (($extrafields->attribute_type[$key] == 'varchar') ||
+									($extrafields->attribute_type[$key] == 'text')) {
+										if (!empty($arrayquery['options_'.$key])) {
+											$sqlwhere[]= " (tse.".$key." LIKE '".$arrayquery['options_'.$key]."')";
+										}
+									} elseif (($extrafields->attribute_type[$key] == 'int') ||
+											($extrafields->attribute_type[$key] == 'double')) {
+												if (!empty($arrayquery['options_'.$key.'_max'])) {
+													$sqlwhere[]= " (tse.".$key." >= ".$arrayquery['options_'.$key.'_max']." AND tse.".$key." <= ".$arrayquery['options_'.$key.'_min'].")";
+												}
+									} else if (($extrafields->attribute_type[$key] == 'date') ||
+											($extrafields->attribute_type[$key] == 'datetime')) {
+												if (!empty($arrayquery['options_'.$key.'_end_dt'])){
+													$sqlwhere[]= " (tse.".$key." >= '".$this->db->idate($arrayquery['options_'.$key.'_st_dt'])."' AND tse.".$key." <= '".$this->db->idate($arrayquery['options_'.$key.'_end_dt'])."')";
+												}
+											}else if ($extrafields->attribute_type[$key] == 'boolean') {
+												if ($arrayquery['options_'.$key]!=''){
+													$sqlwhere[]= " (tse.".$key." = ".$arrayquery['options_'.$key].")";
+												}
+											}else{
+												if (is_array($arrayquery['options_'.$key])) {
+													$sqlwhere[]= " (tse.".$key." IN ('".implode("','",$arrayquery['options_'.$key])."'))";
+												} elseif (!empty($arrayquery['options_'.$key])) {
+													$sqlwhere[]= " (tse.".$key." LIKE '".$arrayquery['options_'.$key]."')";
+												}
+											}
+						}
+					}
+				}
+			}
+			if (count($sqlwhere)>0)	$sql.= " WHERE ".implode(" AND ",$sqlwhere);
 		}
 
-
 		dol_syslog(get_class($this) . "::query_contact sql=" . $sql, LOG_DEBUG);
 		$resql = $this->db->query($sql);
 		if ($resql) {

+ 57 - 31
htdocs/comm/propal/card.php

@@ -686,6 +686,7 @@ if (empty($reshook))
 		$predef='';
 		$product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
 		$price_ht = GETPOST('price_ht');
+		$price_ht_devise = GETPOST('multicurrency_price_ht');
 		$prod_entry_mode = GETPOST('prod_entry_mode');
 		if ($prod_entry_mode == 'free')
 		{
@@ -718,7 +719,7 @@ if (empty($reshook))
 			$error ++;
 		}
 
-		if ($prod_entry_mode == 'free' && empty($idprod) && $price_ht == '') 	// Unit price can be 0 but not ''. Also price can be negative for proposal.
+		if ($prod_entry_mode == 'free' && empty($idprod) && $price_ht == '' && $price_ht_devise == '') 	// Unit price can be 0 but not ''. Also price can be negative for proposal.
 		{
 			setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
 			$error ++;
@@ -878,6 +879,7 @@ if (empty($reshook))
 				$type = GETPOST('type');
 
 				$fk_unit = GETPOST('units', 'alpha');
+				$pu_ht_devise = price2num($price_ht_devise, 'MU');
 			}
 
 			// Margin
@@ -900,7 +902,7 @@ if (empty($reshook))
 				setEventMessages($mesg, null, 'errors');
 			} else {
 				// Insert line
-				$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_options, $fk_unit);
+				$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_options, $fk_unit, '', 0, $pu_ht_devise);
 
 				if ($result > 0) {
 					$db->commit();
@@ -980,6 +982,8 @@ if (empty($reshook))
 		$fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : '');
 		$buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : '');    // If buying_price is '0', we muste keep this value
 
+		$pu_ht_devise = GETPOST('multicurrency_subprice');
+
 		$date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
 		$date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
 
@@ -1031,7 +1035,19 @@ if (empty($reshook))
 		if (! $error) {
 			$db->begin();
 
-			$result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_options, $_POST["units"]);
+			if (empty($user->rights->margins->creer))
+			{
+				foreach ($object->lines as &$line)
+				{
+					if ($line->id == GETPOST('lineid'))
+					{
+						$fournprice = $line->fk_fournprice;
+						$buyingprice = $line->pa_ht;
+						break;
+					}
+				}
+			}
+			$result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_options, $_POST["units"], $pu_ht_devise);
 
 			if ($result >= 0) {
 				$db->commit();
@@ -1090,17 +1106,17 @@ if (empty($reshook))
 
 	// Set project
 	else if ($action == 'classin' && $user->rights->propal->creer) {
-		$object->setProject($_POST['projectid']);
+		$object->setProject(GETPOST('projectid','int'));
 	}
 
 	// Delai de livraison
 	else if ($action == 'setavailability' && $user->rights->propal->creer) {
-		$result = $object->availability($_POST['availability_id']);
+		$result = $object->set_availability($user, GETPOST('availability_id','int'));
 	}
 
 	// Origine de la propale
 	else if ($action == 'setdemandreason' && $user->rights->propal->creer) {
-		$result = $object->demand_reason($_POST['demand_reason_id']);
+		$result = $object->set_demand_reason($user, GETPOST('demand_reason_id','int'));
 	}
 
 	// Conditions de reglement
@@ -1721,10 +1737,10 @@ if ($action == 'create')
 
 
 	// Proposal card
-	
+
 	$linkback = '<a href="' . DOL_URL_ROOT . '/comm/propal/list.php' . (! empty($socid) ? '?socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
 
-	
+
 	$morehtmlref='<div class="refidno">';
 	// Ref customer
 	$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->propal->creer, 'string', '', 0, 1);
@@ -1764,17 +1780,17 @@ if ($action == 'create')
         }
     }
     $morehtmlref.='</div>';
-    
-    
+
+
 	dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
-	
-    
+
+
     print '<div class="fichecenter">';
     print '<div class="fichehalfleft">';
     print '<div class="underbanner clearboth"></div>';
-    
+
 	print '<table class="border" width="100%">';
-    
+
     // Ref
     /*
 	print '<tr><td>' . $langs->trans('Ref') . '</td><td colspan="5">';
@@ -1804,7 +1820,7 @@ if ($action == 'create')
 	print '</td>';
 	print '</tr>';
     */
-	
+
 	// Company
 	/*
 	print '<tr><td>' . $langs->trans('Company') . '</td><td colspan="5">' . $soc->getNomUrl(1) . '</td>';
@@ -2022,10 +2038,18 @@ if ($action == 'create')
 			print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editmulticurrencyrate&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '</a></td>';
 		print '</tr></table>';
 		print '</td><td>';
-		if ($action == 'editmulticurrencyrate') {
+		if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') {
+			if($action == 'actualizemulticurrencyrate') {
+				list($object->fk_multicurrency, $object->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($object->db, $object->multicurrency_code);
+			}
 			$form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code);
 		} else {
 			$form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code);
+			if($object->statut == 0) {
+				print '<div class="inline-block"> &nbsp; &nbsp; &nbsp; &nbsp; ';
+				print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=actualizemulticurrencyrate">'.$langs->trans("ActualizeCurrency").'</a>';
+				print '</div>';
+			}
 		}
 		print '</td></tr>';
 	}
@@ -2127,42 +2151,42 @@ if ($action == 'create')
 	include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
 
 	print '</table>';
-	
+
 	print '</div>';
 	print '<div class="fichehalfright">';
 	print '<div class="ficheaddleft">';
 	print '<div class="underbanner clearboth"></div>';
-	
+
     print '<table class="border centpercent">';
-    
+
     if (!empty($conf->multicurrency->enabled) && ($object->multicurrency_code != $conf->currency))
     {
         // Multicurrency Amount HT
         print '<tr><td class="titlefieldmiddle">' . fieldLabel('MulticurrencyAmountHT','multicurrency_total_ht') . '</td>';
         print '<td class="nowrap">' . price($object->multicurrency_total_ht, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>';
         print '</tr>';
-    
+
         // Multicurrency Amount VAT
         print '<tr><td>' . fieldLabel('MulticurrencyAmountVAT','multicurrency_total_tva') . '</td>';
         print '<td class="nowrap">' . price($object->multicurrency_total_tva, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>';
         print '</tr>';
-    
+
         // Multicurrency Amount TTC
         print '<tr><td>' . fieldLabel('MulticurrencyAmountTTC','multicurrency_total_ttc') . '</td>';
         print '<td class="nowrap">' . price($object->multicurrency_total_ttc, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>';
         print '</tr>';
     }
-        
+
 	// Amount HT
 	print '<tr><td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
 	print '<td class="nowrap">' . price($object->total_ht, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>';
 	print '</tr>';
-	
+
 	// Amount VAT
 	print '<tr><td>' . $langs->trans('AmountVAT') . '</td>';
 	print '<td class="nowrap">' . price($object->total_tva, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>';
 	print '</tr>';
-	
+
 	// Amount Local Taxes
 	if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) 	// Localtax1
 	{
@@ -2176,27 +2200,27 @@ if ($action == 'create')
 	    print '<td class="nowrap">' . price($object->total_localtax2, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>';
 	    print '</tr>';
 	}
-	
+
 	// Amount TTC
 	print '<tr><td>' . $langs->trans('AmountTTC') . '</td>';
 	print '<td class="nowrap">' . price($object->total_ttc, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>';
 	print '</tr>';
-	
+
 	// Statut
 	//print '<tr><td height="10">' . $langs->trans('Status') . '</td><td align="left" colspan="2">' . $object->getLibStatut(4) . '</td></tr>';
-	
+
 	print '</table>';
-	
+
 	// Margin Infos
 	if (! empty($conf->margin->enabled))
 	{
 	    $formmargin->displayMarginInfos($object);
 	}
-	
+
 	print '</div>';
 	print '</div>';
 	print '</div>';
-	
+
 	print '<div class="clearboth"></div><br>';
 
 	if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) {
@@ -2229,6 +2253,7 @@ if ($action == 'create')
 		include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
 	}
 
+    print '<div class="div-table-responsive">';
 	print '<table id="tablelines" class="noborder noshadow" width="100%">';
 
 	if (! empty($object->lines))
@@ -2250,6 +2275,7 @@ if ($action == 'create')
 	}
 
 	print '</table>';
+    print '</div>';
 
 	print "</form>\n";
 
@@ -2409,7 +2435,7 @@ if ($action == 'create')
 		// Show links to link elements
 		$linktoelem = $form->showLinkToObjectBlock($object, null, array('propal'));
 		$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
-		
+
 
 		print '</div><div class="fichehalfright"><div class="ficheaddleft">';
 

+ 8 - 7
htdocs/comm/propal/class/api_proposals.class.php

@@ -90,17 +90,19 @@ class Proposals extends DolibarrApi
      * @param int		$limit		        Limit for list
      * @param int		$page		        Page number
      * @param string   	$thirdparty_ids	    Thirdparty ids to filter commercial proposal of. Example: '1' or '1,2,3'          {@pattern /^[0-9,]*$/i}
-     * @param string    $sqlfilters         Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
+     * @param string    $sqlfilters         Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.datec:<:'20160101')"
      * @return  array                       Array of order objects
      */
     function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
         global $db, $conf;
         
         $obj_ret = array();
-        // case of external user, $thirdpartyid param is ignored and replaced by user's socid
+
+        // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
         $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids;
             
         // If the internal user must only see his customers, force searching by him
+        $search_sale = 0;
         if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
 
         $sql = "SELECT t.rowid";
@@ -150,13 +152,13 @@ class Proposals extends DolibarrApi
                 $obj = $db->fetch_object($result);
                 $propal_static = new Propal($db);
                 if($propal_static->fetch($obj->rowid)) {
-                    $obj_ret[] = parent::_cleanObjectDatas($propal_static);
+                    $obj_ret[] = $this->_cleanObjectDatas($propal_static);
                 }
                 $i++;
             }
         }
         else {
-            throw new RestException(503, 'Error when retrieve propal list');
+            throw new RestException(503, 'Error when retrieve propal list : '.$db->lasterror());
         }
         if( ! count($obj_ret)) {
             throw new RestException(404, 'No order found');
@@ -188,9 +190,8 @@ class Proposals extends DolibarrApi
           }
           $this->propal->lines = $lines;
         }*/
-        if ($this->propal->create(DolibarrApiAccess::$user) <= 0) {
-            $errormsg = $this->propal->error;
-            throw new RestException(500, $errormsg ? $errormsg : "Error while creating order");
+        if ($this->propal->create(DolibarrApiAccess::$user) < 0) {
+            throw new RestException(500, "Error creating order", array_merge(array($this->propal->error), $this->propal->errors));
         }
         
         return $this->propal->id;

+ 57 - 27
htdocs/comm/propal/class/propal.class.php

@@ -50,7 +50,7 @@ class Propal extends CommonObject
     public $fk_element='fk_propal';
     protected $ismultientitymanaged = 1;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     public $picto='propal';
-    
+
     /**
      * {@inheritdoc}
      */
@@ -392,10 +392,10 @@ class Propal extends CommonObject
      *      @param		string		$origin				'order', ...
      *      @param		int			$origin_id			Id of origin object
      *    	@return    	int         	    			>0 if OK, <0 if KO
-     *
+     * 		@param		double		$pu_ht_devise		Unit price in currency
      *    	@see       	add_product
      */
-	function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $fk_product=0, $remise_percent=0.0, $price_base_type='HT', $pu_ttc=0.0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=0, $pa_ht=0, $label='',$date_start='', $date_end='',$array_options=0, $fk_unit=null, $origin='', $origin_id=0)
+	function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $fk_product=0, $remise_percent=0.0, $price_base_type='HT', $pu_ttc=0.0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=0, $pa_ht=0, $label='',$date_start='', $date_end='',$array_options=0, $fk_unit=null, $origin='', $origin_id=0, $pu_ht_devise = 0)
     {
     	global $mysoc, $conf, $langs;
 
@@ -463,18 +463,22 @@ class Propal extends CommonObject
                 $txtva = preg_replace('/\s*\(.*\)/', '', $txtva);    // Remove code into vatrate.
             }
 
-            $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx);
+            $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
 
             $total_ht  = $tabprice[0];
             $total_tva = $tabprice[1];
             $total_ttc = $tabprice[2];
             $total_localtax1 = $tabprice[9];
             $total_localtax2 = $tabprice[10];
+			$pu_ht  = $tabprice[3];
+			$pu_tva = $tabprice[4];
+			$pu_ttc = $tabprice[5];
 
 			// MultiCurrency
 			$multicurrency_total_ht  = $tabprice[16];
             $multicurrency_total_tva = $tabprice[17];
             $multicurrency_total_ttc = $tabprice[18];
+			$pu_ht_devise = $tabprice[19];
 
             // Rang to use
             $rangtouse = $rang;
@@ -503,7 +507,7 @@ class Propal extends CommonObject
             $this->line->label=$label;
             $this->line->desc=$desc;
             $this->line->qty=$qty;
-            
+
 			$this->line->vat_src_code=$vat_src_code;
             $this->line->tva_tx=$txtva;
             $this->line->localtax1_tx=$txlocaltax1;
@@ -537,7 +541,7 @@ class Propal extends CommonObject
 			// Multicurrency
 			$this->line->fk_multicurrency			= $this->fk_multicurrency;
 			$this->line->multicurrency_code			= $this->multicurrency_code;
-			$this->line->multicurrency_subprice		= price2num($pu_ht * $this->multicurrency_tx);
+			$this->line->multicurrency_subprice		= $pu_ht_devise;
 			$this->line->multicurrency_total_ht 	= $multicurrency_total_ht;
             $this->line->multicurrency_total_tva 	= $multicurrency_total_tva;
             $this->line->multicurrency_total_ttc 	= $multicurrency_total_ttc;
@@ -607,9 +611,10 @@ class Propal extends CommonObject
      *	@param      int			$date_end         	End date of the line
 	 *  @param		array		$array_options		extrafields array
      * 	@param 		string		$fk_unit 			Code of the unit to use. Null to use the default one
+	 * 	@param		double		$pu_ht_devise		Unit price in currency
      *  @return     int     		        		0 if OK, <0 if KO
      */
-	function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=0, $pa_ht=0, $label='', $type=0, $date_start='', $date_end='', $array_options=0, $fk_unit=null)
+	function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=0, $pa_ht=0, $label='', $type=0, $date_start='', $date_end='', $array_options=0, $fk_unit=null, $pu_ht_devise = 0)
     {
         global $mysoc;
 
@@ -638,7 +643,7 @@ class Propal extends CommonObject
             // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
 
             $localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty,$mysoc);
-            
+
             // Clean vat code
             $vat_src_code='';
             if (preg_match('/\((.*)\)/', $txtva, $reg))
@@ -647,17 +652,21 @@ class Propal extends CommonObject
                 $txtva = preg_replace('/\s*\(.*\)/', '', $txtva);    // Remove code into vatrate.
             }
 
-            $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx);
+            $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
             $total_ht  = $tabprice[0];
             $total_tva = $tabprice[1];
             $total_ttc = $tabprice[2];
             $total_localtax1 = $tabprice[9];
             $total_localtax2 = $tabprice[10];
+			$pu_ht  = $tabprice[3];
+			$pu_tva = $tabprice[4];
+			$pu_ttc = $tabprice[5];
 
 			// MultiCurrency
 			$multicurrency_total_ht  = $tabprice[16];
             $multicurrency_total_tva = $tabprice[17];
             $multicurrency_total_ttc = $tabprice[18];
+			$pu_ht_devise = $tabprice[19];
 
             // Anciens indicateurs: $price, $remise (a ne plus utiliser)
             $price = $pu;
@@ -670,6 +679,7 @@ class Propal extends CommonObject
             //Fetch current line from the database and then clone the object and set it in $oldline property
             $line = new PropaleLigne($this->db);
             $line->fetch($rowid);
+			$line->fetch_optionals(); // Fetch extrafields for oldcopy
 
 			$staticline = clone $line;
 
@@ -695,7 +705,7 @@ class Propal extends CommonObject
 			$this->line->localtax1_type		= $localtaxes_type[0];
 			$this->line->localtax2_type		= $localtaxes_type[2];
             $this->line->remise_percent		= $remise_percent;
-            $this->line->subprice			= $pu;
+            $this->line->subprice			= $pu_ht;
             $this->line->info_bits			= $info_bits;
 
             $this->line->vat_src_code		= $vat_src_code;
@@ -724,7 +734,7 @@ class Propal extends CommonObject
             }
 
 			// Multicurrency
-			$this->line->multicurrency_subprice		= price2num($pu * $this->multicurrency_tx);
+			$this->line->multicurrency_subprice		= $pu_ht_devise;
 			$this->line->multicurrency_total_ht 	= $multicurrency_total_ht;
             $this->line->multicurrency_total_tva 	= $multicurrency_total_tva;
             $this->line->multicurrency_total_ttc 	= $multicurrency_total_ttc;
@@ -1179,7 +1189,7 @@ class Propal extends CommonObject
         $clonedObj->ref = $modPropale->getNextValue($objsoc,$clonedObj);
 
         // Create clone
-        
+
         $result=$clonedObj->create($user);
         if ($result < 0) $error++;
         else
@@ -1540,7 +1550,7 @@ class Propal extends CommonObject
             dol_syslog(get_class($this)."::valid action abandonned: already validated", LOG_WARNING);
             return 0;
         }
-        
+
         if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->creer))
        	|| (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->propal_advance->validate))))
         {
@@ -1550,7 +1560,7 @@ class Propal extends CommonObject
         }
 
         $now=dol_now();
-            
+
         $this->db->begin();
 
         // Numbering module definition
@@ -1838,7 +1848,7 @@ class Propal extends CommonObject
      */
     function set_availability($user, $id, $notrigger=0)
     {
-        if (! empty($user->rights->propal->creer))
+        if (! empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT)
         {
         	$error=0;
 
@@ -1848,7 +1858,7 @@ class Propal extends CommonObject
             $sql.= " SET fk_availability = '".$id."'";
             $sql.= " WHERE rowid = ".$this->id;
 
-            dol_syslog(__METHOD__, LOG_DEBUG);
+            dol_syslog(__METHOD__.' availability('.$availability_id.')', LOG_DEBUG);
             $resql=$this->db->query($sql);
             if (!$resql)
             {
@@ -1860,6 +1870,7 @@ class Propal extends CommonObject
             {
             	$this->oldcopy= clone $this;
             	$this->fk_availability = $id;
+            	$this->availability_id = $availability_id;
             }
 
             if (! $notrigger && empty($error))
@@ -1886,6 +1897,14 @@ class Propal extends CommonObject
             	return -1*$error;
             }
         }
+        else
+        {
+        	$error_str='Propal status do not meet requirement '.$this->statut;
+        	dol_syslog(__METHOD__.$error_str, LOG_ERR);
+        	$this->error=$error_str;
+        	$this->errors[]= $this->error;
+        	return -2;
+        }
     }
 
     /**
@@ -1898,14 +1917,14 @@ class Propal extends CommonObject
      */
     function set_demand_reason($user, $id, $notrigger=0)
     {
-        if (! empty($user->rights->propal->creer))
+        if (! empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT)
         {
         	$error=0;
 
         	$this->db->begin();
 
             $sql = "UPDATE ".MAIN_DB_PREFIX."propal ";
-            $sql.= " SET fk_input_reason = '".$id."'";
+            $sql.= " SET fk_input_reason = ".$id;
             $sql.= " WHERE rowid = ".$this->id;
 
             dol_syslog(__METHOD__, LOG_DEBUG);
@@ -1921,6 +1940,7 @@ class Propal extends CommonObject
             {
             	$this->oldcopy= clone $this;
             	$this->fk_input_reason = $id;
+            	$this->demand_reason_id = $id;
             }
 
 
@@ -1948,6 +1968,14 @@ class Propal extends CommonObject
             	return -1*$error;
             }
         }
+        else
+        {
+        	$error_str='Propal status do not meet requirement '.$this->statut;
+        	dol_syslog(__METHOD__.$error_str, LOG_ERR);
+        	$this->error=$error_str;
+        	$this->errors[]= $this->error;
+        	return -2;
+        }
     }
 
     /**
@@ -2405,7 +2433,7 @@ class Propal extends CommonObject
         	$this->statut = self::STATUS_DRAFT;
             $this->brouillon = 1;
         }
-        
+
         if (! $notrigger && empty($error))
         {
         	// Call trigger
@@ -2732,6 +2760,7 @@ class Propal extends CommonObject
      *  @param	int	$availability_id	Id of new delivery time
      * 	@param	int	$notrigger			1=Does not execute triggers, 0= execute triggers
      *  @return int                  	>0 if OK, <0 if KO
+     *  @deprecated  use set_availability
      */
     function availability($availability_id, $notrigger=0)
     {
@@ -2752,7 +2781,7 @@ class Propal extends CommonObject
             	$this->errors[]=$this->db->error();
             	$error++;
             }
-            
+
             if (! $error)
             {
             	$this->oldcopy= clone $this;
@@ -2799,6 +2828,7 @@ class Propal extends CommonObject
      *	@param	int $demand_reason_id 	Id of new source demand
      * 	@param	int	$notrigger			1=Does not execute triggers, 0= execute triggers
      *	@return int						>0 si ok, <0 si ko
+     *	@deprecated use set_demand_reason
      */
     function demand_reason($demand_reason_id, $notrigger=0)
     {
@@ -2819,7 +2849,7 @@ class Propal extends CommonObject
             	$this->errors[]=$this->db->error();
             	$error++;
             }
-            
+
             if (! $error)
             {
             	$this->oldcopy= clone $this;
@@ -3240,7 +3270,7 @@ class Propal extends CommonObject
         global $langs, $conf, $user;
 
         if (! empty($conf->dol_no_mouse_hover)) $notooltip=1;   // Force disable tooltips
-        
+
         $result='';
         $label='';
         $url='';
@@ -3271,7 +3301,7 @@ class Propal extends CommonObject
                 $url = DOL_URL_ROOT.'/comm/propal/document.php?id='.$this->id. $get_params;
             }
         }
-        
+
         $linkclose='';
         if (empty($notooltip) && $user->rights->propal->lire)
         {
@@ -3283,9 +3313,9 @@ class Propal extends CommonObject
             $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
             $linkclose.=' class="classfortooltip"';
         }
-        
+
         $linkstart = '<a href="'.$url.'"';
-        $linkstart.=$linkclose.'>';        
+        $linkstart.=$linkclose.'>';
         $linkend='</a>';
 
         if ($withpicto)
@@ -3349,7 +3379,7 @@ class Propal extends CommonObject
                 $this->lines[$i]->fk_remise_except 	= $obj->fk_remise_except;
                 $this->lines[$i]->remise_percent	= $obj->remise_percent;
 
-                $this->lines[$i]->vat_src_code      = $obj->vat_src_code; 
+                $this->lines[$i]->vat_src_code      = $obj->vat_src_code;
                 $this->lines[$i]->tva_tx			= $obj->tva_tx;
                 $this->lines[$i]->info_bits			= $obj->info_bits;
                 $this->lines[$i]->total_ht			= $obj->total_ht;
@@ -3683,7 +3713,7 @@ class PropaleLigne  extends CommonObjectLine
         if (empty($this->multicurrency_total_ht))  $this->multicurrency_total_ht=0;
         if (empty($this->multicurrency_total_tva)) $this->multicurrency_total_tva=0;
         if (empty($this->multicurrency_total_ttc)) $this->multicurrency_total_ttc=0;
-        
+
        // if buy price not defined, define buyprice as configured in margin admin
 		if ($this->pa_ht == 0 && $pa_ht_isemptystring)
 		{

+ 1 - 0
htdocs/comm/propal/contact.php

@@ -30,6 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/propal.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
+require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
 
 $langs->load("facture");
 $langs->load("orders");

+ 11 - 3
htdocs/comm/propal/info.php

@@ -32,21 +32,30 @@ $langs->load('propal');
 $langs->load('compta');
 
 $id=GETPOST('id','int');
+$ref=GETPOST('ref','alpha');
 $socid=GETPOST('socid','int');
 
 // Security check
 if (! empty($user->societe_id)) $socid=$user->societe_id;
 $result = restrictedArea($user, 'propal', $id);
 
+$object = new Propal($db);
+if (! $object->fetch($id, $ref) > 0)
+{
+    dol_print_error($db);
+    exit;
+}
+
+
 
 /*
  *	View
  */
 
+$form = new Form($db);
+
 llxHeader('',$langs->trans('Proposal'),'EN:Commercial_Proposals|FR:Proposition_commerciale|ES:Presupuestos');
 
-$object = new Propal($db);
-$object->fetch($id);
 $object->fetch_thirdparty();
 
 $head = propal_prepare_head($object);
@@ -110,7 +119,6 @@ print '<br>';
 
 dol_print_object_info($object);
 
-print '</div>';
 print '</div>';
 
 dol_fiche_end();

+ 3 - 3
htdocs/comm/propal/list.php

@@ -289,7 +289,7 @@ if ($sall) {
 }
 if ($search_product_category > 0) $sql.=" AND cp.fk_categorie = ".$search_product_category;
 if ($socid > 0) $sql.= ' AND s.rowid = '.$socid;
-if ($viewstatut <> '')
+if ($viewstatut != '' && $viewstatut != '-1')
 {
 	$sql.= ' AND p.fk_statut IN ('.$viewstatut.')';
 }
@@ -333,7 +333,7 @@ $sql.= $db->order($sortfield,$sortorder);
 $sql.=', p.ref DESC';
 
 // Count total nb of records
-$nbtotalofrecords = 0;
+$nbtotalofrecords = -1;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
 {
     $result = $db->query($sql);
@@ -538,7 +538,7 @@ if ($resql)
 		$moreforfilter.='<div class="divsearchfield">';
 		$moreforfilter.=$langs->trans('IncludingProductWithTag'). ': ';
 		$cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT, null, 'parent', null, null, 1);
-		$moreforfilter.=$form->selectarray('search_product_category', $cate_arbo, $search_product_category, 1, 0, 0, '', 0, 0, 0, 0, '', 1);
+		$moreforfilter.=$form->selectarray('search_product_category', $cate_arbo, $search_product_category, 1, 0, 0, '', 0, 0, 0, 0, 'maxwidth300', 1);
 		$moreforfilter.='</div>';
 	}
 	$parameters=array();

+ 1 - 1
htdocs/comm/propal/note.php

@@ -132,9 +132,9 @@ if ($id > 0 || ! empty($ref))
 			print '<div class="fichecenter">';
 			print '<div class="underbanner clearboth"></div>';
 			
+			$cssclass="titlefield";
 			include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php';
 
-			print '</div>';
 			print '</div>';
 			
 			dol_fiche_end();

+ 4 - 4
htdocs/comm/remise.php

@@ -116,7 +116,7 @@ if ($socid > 0)
     print '<div class="underbanner clearboth"></div>';
 	print '<table class="border centpercent">';
 
-	// Remise
+	// Discount
 	print '<tr><td class="titlefield">';
 	print $langs->trans("CustomerRelativeDiscount").'</td><td>'.price2num($object->remise_percent)."%</td></tr>";
 
@@ -127,13 +127,13 @@ if ($socid > 0)
 
 	print '<table class="border centpercent">';
 
-	// Nouvelle valeur
+	// New value
 	print '<tr><td class="titlefield">';
-	print $langs->trans("NewValue").'</td><td><input type="text" size="5" name="remise" value="'.($_POST["remise"]?$_POST["remise"]:'').'">%</td></tr>';
+	print $langs->trans("NewValue").'</td><td><input type="text" size="5" name="remise" value="'.dol_escape_htmltag(GETPOST("remise")).'">%</td></tr>';
 
 	// Motif/Note
 	print '<tr><td>';
-	print $langs->trans("NoteReason").'</td><td><input type="text" size="60" name="note" value="'.$_POST["note"].'"></td></tr>';
+	print $langs->trans("NoteReason").'</td><td><input type="text" size="60" name="note" value="'.dol_escape_htmltag(GETPOST("note")).'"></td></tr>';
 
 	print "</table>";
 

+ 2 - 2
htdocs/comm/remx.php

@@ -283,14 +283,14 @@ if ($socid > 0)
     	print '<div class="underbanner clearboth"></div>';
     	print '<table class="border" width="100%">';
     	print '<tr><td class="titlefield fieldrequired">'.$langs->trans("AmountHT").'</td>';
-    	print '<td><input type="text" size="5" name="amount_ht" value="'.$_POST["amount_ht"].'">';
+    	print '<td><input type="text" size="5" name="amount_ht" value="'.price2num(GETPOST("amount_ht")).'">';
     	print '<span class="hideonsmartphone">&nbsp;'.$langs->trans("Currency".$conf->currency).'</span></td></tr>';
     	print '<tr><td>'.$langs->trans("VAT").'</td>';
     	print '<td>';
     	print $form->load_tva('tva_tx',GETPOST('tva_tx'),$mysoc,$object);
     	print '</td></tr>';
     	print '<tr><td class="fieldrequired" >'.$langs->trans("NoteReason").'</td>';
-    	print '<td><input type="text" size="60" name="desc" value="'.GETPOST('desc').'"></td></tr>';
+    	print '<td><input type="text" class="quatrevingtpercent" name="desc" value="'.GETPOST('desc').'"></td></tr>';
     
     	print "</table>";
 	}

+ 37 - 8
htdocs/commande/card.php

@@ -115,13 +115,16 @@ if (empty($reshook))
 {
 	if ($cancel) 
 	{
-		if ($action != 'addlink')
+		if ($action != 'addlink' && $action != 'updateline')
 		{
 			$urltogo=$backtopage?$backtopage:dol_buildpath('/commande/list.php',1);
 			header("Location: ".$urltogo);
 			exit;
-		}		
-		if ($id > 0 || ! empty($ref)) $ret = $object->fetch($id,$ref);
+		}
+		if ($id > 0 || ! empty($ref)) {
+		    $ret = $object->fetch($id,$ref);
+		    $object->fetch_thirdparty();
+        }
 		$action='';
 	}
 	
@@ -640,6 +643,7 @@ if (empty($reshook))
 		$predef='';
 		$product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
 		$price_ht = GETPOST('price_ht');
+		$price_ht_devise = GETPOST('multicurrency_price_ht');
 		$prod_entry_mode = GETPOST('prod_entry_mode');
 		if ($prod_entry_mode == 'free')
 		{
@@ -675,7 +679,7 @@ if (empty($reshook))
 			setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
 			$error++;
 		}
-		if ($prod_entry_mode == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) 	// Unit price can be 0 but not ''
+		if ($prod_entry_mode == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '') && (! ($price_ht_devise >= 0) || $price_ht_devise == '')) 	// Unit price can be 0 but not ''
 		{
 			setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
 			$error++;
@@ -829,6 +833,7 @@ if (empty($reshook))
 				$desc = $product_desc;
 				$type = GETPOST('type');
 				$fk_unit=GETPOST('units', 'alpha');
+				$pu_ht_devise = price2num($price_ht_devise, 'MU');
 			}
 
 			// Margin
@@ -850,7 +855,7 @@ if (empty($reshook))
 				setEventMessages($mesg, null, 'errors');
 			} else {
 				// Insert line
-				$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $fk_unit);
+				$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $fk_unit, '', 0, $pu_ht_devise);
 
 				if ($result > 0) {
 					$ret = $object->fetch($object->id); // Reload to get new records
@@ -921,6 +926,7 @@ if (empty($reshook))
 		$description=dol_htmlcleanlastbr(GETPOST('product_desc'));
 		$pu_ht=GETPOST('price_ht');
 		$vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0);
+		$pu_ht_devise = GETPOST('multicurrency_subprice');
 
 		// Define info_bits
 		$info_bits = 0;
@@ -981,7 +987,20 @@ if (empty($reshook))
 		}
 
 		if (! $error) {
-			$result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOST('units'));
+
+			if (empty($user->rights->margins->creer))
+			{
+				foreach ($object->lines as &$line)
+				{
+					if ($line->id == GETPOST('lineid'))
+					{
+						$fournprice = $line->fk_fournprice;
+						$buyingprice = $line->pa_ht;
+						break;
+					}
+				}
+			}
+			$result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOST('units'),$pu_ht_devise);
 
 			if ($result >= 0) {
 				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
@@ -1648,7 +1667,7 @@ if ($action == 'create' && $user->rights->commande->creer)
 	}
 
 	// Template to use by default
-	print '<tr><td>' . $langs->trans('Model') . '</td>';
+	print '<tr><td>' . $langs->trans('DefaultModel') . '</td>';
 	print '<td colspan="2">';
 	include_once DOL_DOCUMENT_ROOT . '/core/modules/commande/modules_commande.php';
 	$liste = ModelePDFCommandes::liste_modeles($db);
@@ -2212,10 +2231,18 @@ if ($action == 'create' && $user->rights->commande->creer)
 				print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editmulticurrencyrate&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '</a></td>';
 			print '</tr></table>';
 			print '</td><td>';
-			if ($action == 'editmulticurrencyrate') {
+			if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') {
+    			if($action == 'actualizemulticurrencyrate') {
+    				list($object->fk_multicurrency, $object->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($object->db, $object->multicurrency_code);
+    			}
 				$form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code);
 			} else {
 				$form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code);
+				if($object->statut == 0) {
+					print '<div class="inline-block"> &nbsp; &nbsp; &nbsp; &nbsp; ';
+					print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=actualizemulticurrencyrate">'.$langs->trans("ActualizeCurrency").'</a>';
+					print '</div>';
+				}
 			}
 			print '</td></tr>';
 		}
@@ -2428,6 +2455,7 @@ if ($action == 'create' && $user->rights->commande->creer)
 			include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
 		}
 
+        print '<div class="div-table-responsive">';
 		print '<table id="tablelines" class="noborder noshadow" width="100%">';
 
 		// Show object lines
@@ -2453,6 +2481,7 @@ if ($action == 'create' && $user->rights->commande->creer)
 			}
 		}
 		print '</table>';
+        print '</div>';
 
 		print "</form>\n";
 

+ 4 - 3
htdocs/commande/class/api_deprecated_commande.class.php

@@ -115,6 +115,7 @@ class CommandeApi extends DolibarrApi
         $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $societe;
 
         // If the internal user must only see his customers, force searching by him
+        $search_sale = 0;
         if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id;
 
         $sql = "SELECT s.rowid";
@@ -138,7 +139,7 @@ class CommandeApi extends DolibarrApi
             $sql .= " AND sc.fk_user = ".$search_sale;
         }
 
-        $nbtotalofrecords = 0;
+        $nbtotalofrecords = -1;
         if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
         {
             $result = $db->query($sql);
@@ -167,13 +168,13 @@ class CommandeApi extends DolibarrApi
                 $obj = $db->fetch_object($result);
                 $commande_static = new Commande($db);
                 if($commande_static->fetch($obj->rowid)) {
-                    $obj_ret[] = parent::_cleanObjectDatas($commande_static);
+                    $obj_ret[] = $this->_cleanObjectDatas($commande_static);
                 }
                 $i++;
             }
         }
         else {
-            throw new RestException(503, 'Error when retrieve commande list');
+            throw new RestException(503, 'Error when retrieve commande list : '.$db->lasterror());
         }
         if( ! count($obj_ret)) {
             throw new RestException(404, 'No commande found');

+ 9 - 6
htdocs/commande/class/api_orders.class.php

@@ -94,15 +94,19 @@ class Orders extends DolibarrApi
      * @param string   	       $thirdparty_ids	    Thirdparty ids to filter orders of. {@example '1' or '1,2,3'} {@pattern /^[0-9,]*$/i}
      * @param string           $sqlfilters          Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
      * @return  array                               Array of order objects
+     *
+	 * @throws RestException
      */
     function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
         global $db, $conf;
 
         $obj_ret = array();
-        // case of external user, $thirdpartyid param is ignored and replaced by user's socid
+        
+        // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
         $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids;
 
         // If the internal user must only see his customers, force searching by him
+        $search_sale = 0;
         if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
 
         $sql = "SELECT t.rowid";
@@ -153,13 +157,13 @@ class Orders extends DolibarrApi
                 $obj = $db->fetch_object($result);
                 $commande_static = new Commande($db);
                 if($commande_static->fetch($obj->rowid)) {
-                    $obj_ret[] = parent::_cleanObjectDatas($commande_static);
+                    $obj_ret[] = $this->_cleanObjectDatas($commande_static);
                 }
                 $i++;
             }
         }
         else {
-            throw new RestException(503, 'Error when retrieve commande list');
+            throw new RestException(503, 'Error when retrieve commande list : '.$db->lasterror());
         }
         if( ! count($obj_ret)) {
             throw new RestException(404, 'No order found');
@@ -191,9 +195,8 @@ class Orders extends DolibarrApi
           }
           $this->commande->lines = $lines;
         }*/
-        if ($this->commande->create(DolibarrApiAccess::$user) <= 0) {
-            $errormsg = $this->commande->error;
-            throw new RestException(500, $errormsg ? $errormsg : "Error while creating order");
+        if ($this->commande->create(DolibarrApiAccess::$user) < 0) {
+            throw new RestException(500, "Error creating order", array_merge(array($this->commande->error), $this->commande->errors));
         }
 
         return $this->commande->id;

+ 22 - 14
htdocs/commande/class/commande.class.php

@@ -1225,6 +1225,7 @@ class Commande extends CommonOrder
      * 	@param 		string			$fk_unit 			Code of the unit to use. Null to use the default one
      * 	@param		string		    $origin				'order', ...
      *  @param		int			    $origin_id			Id of origin object
+	 * 	@param		double			$pu_ht_devise		Unit price in currency
      *	@return     int             					>0 if OK, <0 if KO
      *
      *	@see        add_product
@@ -1234,7 +1235,7 @@ class Commande extends CommonOrder
      *	par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,produit)
      *	et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue)
      */
-	function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $info_bits=0, $fk_remise_except=0, $price_base_type='HT', $pu_ttc=0, $date_start='', $date_end='', $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='',$array_options=0, $fk_unit=null, $origin='', $origin_id=0)
+	function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $info_bits=0, $fk_remise_except=0, $price_base_type='HT', $pu_ttc=0, $date_start='', $date_end='', $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='',$array_options=0, $fk_unit=null, $origin='', $origin_id=0, $pu_ht_devise = 0)
     {
     	global $mysoc, $conf, $langs, $user;
 
@@ -1310,18 +1311,20 @@ class Commande extends CommonOrder
     		    $txtva = preg_replace('/\s*\(.*\)/', '', $txtva);    // Remove code into vatrate.
     		}
 
-            $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx);
+            $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
 
             $total_ht  = $tabprice[0];
             $total_tva = $tabprice[1];
             $total_ttc = $tabprice[2];
             $total_localtax1 = $tabprice[9];
             $total_localtax2 = $tabprice[10];
+			$pu_ht = $tabprice[3];
 
 			// MultiCurrency
 			$multicurrency_total_ht  = $tabprice[16];
             $multicurrency_total_tva = $tabprice[17];
             $multicurrency_total_ttc = $tabprice[18];
+			$pu_ht_devise = $tabprice[19];
 
             // Rang to use
             $rangtouse = $rang;
@@ -1385,7 +1388,7 @@ class Commande extends CommonOrder
 			// Multicurrency
 			$this->line->fk_multicurrency			= $this->fk_multicurrency;
 			$this->line->multicurrency_code			= $this->multicurrency_code;
-			$this->line->multicurrency_subprice		= price2num($pu_ht * $this->multicurrency_tx);
+			$this->line->multicurrency_subprice		= $pu_ht_devise;
 			$this->line->multicurrency_total_ht 	= $multicurrency_total_ht;
             $this->line->multicurrency_total_tva 	= $multicurrency_total_tva;
             $this->line->multicurrency_total_ttc 	= $multicurrency_total_ttc;
@@ -2745,17 +2748,17 @@ class Commande extends CommonOrder
      *  Update a line in database
      *
      *  @param    	int				$rowid            	Id of line to update
-     *  @param    	string			$desc             	Description de la ligne
-     *  @param    	float			$pu               	Prix unitaire
+     *  @param    	string			$desc             	Description of line
+     *  @param    	float			$pu               	Unit price
      *  @param    	float			$qty              	Quantity
-     *  @param    	float			$remise_percent   	Pourcentage de remise de la ligne
+     *  @param    	float			$remise_percent   	Percent of discount
      *  @param    	float			$txtva           	Taux TVA
      * 	@param		float			$txlocaltax1		Local tax 1 rate
      *  @param		float			$txlocaltax2		Local tax 2 rate
      *  @param    	string			$price_base_type	HT or TTC
      *  @param    	int				$info_bits        	Miscellaneous informations on line
-     *  @param    	int		$date_start        	Start date of the line
-     *  @param    	int		$date_end          	End date of the line
+     *  @param    	int				$date_start        	Start date of the line
+     *  @param    	int				$date_end          	End date of the line
      * 	@param		int				$type				Type of line (0=product, 1=service)
      * 	@param		int				$fk_parent_line		Id of parent line (0 in most cases, used by modules adding sublevels into lines).
      * 	@param		int				$skip_update_total	Keep fields total_xxx to 0 (used for special lines by some modules)
@@ -2765,9 +2768,10 @@ class Commande extends CommonOrder
      *  @param		int				$special_code		Special code (also used by externals modules!)
 	 *  @param		array			$array_options		extrafields array
      * 	@param 		string			$fk_unit 			Code of the unit to use. Null to use the default one
+	 *  @param		double			$pu_ht_devise		Amount in currency
      *  @return   	int              					< 0 if KO, > 0 if OK
      */
-	function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0,$txlocaltax2=0.0, $price_base_type='HT', $info_bits=0, $date_start='', $date_end='', $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_options=0, $fk_unit=null)
+	function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0,$txlocaltax2=0.0, $price_base_type='HT', $info_bits=0, $date_start='', $date_end='', $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_options=0, $fk_unit=null, $pu_ht_devise = 0)
     {
         global $conf, $mysoc, $langs, $user;
 
@@ -2811,28 +2815,32 @@ class Commande extends CommonOrder
     		    $txtva = preg_replace('/\s*\(.*\)/', '', $txtva);    // Remove code into vatrate.
     		}
 
-            $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx);
+            $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
 
             $total_ht  = $tabprice[0];
             $total_tva = $tabprice[1];
             $total_ttc = $tabprice[2];
             $total_localtax1 = $tabprice[9];
             $total_localtax2 = $tabprice[10];
+			$pu_ht  = $tabprice[3];
+			$pu_tva = $tabprice[4];
+			$pu_ttc = $tabprice[5];
 
 			// MultiCurrency
 			$multicurrency_total_ht  = $tabprice[16];
             $multicurrency_total_tva = $tabprice[17];
             $multicurrency_total_ttc = $tabprice[18];
+			$pu_ht_devise = $tabprice[19];
 
             // Anciens indicateurs: $price, $subprice, $remise (a ne plus utiliser)
-            $price = $pu;
+            $price = $pu_ht;
 			if ($price_base_type == 'TTC')
 			{
-				$subprice = $tabprice[5];
+				$subprice = $pu_ttc;
 			}
 			else
 			{
-				$subprice = $pu;
+				$subprice = $pu_ht;
 			}
             $remise = 0;
             if ($remise_percent > 0)
@@ -2910,7 +2918,7 @@ class Commande extends CommonOrder
 			$this->line->pa_ht = $pa_ht;
 
 			// Multicurrency
-			$this->line->multicurrency_subprice		= price2num($subprice * $this->multicurrency_tx);
+			$this->line->multicurrency_subprice		= $pu_ht_devise;
 			$this->line->multicurrency_total_ht 	= $multicurrency_total_ht;
             $this->line->multicurrency_total_tva 	= $multicurrency_total_tva;
             $this->line->multicurrency_total_ttc 	= $multicurrency_total_ttc;

+ 2 - 1
htdocs/commande/class/commandestats.class.php

@@ -81,7 +81,8 @@ class CommandeStats extends Stats
 			$this->where.= " c.fk_statut > 2";    // Only approved & ordered
 		}
 		//$this->where.= " AND c.fk_soc = s.rowid AND c.entity = ".$conf->entity;
-		$this->where.= " AND c.entity = ".$conf->entity;
+		$this->where.= ' AND c.entity IN ('.getEntity('commande', 1).')';
+		
 		if (!$user->rights->societe->client->voir && !$this->socid) $this->where .= " AND c.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id;
 		if ($this->socid)
 		{

+ 54 - 61
htdocs/commande/contact.php

@@ -30,6 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/order.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
+require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
 
 $langs->load("orders");
 $langs->load("sendings");
@@ -139,69 +140,61 @@ if ($id > 0 || ! empty($ref))
 
 	if ($object->fetch($id, $ref) > 0)
 	{
-		$soc = new Societe($db);
-		$soc->fetch($object->socid);
-
-
+	    $object->fetch_thirdparty();
+	    
 		$head = commande_prepare_head($object);
 		dol_fiche_head($head, 'contact', $langs->trans("CustomerOrder"), 0, 'order');
 
-
-	   /*
-		*   Facture synthese pour rappel
-		*/
-		print '<table class="border" width="100%">';
-
-		$linkback = '<a href="'.DOL_URL_ROOT.'/commande/list.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
-
-		// Ref
-		print '<tr><td class="titlefield">'.$langs->trans("Ref").'</td><td colspan="3">';
-		print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref');
-		print "</td></tr>";
-
-		// Ref commande client
-		print '<tr><td>';
-        print '<table class="nobordernopadding" width="100%"><tr><td class="nowrap">';
-		print $langs->trans('RefCustomer').'</td><td align="left">';
-        print '</td>';
-        print '</tr></table>';
-        print '</td><td colspan="3">';
-		print $object->ref_client;
-		print '</td>';
-		print '</tr>';
-
-		// Customer
-		if (is_null($object->thirdparty))	$object->fetch_thirdparty();
-
-		print "<tr><td>".$langs->trans("Company")."</td>";
-		print '<td colspan="3">'.$object->thirdparty->getNomUrl(1).'</td></tr>';
-
-		// Delivery address
-		if (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT))
-		{
-			print '<tr><td>';
-			print '<table class="nobordernopadding" width="100%"><tr><td>';
-			print $langs->trans('DeliveryAddress');
-			print '</td>';
-
-			if ($action != 'editdelivery_address' && $object->brouillon) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editdelivery_address&amp;socid='.$object->socid.'&amp;id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetDeliveryAddress'),1).'</a></td>';
-			print '</tr></table>';
-			print '</td><td colspan="3">';
-
-			if ($action == 'editdelivery_address')
-			{
-				$formother->form_address($_SERVER['PHP_SELF'].'?id='.$object->id,$object->fk_delivery_address,GETPOST('socid','int'),'fk_address','commande',$object->id);
-			}
-			else
-			{
-				$formother->form_address($_SERVER['PHP_SELF'].'?id='.$object->id,$object->fk_delivery_address,GETPOST('socid','int'),'none','commande',$object->id);
-			}
-			print '</td></tr>';
-		}
-
-		print "</table>";
-
-		print '</div>';
+		
+		// Order card
+		
+		$linkback = '<a href="' . DOL_URL_ROOT . '/commande/list.php' . (! empty($socid) ? '?socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
+		
+		
+		$morehtmlref='<div class="refidno">';
+		// Ref customer
+		$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
+		$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
+		// Thirdparty
+		$morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
+	    // Project
+	    if (! empty($conf->projet->enabled))
+	    {
+	        $langs->load("projects");
+	        $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
+	        if ($user->rights->commande->creer)
+	        {
+	            if ($action != 'classify')
+	                //$morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
+	                $morehtmlref.=' : ';
+	                if ($action == 'classify') {
+	                    //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
+	                    $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
+	                    $morehtmlref.='<input type="hidden" name="action" value="classin">';
+	                    $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+	                    $morehtmlref.=$formproject->select_projects($object->thirdparty->id, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
+	                    $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
+	                    $morehtmlref.='</form>';
+	                } else {
+	                    $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->thirdparty->id, $object->fk_project, 'none', 0, 0, 0, 1);
+	                }
+	        } else {
+	            if (! empty($object->fk_project)) {
+	                $proj = new Project($db);
+	                $proj->fetch($object->fk_project);
+	                $morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
+	                $morehtmlref.=$proj->ref;
+	                $morehtmlref.='</a>';
+	            } else {
+	                $morehtmlref.='';
+	            }
+	        }
+	    }
+		$morehtmlref.='</div>';		
+
+		dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0, '', '', 1);
+
+		dol_fiche_end();
 
 		print '<br>';
 
@@ -215,7 +208,7 @@ if ($id > 0 || ! empty($ref))
 	}
 	else
 	{
-		// Contrat non trouve
+		// Contact not found
 		print "ErrorRecordNotFound";
 	}
 }

+ 24 - 21
htdocs/commande/customer.php

@@ -44,11 +44,13 @@ accessforbidden();
 
 $langs->load("companies");
 $langs->load("orders");
+
+$limit = GETPOST("limit")?GETPOST("limit","int"):$conf->liste_limit;
 $sortfield = GETPOST("sortfield",'alpha');
 $sortorder = GETPOST("sortorder",'alpha');
 $page = GETPOST("page",'int');
 if ($page == -1) { $page = 0; }
-$offset = $conf->liste_limit * $page;
+$offset = $limit * $page;
 $pageprev = $page - 1;
 $pagenext = $page + 1;
 if (! $sortorder) $sortorder="ASC";
@@ -77,32 +79,32 @@ $sql.= " AND s.entity IN (".getEntity('societe', 1).")";
 if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
 if (dol_strlen($stcomm))
 {
-	$sql.= " AND s.fk_stcomm=$stcomm";
-}
-
-if ($_GET["search_nom"])
-{
-	$sql.= " AND s.nom like '%".$db->escape(strtolower($_GET["search_nom"]))."%'";
-}
-if ($_GET["search_compta"])
-{
-	$sql.= " AND s.code_compta like '%".$db->escape($_GET["search_compta"])."%'";
-}
-if ($_GET["search_code_client"])
-{
-	$sql.= " AND s.code_client like '%".$db->escape($_GET["search_code_client"])."%'";
+	$sql.= " AND s.fk_stcomm=".$stcomm;
 }
+if (GETPOST("search_nom"))  $sql.= natural_search("s.nom", GETPOST("search_nom"));
+if (GETPOST("search_compta")) $sql.= natural_search("s.code_compta", GETPOST("search_compta"));
+if (GETPOST("search_code_client")) $sql.= natural_search("s.code_client", GETPOST("search_code_client"));
 if (dol_strlen($begin))
 {
 	$sql.= " AND s.nom like '".$db->escape($begin)."'";
 }
-if ($socid)
+if ($socid > 0)
 {
 	$sql.= " AND s.rowid = ".$socid;
 }
 $sql.= " AND c.fk_statut in (1, 2) AND c.facture = 0";
 $sql.= " GROUP BY s.nom";
-$sql.= " ORDER BY $sortfield $sortorder " . $db->plimit($conf->liste_limit+1, $offset);
+$sql.= $db->order($sortfield,$sortorder);
+
+// Count total nb of records
+$nbtotalofrecords = -1;
+if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
+{
+	$result = $db->query($sql);
+	$nbtotalofrecords = $db->num_rows($result);
+}
+
+$sql.= $db->plimit($limit + 1, $offset);
 //print $sql;
 
 $resql = $db->query($sql);
@@ -129,26 +131,27 @@ if ($resql)
 	print '<tr class="liste_titre">';
 
 	print '<td align="left" class="liste_titre">';
-	print '<input class="flat" type="text" name="search_nom" value="'.$_GET["search_nom"].'"></td>';
+	print '<input class="flat" type="text" name="search_nom" value="'.dol_escape_htmltag(GETPOST("search_nom")).'"></td>';
 
 	print '<td class="liste_titre">&nbsp;</td>';
 
 	print '<td align="left" class="liste_titre">';
-	print '<input class="flat" type="text" size="10" name="search_code_client" value="'.$_GET["search_code_client"].'">';
+	print '<input class="flat" type="text" size="10" name="search_code_client" value="'.dol_escape_htmltag(GETPOST("search_code_client")).'">';
 	print '</td>';
 
 	print '<td align="left" class="liste_titre">';
-	print '<input class="flat" type="text" size="10" name="search_compta" value="'.$_GET["search_compta"].'">';
+	print '<input class="flat" type="text" size="10" name="search_compta" value="'.dol_escape_htmltag(GETPOST("search_compta")).'">';
 	print '</td>';
 
 	print '<td align="right" colspan="2" class="liste_titre">';
 	print '<input type="image" class="liste_titre" src="'.img_picto($langs->trans("Search"),'search.png','','',1).'" name="button_search" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
 	print '</td>';
+	
 	print "</tr>\n";
 
 	$var=true;
 
-	while ($i < min($num,$conf->liste_limit))
+	while ($i < min($num,$limit))
 	{
 		$obj = $db->fetch_object($resql);
 

+ 63 - 14
htdocs/commande/document.php

@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2003-2007 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2008 Laurent Destailleur   <eldy@users.sourceforge.net>
+ * Copyright (C) 2004-2016 Laurent Destailleur   <eldy@users.sourceforge.net>
  * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
  * Copyright (C) 2005-2012 Regis Houssin         <regis.houssin@capnetworks.com>
  * Copyright (C) 2013      Cédric Salvador       <csalvador@gpcsolutions.fr>
@@ -94,30 +94,79 @@ if ($id > 0 || ! empty($ref))
 		$head = commande_prepare_head($object);
 		dol_fiche_head($head, 'documents', $langs->trans('CustomerOrder'), 0, 'order');
 
-
 		// Construit liste des fichiers
 		$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
 		$totalsize=0;
 		foreach($filearray as $key => $file)
 		{
-			$totalsize+=$file['size'];
+		    $totalsize+=$file['size'];
 		}
-
-
+		
+		// Order card
+		
+		$linkback = '<a href="' . DOL_URL_ROOT . '/commande/list.php' . (! empty($socid) ? '?socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
+		
+		
+		$morehtmlref='<div class="refidno">';
+		// Ref customer
+		$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
+		$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
+		// Thirdparty
+		$morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
+		// Project
+		if (! empty($conf->projet->enabled))
+		{
+		    $langs->load("projects");
+		    $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
+		    if ($user->rights->commande->creer)
+		    {
+		        if ($action != 'classify')
+		            //$morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
+		            $morehtmlref.=' : ';
+		            if ($action == 'classify') {
+		                //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
+		                $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
+		                $morehtmlref.='<input type="hidden" name="action" value="classin">';
+		                $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+		                $morehtmlref.=$formproject->select_projects($object->thirdparty->id, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
+		                $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
+		                $morehtmlref.='</form>';
+		            } else {
+		                $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->thirdparty->id, $object->fk_project, 'none', 0, 0, 0, 1);
+		            }
+		    } else {
+		        if (! empty($object->fk_project)) {
+		            $proj = new Project($db);
+		            $proj->fetch($object->fk_project);
+		            $morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
+		            $morehtmlref.=$proj->ref;
+		            $morehtmlref.='</a>';
+		        } else {
+		            $morehtmlref.='';
+		        }
+		    }
+		}
+		$morehtmlref.='</div>';
+		
+		// Order card
+		
+		$linkback = '<a href="' . DOL_URL_ROOT . '/commande/list.php' . (! empty($socid) ? '?socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
+		
+		dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);	
+		
+		print '<div class="fichecenter">';
+		print '<div class="underbanner clearboth"></div>';
+		
 		print '<table class="border" width="100%">';
 
-		$linkback = '<a href="'.DOL_URL_ROOT.'/commande/list.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
-
-		// Ref
-		print '<tr><td width="30%">'.$langs->trans('Ref').'</td><td colspan="3">';
-		print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref');
-		print '</td></tr>';
-
-		print '<tr><td>'.$langs->trans('Company').'</td><td colspan="3">'.$object->thirdparty->getNomUrl(1).'</td></tr>';
-		print '<tr><td>'.$langs->trans("NbOfAttachedFiles").'</td><td colspan="3">'.count($filearray).'</td></tr>';
+		print '<tr><td class="titlefield">'.$langs->trans("NbOfAttachedFiles").'</td><td colspan="3">'.count($filearray).'</td></tr>';
 		print '<tr><td>'.$langs->trans("TotalSizeOfAttachedFiles").'</td><td colspan="3">'.$totalsize.' '.$langs->trans("bytes").'</td></tr>';
+
 		print "</table>\n";
+		
 		print "</div>\n";
+		
+		print dol_fiche_end();
 
 		$modulepart = 'commande';
 		$permission = $user->rights->commande->creer;

+ 68 - 8
htdocs/commande/info.php

@@ -32,12 +32,21 @@ if (!$user->rights->commande->lire)	accessforbidden();
 $langs->load("orders");
 $langs->load("sendings");
 
-// Security check
 $socid=0;
 $comid = GETPOST("id",'int');
+$id = GETPOST("id",'int');
+$ref=GETPOST('ref','alpha');
+
+// Security check
 if ($user->societe_id) $socid=$user->societe_id;
 $result=restrictedArea($user,'commande',$comid,'');
 
+$object = new Commande($db);
+if (! $object->fetch($id, $ref) > 0)
+{
+    dol_print_error($db);
+    exit;
+}
 
 
 /*
@@ -46,21 +55,72 @@ $result=restrictedArea($user,'commande',$comid,'');
 
 llxHeader('',$langs->trans('Order'),'EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes');
 
-$commande = new Commande($db);
-$commande->fetch($comid);
-$commande->info($comid);
-$soc = new Societe($db);
-$soc->fetch($commande->socid);
+$object->fetch_thirdparty();
+$object->info($object->id);
 
-$head = commande_prepare_head($commande);
+$head = commande_prepare_head($object);
 dol_fiche_head($head, 'info', $langs->trans("CustomerOrder"), 0, 'order');
 
+// Order card
+
+$linkback = '<a href="' . DOL_URL_ROOT . '/commande/list.php' . (! empty($socid) ? '?socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
+
+$morehtmlref='<div class="refidno">';
+// Ref customer
+$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
+$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
+// Thirdparty
+$morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
+// Project
+if (! empty($conf->projet->enabled))
+{
+    $langs->load("projects");
+    $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
+    if ($user->rights->commande->creer)
+    {
+        if ($action != 'classify')
+            //$morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
+            $morehtmlref.=' : ';
+            if ($action == 'classify') {
+                //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
+                $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
+                $morehtmlref.='<input type="hidden" name="action" value="classin">';
+                $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+                $morehtmlref.=$formproject->select_projects($object->thirdparty->id, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
+                $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
+                $morehtmlref.='</form>';
+            } else {
+                $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->thirdparty->id, $object->fk_project, 'none', 0, 0, 0, 1);
+            }
+    } else {
+        if (! empty($object->fk_project)) {
+            $proj = new Project($db);
+            $proj->fetch($object->fk_project);
+            $morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
+            $morehtmlref.=$proj->ref;
+            $morehtmlref.='</a>';
+        } else {
+            $morehtmlref.='';
+        }
+    }
+}
+$morehtmlref.='</div>';
+
+
+dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
+
+print '<div class="fichecenter">';
+print '<div class="underbanner clearboth"></div>';
+
+print '<br>';
 
 print '<table width="100%"><tr><td>';
-dol_print_object_info($commande);
+dol_print_object_info($object);
 print '</td></tr></table>';
 
 print '</div>';
 
+dol_fiche_end();
+
 llxFooter();
 $db->close();

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác