diff --git a/ChangeLog b/ChangeLog
index c0eb78120b0da2510ccf634bbf5220a0a7f807a1..a70c0f58da28d800bab85c50c1a4bbc18c2af8ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@ English Dolibarr ChangeLog
 
 ***** ChangeLog for 3.4 compared to 3.3.2 *****
 For users:
+- New: Can use ODS templates as document templates.
 - New: Add link to autofill/reset with quantity to ship when creating a
   delivery receipt.
 - New: Event into calendar use different colors for different users.
@@ -11,44 +12,48 @@ For users:
 - New: Add a tab "consumption" on thirdparties to list products bought/sells.
 - New: Some performance enhancements.
 - New: Can attach files onto trip and expenses modules.
-- New: Add option MAIN_PDF_TITLE_BACKGROUND_COLOR.
+- New: Add hidden option MAIN_PDF_TITLE_BACKGROUND_COLOR.
 - New: Merge tab customer and prospect.
 - New: Add ES formated address country rule.
-- New: Can define a hierarchical responsible on user.
-- New: Add a hierarchical view for users.
+- New: Can define a hierarchical responsible on user and add a tree view to 
+  see hierarchy of users.
 - New: Can expand/collapse menus, categories and users list.
-- New: extra parameters are supported into ODT templates.
-- New: total per vat rate are available as tags for ODT templates.
-- New: Add more types for extra parameters (lists, phone, emails, checkbox, prices).
+- New: extra parameters are supported into ODT/ODS templates.
+- New: total per vat rate are available as tags for ODT/ODS templates.
 - New: Some part of interface use more CSS3 (ie: agenda)
-- New: [ task #707 ] Create option ProfIdx are mandatory to validate a invoice.
+- New: [ task #707 ] Create option "ProfIdx is mandatory to validate a invoice".
 - New: Can define if we want to use VAT or not for subscriptions (foundation module).
-- New: Can define a default choice for choice "More action when recording
-  a subscription" (foundation module).
-- New: Add link to check professional id for india.
+- New: Can define a default choice for "More action when recording a
+  subscription" (foundation module).
+- New: Add link to check professional id for India.
 - New: [ task #731 ] Uniformize ref generation
 - New: [ task #748 ] Add a link "Dolibarr" into left menu
-- New: Script email_unpaid_invoices_to_representative accepts now a parameter test
-  and a delay.
-- New: Can define a different clicktodial setup per user.
-- New: Add option INVOICE_CAN_NEVER_BE_REMOVED.
-- New: Enhance agenda module to reach RFC2445 (add busy information).
+- New: Script email_unpaid_invoices_to_representative accepts now a parameter "test"
+  and a "late delay".
+- New: Can define different clicktodial setups for each user.
+- New: Add hidden option INVOICE_CAN_NEVER_BE_REMOVED.
+- New: Enhance agenda module to reach RFC2445 ("type" not enabled by default and add
+  "busy" information).
 - New: Add module Opensurvey.
-- New: Default aprrover for holidays i sby default hierchical parent.
+- New: Default approver for holidays is set by default to hierchical parent.
 - First change to prepare feature "click to print" (IPP) for PDF.
-- New: [ task #350 ] Merge tab customer and prospect
-- New: [ task #710 ] Add substitution into mailing send (and HTML is now valid)
-- New: [ task #711 ] Add combobox for contact as done for product/thirdparty
-- New: [ task #714 ] In Emailing module admin autogenerate security key of READRECIEPT
-- New: [ task #743 ] GED : Add aministration option to disabled autotree to display
-- New: [ task #767 ] Customer Address fallback when a contact doesn't have an address
-- New: [ task #768 ] WYSIWYG for all mail
-- New: [ task #773 ] Add Project document in GED(ECM) modules
-- New: [ task #783 ] Add checkbox and radio into extrafield feature
-- New: [ task #798 ] Add range limit date on product/services as it is done on order and invoice
-- New: [ task #814 ] Add extrafield feature into Project/project tasks module
-- New: [ task #770 ] Add ODT document generation for Projects module
-- New: [ task #741 ] Add intervention box
+- New: [ task #350 ] Merge tab customer and prospect.
+- New: [ task #710 ] Add substitution into mailing send (and HTML is now valid).
+- New: [ task #711 ] Add combobox for contact, as done for product/thirdparty.
+- New: [ task #714 ] In Emailing module admin autogenerate security key of READRECEIPT.
+- New: [ task #743 ] GED : Add aministration option to disable autotree display.
+- New: [ task #767 ] Customer Address fallback when a contact doesn't have an address.
+- New: [ task #768 ] WYSIWYG for all mails.
+- New: [ task #773 ] Add Project document in GED(ECM) modules.
+- New: [ task #783 ] Add more types for extra parameters (lists, phone, emails, checkbox,
+  prices, radio).
+- New: [ task #798 ] Add range limit date on product/services as it is done on order 
+  and invoice.
+- New: [ task #814 ] Add extrafield feature for projects ands tasks.
+- New: [ task #770 ] Add ODT document generation for Projects module.
+- New: [ task #741 ] Add intervention box.
+- New: [ task #826 ] Optionnal increase stock when deleting an invoice already validated.
+- New: [ task #823 ] Shipping_validate email notification.
 
 For translators:
 - Update language files.
@@ -58,8 +63,8 @@ For developers:
 - An external module can force its theme.
 - Add function dol_set_focus('#xxx').
 - A mymodule can bring its own core/modules/mymodule/modules_mymodule.php file.
-- Removed not used libraries.
-- More web services. 
+- Removed some not used libraries.
+- More web services.
 - Renamed some database fields, code variables and parameters from french to english.
 - First change to manage margins on contracts.
 - Add hook getFormMail.
@@ -86,7 +91,7 @@ WARNING: If you used external modules, some of them may need to be upgraded due
 
 ***** ChangeLog for 3.3.2 compared to 3.3.1 *****
 
-- Fix: Ducth (nl_NL) translation
+- Fix: Dutch (nl_NL) translation
 - Fix: [ bug #790 ] Spanish localtax RE not being correctly calculated
 - Generalize fix: file with a specific mask not found, again
 - Fix: translations and BILL_SUPPLIER_BUILDDOC trigger
@@ -99,11 +104,12 @@ WARNING: If you used external modules, some of them may need to be upgraded due
 - Fix: [ bug #806 ] Margins module with orders2invoice does not respect cost price
 - Fix: Orderstoinvoice didn't act as expected when no order was checked
 - Fix: Bad link to all proposals into Third party card if customer is prospect
+- Fix: [ bug #774 ] Bug on creating event with box "all day" crossed
 - Fix: [ bug #789 ] VAT not being calculated in POS
 - Fix: [ bug #794 ] Lost filter on zipcode in prospect list
-- Fix: [ bug #774 ] Bug on creating event with box "all day" crossed
 - Fix: [ bug #810 ] Cannot update ODT template path
 - Fix: [ bug #824 ] MAIN_DB_PREFIX not use into dictionnary
+- Fix: [ bug #828 ] Error when code_region is not a number in llx_c_regions (with postgres)
 
 
 ***** ChangeLog for 3.3.1 compared to 3.3 *****
diff --git a/dev/skeletons/modMyModule.class.php b/dev/skeletons/modMyModule.class.php
index 2f203cbfeb214865be205d1bc092fe4a53dc71b1..5711b61c4ac4dd6c66f3e929fe4be261435fae02 100644
--- a/dev/skeletons/modMyModule.class.php
+++ b/dev/skeletons/modMyModule.class.php
@@ -133,7 +133,11 @@ class modMyModule extends DolibarrModules
         $this->tabs = array();
 
         // Dictionnaries
-        if (! isset($conf->mymodule->enabled)) $conf->mymodule->enabled=0;
+	    if (! isset($conf->mymodule->enabled)) 
+        {
+        	$conf->mymodule=new stdClass();
+        	$conf->mymodule->enabled=0;
+        }
 		$this->dictionnaries=array();
         /* Example:
         if (! isset($conf->mymodule->enabled)) $conf->mymodule->enabled=0;	// This is to avoid warnings
diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php
index 87a9b14877efe8c4173b656167fe7a7fe48c6752..13a6bdea81089f34a7f63e0fb03391bb9a22990f 100644
--- a/htdocs/adherents/class/adherent.class.php
+++ b/htdocs/adherents/class/adherent.class.php
@@ -1520,7 +1520,12 @@ class Adherent extends CommonObject
             $lien = '<a href="'.DOL_URL_ROOT.'/adherents/card_subscriptions.php?rowid='.$this->id.'">';
             $lienfin='</a>';
         }
-
+        if ($option == 'category')
+        {
+        	$lien = '<a href="'.DOL_URL_ROOT.'/categories/categorie.php?id='.$this->id.'&type=3">';
+        	$lienfin='</a>';
+        }
+        
         $picto='user';
         $label=$langs->trans("ShowMember");
 
diff --git a/htdocs/admin/agenda.php b/htdocs/admin/agenda.php
index 7eb659bde97b76d51977b7bee3e5c8c350ded457..4e53a709d20c12c9b41aeafcd245eaf673bd025a 100644
--- a/htdocs/admin/agenda.php
+++ b/htdocs/admin/agenda.php
@@ -65,8 +65,8 @@ else
 
 
 /*
-*	Actions
-*/
+ *	Actions
+ */
 if ($action == "save" && empty($cancel))
 {
     $i=0;
@@ -125,7 +125,7 @@ if (preg_match('/del_(.*)/',$action,$reg))
 
 
 /**
- * Affichage du formulaire de saisie
+ * View
  */
 
 llxHeader();
@@ -184,48 +184,7 @@ print "</center>";
 
 print "</form>\n";
 
-print '</div>';
-
-/*
- * Other options
-*/
-
-print_titre($langs->trans("OtherOptions"));
-
-$var=true;
-
-print '<table class="noborder allwidth">'."\n";
-print '<tr class="liste_titre">'."\n";
-print '<td>'.$langs->trans("Parameters").'</td>'."\n";
-print '<td align="center" width="20">&nbsp;</td>'."\n";
-print '<td align="center" width="100">'.$langs->trans("Value").'</td>'."\n";
-print '</tr>'."\n";
-
-// Manual or automatic
-$var=!$var;
-print '<tr '.$bc[$var].'>'."\n";
-print '<td>'.$langs->trans("AGENDA_USE_EVENT_TYPE").'</td>'."\n";
-print '<td align="center" width="20">&nbsp;</td>'."\n";
-
-print '<td align="center" width="100">'."\n";
-if ($conf->use_javascript_ajax)
-{
-	print ajax_constantonoff('AGENDA_USE_EVENT_TYPE');
-}
-else
-{
-	if($conf->global->AGENDA_USE_EVENT_TYPE == 0)
-	{
-		print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_AGENDA_USE_EVENT_TYPE">'.img_picto($langs->trans("Disabled"),'off').'</a>';
-	}
-	else if($conf->global->BUSINESS_VISIBLE_TO_ALL_BY_DEFAULT == 1)
-	{
-		print '<a href="'.$_SERVER['PHP_SELF'].'?action=del_AGENDA_USE_EVENT_TYPE">'.img_picto($langs->trans("Enabled"),'on').'</a>';
-	}
-}
-print '</td></tr>'."\n";
-
-print '</table>';
+dol_fiche_end();
 
 print "<br>";
 
diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php
new file mode 100644
index 0000000000000000000000000000000000000000..cffbed706cee658d6cda5d306aa4f7f0298d9f0f
--- /dev/null
+++ b/htdocs/admin/agenda_other.php
@@ -0,0 +1,135 @@
+<?php
+/* Copyright (C) 2008-2010	Laurent Destailleur <eldy@users.sourceforge.net>
+ * Copyright (C) 2011		Regis Houssin		<regis.houssin@capnetworks.com>
+ * Copyright (C) 2011-2012  Juanjo Menent		<jmenent@2byte.es>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *	    \file       htdocs/admin/agenda.php
+ *      \ingroup    agenda
+ *      \brief      Autocreate actions for agenda module setup page
+ */
+
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
+
+if (!$user->admin)
+    accessforbidden();
+
+$langs->load("admin");
+$langs->load("other");
+
+$action = GETPOST('action','alpha');
+$cancel = GETPOST('cancel','alpha');
+
+
+/*
+ *	Actions
+ */
+
+if (preg_match('/set_(.*)/',$action,$reg))
+{
+	$code=$reg[1];
+	$value=(GETPOST($code) ? GETPOST($code) : 1);
+	if (dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity) > 0)
+	{
+		Header("Location: ".$_SERVER["PHP_SELF"]);
+		exit;
+	}
+	else
+	{
+		dol_print_error($db);
+	}
+}
+
+if (preg_match('/del_(.*)/',$action,$reg))
+{
+	$code=$reg[1];
+	if (dolibarr_del_const($db, $code, $conf->entity) > 0)
+	{
+		Header("Location: ".$_SERVER["PHP_SELF"]);
+		exit;
+	}
+	else
+	{
+		dol_print_error($db);
+	}
+}
+
+
+/**
+ * View
+ */
+
+llxHeader();
+
+$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
+print_fiche_titre($langs->trans("AgendaSetup"),$linkback,'setup');
+print "<br>\n";
+
+
+$head=agenda_prepare_head();
+
+dol_fiche_head($head, 'other', $langs->trans("Agenda"));
+
+print_titre($langs->trans("OtherOptions"));
+
+$var=true;
+
+print '<table class="noborder allwidth">'."\n";
+print '<tr class="liste_titre">'."\n";
+print '<td>'.$langs->trans("Parameters").'</td>'."\n";
+print '<td align="center" width="20">&nbsp;</td>'."\n";
+print '<td align="center" width="100">'.$langs->trans("Value").'</td>'."\n";
+print '</tr>'."\n";
+
+// Manual or automatic
+$var=!$var;
+print '<tr '.$bc[$var].'>'."\n";
+print '<td>'.$langs->trans("AGENDA_USE_EVENT_TYPE").'</td>'."\n";
+print '<td align="center" width="20">&nbsp;</td>'."\n";
+
+print '<td align="center" width="100">'."\n";
+if ($conf->use_javascript_ajax)
+{
+	print ajax_constantonoff('AGENDA_USE_EVENT_TYPE');
+}
+else
+{
+	if($conf->global->AGENDA_USE_EVENT_TYPE == 0)
+	{
+		print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_AGENDA_USE_EVENT_TYPE">'.img_picto($langs->trans("Disabled"),'off').'</a>';
+	}
+	else if($conf->global->BUSINESS_VISIBLE_TO_ALL_BY_DEFAULT == 1)
+	{
+		print '<a href="'.$_SERVER['PHP_SELF'].'?action=del_AGENDA_USE_EVENT_TYPE">'.img_picto($langs->trans("Enabled"),'on').'</a>';
+	}
+}
+print '</td></tr>'."\n";
+
+print '</table>';
+
+dol_fiche_end();
+
+print "<br>";
+
+dol_htmloutput_mesg($mesg);
+
+llxFooter();
+
+$db->close();
+?>
diff --git a/htdocs/admin/carrier.php b/htdocs/admin/carrier.php
deleted file mode 100644
index edb995d3fe7cd02a4de6888d72a8e4c5044fe379..0000000000000000000000000000000000000000
--- a/htdocs/admin/carrier.php
+++ /dev/null
@@ -1,222 +0,0 @@
-<?php
-/*
- * Copyright (C) 2013 Laurent Destailleur   <eldy@users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- *  \file       htdocs/admin/carrier.php
- *  \ingroup    expedition
- *  \brief      Page to setup carriers. TODO Delete this page. We mut use dictionnary instead.
- */
-
-require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
-
-$langs->load("admin");
-$langs->load("sendings");
-$langs->load("deliveries");
-$langs->load('other');
-
-if (! $user->admin)
-    accessforbidden();
-
-$action=GETPOST('action','alpha');
-$carrier=GETPOST('carrier','int');
-
-$object = new Expedition($db);
-
-
-/*
- * Actions
- */
-//if ($action==setvalue AND $carrier)
-if ($action=='setvalue')
-{
-    // need to add check on values
-    $object->update['code']=GETPOST('code','alpha');
-    $object->update['libelle']=GETPOST('libelle','alpha');
-    $object->update['description']=GETPOST('description','alpha');
-    $object->update['tracking']=GETPOST('tracking','alpha');
-    $object->update_delivery_method($carrier);
-    header("Location: carrier.php");
-    exit;
-}
-
-if ($action=='activate_carrier' && $carrier!='')
-{
-    $object->activ_delivery_method($carrier);
-}
-
-if ($action=='disable_carrier' && $carrier!='')
-{
-    $object->disable_delivery_method($carrier);
-}
-
-/*
- * View
- */
-
-$form=new Form($db);
-
-llxHeader("","");
-
-$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
-print_fiche_titre($langs->trans("SendingsSetup"),$linkback,'setup');
-print '<br>';
-
-
-//if ($mesg) print $mesg.'<br>';
-
-
-$h = 0;
-
-$head[$h][0] = DOL_URL_ROOT."/admin/confexped.php";
-$head[$h][1] = $langs->trans("Setup");
-$h++;
-
-$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php";
-$head[$h][1] = $langs->trans("Carriers");
-$hselected=$h;
-$h++;
-
-if (! empty($conf->global->MAIN_SUBMODULE_EXPEDITION))
-{
-    $head[$h][0] = DOL_URL_ROOT."/admin/expedition.php";
-    $head[$h][1] = $langs->trans("Sending");
-    $h++;
-}
-
-if (! empty($conf->global->MAIN_SUBMODULE_LIVRAISON))
-{
-    $head[$h][0] = DOL_URL_ROOT."/admin/livraison.php";
-    $head[$h][1] = $langs->trans("Receivings");
-    $h++;
-}
-
-dol_fiche_head($head, $hselected, $langs->trans("ModuleSetup"));
-
-/*
- * Carrier List
- */
-if ($action=='edit_carrier' || $action=='setvalue')
-{
-    // Carrier Edit
-    if ($carrier!='') $object->list_delivery_methods($carrier);
-    print_titre($langs->trans("CarrierEdit"));
-
-    print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?carrier='.$carrier.'">';
-    print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-    print '<input type="hidden" name="action" value="setvalue">';
-
-
-    print '<table class="nobordernopadding" width="100%">';
-
-    $var=true;
-    print '<tr class="liste_titre">';
-    print '<td width="150">'.$langs->trans("CarrierParameter").'</td>';
-    print '<td>'.$langs->trans("Value").'</td>';
-    print "</tr>\n";
-
-    $var=!$var;
-    print '<tr '.$bc[$var].'><td class="fieldrequired">';
-    print $langs->trans("Code").'</td><td>';
-    print '<input size="32" type="text" name="code" value="'.$object->listmeths[0]['code'].'">';
-    print ' &nbsp; '.$langs->trans("Example").': CODE';
-    print '</td></tr>';
-
-    $var=!$var;
-    print '<tr '.$bc[$var].'><td class="fieldrequired">';
-    print $langs->trans("Name").'</td><td>';
-    print '<input size="32" type="text" name="libelle" value="'.$object->listmeths[0]['libelle'].'">';
-    print '</td></tr>';
-
-    $var=!$var;
-    print '<tr '.$bc[$var].'><td class="fieldrequired">';
-    print $langs->trans("Description").'</td><td>';
-    print '<input size="64" type="text" name="description" value="'.$object->listmeths[0]['description'].'">';
-    print '</td></tr>';
-
-    $var=!$var;
-    print '<tr '.$bc[$var].'><td class="fieldrequired">';
-    print $langs->trans("Tracking").'</td><td>';
-    print '<input size="80" type="text" name="tracking" value="'.$object->listmeths[0]['tracking'].'">';
-    print ' &nbsp; '.$langs->trans("Example").': http://www.website.com/dir/{TRACKID}';
-    print '</td></tr>';
-
-    if ($carrier)
-    {
-    print '<tr><td colspan="2" align="center"><br><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td></tr>';
-    }
-    else
-    {
-    print '<tr><td colspan="2" align="center"><br><input type="submit" class="button" value="'.$langs->trans("Add").'"></td></tr>';
-    }
-
-    print '</table>';
-    print '</form>';
-
-}
-else
-{
-    // Display List
-    $object->list_delivery_methods();
-    $var=true;
-    print_titre($langs->trans("CarrierList"));
-
-    print '<table class="noborder" width="100%">';
-    print '<tr class="liste_titre">';
-    print '<td width="80">'.$langs->trans("Code").'</td>';
-    print '<td width="150">'.$langs->trans("Name").'</td>';
-    print '<td>'.$langs->trans("Description").'</td>';
-    print '<td>'.$langs->trans("TrackingUrl").'</td>';
-    print '<td align="center" width="60">'.$langs->trans("Status").'</td>';
-    print '<td align="center" width="30">'.$langs->trans("Edit").'</td>';
-    print "</tr>\n";
-    $numlistmeths=count($object->listmeths);
-    for ($i=0; $i<$numlistmeths; $i++)
-    {
-        $var=!$var;
-        print "<tr ".$bc[$var].">";
-        print '<td>'.$object->listmeths[$i]['code'].'</td>';
-        print '<td>'.$object->listmeths[$i]['libelle'].'</td>';
-        print '<td>'.$object->listmeths[$i]['description'].'</td>';
-        print '<td>'.dol_trunc($object->listmeths[$i]['tracking'],92,'middle').'</td>';
-        print '<td align="center">';
-        if($object->listmeths[$i]['active'] == 0)
-        {
-            print '<a href="carrier.php?action=activate_carrier&amp;carrier='.$object->listmeths[$i]['rowid'].'">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>';
-        }
-        else
-        {
-            print '<a href="carrier.php?action=disable_carrier&amp;carrier='.$object->listmeths[$i]['rowid'].'">'.img_picto($langs->trans("Enabled"),'switch_on').'</a>';
-        }
-        print '</td><td align="center">';
-        print '<a href="carrier.php?action=edit_carrier&amp;carrier='.$object->listmeths[$i]['rowid'].'">'.img_picto($langs->trans("Edit"),'edit').'</a>';
-        print '</td>';
-        print "</tr>\n";
-    }
-            print '<tr><td align="center"><a href="carrier.php?action=edit_carrier"><br>'.$langs->trans("Add").'</a></td><tr>';
-
-    print '</table><br>';
-
-    print '</div>';
-}
-
-llxFooter();
-
-$db->close();
-?>
diff --git a/htdocs/admin/compta.php b/htdocs/admin/compta.php
index a5213413d546a925a226bfe435670eae17bbc5e1..c30af26f1c009d09325375ea541537e874852bc7 100644
--- a/htdocs/admin/compta.php
+++ b/htdocs/admin/compta.php
@@ -107,7 +107,7 @@ print '<br>';
 $h = 0;
 
 $head[$h][0] = DOL_URL_ROOT."/admin/compta.php";
-$head[$h][1] = $langs->trans("Compta");
+$head[$h][1] = $langs->trans("Accountancy");
 $head[$h][2] = 'Compta';
 $hselected=$h;
 $h++;
diff --git a/htdocs/admin/confexped.php b/htdocs/admin/confexped.php
index 6653badfb36443924471fe1336435488ec187dda..d9be768461ffa088a69e55ddf0ab9205253a99ab 100644
--- a/htdocs/admin/confexped.php
+++ b/htdocs/admin/confexped.php
@@ -84,10 +84,6 @@ $head[$h][1] = $langs->trans("Setup");
 $hselected=$h;
 $h++;
 
-$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php";
-$head[$h][1] = $langs->trans("Carriers");
-$h++;
-
 if (! empty($conf->global->MAIN_SUBMODULE_EXPEDITION))
 {
 	$head[$h][0] = DOL_URL_ROOT."/admin/expedition.php";
diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php
index cf93f472019bfd8c8d89fd43a53469b2539f5873..41178e36012b24bc44465b66c978586cdf8cd377 100644
--- a/htdocs/admin/dict.php
+++ b/htdocs/admin/dict.php
@@ -6,9 +6,9 @@
  * Copyright (C) 2010-2011 Juanjo Menent        <jmenent@2byte.es>
  * Copyright (C) 2011      Philippe Grand       <philippe.grand@atoo-net.com>
  * Copyright (C) 2011      Remy Younes          <ryounes@gmail.com>
- * Copyright (C) 2012      Marcos García        <marcosgdf@gmail.com>
+ * Copyright (C) 2012-2013 Marcos García        <marcosgdf@gmail.com>
  * Copyright (C) 2012      Christophe Battarel	<christophe.battarel@ltairis.fr>
- * Copyright (C) 2011-2012 Alexandre Spangaro	  <alexandre.spangaro@gmail.com>
+ * Copyright (C) 2011-2012 Alexandre Spangaro	<alexandre.spangaro@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -147,7 +147,7 @@ $tabsql[14]= "SELECT e.rowid as rowid, e.code as code, e.libelle, e.price, e.org
 $tabsql[15]= "SELECT rowid   as rowid, code, label as libelle, width, height, unit, active FROM ".MAIN_DB_PREFIX."c_paper_format";
 $tabsql[16]= "SELECT code, label as libelle, active FROM ".MAIN_DB_PREFIX."c_prospectlevel";
 $tabsql[17]= "SELECT id      as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_type_fees";
-$tabsql[18]= "SELECT rowid   as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_shipment_mode";
+$tabsql[18]= "SELECT rowid   as rowid, code, libelle, tracking, active FROM ".MAIN_DB_PREFIX."c_shipment_mode";
 $tabsql[19]= "SELECT id      as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_effectif";
 $tabsql[20]= "SELECT rowid   as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_input_method";
 $tabsql[21]= "SELECT c.rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_availability AS c";
@@ -203,7 +203,7 @@ $tabfield[14]= "code,libelle,price,organization,country_id,country";
 $tabfield[15]= "code,libelle,width,height,unit";
 $tabfield[16]= "code,libelle";
 $tabfield[17]= "code,libelle";
-$tabfield[18]= "code,libelle";
+$tabfield[18]= "code,libelle,tracking";
 $tabfield[19]= "code,libelle";
 $tabfield[20]= "code,libelle";
 $tabfield[21]= "code,label";
@@ -231,7 +231,7 @@ $tabfieldvalue[14]= "code,libelle,price,organization,country";
 $tabfieldvalue[15]= "code,libelle,width,height,unit";
 $tabfieldvalue[16]= "code,libelle";
 $tabfieldvalue[17]= "code,libelle";
-$tabfieldvalue[18]= "code,libelle";
+$tabfieldvalue[18]= "code,libelle,tracking";
 $tabfieldvalue[19]= "code,libelle";
 $tabfieldvalue[20]= "code,libelle";
 $tabfieldvalue[21]= "code,label";
@@ -259,7 +259,7 @@ $tabfieldinsert[14]= "code,libelle,price,organization,fk_pays";
 $tabfieldinsert[15]= "code,label,width,height,unit";
 $tabfieldinsert[16]= "code,label";
 $tabfieldinsert[17]= "code,libelle";
-$tabfieldinsert[18]= "code,libelle";
+$tabfieldinsert[18]= "code,libelle,tracking";
 $tabfieldinsert[19]= "code,libelle";
 $tabfieldinsert[20]= "code,libelle";
 $tabfieldinsert[21]= "code,label";
@@ -391,7 +391,7 @@ if ($id == 11)
 
 // Define localtax_typeList (used for dictionnary "c_tva")
 $localtax_typeList = array();
-if (GETPOST("id") == 10)
+if ($id == 10)
 {
 	$localtax_typeList = array(
 			"0" => $langs->trans("No"),
@@ -441,22 +441,32 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
             if ($fieldnamekey == 'position') $fieldnamekey = 'Position';
             if ($fieldnamekey == 'unicode') $fieldnamekey = 'Unicode';
 
-            $msg.=$langs->trans("ErrorFieldRequired",$langs->transnoentities($fieldnamekey)).'<br>';
+            $msg.=$langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)).'<br>';
         }
     }
     // Other checks
     if ($tabname[$id] == MAIN_DB_PREFIX."c_actioncomm" && isset($_POST["type"]) && in_array($_POST["type"],array('system','systemauto'))) {
         $ok=0;
-        $msg.="Value 'system' and 'systemauto' for type is reserved. You can use 'user' as value to add your own record.<br>";
+        $msg.= $langs->transnoentities('ErrorReservedTypeSystemSystemAuto').'<br>';
     }
-    if (isset($_POST["code"]) && $_POST["code"]=='0') {
-        $ok=0;
-        $msg.="Code can't contains value 0<br>";
+    if (isset($_POST["code"]))
+    {
+    	if ($_POST["code"]=='0')
+    	{
+        	$ok=0;
+        	$msg.= $langs->transnoentities('ErrorCodeCantContainZero').'<br>';
+        }
+        if (!is_numeric($_POST['code']))
+    	{
+	    	$ok = 0;
+	    	$msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'<br />';
+	    }
     }
     if (isset($_POST["country"]) && $_POST["country"]=='0') {
         $ok=0;
-        $msg.=$langs->trans("ErrorFieldRequired",$langs->trans("Country")).'<br>';
+        $msg.=$langs->transnoentities("ErrorFieldRequired",$langs->transnoentities("Country")).'<br>';
     }
+
 	// Clean some parameters
     if (isset($_POST["localtax1"]) && empty($_POST["localtax1"])) $_POST["localtax1"]='0';	// If empty, we force to 0
     if (isset($_POST["localtax2"]) && empty($_POST["localtax2"])) $_POST["localtax2"]='0';	// If empty, we force to 0
@@ -518,7 +528,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
         else
         {
             if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
-                $msg=$langs->trans("ErrorRecordAlreadyExists").'<br>';
+                $msg=$langs->transnoentities("ErrorRecordAlreadyExists").'<br>';
             }
             else {
                 dol_print_error($db);
@@ -588,7 +598,7 @@ if ($action == 'confirm_delete' && $confirm == 'yes')       // delete
     {
         if ($db->errno() == 'DB_ERROR_CHILD_EXISTS')
         {
-            $msg='<div class="error">'.$langs->trans("ErrorRecordIsUsedByChild").'</div>';
+            $msg='<div class="error">'.$langs->transnoentities("ErrorRecordIsUsedByChild").'</div>';
         }
         else
         {
@@ -994,6 +1004,7 @@ if ($id)
                                 $valuetoshow=($obj->code && $key != "Civility".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
                             }
                             else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_type_contact') {
+                            	$langs->load('agenda');
                                 $key=$langs->trans("TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code));
                                 $valuetoshow=($obj->code && $key != "TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]);
                             }
@@ -1084,15 +1095,23 @@ if ($id)
                     }
 
                     // Est-ce une entree du dictionnaire qui peut etre desactivee ?
-                    $iserasable=1;  // Oui par defaut
-                    if (isset($obj->code) && ($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i',$obj->code))) $iserasable=0;
-                    if (isset($obj->code) && $obj->code == 'RECEP') $iserasable=0;
-                    if (isset($obj->code) && $obj->code == 'EF0') $iserasable=0;
+                    // True by default
+                    $iserasable=1;
+
+                    if (isset($obj->code))
+                    {
+                    	if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i',$obj->code))) $iserasable = 0;
+                    	else if ($obj->code == 'RECEP') $iserasable = 0;
+                    	else if ($obj->code == 'EF0') $iserasable = 0;
+                    } 
+
                     if (isset($obj->type) && in_array($obj->type, array('system', 'systemauto'))) $iserasable=0;
 
+                    $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&amp;code='.(! empty($obj->code)?$obj->code:'').'&amp;id='.$id.'&amp;';
+
                     // Active
                     print '<td align="center" nowrap="nowrap">';
-                    if ($iserasable) print '<a href="'.$_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&amp;code='.(! empty($obj->code)?$obj->code:'').'&amp;id='.$id.'&amp;action='.$acts[$obj->active].'">'.$actl[$obj->active].'</a>';
+                    if ($iserasable) print '<a href="'.$url.'action='.$acts[$obj->active].'">'.$actl[$obj->active].'</a>';
                     else
                  	{
                   		if (isset($obj->type) && in_array($obj->type, array('system', 'systemauto')) && empty($obj->active)) print $langs->trans("Deprecated");
@@ -1101,11 +1120,11 @@ if ($id)
                     print "</td>";
 
                     // Modify link
-                    if ($iserasable) print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&amp;code='.(! empty($obj->code)?$obj->code:'').'&amp;id='.$id.'&amp;action=edit#'.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'">'.img_edit().'</a></td>';
+                    if ($iserasable) print '<td align="center"><a href="'.$url.'action=edit#'.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'">'.img_edit().'</a></td>';
                     else print '<td>&nbsp;</td>';
 
                     // Delete link
-                    if ($iserasable) print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&amp;code='.(! empty($obj->code)?$obj->code:'').'&amp;id='.$id.'&amp;action=delete">'.img_delete().'</a></td>';
+                    if ($iserasable) print '<td align="center"><a href="'.$url.'action=delete">'.img_delete().'</a></td>';
                     else print '<td>&nbsp;</td>';
 
                     print "</tr>\n";
@@ -1153,7 +1172,7 @@ else
 
             $var=!$var;
             $value=$tabname[$i];
-            print '<tr '.$bc[$var].'><td width="30%">';
+            print '<tr '.$bc[$var].'><td width="50%">';
             if (! empty($tabcond[$i]))
             {
                 print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$i.'">'.$langs->trans($tablib[$i]).'</a>';
@@ -1299,6 +1318,7 @@ function fieldList($fieldlist,$obj='',$tabname='')
 			print '<td>';
 			$size='';
 			if ($fieldlist[$field]=='libelle') $size='size="32" ';
+			if ($fieldlist[$field]=='tracking') $size='size="92" ';
 			if ($fieldlist[$field]=='accountancy_code') $size='size="15" ';
 			if ($fieldlist[$field]=='accountancy_code_sell') $size='size="15" ';
 			if ($fieldlist[$field]=='accountancy_code_buy') $size='size="15" ';
diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php
index 34535b1d321e792ae5ec10c1548a847c105b9808..28e5b912de2090462108ba0ae4f0f98c5ff451ca 100644
--- a/htdocs/admin/expedition.php
+++ b/htdocs/admin/expedition.php
@@ -201,10 +201,6 @@ $head[$h][0] = DOL_URL_ROOT."/admin/confexped.php";
 $head[$h][1] = $langs->trans("Setup");
 $h++;
 
-$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php";
-$head[$h][1] = $langs->trans("Carriers");
-$h++;
-
 $head[$h][0] = DOL_URL_ROOT."/admin/expedition.php";
 $head[$h][1] = $langs->trans("Sending");
 $hselected=$h;
diff --git a/htdocs/admin/livraison.php b/htdocs/admin/livraison.php
index 49cbeee902633144c365b5da7c44def23446b527..677e2b3773b76bfada437be4514439d887b0e00e 100644
--- a/htdocs/admin/livraison.php
+++ b/htdocs/admin/livraison.php
@@ -189,10 +189,6 @@ $head[$h][0] = DOL_URL_ROOT."/admin/confexped.php";
 $head[$h][1] = $langs->trans("Setup");
 $h++;
 
-$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php";
-$head[$h][1] = $langs->trans("Carriers");
-$h++;
-
 if (! empty($conf->global->MAIN_SUBMODULE_EXPEDITION))
 {
     $head[$h][0] = DOL_URL_ROOT."/admin/expedition.php";
diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php
index 569200f35e480c4861163fc1c9c36ba8364bb2aa..f7bd7ad95d757515cb64d9ed63e2e7cce2cf4dc1 100644
--- a/htdocs/admin/menus/edit.php
+++ b/htdocs/admin/menus/edit.php
@@ -29,6 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/menubase.class.php';
 
 
 $langs->load("admin");
+$langs->load('other');
 
 if (! $user->admin) accessforbidden();
 
diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php
index 4440d632b2e6440fa740e983695d8f91c0b64ed0..acdf756eb86de00428cb1c34fb623ffc5b76f732 100644
--- a/htdocs/admin/modules.php
+++ b/htdocs/admin/modules.php
@@ -194,7 +194,7 @@ asort($orders);
 
 $nbofactivatedmodules=count($conf->modules);
 $moreinfo=$langs->trans("TotalNumberOfActivatedModules",($nbofactivatedmodules-1));
-
+if ($nbofactivatedmodules <= 1) $moreinfo .= ' '.img_warning($langs->trans("YouMustEnableOneModule"));
 print load_fiche_titre($langs->trans("ModulesSetup"),$moreinfo,'setup');
 
 // Start to show page
@@ -206,7 +206,7 @@ if ($mode==='functional')  print $langs->trans("ModulesJobDesc")."<br>\n";
 if ($mode==='marketplace') print $langs->trans("ModulesMarketPlaceDesc")."<br>\n";
 if ($mode==='expdev')      print $langs->trans("ModuleFamilyExperimental")."<br>\n";
 
-if ($nbofactivatedmodules <= 1) print ' '.img_warning($langs->trans("YouMustEnableOneModule"));
+
 //print '<br>'."\n";
 
 
diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php
index bbdbf3276db09d3752d4ed9d4ea8a1c81b304462..0390efcdda47ad7c55b9e73fa00d49eb0af84740 100644
--- a/htdocs/admin/stock.php
+++ b/htdocs/admin/stock.php
@@ -4,6 +4,7 @@
  * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
  * Copyright (C) 2012      Juanjo Menent		<jmenent@2byte.es>
  * Copyright (C) 2013      Philippe Grand       <philippe.grand@atoo-net.com>
+ * Copyright (C) 2013      Florian Henry       <florian.henry@open-concept.pro>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -67,6 +68,7 @@ if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_BILL'
 	$res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_BILL", '','chaine',0,'',$conf->entity);
 	$res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", '','chaine',0,'',$conf->entity);
 	$res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", '','chaine',0,'',$conf->entity);
+	$res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_DELETE_INVOICE", '','chaine',0,'',$conf->entity);
 	if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_BILL')           $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_BILL", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_BILL','alpha'),'chaine',0,'',$conf->entity);
 	if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER','alpha'),'chaine',0,'',$conf->entity);
 	if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER','alpha'),'chaine',0,'',$conf->entity);
@@ -239,6 +241,19 @@ if (! empty($conf->fournisseur->enabled))
 	print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
 	print "</form>\n</td>\n</tr>\n";
 }
+if (! empty($conf->facture->enabled))
+{
+	$var=!$var;
+	print "<tr ".$bc[$var].">";
+	print '<td width="60%">'.$langs->trans("ReStockOnDeleteInvoice").'</td>';
+	print '<td width="160" align="right">';
+	print "<form method=\"post\" action=\"stock.php\">";
+	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+	print "<input type=\"hidden\" name=\"action\" value=\"STOCK_CALCULATE_ON_DELETE_INVOICE\">";
+	print $form->selectyesno("STOCK_CALCULATE_ON_DELETE_INVOICE",$conf->global->STOCK_CALCULATE_ON_DELETE_INVOICE,1);
+	print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
+	print "</form>\n</td>\n</tr>\n";
+}
 
 print '</table>';
 
diff --git a/htdocs/categories/categorie.php b/htdocs/categories/categorie.php
index ddc7079c7866211b4b8f2422c5c8290d05f6b4e0..ec2a2b49d63a4889f905a6077e7bf77aa98fd6f9 100644
--- a/htdocs/categories/categorie.php
+++ b/htdocs/categories/categorie.php
@@ -99,7 +99,7 @@ $error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->e
 
 if (empty($reshook))
 {
-	//Suppression d'un objet d'une categorie
+	// Remove element from category
 	if ($removecat > 0)
 	{
 		if ($type==0 && ($user->rights->produit->creer || $user->rights->service->creer))
@@ -113,17 +113,20 @@ if (empty($reshook))
 		{
 			$object = new Societe($db);
 			$result = $object->fetch($objectid);
+			$elementtype = 'fournisseur';
 		}
 		if ($type==2 && $user->rights->societe->creer)
 		{
 			$object = new Societe($db);
 			$result = $object->fetch($objectid);
+			$elementtype = 'societe';
 		}
 		if ($type == 3 && $user->rights->adherent->creer)
 		{
 			require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
 			$object = new Adherent($db);
 			$result = $object->fetch($objectid);
+			$elementtype = 'member';
 		}
 		$cat = new Categorie($db);
 		$result=$cat->fetch($removecat);
@@ -507,7 +510,7 @@ function formCategory($db,$object,$typeid,$socid=0)
 				//print $c->getNomUrl(1);
 				print img_object('','category').' '.$way."</td>";
 
-				// Lien supprimer
+				// Link to delete from category
 				print '<td align="right">';
 				$permission=0;
 				if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer);
diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php
index 96c111f2dc0c15084366811d8d3b65363a9bec51..377c06fd8d8f5a3a795bc8d1038de9005bd65f37 100644
--- a/htdocs/categories/class/categorie.class.php
+++ b/htdocs/categories/class/categorie.class.php
@@ -420,6 +420,7 @@ class Categorie
 		$sql .= " WHERE fk_categorie = ".$this->id;
 		$sql .= " AND   fk_".($type=='fournisseur'?'societe':$type)."   = ".$obj->id;
 
+		dol_syslog(get_class($this).'::del_type sql='.$sql);
 		if ($this->db->query($sql))
 		{
 			return 1;
diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php
index f174f5f4a60e7846f7eb11f271ea8b0261fad42b..57cffd387de53d7a92f9af4694d81b94a1d6f227 100644
--- a/htdocs/categories/viewcat.php
+++ b/htdocs/categories/viewcat.php
@@ -36,6 +36,7 @@ $ref=GETPOST('ref');
 $type=GETPOST('type');
 $action=GETPOST('action');
 $confirm=GETPOST('confirm');
+$removeelem = GETPOST('removeelem','int');
 
 if ($id == "")
 {
@@ -61,6 +62,40 @@ $type=$object->type;
  *	Actions
  */
 
+// Remove element from category
+if ($id > 0 && $removeelem > 0)
+{
+	if ($type==0 && ($user->rights->produit->creer || $user->rights->service->creer))
+	{
+		require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+		$tmpobject = new Product($db);
+		$result = $tmpobject->fetch($removeelem);
+		$elementtype = 'product';
+	}
+	if ($type==1 && $user->rights->societe->creer)
+	{
+		$tmpobject = new Societe($db);
+		$result = $tmpobject->fetch($removeelem);
+		$elementtype = 'fournisseur';
+	}
+	if ($type==2 && $user->rights->societe->creer)
+	{
+		$tmpobject = new Societe($db);
+		$result = $tmpobject->fetch($removeelem);
+		$elementtype = 'societe';
+	}
+	if ($type == 3 && $user->rights->adherent->creer)
+	{
+		require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
+		$tmpobject = new Adherent($db);
+		$result = $tmpobject->fetch($removeelem);
+		$elementtype = 'member';
+	}
+	
+	$result=$object->del_type($tmpobject,$elementtype);
+	if ($result < 0) dol_print_error('',$object->error);
+}
+
 if ($user->rights->categorie->supprimer && $action == 'confirm_delete' && $confirm == 'yes')
 {
 	if ($object->delete($user) >= 0)
@@ -214,7 +249,7 @@ if ($object->type == 0)
 	{
 		print "<br>";
 		print "<table class='noborder' width='100%'>\n";
-		print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("ProductsAndServices")."</td></tr>\n";
+		print '<tr class="liste_titre"><td colspan="3">'.$langs->trans("ProductsAndServices")."</td></tr>\n";
 
 		if (count($prods) > 0)
 		{
@@ -224,10 +259,24 @@ if ($object->type == 0)
 				$var=!$var;
 				print "\t<tr ".$bc[$var].">\n";
 				print '<td nowrap="nowrap" valign="top">';
-				if ($prod->type == 1) print img_object($langs->trans("ShowService"),"service");
-				else print img_object($langs->trans("ShowProduct"),"product");
-				print " <a href='".DOL_URL_ROOT."/product/fiche.php?id=".$prod->id."'>".$prod->ref."</a></td>\n";
+				print $prod->getNomUrl(1,'category');
+				print "</td>\n";
 				print '<td valign="top">'.$prod->libelle."</td>\n";
+				// Link to delete from category
+				print '<td align="right">';
+				$typeid=$object->type;
+				$permission=0;
+				if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer);
+				if ($typeid == 1) $permission=$user->rights->societe->creer;
+				if ($typeid == 2) $permission=$user->rights->societe->creer;
+				if ($typeid == 3) $permission=$user->rights->adherent->creer;
+				if ($permission)
+				{
+					print "<a href= '".$_SERVER['PHP_SELF']."?".(empty($socid)?'id':'socid')."=".$object->id."&amp;type=".$typeid."&amp;removeelem=".$prod->id."'>";
+					print img_delete($langs->trans("DeleteFromCat")).' ';
+					print $langs->trans("DeleteFromCat")."</a>";
+				}
+				print '</td>';
 				print "</tr>\n";
 			}
 		}
@@ -249,8 +298,8 @@ if ($object->type == 1)
 	else
 	{
 		print "<br>";
-		print "<table class='noborder' width='100%'>\n";
-		print "<tr class='liste_titre'><td>".$langs->trans("Suppliers")."</td></tr>\n";
+		print '<table class="noborder" width="100%">'."\n";
+		print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Suppliers")."</td></tr>\n";
 
 		if (count($socs) > 0)
 		{
@@ -261,9 +310,24 @@ if ($object->type == 1)
 				print "\t<tr ".$bc[$var].">\n";
 
 				print '<td nowrap="nowrap" valign="top">';
-				print $soc->getNomUrl(1);
+				print $soc->getNomUrl(1,'category_supplier');
 				print "</td>\n";
-
+				// Link to delete from category
+				print '<td align="right">';
+				$typeid=$object->type;
+				$permission=0;
+				if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer);
+				if ($typeid == 1) $permission=$user->rights->societe->creer;
+				if ($typeid == 2) $permission=$user->rights->societe->creer;
+				if ($typeid == 3) $permission=$user->rights->adherent->creer;
+				if ($permission)
+				{
+					print "<a href= '".$_SERVER['PHP_SELF']."?".(empty($socid)?'id':'socid')."=".$object->id."&amp;type=".$typeid."&amp;removeelem=".$soc->id."'>";
+					print img_delete($langs->trans("DeleteFromCat")).' ';
+					print $langs->trans("DeleteFromCat")."</a>";
+				}
+				print '</td>';
+				
 				print "</tr>\n";
 			}
 		}
@@ -285,8 +349,8 @@ if($object->type == 2)
 	else
 	{
 		print "<br>";
-		print "<table class='noborder' width='100%'>\n";
-		print "<tr class='liste_titre'><td>".$langs->trans("Customers")."</td></tr>\n";
+		print '<table class="noborder" width="100%">'."\n";
+		print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Customers")."</td></tr>\n";
 
 		if (count($socs) > 0)
 		{
@@ -298,9 +362,23 @@ if($object->type == 2)
 				$var=!$var;
 				print "\t<tr ".$bc[$var].">\n";
 				print '<td nowrap="nowrap" valign="top">';
-				print $soc->getNomUrl(1);
+				print $soc->getNomUrl(1,'category');
 				print "</td>\n";
-
+				// Link to delete from category
+				print '<td align="right">';
+				$typeid=$object->type;
+				$permission=0;
+				if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer);
+				if ($typeid == 1) $permission=$user->rights->societe->creer;
+				if ($typeid == 2) $permission=$user->rights->societe->creer;
+				if ($typeid == 3) $permission=$user->rights->adherent->creer;
+				if ($permission)
+				{
+					print "<a href= '".$_SERVER['PHP_SELF']."?".(empty($socid)?'id':'socid')."=".$object->id."&amp;type=".$typeid."&amp;removeelem=".$soc->id."'>";
+					print img_delete($langs->trans("DeleteFromCat")).' ';
+					print $langs->trans("DeleteFromCat")."</a>";
+				}
+				print '</td>';
 				print "</tr>\n";
 			}
 		}
@@ -326,7 +404,7 @@ if ($object->type == 3)
 	{
 		print "<br>";
 		print "<table class='noborder' width='100%'>\n";
-		print '<tr class="liste_titre"><td colspan="3">'.$langs->trans("Member")."</td></tr>\n";
+		print '<tr class="liste_titre"><td colspan="4">'.$langs->trans("Member")."</td></tr>\n";
 
 		if (count($prods) > 0)
 		{
@@ -336,10 +414,25 @@ if ($object->type == 3)
 				$var=!$var;
 				print "\t<tr ".$bc[$var].">\n";
 				print '<td nowrap="nowrap" valign="top">';
-				print $member->getNomUrl(1);
+				$member->ref=$member->login;
+				print $member->getNomUrl(1,0,'category');
 				print "</td>\n";
 				print '<td valign="top">'.$member->lastname."</td>\n";
 				print '<td valign="top">'.$member->firstname."</td>\n";
+				// Link to delete from category
+				print '<td align="right">';
+				$typeid=$object->type;
+				$permission=0;
+				if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer);
+				if ($typeid == 1) $permission=$user->rights->societe->creer;
+				if ($typeid == 2) $permission=$user->rights->societe->creer;
+				if ($typeid == 3) $permission=$user->rights->adherent->creer;
+				if ($permission)
+				{
+					print "<a href= '".$_SERVER['PHP_SELF']."?".(empty($socid)?'id':'socid')."=".$object->id."&amp;type=".$typeid."&amp;removeelem=".$member->id."'>";
+					print img_delete($langs->trans("DeleteFromCat")).' ';
+					print $langs->trans("DeleteFromCat")."</a>";
+				}
 				print "</tr>\n";
 			}
 		}
diff --git a/htdocs/comm/action/class/cactioncomm.class.php b/htdocs/comm/action/class/cactioncomm.class.php
index c686db153c4b65fc6fa94f46904d530e010d59a0..e9fe439e75c22a9de6f221b883b9d83ce2066240 100644
--- a/htdocs/comm/action/class/cactioncomm.class.php
+++ b/htdocs/comm/action/class/cactioncomm.class.php
@@ -132,7 +132,7 @@ class CActionComm
                     $qualified=1;
 
                     // $obj->type can be system, systemauto, module, moduleauto, xxx, xxxauto
-                    if ($qualified && $onlyautoornot && preg_match('/^system/',$obj->type) && ! preg_match('/^AC_OTH/',$obj->code)) $qualified=0;	// We discard detailed system events. We keep only the 2 generic lines (AC_OTH and AC_OTHER)
+                    if ($qualified && $onlyautoornot && preg_match('/^system/',$obj->type) && ! preg_match('/^AC_OTH/',$obj->code)) $qualified=0;	// We discard detailed system events. We keep only the 2 generic lines (AC_OTH and AC_OTH_AUTO)
 
                     if ($qualified && $obj->module)
                     {
diff --git a/htdocs/comm/action/fiche.php b/htdocs/comm/action/fiche.php
index 37c5aaba693913ff2311b6d37c841df31d6288a3..4b4917715b5f0acaf80bc8eaf22c042f9bebee90 100644
--- a/htdocs/comm/action/fiche.php
+++ b/htdocs/comm/action/fiche.php
@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2004-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005      Simon TOSSER         <simon@kornog-computing.com>
  * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
  * Copyright (C) 2010      Juanjo Menent        <jmenent@2byte.es>
@@ -592,7 +592,7 @@ if ($action == 'create')
     // Description
     print '<tr><td valign="top">'.$langs->trans("Description").'</td><td>';
     require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-    $doleditor=new DolEditor('note',(GETPOST('note')?GETPOST('note'):$actioncomm->note),'',280,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_7,90);
+    $doleditor=new DolEditor('note',(GETPOST('note')?GETPOST('note'):$actioncomm->note),'',240,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_7,90);
     $doleditor->Create();
     print '</td></tr>';
 
@@ -663,7 +663,6 @@ if ($id > 0)
 	 */
 
 	$head=actions_prepare_head($act);
-	dol_fiche_head($head, 'card', $langs->trans("Action"),0,'action');
 
 	$now=dol_now();
 	$delay_warning=$conf->global->MAIN_DELAY_ACTIONS_TODO*24*60*60;
@@ -711,6 +710,8 @@ if ($id > 0)
 		print '<input type="hidden" name="ref_ext" value="'.$act->ref_ext.'">';
 		if ($backtopage) print '<input type="hidden" name="backtopage" value="'.($backtopage != '1'? $backtopage : $_SERVER["HTTP_REFERER"]).'">';
 
+		dol_fiche_head($head, 'card', $langs->trans("Action"),0,'action');
+		
 		print '<table class="border" width="100%">';
 
 		// Ref
@@ -836,7 +837,9 @@ if ($id > 0)
 
 		print '</table>';
 
-		print '<center><br><input type="submit" class="button" name="edit" value="'.$langs->trans("Save").'">';
+		dol_fiche_end();
+		
+		print '<center><input type="submit" class="button" name="edit" value="'.$langs->trans("Save").'">';
 		print ' &nbsp; &nbsp; <input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
 		print '</center>';
 
@@ -844,6 +847,8 @@ if ($id > 0)
 	}
 	else
 	{
+		dol_fiche_head($head, 'card', $langs->trans("Action"),0,'action');
+		
 		// Affichage fiche action en mode visu
 		print '<table class="border" width="100%">';
 
@@ -1021,14 +1026,13 @@ if ($id > 0)
 			}
 			print '</table><br><br>';
 		}
-	}
 
-	print "</div>\n";
+		dol_fiche_end();
+	}
 
 
 	/*
 	 * Barre d'actions
-	 *
 	 */
 
 	print '<div class="tabsAction">';
diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php
index 49a84a28d227710984e379f06a1b5508d83f0b06..813c25783746cdeaee88438be15eb45f8d215901 100644
--- a/htdocs/comm/action/index.php
+++ b/htdocs/comm/action/index.php
@@ -1,7 +1,7 @@
 <?php
 /* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  * Copyright (C) 2003      Eric Seigne          <erics@rycks.com>
- * Copyright (C) 2004-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2004-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
  * Copyright (C) 2011      Juanjo Menent        <jmenent@2byte.es>
  *
@@ -72,11 +72,11 @@ $year=GETPOST("year","int")?GETPOST("year","int"):date("Y");
 $month=GETPOST("month","int")?GETPOST("month","int"):date("m");
 $week=GETPOST("week","int")?GETPOST("week","int"):date("W");
 $day=GETPOST("day","int")?GETPOST("day","int"):0;
-$actioncode=GETPOST("actioncode","alpha",3);
 $pid=GETPOST("projectid","int",3);
 $status=GETPOST("status");
 $type=GETPOST("type");
 $maxprint=(isset($_GET["maxprint"])?GETPOST("maxprint"):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW);
+$actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=="0"?'':(empty($conf->global->AGENDA_USE_EVENT_TYPE)?'AC_OTH':''));
 
 if (GETPOST('viewcal'))  {
     $action='show_month'; $day='';
@@ -271,7 +271,7 @@ $param.='&year='.$year.'&month='.$month.($day?'&day='.$day:'');
 $head = calendars_prepare_head('');
 
 dol_fiche_head($head, 'card', $langs->trans('Events'), 0, $picto);
-print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$listofextcals);
+print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$listofextcals,$actioncode);
 dol_fiche_end();
 
 $link='';
diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php
index b603792b95728468cb176401a3884f54ae7dabac..9e7a7a959bb6ea6c4bfb7346564fde7988579cea 100644
--- a/htdocs/comm/action/listactions.php
+++ b/htdocs/comm/action/listactions.php
@@ -238,7 +238,7 @@ if ($resql)
 	$i = 0;
 	print '<table class="liste" width="100%">';
 	print '<tr class="liste_titre">';
-	print_liste_field_titre($langs->trans("Action"),$_SERVER["PHP_SELF"],"acode",$param,"","",$sortfield,$sortorder);
+	print_liste_field_titre($langs->trans("Action"),$_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder);
 	//print_liste_field_titre($langs->trans("Title"),$_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder);
 	print_liste_field_titre($langs->trans("DateStart"),$_SERVER["PHP_SELF"],"a.datep",$param,'','align="center"',$sortfield,$sortorder);
 	print_liste_field_titre($langs->trans("DateEnd"),$_SERVER["PHP_SELF"],"a.datep2",$param,'','align="center"',$sortfield,$sortorder);
diff --git a/htdocs/comm/action/rapport/index.php b/htdocs/comm/action/rapport/index.php
index 33a30e9c6b6e2c6dd68ce192abd5914fae68b52f..fa100e532f352e60c3bcee566ec6d0a6ea49f1de 100644
--- a/htdocs/comm/action/rapport/index.php
+++ b/htdocs/comm/action/rapport/index.php
@@ -132,7 +132,7 @@ if ($resql)
 
 			if (file_exists($file))
 			{
-				print '<td align="center"><a href="'.DOL_URL_ROOT.'/document.php?page='.$page.'&amp;file='.urlencode($relativepath).'&amp;modulepart=actionsreport">'.img_pdf().'</a></td>';
+				print '<td align="center"><a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?page='.$page.'&amp;file='.urlencode($relativepath).'&amp;modulepart=actionsreport">'.img_pdf().'</a></td>';
 				print '<td align="center">'.dol_print_date(dol_filemtime($file),'dayhour').'</td>';
 				print '<td align="center">'.dol_print_size(dol_filesize($file)).'</td>';
 			}
diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php
index c178c37078b49e1b0394299b73204025ffe4812b..2a7c92dce56b30620b76d308cf88fcee8692af4f 100644
--- a/htdocs/comm/propal.php
+++ b/htdocs/comm/propal.php
@@ -1534,7 +1534,7 @@ else
 			require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
 			$notify=new Notify($db);
 			$text.='<br>';
-			$text.=$notify->confirmMessage('NOTIFY_VAL_PROPAL',$object->socid);
+			$text.=$notify->confirmMessage('PROPAL_VALIDATE',$object->socid);
 		}
 
 		if (! $error) $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateProp'), $text, 'confirm_validate','',0,1);
@@ -2171,7 +2171,7 @@ else
 
 
 		//print '</td></tr></table>';
-		print '</div></div></div>';
+		print '</div></div></div>';
 	}
 
 
diff --git a/htdocs/comm/propal/apercu.php b/htdocs/comm/propal/apercu.php
index fa01f818b162cd3e2a2e490a590d58468e1b9074..8972baaac88cb47ff1791ebf261ae5ab6d26490a 100644
--- a/htdocs/comm/propal/apercu.php
+++ b/htdocs/comm/propal/apercu.php
@@ -142,7 +142,7 @@ if ($id > 0 || ! empty($ref))
 
 			print "<tr $bc[$var]><td>".$langs->trans("Propal")." PDF</td>";
 
-			print '<td><a href="'.DOL_URL_ROOT . '/document.php?modulepart=propal&file='.urlencode($relativepath).'">'.$object->ref.'.pdf</a></td>';
+			print '<td><a data-ajax="false" href="'.DOL_URL_ROOT . '/document.php?modulepart=propal&file='.urlencode($relativepath).'">'.$object->ref.'.pdf</a></td>';
 
 			print '<td align="right">'.dol_print_size(dol_filesize($file)).'</td>';
 			print '<td align="right">'.dol_print_date(dol_filemtime($file),'dayhour').'</td>';
diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php
index 4063802ffa47fdb1f56e5ab759f6618f244c6e69..1d4d5b82c24bd96294890b02395e3026a19408f9 100644
--- a/htdocs/comm/propal/list.php
+++ b/htdocs/comm/propal/list.php
@@ -3,7 +3,7 @@
  * Copyright (C) 2004-2011 Laurent Destailleur   <eldy@users.sourceforge.net>
  * Copyright (C) 2004      Eric Seigne           <eric.seigne@ryxeo.com>
  * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
- * Copyright (C) 2005-2012 Regis Houssin         <regis.houssin@capnetworks.com>
+ * Copyright (C) 2005-2013 Regis Houssin         <regis.houssin@capnetworks.com>
  * Copyright (C) 2006      Andre Cianfarani      <acianfa@free.fr>
  * Copyright (C) 2010-2011 Juanjo Menent         <jmenent@2byte.es>
  * Copyright (C) 2010-2011 Philippe Grand        <philippe.grand@atoo-net.com>
@@ -165,7 +165,7 @@ if ($search_societe)
 }
 if ($search_montant_ht)
 {
-	$sql.= " AND p.total_ht='".$db->escape(trim($search_montant_ht))."'";
+	$sql.= " AND p.total_ht='".$db->escape(price2num(trim($search_montant_ht)))."'";
 }
 if ($sall) $sql.= " AND (s.nom LIKE '%".$db->escape($sall)."%' OR p.note LIKE '%".$db->escape($sall)."%' OR pd.description LIKE '%".$db->escape($sall)."%')";
 if ($socid) $sql.= ' AND s.rowid = '.$socid;
diff --git a/htdocs/commande/apercu.php b/htdocs/commande/apercu.php
index 03957361ae26eed2d23e7f7e125d2015c6126095..f92a309a53cc29bc5eff8771570ceda35bef4b24 100644
--- a/htdocs/commande/apercu.php
+++ b/htdocs/commande/apercu.php
@@ -128,7 +128,7 @@ if ($id > 0 || ! empty($ref))
 
 			print "<tr $bc[$var]><td>".$langs->trans("Order")." PDF</td>";
 
-			print '<td><a href="'.DOL_URL_ROOT . '/document.php?modulepart=commande&file='.urlencode($relativepath).'">'.$object->ref.'.pdf</a></td>';
+			print '<td><a data-ajax="false" href="'.DOL_URL_ROOT . '/document.php?modulepart=commande&file='.urlencode($relativepath).'">'.$object->ref.'.pdf</a></td>';
 			print '<td align="right">'.dol_print_size(dol_filesize($file)).'</td>';
 			print '<td align="right">'.dol_print_date(dol_filemtime($file),'dayhour').'</td>';
 			print '</tr>';
@@ -139,7 +139,7 @@ if ($id > 0 || ! empty($ref))
 			{
 				print "<tr $bc[$var]><td>Commande detaillee</td>";
 
-				print '<td><a href="'.DOL_URL_ROOT . '/document.php?modulepart=commande&file='.urlencode($relativepathdetail).'">'.$object->ref.'-detail.pdf</a></td>';
+				print '<td><a data-ajax="false" href="'.DOL_URL_ROOT . '/document.php?modulepart=commande&file='.urlencode($relativepathdetail).'">'.$object->ref.'-detail.pdf</a></td>';
 				print '<td align="right">'.dol_print_size(dol_filesize($filedetail)).'</td>';
 				print '<td align="right">'.dol_print_date(dol_filemtime($filedetail),'dayhour').'</td>';
 				print '</tr>';
diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php
index 2a501f10f73f30596a69804cef7079208b454560..4801305a091551dd247f5951e802eb572047ad61 100644
--- a/htdocs/commande/fiche.php
+++ b/htdocs/commande/fiche.php
@@ -1,34 +1,34 @@
 <?php
 /* Copyright (C) 2003-2006	Rodolphe Quiedeville	<rodolphe@quiedeville.org>
  * Copyright (C) 2004-2013	Laurent Destailleur		<eldy@users.sourceforge.net>
- * Copyright (C) 2005		Marc Barilley / Ocebo	<marc@ocebo.com>
- * Copyright (C) 2005-2013	Regis Houssin			<regis.houssin@capnetworks.com>
- * Copyright (C) 2006		Andre Cianfarani		<acianfa@free.fr>
- * Copyright (C) 2010-2013	Juanjo Menent			<jmenent@2byte.es>
- * Copyright (C) 2011		Philippe Grand			<philippe.grand@atoo-net.com>
- * Copyright (C) 2012		Christophe Battarel		<christophe.battarel@altairis.fr>
- * Copyright (C) 2012		Marcos García			<marcosgdf@gmail.com>
- * Copyright (C) 2013		Florian Henry			<florian.henry@open-concept.pro>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
+* Copyright (C) 2005		Marc Barilley / Ocebo	<marc@ocebo.com>
+* Copyright (C) 2005-2013	Regis Houssin			<regis.houssin@capnetworks.com>
+* Copyright (C) 2006		Andre Cianfarani		<acianfa@free.fr>
+* Copyright (C) 2010-2013	Juanjo Menent			<jmenent@2byte.es>
+* Copyright (C) 2011		Philippe Grand			<philippe.grand@atoo-net.com>
+* Copyright (C) 2012		Christophe Battarel		<christophe.battarel@altairis.fr>
+* Copyright (C) 2012		Marcos García			<marcosgdf@gmail.com>
+* Copyright (C) 2013		Florian Henry			<florian.henry@open-concept.pro>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
 
 /**
  *	\file       htdocs/commande/fiche.php
- *	\ingroup    commande
- *	\brief      Page to show customer order
- */
+*	\ingroup    commande
+*	\brief      Page to show customer order
+*/
 
 require '../main.inc.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
@@ -541,7 +541,7 @@ else if ($action == 'setnote_public' && $user->rights->commande->creer)
 
 else if ($action == 'setnote_private' && $user->rights->commande->creer)
 {
-	$result=$object->update_note_rivate(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES));
+	$result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private');
 	if ($result < 0) dol_print_error($db,$object->error);
 }
 
@@ -1121,7 +1121,7 @@ else if ($action == 'print_file' AND $user->rights->printipp->use)
 {
 	require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php';
 	$printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD);
-    $printer->print_file(GETPOST('file','alpha'),GETPOST('printer','alpha'));
+	$printer->print_file(GETPOST('file','alpha'),GETPOST('printer','alpha'));
 }
 
 else if ($action == 'update_extras')
@@ -1784,7 +1784,7 @@ else
 				require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
 				$notify=new Notify($db);
 				$text.='<br>';
-				$text.=$notify->confirmMessage('NOTIFY_VAL_ORDER',$object->socid);
+				$text.=$notify->confirmMessage('ORDER_VALIDATE',$object->socid);
 			}
 			$formquestion=array();
 			if (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $object->hasProductsOrServices(1))
@@ -1935,15 +1935,15 @@ else
 		print '<td colspan="3">'.$soc->getNomUrl(1).'</td>';
 		print '</tr>';
 
-		if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
-		{
-			$filterabsolutediscount="fk_facture_source IS NULL";  // If we want deposit to be substracted to payments only and not to total of final invoice
-			$filtercreditnote="fk_facture_source IS NOT NULL";    // If we want deposit to be substracted to payments only and not to total of final invoice
-		}
-		else
-		{
-			$filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')";
-			$filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'";
+		if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
+		{
+			$filterabsolutediscount="fk_facture_source IS NULL";  // If we want deposit to be substracted to payments only and not to total of final invoice
+			$filtercreditnote="fk_facture_source IS NOT NULL";    // If we want deposit to be substracted to payments only and not to total of final invoice
+		}
+		else
+		{
+			$filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')";
+			$filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'";
 		}
 
 		// Relative and absolute discounts
@@ -2135,48 +2135,23 @@ else
 		$reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
 		if (empty($reshook) && ! empty($extrafields->attribute_label))
 		{
+			if(count($extrafields->attribute_label) > 0) {
 
-			if ($action == 'edit_extras')
-			{
-				print '<form enctype="multipart/form-data" action="'.$_SERVER["PHP_SELF"].'" method="post" name="formsoc">';
-				print '<input type="hidden" name="action" value="update_extras">';
-				print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-				print '<input type="hidden" name="id" value="'.$object->id.'">';
-			}
-
-			// TODO : use showOptionals($extrafields) function
-			foreach($extrafields->attribute_label as $key=>$label)
-			{
-				$value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]);
-				if ($extrafields->attribute_type[$key] == 'separate')
+				if ($action == 'edit_extras')
 				{
-					print $extrafields->showSeparator($key);
+					print '<form enctype="multipart/form-data" action="'.$_SERVER["PHP_SELF"].'" method="post" name="formsoc">';
+					print '<input type="hidden" name="action" value="update_extras">';
+					print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+					print '<input type="hidden" name="id" value="'.$object->id.'">';
 				}
-				else
-				{
-					print '<tr><td';
-					if (! empty($extrafields->attribute_required[$key])) print ' class="fieldrequired"';
-					print '>'.$label.'</td><td colspan="3">';
 
-					// Convert date into timestamp format
-					if (in_array($extrafields->attribute_type[$key],array('date','datetime')))
-					{
-						$value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key];
-					}
 
-					if ($action == 'edit_extras' &&  $user->rights->propal->creer)
-					{
-						print $extrafields->showInputField($key,$value);
-					}
-					else
-					{
-						print $extrafields->showOutputField($key,$value);
-					}
-					print '</td></tr>'."\n";
+				if ($action == 'edit_extras' &&  $user->rights->propal->creer) {
+					print $object->showOptionals($extrafields,'edit');
+				}
+				else {
+					print $object->showOptionals($extrafields);
 				}
-			}
-
-			if(count($extrafields->attribute_label) > 0) {
 
 				if ($action == 'edit_extras' && $user->rights->propal->creer)
 				{
@@ -2195,9 +2170,9 @@ else
 			}
 		}
 
-		$rowspan=4;
-		if ($mysoc->localtax1_assuj=="1") $rowspan++;
-		if ($mysoc->localtax2_assuj=="1") $rowspan++;
+		$rowspan=4;
+		if ($mysoc->localtax1_assuj=="1") $rowspan++;
+		if ($mysoc->localtax2_assuj=="1") $rowspan++;
 
 		// Total HT
 		print '<tr><td>'.$langs->trans('AmountHT').'</td>';
@@ -2307,7 +2282,7 @@ else
 
 		/*
 		 * Boutons actions
-		 */
+		*/
 		if ($action != 'presend')
 		{
 			if ($user->societe_id == 0 && $action <> 'editline')
@@ -2436,7 +2411,7 @@ else
 				print '</div>';
 			}
 		}
-		print '<br>';
+		print '<br>';
 
 
 		if ($action != 'presend')
@@ -2447,7 +2422,7 @@ else
 
 			/*
 			 * Documents generes
-			 */
+			*/
 			$comref = dol_sanitizeFileName($object->ref);
 			$file = $conf->commande->dir_output . '/' . $comref . '/' . $comref . '.pdf';
 			$relativepath = $comref.'/'.$comref.'.pdf';
@@ -2461,7 +2436,7 @@ else
 
 			/*
 			 * Linked object block
-			 */
+			*/
 			$somethingshown=$object->showLinkedObjectBlock();
 
 			print '</div><div class="fichehalfright"><div class="ficheaddleft">';
@@ -2473,7 +2448,7 @@ else
 			$somethingshown=$formactions->showactions($object,'order',$socid);
 
 			//print '</td></tr></table>';
-            print '</div></div></div>';
+			print '</div></div></div>';
 		}
 
 
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index 53e839e024111f43bc5eefaabae72c02fd0b1e61..6c190bac20bd2bd3d89b7d6e6af137e887beac2e 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -1,34 +1,34 @@
 <?php
 /* Copyright (C) 2002-2006 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
  * Copyright (C) 2004      Eric Seigne           <eric.seigne@ryxeo.com>
- * Copyright (C) 2004-2013 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) 2006      Andre Cianfarani      <acianfa@free.fr>
- * Copyright (C) 2010-2013 Juanjo Menent         <jmenent@2byte.es>
- * Copyright (C) 2012      Christophe Battarel   <christophe.battarel@altairis.fr>
- * Copyright (C) 2013      Jean-Francois FERRY   <jfefe@aternatik.fr>
- * Copyright (C) 2013      Florian Henry		 <florian.henry@open-concept.pro>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
+* Copyright (C) 2004-2013 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) 2006      Andre Cianfarani      <acianfa@free.fr>
+* Copyright (C) 2010-2013 Juanjo Menent         <jmenent@2byte.es>
+* Copyright (C) 2012      Christophe Battarel   <christophe.battarel@altairis.fr>
+* Copyright (C) 2013      Jean-Francois FERRY   <jfefe@aternatik.fr>
+* Copyright (C) 2013      Florian Henry		 <florian.henry@open-concept.pro>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
 
 /**
  *	\file       htdocs/compta/facture.php
- *	\ingroup    facture
- *	\brief      Page to create/see an invoice
- */
+*	\ingroup    facture
+*	\brief      Page to create/see an invoice
+*/
 
 require '../main.inc.php';
 require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
@@ -99,7 +99,7 @@ $hookmanager->initHooks(array('invoicecard'));
 
 /*
  * Actions
- */
+*/
 
 $parameters=array('socid'=>$socid);
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
@@ -108,47 +108,47 @@ $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);
 // Action clone object
 if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->facture->creer)
 {
-    if (1==0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"]))
-    {
-        $mesgs[]='<div class="error">'.$langs->trans("NoCloneOptionsSpecified").'</div>';
-    }
-    else
-    {
-    	if ($object->fetch($id) > 0)
-    	{
-    		$result=$object->createFromClone($socid);
-    		if ($result > 0)
-    		{
-    			header("Location: ".$_SERVER['PHP_SELF'].'?facid='.$result);
-    			exit;
-    		}
-    		else
-    		{
-    			$mesgs[]=$object->error;
-    			$action='';
-    		}
-    	}
-    }
+	if (1==0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"]))
+	{
+		$mesgs[]='<div class="error">'.$langs->trans("NoCloneOptionsSpecified").'</div>';
+	}
+	else
+	{
+		if ($object->fetch($id) > 0)
+		{
+			$result=$object->createFromClone($socid);
+			if ($result > 0)
+			{
+				header("Location: ".$_SERVER['PHP_SELF'].'?facid='.$result);
+				exit;
+			}
+			else
+			{
+				$mesgs[]=$object->error;
+				$action='';
+			}
+		}
+	}
 }
 
 // Change status of invoice
 else if ($action == 'reopen' && $user->rights->facture->creer)
 {
-    $result = $object->fetch($id);
-    if ($object->statut == 2
-    || ($object->statut == 3 && $object->close_code != 'replaced'))
-    {
-        $result = $object->set_unpaid($user);
-        if ($result > 0)
-        {
-            header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
-            exit;
-        }
-        else
-        {
-            $mesgs[]='<div class="error">'.$object->error.'</div>';
-        }
-    }
+	$result = $object->fetch($id);
+	if ($object->statut == 2
+		|| ($object->statut == 3 && $object->close_code != 'replaced'))
+	{
+		$result = $object->set_unpaid($user);
+		if ($result > 0)
+		{
+			header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
+			exit;
+		}
+		else
+		{
+			$mesgs[]='<div class="error">'.$object->error.'</div>';
+		}
+	}
 }
 
 // Delete invoice
@@ -156,7 +156,20 @@ else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->fact
 {
 	$result = $object->fetch($id);
 	$object->fetch_thirdparty();
-	$result = $object->delete();
+
+	$idwarehouse=GETPOST('idwarehouse');
+
+	$qualified_for_stock_change=0;
+	if (empty($conf->global->STOCK_SUPPORTS_SERVICES))
+	{
+		$qualified_for_stock_change=$object->hasProductsOrServices(2);
+	}
+	else
+	{
+		$qualified_for_stock_change=$object->hasProductsOrServices(1);
+	}
+
+	$result = $object->delete(0,0,$idwarehouse);
 	if ($result > 0)
 	{
 		header('Location: '.DOL_URL_ROOT.'/compta/facture/list.php');
@@ -208,146 +221,146 @@ else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->
 // Delete link of credit note to invoice
 else if ($action == 'unlinkdiscount' && $user->rights->facture->creer)
 {
-    $discount=new DiscountAbsolute($db);
-    $result=$discount->fetch($_GET["discountid"]);
-    $discount->unlink_invoice();
+	$discount=new DiscountAbsolute($db);
+	$result=$discount->fetch($_GET["discountid"]);
+	$discount->unlink_invoice();
 }
 
 // Validation
 else if ($action == 'valid' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-
-    // On verifie signe facture
-    if ($object->type == 2)
-    {
-        // Si avoir, le signe doit etre negatif
-        if ($object->total_ht >= 0)
-        {
-            $mesgs[]='<div class="error">'.$langs->trans("ErrorInvoiceAvoirMustBeNegative").'</div>';
-            $action='';
-        }
-    }
-    else
-    {
-        // Si non avoir, le signe doit etre positif
-        if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0)
-        {
-            $mesgs[]='<div class="error">'.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive").'</div>';
-            $action='';
-        }
-    }
+	$object->fetch($id);
+
+	// On verifie signe facture
+	if ($object->type == 2)
+	{
+		// Si avoir, le signe doit etre negatif
+		if ($object->total_ht >= 0)
+		{
+			$mesgs[]='<div class="error">'.$langs->trans("ErrorInvoiceAvoirMustBeNegative").'</div>';
+			$action='';
+		}
+	}
+	else
+	{
+		// Si non avoir, le signe doit etre positif
+		if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0)
+		{
+			$mesgs[]='<div class="error">'.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive").'</div>';
+			$action='';
+		}
+	}
 }
 
 else if ($action == 'set_thirdparty' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-    $object->setValueFrom('fk_soc',$socid);
+	$object->fetch($id);
+	$object->setValueFrom('fk_soc',$socid);
 
-    header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
-    exit;
+	header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
+	exit;
 }
 
 else if ($action == 'classin' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-    $object->setProject($_POST['projectid']);
+	$object->fetch($id);
+	$object->setProject($_POST['projectid']);
 }
 
 else if ($action == 'setmode' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-    $result = $object->setPaymentMethods(GETPOST('mode_reglement_id','int'));
-    if ($result < 0) dol_print_error($db,$object->error);
+	$object->fetch($id);
+	$result = $object->setPaymentMethods(GETPOST('mode_reglement_id','int'));
+	if ($result < 0) dol_print_error($db,$object->error);
 }
 else if ($action == 'setinvoicedate' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-    $old_date_lim_reglement=$object->date_lim_reglement;
-    $object->date=dol_mktime(12,0,0,$_POST['invoicedatemonth'],$_POST['invoicedateday'],$_POST['invoicedateyear']);
-    $new_date_lim_reglement=$object->calculate_date_lim_reglement();
-    if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement;
-    if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date;
-    $result=$object->update($user);
-    if ($result < 0) dol_print_error($db,$object->error);
+	$object->fetch($id);
+	$old_date_lim_reglement=$object->date_lim_reglement;
+	$object->date=dol_mktime(12,0,0,$_POST['invoicedatemonth'],$_POST['invoicedateday'],$_POST['invoicedateyear']);
+	$new_date_lim_reglement=$object->calculate_date_lim_reglement();
+	if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement;
+	if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date;
+	$result=$object->update($user);
+	if ($result < 0) dol_print_error($db,$object->error);
 }
 else if ($action == 'setconditions' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-    $object->cond_reglement_code=0;	// To clean property
-    $object->cond_reglement_id=0;		// To clean property
-    $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int'));
-    if ($result < 0) dol_print_error($db,$object->error);
-
-    $old_date_lim_reglement=$object->date_lim_reglement;
-    $new_date_lim_reglement=$object->calculate_date_lim_reglement();
-    if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement;
-    if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date;
-    $result=$object->update($user);
-    if ($result < 0) dol_print_error($db,$object->error);
+	$object->fetch($id);
+	$object->cond_reglement_code=0;	// To clean property
+	$object->cond_reglement_id=0;		// To clean property
+	$result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int'));
+	if ($result < 0) dol_print_error($db,$object->error);
+
+	$old_date_lim_reglement=$object->date_lim_reglement;
+	$new_date_lim_reglement=$object->calculate_date_lim_reglement();
+	if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement;
+	if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date;
+	$result=$object->update($user);
+	if ($result < 0) dol_print_error($db,$object->error);
 }
 else if ($action == 'setpaymentterm' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-    $object->date_lim_reglement=dol_mktime(12,0,0,$_POST['paymenttermmonth'],$_POST['paymenttermday'],$_POST['paymenttermyear']);
-    if ($object->date_lim_reglement < $object->date)
-    {
-    	$object->date_lim_reglement=$object->calculate_date_lim_reglement();
-    	setEventMessage($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"),'warnings');
-    }
-    $result=$object->update($user);
-    if ($result < 0) dol_print_error($db,$object->error);
+	$object->fetch($id);
+	$object->date_lim_reglement=dol_mktime(12,0,0,$_POST['paymenttermmonth'],$_POST['paymenttermday'],$_POST['paymenttermyear']);
+	if ($object->date_lim_reglement < $object->date)
+	{
+		$object->date_lim_reglement=$object->calculate_date_lim_reglement();
+		setEventMessage($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"),'warnings');
+	}
+	$result=$object->update($user);
+	if ($result < 0) dol_print_error($db,$object->error);
 }
 else if ($action == 'setrevenuestamp' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-    $object->revenuestamp=GETPOST('revenuestamp');
-    $result=$object->update($user);
-    $object->update_price(1);
-    if ($result < 0) dol_print_error($db,$object->error);
+	$object->fetch($id);
+	$object->revenuestamp=GETPOST('revenuestamp');
+	$result=$object->update($user);
+	$object->update_price(1);
+	if ($result < 0) dol_print_error($db,$object->error);
 }
 else if ($action == 'setremisepercent' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-    $result = $object->set_remise($user, $_POST['remise_percent']);
+	$object->fetch($id);
+	$result = $object->set_remise($user, $_POST['remise_percent']);
 }
 else if ($action == "setabsolutediscount" && $user->rights->facture->creer)
 {
-    // POST[remise_id] ou POST[remise_id_for_payment]
-    if (! empty($_POST["remise_id"]))
-    {
-        $ret=$object->fetch($id);
-        if ($ret > 0)
-        {
-            $result=$object->insert_discount($_POST["remise_id"]);
-            if ($result < 0)
-            {
-                $mesgs[]='<div class="error">'.$object->error.'</div>';
-            }
-        }
-        else
-        {
-            dol_print_error($db,$object->error);
-        }
-    }
-    if (! empty($_POST["remise_id_for_payment"]))
-    {
-        require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
-        $discount = new DiscountAbsolute($db);
-        $discount->fetch($_POST["remise_id_for_payment"]);
-
-        $result=$discount->link_to_invoice(0,$id);
-        if ($result < 0)
-        {
-            $mesgs[]='<div class="error">'.$discount->error.'</div>';
-        }
-    }
+	// POST[remise_id] ou POST[remise_id_for_payment]
+	if (! empty($_POST["remise_id"]))
+	{
+		$ret=$object->fetch($id);
+		if ($ret > 0)
+		{
+			$result=$object->insert_discount($_POST["remise_id"]);
+			if ($result < 0)
+			{
+				$mesgs[]='<div class="error">'.$object->error.'</div>';
+			}
+		}
+		else
+		{
+			dol_print_error($db,$object->error);
+		}
+	}
+	if (! empty($_POST["remise_id_for_payment"]))
+	{
+		require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
+		$discount = new DiscountAbsolute($db);
+		$discount->fetch($_POST["remise_id_for_payment"]);
+
+		$result=$discount->link_to_invoice(0,$id);
+		if ($result < 0)
+		{
+			$mesgs[]='<div class="error">'.$discount->error.'</div>';
+		}
+	}
 }
 
 else if ($action == 'set_ref_client' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-    $object->set_ref_client($_POST['ref_client']);
+	$object->fetch($id);
+	$object->set_ref_client($_POST['ref_client']);
 }
 
 else if ($action == 'setnote_public' && $user->rights->facture->creer)
@@ -367,968 +380,1071 @@ else if ($action == 'setnote_private' && $user->rights->facture->creer)
 // Classify to validated
 else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider)
 {
-    $idwarehouse=GETPOST('idwarehouse');
-
-    $object->fetch($id);
-    $object->fetch_thirdparty();
-
-    // Check parameters
-
-    // Check for  mandatory prof id
-    for ($i = 1; $i < 5; $i++)
-    {
-
-    	$idprof_mandatory ='SOCIETE_IDPROF'.($i).'_INVOICE_MANDATORY';
-    	$idprof='idprof'.$i;
-    	if (! $object->thirdparty->$idprof && ! empty($conf->global->$idprof_mandatory))
-        {
-        	if (! $error) $langs->load("errors");
-    		$error++;
-
-    		setEventMessage($langs->trans('ErrorProdIdIsMandatory',$langs->transcountry('ProfId'.$i, $object->thirdparty->country_code)),'errors');
-    	}
-    }
-
-    //Check for warehouse
-    if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1))
-    {
-        if (! $idwarehouse || $idwarehouse == -1)
-        {
-            $error++;
-            setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors');
-            $action='';
-        }
-    }
-
-    if (! $error)
-    {
-        $result = $object->validate($user,'',$idwarehouse);
-        if ($result >= 0)
-        {
-            // Define output language
-            $outputlangs = $langs;
-            $newlang='';
-            if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
-            if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
-            if (! empty($newlang))
-            {
-                $outputlangs = new Translate("",$conf);
-                $outputlangs->setDefaultLang($newlang);
-            }
-            if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
-            {
-                $ret=$object->fetch($id);    // Reload to get new records
-                facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-            }
-        }
-        else
-        {
-            setEventMessage($object->error,'errors');
-        }
-    }
+	$idwarehouse=GETPOST('idwarehouse');
+
+	$object->fetch($id);
+	$object->fetch_thirdparty();
+
+	// Check parameters
+
+	// Check for  mandatory prof id
+	for ($i = 1; $i < 5; $i++)
+	{
+
+		$idprof_mandatory ='SOCIETE_IDPROF'.($i).'_INVOICE_MANDATORY';
+		$idprof='idprof'.$i;
+		if (! $object->thirdparty->$idprof && ! empty($conf->global->$idprof_mandatory))
+		{
+			if (! $error) $langs->load("errors");
+			$error++;
+
+			setEventMessage($langs->trans('ErrorProdIdIsMandatory',$langs->transcountry('ProfId'.$i, $object->thirdparty->country_code)),'errors');
+		}
+	}
+
+	$qualified_for_stock_change=0;
+	if (empty($conf->global->STOCK_SUPPORTS_SERVICES))
+	{
+		$qualified_for_stock_change=$object->hasProductsOrServices(2);
+	}
+	else
+	{
+		$qualified_for_stock_change=$object->hasProductsOrServices(1);
+	}
+
+	//Check for warehouse
+	if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change)
+	{
+		if (! $idwarehouse || $idwarehouse == -1)
+		{
+			$error++;
+			setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors');
+			$action='';
+		}
+	}
+
+	if (! $error)
+	{
+		$result = $object->validate($user,'',$idwarehouse);
+		if ($result >= 0)
+		{
+			// Define output language
+			$outputlangs = $langs;
+			$newlang='';
+			if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
+			if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
+			if (! empty($newlang))
+			{
+				$outputlangs = new Translate("",$conf);
+				$outputlangs->setDefaultLang($newlang);
+			}
+			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+			{
+				$ret=$object->fetch($id);    // Reload to get new records
+				facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+			}
+		}
+		else
+		{
+			setEventMessage($object->error,'errors');
+		}
+	}
 }
 
 // Go back to draft status (unvalidate)
 else if ($action == 'confirm_modif' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate))
 {
-    $idwarehouse=GETPOST('idwarehouse');
-
-    $object->fetch($id);
-    $object->fetch_thirdparty();
-
-    // Check parameters
-    if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1))
-    {
-        if (! $idwarehouse || $idwarehouse == -1)
-        {
-            $error++;
-            setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors');
-            $action='';
-        }
-    }
-
-    if (! $error)
-    {
-	    // On verifie si la facture a des paiements
-	    $sql = 'SELECT pf.amount';
-	    $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
-	    $sql.= ' WHERE pf.fk_facture = '.$object->id;
-
-	    $result = $db->query($sql);
-	    if ($result)
-	    {
-	        $i = 0;
-	        $num = $db->num_rows($result);
-
-	        while ($i < $num)
-	        {
-	            $objp = $db->fetch_object($result);
-	            $totalpaye += $objp->amount;
-	            $i++;
-	        }
-	    }
-	    else
-	    {
-	        dol_print_error($db,'');
-	    }
-
-	    $resteapayer = $object->total_ttc - $totalpaye;
-
-	    // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
-	    $ventilExportCompta = $object->getVentilExportCompta();
-
-	    // On verifie si aucun paiement n'a ete effectue
-	    if ($resteapayer == $object->total_ttc	&& $object->paye == 0 && $ventilExportCompta == 0)
-	    {
-	        $object->set_draft($user, $idwarehouse);
-
-	        // Define output language
-	        $outputlangs = $langs;
-	        $newlang='';
-	        if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
-	        if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
-	        if (! empty($newlang))
-	        {
-	            $outputlangs = new Translate("",$conf);
-	            $outputlangs->setDefaultLang($newlang);
-	        }
-	        if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
-	        {
-                $ret=$object->fetch($id);    // Reload to get new records
-	            facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-	        }
-	    }
-    }
+	$idwarehouse=GETPOST('idwarehouse');
+
+	$object->fetch($id);
+	$object->fetch_thirdparty();
+
+	$qualified_for_stock_change=0;
+	if (empty($conf->global->STOCK_SUPPORTS_SERVICES))
+	{
+		$qualified_for_stock_change=$object->hasProductsOrServices(2);
+	}
+	else
+	{
+		$qualified_for_stock_change=$object->hasProductsOrServices(1);
+	}
+
+	// Check parameters
+	if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change)
+	{
+		if (! $idwarehouse || $idwarehouse == -1)
+		{
+			$error++;
+			setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors');
+			$action='';
+		}
+	}
+
+	if (! $error)
+	{
+		// On verifie si la facture a des paiements
+		$sql = 'SELECT pf.amount';
+		$sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
+		$sql.= ' WHERE pf.fk_facture = '.$object->id;
+
+		$result = $db->query($sql);
+		if ($result)
+		{
+			$i = 0;
+			$num = $db->num_rows($result);
+
+			while ($i < $num)
+			{
+				$objp = $db->fetch_object($result);
+				$totalpaye += $objp->amount;
+				$i++;
+			}
+		}
+		else
+		{
+			dol_print_error($db,'');
+		}
+
+		$resteapayer = $object->total_ttc - $totalpaye;
+
+		// On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
+		$ventilExportCompta = $object->getVentilExportCompta();
+
+		// On verifie si aucun paiement n'a ete effectue
+		if ($resteapayer == $object->total_ttc	&& $object->paye == 0 && $ventilExportCompta == 0)
+		{
+			$object->set_draft($user, $idwarehouse);
+
+			// Define output language
+			$outputlangs = $langs;
+			$newlang='';
+			if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
+			if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
+			if (! empty($newlang))
+			{
+				$outputlangs = new Translate("",$conf);
+				$outputlangs->setDefaultLang($newlang);
+			}
+			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+			{
+				$ret=$object->fetch($id);    // Reload to get new records
+				facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+			}
+		}
+	}
 }
 
 // Classify "paid"
 else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement)
 {
-    $object->fetch($id);
-    $result = $object->set_paid($user);
+	$object->fetch($id);
+	$result = $object->set_paid($user);
 }
 // Classif  "paid partialy"
 else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $user->rights->facture->paiement)
 {
-    $object->fetch($id);
-    $close_code=$_POST["close_code"];
-    $close_note=$_POST["close_note"];
-    if ($close_code)
-    {
-        $result = $object->set_paid($user,$close_code,$close_note);
-    }
-    else
-    {
-        setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors');
-    }
+	$object->fetch($id);
+	$close_code=$_POST["close_code"];
+	$close_note=$_POST["close_note"];
+	if ($close_code)
+	{
+		$result = $object->set_paid($user,$close_code,$close_note);
+	}
+	else
+	{
+		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors');
+	}
 }
 // Classify "abandoned"
 else if ($action == 'confirm_canceled' && $confirm == 'yes')
 {
-    $object->fetch($id);
-    $close_code=$_POST["close_code"];
-    $close_note=$_POST["close_note"];
-    if ($close_code)
-    {
-        $result = $object->set_canceled($user,$close_code,$close_note);
-    }
-    else
-    {
-        setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors');
-    }
+	$object->fetch($id);
+	$close_code=$_POST["close_code"];
+	$close_note=$_POST["close_note"];
+	if ($close_code)
+	{
+		$result = $object->set_canceled($user,$close_code,$close_note);
+	}
+	else
+	{
+		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors');
+	}
 }
 
 // Convertir en reduc
 else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer)
 {
-    $db->begin();
-
-    $object->fetch($id);
-    $object->fetch_thirdparty();
-    $object->fetch_lines();
-
-    if (! $object->paye)	// protection against multiple submit
-    {
-        // Boucle sur chaque taux de tva
-        $i=0;
-        foreach($object->lines as $line)
-        {
-            $amount_ht[$line->tva_tx]+=$line->total_ht;
-            $amount_tva[$line->tva_tx]+=$line->total_tva;
-            $amount_ttc[$line->tva_tx]+=$line->total_ttc;
-            $i++;
-        }
-
-        // Insert one discount by VAT rate category
-        $discount = new DiscountAbsolute($db);
-        if ($object->type == 2)     $discount->description='(CREDIT_NOTE)';
-        elseif ($object->type == 3) $discount->description='(DEPOSIT)';
-        else {
-            $this->error="CantConvertToReducAnInvoiceOfThisType";
-            return -1;
-        }
-        $discount->tva_tx=abs($object->total_ttc);
-        $discount->fk_soc=$object->socid;
-        $discount->fk_facture_source=$object->id;
-
-        $error=0;
-        foreach($amount_ht as $tva_tx => $xxx)
-        {
-            $discount->amount_ht=abs($amount_ht[$tva_tx]);
-            $discount->amount_tva=abs($amount_tva[$tva_tx]);
-            $discount->amount_ttc=abs($amount_ttc[$tva_tx]);
-            $discount->tva_tx=abs($tva_tx);
-
-            $result=$discount->create($user);
-            if ($result < 0)
-            {
-                $error++;
-                break;
-            }
-        }
-
-        if (! $error)
-        {
-            // Classe facture
-            $result=$object->set_paid($user);
-            if ($result > 0)
-            {
-                //$mesgs[]='OK'.$discount->id;
-                $db->commit();
-            }
-            else
-            {
-                $mesgs[]='<div class="error">'.$object->error.'</div>';
-                $db->rollback();
-            }
-        }
-        else
-        {
-            $mesgs[]='<div class="error">'.$discount->error.'</div>';
-            $db->rollback();
-        }
-    }
+	$db->begin();
+
+	$object->fetch($id);
+	$object->fetch_thirdparty();
+	$object->fetch_lines();
+
+	if (! $object->paye)	// protection against multiple submit
+	{
+		// Boucle sur chaque taux de tva
+		$i=0;
+		foreach($object->lines as $line)
+		{
+			$amount_ht[$line->tva_tx]+=$line->total_ht;
+			$amount_tva[$line->tva_tx]+=$line->total_tva;
+			$amount_ttc[$line->tva_tx]+=$line->total_ttc;
+			$i++;
+		}
+
+		// Insert one discount by VAT rate category
+		$discount = new DiscountAbsolute($db);
+		if ($object->type == 2)     $discount->description='(CREDIT_NOTE)';
+		elseif ($object->type == 3) $discount->description='(DEPOSIT)';
+		else {
+			$this->error="CantConvertToReducAnInvoiceOfThisType";
+			return -1;
+		}
+		$discount->tva_tx=abs($object->total_ttc);
+		$discount->fk_soc=$object->socid;
+		$discount->fk_facture_source=$object->id;
+
+		$error=0;
+		foreach($amount_ht as $tva_tx => $xxx)
+		{
+			$discount->amount_ht=abs($amount_ht[$tva_tx]);
+			$discount->amount_tva=abs($amount_tva[$tva_tx]);
+			$discount->amount_ttc=abs($amount_ttc[$tva_tx]);
+			$discount->tva_tx=abs($tva_tx);
+
+			$result=$discount->create($user);
+			if ($result < 0)
+			{
+				$error++;
+				break;
+			}
+		}
+
+		if (! $error)
+		{
+			// Classe facture
+			$result=$object->set_paid($user);
+			if ($result > 0)
+			{
+				//$mesgs[]='OK'.$discount->id;
+				$db->commit();
+			}
+			else
+			{
+				$mesgs[]='<div class="error">'.$object->error.'</div>';
+				$db->rollback();
+			}
+		}
+		else
+		{
+			$mesgs[]='<div class="error">'.$discount->error.'</div>';
+			$db->rollback();
+		}
+	}
 }
 
 /*
  * Insert new invoice in database
- */
+*/
 else if ($action == 'add' && $user->rights->facture->creer)
 {
 	if ($socid>0)
-    	$object->socid=GETPOST('socid','int');
-
-    $db->begin();
-
-    $error=0;
-
-    // Get extra fields
-    foreach($_POST as $key => $value)
-    {
-    	if (preg_match("/^options_/",$key))
-    	{
-    		$object->array_options[$key]=GETPOST($key);
-    	}
-    }
-
-    // Replacement invoice
-    if ($_POST['type'] == 1)
-    {
-        $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-        if (empty($datefacture))
-        {
-            $error++;
-            setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
-        }
-
-        if (! ($_POST['fac_replacement'] > 0))
-        {
-            $error++;
-            setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("ReplaceInvoice")),'errors');
-        }
-
-        if (! $error)
-        {
-            // This is a replacement invoice
-            $result=$object->fetch($_POST['fac_replacement']);
-            $object->fetch_thirdparty();
-
-            $object->date				= $datefacture;
-            $object->note_public		= trim($_POST['note_public']);
-            $object->note				= trim($_POST['note']);
-            $object->ref_client			= $_POST['ref_client'];
-            $object->ref_int			= $_POST['ref_int'];
-            $object->modelpdf			= $_POST['model'];
-            $object->fk_project			= $_POST['projectid'];
-            $object->cond_reglement_id	= $_POST['cond_reglement_id'];
-            $object->mode_reglement_id	= $_POST['mode_reglement_id'];
-            $object->remise_absolue		= $_POST['remise_absolue'];
-            $object->remise_percent		= $_POST['remise_percent'];
-
-            // Proprietes particulieres a facture de remplacement
-            $object->fk_facture_source	= $_POST['fac_replacement'];
-            $object->type				= 1;
-
-            $id=$object->createFromCurrent($user);
-            if ($id <= 0) $mesgs[]=$object->error;
-        }
-    }
-
-    // Credit note invoice
-    if ($_POST['type'] == 2)
-    {
-        if (! $_POST['fac_avoir'] > 0)
-        {
-            $error++;
-            setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CorrectInvoice")),'errors');
-        }
-
-        $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-        if (empty($datefacture))
-        {
-            $error++;
-            setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("Date")),'errors');
-        }
-
-        if (! $error)
-        {
-            // Si facture avoir
-            $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-
-            //$result=$object->fetch($_POST['fac_avoir']);
-
-            $object->socid				= GETPOST('socid','int');
-            $object->number				= $_POST['facnumber'];
-            $object->date				= $datefacture;
-            $object->note_public		= trim($_POST['note_public']);
-            $object->note				= trim($_POST['note']);
-            $object->ref_client			= $_POST['ref_client'];
-            $object->ref_int			= $_POST['ref_int'];
-            $object->modelpdf			= $_POST['model'];
-            $object->fk_project			= $_POST['projectid'];
-            $object->cond_reglement_id	= 0;
-            $object->mode_reglement_id	= $_POST['mode_reglement_id'];
-            $object->remise_absolue		= $_POST['remise_absolue'];
-            $object->remise_percent		= $_POST['remise_percent'];
-
-            // Proprietes particulieres a facture avoir
-            $object->fk_facture_source	= $_POST['fac_avoir'];
-            $object->type				= 2;
-
-            $id = $object->create($user);
-
-            // Add predefined lines
-            for ($i = 1; $i <= $NBLINES; $i++)
-            {
-                if ($_POST['idprod'.$i])
-                {
-                    $product=new Product($db);
-                    $product->fetch($_POST['idprod'.$i]);
-                    $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']);
-                    $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']);
-                    $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type);
-                }
-            }
-        }
-    }
-
-    // Standard invoice or Deposit invoice created from a Predefined invoice
-    if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0)
-    {
-        $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-        if (empty($datefacture))
-        {
-            $error++;
-            setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
-        }
-
-        if (! $error)
-        {
-            $object->socid			= GETPOST('socid','int');
-            $object->type           = $_POST['type'];
-            $object->number         = $_POST['facnumber'];
-            $object->date           = $datefacture;
-            $object->note_public	= trim($_POST['note_public']);
-            $object->note_private   = trim($_POST['note_private']);
-            $object->ref_client     = $_POST['ref_client'];
-            $object->ref_int     	= $_POST['ref_int'];
-            $object->modelpdf       = $_POST['model'];
-
-            // Source facture
-            $object->fac_rec        = $_POST['fac_rec'];
-
-            $id = $object->create($user);
-        }
-    }
-
-    // Standard or deposit or proforma invoice
-    if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0)
-    {
-    	if (GETPOST('socid','int')<1)
-    	{
-    		$error++;
-            setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Customer")),'errors');
-    	}
-
-        $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-        if (empty($datefacture))
-        {
-            $error++;
-            setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
-        }
-
-        if (! $error)
-        {
-            // Si facture standard
-            $object->socid				= GETPOST('socid','int');
-            $object->type				= GETPOST('type');
-            $object->number				= $_POST['facnumber'];
-            $object->date				= $datefacture;
-            $object->note_public		= trim($_POST['note_public']);
-            $object->note_private		= trim($_POST['note_private']);
-            $object->ref_client			= $_POST['ref_client'];
-            $object->ref_int			= $_POST['ref_int'];
-            $object->modelpdf			= $_POST['model'];
-            $object->fk_project			= $_POST['projectid'];
-            $object->cond_reglement_id	= ($_POST['type'] == 3?1:$_POST['cond_reglement_id']);
-            $object->mode_reglement_id	= $_POST['mode_reglement_id'];
-            $object->amount				= $_POST['amount'];
-            $object->remise_absolue		= $_POST['remise_absolue'];
-            $object->remise_percent		= $_POST['remise_percent'];
-   			$object->fetch_thirdparty();
-
-            // If creation from another object of another module (Example: origin=propal, originid=1)
-            if ($_POST['origin'] && $_POST['originid'])
-            {
-                // Parse element/subelement (ex: project_task)
-                $element = $subelement = $_POST['origin'];
-                if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs))
-                {
-                    $element = $regs[1];
-                    $subelement = $regs[2];
-                }
-
-                // For compatibility
-                if ($element == 'order')    { $element = $subelement = 'commande'; }
-                if ($element == 'propal')   { $element = 'comm/propal'; $subelement = 'propal'; }
-                if ($element == 'contract') { $element = $subelement = 'contrat'; }
-                if ($element == 'inter')    { $element = $subelement = 'ficheinter'; }
-                if ($element == 'shipping') { $element = $subelement = 'expedition'; }
-
-                $object->origin    = $_POST['origin'];
-                $object->origin_id = $_POST['originid'];
-
-                // Possibility to add external linked objects with hooks
-                $object->linked_objects[$object->origin] = $object->origin_id;
-                if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects']))
-                {
-                	$object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
-                }
-
-                $id = $object->create($user);
-
-                if ($id > 0)
-                {
-                    dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
-
-                    $classname = ucfirst($subelement);
-                    $srcobject = new $classname($db);
-
-                    dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines");
-                    $result=$srcobject->fetch($object->origin_id);
-                    if ($result > 0)
-                    {
-                        $lines = $srcobject->lines;
-                        if (empty($lines) && method_exists($srcobject,'fetch_lines'))  $lines = $srcobject->fetch_lines();
-
-                        $fk_parent_line=0;
-                        $num=count($lines);
-
-                        for ($i=0;$i<$num;$i++)
-                        {
-                        	$label=(! empty($lines[$i]->label)?$lines[$i]->label:'');
-                            $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle);
-
-                            if ($lines[$i]->subprice < 0)
-                            {
-                                // Negative line, we create a discount line
-                            	$discount = new DiscountAbsolute($db);
-                            	$discount->fk_soc=$object->socid;
-                                $discount->amount_ht=abs($lines[$i]->total_ht);
-                                $discount->amount_tva=abs($lines[$i]->total_tva);
-                                $discount->amount_ttc=abs($lines[$i]->total_ttc);
-                                $discount->tva_tx=$lines[$i]->tva_tx;
-                                $discount->fk_user=$user->id;
-                                $discount->description=$desc;
-                                $discountid=$discount->create($user);
-                                if ($discountid > 0)
-                                {
-                                    $result=$object->insert_discount($discountid);    // This include link_to_invoice
-                                }
-                                else
-                                {
-                                    $mesgs[]=$discount->error;
-                                    $error++;
-                                    break;
-                                }
-                            }
-                            else
-                            {
-                                // Positive line
-                                $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0);
-
-                                // Date start
-                                $date_start=false;
-                                if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue;
-                                if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel;
-                                if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start;
-
-                                //Date end
-                                $date_end=false;
-                                if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue;
-                                if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel;
-                                if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end;
-
-                                // Reset fk_parent_line for no child products and special product
-                                if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
-                                    $fk_parent_line = 0;
-                                }
-
-                                $result = $object->addline(
-                                    $id,
-                                    $desc,
-                                    $lines[$i]->subprice,
-                                    $lines[$i]->qty,
-                                    $lines[$i]->tva_tx,
-                                    $lines[$i]->localtax1_tx,
-                                    $lines[$i]->localtax2_tx,
-                                    $lines[$i]->fk_product,
-                                    $lines[$i]->remise_percent,
-                                    $date_start,
-                                    $date_end,
-                                    0,
-                                    $lines[$i]->info_bits,
-                                    $lines[$i]->fk_remise_except,
-                                    'HT',
-                                    0,
-                                    $product_type,
-                                    $lines[$i]->rang,
-                                    $lines[$i]->special_code,
-                                    $object->origin,
-                                    $lines[$i]->rowid,
-                                    $fk_parent_line,
-                                    $lines[$i]->fk_fournprice,
-                                    $lines[$i]->pa_ht,
-                                	$label
-                                );
-
-                                if ($result > 0)
-                                {
-                                    $lineid=$result;
-                                }
-                                else
-                                {
-                                    $lineid=0;
-                                    $error++;
-                                    break;
-                                }
-
-                                // Defined the new fk_parent_line
-                                if ($result > 0 && $lines[$i]->product_type == 9) {
-                                    $fk_parent_line = $result;
-                                }
-                            }
-                        }
-
-                        // Hooks
-                        $parameters=array('objFrom'=>$srcobject);
-                        $reshook=$hookmanager->executeHooks('createFrom',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
-                        if ($reshook < 0) $error++;
-                    }
-                    else
-                    {
-                        $mesgs[]=$srcobject->error;
-                        $error++;
-                    }
-                }
-                else
-                {
-                    $mesgs[]=$object->error;
-                    $error++;
-                }
-            }
-            // If some invoice's lines already known
-            else
-            {
-                $id = $object->create($user);
-
-                for ($i = 1; $i <= $NBLINES; $i++)
-                {
-                    if ($_POST['idprod'.$i])
-                    {
-                        $product=new Product($db);
-                        $product->fetch($_POST['idprod'.$i]);
-                        $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']);
-                        $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']);
-                        $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type);
-                    }
-                }
-            }
-        }
-    }
-
-    // End of object creation, we show it
-    if ($id > 0 && ! $error)
-    {
-        $db->commit();
-        header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
-        exit;
-    }
-    else
-    {
-        $db->rollback();
-        $action='create';
-        $_GET["origin"]=$_POST["origin"];
-        $_GET["originid"]=$_POST["originid"];
-        $mesgs[]='<div class="error">'.$object->error.'</div>';
-    }
-}
+		$object->socid=GETPOST('socid','int');
 
-// Add a new line
-else if (($action == 'addline' || $action == 'addline_predef') && $user->rights->facture->creer)
-{
-	$langs->load('errors');
-    $error = 0;
+	$db->begin();
 
-    $idprod=GETPOST('idprod', 'int');
-	$product_desc = (GETPOST('product_desc')?GETPOST('product_desc'):(GETPOST('np_desc')?GETPOST('np_desc'):(GETPOST('dp_desc')?GETPOST('dp_desc'):'')));
-	$price_ht = GETPOST('price_ht');
-	$tva_tx=(GETPOST('tva_tx')?GETPOST('tva_tx'):0);
+	$error=0;
 
-	if ((empty($idprod) || GETPOST('usenewaddlineform')) && ($price_ht < 0) && (GETPOST('qty') < 0))
-    {
-        setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors');
-        $error++;
-    }
-    if (empty($idprod) && GETPOST('type') < 0)
-    {
-        setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors');
-        $error++;
-    }
-	if ((empty($idprod) || GETPOST('usenewaddlineform')) && (!($price_ht >= 0) || $price_ht == ''))	// Unit price can be 0 but not ''
+	// Get extra fields
+	foreach($_POST as $key => $value)
 	{
-		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("UnitPriceHT")), 'errors');
-		$error++;
+		if (preg_match("/^options_/",$key))
+		{
+			$object->array_options[$key]=GETPOST($key);
+		}
 	}
-    if (! GETPOST('qty') && GETPOST('qty') == '')
-    {
-        setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors');
-        $error++;
-    }
-    if (empty($idprod) && empty($product_desc))
-    {
-        setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors');
-        $error++;
-    }
-
-    if (! $error && (GETPOST('qty') >= 0) && (! empty($product_desc) || ! empty($idprod)))
-    {
-        $ret=$object->fetch($id);
-        if ($ret < 0)
-        {
-            dol_print_error($db,$object->error);
-            exit;
-        }
-        $ret=$object->fetch_thirdparty();
-
-        // Clean parameters
-        $predef=((! empty($idprod) && $conf->global->MAIN_FEATURES_LEVEL < 2) ? '_predef' : '');
-        $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year'));
-        $date_end=dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year'));
-        $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT');
-
-        // Define special_code for special lines
-        $special_code=0;
-        //if (empty($_POST['qty'])) $special_code=3;	// Options should not exists on invoices
-
-        // Ecrase $pu par celui du produit
-        // Ecrase $desc par celui du produit
-        // Ecrase $txtva par celui du produit
-        // Ecrase $base_price_type par celui du produit
-        if (! empty($idprod))
-        {
-            $prod = new Product($db);
-            $prod->fetch($idprod);
-
-            $label = ((GETPOST('product_label') && GETPOST('product_label')!=$prod->label)?GETPOST('product_label'):'');
-
-            // Update if prices fields are defined
-            if (GETPOST('usenewaddlineform'))
-            {
-            	$pu_ht=price2num($price_ht, 'MU');
-				$pu_ttc=price2num(GETPOST('price_ttc'), 'MU');
-				$tva_npr=(preg_match('/\*/', $tva_tx)?1:0);
-				$tva_tx=str_replace('*','', $tva_tx);
-				$desc = $product_desc;
-            }
-            else
-			{
-            	$tva_tx = get_default_tva($mysoc,$object->client,$prod->id);
-            	$tva_npr = get_default_npr($mysoc,$object->client,$prod->id);
-
-            	// We define price for product
-            	if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level))
-            	{
-            		$pu_ht = $prod->multiprices[$object->client->price_level];
-            		$pu_ttc = $prod->multiprices_ttc[$object->client->price_level];
-            		$price_min = $prod->multiprices_min[$object->client->price_level];
-            		$price_base_type = $prod->multiprices_base_type[$object->client->price_level];
-            	}
-            	else
-            	{
-            		$pu_ht = $prod->price;
-            		$pu_ttc = $prod->price_ttc;
-            		$price_min = $prod->price_min;
-            		$price_base_type = $prod->price_base_type;
-            	}
-
-            	// On reevalue prix selon taux tva car taux tva transaction peut etre different
-            	// de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur).
-            	if ($tva_tx != $prod->tva_tx)
-            	{
-            		if ($price_base_type != 'HT')
-            		{
-            			$pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU');
-            		}
-            		else
-            		{
-            			$pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU');
-            		}
-            	}
-
-            	$desc='';
-
-            	// Define output language
-            	if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE))
-            	{
-            		$outputlangs = $langs;
-            		$newlang='';
-            		if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
-            		if (empty($newlang)) $newlang=$object->client->default_lang;
-            		if (! empty($newlang))
-            		{
-            			$outputlangs = new Translate("",$conf);
-            			$outputlangs->setDefaultLang($newlang);
-            		}
-
-            		$desc = (! empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description;
-            	}
-            	else
-            	{
-            		$desc = $prod->description;
-            	}
-
-            	$desc=dol_concatdesc($desc,$product_desc);
-
-	            // Add custom code and origin country into description
-	            if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code)))
-	            {
-	                $tmptxt='(';
-	                if (! empty($prod->customcode)) $tmptxt.=$langs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode;
-	                if (! empty($prod->customcode) && ! empty($prod->country_code)) $tmptxt.=' - ';
-	                if (! empty($prod->country_code)) $tmptxt.=$langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code,0,$db,$langs,0);
-	                $tmptxt.=')';
-	                $desc= dol_concatdesc($desc, $tmptxt);
-	            }
-            }
-
-            $type = $prod->type;
-        }
-        else
-        {
-            $pu_ht		= price2num($price_ht, 'MU');
-			$pu_ttc		= price2num(GETPOST('price_ttc'), 'MU');
-			$tva_npr	= (preg_match('/\*/', $tva_tx)?1:0);
-			$tva_tx		= str_replace('*', '', $tva_tx);
-			$label		= (GETPOST('product_label')?GETPOST('product_label'):'');
-			$desc		= $product_desc;
-			$type		= GETPOST('type');
-        }
-
-        // Margin
-        $fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):'');
-		$buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):'');
 
-        // Local Taxes
-        $localtax1_tx= get_localtax($tva_tx, 1, $object->client);
-        $localtax2_tx= get_localtax($tva_tx, 2, $object->client);
-
-        $info_bits=0;
-        if ($tva_npr) $info_bits |= 0x01;
+	// Replacement invoice
+	if ($_POST['type'] == 1)
+	{
+		$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+		if (empty($datefacture))
+		{
+			$error++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
+		}
 
-        if (! empty($price_min) && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min)))
-        {
-        	$mesg = $langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').$langs->getCurrencySymbol($conf->currency));
-			setEventMessage($mesg, 'errors');
-        }
-        else
-        {
-        	// Insert line
-        	$result = $object->addline(
-        			$id,
-        			$desc,
-        			$pu_ht,
-        			GETPOST('qty'),
-        			$tva_tx,
-        			$localtax1_tx,
-        			$localtax2_tx,
-        			$idprod,
-        			GETPOST('remise_percent'),
-        			$date_start,
-        			$date_end,
-        			0,
-        			$info_bits,
-        			'',
-        			$price_base_type,
-        			$pu_ttc,
-        			$type,
-        			-1,
-        			$special_code,
-        			'',
-        			0,
-        			GETPOST('fk_parent_line'),
-        			$fournprice,
-        			$buyingprice,
-        			$label
-        	);
-
-        	if ($result > 0)
-        	{
-        		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
-        		{
-        			// Define output language
-        			$outputlangs = $langs;
-        			$newlang=GETPOST('lang_id','alpha');
-        			if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) $newlang=$object->client->default_lang;
-        			if (! empty($newlang))
-        			{
-        				$outputlangs = new Translate("",$conf);
-        				$outputlangs->setDefaultLang($newlang);
-        			}
-
-        			$ret=$object->fetch($id);    // Reload to get new records
-        			facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-        		}
-
-        		unset($_POST['qty']);
-        		unset($_POST['type']);
-        		unset($_POST['idprod']);
-        		unset($_POST['remise_percent']);
-        		unset($_POST['price_ht']);
-				unset($_POST['price_ttc']);
-				unset($_POST['tva_tx']);
-				unset($_POST['product_ref']);
-				unset($_POST['product_label']);
-				unset($_POST['product_desc']);
-				unset($_POST['fournprice']);
-				unset($_POST['buying_price']);
+		if (! ($_POST['fac_replacement'] > 0))
+		{
+			$error++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("ReplaceInvoice")),'errors');
+		}
 
-				// old method
-				unset($_POST['np_desc']);
-				unset($_POST['dp_desc']);
-        	}
-        	else
-        	{
-        		setEventMessage($object->error, 'errors');
-        	}
-
-        	$action='';
-        }
-    }
-}
+		if (! $error)
+		{
+			// This is a replacement invoice
+			$result=$object->fetch($_POST['fac_replacement']);
+			$object->fetch_thirdparty();
+
+			$object->date				= $datefacture;
+			$object->note_public		= trim($_POST['note_public']);
+			$object->note				= trim($_POST['note']);
+			$object->ref_client			= $_POST['ref_client'];
+			$object->ref_int			= $_POST['ref_int'];
+			$object->modelpdf			= $_POST['model'];
+			$object->fk_project			= $_POST['projectid'];
+			$object->cond_reglement_id	= $_POST['cond_reglement_id'];
+			$object->mode_reglement_id	= $_POST['mode_reglement_id'];
+			$object->remise_absolue		= $_POST['remise_absolue'];
+			$object->remise_percent		= $_POST['remise_percent'];
+
+			// Proprietes particulieres a facture de remplacement
+			$object->fk_facture_source	= $_POST['fac_replacement'];
+			$object->type				= 1;
+
+			$id=$object->createFromCurrent($user);
+			if ($id <= 0) $mesgs[]=$object->error;
+		}
+	}
 
-else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['save'] == $langs->trans('Save'))
-{
-    if (! $object->fetch($id) > 0) dol_print_error($db);
-    $object->fetch_thirdparty();
-
-    // Clean parameters
-    $date_start='';
-    $date_end='';
-    $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'));
-    $description=dol_htmlcleanlastbr(GETPOST('product_desc'));
-    $pu_ht=GETPOST('price_ht');
-    $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0);
-
-    // Define info_bits
-    $info_bits=0;
-    if (preg_match('/\*/', $vat_rate)) $info_bits |= 0x01;
-
-    // Define vat_rate
-    $vat_rate=str_replace('*','',$vat_rate);
-    $localtax1_rate=get_localtax($vat_rate,1,$object->client);
-    $localtax2_rate=get_localtax($vat_rate,2,$object->client);
-
-  	// Add buying price
-	$fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):'');
-	$buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):'');
+	// Credit note invoice
+	if ($_POST['type'] == 2)
+	{
+		if (! $_POST['fac_avoir'] > 0)
+		{
+			$error++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CorrectInvoice")),'errors');
+		}
 
-    // Check minimum price
-	$productid = GETPOST('productid', 'int');
-    if (! empty($productid))
-    {
-        $product = new Product($db);
-        $product->fetch($productid);
-
-        $type=$product->type;
-
-        $price_min = $product->price_min;
-        if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level))
-        	$price_min = $product->multiprices_min[$object->client->price_level];
-
-        $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label'):'');
-
-        if ($price_min && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min)))
-        {
-        	setEventMessage($langs->trans("CantBeLessThanMinPrice", price2num($price_min,'MU')).$langs->getCurrencySymbol($conf->currency), 'errors');
-        	$error++;
-        }
-    }
-    else
-    {
-    	$type = GETPOST('type');
-    	$label = (GETPOST('product_label') ? GETPOST('product_label'):'');
-
-    	// Check parameters
-    	if (GETPOST('type') < 0) {
-    		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors');
-    		$error++;
-    	}
-    }
+		$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+		if (empty($datefacture))
+		{
+			$error++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("Date")),'errors');
+		}
 
-	// Update line
-	if (! $error)
+		if (! $error)
+		{
+			// Si facture avoir
+			$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+
+			//$result=$object->fetch($_POST['fac_avoir']);
+
+			$object->socid				= GETPOST('socid','int');
+			$object->number				= $_POST['facnumber'];
+			$object->date				= $datefacture;
+			$object->note_public		= trim($_POST['note_public']);
+			$object->note				= trim($_POST['note']);
+			$object->ref_client			= $_POST['ref_client'];
+			$object->ref_int			= $_POST['ref_int'];
+			$object->modelpdf			= $_POST['model'];
+			$object->fk_project			= $_POST['projectid'];
+			$object->cond_reglement_id	= 0;
+			$object->mode_reglement_id	= $_POST['mode_reglement_id'];
+			$object->remise_absolue		= $_POST['remise_absolue'];
+			$object->remise_percent		= $_POST['remise_percent'];
+
+			// Proprietes particulieres a facture avoir
+			$object->fk_facture_source	= $_POST['fac_avoir'];
+			$object->type				= 2;
+
+			$id = $object->create($user);
+
+			// Add predefined lines
+			for ($i = 1; $i <= $NBLINES; $i++)
+			{
+				if ($_POST['idprod'.$i])
+				{
+					$product=new Product($db);
+					$product->fetch($_POST['idprod'.$i]);
+					$startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']);
+					$endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']);
+					$result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type);
+				}
+			}
+		}
+	}
+
+	// Standard invoice or Deposit invoice created from a Predefined invoice
+	if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0)
 	{
-		$result = $object->updateline(
-				GETPOST('lineid'),
-				$description,
+		$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+		if (empty($datefacture))
+		{
+			$error++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
+		}
+
+		if (! $error)
+		{
+			$object->socid			= GETPOST('socid','int');
+			$object->type           = $_POST['type'];
+			$object->number         = $_POST['facnumber'];
+			$object->date           = $datefacture;
+			$object->note_public	= trim($_POST['note_public']);
+			$object->note_private   = trim($_POST['note_private']);
+			$object->ref_client     = $_POST['ref_client'];
+			$object->ref_int     	= $_POST['ref_int'];
+			$object->modelpdf       = $_POST['model'];
+
+			// Source facture
+			$object->fac_rec        = $_POST['fac_rec'];
+
+			$id = $object->create($user);
+		}
+	}
+
+
+
+	// Standard or deposit or proforma invoice
+	if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0)
+	{
+		if (GETPOST('socid','int')<1)
+		{
+			$error++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Customer")),'errors');
+		}
+
+		$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+		if (empty($datefacture))
+		{
+			$error++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
+		}
+
+		if (! $error)
+		{
+			// Si facture standard
+			$object->socid				= GETPOST('socid','int');
+			$object->type				= GETPOST('type');
+			$object->number				= $_POST['facnumber'];
+			$object->date				= $datefacture;
+			$object->note_public		= trim($_POST['note_public']);
+			$object->note_private		= trim($_POST['note_private']);
+			$object->ref_client			= $_POST['ref_client'];
+			$object->ref_int			= $_POST['ref_int'];
+			$object->modelpdf			= $_POST['model'];
+			$object->fk_project			= $_POST['projectid'];
+			$object->cond_reglement_id	= ($_POST['type'] == 3?1:$_POST['cond_reglement_id']);
+			$object->mode_reglement_id	= $_POST['mode_reglement_id'];
+			$object->amount				= $_POST['amount'];
+			$object->remise_absolue		= $_POST['remise_absolue'];
+			$object->remise_percent		= $_POST['remise_percent'];
+			$object->fetch_thirdparty();
+
+			// If creation from another object of another module (Example: origin=propal, originid=1)
+			if ($_POST['origin'] && $_POST['originid'])
+			{
+				// Parse element/subelement (ex: project_task)
+				$element = $subelement = $_POST['origin'];
+				if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs))
+				{
+					$element = $regs[1];
+					$subelement = $regs[2];
+				}
+
+				// For compatibility
+				if ($element == 'order')    {
+					$element = $subelement = 'commande';
+				}
+				if ($element == 'propal')   {
+					$element = 'comm/propal'; $subelement = 'propal';
+				}
+				if ($element == 'contract') {
+					$element = $subelement = 'contrat';
+				}
+				if ($element == 'inter')    {
+					$element = $subelement = 'ficheinter';
+				}
+				if ($element == 'shipping') {
+					$element = $subelement = 'expedition';
+				}
+
+				$object->origin    = $_POST['origin'];
+				$object->origin_id = $_POST['originid'];
+
+				// Possibility to add external linked objects with hooks
+				$object->linked_objects[$object->origin] = $object->origin_id;
+				if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects']))
+				{
+					$object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
+				}
+
+				$id = $object->create($user);
+
+				if ($id > 0)
+				{
+					//If deposit invoice
+					if ($_POST['type'] == 3) {
+						$typeamount=GETPOST('typedeposit','alpha');
+						$valuedeposit=GETPOST('valuedeposit','int');
+						
+						if ($typeamount=='amount') {
+							$amountdeposit=$valuedeposit;
+						}else {
+							$amountdeposit=0;
+							
+							dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
+							
+							$classname = ucfirst($subelement);
+							$srcobject = new $classname($db);
+							
+							dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add deposit line");
+							$result=$srcobject->fetch($object->origin_id);
+							if ($result > 0)
+							{
+								$totalamount=0;
+								$lines = $srcobject->lines;
+								$num=count($lines);
+								for ($i=0;$i<$num;$i++)
+								{
+									$totalamount=+$lines[$i]->subprice;
+								}
+								
+								if ($totalamount!=0) {
+									$amountdeposit=($totalamount*$valuedeposit)/100;
+								}
+							}
+							else
+							{
+								$mesgs[]=$srcobject->error;
+								$error++;
+							}
+							
+						}
+						
+						$result = $object->addline(
+							$id,
+							$langs->trans('Deposit'),
+							$amountdeposit, //subprice
+							1, //quantity
+							$lines[$i]->tva_tx,
+							0, //localtax1_tx
+							0, //localtax2_tx
+							0, //fk_product
+							0, //remise_percent
+							0, //date_start
+							0, //date_end
+							0,
+							$lines[$i]->info_bits, //info_bits
+							0, //info_bits
+							'HT',
+							0,
+							0, //product_type
+							1,
+							$lines[$i]->special_code,
+							$object->origin,
+							0,
+							0,
+							0,
+							0,
+							$langs->trans('Deposit')
+						);
+						
+
+					}else {
+
+						dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
+
+						$classname = ucfirst($subelement);
+						$srcobject = new $classname($db);
+
+						dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines");
+						$result=$srcobject->fetch($object->origin_id);
+						if ($result > 0)
+						{
+							$lines = $srcobject->lines;
+							if (empty($lines) && method_exists($srcobject,'fetch_lines'))  $lines = $srcobject->fetch_lines();
+
+							$fk_parent_line=0;
+							$num=count($lines);
+
+							for ($i=0;$i<$num;$i++)
+							{
+								$label=(! empty($lines[$i]->label)?$lines[$i]->label:'');
+								$desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle);
+
+								if ($lines[$i]->subprice < 0)
+								{
+									// Negative line, we create a discount line
+									$discount = new DiscountAbsolute($db);
+									$discount->fk_soc=$object->socid;
+									$discount->amount_ht=abs($lines[$i]->total_ht);
+									$discount->amount_tva=abs($lines[$i]->total_tva);
+									$discount->amount_ttc=abs($lines[$i]->total_ttc);
+									$discount->tva_tx=$lines[$i]->tva_tx;
+									$discount->fk_user=$user->id;
+									$discount->description=$desc;
+									$discountid=$discount->create($user);
+									if ($discountid > 0)
+									{
+										$result=$object->insert_discount($discountid);    // This include link_to_invoice
+									}
+									else
+									{
+										$mesgs[]=$discount->error;
+										$error++;
+										break;
+									}
+								}
+								else
+								{
+									// Positive line
+									$product_type=($lines[$i]->product_type?$lines[$i]->product_type:0);
+
+									// Date start
+									$date_start=false;
+									if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue;
+									if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel;
+									if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start;
+
+									//Date end
+									$date_end=false;
+									if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue;
+									if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel;
+									if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end;
+
+									// Reset fk_parent_line for no child products and special product
+									if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
+										$fk_parent_line = 0;
+									}
+
+									$result = $object->addline(
+										$id,
+										$desc,
+										$lines[$i]->subprice,
+										$lines[$i]->qty,
+										$lines[$i]->tva_tx,
+										$lines[$i]->localtax1_tx,
+										$lines[$i]->localtax2_tx,
+										$lines[$i]->fk_product,
+										$lines[$i]->remise_percent,
+										$date_start,
+										$date_end,
+										0,
+										$lines[$i]->info_bits,
+										$lines[$i]->fk_remise_except,
+										'HT',
+										0,
+										$product_type,
+										$lines[$i]->rang,
+										$lines[$i]->special_code,
+										$object->origin,
+										$lines[$i]->rowid,
+										$fk_parent_line,
+										$lines[$i]->fk_fournprice,
+										$lines[$i]->pa_ht,
+										$label
+									);
+
+									if ($result > 0)
+									{
+										$lineid=$result;
+									}
+									else
+									{
+										$lineid=0;
+										$error++;
+										break;
+									}
+
+									// Defined the new fk_parent_line
+									if ($result > 0 && $lines[$i]->product_type == 9) {
+										$fk_parent_line = $result;
+									}
+								}
+							}
+
+							// Hooks
+							$parameters=array('objFrom'=>$srcobject);
+							$reshook=$hookmanager->executeHooks('createFrom',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
+							if ($reshook < 0) $error++;
+						}
+						else
+						{
+							$mesgs[]=$srcobject->error;
+							$error++;
+						}
+					}
+				}
+				else
+				{
+					$mesgs[]=$object->error;
+					$error++;
+				}
+			}
+			// If some invoice's lines already known
+			else
+			{
+				$id = $object->create($user);
+
+				for ($i = 1; $i <= $NBLINES; $i++)
+				{
+					if ($_POST['idprod'.$i])
+					{
+						$product=new Product($db);
+						$product->fetch($_POST['idprod'.$i]);
+						$startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']);
+						$endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']);
+						$result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type);
+					}
+				}
+			}
+		}
+	}
+
+	// End of object creation, we show it
+	if ($id > 0 && ! $error)
+	{
+		$db->commit();
+		header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);
+		exit;
+	}
+	else
+	{
+		$db->rollback();
+		$action='create';
+		$_GET["origin"]=$_POST["origin"];
+		$_GET["originid"]=$_POST["originid"];
+		$mesgs[]='<div class="error">'.$object->error.'</div>';
+	}
+}
+
+// Add a new line
+else if (($action == 'addline' || $action == 'addline_predef') && $user->rights->facture->creer)
+{
+	$langs->load('errors');
+	$error = 0;
+
+	$idprod=GETPOST('idprod', 'int');
+	$product_desc = (GETPOST('product_desc')?GETPOST('product_desc'):(GETPOST('np_desc')?GETPOST('np_desc'):(GETPOST('dp_desc')?GETPOST('dp_desc'):'')));
+	$price_ht = GETPOST('price_ht');
+	$tva_tx=(GETPOST('tva_tx')?GETPOST('tva_tx'):0);
+
+	if ((empty($idprod) || GETPOST('usenewaddlineform')) && ($price_ht < 0) && (GETPOST('qty') < 0))
+	{
+		setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors');
+		$error++;
+	}
+	if (empty($idprod) && GETPOST('type') < 0)
+	{
+		setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors');
+		$error++;
+	}
+	if ((empty($idprod) || GETPOST('usenewaddlineform')) && (!($price_ht >= 0) || $price_ht == ''))	// Unit price can be 0 but not ''
+	{
+		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("UnitPriceHT")), 'errors');
+		$error++;
+	}
+	if (! GETPOST('qty') && GETPOST('qty') == '')
+	{
+		setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors');
+		$error++;
+	}
+	if (empty($idprod) && empty($product_desc))
+	{
+		setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors');
+		$error++;
+	}
+
+	if (! $error && (GETPOST('qty') >= 0) && (! empty($product_desc) || ! empty($idprod)))
+	{
+		$ret=$object->fetch($id);
+		if ($ret < 0)
+		{
+			dol_print_error($db,$object->error);
+			exit;
+		}
+		$ret=$object->fetch_thirdparty();
+
+		// Clean parameters
+		$predef=((! empty($idprod) && $conf->global->MAIN_FEATURES_LEVEL < 2) ? '_predef' : '');
+		$date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year'));
+		$date_end=dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year'));
+		$price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT');
+
+		// Define special_code for special lines
+		$special_code=0;
+		//if (empty($_POST['qty'])) $special_code=3;	// Options should not exists on invoices
+
+		// Ecrase $pu par celui du produit
+		// Ecrase $desc par celui du produit
+		// Ecrase $txtva par celui du produit
+		// Ecrase $base_price_type par celui du produit
+		if (! empty($idprod))
+		{
+			$prod = new Product($db);
+			$prod->fetch($idprod);
+
+			$label = ((GETPOST('product_label') && GETPOST('product_label')!=$prod->label)?GETPOST('product_label'):'');
+
+			// Update if prices fields are defined
+			if (GETPOST('usenewaddlineform'))
+			{
+				$pu_ht=price2num($price_ht, 'MU');
+				$pu_ttc=price2num(GETPOST('price_ttc'), 'MU');
+				$tva_npr=(preg_match('/\*/', $tva_tx)?1:0);
+				$tva_tx=str_replace('*','', $tva_tx);
+				$desc = $product_desc;
+			}
+			else
+			{
+				$tva_tx = get_default_tva($mysoc,$object->client,$prod->id);
+				$tva_npr = get_default_npr($mysoc,$object->client,$prod->id);
+
+				// We define price for product
+				if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level))
+				{
+					$pu_ht = $prod->multiprices[$object->client->price_level];
+					$pu_ttc = $prod->multiprices_ttc[$object->client->price_level];
+					$price_min = $prod->multiprices_min[$object->client->price_level];
+					$price_base_type = $prod->multiprices_base_type[$object->client->price_level];
+				}
+				else
+				{
+					$pu_ht = $prod->price;
+					$pu_ttc = $prod->price_ttc;
+					$price_min = $prod->price_min;
+					$price_base_type = $prod->price_base_type;
+				}
+
+				// On reevalue prix selon taux tva car taux tva transaction peut etre different
+				// de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur).
+				if ($tva_tx != $prod->tva_tx)
+				{
+					if ($price_base_type != 'HT')
+					{
+						$pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU');
+					}
+					else
+					{
+						$pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU');
+					}
+				}
+
+				$desc='';
+
+				// Define output language
+				if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE))
+				{
+					$outputlangs = $langs;
+					$newlang='';
+					if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
+					if (empty($newlang)) $newlang=$object->client->default_lang;
+					if (! empty($newlang))
+					{
+						$outputlangs = new Translate("",$conf);
+						$outputlangs->setDefaultLang($newlang);
+					}
+
+					$desc = (! empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description;
+				}
+				else
+				{
+					$desc = $prod->description;
+				}
+
+				$desc=dol_concatdesc($desc,$product_desc);
+
+				// Add custom code and origin country into description
+				if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code)))
+				{
+					$tmptxt='(';
+					if (! empty($prod->customcode)) $tmptxt.=$langs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode;
+					if (! empty($prod->customcode) && ! empty($prod->country_code)) $tmptxt.=' - ';
+					if (! empty($prod->country_code)) $tmptxt.=$langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code,0,$db,$langs,0);
+					$tmptxt.=')';
+					$desc= dol_concatdesc($desc, $tmptxt);
+				}
+			}
+
+			$type = $prod->type;
+		}
+		else
+		{
+			$pu_ht		= price2num($price_ht, 'MU');
+			$pu_ttc		= price2num(GETPOST('price_ttc'), 'MU');
+			$tva_npr	= (preg_match('/\*/', $tva_tx)?1:0);
+			$tva_tx		= str_replace('*', '', $tva_tx);
+			$label		= (GETPOST('product_label')?GETPOST('product_label'):'');
+			$desc		= $product_desc;
+			$type		= GETPOST('type');
+		}
+
+		// Margin
+		$fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):'');
+		$buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):'');
+
+		// Local Taxes
+		$localtax1_tx= get_localtax($tva_tx, 1, $object->client);
+		$localtax2_tx= get_localtax($tva_tx, 2, $object->client);
+
+		$info_bits=0;
+		if ($tva_npr) $info_bits |= 0x01;
+
+		if (! empty($price_min) && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min)))
+		{
+			$mesg = $langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').$langs->getCurrencySymbol($conf->currency));
+			setEventMessage($mesg, 'errors');
+		}
+		else
+		{
+			// Insert line
+			$result = $object->addline(
+				$id,
+				$desc,
 				$pu_ht,
 				GETPOST('qty'),
+				$tva_tx,
+				$localtax1_tx,
+				$localtax2_tx,
+				$idprod,
 				GETPOST('remise_percent'),
 				$date_start,
 				$date_end,
-				$vat_rate,
-				$localtax1_rate,
-				$localtax2_rate,
-				'HT',
+				0,
 				$info_bits,
+				'',
+				$price_base_type,
+				$pu_ttc,
 				$type,
-				GETPOST('fk_parent_line'),
+				-1,
+				$special_code,
+				'',
 				0,
+				GETPOST('fk_parent_line'),
 				$fournprice,
 				$buyingprice,
 				$label
+			);
+
+			if ($result > 0)
+			{
+				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+				{
+					// Define output language
+					$outputlangs = $langs;
+					$newlang=GETPOST('lang_id','alpha');
+					if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) $newlang=$object->client->default_lang;
+					if (! empty($newlang))
+					{
+						$outputlangs = new Translate("",$conf);
+						$outputlangs->setDefaultLang($newlang);
+					}
+
+					$ret=$object->fetch($id);    // Reload to get new records
+					facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+				}
+
+				unset($_POST['qty']);
+				unset($_POST['type']);
+				unset($_POST['idprod']);
+				unset($_POST['remise_percent']);
+				unset($_POST['price_ht']);
+				unset($_POST['price_ttc']);
+				unset($_POST['tva_tx']);
+				unset($_POST['product_ref']);
+				unset($_POST['product_label']);
+				unset($_POST['product_desc']);
+				unset($_POST['fournprice']);
+				unset($_POST['buying_price']);
+
+				// old method
+				unset($_POST['np_desc']);
+				unset($_POST['dp_desc']);
+			}
+			else
+			{
+				setEventMessage($object->error, 'errors');
+			}
+
+			$action='';
+		}
+	}
+}
+
+else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['save'] == $langs->trans('Save'))
+{
+	if (! $object->fetch($id) > 0) dol_print_error($db);
+	$object->fetch_thirdparty();
+
+	// Clean parameters
+	$date_start='';
+	$date_end='';
+	$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'));
+	$description=dol_htmlcleanlastbr(GETPOST('product_desc'));
+	$pu_ht=GETPOST('price_ht');
+	$vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0);
+
+	// Define info_bits
+	$info_bits=0;
+	if (preg_match('/\*/', $vat_rate)) $info_bits |= 0x01;
+
+	// Define vat_rate
+	$vat_rate=str_replace('*','',$vat_rate);
+	$localtax1_rate=get_localtax($vat_rate,1,$object->client);
+	$localtax2_rate=get_localtax($vat_rate,2,$object->client);
+
+	// Add buying price
+	$fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):'');
+	$buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):'');
+
+	// Check minimum price
+	$productid = GETPOST('productid', 'int');
+	if (! empty($productid))
+	{
+		$product = new Product($db);
+		$product->fetch($productid);
+
+		$type=$product->type;
+
+		$price_min = $product->price_min;
+		if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level))
+			$price_min = $product->multiprices_min[$object->client->price_level];
+
+		$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label'):'');
+
+		if ($price_min && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min)))
+		{
+			setEventMessage($langs->trans("CantBeLessThanMinPrice", price2num($price_min,'MU')).$langs->getCurrencySymbol($conf->currency), 'errors');
+			$error++;
+		}
+	}
+	else
+	{
+		$type = GETPOST('type');
+		$label = (GETPOST('product_label') ? GETPOST('product_label'):'');
+
+		// Check parameters
+		if (GETPOST('type') < 0) {
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors');
+			$error++;
+		}
+	}
+
+	// Update line
+	if (! $error)
+	{
+		$result = $object->updateline(
+			GETPOST('lineid'),
+			$description,
+			$pu_ht,
+			GETPOST('qty'),
+			GETPOST('remise_percent'),
+			$date_start,
+			$date_end,
+			$vat_rate,
+			$localtax1_rate,
+			$localtax2_rate,
+			'HT',
+			$info_bits,
+			$type,
+			GETPOST('fk_parent_line'),
+			0,
+			$fournprice,
+			$buyingprice,
+			$label
 		);
 
 		if ($result >= 0)
@@ -1367,329 +1483,331 @@ else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['sa
 		{
 			setEventMessage($object->error, 'errors');
 		}
-    }
+	}
 }
 
 else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel'))
 {
-    header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);   // Pour reaffichage de la fiche en cours d'edition
-    exit;
+	header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id);   // Pour reaffichage de la fiche en cours d'edition
+	exit;
 }
 
 // Modify line position (up)
 else if ($action == 'up' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-    $object->fetch_thirdparty();
-    $object->line_up($_GET['rowid']);
-
-    // Define output language
-    $outputlangs = $langs;
-    $newlang='';
-    if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
-    if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
-    if (! empty($newlang))
-    {
-        $outputlangs = new Translate("",$conf);
-        $outputlangs->setDefaultLang($newlang);
-    }
-    if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-
-    header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']);
-    exit;
+	$object->fetch($id);
+	$object->fetch_thirdparty();
+	$object->line_up($_GET['rowid']);
+
+	// Define output language
+	$outputlangs = $langs;
+	$newlang='';
+	if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
+	if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
+	if (! empty($newlang))
+	{
+		$outputlangs = new Translate("",$conf);
+		$outputlangs->setDefaultLang($newlang);
+	}
+	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+
+	header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']);
+	exit;
 }
 // Modify line position (down)
 else if ($action == 'down' && $user->rights->facture->creer)
 {
-    $object->fetch($id);
-    $object->fetch_thirdparty();
-    $object->line_down($_GET['rowid']);
-
-    // Define output language
-    $outputlangs = $langs;
-    $newlang='';
-    if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
-    if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
-    if (! empty($newlang))
-    {
-        $outputlangs = new Translate("",$conf);
-        $outputlangs->setDefaultLang($newlang);
-    }
-    if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-
-    header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']);
-    exit;
+	$object->fetch($id);
+	$object->fetch_thirdparty();
+	$object->line_down($_GET['rowid']);
+
+	// Define output language
+	$outputlangs = $langs;
+	$newlang='';
+	if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
+	if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
+	if (! empty($newlang))
+	{
+		$outputlangs = new Translate("",$conf);
+		$outputlangs->setDefaultLang($newlang);
+	}
+	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+
+	header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']);
+	exit;
 }
 
 /*
  * Add file in email form
- */
+*/
 if (GETPOST('addfile'))
 {
-    require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 
-    // Set tmp user directory
-    $vardir=$conf->user->dir_output."/".$user->id;
-    $upload_dir_tmp = $vardir.'/temp';
+	// Set tmp user directory
+	$vardir=$conf->user->dir_output."/".$user->id;
+	$upload_dir_tmp = $vardir.'/temp';
 
-    dol_add_file_process($upload_dir_tmp,0,0);
-    $action='presend';
+	dol_add_file_process($upload_dir_tmp,0,0);
+	$action='presend';
 }
 
 /*
  * Remove file in email form
- */
+*/
 if (! empty($_POST['removedfile']))
 {
-    require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 
-    // Set tmp user directory
-    $vardir=$conf->user->dir_output."/".$user->id;
-    $upload_dir_tmp = $vardir.'/temp';
+	// Set tmp user directory
+	$vardir=$conf->user->dir_output."/".$user->id;
+	$upload_dir_tmp = $vardir.'/temp';
 
 	// TODO Delete only files that was uploaded from email form
-    dol_remove_file_process($_POST['removedfile'],0);
-    $action='presend';
+	dol_remove_file_process($_POST['removedfile'],0);
+	$action='presend';
 }
 
 /*
  * Send mail
- */
+*/
 if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_POST['removedfile'] && ! $_POST['cancel'])
 {
-    $langs->load('mails');
-
-    $actiontypecode='';$subject='';$actionmsg='';$actionmsg2='';
-
-    $result=$object->fetch($id);
-    $result=$object->fetch_thirdparty();
-
-    if ($result > 0)
-    {
-//        $ref = dol_sanitizeFileName($object->ref);
-//        $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf';
-
-//        if (is_readable($file))
-//        {
-            if ($_POST['sendto'])
-            {
-                // Le destinataire a ete fourni via le champ libre
-                $sendto = $_POST['sendto'];
-                $sendtoid = 0;
-            }
-            elseif ($_POST['receiver'] != '-1')
-            {
-                // Recipient was provided from combo list
-                if ($_POST['receiver'] == 'thirdparty') // Id of third party
-                {
-                    $sendto = $object->client->email;
-                    $sendtoid = 0;
-                }
-                else	// Id du contact
-                {
-                    $sendto = $object->client->contact_get_property($_POST['receiver'],'email');
-                    $sendtoid = $_POST['receiver'];
-                }
-            }
-
-            if (dol_strlen($sendto))
-            {
-                $langs->load("commercial");
-
-                $from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>';
-                $replyto = $_POST['replytoname']. ' <' . $_POST['replytomail'].'>';
-                $message = $_POST['message'];
-                $sendtocc = $_POST['sendtocc'];
-                $deliveryreceipt = $_POST['deliveryreceipt'];
-
-                if ($action == 'send')
-                {
-                    if (dol_strlen($_POST['subject'])) $subject = $_POST['subject'];
-                    else $subject = $langs->transnoentities('Bill').' '.$object->ref;
-                    $actiontypecode='AC_FAC';
-                    $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n";
-                    if ($message)
-                    {
-                        $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n";
-                        $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n";
-                        $actionmsg.=$message;
-                    }
-                    //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
-                }
-                if ($action == 'relance')
-                {
-                    if (dol_strlen($_POST['subject'])) $subject = $_POST['subject'];
-                    else $subject = $langs->transnoentities('Relance facture '.$object->ref);
-                    $actiontypecode='AC_FAC';
-                    $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n";
-                    if ($message) {
-                        $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n";
-                        $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n";
-                        $actionmsg.=$message;
-                    }
-                    //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
-                }
-
-                // Create form object
-                include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
-                $formmail = new FormMail($db);
-
-                $attachedfiles=$formmail->get_attached_files();
-                $filepath = $attachedfiles['paths'];
-                $filename = $attachedfiles['names'];
-                $mimetype = $attachedfiles['mimes'];
-
-                // Send mail
-                require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
-                $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1);
-                if ($mailfile->error)
-                {
-                    $mesgs[]='<div class="error">'.$mailfile->error.'</div>';
-                }
-                else
-                {
-                    $result=$mailfile->sendfile();
-                    if ($result)
-                    {
-                        $error=0;
-
-                        // Initialisation donnees
-                        $object->sendtoid		= $sendtoid;
-                        $object->actiontypecode	= $actiontypecode;
-                        $object->actionmsg		= $actionmsg;  // Long text
-                        $object->actionmsg2		= $actionmsg2; // Short text
-                        $object->fk_element		= $object->id;
-                        $object->elementtype	= $object->element;
-
-                        // Appel des triggers
-                        include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-                        $interface=new Interfaces($db);
-                        $result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf);
-                        if ($result < 0) { $error++; $this->errors=$interface->errors; }
-                        // Fin appel triggers
-
-                        if ($error)
-                        {
-                            dol_print_error($db);
-                        }
-                        else
-                        {
-                            // Redirect here
-                            // This avoid sending mail twice if going out and then back to page
-                        	$mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2));
-                        	setEventMessage($mesg);
-                            header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id);
-                            exit;
-                        }
-                    }
-                    else
-                    {
-                        $langs->load("other");
-                        $mesg='<div class="error">';
-                        if ($mailfile->error)
-                        {
-                            $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto);
-                            $mesg.='<br>'.$mailfile->error;
-                        }
-                        else
-                        {
-                            $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
-                        }
-                        $mesg.='</div>';
-                        $mesgs[]=$mesg;
-                    }
-                }
-/*            }
-            else
-            {
-                $langs->load("other");
-                $mesgs[]='<div class="error">'.$langs->trans('ErrorMailRecipientIsEmpty').'</div>';
-                dol_syslog('Recipient email is empty');
-            }*/
-        }
-        else
-        {
-            $langs->load("errors");
-            $mesgs[]='<div class="error">'.$langs->trans('ErrorCantReadFile',$file).'</div>';
-            dol_syslog('Failed to read file: '.$file);
-        }
-    }
-    else
-    {
-        $langs->load("other");
-        $mesgs[]='<div class="error">'.$langs->trans('ErrorFailedToReadEntity',$langs->trans("Invoice")).'</div>';
-        dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.');
-    }
-
-    $action = 'presend';
-}
-
-/*
- * Generate document
- */
-else if ($action == 'builddoc')	// En get ou en post
-{
-    $object->fetch($id);
-    $object->fetch_thirdparty();
-
-    if (GETPOST('model'))   $object->setDocModel($user, GETPOST('model'));
-	if (GETPOST('fk_bank')) $object->fk_bank=GETPOST('fk_bank');
-
-    // Define output language
-    $outputlangs = $langs;
-    $newlang='';
-    if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
-    if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
-    if (! empty($newlang))
-    {
-        $outputlangs = new Translate("",$conf);
-        $outputlangs->setDefaultLang($newlang);
-    }
-    $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-    if ($result <= 0)
-    {
-        dol_print_error($db,$result);
-        exit;
-    }
-    else
-    {
-        header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc'));
-        exit;
-    }
-}
-
-// Remove file in doc form
-else if ($action == 'remove_file')
-{
-	if ($object->fetch($id))
-	{
-		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+	$langs->load('mails');
 
-		$object->fetch_thirdparty();
+	$actiontypecode='';$subject='';$actionmsg='';$actionmsg2='';
 
-		$langs->load("other");
-		$upload_dir = $conf->facture->dir_output;
-		$file = $upload_dir . '/' . GETPOST('file');
-		$ret=dol_delete_file($file,0,0,0,$object);
-		if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile')));
-		else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors');
-		$action='';
-	}
-}
+	$result=$object->fetch($id);
+	$result=$object->fetch_thirdparty();
 
-if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer)
-{
-	if ($action == 'addcontact')
+	if ($result > 0)
 	{
-		$result = $object->fetch($id);
+		//        $ref = dol_sanitizeFileName($object->ref);
+		//        $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf';
 
-		if ($result > 0 && $id > 0)
+		//        if (is_readable($file))
+		//        {
+		if ($_POST['sendto'])
 		{
-			$contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
-			$result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]);
+			// Le destinataire a ete fourni via le champ libre
+			$sendto = $_POST['sendto'];
+			$sendtoid = 0;
+		}
+		elseif ($_POST['receiver'] != '-1')
+		{
+			// Recipient was provided from combo list
+			if ($_POST['receiver'] == 'thirdparty') // Id of third party
+			{
+				$sendto = $object->client->email;
+				$sendtoid = 0;
+			}
+			else	// Id du contact
+			{
+				$sendto = $object->client->contact_get_property($_POST['receiver'],'email');
+				$sendtoid = $_POST['receiver'];
+			}
 		}
 
-		if ($result >= 0)
+		if (dol_strlen($sendto))
+		{
+			$langs->load("commercial");
+
+			$from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>';
+			$replyto = $_POST['replytoname']. ' <' . $_POST['replytomail'].'>';
+			$message = $_POST['message'];
+			$sendtocc = $_POST['sendtocc'];
+			$deliveryreceipt = $_POST['deliveryreceipt'];
+
+			if ($action == 'send')
+			{
+				if (dol_strlen($_POST['subject'])) $subject = $_POST['subject'];
+				else $subject = $langs->transnoentities('Bill').' '.$object->ref;
+				$actiontypecode='AC_FAC';
+				$actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n";
+				if ($message)
+				{
+					$actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n";
+					$actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n";
+					$actionmsg.=$message;
+				}
+				//$actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
+			}
+			if ($action == 'relance')
+			{
+				if (dol_strlen($_POST['subject'])) $subject = $_POST['subject'];
+				else $subject = $langs->transnoentities('Relance facture '.$object->ref);
+				$actiontypecode='AC_FAC';
+				$actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n";
+				if ($message) {
+					$actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n";
+					$actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n";
+					$actionmsg.=$message;
+				}
+				//$actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
+			}
+
+			// Create form object
+			include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
+			$formmail = new FormMail($db);
+
+			$attachedfiles=$formmail->get_attached_files();
+			$filepath = $attachedfiles['paths'];
+			$filename = $attachedfiles['names'];
+			$mimetype = $attachedfiles['mimes'];
+
+			// Send mail
+			require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
+			$mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1);
+			if ($mailfile->error)
+			{
+				$mesgs[]='<div class="error">'.$mailfile->error.'</div>';
+			}
+			else
+			{
+				$result=$mailfile->sendfile();
+				if ($result)
+				{
+					$error=0;
+
+					// Initialisation donnees
+					$object->sendtoid		= $sendtoid;
+					$object->actiontypecode	= $actiontypecode;
+					$object->actionmsg		= $actionmsg;  // Long text
+					$object->actionmsg2		= $actionmsg2; // Short text
+					$object->fk_element		= $object->id;
+					$object->elementtype	= $object->element;
+
+					// Appel des triggers
+					include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+					$interface=new Interfaces($db);
+					$result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf);
+					if ($result < 0) {
+						$error++; $this->errors=$interface->errors;
+					}
+					// Fin appel triggers
+
+					if ($error)
+					{
+						dol_print_error($db);
+					}
+					else
+					{
+						// Redirect here
+						// This avoid sending mail twice if going out and then back to page
+						$mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2));
+						setEventMessage($mesg);
+						header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id);
+						exit;
+					}
+				}
+				else
+				{
+					$langs->load("other");
+					$mesg='<div class="error">';
+					if ($mailfile->error)
+					{
+						$mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto);
+						$mesg.='<br>'.$mailfile->error;
+					}
+					else
+					{
+						$mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
+					}
+					$mesg.='</div>';
+					$mesgs[]=$mesg;
+				}
+			}
+			/*            }
+			 else
+			{
+			$langs->load("other");
+			$mesgs[]='<div class="error">'.$langs->trans('ErrorMailRecipientIsEmpty').'</div>';
+			dol_syslog('Recipient email is empty');
+			}*/
+		}
+		else
+		{
+			$langs->load("errors");
+			$mesgs[]='<div class="error">'.$langs->trans('ErrorCantReadFile',$file).'</div>';
+			dol_syslog('Failed to read file: '.$file);
+		}
+	}
+	else
+	{
+		$langs->load("other");
+		$mesgs[]='<div class="error">'.$langs->trans('ErrorFailedToReadEntity',$langs->trans("Invoice")).'</div>';
+		dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.');
+	}
+
+	$action = 'presend';
+}
+
+/*
+ * Generate document
+*/
+else if ($action == 'builddoc')	// En get ou en post
+{
+	$object->fetch($id);
+	$object->fetch_thirdparty();
+
+	if (GETPOST('model'))   $object->setDocModel($user, GETPOST('model'));
+	if (GETPOST('fk_bank')) $object->fk_bank=GETPOST('fk_bank');
+
+	// Define output language
+	$outputlangs = $langs;
+	$newlang='';
+	if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
+	if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
+	if (! empty($newlang))
+	{
+		$outputlangs = new Translate("",$conf);
+		$outputlangs->setDefaultLang($newlang);
+	}
+	$result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+	if ($result <= 0)
+	{
+		dol_print_error($db,$result);
+		exit;
+	}
+	else
+	{
+		header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc'));
+		exit;
+	}
+}
+
+// Remove file in doc form
+else if ($action == 'remove_file')
+{
+	if ($object->fetch($id))
+	{
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+		$object->fetch_thirdparty();
+
+		$langs->load("other");
+		$upload_dir = $conf->facture->dir_output;
+		$file = $upload_dir . '/' . GETPOST('file');
+		$ret=dol_delete_file($file,0,0,0,$object);
+		if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile')));
+		else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors');
+		$action='';
+	}
+}
+
+if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer)
+{
+	if ($action == 'addcontact')
+	{
+		$result = $object->fetch($id);
+
+		if ($result > 0 && $id > 0)
+		{
+			$contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
+			$result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]);
+		}
+
+		if ($result >= 0)
 		{
 			header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
 			exit;
@@ -1767,7 +1885,7 @@ if ($action == 'update_extras')
 
 /*
  * View
- */
+*/
 
 $form = new Form($db);
 $formother=new FormOther($db);
@@ -1781,276 +1899,290 @@ llxHeader('',$langs->trans('Bill'),'EN:Customers_Invoices|FR:Factures_Clients|ES
 
 /*********************************************************************
  *
- * Mode creation
- *
- **********************************************************************/
+* Mode creation
+*
+**********************************************************************/
 if ($action == 'create')
 {
-    $facturestatic=new Facture($db);
-    $extralabels=$extrafields->fetch_name_optionals_label('facture');
-
-    print_fiche_titre($langs->trans('NewBill'));
-
-    $soc = new Societe($db);
-    if ($socid>0) $res=$soc->fetch($socid);
-
-    if (! empty($origin) && ! empty($originid))
-    {
-        // Parse element/subelement (ex: project_task)
-        $element = $subelement = $origin;
-        if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs))
-        {
-            $element = $regs[1];
-            $subelement = $regs[2];
-        }
-
-        if ($element == 'project')
-        {
-            $projectid=$originid;
-        }
-        else
-        {
-            // For compatibility
-            if ($element == 'order' || $element == 'commande')    { $element = $subelement = 'commande'; }
-            if ($element == 'propal')   { $element = 'comm/propal'; $subelement = 'propal'; }
-            if ($element == 'contract') { $element = $subelement = 'contrat'; }
-            if ($element == 'shipping') { $element = $subelement = 'expedition'; }
-
-            dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
-
-            $classname = ucfirst($subelement);
-            $objectsrc = new $classname($db);
-            $objectsrc->fetch($originid);
-            if (empty($objectsrc->lines) && method_exists($objectsrc,'fetch_lines'))  $objectsrc->fetch_lines();
-            $objectsrc->fetch_thirdparty();
-
-            $projectid			= (! empty($objectsrc->fk_project)?$objectsrc->fk_project:'');
-            $ref_client			= (! empty($objectsrc->ref_client)?$objectsrc->ref_client:'');
-            $ref_int			= (! empty($objectsrc->ref_int)?$objectsrc->ref_int:'');
-
-            $soc = $objectsrc->thirdparty;
-            $cond_reglement_id 	= (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1));
-            $mode_reglement_id 	= (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0));
-            $remise_percent 	= (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0));
-            $remise_absolue 	= (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0));
-            $dateinvoice		= empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0;
-        }
-    }
-    else
-    {
-        $cond_reglement_id 	= $soc->cond_reglement_id;
-        $mode_reglement_id 	= $soc->mode_reglement_id;
-        $remise_percent 	= $soc->remise_percent;
-        $remise_absolue 	= 0;
-        $dateinvoice		= empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0;
-    }
-    $absolute_discount=$soc->getAvailableDiscounts();
-
-
-    if (! empty($conf->use_javascript_ajax))
-    {
-        print ajax_combobox('fac_replacement');
-        print ajax_combobox('fac_avoir');
-    }
-
-    print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-    print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-    print '<input type="hidden" name="action" value="add">';
+	$facturestatic=new Facture($db);
+	$extralabels=$extrafields->fetch_name_optionals_label('facture');
+
+	print_fiche_titre($langs->trans('NewBill'));
+
+	$soc = new Societe($db);
+	if ($socid>0) $res=$soc->fetch($socid);
+
+	if (! empty($origin) && ! empty($originid))
+	{
+		// Parse element/subelement (ex: project_task)
+		$element = $subelement = $origin;
+		if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs))
+		{
+			$element = $regs[1];
+			$subelement = $regs[2];
+		}
+
+		if ($element == 'project')
+		{
+			$projectid=$originid;
+		}
+		else
+		{
+			// For compatibility
+			if ($element == 'order' || $element == 'commande')    {
+				$element = $subelement = 'commande';
+			}
+			if ($element == 'propal')   {
+				$element = 'comm/propal'; $subelement = 'propal';
+			}
+			if ($element == 'contract') {
+				$element = $subelement = 'contrat';
+			}
+			if ($element == 'shipping') {
+				$element = $subelement = 'expedition';
+			}
+
+			dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
+
+			$classname = ucfirst($subelement);
+			$objectsrc = new $classname($db);
+			$objectsrc->fetch($originid);
+			if (empty($objectsrc->lines) && method_exists($objectsrc,'fetch_lines'))  $objectsrc->fetch_lines();
+			$objectsrc->fetch_thirdparty();
+
+			$projectid			= (! empty($objectsrc->fk_project)?$objectsrc->fk_project:'');
+			$ref_client			= (! empty($objectsrc->ref_client)?$objectsrc->ref_client:'');
+			$ref_int			= (! empty($objectsrc->ref_int)?$objectsrc->ref_int:'');
+
+			$soc = $objectsrc->thirdparty;
+			$cond_reglement_id 	= (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1));
+			$mode_reglement_id 	= (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0));
+			$remise_percent 	= (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0));
+			$remise_absolue 	= (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0));
+			$dateinvoice		= empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0;
+		}
+	}
+	else
+	{
+		$cond_reglement_id 	= $soc->cond_reglement_id;
+		$mode_reglement_id 	= $soc->mode_reglement_id;
+		$remise_percent 	= $soc->remise_percent;
+		$remise_absolue 	= 0;
+		$dateinvoice		= empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0;
+	}
+	$absolute_discount=$soc->getAvailableDiscounts();
+
+
+	if (! empty($conf->use_javascript_ajax))
+	{
+		print ajax_combobox('fac_replacement');
+		print ajax_combobox('fac_avoir');
+	}
+
+	print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
+	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+	print '<input type="hidden" name="action" value="add">';
 	if ($soc->id > 0)
 		print '<input type="hidden" name="socid" value="'.$soc->id.'">' ."\n";
-    print '<input name="facnumber" type="hidden" value="provisoire">';
-    print '<input name="ref_client" type="hidden" value="'.$ref_client.'">';
-    print '<input name="ref_int" type="hidden" value="'.$ref_int.'">';
-    print '<input type="hidden" name="origin" value="'.$origin.'">';
-    print '<input type="hidden" name="originid" value="'.$originid.'">';
-
-    print '<table class="border" width="100%">';
-
-    // Ref
-    print '<tr><td class="fieldrequired">'.$langs->trans('Ref').'</td><td colspan="2">'.$langs->trans('Draft').'</td></tr>';
-
-    // Factures predefinies
-    if (empty($origin) && empty($originid) && $socid>0)
-    {
-        $sql = 'SELECT r.rowid, r.titre, r.total_ttc';
-        $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r';
-        $sql.= ' WHERE r.fk_soc = '.$soc->id;
-
-        $resql=$db->query($sql);
-        if ($resql)
-        {
-            $num = $db->num_rows($resql);
-            $i = 0;
-
-            if ($num > 0)
-            {
-                print '<tr><td>'.$langs->trans('CreateFromRepeatableInvoice').'</td><td>';
-                print '<select class="flat" name="fac_rec">';
-                print '<option value="0" selected="selected"></option>';
-                while ($i < $num)
-                {
-                    $objp = $db->fetch_object($resql);
-                    print '<option value="'.$objp->rowid.'"';
-                    if (GETPOST('fac_rec') == $objp->rowid) print ' selected="selected"';
-                    print '>'.$objp->titre.' ('.price($objp->total_ttc).' '.$langs->trans("TTC").')</option>';
-                    $i++;
-                }
-                print '</select></td></tr>';
-            }
-            $db->free($resql);
-        }
-        else
-       {
-            dol_print_error($db);
-        }
-    }
-
-    // Tiers
-    print '<tr>';
-    print '<td class="fieldrequired">'.$langs->trans('Customer').'</td>';
-    if($soc->id > 0)
-    {
-    	print '<td colspan="2">';
-    	print $soc->getNomUrl(1);
-    	print '<input type="hidden" name="socid" value="'.$soc->id.'">';
-    	print '</td>';
-    }
-    else
-   {
-   		print '<td colspan="2">';
-   		print $form->select_company('','socid','s.client = 1 OR s.client = 3',1);
-   		print '</td>';
-    }
-    print '</tr>'."\n";
-
-    // Type de facture
-    $facids=$facturestatic->list_replacable_invoices($soc->id);
-    if ($facids < 0)
-    {
-        dol_print_error($db,$facturestatic);
-        exit;
-    }
-    $options="";
-    foreach ($facids as $facparam)
-    {
-        $options.='<option value="'.$facparam['id'].'"';
-        if ($facparam['id'] == $_POST['fac_replacement']) $options.=' selected="selected"';
-        $options.='>'.$facparam['ref'];
-        $options.=' ('.$facturestatic->LibStatut(0,$facparam['status']).')';
-        $options.='</option>';
-    }
-
-    $facids=$facturestatic->list_qualified_avoir_invoices($soc->id);
-    if ($facids < 0)
-    {
-        dol_print_error($db,$facturestatic);
-        exit;
-    }
-    $optionsav="";
-    $newinvoice_static=new Facture($db);
-    foreach ($facids as $key => $valarray)
-    {
-        $newinvoice_static->id=$key;
-        $newinvoice_static->ref=$valarray['ref'];
-        $newinvoice_static->statut=$valarray['status'];
-        $newinvoice_static->type=$valarray['type'];
-        $newinvoice_static->paye=$valarray['paye'];
-
-        $optionsav.='<option value="'.$key.'"';
-        if ($key == $_POST['fac_avoir']) $optionsav.=' selected="selected"';
-        $optionsav.='>';
-        $optionsav.=$newinvoice_static->ref;
-        $optionsav.=' ('.$newinvoice_static->getLibStatut(1,$valarray['paymentornot']).')';
-        $optionsav.='</option>';
-    }
-
-    print '<tr><td valign="top" class="fieldrequired">'.$langs->trans('Type').'</td><td colspan="2">';
-    print '<table class="nobordernopadding">'."\n";
-
-    // Standard invoice
-    print '<tr height="18"><td width="16px" valign="middle">';
-    print '<input type="radio" name="type" value="0"'.(GETPOST('type')==0?' checked="checked"':'').'>';
-    print '</td><td valign="middle">';
-    $desc=$form->textwithpicto($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1);
-    print $desc;
-    print '</td></tr>'."\n";
-
-    // Proforma
-    if (! empty($conf->global->FACTURE_USE_PROFORMAT))
-    {
-        print '<tr height="18"><td width="16px" valign="middle">';
-        print '<input type="radio" name="type" value="4"'.(GETPOST('type')==4?' checked="checked"':'').'>';
-        print '</td><td valign="middle">';
-        $desc=$form->textwithpicto($langs->trans("InvoiceProForma"),$langs->transnoentities("InvoiceProFormaDesc"),1);
-        print $desc;
-        print '</td></tr>'."\n";
-    }
-
-    if (empty($origin))
-    {
-	    // Deposit
-	    print '<tr height="18"><td width="16px" valign="middle">';
-	    print '<input type="radio" name="type" value="3"'.(GETPOST('type')==3?' checked="checked"':'').'>';
-	    print '</td><td valign="middle">';
-	    $desc=$form->textwithpicto($langs->trans("InvoiceDeposit"),$langs->transnoentities("InvoiceDepositDesc"),1);
-	    print $desc;
-	    print '</td></tr>'."\n";
-    }
-
-    if ($socid > 0)
-	{
-	    // Replacement
-	    print '<tr height="18"><td valign="middle">';
-	    print '<input type="radio" name="type" value="1"'.(GETPOST('type')==1?' checked="checked"':'');
-	    if (! $options) print ' disabled="disabled"';
-	    print '>';
-	    print '</td><td valign="middle">';
-	    $text=$langs->trans("InvoiceReplacementAsk").' ';
-	    $text.='<select class="flat" name="fac_replacement" id="fac_replacement"';
-	    if (! $options) $text.=' disabled="disabled"';
-	    $text.='>';
-	    if ($options)
-	    {
-	        $text.='<option value="-1"></option>';
-	        $text.=$options;
-	    }
-	    else
-	    {
-	        $text.='<option value="-1">'.$langs->trans("NoReplacableInvoice").'</option>';
-	    }
-	    $text.='</select>';
-	    $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1);
-	    print $desc;
-	    print '</td></tr>'."\n";
-	}
-
-    if (empty($origin) && $socid > 0)
-    {
-    	// Credit note
-	    print '<tr height="18"><td valign="middle">';
-	    print '<input type="radio" name="type" value="2"'.(GETPOST('type')==2?' checked=true':'');
-	    if (! $optionsav) print ' disabled="disabled"';
-	    print '>';
-	    print '</td><td valign="middle">';
-	    $text=$langs->transnoentities("InvoiceAvoirAsk").' ';
-	    //	$text.='<input type="text" value="">';
-	    $text.='<select class="flat" name="fac_avoir" id="fac_avoir"';
-	    if (! $optionsav) $text.=' disabled="disabled"';
-	    $text.='>';
-	    if ($optionsav)
-	    {
-	        $text.='<option value="-1"></option>';
-	        $text.=$optionsav;
-	    }
-	    else
-	    {
-	        $text.='<option value="-1">'.$langs->trans("NoInvoiceToCorrect").'</option>';
-	    }
-	    $text.='</select>';
-	    $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1);
-	    print $desc;
-	    print '</td></tr>'."\n";
-    }
+	print '<input name="facnumber" type="hidden" value="provisoire">';
+	print '<input name="ref_client" type="hidden" value="'.$ref_client.'">';
+	print '<input name="ref_int" type="hidden" value="'.$ref_int.'">';
+	print '<input type="hidden" name="origin" value="'.$origin.'">';
+	print '<input type="hidden" name="originid" value="'.$originid.'">';
+
+	print '<table class="border" width="100%">';
+
+	// Ref
+	print '<tr><td class="fieldrequired">'.$langs->trans('Ref').'</td><td colspan="2">'.$langs->trans('Draft').'</td></tr>';
+
+	// Factures predefinies
+	if (empty($origin) && empty($originid) && $socid>0)
+	{
+		$sql = 'SELECT r.rowid, r.titre, r.total_ttc';
+		$sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r';
+		$sql.= ' WHERE r.fk_soc = '.$soc->id;
+
+		$resql=$db->query($sql);
+		if ($resql)
+		{
+			$num = $db->num_rows($resql);
+			$i = 0;
+
+			if ($num > 0)
+			{
+				print '<tr><td>'.$langs->trans('CreateFromRepeatableInvoice').'</td><td>';
+				print '<select class="flat" name="fac_rec">';
+				print '<option value="0" selected="selected"></option>';
+				while ($i < $num)
+				{
+					$objp = $db->fetch_object($resql);
+					print '<option value="'.$objp->rowid.'"';
+					if (GETPOST('fac_rec') == $objp->rowid) print ' selected="selected"';
+					print '>'.$objp->titre.' ('.price($objp->total_ttc).' '.$langs->trans("TTC").')</option>';
+					$i++;
+				}
+				print '</select></td></tr>';
+			}
+			$db->free($resql);
+		}
+		else
+		{
+			dol_print_error($db);
+		}
+	}
+
+	// Tiers
+	print '<tr>';
+	print '<td class="fieldrequired">'.$langs->trans('Customer').'</td>';
+	if($soc->id > 0)
+	{
+		print '<td colspan="2">';
+		print $soc->getNomUrl(1);
+		print '<input type="hidden" name="socid" value="'.$soc->id.'">';
+		print '</td>';
+	}
+	else
+	{
+		print '<td colspan="2">';
+		print $form->select_company('','socid','s.client = 1 OR s.client = 3',1);
+		print '</td>';
+	}
+	print '</tr>'."\n";
+
+	// Type de facture
+	$facids=$facturestatic->list_replacable_invoices($soc->id);
+	if ($facids < 0)
+	{
+		dol_print_error($db,$facturestatic);
+		exit;
+	}
+	$options="";
+	foreach ($facids as $facparam)
+	{
+		$options.='<option value="'.$facparam['id'].'"';
+		if ($facparam['id'] == $_POST['fac_replacement']) $options.=' selected="selected"';
+		$options.='>'.$facparam['ref'];
+		$options.=' ('.$facturestatic->LibStatut(0,$facparam['status']).')';
+		$options.='</option>';
+	}
+
+	$facids=$facturestatic->list_qualified_avoir_invoices($soc->id);
+	if ($facids < 0)
+	{
+		dol_print_error($db,$facturestatic);
+		exit;
+	}
+	$optionsav="";
+	$newinvoice_static=new Facture($db);
+	foreach ($facids as $key => $valarray)
+	{
+		$newinvoice_static->id=$key;
+		$newinvoice_static->ref=$valarray['ref'];
+		$newinvoice_static->statut=$valarray['status'];
+		$newinvoice_static->type=$valarray['type'];
+		$newinvoice_static->paye=$valarray['paye'];
+
+		$optionsav.='<option value="'.$key.'"';
+		if ($key == $_POST['fac_avoir']) $optionsav.=' selected="selected"';
+		$optionsav.='>';
+		$optionsav.=$newinvoice_static->ref;
+		$optionsav.=' ('.$newinvoice_static->getLibStatut(1,$valarray['paymentornot']).')';
+		$optionsav.='</option>';
+	}
+
+	print '<tr><td valign="top" class="fieldrequired">'.$langs->trans('Type').'</td><td colspan="2">';
+	print '<table class="nobordernopadding">'."\n";
+
+	// Standard invoice
+	print '<tr height="18"><td width="16px" valign="middle">';
+	print '<input type="radio" name="type" value="0"'.(GETPOST('type')==0?' checked="checked"':'').'>';
+	print '</td><td valign="middle">';
+	$desc=$form->textwithpicto($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1);
+	print $desc;
+	print '</td></tr>'."\n";
+
+	// Proforma
+	if (! empty($conf->global->FACTURE_USE_PROFORMAT))
+	{
+		print '<tr height="18"><td width="16px" valign="middle">';
+		print '<input type="radio" name="type" value="4"'.(GETPOST('type')==4?' checked="checked"':'').'>';
+		print '</td><td valign="middle">';
+		$desc=$form->textwithpicto($langs->trans("InvoiceProForma"),$langs->transnoentities("InvoiceProFormaDesc"),1);
+		print $desc;
+		print '</td></tr>'."\n";
+	}
+
+	if ((empty($origin)) || (($origin=='propal') && (!empty($originid))))
+	{
+		// Deposit
+		print '<tr height="18"><td width="16px" valign="middle">';
+		print '<input type="radio" name="type" value="3"'.(GETPOST('type')==3?' checked="checked"':'').'>';
+		print '</td><td valign="middle" nowrap="nowrap">';
+		$desc=$form->textwithpicto($langs->trans("InvoiceDeposit"),$langs->transnoentities("InvoiceDepositDesc"),1);
+		print '<table class="nobordernopadding"><tr><td>'.$desc.'</td>';
+		if (($origin=='propal') ) {
+			print '<td><select name="typedeposit"><option value="amount">'.$langs->trans('FixAmount').'</option>';
+			print '<option value="variable">'.$langs->trans('VarAmount').'</option></select></td>';
+			print '<td>'.$langs->trans('Value').':<input type="text" name="valuedeposit" size="3" value="'.GETPOST('valuedeposit','int').'"/>';
+		}
+		print '</td></tr></table>';
+		print '</td></tr>'."\n";
+	}
+
+	if ($socid > 0)
+	{
+		// Replacement
+		print '<tr height="18"><td valign="middle">';
+		print '<input type="radio" name="type" value="1"'.(GETPOST('type')==1?' checked="checked"':'');
+		if (! $options) print ' disabled="disabled"';
+		print '>';
+		print '</td><td valign="middle">';
+		$text=$langs->trans("InvoiceReplacementAsk").' ';
+		$text.='<select class="flat" name="fac_replacement" id="fac_replacement"';
+		if (! $options) $text.=' disabled="disabled"';
+		$text.='>';
+		if ($options)
+		{
+			$text.='<option value="-1"></option>';
+			$text.=$options;
+		}
+		else
+		{
+			$text.='<option value="-1">'.$langs->trans("NoReplacableInvoice").'</option>';
+		}
+		$text.='</select>';
+		$desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1);
+		print $desc;
+		print '</td></tr>'."\n";
+	}
+
+	if (empty($origin) && $socid > 0)
+	{
+		// Credit note
+		print '<tr height="18"><td valign="middle">';
+		print '<input type="radio" name="type" value="2"'.(GETPOST('type')==2?' checked=true':'');
+		if (! $optionsav) print ' disabled="disabled"';
+		print '>';
+		print '</td><td valign="middle">';
+		$text=$langs->transnoentities("InvoiceAvoirAsk").' ';
+		//	$text.='<input type="text" value="">';
+		$text.='<select class="flat" name="fac_avoir" id="fac_avoir"';
+		if (! $optionsav) $text.=' disabled="disabled"';
+		$text.='>';
+		if ($optionsav)
+		{
+			$text.='<option value="-1"></option>';
+			$text.=$optionsav;
+		}
+		else
+		{
+			$text.='<option value="-1">'.$langs->trans("NoInvoiceToCorrect").'</option>';
+		}
+		$text.='</select>';
+		$desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1);
+		print $desc;
+		print '</td></tr>'."\n";
+	}
 
 	print '</table>';
 	print '</td></tr>';
@@ -2061,7 +2193,7 @@ if ($action == 'create')
 		print '<tr><td>'.$langs->trans('Discounts').'</td><td colspan="2">';
 		if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",'<a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$soc->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid')).'">'.$soc->remise_client.'</a>');
 		else print $langs->trans("CompanyHasNoRelativeDiscount");
-	    print ' <a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$soc->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid')).'">('.$langs->trans("EditRelativeDiscount").')</a>';
+		print ' <a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$soc->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid')).'">('.$langs->trans("EditRelativeDiscount").')</a>';
 		print '. ';
 		print '<br>';
 		if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",'<a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$soc->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid')).'">'.price($absolute_discount).'</a>',$langs->trans("Currency".$conf->currency));
@@ -2071,1539 +2203,1585 @@ if ($action == 'create')
 		print '</td></tr>';
 	}
 
-    // Date invoice
-    print '<tr><td class="fieldrequired">'.$langs->trans('Date').'</td><td colspan="2">';
-    $form->select_date($dateinvoice,'','','','',"add",1,1);
-    print '</td></tr>';
-
-    // Payment term
-    print '<tr><td nowrap>'.$langs->trans('PaymentConditionsShort').'</td><td colspan="2">';
-    $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id');
-    print '</td></tr>';
-
-    // Payment mode
-    print '<tr><td>'.$langs->trans('PaymentMode').'</td><td colspan="2">';
-    $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id');
-    print '</td></tr>';
-
-    // Project
-    if (! empty($conf->projet->enabled) && $socid>0)
-    {
-        $langs->load('projects');
-        print '<tr><td>'.$langs->trans('Project').'</td><td colspan="2">';
-        select_projects($soc->id, $projectid, 'projectid');
-        print '</td></tr>';
-    }
-
-    // Other attributes
-    $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"');
-    $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
-    if (empty($reshook) && ! empty($extrafields->attribute_label))
-    {
-        print $object->showOptionals($extrafields,'edit');
-    }
-
-    // Modele PDF
-    print '<tr><td>'.$langs->trans('Model').'</td>';
-    print '<td>';
-    include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
-    $liste=ModelePDFFactures::liste_modeles($db);
-    print $form->selectarray('model',$liste,$conf->global->FACTURE_ADDON_PDF);
-    print "</td></tr>";
-
-    // Public note
-    print '<tr>';
-    print '<td class="border" valign="top">'.$langs->trans('NotePublic').'</td>';
-    print '<td valign="top" colspan="2">';
-    $note_public='';
-    if (is_object($objectsrc))    // Take value from source object
-    {
-    	$note_public=$objectsrc->note_public;
-    }
-    $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70);
-    print $doleditor->Create(1);
-
-    //print '<textarea name="note_public" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_public.'</textarea></td></tr>';
-
-    // Private note
-    if (empty($user->societe_id))
-    {
-        print '<tr>';
-        print '<td class="border" valign="top">'.$langs->trans('NotePrivate').'</td>';
-        print '<td valign="top" colspan="2">';
-        $note_private='';
-        if (! empty($origin) && ! empty($originid) && is_object($objectsrc))    // Take value from source object
-        {
-        	$note_private=$objectsrc->note_private;
-        }
-        $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70);
-        print $doleditor->Create(1);
-        //print '<textarea name="note_private" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_private.'.</textarea></td></tr>';
-    }
-
-    if (! empty($origin) && ! empty($originid) && is_object($objectsrc))
-    {
-        // TODO for compatibility
-        if ($origin == 'contrat')
-        {
-            // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
-            $objectsrc->remise_absolue=$remise_absolue;
-            $objectsrc->remise_percent=$remise_percent;
-            $objectsrc->update_price(1,-1,1);
-        }
-
-        print "\n<!-- ".$classname." info -->";
-        print "\n";
-        print '<input type="hidden" name="amount"         value="'.$objectsrc->total_ht.'">'."\n";
-        print '<input type="hidden" name="total"          value="'.$objectsrc->total_ttc.'">'."\n";
-        print '<input type="hidden" name="tva"            value="'.$objectsrc->total_tva.'">'."\n";
-        print '<input type="hidden" name="origin"         value="'.$objectsrc->element.'">';
-        print '<input type="hidden" name="originid"       value="'.$objectsrc->id.'">';
-
-        $newclassname=$classname;
-        if ($newclassname == 'Propal') $newclassname = 'CommercialProposal';
-        elseif ($newclassname == 'Commande') $newclassname = 'Order';
-
-        print '<tr><td>'.$langs->trans($newclassname).'</td><td colspan="2">'.$objectsrc->getNomUrl(1).'</td></tr>';
-        print '<tr><td>'.$langs->trans('TotalHT').'</td><td colspan="2">'.price($objectsrc->total_ht).'</td></tr>';
-        print '<tr><td>'.$langs->trans('TotalVAT').'</td><td colspan="2">'.price($objectsrc->total_tva)."</td></tr>";
-        if ($mysoc->localtax1_assuj=="1") //Localtax1 RE
-        {
-            print '<tr><td>'.$langs->transcountry("AmountLT1",$mysoc->country_code).'</td><td colspan="2">'.price($objectsrc->total_localtax1)."</td></tr>";
-        }
-
-        if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF
-        {
-            print '<tr><td>'.$langs->transcountry("AmountLT2",$mysoc->country_code).'</td><td colspan="2">'.price($objectsrc->total_localtax2)."</td></tr>";
-        }
-        print '<tr><td>'.$langs->trans('TotalTTC').'</td><td colspan="2">'.price($objectsrc->total_ttc)."</td></tr>";
-    }
-    else
-    {
-        // Show deprecated optional form to add product line here
-        if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE))
-        {
-            print '<tr><td colspan="3">';
-
-            // Zone de choix des produits predefinis a la creation
-            print '<table class="noborder" width="100%">';
-            print '<tr>';
-            print '<td>'.$langs->trans('ProductsAndServices').'</td>';
-            print '<td>'.$langs->trans('Qty').'</td>';
-            print '<td>'.$langs->trans('ReductionShort').'</td>';
-            print '<td> &nbsp; &nbsp; </td>';
-            if (! empty($conf->service->enabled))
-            {
-                print '<td>'.$langs->trans('ServiceLimitedDuration').'</td>';
-            }
-            print '</tr>';
-            for ($i = 1 ; $i <= $NBLINES ; $i++)
-            {
-                print '<tr>';
-                print '<td>';
-                // multiprix
-                if (! empty($conf->global->PRODUIT_MULTIPRICES))
-                $form->select_produits('','idprod'.$i,'',$conf->product->limit_size,$soc->price_level);
-                else
-                $form->select_produits('','idprod'.$i,'',$conf->product->limit_size);
-                print '</td>';
-                print '<td><input type="text" size="2" name="qty'.$i.'" value="1"></td>';
-                print '<td nowrap="nowrap"><input type="text" size="1" name="remise_percent'.$i.'" value="'.$soc->remise_client.'">%</td>';
-                print '<td>&nbsp;</td>';
-                // Si le module service est actif, on propose des dates de debut et fin a la ligne
-                if (! empty($conf->service->enabled))
-                {
-                    print '<td nowrap="nowrap">';
-                    print '<table class="nobordernopadding"><tr class="nocellnopadd">';
-                    print '<td class="nobordernopadding" nowrap="nowrap">';
-                    print $langs->trans('From').' ';
-                    print '</td><td class="nobordernopadding" nowrap="nowrap">';
-                    print $form->select_date('','date_start'.$i,$usehm,$usehm,1,"add");
-                    print '</td></tr>';
-                    print '<td class="nobordernopadding" nowrap="nowrap">';
-                    print $langs->trans('to').' ';
-                    print '</td><td class="nobordernopadding" nowrap="nowrap">';
-                    print $form->select_date('','date_end'.$i,$usehm,$usehm,1,"add");
-                    print '</td></tr></table>';
-                    print '</td>';
-                }
-                print "</tr>\n";
-            }
-
-            print '</table>';
-            print '</td></tr>';
-        }
-    }
-
-    print "</table>\n";
-
-    // Button "Create Draft"
-    print '<br><center><input type="submit" class="button" name="bouton" value="'.$langs->trans('CreateDraft').'"></center>';
-
-    print "</form>\n";
-
-    // Show origin lines
-    if (! empty($origin) && ! empty($originid) && is_object($objectsrc))
-    {
-        print '<br>';
-
-        $title=$langs->trans('ProductsAndServices');
-        print_titre($title);
-
-        print '<table class="noborder" width="100%">';
-
-        $objectsrc->printOriginLinesList();
-
-        print '</table>';
-    }
+	// Date invoice
+	print '<tr><td class="fieldrequired">'.$langs->trans('Date').'</td><td colspan="2">';
+	$form->select_date($dateinvoice,'','','','',"add",1,1);
+	print '</td></tr>';
+
+	// Payment term
+	print '<tr><td nowrap>'.$langs->trans('PaymentConditionsShort').'</td><td colspan="2">';
+	$form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id');
+	print '</td></tr>';
+
+	// Payment mode
+	print '<tr><td>'.$langs->trans('PaymentMode').'</td><td colspan="2">';
+	$form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id');
+	print '</td></tr>';
+
+	// Project
+	if (! empty($conf->projet->enabled) && $socid>0)
+	{
+		$langs->load('projects');
+		print '<tr><td>'.$langs->trans('Project').'</td><td colspan="2">';
+		select_projects($soc->id, $projectid, 'projectid');
+		print '</td></tr>';
+	}
+
+	// Other attributes
+	$parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"');
+	$reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
+	if (empty($reshook) && ! empty($extrafields->attribute_label))
+	{
+		print $object->showOptionals($extrafields,'edit');
+	}
+
+	// Modele PDF
+	print '<tr><td>'.$langs->trans('Model').'</td>';
+	print '<td>';
+	include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
+	$liste=ModelePDFFactures::liste_modeles($db);
+	print $form->selectarray('model',$liste,$conf->global->FACTURE_ADDON_PDF);
+	print "</td></tr>";
+
+	// Public note
+	print '<tr>';
+	print '<td class="border" valign="top">'.$langs->trans('NotePublic').'</td>';
+	print '<td valign="top" colspan="2">';
+	$note_public='';
+	if (is_object($objectsrc))    // Take value from source object
+	{
+		$note_public=$objectsrc->note_public;
+	}
+	$doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70);
+	print $doleditor->Create(1);
+
+	//print '<textarea name="note_public" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_public.'</textarea></td></tr>';
+
+	// Private note
+	if (empty($user->societe_id))
+	{
+		print '<tr>';
+		print '<td class="border" valign="top">'.$langs->trans('NotePrivate').'</td>';
+		print '<td valign="top" colspan="2">';
+		$note_private='';
+		if (! empty($origin) && ! empty($originid) && is_object($objectsrc))    // Take value from source object
+		{
+			$note_private=$objectsrc->note_private;
+		}
+		$doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70);
+		print $doleditor->Create(1);
+		//print '<textarea name="note_private" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_private.'.</textarea></td></tr>';
+	}
+
+	if (! empty($origin) && ! empty($originid) && is_object($objectsrc))
+	{
+		// TODO for compatibility
+		if ($origin == 'contrat')
+		{
+			// Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
+			$objectsrc->remise_absolue=$remise_absolue;
+			$objectsrc->remise_percent=$remise_percent;
+			$objectsrc->update_price(1,-1,1);
+		}
+
+		print "\n<!-- ".$classname." info -->";
+		print "\n";
+		print '<input type="hidden" name="amount"         value="'.$objectsrc->total_ht.'">'."\n";
+		print '<input type="hidden" name="total"          value="'.$objectsrc->total_ttc.'">'."\n";
+		print '<input type="hidden" name="tva"            value="'.$objectsrc->total_tva.'">'."\n";
+		print '<input type="hidden" name="origin"         value="'.$objectsrc->element.'">';
+		print '<input type="hidden" name="originid"       value="'.$objectsrc->id.'">';
+
+		$newclassname=$classname;
+		if ($newclassname == 'Propal') $newclassname = 'CommercialProposal';
+		elseif ($newclassname == 'Commande') $newclassname = 'Order';
+
+		print '<tr><td>'.$langs->trans($newclassname).'</td><td colspan="2">'.$objectsrc->getNomUrl(1).'</td></tr>';
+		print '<tr><td>'.$langs->trans('TotalHT').'</td><td colspan="2">'.price($objectsrc->total_ht).'</td></tr>';
+		print '<tr><td>'.$langs->trans('TotalVAT').'</td><td colspan="2">'.price($objectsrc->total_tva)."</td></tr>";
+		if ($mysoc->localtax1_assuj=="1") //Localtax1 RE
+		{
+			print '<tr><td>'.$langs->transcountry("AmountLT1",$mysoc->country_code).'</td><td colspan="2">'.price($objectsrc->total_localtax1)."</td></tr>";
+		}
+
+		if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF
+		{
+			print '<tr><td>'.$langs->transcountry("AmountLT2",$mysoc->country_code).'</td><td colspan="2">'.price($objectsrc->total_localtax2)."</td></tr>";
+		}
+		print '<tr><td>'.$langs->trans('TotalTTC').'</td><td colspan="2">'.price($objectsrc->total_ttc)."</td></tr>";
+	}
+	else
+	{
+		// Show deprecated optional form to add product line here
+		if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE))
+		{
+			print '<tr><td colspan="3">';
+
+			// Zone de choix des produits predefinis a la creation
+			print '<table class="noborder" width="100%">';
+			print '<tr>';
+			print '<td>'.$langs->trans('ProductsAndServices').'</td>';
+			print '<td>'.$langs->trans('Qty').'</td>';
+			print '<td>'.$langs->trans('ReductionShort').'</td>';
+			print '<td> &nbsp; &nbsp; </td>';
+			if (! empty($conf->service->enabled))
+			{
+				print '<td>'.$langs->trans('ServiceLimitedDuration').'</td>';
+			}
+			print '</tr>';
+			for ($i = 1 ; $i <= $NBLINES ; $i++)
+			{
+				print '<tr>';
+				print '<td>';
+				// multiprix
+				if (! empty($conf->global->PRODUIT_MULTIPRICES))
+					$form->select_produits('','idprod'.$i,'',$conf->product->limit_size,$soc->price_level);
+				else
+					$form->select_produits('','idprod'.$i,'',$conf->product->limit_size);
+				print '</td>';
+				print '<td><input type="text" size="2" name="qty'.$i.'" value="1"></td>';
+				print '<td nowrap="nowrap"><input type="text" size="1" name="remise_percent'.$i.'" value="'.$soc->remise_client.'">%</td>';
+				print '<td>&nbsp;</td>';
+				// Si le module service est actif, on propose des dates de debut et fin a la ligne
+				if (! empty($conf->service->enabled))
+				{
+					print '<td nowrap="nowrap">';
+					print '<table class="nobordernopadding"><tr class="nocellnopadd">';
+					print '<td class="nobordernopadding" nowrap="nowrap">';
+					print $langs->trans('From').' ';
+					print '</td><td class="nobordernopadding" nowrap="nowrap">';
+					print $form->select_date('','date_start'.$i,$usehm,$usehm,1,"add");
+					print '</td></tr>';
+					print '<td class="nobordernopadding" nowrap="nowrap">';
+					print $langs->trans('to').' ';
+					print '</td><td class="nobordernopadding" nowrap="nowrap">';
+					print $form->select_date('','date_end'.$i,$usehm,$usehm,1,"add");
+					print '</td></tr></table>';
+					print '</td>';
+				}
+				print "</tr>\n";
+			}
+
+			print '</table>';
+			print '</td></tr>';
+		}
+	}
+
+	print "</table>\n";
+
+	// Button "Create Draft"
+	print '<br><center><input type="submit" class="button" name="bouton" value="'.$langs->trans('CreateDraft').'"></center>';
+
+	print "</form>\n";
+
+	// Show origin lines
+	if (! empty($origin) && ! empty($originid) && is_object($objectsrc))
+	{
+		print '<br>';
+
+		$title=$langs->trans('ProductsAndServices');
+		print_titre($title);
+
+		print '<table class="noborder" width="100%">';
+
+		$objectsrc->printOriginLinesList();
+
+		print '</table>';
+	}
 
 }
 else if ($id > 0 || ! empty($ref))
 {
-    /*
-     * Show object in view mode
-     */
-
-    $result=$object->fetch($id,$ref);
-
-    // fetch optionals attributes and labels
- 	$extralabels=$extrafields->fetch_name_optionals_label('facture');
-
-    if ($result > 0)
-    {
-        if ($user->societe_id>0 && $user->societe_id!=$object->socid)  accessforbidden('',0);
-
-        $result=$object->fetch_thirdparty();
-
-        $soc = new Societe($db);
-        $soc->fetch($object->socid);
-        $selleruserevenustamp=$mysoc->useRevenueStamp();
-
-        $totalpaye  = $object->getSommePaiement();
-        $totalcreditnotes = $object->getSumCreditNotesUsed();
-        $totaldeposits = $object->getSumDepositsUsed();
-        //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." selleruserrevenuestamp=".$selleruserevenustamp;
-
-        // We can also use bcadd to avoid pb with floating points
-        // For example print 239.2 - 229.3 - 9.9; does not return 0.
-        //$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT);
-        //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
-        $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT');
-
-        if ($object->paye) $resteapayer=0;
-        $resteapayeraffiche=$resteapayer;
-
-        if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
-        {
-            $filterabsolutediscount="fk_facture_source IS NULL";  // If we want deposit to be substracted to payments only and not to total of final invoice
-            $filtercreditnote="fk_facture_source IS NOT NULL";    // If we want deposit to be substracted to payments only and not to total of final invoice
-        }
-        else
-        {
-            $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')";
-            $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'";
-        }
-
-        $absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount);
-        $absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote);
-        $absolute_discount=price2num($absolute_discount,'MT');
-        $absolute_creditnote=price2num($absolute_creditnote,'MT');
-
-        $author = new User($db);
-        if ($object->user_author)
-        {
-            $author->fetch($object->user_author);
-        }
-
-        $objectidnext=$object->getIdReplacingInvoice();
-
-
-        $head = facture_prepare_head($object);
-
-        dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill');
-
-        $formconfirm='';
-
-        // Confirmation de la conversion de l'avoir en reduc
-        if ($action == 'converttoreduc')
-        {
-            $text=$langs->trans('ConfirmConvertToReduc');
-            $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('ConvertToReduc'),$text,'confirm_converttoreduc','',"yes",2);
-        }
-
-        // Confirmation to delete invoice
-        if ($action == 'delete')
-        {
-            $text=$langs->trans('ConfirmDeleteBill');
-            $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','',0,1);
-        }
-
-        // Confirmation de la validation
-        if ($action == 'valid')
-        {
-            // on verifie si l'objet est en numerotation provisoire
-            $objectref = substr($object->ref, 1, 4);
-            if ($objectref == 'PROV')
-            {
-                $savdate=$object->date;
-                if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION))
-                {
-                    $object->date=dol_now();
-                    $object->date_lim_reglement=$object->calculate_date_lim_reglement();
-                }
-                $numref = $object->getNextNumRef($soc);
-                //$object->date=$savdate;
-            }
-            else
-            {
-                $numref = $object->ref;
-            }
-
-            $text=$langs->trans('ConfirmValidateBill',$numref);
-            if (! empty($conf->notification->enabled))
-            {
-                require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
-                $notify=new Notify($db);
-                $text.='<br>';
-                $text.=$notify->confirmMessage('NOTIFY_VAL_FAC',$object->socid);
-            }
-            $formquestion=array();
-
-            if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1))
-            {
-                $langs->load("stocks");
-                require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
-                $formproduct=new FormProduct($db);
-                $label=$object->type==2?$langs->trans("SelectWarehouseForStockIncrease"):$langs->trans("SelectWarehouseForStockDecrease");
-                $formquestion=array(
-                //'text' => $langs->trans("ConfirmClone"),
-                //array('type' => 'checkbox', 'name' => 'clone_content',   'label' => $langs->trans("CloneMainAttributes"),   'value' => 1),
-                //array('type' => 'checkbox', 'name' => 'update_prices',   'label' => $langs->trans("PuttingPricesUpToDate"),   'value' => 1),
-                array('type' => 'other', 'name' => 'idwarehouse',   'label' => $label,   'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1)));
-            }
-            if ($object->type != 2 && $object->total_ttc < 0)    // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on
-            {
-                 $text.='<br>'.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive");
-            }
-            $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ValidateBill'),$text,'confirm_valid',$formquestion,(($object->type != 2 && $object->total_ttc < 0)?"no":"yes"),($conf->notification->enabled?0:2));
-        }
-
-        // Confirm back to draft status
-        if ($action == 'modif')
-        {
-            $text=$langs->trans('ConfirmUnvalidateBill',$object->ref);
-            $formquestion=array();
-            if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1))
-            {
-                $langs->load("stocks");
-                require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
-                $formproduct=new FormProduct($db);
-                $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease");
-                $formquestion=array(
-                //'text' => $langs->trans("ConfirmClone"),
-                //array('type' => 'checkbox', 'name' => 'clone_content',   'label' => $langs->trans("CloneMainAttributes"),   'value' => 1),
-                //array('type' => 'checkbox', 'name' => 'update_prices',   'label' => $langs->trans("PuttingPricesUpToDate"),   'value' => 1),
-                array('type' => 'other', 'name' => 'idwarehouse',   'label' => $label,   'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1)));
-            }
-
-            $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('UnvalidateBill'),$text,'confirm_modif',$formquestion,"yes",1);
-        }
-
-        // Confirmation du classement paye
-        if ($action == 'paid' && $resteapayer <= 0)
-        {
-            $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidBill',$object->ref),'confirm_paid','',"yes",1);
-        }
-        if ($action == 'paid' && $resteapayer > 0)
-        {
-            // Code
-            $i=0;
-            $close[$i]['code']='discount_vat';$i++;
-            $close[$i]['code']='badcustomer';$i++;
-            // Help
-            $i=0;
-            $close[$i]['label']=$langs->trans("HelpEscompte").'<br><br>'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");$i++;
-            $close[$i]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");$i++;
-            // Texte
-            $i=0;
-            $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++;
-            $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++;
-            // arrayreasons[code]=reason
-            foreach($close as $key => $val)
-            {
-                $arrayreasons[$close[$key]['code']]=$close[$key]['reason'];
-            }
-
-            // Cree un tableau formulaire
-            $formquestion=array(
-			'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"),
-            array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"),  'values' => $arrayreasons),
-            array('type' => 'text',  'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100')
-            );
-            // Paiement incomplet. On demande si motif = escompte ou autre
-            $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidPartially',$object->ref),'confirm_paid_partially',$formquestion,"yes");
-        }
-
-        // Confirmation du classement abandonne
-        if ($action == 'canceled')
-        {
-            // S'il y a une facture de remplacement pas encore validee (etat brouillon),
-            // on ne permet pas de classer abandonner la facture.
-            if ($objectidnext)
-            {
-                $facturereplacement=new Facture($db);
-                $facturereplacement->fetch($objectidnext);
-                $statusreplacement=$facturereplacement->statut;
-            }
-            if ($objectidnext && $statusreplacement == 0)
-            {
-                print '<div class="error">'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'</div>';
-            }
-            else
-            {
-                // Code
-                $close[1]['code']='badcustomer';
-                $close[2]['code']='abandon';
-                // Help
-                $close[1]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");
-                $close[2]['label']=$langs->trans("ConfirmClassifyAbandonReasonOtherDesc");
-                // Texte
-                $close[1]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$object->ref),$close[1]['label'],1);
-                $close[2]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"),$close[2]['label'],1);
-                // arrayreasons
-                $arrayreasons[$close[1]['code']]=$close[1]['reason'];
-                $arrayreasons[$close[2]['code']]=$close[2]['reason'];
-
-                // Cree un tableau formulaire
-                $formquestion=array(
-				'text' => $langs->trans("ConfirmCancelBillQuestion"),
-                array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"),  'values' => $arrayreasons),
-                array('type' => 'text',  'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100')
-                );
-
-                $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$object->ref),'confirm_canceled',$formquestion,"yes");
-            }
-        }
-
-        // Confirmation de la suppression d'une ligne produit
-        if ($action == 'ask_deleteline')
-        {
-            $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
-        }
-
-        // Clone confirmation
-        if ($action == 'clone')
-        {
-            // Create an array for form
-            $formquestion=array(
-            //'text' => $langs->trans("ConfirmClone"),
-            //array('type' => 'checkbox', 'name' => 'clone_content',   'label' => $langs->trans("CloneMainAttributes"),   'value' => 1)
-            );
-            // Paiement incomplet. On demande si motif = escompte ou autre
-            $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('CloneInvoice'),$langs->trans('ConfirmCloneInvoice',$object->ref),'confirm_clone',$formquestion,'yes',1);
-        }
-
-        if (! $formconfirm)
-        {
-            $parameters=array('lineid'=>$lineid);
-            $formconfirm=$hookmanager->executeHooks('formConfirm',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
-        }
-
-        // Print form confirm
-        print $formconfirm;
-
-
-        // Invoice content
-
-        print '<table class="border" width="100%">';
-
-        $linkback = '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
-
-        // Ref
-        print '<tr><td width="20%">'.$langs->trans('Ref').'</td>';
-        print '<td colspan="5">';
-        $morehtmlref='';
-        $discount=new DiscountAbsolute($db);
-        $result=$discount->fetch(0,$object->id);
-        if ($result > 0)
-        {
-            $morehtmlref=' ('.$langs->trans("CreditNoteConvertedIntoDiscount",$discount->getNomUrl(1,'discount')).')';
-        }
-        if ($result < 0)
-        {
-            dol_print_error('',$discount->error);
-        }
-        print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref);
-        print '</td></tr>';
+	/*
+	 * Show object in view mode
+	*/
 
-		// Ref customer
-        print '<tr><td width="20%">';
-        print '<table class="nobordernopadding" width="100%"><tr><td>';
-        print $langs->trans('RefCustomer');
-        print '</td>';
-        if ($action != 'refclient' && ! empty($object->brouillon)) print '<td align="right"><a href="'.$_SERVER['PHP_SELF'].'?action=refclient&amp;id='.$object->id.'">'.img_edit($langs->trans('Modify')).'</a></td>';
-        print '</tr></table>';
-        print '</td>';
-        print '<td colspan="5">';
-       	if ($user->rights->facture->creer && $action == 'refclient')
+	$result=$object->fetch($id,$ref);
+
+	// fetch optionals attributes and labels
+	$extralabels=$extrafields->fetch_name_optionals_label('facture');
+
+	if ($result > 0)
+	{
+		if ($user->societe_id>0 && $user->societe_id!=$object->socid)  accessforbidden('',0);
+
+		$result=$object->fetch_thirdparty();
+
+		$soc = new Societe($db);
+		$soc->fetch($object->socid);
+		$selleruserevenustamp=$mysoc->useRevenueStamp();
+
+		$totalpaye  = $object->getSommePaiement();
+		$totalcreditnotes = $object->getSumCreditNotesUsed();
+		$totaldeposits = $object->getSumDepositsUsed();
+		//print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." selleruserrevenuestamp=".$selleruserevenustamp;
+
+		// We can also use bcadd to avoid pb with floating points
+		// For example print 239.2 - 229.3 - 9.9; does not return 0.
+		//$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT);
+		//$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
+		$resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT');
+
+		if ($object->paye) $resteapayer=0;
+		$resteapayeraffiche=$resteapayer;
+
+		if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
 		{
-			print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
-			print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-			print '<input type="hidden" name="action" value="set_ref_client">';
-			print '<input type="text" class="flat" size="20" name="ref_client" value="'.$object->ref_client.'">';
-			print ' <input type="submit" class="button" value="'.$langs->trans('Modify').'">';
-			print '</form>';
+			$filterabsolutediscount="fk_facture_source IS NULL";  // If we want deposit to be substracted to payments only and not to total of final invoice
+			$filtercreditnote="fk_facture_source IS NOT NULL";    // If we want deposit to be substracted to payments only and not to total of final invoice
 		}
 		else
 		{
-			print $object->ref_client;
+			$filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')";
+			$filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'";
 		}
-		print '</td></tr>';
 
-        // Third party
-        print '<tr><td>';
-        print '<table class="nobordernopadding" width="100%">';
-        print '<tr><td>'.$langs->trans('Company').'</td>';
-        print '</td><td colspan="5">';
-        if (! empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer)
-        print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editthirdparty&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'</a></td>';
-        print '</tr></table>';
-        print '</td><td colspan="5">';
-        if ($action == 'editthirdparty')
-        {
-            $form->form_thirdparty($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,'socid');
-        }
-        else
-        {
-            print ' &nbsp;'.$soc->getNomUrl(1,'compta');
-            print ' &nbsp; (<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->socid.'">'.$langs->trans('OtherBills').'</a>)';
-        }
-        print '</tr>';
-
-        // Type
-        print '<tr><td>'.$langs->trans('Type').'</td><td colspan="5">';
-        print $object->getLibType();
-        if ($object->type == 1)
-        {
-            $facreplaced=new Facture($db);
-            $facreplaced->fetch($object->fk_facture_source);
-            print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')';
-        }
-        if ($object->type == 2)
-        {
-            $facusing=new Facture($db);
-            $facusing->fetch($object->fk_facture_source);
-            print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')';
-        }
-
-        $facidavoir=$object->getListIdAvoirFromInvoice();
-        if (count($facidavoir) > 0)
-        {
-            print ' ('.$langs->transnoentities("InvoiceHasAvoir");
-            $i=0;
-            foreach($facidavoir as $id)
-            {
-                if ($i==0) print ' ';
-                else print ',';
-                $facavoir=new Facture($db);
-                $facavoir->fetch($id);
-                print $facavoir->getNomUrl(1);
-            }
-            print ')';
-        }
-        if ($objectidnext > 0)
-        {
-            $facthatreplace=new Facture($db);
-            $facthatreplace->fetch($objectidnext);
-            print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')';
-        }
-        print '</td></tr>';
-
-        // Relative and absolute discounts
-        $addrelativediscount='<a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("EditRelativeDiscounts").'</a>';
-        $addabsolutediscount='<a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("EditGlobalDiscounts").'</a>';
-        $addcreditnote='<a href="'.DOL_URL_ROOT.'/compta/facture.php?action=create&socid='.$soc->id.'&type=2&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("AddCreditNote").'</a>';
-
-        print '<tr><td>'.$langs->trans('Discounts');
-        print '</td><td colspan="5">';
-        if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client);
-        else print $langs->trans("CompanyHasNoRelativeDiscount");
-        //print ' ('.$addrelativediscount.')';
-
-        if ($absolute_discount > 0)
-        {
-            print '. ';
-            if ($object->statut > 0 || $object->type == 2 || $object->type == 3)
-            {
-                if ($object->statut == 0)
-                {
-                    print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
-                    print '. ';
-                }
-                else
-                {
-                    if ($object->statut < 1 || $object->type == 2 || $object->type == 3)
-                    {
-                        $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
-                        print '<br>'.$text.'.<br>';
-                    }
-                    else
-                    {
-                        $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
-                        $text2=$langs->trans("AbsoluteDiscountUse");
-                        print $form->textwithpicto($text,$text2);
-                    }
-                }
-            }
-            else
-            {
-                // Remise dispo de type remise fixe (not credit note)
-                print '<br>';
-                $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' ('.$addabsolutediscount.')');
-            }
-        }
-        else
-        {
-            if ($absolute_creditnote > 0)    // If not, link will be added later
-            {
-                if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')<br>';
-                else print '. ';
-            }
-            else print '. ';
-        }
-        if ($absolute_creditnote > 0)
-        {
-            // If validated, we show link "add credit note to payment"
-            if ($object->statut != 1 || $object->type == 2 || $object->type == 3)
-            {
-                if ($object->statut == 0 && $object->type != 3)
-                {
-                    $text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency));
-                    print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse"));
-                }
-                else
-                {
-                    print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.';
-                }
-            }
-            else
-            {
-                // Remise dispo de type avoir
-                if (! $absolute_discount) print '<br>';
-                //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer);
-                $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0);    // We must allow credit not even if amount is higher
-            }
-        }
-        if (! $absolute_discount && ! $absolute_creditnote)
-        {
-            print $langs->trans("CompanyHasNoAbsoluteDiscount");
-            if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')<br>';
-            else print '. ';
-        }
-        /*if ($object->statut == 0 && $object->type != 2 && $object->type != 3)
-         {
-         if (! $absolute_discount && ! $absolute_creditnote) print '<br>';
-         //print ' &nbsp; - &nbsp; ';
-         print $addabsolutediscount;
-         //print ' &nbsp; - &nbsp; '.$addcreditnote;      // We disbale link to credit note
-         }*/
-        print '</td></tr>';
-
-        // Date invoice
-        print '<tr><td>';
-        print '<table class="nobordernopadding" width="100%"><tr><td>';
-        print $langs->trans('Date');
-        print '</td>';
-        if ($object->type != 2 && $action != 'editinvoicedate' && ! empty($object->brouillon) && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editinvoicedate&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetDate'),1).'</a></td>';
-        print '</tr></table>';
-        print '</td><td colspan="3">';
-
-        if ($object->type != 2)
-        {
-            if ($action == 'editinvoicedate')
-            {
-                $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date,'invoicedate');
-            }
-            else
-            {
-                print dol_print_date($object->date,'daytext');
-            }
-        }
-        else
-        {
-            print dol_print_date($object->date,'daytext');
-        }
-        print '</td>';
-
-
-        /*
-         * List of payments
-         */
-
-        $sign=1;
-        if ($object->type == 2) $sign=-1;
-
-        $nbrows=8; $nbcols=2;
-        if (! empty($conf->projet->enabled)) $nbrows++;
-        if (! empty($conf->banque->enabled)) $nbcols++;
-        if($mysoc->localtax1_assuj=="1") $nbrows++;
-        if($mysoc->localtax2_assuj=="1") $nbrows++;
-        if ($selleruserevenustamp) $nbrows++;
-
-        print '<td rowspan="'.$nbrows.'" colspan="2" valign="top">';
-
-        print '<table class="nobordernopadding" width="100%">';
-
-        // List of payments already done
-        print '<tr class="liste_titre">';
-        print '<td>'.($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).'</td>';
-        print '<td>'.$langs->trans('Type').'</td>';
-        if (! empty($conf->banque->enabled)) print '<td align="right">'.$langs->trans('BankAccount').'</td>';
-        print '<td align="right">'.$langs->trans('Amount').'</td>';
-        print '<td width="18">&nbsp;</td>';
-        print '</tr>';
-
-        $var=true;
-
-        // Payments already done (from payment on this invoice)
-        $sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,';
-        $sql.= ' c.code as payment_code, c.libelle as payment_label,';
-        $sql.= ' pf.amount,';
-        $sql.= ' ba.rowid as baid, ba.ref, ba.label';
-        $sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p';
-        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
-        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
-        $sql.= ' WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid';
-        $sql.= ' ORDER BY p.datep, p.tms';
-
-        $result = $db->query($sql);
-        if ($result)
-        {
-            $num = $db->num_rows($result);
-            $i = 0;
+		$absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount);
+		$absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote);
+		$absolute_discount=price2num($absolute_discount,'MT');
+		$absolute_creditnote=price2num($absolute_creditnote,'MT');
 
-			//if ($object->type != 2)
-            //{
-                if ($num > 0)
-                {
-                    while ($i < $num)
-                    {
-                        $objp = $db->fetch_object($result);
-                        $var=!$var;
-                        print '<tr '.$bc[$var].'><td>';
-                        print '<a href="'.DOL_URL_ROOT.'/compta/paiement/fiche.php?id='.$objp->rowid.'">'.img_object($langs->trans('ShowPayment'),'payment').' ';
-                        print dol_print_date($db->jdate($objp->dp),'day').'</a></td>';
-                        $label=($langs->trans("PaymentType".$objp->payment_code)!=("PaymentType".$objp->payment_code))?$langs->trans("PaymentType".$objp->payment_code):$objp->payment_label;
-                        print '<td>'.$label.' '.$objp->num_paiement.'</td>';
-                        if (! empty($conf->banque->enabled))
-                        {
-                            $bankaccountstatic->id=$objp->baid;
-                            $bankaccountstatic->ref=$objp->ref;
-                            $bankaccountstatic->label=$objp->ref;
-                            print '<td align="right">';
-                            if ($bankaccountstatic->id) print $bankaccountstatic->getNomUrl(1,'transactions');
-                            print '</td>';
-                        }
-                        print '<td align="right">'.price($sign * $objp->amount).'</td>';
-                        print '<td>&nbsp;</td>';
-                        print '</tr>';
-                        $i++;
-                    }
-                }
-                else
-                {
-                    print '<tr '.$bc[$var].'><td colspan="'.$nbcols.'">'.$langs->trans("None").'</td><td></td><td></td></tr>';
-                }
-            //}
-            $db->free($result);
-        }
-        else
-        {
-            dol_print_error($db);
-        }
-
-        if ($object->type != 2)
-        {
-            // Total already paid
-            print '<tr><td colspan="'.$nbcols.'" align="right">';
-            if ($object->type != 3) print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits');
-            else print $langs->trans('AlreadyPaid');
-            print ' :</td><td align="right">'.price($totalpaye).'</td><td>&nbsp;</td></tr>';
-
-            $resteapayeraffiche=$resteapayer;
-
-            // Loop on each credit note or deposit amount applied
-            $creditnoteamount=0;
-            $depositamount=0;
-            $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
-            $sql.= " re.description, re.fk_facture_source";
-            $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re";
-            $sql.= " WHERE fk_facture = ".$object->id;
-            $resql=$db->query($sql);
-            if ($resql)
-            {
-                $num = $db->num_rows($resql);
-                $i = 0;
-                $invoice=new Facture($db);
-                while ($i < $num)
-                {
-                    $obj = $db->fetch_object($resql);
-                    $invoice->fetch($obj->fk_facture_source);
-                    print '<tr><td colspan="'.$nbcols.'" align="right">';
-                    if ($invoice->type == 2) print $langs->trans("CreditNote").' ';
-                    if ($invoice->type == 3) print $langs->trans("Deposit").' ';
-                    print $invoice->getNomUrl(0);
-                    print ' :</td>';
-                    print '<td align="right">'.price($obj->amount_ttc).'</td>';
-                    print '<td align="right">';
-                    print '<a href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=unlinkdiscount&discountid='.$obj->rowid.'">'.img_delete().'</a>';
-                    print '</td></tr>';
-                    $i++;
-                    if ($invoice->type == 2) $creditnoteamount += $obj->amount_ttc;
-                    if ($invoice->type == 3) $depositamount += $obj->amount_ttc;
-                }
-            }
-            else
-            {
-                dol_print_error($db);
-            }
-
-            // Paye partiellement 'escompte'
-            if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat')
-            {
-                print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
-                print $form->textwithpicto($langs->trans("Discount").':',$langs->trans("HelpEscompte"),-1);
-                print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
-                $resteapayeraffiche=0;
-            }
-            // Paye partiellement ou Abandon 'badcustomer'
-            if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer')
-            {
-                print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
-                print $form->textwithpicto($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1);
-                print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
-                //$resteapayeraffiche=0;
-            }
-            // Paye partiellement ou Abandon 'product_returned'
-            if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned')
-            {
-                print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
-                print $form->textwithpicto($langs->trans("ProductReturned").':',$langs->trans("HelpAbandonProductReturned"),-1);
-                print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
-                $resteapayeraffiche=0;
-            }
-            // Paye partiellement ou Abandon 'abandon'
-            if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon')
-            {
-                print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
-                $text=$langs->trans("HelpAbandonOther");
-                if ($object->close_note) $text.='<br><br><b>'.$langs->trans("Reason").'</b>:'.$object->close_note;
-                print $form->textwithpicto($langs->trans("Abandoned").':',$text,-1);
-                print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
-                $resteapayeraffiche=0;
-            }
-
-            // Billed
-            print '<tr><td colspan="'.$nbcols.'" align="right">'.$langs->trans("Billed").' :</td><td align="right" style="border: 1px solid;">'.price($object->total_ttc).'</td><td>&nbsp;</td></tr>';
-
-            // Remainder to pay
-            print '<tr><td colspan="'.$nbcols.'" align="right">';
-            if ($resteapayeraffiche >= 0) print $langs->trans('RemainderToPay');
-            else print $langs->trans('ExcessReceived');
-            print ' :</td>';
-            print '<td align="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($resteapayeraffiche).'</b></td>';
-            print '<td nowrap="nowrap">&nbsp;</td></tr>';
-        }
-        else	// Credit note
-        {
-        	// Total already paid back
-        	print '<tr><td colspan="'.$nbcols.'" align="right">';
-        	print $langs->trans('AlreadyPaidBack');
-        	print ' :</td><td align="right">'.price($sign * $totalpaye).'</td><td>&nbsp;</td></tr>';
-
-            // Billed
-            print '<tr><td colspan="'.$nbcols.'" align="right">'.$langs->trans("Billed").' :</td><td align="right" style="border: 1px solid;">'.price($sign * $object->total_ttc).'</td><td>&nbsp;</td></tr>';
-
-            // Remainder to pay back
-            print '<tr><td colspan="'.$nbcols.'" align="right">';
-            if ($resteapayeraffiche <= 0) print $langs->trans('RemainderToPayBack');
-            else print $langs->trans('ExcessPaydBack');
-            print ' :</td>';
-            print '<td align="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($sign * $resteapayeraffiche).'</b></td>';
-            print '<td nowrap="nowrap">&nbsp;</td></tr>';
-
-            // Sold credit note
-            //print '<tr><td colspan="'.$nbcols.'" align="right">'.$langs->trans('TotalTTC').' :</td>';
-            //print '<td align="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($sign * $object->total_ttc).'</b></td><td>&nbsp;</td></tr>';
-        }
-
-        print '</table>';
-
-		// Margin Infos
-		if (! empty($conf->margin->enabled))
-		{
-			  print '<br>';
-			  $object->displayMarginInfos($object->statut > 0);
-		}
-
-        print '</td></tr>';
-
-        // Conditions de reglement
-        print '<tr><td>';
-        print '<table class="nobordernopadding" width="100%"><tr><td>';
-        print $langs->trans('PaymentConditionsShort');
-        print '</td>';
-        if ($object->type != 2 && $action != 'editconditions' && ! empty($object->brouillon) && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editconditions&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetConditions'),1).'</a></td>';
-        print '</tr></table>';
-        print '</td><td colspan="3">';
-        if ($object->type != 2)
-        {
-            if ($action == 'editconditions')
-            {
-                $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'cond_reglement_id');
-            }
-            else
-            {
-                $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'none');
-            }
-        }
-        else
-        {
-            print '&nbsp;';
-        }
-        print '</td></tr>';
-
-        // Date payment term
-        print '<tr><td>';
-        print '<table class="nobordernopadding" width="100%"><tr><td>';
-        print $langs->trans('DateMaxPayment');
-        print '</td>';
-        if ($object->type != 2 && $action != 'editpaymentterm' && ! empty($object->brouillon) && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editpaymentterm&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetDate'),1).'</a></td>';
-        print '</tr></table>';
-        print '</td><td colspan="3">';
-        if ($object->type != 2)
-        {
-            if ($action == 'editpaymentterm')
-            {
-                $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date_lim_reglement,'paymentterm');
-            }
-            else
-            {
-                print dol_print_date($object->date_lim_reglement,'daytext');
-                if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && ! $object->paye && $object->statut == 1 && ! isset($object->am)) print img_warning($langs->trans('Late'));
-            }
-        }
-        else
-        {
-            print '&nbsp;';
-        }
-        print '</td></tr>';
-
-        // Payment mode
-        print '<tr><td>';
-        print '<table class="nobordernopadding" width="100%"><tr><td>';
-        print $langs->trans('PaymentMode');
-        print '</td>';
-        if ($action != 'editmode' && ! empty($object->brouillon) && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editmode&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetMode'),1).'</a></td>';
-        print '</tr></table>';
-        print '</td><td colspan="3">';
-        if ($action == 'editmode')
-        {
-            $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'mode_reglement_id');
-        }
-        else
-        {
-            $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'none');
-        }
-        print '</td></tr>';
-
-        // Amount
-        print '<tr><td>'.$langs->trans('AmountHT').'</td>';
-        print '<td align="right" colspan="3" nowrap>'.price($object->total_ht,1,'',1,-1,-1,$conf->currency).'</td></tr>';
-        print '<tr><td>'.$langs->trans('AmountVAT').'</td><td align="right" colspan="3" nowrap>'.price($object->total_tva,1,'',1,-1,-1,$conf->currency).'</td></tr>';
+		$author = new User($db);
+		if ($object->user_author)
+		{
+			$author->fetch($object->user_author);
+		}
+
+		$objectidnext=$object->getIdReplacingInvoice();
+
+
+		$head = facture_prepare_head($object);
+
+		dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill');
+
+		$formconfirm='';
+
+		// Confirmation de la conversion de l'avoir en reduc
+		if ($action == 'converttoreduc')
+		{
+			$text=$langs->trans('ConfirmConvertToReduc');
+			$formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('ConvertToReduc'),$text,'confirm_converttoreduc','',"yes",2);
+		}
+
+		// Confirmation to delete invoice
+		if ($action == 'delete')
+		{
+			$text=$langs->trans('ConfirmDeleteBill',$object->ref);
+			$formquestion=array();
+
+			$qualified_for_stock_change=0;
+			if (empty($conf->global->STOCK_SUPPORTS_SERVICES))
+			{
+				$qualified_for_stock_change=$object->hasProductsOrServices(2);
+			}
+			else
+			{
+				$qualified_for_stock_change=$object->hasProductsOrServices(1);
+			}
+
+			if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change && $object->statut>=1)
+			{
+				$langs->load("stocks");
+				require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
+				$formproduct=new FormProduct($db);
+				$label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease");
+				$formquestion=array(
+				//'text' => $langs->trans("ConfirmClone"),
+				//array('type' => 'checkbox', 'name' => 'clone_content',   'label' => $langs->trans("CloneMainAttributes"),   'value' => 1),
+				//array('type' => 'checkbox', 'name' => 'update_prices',   'label' => $langs->trans("PuttingPricesUpToDate"),   'value' => 1),
+				array('type' => 'other', 'name' => 'idwarehouse',   'label' => $label,   'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1,0,0,$langs->trans("NoStockAction"))));
+				$formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete',$formquestion,"yes",1);
+			}else {
+				$formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','','',1);
+			}
+		}
+
+		// Confirmation de la validation
+		if ($action == 'valid')
+		{
+			// on verifie si l'objet est en numerotation provisoire
+			$objectref = substr($object->ref, 1, 4);
+			if ($objectref == 'PROV')
+			{
+				$savdate=$object->date;
+				if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION))
+				{
+					$object->date=dol_now();
+					$object->date_lim_reglement=$object->calculate_date_lim_reglement();
+				}
+				$numref = $object->getNextNumRef($soc);
+				//$object->date=$savdate;
+			}
+			else
+			{
+				$numref = $object->ref;
+			}
+
+			$text=$langs->trans('ConfirmValidateBill',$numref);
+			if (! empty($conf->notification->enabled))
+			{
+				require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
+				$notify=new Notify($db);
+				$text.='<br>';
+				$text.=$notify->confirmMessage('BILL_VALIDATE',$object->socid);
+			}
+			$formquestion=array();
+
+			$qualified_for_stock_change=0;
+			if (empty($conf->global->STOCK_SUPPORTS_SERVICES))
+			{
+				$qualified_for_stock_change=$object->hasProductsOrServices(2);
+			}
+			else
+			{
+				$qualified_for_stock_change=$object->hasProductsOrServices(1);
+			}
+
+			if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change)
+			{
+				$langs->load("stocks");
+				require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
+				$formproduct=new FormProduct($db);
+				$label=$object->type==2?$langs->trans("SelectWarehouseForStockIncrease"):$langs->trans("SelectWarehouseForStockDecrease");
+				$formquestion=array(
+				//'text' => $langs->trans("ConfirmClone"),
+				//array('type' => 'checkbox', 'name' => 'clone_content',   'label' => $langs->trans("CloneMainAttributes"),   'value' => 1),
+				//array('type' => 'checkbox', 'name' => 'update_prices',   'label' => $langs->trans("PuttingPricesUpToDate"),   'value' => 1),
+				array('type' => 'other', 'name' => 'idwarehouse',   'label' => $label,   'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1)));
+			}
+			if ($object->type != 2 && $object->total_ttc < 0)    // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on
+			{
+				$text.='<br>'.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive");
+			}
+			$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ValidateBill'),$text,'confirm_valid',$formquestion,(($object->type != 2 && $object->total_ttc < 0)?"no":"yes"),($conf->notification->enabled?0:2));
+		}
+
+		// Confirm back to draft status
+		if ($action == 'modif')
+		{
+			$text=$langs->trans('ConfirmUnvalidateBill',$object->ref);
+			$formquestion=array();
+
+			$qualified_for_stock_change=0;
+			if (empty($conf->global->STOCK_SUPPORTS_SERVICES))
+			{
+				$qualified_for_stock_change=$object->hasProductsOrServices(2);
+			}
+			else
+			{
+				$qualified_for_stock_change=$object->hasProductsOrServices(1);
+			}
+			if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change)
+			{
+				$langs->load("stocks");
+				require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
+				$formproduct=new FormProduct($db);
+				$label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease");
+				$formquestion=array(
+				//'text' => $langs->trans("ConfirmClone"),
+				//array('type' => 'checkbox', 'name' => 'clone_content',   'label' => $langs->trans("CloneMainAttributes"),   'value' => 1),
+				//array('type' => 'checkbox', 'name' => 'update_prices',   'label' => $langs->trans("PuttingPricesUpToDate"),   'value' => 1),
+				array('type' => 'other', 'name' => 'idwarehouse',   'label' => $label,   'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1)));
+			}
+
+			$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('UnvalidateBill'),$text,'confirm_modif',$formquestion,"yes",1);
+		}
+
+		// Confirmation du classement paye
+		if ($action == 'paid' && $resteapayer <= 0)
+		{
+			$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidBill',$object->ref),'confirm_paid','',"yes",1);
+		}
+		if ($action == 'paid' && $resteapayer > 0)
+		{
+			// Code
+			$i=0;
+			$close[$i]['code']='discount_vat';$i++;
+			$close[$i]['code']='badcustomer';$i++;
+			// Help
+			$i=0;
+			$close[$i]['label']=$langs->trans("HelpEscompte").'<br><br>'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");$i++;
+			$close[$i]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");$i++;
+			// Texte
+			$i=0;
+			$close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++;
+			$close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++;
+			// arrayreasons[code]=reason
+			foreach($close as $key => $val)
+			{
+				$arrayreasons[$close[$key]['code']]=$close[$key]['reason'];
+			}
+
+			// Cree un tableau formulaire
+			$formquestion=array(
+			'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"),
+			array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"),  'values' => $arrayreasons),
+			array('type' => 'text',  'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100')
+			);
+			// Paiement incomplet. On demande si motif = escompte ou autre
+			$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidPartially',$object->ref),'confirm_paid_partially',$formquestion,"yes");
+		}
+
+		// Confirmation du classement abandonne
+		if ($action == 'canceled')
+		{
+			// S'il y a une facture de remplacement pas encore validee (etat brouillon),
+			// on ne permet pas de classer abandonner la facture.
+			if ($objectidnext)
+			{
+				$facturereplacement=new Facture($db);
+				$facturereplacement->fetch($objectidnext);
+				$statusreplacement=$facturereplacement->statut;
+			}
+			if ($objectidnext && $statusreplacement == 0)
+			{
+				print '<div class="error">'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'</div>';
+			}
+			else
+			{
+				// Code
+				$close[1]['code']='badcustomer';
+				$close[2]['code']='abandon';
+				// Help
+				$close[1]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");
+				$close[2]['label']=$langs->trans("ConfirmClassifyAbandonReasonOtherDesc");
+				// Texte
+				$close[1]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$object->ref),$close[1]['label'],1);
+				$close[2]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"),$close[2]['label'],1);
+				// arrayreasons
+				$arrayreasons[$close[1]['code']]=$close[1]['reason'];
+				$arrayreasons[$close[2]['code']]=$close[2]['reason'];
+
+				// Cree un tableau formulaire
+				$formquestion=array(
+				'text' => $langs->trans("ConfirmCancelBillQuestion"),
+				array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"),  'values' => $arrayreasons),
+				array('type' => 'text',  'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100')
+				);
+
+				$formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$object->ref),'confirm_canceled',$formquestion,"yes");
+			}
+		}
+
+		// Confirmation de la suppression d'une ligne produit
+		if ($action == 'ask_deleteline')
+		{
+			$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
+		}
+
+		// Clone confirmation
+		if ($action == 'clone')
+		{
+			// Create an array for form
+			$formquestion=array(
+			//'text' => $langs->trans("ConfirmClone"),
+			//array('type' => 'checkbox', 'name' => 'clone_content',   'label' => $langs->trans("CloneMainAttributes"),   'value' => 1)
+			);
+			// Paiement incomplet. On demande si motif = escompte ou autre
+			$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('CloneInvoice'),$langs->trans('ConfirmCloneInvoice',$object->ref),'confirm_clone',$formquestion,'yes',1);
+		}
+
+		if (! $formconfirm)
+		{
+			$parameters=array('lineid'=>$lineid);
+			$formconfirm=$hookmanager->executeHooks('formConfirm',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
+		}
+
+		// Print form confirm
+		print $formconfirm;
+
+
+		// Invoice content
+
+		print '<table class="border" width="100%">';
+
+		$linkback = '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
+
+		// Ref
+		print '<tr><td width="20%">'.$langs->trans('Ref').'</td>';
+		print '<td colspan="5">';
+		$morehtmlref='';
+		$discount=new DiscountAbsolute($db);
+		$result=$discount->fetch(0,$object->id);
+		if ($result > 0)
+		{
+			$morehtmlref=' ('.$langs->trans("CreditNoteConvertedIntoDiscount",$discount->getNomUrl(1,'discount')).')';
+		}
+		if ($result < 0)
+		{
+			dol_print_error('',$discount->error);
+		}
+		print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref);
+		print '</td></tr>';
+
+		// Ref customer
+		print '<tr><td width="20%">';
+		print '<table class="nobordernopadding" width="100%"><tr><td>';
+		print $langs->trans('RefCustomer');
+		print '</td>';
+		if ($action != 'refclient' && ! empty($object->brouillon)) print '<td align="right"><a href="'.$_SERVER['PHP_SELF'].'?action=refclient&amp;id='.$object->id.'">'.img_edit($langs->trans('Modify')).'</a></td>';
+		print '</tr></table>';
+		print '</td>';
+		print '<td colspan="5">';
+		if ($user->rights->facture->creer && $action == 'refclient')
+		{
+			print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
+			print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+			print '<input type="hidden" name="action" value="set_ref_client">';
+			print '<input type="text" class="flat" size="20" name="ref_client" value="'.$object->ref_client.'">';
+			print ' <input type="submit" class="button" value="'.$langs->trans('Modify').'">';
+			print '</form>';
+		}
+		else
+		{
+			print $object->ref_client;
+		}
+		print '</td></tr>';
+
+		// Third party
+		print '<tr><td>';
+		print '<table class="nobordernopadding" width="100%">';
+		print '<tr><td>'.$langs->trans('Company').'</td>';
+		print '</td><td colspan="5">';
+		if (! empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer)
+			print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editthirdparty&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'</a></td>';
+		print '</tr></table>';
+		print '</td><td colspan="5">';
+		if ($action == 'editthirdparty')
+		{
+			$form->form_thirdparty($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,'socid');
+		}
+		else
+		{
+			print ' &nbsp;'.$soc->getNomUrl(1,'compta');
+			print ' &nbsp; (<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->socid.'">'.$langs->trans('OtherBills').'</a>)';
+		}
 		print '</tr>';
 
-        // Amount Local Taxes
-        if ($mysoc->localtax1_assuj=="1" && $mysoc->useLocalTax(1)) //Localtax1 (example RE)
-        {
-            print '<tr><td>'.$langs->transcountry("AmountLT1",$mysoc->country_code).'</td>';
-            print '<td align="right" colspan="3" nowrap>'.price($object->total_localtax1,1,'',1,-1,-1,$conf->currency).'</td></tr>';
-        }
-        if ($mysoc->localtax2_assuj=="1" && $mysoc->useLocalTax(2)) //Localtax2 (example IRPF)
-        {
-            print '<tr><td>'.$langs->transcountry("AmountLT2",$mysoc->country_code).'</td>';
-            print '<td align="right" colspan="3" nowrap>'.price($object->total_localtax2,1,'',1,-1,-1,$conf->currency).'</td></tr>';
-        }
-
-        // Revenue stamp
-        if ($selleruserevenustamp)		// Test company use revenue stamp
-        {
-	        print '<tr><td>';
-	        print '<table class="nobordernopadding" width="100%"><tr><td>';
-	        print $langs->trans('RevenueStamp');
-	        print '</td>';
-	        if ($action != 'editrevenuestamp' && ! empty($object->brouillon) && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editrevenuestamp&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetRevenuStamp'),1).'</a></td>';
-	        print '</tr></table>';
-	        print '</td><td colspan="3" align="right">';
-	        if ($action == 'editrevenuestamp')
-	        {
-				print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
-				print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-				print '<input type="hidden" name="action" value="setrevenuestamp">';
-				print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code);
-				//print '<input type="text" class="flat" size="4" name="revenuestamp" value="'.price2num($object->revenuestamp).'">';
-				print ' <input type="submit" class="button" value="'.$langs->trans('Modify').'">';
-				print '</form>';
-	        }
-	        else
-	        {
-	        	print price($object->revenuestamp,1,'',1,-1,-1,$conf->currency);
-	        }
-	        print '</td></tr>';
-        }
-
-        // Total with tax
-        print '<tr><td>'.$langs->trans('AmountTTC').'</td><td align="right" colspan="3" nowrap>'.price($object->total_ttc,1,'',1,-1,-1,$conf->currency).'</td></tr>';
-
-        // Statut
-        print '<tr><td>'.$langs->trans('Status').'</td>';
-        print '<td align="left" colspan="3">'.($object->getLibStatut(4,$totalpaye)).'</td></tr>';
-
-        // Project
-        if (! empty($conf->projet->enabled))
-        {
-            $langs->load('projects');
-            print '<tr>';
-            print '<td>';
-
-            print '<table class="nobordernopadding" width="100%"><tr><td>';
-            print $langs->trans('Project');
-            print '</td>';
-            if ($action != 'classify')
-            {
-                print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=classify&amp;facid='.$object->id.'">';
-                print img_edit($langs->trans('SetProject'),1);
-                print '</a></td>';
-            }
-            print '</tr></table>';
-
-            print '</td><td colspan="3">';
-            if ($action == 'classify')
-            {
-                $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'projectid');
-            }
-            else
-            {
-                $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'none');
-            }
-            print '</td>';
-            print '</tr>';
-        }
-
-        // Other attributes
-        $res=$object->fetch_optionals($object->id,$extralabels);
-        $parameters=array('colspan' => ' colspan="2"');
-        $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
-        if (empty($reshook) && ! empty($extrafields->attribute_label))
-        {
-
-        	if ($action == 'edit_extras')
-        	{
-        		print '<form enctype="multipart/form-data" action="'.$_SERVER["PHP_SELF"].'" method="post" name="formsoc">';
-        		print '<input type="hidden" name="action" value="update_extras">';
-        		print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-        		print '<input type="hidden" name="id" value="'.$object->id.'">';
-        	}
-
-        	foreach($extrafields->attribute_label as $key=>$label)
-        	{
-        		$value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]);
-        		if ($extrafields->attribute_type[$key] == 'separate')
-        		{
-        			print $extrafields->showSeparator($key);
-        		}
-        		else
-        		{
-	        		print '<tr><td';
-	        		if (! empty($extrafields->attribute_required[$key])) print ' class="fieldrequired"';
-	        		print '>'.$label.'</td><td colspan="5">';
-	        		// Convert date into timestamp format
-	        		if (in_array($extrafields->attribute_type[$key],array('date','datetime')))
-	        		{
-	        			$value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key];
-	        		}
-
-	        		if ($action == 'edit_extras' && $user->rights->facture->creer)
-	        		{
-	        			print $extrafields->showInputField($key,$value);
-	        		}
-	        		else
-	        		{
-	        			print $extrafields->showOutputField($key,$value);
-	        		}
-	        		print '</td></tr>'."\n";
-        		}
-        	}
-
-        	if(count($extrafields->attribute_label) > 0) {
-
-        		if ($action == 'edit_extras' && $user->rights->facture->creer)
-        		{
-        			print '<tr><td></td><td colspan="5">';
-        			print '<input type="submit" class="button" value="'.$langs->trans('Modify').'">';
-        			print '</form>';
-        			print '</td></tr>';
-
-        		}
-        		else {
-        			if ($object->statut == 0 && $user->rights->facture->creer)
-        			{
-        				print '<tr><td></td><td><a href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit_extras">'.img_picto('','edit').' '.$langs->trans('Modify').'</a></td></tr>';
-        			}
-        		}
-        	}
-        }
-
-        print '</table><br>';
-
-        if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB))
-        {
-        	$blocname = 'contacts';
-        	$title = $langs->trans('ContactsAddresses');
-        	include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
-        }
-
-        if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB))
-        {
-        	$blocname = 'notes';
-        	$title = $langs->trans('Notes');
-        	include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
-        }
-
-        /*
-         * Lines
-         */
-        $result = $object->getLinesArray();
-
-        if (! empty($conf->use_javascript_ajax) && $object->statut == 0)
-        {
-            include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
-        }
-
-        print '<table id="tablelines" class="noborder noshadow" width="100%">';
-
-        // Show object lines
-        if (! empty($object->lines))
-        	$ret=$object->printObjectLines($action,$mysoc,$soc,$lineid,1);
-
-        /*
-         * Form to add new line
-         */
-        if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline')
-        {
-            $var=true;
-
-            if ($conf->global->MAIN_FEATURES_LEVEL > 1)
-            {
-            	// Add free or predefined products/services
-            	$object->formAddObjectLine(1,$mysoc,$soc);
-            }
-            else
-            {
-            	// Add free products/services
-            	$object->formAddFreeProduct(1,$mysoc,$soc);
-
-            	// Add predefined products/services
-            	if (! empty($conf->product->enabled) || ! empty($conf->service->enabled))
-            	{
-            		$var=!$var;
-            		$object->formAddPredefinedProduct(1,$mysoc,$soc);
-            	}
-            }
-
-            $parameters=array();
-            $reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
-        }
-
-        print "</table>\n";
-
-        print "</div>\n";
-
-
-        /*
-         * Boutons actions
-         */
-
-        if ($action != 'prerelance' && $action != 'presend')
-        {
-            if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline')
-            {
-                print '<div class="tabsAction">';
-
-                // Editer une facture deja validee, sans paiement effectue et pas exporte en compta
-                if ($object->statut == 1)
-                {
-                    // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
-                    $ventilExportCompta = $object->getVentilExportCompta();
-
-                    if ($resteapayer == $object->total_ttc	&& $object->paye == 0 && $ventilExportCompta == 0)
-                    {
-                        if (! $objectidnext)
-                        {
-                            if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate)
-                            {
-                                print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=modif">'.$langs->trans('Modify').'</a></div>';
-                            }
-                            else
-                            {
-                                print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans('Modify').'</span></div>';
-                            }
-                        }
-                        else
-                        {
-                            print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('Modify').'</span></div>';
-                        }
-                    }
-                }
-
-                // Reopen a standard paid invoice
-                if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3))				// A paid invoice (partially or completely)
-                {
-                    if (! $objectidnext && $object->close_code != 'replaced')	// Not replaced by another invoice
-                    {
-                        print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=reopen">'.$langs->trans('ReOpen').'</a></div>';
-                    }
-                    else
-                    {
-                        print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ReOpen').'</span></div>';
-                    }
-                }
-
-                // Validate
-                if ($object->statut == 0 && count($object->lines) > 0 &&
-                (
-                (($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0))
-                || ($object->type == 2 && $object->total_ttc <= 0))
-                )
-                {
-                    if ($user->rights->facture->valider)
-                    {
-                        print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=valid">'.$langs->trans('Validate').'</a></div>';
-                    }
-                }
-
-                // Send by mail
-                if (($object->statut == 1 || $object->statut == 2))
-                {
-                    if ($objectidnext)
-                    {
-                        print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('SendByMail').'</span></div>';
-                    }
-                    else
-                    {
-                        if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send)
-                        {
-                            print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=presend&amp;mode=init">'.$langs->trans('SendByMail').'</a></div>';
-                        }
-                        else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">'.$langs->trans('SendByMail').'</a></div>';
-                    }
-                }
-
-                if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER))	// For backward compatibility
-                {
-                    if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0)
-                    {
-                        if ($objectidnext)
-                        {
-                            print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('SendRemindByMail').'</span></div>';
-                        }
-                        else
-                        {
-                            if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send)
-                            {
-                                print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=prerelance&amp;mode=init">'.$langs->trans('SendRemindByMail').'</a></div>';
-                            }
-                            else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">'.$langs->trans('SendRemindByMail').'</a></div>';
-                        }
-                    }
-                }
-
-                // Create payment
-                if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement)
-                {
-                    if ($objectidnext)
-                    {
-                        print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('DoPayment').'</span></div>';
-                    }
-                    else
-                    {
-                        if ($resteapayer == 0)
-                        {
-                            print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPayment').'</span></div>';
-                        }
-                        else
-                        {
-                            print '<div class="inline-block divButAction"><a class="butAction" href="paiement.php?facid='.$object->id.'&amp;action=create">'.$langs->trans('DoPayment').'</a></div>';
-                        }
-                    }
-                }
-
-                // Reverse back money or convert to reduction
-                if ($object->type == 2 || $object->type == 3)
-                {
-                    // For credit note only
-                    if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement)
-                    {
-                        print '<div class="inline-block divButAction"><a class="butAction" href="paiement.php?facid='.$object->id.'&amp;action=create">'.$langs->trans('DoPaymentBack').'</a></div>';
-                    }
-                    // For credit note
-                    if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0)
-                    {
-                        print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertToReduc').'</a></div>';
-                    }
-                    // For deposit invoice
-                    if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer)
-                    {
-                        print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertToReduc').'</a></div>';
-                    }
-                }
-
-                // Classify paid (if not deposit and not credit note. Such invoice are "converted")
-                if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement &&
-                (($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0)) )
-                {
-                    print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaid').'</a></div>';
-                }
-
-                // Classify 'closed not completely paid' (possible si validee et pas encore classee payee)
-                if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0
-                && $user->rights->facture->paiement)
-                {
-                    if ($totalpaye > 0 || $totalcreditnotes > 0)
-                    {
-                        // If one payment or one credit note was linked to this invoice
-                        print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaidPartially').'</a></div>';
-                    }
-                    else
-                    {
-                        if ($objectidnext)
-                        {
-                            print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ClassifyCanceled').'</span></div>';
-                        }
-                        else
-                        {
-                            print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=canceled">'.$langs->trans('ClassifyCanceled').'</a></div>';
-                        }
-                    }
-                }
-
-                // Clone
-                if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer)
-                {
-                    print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=clone&amp;object=invoice">'.$langs->trans("ToClone").'</a></div>';
-                }
-
-                // Clone as predefined
-                if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer)
-                {
-                    if (! $objectidnext)
-                    {
-                        print '<div class="inline-block divButAction"><a class="butAction" href="facture/fiche-rec.php?facid='.$object->id.'&amp;action=create">'.$langs->trans("ChangeIntoRepeatableInvoice").'</a></div>';
-                    }
-                }
-
-                // Delete
-                if ($user->rights->facture->supprimer)
-                {
-                    if (! $object->is_erasable())
-                    {
-                        print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("DisabledBecauseNotErasable").'">'.$langs->trans('Delete').'</a></div>';
-                    }
-                    else if ($objectidnext)
-                    {
-                        print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('Delete').'</a></div>';
-                    }
-                    elseif ($object->getSommePaiement())
-                    {
-                        print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("DisabledBecausePayments").'">'.$langs->trans('Delete').'</a></div>';
-                    }
-                    else
-                    {
-                        print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=delete">'.$langs->trans('Delete').'</a></div>';
-                    }
-                }
-                else
-                {
-                    print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans('Delete').'</a></div>';
-                }
-
-                print '</div>';
-            }
-        }
-        print '<br>';
-
-        if ($action != 'prerelance' && $action != 'presend')
-        {
-			print '<div class="fichecenter"><div class="fichehalfleft">';
-        	//print '<table width="100%"><tr><td width="50%" valign="top">';
-            //print '<a name="builddoc"></a>'; // ancre
-
-            /*
-             * Documents generes
-             */
-            $filename=dol_sanitizeFileName($object->ref);
-            $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref);
-            $urlsource=$_SERVER['PHP_SELF'].'?facid='.$object->id;
-            $genallowed=$user->rights->facture->creer;
-            $delallowed=$user->rights->facture->supprimer;
-
-            print $formfile->showdocuments('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang);
-            $somethingshown=$formfile->numoffiles;
-
-            /*
-             * Linked object block
-             */
-            $somethingshown=$object->showLinkedObjectBlock();
-
-            // Link for paypal payment
-            if (! empty($conf->paypal->enabled) && $object->statut != 0)
-            {
-                include_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php';
-                print showPaypalPaymentUrl('invoice',$object->ref);
-            }
-
-			print '</div><div class="fichehalfright"><div class="ficheaddleft">';
-            //print '</td><td valign="top" width="50%">';
-
-            // List of actions on element
-            include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
-            $formactions=new FormActions($db);
-            $somethingshown=$formactions->showactions($object,'invoice',$socid);
-
-            //print '</td></tr></table>';
-            print '</div></div></div>';
-        }
-        else
-        {
-            /*
-             * Affiche formulaire mail
-             */
-
-            // By default if $action=='presend'
-            $titreform='SendBillByMail';
-            $topicmail='SendBillRef';
-            $action='send';
-            $modelmail='facture_send';
-
-            if ($action == 'prerelance')	// For backward compatibility
-            {
-                $titrefrom='SendReminderBillByMail';
-                $topicmail='SendReminderBillRef';
-                $action='relance';
-                $modelmail='facture_relance';
-            }
-
-            $ref = dol_sanitizeFileName($object->ref);
-            include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-            $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/'));
-            $file=$fileparams['fullname'];
-
-            // Build document if it not exists
-            if (! $file || ! is_readable($file))
-            {
-                // Define output language
-                $outputlangs = $langs;
-                $newlang='';
-                if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
-                if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
-                if (! empty($newlang))
-                {
-                    $outputlangs = new Translate("",$conf);
-                    $outputlangs->setDefaultLang($newlang);
-                }
-
-                $result=facture_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-                if ($result <= 0)
-                {
-                    dol_print_error($db,$result);
-                    exit;
-                }
-                $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/'));
-                $file=$fileparams['fullname'];
-            }
-
-            print '<br>';
-            print_titre($langs->trans($titreform));
-
-            // Cree l'objet formulaire mail
-            include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
-            $formmail = new FormMail($db);
-            $formmail->fromtype = 'user';
-            $formmail->fromid   = $user->id;
-            $formmail->fromname = $user->getFullName($langs);
-            $formmail->frommail = $user->email;
-            $formmail->withfrom=1;
-			$liste=array();
-			foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value)	$liste[$key]=$value;
-			$formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste;
-            $formmail->withtocc=$liste;
-            $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC;
-            $formmail->withtopic=$langs->transnoentities($topicmail,'__FACREF__');
-            $formmail->withfile=2;
-            $formmail->withbody=1;
-            $formmail->withdeliveryreceipt=1;
-            $formmail->withcancel=1;
-            // Tableau des substitutions
-            $formmail->substit['__FACREF__']=$object->ref;
-            $formmail->substit['__SIGNATURE__']=$user->signature;
-            $formmail->substit['__PERSONALIZED__']='';
-            $formmail->substit['__CONTACTCIVNAME__']='';
-
-            //Find the good contact adress
-            $custcontact='';
-            $contactarr=array();
-            $contactarr=$object->liste_contact(-1,'external');
-
-            if (is_array($contactarr) && count($contactarr)>0) {
-            	foreach($contactarr as $contact) {
-            		if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) {
-
-            			require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
-
-            			$contactstatic=new Contact($db);
-            			$contactstatic->fetch($contact['id']);
-            			$custcontact=$contactstatic->getFullName($langs,1);
-            		}
-            	}
-
-            	if (!empty($custcontact)) {
-            		$formmail->substit['__CONTACTCIVNAME__']=$custcontact;
-            	}
-            }
-
-
-            // Tableau des parametres complementaires du post
-            $formmail->param['action']=$action;
-            $formmail->param['models']=$modelmail;
-            $formmail->param['facid']=$object->id;
-            $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id;
-
-            // Init list of files
-            if (GETPOST("mode")=='init')
-            {
-                $formmail->clear_attached_files();
-                $formmail->add_attached_files($file,basename($file),dol_mimetype($file));
-            }
-
-            $formmail->show_form();
-
-            print '<br>';
-        }
-    }
-    else
-    {
-        dol_print_error($db,$object->error);
-    }
+		// Type
+		print '<tr><td>'.$langs->trans('Type').'</td><td colspan="5">';
+		print $object->getLibType();
+		if ($object->type == 1)
+		{
+			$facreplaced=new Facture($db);
+			$facreplaced->fetch($object->fk_facture_source);
+			print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')';
+		}
+		if ($object->type == 2)
+		{
+			$facusing=new Facture($db);
+			$facusing->fetch($object->fk_facture_source);
+			print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')';
+		}
+
+		$facidavoir=$object->getListIdAvoirFromInvoice();
+		if (count($facidavoir) > 0)
+		{
+			print ' ('.$langs->transnoentities("InvoiceHasAvoir");
+			$i=0;
+			foreach($facidavoir as $id)
+			{
+				if ($i==0) print ' ';
+				else print ',';
+				$facavoir=new Facture($db);
+				$facavoir->fetch($id);
+				print $facavoir->getNomUrl(1);
+			}
+			print ')';
+		}
+		if ($objectidnext > 0)
+		{
+			$facthatreplace=new Facture($db);
+			$facthatreplace->fetch($objectidnext);
+			print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')';
+		}
+		print '</td></tr>';
+
+		// Relative and absolute discounts
+		$addrelativediscount='<a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("EditRelativeDiscounts").'</a>';
+		$addabsolutediscount='<a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("EditGlobalDiscounts").'</a>';
+		$addcreditnote='<a href="'.DOL_URL_ROOT.'/compta/facture.php?action=create&socid='.$soc->id.'&type=2&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("AddCreditNote").'</a>';
+
+		print '<tr><td>'.$langs->trans('Discounts');
+		print '</td><td colspan="5">';
+		if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client);
+		else print $langs->trans("CompanyHasNoRelativeDiscount");
+		//print ' ('.$addrelativediscount.')';
+
+		if ($absolute_discount > 0)
+		{
+			print '. ';
+			if ($object->statut > 0 || $object->type == 2 || $object->type == 3)
+			{
+				if ($object->statut == 0)
+				{
+					print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
+					print '. ';
+				}
+				else
+				{
+					if ($object->statut < 1 || $object->type == 2 || $object->type == 3)
+					{
+						$text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
+						print '<br>'.$text.'.<br>';
+					}
+					else
+					{
+						$text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
+						$text2=$langs->trans("AbsoluteDiscountUse");
+						print $form->textwithpicto($text,$text2);
+					}
+				}
+			}
+			else
+			{
+				// Remise dispo de type remise fixe (not credit note)
+				print '<br>';
+				$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' ('.$addabsolutediscount.')');
+			}
+		}
+		else
+		{
+			if ($absolute_creditnote > 0)    // If not, link will be added later
+			{
+				if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')<br>';
+				else print '. ';
+			}
+			else print '. ';
+		}
+		if ($absolute_creditnote > 0)
+		{
+			// If validated, we show link "add credit note to payment"
+			if ($object->statut != 1 || $object->type == 2 || $object->type == 3)
+			{
+				if ($object->statut == 0 && $object->type != 3)
+				{
+					$text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency));
+					print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse"));
+				}
+				else
+				{
+					print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.';
+				}
+			}
+			else
+			{
+				// Remise dispo de type avoir
+				if (! $absolute_discount) print '<br>';
+				//$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer);
+				$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0);    // We must allow credit not even if amount is higher
+			}
+		}
+		if (! $absolute_discount && ! $absolute_creditnote)
+		{
+			print $langs->trans("CompanyHasNoAbsoluteDiscount");
+			if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')<br>';
+			else print '. ';
+		}
+		/*if ($object->statut == 0 && $object->type != 2 && $object->type != 3)
+		 {
+		if (! $absolute_discount && ! $absolute_creditnote) print '<br>';
+		//print ' &nbsp; - &nbsp; ';
+		print $addabsolutediscount;
+		//print ' &nbsp; - &nbsp; '.$addcreditnote;      // We disbale link to credit note
+		}*/
+		print '</td></tr>';
+
+		// Date invoice
+		print '<tr><td>';
+		print '<table class="nobordernopadding" width="100%"><tr><td>';
+		print $langs->trans('Date');
+		print '</td>';
+		if ($object->type != 2 && $action != 'editinvoicedate' && ! empty($object->brouillon) && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editinvoicedate&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetDate'),1).'</a></td>';
+		print '</tr></table>';
+		print '</td><td colspan="3">';
+
+		if ($object->type != 2)
+		{
+			if ($action == 'editinvoicedate')
+			{
+				$form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date,'invoicedate');
+			}
+			else
+			{
+				print dol_print_date($object->date,'daytext');
+			}
+		}
+		else
+		{
+			print dol_print_date($object->date,'daytext');
+		}
+		print '</td>';
+
+
+		/*
+		 * List of payments
+		*/
+
+		$sign=1;
+		if ($object->type == 2) $sign=-1;
+
+		$nbrows=8; $nbcols=2;
+		if (! empty($conf->projet->enabled)) $nbrows++;
+		if (! empty($conf->banque->enabled)) $nbcols++;
+		if($mysoc->localtax1_assuj=="1") $nbrows++;
+		if($mysoc->localtax2_assuj=="1") $nbrows++;
+		if ($selleruserevenustamp) $nbrows++;
+
+		print '<td rowspan="'.$nbrows.'" colspan="2" valign="top">';
+
+		print '<table class="nobordernopadding" width="100%">';
+
+		// List of payments already done
+		print '<tr class="liste_titre">';
+		print '<td>'.($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).'</td>';
+		print '<td>'.$langs->trans('Type').'</td>';
+		if (! empty($conf->banque->enabled)) print '<td align="right">'.$langs->trans('BankAccount').'</td>';
+		print '<td align="right">'.$langs->trans('Amount').'</td>';
+		print '<td width="18">&nbsp;</td>';
+		print '</tr>';
+
+		$var=true;
+
+		// Payments already done (from payment on this invoice)
+		$sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,';
+		$sql.= ' c.code as payment_code, c.libelle as payment_label,';
+		$sql.= ' pf.amount,';
+		$sql.= ' ba.rowid as baid, ba.ref, ba.label';
+		$sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p';
+		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
+		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
+		$sql.= ' WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid';
+		$sql.= ' ORDER BY p.datep, p.tms';
+
+		$result = $db->query($sql);
+		if ($result)
+		{
+			$num = $db->num_rows($result);
+			$i = 0;
+
+			//if ($object->type != 2)
+			//{
+			if ($num > 0)
+			{
+				while ($i < $num)
+				{
+					$objp = $db->fetch_object($result);
+					$var=!$var;
+					print '<tr '.$bc[$var].'><td>';
+					print '<a href="'.DOL_URL_ROOT.'/compta/paiement/fiche.php?id='.$objp->rowid.'">'.img_object($langs->trans('ShowPayment'),'payment').' ';
+					print dol_print_date($db->jdate($objp->dp),'day').'</a></td>';
+					$label=($langs->trans("PaymentType".$objp->payment_code)!=("PaymentType".$objp->payment_code))?$langs->trans("PaymentType".$objp->payment_code):$objp->payment_label;
+					print '<td>'.$label.' '.$objp->num_paiement.'</td>';
+					if (! empty($conf->banque->enabled))
+					{
+						$bankaccountstatic->id=$objp->baid;
+						$bankaccountstatic->ref=$objp->ref;
+						$bankaccountstatic->label=$objp->ref;
+						print '<td align="right">';
+						if ($bankaccountstatic->id) print $bankaccountstatic->getNomUrl(1,'transactions');
+						print '</td>';
+					}
+					print '<td align="right">'.price($sign * $objp->amount).'</td>';
+					print '<td>&nbsp;</td>';
+					print '</tr>';
+					$i++;
+				}
+			}
+			else
+			{
+				print '<tr '.$bc[$var].'><td colspan="'.$nbcols.'">'.$langs->trans("None").'</td><td></td><td></td></tr>';
+			}
+			//}
+			$db->free($result);
+			}
+			else
+			{
+				dol_print_error($db);
+			}
+
+			if ($object->type != 2)
+			{
+				// Total already paid
+				print '<tr><td colspan="'.$nbcols.'" align="right">';
+				if ($object->type != 3) print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits');
+				else print $langs->trans('AlreadyPaid');
+				print ' :</td><td align="right">'.price($totalpaye).'</td><td>&nbsp;</td></tr>';
+
+				$resteapayeraffiche=$resteapayer;
+
+				// Loop on each credit note or deposit amount applied
+				$creditnoteamount=0;
+				$depositamount=0;
+				$sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
+				$sql.= " re.description, re.fk_facture_source";
+				$sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re";
+				$sql.= " WHERE fk_facture = ".$object->id;
+				$resql=$db->query($sql);
+				if ($resql)
+				{
+					$num = $db->num_rows($resql);
+					$i = 0;
+					$invoice=new Facture($db);
+					while ($i < $num)
+					{
+						$obj = $db->fetch_object($resql);
+						$invoice->fetch($obj->fk_facture_source);
+						print '<tr><td colspan="'.$nbcols.'" align="right">';
+						if ($invoice->type == 2) print $langs->trans("CreditNote").' ';
+						if ($invoice->type == 3) print $langs->trans("Deposit").' ';
+						print $invoice->getNomUrl(0);
+						print ' :</td>';
+						print '<td align="right">'.price($obj->amount_ttc).'</td>';
+						print '<td align="right">';
+						print '<a href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=unlinkdiscount&discountid='.$obj->rowid.'">'.img_delete().'</a>';
+						print '</td></tr>';
+						$i++;
+						if ($invoice->type == 2) $creditnoteamount += $obj->amount_ttc;
+						if ($invoice->type == 3) $depositamount += $obj->amount_ttc;
+					}
+				}
+				else
+				{
+					dol_print_error($db);
+				}
+
+				// Paye partiellement 'escompte'
+				if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat')
+				{
+					print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
+					print $form->textwithpicto($langs->trans("Discount").':',$langs->trans("HelpEscompte"),-1);
+					print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
+					$resteapayeraffiche=0;
+				}
+				// Paye partiellement ou Abandon 'badcustomer'
+				if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer')
+				{
+					print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
+					print $form->textwithpicto($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1);
+					print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
+					//$resteapayeraffiche=0;
+				}
+				// Paye partiellement ou Abandon 'product_returned'
+				if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned')
+				{
+					print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
+					print $form->textwithpicto($langs->trans("ProductReturned").':',$langs->trans("HelpAbandonProductReturned"),-1);
+					print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
+					$resteapayeraffiche=0;
+				}
+				// Paye partiellement ou Abandon 'abandon'
+				if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon')
+				{
+					print '<tr><td colspan="'.$nbcols.'" align="right" nowrap="1">';
+					$text=$langs->trans("HelpAbandonOther");
+					if ($object->close_note) $text.='<br><br><b>'.$langs->trans("Reason").'</b>:'.$object->close_note;
+					print $form->textwithpicto($langs->trans("Abandoned").':',$text,-1);
+					print '</td><td align="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).'</td><td>&nbsp;</td></tr>';
+					$resteapayeraffiche=0;
+				}
+
+				// Billed
+				print '<tr><td colspan="'.$nbcols.'" align="right">'.$langs->trans("Billed").' :</td><td align="right" style="border: 1px solid;">'.price($object->total_ttc).'</td><td>&nbsp;</td></tr>';
+
+				// Remainder to pay
+				print '<tr><td colspan="'.$nbcols.'" align="right">';
+				if ($resteapayeraffiche >= 0) print $langs->trans('RemainderToPay');
+				else print $langs->trans('ExcessReceived');
+				print ' :</td>';
+				print '<td align="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($resteapayeraffiche).'</b></td>';
+				print '<td nowrap="nowrap">&nbsp;</td></tr>';
+			}
+			else	// Credit note
+			{
+				// Total already paid back
+				print '<tr><td colspan="'.$nbcols.'" align="right">';
+				print $langs->trans('AlreadyPaidBack');
+				print ' :</td><td align="right">'.price($sign * $totalpaye).'</td><td>&nbsp;</td></tr>';
+
+				// Billed
+				print '<tr><td colspan="'.$nbcols.'" align="right">'.$langs->trans("Billed").' :</td><td align="right" style="border: 1px solid;">'.price($sign * $object->total_ttc).'</td><td>&nbsp;</td></tr>';
+
+				// Remainder to pay back
+				print '<tr><td colspan="'.$nbcols.'" align="right">';
+				if ($resteapayeraffiche <= 0) print $langs->trans('RemainderToPayBack');
+				else print $langs->trans('ExcessPaydBack');
+				print ' :</td>';
+				print '<td align="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($sign * $resteapayeraffiche).'</b></td>';
+				print '<td nowrap="nowrap">&nbsp;</td></tr>';
+
+				// Sold credit note
+				//print '<tr><td colspan="'.$nbcols.'" align="right">'.$langs->trans('TotalTTC').' :</td>';
+				//print '<td align="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($sign * $object->total_ttc).'</b></td><td>&nbsp;</td></tr>';
+			}
+
+			print '</table>';
+
+			// Margin Infos
+			if (! empty($conf->margin->enabled))
+			{
+				print '<br>';
+				$object->displayMarginInfos($object->statut > 0);
+			}
+
+			print '</td></tr>';
+
+			// Conditions de reglement
+			print '<tr><td>';
+			print '<table class="nobordernopadding" width="100%"><tr><td>';
+			print $langs->trans('PaymentConditionsShort');
+			print '</td>';
+			if ($object->type != 2 && $action != 'editconditions' && ! empty($object->brouillon) && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editconditions&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetConditions'),1).'</a></td>';
+			print '</tr></table>';
+			print '</td><td colspan="3">';
+			if ($object->type != 2)
+			{
+				if ($action == 'editconditions')
+				{
+					$form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'cond_reglement_id');
+				}
+				else
+				{
+					$form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'none');
+				}
+			}
+			else
+			{
+				print '&nbsp;';
+			}
+			print '</td></tr>';
+
+			// Date payment term
+			print '<tr><td>';
+			print '<table class="nobordernopadding" width="100%"><tr><td>';
+			print $langs->trans('DateMaxPayment');
+			print '</td>';
+			if ($object->type != 2 && $action != 'editpaymentterm' && ! empty($object->brouillon) && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editpaymentterm&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetDate'),1).'</a></td>';
+			print '</tr></table>';
+			print '</td><td colspan="3">';
+			if ($object->type != 2)
+			{
+				if ($action == 'editpaymentterm')
+				{
+					$form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date_lim_reglement,'paymentterm');
+				}
+				else
+				{
+					print dol_print_date($object->date_lim_reglement,'daytext');
+					if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && ! $object->paye && $object->statut == 1 && ! isset($object->am)) print img_warning($langs->trans('Late'));
+				}
+			}
+			else
+			{
+				print '&nbsp;';
+			}
+			print '</td></tr>';
+
+			// Payment mode
+			print '<tr><td>';
+			print '<table class="nobordernopadding" width="100%"><tr><td>';
+			print $langs->trans('PaymentMode');
+			print '</td>';
+			if ($action != 'editmode' && ! empty($object->brouillon) && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editmode&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetMode'),1).'</a></td>';
+			print '</tr></table>';
+			print '</td><td colspan="3">';
+			if ($action == 'editmode')
+			{
+				$form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'mode_reglement_id');
+			}
+			else
+			{
+				$form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'none');
+			}
+			print '</td></tr>';
+
+			// Amount
+			print '<tr><td>'.$langs->trans('AmountHT').'</td>';
+			print '<td align="right" colspan="3" nowrap>'.price($object->total_ht,1,'',1,-1,-1,$conf->currency).'</td></tr>';
+			print '<tr><td>'.$langs->trans('AmountVAT').'</td><td align="right" colspan="3" nowrap>'.price($object->total_tva,1,'',1,-1,-1,$conf->currency).'</td></tr>';
+			print '</tr>';
+
+			// Amount Local Taxes
+			if ($mysoc->localtax1_assuj=="1" && $mysoc->useLocalTax(1)) //Localtax1 (example RE)
+			{
+				print '<tr><td>'.$langs->transcountry("AmountLT1",$mysoc->country_code).'</td>';
+				print '<td align="right" colspan="3" nowrap>'.price($object->total_localtax1,1,'',1,-1,-1,$conf->currency).'</td></tr>';
+			}
+			if ($mysoc->localtax2_assuj=="1" && $mysoc->useLocalTax(2)) //Localtax2 (example IRPF)
+			{
+				print '<tr><td>'.$langs->transcountry("AmountLT2",$mysoc->country_code).'</td>';
+				print '<td align="right" colspan="3" nowrap>'.price($object->total_localtax2,1,'',1,-1,-1,$conf->currency).'</td></tr>';
+			}
+
+			// Revenue stamp
+			if ($selleruserevenustamp)		// Test company use revenue stamp
+			{
+				print '<tr><td>';
+				print '<table class="nobordernopadding" width="100%"><tr><td>';
+				print $langs->trans('RevenueStamp');
+				print '</td>';
+				if ($action != 'editrevenuestamp' && ! empty($object->brouillon) && $user->rights->facture->creer) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editrevenuestamp&amp;facid='.$object->id.'">'.img_edit($langs->trans('SetRevenuStamp'),1).'</a></td>';
+				print '</tr></table>';
+				print '</td><td colspan="3" align="right">';
+				if ($action == 'editrevenuestamp')
+				{
+					print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
+					print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+					print '<input type="hidden" name="action" value="setrevenuestamp">';
+					print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code);
+					//print '<input type="text" class="flat" size="4" name="revenuestamp" value="'.price2num($object->revenuestamp).'">';
+					print ' <input type="submit" class="button" value="'.$langs->trans('Modify').'">';
+					print '</form>';
+				}
+				else
+				{
+					print price($object->revenuestamp,1,'',1,-1,-1,$conf->currency);
+				}
+				print '</td></tr>';
+			}
+
+			// Total with tax
+			print '<tr><td>'.$langs->trans('AmountTTC').'</td><td align="right" colspan="3" nowrap>'.price($object->total_ttc,1,'',1,-1,-1,$conf->currency).'</td></tr>';
+
+			// Statut
+			print '<tr><td>'.$langs->trans('Status').'</td>';
+			print '<td align="left" colspan="3">'.($object->getLibStatut(4,$totalpaye)).'</td></tr>';
+
+			// Project
+			if (! empty($conf->projet->enabled))
+			{
+				$langs->load('projects');
+				print '<tr>';
+				print '<td>';
+
+				print '<table class="nobordernopadding" width="100%"><tr><td>';
+				print $langs->trans('Project');
+				print '</td>';
+				if ($action != 'classify')
+				{
+					print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=classify&amp;facid='.$object->id.'">';
+					print img_edit($langs->trans('SetProject'),1);
+					print '</a></td>';
+				}
+				print '</tr></table>';
+
+				print '</td><td colspan="3">';
+				if ($action == 'classify')
+				{
+					$form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'projectid');
+				}
+				else
+				{
+					$form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'none');
+				}
+				print '</td>';
+				print '</tr>';
+			}
+
+			// Other attributes
+			$res=$object->fetch_optionals($object->id,$extralabels);
+			$parameters=array('colspan' => ' colspan="2"');
+			$reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
+			if (empty($reshook) && ! empty($extrafields->attribute_label))
+			{
+
+				if ($action == 'edit_extras')
+				{
+					print '<form enctype="multipart/form-data" action="'.$_SERVER["PHP_SELF"].'" method="post" name="formsoc">';
+					print '<input type="hidden" name="action" value="update_extras">';
+					print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+					print '<input type="hidden" name="id" value="'.$object->id.'">';
+				}
+
+				foreach($extrafields->attribute_label as $key=>$label)
+				{
+					$value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]);
+					if ($extrafields->attribute_type[$key] == 'separate')
+					{
+						print $extrafields->showSeparator($key);
+					}
+					else
+					{
+						print '<tr><td';
+						if (! empty($extrafields->attribute_required[$key])) print ' class="fieldrequired"';
+						print '>'.$label.'</td><td colspan="5">';
+						// Convert date into timestamp format
+						if (in_array($extrafields->attribute_type[$key],array('date','datetime')))
+						{
+							$value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key];
+						}
+
+						if ($action == 'edit_extras' && $user->rights->facture->creer)
+						{
+							print $extrafields->showInputField($key,$value);
+						}
+						else
+						{
+							print $extrafields->showOutputField($key,$value);
+						}
+						print '</td></tr>'."\n";
+					}
+				}
+
+				if(count($extrafields->attribute_label) > 0) {
+
+					if ($action == 'edit_extras' && $user->rights->facture->creer)
+					{
+						print '<tr><td></td><td colspan="5">';
+						print '<input type="submit" class="button" value="'.$langs->trans('Modify').'">';
+						print '</form>';
+						print '</td></tr>';
+
+					}
+					else {
+						if ($object->statut == 0 && $user->rights->facture->creer)
+						{
+							print '<tr><td></td><td><a href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit_extras">'.img_picto('','edit').' '.$langs->trans('Modify').'</a></td></tr>';
+						}
+					}
+				}
+			}
+
+			print '</table><br>';
+
+			if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB))
+			{
+				$blocname = 'contacts';
+				$title = $langs->trans('ContactsAddresses');
+				include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
+			}
+
+			if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB))
+			{
+				$blocname = 'notes';
+				$title = $langs->trans('Notes');
+				include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
+			}
+
+			/*
+			 * Lines
+			*/
+			$result = $object->getLinesArray();
+
+			if (! empty($conf->use_javascript_ajax) && $object->statut == 0)
+			{
+				include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
+			}
+
+			print '<table id="tablelines" class="noborder noshadow" width="100%">';
+
+			// Show object lines
+			if (! empty($object->lines))
+				$ret=$object->printObjectLines($action,$mysoc,$soc,$lineid,1);
+
+			/*
+			 * Form to add new line
+			*/
+			if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline')
+			{
+				$var=true;
+
+				if ($conf->global->MAIN_FEATURES_LEVEL > 1)
+				{
+					// Add free or predefined products/services
+					$object->formAddObjectLine(1,$mysoc,$soc);
+				}
+				else
+				{
+					// Add free products/services
+					$object->formAddFreeProduct(1,$mysoc,$soc);
+
+					// Add predefined products/services
+					if (! empty($conf->product->enabled) || ! empty($conf->service->enabled))
+					{
+						$var=!$var;
+						$object->formAddPredefinedProduct(1,$mysoc,$soc);
+					}
+				}
+
+				$parameters=array();
+				$reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
+			}
+
+			print "</table>\n";
+
+			print "</div>\n";
+
+
+			/*
+			 * Boutons actions
+			*/
+
+			if ($action != 'prerelance' && $action != 'presend')
+			{
+				if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline')
+				{
+					print '<div class="tabsAction">';
+
+					// Editer une facture deja validee, sans paiement effectue et pas exporte en compta
+					if ($object->statut == 1)
+					{
+						// On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
+						$ventilExportCompta = $object->getVentilExportCompta();
+
+						if ($resteapayer == $object->total_ttc	&& $object->paye == 0 && $ventilExportCompta == 0)
+						{
+							if (! $objectidnext)
+							{
+								if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate)
+								{
+									print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=modif">'.$langs->trans('Modify').'</a></div>';
+								}
+								else
+								{
+									print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans('Modify').'</span></div>';
+								}
+							}
+							else
+							{
+								print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('Modify').'</span></div>';
+							}
+						}
+					}
+
+					// Reopen a standard paid invoice
+					if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3))				// A paid invoice (partially or completely)
+					{
+						if (! $objectidnext && $object->close_code != 'replaced')	// Not replaced by another invoice
+						{
+							print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=reopen">'.$langs->trans('ReOpen').'</a></div>';
+						}
+						else
+						{
+							print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ReOpen').'</span></div>';
+						}
+					}
+
+					// Validate
+					if ($object->statut == 0 && count($object->lines) > 0 &&
+						(
+							(($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0))
+							|| ($object->type == 2 && $object->total_ttc <= 0))
+					)
+					{
+						if ($user->rights->facture->valider)
+						{
+							print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=valid">'.$langs->trans('Validate').'</a></div>';
+						}
+					}
+
+					// Send by mail
+					if (($object->statut == 1 || $object->statut == 2))
+					{
+						if ($objectidnext)
+						{
+							print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('SendByMail').'</span></div>';
+						}
+						else
+						{
+							if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send)
+							{
+								print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=presend&amp;mode=init">'.$langs->trans('SendByMail').'</a></div>';
+							}
+							else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">'.$langs->trans('SendByMail').'</a></div>';
+						}
+					}
+
+					if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER))	// For backward compatibility
+					{
+						if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0)
+						{
+							if ($objectidnext)
+							{
+								print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('SendRemindByMail').'</span></div>';
+							}
+							else
+							{
+								if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send)
+								{
+									print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=prerelance&amp;mode=init">'.$langs->trans('SendRemindByMail').'</a></div>';
+								}
+								else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">'.$langs->trans('SendRemindByMail').'</a></div>';
+							}
+						}
+					}
+
+					// Create payment
+					if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement)
+					{
+						if ($objectidnext)
+						{
+							print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('DoPayment').'</span></div>';
+						}
+						else
+						{
+							if ($resteapayer == 0)
+							{
+								print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPayment').'</span></div>';
+							}
+							else
+							{
+								print '<div class="inline-block divButAction"><a class="butAction" href="paiement.php?facid='.$object->id.'&amp;action=create">'.$langs->trans('DoPayment').'</a></div>';
+							}
+						}
+					}
+
+					// Reverse back money or convert to reduction
+					if ($object->type == 2 || $object->type == 3)
+					{
+						// For credit note only
+						if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement)
+						{
+							print '<div class="inline-block divButAction"><a class="butAction" href="paiement.php?facid='.$object->id.'&amp;action=create">'.$langs->trans('DoPaymentBack').'</a></div>';
+						}
+						// For credit note
+						if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0)
+						{
+							print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertToReduc').'</a></div>';
+						}
+						// For deposit invoice
+						if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer)
+						{
+							print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertToReduc').'</a></div>';
+						}
+					}
+
+					// Classify paid (if not deposit and not credit note. Such invoice are "converted")
+					if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement &&
+						(($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0)) )
+					{
+						print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaid').'</a></div>';
+					}
+
+					// Classify 'closed not completely paid' (possible si validee et pas encore classee payee)
+					if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0
+						&& $user->rights->facture->paiement)
+					{
+						if ($totalpaye > 0 || $totalcreditnotes > 0)
+						{
+							// If one payment or one credit note was linked to this invoice
+							print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaidPartially').'</a></div>';
+						}
+						else
+						{
+							if ($objectidnext)
+							{
+								print '<div class="inline-block divButAction"><span class="butActionRefused" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ClassifyCanceled').'</span></div>';
+							}
+							else
+							{
+								print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=canceled">'.$langs->trans('ClassifyCanceled').'</a></div>';
+							}
+						}
+					}
+
+					// Clone
+					if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer)
+					{
+						print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=clone&amp;object=invoice">'.$langs->trans("ToClone").'</a></div>';
+					}
+
+					// Clone as predefined
+					if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer)
+					{
+						if (! $objectidnext)
+						{
+							print '<div class="inline-block divButAction"><a class="butAction" href="facture/fiche-rec.php?facid='.$object->id.'&amp;action=create">'.$langs->trans("ChangeIntoRepeatableInvoice").'</a></div>';
+						}
+					}
+
+					// Delete
+					if ($user->rights->facture->supprimer)
+					{
+						if (! $object->is_erasable())
+						{
+							print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("DisabledBecauseNotErasable").'">'.$langs->trans('Delete').'</a></div>';
+						}
+						else if ($objectidnext)
+						{
+							print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('Delete').'</a></div>';
+						}
+						elseif ($object->getSommePaiement())
+						{
+							print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("DisabledBecausePayments").'">'.$langs->trans('Delete').'</a></div>';
+						}
+						else
+						{
+							print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=delete">'.$langs->trans('Delete').'</a></div>';
+						}
+					}
+					else
+					{
+						print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans('Delete').'</a></div>';
+					}
+
+					print '</div>';
+				}
+			}
+			print '<br>';
+
+			if ($action != 'prerelance' && $action != 'presend')
+			{
+				print '<div class="fichecenter"><div class="fichehalfleft">';
+				//print '<table width="100%"><tr><td width="50%" valign="top">';
+				//print '<a name="builddoc"></a>'; // ancre
+
+				/*
+				 * Documents generes
+				*/
+				$filename=dol_sanitizeFileName($object->ref);
+				$filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref);
+				$urlsource=$_SERVER['PHP_SELF'].'?facid='.$object->id;
+				$genallowed=$user->rights->facture->creer;
+				$delallowed=$user->rights->facture->supprimer;
+
+				print $formfile->showdocuments('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang);
+				$somethingshown=$formfile->numoffiles;
+
+				/*
+				 * Linked object block
+				*/
+				$somethingshown=$object->showLinkedObjectBlock();
+
+				// Link for paypal payment
+				if (! empty($conf->paypal->enabled) && $object->statut != 0)
+				{
+					include_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php';
+					print showPaypalPaymentUrl('invoice',$object->ref);
+				}
+
+				print '</div><div class="fichehalfright"><div class="ficheaddleft">';
+				//print '</td><td valign="top" width="50%">';
+
+				// List of actions on element
+				include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
+				$formactions=new FormActions($db);
+				$somethingshown=$formactions->showactions($object,'invoice',$socid);
+
+				//print '</td></tr></table>';
+				print '</div></div></div>';
+			}
+			else
+			{
+				/*
+				 * Affiche formulaire mail
+				*/
+
+				// By default if $action=='presend'
+				$titreform='SendBillByMail';
+				$topicmail='SendBillRef';
+				$action='send';
+				$modelmail='facture_send';
+
+				if ($action == 'prerelance')	// For backward compatibility
+				{
+					$titrefrom='SendReminderBillByMail';
+					$topicmail='SendReminderBillRef';
+					$action='relance';
+					$modelmail='facture_relance';
+				}
+
+				$ref = dol_sanitizeFileName($object->ref);
+				include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+				$fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/'));
+				$file=$fileparams['fullname'];
+
+				// Build document if it not exists
+				if (! $file || ! is_readable($file))
+				{
+					// Define output language
+					$outputlangs = $langs;
+					$newlang='';
+					if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id'];
+					if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang;
+					if (! empty($newlang))
+					{
+						$outputlangs = new Translate("",$conf);
+						$outputlangs->setDefaultLang($newlang);
+					}
+
+					$result=facture_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+					if ($result <= 0)
+					{
+						dol_print_error($db,$result);
+						exit;
+					}
+					$fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/'));
+					$file=$fileparams['fullname'];
+				}
+
+				print '<br>';
+				print_titre($langs->trans($titreform));
+
+				// Cree l'objet formulaire mail
+				include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
+				$formmail = new FormMail($db);
+				$formmail->fromtype = 'user';
+				$formmail->fromid   = $user->id;
+				$formmail->fromname = $user->getFullName($langs);
+				$formmail->frommail = $user->email;
+				$formmail->withfrom=1;
+				$liste=array();
+				foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value)	$liste[$key]=$value;
+				$formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste;
+				$formmail->withtocc=$liste;
+				$formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC;
+				$formmail->withtopic=$langs->transnoentities($topicmail,'__FACREF__');
+				$formmail->withfile=2;
+				$formmail->withbody=1;
+				$formmail->withdeliveryreceipt=1;
+				$formmail->withcancel=1;
+				// Tableau des substitutions
+				$formmail->substit['__FACREF__']=$object->ref;
+				$formmail->substit['__SIGNATURE__']=$user->signature;
+				$formmail->substit['__PERSONALIZED__']='';
+				$formmail->substit['__CONTACTCIVNAME__']='';
+
+				//Find the good contact adress
+				$custcontact='';
+				$contactarr=array();
+				$contactarr=$object->liste_contact(-1,'external');
+
+				if (is_array($contactarr) && count($contactarr)>0) {
+					foreach($contactarr as $contact) {
+						if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) {
+
+							require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
+
+							$contactstatic=new Contact($db);
+							$contactstatic->fetch($contact['id']);
+							$custcontact=$contactstatic->getFullName($langs,1);
+						}
+					}
+
+					if (!empty($custcontact)) {
+						$formmail->substit['__CONTACTCIVNAME__']=$custcontact;
+					}
+				}
+
+
+				// Tableau des parametres complementaires du post
+				$formmail->param['action']=$action;
+				$formmail->param['models']=$modelmail;
+				$formmail->param['facid']=$object->id;
+				$formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id;
+
+				// Init list of files
+				if (GETPOST("mode")=='init')
+				{
+					$formmail->clear_attached_files();
+					$formmail->add_attached_files($file,basename($file),dol_mimetype($file));
+				}
+
+				$formmail->show_form();
+
+				print '<br>';
+			}
+	}
+	else
+	{
+		dol_print_error($db,$object->error);
+	}
 }
 
 dol_htmloutput_mesg('',$mesgs);
diff --git a/htdocs/compta/facture/apercu.php b/htdocs/compta/facture/apercu.php
index 2db60bada79009b7ada75d9a3e95f88d77dd482c..f31f0a50f0f335c2e86be2298a6ad1641dcfe6ee 100644
--- a/htdocs/compta/facture/apercu.php
+++ b/htdocs/compta/facture/apercu.php
@@ -318,7 +318,7 @@ if ($id > 0 || ! empty($ref))
 
             print "<tr $bc[$var]><td>".$langs->trans("Bill")." PDF</td>";
 
-            print '<td><a href="'.DOL_URL_ROOT . '/document.php?modulepart=facture&file='.urlencode($relativepath).'">'.$object->ref.'.pdf</a></td>';
+            print '<td><a data-ajax="false" href="'.DOL_URL_ROOT . '/document.php?modulepart=facture&file='.urlencode($relativepath).'">'.$object->ref.'.pdf</a></td>';
             print '<td align="right">'.dol_print_size(dol_filesize($file)). '</td>';
             print '<td align="right">'.dol_print_date(dol_filemtime($file),'dayhour').'</td>';
             print '</tr>';
@@ -328,7 +328,7 @@ if ($id > 0 || ! empty($ref))
             {
                 print "<tr $bc[$var]><td>Facture detaillee</td>";
 
-                print '<td><a href="'.DOL_URL_ROOT . '/document.php?modulepart=facture&file='.urlencode($relativepathdetail).'">'.$object->ref.'-detail.pdf</a></td>';
+                print '<td><a data-ajax="false" href="'.DOL_URL_ROOT . '/document.php?modulepart=facture&file='.urlencode($relativepathdetail).'">'.$object->ref.'-detail.pdf</a></td>';
                 print '<td align="right">'.dol_print_size(dol_filesize($filedetail)).'</td>';
                 print '<td align="right">'.dol_print_date(dol_filemtime($filedetail),'dayhour').'</td>';
                 print '</tr>';
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index f36ddc88a1d70a393eeb0987b5ade8aec419fb16..a2a9cf6da139abdee89bb790c6ee27c0649a6aa5 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -1,37 +1,37 @@
 <?php
 /* Copyright (C) 2002-2007 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
  * Copyright (C) 2004-2012 Laurent Destailleur   <eldy@users.sourceforge.net>
- * Copyright (C) 2004      Sebastien Di Cintio   <sdicintio@ressource-toi.org>
- * Copyright (C) 2004      Benoit Mortier        <benoit.mortier@opensides.be>
- * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
- * Copyright (C) 2005-2013 Regis Houssin         <regis.houssin@capnetworks.com>
- * Copyright (C) 2006      Andre Cianfarani      <acianfa@free.fr>
- * Copyright (C) 2007      Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
- * Copyright (C) 2010-2012 Juanjo Menent         <jmenent@2byte.es>
- * Copyright (C) 2012      Christophe Battarel   <christophe.battarel@altairis.fr>
- * Copyright (C) 2012      Marcos García         <marcosgdf@gmail.com>
- * Copyright (C) 2013      Cedric Gross          <c.gross@kreiz-it.fr>
- * Copyright (C) 2013      Florian Henry		  	<florian.henry@open-concept.pro>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
+* Copyright (C) 2004      Sebastien Di Cintio   <sdicintio@ressource-toi.org>
+* Copyright (C) 2004      Benoit Mortier        <benoit.mortier@opensides.be>
+* Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
+* Copyright (C) 2005-2013 Regis Houssin         <regis.houssin@capnetworks.com>
+* Copyright (C) 2006      Andre Cianfarani      <acianfa@free.fr>
+* Copyright (C) 2007      Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
+* Copyright (C) 2010-2012 Juanjo Menent         <jmenent@2byte.es>
+* Copyright (C) 2012      Christophe Battarel   <christophe.battarel@altairis.fr>
+* Copyright (C) 2012      Marcos García         <marcosgdf@gmail.com>
+* Copyright (C) 2013      Cedric Gross          <c.gross@kreiz-it.fr>
+* Copyright (C) 2013      Florian Henry		  	<florian.henry@open-concept.pro>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
 
 /**
  *	\file       htdocs/compta/facture/class/facture.class.php
- *	\ingroup    facture
- *	\brief      File of class to manage invoices
- */
+*	\ingroup    facture
+*	\brief      File of class to manage invoices
+*/
 
 include_once DOL_DOCUMENT_ROOT.'/core/class/commoninvoice.class.php';
 require_once DOL_DOCUMENT_ROOT .'/product/class/product.class.php';
@@ -44,3097 +44,3136 @@ require_once DOL_DOCUMENT_ROOT .'/margin/lib/margins.lib.php';
  */
 class Facture extends CommonInvoice
 {
-    public $element='facture';
-    public $table_element='facture';
-    public $table_element_line = 'facturedet';
-    public $fk_element = 'fk_facture';
-    protected $ismultientitymanaged = 1;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
-
-    var $id;
-    //! Id client
-    var $socid;
-    //! Objet societe client (to load with fetch_client method)
-    var $client;
-    var $author;
-    var $fk_user_author;
-    var $fk_user_valid;
-    //! Invoice date
-    var $date;				// Invoice date
-    var $date_creation;		// Creation date
-    var $date_validation;	// Validation date
-    var $datem;
-    var $ref;
-    var $ref_client;
-    var $ref_ext;
-    var $ref_int;
-    //! 0=Standard invoice, 1=Replacement invoice, 2=Credit note invoice, 3=Deposit invoice, 4=Proforma invoice
-    var $type=0;
-
-    //var $amount;
-    var $remise_absolue;
-    var $remise_percent;
-    var $total_ht=0;
-    var $total_tva=0;
-    var $total_ttc=0;
-    var $revenuestamp;
-    var $note;			// deprecated
-    var $note_private;
-    var $note_public;
-    //! 0=draft,
-    //! 1=validated (need to be paid),
-    //! 2=classified paid partially (close_code='discount_vat','badcustomer') or completely (close_code=null),
-    //! 3=classified abandoned and no payment done (close_code='badcustomer','abandon' or 'replaced')
-    var $statut;
-    //! Fermeture apres paiement partiel: discount_vat, badcustomer, abandon
-    //! Fermeture alors que aucun paiement: replaced (si remplace), abandon
-    var $close_code;
-    //! Commentaire si mis a paye sans paiement complet
-    var $close_note;
-    //! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code
-    var $paye;
-    //! id of source invoice if replacement invoice or credit note
-    var $fk_facture_source;
-    var $origin;
-    var $origin_id;
-    var $linked_objects=array();
-    var $fk_project;
-    var $date_lim_reglement;
-    var $cond_reglement_id;			// Id in llx_c_paiement
-    var $cond_reglement_code;		// Code in llx_c_paiement
-    var $mode_reglement_id;			// Id in llx_c_paiement
-    var $mode_reglement_code;		// Code in llx_c_paiement
-    var $fk_bank;					// Field to store bank id to use when payment mode is withdraw
-    var $modelpdf;
-    var $products=array();	// deprecated
-    var $lines=array();
-    var $line;
-    var $extraparams=array();
-    //! Pour board
-    var $nbtodo;
-    var $nbtodolate;
-    var $specimen;
-
-    var $fac_rec;
-
-
-    /**
-     * 	Constructor
-     *
+	public $element='facture';
+	public $table_element='facture';
+	public $table_element_line = 'facturedet';
+	public $fk_element = 'fk_facture';
+	protected $ismultientitymanaged = 1;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
+
+	var $id;
+	//! Id client
+	var $socid;
+	//! Objet societe client (to load with fetch_client method)
+	var $client;
+	var $author;
+	var $fk_user_author;
+	var $fk_user_valid;
+	//! Invoice date
+	var $date;				// Invoice date
+	var $date_creation;		// Creation date
+	var $date_validation;	// Validation date
+	var $datem;
+	var $ref;
+	var $ref_client;
+	var $ref_ext;
+	var $ref_int;
+	//! 0=Standard invoice, 1=Replacement invoice, 2=Credit note invoice, 3=Deposit invoice, 4=Proforma invoice
+	var $type=0;
+
+	//var $amount;
+	var $remise_absolue;
+	var $remise_percent;
+	var $total_ht=0;
+	var $total_tva=0;
+	var $total_ttc=0;
+	var $revenuestamp;
+	var $note;			// deprecated
+	var $note_private;
+	var $note_public;
+	//! 0=draft,
+	//! 1=validated (need to be paid),
+	//! 2=classified paid partially (close_code='discount_vat','badcustomer') or completely (close_code=null),
+	//! 3=classified abandoned and no payment done (close_code='badcustomer','abandon' or 'replaced')
+	var $statut;
+	//! Fermeture apres paiement partiel: discount_vat, badcustomer, abandon
+	//! Fermeture alors que aucun paiement: replaced (si remplace), abandon
+	var $close_code;
+	//! Commentaire si mis a paye sans paiement complet
+	var $close_note;
+	//! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code
+	var $paye;
+	//! id of source invoice if replacement invoice or credit note
+	var $fk_facture_source;
+	var $origin;
+	var $origin_id;
+	var $linked_objects=array();
+	var $fk_project;
+	var $date_lim_reglement;
+	var $cond_reglement_id;			// Id in llx_c_paiement
+	var $cond_reglement_code;		// Code in llx_c_paiement
+	var $mode_reglement_id;			// Id in llx_c_paiement
+	var $mode_reglement_code;		// Code in llx_c_paiement
+	var $fk_bank;					// Field to store bank id to use when payment mode is withdraw
+	var $modelpdf;
+	var $products=array();	// deprecated
+	var $lines=array();
+	var $line;
+	var $extraparams=array();
+	//! Pour board
+	var $nbtodo;
+	var $nbtodolate;
+	var $specimen;
+
+	var $fac_rec;
+
+
+	/**
+	 * 	Constructor
+	 *
 	 * 	@param	DoliDB		$db			Database handler
-     */
-    function __construct($db)
-    {
-        $this->db = $db;
-    }
-
-    /**
-     *	Create invoice in database
-     *  Note: this->ref can be set or empty. If empty, we will use "(PROV)"
-     *
-     *	@param	User	$user      		Object user that create
-     *	@param  int		$notrigger		1=Does not execute triggers, 0 otherwise
-     * 	@param	int		$forceduedate	1=Do not recalculate due date from payment condition but force it with value
-     *	@return	int						<0 if KO, >0 if OK
-     */
-    function create($user,$notrigger=0,$forceduedate=0)
-    {
-        global $langs,$conf,$mysoc,$hookmanager;
-        $error=0;
-
-        // Clean parameters
-        if (empty($this->type)) $this->type = 0;
-        $this->ref_client=trim($this->ref_client);
-        $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated
-        $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note_private));
-        $this->note_public=trim($this->note_public);
-        if (! $this->cond_reglement_id) $this->cond_reglement_id = 0;
-        if (! $this->mode_reglement_id) $this->mode_reglement_id = 0;
-        $this->brouillon = 1;
-
-        dol_syslog(get_class($this)."::create user=".$user->id);
-
-        // Check parameters
-        if (empty($this->date) || empty($user->id))
-        {
-            $this->error="ErrorBadParameter";
-            dol_syslog(get_class($this)."::create Try to create an invoice with an empty parameter (user, date, ...)", LOG_ERR);
-            return -3;
-        }
-        $soc = new Societe($this->db);
-        $result=$soc->fetch($this->socid);
-        if ($result < 0)
-        {
-            $this->error="Failed to fetch company";
-            dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
-            return -2;
-        }
+	 */
+	function __construct($db)
+	{
+		$this->db = $db;
+	}
+
+	/**
+	 *	Create invoice in database
+	 *  Note: this->ref can be set or empty. If empty, we will use "(PROV)"
+	 *
+	 *	@param	User	$user      		Object user that create
+	 *	@param  int		$notrigger		1=Does not execute triggers, 0 otherwise
+	 * 	@param	int		$forceduedate	1=Do not recalculate due date from payment condition but force it with value
+	 *	@return	int						<0 if KO, >0 if OK
+	 */
+	function create($user,$notrigger=0,$forceduedate=0)
+	{
+		global $langs,$conf,$mysoc,$hookmanager;
+		$error=0;
 
-        $now=dol_now();
+		// Clean parameters
+		if (empty($this->type)) $this->type = 0;
+		$this->ref_client=trim($this->ref_client);
+		$this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated
+		$this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note_private));
+		$this->note_public=trim($this->note_public);
+		if (! $this->cond_reglement_id) $this->cond_reglement_id = 0;
+		if (! $this->mode_reglement_id) $this->mode_reglement_id = 0;
+		$this->brouillon = 1;
 
-        $this->db->begin();
+		dol_syslog(get_class($this)."::create user=".$user->id);
 
-        // Create invoice from a predefined invoice
-        if ($this->fac_rec > 0)
-        {
-            require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
-            $_facrec = new FactureRec($this->db);
-            $result=$_facrec->fetch($this->fac_rec);
-
-            $this->fk_project        = $_facrec->fk_project;
-            $this->cond_reglement    = $_facrec->cond_reglement_id;
-            $this->cond_reglement_id = $_facrec->cond_reglement_id;
-            $this->mode_reglement    = $_facrec->mode_reglement_id;
-            $this->mode_reglement_id = $_facrec->mode_reglement_id;
-            $this->remise_absolue    = $_facrec->remise_absolue;
-            $this->remise_percent    = $_facrec->remise_percent;
-
-            // Clean parametres
-            if (! $this->type) $this->type = 0;
-            $this->ref_client=trim($this->ref_client);
-            $this->note_private=trim($this->note_private);
-            $this->note_public=trim($this->note_public);
-            //if (! $this->remise) $this->remise = 0;
-            if (! $this->mode_reglement_id) $this->mode_reglement_id = 0;
-            $this->brouillon = 1;
-        }
+		// Check parameters
+		if (empty($this->date) || empty($user->id))
+		{
+			$this->error="ErrorBadParameter";
+			dol_syslog(get_class($this)."::create Try to create an invoice with an empty parameter (user, date, ...)", LOG_ERR);
+			return -3;
+		}
+		$soc = new Societe($this->db);
+		$result=$soc->fetch($this->socid);
+		if ($result < 0)
+		{
+			$this->error="Failed to fetch company";
+			dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
+			return -2;
+		}
 
-        // Define due date if not already defined
-        $datelim=(empty($forceduedate)?$this->calculate_date_lim_reglement():$forceduedate);
-
-        // Insert into database
-        $socid  = $this->socid;
-
-        $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture (";
-        $sql.= " facnumber";
-        $sql.= ", entity";
-        $sql.= ", ref_ext";
-        $sql.= ", type";
-        $sql.= ", fk_soc";
-        $sql.= ", datec";
-        $sql.= ", remise_absolue";
-        $sql.= ", remise_percent";
-        $sql.= ", datef";
-        $sql.= ", note_private";
-        $sql.= ", note_public";
-        $sql.= ", ref_client, ref_int";
-        $sql.= ", fk_facture_source, fk_user_author, fk_projet";
-        $sql.= ", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf";
-        $sql.= ")";
-        $sql.= " VALUES (";
-        $sql.= "'(PROV)'";
-        $sql.= ", ".$conf->entity;
-        $sql.= ", ".($this->ref_ext?"'".$this->db->escape($this->ref_ext)."'":"null");
-        $sql.= ", '".$this->type."'";
-        $sql.= ", '".$socid."'";
-        $sql.= ", '".$this->db->idate($now)."'";
-        $sql.= ",".($this->remise_absolue>0?$this->remise_absolue:'NULL');
-        $sql.= ",".($this->remise_percent>0?$this->remise_percent:'NULL');
-        $sql.= ", '".$this->db->idate($this->date)."'";
-        $sql.= ",".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null");
-        $sql.= ",".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null");
-        $sql.= ",".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null");
-        $sql.= ",".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null");
-        $sql.= ",".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null");
-        $sql.= ",".($user->id > 0 ? "'".$user->id."'":"null");
-        $sql.= ",".($this->fk_project?$this->fk_project:"null");
-        $sql.= ','.$this->cond_reglement_id;
-        $sql.= ",".$this->mode_reglement_id;
-        $sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."')";
-
-        dol_syslog(get_class($this)."::create sql=".$sql);
-        $resql=$this->db->query($sql);
-        if ($resql)
-        {
-            $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture');
-
-            // Update ref with new one
-            $this->ref='(PROV'.$this->id.')';
-            $sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET facnumber='".$this->ref."' WHERE rowid=".$this->id;
-
-            dol_syslog(get_class($this)."::create sql=".$sql);
-            $resql=$this->db->query($sql);
-            if (! $resql) $error++;
-
-            // Add object linked
-            if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects))
-            {
-            	foreach($this->linked_objects as $origin => $origin_id)
-            	{
-            		$ret = $this->add_object_linked($origin, $origin_id);
-            		if (! $ret)
-            		{
-            			dol_print_error($this->db);
-            			$error++;
-            		}
-
-            		// TODO mutualiser
-            		if ($origin == 'commande')
-            		{
-            			// On recupere les differents contact interne et externe
-            			$order = new Commande($this->db);
-            			$order->id = $origin_id;
-
-            			// On recupere le commercial suivi propale
-            			$this->userid = $order->getIdcontact('internal', 'SALESREPFOLL');
-
-            			if ($this->userid)
-            			{
-            				//On passe le commercial suivi commande en commercial suivi paiement
-            				$this->add_contact($this->userid[0], 'SALESREPFOLL', 'internal');
-            			}
-
-            			// On recupere le contact client facturation commande
-            			$this->contactid = $order->getIdcontact('external', 'BILLING');
-
-            			if ($this->contactid)
-            			{
-            				//On passe le contact client facturation commande en contact client facturation
-            				$this->add_contact($this->contactid[0], 'BILLING', 'external');
-            			}
-            		}
-            	}
-            }
-
-            /*
-             *  Insert lines of invoices into database
-             */
-            if (count($this->lines) && is_object($this->lines[0]))
-            {
-            	$fk_parent_line = 0;
-
-                dol_syslog("There is ".count($this->lines)." lines that are invoice lines objects");
-                foreach ($this->lines as $i => $val)
-                {
-                    $newinvoiceline=new FactureLigne($this->db);
-                    $newinvoiceline=$this->lines[$i];
-                    $newinvoiceline->fk_facture=$this->id;
-                    if ($result >= 0 && ($newinvoiceline->info_bits & 0x01) == 0)	// We keep only lines with first bit = 0
-                    {
-                    	// Reset fk_parent_line for no child products and special product
+		$now=dol_now();
+
+		$this->db->begin();
+
+		// Create invoice from a predefined invoice
+		if ($this->fac_rec > 0)
+		{
+			require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
+			$_facrec = new FactureRec($this->db);
+			$result=$_facrec->fetch($this->fac_rec);
+
+			$this->fk_project        = $_facrec->fk_project;
+			$this->cond_reglement    = $_facrec->cond_reglement_id;
+			$this->cond_reglement_id = $_facrec->cond_reglement_id;
+			$this->mode_reglement    = $_facrec->mode_reglement_id;
+			$this->mode_reglement_id = $_facrec->mode_reglement_id;
+			$this->remise_absolue    = $_facrec->remise_absolue;
+			$this->remise_percent    = $_facrec->remise_percent;
+
+			// Clean parametres
+			if (! $this->type) $this->type = 0;
+			$this->ref_client=trim($this->ref_client);
+			$this->note_private=trim($this->note_private);
+			$this->note_public=trim($this->note_public);
+			//if (! $this->remise) $this->remise = 0;
+			if (! $this->mode_reglement_id) $this->mode_reglement_id = 0;
+			$this->brouillon = 1;
+		}
+
+		// Define due date if not already defined
+		$datelim=(empty($forceduedate)?$this->calculate_date_lim_reglement():$forceduedate);
+
+		// Insert into database
+		$socid  = $this->socid;
+
+		$sql = "INSERT INTO ".MAIN_DB_PREFIX."facture (";
+		$sql.= " facnumber";
+		$sql.= ", entity";
+		$sql.= ", ref_ext";
+		$sql.= ", type";
+		$sql.= ", fk_soc";
+		$sql.= ", datec";
+		$sql.= ", remise_absolue";
+		$sql.= ", remise_percent";
+		$sql.= ", datef";
+		$sql.= ", note_private";
+		$sql.= ", note_public";
+		$sql.= ", ref_client, ref_int";
+		$sql.= ", fk_facture_source, fk_user_author, fk_projet";
+		$sql.= ", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf";
+		$sql.= ")";
+		$sql.= " VALUES (";
+		$sql.= "'(PROV)'";
+		$sql.= ", ".$conf->entity;
+		$sql.= ", ".($this->ref_ext?"'".$this->db->escape($this->ref_ext)."'":"null");
+		$sql.= ", '".$this->type."'";
+		$sql.= ", '".$socid."'";
+		$sql.= ", '".$this->db->idate($now)."'";
+		$sql.= ",".($this->remise_absolue>0?$this->remise_absolue:'NULL');
+		$sql.= ",".($this->remise_percent>0?$this->remise_percent:'NULL');
+		$sql.= ", '".$this->db->idate($this->date)."'";
+		$sql.= ",".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null");
+		$sql.= ",".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null");
+		$sql.= ",".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null");
+		$sql.= ",".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null");
+		$sql.= ",".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null");
+		$sql.= ",".($user->id > 0 ? "'".$user->id."'":"null");
+		$sql.= ",".($this->fk_project?$this->fk_project:"null");
+		$sql.= ','.$this->cond_reglement_id;
+		$sql.= ",".$this->mode_reglement_id;
+		$sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."')";
+
+		dol_syslog(get_class($this)."::create sql=".$sql);
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
+			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture');
+
+			// Update ref with new one
+			$this->ref='(PROV'.$this->id.')';
+			$sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET facnumber='".$this->ref."' WHERE rowid=".$this->id;
+
+			dol_syslog(get_class($this)."::create sql=".$sql);
+			$resql=$this->db->query($sql);
+			if (! $resql) $error++;
+
+			// Add object linked
+			if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects))
+			{
+				foreach($this->linked_objects as $origin => $origin_id)
+				{
+					$ret = $this->add_object_linked($origin, $origin_id);
+					if (! $ret)
+					{
+						dol_print_error($this->db);
+						$error++;
+					}
+
+					// TODO mutualiser
+					if ($origin == 'commande')
+					{
+						// On recupere les differents contact interne et externe
+						$order = new Commande($this->db);
+						$order->id = $origin_id;
+
+						// On recupere le commercial suivi propale
+						$this->userid = $order->getIdcontact('internal', 'SALESREPFOLL');
+
+						if ($this->userid)
+						{
+							//On passe le commercial suivi commande en commercial suivi paiement
+							$this->add_contact($this->userid[0], 'SALESREPFOLL', 'internal');
+						}
+
+						// On recupere le contact client facturation commande
+						$this->contactid = $order->getIdcontact('external', 'BILLING');
+
+						if ($this->contactid)
+						{
+							//On passe le contact client facturation commande en contact client facturation
+							$this->add_contact($this->contactid[0], 'BILLING', 'external');
+						}
+					}
+				}
+			}
+
+			/*
+			 *  Insert lines of invoices into database
+			*/
+			if (count($this->lines) && is_object($this->lines[0]))
+			{
+				$fk_parent_line = 0;
+
+				dol_syslog("There is ".count($this->lines)." lines that are invoice lines objects");
+				foreach ($this->lines as $i => $val)
+				{
+					$newinvoiceline=new FactureLigne($this->db);
+					$newinvoiceline=$this->lines[$i];
+					$newinvoiceline->fk_facture=$this->id;
+					if ($result >= 0 && ($newinvoiceline->info_bits & 0x01) == 0)	// We keep only lines with first bit = 0
+					{
+						// Reset fk_parent_line for no child products and special product
 						if (($newinvoiceline->product_type != 9 && empty($newinvoiceline->fk_parent_line)) || $newinvoiceline->product_type == 9) {
 							$fk_parent_line = 0;
 						}
 
-                    	$newinvoiceline->fk_parent_line=$fk_parent_line;
+						$newinvoiceline->fk_parent_line=$fk_parent_line;
 						$result=$newinvoiceline->insert();
 
-                    	// Defined the new fk_parent_line
+						// Defined the new fk_parent_line
 						if ($result > 0 && $newinvoiceline->product_type == 9) {
 							$fk_parent_line = $result;
 						}
-                    }
-                    if ($result < 0)
-                    {
-                        $this->error=$newinvoiceline->error;
-                        $error++;
-                        break;
-                    }
-                }
-            }
-            else
-            {
-            	$fk_parent_line = 0;
-
-                dol_syslog("There is ".count($this->lines)." lines that are array lines");
-                foreach ($this->lines as $i => $val)
-                {
-                    if (($this->lines[$i]->info_bits & 0x01) == 0)	// We keep only lines with first bit = 0
-                    {
-	                    // Reset fk_parent_line for no child products and special product
+					}
+					if ($result < 0)
+					{
+						$this->error=$newinvoiceline->error;
+						$error++;
+						break;
+					}
+				}
+			}
+			else
+			{
+				$fk_parent_line = 0;
+
+				dol_syslog("There is ".count($this->lines)." lines that are array lines");
+				foreach ($this->lines as $i => $val)
+				{
+					if (($this->lines[$i]->info_bits & 0x01) == 0)	// We keep only lines with first bit = 0
+					{
+						// Reset fk_parent_line for no child products and special product
 						if (($this->lines[$i]->product_type != 9 && empty($this->lines[$i]->fk_parent_line)) || $this->lines[$i]->product_type == 9) {
 							$fk_parent_line = 0;
 						}
 
-                        $result = $this->addline(
-                            $this->id,
-                            $this->lines[$i]->desc,
-                            $this->lines[$i]->subprice,
-                            $this->lines[$i]->qty,
-                            $this->lines[$i]->tva_tx,
-                            $this->lines[$i]->localtax1_tx,
-                            $this->lines[$i]->localtax2_tx,
-                            $this->lines[$i]->fk_product,
-                            $this->lines[$i]->remise_percent,
-                            $this->lines[$i]->date_start,
-                            $this->lines[$i]->date_end,
-                            $this->lines[$i]->fk_code_ventilation,
-                            $this->lines[$i]->info_bits,
-                            $this->lines[$i]->fk_remise_except,
-                            'HT',
-                            0,
-                            $this->lines[$i]->product_type,
-                            $this->lines[$i]->rang,
-                            $this->lines[$i]->special_code,
-                            '',
-                            0,
-                            $fk_parent_line,
-                            $this->lines[$i]->fk_fournprice,
-                            $this->lines[$i]->pa_ht,
-                        	$this->lines[$i]->label
-                        );
-                        if ($result < 0)
-                        {
-                            $this->error=$this->db->lasterror();
-                            dol_print_error($this->db);
-                            $this->db->rollback();
-                            return -1;
-                        }
-
-	                    // Defined the new fk_parent_line
+						$result = $this->addline(
+							$this->id,
+							$this->lines[$i]->desc,
+							$this->lines[$i]->subprice,
+							$this->lines[$i]->qty,
+							$this->lines[$i]->tva_tx,
+							$this->lines[$i]->localtax1_tx,
+							$this->lines[$i]->localtax2_tx,
+							$this->lines[$i]->fk_product,
+							$this->lines[$i]->remise_percent,
+							$this->lines[$i]->date_start,
+							$this->lines[$i]->date_end,
+							$this->lines[$i]->fk_code_ventilation,
+							$this->lines[$i]->info_bits,
+							$this->lines[$i]->fk_remise_except,
+							'HT',
+							0,
+							$this->lines[$i]->product_type,
+							$this->lines[$i]->rang,
+							$this->lines[$i]->special_code,
+							'',
+							0,
+							$fk_parent_line,
+							$this->lines[$i]->fk_fournprice,
+							$this->lines[$i]->pa_ht,
+							$this->lines[$i]->label
+						);
+						if ($result < 0)
+						{
+							$this->error=$this->db->lasterror();
+							dol_print_error($this->db);
+							$this->db->rollback();
+							return -1;
+						}
+
+						// Defined the new fk_parent_line
 						if ($result > 0 && $this->lines[$i]->product_type == 9) {
 							$fk_parent_line = $result;
 						}
-                    }
-                }
-            }
-
-            /*
-             * Insert lines of predefined invoices
-             */
-            if (! $error && $this->fac_rec > 0)
-            {
-                foreach ($_facrec->lines as $i => $val)
-                {
-                    if ($_facrec->lines[$i]->fk_product)
-                    {
-                        $prod = new Product($this->db);
-                        $res=$prod->fetch($_facrec->lines[$i]->fk_product);
-                    }
-                    $tva_tx = get_default_tva($mysoc,$soc,$prod->id);
-                    $localtax1_tx=get_localtax($tva_tx,1,$soc);
-                    $localtax2_tx=get_localtax($tva_tx,2,$soc);
-
-                    $result_insert = $this->addline(
-                        $this->id,
-                        $_facrec->lines[$i]->desc,
-                        $_facrec->lines[$i]->subprice,
-                        $_facrec->lines[$i]->qty,
-                        $tva_tx,
-                        $localtax1_tx,
-                        $localtax2_tx,
-                        $_facrec->lines[$i]->fk_product,
-                        $_facrec->lines[$i]->remise_percent,
-                        '','',0,0,'','HT',0,
-                        $_facrec->lines[$i]->product_type,
-                        $_facrec->lines[$i]->rang,
-                        $_facrec->lines[$i]->special_code,
-                    	'',
-                    	0,
-                    	0,
-                    	null,
-                    	0,
-                    	$_facrec->lines[$i]->label
-                    );
-
-                    if ( $result_insert < 0)
-                    {
-                        $error++;
-                        $this->error=$this->db->error();
-                        break;
-                    }
-                }
-            }
-
-            if (! $error)
-            {
-                $result=$this->update_price(1);
-                if ($result > 0)
-                {
-                	// Actions on extra fields (by external module or standard code)
-                	// FIXME le hook fait double emploi avec le trigger !!
-                	$hookmanager->initHooks(array('invoicedao'));
-                	$parameters=array('invoiceid'=>$this->id);
-                	$reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
-                	if (empty($reshook))
-                	{
-                		if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
-                		{
-                			$result=$this->insertExtraFields();
-                			if ($result < 0)
-                			{
-                				$error++;
-                			}
-                		}
-                	}
-                	else if ($reshook < 0) $error++;
-
-                    // Appel des triggers
-                    include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-                    $interface=new Interfaces($this->db);
-                    $result=$interface->run_triggers('BILL_CREATE',$this,$user,$langs,$conf);
-                    if ($result < 0) { $error++; $this->errors=$interface->errors; }
-                    // Fin appel triggers
-
-                    if (! $error)
-                    {
-                        $this->db->commit();
-                        return $this->id;
-                    }
-                    else
-                    {
-                        $this->db->rollback();
-                        return -4;
-                    }
-                }
-                else
-                {
-                    $this->error=$langs->trans('FailedToUpdatePrice');
-                    $this->db->rollback();
-                    return -3;
-                }
-            }
-            else
-            {
-                dol_syslog(get_class($this)."::create error ".$this->error, LOG_ERR);
-                $this->db->rollback();
-                return -2;
-            }
-        }
-        else
-        {
-            $this->error=$this->db->error();
-            dol_syslog(get_class($this)."::create error ".$this->error." sql=".$sql, LOG_ERR);
-            $this->db->rollback();
-            return -1;
-        }
-    }
-
-
-    /**
-     *	Create a new invoice in database from current invoice
-     *
-     *	@param      User	$user    		Object user that ask creation
-     *	@param		int		$invertdetail	Reverse sign of amounts for lines
-     *	@return		int						<0 if KO, >0 if OK
-     */
-    function createFromCurrent($user,$invertdetail=0)
-    {
-        // Charge facture source
-        $facture=new Facture($this->db);
-
-        $facture->fk_facture_source = $this->fk_facture_source;
-        $facture->type 			    = $this->type;
-        $facture->socid 		    = $this->socid;
-        $facture->date              = $this->date;
-        $facture->note_public       = $this->note_public;
-        $facture->note_private      = $this->note_private;
-        $facture->ref_client        = $this->ref_client;
-        $facture->modelpdf          = $this->modelpdf;
-        $facture->fk_project        = $this->fk_project;
-        $facture->cond_reglement_id = $this->cond_reglement_id;
-        $facture->mode_reglement_id = $this->mode_reglement_id;
-        $facture->remise_absolue    = $this->remise_absolue;
-        $facture->remise_percent    = $this->remise_percent;
-
-        $facture->lines		    	= $this->lines;	// Tableau des lignes de factures
-        $facture->products		    = $this->lines;	// Tant que products encore utilise
-
-        // Loop on each line of new invoice
-        foreach($facture->lines as $i => $line)
-        {
-            if ($invertdetail)
-            {
-                $facture->lines[$i]->subprice  = -$facture->lines[$i]->subprice;
-                $facture->lines[$i]->total_ht  = -$facture->lines[$i]->total_ht;
-                $facture->lines[$i]->total_tva = -$facture->lines[$i]->total_tva;
-                $facture->lines[$i]->total_localtax1 = -$facture->lines[$i]->total_localtax1;
-                $facture->lines[$i]->total_localtax2 = -$facture->lines[$i]->total_localtax2;
-                $facture->lines[$i]->total_ttc = -$facture->lines[$i]->total_ttc;
-            }
-        }
+					}
+				}
+			}
 
-        dol_syslog(get_class($this)."::createFromCurrent invertdetail=".$invertdetail." socid=".$this->socid." nboflines=".count($facture->lines));
+			/*
+			 * Insert lines of predefined invoices
+			*/
+			if (! $error && $this->fac_rec > 0)
+			{
+				foreach ($_facrec->lines as $i => $val)
+				{
+					if ($_facrec->lines[$i]->fk_product)
+					{
+						$prod = new Product($this->db);
+						$res=$prod->fetch($_facrec->lines[$i]->fk_product);
+					}
+					$tva_tx = get_default_tva($mysoc,$soc,$prod->id);
+					$localtax1_tx=get_localtax($tva_tx,1,$soc);
+					$localtax2_tx=get_localtax($tva_tx,2,$soc);
+
+					$result_insert = $this->addline(
+						$this->id,
+						$_facrec->lines[$i]->desc,
+						$_facrec->lines[$i]->subprice,
+						$_facrec->lines[$i]->qty,
+						$tva_tx,
+						$localtax1_tx,
+						$localtax2_tx,
+						$_facrec->lines[$i]->fk_product,
+						$_facrec->lines[$i]->remise_percent,
+						'','',0,0,'','HT',0,
+						$_facrec->lines[$i]->product_type,
+						$_facrec->lines[$i]->rang,
+						$_facrec->lines[$i]->special_code,
+						'',
+						0,
+						0,
+						null,
+						0,
+						$_facrec->lines[$i]->label
+					);
+
+					if ( $result_insert < 0)
+					{
+						$error++;
+						$this->error=$this->db->error();
+						break;
+					}
+				}
+			}
 
-        $facid = $facture->create($user);
-        if ($facid <= 0)
-        {
-            $this->error=$facture->error;
-            $this->errors=$facture->errors;
-        }
+			if (! $error)
+			{
+				$result=$this->update_price(1);
+				if ($result > 0)
+				{
+					// Actions on extra fields (by external module or standard code)
+					// FIXME le hook fait double emploi avec le trigger !!
+					$hookmanager->initHooks(array('invoicedao'));
+					$parameters=array('invoiceid'=>$this->id);
+					$reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
+					if (empty($reshook))
+					{
+						if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
+						{
+							$result=$this->insertExtraFields();
+							if ($result < 0)
+							{
+								$error++;
+							}
+						}
+					}
+					else if ($reshook < 0) $error++;
+
+					// Appel des triggers
+					include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+					$interface=new Interfaces($this->db);
+					$result=$interface->run_triggers('BILL_CREATE',$this,$user,$langs,$conf);
+					if ($result < 0) {
+						$error++; $this->errors=$interface->errors;
+					}
+					// Fin appel triggers
+
+					if (! $error)
+					{
+						$this->db->commit();
+						return $this->id;
+					}
+					else
+					{
+						$this->db->rollback();
+						return -4;
+					}
+				}
+				else
+				{
+					$this->error=$langs->trans('FailedToUpdatePrice');
+					$this->db->rollback();
+					return -3;
+				}
+			}
+			else
+			{
+				dol_syslog(get_class($this)."::create error ".$this->error, LOG_ERR);
+				$this->db->rollback();
+				return -2;
+			}
+		}
+		else
+		{
+			$this->error=$this->db->error();
+			dol_syslog(get_class($this)."::create error ".$this->error." sql=".$sql, LOG_ERR);
+			$this->db->rollback();
+			return -1;
+		}
+	}
 
-        return $facid;
-    }
 
+	/**
+	 *	Create a new invoice in database from current invoice
+	 *
+	 *	@param      User	$user    		Object user that ask creation
+	 *	@param		int		$invertdetail	Reverse sign of amounts for lines
+	 *	@return		int						<0 if KO, >0 if OK
+	 */
+	function createFromCurrent($user,$invertdetail=0)
+	{
+		// Charge facture source
+		$facture=new Facture($this->db);
+
+		$facture->fk_facture_source = $this->fk_facture_source;
+		$facture->type 			    = $this->type;
+		$facture->socid 		    = $this->socid;
+		$facture->date              = $this->date;
+		$facture->note_public       = $this->note_public;
+		$facture->note_private      = $this->note_private;
+		$facture->ref_client        = $this->ref_client;
+		$facture->modelpdf          = $this->modelpdf;
+		$facture->fk_project        = $this->fk_project;
+		$facture->cond_reglement_id = $this->cond_reglement_id;
+		$facture->mode_reglement_id = $this->mode_reglement_id;
+		$facture->remise_absolue    = $this->remise_absolue;
+		$facture->remise_percent    = $this->remise_percent;
+
+		$facture->lines		    	= $this->lines;	// Tableau des lignes de factures
+		$facture->products		    = $this->lines;	// Tant que products encore utilise
+
+		// Loop on each line of new invoice
+		foreach($facture->lines as $i => $line)
+		{
+			if ($invertdetail)
+			{
+				$facture->lines[$i]->subprice  = -$facture->lines[$i]->subprice;
+				$facture->lines[$i]->total_ht  = -$facture->lines[$i]->total_ht;
+				$facture->lines[$i]->total_tva = -$facture->lines[$i]->total_tva;
+				$facture->lines[$i]->total_localtax1 = -$facture->lines[$i]->total_localtax1;
+				$facture->lines[$i]->total_localtax2 = -$facture->lines[$i]->total_localtax2;
+				$facture->lines[$i]->total_ttc = -$facture->lines[$i]->total_ttc;
+			}
+		}
 
-    /**
-     *		Load an object from its id and create a new one in database
-     *
-     *		@param		int				$socid			Id of thirdparty
-     * 	 	@return		int								New id of clone
-     */
-    function createFromClone($socid=0)
-    {
-        global $conf,$user,$langs;
+		dol_syslog(get_class($this)."::createFromCurrent invertdetail=".$invertdetail." socid=".$this->socid." nboflines=".count($facture->lines));
 
-        $error=0;
+		$facid = $facture->create($user);
+		if ($facid <= 0)
+		{
+			$this->error=$facture->error;
+			$this->errors=$facture->errors;
+		}
 
-        $this->db->begin();
+		return $facid;
+	}
 
-        // Load source object
-        $objFrom = dol_clone($this);
 
-        // Change socid if needed
-        if (! empty($socid) && $socid != $this->socid)
-        {
-        	$objsoc = new Societe($this->db);
-
-        	if ($objsoc->fetch($socid)>0)
-        	{
-        		$this->socid 				= $objsoc->id;
-        		$this->cond_reglement_id	= (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
-        		$this->mode_reglement_id	= (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
-        		$this->fk_project			= '';
-        		$this->fk_delivery_address	= '';
-        	}
-
-        	// TODO Change product price if multi-prices
-        }
+	/**
+	 *		Load an object from its id and create a new one in database
+	 *
+	 *		@param		int				$socid			Id of thirdparty
+	 * 	 	@return		int								New id of clone
+	 */
+	function createFromClone($socid=0)
+	{
+		global $conf,$user,$langs;
 
-        $this->id=0;
-        $this->statut=0;
-
-        // Clear fields
-        $this->user_author        = $user->id;
-        $this->user_valid         = '';
-        $this->fk_facture_source  = 0;
-        $this->date_creation      = '';
-        $this->date_validation    = '';
-        $this->ref_client         = '';
-        $this->close_code         = '';
-        $this->close_note         = '';
-        $this->products = $this->lines;	// Tant que products encore utilise
-
-        // Loop on each line of new invoice
-        foreach($this->lines as $i => $line)
-        {
-            if (($this->lines[$i]->info_bits & 0x02) == 0x02)	// We do not clone line of discounts
-            {
-                unset($this->lines[$i]);
-                unset($this->products[$i]);	// Tant que products encore utilise
-            }
-        }
+		$error=0;
+
+		$this->db->begin();
 
-        // Create clone
-        $result=$this->create($user);
-        if ($result < 0) $error++;
+		// Load source object
+		$objFrom = dol_clone($this);
 
-        if (! $error)
-        {
-        	// Hook of thirdparty module
+		// Change socid if needed
+		if (! empty($socid) && $socid != $this->socid)
+		{
+			$objsoc = new Societe($this->db);
+
+			if ($objsoc->fetch($socid)>0)
+			{
+				$this->socid 				= $objsoc->id;
+				$this->cond_reglement_id	= (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
+				$this->mode_reglement_id	= (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
+				$this->fk_project			= '';
+				$this->fk_delivery_address	= '';
+			}
+
+			// TODO Change product price if multi-prices
+		}
+
+		$this->id=0;
+		$this->statut=0;
+
+		// Clear fields
+		$this->user_author        = $user->id;
+		$this->user_valid         = '';
+		$this->fk_facture_source  = 0;
+		$this->date_creation      = '';
+		$this->date_validation    = '';
+		$this->ref_client         = '';
+		$this->close_code         = '';
+		$this->close_note         = '';
+		$this->products = $this->lines;	// Tant que products encore utilise
+
+		// Loop on each line of new invoice
+		foreach($this->lines as $i => $line)
+		{
+			if (($this->lines[$i]->info_bits & 0x02) == 0x02)	// We do not clone line of discounts
+			{
+				unset($this->lines[$i]);
+				unset($this->products[$i]);	// Tant que products encore utilise
+			}
+		}
+
+		// Create clone
+		$result=$this->create($user);
+		if ($result < 0) $error++;
+
+		if (! $error)
+		{
+			// Hook of thirdparty module
 			if (is_object($hookmanager))
 			{
-			    $parameters=array('objFrom'=>$objFrom);
-			    $action='';
+				$parameters=array('objFrom'=>$objFrom);
+				$action='';
 				$reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
 				if ($reshook < 0) $error++;
 			}
 
-            // Appel des triggers
-            include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-            $interface=new Interfaces($this->db);
-            $result=$interface->run_triggers('BILL_CLONE',$this,$user,$langs,$conf);
-            if ($result < 0) { $error++; $this->errors=$interface->errors; }
-            // Fin appel triggers
-        }
+			// Appel des triggers
+			include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+			$interface=new Interfaces($this->db);
+			$result=$interface->run_triggers('BILL_CLONE',$this,$user,$langs,$conf);
+			if ($result < 0) {
+				$error++; $this->errors=$interface->errors;
+			}
+			// Fin appel triggers
+		}
 
-        // End
-        if (! $error)
-        {
-            $this->db->commit();
-            return $this->id;
-        }
-        else
-        {
-            $this->db->rollback();
-            return -1;
-        }
-    }
-
-    /**
-     *  Load an object from an order and create a new invoice into database
-     *
-     *  @param      Object			$object         	Object source
-     *  @return     int             					<0 if KO, 0 if nothing done, 1 if OK
-     */
-    function createFromOrder($object)
-    {
-        global $conf,$user,$langs,$hookmanager;
-
-        $error=0;
-
-        // Closed order
-        $this->date = dol_now();
-        $this->source = 0;
-
-        $num=count($object->lines);
-        for ($i = 0; $i < $num; $i++)
-        {
-            $line = new FactureLigne($this->db);
-
-            $line->libelle			= $object->lines[$i]->libelle;
-            $line->label			= $object->lines[$i]->label;
-            $line->desc				= $object->lines[$i]->desc;
-            $line->subprice			= $object->lines[$i]->subprice;
-            $line->total_ht			= $object->lines[$i]->total_ht;
-            $line->total_tva		= $object->lines[$i]->total_tva;
-            $line->total_ttc		= $object->lines[$i]->total_ttc;
-            $line->tva_tx			= $object->lines[$i]->tva_tx;
-            $line->localtax1_tx		= $object->lines[$i]->localtax1_tx;
-            $line->localtax2_tx		= $object->lines[$i]->localtax2_tx;
-            $line->qty				= $object->lines[$i]->qty;
-            $line->fk_remise_except	= $object->lines[$i]->fk_remise_except;
-            $line->remise_percent	= $object->lines[$i]->remise_percent;
-            $line->fk_product		= $object->lines[$i]->fk_product;
-            $line->info_bits		= $object->lines[$i]->info_bits;
-            $line->product_type		= $object->lines[$i]->product_type;
-            $line->rang				= $object->lines[$i]->rang;
-            $line->special_code		= $object->lines[$i]->special_code;
-            $line->fk_parent_line	= $object->lines[$i]->fk_parent_line;
-
-            $this->lines[$i] = $line;
-        }
+		// End
+		if (! $error)
+		{
+			$this->db->commit();
+			return $this->id;
+		}
+		else
+		{
+			$this->db->rollback();
+			return -1;
+		}
+	}
 
-        $this->socid                = $object->socid;
-        $this->fk_project           = $object->fk_project;
-        $this->cond_reglement_id    = $object->cond_reglement_id;
-        $this->mode_reglement_id    = $object->mode_reglement_id;
-        $this->availability_id      = $object->availability_id;
-        $this->demand_reason_id     = $object->demand_reason_id;
-        $this->date_livraison       = $object->date_livraison;
-        $this->fk_delivery_address  = $object->fk_delivery_address;
-        $this->contact_id           = $object->contactid;
-        $this->ref_client           = $object->ref_client;
-        $this->note_private         = $object->note_private;
-        $this->note_public          = $object->note_public;
-
-        $this->origin				= $object->element;
-        $this->origin_id			= $object->id;
-
-        // Possibility to add external linked objects with hooks
-        $this->linked_objects[$this->origin] = $this->origin_id;
-        if (! empty($object->other_linked_objects) && is_array($object->other_linked_objects))
-        {
-        	$this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
-        }
+	/**
+	 *  Load an object from an order and create a new invoice into database
+	 *
+	 *  @param      Object			$object         	Object source
+	 *  @return     int             					<0 if KO, 0 if nothing done, 1 if OK
+	 */
+	function createFromOrder($object)
+	{
+		global $conf,$user,$langs,$hookmanager;
 
-        $ret = $this->create($user);
+		$error=0;
 
-        if ($ret > 0)
-        {
-            // Actions hooked (by external module)
-            $hookmanager->initHooks(array('invoicedao'));
+		// Closed order
+		$this->date = dol_now();
+		$this->source = 0;
 
-            $parameters=array('objFrom'=>$object);
-            $action='';
+		$num=count($object->lines);
+		for ($i = 0; $i < $num; $i++)
+		{
+			$line = new FactureLigne($this->db);
+
+			$line->libelle			= $object->lines[$i]->libelle;
+			$line->label			= $object->lines[$i]->label;
+			$line->desc				= $object->lines[$i]->desc;
+			$line->subprice			= $object->lines[$i]->subprice;
+			$line->total_ht			= $object->lines[$i]->total_ht;
+			$line->total_tva		= $object->lines[$i]->total_tva;
+			$line->total_ttc		= $object->lines[$i]->total_ttc;
+			$line->tva_tx			= $object->lines[$i]->tva_tx;
+			$line->localtax1_tx		= $object->lines[$i]->localtax1_tx;
+			$line->localtax2_tx		= $object->lines[$i]->localtax2_tx;
+			$line->qty				= $object->lines[$i]->qty;
+			$line->fk_remise_except	= $object->lines[$i]->fk_remise_except;
+			$line->remise_percent	= $object->lines[$i]->remise_percent;
+			$line->fk_product		= $object->lines[$i]->fk_product;
+			$line->info_bits		= $object->lines[$i]->info_bits;
+			$line->product_type		= $object->lines[$i]->product_type;
+			$line->rang				= $object->lines[$i]->rang;
+			$line->special_code		= $object->lines[$i]->special_code;
+			$line->fk_parent_line	= $object->lines[$i]->fk_parent_line;
+
+			$this->lines[$i] = $line;
+		}
+
+		$this->socid                = $object->socid;
+		$this->fk_project           = $object->fk_project;
+		$this->cond_reglement_id    = $object->cond_reglement_id;
+		$this->mode_reglement_id    = $object->mode_reglement_id;
+		$this->availability_id      = $object->availability_id;
+		$this->demand_reason_id     = $object->demand_reason_id;
+		$this->date_livraison       = $object->date_livraison;
+		$this->fk_delivery_address  = $object->fk_delivery_address;
+		$this->contact_id           = $object->contactid;
+		$this->ref_client           = $object->ref_client;
+		$this->note_private         = $object->note_private;
+		$this->note_public          = $object->note_public;
+
+		$this->origin				= $object->element;
+		$this->origin_id			= $object->id;
+
+		// Possibility to add external linked objects with hooks
+		$this->linked_objects[$this->origin] = $this->origin_id;
+		if (! empty($object->other_linked_objects) && is_array($object->other_linked_objects))
+		{
+			$this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
+		}
+
+		$ret = $this->create($user);
+
+		if ($ret > 0)
+		{
+			// Actions hooked (by external module)
+			$hookmanager->initHooks(array('invoicedao'));
+
+			$parameters=array('objFrom'=>$object);
+			$action='';
 			$reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
 			if ($reshook < 0) $error++;
 
-            if (! $error)
-            {
-                return 1;
-            }
-            else return -1;
-        }
-        else return -1;
-    }
-
-    /**
-     *      Return clicable link of object (with eventually picto)
-     *
-     *      @param	int		$withpicto       Add picto into link
-     *      @param  string	$option          Where point the link
-     *      @param  int		$max             Maxlength of ref
-     *      @param  int		$short           1=Return just URL
-     *      @param  string  $moretitle       Add more text to title tooltip
-     *      @return string 			         String with URL
-     */
-    function getNomUrl($withpicto=0,$option='',$max=0,$short=0,$moretitle='')
-    {
-        global $langs;
-
-        $result='';
-
-        if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id;
-        else $url = DOL_URL_ROOT.'/compta/facture.php?facid='.$this->id;
-
-        if ($short) return $url;
-
-        $picto='bill';
-        if ($this->type == 1) $picto.='r';	// Replacement invoice
-        if ($this->type == 2) $picto.='a';	// Credit note
-        if ($this->type == 3) $picto.='d';	// Deposit invoice
-
-        $label=$langs->trans("ShowInvoice").': '.$this->ref;
-        if ($this->type == 1) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref;
-        if ($this->type == 2) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref;
-        if ($this->type == 3) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref;
-        if ($moretitle) $label.=' - '.$moretitle;
-
-        //$linkstart='<a href="'.$url.'" title="'.dol_escape_htmltag($label).'">';
-        $linkstart='<a href="'.$url.'">';
-        $linkend='</a>';
-
-        if ($withpicto) $result.=($linkstart.img_object(($max?dol_trunc($label,$max):$label),$picto).$linkend);
-        if ($withpicto && $withpicto != 2) $result.=' ';
-        if ($withpicto != 2) $result.=$linkstart.($max?dol_trunc($this->ref,$max):$this->ref).$linkend;
-        return $result;
-    }
-
-
-    /**
-     *	Get object and lines from database
-     *
-     *	@param      int		$rowid       	Id of object to load
-     * 	@param		string	$ref			Reference of invoice
-     * 	@param		string	$ref_ext		External reference of invoice
-     * 	@param		int		$ref_int		Internal reference of other object
-     *	@return     int         			>0 if OK, <0 if KO, 0 if not found
-     */
-    function fetch($rowid, $ref='', $ref_ext='', $ref_int='')
-    {
-        global $conf;
-
-        if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1;
-
-        $sql = 'SELECT f.rowid,f.facnumber,f.ref_client,f.ref_ext,f.ref_int,f.type,f.fk_soc,f.amount,f.tva, f.localtax1, f.localtax2, f.total, f.total_ttc, f.revenuestamp';
-        $sql.= ', f.remise_percent, f.remise_absolue, f.remise';
-        $sql.= ', f.datef as df';
-        $sql.= ', f.date_lim_reglement as dlr';
-        $sql.= ', f.datec as datec';
-        $sql.= ', f.date_valid as datev';
-        $sql.= ', f.tms as datem';
-        $sql.= ', f.note_private, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.fk_user_valid, f.model_pdf';
-        $sql.= ', f.fk_facture_source';
-        $sql.= ', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet, f.extraparams';
-        $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
-        $sql.= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc';
-        $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f';
-        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
-        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id';
-        $sql.= ' WHERE f.entity = '.$conf->entity;
-        if ($rowid)   $sql.= " AND f.rowid=".$rowid;
-        if ($ref)     $sql.= " AND f.facnumber='".$this->db->escape($ref)."'";
-        if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'";
-        if ($ref_int) $sql.= " AND f.ref_int='".$this->db->escape($ref_int)."'";
-
-        dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG);
-        $result = $this->db->query($sql);
-        if ($result)
-        {
-            if ($this->db->num_rows($result))
-            {
-                $obj = $this->db->fetch_object($result);
-
-                $this->id					= $obj->rowid;
-                $this->ref					= $obj->facnumber;
-                $this->ref_client			= $obj->ref_client;
-                $this->ref_ext				= $obj->ref_ext;
-                $this->ref_int				= $obj->ref_int;
-                $this->type					= $obj->type;
-                $this->date					= $this->db->jdate($obj->df);
-                $this->date_creation		= $this->db->jdate($obj->datec);
-                $this->date_validation		= $this->db->jdate($obj->datev);
-                $this->datem				= $this->db->jdate($obj->datem);
-                $this->remise_percent		= $obj->remise_percent;
-                $this->remise_absolue		= $obj->remise_absolue;
-                //$this->remise				= $obj->remise;
-                $this->total_ht				= $obj->total;
-                $this->total_tva			= $obj->tva;
-                $this->total_localtax1		= $obj->localtax1;
-                $this->total_localtax2		= $obj->localtax2;
-                $this->total_ttc			= $obj->total_ttc;
-                $this->revenuestamp         = $obj->revenuestamp;
-                $this->paye					= $obj->paye;
-                $this->close_code			= $obj->close_code;
-                $this->close_note			= $obj->close_note;
-                $this->socid				= $obj->fk_soc;
-                $this->statut				= $obj->fk_statut;
-                $this->date_lim_reglement	= $this->db->jdate($obj->dlr);
-                $this->mode_reglement_id	= $obj->fk_mode_reglement;
-                $this->mode_reglement_code	= $obj->mode_reglement_code;
-                $this->mode_reglement		= $obj->mode_reglement_libelle;
-                $this->cond_reglement_id	= $obj->fk_cond_reglement;
-                $this->cond_reglement_code	= $obj->cond_reglement_code;
-                $this->cond_reglement		= $obj->cond_reglement_libelle;
-                $this->cond_reglement_doc	= $obj->cond_reglement_libelle_doc;
-                $this->fk_project			= $obj->fk_projet;
-                $this->fk_facture_source	= $obj->fk_facture_source;
-                $this->note					= $obj->note_private;	// deprecated
-                $this->note_private			= $obj->note_private;
-                $this->note_public			= $obj->note_public;
-                $this->user_author			= $obj->fk_user_author;
-                $this->user_valid			= $obj->fk_user_valid;
-                $this->modelpdf				= $obj->model_pdf;
-
-                $this->extraparams			= (array) json_decode($obj->extraparams, true);
-
-                if ($this->statut == 0)	$this->brouillon = 1;
-
-                // Retreive all extrafield for invoice
-                // fetch optionals attributes and labels
-                if(!class_exists('Extrafields'))
-                	require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php');
-                $extrafields=new ExtraFields($this->db);
-                $extralabels=$extrafields->fetch_name_optionals_label('facture',true);
-                if (count($extralabels)>0) {
-                	$this->array_options = array();
-                }
-                foreach($extrafields->attribute_label as $key=>$label)
-                {
-                	$this->array_options['options_'.$key]=$label;
-                }
-
-                /*
-                 * Lines
-                 */
-
-                $this->lines  = array();
-
-                $result=$this->fetch_lines();
-                if ($result < 0)
-                {
-                    $this->error=$this->db->error();
-                    dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR);
-                    return -3;
-                }
-                return 1;
-            }
-            else
-            {
-                $this->error='Bill with id '.$rowid.' or ref '.$ref.' not found sql='.$sql;
-                dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR);
-                return 0;
-            }
-        }
-        else
-        {
-            $this->error=$this->db->error();
-            dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR);
-            return -1;
-        }
-    }
-
-
-    /**
-     *	Load all detailed lines into this->lines
-     *
-     *	@return     int         1 if OK, < 0 if KO
-     */
-    function fetch_lines()
-    {
-        $this->lines=array();
-
-        $sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.tva_tx, ';
-        $sql.= ' l.localtax1_tx, l.localtax2_tx, l.remise, l.remise_percent, l.fk_remise_except, l.subprice,';
-        $sql.= ' l.rang, l.special_code,';
-        $sql.= ' l.date_start as date_start, l.date_end as date_end,';
-        $sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
-        $sql.= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
-        $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l';
-        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
-        $sql.= ' WHERE l.fk_facture = '.$this->id;
-        $sql.= ' ORDER BY l.rang';
-
-        dol_syslog(get_class($this).'::fetch_lines sql='.$sql, LOG_DEBUG);
-        $result = $this->db->query($sql);
-        if ($result)
-        {
-            $num = $this->db->num_rows($result);
-            $i = 0;
-            while ($i < $num)
-            {
-                $objp = $this->db->fetch_object($result);
-                $line = new FactureLigne($this->db);
-
-                $line->rowid	        = $objp->rowid;
-                $line->label            = $objp->custom_label;
-                $line->desc             = $objp->description;		// Description line
-                $line->product_type     = $objp->product_type;		// Type of line
-                $line->product_ref      = $objp->product_ref;		// Ref product
-                $line->libelle          = $objp->product_label;		// TODO deprecated
-                $line->product_label	= $objp->product_label;		// Label product
-                $line->product_desc     = $objp->product_desc;		// Description product
-                $line->fk_product_type  = $objp->fk_product_type;	// Type of product
-                $line->qty              = $objp->qty;
-                $line->subprice         = $objp->subprice;
-                $line->tva_tx           = $objp->tva_tx;
-                $line->localtax1_tx     = $objp->localtax1_tx;
-                $line->localtax2_tx     = $objp->localtax2_tx;
-                $line->remise_percent   = $objp->remise_percent;
-                $line->fk_remise_except = $objp->fk_remise_except;
-                $line->fk_product       = $objp->fk_product;
-                $line->date_start       = $this->db->jdate($objp->date_start);
-                $line->date_end         = $this->db->jdate($objp->date_end);
-                $line->date_start       = $this->db->jdate($objp->date_start);
-                $line->date_end         = $this->db->jdate($objp->date_end);
-                $line->info_bits        = $objp->info_bits;
-                $line->total_ht         = $objp->total_ht;
-                $line->total_tva        = $objp->total_tva;
-                $line->total_localtax1  = $objp->total_localtax1;
-                $line->total_localtax2  = $objp->total_localtax2;
-                $line->total_ttc        = $objp->total_ttc;
-                $line->code_ventilation = $objp->fk_code_ventilation;
-				$line->fk_fournprice 	= $objp->fk_fournprice;
-		      	$marginInfos			= getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
-		   		$line->pa_ht 			= $marginInfos[0];
-		    	$line->marge_tx			= $marginInfos[1];
-		     	$line->marque_tx		= $marginInfos[2];
-                $line->rang				= $objp->rang;
-                $line->special_code		= $objp->special_code;
-                $line->fk_parent_line	= $objp->fk_parent_line;
-
-                // Ne plus utiliser
-                //$line->price            = $objp->price;
-                //$line->remise           = $objp->remise;
-
-                $this->lines[$i] = $line;
-
-                $i++;
-            }
-            $this->db->free($result);
-            return 1;
-        }
-        else
-        {
-            $this->error=$this->db->error();
-            dol_syslog(get_class($this).'::fetch_lines '.$this->error,LOG_ERR);
-            return -3;
-        }
-    }
-
-
-    /**
-     *      Update database
-     *
-     *      @param      User	$user        	User that modify
-     *      @param      int		$notrigger	    0=launch triggers after, 1=disable triggers
-     *      @return     int      			   	<0 if KO, >0 if OK
-     */
-    function update($user=0, $notrigger=0)
-    {
-        global $conf, $langs;
-        $error=0;
-
-        // Clean parameters
-        if (empty($this->type)) $this->type=0;
-        if (isset($this->facnumber)) $this->facnumber=trim($this->ref);
-        if (isset($this->ref_client)) $this->ref_client=trim($this->ref_client);
-        if (isset($this->increment)) $this->increment=trim($this->increment);
-        if (isset($this->close_code)) $this->close_code=trim($this->close_code);
-        if (isset($this->close_note)) $this->close_note=trim($this->close_note);
-        if (isset($this->note) || isset($this->note_private)) $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private));		// deprecated
-        if (isset($this->note) || isset($this->note_private)) $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note));
-        if (isset($this->note_public)) $this->note_public=trim($this->note_public);
-        if (isset($this->modelpdf)) $this->modelpdf=trim($this->modelpdf);
-        if (isset($this->import_key)) $this->import_key=trim($this->import_key);
-
-        // Check parameters
-        // Put here code to add control on parameters values
-
-        // Update request
-        $sql = "UPDATE ".MAIN_DB_PREFIX."facture SET";
-
-        $sql.= " facnumber=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").",";
-        $sql.= " type=".(isset($this->type)?$this->type:"null").",";
-        $sql.= " ref_client=".(isset($this->ref_client)?"'".$this->db->escape($this->ref_client)."'":"null").",";
-        $sql.= " increment=".(isset($this->increment)?"'".$this->db->escape($this->increment)."'":"null").",";
-        $sql.= " fk_soc=".(isset($this->socid)?$this->socid:"null").",";
-        $sql.= " datec=".(strval($this->date_creation)!='' ? "'".$this->db->idate($this->date_creation)."'" : 'null').",";
-        $sql.= " datef=".(strval($this->date)!='' ? "'".$this->db->idate($this->date)."'" : 'null').",";
-        $sql.= " date_valid=".(strval($this->date_validation)!='' ? "'".$this->db->idate($this->date_validation)."'" : 'null').",";
-        $sql.= " paye=".(isset($this->paye)?$this->paye:"null").",";
-        $sql.= " remise_percent=".(isset($this->remise_percent)?$this->remise_percent:"null").",";
-        $sql.= " remise_absolue=".(isset($this->remise_absolue)?$this->remise_absolue:"null").",";
-        //$sql.= " remise=".(isset($this->remise)?$this->remise:"null").",";
-        $sql.= " close_code=".(isset($this->close_code)?"'".$this->db->escape($this->close_code)."'":"null").",";
-        $sql.= " close_note=".(isset($this->close_note)?"'".$this->db->escape($this->close_note)."'":"null").",";
-        $sql.= " tva=".(isset($this->total_tva)?$this->total_tva:"null").",";
-        $sql.= " localtax1=".(isset($this->total_localtax1)?$this->total_localtax1:"null").",";
-        $sql.= " localtax2=".(isset($this->total_localtax2)?$this->total_localtax2:"null").",";
-        $sql.= " total=".(isset($this->total_ht)?$this->total_ht:"null").",";
-        $sql.= " total_ttc=".(isset($this->total_ttc)?$this->total_ttc:"null").",";
-        $sql.= " revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp != '')?$this->revenuestamp:"null").",";
-        $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").",";
-        $sql.= " fk_user_author=".(isset($this->user_author)?$this->user_author:"null").",";
-        $sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").",";
-        $sql.= " fk_facture_source=".(isset($this->fk_facture_source)?$this->fk_facture_source:"null").",";
-        $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").",";
-        $sql.= " fk_cond_reglement=".(isset($this->cond_reglement_id)?$this->cond_reglement_id:"null").",";
-        $sql.= " fk_mode_reglement=".(isset($this->mode_reglement_id)?$this->mode_reglement_id:"null").",";
-        $sql.= " date_lim_reglement=".(strval($this->date_lim_reglement)!='' ? "'".$this->db->idate($this->date_lim_reglement)."'" : 'null').",";
-        $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").",";
-        $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").",";
-        $sql.= " model_pdf=".(isset($this->modelpdf)?"'".$this->db->escape($this->modelpdf)."'":"null").",";
-        $sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null")."";
-
-        $sql.= " WHERE rowid=".$this->id;
-
-        $this->db->begin();
-
-        dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG);
-        $resql = $this->db->query($sql);
-        if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
-
-        if (! $error)
-        {
-            if (! $notrigger)
-            {
-                // Call triggers
-                include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-                $interface=new Interfaces($this->db);
-                $result=$interface->run_triggers('BILL_MODIFY',$this,$user,$langs,$conf);
-                if ($result < 0) { $error++; $this->errors=$interface->errors; }
-                // End call triggers
-            }
-        }
-
-        // Commit or rollback
-        if ($error)
-        {
-            foreach($this->errors as $errmsg)
-            {
-                dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
-                $this->error.=($this->error?', '.$errmsg:$errmsg);
-            }
-            $this->db->rollback();
-            return -1*$error;
-        }
-        else
-        {
-            $this->db->commit();
-            return 1;
-        }
-    }
+			if (! $error)
+			{
+				return 1;
+			}
+			else return -1;
+		}
+		else return -1;
+	}
 
+	/**
+	 *      Return clicable link of object (with eventually picto)
+	 *
+	 *      @param	int		$withpicto       Add picto into link
+	 *      @param  string	$option          Where point the link
+	 *      @param  int		$max             Maxlength of ref
+	 *      @param  int		$short           1=Return just URL
+	 *      @param  string  $moretitle       Add more text to title tooltip
+	 *      @return string 			         String with URL
+	 */
+	function getNomUrl($withpicto=0,$option='',$max=0,$short=0,$moretitle='')
+	{
+		global $langs;
 
-    /**
-     *    Add a discount line into invoice using an existing absolute discount
-     *
-     *    @param     int	$idremise	Id of absolute discount
-     *    @return    int          		>0 if OK, <0 if KO
-     */
-    function insert_discount($idremise)
-    {
-        global $langs;
+		$result='';
 
-        include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
-        include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
+		if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id;
+		else $url = DOL_URL_ROOT.'/compta/facture.php?facid='.$this->id;
 
-        $this->db->begin();
+		if ($short) return $url;
 
-        $remise=new DiscountAbsolute($this->db);
-        $result=$remise->fetch($idremise);
+		$picto='bill';
+		if ($this->type == 1) $picto.='r';	// Replacement invoice
+		if ($this->type == 2) $picto.='a';	// Credit note
+		if ($this->type == 3) $picto.='d';	// Deposit invoice
 
-        if ($result > 0)
-        {
-            if ($remise->fk_facture)	// Protection against multiple submission
-            {
-                $this->error=$langs->trans("ErrorDiscountAlreadyUsed");
-                $this->db->rollback();
-                return -5;
-            }
-
-            $facligne=new FactureLigne($this->db);
-            $facligne->fk_facture=$this->id;
-            $facligne->fk_remise_except=$remise->id;
-            $facligne->desc=$remise->description;   	// Description ligne
-            $facligne->tva_tx=$remise->tva_tx;
-            $facligne->subprice=-$remise->amount_ht;
-            $facligne->fk_product=0;					// Id produit predefini
-            $facligne->qty=1;
-            $facligne->remise_percent=0;
-            $facligne->rang=-1;
-            $facligne->info_bits=2;
-
-            $facligne->total_ht  = -$remise->amount_ht;
-            $facligne->total_tva = -$remise->amount_tva;
-            $facligne->total_ttc = -$remise->amount_ttc;
-
-            $lineid=$facligne->insert();
-            if ($lineid > 0)
-            {
-                $result=$this->update_price(1);
-                if ($result > 0)
-                {
-                    // Create linke between discount and invoice line
-                    $result=$remise->link_to_invoice($lineid,0);
-                    if ($result < 0)
-                    {
-                        $this->error=$remise->error;
-                        $this->db->rollback();
-                        return -4;
-                    }
-
-                    $this->db->commit();
-                    return 1;
-                }
-                else
-                {
-                    $this->error=$facligne->error;
-                    $this->db->rollback();
-                    return -1;
-                }
-            }
-            else
-            {
-                $this->error=$facligne->error;
-                $this->db->rollback();
-                return -2;
-            }
-        }
-        else
-        {
-            $this->db->rollback();
-            return -3;
-        }
-    }
-
-    /**
-     *	Set customer ref
-     *
-     *	@param     	string	$ref_client		Customer ref
-     *	@return		int						<0 if KO, >0 if OK
-     */
-    function set_ref_client($ref_client)
-    {
-        $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
-        if (empty($ref_client))
-        $sql .= ' SET ref_client = NULL';
-        else
-        $sql .= ' SET ref_client = \''.$this->db->escape($ref_client).'\'';
-        $sql .= ' WHERE rowid = '.$this->id;
-        if ($this->db->query($sql))
-        {
-            $this->ref_client = $ref_client;
-            return 1;
-        }
-        else
-        {
-            dol_print_error($this->db);
-            return -1;
-        }
-    }
+		$label=$langs->trans("ShowInvoice").': '.$this->ref;
+		if ($this->type == 1) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref;
+		if ($this->type == 2) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref;
+		if ($this->type == 3) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref;
+		if ($moretitle) $label.=' - '.$moretitle;
 
-    /**
-     *	Delete invoice
-     *
-     *	@param     	int		$rowid      	Id of invoice to delete. If empty, we delete current instance of invoice
-     *	@param		int		$notrigger		1=Does not execute triggers, 0= execute triggers
-     *	@return		int						<0 if KO, >0 if OK
-     */
-    function delete($rowid=0, $notrigger=0)
-    {
-        global $user,$langs,$conf;
-        require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+		//$linkstart='<a href="'.$url.'" title="'.dol_escape_htmltag($label).'">';
+		$linkstart='<a href="'.$url.'">';
+		$linkend='</a>';
 
-        if (! $rowid) $rowid=$this->id;
+		if ($withpicto) $result.=($linkstart.img_object(($max?dol_trunc($label,$max):$label),$picto).$linkend);
+		if ($withpicto && $withpicto != 2) $result.=' ';
+		if ($withpicto != 2) $result.=$linkstart.($max?dol_trunc($this->ref,$max):$this->ref).$linkend;
+		return $result;
+	}
 
-        dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG);
 
-        // TODO Test if there is at least on payment. If yes, refuse to delete.
+	/**
+	 *	Get object and lines from database
+	 *
+	 *	@param      int		$rowid       	Id of object to load
+	 * 	@param		string	$ref			Reference of invoice
+	 * 	@param		string	$ref_ext		External reference of invoice
+	 * 	@param		int		$ref_int		Internal reference of other object
+	 *	@return     int         			>0 if OK, <0 if KO, 0 if not found
+	 */
+	function fetch($rowid, $ref='', $ref_ext='', $ref_int='')
+	{
+		global $conf;
+
+		if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1;
+
+		$sql = 'SELECT f.rowid,f.facnumber,f.ref_client,f.ref_ext,f.ref_int,f.type,f.fk_soc,f.amount,f.tva, f.localtax1, f.localtax2, f.total, f.total_ttc, f.revenuestamp';
+		$sql.= ', f.remise_percent, f.remise_absolue, f.remise';
+		$sql.= ', f.datef as df';
+		$sql.= ', f.date_lim_reglement as dlr';
+		$sql.= ', f.datec as datec';
+		$sql.= ', f.date_valid as datev';
+		$sql.= ', f.tms as datem';
+		$sql.= ', f.note_private, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.fk_user_valid, f.model_pdf';
+		$sql.= ', f.fk_facture_source';
+		$sql.= ', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet, f.extraparams';
+		$sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
+		$sql.= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc';
+		$sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f';
+		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
+		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id';
+		$sql.= ' WHERE f.entity = '.$conf->entity;
+		if ($rowid)   $sql.= " AND f.rowid=".$rowid;
+		if ($ref)     $sql.= " AND f.facnumber='".$this->db->escape($ref)."'";
+		if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'";
+		if ($ref_int) $sql.= " AND f.ref_int='".$this->db->escape($ref_int)."'";
+
+		dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG);
+		$result = $this->db->query($sql);
+		if ($result)
+		{
+			if ($this->db->num_rows($result))
+			{
+				$obj = $this->db->fetch_object($result);
+
+				$this->id					= $obj->rowid;
+				$this->ref					= $obj->facnumber;
+				$this->ref_client			= $obj->ref_client;
+				$this->ref_ext				= $obj->ref_ext;
+				$this->ref_int				= $obj->ref_int;
+				$this->type					= $obj->type;
+				$this->date					= $this->db->jdate($obj->df);
+				$this->date_creation		= $this->db->jdate($obj->datec);
+				$this->date_validation		= $this->db->jdate($obj->datev);
+				$this->datem				= $this->db->jdate($obj->datem);
+				$this->remise_percent		= $obj->remise_percent;
+				$this->remise_absolue		= $obj->remise_absolue;
+				//$this->remise				= $obj->remise;
+				$this->total_ht				= $obj->total;
+				$this->total_tva			= $obj->tva;
+				$this->total_localtax1		= $obj->localtax1;
+				$this->total_localtax2		= $obj->localtax2;
+				$this->total_ttc			= $obj->total_ttc;
+				$this->revenuestamp         = $obj->revenuestamp;
+				$this->paye					= $obj->paye;
+				$this->close_code			= $obj->close_code;
+				$this->close_note			= $obj->close_note;
+				$this->socid				= $obj->fk_soc;
+				$this->statut				= $obj->fk_statut;
+				$this->date_lim_reglement	= $this->db->jdate($obj->dlr);
+				$this->mode_reglement_id	= $obj->fk_mode_reglement;
+				$this->mode_reglement_code	= $obj->mode_reglement_code;
+				$this->mode_reglement		= $obj->mode_reglement_libelle;
+				$this->cond_reglement_id	= $obj->fk_cond_reglement;
+				$this->cond_reglement_code	= $obj->cond_reglement_code;
+				$this->cond_reglement		= $obj->cond_reglement_libelle;
+				$this->cond_reglement_doc	= $obj->cond_reglement_libelle_doc;
+				$this->fk_project			= $obj->fk_projet;
+				$this->fk_facture_source	= $obj->fk_facture_source;
+				$this->note					= $obj->note_private;	// deprecated
+				$this->note_private			= $obj->note_private;
+				$this->note_public			= $obj->note_public;
+				$this->user_author			= $obj->fk_user_author;
+				$this->user_valid			= $obj->fk_user_valid;
+				$this->modelpdf				= $obj->model_pdf;
+
+				$this->extraparams			= (array) json_decode($obj->extraparams, true);
+
+				if ($this->statut == 0)	$this->brouillon = 1;
+
+				// Retreive all extrafield for invoice
+				// fetch optionals attributes and labels
+				if(!class_exists('Extrafields'))
+					require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php');
+				$extrafields=new ExtraFields($this->db);
+				$extralabels=$extrafields->fetch_name_optionals_label('facture',true);
+				if (count($extralabels)>0) {
+					$this->array_options = array();
+				}
+				foreach($extrafields->attribute_label as $key=>$label)
+				{
+					$this->array_options['options_'.$key]=$label;
+				}
 
-        $error=0;
-        $this->db->begin();
+				/*
+				 * Lines
+				*/
 
-        if (! $error && ! $notrigger)
-        {
-        	// Appel des triggers
-        	include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-        	$interface=new Interfaces($this->db);
-        	$result=$interface->run_triggers('BILL_DELETE',$this,$user,$langs,$conf);
-        	if ($result < 0) {
-        		$error++; $this->errors=$interface->errors;
-        	}
-        	// Fin appel triggers
-        }
+				$this->lines  = array();
 
-        if (! $error)
-        {
-        	// Delete linked object
-        	$res = $this->deleteObjectLinked();
-        	if ($res < 0) $error++;
-        }
+				$result=$this->fetch_lines();
+				if ($result < 0)
+				{
+					$this->error=$this->db->error();
+					dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR);
+					return -3;
+				}
+				return 1;
+			}
+			else
+			{
+				$this->error='Bill with id '.$rowid.' or ref '.$ref.' not found sql='.$sql;
+				dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR);
+				return 0;
+			}
+		}
+		else
+		{
+			$this->error=$this->db->error();
+			dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR);
+			return -1;
+		}
+	}
 
-        if (! $error)
-        {
-        	// If invoice was converted into a discount not yet consumed, we remove discount
-            $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'societe_remise_except';
-            $sql.= ' WHERE fk_facture_source = '.$rowid;
-            $sql.= ' AND fk_facture_line IS NULL';
-            $resql=$this->db->query($sql);
-
-            // If invoice has consumned discounts
-            $this->fetch_lines();
-            $list_rowid_det=array();
-            foreach($this->lines as $key => $invoiceline)
-            {
-                $list_rowid_det[]=$invoiceline->rowid;
-            }
-
-            // Consumned discounts are freed
-            if (count($list_rowid_det))
-            {
-                $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
-                $sql.= ' SET fk_facture = NULL, fk_facture_line = NULL';
-                $sql.= ' WHERE fk_facture_line IN ('.join(',',$list_rowid_det).')';
-
-                dol_syslog(get_class($this)."::delete sql=".$sql);
-                if (! $this->db->query($sql))
-                {
-                    $this->error=$this->db->error()." sql=".$sql;
-                    dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
-                    $this->db->rollback();
-                    return -5;
-                }
-            }
-
-            // Delete invoice line
-            $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$rowid;
-            if ($this->db->query($sql) && $this->delete_linked_contact())
-            {
-                $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.$rowid;
-                $resql=$this->db->query($sql);
-                if ($resql)
-                {
-                	// On efface le repertoire de pdf provisoire
-                	$ref = dol_sanitizeFileName($this->ref);
-                	if ($conf->facture->dir_output)
-                	{
-                		$dir = $conf->facture->dir_output . "/" . $ref;
-                		$file = $conf->facture->dir_output . "/" . $ref . "/" . $ref . ".pdf";
-                		if (file_exists($file))	// We must delete all files before deleting directory
-                		{
-                			$ret=dol_delete_preview($this);
-
-                			if (! dol_delete_file($file,0,0,0,$this)) // For triggers
-                			{
-                				$this->error=$langs->trans("ErrorCanNotDeleteFile",$file);
-                				$this->db->rollback();
-                				return 0;
-                			}
-                		}
-                		if (file_exists($dir))
-                		{
-                			if (! dol_delete_dir_recursive($dir)) // For remove dir and meta
-                			{
-                				$this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
-                				$this->db->rollback();
-                				return 0;
-                			}
-                		}
-                	}
-
-                    $this->db->commit();
-                    return 1;
-                }
-                else
-                {
-                    $this->error=$this->db->lasterror()." sql=".$sql;
-                    dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
-                    $this->db->rollback();
-                    return -6;
-                }
-            }
-            else
-            {
-                $this->error=$this->db->lasterror()." sql=".$sql;
-                dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
-                $this->db->rollback();
-                return -4;
-            }
-        }
-        else
-        {
-            $this->error=$this->db->lasterror();
-            dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
-            $this->db->rollback();
-            return -2;
-        }
-    }
-
-
-    /**
-     *	Renvoi une date limite de reglement de facture en fonction des
-     *	conditions de reglements de la facture et date de facturation
-     *
-     *	@param      string	$cond_reglement   	Condition of payment (code or id) to use. If 0, we use current condition.
-     *	@return     date     			       	Date limite de reglement si ok, <0 si ko
-     */
-    function calculate_date_lim_reglement($cond_reglement=0)
-    {
-        if (! $cond_reglement) $cond_reglement=$this->cond_reglement_code;
-        if (! $cond_reglement) $cond_reglement=$this->cond_reglement_id;
-
-        $cdr_nbjour=0; $cdr_fdm=0; $cdr_decalage=0;
-
-        $sqltemp = 'SELECT c.fdm,c.nbjour,c.decalage';
-        $sqltemp.= ' FROM '.MAIN_DB_PREFIX.'c_payment_term as c';
-        if (is_numeric($cond_reglement)) $sqltemp.= " WHERE c.rowid=".$cond_reglement;
-        else $sqltemp.= " WHERE c.code='".$this->db->escape($cond_reglement)."'";
-
-        dol_syslog(get_class($this).'::calculate_date_lim_reglement sql='.$sqltemp);
-        $resqltemp=$this->db->query($sqltemp);
-        if ($resqltemp)
-        {
-            if ($this->db->num_rows($resqltemp))
-            {
-                $obj = $this->db->fetch_object($resqltemp);
-                $cdr_nbjour = $obj->nbjour;
-                $cdr_fdm = $obj->fdm;
-                $cdr_decalage = $obj->decalage;
-            }
-        }
-        else
-        {
-            $this->error=$this->db->error();
-            return -1;
-        }
-        $this->db->free($resqltemp);
 
-        /* Definition de la date limite */
+	/**
+	 *	Load all detailed lines into this->lines
+	 *
+	 *	@return     int         1 if OK, < 0 if KO
+	 */
+	function fetch_lines()
+	{
+		$this->lines=array();
+
+		$sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.tva_tx, ';
+		$sql.= ' l.localtax1_tx, l.localtax2_tx, l.remise, l.remise_percent, l.fk_remise_except, l.subprice,';
+		$sql.= ' l.rang, l.special_code,';
+		$sql.= ' l.date_start as date_start, l.date_end as date_end,';
+		$sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
+		$sql.= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
+		$sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l';
+		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
+		$sql.= ' WHERE l.fk_facture = '.$this->id;
+		$sql.= ' ORDER BY l.rang';
+
+		dol_syslog(get_class($this).'::fetch_lines sql='.$sql, LOG_DEBUG);
+		$result = $this->db->query($sql);
+		if ($result)
+		{
+			$num = $this->db->num_rows($result);
+			$i = 0;
+			while ($i < $num)
+			{
+				$objp = $this->db->fetch_object($result);
+				$line = new FactureLigne($this->db);
+
+				$line->rowid	        = $objp->rowid;
+				$line->label            = $objp->custom_label;
+				$line->desc             = $objp->description;		// Description line
+				$line->product_type     = $objp->product_type;		// Type of line
+				$line->product_ref      = $objp->product_ref;		// Ref product
+				$line->libelle          = $objp->product_label;		// TODO deprecated
+				$line->product_label	= $objp->product_label;		// Label product
+				$line->product_desc     = $objp->product_desc;		// Description product
+				$line->fk_product_type  = $objp->fk_product_type;	// Type of product
+				$line->qty              = $objp->qty;
+				$line->subprice         = $objp->subprice;
+				$line->tva_tx           = $objp->tva_tx;
+				$line->localtax1_tx     = $objp->localtax1_tx;
+				$line->localtax2_tx     = $objp->localtax2_tx;
+				$line->remise_percent   = $objp->remise_percent;
+				$line->fk_remise_except = $objp->fk_remise_except;
+				$line->fk_product       = $objp->fk_product;
+				$line->date_start       = $this->db->jdate($objp->date_start);
+				$line->date_end         = $this->db->jdate($objp->date_end);
+				$line->date_start       = $this->db->jdate($objp->date_start);
+				$line->date_end         = $this->db->jdate($objp->date_end);
+				$line->info_bits        = $objp->info_bits;
+				$line->total_ht         = $objp->total_ht;
+				$line->total_tva        = $objp->total_tva;
+				$line->total_localtax1  = $objp->total_localtax1;
+				$line->total_localtax2  = $objp->total_localtax2;
+				$line->total_ttc        = $objp->total_ttc;
+				$line->code_ventilation = $objp->fk_code_ventilation;
+				$line->fk_fournprice 	= $objp->fk_fournprice;
+				$marginInfos			= getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
+				$line->pa_ht 			= $marginInfos[0];
+				$line->marge_tx			= $marginInfos[1];
+				$line->marque_tx		= $marginInfos[2];
+				$line->rang				= $objp->rang;
+				$line->special_code		= $objp->special_code;
+				$line->fk_parent_line	= $objp->fk_parent_line;
 
-        // 1 : ajout du nombre de jours
-        $datelim = $this->date + ($cdr_nbjour * 3600 * 24);
+				// Ne plus utiliser
+				//$line->price            = $objp->price;
+				//$line->remise           = $objp->remise;
 
-        // 2 : application de la regle "fin de mois"
-        if ($cdr_fdm)
-        {
-            $mois=date('m', $datelim);
-            $annee=date('Y', $datelim);
-            if ($mois == 12)
-            {
-                $mois = 1;
-                $annee += 1;
-            }
-            else
-            {
-                $mois += 1;
-            }
-            // On se deplace au debut du mois suivant, et on retire un jour
-            $datelim=dol_mktime(12,0,0,$mois,1,$annee);
-            $datelim -= (3600 * 24);
-        }
+				$this->lines[$i] = $line;
 
-        // 3 : application du decalage
-        $datelim += ($cdr_decalage * 3600 * 24);
-
-        return $datelim;
-    }
-
-    /**
-     *  Tag la facture comme paye completement (close_code non renseigne) ou partiellement (close_code renseigne) + appel trigger BILL_PAYED
-     *
-     *  @param	User	$user      	Objet utilisateur qui modifie
-     *	@param  string	$close_code	Code renseigne si on classe a payee completement alors que paiement incomplet (cas escompte par exemple)
-     *	@param  string	$close_note	Commentaire renseigne si on classe a payee alors que paiement incomplet (cas escompte par exemple)
-     *  @return int         		<0 if KO, >0 if OK
-     */
-    function set_paid($user,$close_code='',$close_note='')
-    {
-        global $conf,$langs;
-        $error=0;
-
-        if ($this->paye != 1)
-        {
-            $this->db->begin();
-
-            dol_syslog(get_class($this)."::set_paid rowid=".$this->id, LOG_DEBUG);
-            $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET';
-            $sql.= ' fk_statut=2';
-            if (! $close_code) $sql.= ', paye=1';
-            if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'";
-            if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'";
-            $sql.= ' WHERE rowid = '.$this->id;
-
-            $resql = $this->db->query($sql);
-            if ($resql)
-            {
-                // Appel des triggers
-                include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-                $interface=new Interfaces($this->db);
-                $result=$interface->run_triggers('BILL_PAYED',$this,$user,$langs,$conf);
-                if ($result < 0) { $error++; $this->errors=$interface->errors; }
-                // Fin appel triggers
-            }
-            else
-            {
-                $error++;
-                $this->error=$this->db->error();
-                dol_print_error($this->db);
-            }
-
-            if (! $error)
-            {
-                $this->db->commit();
-                return 1;
-            }
-            else
-            {
-                $this->db->rollback();
-                return -1;
-            }
-        }
-        else
-        {
-            return 0;
-        }
-    }
-
-
-    /**
-     *  Tag la facture comme non payee completement + appel trigger BILL_UNPAYED
-     *	Fonction utilisee quand un paiement prelevement est refuse,
-     * 	ou quand une facture annulee et reouverte.
-     *
-     *  @param	User	$user       Object user that change status
-     *  @return int         		<0 if KO, >0 if OK
-     */
-    function set_unpaid($user)
-    {
-        global $conf,$langs;
-        $error=0;
-
-        $this->db->begin();
-
-        $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
-        $sql.= ' SET paye=0, fk_statut=1, close_code=null, close_note=null';
-        $sql.= ' WHERE rowid = '.$this->id;
-
-        dol_syslog(get_class($this)."::set_unpaid sql=".$sql);
-        $resql = $this->db->query($sql);
-        if ($resql)
-        {
-            // Appel des triggers
-            include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-            $interface=new Interfaces($this->db);
-            $result=$interface->run_triggers('BILL_UNPAYED',$this,$user,$langs,$conf);
-            if ($result < 0) { $error++; $this->errors=$interface->errors; }
-            // Fin appel triggers
-        }
-        else
-        {
-            $error++;
-            $this->error=$this->db->error();
-            dol_print_error($this->db);
-        }
+				$i++;
+			}
+			$this->db->free($result);
+			return 1;
+		}
+		else
+		{
+			$this->error=$this->db->error();
+			dol_syslog(get_class($this).'::fetch_lines '.$this->error,LOG_ERR);
+			return -3;
+		}
+	}
 
-        if (! $error)
-        {
-            $this->db->commit();
-            return 1;
-        }
-        else
-        {
-            $this->db->rollback();
-            return -1;
-        }
-    }
-
-
-    /**
-     *	Tag invoice as canceled, with no payment on it (example for replacement invoice or payment never received) + call trigger BILL_CANCEL
-     *	Warning, if option to decrease stock on invoice was set, this function does not change stock (it might be a cancel because
-     *  of no payment even if merchandises were sent).
-     *
-     *	@param	User	$user        	Object user making change
-     *	@param	string	$close_code		Code de fermeture
-     *	@param	string	$close_note		Comment
-     *	@return int         			<0 if KO, >0 if OK
-     */
-    function set_canceled($user,$close_code='',$close_note='')
-    {
-        global $conf,$langs;
 
+	/**
+	 *      Update database
+	 *
+	 *      @param      User	$user        	User that modify
+	 *      @param      int		$notrigger	    0=launch triggers after, 1=disable triggers
+	 *      @return     int      			   	<0 if KO, >0 if OK
+	 */
+	function update($user=0, $notrigger=0)
+	{
+		global $conf, $langs;
 		$error=0;
 
-        dol_syslog(get_class($this)."::set_canceled rowid=".$this->id, LOG_DEBUG);
+		// Clean parameters
+		if (empty($this->type)) $this->type=0;
+		if (isset($this->facnumber)) $this->facnumber=trim($this->ref);
+		if (isset($this->ref_client)) $this->ref_client=trim($this->ref_client);
+		if (isset($this->increment)) $this->increment=trim($this->increment);
+		if (isset($this->close_code)) $this->close_code=trim($this->close_code);
+		if (isset($this->close_note)) $this->close_note=trim($this->close_note);
+		if (isset($this->note) || isset($this->note_private)) $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private));		// deprecated
+		if (isset($this->note) || isset($this->note_private)) $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note));
+		if (isset($this->note_public)) $this->note_public=trim($this->note_public);
+		if (isset($this->modelpdf)) $this->modelpdf=trim($this->modelpdf);
+		if (isset($this->import_key)) $this->import_key=trim($this->import_key);
+
+		// Check parameters
+		// Put here code to add control on parameters values
+
+		// Update request
+		$sql = "UPDATE ".MAIN_DB_PREFIX."facture SET";
+
+		$sql.= " facnumber=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").",";
+		$sql.= " type=".(isset($this->type)?$this->type:"null").",";
+		$sql.= " ref_client=".(isset($this->ref_client)?"'".$this->db->escape($this->ref_client)."'":"null").",";
+		$sql.= " increment=".(isset($this->increment)?"'".$this->db->escape($this->increment)."'":"null").",";
+		$sql.= " fk_soc=".(isset($this->socid)?$this->socid:"null").",";
+		$sql.= " datec=".(strval($this->date_creation)!='' ? "'".$this->db->idate($this->date_creation)."'" : 'null').",";
+		$sql.= " datef=".(strval($this->date)!='' ? "'".$this->db->idate($this->date)."'" : 'null').",";
+		$sql.= " date_valid=".(strval($this->date_validation)!='' ? "'".$this->db->idate($this->date_validation)."'" : 'null').",";
+		$sql.= " paye=".(isset($this->paye)?$this->paye:"null").",";
+		$sql.= " remise_percent=".(isset($this->remise_percent)?$this->remise_percent:"null").",";
+		$sql.= " remise_absolue=".(isset($this->remise_absolue)?$this->remise_absolue:"null").",";
+		//$sql.= " remise=".(isset($this->remise)?$this->remise:"null").",";
+		$sql.= " close_code=".(isset($this->close_code)?"'".$this->db->escape($this->close_code)."'":"null").",";
+		$sql.= " close_note=".(isset($this->close_note)?"'".$this->db->escape($this->close_note)."'":"null").",";
+		$sql.= " tva=".(isset($this->total_tva)?$this->total_tva:"null").",";
+		$sql.= " localtax1=".(isset($this->total_localtax1)?$this->total_localtax1:"null").",";
+		$sql.= " localtax2=".(isset($this->total_localtax2)?$this->total_localtax2:"null").",";
+		$sql.= " total=".(isset($this->total_ht)?$this->total_ht:"null").",";
+		$sql.= " total_ttc=".(isset($this->total_ttc)?$this->total_ttc:"null").",";
+		$sql.= " revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp != '')?$this->revenuestamp:"null").",";
+		$sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").",";
+		$sql.= " fk_user_author=".(isset($this->user_author)?$this->user_author:"null").",";
+		$sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").",";
+		$sql.= " fk_facture_source=".(isset($this->fk_facture_source)?$this->fk_facture_source:"null").",";
+		$sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").",";
+		$sql.= " fk_cond_reglement=".(isset($this->cond_reglement_id)?$this->cond_reglement_id:"null").",";
+		$sql.= " fk_mode_reglement=".(isset($this->mode_reglement_id)?$this->mode_reglement_id:"null").",";
+		$sql.= " date_lim_reglement=".(strval($this->date_lim_reglement)!='' ? "'".$this->db->idate($this->date_lim_reglement)."'" : 'null').",";
+		$sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").",";
+		$sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").",";
+		$sql.= " model_pdf=".(isset($this->modelpdf)?"'".$this->db->escape($this->modelpdf)."'":"null").",";
+		$sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null")."";
+
+		$sql.= " WHERE rowid=".$this->id;
 
-        $this->db->begin();
+		$this->db->begin();
 
-        $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET';
-        $sql.= ' fk_statut=3';
-        if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'";
-        if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'";
-        $sql.= ' WHERE rowid = '.$this->id;
+		dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG);
+		$resql = $this->db->query($sql);
+		if (! $resql) {
+			$error++; $this->errors[]="Error ".$this->db->lasterror();
+		}
 
-        $resql = $this->db->query($sql);
-        if ($resql)
-        {
-            // On desaffecte de la facture les remises liees
-            // car elles n'ont pas ete utilisees vu que la facture est abandonnee.
-            $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
-            $sql.= ' SET fk_facture = NULL';
-            $sql.= ' WHERE fk_facture = '.$this->id;
-
-            $resql=$this->db->query($sql);
-            if ($resql)
-            {
-                // Appel des triggers
-                include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-                $interface=new Interfaces($this->db);
-                $result=$interface->run_triggers('BILL_CANCEL',$this,$user,$langs,$conf);
-                if ($result < 0) { $error++; $this->errors=$interface->errors; }
-                // Fin appel triggers
-
-                $this->db->commit();
-                return 1;
-            }
-            else
-            {
-                $this->error=$this->db->error()." sql=".$sql;
-                $this->db->rollback();
-                return -1;
-            }
-        }
-        else
-        {
-            $this->error=$this->db->error()." sql=".$sql;
-            $this->db->rollback();
-            return -2;
-        }
-    }
-
-    /**
-     * Tag invoice as validated + call trigger BILL_VALIDATE
-     * Object must have lines loaded with fetch_lines
-     *
-     * @param	User	$user           Object user that validate
-     * @param   string	$force_number	Reference to force on invoice
-     * @param	int		$idwarehouse	Id of warehouse to use for stock decrease
-     * @return	int						<0 if KO, >0 if OK
-     */
-    function validate($user, $force_number='', $idwarehouse=0)
-    {
-        global $conf,$langs;
-        require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-
-        $now=dol_now();
-
-        $error=0;
-        dol_syslog(get_class($this).'::validate user='.$user->id.', force_number='.$force_number.', idwarehouse='.$idwarehouse);
-
-	    // Check parameters
-        if (! $this->brouillon)
-        {
-            dol_syslog(get_class($this)."::validate no draft status", LOG_WARNING);
-            return 0;
-        }
+		if (! $error)
+		{
+			if (! $notrigger)
+			{
+				// Call triggers
+				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+				$interface=new Interfaces($this->db);
+				$result=$interface->run_triggers('BILL_MODIFY',$this,$user,$langs,$conf);
+				if ($result < 0) {
+					$error++; $this->errors=$interface->errors;
+				}
+				// End call triggers
+			}
+		}
+
+		// Commit or rollback
+		if ($error)
+		{
+			foreach($this->errors as $errmsg)
+			{
+				dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
+				$this->error.=($this->error?', '.$errmsg:$errmsg);
+			}
+			$this->db->rollback();
+			return -1*$error;
+		}
+		else
+		{
+			$this->db->commit();
+			return 1;
+		}
+	}
+
+
+	/**
+	 *    Add a discount line into invoice using an existing absolute discount
+	 *
+	 *    @param     int	$idremise	Id of absolute discount
+	 *    @return    int          		>0 if OK, <0 if KO
+	 */
+	function insert_discount($idremise)
+	{
+		global $langs;
+
+		include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
+		include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
+
+		$this->db->begin();
+
+		$remise=new DiscountAbsolute($this->db);
+		$result=$remise->fetch($idremise);
+
+		if ($result > 0)
+		{
+			if ($remise->fk_facture)	// Protection against multiple submission
+			{
+				$this->error=$langs->trans("ErrorDiscountAlreadyUsed");
+				$this->db->rollback();
+				return -5;
+			}
+
+			$facligne=new FactureLigne($this->db);
+			$facligne->fk_facture=$this->id;
+			$facligne->fk_remise_except=$remise->id;
+			$facligne->desc=$remise->description;   	// Description ligne
+			$facligne->tva_tx=$remise->tva_tx;
+			$facligne->subprice=-$remise->amount_ht;
+			$facligne->fk_product=0;					// Id produit predefini
+			$facligne->qty=1;
+			$facligne->remise_percent=0;
+			$facligne->rang=-1;
+			$facligne->info_bits=2;
+
+			$facligne->total_ht  = -$remise->amount_ht;
+			$facligne->total_tva = -$remise->amount_tva;
+			$facligne->total_ttc = -$remise->amount_ttc;
+
+			$lineid=$facligne->insert();
+			if ($lineid > 0)
+			{
+				$result=$this->update_price(1);
+				if ($result > 0)
+				{
+					// Create linke between discount and invoice line
+					$result=$remise->link_to_invoice($lineid,0);
+					if ($result < 0)
+					{
+						$this->error=$remise->error;
+						$this->db->rollback();
+						return -4;
+					}
+
+					$this->db->commit();
+					return 1;
+				}
+				else
+				{
+					$this->error=$facligne->error;
+					$this->db->rollback();
+					return -1;
+				}
+			}
+			else
+			{
+				$this->error=$facligne->error;
+				$this->db->rollback();
+				return -2;
+			}
+		}
+		else
+		{
+			$this->db->rollback();
+			return -3;
+		}
+	}
+
+	/**
+	 *	Set customer ref
+	 *
+	 *	@param     	string	$ref_client		Customer ref
+	 *	@return		int						<0 if KO, >0 if OK
+	 */
+	function set_ref_client($ref_client)
+	{
+		$sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
+		if (empty($ref_client))
+			$sql .= ' SET ref_client = NULL';
+		else
+			$sql .= ' SET ref_client = \''.$this->db->escape($ref_client).'\'';
+		$sql .= ' WHERE rowid = '.$this->id;
+		if ($this->db->query($sql))
+		{
+			$this->ref_client = $ref_client;
+			return 1;
+		}
+		else
+		{
+			dol_print_error($this->db);
+			return -1;
+		}
+	}
+
+	/**
+	 *	Delete invoice
+	 *
+	 *	@param     	int		$rowid      	Id of invoice to delete. If empty, we delete current instance of invoice
+	 *	@param		int		$notrigger		1=Does not execute triggers, 0= execute triggers
+	 *	@param		int		$idwarehouse	Id warehouse to use for stock change.
+	 *	@return		int						<0 if KO, >0 if OK
+	 */
+	function delete($rowid=0, $notrigger=0, $idwarehouse=-1)
+	{
+		global $user,$langs,$conf;
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+		if (empty($rowid)) $rowid=$this->id;
+
+		dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG);
+
+		// TODO Test if there is at least on payment. If yes, refuse to delete.
+
+		$error=0;
+		$this->db->begin();
+
+		if (! $error && ! $notrigger)
+		{
+			// Appel des triggers
+			include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+			$interface=new Interfaces($this->db);
+			$result=$interface->run_triggers('BILL_DELETE',$this,$user,$langs,$conf);
+			if ($result < 0) {
+				$error++; $this->errors=$interface->errors;
+			}
+			// Fin appel triggers
+		}
+
+		if (! $error)
+		{
+			// Delete linked object
+			$res = $this->deleteObjectLinked();
+			if ($res < 0) $error++;
+		}
+
+		if (! $error)
+		{
+			// If invoice was converted into a discount not yet consumed, we remove discount
+			$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'societe_remise_except';
+			$sql.= ' WHERE fk_facture_source = '.$rowid;
+			$sql.= ' AND fk_facture_line IS NULL';
+			$resql=$this->db->query($sql);
+
+			// If invoice has consumned discounts
+			$this->fetch_lines();
+			$list_rowid_det=array();
+			foreach($this->lines as $key => $invoiceline)
+			{
+				$list_rowid_det[]=$invoiceline->rowid;
+			}
+
+			// Consumned discounts are freed
+			if (count($list_rowid_det))
+			{
+				$sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
+				$sql.= ' SET fk_facture = NULL, fk_facture_line = NULL';
+				$sql.= ' WHERE fk_facture_line IN ('.join(',',$list_rowid_det).')';
+
+				dol_syslog(get_class($this)."::delete sql=".$sql);
+				if (! $this->db->query($sql))
+				{
+					$this->error=$this->db->error()." sql=".$sql;
+					dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
+					$this->db->rollback();
+					return -5;
+				}
+			}
+
+			// If we decrament stock on invoice validation, we increment
+			if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse!=-1)
+			{
+				require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
+				$langs->load("agenda");
+			
+				$num=count($this->lines);
+				for ($i = 0; $i < $num; $i++)
+				{
+					if ($this->lines[$i]->fk_product > 0)
+					{
+						$mouvP = new MouvementStock($this->db);
+						// We decrease stock for product
+						if ($this->type == 2) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceDeleteDolibarr",$this->ref));
+						else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceDeleteDolibarr",$this->ref));	// we use 0 for price, to not change the weighted average value
+					}
+				}
+			}
+
+
+			// Delete invoice line
+			$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$rowid;
+			if ($this->db->query($sql) && $this->delete_linked_contact())
+			{
+				$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.$rowid;
+				$resql=$this->db->query($sql);
+				if ($resql)
+				{
+					// On efface le repertoire de pdf provisoire
+					$ref = dol_sanitizeFileName($this->ref);
+					if ($conf->facture->dir_output)
+					{
+						$dir = $conf->facture->dir_output . "/" . $ref;
+						$file = $conf->facture->dir_output . "/" . $ref . "/" . $ref . ".pdf";
+						if (file_exists($file))	// We must delete all files before deleting directory
+						{
+							$ret=dol_delete_preview($this);
+
+							if (! dol_delete_file($file,0,0,0,$this)) // For triggers
+							{
+								$this->error=$langs->trans("ErrorCanNotDeleteFile",$file);
+								$this->db->rollback();
+								return 0;
+							}
+						}
+						if (file_exists($dir))
+						{
+							if (! dol_delete_dir_recursive($dir)) // For remove dir and meta
+							{
+								$this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
+								$this->db->rollback();
+								return 0;
+							}
+						}
+					}
+
+					$this->db->commit();
+					return 1;
+				}
+				else
+				{
+					$this->error=$this->db->lasterror()." sql=".$sql;
+					dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
+					$this->db->rollback();
+					return -6;
+				}
+			}
+			else
+			{
+				$this->error=$this->db->lasterror()." sql=".$sql;
+				dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
+				$this->db->rollback();
+				return -4;
+			}
+		}
+		else
+		{
+			$this->error=$this->db->lasterror();
+			dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
+			$this->db->rollback();
+			return -2;
+		}
+	}
+
+
+	/**
+	 *	Renvoi une date limite de reglement de facture en fonction des
+	 *	conditions de reglements de la facture et date de facturation
+	 *
+	 *	@param      string	$cond_reglement   	Condition of payment (code or id) to use. If 0, we use current condition.
+	 *	@return     date     			       	Date limite de reglement si ok, <0 si ko
+	 */
+	function calculate_date_lim_reglement($cond_reglement=0)
+	{
+		if (! $cond_reglement) $cond_reglement=$this->cond_reglement_code;
+		if (! $cond_reglement) $cond_reglement=$this->cond_reglement_id;
+
+		$cdr_nbjour=0; $cdr_fdm=0; $cdr_decalage=0;
+
+		$sqltemp = 'SELECT c.fdm,c.nbjour,c.decalage';
+		$sqltemp.= ' FROM '.MAIN_DB_PREFIX.'c_payment_term as c';
+		if (is_numeric($cond_reglement)) $sqltemp.= " WHERE c.rowid=".$cond_reglement;
+		else $sqltemp.= " WHERE c.code='".$this->db->escape($cond_reglement)."'";
+
+		dol_syslog(get_class($this).'::calculate_date_lim_reglement sql='.$sqltemp);
+		$resqltemp=$this->db->query($sqltemp);
+		if ($resqltemp)
+		{
+			if ($this->db->num_rows($resqltemp))
+			{
+				$obj = $this->db->fetch_object($resqltemp);
+				$cdr_nbjour = $obj->nbjour;
+				$cdr_fdm = $obj->fdm;
+				$cdr_decalage = $obj->decalage;
+			}
+		}
+		else
+		{
+			$this->error=$this->db->error();
+			return -1;
+		}
+		$this->db->free($resqltemp);
+
+		/* Definition de la date limite */
+
+		// 1 : ajout du nombre de jours
+		$datelim = $this->date + ($cdr_nbjour * 3600 * 24);
+
+		// 2 : application de la regle "fin de mois"
+		if ($cdr_fdm)
+		{
+			$mois=date('m', $datelim);
+			$annee=date('Y', $datelim);
+			if ($mois == 12)
+			{
+				$mois = 1;
+				$annee += 1;
+			}
+			else
+			{
+				$mois += 1;
+			}
+			// On se deplace au debut du mois suivant, et on retire un jour
+			$datelim=dol_mktime(12,0,0,$mois,1,$annee);
+			$datelim -= (3600 * 24);
+		}
+
+		// 3 : application du decalage
+		$datelim += ($cdr_decalage * 3600 * 24);
+
+		return $datelim;
+	}
+
+	/**
+	 *  Tag la facture comme paye completement (close_code non renseigne) ou partiellement (close_code renseigne) + appel trigger BILL_PAYED
+	 *
+	 *  @param	User	$user      	Objet utilisateur qui modifie
+	 *	@param  string	$close_code	Code renseigne si on classe a payee completement alors que paiement incomplet (cas escompte par exemple)
+	 *	@param  string	$close_note	Commentaire renseigne si on classe a payee alors que paiement incomplet (cas escompte par exemple)
+	 *  @return int         		<0 if KO, >0 if OK
+	 */
+	function set_paid($user,$close_code='',$close_note='')
+	{
+		global $conf,$langs;
+		$error=0;
+
+		if ($this->paye != 1)
+		{
+			$this->db->begin();
+
+			dol_syslog(get_class($this)."::set_paid rowid=".$this->id, LOG_DEBUG);
+			$sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET';
+			$sql.= ' fk_statut=2';
+			if (! $close_code) $sql.= ', paye=1';
+			if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'";
+			if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'";
+			$sql.= ' WHERE rowid = '.$this->id;
+
+			$resql = $this->db->query($sql);
+			if ($resql)
+			{
+				// Appel des triggers
+				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+				$interface=new Interfaces($this->db);
+				$result=$interface->run_triggers('BILL_PAYED',$this,$user,$langs,$conf);
+				if ($result < 0) {
+					$error++; $this->errors=$interface->errors;
+				}
+				// Fin appel triggers
+			}
+			else
+			{
+				$error++;
+				$this->error=$this->db->error();
+				dol_print_error($this->db);
+			}
+
+			if (! $error)
+			{
+				$this->db->commit();
+				return 1;
+			}
+			else
+			{
+				$this->db->rollback();
+				return -1;
+			}
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+
+	/**
+	 *  Tag la facture comme non payee completement + appel trigger BILL_UNPAYED
+	 *	Fonction utilisee quand un paiement prelevement est refuse,
+	 * 	ou quand une facture annulee et reouverte.
+	 *
+	 *  @param	User	$user       Object user that change status
+	 *  @return int         		<0 if KO, >0 if OK
+	 */
+	function set_unpaid($user)
+	{
+		global $conf,$langs;
+		$error=0;
+
+		$this->db->begin();
+
+		$sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
+		$sql.= ' SET paye=0, fk_statut=1, close_code=null, close_note=null';
+		$sql.= ' WHERE rowid = '.$this->id;
+
+		dol_syslog(get_class($this)."::set_unpaid sql=".$sql);
+		$resql = $this->db->query($sql);
+		if ($resql)
+		{
+			// Appel des triggers
+			include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+			$interface=new Interfaces($this->db);
+			$result=$interface->run_triggers('BILL_UNPAYED',$this,$user,$langs,$conf);
+			if ($result < 0) {
+				$error++; $this->errors=$interface->errors;
+			}
+			// Fin appel triggers
+		}
+		else
+		{
+			$error++;
+			$this->error=$this->db->error();
+			dol_print_error($this->db);
+		}
+
+		if (! $error)
+		{
+			$this->db->commit();
+			return 1;
+		}
+		else
+		{
+			$this->db->rollback();
+			return -1;
+		}
+	}
+
+
+	/**
+	 *	Tag invoice as canceled, with no payment on it (example for replacement invoice or payment never received) + call trigger BILL_CANCEL
+	 *	Warning, if option to decrease stock on invoice was set, this function does not change stock (it might be a cancel because
+	 *  of no payment even if merchandises were sent).
+	 *
+	 *	@param	User	$user        	Object user making change
+	 *	@param	string	$close_code		Code de fermeture
+	 *	@param	string	$close_note		Comment
+	 *	@return int         			<0 if KO, >0 if OK
+	 */
+	function set_canceled($user,$close_code='',$close_note='')
+	{
+		global $conf,$langs;
+
+		$error=0;
+
+		dol_syslog(get_class($this)."::set_canceled rowid=".$this->id, LOG_DEBUG);
+
+		$this->db->begin();
+
+		$sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET';
+		$sql.= ' fk_statut=3';
+		if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'";
+		if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'";
+		$sql.= ' WHERE rowid = '.$this->id;
+
+		$resql = $this->db->query($sql);
+		if ($resql)
+		{
+			// On desaffecte de la facture les remises liees
+			// car elles n'ont pas ete utilisees vu que la facture est abandonnee.
+			$sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
+			$sql.= ' SET fk_facture = NULL';
+			$sql.= ' WHERE fk_facture = '.$this->id;
+
+			$resql=$this->db->query($sql);
+			if ($resql)
+			{
+				// Appel des triggers
+				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+				$interface=new Interfaces($this->db);
+				$result=$interface->run_triggers('BILL_CANCEL',$this,$user,$langs,$conf);
+				if ($result < 0) {
+					$error++; $this->errors=$interface->errors;
+				}
+				// Fin appel triggers
+
+				$this->db->commit();
+				return 1;
+			}
+			else
+			{
+				$this->error=$this->db->error()." sql=".$sql;
+				$this->db->rollback();
+				return -1;
+			}
+		}
+		else
+		{
+			$this->error=$this->db->error()." sql=".$sql;
+			$this->db->rollback();
+			return -2;
+		}
+	}
+
+	/**
+	 * Tag invoice as validated + call trigger BILL_VALIDATE
+	 * Object must have lines loaded with fetch_lines
+	 *
+	 * @param	User	$user           Object user that validate
+	 * @param   string	$force_number	Reference to force on invoice
+	 * @param	int		$idwarehouse	Id of warehouse to use for stock decrease
+	 * @return	int						<0 if KO, >0 if OK
+	 */
+	function validate($user, $force_number='', $idwarehouse=0)
+	{
+		global $conf,$langs;
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+		$now=dol_now();
+
+		$error=0;
+		dol_syslog(get_class($this).'::validate user='.$user->id.', force_number='.$force_number.', idwarehouse='.$idwarehouse);
+
+		// Check parameters
+		if (! $this->brouillon)
+		{
+			dol_syslog(get_class($this)."::validate no draft status", LOG_WARNING);
+			return 0;
+		}
+
+		if (! $user->rights->facture->valider)
+		{
+			$this->error='Permission denied';
+			dol_syslog(get_class($this)."::validate ".$this->error, LOG_ERR);
+			return -1;
+		}
+
+		$this->db->begin();
+
+		$this->fetch_thirdparty();
+		$this->fetch_lines();
+
+		// Check parameters
+		if ($this->type == 1)		// si facture de remplacement
+		{
+			// Controle que facture source connue
+			if ($this->fk_facture_source <= 0)
+			{
+				$this->error=$langs->trans("ErrorFieldRequired",$langs->trans("InvoiceReplacement"));
+				$this->db->rollback();
+				return -10;
+			}
+
+			// Charge la facture source a remplacer
+			$facreplaced=new Facture($this->db);
+			$result=$facreplaced->fetch($this->fk_facture_source);
+			if ($result <= 0)
+			{
+				$this->error=$langs->trans("ErrorBadInvoice");
+				$this->db->rollback();
+				return -11;
+			}
+
+			// Controle que facture source non deja remplacee par une autre
+			$idreplacement=$facreplaced->getIdReplacingInvoice('validated');
+			if ($idreplacement && $idreplacement != $this->id)
+			{
+				$facreplacement=new Facture($this->db);
+				$facreplacement->fetch($idreplacement);
+				$this->error=$langs->trans("ErrorInvoiceAlreadyReplaced",$facreplaced->ref,$facreplacement->ref);
+				$this->db->rollback();
+				return -12;
+			}
+
+			$result=$facreplaced->set_canceled($user,'replaced','');
+			if ($result < 0)
+			{
+				$this->error=$facreplaced->error;
+				$this->db->rollback();
+				return -13;
+			}
+		}
+
+		// Define new ref
+		if ($force_number)
+		{
+			$num = $force_number;
+		}
+		else if (preg_match('/^[\(]?PROV/i', $this->ref))
+		{
+			if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION))	// If option enabled, we force invoice date
+			{
+				$this->date=dol_now();
+				$this->date_lim_reglement=$this->calculate_date_lim_reglement();
+			}
+			$num = $this->getNextNumRef($this->client);
+		}
+		else
+		{
+			$num = $this->ref;
+		}
+
+		if ($num)
+		{
+			$this->update_price(1);
+
+			// Validate
+			$sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
+			$sql.= " SET facnumber='".$num."', fk_statut = 1, fk_user_valid = ".$user->id.", date_valid = '".$this->db->idate($now)."'";
+			if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION))	// If option enabled, we force invoice date
+			{
+				$sql.= ', datef='.$this->db->idate($this->date);
+				$sql.= ', date_lim_reglement='.$this->db->idate($this->date_lim_reglement);
+			}
+			$sql.= ' WHERE rowid = '.$this->id;
+
+			dol_syslog(get_class($this)."::validate sql=".$sql);
+			$resql=$this->db->query($sql);
+			if (! $resql)
+			{
+				dol_syslog(get_class($this)."::validate Echec update - 10 - sql=".$sql, LOG_ERR);
+				dol_print_error($this->db);
+				$error++;
+			}
+
+			// On verifie si la facture etait une provisoire
+			if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref)))
+			{
+				// La verif qu'une remise n'est pas utilisee 2 fois est faite au moment de l'insertion de ligne
+			}
+
+			if (! $error)
+			{
+				// Define third party as a customer
+				$result=$this->client->set_as_client();
+
+				// Si active on decremente le produit principal et ses composants a la validation de facture
+				if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL))
+				{
+					require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
+					$langs->load("agenda");
+
+					// Loop on each line
+					$cpt=count($this->lines);
+					for ($i = 0; $i < $cpt; $i++)
+					{
+						if ($this->lines[$i]->fk_product > 0)
+						{
+							$mouvP = new MouvementStock($this->db);
+							// We decrease stock for product
+							if ($this->type == 2) $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num));
+							else $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num));
+							if ($result < 0) {
+								$error++;
+							}
+						}
+					}
+				}
+			}
+
+			if (! $error)
+			{
+				$this->oldref = '';
+
+				// Rename directory if dir was a temporary ref
+				if (preg_match('/^[\(]?PROV/i', $this->ref))
+				{
+					// On renomme repertoire facture ($this->ref = ancienne ref, $num = nouvelle ref)
+					// afin de ne pas perdre les fichiers attaches
+					$facref = dol_sanitizeFileName($this->ref);
+					$snumfa = dol_sanitizeFileName($num);
+					$dirsource = $conf->facture->dir_output.'/'.$facref;
+					$dirdest = $conf->facture->dir_output.'/'.$snumfa;
+					if (file_exists($dirsource))
+					{
+						dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest);
+
+						if (@rename($dirsource, $dirdest))
+						{
+							$this->oldref = $facref;
+
+							dol_syslog("Rename ok");
+							// Suppression ancien fichier PDF dans nouveau rep
+							dol_delete_file($conf->facture->dir_output.'/'.$snumfa.'/'.$facref.'*.*');
+						}
+					}
+				}
+			}
+
+			// Set new ref and define current statut
+			if (! $error)
+			{
+				$this->ref = $num;
+				$this->facnumber=$num;
+				$this->statut=1;
+				$this->brouillon=0;
+				$this->date_validation=$now;
+			}
+
+			// Trigger calls
+			if (! $error)
+			{
+				// Appel des triggers
+				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+				$interface=new Interfaces($this->db);
+				$result=$interface->run_triggers('BILL_VALIDATE',$this,$user,$langs,$conf);
+				if ($result < 0) {
+					$error++; $this->errors=$interface->errors;
+				}
+				// Fin appel triggers
+			}
+		}
+		else
+		{
+			$error++;
+		}
+
+		if (! $error)
+		{
+			$this->db->commit();
+			return 1;
+		}
+		else
+		{
+			$this->db->rollback();
+			$this->error=$this->db->lasterror();
+			return -1;
+		}
+	}
+
+	/**
+	 *	Set draft status
+	 *
+	 *	@param	User	$user			Object user that modify
+	 *	@param	int		$idwarehouse	Id warehouse to use for stock change.
+	 *	@return	int						<0 if KO, >0 if OK
+	 */
+	function set_draft($user,$idwarehouse=-1)
+	{
+		global $conf,$langs;
+
+		$error=0;
+
+		if ($this->statut == 0)
+		{
+			dol_syslog(get_class($this)."::set_draft already draft status", LOG_WARNING);
+			return 0;
+		}
+
+		$this->db->begin();
+
+		$sql = "UPDATE ".MAIN_DB_PREFIX."facture";
+		$sql.= " SET fk_statut = 0";
+		$sql.= " WHERE rowid = ".$this->id;
+
+		dol_syslog(get_class($this)."::set_draft sql=".$sql, LOG_DEBUG);
+		$result=$this->db->query($sql);
+		if ($result)
+		{
+			// Si on decremente le produit principal et ses composants a la validation de facture, on réincrement
+			if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL))
+			{
+				require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
+				$langs->load("agenda");
+
+				$num=count($this->lines);
+				for ($i = 0; $i < $num; $i++)
+				{
+					if ($this->lines[$i]->fk_product > 0)
+					{
+						$mouvP = new MouvementStock($this->db);
+						// We decrease stock for product
+						if ($this->type == 2) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref));
+						else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref));	// we use 0 for price, to not change the weighted average value
+					}
+				}
+			}
+
+			if ($error == 0)
+			{
+				$old_statut=$this->statut;
+				$this->brouillon = 1;
+				$this->statut = 0;
+				// Appel des triggers
+				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+				$interface=new Interfaces($this->db);
+				$result=$interface->run_triggers('BILL_UNVALIDATE',$this,$user,$langs,$conf);
+				if ($result < 0) {
+					$error++;
+					$this->errors=$interface->errors;
+					$this->statut=$old_statut;
+					$this->brouillon=0;
+				}
+				// Fin appel triggers
+			} else {
+				$this->db->rollback();
+				return -1;
+			}
+
+			if ($error == 0)
+			{
+				$this->db->commit();
+				return 1;
+			}
+			else
+			{
+				$this->db->rollback();
+				return -1;
+			}
+		}
+		else
+		{
+			$this->error=$this->db->error();
+			$this->db->rollback();
+			return -1;
+		}
+	}
+
+
+	/**
+	 * 		Add an invoice line into database (linked to product/service or not).
+	 * 		Les parametres sont deja cense etre juste et avec valeurs finales a l'appel
+	 *		de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini
+	 *		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)
+	 *
+	 * 		@param    	int			$facid           	Id de la facture
+	 * 		@param    	string		$desc            	Description de la ligne
+	 * 		@param    	double		$pu_ht              Prix unitaire HT (> 0 even for credit note)
+	 * 		@param    	double		$qty             	Quantite
+	 * 		@param    	double		$txtva           	Taux de tva force, sinon -1
+	 * 		@param		double		$txlocaltax1		Local tax 1 rate
+	 *  	@param		double		$txlocaltax2		Local tax 2 rate
+	 *		@param    	int			$fk_product      	Id du produit/service predefini
+	 * 		@param    	double		$remise_percent  	Pourcentage de remise de la ligne
+	 * 		@param    	timestamp	$date_start      	Date de debut de validite du service
+	 * 		@param    	timestamp	$date_end        	Date de fin de validite du service
+	 * 		@param    	int			$ventil          	Code de ventilation comptable
+	 * 		@param    	int			$info_bits			Bits de type de lignes
+	 *		@param    	int			$fk_remise_except	Id remise
+	 *		@param		string		$price_base_type	HT or TTC
+	 * 		@param    	double		$pu_ttc             Prix unitaire TTC (> 0 even for credit note)
+	 * 		@param		int			$type				Type of line (0=product, 1=service)
+	 *      @param      int			$rang               Position of line
+	 *      @param		int			$special_code		Special code (also used by externals modules!)
+	 *      @param		string		$origin				'order', ...
+	 *      @param		int			$origin_id			Id of origin object
+	 *      @param		int			$fk_parent_line		Id of parent line
+	 * 		@param		int			$fk_fournprice		To calculate margin
+	 * 		@param		int			$pa_ht				Buying price of line
+	 * 		@param		string		$label				Label of the line
+	 *    	@return    	int             				<0 if KO, Id of line if OK
+	 */
+	function addline($facid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='')
+	{
+		dol_syslog(get_class($this)."::Addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product,remise_percent=$remise_percent,date_start=$date_start,date_end=$date_end,ventil=$ventil,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type", LOG_DEBUG);
+		include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
+
+		// Clean parameters
+		if (empty($remise_percent)) $remise_percent=0;
+		if (empty($qty)) $qty=0;
+		if (empty($info_bits)) $info_bits=0;
+		if (empty($rang)) $rang=0;
+		if (empty($ventil)) $ventil=0;
+		if (empty($txtva)) $txtva=0;
+		if (empty($txlocaltax1)) $txlocaltax1=0;
+		if (empty($txlocaltax2)) $txlocaltax2=0;
+		if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0;
+
+		$remise_percent=price2num($remise_percent);
+		$qty=price2num($qty);
+		$pu_ht=price2num($pu_ht);
+		$pu_ttc=price2num($pu_ttc);
+		$pa_ht=price2num($pa_ht);
+		$txtva=price2num($txtva);
+		$txlocaltax1=price2num($txlocaltax1);
+		$txlocaltax2=price2num($txlocaltax2);
+
+		if ($price_base_type=='HT')
+		{
+			$pu=$pu_ht;
+		}
+		else
+		{
+			$pu=$pu_ttc;
+		}
+
+		// Check parameters
+		if ($type < 0) return -1;
+
+		if (! empty($this->brouillon))
+		{
+			$this->db->begin();
+
+			// Calcul du total TTC et de la TVA pour la ligne a partir de
+			// qty, pu, remise_percent et txtva
+			// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
+			// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
+			$tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type);
+			$total_ht  = $tabprice[0];
+			$total_tva = $tabprice[1];
+			$total_ttc = $tabprice[2];
+			$total_localtax1 = $tabprice[9];
+			$total_localtax2 = $tabprice[10];
+			$pu_ht = $tabprice[3];
+
+			// Rang to use
+			$rangtouse = $rang;
+			if ($rangtouse == -1)
+			{
+				$rangmax = $this->line_max($fk_parent_line);
+				$rangtouse = $rangmax + 1;
+			}
+
+			$product_type=$type;
+			if ($fk_product)
+			{
+				$product=new Product($this->db);
+				$result=$product->fetch($fk_product);
+				$product_type=$product->type;
+			}
+
+			// Insert line
+			$this->line=new FactureLigne($this->db);
+			$this->line->fk_facture=$facid;
+			$this->line->label=$label;
+			$this->line->desc=$desc;
+			$this->line->qty=            ($this->type==2?abs($qty):$qty);	// For credit note, quantity is always positive and unit price negative
+			$this->line->tva_tx=$txtva;
+			$this->line->localtax1_tx=$txlocaltax1;
+			$this->line->localtax2_tx=$txlocaltax2;
+			$this->line->fk_product=$fk_product;
+			$this->line->product_type=$product_type;
+			$this->line->remise_percent=$remise_percent;
+			$this->line->subprice=       ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise
+			$this->line->date_start=$date_start;
+			$this->line->date_end=$date_end;
+			$this->line->ventil=$ventil;
+			$this->line->rang=$rangtouse;
+			$this->line->info_bits=$info_bits;
+			$this->line->fk_remise_except=$fk_remise_except;
+			$this->line->total_ht=       (($this->type==2||$qty<0)?-abs($total_ht):$total_ht);  // For credit note and if qty is negative, total is negative
+			$this->line->total_tva=      (($this->type==2||$qty<0)?-abs($total_tva):$total_tva);
+			$this->line->total_localtax1=(($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1);
+			$this->line->total_localtax2=(($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2);
+			$this->line->total_ttc=      (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc);
+			$this->line->special_code=$special_code;
+			$this->line->fk_parent_line=$fk_parent_line;
+			$this->line->origin=$origin;
+			$this->line->origin_id=$origin_id;
+
+			// infos marge
+			$this->line->fk_fournprice = $fk_fournprice;
+			$this->line->pa_ht = $pa_ht;
+
+			$result=$this->line->insert();
+			if ($result > 0)
+			{
+				// Reorder if child line
+				if (! empty($fk_parent_line)) $this->line_order(true,'DESC');
+
+				// Mise a jour informations denormalisees au niveau de la facture meme
+				$this->id=$facid;	// TODO To move this we must remove parameter facid into this function declaration
+				$result=$this->update_price(1);
+				if ($result > 0)
+				{
+					$this->db->commit();
+					return $this->line->rowid;
+				}
+				else
+				{
+					$this->error=$this->db->error();
+					dol_syslog("Error sql=$sql, error=".$this->error,LOG_ERR);
+					$this->db->rollback();
+					return -1;
+				}
+			}
+			else
+			{
+				$this->error=$this->line->error;
+				$this->db->rollback();
+				return -2;
+			}
+		}
+	}
+
+	/**
+	 *  Update a detail line
+	 *
+	 *  @param     	int			$rowid           	Id of line to update
+	 *  @param     	string		$desc            	Description of line
+	 *  @param     	double		$pu              	Prix unitaire (HT ou TTC selon price_base_type) (> 0 even for credit note lines)
+	 *  @param     	double		$qty             	Quantity
+	 *  @param     	double		$remise_percent  	Pourcentage de remise de la ligne
+	 *  @param     	date		$date_start      	Date de debut de validite du service
+	 *  @param     	date		$date_end        	Date de fin de validite du service
+	 *  @param     	double		$txtva          	VAT Rate
+	 * 	@param		double		$txlocaltax1		Local tax 1 rate
+	 *  @param		double		$txlocaltax2		Local tax 2 rate
+	 * 	@param     	string		$price_base_type 	HT or TTC
+	 * 	@param     	int			$info_bits 		    Miscellaneous informations
+	 * 	@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)
+	 * 	@param		int			$fk_fournprice		Id of origin supplier price
+	 * 	@param		int			$pa_ht				Price (without tax) of product when it was bought
+	 * 	@param		string		$label				Label of the line
+	 * 	@param		int			$special_code		Special code (also used by externals modules!)
+	 *  @return    	int             				< 0 if KO, > 0 if OK
+	 */
+	function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0)
+	{
+		include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
+
+		dol_syslog(get_class($this)."::updateline $rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1, $txlocaltax2, $price_base_type, $info_bits, $type, $fk_parent_line", LOG_DEBUG);
+
+		if ($this->brouillon)
+		{
+			$this->db->begin();
+
+			// Clean parameters
+			if (empty($qty)) $qty=0;
+			if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0;
+			if (empty($special_code) || $special_code == 3) $special_code=0;
+
+			$remise_percent	= price2num($remise_percent);
+			$qty			= price2num($qty);
+			$pu 			= price2num($pu);
+			$pa_ht			= price2num($pa_ht);
+			$txtva			= price2num($txtva);
+			$txlocaltax1	= price2num($txlocaltax1);
+			$txlocaltax2	= price2num($txlocaltax2);
+
+			// Check parameters
+			if ($type < 0) return -1;
+
+			// Calculate total with, without tax and tax from qty, pu, remise_percent and txtva
+			// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
+			// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
+			$tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type);
+			$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];
+
+			// Old properties: $price, $remise (deprecated)
+			$price = $pu;
+			$remise = 0;
+			if ($remise_percent > 0)
+			{
+				$remise = round(($pu * $remise_percent / 100),2);
+				$price = ($pu - $remise);
+			}
+			$price    = price2num($price);
+
+			// Update line into database
+			$this->line=new FactureLigne($this->db);
+
+			// Stock previous line records
+			$staticline=new FactureLigne($this->db);
+			$staticline->fetch($rowid);
+			$this->line->oldline = $staticline;
+
+			// Reorder if fk_parent_line change
+			if (! empty($fk_parent_line) && ! empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line)
+			{
+				$rangmax = $this->line_max($fk_parent_line);
+				$this->line->rang = $rangmax + 1;
+			}
+
+			$this->line->rowid				= $rowid;
+			$this->line->label				= $label;
+			$this->line->desc				= $desc;
+			$this->line->qty				= ($this->type==2?abs($qty):$qty);	// For credit note, quantity is always positive and unit price negative
+			$this->line->tva_tx				= $txtva;
+			$this->line->localtax1_tx		= $txlocaltax1;
+			$this->line->localtax2_tx		= $txlocaltax2;
+			$this->line->remise_percent		= $remise_percent;
+			$this->line->subprice			= ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise
+			$this->line->date_start			= $date_start;
+			$this->line->date_end			= $date_end;
+			$this->line->total_ht			= (($this->type==2||$qty<0)?-abs($total_ht):$total_ht);  // For credit note and if qty is negative, total is negative
+			$this->line->total_tva			= (($this->type==2||$qty<0)?-abs($total_tva):$total_tva);
+			$this->line->total_localtax1	= (($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1);
+			$this->line->total_localtax2	= (($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2);
+			$this->line->total_ttc			= (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc);
+			$this->line->info_bits			= $info_bits;
+			$this->line->special_code		= $special_code;
+			$this->line->product_type		= $type;
+			$this->line->fk_parent_line		= $fk_parent_line;
+			$this->line->skip_update_total	= $skip_update_total;
+
+			// infos marge
+			$this->line->fk_fournprice = $fk_fournprice;
+			$this->line->pa_ht = $pa_ht;
+
+			// A ne plus utiliser
+			//$this->line->price=$price;
+			//$this->line->remise=$remise;
+
+			$result=$this->line->update();
+			if ($result > 0)
+			{
+				// Reorder if child line
+				if (! empty($fk_parent_line)) $this->line_order(true,'DESC');
+
+				// Mise a jour info denormalisees au niveau facture
+				$this->update_price(1);
+				$this->db->commit();
+				return $result;
+			}
+			else
+			{
+				$this->db->rollback();
+				return -1;
+			}
+		}
+		else
+		{
+			$this->error="Invoice statut makes operation forbidden";
+			return -2;
+		}
+	}
+
+	/**
+	 *	Delete line in database
+	 *
+	 *	@param		int		$rowid		Id of line to delete
+	 *	@return		int					<0 if KO, >0 if OK
+	 */
+	function deleteline($rowid)
+	{
+		global $langs, $conf;
+
+		dol_syslog(get_class($this)."::deleteline rowid=".$rowid, LOG_DEBUG);
+
+		if (! $this->brouillon)
+		{
+			$this->error='ErrorBadStatus';
+			return -1;
+		}
+
+		$this->db->begin();
+
+		// Libere remise liee a ligne de facture
+		$sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
+		$sql.= ' SET fk_facture_line = NULL';
+		$sql.= ' WHERE fk_facture_line = '.$rowid;
+
+		dol_syslog(get_class($this)."::deleteline sql=".$sql);
+		$result = $this->db->query($sql);
+		if (! $result)
+		{
+			$this->error=$this->db->error();
+			dol_syslog(get_class($this)."::deleteline Error ".$this->error, LOG_ERR);
+			$this->db->rollback();
+			return -1;
+		}
+
+		$line=new FactureLigne($this->db);
+
+		// For triggers
+		$line->fetch($rowid);
+
+		if ($line->delete() > 0)
+		{
+			$result=$this->update_price(1);
+
+			if ($result > 0)
+			{
+				$this->db->commit();
+				return 1;
+			}
+			else
+			{
+				$this->db->rollback();
+				$this->error=$this->db->lasterror();
+				return -1;
+			}
+		}
+		else
+		{
+			$this->db->rollback();
+			$this->error=$this->db->lasterror();
+			return -1;
+		}
+	}
+
+	/**
+	 *	Set percent discount
+	 *
+	 *	@param     	User	$user		User that set discount
+	 *	@param     	double	$remise		Discount
+	 *	@return		int 		<0 if ko, >0 if ok
+	 */
+	function set_remise($user, $remise)
+	{
+		// Clean parameters
+		if (empty($remise)) $remise=0;
+
+		if ($user->rights->facture->creer)
+		{
+			$remise=price2num($remise);
+
+			$sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
+			$sql.= ' SET remise_percent = '.$remise;
+			$sql.= ' WHERE rowid = '.$this->id;
+			$sql.= ' AND fk_statut = 0 ;';
+
+			if ($this->db->query($sql))
+			{
+				$this->remise_percent = $remise;
+				$this->update_price(1);
+				return 1;
+			}
+			else
+			{
+				$this->error=$this->db->error();
+				return -1;
+			}
+		}
+	}
+
+
+	/**
+	 *	Set absolute discount
+	 *
+	 *	@param     	User	$user 		User that set discount
+	 *	@param     	double	$remise		Discount
+	 *	@return		int 				<0 if KO, >0 if OK
+	 */
+	function set_remise_absolue($user, $remise)
+	{
+		if (empty($remise)) $remise=0;
 
-        if (! $user->rights->facture->valider)
-        {
-            $this->error='Permission denied';
-            dol_syslog(get_class($this)."::validate ".$this->error, LOG_ERR);
-            return -1;
-        }
+		if ($user->rights->facture->creer)
+		{
+			$remise=price2num($remise);
 
-        $this->db->begin();
+			$sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
+			$sql.= ' SET remise_absolue = '.$remise;
+			$sql.= ' WHERE rowid = '.$this->id;
+			$sql.= ' AND fk_statut = 0 ;';
 
-        $this->fetch_thirdparty();
-        $this->fetch_lines();
+			dol_syslog(get_class($this)."::set_remise_absolue sql=$sql");
 
-        // Check parameters
-        if ($this->type == 1)		// si facture de remplacement
-        {
-            // Controle que facture source connue
-            if ($this->fk_facture_source <= 0)
-            {
-                $this->error=$langs->trans("ErrorFieldRequired",$langs->trans("InvoiceReplacement"));
-                $this->db->rollback();
-                return -10;
-            }
-
-            // Charge la facture source a remplacer
-            $facreplaced=new Facture($this->db);
-            $result=$facreplaced->fetch($this->fk_facture_source);
-            if ($result <= 0)
-            {
-                $this->error=$langs->trans("ErrorBadInvoice");
-                $this->db->rollback();
-                return -11;
-            }
-
-            // Controle que facture source non deja remplacee par une autre
-            $idreplacement=$facreplaced->getIdReplacingInvoice('validated');
-            if ($idreplacement && $idreplacement != $this->id)
-            {
-                $facreplacement=new Facture($this->db);
-                $facreplacement->fetch($idreplacement);
-                $this->error=$langs->trans("ErrorInvoiceAlreadyReplaced",$facreplaced->ref,$facreplacement->ref);
-                $this->db->rollback();
-                return -12;
-            }
-
-            $result=$facreplaced->set_canceled($user,'replaced','');
-            if ($result < 0)
-            {
-                $this->error=$facreplaced->error;
-                $this->db->rollback();
-                return -13;
-            }
-        }
+			if ($this->db->query($sql))
+			{
+				$this->remise_absolue = $remise;
+				$this->update_price(1);
+				return 1;
+			}
+			else
+			{
+				$this->error=$this->db->error();
+				return -1;
+			}
+		}
+	}
 
-        // Define new ref
-        if ($force_number)
-        {
-            $num = $force_number;
-        }
-        else if (preg_match('/^[\(]?PROV/i', $this->ref))
-        {
-            if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION))	// If option enabled, we force invoice date
-            {
-                $this->date=dol_now();
-                $this->date_lim_reglement=$this->calculate_date_lim_reglement();
-            }
-            $num = $this->getNextNumRef($this->client);
-        }
-        else
-        {
-            $num = $this->ref;
-        }
+	/**
+	 *  Return list of payments
+	 *
+	 *	@param		string	$filtertype		1 to filter on type of payment == 'PRE'
+	 *  @return     array					Array with list of payments
+	 */
+	function getListOfPayments($filtertype='')
+	{
+		$retarray=array();
 
-        if ($num)
-        {
-            $this->update_price(1);
-
-            // Validate
-            $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
-            $sql.= " SET facnumber='".$num."', fk_statut = 1, fk_user_valid = ".$user->id.", date_valid = '".$this->db->idate($now)."'";
-            if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION))	// If option enabled, we force invoice date
-            {
-                $sql.= ', datef='.$this->db->idate($this->date);
-                $sql.= ', date_lim_reglement='.$this->db->idate($this->date_lim_reglement);
-            }
-            $sql.= ' WHERE rowid = '.$this->id;
-
-            dol_syslog(get_class($this)."::validate sql=".$sql);
-            $resql=$this->db->query($sql);
-            if (! $resql)
-            {
-                dol_syslog(get_class($this)."::validate Echec update - 10 - sql=".$sql, LOG_ERR);
-                dol_print_error($this->db);
-                $error++;
-            }
-
-            // On verifie si la facture etait une provisoire
-            if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref)))
-            {
-                // La verif qu'une remise n'est pas utilisee 2 fois est faite au moment de l'insertion de ligne
-            }
-
-            if (! $error)
-            {
-                // Define third party as a customer
-                $result=$this->client->set_as_client();
-
-                // Si active on decremente le produit principal et ses composants a la validation de facture
-                if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL))
-                {
-                    require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
-                    $langs->load("agenda");
-
-                    // Loop on each line
-                    $cpt=count($this->lines);
-                    for ($i = 0; $i < $cpt; $i++)
-                    {
-                        if ($this->lines[$i]->fk_product > 0)
-                        {
-                            $mouvP = new MouvementStock($this->db);
-                            // We decrease stock for product
-                            if ($this->type == 2) $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num));
-                            else $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num));
-                            if ($result < 0) { $error++; }
-                        }
-                    }
-                }
-            }
-
-            if (! $error)
-            {
-            	$this->oldref = '';
-
-                // Rename directory if dir was a temporary ref
-                if (preg_match('/^[\(]?PROV/i', $this->ref))
-                {
-                    // On renomme repertoire facture ($this->ref = ancienne ref, $num = nouvelle ref)
-                    // afin de ne pas perdre les fichiers attaches
-                    $facref = dol_sanitizeFileName($this->ref);
-                    $snumfa = dol_sanitizeFileName($num);
-                    $dirsource = $conf->facture->dir_output.'/'.$facref;
-                    $dirdest = $conf->facture->dir_output.'/'.$snumfa;
-                    if (file_exists($dirsource))
-                    {
-                        dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest);
-
-                        if (@rename($dirsource, $dirdest))
-                        {
-                        	$this->oldref = $facref;
-
-                            dol_syslog("Rename ok");
-                            // Suppression ancien fichier PDF dans nouveau rep
-                            dol_delete_file($conf->facture->dir_output.'/'.$snumfa.'/'.$facref.'*.*');
-                        }
-                    }
-                }
-            }
-
-            // Set new ref and define current statut
-            if (! $error)
-            {
-            	$this->ref = $num;
-                $this->facnumber=$num;
-                $this->statut=1;
-                $this->brouillon=0;
-                $this->date_validation=$now;
-            }
-
-            // Trigger calls
-            if (! $error)
-            {
-                // Appel des triggers
-                include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-                $interface=new Interfaces($this->db);
-                $result=$interface->run_triggers('BILL_VALIDATE',$this,$user,$langs,$conf);
-                if ($result < 0) { $error++; $this->errors=$interface->errors; }
-                // Fin appel triggers
-            }
-        }
-        else
-        {
-            $error++;
-        }
+		$table='paiement_facture';
+		$table2='paiement';
+		$field='fk_facture';
+		$field2='fk_paiement';
+		if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier')
+		{
+			$table='paiementfourn_facturefourn';
+			$table2='paiementfourn';
+			$field='fk_facturefourn';
+			$field2='fk_paiementfourn';
+		}
 
-        if (! $error)
-        {
-            $this->db->commit();
-            return 1;
-        }
-        else
-        {
-            $this->db->rollback();
-            $this->error=$this->db->lasterror();
-            return -1;
-        }
-    }
-
-    /**
-     *	Set draft status
-     *
-     *	@param	User	$user			Object user that modify
-     *	@param	int		$idwarehouse	Id warehouse to use for stock change.
-     *	@return	int						<0 if KO, >0 if OK
-     */
-    function set_draft($user,$idwarehouse=-1)
-    {
-        global $conf,$langs;
-
-        $error=0;
-
-        if ($this->statut == 0)
-        {
-            dol_syslog(get_class($this)."::set_draft already draft status", LOG_WARNING);
-            return 0;
-        }
+		$sql = 'SELECT pf.amount, p.fk_paiement, p.datep, t.code';
+		$sql.= ' FROM '.MAIN_DB_PREFIX.$table.' as pf, '.MAIN_DB_PREFIX.$table2.' as p, '.MAIN_DB_PREFIX.'c_paiement as t';
+		$sql.= ' WHERE pf.'.$field.' = '.$this->id;
+		$sql.= ' AND pf.'.$field2.' = p.rowid';
+		$sql.= ' AND p.fk_paiement = t.id';
+		if ($filtertype) $sql.=" AND t.code='PRE'";
 
-        $this->db->begin();
+		dol_syslog(get_class($this)."::getListOfPayments sql=".$sql, LOG_DEBUG);
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
+			$num = $this->db->num_rows($resql);
+			$i=0;
+			while ($i < $num)
+			{
+				$obj = $this->db->fetch_object($resql);
+				$retarray[]=array('amount'=>$obj->amount,'type'=>$obj->code, 'date'=>$obj->datep);
+				$i++;
+			}
+			$this->db->free($resql);
+			return $retarray;
+		}
+		else
+		{
+			$this->error=$this->db->lasterror();
+			dol_print_error($this->db);
+			return array();
+		}
+	}
 
-        $sql = "UPDATE ".MAIN_DB_PREFIX."facture";
-        $sql.= " SET fk_statut = 0";
-        $sql.= " WHERE rowid = ".$this->id;
 
-        dol_syslog(get_class($this)."::set_draft sql=".$sql, LOG_DEBUG);
-        $result=$this->db->query($sql);
-        if ($result)
-        {
-            // Si on decremente le produit principal et ses composants a la validation de facture, on réincrement
-            if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL))
-            {
-                require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
-                $langs->load("agenda");
-
-                $num=count($this->lines);
-                for ($i = 0; $i < $num; $i++)
-                {
-                    if ($this->lines[$i]->fk_product > 0)
-                    {
-                        $mouvP = new MouvementStock($this->db);
-                        // We decrease stock for product
-                        if ($this->type == 2) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref));
-                        else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref));	// we use 0 for price, to not change the weighted average value
-                    }
-                }
-            }
+	/**
+	 *    	Return amount (with tax) of all credit notes and deposits invoices used by invoice
+	 *
+	 *		@return		int			<0 if KO, Sum of credit notes and deposits amount otherwise
+	 */
+	function getSumCreditNotesUsed()
+	{
+		require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
 
-			if ($error == 0)
-            {
-				$old_statut=$this->statut;
-            	$this->brouillon = 1;
-            	$this->statut = 0;
-				// Appel des triggers
-				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-				$interface=new Interfaces($this->db);
-				$result=$interface->run_triggers('BILL_UNVALIDATE',$this,$user,$langs,$conf);
-				if ($result < 0) {
-					$error++;
-					$this->errors=$interface->errors;
-					$this->statut=$old_statut;
-					$this->brouillon=0;
-				}
-				// Fin appel triggers
-			} else {
-				$this->db->rollback();
-				return -1;
-			}
+		$discountstatic=new DiscountAbsolute($this->db);
+		$result=$discountstatic->getSumCreditNotesUsed($this);
+		if ($result >= 0)
+		{
+			return $result;
+		}
+		else
+		{
+			$this->error=$discountstatic->error;
+			return -1;
+		}
+	}
 
-            if ($error == 0)
-            {
-                $this->db->commit();
-                return 1;
-            }
-            else
-            {
-                $this->db->rollback();
-                return -1;
-            }
-        }
-        else
-        {
-            $this->error=$this->db->error();
-            $this->db->rollback();
-            return -1;
-        }
-    }
-
-
-    /**
-     * 		Add an invoice line into database (linked to product/service or not).
-     * 		Les parametres sont deja cense etre juste et avec valeurs finales a l'appel
-     *		de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini
-     *		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)
-     *
-     * 		@param    	int			$facid           	Id de la facture
-     * 		@param    	string		$desc            	Description de la ligne
-     * 		@param    	double		$pu_ht              Prix unitaire HT (> 0 even for credit note)
-     * 		@param    	double		$qty             	Quantite
-     * 		@param    	double		$txtva           	Taux de tva force, sinon -1
-     * 		@param		double		$txlocaltax1		Local tax 1 rate
-     *  	@param		double		$txlocaltax2		Local tax 2 rate
-     *		@param    	int			$fk_product      	Id du produit/service predefini
-     * 		@param    	double		$remise_percent  	Pourcentage de remise de la ligne
-     * 		@param    	timestamp	$date_start      	Date de debut de validite du service
-     * 		@param    	timestamp	$date_end        	Date de fin de validite du service
-     * 		@param    	int			$ventil          	Code de ventilation comptable
-     * 		@param    	int			$info_bits			Bits de type de lignes
-     *		@param    	int			$fk_remise_except	Id remise
-     *		@param		string		$price_base_type	HT or TTC
-     * 		@param    	double		$pu_ttc             Prix unitaire TTC (> 0 even for credit note)
-     * 		@param		int			$type				Type of line (0=product, 1=service)
-     *      @param      int			$rang               Position of line
-     *      @param		int			$special_code		Special code (also used by externals modules!)
-     *      @param		string		$origin				'order', ...
-     *      @param		int			$origin_id			Id of origin object
-     *      @param		int			$fk_parent_line		Id of parent line
-     * 		@param		int			$fk_fournprice		To calculate margin
-     * 		@param		int			$pa_ht				Buying price of line
-     * 		@param		string		$label				Label of the line
-     *    	@return    	int             				<0 if KO, Id of line if OK
-     */
-    function addline($facid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='')
-    {
-        dol_syslog(get_class($this)."::Addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product,remise_percent=$remise_percent,date_start=$date_start,date_end=$date_end,ventil=$ventil,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type", LOG_DEBUG);
-        include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
-
-        // Clean parameters
-        if (empty($remise_percent)) $remise_percent=0;
-        if (empty($qty)) $qty=0;
-        if (empty($info_bits)) $info_bits=0;
-        if (empty($rang)) $rang=0;
-        if (empty($ventil)) $ventil=0;
-        if (empty($txtva)) $txtva=0;
-        if (empty($txlocaltax1)) $txlocaltax1=0;
-        if (empty($txlocaltax2)) $txlocaltax2=0;
-        if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0;
-
-        $remise_percent=price2num($remise_percent);
-        $qty=price2num($qty);
-        $pu_ht=price2num($pu_ht);
-        $pu_ttc=price2num($pu_ttc);
-        $pa_ht=price2num($pa_ht);
-        $txtva=price2num($txtva);
-        $txlocaltax1=price2num($txlocaltax1);
-        $txlocaltax2=price2num($txlocaltax2);
-
-        if ($price_base_type=='HT')
-        {
-            $pu=$pu_ht;
-        }
-        else
-        {
-            $pu=$pu_ttc;
-        }
+	/**
+	 *    	Return amount (with tax) of all deposits invoices used by invoice
+	 *
+	 *		@return		int			<0 if KO, Sum of deposits amount otherwise
+	 */
+	function getSumDepositsUsed()
+	{
+		require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
 
-        // Check parameters
-        if ($type < 0) return -1;
+		$discountstatic=new DiscountAbsolute($this->db);
+		$result=$discountstatic->getSumDepositsUsed($this);
+		if ($result >= 0)
+		{
+			return $result;
+		}
+		else
+		{
+			$this->error=$discountstatic->error;
+			return -1;
+		}
+	}
 
-        if (! empty($this->brouillon))
-        {
-            $this->db->begin();
-
-            // Calcul du total TTC et de la TVA pour la ligne a partir de
-            // qty, pu, remise_percent et txtva
-            // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
-            // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
-            $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type);
-            $total_ht  = $tabprice[0];
-            $total_tva = $tabprice[1];
-            $total_ttc = $tabprice[2];
-            $total_localtax1 = $tabprice[9];
-            $total_localtax2 = $tabprice[10];
-            $pu_ht = $tabprice[3];
-
-            // Rang to use
-            $rangtouse = $rang;
-            if ($rangtouse == -1)
-            {
-                $rangmax = $this->line_max($fk_parent_line);
-                $rangtouse = $rangmax + 1;
-            }
-
-            $product_type=$type;
-            if ($fk_product)
-            {
-                $product=new Product($this->db);
-                $result=$product->fetch($fk_product);
-                $product_type=$product->type;
-            }
-
-            // Insert line
-            $this->line=new FactureLigne($this->db);
-            $this->line->fk_facture=$facid;
-            $this->line->label=$label;
-            $this->line->desc=$desc;
-            $this->line->qty=            ($this->type==2?abs($qty):$qty);	// For credit note, quantity is always positive and unit price negative
-            $this->line->tva_tx=$txtva;
-            $this->line->localtax1_tx=$txlocaltax1;
-            $this->line->localtax2_tx=$txlocaltax2;
-            $this->line->fk_product=$fk_product;
-            $this->line->product_type=$product_type;
-            $this->line->remise_percent=$remise_percent;
-            $this->line->subprice=       ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise
-            $this->line->date_start=$date_start;
-            $this->line->date_end=$date_end;
-            $this->line->ventil=$ventil;
-            $this->line->rang=$rangtouse;
-            $this->line->info_bits=$info_bits;
-            $this->line->fk_remise_except=$fk_remise_except;
-            $this->line->total_ht=       (($this->type==2||$qty<0)?-abs($total_ht):$total_ht);  // For credit note and if qty is negative, total is negative
-            $this->line->total_tva=      (($this->type==2||$qty<0)?-abs($total_tva):$total_tva);
-            $this->line->total_localtax1=(($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1);
-            $this->line->total_localtax2=(($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2);
-            $this->line->total_ttc=      (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc);
-            $this->line->special_code=$special_code;
-            $this->line->fk_parent_line=$fk_parent_line;
-            $this->line->origin=$origin;
-            $this->line->origin_id=$origin_id;
+	/**
+	 *      Return next reference of customer invoice not already used (or last reference)
+	 *      according to numbering module defined into constant FACTURE_ADDON
+	 *
+	 *      @param	   Society		$soc		object company
+	 *      @param     string		$mode		'next' for next value or 'last' for last value
+	 *      @return    string					free ref or last ref
+	 */
+	function getNextNumRef($soc,$mode='next')
+	{
+		global $conf, $db, $langs;
+		$langs->load("bills");
 
-			// infos marge
-			$this->line->fk_fournprice = $fk_fournprice;
-			$this->line->pa_ht = $pa_ht;
+		// Clean parameters (if not defined or using deprecated value)
+		if (empty($conf->global->FACTURE_ADDON)) $conf->global->FACTURE_ADDON='mod_facture_terre';
+		else if ($conf->global->FACTURE_ADDON=='terre') $conf->global->FACTURE_ADDON='mod_facture_terre';
+		else if ($conf->global->FACTURE_ADDON=='mercure') $conf->global->FACTURE_ADDON='mod_facture_mercure';
 
-            $result=$this->line->insert();
-            if ($result > 0)
-            {
-            	// Reorder if child line
-				if (! empty($fk_parent_line)) $this->line_order(true,'DESC');
+		$mybool=false;
 
-                // Mise a jour informations denormalisees au niveau de la facture meme
-                $this->id=$facid;	// TODO To move this we must remove parameter facid into this function declaration
-                $result=$this->update_price(1);
-                if ($result > 0)
-                {
-                    $this->db->commit();
-                    return $this->line->rowid;
-                }
-                else
-                {
-                    $this->error=$this->db->error();
-                    dol_syslog("Error sql=$sql, error=".$this->error,LOG_ERR);
-                    $this->db->rollback();
-                    return -1;
-                }
-            }
-            else
-            {
-                $this->error=$this->line->error;
-                $this->db->rollback();
-                return -2;
-            }
-        }
-    }
-
-    /**
-     *  Update a detail line
-     *
-     *  @param     	int			$rowid           	Id of line to update
-     *  @param     	string		$desc            	Description of line
-     *  @param     	double		$pu              	Prix unitaire (HT ou TTC selon price_base_type) (> 0 even for credit note lines)
-     *  @param     	double		$qty             	Quantity
-     *  @param     	double		$remise_percent  	Pourcentage de remise de la ligne
-     *  @param     	date		$date_start      	Date de debut de validite du service
-     *  @param     	date		$date_end        	Date de fin de validite du service
-     *  @param     	double		$txtva          	VAT Rate
-     * 	@param		double		$txlocaltax1		Local tax 1 rate
-     *  @param		double		$txlocaltax2		Local tax 2 rate
-     * 	@param     	string		$price_base_type 	HT or TTC
-     * 	@param     	int			$info_bits 		    Miscellaneous informations
-     * 	@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)
-     * 	@param		int			$fk_fournprice		Id of origin supplier price
-     * 	@param		int			$pa_ht				Price (without tax) of product when it was bought
-     * 	@param		string		$label				Label of the line
-     * 	@param		int			$special_code		Special code (also used by externals modules!)
-     *  @return    	int             				< 0 if KO, > 0 if OK
-     */
-    function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0)
-    {
-        include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
-
-        dol_syslog(get_class($this)."::updateline $rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1, $txlocaltax2, $price_base_type, $info_bits, $type, $fk_parent_line", LOG_DEBUG);
-
-        if ($this->brouillon)
-        {
-            $this->db->begin();
-
-            // Clean parameters
-            if (empty($qty)) $qty=0;
-            if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0;
-            if (empty($special_code) || $special_code == 3) $special_code=0;
-
-            $remise_percent	= price2num($remise_percent);
-            $qty			= price2num($qty);
-            $pu 			= price2num($pu);
-            $pa_ht			= price2num($pa_ht);
-            $txtva			= price2num($txtva);
-            $txlocaltax1	= price2num($txlocaltax1);
-            $txlocaltax2	= price2num($txlocaltax2);
-
-            // Check parameters
-            if ($type < 0) return -1;
-
-            // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva
-            // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
-            // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
-            $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type);
-            $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];
-
-            // Old properties: $price, $remise (deprecated)
-            $price = $pu;
-            $remise = 0;
-            if ($remise_percent > 0)
-            {
-                $remise = round(($pu * $remise_percent / 100),2);
-                $price = ($pu - $remise);
-            }
-            $price    = price2num($price);
-
-            // Update line into database
-            $this->line=new FactureLigne($this->db);
-
-            // Stock previous line records
-			$staticline=new FactureLigne($this->db);
-			$staticline->fetch($rowid);
-			$this->line->oldline = $staticline;
+		$file = $conf->global->FACTURE_ADDON.".php";
+		$classname = $conf->global->FACTURE_ADDON;
+		// Include file with class
+		foreach ($conf->file->dol_document_root as $dirroot)
+		{
+			$dir = $dirroot."/core/modules/facture/";
+			// Load file with numbering class (if found)
+			$mybool|=@include_once $dir.$file;
+		}
 
-			// Reorder if fk_parent_line change
-			if (! empty($fk_parent_line) && ! empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line)
+		// For compatibility
+		if (! $mybool)
+		{
+			$file = $conf->global->FACTURE_ADDON."/".$conf->global->FACTURE_ADDON.".modules.php";
+			$classname = "mod_facture_".$conf->global->FACTURE_ADDON;
+			// Include file with class
+			foreach ($conf->file->dol_document_root as $dirroot)
 			{
-				$rangmax = $this->line_max($fk_parent_line);
-				$this->line->rang = $rangmax + 1;
+				$dir = $dirroot."/core/modules/facture/";
+				// Load file with numbering class (if found)
+				$mybool|=@include_once $dir.$file;
 			}
+		}
+		//print "xx".$mybool.$dir.$file."-".$classname;
 
-            $this->line->rowid				= $rowid;
-            $this->line->label				= $label;
-            $this->line->desc				= $desc;
-            $this->line->qty				= ($this->type==2?abs($qty):$qty);	// For credit note, quantity is always positive and unit price negative
-            $this->line->tva_tx				= $txtva;
-            $this->line->localtax1_tx		= $txlocaltax1;
-            $this->line->localtax2_tx		= $txlocaltax2;
-            $this->line->remise_percent		= $remise_percent;
-            $this->line->subprice			= ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise
-            $this->line->date_start			= $date_start;
-            $this->line->date_end			= $date_end;
-            $this->line->total_ht			= (($this->type==2||$qty<0)?-abs($total_ht):$total_ht);  // For credit note and if qty is negative, total is negative
-            $this->line->total_tva			= (($this->type==2||$qty<0)?-abs($total_tva):$total_tva);
-            $this->line->total_localtax1	= (($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1);
-            $this->line->total_localtax2	= (($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2);
-            $this->line->total_ttc			= (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc);
-            $this->line->info_bits			= $info_bits;
-            $this->line->special_code		= $special_code;
-            $this->line->product_type		= $type;
-            $this->line->fk_parent_line		= $fk_parent_line;
-            $this->line->skip_update_total	= $skip_update_total;
+		if (! $mybool)
+		{
+			dol_print_error('',"Failed to include file ".$file);
+			return '';
+		}
 
-			// infos marge
-			$this->line->fk_fournprice = $fk_fournprice;
-			$this->line->pa_ht = $pa_ht;
+		$obj = new $classname();
 
-            // A ne plus utiliser
-            //$this->line->price=$price;
-            //$this->line->remise=$remise;
-
-            $result=$this->line->update();
-            if ($result > 0)
-            {
-            	// Reorder if child line
-            	if (! empty($fk_parent_line)) $this->line_order(true,'DESC');
-
-                // Mise a jour info denormalisees au niveau facture
-                $this->update_price(1);
-                $this->db->commit();
-                return $result;
-            }
-            else
-            {
-                $this->db->rollback();
-                return -1;
-            }
-        }
-        else
-        {
-            $this->error="Invoice statut makes operation forbidden";
-            return -2;
-        }
-    }
+		$numref = "";
+		$numref = $obj->getNumRef($soc,$this,$mode);
+
+		if ( $numref != "")
+		{
+			return $numref;
+		}
+		else
+		{
+			//dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error);
+			return false;
+		}
+	}
 
-    /**
-     *	Delete line in database
-     *
-     *	@param		int		$rowid		Id of line to delete
-     *	@return		int					<0 if KO, >0 if OK
-     */
-    function deleteline($rowid)
-    {
-        global $langs, $conf;
+	/**
+	 *	Load miscellaneous information for tab "Info"
+	 *
+	 *	@param  int		$id		Id of object to load
+	 *	@return	void
+	 */
+	function info($id)
+	{
+		$sql = 'SELECT c.rowid, datec, date_valid as datev, tms as datem,';
+		$sql.= ' fk_user_author, fk_user_valid';
+		$sql.= ' FROM '.MAIN_DB_PREFIX.'facture as c';
+		$sql.= ' WHERE c.rowid = '.$id;
 
-        dol_syslog(get_class($this)."::deleteline rowid=".$rowid, LOG_DEBUG);
+		$result=$this->db->query($sql);
+		if ($result)
+		{
+			if ($this->db->num_rows($result))
+			{
+				$obj = $this->db->fetch_object($result);
+				$this->id = $obj->rowid;
+				if ($obj->fk_user_author)
+				{
+					$cuser = new User($this->db);
+					$cuser->fetch($obj->fk_user_author);
+					$this->user_creation     = $cuser;
+				}
+				if ($obj->fk_user_valid)
+				{
+					$vuser = new User($this->db);
+					$vuser->fetch($obj->fk_user_valid);
+					$this->user_validation = $vuser;
+				}
+				$this->date_creation     = $this->db->jdate($obj->datec);
+				$this->date_modification = $this->db->jdate($obj->datem);
+				$this->date_validation   = $this->db->jdate($obj->datev);	// Should be in log table
+			}
+			$this->db->free($result);
+		}
+		else
+		{
+			dol_print_error($this->db);
+		}
+	}
 
-        if (! $this->brouillon)
-        {
-            $this->error='ErrorBadStatus';
-            return -1;
-        }
+	/**
+	 *	Renvoi si les lignes de facture sont ventilees et/ou exportees en compta
+	 *
+	 *   @return     int         <0 if KO, 0=no, 1=yes
+	 */
+	function getVentilExportCompta()
+	{
+		// On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
+		$ventilExportCompta = 0 ;
+		$num=count($this->lines);
+		for ($i = 0; $i < $num; $i++)
+		{
+			if ($this->lines[$i]->export_compta <> 0 && $this->lines[$i]->code_ventilation <> 0)
+			{
+				$ventilExportCompta++;
+			}
+		}
 
-        $this->db->begin();
+		if ($ventilExportCompta <> 0)
+		{
+			return 1;
+		}
+		else
+		{
+			return 0;
+		}
+	}
 
-        // Libere remise liee a ligne de facture
-        $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
-        $sql.= ' SET fk_facture_line = NULL';
-        $sql.= ' WHERE fk_facture_line = '.$rowid;
 
-        dol_syslog(get_class($this)."::deleteline sql=".$sql);
-        $result = $this->db->query($sql);
-        if (! $result)
-        {
-            $this->error=$this->db->error();
-            dol_syslog(get_class($this)."::deleteline Error ".$this->error, LOG_ERR);
-            $this->db->rollback();
-            return -1;
-        }
+	/**
+	 *  Return if an invoice can be deleted
+	 *	Rule is:
+	 *	If hidden option INVOICE_CAN_ALWAYS_BE_REMOVED is on, we can
+	 *  If invoice has a definitive ref, is last, without payment and not dipatched into accountancy -> yes end of rule
+	 *  If invoice is draft and ha a temporary ref -> yes
+	 *
+	 *  @return    int         <0 if KO, 0=no, 1=yes
+	 */
+	function is_erasable()
+	{
+		global $conf;
 
-        $line=new FactureLigne($this->db);
+		if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED)) return 1;
+		if (! empty($conf->global->INVOICE_CAN_NEVER_BE_REMOVED))  return 0;
 
-        // For triggers
-        $line->fetch($rowid);
+		// on verifie si la facture est en numerotation provisoire
+		$facref = substr($this->ref, 1, 4);
 
-        if ($line->delete() > 0)
-        {
-        	$result=$this->update_price(1);
-
-        	if ($result > 0)
-        	{
-        		$this->db->commit();
-        		return 1;
-        	}
-        	else
-        	{
-        		$this->db->rollback();
-        		$this->error=$this->db->lasterror();
-        		return -1;
-        	}
-        }
-        else
-        {
-        	$this->db->rollback();
-        	$this->error=$this->db->lasterror();
-        	return -1;
-        }
-    }
-
-    /**
-     *	Set percent discount
-     *
-     *	@param     	User	$user		User that set discount
-     *	@param     	double	$remise		Discount
-     *	@return		int 		<0 if ko, >0 if ok
-     */
-    function set_remise($user, $remise)
-    {
-        // Clean parameters
-        if (empty($remise)) $remise=0;
-
-        if ($user->rights->facture->creer)
-        {
-            $remise=price2num($remise);
-
-            $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
-            $sql.= ' SET remise_percent = '.$remise;
-            $sql.= ' WHERE rowid = '.$this->id;
-            $sql.= ' AND fk_statut = 0 ;';
-
-            if ($this->db->query($sql))
-            {
-                $this->remise_percent = $remise;
-                $this->update_price(1);
-                return 1;
-            }
-            else
-            {
-                $this->error=$this->db->error();
-                return -1;
-            }
-        }
-    }
+		// If not a draft invoice and not temporary invoice
+		if ($facref != 'PROV')
+		{
+			$maxfacnumber = $this->getNextNumRef($this->client,'last');
+			$ventilExportCompta = $this->getVentilExportCompta();
+			// If there is no invoice into the reset range and not already dispatched, we can delete
+			if ($maxfacnumber == '' && $ventilExportCompta == 0) return 1;
+			// If invoice to delete is last one and not already dispatched, we can delete
+			if ($maxfacnumber == $this->ref && $ventilExportCompta == 0) return 1;
+		}
+		else if ($this->statut == 0 && $facref == 'PROV') // Si facture brouillon et provisoire
+		{
+			return 1;
+		}
 
+		return 0;
+	}
 
-    /**
-     *	Set absolute discount
-     *
-     *	@param     	User	$user 		User that set discount
-     *	@param     	double	$remise		Discount
-     *	@return		int 				<0 if KO, >0 if OK
-     */
-    function set_remise_absolue($user, $remise)
-    {
-        if (empty($remise)) $remise=0;
 
-        if ($user->rights->facture->creer)
-        {
-            $remise=price2num($remise);
-
-            $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
-            $sql.= ' SET remise_absolue = '.$remise;
-            $sql.= ' WHERE rowid = '.$this->id;
-            $sql.= ' AND fk_statut = 0 ;';
-
-            dol_syslog(get_class($this)."::set_remise_absolue sql=$sql");
-
-            if ($this->db->query($sql))
-            {
-                $this->remise_absolue = $remise;
-                $this->update_price(1);
-                return 1;
-            }
-            else
-            {
-                $this->error=$this->db->error();
-                return -1;
-            }
-        }
-    }
-
-    /**
-     *  Return list of payments
-     *
-     *	@param		string	$filtertype		1 to filter on type of payment == 'PRE'
-     *  @return     array					Array with list of payments
-     */
-    function getListOfPayments($filtertype='')
-    {
-        $retarray=array();
-
-        $table='paiement_facture';
-        $table2='paiement';
-        $field='fk_facture';
-        $field2='fk_paiement';
-        if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier')
-        {
-            $table='paiementfourn_facturefourn';
-            $table2='paiementfourn';
-            $field='fk_facturefourn';
-            $field2='fk_paiementfourn';
-        }
+	/**
+	 *	Renvoi liste des factures remplacables
+	 *	Statut validee ou abandonnee pour raison autre + non payee + aucun paiement + pas deja remplacee
+	 *
+	 *	@param		int		$socid		Id societe
+	 *	@return    	array				Tableau des factures ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1)
+	 */
+	function list_replacable_invoices($socid=0)
+	{
+		global $conf;
+
+		$return = array();
+
+		$sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut,";
+		$sql.= " ff.rowid as rowidnext";
+		$sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
+		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture";
+		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON f.rowid = ff.fk_facture_source";
+		$sql.= " WHERE (f.fk_statut = 1 OR (f.fk_statut = 3 AND f.close_code = 'abandon'))";
+		$sql.= " AND f.entity = ".$conf->entity;
+		$sql.= " AND f.paye = 0";					// Pas classee payee completement
+		$sql.= " AND pf.fk_paiement IS NULL";		// Aucun paiement deja fait
+		$sql.= " AND ff.fk_statut IS NULL";			// Renvoi vrai si pas facture de remplacement
+		if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid;
+		$sql.= " ORDER BY f.facnumber";
+
+		dol_syslog(get_class($this)."::list_replacable_invoices sql=$sql");
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
+			while ($obj=$this->db->fetch_object($resql))
+			{
+				$return[$obj->rowid]=array(	'id' => $obj->rowid,
+				'ref' => $obj->facnumber,
+				'status' => $obj->fk_statut);
+			}
+			//print_r($return);
+			return $return;
+		}
+		else
+		{
+			$this->error=$this->db->error();
+			dol_syslog(get_class($this)."::list_replacable_invoices ".$this->error, LOG_ERR);
+			return -1;
+		}
+	}
 
-        $sql = 'SELECT pf.amount, p.fk_paiement, p.datep, t.code';
-        $sql.= ' FROM '.MAIN_DB_PREFIX.$table.' as pf, '.MAIN_DB_PREFIX.$table2.' as p, '.MAIN_DB_PREFIX.'c_paiement as t';
-        $sql.= ' WHERE pf.'.$field.' = '.$this->id;
-        $sql.= ' AND pf.'.$field2.' = p.rowid';
-        $sql.= ' AND p.fk_paiement = t.id';
-        if ($filtertype) $sql.=" AND t.code='PRE'";
 
-        dol_syslog(get_class($this)."::getListOfPayments sql=".$sql, LOG_DEBUG);
-        $resql=$this->db->query($sql);
-        if ($resql)
-        {
-            $num = $this->db->num_rows($resql);
-            $i=0;
-            while ($i < $num)
-            {
-                $obj = $this->db->fetch_object($resql);
-                $retarray[]=array('amount'=>$obj->amount,'type'=>$obj->code, 'date'=>$obj->datep);
-                $i++;
-            }
-            $this->db->free($resql);
-            return $retarray;
-        }
-        else
-        {
-            $this->error=$this->db->lasterror();
-            dol_print_error($this->db);
-            return array();
-        }
-    }
+	/**
+	 *	Renvoi liste des factures qualifiables pour correction par avoir
+	 *	Les factures qui respectent les regles suivantes sont retournees:
+	 *	(validee + paiement en cours) ou classee (payee completement ou payee partiellement) + pas deja remplacee + pas deja avoir
+	 *
+	 *	@param		int		$socid		Id societe
+	 *	@return    	array				Tableau des factures ($id => array('ref'=>,'paymentornot'=>,'status'=>,'paye'=>)
+	 */
+	function list_qualified_avoir_invoices($socid=0)
+	{
+		global $conf;
+
+		$return = array();
+
+		$sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut, f.type, f.paye, pf.fk_paiement";
+		$sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
+		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture";
+		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=1)";
+		$sql.= " WHERE f.entity = ".$conf->entity;
+		$sql.= " AND f.fk_statut in (1,2)";
+		//  $sql.= " WHERE f.fk_statut >= 1";
+		//	$sql.= " AND (f.paye = 1";				// Classee payee completement
+		//	$sql.= " OR f.close_code IS NOT NULL)";	// Classee payee partiellement
+		$sql.= " AND ff.type IS NULL";			// Renvoi vrai si pas facture de remplacement
+		$sql.= " AND f.type != 2";				// Type non 2 si facture non avoir
+		if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid;
+		$sql.= " ORDER BY f.facnumber";
+
+		dol_syslog(get_class($this)."::list_qualified_avoir_invoices sql=".$sql);
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
+			while ($obj=$this->db->fetch_object($resql))
+			{
+				$qualified=0;
+				if ($obj->fk_statut == 1) $qualified=1;
+				if ($obj->fk_statut == 2) $qualified=1;
+				if ($qualified)
+				{
+					//$ref=$obj->facnumber;
+					$paymentornot=($obj->fk_paiement?1:0);
+					$return[$obj->rowid]=array('ref'=>$obj->facnumber,'status'=>$obj->fk_statut,'type'=>$obj->type,'paye'=>$obj->paye,'paymentornot'=>$paymentornot);
+				}
+			}
 
+			return $return;
+		}
+		else
+		{
+			$this->error=$this->db->error();
+			dol_syslog(get_class($this)."::list_avoir_invoices ".$this->error, LOG_ERR);
+			return -1;
+		}
+	}
 
-    /**
-     *    	Return amount (with tax) of all credit notes and deposits invoices used by invoice
-     *
-     *		@return		int			<0 if KO, Sum of credit notes and deposits amount otherwise
-     */
-    function getSumCreditNotesUsed()
-    {
-        require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
 
-        $discountstatic=new DiscountAbsolute($this->db);
-        $result=$discountstatic->getSumCreditNotesUsed($this);
-        if ($result >= 0)
-        {
-            return $result;
-        }
-        else
-        {
-            $this->error=$discountstatic->error;
-            return -1;
-        }
-    }
-
-    /**
-     *    	Return amount (with tax) of all deposits invoices used by invoice
-     *
-     *		@return		int			<0 if KO, Sum of deposits amount otherwise
-     */
-    function getSumDepositsUsed()
-    {
-        require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
-
-        $discountstatic=new DiscountAbsolute($this->db);
-        $result=$discountstatic->getSumDepositsUsed($this);
-        if ($result >= 0)
-        {
-            return $result;
-        }
-        else
-        {
-            $this->error=$discountstatic->error;
-            return -1;
-        }
-    }
-
-    /**
-     *      Return next reference of customer invoice not already used (or last reference)
-     *      according to numbering module defined into constant FACTURE_ADDON
-     *
-     *      @param	   Society		$soc		object company
-     *      @param     string		$mode		'next' for next value or 'last' for last value
-     *      @return    string					free ref or last ref
-     */
-    function getNextNumRef($soc,$mode='next')
-    {
-        global $conf, $db, $langs;
-        $langs->load("bills");
-
-        // Clean parameters (if not defined or using deprecated value)
-        if (empty($conf->global->FACTURE_ADDON)) $conf->global->FACTURE_ADDON='mod_facture_terre';
-        else if ($conf->global->FACTURE_ADDON=='terre') $conf->global->FACTURE_ADDON='mod_facture_terre';
-        else if ($conf->global->FACTURE_ADDON=='mercure') $conf->global->FACTURE_ADDON='mod_facture_mercure';
-
-        $mybool=false;
-
-        $file = $conf->global->FACTURE_ADDON.".php";
-        $classname = $conf->global->FACTURE_ADDON;
-        // Include file with class
-        foreach ($conf->file->dol_document_root as $dirroot)
-        {
-            $dir = $dirroot."/core/modules/facture/";
-            // Load file with numbering class (if found)
-            $mybool|=@include_once $dir.$file;
-        }
+	/**
+	 *	Create a withdrawal request for a standing order
+	 *
+	 *	@param      User	$user       User asking standing order
+	 *	@return     int         		<0 if KO, >0 if OK
+	 */
+	function demande_prelevement($user)
+	{
+		dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG);
 
-        // For compatibility
-        if (! $mybool)
-        {
-            $file = $conf->global->FACTURE_ADDON."/".$conf->global->FACTURE_ADDON.".modules.php";
-            $classname = "mod_facture_".$conf->global->FACTURE_ADDON;
-            // Include file with class
-            foreach ($conf->file->dol_document_root as $dirroot)
-            {
-                $dir = $dirroot."/core/modules/facture/";
-                // Load file with numbering class (if found)
-                $mybool|=@include_once $dir.$file;
-            }
-        }
-        //print "xx".$mybool.$dir.$file."-".$classname;
+		$soc = new Societe($this->db);
+		$soc->id = $this->socid;
+		$soc->load_ban();
 
-        if (! $mybool)
-        {
-            dol_print_error('',"Failed to include file ".$file);
-            return '';
-        }
+		if ($this->statut > 0 && $this->paye == 0)
+		{
+			$sql = 'SELECT count(*)';
+			$sql.= ' FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande';
+			$sql.= ' WHERE fk_facture = '.$this->id;
+			$sql.= ' AND traite = 0';
+
+			$resql=$this->db->query($sql);
+			if ($resql)
+			{
+				$row = $this->db->fetch_row($resql);
+				if ($row[0] == 0)
+				{
+					$now=dol_now();
+
+					$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande';
+					$sql .= ' (fk_facture, amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib)';
+					$sql .= ' VALUES ('.$this->id;
+					$sql .= ",'".price2num($this->total_ttc)."'";
+					$sql .= ",".$this->db->idate($now).",".$user->id;
+					$sql .= ",'".$soc->bank_account->code_banque."'";
+					$sql .= ",'".$soc->bank_account->code_guichet."'";
+					$sql .= ",'".$soc->bank_account->number."'";
+					$sql .= ",'".$soc->bank_account->cle_rib."')";
+					if ( $this->db->query($sql))
+					{
+						return 1;
+					}
+					else
+					{
+						$this->error=$this->db->error();
+						dol_syslog(get_class($this).'::demandeprelevement Erreur');
+						return -1;
+					}
+				}
+				else
+				{
+					$this->error="A request already exists";
+					dol_syslog(get_class($this).'::demandeprelevement Impossible de creer une demande, demande deja en cours');
+				}
+			}
+			else
+			{
+				$this->error=$this->db->error();
+				dol_syslog(get_class($this).'::demandeprelevement Erreur -2');
+				return -2;
+			}
+		}
+		else
+		{
+			$this->error="Status of invoice does not allow this";
+			dol_syslog(get_class($this)."::demandeprelevement ".$this->error." $this->statut, $this->paye, $this->mode_reglement_id");
+			return -3;
+		}
+	}
 
-        $obj = new $classname();
+	/**
+	 *  Supprime une demande de prelevement
+	 *
+	 *  @param  Use		$user       utilisateur creant la demande
+	 *  @param  int		$did        id de la demande a supprimer
+	 *  @return	int					<0 if OK, >0 if KO
+	 */
+	function demande_prelevement_delete($user, $did)
+	{
+		$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande';
+		$sql .= ' WHERE rowid = '.$did;
+		$sql .= ' AND traite = 0';
+		if ( $this->db->query($sql) )
+		{
+			return 0;
+		}
+		else
+		{
+			$this->error=$this->db->lasterror();
+			dol_syslog(get_class($this).'::demande_prelevement_delete Error '.$this->error);
+			return -1;
+		}
+	}
 
-        $numref = "";
-        $numref = $obj->getNumRef($soc,$this,$mode);
 
-        if ( $numref != "")
-        {
-            return $numref;
-        }
-        else
-        {
-            //dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error);
-            return false;
-        }
-    }
-
-    /**
-     *	Load miscellaneous information for tab "Info"
-     *
-     *	@param  int		$id		Id of object to load
-     *	@return	void
-     */
-    function info($id)
-    {
-        $sql = 'SELECT c.rowid, datec, date_valid as datev, tms as datem,';
-        $sql.= ' fk_user_author, fk_user_valid';
-        $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as c';
-        $sql.= ' WHERE c.rowid = '.$id;
-
-        $result=$this->db->query($sql);
-        if ($result)
-        {
-            if ($this->db->num_rows($result))
-            {
-                $obj = $this->db->fetch_object($result);
-                $this->id = $obj->rowid;
-                if ($obj->fk_user_author)
-                {
-                    $cuser = new User($this->db);
-                    $cuser->fetch($obj->fk_user_author);
-                    $this->user_creation     = $cuser;
-                }
-                if ($obj->fk_user_valid)
-                {
-                    $vuser = new User($this->db);
-                    $vuser->fetch($obj->fk_user_valid);
-                    $this->user_validation = $vuser;
-                }
-                $this->date_creation     = $this->db->jdate($obj->datec);
-                $this->date_modification = $this->db->jdate($obj->datem);
-                $this->date_validation   = $this->db->jdate($obj->datev);	// Should be in log table
-            }
-            $this->db->free($result);
-        }
-        else
-        {
-            dol_print_error($this->db);
-        }
-    }
-
-    /**
-     *	Renvoi si les lignes de facture sont ventilees et/ou exportees en compta
-     *
-     *   @return     int         <0 if KO, 0=no, 1=yes
-     */
-    function getVentilExportCompta()
-    {
-        // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
-        $ventilExportCompta = 0 ;
-        $num=count($this->lines);
-        for ($i = 0; $i < $num; $i++)
-        {
-            if ($this->lines[$i]->export_compta <> 0 && $this->lines[$i]->code_ventilation <> 0)
-            {
-                $ventilExportCompta++;
-            }
-        }
+	/**
+	 *	Load indicators for dashboard (this->nbtodo and this->nbtodolate)
+	 *
+	 *	@param      User	$user    	Object user
+	 *	@return     int                 <0 if KO, >0 if OK
+	 */
+	function load_board($user)
+	{
+		global $conf, $user;
 
-        if ($ventilExportCompta <> 0)
-        {
-            return 1;
-        }
-        else
-        {
-            return 0;
-        }
-    }
-
-
-    /**
-     *  Return if an invoice can be deleted
-     *	Rule is:
-     *	If hidden option INVOICE_CAN_ALWAYS_BE_REMOVED is on, we can
-     *  If invoice has a definitive ref, is last, without payment and not dipatched into accountancy -> yes end of rule
-     *  If invoice is draft and ha a temporary ref -> yes
-     *
-     *  @return    int         <0 if KO, 0=no, 1=yes
-     */
-    function is_erasable()
-    {
-        global $conf;
-
-        if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED)) return 1;
-        if (! empty($conf->global->INVOICE_CAN_NEVER_BE_REMOVED))  return 0;
-
-        // on verifie si la facture est en numerotation provisoire
-        $facref = substr($this->ref, 1, 4);
-
-        // If not a draft invoice and not temporary invoice
-        if ($facref != 'PROV')
-        {
-            $maxfacnumber = $this->getNextNumRef($this->client,'last');
-            $ventilExportCompta = $this->getVentilExportCompta();
-            // If there is no invoice into the reset range and not already dispatched, we can delete
-            if ($maxfacnumber == '' && $ventilExportCompta == 0) return 1;
-            // If invoice to delete is last one and not already dispatched, we can delete
-            if ($maxfacnumber == $this->ref && $ventilExportCompta == 0) return 1;
-        }
-        else if ($this->statut == 0 && $facref == 'PROV') // Si facture brouillon et provisoire
-        {
-            return 1;
-        }
+		$now=dol_now();
 
-        return 0;
-    }
-
-
-    /**
-     *	Renvoi liste des factures remplacables
-     *	Statut validee ou abandonnee pour raison autre + non payee + aucun paiement + pas deja remplacee
-     *
-     *	@param		int		$socid		Id societe
-     *	@return    	array				Tableau des factures ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1)
-     */
-    function list_replacable_invoices($socid=0)
-    {
-        global $conf;
-
-        $return = array();
-
-        $sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut,";
-        $sql.= " ff.rowid as rowidnext";
-        $sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
-        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture";
-        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON f.rowid = ff.fk_facture_source";
-        $sql.= " WHERE (f.fk_statut = 1 OR (f.fk_statut = 3 AND f.close_code = 'abandon'))";
-        $sql.= " AND f.entity = ".$conf->entity;
-        $sql.= " AND f.paye = 0";					// Pas classee payee completement
-        $sql.= " AND pf.fk_paiement IS NULL";		// Aucun paiement deja fait
-        $sql.= " AND ff.fk_statut IS NULL";			// Renvoi vrai si pas facture de remplacement
-        if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid;
-        $sql.= " ORDER BY f.facnumber";
-
-        dol_syslog(get_class($this)."::list_replacable_invoices sql=$sql");
-        $resql=$this->db->query($sql);
-        if ($resql)
-        {
-            while ($obj=$this->db->fetch_object($resql))
-            {
-                $return[$obj->rowid]=array(	'id' => $obj->rowid,
-				'ref' => $obj->facnumber,
-				'status' => $obj->fk_statut);
-            }
-            //print_r($return);
-            return $return;
-        }
-        else
-        {
-            $this->error=$this->db->error();
-            dol_syslog(get_class($this)."::list_replacable_invoices ".$this->error, LOG_ERR);
-            return -1;
-        }
-    }
-
-
-    /**
-     *	Renvoi liste des factures qualifiables pour correction par avoir
-     *	Les factures qui respectent les regles suivantes sont retournees:
-     *	(validee + paiement en cours) ou classee (payee completement ou payee partiellement) + pas deja remplacee + pas deja avoir
-     *
-     *	@param		int		$socid		Id societe
-     *	@return    	array				Tableau des factures ($id => array('ref'=>,'paymentornot'=>,'status'=>,'paye'=>)
-     */
-    function list_qualified_avoir_invoices($socid=0)
-    {
-        global $conf;
-
-        $return = array();
-
-        $sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut, f.type, f.paye, pf.fk_paiement";
-        $sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
-        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture";
-        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=1)";
-        $sql.= " WHERE f.entity = ".$conf->entity;
-        $sql.= " AND f.fk_statut in (1,2)";
-        //  $sql.= " WHERE f.fk_statut >= 1";
-        //	$sql.= " AND (f.paye = 1";				// Classee payee completement
-        //	$sql.= " OR f.close_code IS NOT NULL)";	// Classee payee partiellement
-        $sql.= " AND ff.type IS NULL";			// Renvoi vrai si pas facture de remplacement
-        $sql.= " AND f.type != 2";				// Type non 2 si facture non avoir
-        if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid;
-        $sql.= " ORDER BY f.facnumber";
-
-        dol_syslog(get_class($this)."::list_qualified_avoir_invoices sql=".$sql);
-        $resql=$this->db->query($sql);
-        if ($resql)
-        {
-            while ($obj=$this->db->fetch_object($resql))
-            {
-                $qualified=0;
-                if ($obj->fk_statut == 1) $qualified=1;
-                if ($obj->fk_statut == 2) $qualified=1;
-                if ($qualified)
-                {
-                    //$ref=$obj->facnumber;
-                    $paymentornot=($obj->fk_paiement?1:0);
-                    $return[$obj->rowid]=array('ref'=>$obj->facnumber,'status'=>$obj->fk_statut,'type'=>$obj->type,'paye'=>$obj->paye,'paymentornot'=>$paymentornot);
-                }
-            }
-
-            return $return;
-        }
-        else
-        {
-            $this->error=$this->db->error();
-            dol_syslog(get_class($this)."::list_avoir_invoices ".$this->error, LOG_ERR);
-            return -1;
-        }
-    }
+		$this->nbtodo=$this->nbtodolate=0;
+		$clause = " WHERE";
 
+		$sql = "SELECT f.rowid, f.date_lim_reglement as datefin";
+		$sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
+		if (!$user->rights->societe->client->voir && !$user->societe_id)
+		{
+			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON f.fk_soc = sc.fk_soc";
+			$sql.= " WHERE sc.fk_user = " .$user->id;
+			$clause = " AND";
+		}
+		$sql.= $clause." f.paye=0";
+		$sql.= " AND f.entity = ".$conf->entity;
+		$sql.= " AND f.fk_statut = 1";
+		if ($user->societe_id) $sql.= " AND f.fk_soc = ".$user->societe_id;
 
-    /**
-     *	Create a withdrawal request for a standing order
-     *
-     *	@param      User	$user       User asking standing order
-     *	@return     int         		<0 if KO, >0 if OK
-     */
-    function demande_prelevement($user)
-    {
-        dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG);
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
+			while ($obj=$this->db->fetch_object($resql))
+			{
+				$this->nbtodo++;
+				if ($this->db->jdate($obj->datefin) < ($now - $conf->facture->client->warning_delay)) $this->nbtodolate++;
+			}
+			return 1;
+		}
+		else
+		{
+			dol_print_error($this->db);
+			$this->error=$this->db->error();
+			return -1;
+		}
+	}
 
-        $soc = new Societe($this->db);
-        $soc->id = $this->socid;
-        $soc->load_ban();
 
-        if ($this->statut > 0 && $this->paye == 0)
-        {
-            $sql = 'SELECT count(*)';
-            $sql.= ' FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande';
-            $sql.= ' WHERE fk_facture = '.$this->id;
-            $sql.= ' AND traite = 0';
-
-            $resql=$this->db->query($sql);
-            if ($resql)
-            {
-                $row = $this->db->fetch_row($resql);
-                if ($row[0] == 0)
-                {
-                	$now=dol_now();
-
-                    $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande';
-                    $sql .= ' (fk_facture, amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib)';
-                    $sql .= ' VALUES ('.$this->id;
-                    $sql .= ",'".price2num($this->total_ttc)."'";
-                    $sql .= ",".$this->db->idate($now).",".$user->id;
-                    $sql .= ",'".$soc->bank_account->code_banque."'";
-                    $sql .= ",'".$soc->bank_account->code_guichet."'";
-                    $sql .= ",'".$soc->bank_account->number."'";
-                    $sql .= ",'".$soc->bank_account->cle_rib."')";
-                    if ( $this->db->query($sql))
-                    {
-                        return 1;
-                    }
-                    else
-                    {
-                        $this->error=$this->db->error();
-                        dol_syslog(get_class($this).'::demandeprelevement Erreur');
-                        return -1;
-                    }
-                }
-                else
-                {
-                    $this->error="A request already exists";
-                    dol_syslog(get_class($this).'::demandeprelevement Impossible de creer une demande, demande deja en cours');
-                }
-            }
-            else
-            {
-                $this->error=$this->db->error();
-                dol_syslog(get_class($this).'::demandeprelevement Erreur -2');
-                return -2;
-            }
-        }
-        else
-        {
-            $this->error="Status of invoice does not allow this";
-            dol_syslog(get_class($this)."::demandeprelevement ".$this->error." $this->statut, $this->paye, $this->mode_reglement_id");
-            return -3;
-        }
-    }
-
-    /**
-     *  Supprime une demande de prelevement
-     *
-     *  @param  Use		$user       utilisateur creant la demande
-     *  @param  int		$did        id de la demande a supprimer
-     *  @return	int					<0 if OK, >0 if KO
-     */
-    function demande_prelevement_delete($user, $did)
-    {
-        $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande';
-        $sql .= ' WHERE rowid = '.$did;
-        $sql .= ' AND traite = 0';
-        if ( $this->db->query($sql) )
-        {
-            return 0;
-        }
-        else
-        {
-            $this->error=$this->db->lasterror();
-            dol_syslog(get_class($this).'::demande_prelevement_delete Error '.$this->error);
-            return -1;
-        }
-    }
+	/* gestion des contacts d'une facture */
 
+	/**
+	 *	Retourne id des contacts clients de facturation
+	 *
+	 *	@return     array       Liste des id contacts facturation
+	 */
+	function getIdBillingContact()
+	{
+		return $this->getIdContact('external','BILLING');
+	}
 
-    /**
-     *	Load indicators for dashboard (this->nbtodo and this->nbtodolate)
-     *
-     *	@param      User	$user    	Object user
-     *	@return     int                 <0 if KO, >0 if OK
-     */
-    function load_board($user)
-    {
-        global $conf, $user;
+	/**
+	 *	Retourne id des contacts clients de livraison
+	 *
+	 *	@return     array       Liste des id contacts livraison
+	 */
+	function getIdShippingContact()
+	{
+		return $this->getIdContact('external','SHIPPING');
+	}
 
-        $now=dol_now();
 
-        $this->nbtodo=$this->nbtodolate=0;
-        $clause = " WHERE";
+	/**
+	 *  Initialise an instance with random values.
+	 *  Used to build previews or test instances.
+	 *	id must be 0 if object instance is a specimen.
+	 *
+	 *	@param	string		$option		''=Create a specimen invoice with lines, 'nolines'=No lines
+	 *  @return	void
+	 */
+	function initAsSpecimen($option='')
+	{
+		global $user,$langs,$conf;
+
+		$now=dol_now();
+		$arraynow=dol_getdate($now);
+		$nownotime=dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
+
+		$prodids = array();
+		$sql = "SELECT rowid";
+		$sql.= " FROM ".MAIN_DB_PREFIX."product";
+		$sql.= " WHERE entity IN (".getEntity('product', 1).")";
+		$resql = $this->db->query($sql);
+		if ($resql)
+		{
+			$num_prods = $this->db->num_rows($resql);
+			$i = 0;
+			while ($i < $num_prods)
+			{
+				$i++;
+				$row = $this->db->fetch_row($resql);
+				$prodids[$i] = $row[0];
+			}
+		}
 
-        $sql = "SELECT f.rowid, f.date_lim_reglement as datefin";
-        $sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
-        if (!$user->rights->societe->client->voir && !$user->societe_id)
-        {
-            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON f.fk_soc = sc.fk_soc";
-            $sql.= " WHERE sc.fk_user = " .$user->id;
-            $clause = " AND";
-        }
-        $sql.= $clause." f.paye=0";
-        $sql.= " AND f.entity = ".$conf->entity;
-        $sql.= " AND f.fk_statut = 1";
-        if ($user->societe_id) $sql.= " AND f.fk_soc = ".$user->societe_id;
+		// Initialize parameters
+		$this->id=0;
+		$this->ref = 'SPECIMEN';
+		$this->specimen=1;
+		$this->socid = 1;
+		$this->date = $nownotime;
+		$this->date_lim_reglement = $nownotime + 3600 * 24 *30;
+		$this->cond_reglement_id   = 1;
+		$this->cond_reglement_code = 'RECEP';
+		$this->date_lim_reglement=$this->calculate_date_lim_reglement();
+		$this->mode_reglement_id   = 0;		// Not forced to show payment mode CHQ + VIR
+		$this->mode_reglement_code = '';	// Not forced to show payment mode CHQ + VIR
+		$this->note_public='This is a comment (public)';
+		$this->note_private='This is a comment (private)';
+		$this->note='This is a comment (private)';
+
+		if (empty($option) || $option != 'nolines')
+		{
+			// Lines
+			$nbp = 5;
+			$xnbp = 0;
+			while ($xnbp < $nbp)
+			{
+				$line=new FactureLigne($this->db);
+				$line->desc=$langs->trans("Description")." ".$xnbp;
+				$line->qty=1;
+				$line->subprice=100;
+				$line->tva_tx=19.6;
+				$line->localtax1_tx=0;
+				$line->localtax2_tx=0;
+				$line->remise_percent=0;
+				if ($xnbp == 1)        // Qty is negative (product line)
+				{
+					$prodid = rand(1, $num_prods);
+					$line->fk_product=$prodids[$prodid];
+					$line->qty=-1;
+					$line->total_ht=-100;
+					$line->total_ttc=-119.6;
+					$line->total_tva=-19.6;
+				}
+				else if ($xnbp == 2)    // UP is negative (free line)
+				{
+					$line->subprice=-100;
+					$line->total_ht=-100;
+					$line->total_ttc=-119.6;
+					$line->total_tva=-19.6;
+					$line->remise_percent=0;
+				}
+				else if ($xnbp == 3)    // Discount is 50% (product line)
+				{
+					$prodid = rand(1, $num_prods);
+					$line->fk_product=$prodids[$prodid];
+					$line->total_ht=50;
+					$line->total_ttc=59.8;
+					$line->total_tva=9.8;
+					$line->remise_percent=50;
+				}
+				else    // (product line)
+				{
+					$prodid = rand(1, $num_prods);
+					$line->fk_product=$prodids[$prodid];
+					$line->total_ht=100;
+					$line->total_ttc=119.6;
+					$line->total_tva=19.6;
+					$line->remise_percent=00;
+				}
 
-        $resql=$this->db->query($sql);
-        if ($resql)
-        {
-            while ($obj=$this->db->fetch_object($resql))
-            {
-                $this->nbtodo++;
-                if ($this->db->jdate($obj->datefin) < ($now - $conf->facture->client->warning_delay)) $this->nbtodolate++;
-            }
-            return 1;
-        }
-        else
-        {
-            dol_print_error($this->db);
-            $this->error=$this->db->error();
-            return -1;
-        }
-    }
-
-
-    /* gestion des contacts d'une facture */
-
-    /**
-     *	Retourne id des contacts clients de facturation
-     *
-     *	@return     array       Liste des id contacts facturation
-     */
-    function getIdBillingContact()
-    {
-        return $this->getIdContact('external','BILLING');
-    }
-
-    /**
-     *	Retourne id des contacts clients de livraison
-     *
-     *	@return     array       Liste des id contacts livraison
-     */
-    function getIdShippingContact()
-    {
-        return $this->getIdContact('external','SHIPPING');
-    }
-
-
-    /**
-     *  Initialise an instance with random values.
-     *  Used to build previews or test instances.
-     *	id must be 0 if object instance is a specimen.
-     *
-     *	@param	string		$option		''=Create a specimen invoice with lines, 'nolines'=No lines
-     *  @return	void
-     */
-    function initAsSpecimen($option='')
-    {
-        global $user,$langs,$conf;
-
-        $now=dol_now();
-        $arraynow=dol_getdate($now);
-        $nownotime=dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
-
-        $prodids = array();
-        $sql = "SELECT rowid";
-        $sql.= " FROM ".MAIN_DB_PREFIX."product";
-        $sql.= " WHERE entity IN (".getEntity('product', 1).")";
-        $resql = $this->db->query($sql);
-        if ($resql)
-        {
-            $num_prods = $this->db->num_rows($resql);
-            $i = 0;
-            while ($i < $num_prods)
-            {
-                $i++;
-                $row = $this->db->fetch_row($resql);
-                $prodids[$i] = $row[0];
-            }
-        }
+				$this->lines[$xnbp]=$line;
+				$xnbp++;
 
-        // Initialize parameters
-        $this->id=0;
-        $this->ref = 'SPECIMEN';
-        $this->specimen=1;
-        $this->socid = 1;
-        $this->date = $nownotime;
-        $this->date_lim_reglement = $nownotime + 3600 * 24 *30;
-        $this->cond_reglement_id   = 1;
-        $this->cond_reglement_code = 'RECEP';
-        $this->date_lim_reglement=$this->calculate_date_lim_reglement();
-        $this->mode_reglement_id   = 0;		// Not forced to show payment mode CHQ + VIR
-        $this->mode_reglement_code = '';	// Not forced to show payment mode CHQ + VIR
-        $this->note_public='This is a comment (public)';
-        $this->note_private='This is a comment (private)';
-        $this->note='This is a comment (private)';
-
-        if (empty($option) || $option != 'nolines')
-        {
-            // Lines
-            $nbp = 5;
-            $xnbp = 0;
-            while ($xnbp < $nbp)
-            {
-                $line=new FactureLigne($this->db);
-                $line->desc=$langs->trans("Description")." ".$xnbp;
-                $line->qty=1;
-                $line->subprice=100;
-                $line->tva_tx=19.6;
-                $line->localtax1_tx=0;
-                $line->localtax2_tx=0;
-    		    $line->remise_percent=0;
-                if ($xnbp == 1)        // Qty is negative (product line)
-    			{
-                    $prodid = rand(1, $num_prods);
-                    $line->fk_product=$prodids[$prodid];
-    			    $line->qty=-1;
-                    $line->total_ht=-100;
-    			    $line->total_ttc=-119.6;
-    			    $line->total_tva=-19.6;
-    			}
-    			else if ($xnbp == 2)    // UP is negative (free line)
-    			{
-                    $line->subprice=-100;
-    			    $line->total_ht=-100;
-    			    $line->total_ttc=-119.6;
-    			    $line->total_tva=-19.6;
-    			    $line->remise_percent=0;
-    			}
-            	else if ($xnbp == 3)    // Discount is 50% (product line)
-    			{
-                    $prodid = rand(1, $num_prods);
-                    $line->fk_product=$prodids[$prodid];
-    			    $line->total_ht=50;
-    			    $line->total_ttc=59.8;
-    			    $line->total_tva=9.8;
-    			    $line->remise_percent=50;
-    			}
-    			else    // (product line)
-    			{
-                    $prodid = rand(1, $num_prods);
-                    $line->fk_product=$prodids[$prodid];
-    			    $line->total_ht=100;
-    			    $line->total_ttc=119.6;
-    			    $line->total_tva=19.6;
-        			$line->remise_percent=00;
-    			}
-
-                $this->lines[$xnbp]=$line;
-                $xnbp++;
-
-                $this->total_ht       += $line->total_ht;
-        		$this->total_tva      += $line->total_tva;
-        		$this->total_ttc      += $line->total_ttc;
-            }
-            $this->revenuestamp = 0;
-            
-            // Add a line "offered"
-            $line=new FactureLigne($this->db);
-            $line->desc=$langs->trans("Description")." (offered line)";
-            $line->qty=1;
-            $line->subprice=100;
-            $line->tva_tx=19.6;
-            $line->localtax1_tx=0;
-            $line->localtax2_tx=0;
-            $line->remise_percent=100;
-            $line->total_ht=0;
-            $line->total_ttc=0;    // 90 * 1.196
-            $line->total_tva=0;
-            $prodid = rand(1, $num_prods);
-            $line->fk_product=$prodids[$prodid];
-
-            $this->lines[$xnbp]=$line;
-            $xnbp++;
-        }
-    }
+				$this->total_ht       += $line->total_ht;
+				$this->total_tva      += $line->total_tva;
+				$this->total_ttc      += $line->total_ttc;
+			}
+			$this->revenuestamp = 0;
+
+			// Add a line "offered"
+			$line=new FactureLigne($this->db);
+			$line->desc=$langs->trans("Description")." (offered line)";
+			$line->qty=1;
+			$line->subprice=100;
+			$line->tva_tx=19.6;
+			$line->localtax1_tx=0;
+			$line->localtax2_tx=0;
+			$line->remise_percent=100;
+			$line->total_ht=0;
+			$line->total_ttc=0;    // 90 * 1.196
+			$line->total_tva=0;
+			$prodid = rand(1, $num_prods);
+			$line->fk_product=$prodids[$prodid];
+
+			$this->lines[$xnbp]=$line;
+			$xnbp++;
+		}
+	}
 
-    /**
-     *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
-     *
+	/**
+	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
+	 *
 	 *      @return         int     <0 if KO, >0 if OK
-     */
-    function load_state_board()
-    {
-        global $conf, $user;
+	 */
+	function load_state_board()
+	{
+		global $conf, $user;
 
-        $this->nb=array();
+		$this->nb=array();
 
-        $clause = "WHERE";
+		$clause = "WHERE";
 
-        $sql = "SELECT count(f.rowid) as nb";
-        $sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
-        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid";
-        if (!$user->rights->societe->client->voir && !$user->societe_id)
-        {
-            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
-            $sql.= " WHERE sc.fk_user = " .$user->id;
-            $clause = "AND";
-        }
-        $sql.= " ".$clause." f.entity = ".$conf->entity;
+		$sql = "SELECT count(f.rowid) as nb";
+		$sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
+		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid";
+		if (!$user->rights->societe->client->voir && !$user->societe_id)
+		{
+			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
+			$sql.= " WHERE sc.fk_user = " .$user->id;
+			$clause = "AND";
+		}
+		$sql.= " ".$clause." f.entity = ".$conf->entity;
 
-        $resql=$this->db->query($sql);
-        if ($resql)
-        {
-            while ($obj=$this->db->fetch_object($resql))
-            {
-                $this->nb["invoices"]=$obj->nb;
-            }
-            return 1;
-        }
-        else
-        {
-            dol_print_error($this->db);
-            $this->error=$this->db->error();
-            return -1;
-        }
-    }
-
-    /**
-     * 	Create an array of invoice lines
-     *
-     * 	@return int		>0 if OK, <0 if KO
-     */
-    function getLinesArray()
-    {
-        $sql = 'SELECT l.rowid, l.label as custom_label, l.description, l.fk_product, l.product_type, l.qty, l.tva_tx,';
-        $sql.= ' l.fk_remise_except, l.localtax1_tx, l.localtax2_tx,';
-        $sql.= ' l.remise_percent, l.subprice, l.info_bits, l.rang, l.special_code, l.fk_parent_line,';
-        $sql.= ' l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
-        $sql.= ' l.date_start, l.date_end,';
-        $sql.= ' p.ref as product_ref, p.fk_product_type, p.label as product_label,';
-        $sql.= ' p.description as product_desc';
-        $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l';
-        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product p ON l.fk_product=p.rowid';
-        $sql.= ' WHERE l.fk_facture = '.$this->id;
-        $sql.= ' ORDER BY l.rang ASC, l.rowid';
-
-        $resql = $this->db->query($sql);
-        if ($resql)
-        {
-            $num = $this->db->num_rows($resql);
-            $i = 0;
-
-            while ($i < $num)
-            {
-                $obj = $this->db->fetch_object($resql);
-
-                $this->lines[$i]->id				= $obj->rowid;
-                $this->lines[$i]->label 			= $obj->custom_label;
-                $this->lines[$i]->description 		= $obj->description;
-                $this->lines[$i]->fk_product		= $obj->fk_product;
-                $this->lines[$i]->ref				= $obj->product_ref;
-                $this->lines[$i]->product_label		= $obj->product_label;
-                $this->lines[$i]->product_desc		= $obj->product_desc;
-                $this->lines[$i]->fk_product_type	= $obj->fk_product_type;
-                $this->lines[$i]->product_type		= $obj->product_type;
-                $this->lines[$i]->qty				= $obj->qty;
-                $this->lines[$i]->subprice			= $obj->subprice;
-                $this->lines[$i]->fk_remise_except 	= $obj->fk_remise_except;
-                $this->lines[$i]->remise_percent	= $obj->remise_percent;
-                $this->lines[$i]->tva_tx			= $obj->tva_tx;
-                $this->lines[$i]->info_bits			= $obj->info_bits;
-                $this->lines[$i]->total_ht			= $obj->total_ht;
-                $this->lines[$i]->total_tva			= $obj->total_tva;
-                $this->lines[$i]->total_ttc			= $obj->total_ttc;
-                $this->lines[$i]->fk_parent_line	= $obj->fk_parent_line;
-                $this->lines[$i]->special_code		= $obj->special_code;
-                $this->lines[$i]->rang				= $obj->rang;
-                $this->lines[$i]->date_start		= $this->db->jdate($obj->date_start);
-                $this->lines[$i]->date_end			= $this->db->jdate($obj->date_end);
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
+			while ($obj=$this->db->fetch_object($resql))
+			{
+				$this->nb["invoices"]=$obj->nb;
+			}
+			return 1;
+		}
+		else
+		{
+			dol_print_error($this->db);
+			$this->error=$this->db->error();
+			return -1;
+		}
+	}
+
+	/**
+	 * 	Create an array of invoice lines
+	 *
+	 * 	@return int		>0 if OK, <0 if KO
+	 */
+	function getLinesArray()
+	{
+		$sql = 'SELECT l.rowid, l.label as custom_label, l.description, l.fk_product, l.product_type, l.qty, l.tva_tx,';
+		$sql.= ' l.fk_remise_except, l.localtax1_tx, l.localtax2_tx,';
+		$sql.= ' l.remise_percent, l.subprice, l.info_bits, l.rang, l.special_code, l.fk_parent_line,';
+		$sql.= ' l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
+		$sql.= ' l.date_start, l.date_end,';
+		$sql.= ' p.ref as product_ref, p.fk_product_type, p.label as product_label,';
+		$sql.= ' p.description as product_desc';
+		$sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l';
+		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product p ON l.fk_product=p.rowid';
+		$sql.= ' WHERE l.fk_facture = '.$this->id;
+		$sql.= ' ORDER BY l.rang ASC, l.rowid';
+
+		$resql = $this->db->query($sql);
+		if ($resql)
+		{
+			$num = $this->db->num_rows($resql);
+			$i = 0;
+
+			while ($i < $num)
+			{
+				$obj = $this->db->fetch_object($resql);
+
+				$this->lines[$i]->id				= $obj->rowid;
+				$this->lines[$i]->label 			= $obj->custom_label;
+				$this->lines[$i]->description 		= $obj->description;
+				$this->lines[$i]->fk_product		= $obj->fk_product;
+				$this->lines[$i]->ref				= $obj->product_ref;
+				$this->lines[$i]->product_label		= $obj->product_label;
+				$this->lines[$i]->product_desc		= $obj->product_desc;
+				$this->lines[$i]->fk_product_type	= $obj->fk_product_type;
+				$this->lines[$i]->product_type		= $obj->product_type;
+				$this->lines[$i]->qty				= $obj->qty;
+				$this->lines[$i]->subprice			= $obj->subprice;
+				$this->lines[$i]->fk_remise_except 	= $obj->fk_remise_except;
+				$this->lines[$i]->remise_percent	= $obj->remise_percent;
+				$this->lines[$i]->tva_tx			= $obj->tva_tx;
+				$this->lines[$i]->info_bits			= $obj->info_bits;
+				$this->lines[$i]->total_ht			= $obj->total_ht;
+				$this->lines[$i]->total_tva			= $obj->total_tva;
+				$this->lines[$i]->total_ttc			= $obj->total_ttc;
+				$this->lines[$i]->fk_parent_line	= $obj->fk_parent_line;
+				$this->lines[$i]->special_code		= $obj->special_code;
+				$this->lines[$i]->rang				= $obj->rang;
+				$this->lines[$i]->date_start		= $this->db->jdate($obj->date_start);
+				$this->lines[$i]->date_end			= $this->db->jdate($obj->date_end);
 				$this->lines[$i]->fk_fournprice		= $obj->fk_fournprice;
 				$marginInfos						= getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht);
 				$this->lines[$i]->pa_ht				= $marginInfos[0];
 				$this->lines[$i]->marge_tx			= $marginInfos[1];
 				$this->lines[$i]->marque_tx			= $marginInfos[2];
 
-                $i++;
-            }
-            $this->db->free($resql);
+				$i++;
+			}
+			$this->db->free($resql);
 
-            return 1;
-        }
-        else
-        {
-            $this->error=$this->db->error();
-            dol_syslog("Error sql=".$sql.", error=".$this->error,LOG_ERR);
-            return -1;
-        }
-    }
+			return 1;
+		}
+		else
+		{
+			$this->error=$this->db->error();
+			dol_syslog("Error sql=".$sql.", error=".$this->error,LOG_ERR);
+			return -1;
+		}
+	}
 
 }
 
@@ -3147,322 +3186,324 @@ class Facture extends CommonInvoice
  */
 class FactureLigne
 {
-    var $db;
-    var $error;
-
-    var $oldline;
-
-    //! From llx_facturedet
-    var $rowid;
-    //! Id facture
-    var $fk_facture;
-    //! Id parent line
-    var $fk_parent_line;
-    var $label;
-    //! Description ligne
-    var $desc;
-    var $fk_product;		// Id of predefined product
-    var $product_type = 0;	// Type 0 = product, 1 = Service
-
-    var $qty;				// Quantity (example 2)
-    var $tva_tx;			// Taux tva produit/service (example 19.6)
-    var $localtax1_tx;		// Local tax 1
-    var $localtax2_tx;		// Local tax 2
-    var $subprice;      	// P.U. HT (example 100)
-    var $remise_percent;	// % de la remise ligne (example 20%)
-    var $fk_remise_except;	// Link to line into llx_remise_except
-    var $rang = 0;
-
-  	var $fk_fournprice;
-  	var $pa_ht;
-  	var $marge_tx;
-  	var $marque_tx;
-
-    var $info_bits = 0;		// Liste d'options cumulables:
-    // Bit 0:	0 si TVA normal - 1 si TVA NPR
-    // Bit 1:	0 si ligne normal - 1 si bit discount (link to line into llx_remise_except)
-
-    var $special_code;	// Liste d'options non cumulabels:
-    // 1: frais de port
-    // 2: ecotaxe
-    // 3: ??
-
-    var $origin;
-    var $origin_id;
-
-    //! Total HT  de la ligne toute quantite et incluant la remise ligne
-    var $total_ht;
-    //! Total TVA  de la ligne toute quantite et incluant la remise ligne
-    var $total_tva;
-    var $total_localtax1; //Total Local tax 1 de la ligne
-    var $total_localtax2; //Total Local tax 2 de la ligne
-    //! Total TTC de la ligne toute quantite et incluant la remise ligne
-    var $total_ttc;
-
-    var $fk_code_ventilation = 0;
-
-    var $date_start;
-    var $date_end;
-
-    // Ne plus utiliser
-    //var $price;         	// P.U. HT apres remise % de ligne (exemple 80)
-    //var $remise;			// Montant calcule de la remise % sur PU HT (exemple 20)
-
-    // From llx_product
-    var $ref;				// Product ref (deprecated)
-    var $product_ref;       // Product ref
-    var $libelle;      		// Product label (deprecated)
-    var $product_label;     // Product label
-    var $product_desc;  	// Description produit
-
-    var $skip_update_total; // Skip update price total for special lines
-
-
-    /**
-     *  Constructor
-     *
-     *  @param	DoliDB		$db		Database handler
-     */
-    function __construct($db)
-    {
-        $this->db = $db;
-    }
-
-    /**
-     *	Load invoice line from database
-     *
-     *	@param	int		$rowid      id of invoice line to get
-     *	@return	int					<0 if KO, >0 if OK
-     */
-    function fetch($rowid)
-    {
-        $sql = 'SELECT fd.rowid, fd.fk_facture, fd.fk_parent_line, fd.fk_product, fd.product_type, fd.label as custom_label, fd.description, fd.price, fd.qty, fd.tva_tx,';
-        $sql.= ' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice,';
-        $sql.= ' fd.date_start as date_start, fd.date_end as date_end, fd.fk_product_fournisseur_price as fk_fournprice, fd.buy_price_ht as pa_ht,';
-        $sql.= ' fd.info_bits, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,';
-        $sql.= ' fd.fk_code_ventilation,';
-        $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc';
-        $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd';
-        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON fd.fk_product = p.rowid';
-        $sql.= ' WHERE fd.rowid = '.$rowid;
-
-        $result = $this->db->query($sql);
-        if ($result)
-        {
-            $objp = $this->db->fetch_object($result);
-
-            $this->rowid				= $objp->rowid;
-            $this->fk_facture			= $objp->fk_facture;
-            $this->fk_parent_line		= $objp->fk_parent_line;
-            $this->label				= $objp->custom_label;
-            $this->desc					= $objp->description;
-            $this->qty					= $objp->qty;
-            $this->subprice				= $objp->subprice;
-            $this->tva_tx				= $objp->tva_tx;
-            $this->localtax1_tx			= $objp->localtax1_tx;
-            $this->localtax2_tx			= $objp->localtax2_tx;
-            $this->remise_percent		= $objp->remise_percent;
-            $this->fk_remise_except		= $objp->fk_remise_except;
-            $this->fk_product			= $objp->fk_product;
-            $this->product_type			= $objp->product_type;
-            $this->date_start			= $this->db->jdate($objp->date_start);
-            $this->date_end				= $this->db->jdate($objp->date_end);
-            $this->info_bits			= $objp->info_bits;
-            $this->total_ht				= $objp->total_ht;
-            $this->total_tva			= $objp->total_tva;
-            $this->total_localtax1		= $objp->total_localtax1;
-            $this->total_localtax2		= $objp->total_localtax2;
-            $this->total_ttc			= $objp->total_ttc;
-            $this->fk_code_ventilation	= $objp->fk_code_ventilation;
-            $this->rang					= $objp->rang;
+	var $db;
+	var $error;
+
+	var $oldline;
+
+	//! From llx_facturedet
+	var $rowid;
+	//! Id facture
+	var $fk_facture;
+	//! Id parent line
+	var $fk_parent_line;
+	var $label;
+	//! Description ligne
+	var $desc;
+	var $fk_product;		// Id of predefined product
+	var $product_type = 0;	// Type 0 = product, 1 = Service
+
+	var $qty;				// Quantity (example 2)
+	var $tva_tx;			// Taux tva produit/service (example 19.6)
+	var $localtax1_tx;		// Local tax 1
+	var $localtax2_tx;		// Local tax 2
+	var $subprice;      	// P.U. HT (example 100)
+	var $remise_percent;	// % de la remise ligne (example 20%)
+	var $fk_remise_except;	// Link to line into llx_remise_except
+	var $rang = 0;
+
+	var $fk_fournprice;
+	var $pa_ht;
+	var $marge_tx;
+	var $marque_tx;
+
+	var $info_bits = 0;		// Liste d'options cumulables:
+	// Bit 0:	0 si TVA normal - 1 si TVA NPR
+	// Bit 1:	0 si ligne normal - 1 si bit discount (link to line into llx_remise_except)
+
+	var $special_code;	// Liste d'options non cumulabels:
+	// 1: frais de port
+	// 2: ecotaxe
+	// 3: ??
+
+	var $origin;
+	var $origin_id;
+
+	//! Total HT  de la ligne toute quantite et incluant la remise ligne
+	var $total_ht;
+	//! Total TVA  de la ligne toute quantite et incluant la remise ligne
+	var $total_tva;
+	var $total_localtax1; //Total Local tax 1 de la ligne
+	var $total_localtax2; //Total Local tax 2 de la ligne
+	//! Total TTC de la ligne toute quantite et incluant la remise ligne
+	var $total_ttc;
+
+	var $fk_code_ventilation = 0;
+
+	var $date_start;
+	var $date_end;
+
+	// Ne plus utiliser
+	//var $price;         	// P.U. HT apres remise % de ligne (exemple 80)
+	//var $remise;			// Montant calcule de la remise % sur PU HT (exemple 20)
+
+	// From llx_product
+	var $ref;				// Product ref (deprecated)
+	var $product_ref;       // Product ref
+	var $libelle;      		// Product label (deprecated)
+	var $product_label;     // Product label
+	var $product_desc;  	// Description produit
+
+	var $skip_update_total; // Skip update price total for special lines
+
+
+	/**
+	 *  Constructor
+	 *
+	 *  @param	DoliDB		$db		Database handler
+	 */
+	function __construct($db)
+	{
+		$this->db = $db;
+	}
+
+	/**
+	 *	Load invoice line from database
+	 *
+	 *	@param	int		$rowid      id of invoice line to get
+	 *	@return	int					<0 if KO, >0 if OK
+	 */
+	function fetch($rowid)
+	{
+		$sql = 'SELECT fd.rowid, fd.fk_facture, fd.fk_parent_line, fd.fk_product, fd.product_type, fd.label as custom_label, fd.description, fd.price, fd.qty, fd.tva_tx,';
+		$sql.= ' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice,';
+		$sql.= ' fd.date_start as date_start, fd.date_end as date_end, fd.fk_product_fournisseur_price as fk_fournprice, fd.buy_price_ht as pa_ht,';
+		$sql.= ' fd.info_bits, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,';
+		$sql.= ' fd.fk_code_ventilation,';
+		$sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc';
+		$sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd';
+		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON fd.fk_product = p.rowid';
+		$sql.= ' WHERE fd.rowid = '.$rowid;
+
+		$result = $this->db->query($sql);
+		if ($result)
+		{
+			$objp = $this->db->fetch_object($result);
+
+			$this->rowid				= $objp->rowid;
+			$this->fk_facture			= $objp->fk_facture;
+			$this->fk_parent_line		= $objp->fk_parent_line;
+			$this->label				= $objp->custom_label;
+			$this->desc					= $objp->description;
+			$this->qty					= $objp->qty;
+			$this->subprice				= $objp->subprice;
+			$this->tva_tx				= $objp->tva_tx;
+			$this->localtax1_tx			= $objp->localtax1_tx;
+			$this->localtax2_tx			= $objp->localtax2_tx;
+			$this->remise_percent		= $objp->remise_percent;
+			$this->fk_remise_except		= $objp->fk_remise_except;
+			$this->fk_product			= $objp->fk_product;
+			$this->product_type			= $objp->product_type;
+			$this->date_start			= $this->db->jdate($objp->date_start);
+			$this->date_end				= $this->db->jdate($objp->date_end);
+			$this->info_bits			= $objp->info_bits;
+			$this->total_ht				= $objp->total_ht;
+			$this->total_tva			= $objp->total_tva;
+			$this->total_localtax1		= $objp->total_localtax1;
+			$this->total_localtax2		= $objp->total_localtax2;
+			$this->total_ttc			= $objp->total_ttc;
+			$this->fk_code_ventilation	= $objp->fk_code_ventilation;
+			$this->rang					= $objp->rang;
 			$this->fk_fournprice		= $objp->fk_fournprice;
 			$marginInfos				= getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
 			$this->pa_ht				= $marginInfos[0];
 			$this->marge_tx				= $marginInfos[1];
 			$this->marque_tx			= $marginInfos[2];
 
-            $this->ref					= $objp->product_ref;      // deprecated
-            $this->product_ref			= $objp->product_ref;
-            $this->libelle				= $objp->product_libelle;  // deprecated
-            $this->product_label		= $objp->product_libelle;
-            $this->product_desc			= $objp->product_desc;
+			$this->ref					= $objp->product_ref;      // deprecated
+			$this->product_ref			= $objp->product_ref;
+			$this->libelle				= $objp->product_libelle;  // deprecated
+			$this->product_label		= $objp->product_libelle;
+			$this->product_desc			= $objp->product_desc;
 
-            $this->db->free($result);
-        }
-        else
-        {
-            dol_print_error($this->db);
-        }
-    }
-
-    /**
-     *	Insert line in database
-     *
-     *	@param      int		$notrigger		1 no triggers
-     *	@return		int						<0 if KO, >0 if OK
-     */
-    function insert($notrigger=0)
-    {
-        global $langs,$user,$conf;
+			$this->db->free($result);
+		}
+		else
+		{
+			dol_print_error($this->db);
+		}
+	}
+
+	/**
+	 *	Insert line in database
+	 *
+	 *	@param      int		$notrigger		1 no triggers
+	 *	@return		int						<0 if KO, >0 if OK
+	 */
+	function insert($notrigger=0)
+	{
+		global $langs,$user,$conf;
 
 		$error=0;
 
-        dol_syslog(get_class($this)."::insert rang=".$this->rang, LOG_DEBUG);
-
-        // Clean parameters
-        $this->desc=trim($this->desc);
-        if (empty($this->tva_tx)) $this->tva_tx=0;
-        if (empty($this->localtax1_tx)) $this->localtax1_tx=0;
-        if (empty($this->localtax2_tx)) $this->localtax2_tx=0;
-        if (empty($this->total_localtax1)) $this->total_localtax1=0;
-        if (empty($this->total_localtax2)) $this->total_localtax2=0;
-        if (empty($this->rang)) $this->rang=0;
-        if (empty($this->remise_percent)) $this->remise_percent=0;
-        if (empty($this->info_bits)) $this->info_bits=0;
-        if (empty($this->subprice)) $this->subprice=0;
-        if (empty($this->special_code)) $this->special_code=0;
-        if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
-
-        if (empty($this->pa_ht)) $this->pa_ht=0;
-
-        // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente
-        if ($this->pa_ht == 0) {
-        	if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1))
-        		$this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100);
-        }
+		dol_syslog(get_class($this)."::insert rang=".$this->rang, LOG_DEBUG);
+
+		// Clean parameters
+		$this->desc=trim($this->desc);
+		if (empty($this->tva_tx)) $this->tva_tx=0;
+		if (empty($this->localtax1_tx)) $this->localtax1_tx=0;
+		if (empty($this->localtax2_tx)) $this->localtax2_tx=0;
+		if (empty($this->total_localtax1)) $this->total_localtax1=0;
+		if (empty($this->total_localtax2)) $this->total_localtax2=0;
+		if (empty($this->rang)) $this->rang=0;
+		if (empty($this->remise_percent)) $this->remise_percent=0;
+		if (empty($this->info_bits)) $this->info_bits=0;
+		if (empty($this->subprice)) $this->subprice=0;
+		if (empty($this->special_code)) $this->special_code=0;
+		if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
+
+		if (empty($this->pa_ht)) $this->pa_ht=0;
+
+		// si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente
+		if ($this->pa_ht == 0) {
+			if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1))
+				$this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100);
+		}
 
-        // Check parameters
-        if ($this->product_type < 0) return -1;
-
-        $this->db->begin();
-
-        // Insertion dans base de la ligne
-        $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facturedet';
-        $sql.= ' (fk_facture, fk_parent_line, label, description, qty, tva_tx, localtax1_tx, localtax2_tx,';
-        $sql.= ' fk_product, product_type, remise_percent, subprice, fk_remise_except,';
-        $sql.= ' date_start, date_end, fk_code_ventilation, ';
-        $sql.= ' rang, special_code, fk_product_fournisseur_price, buy_price_ht,';
-        $sql.= ' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2)';
-        $sql.= " VALUES (".$this->fk_facture.",";
-        $sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").",";
-        $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").",";
-        $sql.= " '".$this->db->escape($this->desc)."',";
-        $sql.= " ".price2num($this->qty).",";
-        $sql.= " ".price2num($this->tva_tx).",";
-        $sql.= " ".price2num($this->localtax1_tx).",";
-        $sql.= " ".price2num($this->localtax2_tx).",";
-        $sql.= ' '.(! empty($this->fk_product)?$this->fk_product:"null").',';
-        $sql.= " ".$this->product_type.",";
-        $sql.= " ".price2num($this->remise_percent).",";
-        $sql.= " ".price2num($this->subprice).",";
-        $sql.= ' '.(! empty($this->fk_remise_except)?$this->fk_remise_except:"null").',';
-        $sql.= " ".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null").",";
-        $sql.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null").",";
-        $sql.= ' '.$this->fk_code_ventilation.',';
-        $sql.= ' '.$this->rang.',';
-        $sql.= ' '.$this->special_code.',';
-        $sql.= ' '.(! empty($this->fk_fournprice)?$this->fk_fournprice:"null").',';
-        $sql.= ' '.price2num($this->pa_ht).',';
-        $sql.= " '".$this->info_bits."',";
-        $sql.= " ".price2num($this->total_ht).",";
+		// Check parameters
+		if ($this->product_type < 0) return -1;
+
+		$this->db->begin();
+
+		// Insertion dans base de la ligne
+		$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facturedet';
+		$sql.= ' (fk_facture, fk_parent_line, label, description, qty, tva_tx, localtax1_tx, localtax2_tx,';
+		$sql.= ' fk_product, product_type, remise_percent, subprice, fk_remise_except,';
+		$sql.= ' date_start, date_end, fk_code_ventilation, ';
+		$sql.= ' rang, special_code, fk_product_fournisseur_price, buy_price_ht,';
+		$sql.= ' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2)';
+		$sql.= " VALUES (".$this->fk_facture.",";
+		$sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").",";
+		$sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").",";
+		$sql.= " '".$this->db->escape($this->desc)."',";
+		$sql.= " ".price2num($this->qty).",";
+		$sql.= " ".price2num($this->tva_tx).",";
+		$sql.= " ".price2num($this->localtax1_tx).",";
+		$sql.= " ".price2num($this->localtax2_tx).",";
+		$sql.= ' '.(! empty($this->fk_product)?$this->fk_product:"null").',';
+		$sql.= " ".$this->product_type.",";
+		$sql.= " ".price2num($this->remise_percent).",";
+		$sql.= " ".price2num($this->subprice).",";
+		$sql.= ' '.(! empty($this->fk_remise_except)?$this->fk_remise_except:"null").',';
+		$sql.= " ".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null").",";
+		$sql.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null").",";
+		$sql.= ' '.$this->fk_code_ventilation.',';
+		$sql.= ' '.$this->rang.',';
+		$sql.= ' '.$this->special_code.',';
+		$sql.= ' '.(! empty($this->fk_fournprice)?$this->fk_fournprice:"null").',';
+		$sql.= ' '.price2num($this->pa_ht).',';
+		$sql.= " '".$this->info_bits."',";
+		$sql.= " ".price2num($this->total_ht).",";
 		$sql.= " ".price2num($this->total_tva).",";
 		$sql.= " ".price2num($this->total_ttc).",";
-        $sql.= " ".price2num($this->total_localtax1).",";
-        $sql.= " ".price2num($this->total_localtax2);
-        $sql.= ')';
+		$sql.= " ".price2num($this->total_localtax1).",";
+		$sql.= " ".price2num($this->total_localtax2);
+		$sql.= ')';
 
-        dol_syslog(get_class($this)."::insert sql=".$sql);
-        $resql=$this->db->query($sql);
-        if ($resql)
-        {
-            $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'facturedet');
-
-            // Si fk_remise_except defini, on lie la remise a la facture
-            // ce qui la flague comme "consommee".
-            if ($this->fk_remise_except)
-            {
-                $discount=new DiscountAbsolute($this->db);
-                $result=$discount->fetch($this->fk_remise_except);
-                if ($result >= 0)
-                {
-                    // Check if discount was found
-                    if ($result > 0)
-                    {
-                        // Check if discount not already affected to another invoice
-                        if ($discount->fk_facture)
-                        {
-                            $this->error=$langs->trans("ErrorDiscountAlreadyUsed",$discount->id);
-                            dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR);
-                            $this->db->rollback();
-                            return -3;
-                        }
-                        else
-                        {
-                            $result=$discount->link_to_invoice($this->rowid,0);
-                            if ($result < 0)
-                            {
-                                $this->error=$discount->error;
-                                dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR);
-                                $this->db->rollback();
-                                return -3;
-                            }
-                        }
-                    }
-                    else
-                    {
-                        $this->error=$langs->trans("ErrorADiscountThatHasBeenRemovedIsIncluded");
-                        dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR);
-                        $this->db->rollback();
-                        return -3;
-                    }
-                }
-                else
-                {
-                    $this->error=$discount->error;
-                    dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR);
-                    $this->db->rollback();
-                    return -3;
-                }
-            }
-
-            if (! $notrigger)
-            {
-                // Appel des triggers
-                include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-                $interface=new Interfaces($this->db);
-                $result = $interface->run_triggers('LINEBILL_INSERT',$this,$user,$langs,$conf);
-                if ($result < 0) { $error++; $this->errors=$interface->errors; }
-                // Fin appel triggers
-            }
-
-            $this->db->commit();
-            return $this->rowid;
+		dol_syslog(get_class($this)."::insert sql=".$sql);
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
+			$this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'facturedet');
 
-        }
-        else
-        {
-            $this->error=$this->db->error();
-            dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR);
-            $this->db->rollback();
-            return -2;
-        }
-    }
-
-    /**
-     *	Update line into database
-     *
-     *	@param		User	$user		User object
-     *	@param		int		$notrigger	Disable triggers
-     *	@return		int					<0 if KO, >0 if OK
-     */
-    function update($user='',$notrigger=0)
-    {
-        global $user,$langs,$conf;
+			// Si fk_remise_except defini, on lie la remise a la facture
+			// ce qui la flague comme "consommee".
+			if ($this->fk_remise_except)
+			{
+				$discount=new DiscountAbsolute($this->db);
+				$result=$discount->fetch($this->fk_remise_except);
+				if ($result >= 0)
+				{
+					// Check if discount was found
+					if ($result > 0)
+					{
+						// Check if discount not already affected to another invoice
+						if ($discount->fk_facture)
+						{
+							$this->error=$langs->trans("ErrorDiscountAlreadyUsed",$discount->id);
+							dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR);
+							$this->db->rollback();
+							return -3;
+						}
+						else
+						{
+							$result=$discount->link_to_invoice($this->rowid,0);
+							if ($result < 0)
+							{
+								$this->error=$discount->error;
+								dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR);
+								$this->db->rollback();
+								return -3;
+							}
+						}
+					}
+					else
+					{
+						$this->error=$langs->trans("ErrorADiscountThatHasBeenRemovedIsIncluded");
+						dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR);
+						$this->db->rollback();
+						return -3;
+					}
+				}
+				else
+				{
+					$this->error=$discount->error;
+					dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR);
+					$this->db->rollback();
+					return -3;
+				}
+			}
+
+			if (! $notrigger)
+			{
+				// Appel des triggers
+				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+				$interface=new Interfaces($this->db);
+				$result = $interface->run_triggers('LINEBILL_INSERT',$this,$user,$langs,$conf);
+				if ($result < 0) {
+					$error++; $this->errors=$interface->errors;
+				}
+				// Fin appel triggers
+			}
+
+			$this->db->commit();
+			return $this->rowid;
+
+		}
+		else
+		{
+			$this->error=$this->db->error();
+			dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR);
+			$this->db->rollback();
+			return -2;
+		}
+	}
+
+	/**
+	 *	Update line into database
+	 *
+	 *	@param		User	$user		User object
+	 *	@param		int		$notrigger	Disable triggers
+	 *	@return		int					<0 if KO, >0 if OK
+	 */
+	function update($user='',$notrigger=0)
+	{
+		global $user,$langs,$conf;
 
 		$error=0;
 
-        // Clean parameters
-        $this->desc=trim($this->desc);
+		// Clean parameters
+		$this->desc=trim($this->desc);
 		if (empty($this->tva_tx)) $this->tva_tx=0;
 		if (empty($this->localtax1_tx)) $this->localtax1_tx=0;
 		if (empty($this->localtax2_tx)) $this->localtax2_tx=0;
@@ -3474,18 +3515,18 @@ class FactureLigne
 		if (empty($this->product_type)) $this->product_type=0;
 		if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
 
-        // Check parameters
-        if ($this->product_type < 0) return -1;
+		// Check parameters
+		if ($this->product_type < 0) return -1;
 
-        if (empty($this->pa_ht)) $this->pa_ht=0;
+		if (empty($this->pa_ht)) $this->pa_ht=0;
 
-        // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente
-        if ($this->pa_ht == 0) {
-        	if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1))
-        		$this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100);
-        }
+		// si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente
+		if ($this->pa_ht == 0) {
+			if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1))
+				$this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100);
+		}
 
-        $this->db->begin();
+		$this->db->begin();
 
         // Mise a jour ligne en base
         $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET";
@@ -3512,36 +3553,38 @@ class FactureLigne
         	$sql.= ",total_localtax1=".price2num($this->total_localtax1)."";
         	$sql.= ",total_localtax2=".price2num($this->total_localtax2)."";
         }
-		$sql.= " , fk_product_fournisseur_price='".$this->fk_fournprice."'";
+		$sql.= " , fk_product_fournisseur_price=".(! empty($this->fk_fournprice)?"'".$this->db->escape($this->fk_fournprice)."'":"null");
 		$sql.= " , buy_price_ht='".price2num($this->pa_ht)."'";
-        $sql.= ",fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null");
-        if (! empty($this->rang)) $sql.= ", rang=".$this->rang;
-        $sql.= " WHERE rowid = ".$this->rowid;
+		$sql.= ",fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null");
+		if (! empty($this->rang)) $sql.= ", rang=".$this->rang;
+		$sql.= " WHERE rowid = ".$this->rowid;
 
-        dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG);
-        $resql=$this->db->query($sql);
-        if ($resql)
-        {
-            if (! $notrigger)
-            {
-                // Appel des triggers
-                include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-                $interface=new Interfaces($this->db);
-                $result = $interface->run_triggers('LINEBILL_UPDATE',$this,$user,$langs,$conf);
-                if ($result < 0) { $error++; $this->errors=$interface->errors; }
-                // Fin appel triggers
-            }
-            $this->db->commit();
-            return 1;
-        }
-        else
-        {
-            $this->error=$this->db->error();
-            dol_syslog(get_class($this)."::update Error ".$this->error, LOG_ERR);
-            $this->db->rollback();
-            return -2;
-        }
-    }
+		dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG);
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
+			if (! $notrigger)
+			{
+				// Appel des triggers
+				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+				$interface=new Interfaces($this->db);
+				$result = $interface->run_triggers('LINEBILL_UPDATE',$this,$user,$langs,$conf);
+				if ($result < 0) {
+					$error++; $this->errors=$interface->errors;
+				}
+				// Fin appel triggers
+			}
+			$this->db->commit();
+			return 1;
+		}
+		else
+		{
+			$this->error=$this->db->error();
+			dol_syslog(get_class($this)."::update Error ".$this->error, LOG_ERR);
+			$this->db->rollback();
+			return -2;
+		}
+	}
 
 	/**
 	 * 	Delete line in database
@@ -3564,7 +3607,9 @@ class FactureLigne
 			include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
 			$interface=new Interfaces($this->db);
 			$result = $interface->run_triggers('LINEBILL_DELETE',$this,$user,$langs,$conf);
-			if ($result < 0) { $error++; $this->errors=$interface->errors; }
+			if ($result < 0) {
+				$error++; $this->errors=$interface->errors;
+			}
 			// Fin appel triggers
 
 			$this->db->commit();
@@ -3580,45 +3625,45 @@ class FactureLigne
 		}
 	}
 
-    /**
-     *  Mise a jour en base des champs total_xxx de ligne de facture
-     *
-     *	@return		int		<0 if KO, >0 if OK
-     */
-    function update_total()
-    {
-        $this->db->begin();
-        dol_syslog(get_class($this)."::update_total", LOG_DEBUG);
-
-        // Clean parameters
+	/**
+	 *  Mise a jour en base des champs total_xxx de ligne de facture
+	 *
+	 *	@return		int		<0 if KO, >0 if OK
+	 */
+	function update_total()
+	{
+		$this->db->begin();
+		dol_syslog(get_class($this)."::update_total", LOG_DEBUG);
+
+		// Clean parameters
 		if (empty($this->total_localtax1)) $this->total_localtax1=0;
 		if (empty($this->total_localtax2)) $this->total_localtax2=0;
 
-        // Mise a jour ligne en base
-        $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET";
-        $sql.= " total_ht=".price2num($this->total_ht)."";
-        $sql.= ",total_tva=".price2num($this->total_tva)."";
-        $sql.= ",total_localtax1=".price2num($this->total_localtax1)."";
-        $sql.= ",total_localtax2=".price2num($this->total_localtax2)."";
-        $sql.= ",total_ttc=".price2num($this->total_ttc)."";
-        $sql.= " WHERE rowid = ".$this->rowid;
+		// Mise a jour ligne en base
+		$sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET";
+		$sql.= " total_ht=".price2num($this->total_ht)."";
+		$sql.= ",total_tva=".price2num($this->total_tva)."";
+		$sql.= ",total_localtax1=".price2num($this->total_localtax1)."";
+		$sql.= ",total_localtax2=".price2num($this->total_localtax2)."";
+		$sql.= ",total_ttc=".price2num($this->total_ttc)."";
+		$sql.= " WHERE rowid = ".$this->rowid;
 
-        dol_syslog(get_class($this)."::update_total sql=".$sql, LOG_DEBUG);
+		dol_syslog(get_class($this)."::update_total sql=".$sql, LOG_DEBUG);
 
-        $resql=$this->db->query($sql);
-        if ($resql)
-        {
-            $this->db->commit();
-            return 1;
-        }
-        else
-        {
-            $this->error=$this->db->error();
-            dol_syslog(get_class($this)."::update_total Error ".$this->error, LOG_ERR);
-            $this->db->rollback();
-            return -2;
-        }
-    }
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
+			$this->db->commit();
+			return 1;
+		}
+		else
+		{
+			$this->error=$this->db->error();
+			dol_syslog(get_class($this)."::update_total Error ".$this->error, LOG_ERR);
+			$this->db->rollback();
+			return -2;
+		}
+	}
 }
 
 ?>
diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php
index 1003dd2370093f30bd0eac56eee97d7f61b105b0..952fc760af54018b59f5b9c25f320ef6e79603f3 100644
--- a/htdocs/compta/facture/list.php
+++ b/htdocs/compta/facture/list.php
@@ -3,7 +3,7 @@
  * Copyright (C) 2004      Eric Seigne           <eric.seigne@ryxeo.com>
  * Copyright (C) 2004-2012 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) 2005-2013 Regis Houssin         <regis.houssin@capnetworks.com>
  * Copyright (C) 2006      Andre Cianfarani      <acianfa@free.fr>
  * Copyright (C) 2010-2012 Juanjo Menent         <jmenent@2byte.es>
  * Copyright (C) 2012      Christophe Battarel   <christophe.battarel@altairis.fr>
@@ -183,11 +183,11 @@ if ($search_societe)
 }
 if ($search_montant_ht)
 {
-    $sql.= ' AND f.total = \''.$db->escape(trim($search_montant_ht)).'\'';
+    $sql.= ' AND f.total = \''.$db->escape(price2num(trim($search_montant_ht))).'\'';
 }
 if ($search_montant_ttc)
 {
-    $sql.= ' AND f.total_ttc = \''.$db->escape(trim($search_montant_ttc)).'\'';
+    $sql.= ' AND f.total_ttc = \''.$db->escape(price2num(trim($search_montant_ttc))).'\'';
 }
 if ($month > 0)
 {
diff --git a/htdocs/compta/journal/purchasesjournal.php b/htdocs/compta/journal/purchasesjournal.php
index a37d5c240dfddbb86727841db26885bbe340e17d..2269c0035b9e44278cd07c807c48ad769fbea705 100755
--- a/htdocs/compta/journal/purchasesjournal.php
+++ b/htdocs/compta/journal/purchasesjournal.php
@@ -3,7 +3,8 @@
  * Copyright (C) 2007-2010	Jean Heimburger		<jean@tiaris.info>
  * Copyright (C) 2011		Juanjo Menent		<jmenent@2byte.es>
  * Copyright (C) 2012		Regis Houssin		<regis.houssin@capnetworks.com>
- * Copyright (C) 2011-2012 Alexandre Spangaro	  <alexandre.spangaro@gmail.com>
+ * Copyright (C) 2011-2012	Alexandre spangaro	<alexandre.spangaro@gmail.com>
+ * Copyright (C) 2013		Marcos García		<marcosgdf@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -99,12 +100,9 @@ $sql = "SELECT f.rowid, f.ref_supplier, f.type, f.datef, f.libelle,";
 $sql.= " fd.total_ttc, fd.tva_tx, fd.total_ht, fd.tva as total_tva, fd.product_type, fd.localtax1_tx, fd.localtax2_tx, fd.total_localtax1, fd.total_localtax2,";
 $sql.= " s.rowid as socid, s.nom as name, s.code_compta_fournisseur,";
 $sql.= " p.rowid as pid, p.ref as ref, p.accountancy_code_buy,";
-$sql.= " ct.accountancy_code_buy as account_tva, ct.recuperableonly,";
-$sql.= " ctl1.accountancy_code_buy as account_localtax1, ctl2.accountancy_code_buy as account_localtax2";
+$sql.= " ct.accountancy_code_buy as account_tva, ct.recuperableonly";
 $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn_det fd";
 $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ct ON fd.tva_tx = ct.taux AND fd.info_bits = ct.recuperableonly AND ct.fk_pays = '".$idpays."'";
-$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl1 ON fd.localtax1_tx = ctl1.localtax1 AND ctl1.fk_pays = '".$idpays."'";
-$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl2 ON fd.localtax2_tx = ctl2.localtax2 AND ctl2.fk_pays = '".$idpays."'";
 $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = fd.fk_product";
 $sql.= " JOIN ".MAIN_DB_PREFIX."facture_fourn f ON f.rowid = fd.fk_facture_fourn";
 $sql.= " JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid = f.fk_soc" ;
@@ -145,6 +143,11 @@ if ($result)
 		$compta_localtax1 = (! empty($obj->account_localtax1)?$obj->account_localtax1:$langs->trans("CodeNotDef"));
 		$compta_localtax2 = (! empty($obj->account_localtax2)?$obj->account_localtax2:$langs->trans("CodeNotDef"));
 
+		$account_localtax1=getLocalTaxesFromRate($obj->tva_tx, 1, $mysoc);
+		$compta_localtax1= (! empty($account_localtax1[2])?$account_localtax1[2]:$langs->trans("CodeNotDef"));
+		$account_localtax2=getLocalTaxesFromRate($obj->tva_tx, 2, $mysoc);
+		$compta_localtax2= (! empty($account_localtax2[2])?$account_localtax2[2]:$langs->trans("CodeNotDef"));
+		
 		$tabfac[$obj->rowid]["date"] = $obj->datef;
 		$tabfac[$obj->rowid]["ref"] = $obj->ref_supplier;
 		$tabfac[$obj->rowid]["type"] = $obj->type;
@@ -166,7 +169,6 @@ else {
 /*
  * Show result array
  */
-$i = 0;
 print "<table class=\"noborder\" width=\"100%\">";
 print "<tr class=\"liste_titre\">";
 ///print "<td>".$langs->trans("JournalNum")."</td>";
@@ -177,96 +179,71 @@ print "<td>".$langs->trans("Type")."</td><td align='right'>".$langs->trans("Debi
 print "</tr>\n";
 
 $var=true;
-$r='';
 
 $invoicestatic=new FactureFournisseur($db);
 $companystatic=new Fournisseur($db);
 
 foreach ($tabfac as $key => $val)
 {
-	$invoicestatic->id=$key;
-	$invoicestatic->ref=$val["ref"];
-	$invoicestatic->type=$val["type"];
-
-	// product
-	foreach ($tabht[$key] as $k => $mt)
-	{
-		if ($mt)
-		{
-			print "<tr ".$bc[$var]." >";
-			//print "<td>".$conf->global->COMPTA_JOURNAL_BUY."</td>";
-			print "<td>".$val["date"]."</td>";
-			print "<td>".$invoicestatic->getNomUrl(1)."</td>";
-			print "<td>".$k."</td><td>".$langs->trans("Products")."</td>";
-			print '<td align="right">'.($mt>=0?price($mt):'')."</td>";
-			print '<td align="right">'.($mt<0?price(-$mt):'')."</td>";
-			print "</tr>";
-		}
-	}
-	// vat
-	foreach ($tabtva[$key] as $k => $mt)
+	$invoicestatic->id = $key;
+	$invoicestatic->ref = $val["ref"];
+	$invoicestatic->type = $val["type"];
+
+	$companystatic->id = $tabcompany[$key]['id'];
+	$companystatic->name = $tabcompany[$key]['name'];
+
+	$lines = array(
+		array(
+			'var' => $tabht[$key],
+			'label' => $langs->trans('Products'),
+		),
+		array(
+			'var' => $tabtva[$key],
+			'label' => $langs->trans('VAT')
+		),
+		array(
+			'var' => $tablocaltax1[$key],
+			'label' => $langs->transcountry('LT1', $mysoc->country_code)
+		),
+		array(
+			'var' => $tablocaltax2[$key],
+			'label' => $langs->transcountry('LT2', $mysoc->country_code)
+		),
+		array(
+			'var' => $tabttc[$key],
+			'label' => $langs->trans('ThirdParty').' ('.$companystatic->getNomUrl(0, 'supplier', 16).')',
+			'nomtcheck' => true,
+			'inv' => true
+		)
+	);
+
+	foreach ($lines as $line)
 	{
-		if ($mt)
+		foreach ($line['var'] as $k => $mt)
 		{
-			print "<tr ".$bc[$var]." >";
-			//print "<td>".$conf->global->COMPTA_JOURNAL_BUY."</td>";
-			print "<td>".$val["date"]."</td>";
-			print "<td>".$invoicestatic->getNomUrl(1)."</td>";
-			print "<td>".$k."</td><td>".$langs->trans("VAT")."</td>";
-			print '<td align="right">'.($mt>=0?price($mt):'')."</td>";
-			print '<td align="right">'.($mt<0?price(-$mt):'')."</td>";
-			print "</tr>";
+			if (isset($line['nomtcheck']) || $mt)
+			{
+				print "<tr ".$bc[$var]." >";
+				//print "<td>".$conf->global->COMPTA_JOURNAL_BUY."</td>";
+				print "<td>".$val["date"]."</td>";
+				print "<td>".$invoicestatic->getNomUrl(1)."</td>";
+				print "<td>".$k."</td><td>".$line['label']."</td>";
+
+				if (isset($line['inv']))
+				{
+					print '<td align="right">'.($mt<0?price(-$mt):'')."</td>";
+	    			print '<td align="right">'.($mt>=0?price($mt):'')."</td>";
+				}
+				else
+				{
+					print '<td align="right">'.($mt>=0?price($mt):'')."</td>";
+					print '<td align="right">'.($mt<0?price(-$mt):'')."</td>";
+				}
+				
+				print "</tr>";
+			}
 		}
 	}
-	// localtax1
-	foreach ($tablocaltax1[$key] as $k => $mt)
-	{
-	    if ($mt)
-	    {
-    		print "<tr ".$bc[$var].">";
-    		//print "<td>".$conf->global->COMPTA_JOURNAL_BUY."</td>";
-    		print "<td>".$val["date"]."</td>";
-    		print "<td>".$invoicestatic->getNomUrl(1)."</td>";
-    		print "<td>".$k."</td><td>".$langs->transcountrynoentities("LT1",$mysoc->country_code)."</td>";
-    		print "<td align='right'>".($mt>=0?price($mt):'')."</td>";
-    		print "<td align='right'>".($mt<0?price(-$mt):'')."</td>";
-    		print "</tr>";
-	    }
-	}
-	// localtax2
-	foreach ($tablocaltax2[$key] as $k => $mt)
-	{
-	    if ($mt)
-	    {
-    		print "<tr ".$bc[$var].">";
-    		//print "<td>".$conf->global->COMPTA_JOURNAL_BUY."</td>";
-    		print "<td>".$val["date"]."</td>";
-    		print "<td>".$invoicestatic->getNomUrl(1)."</td>";
-    		print "<td>".$k."</td><td>".$langs->transcountrynoentities("LT2",$mysoc->country_code)."</td>";
-    		print "<td align='right'>".($mt>=0?price($mt):'')."</td>";
-    		print "<td align='right'>".($mt<0?price(-$mt):'')."</td>";
-    		print "</tr>";
-	    }
-	}
-	print "<tr ".$bc[$var].">";
-	// third party
-	//print "<td>".$conf->global->COMPTA_JOURNAL_BUY."</td>";
-	print "<td>".$val["date"]."</td>";
-	print "<td>".$invoicestatic->getNomUrl(1)."</td>";
-
-	foreach ($tabttc[$key] as $k => $mt)
-	{
-    	$companystatic->id=$tabcompany[$key]['id'];
-    	$companystatic->name=$tabcompany[$key]['name'];
-
-    	print "<td>".$k;
-	    print "</td><td>".$langs->trans("ThirdParty");
-		print ' ('.$companystatic->getNomUrl(0,'supplier',16).')';
-	    print "</td>";
-	    print '<td align="right">'.($mt<0?price(-$mt):'')."</td>";
-	    print '<td align="right">'.($mt>=0?price($mt):'')."</td>";
-	}
-	print "</tr>";
 
 	$var = !$var;
 }
diff --git a/htdocs/compta/journal/sellsjournal.php b/htdocs/compta/journal/sellsjournal.php
index ddb12839bf4dd409b110abc1c10e6fec5ba006aa..859c1ff2ea51a16bf5772508deee8d8439651640 100755
--- a/htdocs/compta/journal/sellsjournal.php
+++ b/htdocs/compta/journal/sellsjournal.php
@@ -3,8 +3,8 @@
  * Copyright (C) 2007-2010	Jean Heimburger		<jean@tiaris.info>
  * Copyright (C) 2011		Juanjo Menent		<jmenent@2byte.es>
  * Copyright (C) 2012		Regis Houssin		<regis.houssin@capnetworks.com>
- * Copyright (C) 2011-2012 Alexandre Spangaro	  <alexandre.spangaro@gmail.com>
- * Copyright (C) 2013       Marcos García <marcosgdf@gmail.com>
+ * Copyright (C) 2011-2012  Alexandre Spangaro	<alexandre.spangaro@gmail.com>
+ * Copyright (C) 2013		Marcos García		<marcosgdf@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -102,15 +102,12 @@ $sql = "SELECT f.rowid, f.facnumber, f.type, f.datef, f.ref_client,";
 $sql.= " fd.product_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.total_ttc, fd.localtax1_tx, fd.localtax2_tx, fd.total_localtax1, fd.total_localtax2,";
 $sql.= " s.rowid as socid, s.nom as name, s.code_compta, s.client,";
 $sql.= " p.rowid as pid, p.ref as pref, p.accountancy_code_sell,";
-$sql.= " ct.accountancy_code_sell as account_tva, ct.recuperableonly,";
-$sql.= " ctl1.accountancy_code_sell as account_localtax1, ctl2.accountancy_code_sell as account_localtax2";
+$sql.= " ct.accountancy_code_sell as account_tva, ct.recuperableonly";
 $sql.= " FROM ".MAIN_DB_PREFIX."facturedet fd";
 $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = fd.fk_product";
 $sql.= " JOIN ".MAIN_DB_PREFIX."facture f ON f.rowid = fd.fk_facture";
 $sql.= " JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid = f.fk_soc";
 $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ct ON fd.tva_tx = ct.taux AND fd.info_bits = ct.recuperableonly AND ct.fk_pays = '".$idpays."'";
-$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl1 ON fd.localtax1_tx = ctl1.localtax1 AND ctl1.fk_pays = '".$idpays."'";
-$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl2 ON fd.localtax2_tx = ctl2.localtax2 AND ctl2.fk_pays = '".$idpays."'";
 $sql.= " WHERE f.entity = ".$conf->entity;
 $sql.= " AND f.fk_statut > 0";
 if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
@@ -129,6 +126,8 @@ if ($result)
 	$tablocaltax2 = array();
 	$tabttc = array();
 	$tabcompany = array();
+	$account_localtax1=0;
+	$account_localtax2=0;
 
 	$num = $db->num_rows($result);
    	$i=0;
@@ -147,9 +146,12 @@ if ($result)
 		}
 		$cpttva = (! empty($conf->global->COMPTA_VAT_ACCOUNT)?$conf->global->COMPTA_VAT_ACCOUNT:$langs->trans("CodeNotDef"));
 		$compta_tva = (! empty($obj->account_tva)?$obj->account_tva:$cpttva);
-		$compta_localtax1 = (! empty($obj->account_localtax1)?$obj->account_localtax1:$langs->trans("CodeNotDef"));
-		$compta_localtax2 = (! empty($obj->account_localtax2)?$obj->account_localtax2:$langs->trans("CodeNotDef"));
 
+		$account_localtax1=getLocalTaxesFromRate($obj->tva_tx, 1, $mysoc);
+		$compta_localtax1= (! empty($account_localtax1[3])?$account_localtax1[3]:$langs->trans("CodeNotDef"));
+		$account_localtax2=getLocalTaxesFromRate($obj->tva_tx, 2, $mysoc);
+		$compta_localtax2= (! empty($account_localtax2[3])?$account_localtax2[3]:$langs->trans("CodeNotDef"));
+		
     	//la ligne facture
    		$tabfac[$obj->rowid]["date"] = $obj->datef;
    		$tabfac[$obj->rowid]["ref"] = $obj->facnumber;
@@ -178,17 +180,15 @@ else {
  */
 
 
-$i = 0;
-print "<table class=\"noborder\" width=\"100%\">";
-print "<tr class=\"liste_titre\">";
+print '<table class="noborder" width="100%">';
+print '<tr class="liste_titre">';
 //print "<td>".$langs->trans("JournalNum")."</td>";
-print "<td>".$langs->trans("Date")."</td><td>".$langs->trans("Piece").' ('.$langs->trans("InvoiceRef").")</td>";
-print "<td>".$langs->trans("Account")."</td>";
-print "<td>".$langs->trans("Type")."</td><td align='right'>".$langs->trans("Debit")."</td><td align='right'>".$langs->trans("Credit")."</td>";
+print '<td>'.$langs->trans('Date').'</td><td>'.$langs->trans('Piece').' ('.$langs->trans('InvoiceRef').')</td>';
+print '<td>'.$langs->trans('Account').'</td>';
+print '<td>'.$langs->trans('Type').'</td><td align="right">'.$langs->trans('Debit').'</td><td align="right">'.$langs->trans('Credit').'</td>';
 print "</tr>\n";
 
 $var=true;
-$r='';
 
 $invoicestatic=new Facture($db);
 $companystatic=new Client($db);
@@ -199,74 +199,62 @@ foreach ($tabfac as $key => $val)
 	$invoicestatic->ref=$val["ref"];
 	$invoicestatic->type=$val["type"];
 
-	print "<tr ".$bc[$var].">";
-	// third party
-	//print "<td>".$conf->global->COMPTA_JOURNAL_SELL."</td>";
-	print "<td>".$val["date"]."</td>";
-	print "<td>".$invoicestatic->getNomUrl(1)."</td>";
-	foreach ($tabttc[$key] as $k => $mt)
+	$companystatic->id=$tabcompany[$key]['id'];
+	$companystatic->name=$tabcompany[$key]['name'];
+	$companystatic->client=$tabcompany[$key]['client'];
+
+	$lines = array(
+		array(
+			'var' => $tabttc[$key],
+			'label' => $langs->trans('ThirdParty').' ('.$companystatic->getNomUrl(0, 'customer', 16).')',
+			'nomtcheck' => true,
+			'inv' => true
+		),
+		array(
+			'var' => $tabht[$key],
+			'label' => $langs->trans('Products'),
+		),
+		array(
+			'var' => $tabtva[$key],
+			'label' => $langs->trans('VAT')
+		),
+		array(
+			'var' => $tablocaltax1[$key],
+			'label' => $langs->transcountry('LT1', $mysoc->country_code)
+		),
+		array(
+			'var' => $tablocaltax2[$key],
+			'label' => $langs->transcountry('LT2', $mysoc->country_code)
+		)	
+	);
+
+	foreach ($lines as $line)
 	{
-    	$companystatic->id=$tabcompany[$key]['id'];
-    	$companystatic->name=$tabcompany[$key]['name'];
-    	$companystatic->client=$tabcompany[$key]['client'];
-    	print "<td>".$k;
-		print "</td><td>".$langs->trans("ThirdParty");
-		print ' ('.$companystatic->getNomUrl(0,'customer',16).')';
-		print "</td><td align='right'>".($mt>=0?price($mt):'')."</td><td align='right'>".($mt<0?price(-$mt):'')."</td>";
-	}
-	print "</tr>";
-	// product
-	foreach ($tabht[$key] as $k => $mt)
-	{
-		if ($mt)
+		foreach ($line['var'] as $k => $mt)
 		{
-			print "<tr ".$bc[$var].">";
-			//print "<td>".$conf->global->COMPTA_JOURNAL_SELL."</td>";
-			print "<td>".$val["date"]."</td>";
-			print "<td>".$invoicestatic->getNomUrl(1)."</td>";
-			print "<td>".$k;
-			print "</td><td>".$langs->trans("Products")."</td><td align='right'>".($mt<0?price(-$mt):'')."</td><td align='right'>".($mt>=0?price($mt):'')."</td></tr>";
+			if (isset($line['nomtcheck']) || $mt)
+			{
+				print "<tr ".$bc[$var]." >";
+				//print "<td>".$conf->global->COMPTA_JOURNAL_SELL."</td>";
+				print "<td>".$val["date"]."</td>";
+				print "<td>".$invoicestatic->getNomUrl(1)."</td>";
+				print "<td>".$k."</td><td>".$line['label']."</td>";
+
+				if (isset($line['inv']))
+				{
+					print '<td align="right">'.($mt>=0?price($mt):'')."</td>";
+					print '<td align="right">'.($mt<0?price(-$mt):'')."</td>";
+				}
+				else
+				{
+					print '<td align="right">'.($mt<0?price(-$mt):'')."</td>";
+	    			print '<td align="right">'.($mt>=0?price($mt):'')."</td>";
+				}
+
+				print "</tr>";
+			}
 		}
 	}
-	// vat
-	foreach ($tabtva[$key] as $k => $mt)
-	{
-	    if ($mt)
-	    {
-    		print "<tr ".$bc[$var].">";
-    		//print "<td>".$conf->global->COMPTA_JOURNAL_SELL."</td>";
-    		print "<td>".$val["date"]."</td>";
-    		print "<td>".$invoicestatic->getNomUrl(1)."</td>";
-    		print "<td>".$k;
-    		print "</td><td>".$langs->trans("VAT")."</td><td align='right'>".($mt<0?price(-$mt):'')."</td><td align='right'>".($mt>=0?price($mt):'')."</td></tr>";
-	    }
-	}
-	// localtax1
-	foreach ($tablocaltax1[$key] as $k => $mt)
-	{
-	    if ($mt)
-	    {
-    		print "<tr ".$bc[$var].">";
-    		//print "<td>".$conf->global->COMPTA_JOURNAL_SELL."</td>";
-    		print "<td>".$val["date"]."</td>";
-    		print "<td>".$invoicestatic->getNomUrl(1)."</td>";
-    		print "<td>".$k;
-    		print "</td><td>".$langs->transcountrynoentities("LT1",$mysoc->country_code)."</td><td align='right'>".($mt<0?price(-$mt):'')."</td><td align='right'>".($mt>=0?price($mt):'')."</td></tr>";
-	    }
-	}
-	// localtax2
-	foreach ($tablocaltax2[$key] as $k => $mt)
-	{
-	    if ($mt)
-	    {
-    		print "<tr ".$bc[$var].">";
-    		//print "<td>".$conf->global->COMPTA_JOURNAL_SELL."</td>";
-    		print "<td>".$val["date"]."</td>";
-    		print "<td>".$invoicestatic->getNomUrl(1)."</td>";
-    		print "<td>".$k;
-    		print "</td><td>".$langs->transcountrynoentities("LT2",$mysoc->country_code)."</td><td align='right'>".($mt<0?price(-$mt):'')."</td><td align='right'>".($mt>=0?price($mt):'')."</td></tr>";
-	    }
-	}
 
 	$var = !$var;
 }
diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php
index 4a8f93a52f6c5ba42e30d6ea0bcfb8efa9f17ec0..232126d68e29bc2c34351f5024780e4cf21fab7a 100644
--- a/htdocs/compta/paiement.php
+++ b/htdocs/compta/paiement.php
@@ -286,7 +286,8 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
             					$(\'.fieldrequireddyn\').addClass(\'fieldrequired\');
             					if ($(\'#fieldchqemetteur\').val() == \'\')
             					{
-            						$(\'#fieldchqemetteur\').val(jQuery(\'#thirdpartylabel\').val());
+            						var emetteur = ('.$facture->type.' == 2) ? \''.dol_escape_htmltag(MAIN_INFO_SOCIETE_NOM).'\' : jQuery(\'#thirdpartylabel\').val();
+            						$(\'#fieldchqemetteur\').val(emetteur);
             					}
             				}
             				else
diff --git a/htdocs/compta/paiement/rapport.php b/htdocs/compta/paiement/rapport.php
index 1bb4ad3a9cae9a7d4f821923c0fbff2ff035fa96..ce4a3b7cb7f061d1c69f82f20659c5cb6d13b228 100644
--- a/htdocs/compta/paiement/rapport.php
+++ b/htdocs/compta/paiement/rapport.php
@@ -154,7 +154,7 @@ if ($year)
                     $var=!$var;
                     $tfile = $dir . '/'.$year.'/'.$file;
                     $relativepath = $year.'/'.$file;
-                    print "<tr $bc[$var]>".'<td><a href="'.DOL_URL_ROOT . '/document.php?modulepart=facture_paiement&amp;file='.urlencode($relativepath).'">'.img_pdf().' '.$file.'</a></td>';
+                    print "<tr ".$bc[$var].">".'<td><a data-ajax="false" href="'.DOL_URL_ROOT . '/document.php?modulepart=facture_paiement&amp;file='.urlencode($relativepath).'">'.img_pdf().' '.$file.'</a></td>';
                     print '<td align="right">'.dol_print_size(dol_filesize($tfile)).'</td>';
                     print '<td align="right">'.dol_print_date(dol_filemtime($tfile),"dayhour").'</td></tr>';
                 }
diff --git a/htdocs/compta/prelevement/bon.php b/htdocs/compta/prelevement/bon.php
index 6448a5b3df5cf793de628852034f6509d71ea36c..89b40e095bc7dea1da2a4155b773d85fcd8f3ab2 100644
--- a/htdocs/compta/prelevement/bon.php
+++ b/htdocs/compta/prelevement/bon.php
@@ -63,7 +63,7 @@ if ($id > 0 || ! empty($ref))
 
 		$relativepath = 'bon/'.$object->ref;
 
-		print '<a href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$object->ref.'</a>';
+		print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$object->ref.'</a>';
 
 		print '</td></tr>';
 		print '</table><br>';
diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php
index 5271dbd03b433cf193915648e4708b87e2df83ad..ee5558b8ba20bbc5e8df7007be06210c925feaca 100644
--- a/htdocs/compta/prelevement/factures.php
+++ b/htdocs/compta/prelevement/factures.php
@@ -94,7 +94,7 @@ if ($prev_id)
 		print '<table class="border" width="100%"><tr><td width="20%">';
 		print $langs->trans("WithdrawalFile").'</td><td>';
 		$relativepath = 'receipts/'.$bon->ref;
-		print '<a href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$relativepath.'</a>';
+		print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$relativepath.'</a>';
 		print '</td></tr></table>';
 	
 		dol_fiche_end();
diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php
index 3cc372094a379f9f4385cdd97f96dbd014dc88db..335bfbc26c640930359ed2f6b96c895f02157e33 100644
--- a/htdocs/compta/prelevement/fiche-rejet.php
+++ b/htdocs/compta/prelevement/fiche-rejet.php
@@ -93,7 +93,7 @@ if ($prev_id)
 		print '<table class="border" width="100%"><tr><td width="20%">';
 		print $langs->trans("WithdrawalFile").'</td><td>';
 		$relativepath = 'receipts/'.$bon->ref;
-		print '<a href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$relativepath.'</a>';
+		print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$relativepath.'</a>';
 		print '</td></tr></table>';
 	
 		dol_fiche_end();
diff --git a/htdocs/compta/prelevement/fiche-stat.php b/htdocs/compta/prelevement/fiche-stat.php
index 20e9c09145f017586f759f7e3dd5c565ffe94865..ee03e0d18b2827a7a6b947d7a46849cd5f2dc72a 100644
--- a/htdocs/compta/prelevement/fiche-stat.php
+++ b/htdocs/compta/prelevement/fiche-stat.php
@@ -92,7 +92,7 @@ if ($prev_id)
 		print '<table class="border" width="100%"><tr><td width="20%">';
 		print $langs->trans("WithdrawalFile").'</td><td>';
 		$relativepath = 'receipts/'.$bon->ref;
-		print '<a href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$relativepath.'</a>';
+		print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$relativepath.'</a>';
 		print '</td></tr></table>';
 	
 		dol_fiche_end();
diff --git a/htdocs/compta/prelevement/fiche.php b/htdocs/compta/prelevement/fiche.php
index 283f0c241833c8b0530fc77e1c32a5e946e575da..fee2f1ecc24901d5d82bd27dd4bf32dea356398e 100644
--- a/htdocs/compta/prelevement/fiche.php
+++ b/htdocs/compta/prelevement/fiche.php
@@ -191,7 +191,7 @@ if ($id > 0)
 	print '<table class="border" width="100%"><tr><td width="20%">';
 	print $langs->trans("WithdrawalFile").'</td><td>';
 	$relativepath = 'receipts/'.$bon->ref;
-	print '<a href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$relativepath.'</a>';
+	print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$relativepath.'</a>';
 	print '</td></tr></table>';
 
 	dol_fiche_end();
diff --git a/htdocs/compta/prelevement/lignes.php b/htdocs/compta/prelevement/lignes.php
index 298effa2b15b9702c0f6e2f3b004f5393090ed66..5e186774abe58aa6358c591110a211156aa04791 100644
--- a/htdocs/compta/prelevement/lignes.php
+++ b/htdocs/compta/prelevement/lignes.php
@@ -101,7 +101,7 @@ if ($prev_id)
 		print '<table class="border" width="100%"><tr><td width="20%">';
 		print $langs->trans("WithdrawalFile").'</td><td>';
 		$relativepath = 'receipts/'.$bon->ref;
-		print '<a href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$relativepath.'</a>';
+		print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?type=text/plain&amp;modulepart=prelevement&amp;file='.urlencode($relativepath).'">'.$relativepath.'</a>';
 		print '</td></tr></table>';
 
 		dol_fiche_end();
diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php
new file mode 100644
index 0000000000000000000000000000000000000000..6adbd4ebf06f0eb8964b5b418e78700d47905b15
--- /dev/null
+++ b/htdocs/compta/stats/cabyprodserv.php
@@ -0,0 +1,390 @@
+<?php
+/* Copyright (C) 2013      Antoine Iauch        <aiauch@gpcsolutions.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *       \file        htdocs/compta/stats/cabyprodserv.php
+ *       \brief       Page reporting TO by Products & Services
+ */
+
+require '../../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
+
+$langs->load("products");
+$langs->load("categories");
+$langs->load("errors");
+
+// Security pack (data & check)
+$socid = GETPOST('socid','int');
+
+if ($user->societe_id > 0) $socid = $user->societe_id;
+if (! empty($conf->comptabilite->enabled)) $result=restrictedArea($user,'compta','','','resultat');
+if (! empty($conf->accounting->enabled)) $result=restrictedArea($user,'accounting','','','comptarapport');
+
+// Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES')
+$modecompta = $conf->global->COMPTA_MODE;
+if (GETPOST("modecompta")) $modecompta=GETPOST("modecompta");
+
+$sortorder=isset($_GET["sortorder"])?$_GET["sortorder"]:$_POST["sortorder"];
+$sortfield=isset($_GET["sortfield"])?$_GET["sortfield"]:$_POST["sortfield"];
+if (! $sortorder) $sortorder="asc";
+if (! $sortfield) $sortfield="name";
+
+// Category
+$selected_cat = (int)GETPOST('search_categ', 'int');
+$subcat = false;
+if (GETPOST('subcat', 'alpha') === 'yes') {
+    $subcat = true;
+}
+
+// Date range
+$year=GETPOST("year");
+$month=GETPOST("month");
+$date_startyear = GETPOST("date_startyear");
+$date_startmonth = GETPOST("date_startmonth");
+$date_startday = GETPOST("date_startday");
+$date_endyear = GETPOST("date_endyear");
+$date_endmonth = GETPOST("date_endmonth");
+$date_endday = GETPOST("date_endday");
+if (empty($year))
+{
+	$year_current = strftime("%Y",dol_now());
+	$month_current = strftime("%m",dol_now());
+	$year_start = $year_current;
+} else {
+	$year_current = $year;
+	$month_current = strftime("%m",dol_now());
+	$year_start = $year;
+}
+$date_start=dol_mktime(0,0,0,$_REQUEST["date_startmonth"],$_REQUEST["date_startday"],$_REQUEST["date_startyear"]);
+$date_end=dol_mktime(23,59,59,$_REQUEST["date_endmonth"],$_REQUEST["date_endday"],$_REQUEST["date_endyear"]);
+// Quarter
+if (empty($date_start) || empty($date_end)) // We define date_start and date_end
+{
+	$q=GETPOST("q")?GETPOST("q"):0;
+	if ($q==0)
+	{
+		// We define date_start and date_end
+		$month_start=GETPOST("month")?GETPOST("month"):($conf->global->SOCIETE_FISCAL_MONTH_START?($conf->global->SOCIETE_FISCAL_MONTH_START):1);
+		$year_end=$year_start;
+		$month_end=$month_start;
+		if (! GETPOST("month"))	// If month not forced
+		{
+			if (! GETPOST('year') && $month_start > $month_current)
+			{
+				$year_start--;
+				$year_end--;
+			}
+			$month_end=$month_start-1;
+			if ($month_end < 1) $month_end=12;
+			else $year_end++;
+		}
+		$date_start=dol_get_first_day($year_start,$month_start,false); $date_end=dol_get_last_day($year_end,$month_end,false);
+	}
+	if ($q==1) { $date_start=dol_get_first_day($year_start,1,false); $date_end=dol_get_last_day($year_start,3,false); }
+	if ($q==2) { $date_start=dol_get_first_day($year_start,4,false); $date_end=dol_get_last_day($year_start,6,false); }
+	if ($q==3) { $date_start=dol_get_first_day($year_start,7,false); $date_end=dol_get_last_day($year_start,9,false); }
+	if ($q==4) { $date_start=dol_get_first_day($year_start,10,false); $date_end=dol_get_last_day($year_start,12,false); }
+} else {
+	// TODO We define q
+}
+
+$commonparams=array();
+$commonparams['modecompta']=$modecompta;
+$commonparams['sortorder'] = $sortorder;
+$commonparams['sortfield'] = $sortfield;
+
+$headerparams = array();
+$headerparams['date_startyear'] = $date_startyear;
+$headerparams['date_startmonth'] = $date_startmonth;
+$headerparams['date_startday'] = $date_startday;
+$headerparams['date_endyear'] = $date_endyear;
+$headerparams['date_endmonth'] = $date_endmonth;
+$headerparams['date_endday'] = $date_endday;
+$headerparams['q'] = $q;
+
+$tableparams = array();
+$tableparams['search_categ'] = $selected_cat;
+$tableparams['subcat'] = ($subcat === true)?'yes':'';
+
+// Adding common parameters
+$allparams = array_merge($commonparams, $headerparams, $tableparams);
+$headerparams = array_merge($commonparams, $headerparams);
+$tableparams = array_merge($commonparams, $tableparams);
+
+foreach($allparams as $key => $value) {
+    $paramslink .= '&' . $key . '=' . $value;
+}
+/*
+ * View
+ */
+llxHeader();
+$form=new Form($db);
+$formother = new FormOther($db);
+
+// Show report header
+$nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByProductsAndServices");
+
+if ($modecompta=="CREANCES-DETTES") {
+    $nom.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&modecompta=RECETTES-DEPENSES">','</a>').')';
+
+    $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
+
+    $description=$langs->trans("RulesCADue");
+	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
+	    $description.= $langs->trans("DepositsAreNotIncluded");
+	} else {
+	    $description.= $langs->trans("DepositsAreIncluded");
+	}
+
+    $builddate=time();
+} else {
+    $nom.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&modecompta=CREANCES-DETTES">','</a>').')';
+
+    $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
+
+    $description=$langs->trans("RulesCAIn");
+    $description.= $langs->trans("DepositsAreIncluded");
+
+    $builddate=time();
+}
+
+report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$tableparams);
+
+
+// SQL request
+$catotal=0;
+
+if ($modecompta == 'CREANCES-DETTES') {
+    $sql = "SELECT DISTINCT p.rowid as rowid, p.ref as ref, p.label as label,";
+    $sql.= " sum(DISTINCT l.total_ht) as amount, sum(DISTINCT l.total_ttc) as amount_ttc";
+    $sql.= " FROM ".MAIN_DB_PREFIX."product as p";
+    $sql.= " JOIN ".MAIN_DB_PREFIX."facturedet as l";
+    $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON l.fk_facture = f.rowid";
+    if ($selected_cat === -2) {
+	$sql.=" LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product";
+    }
+    if ($selected_cat && $selected_cat !== -2) {
+	$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie as c ON c.rowid = " . $selected_cat;
+	if ($subcat) {
+	    $sql.=" OR c.fk_parent = " . $selected_cat;
+	}
+	$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON cp.fk_categorie = c.rowid";
+    }
+    $sql.= " WHERE l.fk_product = p.rowid";
+    $sql.= " AND f.fk_statut in (1,2)";
+    if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
+	$sql.= " AND f.type IN (0,1,2)";
+    } else {
+	$sql.= " AND f.type IN (0,1,2,3)";
+    }
+    if ($date_start && $date_end) {
+	$sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
+    }
+    if ($selected_cat === -2) {
+	$sql.=" AND cp.fk_product is null";
+    }
+    if ($selected_cat && $selected_cat !== -2) {
+	$sql.= " AND cp.fk_product = p.rowid";
+    }
+    $sql.= " AND f.entity = ".$conf->entity;
+    $sql.= " GROUP BY p.rowid ";
+    $sql.= "ORDER BY p.ref ";
+
+    $result = $db->query($sql);
+    if ($result) {
+	$num = $db->num_rows($result);
+	$i=0;
+	while ($i < $num) {
+		$obj = $db->fetch_object($result);
+		$amount_ht[$obj->rowid] = $obj->amount;
+		$amount[$obj->rowid] = $obj->amount_ttc;
+		$name[$obj->rowid] = $obj->ref . '&nbsp;-&nbsp;' . $obj->label;
+		$catotal_ht+=$obj->amount;
+		$catotal+=$obj->amount_ttc;
+		$i++;
+	}
+    } else {
+	dol_print_error($db);
+    }
+
+    // Show Array
+    $i=0;
+    print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
+    // Extra parameters management
+    foreach($headerparams as $key => $value)
+    {
+	 print '<input type="hidden" name="'.$key.'" value="'.$value.'">';
+    }
+
+    print '<table class="noborder" width="100%">';
+    // Category filter
+    print '<tr class="liste_titre">';
+    print '<td>';
+    print $langs->trans("Category") . ': ' . $formother->select_categories(0, $selected_cat, 'search_categ', true);
+    print ' ';
+    print $langs->trans("SubCats") . '? ';
+    print '<input type="checkbox" name="subcat" value="yes"';
+    if ($subcat) {
+	print ' checked';
+    }
+    print '></td>';
+    print '<td colspan="3" align="right">';
+    print '<input type="image" class="liste_titre" name="button_search" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/search.png"  value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
+    print '</td></tr>';
+	    // Array header
+    print "<tr class=\"liste_titre\">";
+    print_liste_field_titre(
+	    $langs->trans("Product"),
+	    $_SERVER["PHP_SELF"],
+	    "name",
+	    "",
+	    $paramslink,
+	    "",
+	    $sortfield,
+	    $sortorder
+	    );
+    print_liste_field_titre(
+	    $langs->trans('AmountHT'),
+	    $_SERVER["PHP_SELF"],
+	    "amount_ht",
+	    "",
+	    $paramslink,
+	    'align="right"',
+	    $sortfield,
+	    $sortorder
+	    );
+    print_liste_field_titre(
+	    $langs->trans("AmountTTC"),
+	    $_SERVER["PHP_SELF"],
+	    "amount_ttc",
+	    "",
+	    $paramslink,
+	    'align="right"',
+	    $sortfield,
+	    $sortorder
+	    );
+    print_liste_field_titre(
+	    $langs->trans("Percentage"),
+	    $_SERVER["PHP_SELF"],
+	    "amount_ttc",
+	    "",
+	    $paramslink,
+	    'align="right"',
+	    $sortfield,
+	    $sortorder
+	    );
+    // TODO: statistics?
+    print "</tr>\n";
+
+    // Array Data
+    $var=true;
+
+    if (count($amount)) {
+	    $arrayforsort=$name;
+	    // defining arrayforsort
+	    if ($sortfield == 'nom' && $sortorder == 'asc') {
+		    asort($name);
+		    $arrayforsort=$name;
+	    }
+	    if ($sortfield == 'nom' && $sortorder == 'desc') {
+		    arsort($name);
+		    $arrayforsort=$name;
+	    }
+	    if ($sortfield == 'amount_ht' && $sortorder == 'asc') {
+		asort($amount_ht);
+		$arrayforsort=$amount_ht;
+	    }
+	    if ($sortfield == 'amount_ht' && $sortorder == 'desc') {
+		arsort($amount_ht);
+		$arrayforsort=$amount_ht;
+	    }
+	    if ($sortfield == 'amount_ttc' && $sortorder == 'asc') {
+		    asort($amount);
+		    $arrayforsort=$amount;
+	    }
+	    if ($sortfield == 'amount_ttc' && $sortorder == 'desc') {
+		    arsort($amount);
+		    $arrayforsort=$amount;
+	    }
+	    foreach($arrayforsort as $key=>$value) {
+		    $var=!$var;
+		    print "<tr ".$bc[$var].">";
+
+		    // Third party
+		     $fullname=$name[$key];
+		    if ($key >= 0) {
+			$linkname='<a href="'.DOL_URL_ROOT.'/product/fiche.php?id='.$key.'">'.img_object($langs->trans("ShowProduct"),'product').' '.$fullname.'</a>';
+		    } else {
+			$linkname=$langs->trans("PaymentsNotLinkedToProduct");
+		    }
+
+		print "<td>".$linkname."</td>\n";
+
+		// Amount w/o VAT
+		print '<td align="right">';
+		if ($key > 0) {
+		    print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?productid='.$key.'">';
+		} else {
+		    print '<a href="#">';
+		}
+		print price($amount_ht[$key]);
+		print '</td>';
+
+		// Amount with VAT
+		print '<td align="right">';
+		if ($key > 0) {
+		    print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?productid='.$key.'">';
+		} else {
+		    print '<a href="#">';
+		}
+		print price($amount[$key]);
+		print '</a>';
+		print '</td>';
+
+		// Percent;
+		print '<td align="right">'.($catotal > 0 ? round(100 * $amount[$key] / $catotal, 2).'%' : '&nbsp;').'</td>';
+
+		// TODO: statistics?
+
+		print "</tr>\n";
+		$i++;
+	    }
+
+	    // Total
+	    print '<tr class="liste_total">';
+	    print '<td>'.$langs->trans("Total").'</td>';
+	    print '<td align="right">'.price($catotal_ht).'</td>';
+	    print '<td align="right">'.price($catotal).'</td>';
+	    print '<td>&nbsp;</td>';
+	    print '</tr>';
+
+	    $db->free($result);
+    }
+    print "</table>";
+    print '</form>';
+} else {
+    // $modecompta != 'CREANCES-DETTES'
+    // TODO: better message
+    print '<div class="warning">' . $langs->trans("WarningNotRelevant") . '</div>';
+}
+
+llxFooter();
+$db->close();
+?>
diff --git a/htdocs/compta/stats/cabyuser.php b/htdocs/compta/stats/cabyuser.php
index 86f16cf36841afee21787a65cfe96e619f4f2b5a..82bbff465eba721408848d9fe1a08ffa00338069 100644
--- a/htdocs/compta/stats/cabyuser.php
+++ b/htdocs/compta/stats/cabyuser.php
@@ -2,6 +2,7 @@
 /* Copyright (C) 2001-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  * Copyright (C) 2004-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
+ * Copyright (C) 2013      Antoine Iauch        <aiauch@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -46,6 +47,12 @@ if (! $sortfield) $sortfield="name";
 // Date range
 $year=GETPOST("year");
 $month=GETPOST("month");
+$date_startyear = GETPOST("date_startyear");
+$date_startmonth = GETPOST("date_startmonth");
+$date_startday = GETPOST("date_startday");
+$date_endyear = GETPOST("date_endyear");
+$date_endmonth = GETPOST("date_endmonth");
+$date_endday = GETPOST("date_endday");
 if (empty($year))
 {
 	$year_current = strftime("%Y",dol_now());
@@ -89,9 +96,34 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end
 else
 {
 	// TODO We define q
-
 }
 
+$commonparams=array();
+$commonparams['modecompta']=$modecompta;
+$commonparams['sortorder'] = $sortorder;
+$commonparams['sortfield'] = $sortfield;
+
+$headerparams = array();
+$headerparams['date_startyear'] = $date_startyear;
+$headerparams['date_startmonth'] = $date_startmonth;
+$headerparams['date_startday'] = $date_startday;
+$headerparams['date_endyear'] = $date_endyear;
+$headerparams['date_endmonth'] = $date_endmonth;
+$headerparams['date_endday'] = $date_endday;
+$headerparams['q'] = $q;
+
+$tableparams = array();
+$tableparams['search_categ'] = $selected_cat;
+$tableparams['subcat'] = ($subcat === true)?'yes':'';
+
+// Adding common parameters
+$allparams = array_merge($commonparams, $headerparams, $tableparams);
+$headerparams = array_merge($commonparams, $headerparams);
+$tableparams = array_merge($commonparams, $tableparams);
+
+foreach($allparams as $key => $value) {
+    $paramslink .= '&' . $key . '=' . $value;
+}
 
 /*
  * View
@@ -102,9 +134,8 @@ llxHeader();
 
 $form=new Form($db);
 
-// Affiche en-tete du rapport
-if ($modecompta=="CREANCES-DETTES")
-{
+// Show report header
+if ($modecompta=="CREANCES-DETTES") {
     $nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByUserAuthorOfInvoice");
     $nom.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&modecompta=RECETTES-DEPENSES">','</a>').')';
 	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
@@ -114,8 +145,7 @@ if ($modecompta=="CREANCES-DETTES")
 	else  $description.= $langs->trans("DepositsAreIncluded");
     $builddate=time();
     //$exportlink=$langs->trans("NotYetAvailable");
-}
-else {
+} else {
     $nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByUserAuthorOfInvoice");
     $nom.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&modecompta=CREANCES-DETTES">','</a>').')';
 	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
@@ -131,20 +161,29 @@ if (! empty($modecompta)) $moreparam['modecompta']=$modecompta;
 report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$moreparam);
 
 
-// Charge tableau
-$catotal=0;
-if ($modecompta == 'CREANCES-DETTES')
+// Show array
+print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
+// Extra parameters management
+foreach($headerparams as $key => $value)
 {
+     print '<input type="hidden" name="'.$key.'" value="'.$value.'">';
+}
+
+$catotal=0;
+if ($modecompta == 'CREANCES-DETTES') {
     $sql = "SELECT u.rowid as rowid, u.lastname as name, u.firstname as firstname, sum(f.total) as amount, sum(f.total_ttc) as amount_ttc";
     $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
     $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.fk_user_author = u.rowid";
     $sql.= " WHERE f.fk_statut in (1,2)";
-	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-	else $sql.= " AND f.type IN (0,1,2,3)";
-	if ($date_start && $date_end) $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
-}
-else
-{
+	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
+	    $sql.= " AND f.type IN (0,1,2)";
+	    } else {
+	    $sql.= " AND f.type IN (0,1,2,3)";
+	}
+	if ($date_start && $date_end) {
+	    $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
+	}
+} else {
     /*
      * Liste des paiements (les anciens paiements ne sont pas vus par cette requete car, sur les
      * vieilles versions, ils n'etaient pas lies via paiement_facture. On les ajoute plus loin)
@@ -155,7 +194,9 @@ else
 	$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON pf.fk_facture = f.rowid";
 	$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement as p ON p.rowid = pf.fk_paiement";
 	$sql.= " WHERE 1=1";
-	if ($date_start && $date_end) $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'";
+	if ($date_start && $date_end) {
+	    $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'";
+	}
 }
 $sql.= " AND f.entity = ".$conf->entity;
 if ($socid) $sql.= " AND f.fk_soc = ".$socid;
@@ -163,27 +204,25 @@ $sql .= " GROUP BY u.rowid, u.lastname, u.firstname";
 $sql .= " ORDER BY u.rowid";
 
 $result = $db->query($sql);
-if ($result)
-{
+if ($result) {
     $num = $db->num_rows($result);
     $i=0;
-    while ($i < $num)
-    {
+    while ($i < $num) {
          $obj = $db->fetch_object($result);
-         $amount[$obj->rowid] = $obj->amount_ttc;
-         $name[$obj->rowid] = $obj->lastname.' '.$obj->firstname;
-         $catotal+=$obj->amount_ttc;
-         $i++;
+	 $amount_ht[$obj->rowid] = $obj->amount;
+	 $amount[$obj->rowid] = $obj->amount_ttc;
+	 $name[$obj->rowid] = $obj->name.' '.$obj->firstname;
+	 $catotal_ht+=$obj->amount;
+	 $catotal+=$obj->amount_ttc;
+	 $i++;
     }
-}
-else {
+} else {
     dol_print_error($db);
 }
 
-// On ajoute les paiements ancienne version, non lies par paiement_facture donc sans user
-if ($modecompta != 'CREANCES-DETTES')
-{
-    $sql = "SELECT -1 as rowidx, '' as lastname, '' as firstname, sum(p.amount) as amount_ttc";
+// Adding old-version payments, non-bound by "paiement_facture" then without User
+if ($modecompta != 'CREANCES-DETTES') {
+    $sql = "SELECT -1 as rowidx, '' as name, '' as firstname, sum(DISTINCT p.amount) as amount_ttc";
     $sql.= " FROM ".MAIN_DB_PREFIX."bank as b";
     $sql.= ", ".MAIN_DB_PREFIX."bank_account as ba";
     $sql.= ", ".MAIN_DB_PREFIX."paiement as p";
@@ -192,42 +231,86 @@ if ($modecompta != 'CREANCES-DETTES')
     $sql.= " AND p.fk_bank = b.rowid";
     $sql.= " AND b.fk_account = ba.rowid";
     $sql.= " AND ba.entity = ".$conf->entity;
-	if ($date_start && $date_end) $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'";
+	if ($date_start && $date_end) {
+	    $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'";
+	}
     $sql.= " GROUP BY rowidx, name, firstname";
     $sql.= " ORDER BY rowidx";
 
     $result = $db->query($sql);
-    if ($result)
-    {
+    if ($result) {
         $num = $db->num_rows($result);
         $i=0;
-        while ($i < $num)
-        {
+        while ($i < $num) {
             $obj = $db->fetch_object($result);
             $amount[$obj->rowidx] = $obj->amount_ttc;
-            $name[$obj->rowidx] = $obj->lastname.' '.$obj->firstname;
+            $name[$obj->rowidx] = $obj->name.' '.$obj->firstname;
             $catotal+=$obj->amount_ttc;
             $i++;
         }
-    }
-    else {
+    } else {
         dol_print_error($db);
     }
 }
 
-
 $i = 0;
 print "<table class=\"noborder\" width=\"100%\">";
 print "<tr class=\"liste_titre\">";
-print_liste_field_titre($langs->trans("User"),$_SERVER["PHP_SELF"],"name","",'&amp;year='.($year).'&modecompta='.$modecompta,"",$sortfield,$sortorder);
-print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER["PHP_SELF"],"amount_ttc","",'&amp;year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder);
-print_liste_field_titre($langs->trans("Percentage"),$_SERVER["PHP_SELF"],"amount_ttc","",'&amp;year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder);
-print_liste_field_titre($langs->trans("OtherStatistics"),$_SERVER["PHP_SELF"],"","","",'align="center" width="20%"');
+print_liste_field_titre(
+	$langs->trans("User"),
+	$_SERVER["PHP_SELF"],
+	"name",
+	"",
+	$paramslink,
+	"",
+	$sortfield,
+	$sortorder
+	);
+if ($modecompta == 'CREANCES-DETTES') {
+    print_liste_field_titre(
+           $langs->trans('AmountHT'),
+           $_SERVER["PHP_SELF"],
+           "amount_ht",
+           "",
+           $paramslink,
+           'align="right"',
+           $sortfield,
+           $sortorder
+	   );
+    } else {
+	print '<td colspan="1"></td>';
+}
+print_liste_field_titre(
+	$langs->trans("AmountTTC"),
+	$_SERVER["PHP_SELF"],
+	"amount_ttc",
+	"",
+	$paramslink,
+	'align="right"',
+	$sortfield,
+	$sortorder
+	);
+print_liste_field_titre(
+	$langs->trans("Percentage"),
+	$_SERVER["PHP_SELF"],"amount_ttc",
+	"",
+	$paramslink,
+	'align="right"',
+	$sortfield,
+	$sortorder
+	);
+print_liste_field_titre(
+	$langs->trans("OtherStatistics"),
+	$_SERVER["PHP_SELF"],
+	"",
+	"",
+	"",
+	'align="center" width="20%"'
+	);
 print "</tr>\n";
 $var=true;
 
-if (count($amount))
-{
+if (count($amount)) {
     $arrayforsort=$name;
 
     // We define arrayforsort
@@ -239,6 +322,14 @@ if (count($amount))
         arsort($name);
         $arrayforsort=$name;
     }
+    if ($sortfield == 'amount_ht' && $sortorder == 'asc') {
+        asort($amount_ht);
+        $arrayforsort=$amount_ht;
+    }
+    if ($sortfield == 'amount_ht' && $sortorder == 'desc') {
+        arsort($amount_ht);
+        $arrayforsort=$amount_ht;
+    }
     if ($sortfield == 'amount_ttc' && $sortorder == 'asc') {
         asort($amount);
         $arrayforsort=$amount;
@@ -248,8 +339,7 @@ if (count($amount))
         $arrayforsort=$amount;
     }
 
-    foreach($arrayforsort as $key => $value)
-    {
+    foreach($arrayforsort as $key => $value) {
         $var=!$var;
         print "<tr ".$bc[$var].">";
 
@@ -257,23 +347,44 @@ if (count($amount))
         $fullname=$name[$key];
         if ($key >= 0) {
             $linkname='<a href="'.DOL_URL_ROOT.'/user/fiche.php?id='.$key.'">'.img_object($langs->trans("ShowUser"),'user').' '.$fullname.'</a>';
-        }
-        else {
+        } else {
             $linkname=$langs->trans("PaymentsNotLinkedToUser");
         }
         print "<td>".$linkname."</td>\n";
 
-        // Amount
+	// Amount w/o VAT
         print '<td align="right">';
         if ($modecompta != 'CREANCES-DETTES')
         {
-            if ($key > 0) print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?userid='.$key.'">';
-            else print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?userid=-1">';
+            if ($key > 0) {
+		print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?userid='.$key.'">';
+		} else {
+		    print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?userid=-1">';
+		}
+        } else {
+            if ($key > 0) {
+		print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?userid='.$key.'">';
+	    } else {
+		print '<a href="#">';
+	    }
+	    print price($amount_ht[$key]);
         }
-        else
-        {
-            if ($key > 0) print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?userid='.$key.'">';
-            else print '<a href="#">';
+        print '</td>';
+
+        // Amount with VAT
+        print '<td align="right">';
+        if ($modecompta != 'CREANCES-DETTES') {
+            if ($key > 0) {
+		print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?userid='.$key.'">';
+		} else {
+		    print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?userid=-1">';
+		}
+        } else {
+            if ($key > 0) {
+		print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?userid='.$key.'">';
+	    } else {
+		print '<a href="#">';
+	    }
         }
         print price($amount[$key]);
         print '</td>';
@@ -283,17 +394,30 @@ if (count($amount))
 
         // Other stats
         print '<td align="center">';
-        if (! empty($conf->propal->enabled) && $key>0) print '&nbsp;<a href="'.DOL_URL_ROOT.'/comm/propal/stats/index.php?userid='.$key.'">'.img_picto($langs->trans("ProposalStats"),"stats").'</a>&nbsp;';
-        if (! empty($conf->commande->enabled) && $key>0) print '&nbsp;<a href="'.DOL_URL_ROOT.'/commande/stats/index.php?userid='.$key.'">'.img_picto($langs->trans("OrderStats"),"stats").'</a>&nbsp;';
-        if (! empty($conf->facture->enabled) && $key>0) print '&nbsp;<a href="'.DOL_URL_ROOT.'/compta/facture/stats/index.php?userid='.$key.'">'.img_picto($langs->trans("InvoiceStats"),"stats").'</a>&nbsp;';
+        if (! empty($conf->propal->enabled) && $key>0) {
+	    print '&nbsp;<a href="'.DOL_URL_ROOT.'/comm/propal/stats/index.php?userid='.$key.'">'.img_picto($langs->trans("ProposalStats"),"stats").'</a>&nbsp;';
+	}
+        if (! empty($conf->commande->enabled) && $key>0) {
+	    print '&nbsp;<a href="'.DOL_URL_ROOT.'/commande/stats/index.php?userid='.$key.'">'.img_picto($langs->trans("OrderStats"),"stats").'</a>&nbsp;';
+	}
+        if (! empty($conf->facture->enabled) && $key>0) {
+	    print '&nbsp;<a href="'.DOL_URL_ROOT.'/compta/facture/stats/index.php?userid='.$key.'">'.img_picto($langs->trans("InvoiceStats"),"stats").'</a>&nbsp;';
+	}
         print '</td>';
-
         print "</tr>\n";
         $i++;
     }
 
     // Total
-    print '<tr class="liste_total"><td>'.$langs->trans("Total").'</td><td align="right">'.price($catotal).'</td><td>&nbsp;</td>';
+    print '<tr class="liste_total">';
+    print '<td>'.$langs->trans("Total").'</td>';
+    if ($modecompta != 'CREANCES-DETTES') {
+	print '<td colspan="1"></td>';
+    } else {
+	    print '<td align="right">'.price($catotal_ht).'</td>';
+    }
+    print '<td align="right">'.price($catotal).'</td>';
+    print '<td>&nbsp;</td>';
     print '<td>&nbsp;</td>';
     print '</tr>';
 
diff --git a/htdocs/compta/stats/casoc.php b/htdocs/compta/stats/casoc.php
index b658cf636d65d9986290103e5876c72dff4a9e7d..32d527cc7796955dbae07d1ef4e51ba0a984a7d0 100644
--- a/htdocs/compta/stats/casoc.php
+++ b/htdocs/compta/stats/casoc.php
@@ -3,6 +3,7 @@
  * Copyright (C) 2004-2011 Laurent Destailleur   <eldy@users.sourceforge.net>
  * Copyright (C) 2005-2009 Regis Houssin         <regis.houssin@capnetworks.com>
  * Copyright (C) 2007      Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
+ * Copyright (C) 2013      Antoine Iauch         <aiauch@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,8 +28,10 @@ require '../../main.inc.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
 
 $langs->load("companies");
+$langs->load("categories");
 
 // Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES')
 $modecompta = $conf->global->COMPTA_MODE;
@@ -41,6 +44,13 @@ if (! $sortfield) $sortfield="nom";
 
 $socid = GETPOST('socid','int');
 
+// Category
+$selected_cat = (int)GETPOST('search_categ', 'int');
+$subcat = false;
+if (GETPOST('subcat', 'alpha') === 'yes') {
+    $subcat = true;
+}
+
 // Security check
 if ($user->societe_id > 0) $socid = $user->societe_id;
 if (! empty($conf->comptabilite->enabled)) $result=restrictedArea($user,'compta','','','resultat');
@@ -49,6 +59,12 @@ if (! empty($conf->accounting->enabled)) $result=restrictedArea($user,'accountin
 // Date range
 $year=GETPOST("year");
 $month=GETPOST("month");
+$date_startyear = GETPOST("date_startyear");
+$date_startmonth = GETPOST("date_startmonth");
+$date_startday = GETPOST("date_startday");
+$date_endyear = GETPOST("date_endyear");
+$date_endmonth = GETPOST("date_endmonth");
+$date_endday = GETPOST("date_endday");
 if (empty($year))
 {
 	$year_current = strftime("%Y",dol_now());
@@ -92,10 +108,34 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end
 else
 {
 	// TODO We define q
-
 }
 
-
+$commonparams=array();
+$commonparams['modecompta']=$modecompta;
+$commonparams['sortorder'] = $sortorder;
+$commonparams['sortfield'] = $sortfield;
+
+$headerparams = array();
+$headerparams['date_startyear'] = $date_startyear;
+$headerparams['date_startmonth'] = $date_startmonth;
+$headerparams['date_startday'] = $date_startday;
+$headerparams['date_endyear'] = $date_endyear;
+$headerparams['date_endmonth'] = $date_endmonth;
+$headerparams['date_endday'] = $date_endday;
+$headerparams['q'] = $q;
+
+$tableparams = array();
+$tableparams['search_categ'] = $selected_cat;
+$tableparams['subcat'] = ($subcat === true)?'yes':'';
+
+// Adding common parameters
+$allparams = array_merge($commonparams, $headerparams, $tableparams);
+$headerparams = array_merge($commonparams, $headerparams);
+$tableparams = array_merge($commonparams, $tableparams);
+
+foreach($allparams as $key => $value) {
+    $paramslink .= '&' . $key . '=' . $value;
+}
 
 /*
  * View
@@ -105,8 +145,9 @@ llxHeader();
 
 $form=new Form($db);
 $thirdparty_static=new Societe($db);
+$formother = new FormOther($db);
 
-// Affiche en-tete de rapport
+// Show report header
 if ($modecompta=="CREANCES-DETTES")
 {
 	$nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByThirdParties");
@@ -118,8 +159,7 @@ if ($modecompta=="CREANCES-DETTES")
 	else  $description.= $langs->trans("DepositsAreIncluded");
 	$builddate=time();
 	//$exportlink=$langs->trans("NotYetAvailable");
-}
-else {
+} else {
 	$nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByThirdParties");
 	$nom.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&modecompta=CREANCES-DETTES">','</a>').')';
 	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
@@ -129,26 +169,44 @@ else {
 	$builddate=time();
 	//$exportlink=$langs->trans("NotYetAvailable");
 }
-$moreparam=array();
-if (! empty($modecompta)) $moreparam['modecompta']=$modecompta;
-report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$moreparam);
 
+report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$tableparams);
 
-// Charge tableau
+
+// Show Array
 $catotal=0;
-if ($modecompta == 'CREANCES-DETTES')
-{
-	$sql = "SELECT s.rowid as socid, s.nom as name, sum(f.total) as amount, sum(f.total_ttc) as amount_ttc";
+if ($modecompta == 'CREANCES-DETTES') {
+	$sql = "SELECT DISTINCT s.rowid as socid, s.nom as name,";
+	$sql.= " sum(DISTINCT f.total) as amount, sum(DISTINCT f.total_ttc) as amount_ttc";
 	$sql.= " FROM ".MAIN_DB_PREFIX."societe as s";
-	$sql.= ", ".MAIN_DB_PREFIX."facture as f";
+	$sql.= " JOIN ".MAIN_DB_PREFIX."facture as f";
+	if ($selected_cat === -2) {
+	    $sql.= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON s.rowid = cs.fk_societe";
+	}
+	if ($selected_cat && $selected_cat !== -2) {
+	    $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie as c ON c.rowid = ".$selected_cat;
+	    if (subcat) {
+		$sql.=" OR c.fk_parent = " . $selected_cat;
+	    }
+	     $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON cs.fk_categorie = c.rowid";
+	}
 	$sql.= " WHERE f.fk_statut in (1,2)";
-	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-	else $sql.= " AND f.type IN (0,1,2,3)";
+	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
+	    $sql.= " AND f.type IN (0,1,2)";
+	} else {
+	    $sql.= " AND f.type IN (0,1,2,3)";
+	}
 	$sql.= " AND f.fk_soc = s.rowid";
-	if ($date_start && $date_end) $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
-}
-else
-{
+	if ($date_start && $date_end) {
+	    $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
+	}
+	if ($selected_cat === -2) {
+	    $sql.=" AND cs.fk_societe is null";
+	}
+	if ($selected_cat && $selected_cat !== -2) {
+	    $sql.= " AND cs.fk_societe = s.rowid";
+	}
+    } else {
 	/*
 	 * Liste des paiements (les anciens paiements ne sont pas vus par cette requete car, sur les
 	 * vieilles versions, ils n'etaient pas lies via paiement_facture. On les ajoute plus loin)
@@ -161,7 +219,9 @@ else
 	$sql .= " WHERE p.rowid = pf.fk_paiement";
 	$sql.= " AND pf.fk_facture = f.rowid";
 	$sql.= " AND f.fk_soc = s.rowid";
-	if ($date_start && $date_end) $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'";
+	if ($date_start && $date_end) {
+	    $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'";
+	}
 }
 $sql.= " AND f.entity = ".$conf->entity;
 if ($socid) $sql.= " AND f.fk_soc = ".$socid;
@@ -169,27 +229,26 @@ $sql.= " GROUP BY s.rowid, s.nom";
 $sql.= " ORDER BY s.rowid";
 
 $result = $db->query($sql);
-if ($result)
-{
+if ($result) {
 	$num = $db->num_rows($result);
 	$i=0;
-	while ($i < $num)
-	{
+	while ($i < $num) {
 		$obj = $db->fetch_object($result);
-		$amount[$obj->socid] += $obj->amount_ttc;
-		$name[$obj->socid] = $obj->name;
-		$catotal+=$obj->amount_ttc;
-		$i++;
+	        $amount_ht[$obj->socid] = $obj->amount;
+	        $amount[$obj->socid] = $obj->amount_ttc;
+	        $name[$obj->socid] = $obj->name.' '.$obj->firstname;
+	        $catotal_ht+=$obj->amount;
+	        $catotal+=$obj->amount_ttc;
+	        $i++;
+
 	}
-}
-else {
+} else {
 	dol_print_error($db);
 }
 
 // On ajoute les paiements anciennes version, non lies par paiement_facture
-if ($modecompta != 'CREANCES-DETTES')
-{
-	$sql = "SELECT '0' as socid, 'Autres' as name, sum(p.amount) as amount_ttc";
+if ($modecompta != 'CREANCES-DETTES') {
+	$sql = "SELECT '0' as socid, 'Autres' as name, sum(DISTINCT p.amount) as amount_ttc";
 	$sql.= " FROM ".MAIN_DB_PREFIX."bank as b";
 	$sql.= ", ".MAIN_DB_PREFIX."bank_account as ba";
 	$sql.= ", ".MAIN_DB_PREFIX."paiement as p";
@@ -203,20 +262,17 @@ if ($modecompta != 'CREANCES-DETTES')
 	$sql.= " ORDER BY name";
 
 	$result = $db->query($sql);
-	if ($result)
-	{
+	if ($result) {
 		$num = $db->num_rows($result);
 		$i=0;
-		while ($i < $num)
-		{
+		while ($i < $num) {
 			$obj = $db->fetch_object($result);
 			$amount[$obj->rowid] += $obj->amount_ttc;
 			$name[$obj->rowid] = $obj->name;
 			$catotal+=$obj->amount_ttc;
 			$i++;
 		}
-	}
-	else {
+	} else {
 		dol_print_error($db);
 	}
 }
@@ -224,20 +280,87 @@ if ($modecompta != 'CREANCES-DETTES')
 
 // Show array
 $i = 0;
+print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
+// Extra parameters management
+foreach($headerparams as $key => $value)
+{
+     print '<input type="hidden" name="'.$key.'" value="'.$value.'">';
+}
 print "<table class=\"noborder\" width=\"100%\">";
-print "<tr class=\"liste_titre\">";
-print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"nom","",'&amp;year='.($year).'&modecompta='.$modecompta,"",$sortfield,$sortorder);
-print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER["PHP_SELF"],"amount_ttc","",'&amp;year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder);
-print_liste_field_titre($langs->trans("Percentage"),$_SERVER["PHP_SELF"],"amount_ttc","",'&amp;year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder);
-print_liste_field_titre($langs->trans("OtherStatistics"),$_SERVER["PHP_SELF"],"","","",'align="center" width="20%"');
+    // Category filter
+print '<tr class="liste_titre">';
+print '<td>';
+print $langs->trans("Category") . ': ' . $formother->select_categories(2, $selected_cat, 'search_categ', true);
+print ' ';
+print $langs->trans("SubCats") . '? ';
+print '<input type="checkbox" name="subcat" value="yes"';
+if ($subcat) {
+    print ' checked="checked"';
+}
+print'></td>';
+print '<td colspan="4" align="right">';
+print '<input type="image" class="liste_titre" name="button_search" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/search.png"  value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
+print '</td>';
+print '</tr>';
+    // Array titles
+print "<tr class='liste_titre'>";
+print_liste_field_titre(
+	$langs->trans("Company"),
+	$_SERVER["PHP_SELF"],
+	"nom",
+	"",
+	$paramslink,
+	"",
+	$sortfield,$sortorder
+	);
+if ($modecompta == 'CREANCES-DETTES') {
+    print_liste_field_titre(
+           $langs->trans('AmountHT'),
+           $_SERVER["PHP_SELF"],
+           "amount_ht",
+           "",
+           $paramslink,
+           'align="right"',
+           $sortfield,
+           $sortorder
+	);
+    } else {
+	print '<td colspan="1"></td>';
+}
+print_liste_field_titre(
+	$langs->trans("AmountTTC"),
+	$_SERVER["PHP_SELF"],
+	"amount_ttc",
+	"",
+	$paramslink,
+	'align="right"',
+	$sortfield,
+	$sortorder
+	);
+print_liste_field_titre(
+	$langs->trans("Percentage"),
+	$_SERVER["PHP_SELF"],
+	"amount_ttc",
+	"",
+	$paramslink,
+	'align="right"',
+	$sortfield,
+	$sortorder
+	);
+print_liste_field_titre(
+	$langs->trans("OtherStatistics"),
+	$_SERVER["PHP_SELF"],
+	"",
+	"",
+	"",
+	'align="center" width="20%"'
+	);
 print "</tr>\n";
 $var=true;
 
-if (count($amount))
-{
+if (count($amount)) {
 	$arrayforsort=$name;
-
-	// On definit tableau arrayforsort
+	// Defining array arrayforsort
 	if ($sortfield == 'nom' && $sortorder == 'asc') {
 		asort($name);
 		$arrayforsort=$name;
@@ -246,6 +369,14 @@ if (count($amount))
 		arsort($name);
 		$arrayforsort=$name;
 	}
+	if ($sortfield == 'amount_ht' && $sortorder == 'asc') {
+	    asort($amount_ht);
+	    $arrayforsort=$amount_ht;
+	}
+	if ($sortfield == 'amount_ht' && $sortorder == 'desc') {
+	    arsort($amount_ht);
+	    $arrayforsort=$amount_ht;
+	}
 	if ($sortfield == 'amount_ttc' && $sortorder == 'asc') {
 		asort($amount);
 		$arrayforsort=$amount;
@@ -255,8 +386,7 @@ if (count($amount))
 		$arrayforsort=$amount;
 	}
 
-	foreach($arrayforsort as $key=>$value)
-	{
+	foreach($arrayforsort as $key=>$value) {
 		$var=!$var;
 		print "<tr ".$bc[$var].">";
 
@@ -267,23 +397,43 @@ if (count($amount))
 		    $thirdparty_static->name=$fullname;
 		    $thirdparty_static->client=1;
 		    $linkname=$thirdparty_static->getNomUrl(1,'customer');
-		}
-		else {
+		} else {
 			$linkname=$langs->trans("PaymentsNotLinkedToInvoice");
 		}
 		print "<td>".$linkname."</td>\n";
 
-		// Amount
+		// Amount w/o VAT
 		print '<td align="right">';
-		if ($modecompta != 'CREANCES-DETTES')
-		{
-    		if ($key > 0) print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?socid='.$key.'">';
-    		else print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?orphelins=1">';
+		if ($modecompta != 'CREANCES-DETTES') {
+                    if ($key > 0) {
+			print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?userid='.$key.'">';
+		    } else {
+			print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?userid=-1">';
+		    }
+		} else {
+		    if ($key > 0) {
+			print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?userid='.$key.'">';
+		    } else {
+			print '<a href="#">';
+		    }
+		print price($amount_ht[$key]);
 		}
-		else
-		{
-            if ($key > 0) print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$key.'">';
-            else print '<a href="#">';
+		print '</td>';
+
+		// Amount with VAT
+		print '<td align="right">';
+		if ($modecompta != 'CREANCES-DETTES') {
+                    if ($key > 0) {
+                        print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?socid='.$key.'">';
+		    } else {
+			print '<a href="'.DOL_URL_ROOT.'/compta/paiement/liste.php?orphelins=1">';
+		    }
+		} else {
+                    if ($key > 0) {
+                        print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$key.'">';
+		    } else {
+			print '<a href="#">';
+		    }
 		}
 		print price($amount[$key]);
 		print '</a>';
@@ -294,17 +444,30 @@ if (count($amount))
 
         // Other stats
         print '<td align="center">';
-        if (! empty($conf->propal->enabled) && $key>0) print '&nbsp;<a href="'.DOL_URL_ROOT.'/comm/propal/stats/index.php?socid='.$key.'">'.img_picto($langs->trans("ProposalStats"),"stats").'</a>&nbsp;';
-        if (! empty($conf->commande->enabled) && $key>0) print '&nbsp;<a href="'.DOL_URL_ROOT.'/commande/stats/index.php?socid='.$key.'">'.img_picto($langs->trans("OrderStats"),"stats").'</a>&nbsp;';
-        if (! empty($conf->facture->enabled) && $key>0) print '&nbsp;<a href="'.DOL_URL_ROOT.'/compta/facture/stats/index.php?socid='.$key.'">'.img_picto($langs->trans("InvoiceStats"),"stats").'</a>&nbsp;';
+        if (! empty($conf->propal->enabled) && $key>0) {
+	    print '&nbsp;<a href="'.DOL_URL_ROOT.'/comm/propal/stats/index.php?socid='.$key.'">'.img_picto($langs->trans("ProposalStats"),"stats").'</a>&nbsp;';
+	}
+        if (! empty($conf->commande->enabled) && $key>0) {
+	    print '&nbsp;<a href="'.DOL_URL_ROOT.'/commande/stats/index.php?socid='.$key.'">'.img_picto($langs->trans("OrderStats"),"stats").'</a>&nbsp;';
+	}
+        if (! empty($conf->facture->enabled) && $key>0) {
+	    print '&nbsp;<a href="'.DOL_URL_ROOT.'/compta/facture/stats/index.php?socid='.$key.'">'.img_picto($langs->trans("InvoiceStats"),"stats").'</a>&nbsp;';
+	}
         print '</td>';
-
-		print "</tr>\n";
-		$i++;
+	print "</tr>\n";
+	$i++;
 	}
 
 	// Total
-	print '<tr class="liste_total"><td>'.$langs->trans("Total").'</td><td align="right">'.price($catotal).'</td><td>&nbsp;</td>';
+	print '<tr class="liste_total">';
+	print '<td>'.$langs->trans("Total").'</td>';
+	if ($modecompta != 'CREANCES-DETTES') {
+	    print '<td colspan="1"></td>';
+	} else {
+	    print '<td align="right">'.price($catotal_ht).'</td>';
+	}
+	print '<td align="right">'.price($catotal).'</td>';
+	print '<td>&nbsp;</td>';
 	print '<td>&nbsp;</td>';
 	print '</tr>';
 
@@ -312,8 +475,7 @@ if (count($amount))
 }
 
 print "</table>";
-print '<br>';
-
+print '</form>';
 
 llxFooter();
 
diff --git a/htdocs/contrat/note.php b/htdocs/contrat/note.php
index ee66e4583f7d5d9ba44d6dcbe6f7ee8cff96b462..c8edf493f638a7e0bb435de2ad928f82889c9ab9 100644
--- a/htdocs/contrat/note.php
+++ b/htdocs/contrat/note.php
@@ -50,7 +50,7 @@ $object->fetch($id,$ref);
 
 if ($action == 'setnote_public' && $user->rights->contrat->creer)
 {
-	$result=$object->update_note(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note_public')), ENT_QUOTES),'_pubic');
+	$result=$object->update_note(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note_public')), ENT_QUOTES),'_public');
 	if ($result < 0) dol_print_error($db,$object->error);
 }
 
diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php
index ef4d976d4d7b92f88131da0dbddb5298ab19c3ed..2389a681000535eef087c440ce8639be77a57c27 100644
--- a/htdocs/core/ajax/ajaxdirpreview.php
+++ b/htdocs/core/ajax/ajaxdirpreview.php
@@ -4,6 +4,7 @@
  * Copyright (C) 2005      Simon Tosser         <simon@kornog-computing.com>
  * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
  * Copyright (C) 2010	   Pierre Morin         <pierre.morin@auguria.net>
+ * Copyright (C) 2013      Marcos García        <marcosgdf@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -139,8 +140,7 @@ if (! dol_is_dir($upload_dir))
 print '<!-- TYPE='.$type.' -->'."\n";
 print '<!-- Page called with mode='.(isset($mode)?$mode:'').' type='.$type.' module='.$module.' url='.$_SERVER["PHP_SELF"].'?'.$_SERVER["QUERY_STRING"].' -->'."\n";
 
-$param='';
-$param.=($sortfield?'&sortfield='.$sortfield:'').($sortorder?'&sortorder='.$sortorder:'');
+$param=($sortfield?'&sortfield='.$sortfield:'').($sortorder?'&sortorder='.$sortorder:'');
 $url=DOL_URL_ROOT.'/ecm/index.php';
 
 // Dir scan
@@ -149,126 +149,73 @@ if ($type == 'directory')
     $formfile=new FormFile($db);
 
     $maxlengthname=40;
+    $excludefiles = array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$');
+    $sorting = (strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC);
 
     // Right area. If module is defined, we are in automatic ecm.
-    if ($module == 'company')  // Auto area for suppliers invoices
-    {
-        $upload_dir = $conf->societe->dir_output; // TODO change for multicompany sharing
-        $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
-
-        $param.='&module='.$module;
-        $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound")));
-
-        $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url);
-    }
-    else if ($module == 'invoice')  // Auto area for suppliers invoices
-    {
-        $upload_dir = $conf->facture->dir_output;
-        $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
-
-        $param.='&module='.$module;
-        $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound")));
-
-        $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url);
-    }
-    else if ($module == 'invoice_supplier')  // Auto area for suppliers invoices
+    $automodules = array('company', 'invoice', 'invoice_supplier', 'propal', 'order', 'order_supplier', 'contract', 'product', 'tax', 'project');
+
+    // TODO change for multicompany sharing
+    // Auto area for suppliers invoices
+    if ($module == 'company') $upload_dir = $conf->societe->dir_output;
+    // Auto area for suppliers invoices
+    else if ($module == 'invoice') $upload_dir = $conf->facture->dir_output;
+    // Auto area for suppliers invoices
+    else if ($module == 'invoice_supplier')
     {
         $relativepath='facture';
         $upload_dir = $conf->fournisseur->dir_output.'/'.$relativepath;
-        $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
-        $param.='&module='.$module;
-        $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound")));
-        $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url);
-    }
-    else if ($module == 'propal')  // Auto area for customers orders
-    {
-        $upload_dir = $conf->propal->dir_output;
-        $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
-
-        $param.='&module='.$module;
-        $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound")));
-
-        $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url);
-    }
-    else if ($module == 'order')  // Auto area for customers orders
-    {
-        $upload_dir = $conf->commande->dir_output;
-        $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
-
-        $param.='&module='.$module;
-        $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound")));
-
-        $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url);
     }
-    else if ($module == 'order_supplier')  // Auto area for suppliers orders
+    // Auto area for customers orders
+    else if ($module == 'propal') $upload_dir = $conf->propal->dir_output;
+    // Auto area for customers orders
+    else if ($module == 'order') $upload_dir = $conf->commande->dir_output;
+    // Auto area for suppliers orders
+    else if ($module == 'order_supplier')
     {
         $relativepath='commande';
         $upload_dir = $conf->fournisseur->dir_output.'/'.$relativepath;
-        $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
-
-        $param.='&module='.$module;
-        $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound")));
-
-        $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url);
     }
-    else if ($module == 'contract')  // Auto area for suppliers invoices
+    // Auto area for suppliers invoices
+    else if ($module == 'contract') $upload_dir = $conf->contrat->dir_output;
+    // Auto area for products
+    else if ($module == 'product') $upload_dir = $conf->product->dir_output;
+    // Auto area for suppliers invoices
+    else if ($module == 'tax') $upload_dir = $conf->tax->dir_output;
+    // Auto area for projects
+    else if ($module == 'project') $upload_dir = $conf->projet->dir_output;
+
+    if (in_array($module, $automodules))
     {
-        $upload_dir = $conf->contrat->dir_output;
-        $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
-
-        $param.='&module='.$module;
-        $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound")));
-
-        $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url);
-    }
-    else if ($module == 'product')  // Auto area for products
-    {
-        $upload_dir = $conf->product->dir_output;
-        $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
-
         $param.='&module='.$module;
         $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound")));
 
+        $filearray=dol_dir_list($upload_dir,"files",1,'', $excludefiles, $sortfield, $sorting,1);
         $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url);
     }
-    else if ($module == 'tax')  // Auto area for suppliers invoices
-    {
-        $upload_dir = $conf->tax->dir_output;
-        $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
-
-        $param.='&module='.$module;
-        $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound")));
-
-        $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url);
-    }
-    else if ($module == 'project')  // Auto area for projects
-    {
-    	$upload_dir = $conf->projet->dir_output;
-    	$filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
-    	
-    	$param.='&module='.$module;
-    	$textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound")));
-    
-    	$formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url);
-    }
-    else    // Manual area
+    //Manual area
+    else
     {
         $relativepath=$ecmdir->getRelativePath();
         $upload_dir = $conf->ecm->dir_output.'/'.$relativepath;
 
-        $filearray=dol_dir_list($upload_dir,"files",0,'',array('^\.','\.meta$','^temp$','^CVS$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
-
-        if ($section) $param.='&section='.$section;
-        $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("ECMSelectASection")));
         // If $section defined with value 0
         if ($section === '0')
         {
-        	$filearray=array();
-        	$textifempty='<br><div align="center"><font class="warning">'.$langs->trans("DirNotSynchronizedSyncFirst").'</font></div><br>';
+            $filearray=array();
+            $textifempty='<br><div align="center"><font class="warning">'.$langs->trans("DirNotSynchronizedSyncFirst").'</font></div><br>';
         }
+        else $filearray=dol_dir_list($upload_dir,"files",0,'',array('^\.','\.meta$','^temp$','^CVS$'),$sortfield, $sorting,1);
+
+        if ($section)
+        {
+            $param.='&section='.$section;
+            $textifempty = $langs->trans('NoFileFound');
+        }
+        else $textifempty=($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("ECMSelectASection"));
+        
         $formfile->list_of_documents($filearray,'','ecm',$param,1,$relativepath,$user->rights->ecm->upload,1,$textifempty,$maxlengthname,'',$url);
     }
-
 }
 
 if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))
diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php
index ded1a4a30c4d5c4a4c3c8f215468e0714486508e..db8af5ba2652162807dfaa4695a345e3ae59f077 100644
--- a/htdocs/core/ajax/ajaxdirtree.php
+++ b/htdocs/core/ajax/ajaxdirtree.php
@@ -117,7 +117,7 @@ if (file_exists($fullpathselecteddir))
     	        // Loop on all database entries (sqltree) to find the one matching the subdir found into dir to scan
 		        foreach($sqltree as $key => $tmpval)
 		        {
-    	            //print "-- key=".$key." - ".$val['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file).'<br>';
+    	            //print "-- key=".$key." - ".$tmpval['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file)."<br>\n";
 		        	if ($tmpval['fullrelativename'] == (($selecteddir != '/'?$selecteddir.'/':'').$file))		// We found equivalent record into database
 		            {
 		                $val=$tmpval;
diff --git a/htdocs/core/boxes/box_produits_alerte_stock.php b/htdocs/core/boxes/box_produits_alerte_stock.php
index 41070298cac79216f6f139452b68ad7df366972a..57c2cc4de4cd30acde1d15f18b4758f9af657131 100644
--- a/htdocs/core/boxes/box_produits_alerte_stock.php
+++ b/htdocs/core/boxes/box_produits_alerte_stock.php
@@ -64,20 +64,23 @@ class box_produits_alerte_stock extends ModeleBoxes
 
 		if ($user->rights->produit->lire || $user->rights->service->lire)
 		{
-			$sql = "SELECT p.rowid, p.label, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.seuil_stock_alerte, s.reel";
+			$sql = "SELECT p.rowid, p.label, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.seuil_stock_alerte,";
+			$sql.= " SUM(".$db->ifsql("s.reel IS NULL","0","s.reel").") as total_stock";
 			$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
 			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as s on p.rowid = s.fk_product";
 			$sql.= ' WHERE p.entity IN ('.getEntity($productstatic->element, 1).')';
-			$sql.= " AND p.tosell = 1";
+			$sql.= " AND p.tosell = 1 AND p.seuil_stock_alerte > 0";
 			if (empty($user->rights->produit->lire)) $sql.=' AND p.fk_product_type != 0';
 			if (empty($user->rights->service->lire)) $sql.=' AND p.fk_product_type != 1';
-			$sql.= " HAVING s.reel < p.seuil_stock_alerte";
-			$sql.= $db->order('s.reel', 'DESC');
+			$sql.= " GROUP BY p.rowid, p.label, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.seuil_stock_alerte";
+			$sql.= " HAVING SUM(".$db->ifsql("s.reel IS NULL","0","s.reel").") < p.seuil_stock_alerte";
+			$sql.= $db->order('p.seuil_stock_alerte', 'DESC');
 			$sql.= $db->plimit($max, 0);
 
 			$result = $db->query($sql);
 			if ($result)
 			{
+				$langs->load("stocks");
 				$num = $db->num_rows($result);
 				$i = 0;
 				while ($i < $num)
@@ -128,7 +131,8 @@ class box_produits_alerte_stock extends ModeleBoxes
                     'text' => $price_base_type);
 
 					$this->info_box_contents[$i][4] = array('td' => 'align="center"',
-                    'text' => $objp->reel . ' / '.$objp->seuil_stock_alerte);
+                    'text' => $objp->total_stock . ' / '.$objp->seuil_stock_alerte,
+					'text2'=>img_warning($langs->transnoentitiesnoconv("StockLowerThanLimit")));
 
 					$this->info_box_contents[$i][5] = array('td' => 'align="right" width="18"',
                     'text' => $productstatic->LibStatut($objp->tosell,3,0));
@@ -138,7 +142,7 @@ class box_produits_alerte_stock extends ModeleBoxes
 
                     $i++;
 				}
-				if ($num==0) $this->info_box_contents[$i][0] = array('td' => 'align="center"','text'=>$langs->trans("NoRecordedProducts"));
+				if ($num==0) $this->info_box_contents[$i][0] = array('td' => 'align="center"','text'=>$langs->trans("NoTooLowStockProducts"));
 			}
 			else
 			{
diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php
index 2bd51b87f98cabccee8e2071aa515f6bcc9cc644..c681395f5afb09c1c83bcd4661ae13588ba1b67e 100644
--- a/htdocs/core/boxes/modules_boxes.php
+++ b/htdocs/core/boxes/modules_boxes.php
@@ -165,7 +165,8 @@ class ModeleBoxes    // Can't be abtract as it is instanciated to build "empty"
 				print '</td><td class="nocellnopadd boxclose" nowrap="nowrap">';
 				// The image must have the class 'boxhandle' beause it's value used in DOM draggable objects to define the area used to catch the full object
 				print img_picto($langs->trans("MoveBox",$this->box_id),'grip','class="boxhandle hideonsmartphone" style="cursor:move;"');
-				print img_picto($langs->trans("Close",$this->box_id),'close','class="boxclose" style="cursor:pointer;" id="imgclose'.$this->box_id.'"');
+				print img_picto($langs->trans("Close",$this->box_id),'close','class="boxclose" rel="x:y" style="cursor:pointer;" id="imgclose'.$this->box_id.'"');
+				print '<input type="hidden" id="boxlabelentry'.$this->box_id.'" value="'.dol_escape_htmltag($head['text']).'">';
 				print '</td></tr></table>';
 			}
 			print '</td>';
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 9f8a2aabf7d88ce07318785f581c3bddb40b8cc4..73d7e7b0e5d9316fa2aeb4f94e81b0df85f37124 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -2310,7 +2310,7 @@ abstract class CommonObject
     /**
      *  Function to say how many lines object contains
      *
-     *	@param	int		$predefined		-1=All, 0=Count free product/service only, 1=Count predefined product/service only
+     *	@param	int		$predefined		-1=All, 0=Count free product/service only, 1=Count predefined product/service only, 2=Count predefined product, 3=Count predefined service
      *  @return	int						<0 if KO, 0 if no predefined products, nb of lines with predefined products if found
      */
     function hasProductsOrServices($predefined=-1)
@@ -2323,6 +2323,8 @@ abstract class CommonObject
             if ($predefined == -1) $qualified=1;
             if ($predefined == 1 && $val->fk_product > 0) $qualified=1;
             if ($predefined == 0 && $val->fk_product <= 0) $qualified=1;
+            if ($predefined == 2 && $val->fk_product > 0 && $val->product_type==0) $qualified=1;
+            if ($predefined == 3 && $val->fk_product > 0 && $val->product_type==1) $qualified=1;
             if ($qualified) $nb++;
         }
         dol_syslog(get_class($this).'::hasProductsOrServices we found '.$nb.' qualified lines of products/servcies');
@@ -2946,11 +2948,11 @@ abstract class CommonObject
         global $conf,$langs,$bc;
 
         //var_dump($line);
-		if (!empty($line->date_start)) 
-		{ 
+		if (!empty($line->date_start))
+		{
 			$date_start=$line->date_start;
 		}
-		else  
+		else
 		{
 			$date_start=$line->date_debut_prevue;
 			if ($line->date_debut_reel) $date_start=$line->date_debut_reel;
@@ -2959,7 +2961,7 @@ abstract class CommonObject
 		{
 			$date_end=$line->date_end;
 		}
-		else 
+		else
 		{
 			$date_end=$line->date_fin_prevue;
 			if ($line->date_fin_reel) $date_end=$line->date_fin_reel;
@@ -2995,7 +2997,7 @@ abstract class CommonObject
             	$this->tpl['label'].=$line->desc;
             }else {
             	$this->tpl['label'].= ($line->label ? '&nbsp;'.$line->label : '');
-            }            
+            }
             // Dates
             if ($line->product_type == 1 && ($date_start || $date_end))
             {
@@ -3048,149 +3050,160 @@ abstract class CommonObject
     }
 
 
+	/**
+	 *
+	 * @param string $force_price
+	 * @return multitype:number string NULL
+	 */
+	function getMarginInfos($force_price=false) {
+		global $conf;
+		require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
+
+		$marginInfos = array(
+				'pa_products' => 0,
+				'pv_products' => 0,
+				'margin_on_products' => 0,
+				'margin_rate_products' => '',
+				'mark_rate_products' => '',
+				'pa_services' => 0,
+				'pv_services' => 0,
+				'margin_on_services' => 0,
+				'margin_rate_services' => '',
+				'mark_rate_services' => '',
+				'pa_total' => 0,
+				'pv_total' => 0,
+				'total_margin' => 0,
+				'total_margin_rate' => '',
+				'total_mark_rate' => ''
+		);
+
+		foreach($this->lines as $line) {
+			if (empty($line->pa_ht) && isset($line->fk_fournprice) && !$force_price) {
+				$product = new ProductFournisseur($this->db);
+				if ($product->fetch_product_fournisseur_price($line->fk_fournprice))
+					$line->pa_ht = $product->fourn_unitprice;
+				if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == "2" && $product->fourn_unitcharges > 0)
+					$line->pa_ht += $product->fourn_unitcharges;
+			}
+			// si prix d'achat non renseigné et devrait l'être, alors prix achat = prix vente
+			if ((!isset($line->pa_ht) || $line->pa_ht == 0) && $line->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) {
+				$line->pa_ht = $line->subprice * (1 - ($line->remise_percent / 100));
+			}
 
-  function getMarginInfos($force_price=false) {
-  	global $conf;
-    require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
-    $marginInfos = array(
-      'pa_products' => 0,
-      'pv_products' => 0,
-      'margin_on_products' => 0,
-      'margin_rate_products' => '',
-      'mark_rate_products' => '',
-      'pa_services' => 0,
-      'pv_services' => 0,
-      'margin_on_services' => 0,
-      'margin_rate_services' => '',
-      'mark_rate_services' => '',
-      'pa_total' => 0,
-      'pv_total' => 0,
-      'total_margin' => 0,
-      'total_margin_rate' => '',
-      'total_mark_rate' => ''
-    );
-    foreach($this->lines as $line) {
-      if (isset($line->fk_fournprice) && !$force_price) {
-        $product = new ProductFournisseur($this->db);
-        if ($product->fetch_product_fournisseur_price($line->fk_fournprice))
-          $line->pa_ht = $product->fourn_unitprice;
-          if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == "2" && $product->fourn_unitcharges > 0)
-          	$line->pa_ht += $product->fourn_unitcharges;
-      }
-      // si prix d'achat non renseigné et devrait l'être, alors prix achat = prix vente
-      if ((!isset($line->pa_ht) || $line->pa_ht == 0) && $line->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) {
-      	$line->pa_ht = $line->subprice * (1 - ($line->remise_percent / 100));
-      }
-
-      // calcul des marges
-      if (isset($line->fk_remise_except) && isset($conf->global->MARGIN_METHODE_FOR_DISCOUNT)) {    // remise
-        if ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '1') { // remise globale considérée comme produit
-          $marginInfos['pa_products'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
-          $marginInfos['pv_products'] += $line->subprice * (1 - $line->remise_percent / 100);
-			    $marginInfos['pa_total'] +=  $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
-			    $marginInfos['pv_total'] +=  $line->subprice * (1 - $line->remise_percent / 100);
+			// calcul des marges
+			if (isset($line->fk_remise_except) && isset($conf->global->MARGIN_METHODE_FOR_DISCOUNT)) {    // remise
+				if ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '1') { // remise globale considérée comme produit
+					$marginInfos['pa_products'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
+					$marginInfos['pv_products'] += $line->subprice * (1 - $line->remise_percent / 100);
+					$marginInfos['pa_total'] +=  $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
+					$marginInfos['pv_total'] +=  $line->subprice * (1 - $line->remise_percent / 100);
 				}
-        elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '2') { // remise globale considérée comme service
-          $marginInfos['pa_services'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
-          $marginInfos['pv_services'] += $line->subprice * (1 - ($line->remise_percent / 100));
-			    $marginInfos['pa_total'] +=  $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
-			    $marginInfos['pv_total'] +=  $line->subprice * (1 - $line->remise_percent / 100);
+				elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '2') { // remise globale considérée comme service
+					$marginInfos['pa_services'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
+					$marginInfos['pv_services'] += $line->subprice * (1 - ($line->remise_percent / 100));
+					$marginInfos['pa_total'] +=  $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
+					$marginInfos['pv_total'] +=  $line->subprice * (1 - $line->remise_percent / 100);
 				}
-        elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '3') { // remise globale prise en compte uniqt sur total
-          $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
-          $marginInfos['pv_total'] += $line->subprice * (1 - ($line->remise_percent / 100));
+				elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '3') { // remise globale prise en compte uniqt sur total
+					$marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
+					$marginInfos['pv_total'] += $line->subprice * (1 - ($line->remise_percent / 100));
 				}
 			}
-      else {
-        $type=$line->product_type?$line->product_type:$line->fk_product_type;
-        if ($type == 0) {  // product
-          $marginInfos['pa_products'] += $line->qty * $line->pa_ht;
-          $marginInfos['pv_products'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100);
-			    $marginInfos['pa_total'] +=  $line->qty * $line->pa_ht;
-			    $marginInfos['pv_total'] +=  $line->qty * $line->subprice * (1 - $line->remise_percent / 100);
-        }
-        elseif ($type == 1) {  // service
-          $marginInfos['pa_services'] += $line->qty * $line->pa_ht;
-          $marginInfos['pv_services'] += $line->qty * $line->subprice * (1 - ($line->remise_percent / 100));
-			    $marginInfos['pa_total'] +=  $line->qty * $line->pa_ht;
-			    $marginInfos['pv_total'] +=  $line->qty * $line->subprice * (1 - $line->remise_percent / 100);
-        }
-      }
-    }
+			else {
+				$type=$line->product_type?$line->product_type:$line->fk_product_type;
+				if ($type == 0) {  // product
+					$marginInfos['pa_products'] += $line->qty * $line->pa_ht;
+					$marginInfos['pv_products'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100);
+					$marginInfos['pa_total'] +=  $line->qty * $line->pa_ht;
+					$marginInfos['pv_total'] +=  $line->qty * $line->subprice * (1 - $line->remise_percent / 100);
+				}
+				elseif ($type == 1) {  // service
+					$marginInfos['pa_services'] += $line->qty * $line->pa_ht;
+					$marginInfos['pv_services'] += $line->qty * $line->subprice * (1 - ($line->remise_percent / 100));
+					$marginInfos['pa_total'] +=  $line->qty * $line->pa_ht;
+					$marginInfos['pv_total'] +=  $line->qty * $line->subprice * (1 - $line->remise_percent / 100);
+				}
+			}
+		}
 
-    $marginInfos['margin_on_products'] = $marginInfos['pv_products'] - $marginInfos['pa_products'];
-    if ($marginInfos['pa_products'] > 0)
-      $marginInfos['margin_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pa_products'],5);
-    if ($marginInfos['pv_products'] > 0)
-      $marginInfos['mark_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pv_products'],5);
-
-    $marginInfos['margin_on_services'] = $marginInfos['pv_services'] - $marginInfos['pa_services'];
-    if ($marginInfos['pa_services'] > 0)
-      $marginInfos['margin_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pa_services'],5);
-    if ($marginInfos['pv_services'] > 0)
-      $marginInfos['mark_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pv_services'],5);
-
-
-    $marginInfos['total_margin'] = $marginInfos['pv_total'] - $marginInfos['pa_total'];
-    if ($marginInfos['pa_total'] > 0)
-      $marginInfos['total_margin_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pa_total'],5);
-    if ($marginInfos['pv_total'] > 0)
-      $marginInfos['total_mark_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pv_total'],5);
-
-    return $marginInfos;
-  }
-
-  function displayMarginInfos($force_price=false) {
-    global $langs, $conf;
-    $marginInfo = $this->getMarginInfos($force_price);
-    print '<table class="noborder" width="100%">';
-    print '<tr class="liste_titre">';
-    print '<td width="30%">'.$langs->trans('Margins').'</td>';
-    print '<td width="20%" align="right">'.$langs->trans('SellingPrice').'</td>';
-	if ($conf->global->MARGIN_TYPE == "1")
-		print '<td width="20%" align="right">'.$langs->trans('BuyingPrice').'</td>';
-	else
-		print '<td width="20%" align="right">'.$langs->trans('CostPrice').'</td>';
-    print '<td width="20%" align="right">'.$langs->trans('Margin').'</td>';
-    if (! empty($conf->global->DISPLAY_MARGIN_RATES))
-      print '<td align="right">'.$langs->trans('MarginRate').'</td>';
-    if (! empty($conf->global->DISPLAY_MARK_RATES))
-      print '<td align="right">'.$langs->trans('MarkRate').'</td>';
-      print '</tr>';
-    //if ($marginInfo['margin_on_products'] != 0 && $marginInfo['margin_on_services'] != 0) {
-      print '<tr class="impair">';
-      print '<td>'.$langs->trans('MarginOnProducts').'</td>';
-      print '<td align="right">'.price($marginInfo['pv_products']).'</td>';
-      print '<td align="right">'.price($marginInfo['pa_products']).'</td>';
-      print '<td align="right">'.price($marginInfo['margin_on_products']).'</td>';
-      if (! empty($conf->global->DISPLAY_MARGIN_RATES))
-        print '<td align="right">'.(($marginInfo['margin_rate_products'] == '')?'n/a':price($marginInfo['margin_rate_products']).'%').'</td>';
-      if (! empty($conf->global->DISPLAY_MARK_RATES))
-        print '<td align="right">'.(($marginInfo['mark_rate_products'] == '')?'n/a':price($marginInfo['mark_rate_products']).'%').'</td>';
-      print '</tr>';
-      print '<tr class="pair">';
-      print '<td>'.$langs->trans('MarginOnServices').'</td>';
-      print '<td align="right">'.price($marginInfo['pv_services']).'</td>';
-      print '<td align="right">'.price($marginInfo['pa_services']).'</td>';
-      print '<td align="right">'.price($marginInfo['margin_on_services']).'</td>';
-      if (! empty($conf->global->DISPLAY_MARGIN_RATES))
-        print '<td align="right">'.(($marginInfo['margin_rate_services'] == '')?'n/a':price($marginInfo['margin_rate_services']).'%').'</td>';
-      if (! empty($conf->global->DISPLAY_MARK_RATES))
-        print '<td align="right">'.(($marginInfo['mark_rate_services'] == '')?'n/a':price($marginInfo['mark_rate_services']).'%').'</td>';
-      print '</tr>';
-    //}
-    print '<tr class="impair">';
-    print '<td>'.$langs->trans('TotalMargin').'</td>';
-    print '<td align="right">'.price($marginInfo['pv_total']).'</td>';
-    print '<td align="right">'.price($marginInfo['pa_total']).'</td>';
-    print '<td align="right">'.price($marginInfo['total_margin']).'</td>';
-    if (! empty($conf->global->DISPLAY_MARGIN_RATES))
-      print '<td align="right">'.(($marginInfo['total_margin_rate'] == '')?'n/a':price($marginInfo['total_margin_rate']).'%').'</td>';
-    if (! empty($conf->global->DISPLAY_MARK_RATES))
-      print '<td align="right">'.(($marginInfo['total_mark_rate'] == '')?'n/a':price($marginInfo['total_mark_rate']).'%').'</td>';
-    print '</tr>';
-    print '</table>';
-  }
-}
+		$marginInfos['margin_on_products'] = $marginInfos['pv_products'] - $marginInfos['pa_products'];
+		if ($marginInfos['pa_products'] > 0)
+			$marginInfos['margin_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pa_products'],5);
+		if ($marginInfos['pv_products'] > 0)
+			$marginInfos['mark_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pv_products'],5);
+
+		$marginInfos['margin_on_services'] = $marginInfos['pv_services'] - $marginInfos['pa_services'];
+		if ($marginInfos['pa_services'] > 0)
+			$marginInfos['margin_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pa_services'],5);
+		if ($marginInfos['pv_services'] > 0)
+			$marginInfos['mark_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pv_services'],5);
+
+		$marginInfos['total_margin'] = $marginInfos['pv_total'] - $marginInfos['pa_total'];
+		if ($marginInfos['pa_total'] > 0)
+			$marginInfos['total_margin_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pa_total'],5);
+		if ($marginInfos['pv_total'] > 0)
+			$marginInfos['total_mark_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pv_total'],5);
+
+		return $marginInfos;
+	}
+
+	/**
+	 *
+	 * @param string $force_price
+	 */
+	function displayMarginInfos($force_price=false) {
+		global $langs, $conf;
+
+		$marginInfo = $this->getMarginInfos($force_price);
+
+		print '<table class="noborder" width="100%">';
+		print '<tr class="liste_titre">';
+		print '<td width="30%">'.$langs->trans('Margins').'</td>';
+		print '<td width="20%" align="right">'.$langs->trans('SellingPrice').'</td>';
+		if ($conf->global->MARGIN_TYPE == "1")
+			print '<td width="20%" align="right">'.$langs->trans('BuyingPrice').'</td>';
+		else
+			print '<td width="20%" align="right">'.$langs->trans('CostPrice').'</td>';
+		print '<td width="20%" align="right">'.$langs->trans('Margin').'</td>';
+		if (! empty($conf->global->DISPLAY_MARGIN_RATES))
+			print '<td align="right">'.$langs->trans('MarginRate').'</td>';
+		if (! empty($conf->global->DISPLAY_MARK_RATES))
+			print '<td align="right">'.$langs->trans('MarkRate').'</td>';
+		print '</tr>';
+		//if ($marginInfo['margin_on_products'] != 0 && $marginInfo['margin_on_services'] != 0) {
+		print '<tr class="impair">';
+		print '<td>'.$langs->trans('MarginOnProducts').'</td>';
+		print '<td align="right">'.price($marginInfo['pv_products']).'</td>';
+		print '<td align="right">'.price($marginInfo['pa_products']).'</td>';
+		print '<td align="right">'.price($marginInfo['margin_on_products']).'</td>';
+		if (! empty($conf->global->DISPLAY_MARGIN_RATES))
+			print '<td align="right">'.(($marginInfo['margin_rate_products'] == '')?'n/a':price($marginInfo['margin_rate_products']).'%').'</td>';
+		if (! empty($conf->global->DISPLAY_MARK_RATES))
+			print '<td align="right">'.(($marginInfo['mark_rate_products'] == '')?'n/a':price($marginInfo['mark_rate_products']).'%').'</td>';
+		print '</tr>';
+		print '<tr class="pair">';
+		print '<td>'.$langs->trans('MarginOnServices').'</td>';
+		print '<td align="right">'.price($marginInfo['pv_services']).'</td>';
+		print '<td align="right">'.price($marginInfo['pa_services']).'</td>';
+		print '<td align="right">'.price($marginInfo['margin_on_services']).'</td>';
+		if (! empty($conf->global->DISPLAY_MARGIN_RATES))
+			print '<td align="right">'.(($marginInfo['margin_rate_services'] == '')?'n/a':price($marginInfo['margin_rate_services']).'%').'</td>';
+		if (! empty($conf->global->DISPLAY_MARK_RATES))
+			print '<td align="right">'.(($marginInfo['mark_rate_services'] == '')?'n/a':price($marginInfo['mark_rate_services']).'%').'</td>';
+		print '</tr>';
+		//}
+		print '<tr class="impair">';
+		print '<td>'.$langs->trans('TotalMargin').'</td>';
+		print '<td align="right">'.price($marginInfo['pv_total']).'</td>';
+		print '<td align="right">'.price($marginInfo['pa_total']).'</td>';
+		print '<td align="right">'.price($marginInfo['total_margin']).'</td>';
+		if (! empty($conf->global->DISPLAY_MARGIN_RATES))
+			print '<td align="right">'.(($marginInfo['total_margin_rate'] == '')?'n/a':price($marginInfo['total_margin_rate']).'%').'</td>';
+		if (! empty($conf->global->DISPLAY_MARK_RATES))
+			print '<td align="right">'.(($marginInfo['total_mark_rate'] == '')?'n/a':price($marginInfo['total_mark_rate']).'%').'</td>';
+		print '</tr>';
+		print '</table>';
+	}
 
+}
 ?>
diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php
index aae14dba217382083fa8118a7ed19d224385acb3..e2986615ddea536818433d5f273a46afe9276836 100755
--- a/htdocs/core/class/extrafields.class.php
+++ b/htdocs/core/class/extrafields.class.php
@@ -1,34 +1,34 @@
 <?php
 /* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  * Copyright (C) 2002-2003 Jean-Louis Bergamo   <jlb@j1b.org>
- * Copyright (C) 2004      Sebastien Di Cintio  <sdicintio@ressource-toi.org>
- * Copyright (C) 2004      Benoit Mortier	    <benoit.mortier@opensides.be>
- * Copyright (C) 2009-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2009-2012 Regis Houssin        <regis.houssin@capnetworks.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
+* Copyright (C) 2004      Sebastien Di Cintio  <sdicintio@ressource-toi.org>
+* Copyright (C) 2004      Benoit Mortier	    <benoit.mortier@opensides.be>
+* Copyright (C) 2009-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
+* Copyright (C) 2009-2012 Regis Houssin        <regis.houssin@capnetworks.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
 
 /**
  * 	\file 		htdocs/core/class/extrafields.class.php
- *	\ingroup    core
- *	\brief      File of class to manage extra fields
- */
+*	\ingroup    core
+*	\brief      File of class to manage extra fields
+*/
 
 /**
  *	Class to manage standard extra fields
- */
+*/
 class ExtraFields
 {
 	var $db;
@@ -53,27 +53,29 @@ class ExtraFields
 	var $errno;
 
 	static $type2label=array(
-		'varchar'=>'String',
-		'text'=>'TextLong',
-		'int'=>'Int',
-		'double'=>'Float',
-		'date'=>'Date',
-		'datetime'=>'DateAndTime',
-		'boolean'=>'Boolean',
-		'price'=>'ExtrafieldPrice',
-		'phone'=>'ExtrafieldPhone',
-		'mail'=>'ExtrafieldMail',
-		'select' => 'ExtrafieldSelect',
-		'separate' => 'ExtrafieldSeparator',
-		'checkbox' => 'ExtrafieldCheckBox',
-		'radio' => 'ExtrafieldRadio',
+	'varchar'=>'String',
+	'text'=>'TextLong',
+	'int'=>'Int',
+	'double'=>'Float',
+	'date'=>'Date',
+	'datetime'=>'DateAndTime',
+	'boolean'=>'Boolean',
+	'price'=>'ExtrafieldPrice',
+	'phone'=>'ExtrafieldPhone',
+	'mail'=>'ExtrafieldMail',
+	'select' => 'ExtrafieldSelect',
+	'sellist' => 'ExtrafieldSelectList',
+	'separate' => 'ExtrafieldSeparator',
+	'checkbox' => 'ExtrafieldCheckBox',
+	'radio' => 'ExtrafieldRadio',
+
 	);
 
 	/**
 	 *	Constructor
 	 *
 	 *  @param		DoliDB		$db      Database handler
-	 */
+	*/
 	function __construct($db)
 	{
 		$this->db = $db;
@@ -86,49 +88,49 @@ class ExtraFields
 		$this->attribute_required = array();
 	}
 
-    /**
-     *  Add a new extra field parameter
-     *
-     *  @param	string	$attrname           Code of attribute
-     *  @param  string	$label              label of attribute
-     *  @param  int		$type               Type of attribute ('int', 'text', 'varchar', 'date', 'datehour')
-     *  @param  int		$pos                Position of attribute
-     *  @param  int		$size               Size/length of attribute
-     *  @param  string	$elementtype        Element type ('member', 'product', 'company', ...)
-     *  @param	int		$unique				Is field unique or not
-     *  @param	int		$required			Is field required or not
-     *  @param	string	$default_value		Defaulted value
-     *  @param  array	$param				Params for field 
-     *  @return int      					<=0 if KO, >0 if OK
-     */
-    function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0,$default_value='', $param=0)
+	/**
+	 *  Add a new extra field parameter
+	 *
+	 *  @param	string	$attrname           Code of attribute
+	 *  @param  string	$label              label of attribute
+	 *  @param  int		$type               Type of attribute ('int', 'text', 'varchar', 'date', 'datehour')
+	 *  @param  int		$pos                Position of attribute
+	 *  @param  int		$size               Size/length of attribute
+	 *  @param  string	$elementtype        Element type ('member', 'product', 'company', ...)
+	 *  @param	int		$unique				Is field unique or not
+	 *  @param	int		$required			Is field required or not
+	 *  @param	string	$default_value		Defaulted value
+	 *  @param  array	$param				Params for field
+	 *  @return int      					<=0 if KO, >0 if OK
+	 */
+	function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0,$default_value='', $param=0)
 	{
-        if (empty($attrname)) return -1;
-        if (empty($label)) return -1;
-
-        // Create field into database except for separator type which is not stored in database
-        if ($type != 'separate')
-        {
-        	$result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value,$param);
-        }
-        $err1=$this->errno;
-        if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate')
-        {
-        	// Add declaration of field into table
-            $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param);
-            $err2=$this->errno;
-            if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS'))
-            {
-                $this->error='';
-                $this->errno=0;
-                return 1;
-            }
-            else return -2;
-        }
-        else
-        {
-            return -1;
-        }
+		if (empty($attrname)) return -1;
+		if (empty($label)) return -1;
+
+		// Create field into database except for separator type which is not stored in database
+		if ($type != 'separate')
+		{
+			$result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value,$param);
+		}
+		$err1=$this->errno;
+		if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate')
+		{
+			// Add declaration of field into table
+			$result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param);
+			$err2=$this->errno;
+			if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS'))
+			{
+				$this->error='';
+				$this->errno=0;
+				return 1;
+			}
+			else return -2;
+		}
+		else
+		{
+			return -1;
+		}
 	}
 
 	/**
@@ -138,22 +140,22 @@ class ExtraFields
 	 *	@param	string	$attrname			code of attribute
 	 *  @param	int		$type				Type of attribute ('int', 'text', 'varchar', 'date', 'datehour')
 	 *  @param	int		$length				Size/length of attribute
-     *  @param  string	$elementtype        Element type ('member', 'product', 'company', 'contact', ...)
-     *  @param	int		$unique				Is field unique or not
-     *  @param	int		$required			Is field required or not
-     *  @param  string  $default_value		Default value for field
-     *  @param  array	$param				Params for field  (ex for select list : array('options'=>array('value'=>'label of option'))
-     *  
-     *  @return int      	           		<=0 if KO, >0 if OK
+	 *  @param  string	$elementtype        Element type ('member', 'product', 'company', 'contact', ...)
+	 *  @param	int		$unique				Is field unique or not
+	 *  @param	int		$required			Is field required or not
+	 *  @param  string  $default_value		Default value for field
+	 *  @param  array	$param				Params for field  (ex for select list : array('options'=>array('value'=>'label of option'))
+	 *
+	 *  @return int      	           		<=0 if KO, >0 if OK
 	 */
 	private function create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='',$param='')
 	{
-        $table=$elementtype.'_extrafields';
-        
-        // Special case for not normalized table names
-        if ($elementtype == 'member')  $table='adherent_extrafields';
-        elseif ($elementtype == 'company') $table='societe_extrafields';
-        elseif ($elementtype == 'contact') $table='socpeople_extrafields';
+		$table=$elementtype.'_extrafields';
+
+		// Special case for not normalized table names
+		if ($elementtype == 'member')  $table='adherent_extrafields';
+		elseif ($elementtype == 'company') $table='societe_extrafields';
+		elseif ($elementtype == 'contact') $table='socpeople_extrafields';
 
 		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
 		{
@@ -169,7 +171,7 @@ class ExtraFields
 			}elseif($type=='mail') {
 				$typedb='varchar';
 				$lengthdb='128';
-			} elseif (($type=='select') || ($type=='radio') ||($type=='checkbox')){
+			} elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox')){
 				$typedb='text';
 				$lengthdb='';
 			} else {
@@ -177,12 +179,12 @@ class ExtraFields
 				$lengthdb=$length;
 			}
 			$field_desc = array(
-				'type'=>$typedb, 
-				'value'=>$lengthdb, 
-				'null'=>($required?'NOT NULL':'NULL'),
-				'default' => $default_value
+			'type'=>$typedb,
+			'value'=>$lengthdb,
+			'null'=>($required?'NOT NULL':'NULL'),
+			'default' => $default_value
 			);
-			
+
 			$result=$this->db->DDLAddField(MAIN_DB_PREFIX.$table, $attrname, $field_desc);
 			if ($result > 0)
 			{
@@ -215,9 +217,9 @@ class ExtraFields
 	 *  @param	int		$pos				Position of attribute
 	 *  @param	int		$size				Size/length of attribute
 	 *  @param  string	$elementtype        Element type ('member', 'product', 'company', ...)
-     *  @param	int		$unique				Is field unique or not
-     *  @param	int		$required			Is field required or not
-     *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
+	 *  @param	int		$unique				Is field unique or not
+	 *  @param	int		$required			Is field required or not
+	 *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
 	 *  @return	int							<=0 if KO, >0 if OK
 	 */
 	private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='')
@@ -227,7 +229,7 @@ class ExtraFields
 		// Clean parameters
 		if (empty($pos)) $pos=0;
 
-		
+
 		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
 		{
 			if(is_array($param) and count($param) > 0)
@@ -242,7 +244,7 @@ class ExtraFields
 			{
 				$params='';
 			}
-			
+
 			$sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(name, label, type, pos, size, entity, elementtype, fieldunique, fieldrequired, param)";
 			$sql.= " VALUES('".$attrname."',";
 			$sql.= " '".$this->db->escape($label)."',";
@@ -250,11 +252,11 @@ class ExtraFields
 			$sql.= " '".$pos."',";
 			$sql.= " '".$size."',";
 			$sql.= " ".$conf->entity.",";
-            $sql.= " '".$elementtype."',";
-            $sql.= " '".$unique."',";
-            $sql.= " '".$required."',";
-            $sql.= " '".$params."'";
-            $sql.=')';
+			$sql.= " '".$elementtype."',";
+			$sql.= " '".$unique."',";
+			$sql.= " '".$required."',";
+			$sql.= " '".$params."'";
+			$sql.=')';
 
 			dol_syslog(get_class($this)."::create_label sql=".$sql);
 			if ($this->db->query($sql))
@@ -279,16 +281,16 @@ class ExtraFields
 	 */
 	function delete($attrname, $elementtype='member')
 	{
-        $table=$elementtype.'_extrafields';
+		$table=$elementtype.'_extrafields';
 
-        // Special case for not normalized table names
-        if ($elementtype == 'member')  $table='adherent_extrafields';
-        elseif ($elementtype == 'company') $table='societe_extrafields';
-        elseif ($elementtype == 'contact') $table='socpeople_extrafields';
+		// Special case for not normalized table names
+		if ($elementtype == 'member')  $table='adherent_extrafields';
+		elseif ($elementtype == 'company') $table='societe_extrafields';
+		elseif ($elementtype == 'contact') $table='socpeople_extrafields';
 
 		if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
 		{
-		    $result=$this->db->DDLDropField(MAIN_DB_PREFIX.$table,$attrname);	// This also drop the unique key
+			$result=$this->db->DDLDropField(MAIN_DB_PREFIX.$table,$attrname);	// This also drop the unique key
 			if ($result < 0)
 			{
 				$this->error=$this->db->lasterror();
@@ -310,8 +312,8 @@ class ExtraFields
 	 *	Delete description of an optionnal attribute
 	 *
 	 *	@param	string	$attrname			Code of attribute to delete
-     *  @param  string	$elementtype        Element type ('member', 'product', 'company', ...)
-     *  @return int              			< 0 if KO, 0 if nothing is done, 1 if OK
+	 *  @param  string	$elementtype        Element type ('member', 'product', 'company', ...)
+	 *  @return int              			< 0 if KO, 0 if nothing is done, 1 if OK
 	 */
 	private function delete_label($attrname, $elementtype='member')
 	{
@@ -322,7 +324,7 @@ class ExtraFields
 			$sql = "DELETE FROM ".MAIN_DB_PREFIX."extrafields";
 			$sql.= " WHERE name = '".$attrname."'";
 			$sql.= " AND entity = ".$conf->entity;
-            $sql.= " AND elementtype = '".$elementtype."'";
+			$sql.= " AND elementtype = '".$elementtype."'";
 
 			dol_syslog(get_class($this)."::delete_label sql=".$sql);
 			$resql=$this->db->query($sql);
@@ -350,22 +352,22 @@ class ExtraFields
 	 *  @param	string	$label				Label of attribute
 	 *  @param	string	$type				Type of attribute
 	 *  @param	int		$length				Length of attribute
-     *  @param  string	$elementtype        Element type ('member', 'product', 'company', 'contact', ...)
-     *  @param	int		$unique				Is field unique or not
-     *  @param	int		$required			Is field required or not
-     *  @param	int		$pos				Position of attribute
-     *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
+	 *  @param  string	$elementtype        Element type ('member', 'product', 'company', 'contact', ...)
+	 *  @param	int		$unique				Is field unique or not
+	 *  @param	int		$required			Is field required or not
+	 *  @param	int		$pos				Position of attribute
+	 *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
 	 * 	@return	int							>0 if OK, <=0 if KO
 	 */
 	function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='')
 	{
-        $table=$elementtype.'_extrafields';
-        // Special case for not normalized table names
-        if ($elementtype == 'member')  $table='adherent_extrafields';
-        elseif ($elementtype == 'company') $table='societe_extrafields';
-        elseif ($elementtype == 'contact') $table='socpeople_extrafields';
+		$table=$elementtype.'_extrafields';
+		// Special case for not normalized table names
+		if ($elementtype == 'member')  $table='adherent_extrafields';
+		elseif ($elementtype == 'company') $table='societe_extrafields';
+		elseif ($elementtype == 'contact') $table='socpeople_extrafields';
 
-        if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
+		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
 		{
 			if ($type=='boolean') {
 				$typedb='int';
@@ -379,7 +381,7 @@ class ExtraFields
 			}elseif($type=='mail') {
 				$typedb='varchar';
 				$lengthdb='128';
-			} elseif (($type=='select') || ($type=='radio') ||($type=='checkbox')) {
+			} elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox')) {
 				$typedb='text';
 				$lengthdb='';
 			} else {
@@ -387,7 +389,7 @@ class ExtraFields
 				$lengthdb=$length;
 			}
 			$field_desc = array('type'=>$typedb, 'value'=>$lengthdb, 'null'=>($required?'NOT NULL':'NULL'));
-			
+
 			if ($type != 'separate') // No table update when separate type
 			{
 				$result=$this->db->DDLUpdateField(MAIN_DB_PREFIX.$table, $attrname, $field_desc);
@@ -437,15 +439,15 @@ class ExtraFields
 	 *
 	 *  @param	string	$attrname			Name of attribute
 	 *  @param	string	$label				Label of attribute
-     *  @param  string	$type               Type of attribute
-     *  @param  int		$size		        Length of attribute
-     *  @param  string	$elementtype		Element type ('member', 'product', 'company', ...)
-     *  @param	int		$unique				Is field unique or not
-     *  @param	int		$required			Is field required or not
-     *  @param	int		$pos				Position of attribute
-     *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
-     *  @return	int							<=0 if KO, >0 if OK
-     */
+	 *  @param  string	$type               Type of attribute
+	 *  @param  int		$size		        Length of attribute
+	 *  @param  string	$elementtype		Element type ('member', 'product', 'company', ...)
+	 *  @param	int		$unique				Is field unique or not
+	 *  @param	int		$required			Is field required or not
+	 *  @param	int		$pos				Position of attribute
+	 *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
+	 *  @return	int							<=0 if KO, >0 if OK
+	 */
 	private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='')
 	{
 		global $conf;
@@ -454,12 +456,12 @@ class ExtraFields
 		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
 		{
 			$this->db->begin();
-			
+
 			if(is_array($param) && count($param) > 0)
 			{
 				$param = serialize($param);
 			}
-				
+
 			$sql_del = "DELETE FROM ".MAIN_DB_PREFIX."extrafields";
 			$sql_del.= " WHERE name = '".$attrname."'";
 			$sql_del.= " AND entity = ".$conf->entity;
@@ -484,12 +486,12 @@ class ExtraFields
 			$sql.= " '".$this->db->escape($label)."',";
 			$sql.= " '".$type."',";
 			$sql.= " '".$size."',";
-            $sql.= " '".$elementtype."',";
-            $sql.= " '".$unique."',";
-            $sql.= " '".$required."',";
-            $sql.= " '".$pos."',";
-            $sql.= " '".$param."'";
-            $sql.= ")";
+			$sql.= " '".$elementtype."',";
+			$sql.= " '".$unique."',";
+			$sql.= " '".$required."',";
+			$sql.= " '".$pos."',";
+			$sql.= " '".$param."'";
+			$sql.= ")";
 			dol_syslog(get_class($this)."::update_label sql=".$sql);
 			$resql2=$this->db->query($sql);
 
@@ -555,7 +557,7 @@ class ExtraFields
 			{
 				while ($tab = $this->db->fetch_object($resql))
 				{
-					
+
 					// we can add this attribute to adherent object
 					if ($tab->type != 'separate')
 					{
@@ -565,11 +567,11 @@ class ExtraFields
 					$this->attribute_type[$tab->name]=$tab->type;
 					$this->attribute_label[$tab->name]=$tab->label;
 					$this->attribute_size[$tab->name]=$tab->size;
-                    $this->attribute_elementtype[$tab->name]=$tab->elementtype;
-                    $this->attribute_unique[$tab->name]=$tab->fieldunique;
-                    $this->attribute_required[$tab->name]=$tab->fieldrequired;
-                    $this->attribute_param[$tab->name]=unserialize($tab->param);
-                    $this->attribute_pos[$tab->name]=$tab->pos;
+					$this->attribute_elementtype[$tab->name]=$tab->elementtype;
+					$this->attribute_unique[$tab->name]=$tab->fieldunique;
+					$this->attribute_required[$tab->name]=$tab->fieldrequired;
+					$this->attribute_param[$tab->name]=unserialize($tab->param);
+					$this->attribute_pos[$tab->name]=$tab->pos;
 				}
 			}
 			return $array_name_label;
@@ -593,268 +595,332 @@ class ExtraFields
 	{
 		global $conf,$langs;
 
-        $label=$this->attribute_label[$key];
-	    $type =$this->attribute_type[$key];
-        $size =$this->attribute_size[$key];
-        $elementtype=$this->attribute_elementtype[$key];
-        $unique=$this->attribute_unique[$key];
-        $required=$this->attribute_required[$key];
-        $param=$this->attribute_param[$key];
-        if ($type == 'date')
-        {
-            $showsize=10;
-        }
-        elseif ($type == 'datetime')
-        {
-            $showsize=19;
-        }
-        elseif (in_array($type,array('int','double')))
-        {
-            $showsize=10;
-        }
-        else
-        {
-            $showsize=round($size);
-            if ($showsize > 48) $showsize=48;
-        }
+		$label=$this->attribute_label[$key];
+		$type =$this->attribute_type[$key];
+		$size =$this->attribute_size[$key];
+		$elementtype=$this->attribute_elementtype[$key];
+		$unique=$this->attribute_unique[$key];
+		$required=$this->attribute_required[$key];
+		$param=$this->attribute_param[$key];
+		if ($type == 'date')
+		{
+			$showsize=10;
+		}
+		elseif ($type == 'datetime')
+		{
+			$showsize=19;
+		}
+		elseif (in_array($type,array('int','double')))
+		{
+			$showsize=10;
+		}
+		else
+		{
+			$showsize=round($size);
+			if ($showsize > 48) $showsize=48;
+		}
 
 		if (in_array($type,array('date','datetime')))
-        {
-        	$tmp=explode(',',$size);
-        	$newsize=$tmp[0];
-        	if(!class_exists('Form'))
-        		require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
-        	$formstat = new Form($db);
-        	
-        	$showtime = in_array($type,array('datetime')) ? 1 : 0;
-        	// Do not show current date when field not required (see select_date() method)
-        	if(!$required && $value == '')
-        		$value = '-1';
-        	
-        	$out = $formstat->select_date($value, 'options_'.$key, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1);
-        	//$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$newsize.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
-        }
-        elseif (in_array($type,array('int','double')))
-        {
-        	$tmp=explode(',',$size);
-        	$newsize=$tmp[0];
-        	$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$newsize.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
-        }
-        elseif ($type == 'varchar')
-        {
-        	$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$size.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
-        }
-        elseif ($type == 'text')
-        {
-        	require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-        	$doleditor=new DolEditor('options_'.$key,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100);
-        	$out=$doleditor->Create(1);
-        }
-        elseif ($type == 'boolean')
-        {
-        	$checked='';
-        	if (!empty($value)) {
-        		$checked=' checked="checked" value="1" ';
-        	} else {
-        		$checked=' value="1" ';
-        	}
-        	$out='<input type="checkbox" name="options_'.$key.'" '.$checked.' '.($moreparam?$moreparam:'').'>';
-        }
-        elseif ($type == 'mail')
-        {
-        	$out='<input type="text" name="options_'.$key.'" size="32" value="'.$value.'">';
-        }
-        elseif ($type == 'phone')
-        {
-        	$out='<input type="text" name="options_'.$key.'"  size="20" value="'.$value.'">';
-        }
-        elseif ($type == 'price')
-        {
-        	$out='<input type="text" name="options_'.$key.'"  size="6" value="'.price($value).'"> '.$langs->getCurrencySymbol($conf->currency);
-        }
-        elseif ($type == 'select')
-        {
-        	$out='<select name="options_'.$key.'">';
-        	foreach ($param['options'] as $key=>$val )
-        	{
-        		$out.='<option value="'.$key.'"';
-        		$out.= ($value==$key?'selected="selected"':'');
-        		$out.='>'.$val.'</option>';
-        	}
-        	$out.='</select>';
-        }
-        elseif ($type == 'checkbox')
-        {
-        	$out='';
-        	$value_arr=explode(',',$value);
-
-        	foreach ($param['options'] as $keyopt=>$val )
-        	{
-        		
-        		$out.='<input type="checkbox" name="options_'.$key.'[]"';
-        		$out.=' value="'.$keyopt.'"';
-        		
-        		if ((is_array($value_arr)) && in_array($keyopt,$value_arr)) {
-        			$out.= 'checked="checked"';
-        		}else {
-        			$out.='';
-        		}
-        		
-        		$out.='/>'.$val.'<br>';
-        	}
-        }
-        elseif ($type == 'radio')
-        {
-        	$out='';
-        	foreach ($param['options'] as $keyopt=>$val )
-        	{
-        		$out.='<input type="radio" name="options_'.$key.'"';
-        		$out.=' value="'.$keyopt.'"';
-        		$out.= ($value==$keyopt?'checked="checked"':'');
-        		$out.='/>'.$val.'<br>';
-        	}
-        }
-        /* Add comments
-	    if ($type == 'date') $out.=' (YYYY-MM-DD)';
-        elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
-        */
-	    return $out;
+		{
+			$tmp=explode(',',$size);
+			$newsize=$tmp[0];
+			if(!class_exists('Form'))
+				require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
+			$formstat = new Form($db);
+
+			$showtime = in_array($type,array('datetime')) ? 1 : 0;
+			// Do not show current date when field not required (see select_date() method)
+			if(!$required && $value == '')
+				$value = '-1';
+
+			$out = $formstat->select_date($value, 'options_'.$key, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1);
+			//$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$newsize.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
+		}
+		elseif (in_array($type,array('int','double')))
+		{
+			$tmp=explode(',',$size);
+			$newsize=$tmp[0];
+			$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$newsize.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
+		}
+		elseif ($type == 'varchar')
+		{
+			$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$size.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
+		}
+		elseif ($type == 'text')
+		{
+			require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
+			$doleditor=new DolEditor('options_'.$key,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100);
+			$out=$doleditor->Create(1);
+		}
+		elseif ($type == 'boolean')
+		{
+			$checked='';
+			if (!empty($value)) {
+				$checked=' checked="checked" value="1" ';
+			} else {
+				$checked=' value="1" ';
+			}
+			$out='<input type="checkbox" name="options_'.$key.'" '.$checked.' '.($moreparam?$moreparam:'').'>';
+		}
+		elseif ($type == 'mail')
+		{
+			$out='<input type="text" name="options_'.$key.'" size="32" value="'.$value.'">';
+		}
+		elseif ($type == 'phone')
+		{
+			$out='<input type="text" name="options_'.$key.'"  size="20" value="'.$value.'">';
+		}
+		elseif ($type == 'price')
+		{
+			$out='<input type="text" name="options_'.$key.'"  size="6" value="'.price($value).'"> '.$langs->getCurrencySymbol($conf->currency);
+		}
+		elseif ($type == 'select')
+		{
+			$out='<select name="options_'.$key.'">';
+			foreach ($param['options'] as $key=>$val )
+			{
+				$out.='<option value="'.$key.'"';
+				$out.= ($value==$key?'selected="selected"':'');
+				$out.='>'.$val.'</option>';
+			}
+			$out.='</select>';
+		}
+		elseif ($type == 'sellist')
+		{
+			$out='<select name="options_'.$key.'">';
+
+			$InfoFieldList = explode(":", $param);
+
+			// 0 1 : tableName
+			// 1 2 : label field name Nom du champ contenant le libelle
+			// 2 3 : key fields name (if differ of rowid)
+
+			$keyList='rowid';
+
+			if (count($InfoFieldList)==3)
+				$keyList=$InfoFieldList[2].' as rowid';
+
+			$sql = 'SELECT '.$keyList.', '.$InfoFieldList[1];
+			$sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0];
+
+			$resql = $this->db->query($sql);
+
+			if ($resql)
+			{
+				$out.='<option value="0">&nbsp;</option>';
+				$num = $this->db->num_rows($resql);
+				$i = 0;
+				if ($num)
+				{
+					while ($i < $num)
+					{
+						$obj = $this->db->fetch_object($resql);
+						$labeltoshow=dol_trunc($obj->$InfoFieldList[1],18);
+						if ($value==$obj->rowid)
+						{
+							$out.='<option value="'.$obj->rowid.'" selected="selected">'.$labeltoshow.'</option>';
+						}
+						else
+						{
+							$out.='<option value="'.$obj->rowid.'" >'.$labeltoshow.'</option>';
+						}
+						$i++;
+					}
+				}
+				$this->db->free();
+			}
+			$out.='</select>';
+		}
+		elseif ($type == 'checkbox')
+		{
+			$out='';
+			$value_arr=explode(',',$value);
+
+			foreach ($param['options'] as $keyopt=>$val )
+			{
+
+				$out.='<input type="checkbox" name="options_'.$key.'[]"';
+				$out.=' value="'.$keyopt.'"';
+
+				if ((is_array($value_arr)) && in_array($keyopt,$value_arr)) {
+					$out.= 'checked="checked"';
+				}else {
+					$out.='';
+				}
+
+				$out.='/>'.$val.'<br>';
+			}
+		}
+		elseif ($type == 'radio')
+		{
+			$out='';
+			foreach ($param['options'] as $keyopt=>$val )
+			{
+				$out.='<input type="radio" name="options_'.$key.'"';
+				$out.=' value="'.$keyopt.'"';
+				$out.= ($value==$keyopt?'checked="checked"':'');
+				$out.='/>'.$val.'<br>';
+			}
+		}
+		/* Add comments
+		 if ($type == 'date') $out.=' (YYYY-MM-DD)';
+		elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
+		*/
+		return $out;
 	}
 
-    /**
-     * Return HTML string to put an output field into a page
-     *
-     * @param   string	$key            Key of attribute
-     * @param   string	$value          Value to show
-     * @param	string	$moreparam		More param
-     * @return	string					Formated value
-     */
-    function showOutputField($key,$value,$moreparam='')
-    {
+	/**
+	 * Return HTML string to put an output field into a page
+	 *
+	 * @param   string	$key            Key of attribute
+	 * @param   string	$value          Value to show
+	 * @param	string	$moreparam		More param
+	 * @return	string					Formated value
+	 */
+	function showOutputField($key,$value,$moreparam='')
+	{
 		global $conf,$langs;
 
-        $label=$this->attribute_label[$key];
-        $type=$this->attribute_type[$key];
-        $size=$this->attribute_size[$key];
-        $elementtype=$this->attribute_elementtype[$key];
-        $unique=$this->attribute_unique[$key];
-        $required=$this->attribute_required[$key];
-        $params=$this->attribute_param[$key];
-        if ($type == 'date')
-        {
-            $showsize=10;
-            $value=dol_print_date($value,'day');
-        }
-        elseif ($type == 'datetime')
-        {
-            $showsize=19;
-            $value=dol_print_date($value,'dayhour');
-        }
-        elseif ($type == 'int')
-        {
-            $showsize=10;
-        }
-        elseif ($type == 'boolean')
-        {
-        	$checked='';
-        	if (!empty($value)) {
-        		$checked=' checked="checked" ';
-        	}
-        	$value='<input type="checkbox" '.$checked.' '.($moreparam?$moreparam:'').' readonly="readonly">';
-        }
-        elseif ($type == 'mail')
-        {
-        	$value=dol_print_email($value);
-        }
-        elseif ($type == 'phone')
-        {
-        	$value=dol_print_phone($value);
-        }
-        elseif ($type == 'price')
-        {
-        	$value=price($value).' '.$langs->getCurrencySymbol($conf->currency);
-        }
-        elseif ($type == 'select')
-        {
-        	$value=$params['options'][$value];
-        }
-        elseif ($type == 'radio')
-        {
-        	$value=$params['options'][$value];
-        }
-        elseif ($type == 'checkbox')
-        {
-        	$value_arr=explode(',',$value);
-        	$value='';
-        	if (is_array($value_arr)) 
-        	{
-	        	foreach ($value_arr as $keyval=>$valueval) {
-	        		$value.=$params['options'][$valueval].'<br>';
-	        	}
-        	}
-        }
-        else
-        {
-            $showsize=round($size);
-            if ($showsize > 48) $showsize=48;
-        }
-        //print $type.'-'.$size;
-        $out=$value;
-        return $out;
-    }
-
-    /**
-     * Return HTML string to print separator extrafield
-     * 
-     * @param   string	$key            Key of attribute
-     * @return string
-     */
-    function showSeparator($key) 
-    {
-    	$out = '<tr class="liste_titre"><td colspan="4"><strong>'.$this->attribute_label[$key].'</strong></td></tr>';
-    	return $out;
-    }
-    
-    /**
-     * Fill array_options array for object by extrafields value (using for data send by forms)
-     *
-     * @param   array	$extralabels    $array of extrafields
-     * @param   object	&$object         object
-     * @return	int						1 if array_options set / 0 if no value
-     */
-    function setOptionalsFromPost($extralabels,&$object)
-    {
-    	global $_POST;
-    	
-    	if (is_array($extralabels))
-    	{
-	    	// Get extra fields
-	    	foreach ($extralabels as $key => $value)
-	    	{
-	    		$key_type = $this->attribute_type[$key];
-	    	
-	    		if (in_array($key_type,array('date','datetime')))
-	    		{
-	    			// Clean parameters
-	    			$value_key=dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]);
-	    		}
-	    		else if (in_array($key_type,array('checkbox')))
-	    		{
-	    			$value_arr=GETPOST("options_".$key);
-	    			$value_key=implode($value_arr,',');
-	    		}
-	    		else 
-	    		{
-	    			$value_key=GETPOST("options_".$key);
-	    		}
-	    		$object->array_options["options_".$key]=$value_key;
-	    	}
-    	
-    		return 1;
-    	}
-    	else {
-    		return 0;
-    	}
-    }
+		$label=$this->attribute_label[$key];
+		$type=$this->attribute_type[$key];
+		$size=$this->attribute_size[$key];
+		$elementtype=$this->attribute_elementtype[$key];
+		$unique=$this->attribute_unique[$key];
+		$required=$this->attribute_required[$key];
+		$params=$this->attribute_param[$key];
+		if ($type == 'date')
+		{
+			$showsize=10;
+			$value=dol_print_date($value,'day');
+		}
+		elseif ($type == 'datetime')
+		{
+			$showsize=19;
+			$value=dol_print_date($value,'dayhour');
+		}
+		elseif ($type == 'int')
+		{
+			$showsize=10;
+		}
+		elseif ($type == 'boolean')
+		{
+			$checked='';
+			if (!empty($value)) {
+				$checked=' checked="checked" ';
+			}
+			$value='<input type="checkbox" '.$checked.' '.($moreparam?$moreparam:'').' readonly="readonly">';
+		}
+		elseif ($type == 'mail')
+		{
+			$value=dol_print_email($value);
+		}
+		elseif ($type == 'phone')
+		{
+			$value=dol_print_phone($value);
+		}
+		elseif ($type == 'price')
+		{
+			$value=price($value).' '.$langs->getCurrencySymbol($conf->currency);
+		}
+		elseif ($type == 'select')
+		{
+			$value=$params['options'][$value];
+		}
+		elseif ($type == 'sellist')
+		{
+			$InfoFieldList = explode(":", $params);
+			$keyList='rowid';
+			if (count($InfoFieldList)==3)
+				$keyList=$InfoFieldList[2];
+
+			$sql = 'SELECT '.$InfoFieldList[1];
+			$sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0];
+			$sql.= ' where '.$keyList.'="'.$value.'"';
+
+			$resql = $this->db->query($sql);
+			if ($resql)
+			{
+				$obj = $this->db->fetch_object($resql);
+				$value=$obj->$InfoFieldList[1];
+			}
+		}
+		elseif ($type == 'radio')
+		{
+			$value=$params['options'][$value];
+		}
+		elseif ($type == 'checkbox')
+		{
+			$value_arr=explode(',',$value);
+			$value='';
+			if (is_array($value_arr))
+			{
+				foreach ($value_arr as $keyval=>$valueval) {
+					$value.=$params['options'][$valueval].'<br>';
+				}
+			}
+		}
+		else
+		{
+			$showsize=round($size);
+			if ($showsize > 48) $showsize=48;
+		}
+		//print $type.'-'.$size;
+		$out=$value;
+		return $out;
+	}
+
+	/**
+	 * Return HTML string to print separator extrafield
+	 *
+	 * @param   string	$key            Key of attribute
+	 * @return string
+	 */
+	function showSeparator($key)
+	{
+		$out = '<tr class="liste_titre"><td colspan="4"><strong>'.$this->attribute_label[$key].'</strong></td></tr>';
+		return $out;
+	}
+
+	/**
+	 * Fill array_options array for object by extrafields value (using for data send by forms)
+	 *
+	 * @param   array	$extralabels    $array of extrafields
+	 * @param   object	&$object         object
+	 * @return	int						1 if array_options set / 0 if no value
+	 */
+	function setOptionalsFromPost($extralabels,&$object)
+	{
+		global $_POST;
+			
+		if (is_array($extralabels))
+		{
+			// Get extra fields
+			foreach ($extralabels as $key => $value)
+			{
+				$key_type = $this->attribute_type[$key];
+
+				if (in_array($key_type,array('date','datetime')))
+				{
+					// Clean parameters
+					$value_key=dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]);
+				}
+				else if (in_array($key_type,array('checkbox')))
+				{
+					$value_arr=GETPOST("options_".$key);
+					$value_key=implode($value_arr,',');
+				}
+				else
+				{
+					$value_key=GETPOST("options_".$key);
+				}
+				$object->array_options["options_".$key]=$value_key;
+			}
+
+			return 1;
+		}
+		else {
+			return 0;
+		}
+	}
 }
 ?>
diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php
index 0284872cb92857002e8e884a5df8cc183addf164..6deb0161c2a178cbca10cdabcaf78dc9e38bb494 100755
--- a/htdocs/core/class/hookmanager.class.php
+++ b/htdocs/core/class/hookmanager.class.php
@@ -144,7 +144,6 @@ class HookManager
                 foreach($modules as $module => $actionclassinstance)
                 {
                 	//print 'class='.get_class($actionclassinstance).' method='.$method.' action='.$action;
-
                 	// jump to next class if method does not exists
                     if (! method_exists($actionclassinstance,$method)) continue;
                 	// test to avoid to run twice a hook, when a module implements several active contexts
@@ -178,7 +177,7 @@ class HookManager
 
                     	$result = $actionclassinstance->$method($parameters, $object, $action, $this); // $object and $action can be changed by method ($object->id during creation for example or $action to go back to other action for example)
 
-                    	if (is_array($actionclassinstance->results))  $this->resArray =array_merge($this->resArray, $actionclassinstance->results);
+                    	if (! empty($actionclassinstance->results) && is_array($actionclassinstance->results)) $this->resArray =array_merge($this->resArray, $actionclassinstance->results);
                     	if (! empty($actionclassinstance->resprints)) $this->resPrint.=$actionclassinstance->resprints;
 
                     	// TODO. remove this. array result must be set into $actionclassinstance->results
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index ae60706f5237db3325247977958258759abbb563..976585728312013b65bc155f6bb0d0f8677842ce 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -344,7 +344,7 @@ class Form
      *	Show a text and picto with tooltip on text or picto
      *
      *	@param	string		$text				Text to show
-     *	@param	string		$htmltext			Content html of tooltip. Must be HTML/UTF8 encoded.
+     *	@param	string		$htmltext			HTML content of tooltip. Must be HTML/UTF8 encoded.
      *	@param	int			$tooltipon			1=tooltip sur texte, 2=tooltip sur picto, 3=tooltip sur les 2
      *	@param	int			$direction			-1=Le picto est avant, 0=pas de picto, 1=le picto est apres
      *	@param	string		$img				Code img du picto (use img_xxx() function to get it)
@@ -383,7 +383,7 @@ class Form
         //if ($text != '')	$s.='<'.$tag.$paramfortooltiptd.'>'.(($direction < 0)?'&nbsp;':'').$text.(($direction > 0)?'&nbsp;':'').'</'.$tag.'>';
         $paramfortooltiptd.= (($direction < 0)?' style="padding-left: 3px !important;"':'');
         $paramfortooltiptd.= (($direction > 0)?' style="padding-right: 3px !important;"':'');
-        if ($text != '')	$s.='<'.$tag.$paramfortooltiptd.'>'.$text.'</'.$tag.'>';
+        if ((string) $text != '')	$s.='<'.$tag.$paramfortooltiptd.'>'.$text.'</'.$tag.'>';
         if ($direction > 0)	$s.='<'.$tag.$paramfortooltipimg.' valign="top" width="14">'.$img.'</'.$tag.'>';
         if (empty($notabs))	$s.='</tr></table>';
 
@@ -3333,7 +3333,7 @@ class Form
                 if (strval($set_time) != '' && $set_time != -1)
                 {
                     //$formated_date=dol_print_date($set_time,$conf->format_date_short);
-                    $formated_date=dol_print_date($set_time,$langs->trans("FormatDateShort"));  // FormatDateShort for dol_print_date/FormatDateShortJava that is same for javascript
+                    $formated_date=dol_print_date($set_time,$langs->trans("FormatDateShortInput"));  // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
                 }
 
                 // Calendrier popup version eldy
@@ -3342,7 +3342,7 @@ class Form
                     // Zone de saisie manuelle de la date
                     $retstring.='<input id="'.$prefix.'" name="'.$prefix.'" type="text" size="9" maxlength="11" value="'.$formated_date.'"';
                     $retstring.=($disabled?' disabled="disabled"':'');
-                    $retstring.=' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJava").'\'); "';  // FormatDateShort for dol_print_date/FormatDateShortJava that is same for javascript
+                    $retstring.=' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\'); "';  // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
                     $retstring.='>';
 
                     // Icone calendrier
@@ -3350,7 +3350,7 @@ class Form
                     {
                         $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons"';
                         $base=DOL_URL_ROOT.'/core/';
-                        $retstring.=' onClick="showDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJava").'\',\''.$langs->defaultlang.'\');">'.img_object($langs->trans("SelectDate"),'calendarday','class="datecallink"').'</button>';
+                        $retstring.=' onClick="showDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');">'.img_object($langs->trans("SelectDate"),'calendarday','class="datecallink"').'</button>';
                     }
                     else $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons">'.img_object($langs->trans("Disabled"),'calendarday','class="datecallink"').'</button>';
 
@@ -3359,7 +3359,7 @@ class Form
                     $retstring.='<input type="hidden" id="'.$prefix.'year"  name="'.$prefix.'year"  value="'.$syear.'">'."\n";
                 }
                 else
-              {
+                {
                     print "Bad value of MAIN_POPUP_CALENDAR";
                 }
             }
@@ -3453,7 +3453,7 @@ class Form
             if ($usecalendar == "eldy")
             {
                 $base=DOL_URL_ROOT.'/core/';
-                $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJava").'\',\''.$langs->defaultlang.'\');';
+                $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');';
             }
             else
             {
diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php
index 827a65ed51f7cabbafcbefec1c7983ec01d74b81..b7477c203f56d060c57541daa5f04baf1cdb985c 100644
--- a/htdocs/core/class/html.formactions.class.php
+++ b/htdocs/core/class/html.formactions.class.php
@@ -209,10 +209,10 @@ class FormActions
     /**
      *  Output list of type of event
      *
-     *  @param	string		$selected       Type pre-selectionne
+     *  @param	string		$selected       Type pre-selected (can be 'manual', 'auto' or 'AC_xxx'
      *  @param  string		$htmlname       Nom champ formulaire
      *  @param	string		$excludetype	Type to exclude
-     *  @param	string		$onlyautoornot	Group list by auto events or not
+     *  @param	string		$onlyautoornot	Group list by auto events or not: We keep only the 2 generic lines (AC_OTH and AC_OTH_AUTO)
      * 	@return	void
      */
     function select_type_actions($selected='',$htmlname='actioncode',$excludetype='',$onlyautoornot=0)
@@ -224,11 +224,14 @@ class FormActions
         $caction=new CActionComm($this->db);
         $form=new Form($this->db);
 
-       	// Suggest a list with manual event or all auto events
+       	// Suggest a list with manual events or all auto events
        	$arraylist=$caction->liste_array(1, 'code', $excludetype, $onlyautoornot);
        	array_unshift($arraylist,'&nbsp;');     // Add empty line at start
        	//asort($arraylist);
 
+       	if ($selected == 'manual') $selected='AC_OTH';
+       	if ($selected == 'auto')   $selected='AC_OTH_AUTO';
+       	
         print $form->selectarray($htmlname, $arraylist, $selected);
         if ($user->admin && empty($onlyautoornot)) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionnarySetup"),1);
     }
diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
index 71541ab4a5db01c3178bd4ec1acda5b7d7091837..699977c05ff5feb88ebef119cdf7ce402f076ec7 100644
--- a/htdocs/core/class/html.formfile.class.php
+++ b/htdocs/core/class/html.formfile.class.php
@@ -480,10 +480,10 @@ class FormFile
 
 					// Show file name with link to download
 					$out.= '<td nowrap="nowrap">';
-					$out.= '<a href="'.DOL_URL_ROOT . '/document.php?modulepart='.$modulepart.'&amp;file='.urlencode($relativepath).'"';
+					$out.= '<a data-ajax="false" href="'.DOL_URL_ROOT . '/document.php?modulepart='.$modulepart.'&amp;file='.urlencode($relativepath).'"';
 					$mime=dol_mimetype($relativepath,'',0);
 					if (preg_match('/text/',$mime)) $out.= ' target="_blank"';
-					$out.= '>';
+					$out.= ' target="_blank">';
 					$out.= img_mime($file["name"],$langs->trans("File").': '.$file["name"]).' '.dol_trunc($file["name"],$maxfilenamelength);
 					$out.= '</a>'."\n";
 					$out.= '</td>';
@@ -575,7 +575,7 @@ class FormFile
     			}
 
     			// Show file name with link to download
-    			$out.= '<a href="'.DOL_URL_ROOT . '/document.php?modulepart='.$modulepart.'&amp;file='.urlencode($relativepath).'"';
+    			$out.= '<a data-ajax="false" href="'.DOL_URL_ROOT . '/document.php?modulepart='.$modulepart.'&amp;file='.urlencode($relativepath).'"';
     			$mime=dol_mimetype($relativepath,'',0);
     			if (preg_match('/text/',$mime)) $out.= ' target="_blank"';
     			$out.= '>';
@@ -669,7 +669,7 @@ class FormFile
 					print '<tr '.$bc[$var].'>';
 					print '<td>';
 					//print "XX".$file['name'];	//$file['name'] must be utf8
-					print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
+					print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
 					if ($forcedownload) print '&attachment=1';
 					if (! empty($object->entity)) print '&entity='.$object->entity;
 					print '&file='.urlencode($relativepath.$file['name']).'">';
@@ -855,7 +855,7 @@ class FormFile
                 print '</td>';
                 print '<td>';
                 //print "XX".$file['name']; //$file['name'] must be utf8
-                print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
+                print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
                 if ($forcedownload) print '&attachment=1';
                 print '&file='.urlencode($relativefile).'">';
                 print img_mime($file['name'],$file['name'].' ('.dol_print_size($file['size'],0,0).')').' ';
@@ -865,7 +865,7 @@ class FormFile
                 print '<td align="right">'.dol_print_size($file['size'],1,1).'</td>';
                 print '<td align="center">'.dol_print_date($file['date'],"dayhour").'</td>';
                 print '<td align="right">';
-                if (! empty($useinecm))  print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
+                if (! empty($useinecm))  print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
                 if ($forcedownload) print '&attachment=1';
                 print '&file='.urlencode($relativefile).'">';
                 print img_view().'</a> &nbsp; ';
diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php
index 3de291bbe76f2334b71cbe58baa6a253c917eec9..a0d63e42b4a22a3ed58e0ed0e531406ea1ef50a8 100644
--- a/htdocs/core/class/html.formother.class.php
+++ b/htdocs/core/class/html.formother.class.php
@@ -893,9 +893,34 @@ class FormOther
             $selectboxlist=$form->selectarray('boxcombo', $arrayboxtoactivatelabel,'',1);
         }
 
+        // Javascript code for dynamic actions
         if (! empty($conf->use_javascript_ajax))
         {
 	        print '<script type="text/javascript" language="javascript">
+	        
+	        // To update list of activated boxes
+	        function updateBoxOrder(closing) {
+	        	var left_list = cleanSerialize(jQuery("#left").sortable("serialize"));
+	        	var right_list = cleanSerialize(jQuery("#right").sortable("serialize"));
+	        	var boxorder = \'A:\' + left_list + \'-B:\' + right_list;
+	        	if (boxorder==\'A:A-B:B\' && closing == 1)	// There is no more boxes on screen, and we are after a delete of a box so we must hide title
+	        	{
+	        		jQuery.ajax({
+	        			url: \''.DOL_URL_ROOT.'/core/ajax/box.php?boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.',
+	        			async: false
+	        		});
+	        		// We force reload to be sure to get all boxes into list
+	        		window.location.search=\'mainmenu='.GETPOST("mainmenu").'&leftmenu='.GETPOST('leftmenu').'&action=delbox\';
+	        	}
+	        	else
+	        	{
+	        		jQuery.ajax({
+	        			url: \''.DOL_URL_ROOT.'/core/ajax/box.php?boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.',
+	        			async: true
+	        		});
+	        	}
+	        }
+	        
 	        jQuery(document).ready(function() {
 	        	jQuery("#boxcombo").change(function() {
 	        	var boxid=jQuery("#boxcombo").val();
@@ -910,10 +935,33 @@ class FormOther
 	        			window.location.search=\'mainmenu='.GETPOST("mainmenu").'&leftmenu='.GETPOST('leftmenu').'&action=addbox&boxid=\'+boxid;
 	                }
 	        	});';
-	        if (! count($arrayboxtoactivatelabel)) print 'jQuery("#boxcombo").hide();';
-	        print  '
-	    	});
-	        </script>';
+	        	if (! count($arrayboxtoactivatelabel)) print 'jQuery("#boxcombo").hide();';
+	        	print  '
+	    	
+	        	jQuery("#left, #right").sortable({
+		        	/* placeholder: \'ui-state-highlight\', */
+	    	    	handle: \'.boxhandle\',
+	    	    	revert: \'invalid\',
+	       			items: \'.box\',
+	        		containment: \'.fiche\',
+	        		connectWith: \'.connectedSortable\',
+	        		stop: function(event, ui) {
+	        			updateBoxOrder(0);
+	        		}
+	    		});
+
+	        	jQuery(".boxclose").click(function() {
+	        		var self = this;	// because JQuery can modify this
+	        		var boxid=self.id.substring(8);
+	        		var label=jQuery(\'#boxlabelentry\'+boxid).val();
+	        		jQuery(\'#boxto_\'+boxid).remove();
+	        		// TODO Add id, label into combo list
+	        		updateBoxOrder(1);
+	        	});
+	        
+        	});'."\n";
+	        
+	        print '</script>'."\n";
         }
 
         $nbboxactivated=count($boxidactivatedforuser);
@@ -996,59 +1044,6 @@ class FormOther
 
             print "</td></tr>";
             print "</table>";
-
-            if ($conf->use_javascript_ajax)
-            {
-                print "\n";
-                print '<script type="text/javascript" language="javascript">';
-                // For moving
-                print 'jQuery(function() {
-                            jQuery("#left, #right").sortable({
-                                /* placeholder: \'ui-state-highlight\', */
-                                handle: \'.boxhandle\',
-                                revert: \'invalid\',
-                                items: \'.box\',
-                                containment: \'.fiche\',
-                                connectWith: \'.connectedSortable\',
-                                stop: function(event, ui) {
-                                    updateBoxOrder(0);
-                                }
-                            });
-                        });
-                '."\n";
-                // To update list of activated boxes
-                print 'function updateBoxOrder(closing) {
-	                		var left_list = cleanSerialize(jQuery("#left").sortable("serialize"));
-	                		var right_list = cleanSerialize(jQuery("#right").sortable("serialize"));
-	                		var boxorder = \'A:\' + left_list + \'-B:\' + right_list;
-	    					if (boxorder==\'A:A-B:B\' && closing == 1)	// There is no more boxes on screen, and we are after a delete of a box so we must hide title
-	    					{
-		    					jQuery.ajax({
-		    						url: \''.DOL_URL_ROOT.'/core/ajax/box.php?boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.',
-		    						async: false
-		    					});
-	    						// We force reload to be sure to get all boxes into list
-			        			window.location.search=\'mainmenu='.GETPOST("mainmenu").'&leftmenu='.GETPOST('leftmenu').'&action=delbox\';
-	    					}
-	    					else
-	    					{
-	    						jQuery.ajax({
-		    						url: \''.DOL_URL_ROOT.'/core/ajax/box.php?boxorder=\'+boxorder+\'&zone='.$areacode.'&userid=\'+'.$user->id.',
-		    						async: true
-		    					});
-	    					}
-                		}'."\n";
-                // For closing
-                print 'jQuery(document).ready(function() {
-                          	jQuery(".boxclose").click(function() {
-                          		var self = this;	// because JQuery can modify this
-                              	var boxid=self.id.substring(8);
-                                jQuery(\'#boxto_\'+boxid).remove();
-                                updateBoxOrder(1);
-                           	});
-                       });'."\n";
-                print '</script>'."\n";
-            }
         }
 
         return count($boxactivated);
diff --git a/htdocs/core/datepicker.php b/htdocs/core/datepicker.php
index 76b8dbb4b7914055bccf280c13962bed4985b3ec..a976eb83f01a9bacd8ec57a9c564db54b2405e56 100644
--- a/htdocs/core/datepicker.php
+++ b/htdocs/core/datepicker.php
@@ -224,16 +224,16 @@ function displayBox($selectedDate,$month,$year)
 		if($thedate==$selDate) $dayclass="dpSelected";
 		elseif($thedate==$today) $dayclass="dpToday";
 
-		if ($langs->trans("FormatDateShortJava")=="FormatDateShortJava")
+		if ($langs->trans("FormatDateShortJavaInput")=="FormatDateShortJavaInput")
 		{
-		    print "ERROR FormatDateShortJava not defined for language ".$langs->defaultlang;
+		    print "ERROR FormatDateShortJavaInput not defined for language ".$langs->defaultlang;
 		    exit;
 		}
 
 		// Sur click dans calendrier, appelle fonction dpClickDay
 		echo "<TD class=\"".$dayclass."\"";
 		echo " onMouseOver=\"dpHighlightDay(".$mydate["year"].",parseInt('".dol_print_date($thedate,"%m")."',10),".$mydate["mday"].",tradMonths)\"";
-		echo " onClick=\"dpClickDay(".$mydate["year"].",parseInt('".dol_print_date($thedate,"%m")."',10),".$mydate["mday"].",'".$langs->trans("FormatDateShortJava")."')\"";
+		echo " onClick=\"dpClickDay(".$mydate["year"].",parseInt('".dol_print_date($thedate,"%m")."',10),".$mydate["mday"].",'".$langs->trans("FormatDateShortJavaInput")."')\"";
 		echo ">".sprintf("%02s",$mydate["mday"])."</TD>";
 		$cols++;
 
diff --git a/htdocs/core/get_menudiv.php b/htdocs/core/get_menudiv.php
index 0d9e3c0a54bccb5fbc25de4875a5fd90982e9404..51bda89ffd02bb1f7534af83aad0f0340d850ad5 100644
--- a/htdocs/core/get_menudiv.php
+++ b/htdocs/core/get_menudiv.php
@@ -40,11 +40,6 @@ $langs->load("main");
 $right=($langs->trans("DIRECTION")=='rtl'?'left':'right');
 $left=($langs->trans("DIRECTION")=='rtl'?'right':'left');
 
-//var_dump($langs->defaultlang);
-//var_dump($conf->format_date_short_java);
-//var_dump($langs->trans("FormatDateShortJava"));
-
-
 
 /*
  * View
diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php
index 531ea49eb96676d2f2ca038c57e07067c7c7924e..a11fdac4dda7011a6aa4ef18a0d6afbafe15a58f 100644
--- a/htdocs/core/lib/agenda.lib.php
+++ b/htdocs/core/lib/agenda.lib.php
@@ -40,9 +40,10 @@
  * @param 	int		$pid			Product id
  * @param 	int		$socid			Third party id
  * @param	array	$showextcals	Array with list of external calendars, or -1 to show no legend
+ * @param	string	$actioncode		Preselected value of actioncode for filter on type
  * @return	void
  */
-function print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$showextcals=array())
+function print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$showextcals=array(),$actioncode='')
 {
 	global $conf,$user,$langs,$db;
 
@@ -94,8 +95,7 @@ function print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirt
 				print $langs->trans("Type");
 				print ' &nbsp;</td><td nowrap="nowrap">';
 
-				// print $formactions->select_type_actions(GETPOST('actioncode'), "actioncode");
-				print $formactions->select_type_actions(GETPOST('actioncode')?GETPOST('actioncode'):'manual', "actioncode", '', (empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:0));
+				print $formactions->select_type_actions($actioncode, "actioncode", '', (empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:0));
 
 				print '</td></tr>';
 			}
@@ -384,6 +384,11 @@ function agenda_prepare_head()
 	$head[$h][2] = 'extsites';
 	$h++;
 
+	$head[$h][0] = DOL_URL_ROOT."/admin/agenda_other.php";
+	$head[$h][1] = $langs->trans("Other");
+	$head[$h][2] = 'other';
+	$h++;
+
 	complete_head_from_modules($conf,$langs,$object,$head,$h,'agenda_admin');
 
 	$head[$h][0] = DOL_URL_ROOT."/admin/agenda_extrafields.php";
diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php
index d01c045625005aaa679c3897337477e845826515..695b6deb2c118cced96d6b8191d570e3acba422c 100644
--- a/htdocs/core/lib/company.lib.php
+++ b/htdocs/core/lib/company.lib.php
@@ -47,7 +47,7 @@ function societe_prepare_head($object)
     {
         $head[$h][0] = DOL_URL_ROOT.'/comm/fiche.php?socid='.$object->id;
         if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && ($object->client==2 || $object->client==3)) $head[$h][1] = $langs->trans("Prospect");
-        if ($object->client==3)                       $head[$h][1] .= '/';
+        if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && $object->client==3) $head[$h][1] .= '/';
         if (empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && ($object->client==1 || $object->client==3)) $head[$h][1] .= $langs->trans("Customer");
         $head[$h][2] = 'customer';
         $h++;
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 7ea8087613ea75046f5dbd9c70d1a9a2bd4f641b..b2c2998a4624262f92f36714545c0c6af9c65bc7 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -814,13 +814,14 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e
 	}
 	if (! is_object($outputlangs)) $outputlangs=$langs;
 	if (! $format) $format='daytextshort';
-
+	$reduceformat=(! empty($conf->dol_optimize_smallscreen) && in_array($format,array('day','hour')))?1:0;
+	
 	// Change predefined format into computer format. If found translation in lang file we use it, otherwise we use default.
-	if ($format == 'day')					 $format=($outputlangs->trans("FormatDateShort")!="FormatDateShort"?$outputlangs->trans("FormatDateShort"):$conf->format_date_short);
-	else if ($format == 'hour')			 $format=($outputlangs->trans("FormatHourShort")!="FormatHourShort"?$outputlangs->trans("FormatHourShort"):$conf->format_hour_short);
-	else if ($format == 'hourduration')	 $format=($outputlangs->trans("FormatHourShortDuration")!="FormatHourShortDuration"?$outputlangs->trans("FormatHourShortDuration"):$conf->format_hour_short_duration);
+	if ($format == 'day')				$format=($outputlangs->trans("FormatDateShort")!="FormatDateShort"?$outputlangs->trans("FormatDateShort"):$conf->format_date_short);
+	else if ($format == 'hour')			$format=($outputlangs->trans("FormatHourShort")!="FormatHourShort"?$outputlangs->trans("FormatHourShort"):$conf->format_hour_short);
+	else if ($format == 'hourduration')	$format=($outputlangs->trans("FormatHourShortDuration")!="FormatHourShortDuration"?$outputlangs->trans("FormatHourShortDuration"):$conf->format_hour_short_duration);
 	else if ($format == 'daytext')			 $format=($outputlangs->trans("FormatDateText")!="FormatDateText"?$outputlangs->trans("FormatDateText"):$conf->format_date_text);
-	else if ($format == 'daytextshort')	 $format=($outputlangs->trans("FormatDateTextShort")!="FormatDateTextShort"?$outputlangs->trans("FormatDateTextShort"):$conf->format_date_text_short);
+	else if ($format == 'daytextshort')	$format=($outputlangs->trans("FormatDateTextShort")!="FormatDateTextShort"?$outputlangs->trans("FormatDateTextShort"):$conf->format_date_text_short);
 	else if ($format == 'dayhour')			 $format=($outputlangs->trans("FormatDateHourShort")!="FormatDateHourShort"?$outputlangs->trans("FormatDateHourShort"):$conf->format_date_hour_short);
 	else if ($format == 'dayhoursec')		 $format=($outputlangs->trans("FormatDateHourSecShort")!="FormatDateHourSecShort"?$outputlangs->trans("FormatDateHourSecShort"):$conf->format_date_hour_sec_short);
 	else if ($format == 'dayhourtext')		 $format=($outputlangs->trans("FormatDateHourText")!="FormatDateHourText"?$outputlangs->trans("FormatDateHourText"):$conf->format_date_hour_text);
@@ -828,12 +829,18 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e
 	// Format not sensitive to language
 	else if ($format == 'dayhourlog')		 $format='%Y%m%d%H%M%S';
 	else if ($format == 'dayhourldap')		 $format='%Y%m%d%H%M%SZ';
-	else if ($format == 'dayhourxcard')	 $format='%Y%m%dT%H%M%SZ';
-	else if ($format == 'dayxcard')	 	 $format='%Y%m%d';
+	else if ($format == 'dayhourxcard')	$format='%Y%m%dT%H%M%SZ';
+	else if ($format == 'dayxcard')	 	$format='%Y%m%d';
 	else if ($format == 'dayrfc')			 $format='%Y-%m-%d';             // DATE_RFC3339
 	else if ($format == 'dayhourrfc')		 $format='%Y-%m-%dT%H:%M:%SZ';   // DATETIME RFC3339
-	else if ($format == 'standard')		 $format='%Y-%m-%d %H:%M:%S';
+	else if ($format == 'standard')		$format='%Y-%m-%d %H:%M:%S';
 
+	if ($reduceformat)
+	{
+		$format=str_replace('%Y','%y',$format);
+		$format=str_replace('yyyy','yy',$format);
+	}
+	
 	// If date undefined or "", we return ""
 	if (dol_strlen($time) == 0) return '';		// $time=0 allowed (it means 01/01/1970 00:00:00)
 
@@ -1072,9 +1079,11 @@ function dol_now($mode='gmt')
  */
 function dol_print_size($size,$shortvalue=0,$shortunit=0)
 {
-	global $langs;
+	global $conf,$langs;
 	$level=1024;
-
+	
+	if (! empty($conf->dol_optimize_smallscreen)) $shortunit=1;
+	
 	// Set value text
 	if (empty($shortvalue) || $size < ($level*10))
 	{
@@ -2846,7 +2855,7 @@ function getLocalTaxesFromRate($vatrate, $local, $thirdparty)
 	dol_syslog("getLocalTaxesFromRate vatrate=".$vatrate." local=".$local." thirdparty id=".(is_object($thirdparty)?$thirdparty->id:''));
 
 	// Search local taxes
-	$sql  = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type";
+	$sql  = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type,t.accountancy_code_sell,t.accountancy_code_buy";
 	$sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_pays as p";
 	$sql .= " WHERE t.fk_pays = p.rowid AND p.code = '".$thirdparty->country_code."'";
 	$sql .= " AND t.taux = ".$vatrate." AND t.active = 1";
@@ -2855,9 +2864,9 @@ function getLocalTaxesFromRate($vatrate, $local, $thirdparty)
 	if ($resql)
 	{
 		$obj = $db->fetch_object($resql);
-		if ($local == 1) return array($obj->localtax1_type, $obj->localtax1);
-		elseif ($local == 2) return array($obj->localtax2_type, $obj->localtax2);
-		else return array($obj->localtax1_type, $obj->localtax1, $obj->localtax2_type, $obj->localtax2);
+		if ($local == 1) return array($obj->localtax1_type, $obj->localtax1,$obj->accountancy_code_sell,$obj->accountancy_code_buy);
+		elseif ($local == 2) return array($obj->localtax2_type, $obj->localtax2,$obj->accountancy_code_sell,$obj->accountancy_code_buy);
+		else return array($obj->localtax1_type, $obj->localtax1, $obj->localtax2_type, $obj->localtax2,$obj->accountancy_code_sell,$obj->accountancy_code_buy);
 	}
 
 	return 0;
@@ -3105,12 +3114,16 @@ function get_default_npr($thirdparty_seller, $thirdparty_buyer, $idprod=0, $idpr
 
 	if ($idprodfournprice > 0)
 	{
+		if (! class_exists('ProductFournisseur'))
+			require DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.product.class.php';
 		$prodprice = new ProductFournisseur($db);
 		$prodprice->fetch_product_fournisseur_price($idprodfournprice);
 		return $prodprice->fourn_tva_npr;
 	}
 	elseif ($idprod > 0)
 	{
+		if (! class_exists('Product'))
+			require DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
 		$prod = new Product($db);
 		$prod->fetch($idprod);
 		return $prod->tva_npr;
diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php
index 059400d73997a938f2aab6cc7c8076925337c027..dc6c57002c9ad24af3ca7c9d33ecacd7b80c9051 100644
--- a/htdocs/core/lib/functions2.lib.php
+++ b/htdocs/core/lib/functions2.lib.php
@@ -1283,7 +1283,7 @@ function getListOfModels($db,$type,$maxfilenamelength=0)
                     if (! $tmpdir) { unset($listofdir[$key]); continue; }
                     if (is_dir($tmpdir))
                     {
-                        $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt','','name',SORT_ASC,0,true); // Disable hook for the moment
+                        $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.od(s|t)$','','name',SORT_ASC,0,true); // Disable hook for the moment
                         if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles);
                     }
                 }
diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php
index b9f12ca3f6c6e43c32d83b6b4a16f133b102382a..10099ab7feb7e8c6e1c559f7434324e22c04d02d 100644
--- a/htdocs/core/lib/usergroups.lib.php
+++ b/htdocs/core/lib/usergroups.lib.php
@@ -78,14 +78,15 @@ function user_prepare_head($object)
 	    $head[$h][2] = 'clicktodial';
         $h++;
     }
-
+    
     // Show more tabs from modules
     // Entries must be declared in modules descriptor with line
     // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
     // $this->tabs = array('entity:-tabname);   												to remove a tab
     complete_head_from_modules($conf,$langs,$object,$head,$h,'user');
-
-    if (! empty($user->societe_id))
+	
+    //Info on users is visible only by internal user
+    if (empty($user->societe_id))
     {
     	$head[$h][0] = DOL_URL_ROOT.'/user/note.php?id='.$object->id;
     	$head[$h][1] = $langs->trans("Note");
diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php
index 641925f42a915f523f263529db6b0959411d926d..f4d7f3581db4d20fed86faba2746cfb351f803dc 100644
--- a/htdocs/core/menus/standard/eldy.lib.php
+++ b/htdocs/core/menus/standard/eldy.lib.php
@@ -852,6 +852,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
 				*/
 				if (empty($leftmenu) || $leftmenu=="ca") $newmenu->add("/compta/stats/casoc.php?leftmenu=ca",$langs->trans("ByCompanies"),2,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire);
 				if (empty($leftmenu) || $leftmenu=="ca") $newmenu->add("/compta/stats/cabyuser.php?leftmenu=ca",$langs->trans("ByUsers"),2,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire);
+				if (empty($leftmenu) || $leftmenu=="ca") $newmenu->add("/compta/stats/cabyprodserv.php?leftmenu=ca", $langs->trans("ByProductsAndServices"),2,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire);
+
 
 				// Journaux
 				//if ($leftmenu=="ca") $newmenu->add("/compta/journaux/index.php?leftmenu=ca",$langs->trans("Journaux"),1,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire);
diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
index 00658b7b9cb2d9d3f2866760c4917ea91065b082..3330f491e707eba441008f61e19e312027d326e3 100644
--- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
+++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
@@ -519,8 +519,12 @@ class doc_generic_order_odt extends ModelePDFCommandes
 				$reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
 
 				// Write new file
-				//$result=$odfHandler->exportAsAttachedFile('toto');
-				$odfHandler->saveToDisk($file);
+				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
+					$odfHandler->exportAsAttachedPDF($file);
+				}
+				else {
+					$odfHandler->saveToDisk($file);
+				}	
 
 				if (! empty($conf->global->MAIN_UMASK))
 					@chmod($file, octdec($conf->global->MAIN_UMASK));
diff --git a/htdocs/core/modules/expedition/methode_expedition.modules.php b/htdocs/core/modules/expedition/methode_expedition.modules.php
deleted file mode 100644
index 3ea7ba97ce9935fa2be06f97a6a40dd6d57a8959..0000000000000000000000000000000000000000
--- a/htdocs/core/modules/expedition/methode_expedition.modules.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2007 Laurent Destailleur  <eldy@users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- * or see http://www.gnu.org/
- */
-
-/**
- *	\file       htdocs/core/modules/expedition/methode_expedition.modules.php
- *	\ingroup    expedition
- *	\brief      Fichier contenant la classe mere de generation de bon de livraison en PDF
- *				et la classe mere de numerotation des bons de livraisons
- */
-require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
-
-
-/**
- *	Parent class for shipping method classes
- */
-class ModeleShippingMethod
-{
-    /**
-     * Constructo
-     *
-     * @param	DoliDB		$db		Database handler
-     */
-	function __construct($db)
-	{
-		$this->db = $db;
-		$this->name = "NOT DEFINED";
-		$this->description = "ERROR IN MODULE DESCRIPTION";
-	}
-
-
-	/**
-	 *  Return list of active generation modules
-	 *
-     *  @param	DoliDB	$db     			Database handler
-     *  @param  string	$maxfilenamelength  Max length of value to show
-     *  @return	array						List of templates
-	 */
-	static function liste_modeles($db,$maxfilenamelength=0)
-	{
-		global $conf;
-
-		$type='???';
-		$liste=array();
-
-		include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-		$liste=getListOfModels($db,$type,$maxfilenamelength);
-
-		return $liste;
-	}
-}
-
-?>
diff --git a/htdocs/core/modules/expedition/methode_expedition_colsui.modules.php b/htdocs/core/modules/expedition/methode_expedition_colsui.modules.php
deleted file mode 100644
index fca7ffc38ff09615863b009895b2a4df89f1efff..0000000000000000000000000000000000000000
--- a/htdocs/core/modules/expedition/methode_expedition_colsui.modules.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-/* Copyright (C) 2008 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2008 Bearstech - http://bearstech.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- *	\file       htdocs/core/modules/expedition/methode_expedition_colsui.modules.php
- *	\ingroup    expedition
- */
-include_once 'methode_expedition.modules.php';
-
-/**
- * Class to manage shipment Colsui
- */
-class methode_expedition_colsui extends ModeleShippingMethod
-{
-    /**
-     * Constructor
-     *
-     * @param	DoliDB		$db		Database handler
-     */
-	function __construct($db=0)
-	{
-		$this->db = $db;
-		$this->id = 3; // Do not change this value
-		$this->code = "COLSUI";  // Do not change this value
-		$this->name = "Colissimo Suivi";
-		$this->description = "Colissimo Suivi";
-	}
-
-	/**
-	 * Return URL of provider
-	 *
-	 * @param	string	$tracking_number	Tracking number
-	 * @return	string						URL for tracking
-	 */
-	function provider_url_status($tracking_number)
-	{
-		return sprintf("http://www.coliposte.net/particulier/suivi_particulier.jsp?colispart=%s",$tracking_number);
-	}
-}
-
-?>
diff --git a/htdocs/core/modules/expedition/methode_expedition_enl.modules.php b/htdocs/core/modules/expedition/methode_expedition_enl.modules.php
deleted file mode 100644
index 17e5cf35be9516104f7deca5a48500a1b2e8f0d7..0000000000000000000000000000000000000000
--- a/htdocs/core/modules/expedition/methode_expedition_enl.modules.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-/* Copyright (C) 2003-2008 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- *	\file       htdocs/core/modules/expedition/methode_expedition_enl.modules.php
- *	\ingroup    expedition
- */
-include_once 'methode_expedition.modules.php';
-
-
-/**
- * Class to manage shipment Enl
- */
-class methode_expedition_enl extends ModeleShippingMethod
-{
-    /**
-     * Constructor
-     *
-     * @param	DoliDB		$db		Database handler
-     */
-	function __construct($db=0)
-	{
-		global $langs;
-		$this->db = $db;
-		$this->id = 1; // Do not change this value
-		$this->name = "Enlevement";
-		$this->code = "ENL";
-		$this->description = $langs->trans("Enlevement");
-	}
-
-	/**
-	 * Return URL of provider
-	 *
-	 * @param	string	$tracking_number	Tracking number
-	 * @return	string						URL for tracking
-	 */
-	function provider_url_status($tracking_number)
-	{
-		return '';
-	}
-}
-
-?>
diff --git a/htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php b/htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php
deleted file mode 100644
index c8150af9497b796e53d6fe3db53c93b01554b5a2..0000000000000000000000000000000000000000
--- a/htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-/* Copyright (C) 2011 Regis Houssin  <regis.houssin@capnetworks.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- *	\file       htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php
- *	\ingroup    expedition
- */
-
-include_once 'methode_expedition.modules.php';
-
-
-/**
- * Class to manage shipment lettremax
- */
-class methode_expedition_lettremax extends ModeleShippingMethod
-{
-    /**
-     * Constructor
-     *
-     * @param	DoliDB		$db		Database handler
-     */
-	function __construct($db=0)
-	{
-		$this->db = $db;
-		$this->id = 4; // Do not change this value
-		$this->code = "LETTREMAX";  // Do not change this value
-		$this->name = "Lettre max";
-		$this->description = "Courrier suivi et lettre max";
-	}
-
-	/**
-	 * Return URL of provider
-	 *
-	 * @param	string	$tracking_number	Tracking number
-	 * @return	string						URL for tracking
-	 */
-	function provider_url_status($tracking_number)
-	{
-		return sprintf("http://www.csuivi.courrier.laposte.fr/default.asp?EZ_ACTION=rechercheRapide&numObjet=%s",$tracking_number);
-	}
-}
-
-?>
diff --git a/htdocs/core/modules/expedition/methode_expedition_trans.modules.php b/htdocs/core/modules/expedition/methode_expedition_trans.modules.php
deleted file mode 100644
index d974b7c161a1d7a0857f50e51a0a37c8e413cbb5..0000000000000000000000000000000000000000
--- a/htdocs/core/modules/expedition/methode_expedition_trans.modules.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-/* Copyright (C) 2003-2008 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- *	\file       htdocs/core/modules/expedition/methode_expedition_trans.modules.php
- *	\ingroup    expedition
- */
-include_once 'methode_expedition.modules.php';
-
-
-/**
- * Class to manage shipment Trans
- */
-class methode_expedition_trans extends ModeleShippingMethod
-{
-
-    /**
-     * Constructor
-     *
-     * @param	DoliDB		$db		Database handler
-     */
-	function __construct($db=0)
-	{
-		global $langs;
-
-		$this->db = $db;
-		$this->id = 2; // Ne pas changer cette valeur
-		$this->code = "TRANS";
-		$this->name = "Transporteur";
-		$this->description = $langs->trans("GenericTransport");
-	}
-
-	/**
-	 * Return URL of provider
-	 *
-	 * @param	string	$tracking_number	Tracking number
-	 * @return	string						URL for tracking
-	 */
-	function provider_url_status($tracking_number)
-	{
-		return '';
-	}
-}
-
-?>
diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
index 512bf98be8b4bbd4b006e665e9b8c2e3a1d1bdc4..8aa417c83c022b679d54af1ae0f7d169ba98d411 100644
--- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
+++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
@@ -497,8 +497,12 @@ class doc_generic_invoice_odt extends ModelePDFFactures
 				$reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
 
 				// Write new file
-				//$result=$odfHandler->exportAsAttachedFile('toto');
-				$odfHandler->saveToDisk($file);
+				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
+					$odfHandler->exportAsAttachedPDF($file);
+				}
+				else {
+					$odfHandler->saveToDisk($file);
+				}	
 
 				if (! empty($conf->global->MAIN_UMASK))
 					@chmod($file, octdec($conf->global->MAIN_UMASK));
diff --git a/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php b/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php
index c4a1150d505f398dca2649e36a412fa376b7d9f7..adf1b8689b158254eee1ffd0b63567f516e5527d 100644
--- a/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php
+++ b/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php
@@ -38,6 +38,22 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
  */
 class pdf_typhon extends ModelePDFDeliveryOrder
 {
+    var $db;
+    var $name;
+    var $description;
+    var $type;
+
+    var $phpmin = array(4,3,0); // Minimum version of PHP required by module
+    var $version = 'dolibarr';
+
+    var $page_largeur;
+    var $page_hauteur;
+    var $format;
+	var $marge_gauche;
+	var	$marge_droite;
+	var	$marge_haute;
+	var	$marge_basse;
+
 	var $emetteur;	// Objet societe qui emet
 
 	/**
@@ -75,26 +91,26 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 
 		$this->franchise=!$mysoc->tva_assuj;
 
-		// Recupere emmetteur
+		// Get source company
 		$this->emetteur=$mysoc;
-		if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2);    // By default if not defined
+		if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2);    // By default, if was not defined
 
-		// Defini position des colonnes
+		// Define position of columns
 		$this->posxdesc=$this->marge_gauche+1;
-		$this->posxcomm=120;
+		$this->posxcomm=111;
 		//$this->posxtva=111;
-		$this->posxup=132;
-		$this->posxqty=168;
-		$this->posxdiscount=162;
-		$this->postotalht=177;
+		//$this->posxup=126;
+		$this->posxqty=174;
+		//$this->posxdiscount=162;
+		//$this->postotalht=174;
 		if ($this->page_largeur < 210) // To work with US executive format
 		{
 			$this->posxcomm-=20;
 			//$this->posxtva-=20;
-			$this->posxup-=20;
+			//$this->posxup-=20;
 			$this->posxqty-=20;
-			$this->posxdiscount-=20;
-			$this->postotalht-=20;
+			//$this->posxdiscount-=20;
+			//$this->postotalht-=20;
 		}
 
 		$this->tva=array();
@@ -104,15 +120,19 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 
 
 	/**
-	 *	Fonction generant le bon de livraison sur le disque
-	 *
-	 *	@param	Object		$object   		Object livraison a generer
-	 *	@param	Translate	$outputlangs	Lang output object
-	 *	@return	int         				1 if OK, <=0 if KO
+     *  Function to build pdf onto disk
+     *
+     *  @param		Object		$object				Object to generate
+     *  @param		Translate	$outputlangs		Lang output object
+     *  @param		string		$srctemplatepath	Full path of source filename for generator using a template file
+     *  @param		int			$hidedetails		Do not show line details
+     *  @param		int			$hidedesc			Do not show desc
+     *  @param		int			$hideref			Do not show ref
+     *  @return     int             			1=OK, 0=KO
 	 */
-	function write_file($object,$outputlangs)
+	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
 	{
-		global $user,$langs,$conf;
+		global $user,$langs,$conf,$mysoc,$hookmanager;
 
 		if (! is_object($outputlangs)) $outputlangs=$langs;
 		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
@@ -126,17 +146,23 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 		$outputlangs->load("deliveries");
 		$outputlangs->load("sendings");
 
-		if ($conf->expedition->dir_output."/receipt")
+		if ($conf->expedition->dir_output)
 		{
 			$object->fetch_thirdparty();
 
-			$nblines = count($object->lines);
-
-			$objectref = dol_sanitizeFileName($object->ref);
-			$dir = $conf->expedition->dir_output."/receipt";
-			if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref;
-			$file = $dir . "/" . $objectref . ".pdf";
-
+			// Definition of $dir and $file
+			if ($object->specimen)
+			{
+				$dir = $conf->expedition->dir_output."/receipt";
+				$file = $dir . "/SPECIMEN.pdf";
+			}
+			else
+			{
+				$objectref = dol_sanitizeFileName($object->ref);
+				$dir = $conf->expedition->dir_output."/receipt/" . $objectref;
+				$file = $dir . "/" . $objectref . ".pdf";
+			}
+			
 			if (! file_exists($dir))
 			{
 				if (dol_mkdir($dir) < 0)
@@ -148,9 +174,12 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 
 			if (file_exists($dir))
 			{
-                $pdf=pdf_getInstance($this->format);
+				$nblines = count($object->lines);
+				
+				// Create pdf instance
+				$pdf=pdf_getInstance($this->format);
                 $default_font_size = pdf_getPDFFontSize($outputlangs);	// Must be after pdf_getInstance
-                $heightforinfotot = 50;	// Height reserved to output the info and total part
+                $heightforinfotot = 30;	// Height reserved to output the info and total part
 		        $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5);	// Height reserved to output the free text on last page
 	            $heightforfooter = $this->marge_basse + 8;	// Height reserved to output the footer (value include bottom margin)
                 $pdf->SetAutoPageBreak(1,0);
@@ -195,7 +224,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 
 				/*
 				 // Positionne $this->atleastonediscount si on a au moins une remise
-				 for ($i = 0 ; $i < $nblignes ; $i++)
+				 for ($i = 0 ; $i < $nblines ; $i++)
 				 {
 				 if ($object->lines[$i]->remise_percent)
 				 {
@@ -214,7 +243,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 				$pdf->SetTextColor(0,0,0);
 
 				$tab_top = 90;
-				$tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?22:10);
+				$tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42:10);
 				$tab_height = 130;
 				$tab_height_newpage = 150;
 
@@ -223,7 +252,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 				{
 					$tab_top = 88;
 
-					$pdf->SetFont('','', $default_font_size - 1);   // Dans boucle pour gerer multi-page
+					$pdf->SetFont('','', $default_font_size - 1);
 					$pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($object->note_public), 0, 1);
 					$nexY = $pdf->GetY();
 					$height_note=$nexY-$tab_top;
@@ -252,13 +281,46 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 					$pdf->SetTextColor(0,0,0);
 
 					$pdf->setTopMargin($tab_top_newpage);
-					$pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext);	// The only function to edit the bottom margin of current page to set it.
+					$pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
 					$pageposbefore=$pdf->getPage();
 
 					// Description of product line
 					$curX = $this->posxdesc-1;
-                    pdf_writelinedesc($pdf,$object,$i,$outputlangs,108,3,$curX,$curY);
 
+                    $showpricebeforepagebreak=1;
+                    
+                    $pdf->startTransaction();
+                    pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxcomm-$curX,3,$curX,$curY,$hideref,$hidedesc);
+                    $pageposafter=$pdf->getPage();
+                    if ($pageposafter > $pageposbefore)	// There is a pagebreak
+                    {
+                    	$pdf->rollbackTransaction(true);
+                    	$pageposafter=$pageposbefore;
+                    	//print $pageposafter.'-'.$pageposbefore;exit;
+                    	$pdf->setPageOrientation('', 1, $heightforfooter);	// The only function to edit the bottom margin of current page to set it.
+                    	pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxcomm-$curX,4,$curX,$curY,$hideref,$hidedesc);
+                    	$posyafter=$pdf->GetY();
+                    	if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot)))	// There is no space left for total+free text
+                    	{
+                    		if ($i == ($nblines-1))	// No more lines, and no space left to show total, so we create a new page
+                    		{
+                    			$pdf->AddPage('','',true);
+                    			if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+                    			if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+                    			$pdf->setPage($pagenb+1);
+                    		}
+                    	}
+                    	else
+                    	{
+                    		// We found a page break
+                    		$showpricebeforepagebreak=0;
+                    	}
+                    }
+                    else	// No pagebreak
+                    {
+                    	$pdf->commitTransaction();
+                    }
+                    
 					$nexY = $pdf->GetY();
                     $pageposafter=$pdf->getPage();
 					$pdf->setPage($pageposbefore);
@@ -266,17 +328,15 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
 
 					// We suppose that a too long description is moved completely on next page
-					if ($pageposafter > $pageposbefore) {
+					if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
 						$pdf->setPage($pageposafter); $curY = $tab_top_newpage;
 					}
 
 					$pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
 
-					$nexY = $pdf->GetY()+4;
-
 					/*
 					 // TVA
-					 $pdf->SetXY($this->posxtva, $curY);
+					 $pdf->SetXY($this->posxcomm, $curY);
 					 $pdf->MultiCell(10, 4, ($object->lines[$i]->tva_tx < 0 ? '*':'').abs($object->lines[$i]->tva_tx), 0, 'R');
 
 					 // Prix unitaire HT avant remise
@@ -284,8 +344,9 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 					 $pdf->MultiCell(20, 4, price($object->lines[$i]->subprice), 0, 'R', 0);
 					 */
 					// Quantity
+					//$qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
 					$pdf->SetXY($this->posxqty, $curY);
-					$pdf->MultiCell(30, 3, $object->lines[$i]->qty_shipped, 0, 'R');
+					$pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->posxqty, 3, $object->lines[$i]->qty_shipped, 0, 'R');
 					/*
 					 // Remise sur ligne
 					 $pdf->SetXY($this->posxdiscount, $curY);
@@ -307,7 +368,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 					 */
 
 					// Add line
-					if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1))
+					if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1))
 					{
 						$pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(210,210,210)));
 						//$pdf->SetDrawColor(190,190,200);
@@ -333,6 +394,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 						$pagenb++;
 						$pdf->setPage($pagenb);
 						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+						if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
 					}
 					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
 					{
@@ -349,34 +411,38 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 						$pdf->AddPage();
 						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
 						$pagenb++;
+						if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
 					}
 				}
 
 				// Show square
 				if ($pagenb == 1)
 				{
-					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0);
-					$bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfooter + 1;
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
 				}
 				else
 				{
-					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1);
-					$bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfooter + 1;
+					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
 				}
 
-				/*
-				 * Pied de page
-				 */
+				// Affiche zone infos
+				$posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
+				
+				// Pied de page
 				$this->_pagefoot($pdf,$object,$outputlangs);
-
+				$pdf->AliasNbPages();
+				
 				// Check product remaining to be delivered
 				// TODO doit etre modifie
 				//$waitingDelivery = $object->getRemainingDelivered();
+				/*
 				$waitingDelivery='';
 
 				if (is_array($waitingDelivery) & !empty($waitingDelivery))
 				{
-					$pdf->AddPage('P', 'A4');
+					$pdf->AddPage();
 
 					$this->_pagehead($pdf, $object, 1, $outputlangs);
 					$pdf-> SetY(90);
@@ -426,17 +492,28 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 
 					$this->_pagefoot($pdf,$object,$outputlangs);
 
-				}
-
-				$pdf->AliasNbPages();
+					$pdf->AliasNbPages();
+				}*/
 
 				$pdf->Close();
 
 				$pdf->Output($file,'F');
+
+				// Add pdfgeneration hook
+				if (! is_object($hookmanager))
+				{
+					include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
+					$hookmanager=new HookManager($this->db);
+				}
+				$hookmanager->initHooks(array('pdfgeneration'));
+				$parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
+				global $action;
+				$reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
+
 				if (! empty($conf->global->MAIN_UMASK))
-				@chmod($file, octdec($conf->global->MAIN_UMASK));
+					@chmod($file, octdec($conf->global->MAIN_UMASK));
 
-				return 1;
+				return 1;	// pas d'erreur
 			}
 			else
 			{
@@ -449,66 +526,90 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 		return 0;
 	}
 
-
+	/**
+	 *   Show miscellaneous information (payment mode, payment term, ...)
+	 *
+	 *   @param		PDF			&$pdf     		Object PDF
+	 *   @param		Object		$object			Object to show
+	 *   @param		int			$posy			Y
+	 *   @param		Translate	$outputlangs	Langs object
+	 *   @return	void
+	 */
+	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
+	{
+		global $conf;
+		$default_font_size = pdf_getPDFFontSize($outputlangs);
+	
+		$pdf->SetFont('','', $default_font_size);
+		$pdf->SetXY($this->marge_gauche, $posy);
+		
+		$larg_sign = ($this->page_largeur-$this->marge_gauche-$this->marge_droite)/3;
+		$pdf->Rect($this->marge_gauche, $posy + 1, $larg_sign, 25);
+		$pdf->SetXY($this->marge_gauche + 2, $posy + 2);
+		$pdf->MultiCell($larg_sign,2, $outputlangs->trans("For").' '.$outputlangs->convToOutputCharset($mysoc->name).":",'','L');
+		
+		$pdf->Rect(2*$larg_sign+$this->marge_gauche, $posy + 1, $larg_sign, 25);
+		$pdf->SetXY(2*$larg_sign+$this->marge_gauche + 2, $posy + 2);
+		$pdf->MultiCell($larg_sign,2, $outputlangs->trans("ForCustomer").':','','L');
+	}
+	
 	/**
 	 *   Show table for lines
 	 *
 	 *   @param		PDF			&$pdf     		Object PDF
 	 *   @param		string		$tab_top		Top position of table
 	 *   @param		string		$tab_height		Height of table (rectangle)
-	 *   @param		int			$nexY			Y
+	 *   @param		int			$nexY			Y (not used)
 	 *   @param		Translate	$outputlangs	Langs object
-	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidetop		1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
 	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
 	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf,$mysoc;
+		
+		// Force to disable hidetop and hidebottom
+		$hidebottom=0;
+		if ($hidetop) $hidetop=-1;
+		
 		$default_font_size = pdf_getPDFFontSize($outputlangs);
+		
+		// Amount in (at tab_top - 1)
+		$pdf->SetTextColor(0,0,0);
+		$pdf->SetFont('','', $default_font_size - 2);
 
-		$pdf->SetDrawColor(128,128,128);
+		// Output Rec
+		$this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom);	// Rect prend une longueur en 3eme param et 4eme param
 
-		// Rect prend une longueur en 3eme param
-		$pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height);
-		// line prend une position y en 3eme param
 		if (empty($hidetop))
+		{
 			$pdf->line($this->marge_gauche, $tab_top+6, $this->page_largeur-$this->marge_droite, $tab_top+6);
-
-		$pdf->SetTextColor(0,0,0);
+		}
+		
+		$pdf->SetDrawColor(128,128,128);
 		$pdf->SetFont('','', $default_font_size - 1);
 
-		if (empty($hidetop)) {
+		if (empty($hidetop)) 
+		{
 			$pdf->SetXY($this->posxdesc-1, $tab_top+1);
-			$pdf->MultiCell(80,2, $outputlangs->transnoentities("Designation"),'','L');
+			$pdf->MultiCell($this->posxcomm - $this->posxdesc,2, $outputlangs->transnoentities("Designation"),'','L');
 		}
 
 		// Modif SEB pour avoir une col en plus pour les commentaires clients
 		$pdf->line($this->posxcomm, $tab_top, $this->posxcomm, $tab_top + $tab_height);
 		if (empty($hidetop)) {
 			$pdf->SetXY($this->posxcomm, $tab_top+1);
-			$pdf->MultiCell(80,2, $outputlangs->transnoentities("Comments"),'','L');
+			$pdf->MultiCell($this->posxqty - $this->posxcomm,2, $outputlangs->transnoentities("Comments"),'','L');
 		}
 
 		// Qty
 		$pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height);
 		if (empty($hidetop)) {
 			$pdf->SetXY($this->posxqty-1, $tab_top+1);
-			$pdf->MultiCell(30, 2, $outputlangs->transnoentities("QtyShipped"),'','R');
+			$pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->posxqty, 2, $outputlangs->transnoentities("QtyShipped"),'','R');
 		}
 
-		if (empty($hidebottom)) {
-			// Modif Seb cadres signatures
-			$pdf->SetFont('','', $default_font_size);
-			$larg_sign = ($this->page_largeur-$this->marge_gauche-$this->marge_droite)/3;
-			$pdf->Rect($this->marge_gauche, ($tab_top + $tab_height + 3), $larg_sign, 25);
-			$pdf->SetXY($this->marge_gauche + 2, $tab_top + $tab_height + 5);
-			$pdf->MultiCell($larg_sign,2, $outputlangs->trans("For").' '.$outputlangs->convToOutputCharset($mysoc->name).":",'','L');
-
-			$pdf->Rect(2*$larg_sign+$this->marge_gauche, ($tab_top + $tab_height + 3), $larg_sign, 25);
-			$pdf->SetXY(2*$larg_sign+$this->marge_gauche + 2, $tab_top + $tab_height + 5);
-			$pdf->MultiCell($larg_sign,2, $outputlangs->trans("ForCustomer").':','','L');
-		}
 	}
 
 	/**
@@ -522,22 +623,29 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 	 */
 	function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
 	{
-		global $langs,$conf,$mysoc;
+		global $conf,$langs,$hookmanager;
+
 		$default_font_size = pdf_getPDFFontSize($outputlangs);
 
 		pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
 
-		$pdf->SetTextColor(0,0,60);
-		$pdf->SetFont('','B', $default_font_size + 3);
-
-        $posx=$this->page_largeur-$this->marge_droite-100;
-		$posy=$this->marge_haute;
-
-		$pdf->SetXY($this->marge_gauche,$posy);
-
+		// Show Draft Watermark
+		if($object->statut==0 && (! empty($conf->global->COMMANDE_DRAFT_WATERMARK)) )
+		{
+			pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->COMMANDE_DRAFT_WATERMARK);
+		}
+		
+		$pdf->SetTextColor(0,0,60);
+		$pdf->SetFont('','B', $default_font_size + 3);
+		
+		$posy=$this->marge_haute;
+		$posx=$this->page_largeur-$this->marge_droite-100;
+		
+		$pdf->SetXY($this->marge_gauche,$posy);
+		
 		// Logo
-		$logo=$conf->mycompany->dir_output.'/logos/'.$mysoc->logo;
-		if ($mysoc->logo)
+		$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
+		if ($this->emetteur->logo)
 		{
 			if (is_readable($logo))
 			{
@@ -548,8 +656,8 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 			{
 				$pdf->SetTextColor(200,0,0);
 				$pdf->SetFont('','B', $default_font_size - 2);
-				$pdf->MultiCell(100, 3, $langs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
-				$pdf->MultiCell(100, 3, $langs->transnoentities("ErrorGoToModuleSetup"), 0, 'L');
+				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
+				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
 			}
 		}
 		else $pdf->MultiCell(100, 4, $this->emetteur->name, 0, 'L');
@@ -557,7 +665,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 		$pdf->SetFont('','B', $default_font_size + 2);
 		$pdf->SetXY($posx,$posy);
 		$pdf->SetTextColor(0,0,60);
-		$pdf->MultiCell(100, 4, $outputlangs->transnoentities("DeliveryOrder")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R');
+		$pdf->MultiCell(100, 3, $outputlangs->transnoentities("DeliveryOrder")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R');
 
 		$pdf->SetFont('','',$default_font_size + 2);
 
@@ -585,69 +693,42 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 
 		$pdf->SetTextColor(0,0,60);
 
-		// Add origin linked objects
-		// TODO extend to other objects
-	    $object->fetchObjectLinked('','',$object->id,'delivery');
-
-	    if (! empty($object->linkedObjects))
-		{
-			$outputlangs->load('orders');
-
-			foreach($object->linkedObjects as $elementtype => $objects)
-			{
-				$object->fetchObjectLinked('','',$objects[0]->id,$objects[0]->element);
-
-				foreach($object->linkedObjects as $elementtype => $objects)
-				{
-					$num=count($objects);
-					for ($i=0;$i<$num;$i++)
-					{
-						$order=new Commande($this->db);
-						$result=$order->fetch($objects[$i]->id);
-						if ($result >= 0)
-						{
-							$posy+=5;
-							$pdf->SetXY($posx,$posy);
-							$pdf->SetFont('','', $default_font_size - 1);
-							$text=$order->ref;
-							if ($order->ref_client) $text.=' ('.$order->ref_client.')';
-							$pdf->MultiCell(100, 4, $outputlangs->transnoentities("RefOrder")." : ".$outputlangs->transnoentities($text), '', 'R');
-						}
-					}
-				}
-			}
-		}
-
+		$posy+=2;
+		
+		// Show list of linked objects
+		$posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
+		
 		if ($showaddress)
 		{
-			// Emetteur
+			// Sender properties
+			$carac_emetteur = pdf_build_address($outputlangs,$this->emetteur);
+			
+			// Show sender
 			$posy=42;
+			$posx=$this->marge_gauche;
+			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
 			$hautcadre=40;
+			
+			// Show sender frame
 			$pdf->SetTextColor(0,0,0);
 			$pdf->SetFont('','', $default_font_size - 2);
-			$pdf->SetXY($this->marge_gauche,$posy-5);
-			$pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":");
-
-
-			$pdf->SetXY($this->marge_gauche,$posy);
+			$pdf->SetXY($posx,$posy-5);
+			$pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
+			$pdf->SetXY($posx,$posy);
 			$pdf->SetFillColor(230,230,230);
 			$pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
-
-
-			$pdf->SetXY($this->marge_gauche+2,$posy+3);
-
-			// Nom emetteur
 			$pdf->SetTextColor(0,0,60);
+
+			// Show sender name
+			$pdf->SetXY($posx+2,$posy+3);
 			$pdf->SetFont('','B',$default_font_size);
 			$pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
 
-			// Sender properties
-			$carac_emetteur = pdf_build_address($outputlangs,$this->emetteur);
-
-			$pdf->SetFont('','', $default_font_size - 1);
-			$pdf->SetXY($this->marge_gauche+2,$posy+9);
-			$pdf->MultiCell(80, 3, $carac_emetteur, 0, 'L');
-
+			// Show sender information
+			$pdf->SetXY($posx+2,$posy+8);
+			$pdf->SetFont('','', $default_font_size - 1);
+			$pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
+			
 			// Client destinataire
 			$posy=42;
 			$pdf->SetTextColor(0,0,0);
@@ -655,7 +736,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 			$pdf->SetXY(102,$posy-5);
 			$pdf->MultiCell(80,5, $outputlangs->transnoentities("DeliveryAddress").":", 0, 'L');
 
-			// If SHIPPING contact defined on invoice, we use it
+			// If SHIPPING contact defined on order, we use it
 			$usecontact=false;
 			$arrayidcontact=$object->commande->getIdContact('external','SHIPPING');
 			if (count($arrayidcontact) > 0)
@@ -677,7 +758,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 				$carac_client_name=$outputlangs->convToOutputCharset($object->client->nom);
 			}
 
-			$carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->client,$object->contact,$usecontact,'target');
+			$carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->client,($usecontact?$object->contact:''),$usecontact,'target');
 
 			// Show recipient
 			$widthrecbox=100;
@@ -700,7 +781,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 
 			// Show recipient information
 			$pdf->SetFont('','', $default_font_size - 1);
-			$pdf->SetXY($posx+2,$posy+8);
+			$pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4));
 			$pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
 		}
 
@@ -713,7 +794,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 	 * 		@param	Object		$object				Object to show
 	 *      @param	Translate	$outputlangs		Object lang for output
 	 *      @param	int			$hidefreetext		1=Hide free text
-	 *      @return	void
+	 *      @return	int								Return height of bottom margin including footer text
 	 */
 	function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0)
 	{
diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php
index b4c933ccf697b2a8513151185d73728d634c8679..856f4251e9c0f0db2f8daf85861e33cb6f72d314 100644
--- a/htdocs/core/modules/modBarcode.class.php
+++ b/htdocs/core/modules/modBarcode.class.php
@@ -111,12 +111,12 @@ class modBarcode extends DolibarrModules
 		$this->remove($options);
 
 		$sql = array(
-				array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("EAN8", "EAN8", 0, "1234567", __ENTITY__)','ignoreerror'=>1),
-				array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("EAN13", "EAN13", 0, "123456789012", __ENTITY__)','ignoreerror'=>1),
-				array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("UPC", "UPC", 0, "123456789012", __ENTITY__)','ignoreerror'=>1),
-				array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("ISBN", "ISBN", 0, "123456789", __ENTITY__)','ignoreerror'=>1),
-				array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("C39", "Code 39", 0, "1234567890", __ENTITY__)','ignoreerror'=>1),
-				array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("C128", "Code 128", 0, "ABCD1234567890", __ENTITY__)','ignoreerror'=>1)
+				array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('EAN8', 'EAN8', 0, '1234567', __ENTITY__)",'ignoreerror'=>1),
+				array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('EAN13', 'EAN13', 0, '123456789012', __ENTITY__)",'ignoreerror'=>1),
+				array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('UPC', 'UPC', 0, '123456789012', __ENTITY__)",'ignoreerror'=>1),
+				array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('ISBN', 'ISBN', 0, '123456789', __ENTITY__)",'ignoreerror'=>1),
+				array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('C39', 'Code 39', 0, '1234567890', __ENTITY__)",'ignoreerror'=>1),
+				array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('C128', 'Code 128', 0, 'ABCD1234567890', __ENTITY__)",'ignoreerror'=>1)
 		);
 
 		return $this->_init($sql, $options);
diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php
index 666bcb9a22a54a27927435c6396efc184f9071db..4d18c3d87574dcdcd267ffceca398a83406a39a3 100644
--- a/htdocs/core/modules/modFacture.class.php
+++ b/htdocs/core/modules/modFacture.class.php
@@ -198,10 +198,10 @@ class modFacture extends DolibarrModules
 		$this->export_label[$r]='CustomersInvoicesAndPayments';	// Translation key (used only if key ExportDataset_xxx_z not found)
 		$this->export_icon[$r]='bill';
 		$this->export_permission[$r]=array(array("facture","facture","export"));
-		$this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','c.code'=>'CountryCode','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.code_compta'=>'CustomerAccountancyCode','s.code_compta_fournisseur'=>'SupplierAccountancyCode','s.tva_intra'=>'VATIntra','f.rowid'=>"InvoiceId",'f.facnumber'=>"InvoiceRef",'f.datec'=>"InvoiceDateCreation",'f.datef'=>"DateInvoice",'f.date_lim_reglement'=>"DateDue",'f.total'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.tva'=>"TotalVAT",'f.paye'=>"InvoicePaid",'f.fk_statut'=>'InvoiceStatus','f.note'=>"NotePrivate",'f.note_public'=>"NotePublic",'p.rowid'=>'PaymentId','pf.amount'=>'AmountPayment','p.datep'=>'DatePayment','p.num_paiement'=>'PaymentNumber');
-		//$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number');
-		$this->export_TypeFields_array[$r]=array('s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number');
-		$this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','c.code'=>'company','s.phone'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company','s.tva_intra'=>'company','f.rowid'=>"invoice",'f.facnumber'=>"invoice",'f.datec'=>"invoice",'f.datef'=>"invoice",'f.date_lim_reglement'=>"invoice",'f.total'=>"invoice",'f.total_ttc'=>"invoice",'f.tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice','f.note'=>"invoice",'f.note_public'=>"invoice",'p.rowid'=>'payment','pf.amount'=>'payment','p.datep'=>'payment','p.num_paiement'=>'payment');
+		$this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','c.code'=>'CountryCode','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.code_compta'=>'CustomerAccountancyCode','s.code_compta_fournisseur'=>'SupplierAccountancyCode','s.tva_intra'=>'VATIntra','f.rowid'=>"InvoiceId",'f.facnumber'=>"InvoiceRef",'f.datec'=>"InvoiceDateCreation",'f.datef'=>"DateInvoice",'f.date_lim_reglement'=>"DateDue",'f.total'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.tva'=>"TotalVAT",'f.paye'=>"InvoicePaid",'f.fk_statut'=>'InvoiceStatus','f.note_private'=>"NotePrivate",'f.note_public'=>"NotePublic",'p.rowid'=>'PaymentId','pf.amount'=>'AmountPayment','p.datep'=>'DatePayment','p.num_paiement'=>'PaymentNumber');
+		//$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_private'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number');
+		$this->export_TypeFields_array[$r]=array('s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_private'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number');
+		$this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','c.code'=>'company','s.phone'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company','s.tva_intra'=>'company','f.rowid'=>"invoice",'f.facnumber'=>"invoice",'f.datec'=>"invoice",'f.datef'=>"invoice",'f.date_lim_reglement'=>"invoice",'f.total'=>"invoice",'f.total_ttc'=>"invoice",'f.tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice','f.note_private'=>"invoice",'f.note_public'=>"invoice",'p.rowid'=>'payment','pf.amount'=>'payment','p.datep'=>'payment','p.num_paiement'=>'payment');
 		$this->export_dependencies_array[$r]=array('payment'=>'p.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them
 
 		$this->export_sql_start[$r]='SELECT DISTINCT ';
diff --git a/htdocs/core/modules/modOpenSurvey.class.php b/htdocs/core/modules/modOpenSurvey.class.php
index 0930f7dfa94b7362edb9e1a728d1275c43273e8e..6c49a1c214304d9e3a4b16c8c35c2c5ca1223da5 100755
--- a/htdocs/core/modules/modOpenSurvey.class.php
+++ b/htdocs/core/modules/modOpenSurvey.class.php
@@ -1,7 +1,18 @@
 <?php
-/* Copyright (C) 2008 Laurent Destailleur  <eldy@users.sourceforge.net>
+/* Copyright (C) 2013 Laurent Destailleur  <eldy@users.sourceforge.net>
  *
- * Licensed under the GNU GPL v3 or higher (See file gpl-3.0.html)
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /**
@@ -184,10 +195,11 @@ class modOpenSurvey extends DolibarrModules
 	 */
 	function init($options='')
 	{
+		// Permissions
+		$this->remove($options);
+		
 		$sql = array();
 
-		$result=$this->load_tables();
-
 		return $this->_init($sql,$options);
 	}
 
@@ -205,20 +217,6 @@ class modOpenSurvey extends DolibarrModules
 
 		return $this->_remove($sql,$options);
 	}
-
-
-	/**
-	 *	Create tables and keys required by module
-	 * 	Files mymodule.sql and mymodule.key.sql with create table and create keys
-	 * 	commands must be stored in directory /mymodule/sql/
-	 *	This function is called by this->init.
-	 *
-	 * 	@return		int		<=0 if KO, >0 if OK
-	 */
-	function load_tables()
-	{
-	    return $this->_load_tables('/opensurvey/sql/');
-	}
 }
 
 ?>
diff --git a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php
index 1fbd02bbe6fa24f37e5ee57da50150846f6c220c..4c81babaa551cf0faaed57d29a82c470e5f38f39 100644
--- a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php
+++ b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php
@@ -650,7 +650,7 @@ class doc_generic_project_odt extends ModelePDFProjects
 
 						//Time ressources
 						$sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note";
-						$sql.= ", u.name, u.firstname";
+						$sql.= ", u.lastname, u.firstname";
 						$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
 						$sql .= " , ".MAIN_DB_PREFIX."user as u";
 						$sql .= " WHERE t.fk_task =".$task->id;
@@ -973,8 +973,12 @@ class doc_generic_project_odt extends ModelePDFProjects
 
 
 				// Write new file
-				$odfHandler->saveToDisk($file);	
-				//$odfHandler->exportAsAttachedPDF($file);
+				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
+					$odfHandler->exportAsAttachedPDF($file);
+				}
+				else {
+					$odfHandler->saveToDisk($file);
+				}	
 
 				if (! empty($conf->global->MAIN_UMASK))
 					@chmod($file, octdec($conf->global->MAIN_UMASK));
diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
index 26d67f09a321f1b338c4ab7fc0f5cebe7e28b44e..d4e485562a4d139991fa8b57a1932696104a1cdf 100644
--- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
+++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
@@ -482,8 +482,12 @@ class doc_generic_proposal_odt extends ModelePDFPropales
 				$reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
 
 				// Write new file
-				//$result=$odfHandler->exportAsAttachedFile('toto');
-				$odfHandler->saveToDisk($file);
+				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
+					$odfHandler->exportAsAttachedPDF($file);
+				}
+				else {
+					$odfHandler->saveToDisk($file);
+				}	
 
 				if (! empty($conf->global->MAIN_UMASK))
 					@chmod($file, octdec($conf->global->MAIN_UMASK));
diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php
index acf14c67139f31161b92d2d5b644fd6bf1f76179..e748e45a498fbc33565552ba4011d1199ae2f18e 100644
--- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php
+++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php
@@ -109,7 +109,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc
 			if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0);
 			else
 			{
-				$tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt','','name',SORT_ASC,0,true); // Disable hook for the moment
+				$tmpfiles=dol_dir_list($tmpdir,'files',0,'\.od(s|t)$','','name',SORT_ASC,0,true); // Disable hook for the moment
 				if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles);
 			}
 		}
@@ -210,16 +210,27 @@ class doc_generic_odt extends ModeleThirdPartyDoc
 			{
 				//print "srctemplatepath=".$srctemplatepath;	// Src filename
 				$newfile=basename($srctemplatepath);
-				$newfiletmp=preg_replace('/\.odt/i','',$newfile);
+				$newfiletmp=preg_replace('/\.od(s|t)/i','',$newfile);
 				$newfiletmp=preg_replace('/template_/i','',$newfiletmp);
 				$newfiletmp=preg_replace('/modele_/i','',$newfiletmp);
-				$filename=$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
+				// Get extension (ods or odt)
+				$newfileformat=substr($newfile, strrpos($newfile, '.')+1);
+				if ( ! empty($conf->global->MAIN_ODT_USE_TIMING))
+				{
+					$filename=$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.'.$newfileformat;
+				}
+				else
+				{
+					$filename=$newfiletmp.'.'.$newfileformat;
+				}
 				$file=$dir.'/'.$filename;
 				$object->builddoc_filename=$filename; // For triggers
+				//print "newfileformat=".$newfileformat;
 				//print "newdir=".$dir;
 				//print "newfile=".$newfile;
 				//print "file=".$file;
 				//print "conf->societe->dir_temp=".$conf->societe->dir_temp;
+				//exit;
 
 				dol_mkdir($conf->societe->multidir_temp[$object->entity]);
 
@@ -313,8 +324,12 @@ class doc_generic_odt extends ModeleThirdPartyDoc
 				$reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
 
 				// Write new file
-				//$result=$odfHandler->exportAsAttachedFile('toto');
-				$odfHandler->saveToDisk($file);
+				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
+					$odfHandler->exportAsAttachedPDF($file);
+				}
+				else {
+					$odfHandler->saveToDisk($file);
+				}	
 
 				if (! empty($conf->global->MAIN_UMASK))
 				@chmod($file, octdec($conf->global->MAIN_UMASK));
diff --git a/htdocs/core/search_page.php b/htdocs/core/search_page.php
index 3cab48155aeed4c0ca3ecc24c3f341b3f853a7e0..fe21a82c56fc0d435d5319a11907807ad58a122f 100644
--- a/htdocs/core/search_page.php
+++ b/htdocs/core/search_page.php
@@ -40,11 +40,6 @@ $langs->load("main");
 $right=($langs->trans("DIRECTION")=='rtl'?'left':'right');
 $left=($langs->trans("DIRECTION")=='rtl'?'right':'left');
 
-//var_dump($langs->defaultlang);
-//var_dump($conf->format_date_short_java);
-//var_dump($langs->trans("FormatDateShortJava"));
-
-
 
 /*
  * View
diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php
index 5272c06b31ff81c9592c09cf9755ce7c30a64a6b..44cc7a78bc0de4f5e6d42dc012aba9d9546306f8 100644
--- a/htdocs/core/tpl/admin_extrafields_add.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php
@@ -27,7 +27,7 @@
     		var required = jQuery("#required");
     		var default_value = jQuery("#default_value");
     		<?php
-    		if(GETPOST('type') != "select") 
+    		if((GETPOST('type') != "select") &&  (GETPOST('type') != "sellist"))
     		{
     			print 'jQuery("#value_choice").hide();';
     		}
@@ -48,6 +48,7 @@
     		else if (type == 'boolean') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").hide();}
     		else if (type == 'price') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").hide();}
     		else if (type == 'select') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');  jQuery("#value_choice").show();}
+    		else if (type == 'sellist') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');  jQuery("#value_choice").show();}
     		else if (type == 'checkbox') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');  jQuery("#value_choice").show();}
     		else if (type == 'radio') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');  jQuery("#value_choice").show();}
     		else if (type == 'separate') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');  required.val('').attr('disabled','disabled'); default_value.val('').attr('disabled','disabled'); jQuery("#value_choice").hide();}
@@ -63,6 +64,7 @@
 <form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="post">
 <input type="hidden" name="token" value="<?php echo $_SESSION['newtoken']; ?>">
 <input type="hidden" name="action" value="add">
+<input type="hidden" name="rowid" value="<?php echo $rowid ?>">
 
 <table summary="listofattributes" class="border centpercent">
 <!-- Type -->
@@ -85,7 +87,7 @@
 <table class="nobordernopadding">
 <tr><td width="30%">
 	<textarea name="param" id="param"><?php echo GETPOST('param'); ?></textarea>
-</td><td><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelp"),1,0)?></td></tr>
+</td><td><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelp".$type),1,0)?></td></tr>
 </table>
 </td>
 
diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
index 181fcd55bbc31ed18c3cb6b90d01a0f9680a38d1..d3b06545fa22c09d50830a1817baf3d6fd148b4b 100644
--- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
@@ -44,6 +44,7 @@
 <input type="hidden" name="token" value="<?php echo $_SESSION['newtoken']; ?>">
 <input type="hidden" name="attrname" value="<?php echo $attrname; ?>">
 <input type="hidden" name="action" value="update">
+<input type="hidden" name="rowid" value="<?php echo $rowid ?>">
 
 <table summary="listofattributes" class="border centpercent">
 
@@ -80,7 +81,7 @@ if((($type == 'select') || ($type == 'checkbox') ||(($type == 'radio'))) && is_a
 </td></tr>
 <!--  Value (for select list / radio) -->
 <?php 
-if(($type == 'select') || ($type == 'checkbox') ||(($type == 'radio'))) 
+if(($type == 'select') || ($type == 'sellist') || ($type == 'checkbox') ||(($type == 'radio'))) 
 {
 ?>
 <tr id="value_choice">
@@ -88,7 +89,11 @@ if(($type == 'select') || ($type == 'checkbox') ||(($type == 'radio')))
 	<?php echo $langs->trans("Value"); ?>
 </td>
 <td>
+<table class="nobordernopadding">
+<tr><td width="30%">
 	<textarea name="param" id="param"><?php echo $param_chain; ?></textarea>
+</td><td><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelp".$type),1,0)?></td></tr>
+</table>
 </td>
 </tr>
 <?php 
diff --git a/htdocs/core/tpl/objectline_add.tpl.php b/htdocs/core/tpl/objectline_add.tpl.php
index 497d4a294bac615fcf619ac9f774db9330ff3aab..6a7cffcb3fc793e47290e80b6e096ccea1d8a416 100644
--- a/htdocs/core/tpl/objectline_add.tpl.php
+++ b/htdocs/core/tpl/objectline_add.tpl.php
@@ -80,8 +80,8 @@ if (! empty($conf->margin->enabled)) {
 							'origin_price_ht_cache' => 'price_ht',
 							'origin_tva_tx_cache' => 'tva_tx',
 							'origin_price_ttc_cache' => 'price_ttc',
-							'qty' => 'qty'
-							,'remise_percent' => 'discount'
+							'qty' => 'qty',
+							'remise_percent' => 'discount'
 					),
 					'update_textarea' => array(
 							'product_desc' => 'desc'
@@ -160,7 +160,10 @@ if (! empty($conf->margin->enabled)) {
 		<input type="hidden" id="origin_price_ttc_cache" name="origin_price_ttc_cache" value="" />
 	</td>
 	<td align="right"><input type="text" size="3" id="qty" name="qty" value="<?php echo (GETPOST('qty')?GETPOST('qty'):1); ?>"></td>
-	<td align="right" nowrap="nowrap"><input type="text" size="1" value="<?php echo $buyer->remise_client; ?>" id="remise_percent" name="remise_percent">%</td>
+	<td align="right" nowrap="nowrap">
+		<input type="text" size="1" value="<?php echo $buyer->remise_client; ?>" id="remise_percent" name="remise_percent">%
+		<input type="hidden" id="origin_remise_percent" name="origin_remise_percent" value="<?php echo $buyer->remise_client; ?>" />
+	</td>
 <?php
 $colspan = 4;
 if (! empty($conf->margin->enabled)) {
@@ -373,6 +376,11 @@ $(document).ready(function() {
 		$('#price_ttc').attr('disabled','disabled');
 	}
 
+	$('#remise_percent').bind('change', function() {
+		if ($(this).val() < $('#origin_remise_percent').val())
+			$('#remise_percent').val($('#origin_remise_percent').val());
+	});
+
 	$('#tva_tx').change(function() {
 		if ($(this).val() == 0) {
 			if ($('#idprod').val() == 0) {
diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
index c278544580082a6cf25846aa75e3a7b870c5b826..f3b10e7f1f882db559de5b762a33035fc3363a96 100755
--- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
+++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
@@ -1,6 +1,7 @@
 <?php
 /* Copyright (C) 2006-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2011      Regis Houssin        <regis.houssin@capnetworks.com>
+ * Copyright (C) 2013      Marcos García        <marcosgdf@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,7 +36,8 @@ class InterfaceNotification
     	'PROPAL_VALIDATE',
         'FICHINTER_VALIDATE',
     	'ORDER_SUPPLIER_APPROVE',
-    	'ORDER_SUPPLIER_REFUSE'
+    	'ORDER_SUPPLIER_REFUSE',
+        'SHIPPING_VALIDATE'
    	);
 
     /**
@@ -196,6 +198,19 @@ class InterfaceNotification
             $notify = new Notify($this->db);
             $notify->send($action, $object->socid, $mesg, 'order_supplier', $object->id, $filepdf);
 		}
+        elseif ($action == 'SHIPPING_VALIDATE')
+        {
+            dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
+
+            $ref = dol_sanitizeFileName($object->ref);
+            $filepdf = $conf->expedition->dir_output . '/sending/' . $ref . '/' . $ref . '.pdf';
+            if (! file_exists($filepdf)) $filepdf='';
+            $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated",$object->ref);
+
+
+            $notify = new Notify($this->db);
+            $notify->send($action, $object->socid, $mesg, 'expedition', $object->id, $filepdf);
+        }
 
 		// If not found
 /*
diff --git a/htdocs/ecm/class/ecmdirectory.class.php b/htdocs/ecm/class/ecmdirectory.class.php
index bdb8dd0f366c950f14f6c0c0fb2f29ecdfe4942d..3c12fe066e97406d54a3531f5deaef2ab7426d68 100644
--- a/htdocs/ecm/class/ecmdirectory.class.php
+++ b/htdocs/ecm/class/ecmdirectory.class.php
@@ -142,7 +142,8 @@ class EcmDirectory // extends CommonObject
 
 				$dir=$conf->ecm->dir_output.'/'.$this->getRelativePath();
 				$result=dol_mkdir($dir);
-
+				if ($result < 0) { $error++; $this->error="ErrorFailedToCreateDir"; }
+				
 				// Appel des triggers
 				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
 				$interface=new Interfaces($this->db);
diff --git a/htdocs/ecm/docdir.php b/htdocs/ecm/docdir.php
index 8f71bf4ed97b5c025c02c570ea12ffc6a352260f..5ab21beed0d6691d465f9cd9c839404b465ccc05 100644
--- a/htdocs/ecm/docdir.php
+++ b/htdocs/ecm/docdir.php
@@ -118,6 +118,7 @@ if ($action == 'add' && $user->rights->ecm->setup)
 		{
 			$langs->load("errors");
 			setEventMessage($langs->trans($ecmdir->error), 'errors');
+			setEventMessage($ecmdir->errors, 'errors');
 			$action = 'create';
 		}
 	}
diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php
index f3db4dafc8b191e9b11cf3301fc962701e43226c..95b18e1d814b7573f6f23bf123ccb24ba2373fe5 100644
--- a/htdocs/expedition/class/expedition.class.php
+++ b/htdocs/expedition/class/expedition.class.php
@@ -1199,7 +1199,7 @@ class Expedition extends CommonObject
     {
         global $langs;
 
-        $listmeths = array();
+        $this->listmeths = array();
         $i=0;
 
         $sql = "SELECT em.rowid, em.code, em.libelle, em.description, em.tracking, em.active";
@@ -1216,29 +1216,11 @@ class Expedition extends CommonObject
                 $label=$langs->trans('SendingMethod'.$obj->code);
                 $this->listmeths[$i]['libelle'] = ($label != 'SendingMethod'.$obj->code?$label:$obj->libelle);
                 $this->listmeths[$i]['description'] = $obj->description;
-                if ($obj->tracking)
-                {
-                    $this->listmeths[$i]['tracking'] = $obj->tracking;
-                }
-                else
-                {
-                    if ($obj->code)
-                    {
-                        $classname = "methode_expedition_".strtolower($obj->code);
-
-                        if (file_exists(DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($obj->code).".modules.php") )
-                        {
-                            require_once DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($obj->code).'.modules.php';
-                            $shipmethod = new $classname();
-                            $this->listmeths[$i]['tracking'] = $shipmethod->provider_url_status('{TRACKID}');
-                        }
-                    }
-                }
+                $this->listmeths[$i]['tracking'] = $obj->tracking;
                 $this->listmeths[$i]['active'] = $obj->active;
                 $i++;
             }
         }
-        else dol_print_error($this->db,'');
     }
 
     /**
@@ -1309,8 +1291,6 @@ class Expedition extends CommonObject
 	 */
 	function GetUrlTrackingStatus($value='')
 	{
-		$code='';
-
 		if (! empty($this->shipping_method_id))
 		{
 			$sql = "SELECT em.code, em.tracking";
@@ -1322,46 +1302,21 @@ class Expedition extends CommonObject
 			{
 				if ($obj = $this->db->fetch_object($resql))
 				{
-					$code = $obj->code;
-                    $tracking = $obj->tracking;
+					$tracking = $obj->tracking;
 				}
 			}
 		}
 
-        if ($tracking)
-        {
-                $url = str_replace('{TRACKID}', $value, $tracking);
-                $this->tracking_url = sprintf('<a target="_blank" href="%s">'.($value?$value:'url').'</a>',$url,$url);
-        }
-        else
-        {
-            if ($code)
-            {
-                $classname = "methode_expedition_".strtolower($code);
-
-                $url='';
-                if (file_exists(DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($code).".modules.php") && ! empty($this->tracking_number))
-                {
-                    require_once DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($code).'.modules.php';
-                    $shipmethod = new $classname();
-                    $url = $shipmethod->provider_url_status($this->tracking_number);
-                }
-
-                if ($url)
-                {
-                    $this->tracking_url = sprintf('<a target="_blank" href="%s">'.($value?$value:'url').'</a>',$url,$url);
-                }
-                else
-                {
-                    $this->tracking_url = $value;
-                }
-            }
-            else
-            {
-                $this->tracking_url = $value;
-            }
-        }
-    }
+		if (!empty($tracking) && !empty($value))
+		{
+			$url = str_replace('{TRACKID}', $value, $tracking);
+			$this->tracking_url = sprintf('<a target="_blank" href="%s">'.($value?$value:'url').'</a>',$url,$url);
+		}
+		else
+		{
+			$this->tracking_url = $value;
+		}
+	}
 
 	/**
 	 *	Classify the shipping as invoiced
diff --git a/htdocs/expedition/fiche.php b/htdocs/expedition/fiche.php
index de3107b663fca468e3dd3d2cbddbf780d80ba2fc..996e41a649ac4b363885e509a3a86df993166e26 100644
--- a/htdocs/expedition/fiche.php
+++ b/htdocs/expedition/fiche.php
@@ -5,6 +5,7 @@
  * Copyright (C) 2005-2012	Regis Houssin			<regis.houssin@capnetworks.com>
  * Copyright (C) 2011-2012	Juanjo Menent			<jmenent@2byte.es>
  * Copyright (C) 2013       Florian Henry		  	<florian.henry@open-concept.pro>
+ * Copyright (C) 2013       Marcos García           <marcosgdf@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -698,16 +699,16 @@ if ($action == 'create')
             //$lines = $object->fetch_lines(1);
             $numAsked = count($object->lines);
             
-            print '<script type="text/javascript" language="javascript">
-            jQuery(document).ready(function() {
-	            jQuery("#autofill").click(function() {';
+            print '<script type="text/javascript" language="javascript">
+            jQuery(document).ready(function() {
+	            jQuery("#autofill").click(function() {';
     	    	$i=0;
     	    	while($i < $numAsked)
     	    	{
     	    		print 'jQuery("#qtyl'.$i.'").val(jQuery("#qtyasked'.$i.'").val() - jQuery("#qtydelivered'.$i.'").val());'."\n";
     	    		$i++;
-    	    	}
-        		print '});
+    	    	}
+        		print '});
 	            jQuery("#autoreset").click(function() {';
     	    	$i=0;
     	    	while($i < $numAsked)
@@ -716,8 +717,8 @@ if ($action == 'create')
     	    		$i++;
     	    	}
         		print '});
-        	});
-            </script>';
+        	});
+            </script>';
             
             
             print '<br>';
@@ -904,7 +905,7 @@ if ($action == 'create')
             
             print '<br><center><input type="submit" class="button" value="'.$langs->trans("Create").'"></center>';
             
-            print '</form>';
+            print '</form>';
             
             print '<br>';
         }
@@ -974,7 +975,18 @@ else
                 {
                     $numref = $object->ref;
                 }
-                $ret=$form->form_confirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('ValidateSending'),$langs->trans("ConfirmValidateSending",$numref),'confirm_valid','',0,1);
+
+                $text = $langs->trans("ConfirmValidateSending",$numref);
+
+                if (! empty($conf->notification->enabled))
+                {
+                    require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
+                    $notify=new Notify($db);
+                    $text.='<br>';
+                    $text.=$notify->confirmMessage('SHIPPING_VALIDATE',$object->socid);
+                }
+
+                $ret=$form->form_confirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('ValidateSending'),$text,'confirm_valid','',0,1);
                 if ($ret == 'html') print '<br>';
             }
             /*
diff --git a/htdocs/externalsite/frames.php b/htdocs/externalsite/frames.php
index e93dc392d9343bbaad6d504626e75e405759376d..825398f363651ff6500dae917e61cb7fe0ccab4e 100644
--- a/htdocs/externalsite/frames.php
+++ b/htdocs/externalsite/frames.php
@@ -25,12 +25,12 @@
 
 require '../main.inc.php';
 
-$langs->load("externalsite@externalsite");
+$langs->load("externalsite");
 
 if (empty($conf->global->EXTERNALSITE_URL))
 {
 	llxHeader();
-	print '<div class="error">Module ExternalSite was not configured properly.</div>';
+	print '<div class="error">'.$langs->trans('ExternalSiteModuleNotComplete').'</div>';
 	llxFooter();
 }
 
diff --git a/htdocs/externalsite/frametop.php b/htdocs/externalsite/frametop.php
index 5808c97490972e6f2f30f682d9bdda1c7bcc5724..0bf7a259c8f460e3d44b4a6f49148036b281c050 100644
--- a/htdocs/externalsite/frametop.php
+++ b/htdocs/externalsite/frametop.php
@@ -24,7 +24,7 @@
 
 require ("../main.inc.php");
 
-$langs->load("@externalsite");
+$langs->load("externalsite");
 
 top_htmlhead("","");
 top_menu("","","_top");
diff --git a/htdocs/fichinter/apercu.php b/htdocs/fichinter/apercu.php
index 2bac1eae624fcdcebfe7cfbc52f2f39682d1fb84..507a48d2deef08527536629fccd3d5dc85a5f832 100644
--- a/htdocs/fichinter/apercu.php
+++ b/htdocs/fichinter/apercu.php
@@ -100,7 +100,7 @@ if ($id > 0 || ! empty($ref))
 
 			print "<tr $bc[$var]><td>".$langs->trans("Intervention")." PDF</td>";
 
-			print '<td><a href="'.DOL_URL_ROOT . '/document.php?modulepart=ficheinter&file='.urlencode($relativepath).'">'.$object->ref.'.pdf</a></td>';
+			print '<td><a data-ajax="false" href="'.DOL_URL_ROOT . '/document.php?modulepart=ficheinter&file='.urlencode($relativepath).'">'.$object->ref.'.pdf</a></td>';
 			print '<td align="right">'.dol_print_size(dol_filesize($file)).'</td>';
 			print '<td align="right">'.dol_print_date(dol_filemtime($file),'dayhour').'</td>';
 			print '</tr>';
@@ -110,7 +110,7 @@ if ($id > 0 || ! empty($ref))
 			{
 				print "<tr $bc[$var]><td>Fiche d'intervention detaillee</td>";
 
-				print '<td><a href="'.DOL_URL_ROOT . '/document.php?modulepart=ficheinter&file='.urlencode($relativepathdetail).'">'.$object->ref.'-detail.pdf</a></td>';
+				print '<td><a data-ajax="false" href="'.DOL_URL_ROOT . '/document.php?modulepart=ficheinter&file='.urlencode($relativepathdetail).'">'.$object->ref.'-detail.pdf</a></td>';
 				print '<td align="right">'.dol_print_size(dol_filesize($filedetail)).'</td>';
 				print '<td align="right">'.dol_print_date(dol_filemtime($filedetail),'dayhour').'</td>';
 				print '</tr>';
diff --git a/htdocs/fichinter/fiche.php b/htdocs/fichinter/fiche.php
index 70fed335c9358ba65da5efff9b9142593224a88c..0684c4695cef92f0c765b9dad16a427c289ecf35 100644
--- a/htdocs/fichinter/fiche.php
+++ b/htdocs/fichinter/fiche.php
@@ -386,7 +386,7 @@ else if ($action == 'setnote_public' && $user->rights->ficheinter->creer)
 else if ($action == 'setnote_private' && $user->rights->ficheinter->creer)
 {
     $object->fetch($id);
-    $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES));
+    $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private');
     if ($result < 0) dol_print_error($db,$object->error);
 }
 
diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
index 759258888cff86917309a5d4283ff3990679d572..ac138636b08f8ba06ce6265425d65b9575e9f5fc 100644
--- a/htdocs/fourn/class/fournisseur.facture.class.php
+++ b/htdocs/fourn/class/fournisseur.facture.class.php
@@ -141,6 +141,7 @@ class FactureFournisseur extends CommonInvoice
         $sql.= ", fk_soc";
         $sql.= ", datec";
         $sql.= ", datef";
+		$sql.= ", fk_projet";
         $sql.= ", note_private";
         $sql.= ", note_public";
         $sql.= ", fk_user_author";
@@ -154,6 +155,7 @@ class FactureFournisseur extends CommonInvoice
         $sql.= ", ".$this->socid;
         $sql.= ", '".$this->db->idate($now)."'";
         $sql.= ", '".$this->db->idate($this->date)."'";
+		$sql.= ", ".$this->fk_project;
         $sql.= ", '".$this->db->escape($this->note_private)."'";
         $sql.= ", '".$this->db->escape($this->note_public)."'";
         $sql.= ", ".$user->id.",";
diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php
index 9a86f0e9ee330798d5255cb16b1dbfc81a68e0b5..8d5a3474bf88eb36f77fcc83b1a1a060d4a311df 100644
--- a/htdocs/fourn/class/fournisseur.product.class.php
+++ b/htdocs/fourn/class/fournisseur.product.class.php
@@ -296,7 +296,7 @@ class ProductFournisseur extends Product
     function fetch_product_fournisseur_price($rowid)
     {
         $sql = "SELECT pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.fk_availability,";
-        $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.fk_product, pfp.charges, pfp.unitcharges, pfp.recuperableonly as fourn_tva_npr";
+        $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.fk_product, pfp.charges, pfp.unitcharges"; // , pfp.recuperableonly as fourn_tva_npr";  FIXME this field not exist in llx_product_fournisseur_price
         $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp";
         $sql.= " WHERE pfp.rowid = ".$rowid;
 
@@ -320,7 +320,7 @@ class ProductFournisseur extends Product
             	$this->product_id				= $obj->fk_product;	// deprecated
             	$this->fk_product				= $obj->fk_product;
             	$this->fk_availability			= $obj->fk_availability;
-            	$this->fourn_tva_npr			= $obj->fourn_tva_npr;
+            	//$this->fourn_tva_npr			= $obj->fourn_tva_npr; // FIXME this field not exist in llx_product_fournisseur_price
             	return 1;
             }
             else
diff --git a/htdocs/fourn/commande/fiche.php b/htdocs/fourn/commande/fiche.php
index 653397cfaf596da24e9f5b0a0f3fc1e0e994cc73..cad571686e8a18f13477cca4d9e01f4d9467c3de 100644
--- a/htdocs/fourn/commande/fiche.php
+++ b/htdocs/fourn/commande/fiche.php
@@ -1077,7 +1077,7 @@ elseif (! empty($object->id))
 			require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
 			$notify=new	Notify($db);
 			$text.='<br>';
-			$text.=$notify->confirmMessage(3,$object->socid);
+			$text.=$notify->confirmMessage('ORDER_SUPPLIER_APPROVE', $object->socid);
 		}
 
 		$ret=$form->form_confirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_valid', '', 0, 1);
@@ -1762,10 +1762,10 @@ elseif (! empty($object->id))
 
 			print "</div>";
 		}
-		print "<br>";
+		print "<br>";
 
 
-		print '<div class="fichecenter"><div class="fichehalfleft">';
+		print '<div class="fichecenter"><div class="fichehalfleft">';
 		//print '<table width="100%"><tr><td width="50%" valign="top">';
 		//print '<a name="builddoc"></a>'; // ancre
 
diff --git a/htdocs/fourn/commande/note.php b/htdocs/fourn/commande/note.php
index 7d4fa0cd4964cc66929dde2ed827a0618ed05d4d..9e629414b6384663e23cb3f6041f0eac8a25fd90 100644
--- a/htdocs/fourn/commande/note.php
+++ b/htdocs/fourn/commande/note.php
@@ -54,9 +54,9 @@ if ($action == 'setnote_public' && $user->rights->fournisseur->commande->creer)
     $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public');
     if ($result < 0) dol_print_error($db,$object->error);
 }
-elseif ($action == 'setnote' && $user->rights->fournisseur->commande->creer)
+elseif ($action == 'setnote_private' && $user->rights->fournisseur->commande->creer)
 {
-    $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES));
+    $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private');
     if ($result < 0) dol_print_error($db,$object->error);
 }
 
diff --git a/htdocs/fourn/facture/fiche.php b/htdocs/fourn/facture/fiche.php
index 6ed624b82fa9ec86f7dd5173cc81e8b67cc98f04..1ea01631f7962ccb1acb739d2d0497aaf92db10a 100644
--- a/htdocs/fourn/facture/fiche.php
+++ b/htdocs/fourn/facture/fiche.php
@@ -41,6 +41,8 @@ if (!empty($conf->produit->enabled))
 	require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
 if (!empty($conf->projet->enabled))
 	require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+if (! empty($conf->projet->enabled))
+	require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
 
 
 $langs->load('bills');
@@ -271,6 +273,7 @@ elseif ($action == 'add' && $user->rights->fournisseur->facture->creer)
         // Creation facture
         $object->ref           = $_POST['ref'];
 		$object->ref_supplier  = $_POST['ref_supplier'];
+		$object->fk_project    = GETPOST('projectid');
         $object->socid         = $_POST['socid'];
         $object->libelle       = $_POST['libelle'];
         $object->date          = $datefacture;
@@ -1153,6 +1156,15 @@ if ($action == 'create')
     print '<tr><td>'.$langs->trans('DateMaxPayment').'</td><td>';
     $form->select_date($datedue,'ech','','','',"add",1,1);
     print '</td></tr>';
+	
+	// Project
+	if (! empty($conf->projet->enabled))
+	{
+		$langs->load('projects');
+		print '<tr><td>'.$langs->trans('Project').'</td><td colspan="2">';
+		select_projects(-1, $projectid, 'projectid');
+		print '</td></tr>';
+	}
 
     print '<tr><td>'.$langs->trans('NotePublic').'</td>';
     print '<td>';
@@ -1330,12 +1342,12 @@ else
             }
 
             $text=$langs->trans('ConfirmValidateBill',$numref);
-            /*if (! empty($conf->notification->enabled))
-            {
-            	require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
-            	$notify=new Notify($db);
-            	$text.='<br>';
-            	$text.=$notify->confirmMessage('NOTIFY_VAL_FAC_SUP',$object->socid);
+            /*if (! empty($conf->notification->enabled))
+            {
+            	require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
+            	$notify=new Notify($db);
+            	$text.='<br>';
+            	$text.=$notify->confirmMessage('BILL_SUPPLIER_VALIDATE',$object->socid);
             }*/
             $formquestion=array();
 
@@ -2054,7 +2066,7 @@ else
                 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete">'.$langs->trans('Delete').'</a>';
             }
             print '</div>';
-            print '<br>';
+            print '<br>';
 
             if ($action != 'edit')
             {
diff --git a/htdocs/fourn/facture/index.php b/htdocs/fourn/facture/index.php
index 3d55e528daf5aa106e5c9d1fdff1734ac2b43e48..5934029aef3e3f1c5cf074724109e2c7d7872dbb 100644
--- a/htdocs/fourn/facture/index.php
+++ b/htdocs/fourn/facture/index.php
@@ -1,7 +1,7 @@
 <?php
 /* Copyright (C) 2002-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  * Copyright (C) 2004-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
+ * Copyright (C) 2005-2013 Regis Houssin        <regis.houssin@capnetworks.com>
  * Copyright (C) 2013	   Philippe Grand		<philippe.grand@atoo-net.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -156,12 +156,12 @@ if (GETPOST("search_societe"))
 
 if (GETPOST("search_montant_ht"))
 {
-	$sql .= " AND fac.total_ht = '".$db->escape(GETPOST("search_montant_ht"))."'";
+	$sql .= " AND fac.total_ht = '".$db->escape(price2num(GETPOST("search_montant_ht")))."'";
 }
 
 if (GETPOST("search_montant_ttc"))
 {
-	$sql .= " AND fac.total_ttc = '".$db->escape(GETPOST("search_montant_ttc"))."'";
+	$sql .= " AND fac.total_ttc = '".$db->escape(price2num(GETPOST("search_montant_ttc")))."'";
 }
 
 $sql.= $db->order($sortfield,$sortorder);
diff --git a/htdocs/fourn/fiche.php b/htdocs/fourn/fiche.php
index 2d9a7a151b35ecd456ecf5f5bf19520319c37b65..13ef8ea85234d5021ec603313c9b1f967cf488df 100644
--- a/htdocs/fourn/fiche.php
+++ b/htdocs/fourn/fiche.php
@@ -85,8 +85,9 @@ if ($object->fetch($id))
 	dol_fiche_head($head, 'supplier', $langs->trans("ThirdParty"),0,'company');
 
 
-	print '<table width="100%" class="notopnoleftnoright">';
-	print '<tr><td valign="top" width="50%" class="notopnoleft">';
+	print '<div class="fichecenter"><div class="fichehalfleft">';
+	//print '<table width="100%" class="notopnoleftnoright">';
+	//print '<tr><td valign="top" width="50%" class="notopnoleft">';
 
 	print '<table width="100%" class="border">';
 	print '<tr><td width="20%">'.$langs->trans("ThirdPartyName").'</td><td width="80%" colspan="3">';
@@ -216,7 +217,11 @@ if ($object->fetch($id))
 
 	print '</table>';
 
-	print '</td><td valign="top" width="50%" class="notopnoleftnoright">';
+	
+	print '</div><div class="fichehalfright"><div class="ficheaddleft">';
+	//print '</td><td valign="top" width="50%" class="notopnoleftnoright">';
+
+	
 	$var=true;
 
 	$MAXLIST=5;
@@ -367,9 +372,12 @@ if ($object->fetch($id))
 		}
 	}
 
-	print '</td></tr>';
-	print '</table>' . "\n";
-	print '</div>';
+	print '</div></div></div>';
+	print '<div style="clear:both"></div>';
+	//print '</td></tr>';
+	//print '</table>' . "\n";
+	
+	dol_fiche_end();
 
 
 	/*
diff --git a/htdocs/holiday/admin/holiday.php b/htdocs/holiday/admin/holiday.php
index 583ab228c9a442650d0279a07006e07dad9cb935..6e7216332ead822510475b14bde9ec1722745a95 100644
--- a/htdocs/holiday/admin/holiday.php
+++ b/htdocs/holiday/admin/holiday.php
@@ -278,7 +278,7 @@ $var=true;
 
 /*$var=!$var;
 print '<tr '.$bc[$var].'>'."\n";
-print '<td style="padding:5px; width: 40%;">'.$langs->trans('GroupToValidateCP').'</td>'."\n";
+print '<td style="padding:5px;">'.$langs->trans('GroupToValidateCP').'</td>'."\n";
 print '<td style="padding:5px;">'.$cp->selectUserGroup('userGroup').'</td>'."\n";
 print '</tr>'."\n";
 */
diff --git a/htdocs/holiday/index.php b/htdocs/holiday/index.php
index c269a148615e45e23347ef1ec3ac09fa11f3bad0..06c7541145378495d56106d390a2ec3482fa1c0a 100644
--- a/htdocs/holiday/index.php
+++ b/htdocs/holiday/index.php
@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2011	Dimitri Mouillard	<dmouillard@teclib.com>
- * Copyright (C) 2012	Laurent Destailleur	<eldy@users.sourceforge.net>
+ * Copyright (C) 2013	Laurent Destailleur	<eldy@users.sourceforge.net>
  * Copyright (C) 2012	Regis Houssin		<regis.houssin@capnetworks.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -228,7 +228,6 @@ if ($id > 0)
 	print "</tr>\n";
 
 	print '</table><br>';
-
 }
 else
 {
@@ -242,7 +241,15 @@ $nbaquis=$holiday->getCPforUser($user_id);
 $nbdeduced=$holiday->getConfCP('nbHolidayDeducted');
 $nb_holiday = $nbaquis / $nbdeduced;
 print $langs->trans('SoldeCPUser',round($nb_holiday,2)).($nbdeduced != 1 ? ' ('.$nbaquis.' / '.$nbdeduced.')' : '');
-print '</div>';
+
+if ($id > 0)
+{
+	dol_fiche_end();
+	print '</br>';
+}
+else {
+	print '</div>';
+} 
 
 print '<form method="get" action="'.$_SERVER["PHP_SELF"].'">'."\n";
 print '<table class="noborder" width="100%;">';
diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php
index 85c8410da7e8bb42272aafca00af0e030f4e73de..d6d35335bed7a4260932faeeed70d8b43a113312 100644
--- a/htdocs/imports/import.php
+++ b/htdocs/imports/import.php
@@ -569,7 +569,7 @@ if ($step == 3 && $datatoimport)
 			print '<tr '.$bc[$var].'>';
 			print '<td width="16">'.img_mime($file).'</td>';
 			print '<td>';
-    		print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=3'.$param.'" target="_blank">';
+    		print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=3'.$param.'" target="_blank">';
     		print $file;
     		print '</a>';
 			print '</td>';
@@ -742,7 +742,7 @@ if ($step == 4 && $datatoimport)
 	print '<td>';
 	$modulepart='import';
 	$relativepath=GETPOST('filetoimport');
-    print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank">';
+    print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank">';
     print $filetoimport;
     print '</a>';
 	print '</td></tr>';
@@ -1172,7 +1172,7 @@ if ($step == 5 && $datatoimport)
 	print '<td>';
 	$modulepart='import';
 	$relativepath=GETPOST('filetoimport');
-    print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank">';
+    print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank">';
     print $filetoimport;
     print '</a>';
     print '</td></tr>';
@@ -1506,7 +1506,7 @@ if ($step == 6 && $datatoimport)
 	print '<td>';
 	$modulepart='import';
     $relativepath=GETPOST('filetoimport');
-    print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank">';
+    print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank">';
     print $filetoimport;
     print '</a>';
 	print '</td></tr>';
diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php
index 7e72eb6f7e24e6107a0ef285e874f38bcb58b7b7..4f91157438b9aec4baa15a20142364a4ec3d1381 100644
--- a/htdocs/includes/odtphp/odf.php
+++ b/htdocs/includes/odtphp/odf.php
@@ -18,152 +18,152 @@ class OdfException extends Exception
 class Odf
 {
 	protected $config = array(
-    	'ZIP_PROXY' => 'PclZipProxy',	// PclZipProxy, PhpZipProxy
-    	'DELIMITER_LEFT' => '{',
-    	'DELIMITER_RIGHT' => '}',
-		'PATH_TO_TMP' => '/tmp'
-		);
-		protected $file;
-		protected $contentXml;			// To store content of content.xml file
-		protected $stylesXml;			// To store content of styles.xml file
-		protected $manifestXml;			// To store content of META-INF/manifest.xml file
-		protected $tmpfile;
-		protected $tmpdir='';
-		protected $images = array();
-		protected $vars = array();
-		protected $segments = array();
-		const PIXEL_TO_CM = 0.026458333;
-		/**
-		 * Class constructor
-		 *
-		 * @param string $filename the name of the odt file
-		 * @throws OdfException
-		 */
-		public function __construct($filename, $config = array())
-		{
-			clearstatcache();
-
-			if (! is_array($config)) {
-				throw new OdfException('Configuration data must be provided as array');
-			}
-			foreach ($config as $configKey => $configValue) {
-				if (array_key_exists($configKey, $this->config)) {
-					$this->config[$configKey] = $configValue;
-				}
-			}
-
-			$md5uniqid = md5(uniqid());
-			if ($this->config['PATH_TO_TMP']) $this->tmpdir = preg_replace('|[\/]$|','',$this->config['PATH_TO_TMP']);	// Remove last \ or /
-			$this->tmpdir .= ($this->tmpdir?'/':'').$md5uniqid;
-			$this->tmpfile = $this->tmpdir.'/'.$md5uniqid.'.odt';	// We keep .odt extension to allow OpenOffice usage during debug.
-
-			// A working directory is required for some zip proxy like PclZipProxy
-			if (in_array($this->config['ZIP_PROXY'],array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) {
-				throw new OdfException('Temporary directory '.$this->config['PATH_TO_TMP'].' must exists');
-			}
-
-			// Create tmp direcoty (will be deleted in destructor)
-			if (!file_exists($this->tmpdir)) {
-				$result=mkdir($this->tmpdir);
-			}
-
-			// Load zip proxy
-			$zipHandler = $this->config['ZIP_PROXY'];
-			if (!defined('PCLZIP_TEMPORARY_DIR')) define('PCLZIP_TEMPORARY_DIR',$this->tmpdir);
-			include_once('zip/'.$zipHandler.'.php');
-			if (! class_exists($this->config['ZIP_PROXY'])) {
-				throw new OdfException($this->config['ZIP_PROXY'] . ' class not found - check your php settings');
+	'ZIP_PROXY' => 'PclZipProxy',	// PclZipProxy, PhpZipProxy
+	'DELIMITER_LEFT' => '{',
+	'DELIMITER_RIGHT' => '}',
+	'PATH_TO_TMP' => '/tmp'
+	);
+	protected $file;
+	protected $contentXml;			// To store content of content.xml file
+	protected $stylesXml;			// To store content of styles.xml file
+	protected $manifestXml;			// To store content of META-INF/manifest.xml file
+	protected $tmpfile;
+	protected $tmpdir='';
+	protected $images = array();
+	protected $vars = array();
+	protected $segments = array();
+	const PIXEL_TO_CM = 0.026458333;
+	/**
+	 * Class constructor
+	 *
+	 * @param string $filename the name of the odt file
+	 * @throws OdfException
+	 */
+	public function __construct($filename, $config = array())
+	{
+		clearstatcache();
+
+		if (! is_array($config)) {
+			throw new OdfException('Configuration data must be provided as array');
+		}
+		foreach ($config as $configKey => $configValue) {
+			if (array_key_exists($configKey, $this->config)) {
+				$this->config[$configKey] = $configValue;
 			}
-			$this->file = new $zipHandler($this->tmpdir);
+		}
 
+		$md5uniqid = md5(uniqid());
+		if ($this->config['PATH_TO_TMP']) $this->tmpdir = preg_replace('|[\/]$|','',$this->config['PATH_TO_TMP']);	// Remove last \ or /
+		$this->tmpdir .= ($this->tmpdir?'/':'').$md5uniqid;
+		$this->tmpfile = $this->tmpdir.'/'.$md5uniqid.'.odt';	// We keep .odt extension to allow OpenOffice usage during debug.
 
-			if ($this->file->open($filename) !== true) {	// This also create the tmpdir directory
-				throw new OdfException("Error while Opening the file '$filename' - Check your odt filename");
-			}
-			if (($this->contentXml = $this->file->getFromName('content.xml')) === false) {
-				throw new OdfException("Nothing to parse - Check that the content.xml file is correctly formed in source file '$filename'");
-			}
-			if (($this->manifestXml = $this->file->getFromName('META-INF/manifest.xml')) === false) {
- 				throw new OdfException("Something is wrong with META-INF/manifest.xml in source file '$filename'");
-			}
-			if (($this->stylesXml = $this->file->getFromName('styles.xml')) === false) {
-				throw new OdfException("Nothing to parse - Check that the styles.xml file is correctly formed in source file '$filename'");
-			}
-			$this->file->close();
+		// A working directory is required for some zip proxy like PclZipProxy
+		if (in_array($this->config['ZIP_PROXY'],array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) {
+			throw new OdfException('Temporary directory '.$this->config['PATH_TO_TMP'].' must exists');
+		}
 
+		// Create tmp direcoty (will be deleted in destructor)
+		if (!file_exists($this->tmpdir)) {
+			$result=mkdir($this->tmpdir);
+		}
 
-			//print "tmpdir=".$tmpdir;
-			//print "filename=".$filename;
-			//print "tmpfile=".$tmpfile;
+		// Load zip proxy
+		$zipHandler = $this->config['ZIP_PROXY'];
+		if (!defined('PCLZIP_TEMPORARY_DIR')) define('PCLZIP_TEMPORARY_DIR',$this->tmpdir);
+		include_once('zip/'.$zipHandler.'.php');
+		if (! class_exists($this->config['ZIP_PROXY'])) {
+			throw new OdfException($this->config['ZIP_PROXY'] . ' class not found - check your php settings');
+		}
+		$this->file = new $zipHandler($this->tmpdir);
 
-			copy($filename, $this->tmpfile);
 
-			$this->_moveRowSegments();
+		if ($this->file->open($filename) !== true) {	// This also create the tmpdir directory
+			throw new OdfException("Error while Opening the file '$filename' - Check your odt filename");
 		}
-
-		/**
-		 * Assing a template variable
-		 *
-		 * @param string $key name of the variable within the template
-		 * @param string $value replacement value
-		 * @param bool $encode if true, special XML characters are encoded
-		 * @throws OdfException
-		 * @return odf
-		 */
-		public function setVars($key, $value, $encode = true, $charset = 'ISO-8859')
-		{
-                    $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT'];
-		    // TODO Warning string may be:
-		    // <text:span text:style-name="T13">{</text:span><text:span text:style-name="T12">aaa</text:span><text:span text:style-name="T13">}</text:span>
-		    // instead of {aaa} so we should enhance this function.
-            //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'<br>';
-		    if (strpos($this->contentXml, $tag) === false && strpos($this->stylesXml , $tag) === false) {
-                //if (strpos($this->contentXml, '">'. $key . '</text;span>') === false) {
-		        throw new OdfException("var $key not found in the document");
-                //}
-		    }
-			$value = $encode ? htmlspecialchars($value) : $value;
-			$value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value;
-			$this->vars[$tag] = str_replace("\n", "<text:line-break/>", $value);
-			return $this;
-		}
-		
-		/**
-		 * Assing a template variable
-		 *
-		 * @param string $key name of the variable within the template
-		 * @param string $value replacement value
-		 * @param bool $encode if true, special XML characters are encoded
-		 * @throws OdfException
-		 * @return odf
-		 */
-		public function setVarsHeadFooter($key, $value, $encode = true, $charset = 'ISO-8859')
-		{
-			$tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT'];
-			// TODO Warning string may be:
-			// <text:span text:style-name="T13">{</text:span><text:span text:style-name="T12">aaa</text:span><text:span text:style-name="T13">}</text:span>
-			// instead of {aaa} so we should enhance this function.
-			//print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'<br>';
-			if (strpos($this->stylesXml, $tag) === false && strpos($this->stylesXml , $tag) === false) {
+		if (($this->contentXml = $this->file->getFromName('content.xml')) === false) {
+			throw new OdfException("Nothing to parse - Check that the content.xml file is correctly formed in source file '$filename'");
+		}
+		if (($this->manifestXml = $this->file->getFromName('META-INF/manifest.xml')) === false) {
+			throw new OdfException("Something is wrong with META-INF/manifest.xml in source file '$filename'");
+		}
+		if (($this->stylesXml = $this->file->getFromName('styles.xml')) === false) {
+			throw new OdfException("Nothing to parse - Check that the styles.xml file is correctly formed in source file '$filename'");
+		}
+		$this->file->close();
+
+
+		//print "tmpdir=".$tmpdir;
+		//print "filename=".$filename;
+		//print "tmpfile=".$tmpfile;
+
+		copy($filename, $this->tmpfile);
+
+		$this->_moveRowSegments();
+	}
+
+	/**
+	 * Assing a template variable
+	 *
+	 * @param string $key name of the variable within the template
+	 * @param string $value replacement value
+	 * @param bool $encode if true, special XML characters are encoded
+	 * @throws OdfException
+	 * @return odf
+	 */
+	public function setVars($key, $value, $encode = true, $charset = 'ISO-8859')
+	{
+		$tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT'];
+		// TODO Warning string may be:
+		// <text:span text:style-name="T13">{</text:span><text:span text:style-name="T12">aaa</text:span><text:span text:style-name="T13">}</text:span>
+		// instead of {aaa} so we should enhance this function.
+		//print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'<br>';
+		if (strpos($this->contentXml, $tag) === false && strpos($this->stylesXml , $tag) === false) {
 			//if (strpos($this->contentXml, '">'. $key . '</text;span>') === false) {
-				throw new OdfException("var $key not found in the document");
-				//}
-			}
-			$value = $encode ? htmlspecialchars($value) : $value;
-				$value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value;
-				$this->vars[$tag] = str_replace("\n", "<text:line-break/>", $value);
-				return $this;
+			throw new OdfException("var $key not found in the document");
+			//}
 		}
-
-		/**
-		 * Evaluating php codes inside the ODT and output the buffer (print, echo) inplace of the code
-		 *
-		 */
-		public function phpEval()
-		{
-			preg_match_all('/[\{\<]\?(php)?\s+(?P<content>.+)\?[\}\>]/iU',$this->contentXml, $matches); // detecting all {?php code ?} or <?php code ? >
-			for ($i=0;$i < count($matches['content']);$i++) {
-				try {
+		$value = $encode ? htmlspecialchars($value) : $value;
+		$value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value;
+		$this->vars[$tag] = str_replace("\n", "<text:line-break/>", $value);
+		return $this;
+	}
+
+	/**
+	 * Assing a template variable
+	 *
+	 * @param string $key name of the variable within the template
+	 * @param string $value replacement value
+	 * @param bool $encode if true, special XML characters are encoded
+	 * @throws OdfException
+	 * @return odf
+	 */
+	public function setVarsHeadFooter($key, $value, $encode = true, $charset = 'ISO-8859')
+	{
+		$tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT'];
+		// TODO Warning string may be:
+		// <text:span text:style-name="T13">{</text:span><text:span text:style-name="T12">aaa</text:span><text:span text:style-name="T13">}</text:span>
+		// instead of {aaa} so we should enhance this function.
+		//print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'<br>';
+		if (strpos($this->stylesXml, $tag) === false && strpos($this->stylesXml , $tag) === false) {
+			//if (strpos($this->contentXml, '">'. $key . '</text;span>') === false) {
+			throw new OdfException("var $key not found in the document");
+			//}
+		}
+		$value = $encode ? htmlspecialchars($value) : $value;
+		$value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value;
+		$this->vars[$tag] = str_replace("\n", "<text:line-break/>", $value);
+		return $this;
+	}
+
+	/**
+	 * Evaluating php codes inside the ODT and output the buffer (print, echo) inplace of the code
+	 *
+	 */
+	public function phpEval()
+	{
+		preg_match_all('/[\{\<]\?(php)?\s+(?P<content>.+)\?[\}\>]/iU',$this->contentXml, $matches); // detecting all {?php code ?} or <?php code ? >
+		for ($i=0;$i < count($matches['content']);$i++) {
+			try {
 				$ob_output = ''; // flush the output for each code. This var will be filled in by the eval($code) and output buffering : any print or echo or output will be redirected into this variable
 				$code = $matches['content'][$i];
 				ob_start();
@@ -171,363 +171,400 @@ class Odf
 				$ob_output = ob_get_contents(); // send the content of the buffer into $ob_output
 				$this->contentXml = str_replace($matches[0][$i], $ob_output, $this->contentXml);
 				ob_end_clean();
-				} catch (Exception $e) {
-					ob_end_clean();
-					$this->contentXml = str_replace($matches[0][$i], 'ERROR: there was a problem while evaluating this portion of code, please fix it: '.$e, $this->contentXml);
-				}
-			}
-			return 0;
-		}
-
-		/**
-		 * Assign a template variable as a picture
-		 *
-		 * @param string $key name of the variable within the template
-		 * @param string $value path to the picture
-		 * @throws OdfException
-		 * @return odf
-		 */
-		public function setImage($key, $value)
-		{
-			$filename = strtok(strrchr($value, '/'), '/.');
-			$file = substr(strrchr($value, '/'), 1);
-			$size = @getimagesize($value);
-			if ($size === false) {
-				throw new OdfException("Invalid image");
+			} catch (Exception $e) {
+				ob_end_clean();
+				$this->contentXml = str_replace($matches[0][$i], 'ERROR: there was a problem while evaluating this portion of code, please fix it: '.$e, $this->contentXml);
 			}
-			list ($width, $height) = $size;
-			$width *= self::PIXEL_TO_CM;
-			$height *= self::PIXEL_TO_CM;
-			$xml = <<<IMG
+		}
+		return 0;
+	}
+
+	/**
+	 * Assign a template variable as a picture
+	 *
+	 * @param string $key name of the variable within the template
+	 * @param string $value path to the picture
+	 * @throws OdfException
+	 * @return odf
+	 */
+	public function setImage($key, $value)
+	{
+		$filename = strtok(strrchr($value, '/'), '/.');
+		$file = substr(strrchr($value, '/'), 1);
+		$size = @getimagesize($value);
+		if ($size === false) {
+			throw new OdfException("Invalid image");
+		}
+		list ($width, $height) = $size;
+		$width *= self::PIXEL_TO_CM;
+		$height *= self::PIXEL_TO_CM;
+		$xml = <<<IMG
 			<draw:frame draw:style-name="fr1" draw:name="$filename" text:anchor-type="aschar" svg:width="{$width}cm" svg:height="{$height}cm" draw:z-index="3"><draw:image xlink:href="Pictures/$file" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/></draw:frame>
 IMG;
-			$this->images[$value] = $file;
-			$this->setVars($key, $xml, false);
-			return $this;
-		}
-
-		/**
-		 * Move segment tags for lines of tables
-		 * Called automatically within the constructor
-		 *
-		 * @return void
-		 */
-		private function _moveRowSegments()
+		$this->images[$value] = $file;
+		$this->setVars($key, $xml, false);
+		return $this;
+	}
+
+	/**
+	 * Move segment tags for lines of tables
+	 * Called automatically within the constructor
+	 *
+	 * @return void
+	 */
+	private function _moveRowSegments()
+	{
+		// Search all possible rows in the document
+		$reg1 = "#<table:table-row[^>]*>(.*)</table:table-row>#smU";
+		preg_match_all($reg1, $this->contentXml, $matches);
+		for ($i = 0, $size = count($matches[0]); $i < $size; $i++) {
+			// Check if the current row contains a segment row.*
+			$reg2 = '#\[!--\sBEGIN\s(row.[\S]*)\s--\](.*)\[!--\sEND\s\\1\s--\]#sm';
+			if (preg_match($reg2, $matches[0][$i], $matches2)) {
+				$balise = str_replace('row.', '', $matches2[1]);
+				// Move segment tags around the row
+				$replace = array(
+				'[!-- BEGIN ' . $matches2[1] . ' --]'	=> '',
+				'[!-- END ' . $matches2[1] . ' --]'		=> '',
+				'<table:table-row'							=> '[!-- BEGIN ' . $balise . ' --]<table:table-row',
+				'</table:table-row>'						=> '</table:table-row>[!-- END ' . $balise . ' --]'
+				);
+				$replacedXML = str_replace(array_keys($replace), array_values($replace), $matches[0][$i]);
+				$this->contentXml = str_replace($matches[0][$i], $replacedXML, $this->contentXml);
+			}
+		}
+	}
+
+	/**
+	 * Merge template variables
+	 * Called automatically for a save
+	 *
+	 * @param  string	$type		'content' or 'styles'
+	 * @return void
+	 */
+	private function _parse($type='content')
+	{
+		// Conditionals substitution
+		// Note: must be done before content substitution, else the variable will be replaced by its value and the conditional won't work anymore
+		foreach($this->vars as $key => $value)
 		{
-			// Search all possible rows in the document
-			$reg1 = "#<table:table-row[^>]*>(.*)</table:table-row>#smU";
-			preg_match_all($reg1, $this->contentXml, $matches);
-			for ($i = 0, $size = count($matches[0]); $i < $size; $i++) {
-				// Check if the current row contains a segment row.*
-				$reg2 = '#\[!--\sBEGIN\s(row.[\S]*)\s--\](.*)\[!--\sEND\s\\1\s--\]#sm';
-				if (preg_match($reg2, $matches[0][$i], $matches2)) {
-					$balise = str_replace('row.', '', $matches2[1]);
-					// Move segment tags around the row
-					$replace = array(
-					'[!-- BEGIN ' . $matches2[1] . ' --]'	=> '',
-					'[!-- END ' . $matches2[1] . ' --]'		=> '',
-					'<table:table-row'							=> '[!-- BEGIN ' . $balise . ' --]<table:table-row',
-					'</table:table-row>'						=> '</table:table-row>[!-- END ' . $balise . ' --]'
-					);
-					$replacedXML = str_replace(array_keys($replace), array_values($replace), $matches[0][$i]);
-					$this->contentXml = str_replace($matches[0][$i], $replacedXML, $this->contentXml);
+			// If value is true (not 0 nor false nor null nor empty string)
+			if($value)
+			{
+				// Remove the IF tag
+				$this->contentXml = str_replace('[!-- IF '.$key.' --]', '', $this->contentXml);
+				// Remove everything between the ELSE tag (if it exists) and the ENDIF tag
+				$reg = '@(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
+				$this->contentXml = preg_replace($reg, '', $this->contentXml);
+			}
+			// Else the value is false, then two cases: no ELSE and we're done, or there is at least one place where there is an ELSE clause, then we replace it
+			else
+			{
+				// Find all conditional blocks for this variable: from IF to ELSE and to ENDIF
+				$reg = '@\[!--\sIF\s' . $key . '\s--\](.*)(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
+				preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER);
+				foreach($matches as $match) { // For each match, if there is an ELSE clause, we replace the whole block by the value in the ELSE clause
+					if (!empty($match[3])) $this->contentXml = str_replace($match[0], $match[3], $this->contentXml);
 				}
+				// Cleanup the other conditional blocks (all the others where there were no ELSE clause, we can just remove them altogether)
+				$this->contentXml = preg_replace($reg, '', $this->contentXml);
 			}
 		}
 
-		/**
-		 * Merge template variables
-		 * Called automatically for a save
-		 *
-                 * @param  string	$type		'content' or 'styles'
-		 * @return void
-		 */
-		private function _parse($type='content')
-		{
-                    // Conditionals substitution
-                    // Note: must be done before content substitution, else the variable will be replaced by its value and the conditional won't work anymore
-                    foreach($this->vars as $key => $value)
-                    {
-                        // If value is true (not 0 nor false nor null nor empty string)
-                        if($value)
-                        {
-                            // Remove the IF tag
-                            $this->contentXml = str_replace('[!-- IF '.$key.' --]', '', $this->contentXml);
-                            // Remove everything between the ELSE tag (if it exists) and the ENDIF tag
-                            $reg = '@(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
-                            $this->contentXml = preg_replace($reg, '', $this->contentXml);
-                        }
-                        // Else the value is false, then two cases: no ELSE and we're done, or there is at least one place where there is an ELSE clause, then we replace it
-                        else
-                        {
-                            // Find all conditional blocks for this variable: from IF to ELSE and to ENDIF
-                            $reg = '@\[!--\sIF\s' . $key . '\s--\](.*)(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
-                            preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER);
-                            foreach($matches as $match) { // For each match, if there is an ELSE clause, we replace the whole block by the value in the ELSE clause
-                                if (!empty($match[3])) $this->contentXml = str_replace($match[0], $match[3], $this->contentXml);
-                            }
-                            // Cleanup the other conditional blocks (all the others where there were no ELSE clause, we can just remove them altogether)
-                            $this->contentXml = preg_replace($reg, '', $this->contentXml);
-                        }
-                    }
-
-                    // Content (variable) substitution
-                    if ($type == 'content')	$this->contentXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->contentXml);
-                    // Styles substitution
-                    if ($type == 'styles')	$this->stylesXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->stylesXml);
-
-		}
-
-		/**
-		 * Add the merged segment to the document
-		 *
-		 * @param Segment $segment
-		 * @throws OdfException
-		 * @return odf
-		 */
-		public function mergeSegment(Segment $segment)
-		{
-			if (! array_key_exists($segment->getName(), $this->segments)) {
-				throw new OdfException($segment->getName() . 'cannot be parsed, has it been set yet ?');
+		// Content (variable) substitution
+		if ($type == 'content')	$this->contentXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->contentXml);
+		// Styles substitution
+		if ($type == 'styles')	$this->stylesXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->stylesXml);
+
+	}
+
+	/**
+	 * Add the merged segment to the document
+	 *
+	 * @param Segment $segment
+	 * @throws OdfException
+	 * @return odf
+	 */
+	public function mergeSegment(Segment $segment)
+	{
+		if (! array_key_exists($segment->getName(), $this->segments)) {
+			throw new OdfException($segment->getName() . 'cannot be parsed, has it been set yet ?');
+		}
+		$string = $segment->getName();
+		// $reg = '@<text:p[^>]*>\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]<\/text:p>@smU';
+		$reg = '@\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]@smU';
+		$this->contentXml = preg_replace($reg, $segment->getXmlParsed(), $this->contentXml);
+		return $this;
+	}
+
+	/**
+	 * Display all the current template variables
+	 *
+	 * @return string
+	 */
+	public function printVars()
+	{
+		return print_r('<pre>' . print_r($this->vars, true) . '</pre>', true);
+	}
+
+	/**
+	 * Display the XML content of the file from odt document
+	 * as it is at the moment
+	 *
+	 * @return string
+	 */
+	public function __toString()
+	{
+		return $this->contentXml;
+	}
+
+	/**
+	 * Display loop segments declared with setSegment()
+	 *
+	 * @return string
+	 */
+	public function printDeclaredSegments()
+	{
+		return '<pre>' . print_r(implode(' ', array_keys($this->segments)), true) . '</pre>';
+	}
+
+	/**
+	 * Declare a segment in order to use it in a loop
+	 *
+	 * @param string $segment
+	 * @throws OdfException
+	 * @return Segment
+	 */
+	public function setSegment($segment)
+	{
+		if (array_key_exists($segment, $this->segments)) {
+			return $this->segments[$segment];
+		}
+		// $reg = "#\[!--\sBEGIN\s$segment\s--\]<\/text:p>(.*)<text:p\s.*>\[!--\sEND\s$segment\s--\]#sm";
+		$reg = "#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm";
+		if (preg_match($reg, html_entity_decode($this->contentXml), $m) == 0) {
+			throw new OdfException("'$segment' segment not found in the document");
+		}
+		$this->segments[$segment] = new Segment($segment, $m[1], $this);
+		return $this->segments[$segment];
+	}
+	/**
+	 * Save the odt file on the disk
+	 *
+	 * @param string $file name of the desired file
+	 * @throws OdfException
+	 * @return void
+	 */
+	public function saveToDisk($file = null)
+	{
+		if ($file !== null && is_string($file)) {
+			if (file_exists($file) && !(is_file($file) && is_writable($file))) {
+				throw new OdfException('Permission denied : can\'t create ' . $file);
 			}
-			$string = $segment->getName();
-			// $reg = '@<text:p[^>]*>\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]<\/text:p>@smU';
-			$reg = '@\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]@smU';
-			$this->contentXml = preg_replace($reg, $segment->getXmlParsed(), $this->contentXml);
-			return $this;
-		}
-
-		/**
-		 * Display all the current template variables
-		 *
-		 * @return string
-		 */
-		public function printVars()
-		{
-			return print_r('<pre>' . print_r($this->vars, true) . '</pre>', true);
+			$this->_save();
+			copy($this->tmpfile, $file);
+		} else {
+			$this->_save();
 		}
-
-		/**
-		 * Display the XML content of the file from odt document
-		 * as it is at the moment
-		 *
-		 * @return string
-		 */
-		public function __toString()
-		{
-			return $this->contentXml;
+	}
+
+	/**
+	 * Write output file onto disk
+	 *
+	 * @throws OdfException
+	 * @return void
+	 */
+	private function _save()
+	{
+		$res=$this->file->open($this->tmpfile);    // tmpfile is odt template
+		$this->_parse('content');
+		$this->_parse('styles');
+
+		if (! $this->file->addFromString('content.xml', $this->contentXml)) {
+			throw new OdfException('Error during file export addFromString');
+		}
+		if (! $this->file->addFromString('styles.xml', $this->stylesXml)) {
+			throw new OdfException('Error during file export addFromString');
+		}
+		foreach ($this->images as $imageKey => $imageValue) {
+			// Add the image inside the ODT document
+			$this->file->addFile($imageKey, 'Pictures/' . $imageValue);
+			// Add the image to the Manifest (which maintains a list of images, necessary to avoid "Corrupt ODT file. Repair?" when opening the file with LibreOffice)
+			$this->addImageToManifest($imageValue);
+		}
+		if (! $this->file->addFromString('./META-INF/manifest.xml', $this->manifestXml)) {
+			throw new OdfException('Error during file export: manifest.xml');
+		}
+		$this->file->close();
+	}
+
+	/**
+	 * Update Manifest file according to added image files
+	 *
+	 * @param string	$file		Image file to add into manifest content
+	 */
+	public function addImageToManifest($file)
+	{
+		// Get the file extension
+		$ext = substr(strrchr($val, '.'), 1);
+		// Create the correct image XML entry to add to the manifest (this is necessary because ODT format requires that we keep a list of the images in the manifest.xml)
+		$add = ' <manifest:file-entry manifest:media-type="image/'.$ext.'" manifest:full-path="Pictures/'.$file.'"/>'."\n";
+		// Append the image to the manifest
+		$this->manifestXml = str_replace('</manifest:manifest>', $add.'</manifest:manifest>', $this->manifestXml); // we replace the manifest closing tag by the image XML entry + manifest closing tag (this results in appending the data, we do not overwrite anything)
+	}
+
+	/**
+	 * Export the file as attached file by HTTP
+	 *
+	 * @param string $name (optional)
+	 * @throws OdfException
+	 * @return void
+	 */
+	public function exportAsAttachedFile($name="")
+	{
+		$this->_save();
+		if (headers_sent($filename, $linenum)) {
+			throw new OdfException("headers already sent ($filename at $linenum)");
 		}
 
-		/**
-		 * Display loop segments declared with setSegment()
-		 *
-		 * @return string
-		 */
-		public function printDeclaredSegments()
+		if( $name == "" )
 		{
-			return '<pre>' . print_r(implode(' ', array_keys($this->segments)), true) . '</pre>';
+			$name = md5(uniqid()) . ".odt";
 		}
 
-		/**
-		 * Declare a segment in order to use it in a loop
-		 *
-		 * @param string $segment
-		 * @throws OdfException
-		 * @return Segment
-		 */
-		public function setSegment($segment)
+		header('Content-type: application/vnd.oasis.opendocument.text');
+		header('Content-Disposition: attachment; filename="'.$name.'"');
+		header('Content-Length: '.filesize($this->tmpfile));
+		readfile($this->tmpfile);
+	}
+
+	/**
+	 * Convert the ODT file to PDF and export the file as attached file by HTTP
+	 * Note: you need to have JODConverter and OpenOffice or LibreOffice installed and executable on the same system as where this php script will be executed. You also need to chmod +x odt2pdf.sh
+	 *
+	 * @param string $name (optional)
+	 * @throws OdfException
+	 * @return void
+	 */
+	public function exportAsAttachedPDF($name="")
+	{
+		global $conf;
+		 
+		if( $name == "" ) $name = md5(uniqid());
+
+		//dol_syslog(get_class($this).'::exportAsAttachedPDF $name='.$name, LOG_DEBUG);
+		$this->saveToDisk($name);
+
+		$execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2);	// 1 or 2
+		 
+		$name=str_replace('.odt', '', $name);
+		$command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name;
+		//dol_syslog('$execmethod='.$execmethod.' Run command='.$command);
+		if ($execmethod == 1)
 		{
-			if (array_key_exists($segment, $this->segments)) {
-				return $this->segments[$segment];
-			}
-			// $reg = "#\[!--\sBEGIN\s$segment\s--\]<\/text:p>(.*)<text:p\s.*>\[!--\sEND\s$segment\s--\]#sm";
-			$reg = "#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm";
-			if (preg_match($reg, html_entity_decode($this->contentXml), $m) == 0) {
-				throw new OdfException("'$segment' segment not found in the document");
-			}
-			$this->segments[$segment] = new Segment($segment, $m[1], $this);
-			return $this->segments[$segment];
+			exec($command, $output_arr, $retval);
 		}
-		/**
-		 * Save the odt file on the disk
-		 *
-		 * @param string $file name of the desired file
-		 * @throws OdfException
-		 * @return void
-		 */
-		public function saveToDisk($file = null)
+		if ($execmethod == 2)
 		{
-			if ($file !== null && is_string($file)) {
-				if (file_exists($file) && !(is_file($file) && is_writable($file))) {
-					throw new OdfException('Permission denied : can\'t create ' . $file);
+			$ok=0;
+			$handle = fopen($outputfile, 'w');
+			if ($handle)
+			{
+				dol_syslog("Run command ".$command);
+				$handlein = popen($command, 'r');
+				while (!feof($handlein))
+				{
+					$read = fgets($handlein);
+					fwrite($handle,$read);
+					$output_arr[]=$read;
 				}
-				$this->_save();
-				copy($this->tmpfile, $file);
-			} else {
-				$this->_save();
+				pclose($handlein);
+				fclose($handle);
 			}
+			if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
 		}
 
-		/**
-		 * Write output file onto disk
-		 *
-		 * @throws OdfException
-		 * @return void
-		 */
-		private function _save()
+		if($retval == 0)
 		{
-			$res=$this->file->open($this->tmpfile);    // tmpfile is odt template
-			$this->_parse('content');
-			$this->_parse('styles');
-
-			if (! $this->file->addFromString('content.xml', $this->contentXml)) {
-				throw new OdfException('Error during file export addFromString');
-			}
-			if (! $this->file->addFromString('styles.xml', $this->stylesXml)) {
-				throw new OdfException('Error during file export addFromString');
-			}
-			foreach ($this->images as $imageKey => $imageValue) {
-				// Add the image inside the ODT document
-				$this->file->addFile($imageKey, 'Pictures/' . $imageValue);
-                                // Add the image to the Manifest (which maintains a list of images, necessary to avoid "Corrupt ODT file. Repair?" when opening the file with LibreOffice)
-				$this->addImageToManifest($imageValue);
-			}
-        	if (! $this->file->addFromString('./META-INF/manifest.xml', $this->manifestXml)) {
-            	throw new OdfException('Error during file export: manifest.xml');
-        	}
-			$this->file->close();
-		}
-
-		/**
-		 * Update Manifest file according to added image files
-		 *
-		 * @param string	$file		Image file to add into manifest content
-		 */
-		public function addImageToManifest($file)
-		{
-                        // Get the file extension
-		        $ext = substr(strrchr($val, '.'), 1);
-                        // Create the correct image XML entry to add to the manifest (this is necessary because ODT format requires that we keep a list of the images in the manifest.xml)
-		        $add = ' <manifest:file-entry manifest:media-type="image/'.$ext.'" manifest:full-path="Pictures/'.$file.'"/>'."\n";
-                        // Append the image to the manifest
-		        $this->manifestXml = str_replace('</manifest:manifest>', $add.'</manifest:manifest>', $this->manifestXml); // we replace the manifest closing tag by the image XML entry + manifest closing tag (this results in appending the data, we do not overwrite anything)
-		}
-
-		/**
-		 * Export the file as attached file by HTTP
-		 *
-		 * @param string $name (optional)
-		 * @throws OdfException
-		 * @return void
-		 */
-		public function exportAsAttachedFile($name="")
-		{
-			$this->_save();
+			//dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG);
 			if (headers_sent($filename, $linenum)) {
 				throw new OdfException("headers already sent ($filename at $linenum)");
 			}
 
-			if( $name == "" )
-			{
-				$name = md5(uniqid()) . ".odt";
-			}
-
-			header('Content-type: application/vnd.oasis.opendocument.text');
-			header('Content-Disposition: attachment; filename="'.$name.'"');
-			header('Content-Length: '.filesize($this->tmpfile));
-			readfile($this->tmpfile);
-		}
-
-		/**
-		 * Convert the ODT file to PDF and export the file as attached file by HTTP
-		 * Note: you need to have JODConverter and OpenOffice or LibreOffice installed and executable on the same system as where this php script will be executed. You also need to chmod +x odt2pdf.sh
-		 *
-		 * @param string $name (optional)
-		 * @throws OdfException
-		 * @return void
-		 */
-		public function exportAsAttachedPDF($name="")
-                {
-                    if( $name == "" ) $name = md5(uniqid());
-
-                    $this->saveToDisk("$name.odt");
-                    exec("./odt2pdf.sh $name",$output,$ret_val);
-                    if($ret_val == 0)
-                    {
-                        if (headers_sent($filename, $linenum)) {
-                            throw new OdfException("headers already sent ($filename at $linenum)");
-                        }
-
-                        header('Content-type: application/pdf');
-                        header('Content-Disposition: attachment; filename="'.$name.'.pdf"');
-                        readfile("$name.pdf");
-                        unlink("$name.odt");
-                        unlink("$name.pdf");
-                    } else {
-                        echo "Error occured:<br>";
-                        foreach($output as $line)
-                            echo $line."<br>";
-                    }
-		}
-
-		/**
-		 * Returns a variable of configuration
-		 *
-		 * @return string The requested variable of configuration
-		 */
-		public function getConfig($configKey)
-		{
-			if (array_key_exists($configKey, $this->config)) {
-				return $this->config[$configKey];
+			if (!empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+				header('Content-type: application/pdf');
+				header('Content-Disposition: attachment; filename="'.$name.'.pdf"');
+				readfile("$name.pdf");
 			}
-			return false;
-		}
-		/**
-		 * Returns the temporary working file
-		 *
-		 * @return string le chemin vers le fichier temporaire de travail
-		 */
-		public function getTmpfile()
-		{
-			return $this->tmpfile;
+			unlink("$name.odt");
+		} else {
+			//dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG);
+			//dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr,true), LOG_DEBUG);
+			echo "Error occured:<br>";
+			foreach($output_arr as $line)
+				echo $line."<br>";
+			//dol_syslog(get_class($this).'::exportAsAttachedPDF ERROR $line='.$line, LOG_DEBUG);
 		}
-
-		/**
-		 * Delete the temporary file when the object is destroyed
-		 */
-		public function __destruct()
-		{
-			if (file_exists($this->tmpfile)) {
-				unlink($this->tmpfile);
-			}
-
-			if (file_exists($this->tmpdir)) {
-				$this->_rrmdir($this->tmpdir);
-				rmdir($this->tmpdir);
-			}
+	}
+
+	/**
+	 * Returns a variable of configuration
+	 *
+	 * @return string The requested variable of configuration
+	 */
+	public function getConfig($configKey)
+	{
+		if (array_key_exists($configKey, $this->config)) {
+			return $this->config[$configKey];
+		}
+		return false;
+	}
+	/**
+	 * Returns the temporary working file
+	 *
+	 * @return string le chemin vers le fichier temporaire de travail
+	 */
+	public function getTmpfile()
+	{
+		return $this->tmpfile;
+	}
+
+	/**
+	 * Delete the temporary file when the object is destroyed
+	 */
+	public function __destruct()
+	{
+		if (file_exists($this->tmpfile)) {
+			unlink($this->tmpfile);
 		}
 
-		/**
-		 * Empty the temporary working directory recursively
-		 * @param $dir the temporary working directory
-		 * @return void
-		 */
-		private function _rrmdir($dir)
-		{
-			if ($handle = opendir($dir)) {
-				while (false !== ($file = readdir($handle))) {
-					if ($file != '.' && $file != '..') {
-						if (is_dir($dir . '/' . $file)) {
-							$this->_rrmdir($dir . '/' . $file);
-							rmdir($dir . '/' . $file);
-						} else {
-							unlink($dir . '/' . $file);
-						}
+		if (file_exists($this->tmpdir)) {
+			$this->_rrmdir($this->tmpdir);
+			rmdir($this->tmpdir);
+		}
+	}
+
+	/**
+	 * Empty the temporary working directory recursively
+	 * @param $dir the temporary working directory
+	 * @return void
+	 */
+	private function _rrmdir($dir)
+	{
+		if ($handle = opendir($dir)) {
+			while (false !== ($file = readdir($handle))) {
+				if ($file != '.' && $file != '..') {
+					if (is_dir($dir . '/' . $file)) {
+						$this->_rrmdir($dir . '/' . $file);
+						rmdir($dir . '/' . $file);
+					} else {
+						unlink($dir . '/' . $file);
 					}
 				}
-				closedir($handle);
 			}
+			closedir($handle);
 		}
+	}
 }
 
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/odtphp/odt2pdf.sh b/htdocs/includes/odtphp/odt2pdf.sh
old mode 100644
new mode 100755
diff --git a/htdocs/install/default.css b/htdocs/install/default.css
index b5f8773db75ef5ad7b738be8efa1fa7e71253c6a..d6c354e092cbaae24b8c7a70a5e96124afb6a00a 100644
--- a/htdocs/install/default.css
+++ b/htdocs/install/default.css
@@ -61,10 +61,10 @@ padding: 0px 0px 0px 0px;
 margin: 0px 0px 0px 0px;
 }
 
-input[type=text] {
+input[type=text], input[type=password] {
     border: 1px solid #ACBCBB;
 }
-input[type=text]:focus, textarea:focus, select:focus {
+input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus {
     border: 1px solid #ACBCBB;
 	box-shadow: 0 0 5px #C091AF;
 }
diff --git a/htdocs/install/doctemplates/thirdparties/template_thirdparty.ods b/htdocs/install/doctemplates/thirdparties/template_thirdparty.ods
new file mode 100644
index 0000000000000000000000000000000000000000..c715d7fb80f94399f3a39710b5d67c73a91db913
Binary files /dev/null and b/htdocs/install/doctemplates/thirdparties/template_thirdparty.ods differ
diff --git a/htdocs/install/etape1.php b/htdocs/install/etape1.php
index 24e56a7ecf07fc9d477f7448b397058090cbcde8..53f1aba9e19cd1692867f793cf0731b77bb5ffa7 100644
--- a/htdocs/install/etape1.php
+++ b/htdocs/install/etape1.php
@@ -458,7 +458,7 @@ if (! $error && $db->connected && $action == "set")
         print '<tr><td>';
         print $langs->trans("ConfFileReload");
         print '</td>';
-        print '<td>'.$langs->trans("OK").'</td></tr>';
+        print '<td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
 
 
         $userroot=isset($_POST["db_user_root"])?$_POST["db_user_root"]:"";
@@ -508,7 +508,7 @@ if (! $error && $db->connected && $action == "set")
                         print $langs->trans("UserCreation").' : ';
                         print $dolibarr_main_db_user;
                         print '</td>';
-                        print '<td>'.$langs->trans("OK").'</td></tr>';
+                        print '<td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
                     }
                     else
                     {
@@ -542,7 +542,7 @@ if (! $error && $db->connected && $action == "set")
                     print $langs->trans("UserCreation").' : ';
                     print $dolibarr_main_db_user;
                     print '</td>';
-                    print '<td>'.$langs->trans("Error").'</td>';
+                    print '<td><img src="../theme/eldy/img/error.png" alt="Error"></td>';
                     print '</tr>';
 
                     // Affiche aide diagnostique
@@ -576,7 +576,7 @@ if (! $error && $db->connected && $action == "set")
                     print $langs->trans("DatabaseCreation")." (".$langs->trans("User")." ".$userroot.") : ";
                     print $dolibarr_main_db_name;
                     print '</td>';
-                    print "<td>".$langs->trans("OK")."</td></tr>";
+                    print '<td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
 
                     $check1=$newdb->getDefaultCharacterSetDatabase();
                     $check2=$newdb->getDefaultCollationDatabase();
@@ -606,7 +606,7 @@ if (! $error && $db->connected && $action == "set")
                 print $langs->trans("DatabaseCreation")." (".$langs->trans("User")." ".$userroot.") : ";
                 print $dolibarr_main_db_name;
                 print '</td>';
-                print '<td>'.$langs->trans("Error").'</td>';
+                print '<td><img src="../theme/eldy/img/error.png" alt="Error"></td>';
                 print '</tr>';
 
                 // Affiche aide diagnostique
@@ -632,43 +632,35 @@ if (! $error && $db->connected && $action == "set")
 
             if ($db->connected == 1)
             {
+                dolibarr_install_syslog("etape1: connexion to server by user ".$conf->db->user." is ok", LOG_DEBUG);
+                print "<tr><td>";
+                print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : ";
+                print $dolibarr_main_db_host;
+                print "</td><td>";
+                print '<img src="../theme/eldy/img/tick.png" alt="Ok">';
+                print "</td></tr>";
+
                 // si acces serveur ok et acces base ok, tout est ok, on ne va pas plus loin, on a meme pas utilise le compte root.
                 if ($db->database_selected == 1)
                 {
-                    dolibarr_install_syslog("etape1: connexion to server by user ".$conf->db->user." is ok", LOG_DEBUG);
-                    print "<tr><td>";
-                    print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : ";
-                    print $dolibarr_main_db_host;
-                    print "</td><td>";
-                    print $langs->trans("OK");
-                    print "</td></tr>";
-
                     dolibarr_install_syslog("etape1: connexion to database : ".$conf->db->name.", by user : ".$conf->db->user." is ok", LOG_DEBUG);
                     print "<tr><td>";
                     print $langs->trans("DatabaseConnection")." (".$langs->trans("User")." ".$conf->db->user.") : ";
                     print $dolibarr_main_db_name;
                     print "</td><td>";
-                    print $langs->trans("OK");
+                    print '<img src="../theme/eldy/img/tick.png" alt="Ok">';
                     print "</td></tr>";
 
                     $error = 0;
                 }
                 else
                 {
-                    dolibarr_install_syslog("etape1: connexion to server by user ".$conf->db->user." is ok", LOG_DEBUG);
-                    print "<tr><td>";
-                    print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : ";
-                    print $dolibarr_main_db_host;
-                    print "</td><td>";
-                    print $langs->trans("OK");
-                    print "</td></tr>";
-
                     dolibarr_install_syslog("etape1: connexion to database ".$conf->db->name.", by user : ".$conf->db->user." has failed", LOG_ERR);
                     print "<tr><td>";
                     print $langs->trans("DatabaseConnection")." (".$langs->trans("User")." ".$conf->db->user.") : ";
                     print $dolibarr_main_db_name;
                     print '</td><td>';
-                    print $langs->trans("Error");
+                    print '<img src="../theme/eldy/img/error.png" alt="Error">';
                     print "</td></tr>";
 
                     // Affiche aide diagnostique
@@ -688,7 +680,7 @@ if (! $error && $db->connected && $action == "set")
                 print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : ";
                 print $dolibarr_main_db_host;
                 print '</td><td>';
-                print '<font class="error">'.$db->error.'</div>';
+                print '<img src="../theme/eldy/img/error.png" alt="Error">';
                 print "</td></tr>";
 
                 // Affiche aide diagnostique
@@ -938,7 +930,7 @@ function write_conf_file($conffile)
 			print $langs->trans("SaveConfigurationFile");
 			print ' <strong>'.$conffile.'</strong>';
 			print "</td><td>";
-			print $langs->trans("OK");
+			print '<img src="../theme/eldy/img/tick.png" alt="Ok">';
 			print "</td></tr>";
 		}
 		else
diff --git a/htdocs/install/etape2.php b/htdocs/install/etape2.php
index 9ad310dec9d09694f10d683c32a6842c952481b5..92b5f2111b7413e2782e1563e114890b3d2bcddd 100644
--- a/htdocs/install/etape2.php
+++ b/htdocs/install/etape2.php
@@ -87,12 +87,12 @@ if ($action == "set")
     if ($db->connected == 1)
     {
         print "<tr><td>";
-        print $langs->trans("ServerConnection")." : ".$conf->db->host."</td><td>".$langs->trans("OK")."</td></tr>";
+        print $langs->trans("ServerConnection")." : ".$conf->db->host.'</td><td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
         $ok = 1 ;
     }
     else
     {
-        print "<tr><td>Failed to connect to server : ".$conf->db->host."</td><td>".$langs->trans("Error")."</td></tr>";
+        print "<tr><td>Failed to connect to server : ".$conf->db->host.'</td><td><img src="../theme/eldy/img/error.png" alt="Error"></td></tr>';
     }
 
     if ($ok)
@@ -104,7 +104,7 @@ if ($action == "set")
         else
         {
             dolibarr_install_syslog("etape2: Connexion failed to database : ".$conf->db->name);
-            print "<tr><td>Failed to select database ".$conf->db->name."</td><td>".$langs->trans("Error")."</td></tr>";
+            print "<tr><td>Failed to select database ".$conf->db->name.'</td><td><img src="../theme/eldy/img/error.png" alt="Error"></td></tr>';
             $ok = 0 ;
         }
     }
@@ -241,13 +241,13 @@ if ($action == "set")
             if ($error == 0)
             {
                 print '<tr><td>';
-                print $langs->trans("TablesAndPrimaryKeysCreation").'</td><td>'.$langs->trans("OK").'</td></tr>';
+                print $langs->trans("TablesAndPrimaryKeysCreation").'</td><td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
                 $ok = 1;
             }
         }
         else
         {
-            print '<tr><td>'.$langs->trans("ErrorFailedToFindSomeFiles",$dir).'</td><td><font class="error">'.$langs->trans("Error").'</font></td></tr>';
+            print '<tr><td>'.$langs->trans("ErrorFailedToFindSomeFiles",$dir).'</td><td><img src="../theme/eldy/img/error.png" alt="Error"></td></tr>';
             dolibarr_install_syslog("Failed to find files to create database in directory ".$dir,LOG_ERR);
         }
     }
@@ -388,7 +388,7 @@ if ($action == "set")
         if ($tablefound && $error == 0)
         {
             print '<tr><td>';
-            print $langs->trans("OtherKeysCreation").'</td><td>'.$langs->trans("OK").'</td></tr>';
+            print $langs->trans("OtherKeysCreation").'</td><td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
             $okkeys = 1;
         }
     }
@@ -466,11 +466,11 @@ if ($action == "set")
             print "<tr><td>".$langs->trans("FunctionsCreation")."</td>";
             if ($ok)
             {
-                print "<td>".$langs->trans("OK")."</td></tr>";
+                print '<td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
             }
             else
             {
-                print '<td><font class="error">'.$langs->trans("Error").'</font></td></tr>';
+                print '<td><img src="../theme/eldy/img/error.png" alt="Error"></td></tr>';
                 $ok = 1 ;
             }
 
@@ -588,11 +588,11 @@ if ($action == "set")
         print "<tr><td>".$langs->trans("ReferenceDataLoading")."</td>";
         if ($ok)
         {
-            print "<td>".$langs->trans("OK")."</td></tr>";
+            print '<td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
         }
         else
         {
-            print '<td><font class="error">'.$langs->trans("Error").'</font></td></tr>';
+            print '<td><img src="../theme/eldy/img/error.png" alt="Error"></td></tr>';
             $ok = 1;    // Data loading are not blocking errors
         }
     }
diff --git a/htdocs/install/fileconf.php b/htdocs/install/fileconf.php
index 5e58d07d28c412c1df6cec06c84c24a5e7fc506a..7a8e1ad1ee9c16e69fe1b68d6c58f182d8d4a251 100644
--- a/htdocs/install/fileconf.php
+++ b/htdocs/install/fileconf.php
@@ -406,7 +406,7 @@ if (! empty($force_install_message))
 	<tr class="hidesqlite">
 		<td class="label" valign="top"><b><?php echo $langs->trans("Password"); ?></b>
 		</td>
-		<td class="label" valign="top"><input type="text" id="db_pass" autocomplete="off"
+		<td class="label" valign="top"><input type="password" id="db_pass" autocomplete="off"
 			name="db_pass"
 			value="<?php
 			//$autofill=((! empty($dolibarr_main_db_pass))?$dolibarr_main_db_pass:$force_install_databasepass);
@@ -460,7 +460,7 @@ if (! empty($force_install_message))
 	<tr class="hidesqlite hideroot">
 		<td class="label" valign="top"><b><?php echo $langs->trans("Password"); ?></b>
 		</td>
-		<td class="label" valign="top"><input type="text" autocomplete="off"
+		<td class="label" valign="top"><input type="password" autocomplete="off"
 			id="db_pass_root" name="db_pass_root" class="needroot"
 			value="<?php
 			$autofill=((! empty($db_pass_root))?$db_pass_root:$force_install_databaserootpass);
diff --git a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql
index e8c1da2aa4f158ec0a810aa4de900a9582214a56..957dadf284512f516983c89bca7f9aaad502fb44 100755
--- a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql
+++ b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql
@@ -180,6 +180,7 @@ UPDATE llx_c_tva set localtax1=0, localtax1_type='0' where localtax1_type = '7';
 UPDATE llx_c_tva set localtax2=0, localtax2_type='0' where localtax2_type = '7';
 
 ALTER TABLE llx_facture_fourn_det ADD COLUMN info_bits integer NOT NULL DEFAULT 0 after date_end;
+ALTER TABLE llx_product_fournisseur_price ADD COLUMN info_bits integer NOT NULL DEFAULT 0 after tva_tx;
 
 ALTER TABLE llx_actioncomm ADD COLUMN code varchar(32) NULL after fk_action;
 
@@ -266,7 +267,6 @@ ALTER TABLE llx_commande_extrafields ADD INDEX idx_commande_extrafields (fk_obje
 ALTER TABLE llx_socpeople ADD COLUMN note_public text after note;
 ALTER TABLE llx_societe ADD COLUMN note_public text after note;
 
-ALTER TABLE llx_facture_fourn_det ADD COLUMN info_bits integer NOT NULL DEFAULT 0 after date_end;
 ALTER TABLE llx_actioncomm ADD COLUMN transparency integer after fk_user_action;
 
 INSERT INTO llx_c_action_trigger (rowid,code,label,description,elementtype,rang) VALUES (29,'FICHINTER_SENTBYMAIL','Intervention sent by mail','Executed when a intervention is sent by mail','ficheinter',29);
@@ -306,3 +306,44 @@ create table llx_projet_task_extrafields
   import_key                varchar(14)                          		-- import key
 ) ENGINE=innodb;
 ALTER TABLE llx_projet_task_extrafields ADD INDEX idx_projet_task_extrafields (fk_object);
+
+
+CREATE TABLE llx_opensurvey_comments (
+    id_comment INTEGER unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
+    id_sondage CHAR(16) NOT NULL,
+    comment text NOT NULL,
+    tms timestamp,
+    usercomment text
+) ENGINE=InnoDB;
+
+CREATE TABLE llx_opensurvey_sondage (
+       id_sondage VARCHAR(16) PRIMARY KEY,
+       id_sondage_admin CHAR(24),
+       commentaires text,
+       mail_admin VARCHAR(128),
+       nom_admin VARCHAR(64),
+       titre text,
+       date_fin datetime,
+       format VARCHAR(2),
+       mailsonde varchar(2) DEFAULT '0',
+       survey_link_visible integer DEFAULT 1,
+	   canedit integer DEFAULT 0,
+       origin varchar(64),
+       tms timestamp,
+	   sujet TEXT
+) ENGINE=InnoDB;
+CREATE TABLE llx_opensurvey_user_studs (
+    id_users INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
+    nom VARCHAR(64) NOT NULL,
+    id_sondage VARCHAR(16) NOT NULL,
+    reponses VARCHAR(100) NOT NULL,
+    tms timestamp
+) ENGINE=InnoDB;
+
+ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_comment (id_comment);
+ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_sondage (id_sondage);
+ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_id_sondage_admin (id_sondage_admin);
+ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_date_fin (date_fin);
+ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_id_users (id_users);
+ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_nom (nom);
+ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_id_sondage (id_sondage);
diff --git a/htdocs/opensurvey/sql/llx_opensurvey_comments.key.sql b/htdocs/install/mysql/tables/llx_opensurvey_comments.key.sql
similarity index 85%
rename from htdocs/opensurvey/sql/llx_opensurvey_comments.key.sql
rename to htdocs/install/mysql/tables/llx_opensurvey_comments.key.sql
index 3f7460f3e8aa9431eaddd76611d8dd34c38cf79d..33365f1ab207f4cb5a6b7b225c0258f61ee64d6f 100755
--- a/htdocs/opensurvey/sql/llx_opensurvey_comments.key.sql
+++ b/htdocs/install/mysql/tables/llx_opensurvey_comments.key.sql
@@ -15,8 +15,8 @@
 -- along with this program. If not, see <http://www.gnu.org/licenses/>.
 -- ============================================================================
 
-ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_comment id_comment;
-ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_sondage id_sondage;
+ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_comment (id_comment);
+ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_sondage (id_sondage);
 
 
 
diff --git a/htdocs/opensurvey/sql/llx_opensurvey_comments.sql b/htdocs/install/mysql/tables/llx_opensurvey_comments.sql
similarity index 100%
rename from htdocs/opensurvey/sql/llx_opensurvey_comments.sql
rename to htdocs/install/mysql/tables/llx_opensurvey_comments.sql
diff --git a/htdocs/opensurvey/sql/llx_opensurvey_sondage.key.sql b/htdocs/install/mysql/tables/llx_opensurvey_sondage.key.sql
similarity index 91%
rename from htdocs/opensurvey/sql/llx_opensurvey_sondage.key.sql
rename to htdocs/install/mysql/tables/llx_opensurvey_sondage.key.sql
index 377f8abc45e6e2d0a9f7ec5f52118a27d21f70c9..3bf5771811e4513b29448841cabcc90067857e0f 100755
--- a/htdocs/opensurvey/sql/llx_opensurvey_sondage.key.sql
+++ b/htdocs/install/mysql/tables/llx_opensurvey_sondage.key.sql
@@ -15,5 +15,5 @@
 -- along with this program. If not, see <http://www.gnu.org/licenses/>.
 -- ============================================================================
 
-ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_id_sondage_admin id_sondage_admin;
-ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_date_fin date_fin;
+ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_id_sondage_admin (id_sondage_admin);
+ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_date_fin (date_fin);
diff --git a/htdocs/opensurvey/sql/llx_opensurvey_sondage.sql b/htdocs/install/mysql/tables/llx_opensurvey_sondage.sql
similarity index 100%
rename from htdocs/opensurvey/sql/llx_opensurvey_sondage.sql
rename to htdocs/install/mysql/tables/llx_opensurvey_sondage.sql
diff --git a/htdocs/opensurvey/sql/llx_opensurvey_user_studs.key.sql b/htdocs/install/mysql/tables/llx_opensurvey_user_studs.key.sql
similarity index 100%
rename from htdocs/opensurvey/sql/llx_opensurvey_user_studs.key.sql
rename to htdocs/install/mysql/tables/llx_opensurvey_user_studs.key.sql
diff --git a/htdocs/opensurvey/sql/llx_opensurvey_user_studs.sql b/htdocs/install/mysql/tables/llx_opensurvey_user_studs.sql
similarity index 100%
rename from htdocs/opensurvey/sql/llx_opensurvey_user_studs.sql
rename to htdocs/install/mysql/tables/llx_opensurvey_user_studs.sql
diff --git a/htdocs/install/mysql/tables/llx_product.key.sql b/htdocs/install/mysql/tables/llx_product.key.sql
index 06ad7ce2f0a4275e2fe36b09336fd940352d873c..1500cfba762a8f8ddde861d953ac03dcc0f747b2 100644
--- a/htdocs/install/mysql/tables/llx_product.key.sql
+++ b/htdocs/install/mysql/tables/llx_product.key.sql
@@ -1,6 +1,6 @@
 -- ============================================================================
 -- Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
--- Copyright (C) 2004-2005 Laurent Destailleur  <eldy@users.sourceforge.net>
+-- Copyright (C) 2004-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
 -- Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
 --
 -- This program is free software; you can redistribute it and/or modify
@@ -24,3 +24,4 @@ ALTER TABLE llx_product ADD UNIQUE INDEX uk_product_ref (ref, entity);
 ALTER TABLE llx_product ADD INDEX idx_product_label (label);
 ALTER TABLE llx_product ADD INDEX idx_product_barcode (barcode);
 ALTER TABLE llx_product ADD INDEX idx_product_import_key (import_key);
+ALTER TABLE llx_product ADD INDEX idx_product_seuil_stock_alerte (seuil_stock_alerte);
diff --git a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql
index 2a26034c1309493d34a37a5e4dd4e79554c6503e..e48c3ce6f8244cd9779efa99917b283f03f12fc3 100644
--- a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql
+++ b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql
@@ -1,7 +1,7 @@
 -- ============================================================================
 -- Copyright (C) 2003		Rodolphe Quiedeville	<rodolphe@quiedeville.org>
 -- Copyright (C) 2009-2011	Laurent Destailleur		<eldy@users.sourceforge.net>
--- Copyright (C) 2009-2012	Regis Houssin			<regis.houssin@capnetworks.com>
+-- Copyright (C) 2009-2013	Regis Houssin			<regis.houssin@capnetworks.com>
 -- Copyright (C) 2012		Juanjo Menent			<jmenent@2byte.es>
 --
 -- This program is free software; you can redistribute it and/or modify
@@ -21,23 +21,23 @@
 
 create table llx_product_fournisseur_price
 (
-  rowid						integer AUTO_INCREMENT PRIMARY KEY,
-  entity					integer DEFAULT 1 NOT NULL,	   -- multi company id
-  datec						datetime,
-  tms							timestamp,
+  rowid					integer AUTO_INCREMENT PRIMARY KEY,
+  entity				integer DEFAULT 1 NOT NULL,	   -- multi company id
+  datec					datetime,
+  tms					timestamp,
   fk_product			integer,
-  fk_soc					integer,
+  fk_soc				integer,
   ref_fourn				varchar(30),
-  fk_availability	integer,	   
-  price						double(24,8) DEFAULT 0,
+  fk_availability		integer,	   
+  price					double(24,8) DEFAULT 0,
   quantity				double,
-  remise_percent			double NOT NULL DEFAULT 0,
+  remise_percent		double NOT NULL DEFAULT 0,
   remise				double NOT NULL DEFAULT 0,
   unitprice				double(24,8) DEFAULT 0,
-	charges					double(24,8) DEFAULT 0,
+  charges				double(24,8) DEFAULT 0,
   unitcharges			double(24,8) DEFAULT 0,
-  tva_tx					double(6,3) NOT NULL,
+  tva_tx				double(6,3) NOT NULL,
   info_bits				integer NOT NULL DEFAULT 0,
-  fk_user					integer,
-  import_key      varchar(14)                  -- Import key
+  fk_user				integer,
+  import_key			varchar(14)                  -- Import key
 )ENGINE=innodb;
diff --git a/htdocs/langs/ar_SA/main.lang b/htdocs/langs/ar_SA/main.lang
index f273f913d049a466020ec5cc34a7230a70cd0fe4..93e44d0cf438d46804c96567c44cfdf18d459635 100644
--- a/htdocs/langs/ar_SA/main.lang
+++ b/htdocs/langs/ar_SA/main.lang
@@ -15,7 +15,11 @@ FONTSIZEFORPDF=9
 SeparatorDecimal=.
 SeparatorThousand=None
 FormatDateShort=%d/%m/%Y
+FormatDateShortInpu=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
@@ -600,7 +604,6 @@ Prefix=بادئة
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 15:55:27).
 // Reference language: en_US -> ar_SA
-FormatDateShortJQuery=dd/mm/yy
 AddLink=إضافة وصلة
 Of=من
 SearchOf=البحث
diff --git a/htdocs/langs/bg_BG/main.lang b/htdocs/langs/bg_BG/main.lang
index 51df97caecba03b4fa6794916cf0ebe4c09ce18e..9356eeac9a0702bd6c3d289845a1994f966c772e 100644
--- a/htdocs/langs/bg_BG/main.lang
+++ b/htdocs/langs/bg_BG/main.lang
@@ -10,8 +10,11 @@ FONTSIZEFORPDF=9
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%d.%m.%Y
+FormatDateShortInput=%d.%m.%Y
 FormatDateShortJava=dd.MM.yyyy
+FormatDateShortJavaInput=dd.MM.yyyy
 FormatDateShortJQuery=dd.mm.yy
+FormatDateShortJQueryInput=dd.mm.yy
 FormatHourShort=%H:%M
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%d %b %Y
diff --git a/htdocs/langs/ca_ES/admin.lang b/htdocs/langs/ca_ES/admin.lang
index fc6bdd8bc00340d1e5361ee59674afbc44d08972..2ef97b1cb2667af2fbf505456fbc52b1d73d0ac5 100644
--- a/htdocs/langs/ca_ES/admin.lang
+++ b/htdocs/langs/ca_ES/admin.lang
@@ -357,7 +357,10 @@ ExtrafieldSelect=Llista de selecció
 ExtrafieldSeparator=Separador
 ExtrafieldCheckBox=Casella de verificació
 ExtrafieldRadio=Botó de selecció excloent
-ExtrafieldParamHelp=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpselect=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpcheckbox=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpradio=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpsellist=La llista ha de ser del table<br><br> per exemple : <br>table:label:(code)<br>
 LibraryToBuildPDF=Llibreria usada per a la creació d'arxius PDF
 WarningUsingFPDF=Atenció: El seu arxiu <b>conf.php</b> conté la directiva <b>dolibarr_pdf_force_fpdf=1</b>. Això fa que s'usi la llibreria FPDF per generar els seus arxius PDF. Aquesta llibreria és antiga i no cobreix algunes funcionalitats (Unicode, transparència d'imatges, idiomes ciríl · lics, àrabs o asiàtics, etc.), Pel que pot tenir problemes en la generació dels PDF.<br> Per resoldre-ho, i disposar d'un suport complet de PDF, pot descarregar la <a href="http://www.tcpdf.org/" target="_blank"> llibreria TCPDF </a>, i a continuació comentar o eliminar la línia <b>$dolibarr_pdf_force_fpdf=1</b>, i afegir al seu lloc <b>$dolibarr_lib_TCPDF_PATH='ruta_a_TCPDF'</b>
 LocalTaxDesc=Alguns països apliquen 2 o 3 taxes a cada línia de factura. Si és el cas, escolliu el tipus de la segona i tercera taxa i el seu valor. Els possibles tipus són: <br> 1: taxa local aplicable a productes i serveis sense IVA (IVA no s'aplica a la taxa local) <br> 2: taxa local s'aplica a productes i serveis abans de l'IVA (IVA es calcula sobre import + taxa local) <br> 3: taxa local s'aplica a productes sense IVA (IVA no s'aplica a la taxa local) <br> 4: taxa local s'aplica a productes abans de l'IVA (IVA es calcula sobre l'import + taxa local) <br> 5: taxa local s'aplica a serveis sense IVA (IVA no s'aplica a la taxa local) <br> 6: taxa local s'aplica a serveis abans de l'IVA (IVA es calcula sobre import + taxa local)
diff --git a/htdocs/langs/ca_ES/main.lang b/htdocs/langs/ca_ES/main.lang
index 35b4d437e4ee20735f17ddeca0d1b3d4b4a53816..b4689f1537dd5dd8663fc25c3517dc0c02d8da3a 100644
--- a/htdocs/langs/ca_ES/main.lang
+++ b/htdocs/langs/ca_ES/main.lang
@@ -4,8 +4,11 @@ DIRECTION=ltr
 SeparatorDecimal=,
 SeparatorThousand=
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
 FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%d %b %Y
diff --git a/htdocs/langs/da_DK/main.lang b/htdocs/langs/da_DK/main.lang
index 7dd615bfa86d5ff82bc8dc8fd10ade576f9fdc02..128bf629fc754242708f3550e5a04ad36602d927 100644
--- a/htdocs/langs/da_DK/main.lang
+++ b/htdocs/langs/da_DK/main.lang
@@ -14,7 +14,11 @@ CHARSET=UTF-8
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
@@ -624,7 +628,6 @@ Prefix=Præfiks
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 15:59:19).
 // Reference language: en_US -> da_DK
-FormatDateShortJQuery=dd/mm/yy
 AddLink=Tilføj link
 Of=af
 SearchOf=Søg
diff --git a/htdocs/langs/de_AT/main.lang b/htdocs/langs/de_AT/main.lang
index ed9d7b27ec26689316a554beaa483267bc9a481b..6a44f3dbfeee58650c48ea315938e46370e2d7ca 100644
--- a/htdocs/langs/de_AT/main.lang
+++ b/htdocs/langs/de_AT/main.lang
@@ -10,7 +10,11 @@ DIRECTION=ltr
 SeparatorDecimal=,
 SeparatorThousand=.
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/MM/yy
+FormatDateShortJQueryInput=dd/MM/yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
diff --git a/htdocs/langs/de_DE/main.lang b/htdocs/langs/de_DE/main.lang
index bac265965ccb55c4e94dca0ea157b50f56c6ce2a..88e22f914d8cd331bd4f630262a5405d6355b956 100644
--- a/htdocs/langs/de_DE/main.lang
+++ b/htdocs/langs/de_DE/main.lang
@@ -11,8 +11,11 @@ DIRECTION=ltr
 SeparatorDecimal=,
 SeparatorThousand=.
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
 FormatDateShortJQuery=dd/MM/yy
+FormatDateShortJQueryInput=dd/MM/yy
 FormatHourShort=%I:%M %p
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%d %b %Y
diff --git a/htdocs/langs/el_GR/main.lang b/htdocs/langs/el_GR/main.lang
index d37b716a9ba47770ace5953907ce0884e4ff7824..b38a1417ea8be59d3966ed05af1af12caed2732e 100644
--- a/htdocs/langs/el_GR/main.lang
+++ b/htdocs/langs/el_GR/main.lang
@@ -7,7 +7,11 @@ FONTSIZEFORPDF=9
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%I:%M %p
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%b %d, %Y
@@ -592,7 +596,6 @@ ShortSunday=Κ
 
 // START - Lines generated via autotranslator.php tool (2011-06-26 15:35:22).
 // Reference language: en_US -> el_GR
-FormatDateShortJQuery=dd/mm/yy
 AddLink=Προσθήκη συνδέσμου
 Of=του
 AmountByMonth=Ποσό ανά μήνα
diff --git a/htdocs/langs/en_AU/main.lang b/htdocs/langs/en_AU/main.lang
index 02b689c7c47eac04d483539a9c090f1fa0b07f83..e1c3f95b5ea336c37db4b7a132776b0be1ebe000 100644
--- a/htdocs/langs/en_AU/main.lang
+++ b/htdocs/langs/en_AU/main.lang
@@ -4,7 +4,11 @@ CHARSET=UTF-8
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
diff --git a/htdocs/langs/en_GB/main.lang b/htdocs/langs/en_GB/main.lang
index 8bd3243e226daaf0b49e1399bc50388a7df0b0a5..6ec5c920232febbab81e33dbe770f1d07660b59a 100644
--- a/htdocs/langs/en_GB/main.lang
+++ b/htdocs/langs/en_GB/main.lang
@@ -3,7 +3,11 @@ CHARSET=UTF-8
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
diff --git a/htdocs/langs/en_IN/main.lang b/htdocs/langs/en_IN/main.lang
index 795d89bce4ef3d29f77953266b9f8a9c5e2d1f40..8bf5df955b5a8a43c8b651c8bcff8e64e56791c6 100644
--- a/htdocs/langs/en_IN/main.lang
+++ b/htdocs/langs/en_IN/main.lang
@@ -4,7 +4,11 @@ DIRECTION=ltr
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%I:%M %p
 FormatDateTextShort=%b %d, %Y
 FormatDateText=%B %d, %Y
diff --git a/htdocs/langs/en_NZ/main.lang b/htdocs/langs/en_NZ/main.lang
index 1e6ca9a9ddc83cc6356f4891eda3ebe22fa3a316..d3f111999680cd0c0663c0ca686bcf1f72fc7dcb 100644
--- a/htdocs/langs/en_NZ/main.lang
+++ b/htdocs/langs/en_NZ/main.lang
@@ -4,7 +4,11 @@ CHARSET=UTF-8
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
diff --git a/htdocs/langs/en_SA/main.lang b/htdocs/langs/en_SA/main.lang
index 146ae3fd85e031db201a81077070e5631493d76f..cb8e3ba6e6d9d0490cb6ffd45b44512f373d7e4a 100644
--- a/htdocs/langs/en_SA/main.lang
+++ b/htdocs/langs/en_SA/main.lang
@@ -6,8 +6,11 @@ FONTSIZEFORPDF=9
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
 FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%I:%M %p
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%d %b %Y
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index e73e752fb2140de46ef6f324d34699689a27f928..290707219bbe6b96a0b52a9922e7efa66ad810b8 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -46,6 +46,8 @@ ErrorModuleRequireDolibarrVersion=Error, this module requires Dolibarr version %
 ErrorDecimalLargerThanAreForbidden=Error, a precision higher than <b>%s</b> is not supported.
 DictionnarySetup=Dictionary setup
 Dictionnary=Dictionaries
+ErrorReservedTypeSystemSystemAuto=Value 'system' and 'systemauto' for type is reserved. You can use 'user' as value to add your own record
+ErrorCodeCantContainZero=Code can't contain value 0
 DisableJavascript=Disable JavaScript and Ajax functions
 ConfirmAjax=Use Ajax confirmation popups
 UseSearchToSelectCompany=Use autocompletion fields to choose third parties (instead of using a list box).<br><br>Also if you have a large number of third parties (> 100 000), you can increase speed by setting constant SOCIETE_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string.
@@ -360,7 +362,10 @@ ExtrafieldSelect = Select list
 ExtrafieldSeparator=Separator
 ExtrafieldCheckBox=Checkbox
 ExtrafieldRadio=Radio button
-ExtrafieldParamHelp=Parameters list have to be like key,value<br><br> for exemple : <br>1,value1<br>2,value2<br>3,value3<br>... 
+ExtrafieldParamHelpselect=Parameters list have to be like key,value<br><br> for exemple : <br>1,value1<br>2,value2<br>3,value3<br>...
+ExtrafieldParamHelpcheckbox=Parameters list have to be like key,value<br><br> for exemple : <br>1,value1<br>2,value2<br>3,value3<br>...
+ExtrafieldParamHelpradio=Parameters list have to be like key,value<br><br> for exemple : <br>1,value1<br>2,value2<br>3,value3<br>...
+ExtrafieldParamHelpsellist=Parameters list have come from table<br><br> for exemple : <br>c_typent:libelle:id<br> 
 LibraryToBuildPDF=Library used to build PDF
 WarningUsingFPDF=Warning: Your <b>conf.php</b> contains directive <b>dolibarr_pdf_force_fpdf=1</b>. This means you use the FPDF library to generate PDF files. This library is old and does not support a lot of features (Unicode, image transparency, cyrillic, arab and asiatic languages, ...), so you may experience errors during PDF generation.<br>To solve this and have a full support of PDF generation, please download <a href="http://www.tcpdf.org/" target="_blank">TCPDF library</a>, then comment or remove the line <b>$dolibarr_pdf_force_fpdf=1</b>, and add instead <b>$dolibarr_lib_TCPDF_PATH='path_to_TCPDF_dir'</b>   
 LocalTaxDesc=Some countries apply 2 or 3 taxes on each invoice line. If this is the case, choose type for second and third tax and its rate. Possible type are:<br>1 : local tax apply on products and services without vat (vat is not applied on local tax)<br>2 : local tax apply on products and services before vat (vat is calculated on amount + localtax)<br>3 : local tax apply on products without vat (vat is not applied on local tax)<br>4 : local tax apply on products before vat (vat is calculated on amount + localtax)<br>5 : local tax apply on services without vat (vat is not applied on local tax)<br>6 : local tax apply on services before vat (vat is calculated on amount + localtax)
@@ -543,6 +548,7 @@ Permission98=Dispatch invoice accountancy lines
 Permission101=Read sendings
 Permission102=Create/modify sendings
 Permission104=Validate sendings
+Permission106=Export sendings
 Permission109=Delete sendings
 Permission111=Read financial accounts
 Permission112=Create/modify/delete and compare transactions
diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang
index 2355c11219444562f161ef6cf995f628a02f4d4e..33d52b04c947b82766cb7e32da6db41c593bdbc7 100644
--- a/htdocs/langs/en_US/agenda.lang
+++ b/htdocs/langs/en_US/agenda.lang
@@ -32,7 +32,7 @@ ViewCal=Month view
 ViewDay=Day view
 ViewWeek=Week view
 ViewWithPredefinedFilters= View with predefined filters
-AutoActions= Automatic filling of agenda
+AutoActions= Automatic filling
 AgendaAutoActionDesc= Define here events for which you want Dolibarr to create automatically an event in agenda. If nothing is checked (by default), only manual actions will be included in agenda.
 AgendaSetupOtherDesc= This page provides options to allow export of your Dolibarr events into an external calendar (thunderbird, google calendar, ...)
 AgendaExtSitesDesc=This page allows to declare external sources of calendars to see their events into Dolibarr agenda.
@@ -40,6 +40,7 @@ ActionsEvents= Events for which Dolibarr will create an action in agenda automat
 PropalValidatedInDolibarr= Proposal %s validated
 InvoiceValidatedInDolibarr= Invoice %s validated
 InvoiceBackToDraftInDolibarr=Invoice %s go back to draft status
+InvoiceDeleteDolibarr=Invoice %s deleted
 OrderValidatedInDolibarr= Order %s validated
 OrderApprovedInDolibarr=Order %s approved
 OrderBackToDraftInDolibarr=Order %s go back to draft status
@@ -66,6 +67,7 @@ AgendaUrlOptions4=<b>logint=%s</b> to restrict output to actions assigned to use
 AgendaUrlOptions5=<b>logind=%s</b> to restrict output to actions done by user <b>%s</b>.
 AgendaShowBirthdayEvents=Show birthday's contacts
 AgendaHideBirthdayEvents=Hide birthday's contacts
+Busy=Busy
 
 # External Sites ical
 ExportCal=Export calendar
diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang
index 41b08dd399fa398b1fd4389aa2647cfbd444cdba..a76156142d6a94d0fd2969a085888d91430f2a84 100644
--- a/htdocs/langs/en_US/bills.lang
+++ b/htdocs/langs/en_US/bills.lang
@@ -311,6 +311,8 @@ PaymentConditionShortPT_ORDER=On order
 PaymentConditionPT_ORDER=On order
 PaymentConditionShortPT_5050=50-50
 PaymentConditionPT_5050=50%% in advance, 50%% on delivery
+FixAmount=Fix amount
+VarAmount=Variable amount (%% tot.)
 
 # PaymentType
 PaymentTypeVIR=Bank deposit
diff --git a/htdocs/langs/en_US/commercial.lang b/htdocs/langs/en_US/commercial.lang
index b6bd7c9881a868a2dd54e1783fe56584b712af11..09fd8e6e30034c7460810fa9a2c486b8e3a9efda 100644
--- a/htdocs/langs/en_US/commercial.lang
+++ b/htdocs/langs/en_US/commercial.lang
@@ -81,6 +81,7 @@ ActionAC_SHIP=Send shipping by mail
 ActionAC_SUP_ORD=Send supplier order by mail
 ActionAC_SUP_INV=Send supplier invoice by mail
 ActionAC_OTH=Other
+ActionAC_OTH_AUTO=Other (automatically inserted events)
 ActionAC_MANUAL=Manually inserted events
 ActionAC_AUTO=Automatically inserted events
 Stats=Sales statistics
@@ -92,4 +93,4 @@ NoData=There is no data
 StatusProsp=Prospect status
 DraftPropals=Draft commercial proposals
 SearchPropal=Search a commercial proposal
-CommercialDashboard=Commercial summary
\ No newline at end of file
+CommercialDashboard=Commercial summary
diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang
index 5e3a36e50518b32fcacea658f6471255335c41be..a1b3cba500418565427c40a3022a1afebce68b17 100644
--- a/htdocs/langs/en_US/compta.lang
+++ b/htdocs/langs/en_US/compta.lang
@@ -152,4 +152,5 @@ Pcg_type=Pcg type
 Pcg_subtype=Pcg subtype
 InvoiceLinesToDispatch=Invoice lines to dispatch
 InvoiceDispatched=Dispatched invoices
-AccountancyDashboard=Accountancy summary
\ No newline at end of file
+AccountancyDashboard=Accountancy summary
+ByProductsAndServices=By products and services
diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang
index 48795ba2ce7663d96c5d9400b2038d09b91580cb..3cfee357c81ab5867057e0a048f82fc4efc80c8e 100644
--- a/htdocs/langs/en_US/errors.lang
+++ b/htdocs/langs/en_US/errors.lang
@@ -136,4 +136,5 @@ WarningLockFileDoesNotExists=Warning, once setup is finished, you must disable i
 WarningUntilDirRemoved=All security warnings (visible by admin users only) will remain active as long as the vulnerability is present (or that constant MAIN_REMOVE_INSTALL_WARNING is added in Setup->Other setup).
 WarningCloseAlways=Warning, closing is done even if amount differs between source and target elements. Enable this feature with caution.
 WarningUsingThisBoxSlowDown=Warning, using this box slow down seriously all pages showing the box.
-WarningClickToDialUserSetupNotComplete=Setup of ClickToDial information for your user are not complete (see tab ClickToDial onto your user card). 
\ No newline at end of file
+WarningClickToDialUserSetupNotComplete=Setup of ClickToDial information for your user are not complete (see tab ClickToDial onto your user card).
+WarningNotRelevant=Irrelevant operation for this dataset
diff --git a/htdocs/langs/en_US/externalsite.lang b/htdocs/langs/en_US/externalsite.lang
index 3ae2098b92a97d334ee325811b80f45db5943887..213fa314ab12d3d1669fd1f8acae6e646482157e 100644
--- a/htdocs/langs/en_US/externalsite.lang
+++ b/htdocs/langs/en_US/externalsite.lang
@@ -1,4 +1,5 @@
 # Dolibarr language file - en_US - externalsite
 CHARSET=UTF-8
 ExternalSiteSetup=Setup link to external website
-ExternalSiteURL=External Site URL
\ No newline at end of file
+ExternalSiteURL=External Site URL
+ExternalSiteModuleNotComplete=Module ExternalSite was not configured properly.
\ No newline at end of file
diff --git a/htdocs/langs/en_US/holiday.lang b/htdocs/langs/en_US/holiday.lang
index 24926ae5e531e499a071ddfa4c2d26586c98f8f1..dc442d7f35fbb994ba04c3388b9d99a69f87abb6 100644
--- a/htdocs/langs/en_US/holiday.lang
+++ b/htdocs/langs/en_US/holiday.lang
@@ -132,4 +132,9 @@ NoCPforMonth=No leave this month.
 Jours=days
 nbJours=Number days
 TitleAdminCP=Configuration of Holidays
-Permission20001=Read / Modify all requests of holidays
+Permission20001=Read/create/modify their holidays
+Permission20002=Read/modify all requests of holidays
+Permission20003=Delete their holidays requests
+Permission20004=Define users holidays
+Permission20005=Review log of modified holidays
+Permission20006=Access holidays monthly report
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index 28de6467cbb16243a5a98d6bdc4ada107c0932bf..c0e2f94d7f554818d8b7b4881381fc012380266c 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -4,8 +4,11 @@ DIRECTION=ltr
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%m/%d/%Y
+FormatDateShortInput=%m/%d/%Y
 FormatDateShortJava=MM/dd/yyyy
+FormatDateShortJavaInput=MM/dd/yyyy
 FormatDateShortJQuery=mm/dd/yy
+FormatDateShortJQueryInput=mm/dd/yy
 FormatHourShort=%I:%M %p
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%b %d, %Y
@@ -472,6 +475,8 @@ Report=Report
 Keyword=Mot clé
 Legend=Legend
 FillTownFromZip=Fill city from zip
+Fill=Fill
+Reset=Reset
 ShowLog=Show log
 File=File
 Files=Files
diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang
index 6a350078731111d035ce636d59127dcea2a9e3d7..bb6c4873c931f27907503293981f1619a2bf8a00 100644
--- a/htdocs/langs/en_US/other.lang
+++ b/htdocs/langs/en_US/other.lang
@@ -152,6 +152,7 @@ EMailTextOrderApproved=The order %s has been approved.
 EMailTextOrderApprovedBy=The order %s has been approved by %s.
 EMailTextOrderRefused=The order %s has been refused.
 EMailTextOrderRefusedBy=The order %s has been refused by %s.
+EMailTextExpeditionValidated=The shipping %s has been validated.
 ImportedWithSet=Importation data set
 DolibarrNotification=Automatic notification
 ResizeDesc=Enter new width <b>OR</b> new height. Ratio will be kept during resizing...
diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
index b58dec53dcbf3058b8b832e02c8d6a22417e30ac..19b1afc3a3f31c4f7427878b43e641128f5a3f12 100644
--- a/htdocs/langs/en_US/products.lang
+++ b/htdocs/langs/en_US/products.lang
@@ -111,10 +111,12 @@ ServiceLimitedDuration=If product is a service with limited duration:
 MultiPricesAbility=Activate the multi-prices
 MultiPricesNumPrices=Number of price
 MultiPriceLevelsName=Price categories
-AssociatedProductsAbility=Activate the sub-products 
-AssociatedProducts=Sub-products
-AssociatedProductsNumber=Number of products composing this product
-ParentProductsNumber=Number of parent product
+AssociatedProductsAbility=Activate the virtual products feature 
+AssociatedProducts=Virtual product
+AssociatedProductsNumber=Number of products composing this virtual product
+ParentProductsNumber=Number of parent virtual product
+IfZeroItIsNotAVirtualProduct=If 0, this product is not a virtual product
+IfZeroItIsNotUsedByVirtualProduct=If 0, this product is not used by any virtual product
 EditAssociate=Associate
 Translation=Translation
 KeywordFilter=Keyword filter
@@ -124,7 +126,7 @@ AddDel=Add/Delete
 Quantity=Quantity
 NoMatchFound=No match found
 ProductAssociationList=List of related products/services: name of product/service (quantity affected)
-ProductParentList=List of products/services with this product as a component
+ProductParentList=List of virtual products/services with this product as a component
 ErrorAssociationIsFatherOfThis=One of selected product is parent with current product
 DeleteProduct=Delete a product/service
 ConfirmDeleteProduct=Are you sure you want to delete this product/service?
@@ -184,4 +186,14 @@ AlwaysUseNewPrice=Always use current price of product/service
 AlwaysUseFixedPrice=Use the fixed price
 PriceByQuantity=Price by quantity
 PriceByQuantityRange=Quantity range
-ProductsDashboard=Products/Services summary
\ No newline at end of file
+ProductsDashboard=Products/Services summary
+### composition fabrication
+Building=Production and items dispatchment
+Build=Produce
+BuildIt=Produce & Dispatch
+BuildindListInfo=Available quantity for production per warehouse (set it to 0 for no further action)
+QtyNeed=Qty
+UnitPmp=Net unit VWAP
+CostPmpHT=Net total VWAP
+ProductUsedForBuild=Auto consumed by production
+ProductBuilded=Production completed
diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang
index 35aa3ca537a2606f24efdeb282fcc53d2c4531d7..8a836c7b3dc5a009f6ea1ad068bceef1ed21e95f 100644
--- a/htdocs/langs/en_US/stocks.lang
+++ b/htdocs/langs/en_US/stocks.lang
@@ -55,6 +55,7 @@ DeStockOnShipment=Decrease real stocks on shipment validation
 ReStockOnBill=Increase real stocks on suppliers invoices/credit notes validation
 ReStockOnValidateOrder=Increase real stocks on suppliers orders approbation
 ReStockOnDispatchOrder=Increase real stocks on manual dispatching into warehouses, after supplier order receiving
+ReStockOnDeleteInvoice=Increase real stocks on invoice deletion
 OrderStatusNotReadyToDispatch=Order has not yet or no more a status that allows dispatching of products in stock warehouses.
 StockDiffPhysicTeoric=Reason for difference stock physical and theoretical
 NoPredefinedProductToDispatch=No predefined products for this object. So no dispatching in stock is required.
@@ -86,4 +87,5 @@ PersonalStock=Personal stock %s
 ThisWarehouseIsPersonalStock=This warehouse represents personal stock of %s %s
 SelectWarehouseForStockDecrease=Choose warehouse to use for stock decrease
 SelectWarehouseForStockIncrease=Choose warehouse to use for stock increase
+NoStockAction=No stock action
 LastWaitingSupplierOrders=Orders waiting for receptions
\ No newline at end of file
diff --git a/htdocs/langs/es_ES/admin.lang b/htdocs/langs/es_ES/admin.lang
index c42a026c87f88d15ff31c59bc0b18a48befbad42..86b6cba5a971a413a5cbe5ef6f2b5f1c23c9de6e 100644
--- a/htdocs/langs/es_ES/admin.lang
+++ b/htdocs/langs/es_ES/admin.lang
@@ -45,6 +45,8 @@ ErrorModuleRequireDolibarrVersion=Error, este módulo requiere una versión %s o
 ErrorDecimalLargerThanAreForbidden=Error, las precisiones superiores a <b>%s</b> no están soportadas.
 DictionnarySetup=Diccionarios
 Dictionnary=Diccionarios
+ErrorReservedTypeSystemSystemAuto=El uso del tipo 'system' y 'systemauto' está reservado. Puede utilizar 'user' como valor para añadir su propio registro
+ErrorCodeCantContainZero=El código no puede contener el valor 0
 DisableJavascript=Desactivar las funciones Javascript
 ConfirmAjax=Utilizar los popups de confirmación Ajax
 UseSearchToSelectCompany=Utilizar un formulario de búsqueda para buscar terceros (en vez de lista desplegable)<br><br>Tenga en cuenta que si tiene un gran número de productos o servicios (>100 000), puede mejorar el rendimiento mediante la constante SOCIETE_DONOTSEARCH_ANYWHERE a 1 en Configuración->Varios. La búsqueda se limitará entonces al inicio de la cadena.
@@ -290,7 +292,7 @@ ServerNotAvailableOnIPOrPort=Servidor no disponible en la dirección <b>%s</b> e
 DoTestServerAvailability=Probar conectividad con el servidor
 DoTestSend=Probar envío
 DoTestSendHTML=Probar envío HTML
-ErrorCantUseRazInStartedYearIfNoYearMonthInMask=Error, no se puede usar opción @ si la secuencia {yy}{mm} o {yyyy}{mm} no se encuentra en la máscara.
+ErrorCantUseRazInStartedYearIfNoYearMonthInMask=Error, no se puede usar la opción @ si la secuencia {yy}{mm} o {yyyy}{mm} no se encuentra en la máscara.
 UMask=Parámetro UMask de nuevos archivos en Unix/Linux/BSD.
 UMaskExplanation=Este parámetro determina los derechos de los archivos creados en el servidor Dolibarr (durante la subida, por ejemplo).<br>Este debe ser el valor octal (por ejemplo, 0666 significa lectura / escritura para todos).<br>Este parámetro no tiene ningún efecto sobre un servidor Windows.
 SeeWikiForAllTeam=Vea el wiki para más detalles de todos los actores y de su organización
@@ -336,7 +338,7 @@ EnterRefToBuildUrl=Introduzca la referencia del objeto %s
 GetSecuredUrl=Obtener la URL calculada
 ButtonHideUnauthorized=Ocultar los botones de acciones no autorizadas en vez de mostrarlos atenuados
 TotalNumberOfActivatedModules=Número total de módulos activados: <b>%s</b>
-YouMustEnableOneModule=Debe activar al menos 1 módulo.
+YouMustEnableOneModule=Debe activar al menos un módulo.
 ProductVatMassChange=Modificar IVA en masa
 ProductVatMassChangeDesc=Esta página le permite cambiar el tipo de IVA definido en  los productos o servicios de un valor a otro. Tenga en cuenta que el cambio se lleva a cabo en masa sobre toda la base de datos.
 OldVATRates=Tasa de IVA antigua
@@ -357,7 +359,10 @@ ExtrafieldSelect=Lista de selección
 ExtrafieldSeparator=Separador
 ExtrafieldCheckBox=Casilla de verificación
 ExtrafieldRadio=Botón de selección excluyente
-ExtrafieldParamHelp=La lista debe ser en forma llave,valor<br><br> por ejemplo : <br>1,texto1<br>2,texto2<br>3,texto3<br>...
+ExtrafieldParamHelpselect=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpcheckbox=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpradio=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpsellist=La llista ha de ser del table<br><br> per exemple : <br>table:label:(code)<br>
 LibraryToBuildPDF=Librería usada para la creación de archivos PDF
 WarningUsingFPDF=Atención: Su archivo <b>conf.php</b> contiene la directiva <b>dolibarr_pdf_force_fpdf=1</b>. Esto hace que se use la librería FPDF para generar sus archivos PDF. Esta librería es antigua y no cubre algunas funcionalidades (Unicode, transparencia de imágenes, idiomas cirílicos, árabes o asiáticos, etc.), por lo que puede tener problemas en la generación de los PDF.<br>Para resolverlo, y disponer de un soporte completo de PDF, puede descargar la <a href="http://www.tcpdf.org/" target="_blank">librería TCPDF</a> , y a continuación comentar o eliminar la línea <b>$dolibarr_pdf_force_fpdf=1</b>, y añadir en su lugar <b>$dolibarr_lib_TCPDF_PATH='ruta_a_TCPDF'</b>   
 LocalTaxDesc=Algunos países aplican 2 o 3 tasas a cada línea de factura. Si es el caso, escoja el tipo de la segunda y tercera tasa y su valor. Los posibles tipos son:<br>1 : tasa local aplicable a productos y servicios sin IVA (IVA no se aplica en la tasa local)<br>2 : tasa local se aplica a productos y servicios antes del IVA (IVA se calcula sobre importe+tasa local)<br>3 : tasa local se aplica a productos sin IVA (IVA no se aplica en la tasa local)<br>4 : tasa local se aplica a productos antes del IVA (IVA se calcula sobre el importe+tasa local)<br>5 : tasa local se aplica a servicios sin IVA (IVA no se aplica a la tasa local)<br>6 : tasa local se aplica a servicios antes del IVA (IVA se calcula sobre importe + tasa local)
@@ -478,6 +483,8 @@ Module2900Name=GeoIPMaxmind
 Module2900Desc=Capacidades de conversión GeoIP Maxmind
 Module5000Name=Multi-empresa
 Module5000Desc=Permite gestionar varias empresas
+Module6000Name=Workflow
+Module6000Desc=Gestión de flujos de trabajo
 Module20000Name=Días libres
 Module20000Desc=Gestión de los días libres de los empleados
 Module50000Name=PayBox
@@ -541,6 +548,7 @@ Permission98=Desglosar líneas de facturas
 Permission101=Consultar expediciones
 Permission102=Crear/modificar expediciones
 Permission104=Validar expediciones
+Permission106=Exportar expediciones
 Permission109=Eliminar expediciones
 Permission111=Consultar cuentas financieras (cuentas bancarias, cajas)
 Permission112=Crear/modificar cantidad/eliminar registros bancarios
@@ -911,7 +919,7 @@ MAIN_ROUNDING_RULE_TOT=Tamaño rango para el redondeo (para algunos países que
 UnitPriceOfProduct=Precio unitario sin IVA de un producto
 TotalPriceAfterRounding=Precio total después del redondeo
 ParameterActiveForNextInputOnly=Parámetro efectivo solamente a partir de las próximas sesiones
-NoEventOrNoAuditSetup=No se han registrado eventos de seguridad. Esto puede ser normal si la auditoría no ha sido habilitado en la página "configuración->seguridad->auditoría".
+NoEventOrNoAuditSetup=No se han registrado eventos de seguridad. Esto puede ser normal si la auditoría no ha sido habilitada en la página "configuración->seguridad->auditoría".
 NoEventFoundWithCriteria=No se han encontrado eventos de seguridad para tales criterios de búsqueda.
 SeeLocalSendMailSetup=Ver la configuración local de sendmail
 BackupDesc=Para realizar una copia de seguridad completa de Dolibarr, usted debe:
diff --git a/htdocs/langs/es_ES/agenda.lang b/htdocs/langs/es_ES/agenda.lang
index e0131db59fef5062fb5a2b247238667c669017ee..70a768bec1553b268642bb7eeafa8c11ee1ca781 100644
--- a/htdocs/langs/es_ES/agenda.lang
+++ b/htdocs/langs/es_ES/agenda.lang
@@ -41,6 +41,7 @@ ActionsEvents=Eventos para que Dolibarr cree una acción de forma automática
 PropalValidatedInDolibarr=Presupuesto %s validado
 InvoiceValidatedInDolibarr=Factura %s validada
 InvoiceBackToDraftInDolibarr=Factura %s devuelta a borrador
+InvoiceDeleteDolibarr=Factura %s eliminada
 OrderValidatedInDolibarr=Pedido %s validado
 OrderApprovedInDolibarr=Pedido %s aprobado
 OrderBackToDraftInDolibarr=Pedido %s devuelto a borrador
diff --git a/htdocs/langs/es_ES/bills.lang b/htdocs/langs/es_ES/bills.lang
index ff1d75eb35893eee2b947115131ce38817104c4c..e4a414b8fed0162e20919b25f60097db20e4aecd 100644
--- a/htdocs/langs/es_ES/bills.lang
+++ b/htdocs/langs/es_ES/bills.lang
@@ -250,7 +250,7 @@ Deposit=Anticipo
 Deposits=Anticipos
 DiscountFromCreditNote=Descuento resultante del abono %s
 DiscountFromDeposit=Pagos de la factura de anticipo %s
-AbsoluteDiscountUse=Este tipo de crédito no puede ser utilizado en una factura antes de su validación
+AbsoluteDiscountUse=Este tipo de descuento no puede ser utilizado en una factura antes de su validación
 CreditNoteDepositUse=La factura debe de estar validada para poder utilizar este tipo de créditos
 NewGlobalDiscount=Nuevo descuento fijo
 NewRelativeDiscount=Nuevo descuento
@@ -287,6 +287,8 @@ TotalOfTwoDiscountMustEqualsOriginal=La suma del importe de los 2 nuevos descuen
 ConfirmRemoveDiscount=¿Está seguro de querer eliminar este descuento?
 RelatedBill=Factura asociada
 RelatedBills=Facturas asociadas
+FixAmount=Importe fijo
+VarAmount=Importe variable (%% total)
 
 # PaymentConditions
 PaymentConditionShortRECEP=A la recepción
diff --git a/htdocs/langs/es_ES/commercial.lang b/htdocs/langs/es_ES/commercial.lang
index 3b5d007aac97bfbd007341602d3a6b53e929a28f..9d774606bf0c56dc1a49a5c70549fcf66aabd833 100644
--- a/htdocs/langs/es_ES/commercial.lang
+++ b/htdocs/langs/es_ES/commercial.lang
@@ -81,6 +81,7 @@ ActionAC_SHIP=Envío expedición por correo
 ActionAC_SUP_ORD=Envío pedido a proveedor por correo
 ActionAC_SUP_INV=Envío factura de proveedor por correo
 ActionAC_OTH=Otra
+ActionAC_OTH_AUTO=Otra (eventos insertados automáticamente)
 ActionAC_MANUAL=Eventos creados manualmente
 ActionAC_AUTO=Eventos creados automáticamente
 Stats=Estadísticas de venta
diff --git a/htdocs/langs/es_ES/externalsite.lang b/htdocs/langs/es_ES/externalsite.lang
index 6052639eb4b00dd4395982d5479fbe57580445d5..131d9f69fc4d642e6995bb737cb42e6d37a78c31 100644
--- a/htdocs/langs/es_ES/externalsite.lang
+++ b/htdocs/langs/es_ES/externalsite.lang
@@ -1,4 +1,5 @@
 # Dolibarr language file - es_ES - externalsite
 CHARSET=UTF-8
 ExternalSiteSetup=Configuración del enlace al sitio web externo
-ExternalSiteURL=URL del sitio externo
\ No newline at end of file
+ExternalSiteURL=URL del sitio externo
+ExternalSiteModuleNotComplete=El módulo Sitio web externo no ha sido configurado correctamente.
\ No newline at end of file
diff --git a/htdocs/langs/es_ES/holiday.lang b/htdocs/langs/es_ES/holiday.lang
index ebf1a0457d933f93fa97cae71df6d97764b32ddd..93387f29525182fa1bda004c1856355fd5f13929 100644
--- a/htdocs/langs/es_ES/holiday.lang
+++ b/htdocs/langs/es_ES/holiday.lang
@@ -132,4 +132,9 @@ NoCPforMonth=Sin vacaciones este mes.
 Jours=días
 nbJours=Número de días
 TitleAdminCP=Configuración de las vacaciones
-Permission20001=Leer / Crear / Modificar sus vacaciones
\ No newline at end of file
+Permission20001=Consultar/crear/modificar sus vacaciones
+Permission20002=Consultar/modificar todas las solicitudes de permisos retribuídos
+Permission20003=Eliminar las solicitudes de permisos retribuídos
+Permission20004=Definir los permisos retribuídos de los usuarios
+Permission20005=Consultar el historial de modificaciones de permisos retribuidos
+Permission20006=Acceder al informe mensual de permisos retribuidos
\ No newline at end of file
diff --git a/htdocs/langs/es_ES/main.lang b/htdocs/langs/es_ES/main.lang
index b1c231a4a67b4ac1185622f4c829d1111a3bc3aa..aece1ad9d15991dabdf5f6ea948821dc3172e90f 100644
--- a/htdocs/langs/es_ES/main.lang
+++ b/htdocs/langs/es_ES/main.lang
@@ -4,8 +4,11 @@ DIRECTION=ltr
 SeparatorDecimal=,
 SeparatorThousand=
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
 FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%d %b %Y
diff --git a/htdocs/langs/es_ES/other.lang b/htdocs/langs/es_ES/other.lang
index 60af821e8c1dfe96975e24970df34780552ce450..6d53b9de9cbd6c257873e09d014646408a0f23a2 100644
--- a/htdocs/langs/es_ES/other.lang
+++ b/htdocs/langs/es_ES/other.lang
@@ -151,6 +151,7 @@ EMailTextOrderApproved=Pedido %s aprobado
 EMailTextOrderApprovedBy=Pedido %s aprobado por %s
 EMailTextOrderRefused=Pedido %s rechazado
 EMailTextOrderRefusedBy=Pedido %s rechazado por %s
+EMailTextExpeditionValidated=El envío %s ha sido validado.
 ImportedWithSet=Lote de importación (import key)
 DolibarrNotification=Notificación automática
 ResizeDesc=Introduzca el nuevo ancho <b>O</b> la nueva altura. La relación se conserva al cambiar el tamaño ...
diff --git a/htdocs/langs/es_ES/stocks.lang b/htdocs/langs/es_ES/stocks.lang
index fe51937ac65160d20a8bc446415d9ab756487a02..be0bf800bb8f2eaa008ce0b8816a02accc4049ed 100644
--- a/htdocs/langs/es_ES/stocks.lang
+++ b/htdocs/langs/es_ES/stocks.lang
@@ -54,6 +54,7 @@ DeStockOnShipment=Decrementar los stocks físicos sobre los envíos
 ReStockOnBill=Incrementar los stocks físicos sobre las facturas/abonos de proveedores
 ReStockOnValidateOrder=Incrementar los stocks físicos sobre los pedidos a proveedores
 ReStockOnDispatchOrder=Incrementa los stocks físicos en el desglose manual de la recepción de los pedidos a proveedores en los almacenes
+ReStockOnDeleteInvoice=Incrementa los stocks físicos en la eliminación de facturas
 OrderStatusNotReadyToDispatch=El pedido aún no está o no tiene un estado que permita un desglose de stock.
 StockDiffPhysicTeoric=Motivo de la diferencia entre valores físicos y teóricos
 NoPredefinedProductToDispatch=No hay productos predefinidos en este objeto. Por lo tanto no se puede realizar un desglose de stock.
@@ -85,4 +86,5 @@ PersonalStock=Stock personal %s
 ThisWarehouseIsPersonalStock=Este almacén representa el stock personal de %s %s
 SelectWarehouseForStockDecrease=Seleccione el almacén a usar en el decremento de stock
 SelectWarehouseForStockIncrease=Seleccione el almacén a usar en el incremento de stock
+NoStockAction=Sin acciones sobre el stock
 LastWaitingSupplierOrders=Pedidos en espera de recepción
\ No newline at end of file
diff --git a/htdocs/langs/es_HN/main.lang b/htdocs/langs/es_HN/main.lang
index 390b2055e2f25e0dc2d31fcb033d0c9729aab0e4..421e7598de5ef373a490dfc27fc8d0628635b455 100644
--- a/htdocs/langs/es_HN/main.lang
+++ b/htdocs/langs/es_HN/main.lang
@@ -3,15 +3,6 @@ CHARSET=UTF-8
 DIRECTION=ltr
 SeparatorDecimal=,
 SeparatorThousand=
-FormatDateShort=%d/%m/%Y
-FormatDateShortJava=dd/MM/yyyy
-FormatHourShort=%H:%M
-FormatHourShortDuration=%H:%M
-FormatDateTextShort=%d %b %Y
-FormatDateText=%d %B %Y
-FormatDateHourShort=%d/%m/%Y %H:%M
-FormatDateHourTextShort=%d %b %Y %H:%M
-FormatDateHourText=%d %B %Y %H:%M
 AmountVAT=Importe ISV
 TotalVAT=Total ISV
 IncludedVAT=ISV incluido
diff --git a/htdocs/langs/es_PR/main.lang b/htdocs/langs/es_PR/main.lang
index 401b367ff52f53ccf003c0e45afb11453c6bbbfb..5cb39740ada2b55204a3711217e14338b1f879d8 100644
--- a/htdocs/langs/es_PR/main.lang
+++ b/htdocs/langs/es_PR/main.lang
@@ -3,15 +3,6 @@ CHARSET=UTF-8
 DIRECTION=ltr
 SeparatorDecimal=,
 SeparatorThousand=
-FormatDateShort=%d/%m/%Y
-FormatDateShortJava=dd/MM/yyyy
-FormatHourShort=%H:%M
-FormatHourShortDuration=%H:%M
-FormatDateTextShort=%d %b %Y
-FormatDateText=%d %B %Y
-FormatDateHourShort=%d/%m/%Y %H:%M
-FormatDateHourTextShort=%d %b %Y %H:%M
-FormatDateHourText=%d %B %Y %H:%M
 AmountVAT=Importe IVU
 TotalVAT=Total IVU
 IncludedVAT=IVU incluido
diff --git a/htdocs/langs/et_EE/main.lang b/htdocs/langs/et_EE/main.lang
index f02122fad5bbcf1285d71c0c0a02f47496fb7901..086bfe8b5b0f3271f0c48bc8c0070d1000b1ce93 100644
--- a/htdocs/langs/et_EE/main.lang
+++ b/htdocs/langs/et_EE/main.lang
@@ -12,8 +12,11 @@ DIRECTION=ltr
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%m/%d/%Y
+FormatDateShortInput=%m/%d/%Y
 FormatDateShortJava=MM/dd/yyyy
+FormatDateShortJavaInput=MM/dd/yyyy
 FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%I:%M %p
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%b %d, %Y
diff --git a/htdocs/langs/fa_IR/main.lang b/htdocs/langs/fa_IR/main.lang
index 4cb4fc7d9f75eaf5fccc9314ad644eaf42ca21c3..6645152d1d298726374735abaff5be54eac9c1aa 100644
--- a/htdocs/langs/fa_IR/main.lang
+++ b/htdocs/langs/fa_IR/main.lang
@@ -15,7 +15,11 @@ FONTSIZEFORPDF=9
 SeparatorDecimal=/
 SeparatorThousand=,
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
diff --git a/htdocs/langs/fi_FI/main.lang b/htdocs/langs/fi_FI/main.lang
index 734a3356dd9485f0cb5cbf64dfd0589c38f8ca78..b451e91e115e2a98778e8001cb93598cec53c524 100644
--- a/htdocs/langs/fi_FI/main.lang
+++ b/htdocs/langs/fi_FI/main.lang
@@ -11,7 +11,11 @@ CHARSET=UTF-8
 SeparatorDecimal=,
 SeparatorThousand=
 FormatDateShort=%d.%m.%Y
+FormatDateShortInput=%d.%m.%Y
 FormatDateShortJava=dd.MM.yyyy
+FormatDateShortJavaInput=dd.MM.yyyy
+FormatDateShortJQuery=dd.mm.yy
+FormatDateShortJQueryInput=dd.mm.yy
 FormatHourShort=%H.%M
 FormatDateTextShort=%d. %b %Y
 FormatDateText=%d. %B %Y
@@ -616,7 +620,6 @@ Prefix=Etuliite
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 16:10:23).
 // Reference language: en_US -> fi_FI
-FormatDateShortJQuery=dd/mm/yy
 AddLink=Lisää linkki
 Of=ja
 SearchOf=Etsi
diff --git a/htdocs/langs/fr_BE/main.lang b/htdocs/langs/fr_BE/main.lang
index 3a222bdd6b9cfe360ec1e034d6766e235021a94d..664e394aebaeec30823e668d713e2cdbff01cbba 100644
--- a/htdocs/langs/fr_BE/main.lang
+++ b/htdocs/langs/fr_BE/main.lang
@@ -3,7 +3,11 @@ CHARSET=UTF-8
 SeparatorDecimal=,
 SeparatorThousand=
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
diff --git a/htdocs/langs/fr_CA/main.lang b/htdocs/langs/fr_CA/main.lang
index 3cd76162e3d0df14698f398d21d3efbdfa5c85b5..ca4b13b8480dbb6a313a11c8589f8c3beed9fe25 100644
--- a/htdocs/langs/fr_CA/main.lang
+++ b/htdocs/langs/fr_CA/main.lang
@@ -3,7 +3,11 @@ CHARSET=UTF-8
 SeparatorDecimal=,
 SeparatorThousand= 
 FormatDateShort=%d.%m.%Y
+FormatDateShortInput=%d.%m.%Y
 FormatDateShortJava=dd.MM.yyyy
+FormatDateShortJavaInput=dd.MM.yyyy
+FormatDateShortJQuery=dd.mm.yy
+FormatDateShortJQueryInput=dd.mm.yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
diff --git a/htdocs/langs/fr_CH/main.lang b/htdocs/langs/fr_CH/main.lang
index dbe4956c6846f3b96452eebf15d272557639c0c1..83cc40057ea728f70c810704c8078e2192fbd22c 100644
--- a/htdocs/langs/fr_CH/main.lang
+++ b/htdocs/langs/fr_CH/main.lang
@@ -3,7 +3,11 @@ CHARSET=UTF-8
 SeparatorDecimal=,
 SeparatorThousand= 
 FormatDateShort=%d-%m-%Y
+FormatDateShortInput=%d-%m-%Y
 FormatDateShortJava=dd-MM-yyyy
+FormatDateShortJavaInput=dd-MM-yyyy
+FormatDateShortJQuery=dd-mm-yy
+FormatDateShortJQueryInput=dd-mm-yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang
index d1bc47fb624c77edecbb103960e4fd7ff796a666..cc2ee5b2a4eb8a3b6649d657b604da6d22bd8ded 100644
--- a/htdocs/langs/fr_FR/admin.lang
+++ b/htdocs/langs/fr_FR/admin.lang
@@ -45,6 +45,8 @@ ErrorModuleRequireDolibarrVersion= Erreur, ce module requiert une version %s ou
 ErrorDecimalLargerThanAreForbidden= Erreur, les précisions supérieures à <b>%s</b> ne sont pas supportées.
 DictionnarySetup= Dictionnaires
 Dictionnary= Dictionnaires
+ErrorReservedTypeSystemSystemAuto=
+ErrorCodeCantContainZero=
 DisableJavascript= Désactiver les fonctions Javascript et Ajax
 ConfirmAjax= Utiliser les popups de confirmation Ajax
 UseSearchToSelectCompany= Utiliser un champ avec autocomplétion pour choisir un tiers (plutôt qu'une liste déroulante).<br><br>Notez que si vous avez un nombre important de tiers (> 100 000), vous pouvez améliorer les performances en définissant la constante SOCIETE_DONOTSEARCH_ANYWHERE à 1 dans Configuration->Divers. La recherche sera alors limitée au début de la chaine.
@@ -357,7 +359,10 @@ ExtrafieldSelect = Liste de sélection
 ExtrafieldSeparator = Séparateur de champ
 ExtrafieldCheckBox=Case à cocher
 ExtrafieldRadio=Case d'option
-ExtrafieldParamHelp=La liste doit être de la forme clef,valeur<br><br> par exemple : <br>1,valeur1<br>2,valeur2<br>3,valeur3<br>...
+ExtrafieldParamHelpselect=La liste doit être de la forme clef,valeur<br><br> par exemple : <br>1,valeur1<br>2,valeur2<br>3,valeur3<br>...
+ExtrafieldParamHelpcheckbox=La liste doit être de la forme clef,valeur<br><br> par exemple : <br>1,valeur1<br>2,valeur2<br>3,valeur3<br>...
+ExtrafieldParamHelpradio=La liste doit être de la forme clef,valeur<br><br> par exemple : <br>1,valeur1<br>2,valeur2<br>3,valeur3<br>...
+ExtrafieldParamHelpsellist=La liste vient d'une table<br><br> par exemple : <br>c_typent:libelle:id<br>
 LibraryToBuildPDF=Bibliothèque utilisée pour la génération des PDF
 WarningUsingFPDF=Attention: Votre fichier <b>conf.php</b> contient la directive <b>dolibarr_pdf_force_fpdf=1</b>. Cela signifie que vous utilisez la librairie FPDF pour générer vos fichiers PDF. Cette librairie est ancienne et ne couvre pas de nombreuses fonctionnalitée (Unicode, transparence des images, langues cyrillic, arabes ou asiatiques...), aussi vous pouvez rencontrez des problèmes durant la génération des PDF.<br>Pour résoudre cela et avoir un support complet de PDF, vous pouvez télécharger la <a href="http://www.tcpdf.org/" target="_blank">librairie TCPDF</a> puis commenter ou supprimer la ligne <b>$dolibarr_pdf_force_fpdf=1</b>, et ajouter à la place <b>$dolibarr_lib_TCPDF_PATH='chemin_vers_TCPDF'</b>   
 LocalTaxDesc=Certains pays appliquent 2 voir 3 taux sur chaque ligne de facture. Si c'est le cas, choisissez le type du deuxième et troisième taux et sa valeur. Les types possibles sont:<br>1 : taxe locale sur les produits et services hors tva (la tva n'est pas appliquée sur la taxe locale)<br>2 : taxe locale sur les produits et services avant tva (la tva est appliquée sur le montant + la taxe locale)<br>3 : taxe locale uniquement sur les produits hors tva (la tva n'est pas appliquée sur la taxe locale)<br>4 : taxe locale uniquement sur les produits avant tva (la tva est appliquée sur le montant + la taxe locale)<br>5 : taxe locale uniquement sur les services hors tva (la tva n'est pas appliquée sur la taxe locale)<br>6 : taxe locale uniquement sur les service avant tva (la tva est appliquée sur le montant + la taxe locale)
@@ -542,6 +547,7 @@ Permission98= Ventiler les lignes de factures
 Permission101= Consulter les expéditions
 Permission102= Créer/modifier les expéditions
 Permission104= Valider les expéditions
+Permission106= Exporter les expéditions
 Permission109= Supprimer les expéditions
 Permission111= Consulter les comptes financiers (comptes bancaires, caisses)
 Permission112= Créer/modifier montant/supprimer écritures bancaires
diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang
index 33555be695135f842fdbef376412f33dd2059348..62b09ec39d18e3b659ca9f01bdf01aaaff7ba1e3 100644
--- a/htdocs/langs/fr_FR/agenda.lang
+++ b/htdocs/langs/fr_FR/agenda.lang
@@ -32,7 +32,7 @@ ViewCal=Vue mois
 ViewDay=Vue jour
 ViewWeek=Vue semaine
 ViewWithPredefinedFilters=Vues avec filtres prédéfinis
-AutoActions=Alimentation automatique de l'agenda
+AutoActions=Alimentation automatique
 AgendaAutoActionDesc=Définissez dans cet onglet les événements pour lesquels dolibarr créera automatiquement une action dans l'agenda. Si aucune case n'est cochée (par défaut), seules les actions manuelles seront incluses dans l'agenda.
 AgendaSetupOtherDesc=Cette page permet de configurer quelques options permettant d'exporter une vue de votre agenda Dolibarr vers un calendrier externe (thunderbird, google calendar, ...)
 AgendaExtSitesDesc=Cette page permet d'ajouter des sources de calendriers externes pour les visualiser au sein de l'agenda Dolibarr.
@@ -40,6 +40,7 @@ ActionsEvents=Événements pour lesquels Dolibarr doit créer une action dans l'
 PropalValidatedInDolibarr=Proposition %s validée
 InvoiceValidatedInDolibarr=Facture %s validée
 InvoiceBackToDraftInDolibarr=Facture %s repassée en brouillon
+InvoiceDeleteDolibarr=Facture %s supprimée
 OrderValidatedInDolibarr=Commande %s validée
 OrderApprovedInDolibarr=Commande %s approuvée
 OrderBackToDraftInDolibarr=Commande %s repassée en brouillon
@@ -66,6 +67,7 @@ AgendaUrlOptions4=<b>logint=%s</b> pour limiter l'export aux actions affectées
 AgendaUrlOptions5=<b>logind=%s</b> pour limiter l'export aux actions réalisées par l'utilisateur <b>%s</b>.
 AgendaShowBirthdayEvents=Afficher anniversaires contacts
 AgendaHideBirthdayEvents=Cacher anniversaires contacts
+Busy=Occupé
 
 # External Sites ical
 ExportCal=Export calendrier
diff --git a/htdocs/langs/fr_FR/bills.lang b/htdocs/langs/fr_FR/bills.lang
index 0c87fb93f66e9ae99861feb9d682c241507b0b53..adfa9a34bdceb63be38e16102ecefae6cf278743 100644
--- a/htdocs/langs/fr_FR/bills.lang
+++ b/htdocs/langs/fr_FR/bills.lang
@@ -322,6 +322,8 @@ PaymentTypeVAD=Paiement en ligne
 PaymentTypeShortVAD=Paiement en ligne
 PaymentTypeTRA=Paiement par traite
 PaymentTypeShortTRA=Traite
+FixAmount=Montant Fixe
+VarAmount=Montant variable (%% tot.)
 
 BankDetails=Coordonnées bancaires
 BankCode=Code banque
diff --git a/htdocs/langs/fr_FR/commercial.lang b/htdocs/langs/fr_FR/commercial.lang
index 5c5747baa92752d5c9c1190d3fdb568c2bd998c3..c13b1b09ea27eaddcf55564e05ca0942cddb095d 100644
--- a/htdocs/langs/fr_FR/commercial.lang
+++ b/htdocs/langs/fr_FR/commercial.lang
@@ -81,6 +81,7 @@ ActionAC_SHIP=Envoi bon d'expédition par mail
 ActionAC_SUP_ORD=Envoi commande fournisseur par mail
 ActionAC_SUP_INV=Envoi facture fournisseur par mail
 ActionAC_OTH=Autre
+ActionAC_OTH_AUTO=Autre (evênements insérés automatiquement)
 ActionAC_MANUAL=Evênements insérés manuellement
 ActionAC_AUTO=Evênements insérés automatiquement
 Stats=Statistiques de vente
diff --git a/htdocs/langs/fr_FR/compta.lang b/htdocs/langs/fr_FR/compta.lang
index 1491a7820f4db69b50c551434cf2ecc71850895e..227b6b734ad6e39b3cf0ad766faa1a16d6a01990 100644
--- a/htdocs/langs/fr_FR/compta.lang
+++ b/htdocs/langs/fr_FR/compta.lang
@@ -163,4 +163,5 @@ Pcg_type=Classe de compte
 Pcg_subtype=Sous classe de compte
 InvoiceLinesToDispatch=Lignes de factures à ventiler
 InvoiceDispatched=Factures ventilées
-AccountancyDashboard=Synthèse compta/tréso
\ No newline at end of file
+AccountancyDashboard=Synthèse compta/tréso
+ByProductsAndServices=Par produits et services
diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang
index f1316e03d1335ce0d233826427ea84f188b711ab..5081f66d5f79212fcc2eece66ed8b66bc30d724b 100644
--- a/htdocs/langs/fr_FR/errors.lang
+++ b/htdocs/langs/fr_FR/errors.lang
@@ -137,4 +137,5 @@ WarningLockFileDoesNotExists=Attention, une fois l'installation terminée, les o
 WarningUntilDirRemoved=Les alertes de sécurité sont visibles par les administrateurs uniquement et resteront actives tant que la vulnérabilité sera avérée (ou que la constante MAIN_REMOVE_INSTALL_WARNING aura été définie dans Configuration->Divers)
 WarningCloseAlways=Attention, la fermeture se fait même lorsque le montant diffère. N'activez cette fonctionnalité qu'en connaissance de cause.
 WarningUsingThisBoxSlowDown=Attention, l'utilisation de cette boite provoque de sérieux ralentissement des pages affichant cette boite.
-WarningClickToDialUserSetupNotComplete=La configuration ClickToDial pour votre compte utilisateur n'est pas complète (voir l'onglet ClickToDial sur votre fiche utilisateur)
\ No newline at end of file
+WarningClickToDialUserSetupNotComplete=La configuration ClickToDial pour votre compte utilisateur n'est pas complète (voir l'onglet ClickToDial sur votre fiche utilisateur)
+WarningNotRelevant=Opération non pertinente pour cet ensemble de données
diff --git a/htdocs/langs/fr_FR/externalsite.lang b/htdocs/langs/fr_FR/externalsite.lang
index ff1fb3112c13da7a26427423f1e38a9aa76a5465..36c8686a3c360f85db2fffe103283377c6b6734c 100644
--- a/htdocs/langs/fr_FR/externalsite.lang
+++ b/htdocs/langs/fr_FR/externalsite.lang
@@ -1,4 +1,5 @@
 # Dolibarr language file - fr_FR - externalsite
 CHARSET=UTF-8
 ExternalSiteSetup=Configuration du lien vers le site externe
-ExternalSiteURL=URL du site externe
\ No newline at end of file
+ExternalSiteURL=URL du site externe
+ExternalSiteModuleNotComplete=
\ No newline at end of file
diff --git a/htdocs/langs/fr_FR/holiday.lang b/htdocs/langs/fr_FR/holiday.lang
index e6c0d33ad987910bde0f4604b9dfa731d2e261d3..a9f4c758d8de2c00907cef215111b86d3c270bce 100644
--- a/htdocs/langs/fr_FR/holiday.lang
+++ b/htdocs/langs/fr_FR/holiday.lang
@@ -130,4 +130,9 @@ NoCPforMonth=Aucun congé ce mois-ci.
 Jours=jours
 nbJours=Nombre jours
 TitleAdminCP=Configuration des Congés
-Permission20001=Lire / Créer / modifier ses congés
+Permission20001=Lire / Créer / modifier ses congès
+Permission20002=Lire / Modifier toutes les demandes de congés payés
+Permission20003=Supprimer des demandes de congés payés
+Permission20004=Définir les congés payés des utilisateurs
+Permission20005=Voir les logs de modification des congés payés
+Permission20006=Accéder au rapport mensuel des congés payés
diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang
index b31b711f3a37b4b641768a4f2b6cfddbc975f83f..bad84a575484aa5bbb8a7725966add85d8bab4ae 100644
--- a/htdocs/langs/fr_FR/main.lang
+++ b/htdocs/langs/fr_FR/main.lang
@@ -4,8 +4,11 @@ DIRECTION=ltr
 SeparatorDecimal=,
 SeparatorThousand= 
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
 FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%d %b %Y
@@ -475,6 +478,8 @@ Report=Rapport
 Keyword=Mot clé
 Legend=Légende
 FillTownFromZip=Renseigner ville
+Fill=Remplir
+Reset=Vider
 ShowLog=Afficher historique
 File=Fichier
 Files=Fichiers
diff --git a/htdocs/langs/fr_FR/other.lang b/htdocs/langs/fr_FR/other.lang
index de941e850a6d118a7657e106fc9f465f6f545893..86218e219be6a54e1a8fefbf712e577eeb267afb 100644
--- a/htdocs/langs/fr_FR/other.lang
+++ b/htdocs/langs/fr_FR/other.lang
@@ -151,6 +151,7 @@ EMailTextOrderApproved=La commande %s a été approuvée.
 EMailTextOrderApprovedBy=La commande %s a été approuvée par %s.
 EMailTextOrderRefused=La commande %s a été refusée.
 EMailTextOrderRefusedBy=La commande %s a été refusée par %s.
+EMailTextExpeditionValidated=
 ImportedWithSet=Lot d'importation (Import key)
 DolibarrNotification=Notification automatique
 ResizeDesc=Entrer la nouvelle largeur <b>OU</b> la nouvelle hauteur. Le ratio est conservé lors du redimensionnement...
diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang
index 3d27fdd9d6d72d857a39320d32ca2d5972ecf0be..bd1c1075e2ee959c224cbe6422bd3de41d84e83c 100644
--- a/htdocs/langs/fr_FR/products.lang
+++ b/htdocs/langs/fr_FR/products.lang
@@ -111,11 +111,13 @@ ServiceLimitedDuration=Si produit de type service à durée limitée :
 MultiPricesAbility=Prise en charge de prix multiples
 MultiPricesNumPrices=Nombre de prix
 MultiPriceLevelsName=Catégorie de prix
-AssociatedProductsAbility=Prise en charge des produits composés
-AssociatedProducts=Composition
-AssociatedProductsNumber=Nbre de sous-produits composant ce produit
-ParentProductsNumber=Nbre de produits parent
-EditAssociate=Composer
+AssociatedProductsAbility=Prise en charge des produits virtuels
+AssociatedProducts=Produit virtuel
+AssociatedProductsNumber=Nbre de sous-produits constituant ce produit virtuel
+ParentProductsNumber=Nbre de produits virtuels parent
+IfZeroItIsNotAVirtualProduct=Si 0, ce produit n'est pas un produit virtuel
+IfZeroItIsNotUsedByVirtualProduct=Si 0, ce produit n'est pas utilisé par un produit virtuel
+EditAssociate=Composer comme produit virtuel
 Translation=Traduction 
 KeywordFilter=Filtre par mot-clé
 CategoryFilter=Filtre par catégorie
@@ -123,8 +125,8 @@ ProductToAddSearch=Recherche des produits à ajouter
 AddDel=Ajouter/Retirer
 Quantity=Quantité
 NoMatchFound=Aucun résultat n'a été trouvé 
-ProductAssociationList=Liste des produits/services composant ce produit: Le nombre entre parenthèse est la quantité affectée dans cette composition.
-ProductParentList=Liste des produits/services avec ce produit comme composante
+ProductAssociationList=Liste des produits/services composant ce produit virtuel: Le nombre entre parenthèse est la quantité affectée dans cette composition.
+ProductParentList=Liste des produits/services virtuels avec ce produit comme composante
 ErrorAssociationIsFatherOfThis=L'un des produits sélectionnés est parent du produit en cours
 DeleteProduct=Supprimer un produit/service
 ConfirmDeleteProduct=Êtes-vous sûr de vouloir supprimer ce produit/service ?
@@ -184,4 +186,12 @@ AlwaysUseNewPrice=Toujours utiliser le prix du jour
 AlwaysUseFixedPrice=Utiliser le prix fixé
 PriceByQuantity=Prix par quantité
 PriceByQuantityRange=Grille de quantités
-ProductsDashboard=Synthèse produits/services
\ No newline at end of file
+ProductsDashboard=Synthèse produits/services
+### composition fabrication
+Building=Fabrication
+Build=Fabriquer
+BuildIt=Lancer la fabrication
+BuildindListInfo=Nombre de produit fabricable par entrepot, si saisie à zéro on ne fabrique pas
+QtyNeed=Affectée
+UnitPmp=Prix Achat Unitaire
+CostPmpHT=Cout à l'achat HT
diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang
index fb016e23ef39d2d5ccf82e364fe3d508cd2b8e6f..1b2daaf95213067edb76909cb6773bb8858bd42d 100644
--- a/htdocs/langs/fr_FR/stocks.lang
+++ b/htdocs/langs/fr_FR/stocks.lang
@@ -55,6 +55,7 @@ DeStockOnShipment=Décrémente les stocks physiques sur validation des expéditi
 ReStockOnBill=Incrémente les stocks physiques sur validation des factures/avoirs fournisseurs
 ReStockOnValidateOrder=Incrémente les stocks physiques sur approbation des commandes fournisseurs
 ReStockOnDispatchOrder=Incrémente les stocks physiques sur ventilation manuelle de la réception des commandes fournisseurs dans les entrepôts
+ReStockOnDeleteInvoice=Incrémente les stocks physiques sur la suppression des factures
 OrderStatusNotReadyToDispatch=La commande n'a pas encore ou n'a plus un statut permettant une ventilation en stock.
 StockDiffPhysicTeoric=Raison écart stock physique-théorique
 NoPredefinedProductToDispatch=Pas de produits prédéfinis dans cet objet. Aucune ventilation en stock n'est donc à faire.
@@ -86,4 +87,5 @@ PersonalStock=Stock personnel %s
 ThisWarehouseIsPersonalStock=Cet entrepôt représente le stock personnel de %s %s 
 SelectWarehouseForStockDecrease=Sélectionner l'entrepôt à utiliser pour la décrémentation du stock
 SelectWarehouseForStockIncrease=Sélectionner l'entrepôt à utiliser pour l'incrémentation du stock
+NoStockAction=Pas d'action sur l'entrepot
 LastWaitingSupplierOrders=Commandes en attente de réception
\ No newline at end of file
diff --git a/htdocs/langs/he_IL/main.lang b/htdocs/langs/he_IL/main.lang
index 1561f46886148e101962d3fe6d9ec84c6dabc269..03c0061acf17ddeea92b7451871a8ced5c1f1bfb 100644
--- a/htdocs/langs/he_IL/main.lang
+++ b/htdocs/langs/he_IL/main.lang
@@ -15,8 +15,11 @@ FONTSIZEFORPDF=9
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%m/%d/%Y
+FormatDateShortInput=%m/%d/%Y
 FormatDateShortJava=MM/dd/yyyy
-FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJavaInput=MM/dd/yyyy
+FormatDateShortJQuery=mm/dd/yy
+FormatDateShortJQueryInput=mm/dd/yy
 FormatHourShort=%I:%M %p
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%b %d, %Y
diff --git a/htdocs/langs/hu_HU/main.lang b/htdocs/langs/hu_HU/main.lang
index 8ee7c82664855c6cf7002ab034be39c580a8f6db..9fb2cf4f61d0cf2b5138ee7e9e498c26bee42cc1 100644
--- a/htdocs/langs/hu_HU/main.lang
+++ b/htdocs/langs/hu_HU/main.lang
@@ -5,7 +5,11 @@ FONTFORPDF=dejavusans
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%I:%M %p
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%b %d, %Y
@@ -587,7 +591,6 @@ ShortSunday=V
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 16:13:31).
 // Reference language: en_US -> hu_HU
-FormatDateShortJQuery=dd/mm/yy
 AddLink=Link hozzáadása
 Of=A
 SearchOf=Keresés
diff --git a/htdocs/langs/is_IS/main.lang b/htdocs/langs/is_IS/main.lang
index 619f60994d9077a1f64ac845de56ab82672253d7..c89746ed4016ff3a00dd4995b927701436f29387 100644
--- a/htdocs/langs/is_IS/main.lang
+++ b/htdocs/langs/is_IS/main.lang
@@ -12,7 +12,11 @@ DIRECTION=ltr
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
@@ -604,7 +608,6 @@ Reason=Ástæða
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 16:26:19).
 // Reference language: en_US -> is_IS
-FormatDateShortJQuery=dd/mm/yy
 AddLink=Bæta við tengli
 Of=á
 SearchOf=Leita
diff --git a/htdocs/langs/it_IT/main.lang b/htdocs/langs/it_IT/main.lang
index 43e9b108b78f6bf736502bbef78a27550e222009..78664cd01f851fe13fac1446d3424f04f1da1915 100644
--- a/htdocs/langs/it_IT/main.lang
+++ b/htdocs/langs/it_IT/main.lang
@@ -270,15 +270,18 @@ FollowingConstantsWillBeSubstituted			   =Le seguenti costanti saranno sostitute
 ForCustomer						   =Per i clienti
 FormatDateHourShort					   =%d/%m/%Y %H.%M
 FormatDateHourText					   =%d %B %Y %H:%M
-FormatDateHourTextShort					   =%d %b %Y %H.%M
+FormatDateHourTextShort				   =%d %b %Y %H.%M
 FormatDateShort						   =%d/%m/%Y
+FormatDateShortInput				   =%d/%m/%Y
 FormatDateShortJava					   =dd/MM/yyyy
-FormatDateShortJQuery					   =dd/mm/yy
+FormatDateShortJavaInput			   =dd/MM/yyyy
+FormatDateShortJQuery				   =dd/mm/yy
+FormatDateShortJQueryInput			   =dd/mm/yy
 FormatDateText						   =%d %B %Y
 FormatDateTextShort					   =%d %b %Y
-FormatHourShortDuration					   =%H:%M
-FormatHourShort					           =%H.%M
-For							   =Per
+FormatHourShortDuration				   =%H:%M
+FormatHourShort				           =%H.%M
+For								   =Per
 FreeZone						   =Testo libero
 Frequency						   =Frequenza
 FridayMin						   =Ven
diff --git a/htdocs/langs/ja_JP/main.lang b/htdocs/langs/ja_JP/main.lang
index 6f6201cb7ec61e592a54429d4e6906df0432e7cb..d4c93c068e5c630b953873a3324f82fdd6a92f34 100644
--- a/htdocs/langs/ja_JP/main.lang
+++ b/htdocs/langs/ja_JP/main.lang
@@ -9,9 +9,12 @@ FONTSIZEFORPDF=9
 // Reference language: en_US -> ja_JP
 SeparatorDecimal=.
 SeparatorThousand=、
-FormatDateShort=%m/%d/%Y
-FormatDateShortJava=MM/dd/yyyy
-FormatDateShortJQuery=dd/mm/yy
+FormatDateShort=%m/%d/%Y
+FormatDateShortInput=%m/%d/%Y
+FormatDateShortJava=MM/dd/yyyy
+FormatDateShortJavaInput=MM/dd/yyyy
+FormatDateShortJQuery=mm/dd/yy
+FormatDateShortJQueryInput=mm/dd/yy
 FormatHourShort=%I:%M %p
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%b %d, %Y
diff --git a/htdocs/langs/nb_NO/main.lang b/htdocs/langs/nb_NO/main.lang
index 203896ba362aa32713b53b9103b75e9bdcb56ca8..123ed5a86ed3b2abeb7bdb2d19bdafda92bb9993 100644
--- a/htdocs/langs/nb_NO/main.lang
+++ b/htdocs/langs/nb_NO/main.lang
@@ -3,7 +3,11 @@ CHARSET=UTF-8
 SeparatorDecimal=,
 SeparatorThousand=
 FormatDateShort=%d.%m.%Y
+FormatDateShortInput=%d.%m.%Y
 FormatDateShortJava=dd.MM.yyyy
+FormatDateShortJavaInput=dd.MM.yyyy
+FormatDateShortJQuery=dd.mm.yy
+FormatDateShortJQueryInput=dd.mm.yy
 FormatHourShort=%H.%M
 FormatDateTextShort=%d. %b %Y
 FormatDateText=%d. %B %Y
@@ -606,7 +610,6 @@ Day0=Søndag
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 17:06:43).
 // Reference language: en_US -> nb_NO
-FormatDateShortJQuery=dd/mm/yy
 AddLink=Legg til link
 Of=av
 SearchOf=Søk
diff --git a/htdocs/langs/nl_BE/main.lang b/htdocs/langs/nl_BE/main.lang
index 3d16e786aedab667cde5358003d427fe4ae52c3f..d4aff86e9c38c769d062a63da95504c0c45eaed8 100644
--- a/htdocs/langs/nl_BE/main.lang
+++ b/htdocs/langs/nl_BE/main.lang
@@ -3,7 +3,11 @@ CHARSET=UTF-8
 SeparatorDecimal=,
 SeparatorThousand= 
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
diff --git a/htdocs/langs/nl_NL/main.lang b/htdocs/langs/nl_NL/main.lang
index 40947ca565f5a30afe4456707b6b19fb91feaefb..100bd776c3a96d9019687576660f63ae3b8a782e 100644
--- a/htdocs/langs/nl_NL/main.lang
+++ b/htdocs/langs/nl_NL/main.lang
@@ -4,7 +4,11 @@ DIRECTION = ltr
 SeparatorDecimal = ,
 SeparatorThousand = .
 FormatDateShort = %d-%m-%Y
+FormatDateShortInput = %d-%m-%Y
 FormatDateShortJava = dd-MM-yyyy
+FormatDateShortJavaInput = dd-MM-yyyy
+FormatDateShortJQuery=dd-mm-yy
+FormatDateShortJQueryInput=dd-mm-yy
 FormatHourShort = %H:%M
 FormatHourShortDuration = %H:%M
 FormatDateTextShort = %d %b %Y
@@ -590,7 +594,6 @@ ShortSunday = Zo
 
 // START - Lines generated via autotranslator.php tool (2011-10-10 01:46:39).
 // Reference language: en_US -> nl_NL
-FormatDateShortJQuery=dd/mm/yy
 JanuaryMin=Jan
 FebruaryMin=Februari
 MarchMin=Mar
diff --git a/htdocs/langs/pl_PL/main.lang b/htdocs/langs/pl_PL/main.lang
index 5f725587178d178f693ac2602bda0887f28836fa..41236b3456a31a2c6648274e533a1019cca761a0 100644
--- a/htdocs/langs/pl_PL/main.lang
+++ b/htdocs/langs/pl_PL/main.lang
@@ -15,7 +15,11 @@ FONTSIZEFORPDF=8
 SeparatorDecimal=,
 SeparatorThousand= 
 FormatDateShort=%d-%m-%Y
+FormatDateShortInput=%d-%m-%Y
 FormatDateShortJava=dd-MM-yyyy
+FormatDateShortJavaInput=dd-MM-yyyy
+FormatDateShortJQuery=dd-mm-yy
+FormatDateShortJQueryInput=dd-mm-yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
@@ -620,7 +624,6 @@ Prefix=Przedrostek
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 17:18:29).
 // Reference language: en_US -> pl_PL
-FormatDateShortJQuery=dd/mm/yy
 AddLink=Dodaj link
 Of=z
 SearchOf=Szukaj
diff --git a/htdocs/langs/pt_PT/main.lang b/htdocs/langs/pt_PT/main.lang
index 86d60b9b03726e0b40558184246a39ef03972923..4df4d1ea5ece281286b09859000ef79b2e5b6602 100644
--- a/htdocs/langs/pt_PT/main.lang
+++ b/htdocs/langs/pt_PT/main.lang
@@ -3,7 +3,11 @@ CHARSET=UTF-8
 SeparatorDecimal=,
 SeparatorThousand=
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
@@ -601,7 +605,6 @@ Prefix=Prefixo
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 15:45:52).
 // Reference language: en_US -> pt_PT
-FormatDateShortJQuery=dd/mm/yy
 AddLink=Adicionar link
 Of=de
 SearchOf=Pesquisar
diff --git a/htdocs/langs/ro_RO/main.lang b/htdocs/langs/ro_RO/main.lang
index df4536746d86c4d513a09546eb56059569ff3d27..8b7530a1702d0f954a634725fe174998c59adff1 100644
--- a/htdocs/langs/ro_RO/main.lang
+++ b/htdocs/langs/ro_RO/main.lang
@@ -13,7 +13,11 @@ FONTSIZEFORPDF=8
 SeparatorDecimal=,
 SeparatorThousand=
 FormatDateShort=%d.%m.%Y
+FormatDateShortInput=%d.%m.%Y
 FormatDateShortJava=dd.MM.yyyy
+FormatDateShortJavaInput=dd.MM.yyyy
+FormatDateShortJQuery=dd.mm.yy
+FormatDateShortJQueryInput=dd.mm.yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
@@ -618,7 +622,6 @@ Prefix=Prefix
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 17:23:15).
 // Reference language: en_US -> ro_RO
-FormatDateShortJQuery=dd/mm/yy
 AddLink=Adauga link-ul
 Of=de
 SearchOf=Căutare
diff --git a/htdocs/langs/ru_RU/main.lang b/htdocs/langs/ru_RU/main.lang
index 1d203fb98f0f4bd0313c9090426e05d454e0b098..30be774c29fb9f64424baf4b63e6d575a095baab 100644
--- a/htdocs/langs/ru_RU/main.lang
+++ b/htdocs/langs/ru_RU/main.lang
@@ -15,7 +15,11 @@ DIRECTION=ltr
 SeparatorDecimal=,
 SeparatorThousand=
 FormatDateShort=%d.%m.%Y
+FormatDateShortInput=%d.%m.%Y
 FormatDateShortJava=dd.MM.yyyy
+FormatDateShortJavaInput=dd.MM.yyyy
+FormatDateShortJQuery=dd.mm.yy
+FormatDateShortJQueryInput=dd.mm.yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
@@ -628,7 +632,6 @@ Person=Персона
 
 // START - Lines generated via autotranslator.php tool (2011-08-18 23:26:41).
 // Reference language: en_US -> ru_RU
-FormatDateShortJQuery=dd/mm/yy
 AddLink=Добавить ссылку
 Of=из
 AmountByMonth=Сумма за месяц
diff --git a/htdocs/langs/ru_UA/main.lang b/htdocs/langs/ru_UA/main.lang
index cef3a719ae09877ab79a362177ada41ffb187ceb..cac36234fbf832c9f13b9704824c7b0823381fbf 100644
--- a/htdocs/langs/ru_UA/main.lang
+++ b/htdocs/langs/ru_UA/main.lang
@@ -10,7 +10,11 @@ DIRECTION=ltr
 SeparatorDecimal=,
 SeparatorThousand=
 FormatDateShort=%d.%m.%Y
+FormatDateShortInput=%d.%m.%Y
 FormatDateShortJava=dd.MM.yyyy
+FormatDateShortJavaInput=dd.MM.yyyy
+FormatDateShortJQuery=dd.mm.yy
+FormatDateShortJQueryInput=dd.mm.yy
 FormatHourShort=%H:%M
 FormatDateTextShort=%d %b %Y
 FormatDateText=%d %B %Y
diff --git a/htdocs/langs/sl_SI/main.lang b/htdocs/langs/sl_SI/main.lang
index 793d9498587ca67b77928c721d29d0be33f50aba..c79ca0d5dc59fd4ff035532a0e2b962f587ec011 100644
--- a/htdocs/langs/sl_SI/main.lang
+++ b/htdocs/langs/sl_SI/main.lang
@@ -6,8 +6,11 @@ FONTSIZEFORPDF=8
 SeparatorDecimal = ,
 SeparatorThousand = .
 FormatDateShort = %d/%m/%Y
+FormatDateShortInput = %d/%m/%Y
 FormatDateShortJava = dd/MM/yyyy
+FormatDateShortJavaInput = dd/MM/yyyy
 FormatDateShortJQuery = dd/mm/yy
+FormatDateShortJQueryInput = dd/mm/yy
 FormatHourShort = %I:%M %p
 FormatHourShortDuration = %H:%M
 FormatDateTextShort = %d. %b, %Y
diff --git a/htdocs/langs/sv_SE/main.lang b/htdocs/langs/sv_SE/main.lang
index 55287b657a03a9ace392cd9a44f946485b335fe5..dde9641a208a1d46958492a11512ef9308340607 100644
--- a/htdocs/langs/sv_SE/main.lang
+++ b/htdocs/langs/sv_SE/main.lang
@@ -12,7 +12,11 @@ DIRECTION=ltr
 SeparatorDecimal=,
 SeparatorThousand=
 FormatDateShort=%Y-%m-%d
+FormatDateShortInput=%Y-%m-%d
 FormatDateShortJava=yyyy-MM-dd
+FormatDateShortJavaInput=yyyy-MM-dd
+FormatDateShortJQuery=yy-mm-dd
+FormatDateShortJQueryInput=yy-mm-dd
 FormatHourShort=%H:%M
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%b %d %Y
@@ -594,7 +598,6 @@ ShortSunday=S
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 17:32:03).
 // Reference language: en_US -> sv_SE
-FormatDateShortJQuery=dd/mm/yy
 AddLink=Tillsätt länk
 Of=av
 SearchOf=Sök
diff --git a/htdocs/langs/tr_TR/main.lang b/htdocs/langs/tr_TR/main.lang
index 7f372bf7dd5cbfeef02a35b5a7dd4241f5845f69..8862e8b7635239138cda576a873243b3a1ffd7cb 100644
--- a/htdocs/langs/tr_TR/main.lang
+++ b/htdocs/langs/tr_TR/main.lang
@@ -14,8 +14,11 @@ FONTSIZEFORPDF=8
 SeparatorDecimal=.
 SeparatorThousand=,
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
 FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%H:%M
 FormatHourShortDuration=%H:%M
 FormatDateTextShort=%d %b %Y
diff --git a/htdocs/langs/zh_CN/main.lang b/htdocs/langs/zh_CN/main.lang
index 04235a1bd69e7ab9854d7591e6d2677d56d626e2..04c6ee545bdd8c315ce52882b99ddc4aca7df9f7 100644
--- a/htdocs/langs/zh_CN/main.lang
+++ b/htdocs/langs/zh_CN/main.lang
@@ -17,7 +17,11 @@ FONTSIZEFORPDF=9
 SeparatorDecimal=.
 SeparatorThousand=None
 FormatDateShort=%d/%m/%Y
+FormatDateShortInput=%d/%m/%Y
 FormatDateShortJava=dd/MM/yyyy
+FormatDateShortJavaInput=dd/MM/yyyy
+FormatDateShortJQuery=dd/mm/yy
+FormatDateShortJQueryInput=dd/mm/yy
 FormatHourShort=%I:%M %p
 FormatDateTextShort=%b %d, %Y
 FormatDateText=%B %d, %Y
@@ -604,7 +608,6 @@ Prefix=字首
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 17:37:09).
 // Reference language: en_US -> zh_CN
-FormatDateShortJQuery=dd/mm/yy
 AddLink=添加链接
 Of=的
 SearchOf=搜索
diff --git a/htdocs/langs/zh_TW/main.lang b/htdocs/langs/zh_TW/main.lang
index b853fbb6073e670a52f2a600f621109f6c1444de..aff84edf1eff972efc35fd995d838547fd3c9025 100644
--- a/htdocs/langs/zh_TW/main.lang
+++ b/htdocs/langs/zh_TW/main.lang
@@ -13,7 +13,11 @@ FONTFORPDF=msungstdlight
 SeparatorDecimal=.
 SeparatorThousand=None
 FormatDateShort=%Y/%m/%d
+FormatDateShortInput=%Y/%m/%d
 FormatDateShortJava=yyyy/MM/dd
+FormatDateShortJavaInput=yyyy/MM/dd
+FormatDateShortJQuery=yy/mm/dd
+FormatDateShortJQueryInput=yy/mm/dd
 FormatHourShort=%I:%M %p
 FormatDateTextShort=%Y %b %d
 FormatDateText=%Y %B %d
@@ -600,7 +604,6 @@ Prefix=字首
 
 // START - Lines generated via autotranslator.php tool (2012-02-29 17:37:09).
 // Reference language: en_US -> zh_CN
-FormatDateShortJQuery=dd/mm/yy
 AddLink=添加鏈接
 Of=的
 SearchOf=搜尋
diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php
index 0a3f2c571df62112b8d9eee22f15b7694b2cccb4..188e830be63bc4e32f306793b637dcabe62ea20d 100644
--- a/htdocs/opensurvey/class/opensurveysondage.class.php
+++ b/htdocs/opensurvey/class/opensurveysondage.class.php
@@ -337,7 +337,7 @@ class Opensurveysondage extends CommonObject
 	 *
      *	@param  User	$user        		User that deletes
      *  @param  int		$notrigger	 		0=launch triggers after, 1=disable triggers
-     *  @param	string	$numsondageadmin	Num sondage to delete
+     *  @param	string	$numsondageadmin	Num sondage admin to delete
 	 *  @return	int					 		<0 if KO, >0 if OK
 	 */
 	function delete($user, $notrigger, $numsondageadmin)
@@ -345,6 +345,8 @@ class Opensurveysondage extends CommonObject
 		global $conf, $langs;
 		$error=0;
 
+		$numsondage=substr($numsondageadmin, 0, 16);
+		
 		$this->db->begin();
 
 		if (! $error)
@@ -366,10 +368,10 @@ class Opensurveysondage extends CommonObject
 		if (! $error)
 		{
 
-			$sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage_admin = '".$numsondageadmin."'";
+			$sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage = '".$numsondage."'";
 			dol_syslog(get_class($this)."::delete sql=".$sql, LOG_DEBUG);
 			$resql=$this->db->query($sql);
-			$sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage_admin = '".$numsondageadmin."'";
+			$sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage = '".$numsondage."'";
 			dol_syslog(get_class($this)."::delete sql=".$sql, LOG_DEBUG);
 			$resql=$this->db->query($sql);
 
diff --git a/htdocs/opensurvey/list.php b/htdocs/opensurvey/list.php
index 506ffecc99e19c21d24c620f93a694109cfedf92..c87526ce5ca389f85e912589e3f37d1840c2890c 100755
--- a/htdocs/opensurvey/list.php
+++ b/htdocs/opensurvey/list.php
@@ -27,6 +27,7 @@ require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
 
 $action=GETPOST('action');
 $id=GETPOST('id');
+$numsondage=substr($id, 0, 16);
 
 if (! $sortorder) $sortorder="ASC";
 if (! $sortfield) $sortfield="p.titre";
@@ -45,16 +46,10 @@ if ($action == 'delete_confirm')
 {
 	$db->begin();
 
-	$sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage_admin = '".$id."'";
-	dol_syslog("Delete poll sql=".$sql, LOG_DEBUG);
-	$resql=$db->query($sql);
-	$sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage_admin = '".$id."'";
-	dol_syslog("Delete poll sql=".$sql, LOG_DEBUG);
-	$resql=$db->query($sql);
-	$sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_sondage WHERE id_sondage_admin = '".$id."'";
-	dol_syslog("Delete poll sql=".$sql, LOG_DEBUG);
-	$resql=$db->query($sql);
-
+	$object=new Opensurveysondage($db);
+	
+	$result=$object->delete($user,'',$numsondageadmin);
+	
 	$db->commit();
 }
 
diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php
index 422f93eff16e72e823f8e6cbb1b9ccfbc56cc31f..45b0a12980807ca2478820a624492b1d18e1d5db 100644
--- a/htdocs/product/class/html.formproduct.class.php
+++ b/htdocs/product/class/html.formproduct.class.php
@@ -109,9 +109,10 @@ class FormProduct
 	 *  @param  int		$empty			1=Can be empty, 0 if not
 	 * 	@param	int		$disabled		1=Select is disabled
 	 * 	@param	int		$fk_product		Add quantity of stock in label for product with id fk_product. Nothing if 0.
+	 *  @param	string	$empty_label	Empty label if needed (only if $empty=1) 
 	 * 	@return	string					HTML select
 	 */
-	function selectWarehouses($selected='',$htmlname='idwarehouse',$filtertype='',$empty=0,$disabled=0,$fk_product=0)
+	function selectWarehouses($selected='',$htmlname='idwarehouse',$filtertype='',$empty=0,$disabled=0,$fk_product=0,$empty_label='')
 	{
 		global $langs,$user;
 
@@ -120,7 +121,7 @@ class FormProduct
 		$this->loadWarehouses($fk_product);
 
 		$out='<select class="flat"'.($disabled?' disabled="disabled"':'').' id="'.$htmlname.'" name="'.($htmlname.($disabled?'_disabled':'')).'">';
-		if ($empty) $out.='<option value="-1">&nbsp;</option>';
+		if ($empty) $out.='<option value="-1">'.($empty_label?$empty_label:'&nbsp;').'</option>';
 		foreach($this->cache_warehouses as $id => $arraytypes)
 		{
 			$out.='<option value="'.$id.'"';
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index a8803d6e5e83ed17fddcff94b0825ef71a2f2d31..8cac5ebe57386f08fa26fc4ec45684a24d55f7ae 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -1797,8 +1797,16 @@ class Product extends CommonObject
 	 */
 	function add_sousproduit($id_pere, $id_fils,$qty)
 	{
-		$sql = 'DELETE from '.MAIN_DB_PREFIX.'product_association';
-		$sql .= ' WHERE fk_product_pere  = "'.$id_pere.'" AND fk_product_fils = "'.$id_fils.'"';
+		// Clean parameters
+		if (! is_numeric($id_pere)) $id_pere=0;
+		if (! is_numeric($id_fils)) $id_fils=0;
+
+		$result=$this->del_sousproduit($id_pere, $id_fils);
+		if ($result < 0) return $result;
+
+		// Check not already father of id_pere (to avoid father -> child -> father links)
+		$sql = 'SELECT fk_product_pere from '.MAIN_DB_PREFIX.'product_association';
+		$sql .= ' WHERE fk_product_pere  = '.$id_fils.' AND fk_product_fils = '.$id_pere;
 		if (! $this->db->query($sql))
 		{
 			dol_print_error($this->db);
@@ -1806,37 +1814,27 @@ class Product extends CommonObject
 		}
 		else
 		{
-			$sql = 'SELECT fk_product_pere from '.MAIN_DB_PREFIX.'product_association';
-			$sql .= ' WHERE fk_product_pere  = "'.$id_fils.'" AND fk_product_fils = "'.$id_pere.'"';
-			if (! $this->db->query($sql))
-			{
-				dol_print_error($this->db);
-				return -1;
-			}
-			else
+			$result = $this->db->query($sql);
+			if ($result)
 			{
-				$result = $this->db->query($sql);
-				if ($result)
+				$num = $this->db->num_rows($result);
+				if($num > 0)
 				{
-					$num = $this->db->num_rows($result);
-					if($num > 0)
+					$this->error="isFatherOfThis";
+					return -1;
+				}
+				else
+				{
+					$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_association(fk_product_pere,fk_product_fils,qty)';
+					$sql .= ' VALUES ('.$id_pere.', '.$id_fils.', '.$qty.')';
+					if (! $this->db->query($sql))
 					{
-						$this->error="isFatherOfThis";
+						dol_print_error($this->db);
 						return -1;
 					}
 					else
 					{
-						$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_association(fk_product_pere,fk_product_fils,qty)';
-						$sql .= ' VALUES ("'.$id_pere.'","'.$id_fils.'","'.$qty.'")';
-						if (! $this->db->query($sql))
-						{
-							dol_print_error($this->db);
-							return -1;
-						}
-						else
-						{
-							return 1;
-						}
+						return 1;
 					}
 				}
 			}
@@ -1848,14 +1846,18 @@ class Product extends CommonObject
 	 *
 	 *  @param      int	$fk_parent		Id du produit auquel ne sera plus lie le produit lie
 	 *  @param      int	$fk_child		Id du produit a ne plus lie
-	 *  @return     int			    	< 0 si erreur, > 0 si ok
+	 *  @return     int			    	< 0 if KO, > 0 if OK
 	 */
 	function del_sousproduit($fk_parent, $fk_child)
 	{
+		if (! is_numeric($fk_parent)) $fk_parent=0;
+		if (! is_numeric($fk_child)) $fk_child=0;
+
 		$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_association";
-		$sql.= " WHERE fk_product_pere  = '".$fk_parent."'";
-		$sql.= " AND fk_product_fils = '".$fk_child."'";
+		$sql.= " WHERE fk_product_pere  = ".$fk_parent;
+		$sql.= " AND fk_product_fils = ".$fk_child;
 
+		dol_syslog(get_class($this).'::del_sousproduit sql='.$sql);
 		if (! $this->db->query($sql))
 		{
 			dol_print_error($this->db);
@@ -2120,7 +2122,7 @@ class Product extends CommonObject
 	 * 	Define value of this->res
 	 *
 	 *	@param		array	$prod			Products array
-	 *	@param		string	$compl_path		Directory path
+	 *	@param		string	$compl_path		Directory path of parents to add before
 	 *	@param		int		$multiply		Because each sublevel must be multiplicated by parent nb
 	 *	@param		int		$level			Init level
 	 *  @return 	void
@@ -2130,65 +2132,36 @@ class Product extends CommonObject
 		global $conf,$langs;
 
 		$product = new Product($this->db);
-		foreach($prod as $nom_pere => $desc_pere)
+		//var_dump($prod);
+		foreach($prod as $id_product => $desc_pere)	// nom_pere is 0 or id of sub_product
 		{
 			if (is_array($desc_pere))	// If this parent desc is an array, this is an array of childs
 			{
 				$id=(! empty($desc_pere[0]) ? $desc_pere[0] :'');
 				$nb=(! empty($desc_pere[1]) ? $desc_pere[1] :'');
 				$type=(! empty($desc_pere[2]) ? $desc_pere[2] :'');
-
-				if ($multiply)
-				{
-					//print "XXX ".$desc_pere[1]." multiply=".$multiply;
-					$img="";
-					$this->fetch($id);
-					$this->load_stock();
-					if ($this->stock_warehouse[1]->real < $this->seuil_stock_alerte)
-					{
-						$img=img_warning($langs->trans("StockTooLow"));
-					}
-					$this->res[]= array(
-/*								"<tr><td>&nbsp; &nbsp; &nbsp; ->
-                                <a href=\"".DOL_URL_ROOT."/product/fiche.php?id=".$desc_pere[0]."\">".$compl_path.stripslashes($nom_pere)."
-                                </a> (".$desc_pere[1].")</td><td align=\"center\"> ".($desc_pere[1]*$multiply)."</td><td>&nbsp</td><td>&nbsp</td>
-                                <td align=\"center\">".$this->stock_entrepot[1]." ".$img."</td></tr>",
-								$desc_pere[0],							// Id product
-*/								'id'=>$id,					// Id product
-								'nb'=>$nb,					// Nb of units that compose parent product
-								'nb_total'=>$nb*$multiply,	// Nb of units for all nb of product
-								'stock'=>$this->stock_warehouse[1]->real,		// Stock
-								'stock_alert'=>$this->seuil_stock_alerte,	// Stock alert
-								'fullpath' => $compl_path.$nom_pere,	// Label
-								'type'=>$type					// Nb of units that compose parent product
-								);
-				}
-				else
-				{
-					$this->fetch($desc_pere[0]);
-					$this->load_stock();
-					$this->res[]= array(
-/*					$compl_path.$nom_pere." (".$desc_pere[1].")",
-					$desc_pere[0],							// Id product
-*/					'id'=>$id,					// Id product
+				$label=(! empty($desc_pere[3]) ? $desc_pere[3] :'');
+				if ($multiply < 1) $multiply=1;
+
+				//print "XXX We add id=".$id." - label=".$label." - nb=".$nb." - multiply=".$multiply." fullpath=".$compl_path.$label."\n";
+				$this->fetch($id);
+				$this->load_stock();
+				$this->res[]= array(
+					'id'=>$id,					// Id product
 					'nb'=>$nb,					// Nb of units that compose parent product
-					'nb_total'=>$nb,				// Nb of units for all nb of product
-					'stock'=>$this->stock_warehouse[1]->real,		// Stock
+					'nb_total'=>$nb*$multiply,	// Nb of units for all nb of product
+					'stock'=>$this->stock_warehouse[1]->real,	// Stock
 					'stock_alert'=>$this->seuil_stock_alerte,	// Stock alert
-					'fullpath' => $compl_path.$nom_pere,	// Label
-					'type'=>$type					// Nb of units that compose parent product
-					);
-				}
-			}
-			else if($nom_pere != "0" && $nom_pere != "1")
-			{
-				$this->res[]= array($compl_path.$nom_pere,$desc_pere);
+					'fullpath' => $compl_path.$label,			// Label
+					'type'=>$type				// Nb of units that compose parent product
+				);
 			}
 
 			// Recursive call if child is an array
-			if (is_array($desc_pere[0]))
+			if (is_array($desc_pere['childs']))
 			{
-				$this ->fetch_prod_arbo($desc_pere[0], $nom_pere." -> ", $desc_pere[1]*$multiply, $level+1);
+				//print 'YYY We go down for '.$desc_pere[3]." -> \n";
+				$this ->fetch_prod_arbo($desc_pere['childs'], $compl_path.$desc_pere[3]." -> ", $desc_pere[1]*$multiply, $level+1);
 			}
 		}
 	}
@@ -2225,11 +2198,12 @@ class Product extends CommonObject
 		$this->res = array();
 		if (isset($this->sousprods) && is_array($this->sousprods))
 		{
-			foreach($this->sousprods as $nom_pere => $desc_pere)
+			foreach($this->sousprods as $prod_name => $desc_product)
 			{
-				if (is_array($desc_pere)) $this->fetch_prod_arbo($desc_pere,"",$multiply);
+				if (is_array($desc_product)) $this->fetch_prod_arbo($desc_product,"",$multiply);
 			}
 		}
+		//var_dump($this->res);
 		return $this->res;
 	}
 
@@ -2290,7 +2264,7 @@ class Product extends CommonObject
 
 
 	/**
-	 *  Return all parent products fo current product
+	 *  Return all direct parent products fo current product
 	 *
 	 *  @return 	array prod
 	 */
@@ -2321,19 +2295,19 @@ class Product extends CommonObject
 	}
 
 	/**
-	 *  Return childs of product with if fk_parent
+	 *  Return childs of product $id
 	 *
-	 * 	@param		int		$fk_parent	Id of product to search childs of
+	 * 	@param		int		$id			Id of product to search childs of
 	 *  @return     array       		Prod
 	 */
-	function getChildsArbo($fk_parent)
+	function getChildsArbo($id)
 	{
 		$sql = "SELECT p.rowid, p.label as label, pa.qty as qty, pa.fk_product_fils as id, p.fk_product_type";
 		$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
 		$sql.= ", ".MAIN_DB_PREFIX."product_association as pa";
 		$sql.= " WHERE p.rowid = pa.fk_product_fils";
-		$sql.= " AND pa.fk_product_pere = ".$fk_parent;
-		$sql.= " AND pa.fk_product_fils != ".$fk_parent;	// This should not happens, it is to avoid invinite loop if it happens
+		$sql.= " AND pa.fk_product_pere = ".$id;
+		$sql.= " AND pa.fk_product_fils != ".$id;	// This should not happens, it is to avoid infinite loop if it happens
 
 		dol_syslog(get_class($this).'::getChildsArbo sql='.$sql);
 		$res  = $this->db->query($sql);
@@ -2348,7 +2322,7 @@ class Product extends CommonObject
 				$listofchilds=$this->getChildsArbo($rec['id']);
 				foreach($listofchilds as $keyChild => $valueChild)
 				{
-					$prods[$rec['rowid']][$keyChild] = $valueChild;
+					$prods[$rec['rowid']]['childs'][$keyChild] = $valueChild;
 				}
 			}
 
@@ -2370,14 +2344,14 @@ class Product extends CommonObject
 	function get_sousproduits_arbo()
 	{
 		$parent = $this->getParent();
-		foreach($parent as $key => $value)
+		foreach($parent as $key => $value)		// key=label, value[0]=id
 		{
 			foreach($this->getChildsArbo($value[0]) as $keyChild => $valueChild)
 			{
 				$parent[$key][$keyChild] = $valueChild;
 			}
 		}
-		foreach($parent as $key => $value)
+		foreach($parent as $key => $value)		// key=label, value is array of childs
 		{
 			$this->sousprods[$key] = $value;
 		}
@@ -2412,6 +2386,10 @@ class Product extends CommonObject
 			$lien = '<a href="'.DOL_URL_ROOT.'/product/composition/fiche.php?id='.$this->id.'">';
 			$lienfin='</a>';
         }
+        else if ($option == 'category')
+        {
+        	$lien = '<a href="'.DOL_URL_ROOT.'/categories/categorie.php?id='.$this->id.'&type=0">';
+        }
         else
 		{
 			$lien = '<a href="'.DOL_URL_ROOT.'/product/fiche.php?id='.$this->id.'">';
diff --git a/htdocs/product/composition/fiche.php b/htdocs/product/composition/fiche.php
index 804759afe3a103fe2fbf9a8e20ad3a73afec5a89..71ce35c76e1370db1d039967eea4fe86df38c968 100644
--- a/htdocs/product/composition/fiche.php
+++ b/htdocs/product/composition/fiche.php
@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2004-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005      Eric Seigne          <eric.seigne@ryxeo.com>
  * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
  * Copyright (C) 2006      Andre Cianfarani     <acianfa@free.fr>
@@ -72,8 +72,8 @@ $cancel <> $langs->trans("Cancel") &&
 	$error=0;
 	for($i=0;$i<$_POST["max_prod"];$i++)
 	{
-		// print "<br> : ".$_POST["prod_id_chk".$i];
-		if($_POST["prod_id_chk".$i] != "")
+		print "<br> : ".$_POST["prod_id_chk".$i];
+		if ($_POST["prod_id_chk".$i] > 0)
 		{
 			if($product->add_sousproduit($id, $_POST["prod_id_".$i],$_POST["prod_qty_".$i]) > 0)
 			{
@@ -198,15 +198,18 @@ if ($id || $ref)
 			print '</tr>';
 
 			// Number of subproducts
-			$prodsfather = $product->getFather(); //Parent Products
+			$prodsfather = $product->getFather(); // Parent Products
 			$product->get_sousproduits_arbo();
-			print '<tr><td>'.$langs->trans("AssociatedProductsNumber").'</td><td>'.count($product->get_arbo_each_prod()).'</td>';
+			$prods_arbo=$product->get_arbo_each_prod();
+			$nbofsubproducts=count($prods_arbo);
+			print '<tr><td>'.$langs->trans("AssociatedProductsNumber").'</td><td>';
+			print $form->textwithpicto($nbofsubproducts, $langs->trans('IfZeroItIsNotAVirtualProduct'));
+			print '</td>';
 
 			dol_fiche_end();
 
 
-			// List of subproducts
-			$prods_arbo = $product->get_arbo_each_prod();
+			// List of products into this virtual product
 			if (count($prods_arbo) > 0)
 			{
 				print '<tr><td colspan="2">';
@@ -223,6 +226,7 @@ if ($id || $ref)
 					//print $productstatic->getNomUrl(1).'<br>';
 					//print $value[0];	// This contains a tr line.
 					print '<tr>';
+					//print '<td>'.$productstatic->getNomUrl(1,'composition').' ('.$value['nb'].($value['nb_total'] > $value['nb']?'->'.$value['nb_total']:'').') &nbsp &nbsp</td>';
 					print '<td>'.$productstatic->getNomUrl(1,'composition').' ('.$value['nb'].') &nbsp &nbsp</td>';
 					if (! empty($conf->stock->enabled)) print '<td>'.$langs->trans("Stock").' : <b>'.$productstatic->stock_reel.'</b></td>';
 					print '</tr>';
@@ -231,8 +235,10 @@ if ($id || $ref)
 				print '</td></tr>';
 			}
 
-			// Number of parent products
-			print '<tr><td>'.$langs->trans("ParentProductsNumber").'</td><td>'.count($prodsfather).'</td>';
+			// Number of parent virtual products
+			print '<tr><td>'.$langs->trans("ParentProductsNumber").'</td><td>';
+			print $form->textwithpicto(count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct'));
+			print '</td>';
 
 			if (count($prodsfather) > 0)
 			{
@@ -286,12 +292,14 @@ if ($id || $ref)
 		// Number of subproducts
 		$prodsfather = $product->getFather(); //Parent Products
 		$product->get_sousproduits_arbo();
-		print '<tr><td>'.$langs->trans("AssociatedProductsNumber").'</td><td>'.count($product->get_arbo_each_prod()).'</td>';
+		$prods_arbo=$product->get_arbo_each_prod();
+		$nbofsubproducts=count($prods_arbo);
+		print '<tr><td>'.$langs->trans("AssociatedProductsNumber").'</td><td>';
+		print $form->textwithpicto($nbofsubproducts, $langs->trans('IfZeroItIsNotAVirtualProduct'));
+		print '</td>';
 		print '</tr>';
 
 		// List of subproducts
-		$prods_arbo = $product->get_arbo_each_prod();
-		//var_dump($prods_arbo);
 		if(count($prods_arbo) > 0)
 		{
 			print '<tr><td colspan="2">';
@@ -316,8 +324,10 @@ if ($id || $ref)
 			print '</td></tr>';
 		}
 
-		// Number of parent products
-		print '<tr><td>'.$langs->trans("ParentProductsNumber").'</td><td>'.count($prodsfather).'</td>';
+		// Number of parent virtual products
+		print '<tr><td>'.$langs->trans("ParentProductsNumber").'</td><td>';
+		print $form->textwithpicto(count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct'));
+		print '</td>';
 
 		if (count($prodsfather) > 0)
 		{
diff --git a/htdocs/product/fiche.php b/htdocs/product/fiche.php
index e8775f4462137492ef3b7167f824845aff8e24a0..143ed6e95516c6d81934cdb994a6b757fa6cb036 100644
--- a/htdocs/product/fiche.php
+++ b/htdocs/product/fiche.php
@@ -693,7 +693,7 @@ else
         print '</td></tr>';
 
         // Label
-        print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td><input name="libelle" size="40" value="'.GETPOST('libelle').'"></td></tr>';
+        print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td><input name="libelle" size="40" maxlength="255" value="'.GETPOST('libelle').'"></td></tr>';
 
         // On sell
         print '<tr><td class="fieldrequired">'.$langs->trans("Status").' ('.$langs->trans("Sell").')</td><td>';
@@ -866,7 +866,7 @@ else
             print '<tr><td width="15%" class="fieldrequired">'.$langs->trans("Ref").'</td><td colspan="2"><input name="ref" size="40" maxlength="32" value="'.$object->ref.'"></td></tr>';
 
             // Label
-            print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td colspan="2"><input name="libelle" size="40" value="'.$object->libelle.'"></td></tr>';
+            print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td colspan="2"><input name="libelle" size="40" maxlength="255" value="'.$object->libelle.'"></td></tr>';
 
             // Status
             print '<tr><td class="fieldrequired">'.$langs->trans("Status").' ('.$langs->trans("Sell").')</td><td colspan="2">';
diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php
index f5af9518de192f5df2c5011c1d69f6b1fb9b7149..321936ad6a9553e5dd1a50de998b50d95a0f01ae 100644
--- a/htdocs/projet/class/project.class.php
+++ b/htdocs/projet/class/project.class.php
@@ -1048,7 +1048,7 @@ class Project extends CommonObject
 				}
 
 				$this->db->begin();
-				$res=$clone_project->update_note(dol_html_entity_decode($clone_project->note_private, ENT_QUOTES));
+				$res=$clone_project->update_note(dol_html_entity_decode($clone_project->note_private, ENT_QUOTES), '_private');
 				if ($res < 0)
 				{
 					$this->error.=$clone_project->error;
diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php
index 0adc21eb6cc3c85a58485f1408bdc1899173a1fd..ac29870106b0380a1b5dea25726378410ba3003e 100644
--- a/htdocs/projet/class/task.class.php
+++ b/htdocs/projet/class/task.class.php
@@ -1064,7 +1064,7 @@ class Task extends CommonObject
 				}
 
 				$this->db->begin();
-				$res=$clone_task->update_note(dol_html_entity_decode($clone_task->note_private, ENT_QUOTES));
+				$res=$clone_task->update_note(dol_html_entity_decode($clone_task->note_private, ENT_QUOTES), '_private');
 				if ($res < 0)
 				{
 					$this->error.=$clone_task->error;
diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php
index 3a36fd1f5915a98b33e90f75007aa8cb308c4bee..e19571f9518d65bd77f4aad0311762115191f3ba 100644
--- a/htdocs/projet/ganttview.php
+++ b/htdocs/projet/ganttview.php
@@ -184,8 +184,8 @@ if (count($tasksarray)>0)
 
 	// Show Gant diagram from $taskarray using JSGantt
 
-	$dateformat=$langs->trans("FormatDateShort");
-	$dateformat=strtolower($langs->trans("FormatDateShortJava"));
+	$dateformat=$langs->trans("FormatDateShort");				// Used by include ganttchart.php later
+	$dateformat=$langs->trans("FormatDateShortJQuery");			// Used by include ganttchart.php later
 	$array_contacts=array();
 	$tasks=array();
 	$project_dependencies=array();
diff --git a/htdocs/projet/note.php b/htdocs/projet/note.php
index 26eafbc16d22136f3dcbd6292d4d5c39e992e17c..dddab2a5e790c63cf434a8204f67de5cc37ddd2a 100644
--- a/htdocs/projet/note.php
+++ b/htdocs/projet/note.php
@@ -63,7 +63,7 @@ if ($action == 'setnote_public' && $user->rights->projet->creer)
 if ($action == 'setnote_private' && $user->rights->projet->creer)
 {
 	$object->fetch($id);
-	$result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES));
+	$result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private');
 	if ($result < 0) dol_print_error($db,$object->error);
 }
 
diff --git a/htdocs/projet/tasks/note.php b/htdocs/projet/tasks/note.php
index 9931bde05103b2c8198b6e2cdb7b642a91ead7a4..1b6bebeb9d5a6a84cd604552f9ffd3f661dc95dd 100644
--- a/htdocs/projet/tasks/note.php
+++ b/htdocs/projet/tasks/note.php
@@ -93,7 +93,7 @@ if ($action == 'setnote_public' && ! empty($permission))
 
 else if ($action == 'setnote_private' && ! empty($permission))
 {
-    $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES));
+    $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private');
     if ($result < 0) dol_print_error($db,$object->error);
 }
 
diff --git a/htdocs/public/demo/index.php b/htdocs/public/demo/index.php
index c0e47ea955d3992bb805582328a389110905dd12..1c03c17c5b5e03549cf229426dc8d763ec8f67ff 100644
--- a/htdocs/public/demo/index.php
+++ b/htdocs/public/demo/index.php
@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2001-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2006-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2006-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2010      Regis Houssin        <regis.houssin@capnetworks.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -42,7 +42,7 @@ $hookmanager->initHooks(array('demo'));
 
 $demoprofiles=array(
 	array('default'=>'1', 'key'=>'profdemoservonly','label'=>'DemoCompanyServiceOnly',
-	'disablemodules'=>'adherent,barcode,boutique,cashdesk,categorie,don,expedition,externalsite,mailmanspip,prelevement,product,stock',
+	'disablemodules'=>'adherent,barcode,boutique,cashdesk,categorie,don,expedition,externalsite,mailmanspip,margin,prelevement,product,stock',
 	'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot8.png'),
 	array('default'=>'-1','key'=>'profdemoshopwithdesk','label'=>'DemoCompanyShopWithCashDesk',
 	'disablemodules'=>'adherent,boutique,categorie,don,externalsite,ficheinter,mailmanspip,prelevement,product,stock',
@@ -54,10 +54,10 @@ $demoprofiles=array(
 	'disablemodules'=>'adherent,boutique,don,externalsite,mailmanspip',
 	'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot9.png'),
 	array('default'=>'-1', 'key'=>'profdemofun','label'=>'DemoFundation',
-	'disablemodules'=>'banque,barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,prelevement,product,projet,propal,propale,service,societe,stock,tax',
+	'disablemodules'=>'banque,barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,margin,prelevement,product,projet,propal,propale,service,societe,stock,tax',
 	'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot6.png'),
 	array('default'=>'0', 'key'=>'profdemofun2','label'=>'DemoFundation2',
-	'disablemodules'=>'barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,prelevement,product,projet,propal,propale,service,societe,stock,tax',
+	'disablemodules'=>'barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,margin,prelevement,product,projet,propal,propale,service,societe,stock,tax',
 	'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot6.png')
 );
 
diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
index d6666495a143302844d5d1595b4216bfd4528594..0c1b80169389f30a5d59f0fbd622817c9e1502ad 100644
--- a/htdocs/societe/class/societe.class.php
+++ b/htdocs/societe/class/societe.class.php
@@ -1455,6 +1455,15 @@ class Societe extends CommonObject
         {
             $lien = '<a href="'.DOL_URL_ROOT.'/fourn/fiche.php?socid='.$this->id;
         }
+        else if ($option == 'category')
+        {
+        	$lien = '<a href="'.DOL_URL_ROOT.'/categories/categorie.php?id='.$this->id.'&type=2';
+        }
+        else if ($option == 'category_supplier')
+        {
+        	$lien = '<a href="'.DOL_URL_ROOT.'/categories/categorie.php?id='.$this->id.'&type=1';
+        }
+       
         // By default
         if (empty($lien))
         {
@@ -1462,7 +1471,7 @@ class Societe extends CommonObject
         }
 
         // Add type of canvas
-        $lien.=(!empty($this->canvas)?'&amp;canvas='.$this->canvas:'').'">';
+        $lien.=(!empty($this->canvas)?'&canvas='.$this->canvas:'').'">';
         $lienfin='</a>';
 
         if ($withpicto) $result.=($lien.img_object($langs->trans("ShowCompany").': '.$name,'company').$lienfin);
diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php
index 7c0a4c0332f251408d02d5e7d868867fc03e57d6..aff1fded6d3da1715e3a1679807733712715cb7a 100644
--- a/htdocs/societe/consumption.php
+++ b/htdocs/societe/consumption.php
@@ -295,14 +295,13 @@ if ($sql_select)
 			// Define output language
 			if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE))
 			{
-				$this->fetch_thirdparty();
 				$prod = new Product($db);
 				$prod->fetch($objp->fk_product);
 
 				$outputlangs = $langs;
 				$newlang='';
 				if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
-				if (empty($newlang)) $newlang=$this->client->default_lang;
+				if (empty($newlang)) $newlang=$object->default_lang;
 				if (! empty($newlang))
 				{
 					$outputlangs = new Translate("",$conf);
diff --git a/htdocs/societe/societe.php b/htdocs/societe/societe.php
index 26583442b2c4e5054a288346783f8aee0f9ca8f1..93401eaebf07a524ce057e9857ac7a4fdc65b564 100644
--- a/htdocs/societe/societe.php
+++ b/htdocs/societe/societe.php
@@ -122,7 +122,7 @@ if ($mode == 'search')
 	if ($search_type > 0 && in_array($search_type,array('1,3','2,3'))) $sql .= " AND s.client IN (".$db->escape($search_type).")";
 	if ($search_type > 0 && in_array($search_type,array('4')))         $sql .= " AND s.fournisseur = 1";
 	if ($search_type == '0') $sql .= " AND s.client = 0 AND s.fournisseur = 0";
-	
+
 	$result=$db->query($sql);
 	if ($result)
 	{
@@ -365,13 +365,13 @@ if ($resql)
 	print '<td class="liste_titre" align="middle">';
 	print '<select class="flat" name="search_type">';
 	print '<option value="-1"'.($search_type==''?' selected="selected"':'').'>&nbsp;</option>';
-	print '<option value="1,3"'.($search_type=='1,3'?' selected="selected"':'').'>'.$langs->trans('Customer').'</option>';
+	if (empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print '<option value="1,3"'.($search_type=='1,3'?' selected="selected"':'').'>'.$langs->trans('Customer').'</option>';
 	if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) print '<option value="2,3"'.($search_type=='2,3'?' selected="selected"':'').'>'.$langs->trans('Prospect').'</option>';
 	//if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) print '<option value="3"'.($search_type=='3'?' selected="selected"':'').'>'.$langs->trans('ProspectCustomer').'</option>';
 	print '<option value="4"'.($search_type=='4'?' selected="selected"':'').'>'.$langs->trans('Supplier').'</option>';
 	print '<option value="0"'.($search_type=='0'?' selected="selected"':'').'>'.$langs->trans('Others').'</option>';
 	print '</select></td>';
-	// Status	
+	// Status
 	print '<td class="liste_titre" align="right">';
 	print '<input type="image" class="liste_titre" name="button_search" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/search.png" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
 	print '&nbsp; ';
diff --git a/htdocs/theme/amarok/graph-color.php b/htdocs/theme/amarok/graph-color.php
index 96e9894c7fa935c8d33636ad7e525f924fb6fa39..1a0d2253a2a4afecd12330079ddf32d2a351acc9 100755
--- a/htdocs/theme/amarok/graph-color.php
+++ b/htdocs/theme/amarok/graph-color.php
@@ -22,10 +22,10 @@
  *      \ingroup    core
  */
 
-global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet;
-$theme_bordercolor = array(235,235,224);
-$theme_datacolor = array(array(125,135,150), array(200,160,180), array(190,190,220), array(170,140,190), array(190,190,170));
-$theme_bgcolor = array(hexdec('F4'),hexdec('F4'),hexdec('F4'));
-$theme_bgcoloronglet = array(hexdec('DE'),hexdec('E7'),hexdec('EC'));
+global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet;
+$theme_bordercolor = array(235,235,224);
+$theme_datacolor = array(array(190,190,220), array(200,160,180), array(125,135,150), array(170,140,190), array(190,190,170));
+$theme_bgcolor = array(hexdec('F4'),hexdec('F4'),hexdec('F4'));
+$theme_bgcoloronglet = array(hexdec('DE'),hexdec('E7'),hexdec('EC'));
 
 ?>
diff --git a/htdocs/theme/amarok/style.css.php b/htdocs/theme/amarok/style.css.php
index 6bf445326218d0c4ee0653a65d5daf55696babd9..c5e92cdcb1bdf2277869745762c89b857895964c 100755
--- a/htdocs/theme/amarok/style.css.php
+++ b/htdocs/theme/amarok/style.css.php
@@ -21,25 +21,28 @@
 
 /**
  *		\file       htdocs/theme/amarok/style.css.php
- *		\brief      Fichier de style CSS du theme amarok
+ *		\brief      File for CSS style sheet Amarok
  */
 
 
 
-//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1');	// Not disabled cause need to load personalized language
+//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1');	// Not disabled because need to load personalized language
 //if (! defined('NOREQUIREDB'))   define('NOREQUIREDB','1');	// Not disabled to increase speed. Language code is found on url.
 if (! defined('NOREQUIRESOC'))    define('NOREQUIRESOC','1');
-//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');	// Not disabled cause need to do translations
+//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');	// Not disabled because need to do translations
 if (! defined('NOCSRFCHECK'))     define('NOCSRFCHECK',1);
 if (! defined('NOTOKENRENEWAL'))  define('NOTOKENRENEWAL',1);
-if (! defined('NOLOGIN'))         define('NOLOGIN',1);
+if (! defined('NOLOGIN'))         define('NOLOGIN',1);			// File must be accessed by logon page so without login
 if (! defined('NOREQUIREMENU'))   define('NOREQUIREMENU',1);
 if (! defined('NOREQUIREHTML'))   define('NOREQUIREHTML',1);
 if (! defined('NOREQUIREAJAX'))   define('NOREQUIREAJAX','1');
 
 session_cache_limiter(FALSE);
 
-require_once("../../main.inc.php");
+require_once '../../main.inc.php';
+
+// Load user to have $user->conf loaded (not done into main because of NOLOGIN constant defined)
+if (empty($user->id) && ! empty($_SESSION['dol_login'])) $user->fetch('',$_SESSION['dol_login']);
 
 // Define css type
 header('Content-type: text/css');
@@ -69,12 +72,55 @@ $fontlist='helvetica,arial,tahoma,verdana';    //$fontlist='Verdana,Helvetica,Ar
 $img_liste_titre=dol_buildpath($path.'/theme/'.$theme.'/img/menus/trtitle.png',1);
 $img_head=dol_buildpath($path.'/theme/'.$theme.'/img/headbg2.jpg',1);
 $img_button=dol_buildpath($path.'/theme/'.$theme.'/img/button_bg.png',1);
+$dol_hide_topmenu=$conf->dol_hide_topmenu;
+$dol_hide_leftmenu=$conf->dol_hide_leftmenu;
+$dol_optimize_smallscreen=$conf->dol_optimize_smallscreen;
+$dol_no_mouse_hover=$conf->dol_no_mouse_hover;
+$dol_use_jmobile=$conf->dol_use_jmobile;
+
+
+// Define reference colors
+// Example: Light grey: $colred=235;$colgreen=235;$colblue=235;
+// Example: Pink:       $colred=230;$colgreen=210;$colblue=230;
+// Example: Green:      $colred=210;$colgreen=230;$colblue=210;
+// Example: Ocean:      $colred=220;$colgreen=220;$colblue=240;
+//$conf->global->THEME_ELDY_ENABLE_PERSONALIZED=0;
+//$user->conf->THEME_ELDY_ENABLE_PERSONALIZED=0;
+//var_dump($user->conf->THEME_ELDY_RGB);
+$colred  =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_RGB)?235:hexdec(substr($conf->global->THEME_ELDY_RGB,0,2))):(empty($user->conf->THEME_ELDY_RGB)?235:hexdec(substr($user->conf->THEME_ELDY_RGB,0,2)));
+$colgreen=empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_RGB)?235:hexdec(substr($conf->global->THEME_ELDY_RGB,2,2))):(empty($user->conf->THEME_ELDY_RGB)?235:hexdec(substr($user->conf->THEME_ELDY_RGB,2,2)));
+$colblue =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_RGB)?235:hexdec(substr($conf->global->THEME_ELDY_RGB,4,2))):(empty($user->conf->THEME_ELDY_RGB)?235:hexdec(substr($user->conf->THEME_ELDY_RGB,4,2)));
+
+// Colors
+$isred=max(0,(2*$colred-$colgreen-$colblue)/2);        // 0 - 255
+$isgreen=max(0,(2*$colgreen-$colred-$colblue)/2);      // 0 - 255
+$isblue=max(0,(2*$colblue-$colred-$colgreen)/2);       // 0 - 255
+$colorback1=($colred-3).','.($colgreen-3).','.($colblue-3);         // topmenu
+$colorback2=($colred+5).','.($colgreen+5).','.($colblue+5);
+$colorbacktab1=($colred+15).','.($colgreen+16).','.($colblue+17);      // vmenu
+$colorbacktab1b=($colred+5).','.($colgreen+6).','.($colblue+7);        // vmenu (not menu)
+$colorbacktab2=($colred-15).','.($colgreen-15).','.($colblue-15);
+$colorbacktitle1=($colred-5).','.($colgreen-5).','.($colblue-5);    // title of array
+$colorbacktitle2=($colred-15).','.($colgreen-15).','.($colblue-15);
+$colorbacktabcard1=($colred+15).','.($colgreen+16).','.($colblue+17);  // card
+$colorbacktabcard2=($colred-15).','.($colgreen-15).','.($colblue-15);
+$colorbacktabactive=($colred-15).','.($colgreen-15).','.($colblue-15);
+$colorbacklineimpair1=(244+round($isred/3)).','.(244+round($isgreen/3)).','.(244+round($isblue/3));    // line impair
+$colorbacklineimpair2=(250+round($isred/3)).','.(250+round($isgreen/3)).','.(250+round($isblue/3));    // line impair
+$colorbacklineimpairhover=(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9));    // line impair
+$colorbacklinepair1='255,255,255';    // line pair
+$colorbacklinepair2='255,255,255';    // line pair
+$colorbacklinepairhover=(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9));
+$colorbackbody='#f5f5f5';
+$colortext='40,40,40';
+$fontsize=empty($conf->dol_optimize_smallscreen)?'12':'14';
+$fontsizesmaller=empty($conf->dol_optimize_smallscreen)?'11':'14';
 
 ?>
 
 
 /* ============================================================================== */
-/* Styles par défaut                                                              */
+/* Default styles                                                                 */
 /* ============================================================================== */
 
 *, html {
@@ -84,31 +130,17 @@ font-size:100%;
 }
 
 body {
-	background-color:#f5f5f5;
-	<?php if ($_SESSION['dol_login'] != '') {?>
-	<?php if (GETPOST("optioncss") != 'print') {?>
-	background-image:url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/vmenu.png',1); ?>);
-	background-repeat:repeat-y;
-	margin:0px;
-	<?php } ?>
-	<?php } else {?>
-	background-image:url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/background_login.png',1); ?>);
-	margin:100px;
-	<?php } ?>
+<?php if (GETPOST("optioncss") == 'print' || ! empty($conf->dol_optimize_smallscreen)) {  ?>
+	background-color: #FFFFFF;
+<?php } else { ?>
+	background-color: <?php print $colorbackbody; ?>;
+<?php } ?>
 	color:#232323;
 	font-size:<?php print $fontsize ?>px;
    	font-family:<?php print $fontlist ?>;
-
     <?php print 'direction:'.$langs->trans("DIRECTION").";\n"; ?>
 }
 
-.checkVatPopup {
-	background-color:#f5f5f5;
-	background-image:none;
-	margin:10px;
-	line-height:16px;
-}
-
 a {
 	font-family:<?php print $fontlist ?>;
 	font-weight:bold;
@@ -194,6 +226,15 @@ div.inline-block
 	display:inline-block;
 }
 
+th .button {
+    -moz-box-shadow: none !important;
+    -webkit-box-shadow: none !important;
+    box-shadow: none !important;
+	-moz-border-radius:0px !important;
+	-webkit-border-radius:0px !important;
+	border-radius:0px !important;
+}
+
 .valignmiddle {
 	vertical-align: middle;
 }
@@ -211,11 +252,102 @@ div.inline-block
 }
 
 
+.blockvmenubookmarks .menu_contenu {
+	background-color: transparent;
+}
+
+/* ! Message d'erreur lors du login : */
+center .error { padding:8px !important; padding-left:26px !important; padding-right:20px; width:inherit; max-width:450px;color:#552323 !important; font-size:14px; border-radius:8px; text-align: left;}
+
+
+
 /* ============================================================================== */
-/* Login																		  */
+/* Styles to hide objects                                                         */
 /* ============================================================================== */
 
-body.body center{color:white;}
+.hideobject { display:none; }
+<?php if (! empty($dol_optimize_smallscreen)) { ?>
+.hideonsmartphone { display: none; }
+.noenlargeonsmartphone { width : 50px !important; display: inline !important; }
+<?php } ?>
+.linkobject { cursor:pointer; }
+
+
+/* ============================================================================== */
+/* Styles for dragging lines                                                      */
+/* ============================================================================== */
+
+.dragClass {
+	color: #333333;
+}
+td.showDragHandle {
+	cursor: move;
+}
+.tdlineupdown {
+	white-space: nowrap;
+}
+
+/* ============================================================================== */
+/* Menu top et 1ere ligne tableau                                                 */
+/* ============================================================================== */
+
+div.tmenu {
+	<?php if (GETPOST("optioncss") == 'print') {?>
+	display:none;
+	<?php } else {?>
+	position:relative;
+	display:block;
+	margin:0;
+	padding:0;
+	padding-left:1em;
+	top:0;
+	left:0;
+	right:0;
+    white-space:nowrap;
+	height:36px;
+	<?php if ($conf->browser->name != 'ie') echo "line-height:36px; /* disabled for ie9 */ \n"; ?>
+	background:#333333;
+    background-image:linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
+	background-image:-o-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
+	background-image:-moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
+	background-image:-webkit-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
+	background-image:-ms-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
+	background-image:-webkit-gradient(
+		linear,
+		left top,
+		left bottom,
+		color-stop(0, rgba(255,255,255,.3)),
+		color-stop(1, rgba(0,0,0,.3))
+	);
+	border-bottom:solid 1px rgba(0,0,0,.8);
+	box-shadow:0 0 6px rgba(0,0,0,.4) !important;
+	z-index:100;
+	<?php } ?>
+}
+
+div.tmenu a {
+	font-weight:normal;
+}
+
+div.tmenu li {
+	display:inline-table;
+	margin-right:1em;
+	text-transform:uppercase;
+}
+
+div.tmenu li a {color:#cccccc;}
+div.tmenu li a:hover { color:rgba(255,255,255,1);}
+
+div.tmenu ul li a.tmenusel {/* texte du menu principal sélectionné */
+	color:#ffffff;
+	font-weight:bold;
+}
+
+.tmenudisabled { color:#808080 !important; cursor: not-allowed; }
+
+
+
+/* Login */
 
 form#login {
 	display:block;
@@ -329,96 +461,6 @@ table.login_table .vmenu {
 	font-size:120%;
 }
 
-.blockvmenubookmarks .menu_contenu {
-	background-color: transparent;
-}
-
-/* ! Message d'erreur lors du login : */
-center .error { padding:8px !important; padding-left:26px !important; padding-right:20px; width:inherit; max-width:450px;color:#552323 !important; font-size:14px; border-radius:8px; text-align: left;}
-
-
-
-/* ============================================================================== */
-/* Styles to hide objects                                                         */
-/* ============================================================================== */
-
-.hideobject { display:none; }
-<?php if (! empty($dol_optimize_smallscreen)) { ?>
-.hideonsmartphone { display: none; }
-.noenlargeonsmartphone { width : 50px !important; display: inline !important; }
-<?php } ?>
-.linkobject { cursor:pointer; }
-
-
-/* For dragging lines */
-
-.dragClass {color:#333333;}
-td.showDragHandle {cursor:move;}
-.tdlineupdown {white-space:nowrap;}
-
-
-/* ============================================================================== */
-/* Menu top et 1ère ligne tableau                                                 */
-/* ============================================================================== */
-
-div.tmenu {
-	<?php if (GETPOST("optioncss") == 'print') {?>
-	display:none;
-	<?php } else {?>
-	position:relative;
-	display:block;
-	margin:0;
-	padding:0;
-	padding-left:1em;
-	top:0;
-	left:0;
-	right:0;
-    white-space:nowrap;
-	height:36px;
-	<?php if ($conf->browser->name != 'ie') echo "line-height:36px; /* disabled for ie9 */ \n"; ?>
-	background:#333333;
-    background-image:linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
-	background-image:-o-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
-	background-image:-moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
-	background-image:-webkit-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
-	background-image:-ms-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
-	background-image:-webkit-gradient(
-		linear,
-		left top,
-		left bottom,
-		color-stop(0, rgba(255,255,255,.3)),
-		color-stop(1, rgba(0,0,0,.3))
-	);
-	border-bottom:solid 1px rgba(0,0,0,.8);
-	box-shadow:0 0 6px rgba(0,0,0,.4) !important;
-	z-index:100;
-	<?php } ?>
-}
-
-div.tmenu a {
-	font-weight:normal;
-}
-
-div.tmenu li {
-	display:inline-table;
-	margin-right:1em;
-	text-transform:uppercase;
-}
-
-div.tmenu li a {color:#cccccc;}
-div.tmenu li a:hover {color:rgba(255,255,255,.2);}
-
-div.tmenu ul li a.tmenusel {/* texte du menu principal sélectionné */
-	color:#ffffff;
-	font-weight:bold;
-}
-
-.tmenudisabled { color:#808080 !important; cursor: not-allowed; }
-
-/* --- end nav --- */
-
-/* Login */
-
 div.login_block {
 	position:absolute;
 	top:5px;
@@ -438,16 +480,16 @@ div.login_block table {
 
 div.login {
 	white-space:nowrap;
-	padding:8px 0px 0px 0px;
+	padding: <?php echo ($conf->dol_optimize_smallscreen?'0':'8')?>px 0px 0px 0px;
 	margin:0px 0px 0px 8px;
 	font-weight:bold;
 }
 
 img.login, img.printer, img.entity {
-	padding:8px 0px 0px 0px;
+	padding: <?php echo ($conf->dol_optimize_smallscreen?'0':'8')?>px 0px 0px 0px;
 	margin:0px 0px 0px 8px;
 	text-decoration:none;
-	color:#ffffff;
+	color: white;
 	font-weight:bold;
 }
 
@@ -461,6 +503,9 @@ div.vmenu {
 	display:none;
 	<?php } else {?>
 	width:170px;
+	-moz-box-shadow: 4px 4px 4px #CCC;
+	-webkit-box-shadow: 4px 4px 4px #CCC;
+	box-shadow: 4px 4px 4px #CCC;
 	<?php } ?>
 }
 
@@ -773,8 +818,11 @@ div.tabs {
 div.tabBar {
     background-color:#ffffff;
     padding:6px;
-    margin:3px 0px 5px;
+    margin:3px 0px 14px 0px;
     border:1px solid #bbbbbb;
+    -moz-box-shadow: 4px 4px 4px #DDD;
+	-webkit-box-shadow: 4px 4px 4px #DDD;
+	box-shadow: 4px 4px 4px #DDD;
 }
 
 div.tabBar table.notopnoleftnoright {
@@ -1066,7 +1114,7 @@ table.liste {
 
 table.liste td {padding:1px 2px 1px 0px;}
 
-tr.liste_titre, tr.box_titre {
+div.liste_titre, tr.liste_titre, tr.box_titre {
 	padding:4px;
 	background-color:rgba(0,0,0,.2);
 	background-image:linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
@@ -1116,13 +1164,13 @@ tr.impair td, tr.pair td {padding:1px 1px 1px 2px;}
 tr.impair table.nobordernopadding td, tr.pair table.nobordernopadding td {padding:1px 0px;}
 
 .impair {
-	background:#f4f4f4;
+	background:#fdfdfd;
 	font-family:<?php print $fontlist ?>;
 	border:0px;
 }
 
 .pair {
-	background:#eaeaea;
+	background:#f4f4f4;
 	font-family:<?php print $fontlist ?>;
 	border:0px;
 }
@@ -1147,12 +1195,12 @@ tr.impair table.nobordernopadding td, tr.pair table.nobordernopadding td {paddin
 }
 
 tr.box_impair {
-	background:#f4f4f4;
+	background:#fdfdfd;
 	font-family:<?php print $fontlist ?>;
 }
 
 tr.box_pair {
-	background:#eaeaea;
+	background:#f4f4f4;
 	font-family:<?php print $fontlist ?>;
 }
 
@@ -1423,7 +1471,7 @@ td.dpHead {
 
 /* Jour courant */
 .dpSelected {
-	background-color:#a61111;
+	background-color:#0B63A2;
 	color:#ffffff;
 	font-weight:bold;
 }
@@ -1468,7 +1516,7 @@ td.dpHead {
 	padding:0px 2px;
 	font-size:9px;
 	border-width:0px;
-	color:#a61111;
+	color:#0B63A2;
 	vertical-align:middle;
 	cursor:pointer;
 }
@@ -1499,17 +1547,9 @@ table.cal_month    { border-spacing: 0px; }
 .cal_current_month_right { border-right: solid 1px #E0E0E0; }
 .cal_other_month_right   { border-right: solid 1px #C0C0C0; }
 
-.cal_other_month {
-	background:#dddddd;
-}
-
-.cal_past_month {
-	background:#eeeeee;
-}
-
-.cal_current_month {
-	background:#ffffff;
-}
+.cal_other_month   { opacity: 0.6; background: #EAEAEA; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 1px; padding-top: 0px; padding-bottom: 0px; }
+.cal_past_month    { opacity: 0.6; background: #EEEEEE; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 1px; padding-top: 0px; padding-bottom: 0px; }
+.cal_current_month { background: #FFFFFF; border-left: solid 1px #E0E0E0; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 1px; padding-top: 0px; padding-bottom: 0px; }
 
 .cal_today {
 	background:#ffffff;
@@ -1518,37 +1558,19 @@ table.cal_month    { border-spacing: 0px; }
 
 div.dayevent table.nobordernopadding tr td {padding:1px;}
 
-table.cal_event {
-	border-collapse:collapse;
-	margin-bottom:1px;
-}
-
-ul.cal_event       { padding-right: 2px; padding-top: 1px; border: none; list-style-type: none; margin: 0 auto; padding-left: 0px; padding-start: 0px; -khtml-padding-start: 0px; -o-padding-start: 0px; -webkit-padding-start: 0px; -webkit-padding-start: 0px; }
+table.cal_event    { border: none; border-collapse: collapse; margin-bottom: 1px; -webkit-border-radius: 6px; border-radius: 6px;
+						-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25);
+						moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25);
+						box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25);
+						background: -webkit-gradient(linear, left top, left bottom, from(#006aac), to(#00438d));
+						}
+table.cal_event td { border: none; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 2px; padding-top: 0px; padding-bottom: 0px; }
+ul.cal_event       { padding-right: 2px; padding-top: 1px; border: none; list-style-type: none; margin: 0 auto; padding-left: 0px; padding-start: 0px; -khtml-padding-start: 0px; -o-padding-start: 0px; -moz-padding-start: 0px; -webkit-padding-start: 0px; }
 li.cal_event       { border: none; list-style-type: none; }
-
-.cal_event a:link {
-	color:#232323;
-	font-size:11px;
-	font-weight:normal !important;
-}
-
-.cal_event a:visited {
-	color:#232323;
-	font-size:11px;
-	font-weight:normal !important;
-}
-
-.cal_event a:active {
-	color:#232323;
-	font-size:11px;
-	font-weight:normal !important;
-}
-
-.cal_event a:hover {
-	color:rgba(255,255,255,.75);
-	font-size:11px;
-	font-weight:normal !important;
-}
+.cal_event a:link    { color: #111111; font-size: 11px; font-weight: normal !important; }
+.cal_event a:visited { color: #111111; font-size: 11px; font-weight: normal !important; }
+.cal_event a:active  { color: #111111; font-size: 11px; font-weight: normal !important; }
+.cal_event a:hover   { color: #111111; font-size: 11px; font-weight: normal !important; color:rgba(255,255,255,.75); }
 
 
 /* ============================================================================== */
diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php
index 47e27f3f968f6030e59ad9514a99a2466b8fa9fa..bcfb9a051bda53ce340294c75f0541885a452480 100644
--- a/htdocs/theme/eldy/style.css.php
+++ b/htdocs/theme/eldy/style.css.php
@@ -58,6 +58,8 @@ if (GETPOST('theme')) $conf->theme=GETPOST('theme');  // If theme was forced on
 $langs->load("main",0,1);
 $right=($langs->trans("DIRECTION")=='rtl'?'left':'right');
 $left=($langs->trans("DIRECTION")=='rtl'?'right':'left');
+$fontsize=empty($conf->dol_optimize_smallscreen)?'12':'12';
+$fontsizesmaller=empty($conf->dol_optimize_smallscreen)?'11':'11';
 
 $path='';    	// This value may be used in future for external module to overwrite theme
 $theme='eldy';	// Value of theme
@@ -198,7 +200,7 @@ if (! empty($conf->dol_optimize_smallscreen)) $fontsize=11;
 ?>
 
 /* ============================================================================== */
-/* Styles par defaut                                                              */
+/* Default styles                                                                 */
 /* ============================================================================== */
 
 body {
@@ -304,8 +306,8 @@ input[type=image] { background-color: transparent; border: none; box-shadow: non
     box-shadow: 4px 4px 4px #CCC;
 }
 form {
-    padding: 0em 0em 0em 0em;
-    margin: 0em 0em 0em 0em;
+    padding:0px;
+    margin:0px;
 }
 div.float
 {
@@ -852,9 +854,9 @@ td.vmenu {
 
 .vmenu {
 	margin-left: 4px;
-<?php if (GETPOST("optioncss") == 'print') { ?>
+	<?php if (GETPOST("optioncss") == 'print') { ?>
     display: none;
-<?php } ?>
+	<?php } ?>
 }
 
 .menu_contenu { padding-top: 1px; }
@@ -1317,11 +1319,14 @@ div.tabsAction {
 
 
 a.tabTitle {
-    background: #657090;
-    color: white;
+/*    background: #657090;
+    color: white;*/
+    color:rgba(0,0,0,.5);
+    margin-right:10px;
+    text-shadow:1px 1px 1px #ffffff;
 	font-family: <?php print $fontlist ?>;
 	font-weight: normal;
-    padding: 0px 6px 2px 6px;
+    padding: 4px 6px 2px 6px;
     margin: 0px 6px;
     text-decoration: none;
     white-space: nowrap;
@@ -1329,7 +1334,7 @@ a.tabTitle {
 
 a.tab:link, a.tab:visited, a.tab:hover, a.tab#active {
 	font-family: <?php print $fontlist ?>;
-    padding: 2px 6px 2px 6px;
+    padding: 4px 6px 2px 6px;
     margin: 0em 0.2em;
     text-decoration: none;
     white-space: nowrap;
@@ -1364,6 +1369,7 @@ a.tab#active {
 a.tab:link, a.tab:visited, a.tab:hover, a.tab#active
 {
     color: #<?php echo $colortextmain; ?>;
+	font-weight: normal !important;
 }
 
 a.tabimage {
diff --git a/htdocs/user/note.php b/htdocs/user/note.php
index 421d30cbc7a9cf55cfdcadb24d4b0d09a3540252..5ccd23f30428a39420d212cc6c0d965a13ef5e11 100644
--- a/htdocs/user/note.php
+++ b/htdocs/user/note.php
@@ -58,7 +58,7 @@ if ($action == 'update' && $user->rights->user->user->creer && ! $_POST["cancel"
 {
 	$db->begin();
 
-	$res=$fuser->update_note($_POST["note"],$user);
+	$res=$fuser->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES));
 	if ($res < 0)
 	{
 		$mesg='<div class="error">'.$adh->error.'</div>';
diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php
index e6836a9b1d4f37cebba6fb3abdeffa47677b6622..bca0ba9ee6a37f4b0369447d0bff89cb66d47931 100644
--- a/htdocs/user/perms.php
+++ b/htdocs/user/perms.php
@@ -260,7 +260,7 @@ print '</tr>'."\n";
 
 // Lastname
 print '<tr><td width="25%" valign="top">'.$langs->trans("Lastname").'</td>';
-print '<td>'.$fuser->lastName.'</td>';
+print '<td>'.$fuser->lastname.'</td>';
 print '</tr>'."\n";
 
 // Firstname
diff --git a/test/phpunit/ModulesTest.php b/test/phpunit/ModulesTest.php
index 357413e3be9343711a817fc7a5324c6143e791bc..8b2a061727526d84665fee313112dae87376d819 100755
--- a/test/phpunit/ModulesTest.php
+++ b/test/phpunit/ModulesTest.php
@@ -138,7 +138,7 @@ class ModulesTest extends PHPUnit_Framework_TestCase
     		$mod=new $class($db);
             $result=$mod->remove();
             $result=$mod->init();
-        	$this->assertLessThan($result, 0);
+        	$this->assertLessThan($result, 0, $modlabel);
         	print __METHOD__." result=".$result."\n";
 		}