From 7f59cf919403d858f00fd3028e6eab875b03d96a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?=
 <marcosgdf@gmail.com>
Date: Sat, 17 Jan 2015 19:28:27 +0100
Subject: [PATCH] Fix: [ bug #1787 ] Incorrect behaviour of doActions hook

---
 ChangeLog                         |    1 +
 htdocs/adherents/fiche.php        |  850 ++++-----
 htdocs/comm/fiche.php             |  126 +-
 htdocs/comm/mailing/fiche.php     |  806 ++++----
 htdocs/comm/propal.php            | 1550 ++++++++--------
 htdocs/comm/prospect/list.php     |   12 +-
 htdocs/commande/fiche.php         | 1977 ++++++++++----------
 htdocs/compta/facture.php         | 2843 +++++++++++++++--------------
 htdocs/compta/paiement.php        |  278 +--
 htdocs/expedition/fiche.php       |  776 ++++----
 htdocs/fourn/facture/paiement.php |  242 +--
 htdocs/fourn/fiche.php            |   57 +-
 htdocs/product/document.php       |   12 +-
 htdocs/product/fournisseurs.php   |  196 +-
 htdocs/resource/card.php          |   69 +-
 15 files changed, 4910 insertions(+), 4885 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2a49b467783..e19f3947a59 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,7 @@ English Dolibarr ChangeLog
 - Fix: amarok is a bugged theme making dolidroid failed. We swith to eldy automatically with dolidroid.
 - Fix: withdrawal create error if in the same month are deleted previus withdrawals.
 - Fix: [ bug #1801 ] FAC_FORCE_DATE_VALIDATION constant alters supplier invoice date given to numeration modules
+- Fix: [ bug #1787 ] Incorrect behaviour of doActions hook
 
 ***** ChangeLog for 3.6.2 compared to 3.6.1 *****
 - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice.
diff --git a/htdocs/adherents/fiche.php b/htdocs/adherents/fiche.php
index ef04edeeb53..97d71d1572a 100644
--- a/htdocs/adherents/fiche.php
+++ b/htdocs/adherents/fiche.php
@@ -121,557 +121,559 @@ $hookmanager->initHooks(array('membercard'));
 $parameters=array('rowid'=>$rowid, 'objcanvas'=>$objcanvas);
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 
-if ($action == 'setuserid' && ($user->rights->user->self->creer || $user->rights->user->user->creer))
-{
-	$error=0;
-	if (empty($user->rights->user->user->creer))	// If can edit only itself user, we can link to itself only
+if (empty($reshook)) {
+
+	if ($action == 'setuserid' && ($user->rights->user->self->creer || $user->rights->user->user->creer))
 	{
-		if ($userid != $user->id && $userid != $object->user_id)
+		$error=0;
+		if (empty($user->rights->user->user->creer))	// If can edit only itself user, we can link to itself only
 		{
-			$error++;
-			$mesg='<div class="error">'.$langs->trans("ErrorUserPermissionAllowsToLinksToItselfOnly").'</div>';
+			if ($userid != $user->id && $userid != $object->user_id)
+			{
+				$error++;
+				$mesg='<div class="error">'.$langs->trans("ErrorUserPermissionAllowsToLinksToItselfOnly").'</div>';
+			}
 		}
-	}
 
-	if (! $error)
-	{
-		if ($userid != $object->user_id)	// If link differs from currently in database
+		if (! $error)
 		{
-			$result=$object->setUserId($userid);
-			if ($result < 0) dol_print_error($object->db,$object->error);
-			$action='';
+			if ($userid != $object->user_id)	// If link differs from currently in database
+			{
+				$result=$object->setUserId($userid);
+				if ($result < 0) dol_print_error($object->db,$object->error);
+				$action='';
+			}
 		}
 	}
-}
 
-if ($action == 'setsocid')
-{
-	$error=0;
-	if (! $error)
+	if ($action == 'setsocid')
 	{
-		if ($socid != $object->fk_soc)	// If link differs from currently in database
+		$error=0;
+		if (! $error)
 		{
-			$sql ="SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
-			$sql.=" WHERE fk_soc = '".$socid."'";
-			$sql.=" AND entity = ".$conf->entity;
-			$resql = $db->query($sql);
-			if ($resql)
+			if ($socid != $object->fk_soc)	// If link differs from currently in database
 			{
-				$obj = $db->fetch_object($resql);
-				if ($obj && $obj->rowid > 0)
+				$sql ="SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
+				$sql.=" WHERE fk_soc = '".$socid."'";
+				$sql.=" AND entity = ".$conf->entity;
+				$resql = $db->query($sql);
+				if ($resql)
 				{
-					$othermember=new Adherent($db);
-					$othermember->fetch($obj->rowid);
-					$thirdparty=new Societe($db);
-					$thirdparty->fetch($socid);
-					$error++;
-					$errmsg='<div class="error">'.$langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty",$othermember->getFullName($langs),$othermember->login,$thirdparty->name).'</div>';
+					$obj = $db->fetch_object($resql);
+					if ($obj && $obj->rowid > 0)
+					{
+						$othermember=new Adherent($db);
+						$othermember->fetch($obj->rowid);
+						$thirdparty=new Societe($db);
+						$thirdparty->fetch($socid);
+						$error++;
+						$errmsg='<div class="error">'.$langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty",$othermember->getFullName($langs),$othermember->login,$thirdparty->name).'</div>';
+					}
 				}
-			}
 
-			if (! $error)
-			{
-				$result=$object->setThirdPartyId($socid);
-				if ($result < 0) dol_print_error($object->db,$object->error);
-				$action='';
+				if (! $error)
+				{
+					$result=$object->setThirdPartyId($socid);
+					if ($result < 0) dol_print_error($object->db,$object->error);
+					$action='';
+				}
 			}
 		}
 	}
-}
 
-// Create user from a member
-if ($action == 'confirm_create_user' && $confirm == 'yes' && $user->rights->user->user->creer)
-{
-	if ($result > 0)
+	// Create user from a member
+	if ($action == 'confirm_create_user' && $confirm == 'yes' && $user->rights->user->user->creer)
 	{
-		// Creation user
-		$nuser = new User($db);
-		$result=$nuser->create_from_member($object,GETPOST('login'));
+		if ($result > 0)
+		{
+			// Creation user
+			$nuser = new User($db);
+			$result=$nuser->create_from_member($object,GETPOST('login'));
 
-		if ($result < 0)
+			if ($result < 0)
+			{
+				$langs->load("errors");
+				$errmsg=$langs->trans($nuser->error);
+			}
+		}
+		else
 		{
-			$langs->load("errors");
-			$errmsg=$langs->trans($nuser->error);
+			$errmsg=$object->error;
 		}
 	}
-	else
-	{
-		$errmsg=$object->error;
-	}
-}
 
-// Create third party from a member
-if ($action == 'confirm_create_thirdparty' && $confirm == 'yes' && $user->rights->societe->creer)
-{
-	if ($result > 0)
+	// Create third party from a member
+	if ($action == 'confirm_create_thirdparty' && $confirm == 'yes' && $user->rights->societe->creer)
 	{
-		// Creation user
-		$company = new Societe($db);
-		$result=$company->create_from_member($object,GETPOST('companyname'));
+		if ($result > 0)
+		{
+			// Creation user
+			$company = new Societe($db);
+			$result=$company->create_from_member($object,GETPOST('companyname'));
 
-		if ($result < 0)
+			if ($result < 0)
+			{
+				$langs->load("errors");
+				$errmsg=$langs->trans($company->error);
+				$errmsgs=$company->errors;
+			}
+		}
+		else
 		{
-			$langs->load("errors");
-			$errmsg=$langs->trans($company->error);
-			$errmsgs=$company->errors;
+			$errmsg=$object->error;
 		}
 	}
-	else
-	{
-		$errmsg=$object->error;
-	}
-}
 
-if ($action == 'confirm_sendinfo' && $confirm == 'yes')
-{
-	if ($object->email)
+	if ($action == 'confirm_sendinfo' && $confirm == 'yes')
 	{
-		$from=$conf->email_from;
-		if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM;
-
-		$result=$object->send_an_email($langs->transnoentitiesnoconv("ThisIsContentOfYourCard")."\n\n%INFOS%\n\n",$langs->transnoentitiesnoconv("CardContent"));
-
-		$langs->load("mails");
-		$mesg=$langs->trans("MailSuccessfulySent", $from, $object->email);
-	}
-}
+		if ($object->email)
+		{
+			$from=$conf->email_from;
+			if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM;
 
-if ($action == 'update' && ! $_POST["cancel"] && $user->rights->adherent->creer)
-{
-	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+			$result=$object->send_an_email($langs->transnoentitiesnoconv("ThisIsContentOfYourCard")."\n\n%INFOS%\n\n",$langs->transnoentitiesnoconv("CardContent"));
 
-	$birthdate='';
-	if (isset($_POST["birthday"]) && $_POST["birthday"]
-			&& isset($_POST["birthmonth"]) && $_POST["birthmonth"]
-			&& isset($_POST["birthyear"]) && $_POST["birthyear"])
-	{
-		$birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]);
-	}
-	$lastname=$_POST["lastname"];
-	$firstname=$_POST["firstname"];
-	$morphy=$morphy=$_POST["morphy"];;
-	if ($morphy != 'mor' && empty($lastname)) {
-		$error++;
-		$langs->load("errors");
-		$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname"))."<br>\n";
-	}
-	if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) {
-		$error++;
-		$langs->load("errors");
-		$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname"))."<br>\n";
+			$langs->load("mails");
+			$mesg=$langs->trans("MailSuccessfulySent", $from, $object->email);
+		}
 	}
 
-	// Create new object
-	if ($result > 0 && ! $error)
+	if ($action == 'update' && ! $_POST["cancel"] && $user->rights->adherent->creer)
 	{
-		$object->oldcopy=dol_clone($object);
-
-		// Change values
-		$object->civility_id = trim($_POST["civility_id"]);
-		$object->firstname   = trim($_POST["firstname"]);
-		$object->lastname    = trim($_POST["lastname"]);
-		$object->login       = trim($_POST["login"]);
-		$object->pass        = trim($_POST["pass"]);
-
-		$object->societe     = trim($_POST["societe"]);
-		$object->company     = trim($_POST["societe"]);
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 
-		$object->address     = trim($_POST["address"]);
-		$object->zip         = trim($_POST["zipcode"]);
-		$object->town        = trim($_POST["town"]);
-		$object->state_id    = $_POST["state_id"];
-		$object->country_id  = $_POST["country_id"];
-
-		$object->phone       = trim($_POST["phone"]);
-		$object->phone_perso = trim($_POST["phone_perso"]);
-		$object->phone_mobile= trim($_POST["phone_mobile"]);
-		$object->email       = trim($_POST["email"]);
-		$object->skype       = trim($_POST["skype"]);
-		$object->birth       = $birthdate;
-
-		$object->typeid      = $_POST["typeid"];
-		//$object->note        = trim($_POST["comment"]);
-		$object->morphy      = $_POST["morphy"];
-
-		$object->amount      = $_POST["amount"];
-
-		if (GETPOST('deletephoto')) $object->photo='';
-		elseif (! empty($_FILES['photo']['name'])) $object->photo  = dol_sanitizeFileName($_FILES['photo']['name']);
-
-		// Get status and public property
-		$object->statut      = $_POST["statut"];
-		$object->public      = $_POST["public"];
-
-		// Fill array 'array_options' with data from add form
-		$ret = $extrafields->setOptionalsFromPost($extralabels,$object);
-
-		// Check if we need to also synchronize user information
-		$nosyncuser=0;
-		if ($object->user_id)	// If linked to a user
+		$birthdate='';
+		if (isset($_POST["birthday"]) && $_POST["birthday"]
+				&& isset($_POST["birthmonth"]) && $_POST["birthmonth"]
+				&& isset($_POST["birthyear"]) && $_POST["birthyear"])
 		{
-			if ($user->id != $object->user_id && empty($user->rights->user->user->creer)) $nosyncuser=1;		// Disable synchronizing
+			$birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]);
 		}
-
-		// Check if we need to also synchronize password information
-		$nosyncuserpass=0;
-		if ($object->user_id)	// If linked to a user
-		{
-			if ($user->id != $object->user_id && empty($user->rights->user->user->password)) $nosyncuserpass=1;	// Disable synchronizing
+		$lastname=$_POST["lastname"];
+		$firstname=$_POST["firstname"];
+		$morphy=$morphy=$_POST["morphy"];;
+		if ($morphy != 'mor' && empty($lastname)) {
+			$error++;
+			$langs->load("errors");
+			$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname"))."<br>\n";
+		}
+		if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) {
+			$error++;
+			$langs->load("errors");
+			$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname"))."<br>\n";
 		}
 
-		$result=$object->update($user,0,$nosyncuser,$nosyncuserpass);
-		if ($result >= 0 && ! count($object->errors))
+		// Create new object
+		if ($result > 0 && ! $error)
 		{
-			// Logo/Photo save
-			$dir= $conf->adherent->dir_output . '/' . get_exdir($object->id,2,0,1).'/photos';
-			$file_OK = is_uploaded_file($_FILES['photo']['tmp_name']);
-			if ($file_OK)
+			$object->oldcopy=dol_clone($object);
+
+			// Change values
+			$object->civility_id = trim($_POST["civility_id"]);
+			$object->firstname   = trim($_POST["firstname"]);
+			$object->lastname    = trim($_POST["lastname"]);
+			$object->login       = trim($_POST["login"]);
+			$object->pass        = trim($_POST["pass"]);
+
+			$object->societe     = trim($_POST["societe"]);
+			$object->company     = trim($_POST["societe"]);
+
+			$object->address     = trim($_POST["address"]);
+			$object->zip         = trim($_POST["zipcode"]);
+			$object->town        = trim($_POST["town"]);
+			$object->state_id    = $_POST["state_id"];
+			$object->country_id  = $_POST["country_id"];
+
+			$object->phone       = trim($_POST["phone"]);
+			$object->phone_perso = trim($_POST["phone_perso"]);
+			$object->phone_mobile= trim($_POST["phone_mobile"]);
+			$object->email       = trim($_POST["email"]);
+			$object->skype       = trim($_POST["skype"]);
+			$object->birth       = $birthdate;
+
+			$object->typeid      = $_POST["typeid"];
+			//$object->note        = trim($_POST["comment"]);
+			$object->morphy      = $_POST["morphy"];
+
+			$object->amount      = $_POST["amount"];
+
+			if (GETPOST('deletephoto')) $object->photo='';
+			elseif (! empty($_FILES['photo']['name'])) $object->photo  = dol_sanitizeFileName($_FILES['photo']['name']);
+
+			// Get status and public property
+			$object->statut      = $_POST["statut"];
+			$object->public      = $_POST["public"];
+
+			// Fill array 'array_options' with data from add form
+			$ret = $extrafields->setOptionalsFromPost($extralabels,$object);
+
+			// Check if we need to also synchronize user information
+			$nosyncuser=0;
+			if ($object->user_id)	// If linked to a user
 			{
-				if (GETPOST('deletephoto'))
-				{
-					require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
-					$fileimg=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/'.$object->photo;
-					$dirthumbs=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/thumbs';
-					dol_delete_file($fileimg);
-					dol_delete_dir_recursive($dirthumbs);
-				}
+				if ($user->id != $object->user_id && empty($user->rights->user->user->creer)) $nosyncuser=1;		// Disable synchronizing
+			}
+
+			// Check if we need to also synchronize password information
+			$nosyncuserpass=0;
+			if ($object->user_id)	// If linked to a user
+			{
+				if ($user->id != $object->user_id && empty($user->rights->user->user->password)) $nosyncuserpass=1;	// Disable synchronizing
+			}
 
-				if (image_format_supported($_FILES['photo']['name']) > 0)
+			$result=$object->update($user,0,$nosyncuser,$nosyncuserpass);
+			if ($result >= 0 && ! count($object->errors))
+			{
+				// Logo/Photo save
+				$dir= $conf->adherent->dir_output . '/' . get_exdir($object->id,2,0,1).'/photos';
+				$file_OK = is_uploaded_file($_FILES['photo']['tmp_name']);
+				if ($file_OK)
 				{
-					dol_mkdir($dir);
+					if (GETPOST('deletephoto'))
+					{
+						require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
+						$fileimg=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/'.$object->photo;
+						$dirthumbs=$conf->adherent->dir_output.'/'.get_exdir($object->id,2,0,1).'/photos/thumbs';
+						dol_delete_file($fileimg);
+						dol_delete_dir_recursive($dirthumbs);
+					}
 
-					if (@is_dir($dir))
+					if (image_format_supported($_FILES['photo']['name']) > 0)
 					{
-						$newfile=$dir.'/'.dol_sanitizeFileName($_FILES['photo']['name']);
-						if (! dol_move_uploaded_file($_FILES['photo']['tmp_name'],$newfile,1,0,$_FILES['photo']['error']) > 0)
-						{
-							$message .= '<div class="error">'.$langs->trans("ErrorFailedToSaveFile").'</div>';
-						}
-						else
+						dol_mkdir($dir);
+
+						if (@is_dir($dir))
 						{
-							// Create small thumbs for company (Ratio is near 16/9)
-							// Used on logon for example
-							$imgThumbSmall = vignette($newfile, $maxwidthsmall, $maxheightsmall, '_small', $quality);
+							$newfile=$dir.'/'.dol_sanitizeFileName($_FILES['photo']['name']);
+							if (! dol_move_uploaded_file($_FILES['photo']['tmp_name'],$newfile,1,0,$_FILES['photo']['error']) > 0)
+							{
+								$message .= '<div class="error">'.$langs->trans("ErrorFailedToSaveFile").'</div>';
+							}
+							else
+							{
+								// Create small thumbs for company (Ratio is near 16/9)
+								// Used on logon for example
+								$imgThumbSmall = vignette($newfile, $maxwidthsmall, $maxheightsmall, '_small', $quality);
 
-							// Create mini thumbs for company (Ratio is near 16/9)
-							// Used on menu or for setup page for example
-							$imgThumbMini = vignette($newfile, $maxwidthmini, $maxheightmini, '_mini', $quality);
+								// Create mini thumbs for company (Ratio is near 16/9)
+								// Used on menu or for setup page for example
+								$imgThumbMini = vignette($newfile, $maxwidthmini, $maxheightmini, '_mini', $quality);
+							}
 						}
 					}
+					else
+					{
+						$errmsgs[] = "ErrorBadImageFormat";
+					}
 				}
 				else
 				{
-					$errmsgs[] = "ErrorBadImageFormat";
+					switch($_FILES['photo']['error'])
+					{
+						case 1: //uploaded file exceeds the upload_max_filesize directive in php.ini
+						case 2: //uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the html form
+							$errors[] = "ErrorFileSizeTooLarge";
+							break;
+						case 3: //uploaded file was only partially uploaded
+							$errors[] = "ErrorFilePartiallyUploaded";
+							break;
+					}
 				}
-			}
-			else
-			{
-				switch($_FILES['photo']['error'])
+
+	            $rowid=$object->id;
+				$action='';
+
+				if (! empty($backtopage))
 				{
-					case 1: //uploaded file exceeds the upload_max_filesize directive in php.ini
-					case 2: //uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the html form
-						$errors[] = "ErrorFileSizeTooLarge";
-						break;
-					case 3: //uploaded file was only partially uploaded
-						$errors[] = "ErrorFilePartiallyUploaded";
-						break;
+					header("Location: ".$backtopage);
+					exit;
 				}
 			}
-
-            $rowid=$object->id;
-			$action='';
-
-			if (! empty($backtopage))
+			else
 			{
-				header("Location: ".$backtopage);
-				exit;
+				if ($object->error) $errmsg=$object->error;
+				else $errmsgs=$object->errors;
+				$action='';
 			}
 		}
 		else
 		{
-			if ($object->error) $errmsg=$object->error;
-			else $errmsgs=$object->errors;
-			$action='';
+			$action='edit';
 		}
 	}
-	else
-	{
-		$action='edit';
-	}
-}
 
-if ($action == 'add' && $user->rights->adherent->creer)
-{
-	if ($canvas) $object->canvas=$canvas;
-	$birthdate='';
-	if (isset($_POST["birthday"]) && $_POST["birthday"]
-			&& isset($_POST["birthmonth"]) && $_POST["birthmonth"]
-			&& isset($_POST["birthyear"]) && $_POST["birthyear"])
-	{
-		$birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]);
-	}
-	$datecotisation='';
-	if (isset($_POST["reday"]) && isset($_POST["remonth"]) && isset($_POST["reyear"]))
+	if ($action == 'add' && $user->rights->adherent->creer)
 	{
-		$datecotisation=dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]);
-	}
+		if ($canvas) $object->canvas=$canvas;
+		$birthdate='';
+		if (isset($_POST["birthday"]) && $_POST["birthday"]
+				&& isset($_POST["birthmonth"]) && $_POST["birthmonth"]
+				&& isset($_POST["birthyear"]) && $_POST["birthyear"])
+		{
+			$birthdate=dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]);
+		}
+		$datecotisation='';
+		if (isset($_POST["reday"]) && isset($_POST["remonth"]) && isset($_POST["reyear"]))
+		{
+			$datecotisation=dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]);
+		}
 
-	$typeid=$_POST["typeid"];
-	$civility_id=$_POST["civility_id"];
-	$lastname=$_POST["lastname"];
-	$firstname=$_POST["firstname"];
-	$societe=$_POST["societe"];
-	$address=$_POST["address"];
-	$zip=$_POST["zipcode"];
-	$town=$_POST["town"];
-	$state_id=$_POST["state_id"];
-	$country_id=$_POST["country_id"];
-
-	$phone=$_POST["phone"];
-	$phone_perso=$_POST["phone_perso"];
-	$phone_mobile=$_POST["phone_mobile"];
-	$skype=$_POST["member_skype"];
-	$email=$_POST["member_email"];
-	$login=$_POST["member_login"];
-	$pass=$_POST["password"];
-	$photo=$_POST["photo"];
-	//$comment=$_POST["comment"];
-	$morphy=$_POST["morphy"];
-	$cotisation=$_POST["cotisation"];
-	$public=$_POST["public"];
-
-	$userid=$_POST["userid"];
-	$socid=$_POST["socid"];
-
-	$object->civility_id = $civility_id;
-	$object->firstname   = $firstname;
-	$object->lastname    = $lastname;
-	$object->societe     = $societe;
-	$object->address     = $address;
-	$object->zip         = $zip;
-	$object->town        = $town;
-	$object->state_id    = $state_id;
-	$object->country_id  = $country_id;
-	$object->phone       = $phone;
-	$object->phone_perso = $phone_perso;
-	$object->phone_mobile= $phone_mobile;
-	$object->skype       = $skype;
-	$object->email       = $email;
-	$object->login       = $login;
-	$object->pass        = $pass;
-	$object->naiss       = $birthdate;
-	$object->photo       = $photo;
-	$object->typeid      = $typeid;
-	//$object->note        = $comment;
-	$object->morphy      = $morphy;
-	$object->user_id     = $userid;
-	$object->fk_soc      = $socid;
-	$object->public      = $public;
-
-	// Fill array 'array_options' with data from add form
-	$ret = $extrafields->setOptionalsFromPost($extralabels,$object);
-
-	// Check parameters
-	if (empty($morphy) || $morphy == "-1") {
-		$error++;
-		$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Nature"))."<br>\n";
-	}
-	// Test si le login existe deja
-	if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
-	{
-		if (empty($login)) {
+		$typeid=$_POST["typeid"];
+		$civility_id=$_POST["civility_id"];
+		$lastname=$_POST["lastname"];
+		$firstname=$_POST["firstname"];
+		$societe=$_POST["societe"];
+		$address=$_POST["address"];
+		$zip=$_POST["zipcode"];
+		$town=$_POST["town"];
+		$state_id=$_POST["state_id"];
+		$country_id=$_POST["country_id"];
+
+		$phone=$_POST["phone"];
+		$phone_perso=$_POST["phone_perso"];
+		$phone_mobile=$_POST["phone_mobile"];
+		$skype=$_POST["member_skype"];
+		$email=$_POST["member_email"];
+		$login=$_POST["member_login"];
+		$pass=$_POST["password"];
+		$photo=$_POST["photo"];
+		//$comment=$_POST["comment"];
+		$morphy=$_POST["morphy"];
+		$cotisation=$_POST["cotisation"];
+		$public=$_POST["public"];
+
+		$userid=$_POST["userid"];
+		$socid=$_POST["socid"];
+
+		$object->civility_id = $civility_id;
+		$object->firstname   = $firstname;
+		$object->lastname    = $lastname;
+		$object->societe     = $societe;
+		$object->address     = $address;
+		$object->zip         = $zip;
+		$object->town        = $town;
+		$object->state_id    = $state_id;
+		$object->country_id  = $country_id;
+		$object->phone       = $phone;
+		$object->phone_perso = $phone_perso;
+		$object->phone_mobile= $phone_mobile;
+		$object->skype       = $skype;
+		$object->email       = $email;
+		$object->login       = $login;
+		$object->pass        = $pass;
+		$object->naiss       = $birthdate;
+		$object->photo       = $photo;
+		$object->typeid      = $typeid;
+		//$object->note        = $comment;
+		$object->morphy      = $morphy;
+		$object->user_id     = $userid;
+		$object->fk_soc      = $socid;
+		$object->public      = $public;
+
+		// Fill array 'array_options' with data from add form
+		$ret = $extrafields->setOptionalsFromPost($extralabels,$object);
+
+		// Check parameters
+		if (empty($morphy) || $morphy == "-1") {
 			$error++;
-			$errmsg .= $langs->trans("ErrorFieldRequired",$langs->trans("Login"))."<br>\n";
+			$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Nature"))."<br>\n";
 		}
-		else {
-			$sql = "SELECT login FROM ".MAIN_DB_PREFIX."adherent WHERE login='".$db->escape($login)."'";
-			$result = $db->query($sql);
-			if ($result) {
-				$num = $db->num_rows($result);
+		// Test si le login existe deja
+		if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
+		{
+			if (empty($login)) {
+				$error++;
+				$errmsg .= $langs->trans("ErrorFieldRequired",$langs->trans("Login"))."<br>\n";
 			}
-			if ($num) {
+			else {
+				$sql = "SELECT login FROM ".MAIN_DB_PREFIX."adherent WHERE login='".$db->escape($login)."'";
+				$result = $db->query($sql);
+				if ($result) {
+					$num = $db->num_rows($result);
+				}
+				if ($num) {
+					$error++;
+					$langs->load("errors");
+					$errmsg .= $langs->trans("ErrorLoginAlreadyExists",$login)."<br>\n";
+				}
+			}
+			if (empty($pass)) {
 				$error++;
-				$langs->load("errors");
-				$errmsg .= $langs->trans("ErrorLoginAlreadyExists",$login)."<br>\n";
+				$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Password"))."<br>\n";
 			}
 		}
-		if (empty($pass)) {
+		if ($morphy != 'mor' && empty($lastname)) {
 			$error++;
-			$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Password"))."<br>\n";
+			$langs->load("errors");
+			$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname"))."<br>\n";
 		}
-	}
-	if ($morphy != 'mor' && empty($lastname)) {
-		$error++;
-		$langs->load("errors");
-		$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname"))."<br>\n";
-	}
-	if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) {
-		$error++;
-		$langs->load("errors");
-		$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname"))."<br>\n";
-	}
-	if (! ($typeid > 0)) {	// Keep () before !
-		$error++;
-		$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type"))."<br>\n";
-	}
-	if ($conf->global->ADHERENT_MAIL_REQUIRED && ! isValidEMail($email)) {
-		$error++;
-		$langs->load("errors");
-		$errmsg .= $langs->trans("ErrorBadEMail",$email)."<br>\n";
-	}
-	$public=0;
-	if (isset($public)) $public=1;
-
-	if (! $error)
-	{
-		$db->begin();
-
-		// Email a peu pres correct et le login n'existe pas
-		$result=$object->create($user);
-		if ($result > 0)
-		{
-			$db->commit();
-			$rowid=$object->id;
-			$action='';
+		if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) {
+			$error++;
+			$langs->load("errors");
+			$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname"))."<br>\n";
 		}
-		else
+		if (! ($typeid > 0)) {	// Keep () before !
+			$error++;
+			$errmsg .= $langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type"))."<br>\n";
+		}
+		if ($conf->global->ADHERENT_MAIL_REQUIRED && ! isValidEMail($email)) {
+			$error++;
+			$langs->load("errors");
+			$errmsg .= $langs->trans("ErrorBadEMail",$email)."<br>\n";
+		}
+		$public=0;
+		if (isset($public)) $public=1;
+
+		if (! $error)
 		{
-			$db->rollback();
+			$db->begin();
 
-			if ($object->error) $errmsg=$object->error;
-			else $errmsgs=$object->errors;
+			// Email a peu pres correct et le login n'existe pas
+			$result=$object->create($user);
+			if ($result > 0)
+			{
+				$db->commit();
+				$rowid=$object->id;
+				$action='';
+			}
+			else
+			{
+				$db->rollback();
+
+				if ($object->error) $errmsg=$object->error;
+				else $errmsgs=$object->errors;
 
+				$action = 'create';
+			}
+		}
+		else {
 			$action = 'create';
 		}
 	}
-	else {
-		$action = 'create';
-	}
-}
 
-if ($user->rights->adherent->supprimer && $action == 'confirm_delete' && $confirm == 'yes')
-{
-	$result=$object->delete($rowid);
-	if ($result > 0)
+	if ($user->rights->adherent->supprimer && $action == 'confirm_delete' && $confirm == 'yes')
 	{
-		if (! empty($backtopage))
+		$result=$object->delete($rowid);
+		if ($result > 0)
 		{
-			header("Location: ".$backtopage);
-			exit;
+			if (! empty($backtopage))
+			{
+				header("Location: ".$backtopage);
+				exit;
+			}
+			else
+			{
+				header("Location: liste.php");
+				exit;
+			}
 		}
 		else
 		{
-			header("Location: liste.php");
-			exit;
+			$errmesg=$object->error;
 		}
 	}
-	else
-	{
-		$errmesg=$object->error;
-	}
-}
 
-if ($user->rights->adherent->creer && $action == 'confirm_valid' && $confirm == 'yes')
-{
-	$error=0;
+	if ($user->rights->adherent->creer && $action == 'confirm_valid' && $confirm == 'yes')
+	{
+		$error=0;
 
-	$db->begin();
+		$db->begin();
 
-	$adht = new AdherentType($db);
-	$adht->fetch($object->typeid);
+		$adht = new AdherentType($db);
+		$adht->fetch($object->typeid);
 
-	$result=$object->validate($user);
+		$result=$object->validate($user);
 
-	if ($result >= 0 && ! count($object->errors))
-	{
-		// Send confirmation Email (selon param du type adherent sinon generique)
-		if ($object->email && GETPOST("send_mail"))
+		if ($result >= 0 && ! count($object->errors))
 		{
-			$result=$object->send_an_email($adht->getMailOnValid(),$conf->global->ADHERENT_MAIL_VALID_SUBJECT,array(),array(),array(),"","",0,2);
-			if ($result < 0)
+			// Send confirmation Email (selon param du type adherent sinon generique)
+			if ($object->email && GETPOST("send_mail"))
 			{
-				$error++;
-				$errmsg.=$object->error;
+				$result=$object->send_an_email($adht->getMailOnValid(),$conf->global->ADHERENT_MAIL_VALID_SUBJECT,array(),array(),array(),"","",0,2);
+				if ($result < 0)
+				{
+					$error++;
+					$errmsg.=$object->error;
+				}
 			}
 		}
-	}
-	else
-	{
-		$error++;
-		if ($object->error) $errmsg=$object->error;
-		else $errmsgs=$object->errors;
-	}
+		else
+		{
+			$error++;
+			if ($object->error) $errmsg=$object->error;
+			else $errmsgs=$object->errors;
+		}
 
-	if (! $error)
-	{
-		$db->commit();
-	}
-	else
-	{
-		$db->rollback();
+		if (! $error)
+		{
+			$db->commit();
+		}
+		else
+		{
+			$db->rollback();
+		}
+		$action='';
 	}
-	$action='';
-}
 
-if ($user->rights->adherent->supprimer && $action == 'confirm_resign')
-{
-	if ($confirm == 'yes')
+	if ($user->rights->adherent->supprimer && $action == 'confirm_resign')
 	{
-		$adht = new AdherentType($db);
-		$adht->fetch($object->typeid);
+		if ($confirm == 'yes')
+		{
+			$adht = new AdherentType($db);
+			$adht->fetch($object->typeid);
 
-		$result=$object->resiliate($user);
+			$result=$object->resiliate($user);
 
-		if ($result >= 0 && ! count($object->errors))
-		{
-			if ($object->email && GETPOST("send_mail"))
+			if ($result >= 0 && ! count($object->errors))
 			{
-				$result=$object->send_an_email($adht->getMailOnResiliate(),$conf->global->ADHERENT_MAIL_RESIL_SUBJECT,array(),array(),array(),"","",0,-1);
+				if ($object->email && GETPOST("send_mail"))
+				{
+					$result=$object->send_an_email($adht->getMailOnResiliate(),$conf->global->ADHERENT_MAIL_RESIL_SUBJECT,array(),array(),array(),"","",0,-1);
+				}
+				if ($result < 0)
+				{
+					$errmsg.=$object->error;
+				}
 			}
-			if ($result < 0)
+			else
 			{
-				$errmsg.=$object->error;
+				if ($object->error) $errmsg=$object->error;
+				else $errmsgs=$object->errors;
+				$action='';
 			}
 		}
-		else
+		if (! empty($backtopage) && ! $errmsg)
 		{
-			if ($object->error) $errmsg=$object->error;
-			else $errmsgs=$object->errors;
-			$action='';
+			header("Location: ".$backtopage);
+			exit;
 		}
 	}
-	if (! empty($backtopage) && ! $errmsg)
-	{
-		header("Location: ".$backtopage);
-		exit;
-	}
-}
 
-// SPIP Management
-if ($user->rights->adherent->supprimer && $action == 'confirm_del_spip' && $confirm == 'yes')
-{
-	if (! count($object->errors))
+	// SPIP Management
+	if ($user->rights->adherent->supprimer && $action == 'confirm_del_spip' && $confirm == 'yes')
 	{
-		if (!$mailmanspip->del_to_spip($object))
+		if (! count($object->errors))
 		{
-			$errmsg.= $langs->trans('DeleteIntoSpipError').': '.$mailmanspip->error."<BR>\n";
+			if (!$mailmanspip->del_to_spip($object))
+			{
+				$errmsg.= $langs->trans('DeleteIntoSpipError').': '.$mailmanspip->error."<BR>\n";
+			}
 		}
 	}
-}
 
-if ($user->rights->adherent->creer && $action == 'confirm_add_spip' && $confirm == 'yes')
-{
-	if (! count($object->errors))
+	if ($user->rights->adherent->creer && $action == 'confirm_add_spip' && $confirm == 'yes')
 	{
-		if (!$mailmanspip->add_to_spip($object))
+		if (! count($object->errors))
 		{
-			$errmsg.= $langs->trans('AddIntoSpipError').': '.$mailmanspip->error."<BR>\n";
+			if (!$mailmanspip->add_to_spip($object))
+			{
+				$errmsg.= $langs->trans('AddIntoSpipError').': '.$mailmanspip->error."<BR>\n";
+			}
 		}
 	}
 }
 
 
-
 /*
  * View
  */
diff --git a/htdocs/comm/fiche.php b/htdocs/comm/fiche.php
index 307a8c57385..0741b468ed9 100644
--- a/htdocs/comm/fiche.php
+++ b/htdocs/comm/fiche.php
@@ -79,76 +79,78 @@ $object = new Societe($db);
 $parameters = array('socid' => $id);
 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some
 
-//Some actions show a "cancel" input submit button with name="cancel"
-$cancelbutton = GETPOST('cancel');
+if (empty($reshook)) {
+	//Some actions show a "cancel" input submit button with name="cancel"
+	$cancelbutton = GETPOST('cancel');
 
-if ($action == 'setcustomeraccountancycode')
-{
-	if (!$cancelbutton) {
-		$result=$object->fetch($id);
-		$object->code_compta=$_POST["customeraccountancycode"];
-		$result=$object->update($object->id,$user,1,1,0);
-		if ($result < 0)
-		{
-			$mesgs[]=join(',',$object->errors);
+	if ($action == 'setcustomeraccountancycode')
+	{
+		if (!$cancelbutton) {
+			$result=$object->fetch($id);
+			$object->code_compta=$_POST["customeraccountancycode"];
+			$result=$object->update($object->id,$user,1,1,0);
+			if ($result < 0)
+			{
+				$mesgs[]=join(',',$object->errors);
+			}
+			$action="";
 		}
-		$action="";
 	}
-}
 
-// conditions de reglement
-if ($action == 'setconditions' && $user->rights->societe->creer)
-{
-	$object->fetch($id);
-	$result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int'));
-	if ($result < 0) dol_print_error($db,$object->error);
-}
-// mode de reglement
-if ($action == 'setmode' && $user->rights->societe->creer)
-{
-	$object->fetch($id);
-	$result=$object->setPaymentMethods(GETPOST('mode_reglement_id','int'));
-	if ($result < 0) dol_print_error($db,$object->error);
-}
-// assujetissement a la TVA
-if ($action == 'setassujtva' && $user->rights->societe->creer)
-{
-	$object->fetch($id);
-	$object->tva_assuj=$_POST['assujtva_value'];
-
-	// TODO move to DAO class
-	$sql = "UPDATE ".MAIN_DB_PREFIX."societe SET tva_assuj='".$_POST['assujtva_value']."' WHERE rowid='".$id."'";
-	$result = $db->query($sql);
-	if (! $result) dol_print_error($result);
-}
+	// conditions de reglement
+	if ($action == 'setconditions' && $user->rights->societe->creer)
+	{
+		$object->fetch($id);
+		$result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int'));
+		if ($result < 0) dol_print_error($db,$object->error);
+	}
+	// mode de reglement
+	if ($action == 'setmode' && $user->rights->societe->creer)
+	{
+		$object->fetch($id);
+		$result=$object->setPaymentMethods(GETPOST('mode_reglement_id','int'));
+		if ($result < 0) dol_print_error($db,$object->error);
+	}
+	// assujetissement a la TVA
+	if ($action == 'setassujtva' && $user->rights->societe->creer)
+	{
+		$object->fetch($id);
+		$object->tva_assuj=$_POST['assujtva_value'];
 
-// set prospect level
-if ($action == 'setprospectlevel' && $user->rights->societe->creer)
-{
-	$object->fetch($id);
-	$object->fk_prospectlevel=GETPOST('prospect_level_id','alpha');
-	$result=$object->set_prospect_level($user);
-	if ($result < 0) setEventMessage($object->error,'errors');
-}
+		// TODO move to DAO class
+		$sql = "UPDATE ".MAIN_DB_PREFIX."societe SET tva_assuj='".$_POST['assujtva_value']."' WHERE rowid='".$id."'";
+		$result = $db->query($sql);
+		if (! $result) dol_print_error($result);
+	}
 
-// Update communication level
-if ($action == 'cstc')
-{
-	$object->fetch($id);
-	$object->stcomm_id=GETPOST('stcomm','int');
-	$result=$object->set_commnucation_level($user);
-	if ($result < 0) setEventMessage($object->error,'errors');
-}
+	// set prospect level
+	if ($action == 'setprospectlevel' && $user->rights->societe->creer)
+	{
+		$object->fetch($id);
+		$object->fk_prospectlevel=GETPOST('prospect_level_id','alpha');
+		$result=$object->set_prospect_level($user);
+		if ($result < 0) setEventMessage($object->error,'errors');
+	}
 
-// Update communication level
-if ($action == 'setOutstandingBill')
-{
-	if (!$cancelbutton) {
+	// Update communication level
+	if ($action == 'cstc')
+	{
 		$object->fetch($id);
-		$object->outstanding_limit = GETPOST('OutstandingBill');
-		$result = $object->set_OutstandingBill($user);
-		if ($result < 0) {
-			setEventMessage($object->error, 'errors');
+		$object->stcomm_id=GETPOST('stcomm','int');
+		$result=$object->set_commnucation_level($user);
+		if ($result < 0) setEventMessage($object->error,'errors');
+	}
+
+	// Update communication level
+	if ($action == 'setOutstandingBill')
+	{
+		if (!$cancelbutton) {
+			$object->fetch($id);
+			$object->outstanding_limit = GETPOST('OutstandingBill');
+			$result = $object->set_OutstandingBill($user);
+			if ($result < 0) {
+				setEventMessage($object->error, 'errors');
+			}
 		}
 	}
 }
diff --git a/htdocs/comm/mailing/fiche.php b/htdocs/comm/mailing/fiche.php
index d803de28357..6e7546fb70d 100644
--- a/htdocs/comm/mailing/fiche.php
+++ b/htdocs/comm/mailing/fiche.php
@@ -102,449 +102,366 @@ $object->substitutionarrayfortest=array(
 $parameters=array();
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 
-// Action clone object
-if ($action == 'confirm_clone' && $confirm == 'yes')
-{
-	if (empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"]))
-	{
-		$mesg='<div class="error">'.$langs->trans("NoCloneOptionsSpecified").'</div>';
-	}
-	else
+if (empty($reshook)) {
+
+	// Action clone object
+	if ($action == 'confirm_clone' && $confirm == 'yes')
 	{
-		$result=$object->createFromClone($object->id,$_REQUEST["clone_content"],$_REQUEST["clone_receivers"]);
-		if ($result > 0)
+		if (empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"]))
 		{
-			header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
-			exit;
+			$mesg='<div class="error">'.$langs->trans("NoCloneOptionsSpecified").'</div>';
 		}
 		else
 		{
-			$mesg=$object->error;
+			$result=$object->createFromClone($object->id,$_REQUEST["clone_content"],$_REQUEST["clone_receivers"]);
+			if ($result > 0)
+			{
+				header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
+				exit;
+			}
+			else
+			{
+				$mesg=$object->error;
+			}
 		}
+	    $action='';
 	}
-    $action='';
-}
 
-// Action send emailing for everybody
-if ($action == 'sendallconfirmed' && $confirm == 'yes')
-{
-	if (empty($conf->global->MAILING_LIMIT_SENDBYWEB))
-	{
-		// Pour des raisons de securite, on ne permet pas cette fonction via l'IHM,
-		// on affiche donc juste un message
-		$mesg='<div class="warning">'.$langs->trans("MailingNeedCommand").'</div>';
-		$mesg.='<br><textarea cols="70" rows="'.ROWS_2.'" wrap="soft">php ./scripts/emailings/mailing-send.php '.$object->id.'</textarea>';
-		$mesg.='<br><br><div class="warning">'.$langs->trans("MailingNeedCommand2").'</div>';
-		$action='';
-	}
-	else if ($conf->global->MAILING_LIMIT_SENDBYWEB < 0)
-	{
-		$mesg='<div class="warning">'.$langs->trans("NotEnoughPermissions").'</div>';
-		$action='';
-	}
-	else
+	// Action send emailing for everybody
+	if ($action == 'sendallconfirmed' && $confirm == 'yes')
 	{
-		$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
-
-		if ($object->statut == 0)
+		if (empty($conf->global->MAILING_LIMIT_SENDBYWEB))
 		{
-			dol_print_error('','ErrorMailIsNotValidated');
-			exit;
+			// Pour des raisons de securite, on ne permet pas cette fonction via l'IHM,
+			// on affiche donc juste un message
+			$mesg='<div class="warning">'.$langs->trans("MailingNeedCommand").'</div>';
+			$mesg.='<br><textarea cols="70" rows="'.ROWS_2.'" wrap="soft">php ./scripts/emailings/mailing-send.php '.$object->id.'</textarea>';
+			$mesg.='<br><br><div class="warning">'.$langs->trans("MailingNeedCommand2").'</div>';
+			$action='';
 		}
-
-		$id       = $object->id;
-		$subject  = $object->sujet;
-		$message  = $object->body;
-		$from     = $object->email_from;
-		$replyto  = $object->email_replyto;
-		$errorsto = $object->email_errorsto;
-		// Le message est-il en html
-		$msgishtml=-1;	// Unknown by default
-		if (preg_match('/[\s\t]*<html>/i',$message)) $msgishtml=1;
-
-		// Warning, we must not use begin-commit transaction here
-		// because we want to save update for each mail sent.
-
-		$nbok=0; $nbko=0;
-
-		// On choisit les mails non deja envoyes pour ce mailing (statut=0)
-		// ou envoyes en erreur (statut=-1)
-		$sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.source_url, mc.source_id, mc.source_type, mc.tag";
-		$sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
-		$sql .= " WHERE mc.statut < 1 AND mc.fk_mailing = ".$object->id;
-
-		dol_syslog("fiche.php: select targets sql=".$sql, LOG_DEBUG);
-		$resql=$db->query($sql);
-		if ($resql)
+		else if ($conf->global->MAILING_LIMIT_SENDBYWEB < 0)
 		{
-			$num = $db->num_rows($resql);	// nb of possible recipients
+			$mesg='<div class="warning">'.$langs->trans("NotEnoughPermissions").'</div>';
+			$action='';
+		}
+		else
+		{
+			$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
 
-			if ($num)
+			if ($object->statut == 0)
 			{
-				dol_syslog("comm/mailing/fiche.php: nb of targets = ".$num, LOG_DEBUG);
+				dol_print_error('','ErrorMailIsNotValidated');
+				exit;
+			}
 
-				$now=dol_now();
+			$id       = $object->id;
+			$subject  = $object->sujet;
+			$message  = $object->body;
+			$from     = $object->email_from;
+			$replyto  = $object->email_replyto;
+			$errorsto = $object->email_errorsto;
+			// Le message est-il en html
+			$msgishtml=-1;	// Unknown by default
+			if (preg_match('/[\s\t]*<html>/i',$message)) $msgishtml=1;
+
+			// Warning, we must not use begin-commit transaction here
+			// because we want to save update for each mail sent.
+
+			$nbok=0; $nbko=0;
+
+			// On choisit les mails non deja envoyes pour ce mailing (statut=0)
+			// ou envoyes en erreur (statut=-1)
+			$sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.source_url, mc.source_id, mc.source_type, mc.tag";
+			$sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
+			$sql .= " WHERE mc.statut < 1 AND mc.fk_mailing = ".$object->id;
+
+			dol_syslog("fiche.php: select targets sql=".$sql, LOG_DEBUG);
+			$resql=$db->query($sql);
+			if ($resql)
+			{
+				$num = $db->num_rows($resql);	// nb of possible recipients
 
-				// Positionne date debut envoi
-				$sql="UPDATE ".MAIN_DB_PREFIX."mailing SET date_envoi=".$db->idate($now)." WHERE rowid=".$object->id;
-				$resql2=$db->query($sql);
-				if (! $resql2)
+				if ($num)
 				{
-					dol_print_error($db);
-				}
+					dol_syslog("comm/mailing/fiche.php: nb of targets = ".$num, LOG_DEBUG);
 
-				// Loop on each email and send it
-				$i = 0;
-
-				while ($i < $num && $i < $conf->global->MAILING_LIMIT_SENDBYWEB)
-				{
+					$now=dol_now();
 
-					$res=1;
-
-					$obj = $db->fetch_object($resql);
-
-					// sendto en RFC2822
-					$sendto = str_replace(',',' ',dolGetFirstLastname($obj->firstname, $obj->lastname))." <".$obj->email.">";
-
-					// Make substitutions on topic and body. From (AA=YY;BB=CC;...) we keep YY, CC, ...
-					$other=explode(';',$obj->other);
-					$tmpfield=explode('=',$other[0],2); $other1=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
-                    $tmpfield=explode('=',$other[1],2); $other2=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
-                    $tmpfield=explode('=',$other[2],2); $other3=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
-                    $tmpfield=explode('=',$other[3],2); $other4=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
-                    $tmpfield=explode('=',$other[4],2); $other5=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
-                    // Array of possible substitutions (See also fie mailing-send.php that should manage same substitutions)
-					$substitutionarray=array(
-							'__ID__' => $obj->source_id,
-							'__EMAIL__' => $obj->email,
-							'__LASTNAME__' => $obj->lastname,
-							'__FIRSTNAME__' => $obj->firstname,
-							'__MAILTOEMAIL__' => '<a href="mailto:'.$obj->email.'">'.$obj->email.'</a>',
-							'__OTHER1__' => $other1,
-							'__OTHER2__' => $other2,
-							'__OTHER3__' => $other3,
-							'__OTHER4__' => $other4,
-							'__OTHER5__' => $other5,
-							'__CHECK_READ__' => '<img src="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-read.php?tag='.$obj->tag.'&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" width="1" height="1" style="width:1px;height:1px" border="0"/>',
-							'__UNSUBSCRIBE__' => '<a href="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-unsubscribe.php?tag='.$obj->tag.'&unsuscrib=1&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" target="_blank">'.$langs->trans("MailUnsubcribe").'</a>'
-					);
-					if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_SECURITY_TOKEN))
+					// Positionne date debut envoi
+					$sql="UPDATE ".MAIN_DB_PREFIX."mailing SET date_envoi=".$db->idate($now)." WHERE rowid=".$object->id;
+					$resql2=$db->query($sql);
+					if (! $resql2)
 					{
-						$substitutionarray['__SECUREKEYPAYPAL__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2);
-						if (empty($conf->global->PAYPAL_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2);
-						else $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN . 'membersubscription' . $obj->source_id, 2);
-					}
-					$substitutionisok=true;
-                    complete_substitutions_array($substitutionarray, $langs);
-					$newsubject=make_substitutions($subject,$substitutionarray);
-					$newmessage=make_substitutions($message,$substitutionarray);
-
-					$arr_file = array();
-					$arr_mime = array();
-					$arr_name = array();
-					$arr_css  = array();
-
-					$listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0);
-					if (count($listofpaths))
-					{
-						foreach($listofpaths as $key => $val)
-						{
-							$arr_file[]=$listofpaths[$key]['fullname'];
-							$arr_mime[]=dol_mimetype($listofpaths[$key]['name']);
-							$arr_name[]=$listofpaths[$key]['name'];
-						}
+						dol_print_error($db);
 					}
 
-					// Fabrication du mail
-					$mail = new CMailFile($newsubject, $sendto, $from, $newmessage, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $errorsto, $arr_css);
+					// Loop on each email and send it
+					$i = 0;
 
-					if ($mail->error)
+					while ($i < $num && $i < $conf->global->MAILING_LIMIT_SENDBYWEB)
 					{
-						$res=0;
-					}
-					if (! $substitutionisok)
-					{
-						$mail->error='Some substitution failed';
-						$res=0;
-					}
 
-					// Send mail
-					if ($res)
-					{
-						$res=$mail->sendfile();
-					}
+						$res=1;
+
+						$obj = $db->fetch_object($resql);
+
+						// sendto en RFC2822
+						$sendto = str_replace(',',' ',dolGetFirstLastname($obj->firstname, $obj->lastname))." <".$obj->email.">";
+
+						// Make substitutions on topic and body. From (AA=YY;BB=CC;...) we keep YY, CC, ...
+						$other=explode(';',$obj->other);
+						$tmpfield=explode('=',$other[0],2); $other1=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
+	                    $tmpfield=explode('=',$other[1],2); $other2=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
+	                    $tmpfield=explode('=',$other[2],2); $other3=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
+	                    $tmpfield=explode('=',$other[3],2); $other4=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
+	                    $tmpfield=explode('=',$other[4],2); $other5=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]);
+	                    // Array of possible substitutions (See also fie mailing-send.php that should manage same substitutions)
+						$substitutionarray=array(
+								'__ID__' => $obj->source_id,
+								'__EMAIL__' => $obj->email,
+								'__LASTNAME__' => $obj->lastname,
+								'__FIRSTNAME__' => $obj->firstname,
+								'__MAILTOEMAIL__' => '<a href="mailto:'.$obj->email.'">'.$obj->email.'</a>',
+								'__OTHER1__' => $other1,
+								'__OTHER2__' => $other2,
+								'__OTHER3__' => $other3,
+								'__OTHER4__' => $other4,
+								'__OTHER5__' => $other5,
+								'__CHECK_READ__' => '<img src="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-read.php?tag='.$obj->tag.'&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" width="1" height="1" style="width:1px;height:1px" border="0"/>',
+								'__UNSUBSCRIBE__' => '<a href="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-unsubscribe.php?tag='.$obj->tag.'&unsuscrib=1&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" target="_blank">'.$langs->trans("MailUnsubcribe").'</a>'
+						);
+						if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_SECURITY_TOKEN))
+						{
+							$substitutionarray['__SECUREKEYPAYPAL__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2);
+							if (empty($conf->global->PAYPAL_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2);
+							else $substitutionarray['__SECUREKEYPAYPAL_MEMBER__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN . 'membersubscription' . $obj->source_id, 2);
+						}
+						$substitutionisok=true;
+	                    complete_substitutions_array($substitutionarray, $langs);
+						$newsubject=make_substitutions($subject,$substitutionarray);
+						$newmessage=make_substitutions($message,$substitutionarray);
+
+						$arr_file = array();
+						$arr_mime = array();
+						$arr_name = array();
+						$arr_css  = array();
+
+						$listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0);
+						if (count($listofpaths))
+						{
+							foreach($listofpaths as $key => $val)
+							{
+								$arr_file[]=$listofpaths[$key]['fullname'];
+								$arr_mime[]=dol_mimetype($listofpaths[$key]['name']);
+								$arr_name[]=$listofpaths[$key]['name'];
+							}
+						}
 
-					if ($res)
-					{
-						// Mail successful
-						$nbok++;
+						// Fabrication du mail
+						$mail = new CMailFile($newsubject, $sendto, $from, $newmessage, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $errorsto, $arr_css);
 
-						dol_syslog("comm/mailing/fiche.php: ok for #".$i.($mail->error?' - '.$mail->error:''), LOG_DEBUG);
+						if ($mail->error)
+						{
+							$res=0;
+						}
+						if (! $substitutionisok)
+						{
+							$mail->error='Some substitution failed';
+							$res=0;
+						}
 
-						$sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
-						$sql.=" SET statut=1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid;
-						$resql2=$db->query($sql);
-						if (! $resql2)
+						// Send mail
+						if ($res)
 						{
-							dol_print_error($db);
+							$res=$mail->sendfile();
 						}
-						else
+
+						if ($res)
 						{
-							//if cheack read is use then update prospect contact status
-							if (strpos($message, '__CHECK_READ__') !== false)
-							{
-								//Update status communication of thirdparty prospect
-								$sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT source_id FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE rowid=".$obj->rowid.")";
-								dol_syslog("fiche.php: set prospect thirdparty status sql=".$sql, LOG_DEBUG);
-								$resql2=$db->query($sql);
-								if (! $resql2)
-								{
-									dol_print_error($db);
-								}
+							// Mail successful
+							$nbok++;
 
-							    //Update status communication of contact prospect
-								$sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."socpeople AS sc INNER JOIN ".MAIN_DB_PREFIX."mailing_cibles AS mc ON mc.rowid=".$obj->rowid." AND mc.source_type = 'contact' AND mc.source_id = sc.rowid)";
-								dol_syslog("fiche.php: set prospect contact status sql=".$sql, LOG_DEBUG);
+							dol_syslog("comm/mailing/fiche.php: ok for #".$i.($mail->error?' - '.$mail->error:''), LOG_DEBUG);
 
-								$resql2=$db->query($sql);
-								if (! $resql2)
+							$sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
+							$sql.=" SET statut=1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid;
+							$resql2=$db->query($sql);
+							if (! $resql2)
+							{
+								dol_print_error($db);
+							}
+							else
+							{
+								//if cheack read is use then update prospect contact status
+								if (strpos($message, '__CHECK_READ__') !== false)
 								{
-									dol_print_error($db);
+									//Update status communication of thirdparty prospect
+									$sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT source_id FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE rowid=".$obj->rowid.")";
+									dol_syslog("fiche.php: set prospect thirdparty status sql=".$sql, LOG_DEBUG);
+									$resql2=$db->query($sql);
+									if (! $resql2)
+									{
+										dol_print_error($db);
+									}
+
+								    //Update status communication of contact prospect
+									$sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."socpeople AS sc INNER JOIN ".MAIN_DB_PREFIX."mailing_cibles AS mc ON mc.rowid=".$obj->rowid." AND mc.source_type = 'contact' AND mc.source_id = sc.rowid)";
+									dol_syslog("fiche.php: set prospect contact status sql=".$sql, LOG_DEBUG);
+
+									$resql2=$db->query($sql);
+									if (! $resql2)
+									{
+										dol_print_error($db);
+									}
 								}
 							}
-						}
 
 
-						//test if CHECK READ change statut prospect contact
-					}
-					else
-					{
-						// Mail failed
-						$nbko++;
+							//test if CHECK READ change statut prospect contact
+						}
+						else
+						{
+							// Mail failed
+							$nbko++;
 
-						dol_syslog("comm/mailing/fiche.php: error for #".$i.($mail->error?' - '.$mail->error:''), LOG_WARNING);
+							dol_syslog("comm/mailing/fiche.php: error for #".$i.($mail->error?' - '.$mail->error:''), LOG_WARNING);
 
-						$sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
-						$sql.=" SET statut=-1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid;
-						$resql2=$db->query($sql);
-						if (! $resql2)
-						{
-							dol_print_error($db);
+							$sql="UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
+							$sql.=" SET statut=-1, date_envoi=".$db->idate($now)." WHERE rowid=".$obj->rowid;
+							$resql2=$db->query($sql);
+							if (! $resql2)
+							{
+								dol_print_error($db);
+							}
 						}
-					}
 
-					$i++;
+						$i++;
+					}
+				}
+				else
+				{
+					setEventMessage($langs->transnoentitiesnoconv("NoMoreRecipientToSendTo"));
 				}
-			}
-			else
-			{
-				setEventMessage($langs->transnoentitiesnoconv("NoMoreRecipientToSendTo"));
-			}
 
-			// Loop finished, set global statut of mail
-			if ($nbko > 0)
-			{
-				$statut=2;	// Status 'sent partially' (because at least one error)
-				if ($nbok > 0) 	setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok));
-				else setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok));
-			}
-			else
-			{
-				if ($nbok >= $num)
+				// Loop finished, set global statut of mail
+				if ($nbko > 0)
 				{
-					$statut=3;	// Send to everybody
-					setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok));
+					$statut=2;	// Status 'sent partially' (because at least one error)
+					if ($nbok > 0) 	setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok));
+					else setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok));
 				}
 				else
 				{
-					$statut=2;	// Status 'sent partially' (because not send to everybody)
-					setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok));
+					if ($nbok >= $num)
+					{
+						$statut=3;	// Send to everybody
+						setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok));
+					}
+					else
+					{
+						$statut=2;	// Status 'sent partially' (because not send to everybody)
+						setEventMessage($langs->transnoentitiesnoconv("EMailSentToNRecipients",$nbok));
+					}
 				}
-			}
 
-			$sql="UPDATE ".MAIN_DB_PREFIX."mailing SET statut=".$statut." WHERE rowid=".$object->id;
-			dol_syslog("comm/mailing/fiche.php: update global status sql=".$sql, LOG_DEBUG);
-			$resql2=$db->query($sql);
-			if (! $resql2)
+				$sql="UPDATE ".MAIN_DB_PREFIX."mailing SET statut=".$statut." WHERE rowid=".$object->id;
+				dol_syslog("comm/mailing/fiche.php: update global status sql=".$sql, LOG_DEBUG);
+				$resql2=$db->query($sql);
+				if (! $resql2)
+				{
+					dol_print_error($db);
+				}
+			}
+			else
 			{
+				dol_syslog($db->error());
 				dol_print_error($db);
 			}
-		}
-		else
-		{
-			dol_syslog($db->error());
-			dol_print_error($db);
-		}
-
-		$action = '';
-	}
-}
-
-// Action send test emailing
-if ($action == 'send' && empty($_POST["cancel"]))
-{
-	$error=0;
 
-	$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
-
-	$object->sendto = $_POST["sendto"];
-	if (! $object->sendto)
-	{
-		$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("MailTo")).'</div>';
-		$error++;
+			$action = '';
+		}
 	}
 
-	if (! $error)
+	// Action send test emailing
+	if ($action == 'send' && empty($_POST["cancel"]))
 	{
-		// Le message est-il en html
-		$msgishtml=-1;	// Inconnu par defaut
-		if (preg_match('/[\s\t]*<html>/i',$object->body)) $msgishtml=1;
-
-		// Pratique les substitutions sur le sujet et message
-		$tmpsujet=make_substitutions($object->sujet,$object->substitutionarrayfortest);
-		$tmpbody=make_substitutions($object->body,$object->substitutionarrayfortest);
-
-		$arr_file = array();
-		$arr_mime = array();
-		$arr_name = array();
-		$arr_css  = array();
-
-        // Ajout CSS
-        if (!empty($object->bgcolor)) $arr_css['bgcolor'] = (preg_match('/^#/',$object->bgcolor)?'':'#').$object->bgcolor;
-        if (!empty($object->bgimage)) $arr_css['bgimage'] = $object->bgimage;
-
-        // Attached files
-		$listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0);
-		if (count($listofpaths))
-		{
-			foreach($listofpaths as $key => $val)
-			{
-				$arr_file[]=$listofpaths[$key]['fullname'];
-				$arr_mime[]=dol_mimetype($listofpaths[$key]['name']);
-				$arr_name[]=$listofpaths[$key]['name'];
-			}
-		}
+		$error=0;
 
-		$mailfile = new CMailFile($tmpsujet,$object->sendto,$object->email_from,$tmpbody, $arr_file,$arr_mime,$arr_name,'', '', 0, $msgishtml,$object->email_errorsto,$arr_css);
+		$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
 
-		$result=$mailfile->sendfile();
-		if ($result)
+		$object->sendto = $_POST["sendto"];
+		if (! $object->sendto)
 		{
-			$mesg='<div class="ok">'.$langs->trans("MailSuccessfulySent",$mailfile->getValidAddress($object->email_from,2),$mailfile->getValidAddress($object->sendto,2)).'</div>';
+			$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->trans("MailTo")).'</div>';
+			$error++;
 		}
-		else
+
+		if (! $error)
 		{
-			$mesg='<div class="error">'.$langs->trans("ResultKo").'<br>'.$mailfile->error.' '.$result.'</div>';
-		}
+			// Le message est-il en html
+			$msgishtml=-1;	// Inconnu par defaut
+			if (preg_match('/[\s\t]*<html>/i',$object->body)) $msgishtml=1;
 
-		$action='';
-	}
-}
+			// Pratique les substitutions sur le sujet et message
+			$tmpsujet=make_substitutions($object->sujet,$object->substitutionarrayfortest);
+			$tmpbody=make_substitutions($object->body,$object->substitutionarrayfortest);
 
-// Action add emailing
-if ($action == 'add')
-{
-	$object->email_from     = trim($_POST["from"]);
-	$object->email_replyto  = trim($_POST["replyto"]);
-	$object->email_errorsto = trim($_POST["errorsto"]);
-	$object->titre          = trim($_POST["titre"]);
-	$object->sujet          = trim($_POST["sujet"]);
-	$object->body           = trim($_POST["body"]);
-	$object->bgcolor        = trim($_POST["bgcolor"]);
-	$object->bgimage        = trim($_POST["bgimage"]);
-
-	if (! $object->titre) $mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle"));
-	if (! $object->sujet) $mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic"));
-	if (! $object->body)  $mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage"));
-
-	if (! $mesg)
-	{
-		if ($object->create($user) >= 0)
-		{
-			header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
-			exit;
-		}
-		$mesg=$object->error;
-	}
+			$arr_file = array();
+			$arr_mime = array();
+			$arr_name = array();
+			$arr_css  = array();
 
-	$mesg='<div class="error">'.$mesg.'</div>';
-	$action="create";
-}
+	        // Ajout CSS
+	        if (!empty($object->bgcolor)) $arr_css['bgcolor'] = (preg_match('/^#/',$object->bgcolor)?'':'#').$object->bgcolor;
+	        if (!empty($object->bgimage)) $arr_css['bgimage'] = $object->bgimage;
 
-// Action update description of emailing
-if ($action == 'settitre' || $action == 'setemail_from' || $actino == 'setreplyto' || $action == 'setemail_errorsto')
-{
-	$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
+	        // Attached files
+			$listofpaths=dol_dir_list($upload_dir,'all',0,'','','name',SORT_ASC,0);
+			if (count($listofpaths))
+			{
+				foreach($listofpaths as $key => $val)
+				{
+					$arr_file[]=$listofpaths[$key]['fullname'];
+					$arr_mime[]=dol_mimetype($listofpaths[$key]['name']);
+					$arr_name[]=$listofpaths[$key]['name'];
+				}
+			}
 
-	if ($action == 'settitre')					$object->titre          = trim(GETPOST('titre','alpha'));
-	else if ($action == 'setemail_from')		$object->email_from     = trim(GETPOST('email_from','alpha'));
-	else if ($action == 'setemail_replyto')		$object->email_replyto  = trim(GETPOST('email_replyto','alpha'));
-	else if ($action == 'setemail_errorsto')	$object->email_errorsto = trim(GETPOST('email_errorsto','alpha'));
+			$mailfile = new CMailFile($tmpsujet,$object->sendto,$object->email_from,$tmpbody, $arr_file,$arr_mime,$arr_name,'', '', 0, $msgishtml,$object->email_errorsto,$arr_css);
 
-	else if ($action == 'settitre' && empty($object->titre))		$mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle"));
-	else if ($action == 'setfrom' && empty($object->email_from))	$mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailFrom"));
+			$result=$mailfile->sendfile();
+			if ($result)
+			{
+				$mesg='<div class="ok">'.$langs->trans("MailSuccessfulySent",$mailfile->getValidAddress($object->email_from,2),$mailfile->getValidAddress($object->sendto,2)).'</div>';
+			}
+			else
+			{
+				$mesg='<div class="error">'.$langs->trans("ResultKo").'<br>'.$mailfile->error.' '.$result.'</div>';
+			}
 
-	if (! $mesg)
-	{
-		if ($object->update($user) >= 0)
-		{
-			header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
-			exit;
+			$action='';
 		}
-		$mesg=$object->error;
 	}
 
-	$mesg='<div class="error">'.$mesg.'</div>';
-	$action="";
-}
-
-/*
- * Add file in email form
- */
-if (! empty($_POST['addfile']))
-{
-	$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
-
-	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-
-    // Set tmp user directory
-    dol_add_file_process($upload_dir,0,0);
-
-	$action="edit";
-}
-
-// Action remove file
-if (! empty($_POST["removedfile"]))
-{
-	$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
-
-	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-
-    dol_remove_file_process($_POST['removedfile'],0);
-
-	$action="edit";
-}
-
-// Action update emailing
-if ($action == 'update' && empty($_POST["removedfile"]) && empty($_POST["cancel"]))
-{
-	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-
-	$isupload=0;
-
-	if (! $isupload)
+	// Action add emailing
+	if ($action == 'add')
 	{
+		$object->email_from     = trim($_POST["from"]);
+		$object->email_replyto  = trim($_POST["replyto"]);
+		$object->email_errorsto = trim($_POST["errorsto"]);
+		$object->titre          = trim($_POST["titre"]);
 		$object->sujet          = trim($_POST["sujet"]);
 		$object->body           = trim($_POST["body"]);
 		$object->bgcolor        = trim($_POST["bgcolor"]);
 		$object->bgimage        = trim($_POST["bgimage"]);
 
+		if (! $object->titre) $mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle"));
 		if (! $object->sujet) $mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic"));
 		if (! $object->body)  $mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage"));
 
 		if (! $mesg)
 		{
-			if ($object->update($user) >= 0)
+			if ($object->create($user) >= 0)
 			{
 				header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
 				exit;
@@ -553,79 +470,164 @@ if ($action == 'update' && empty($_POST["removedfile"]) && empty($_POST["cancel"
 		}
 
 		$mesg='<div class="error">'.$mesg.'</div>';
-		$action="edit";
+		$action="create";
 	}
-	else
+
+	// Action update description of emailing
+	if ($action == 'settitre' || $action == 'setemail_from' || $actino == 'setreplyto' || $action == 'setemail_errorsto')
 	{
-		$action="edit";
+		$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
+
+		if ($action == 'settitre')					$object->titre          = trim(GETPOST('titre','alpha'));
+		else if ($action == 'setemail_from')		$object->email_from     = trim(GETPOST('email_from','alpha'));
+		else if ($action == 'setemail_replyto')		$object->email_replyto  = trim(GETPOST('email_replyto','alpha'));
+		else if ($action == 'setemail_errorsto')	$object->email_errorsto = trim(GETPOST('email_errorsto','alpha'));
+
+		else if ($action == 'settitre' && empty($object->titre))		$mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle"));
+		else if ($action == 'setfrom' && empty($object->email_from))	$mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailFrom"));
+
+		if (! $mesg)
+		{
+			if ($object->update($user) >= 0)
+			{
+				header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
+				exit;
+			}
+			$mesg=$object->error;
+		}
+
+		$mesg='<div class="error">'.$mesg.'</div>';
+		$action="";
 	}
-}
 
-// Action confirmation validation
-if ($action == 'confirm_valid' && $confirm == 'yes')
-{
-	if ($object->id > 0)
+	/*
+	 * Add file in email form
+	 */
+	if (! empty($_POST['addfile']))
 	{
-		$object->valid($user);
-		setEventMessage($langs->trans("MailingSuccessfullyValidated"));
-		header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
-		exit;
+		$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
+
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+	    // Set tmp user directory
+	    dol_add_file_process($upload_dir,0,0);
+
+		$action="edit";
 	}
-	else
+
+	// Action remove file
+	if (! empty($_POST["removedfile"]))
 	{
-		dol_print_error($db);
+		$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
+
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+	    dol_remove_file_process($_POST['removedfile'],0);
+
+		$action="edit";
 	}
-}
 
-// Resend
-if ($action == 'confirm_reset' && $confirm == 'yes')
-{
-	if ($object->id > 0)
+	// Action update emailing
+	if ($action == 'update' && empty($_POST["removedfile"]) && empty($_POST["cancel"]))
 	{
-		$db->begin();
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+		$isupload=0;
 
-		$result=$object->valid($user);
-		if ($result > 0)
+		if (! $isupload)
 		{
-			$result=$object->reset_targets_status($user);
+			$object->sujet          = trim($_POST["sujet"]);
+			$object->body           = trim($_POST["body"]);
+			$object->bgcolor        = trim($_POST["bgcolor"]);
+			$object->bgimage        = trim($_POST["bgimage"]);
+
+			if (! $object->sujet) $mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic"));
+			if (! $object->body)  $mesg.=($mesg?'<br>':'').$langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage"));
+
+			if (! $mesg)
+			{
+				if ($object->update($user) >= 0)
+				{
+					header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
+					exit;
+				}
+				$mesg=$object->error;
+			}
+
+			$mesg='<div class="error">'.$mesg.'</div>';
+			$action="edit";
+		}
+		else
+		{
+			$action="edit";
 		}
+	}
 
-		if ($result > 0)
+	// Action confirmation validation
+	if ($action == 'confirm_valid' && $confirm == 'yes')
+	{
+		if ($object->id > 0)
 		{
-			$db->commit();
+			$object->valid($user);
+			setEventMessage($langs->trans("MailingSuccessfullyValidated"));
 			header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
 			exit;
 		}
 		else
 		{
-			$mesg=$object->error;
-			$db->rollback();
+			dol_print_error($db);
 		}
 	}
-	else
+
+	// Resend
+	if ($action == 'confirm_reset' && $confirm == 'yes')
 	{
-		dol_print_error($db);
+		if ($object->id > 0)
+		{
+			$db->begin();
+
+			$result=$object->valid($user);
+			if ($result > 0)
+			{
+				$result=$object->reset_targets_status($user);
+			}
+
+			if ($result > 0)
+			{
+				$db->commit();
+				header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
+				exit;
+			}
+			else
+			{
+				$mesg=$object->error;
+				$db->rollback();
+			}
+		}
+		else
+		{
+			dol_print_error($db);
+		}
 	}
-}
 
-// Action confirmation suppression
-if ($action == 'confirm_delete' && $confirm == 'yes')
-{
-	if ($object->delete($object->id))
+	// Action confirmation suppression
+	if ($action == 'confirm_delete' && $confirm == 'yes')
 	{
-		$url= (! empty($urlfrom) ? $urlfrom : 'liste.php');
-		header("Location: ".$url);
-		exit;
+		if ($object->delete($object->id))
+		{
+			$url= (! empty($urlfrom) ? $urlfrom : 'liste.php');
+			header("Location: ".$url);
+			exit;
+		}
 	}
-}
 
-if (! empty($_POST["cancel"]))
-{
-	$action = '';
+	if (! empty($_POST["cancel"]))
+	{
+		$action = '';
+	}
 }
 
 
-
 /*
  * View
  */
diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php
index 4929ee9c70e..945f6498ce5 100644
--- a/htdocs/comm/propal.php
+++ b/htdocs/comm/propal.php
@@ -106,65 +106,46 @@ $parameters = array('socid' => $socid);
 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some
                                                                                    // hooks
 
-include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once
+if (empty($reshook)) {
+	include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once
 
-// Action clone object
-if ($action == 'confirm_clone' && $confirm == 'yes') {
-	if (1 == 0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) {
-		setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors');
-	} else {
-		if ($object->id > 0) {
-			$result = $object->createFromClone($socid);
-			if ($result > 0) {
-				header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result);
-				exit();
-			} else {
-				setEventMessage($object->error, 'errors');
-				$action = '';
+	// Action clone object
+	if ($action == 'confirm_clone' && $confirm == 'yes') {
+		if (1 == 0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) {
+			setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors');
+		} else {
+			if ($object->id > 0) {
+				$result = $object->createFromClone($socid);
+				if ($result > 0) {
+					header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result);
+					exit();
+				} else {
+					setEventMessage($object->error, 'errors');
+					$action = '';
+				}
 			}
 		}
 	}
-}
-
-// Delete proposal
-else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->propal->supprimer) {
-	$result = $object->delete($user);
-	if ($result > 0) {
-		header('Location: ' . DOL_URL_ROOT . '/comm/propal/list.php');
-		exit();
-	} else {
-		$langs->load("errors");
-		setEventMessage($langs->trans($object->error), 'errors');
-	}
-}
 
-// Remove line
-else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->propal->creer) {
-	$result = $object->deleteline($lineid);
-	// reorder lines
-	if ($result)
-		$object->line_order(true);
-
-	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-		// Define output language
-		$outputlangs = $langs;
-		if (! empty($conf->global->MAIN_MULTILANGS)) {
-			$outputlangs = new Translate("", $conf);
-			$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
-			$outputlangs->setDefaultLang($newlang);
+	// Delete proposal
+	else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->propal->supprimer) {
+		$result = $object->delete($user);
+		if ($result > 0) {
+			header('Location: ' . DOL_URL_ROOT . '/comm/propal/list.php');
+			exit();
+		} else {
+			$langs->load("errors");
+			setEventMessage($langs->trans($object->error), 'errors');
 		}
-		$ret = $object->fetch($id); // Reload to get new records
-		propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 	}
 
-	header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id);
-	exit();
-}
+	// Remove line
+	else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->propal->creer) {
+		$result = $object->deleteline($lineid);
+		// reorder lines
+		if ($result)
+			$object->line_order(true);
 
-// Validation
-else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->propal->valider) {
-	$result = $object->valid($user);
-	if ($result >= 0) {
 		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
 			// Define output language
 			$outputlangs = $langs;
@@ -176,567 +157,715 @@ else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->pr
 			$ret = $object->fetch($id); // Reload to get new records
 			propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 		}
-	} else {
-		$langs->load("errors");
-		if (count($object->errors) > 0) setEventMessage($object->errors, 'errors');
-		else setEventMessage($langs->trans($object->error), 'errors');
-	}
-}
 
-else if ($action == 'setdate' && $user->rights->propal->creer) {
-	$datep = dol_mktime(12, 0, 0, $_POST ['remonth'], $_POST ['reday'], $_POST ['reyear']);
+		header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id);
+		exit();
+	}
 
-	if (empty($datep)) {
-		$error ++;
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors');
+	// Validation
+	else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->propal->valider) {
+		$result = $object->valid($user);
+		if ($result >= 0) {
+			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+				// Define output language
+				$outputlangs = $langs;
+				if (! empty($conf->global->MAIN_MULTILANGS)) {
+					$outputlangs = new Translate("", $conf);
+					$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
+					$outputlangs->setDefaultLang($newlang);
+				}
+				$ret = $object->fetch($id); // Reload to get new records
+				propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+			}
+		} else {
+			$langs->load("errors");
+			if (count($object->errors) > 0) setEventMessage($object->errors, 'errors');
+			else setEventMessage($langs->trans($object->error), 'errors');
+		}
 	}
 
-	if (! $error) {
-		$result = $object->set_date($user, $datep);
+	else if ($action == 'setdate' && $user->rights->propal->creer) {
+		$datep = dol_mktime(12, 0, 0, $_POST ['remonth'], $_POST ['reday'], $_POST ['reyear']);
+
+		if (empty($datep)) {
+			$error ++;
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors');
+		}
+
+		if (! $error) {
+			$result = $object->set_date($user, $datep);
+			if ($result < 0)
+				dol_print_error($db, $object->error);
+		}
+	} else if ($action == 'setecheance' && $user->rights->propal->creer) {
+		$result = $object->set_echeance($user, dol_mktime(12, 0, 0, $_POST ['echmonth'], $_POST ['echday'], $_POST ['echyear']));
+		if ($result < 0)
+			dol_print_error($db, $object->error);
+	} else if ($action == 'setdate_livraison' && $user->rights->propal->creer) {
+		$result = $object->set_date_livraison($user, dol_mktime(12, 0, 0, $_POST ['liv_month'], $_POST ['liv_day'], $_POST ['liv_year']));
 		if ($result < 0)
 			dol_print_error($db, $object->error);
 	}
-} else if ($action == 'setecheance' && $user->rights->propal->creer) {
-	$result = $object->set_echeance($user, dol_mktime(12, 0, 0, $_POST ['echmonth'], $_POST ['echday'], $_POST ['echyear']));
-	if ($result < 0)
-		dol_print_error($db, $object->error);
-} else if ($action == 'setdate_livraison' && $user->rights->propal->creer) {
-	$result = $object->set_date_livraison($user, dol_mktime(12, 0, 0, $_POST ['liv_month'], $_POST ['liv_day'], $_POST ['liv_year']));
-	if ($result < 0)
-		dol_print_error($db, $object->error);
-}
 
-// Positionne ref client
-else if ($action == 'set_ref_client' && $user->rights->propal->creer) {
-	$object->set_ref_client($user, $_POST ['ref_client']);
-}
+	// Positionne ref client
+	else if ($action == 'set_ref_client' && $user->rights->propal->creer) {
+		$object->set_ref_client($user, $_POST ['ref_client']);
+	}
 
-// Create proposal
-else if ($action == 'add' && $user->rights->propal->creer) {
-	$object->socid = $socid;
-	$object->fetch_thirdparty();
+	// Create proposal
+	else if ($action == 'add' && $user->rights->propal->creer) {
+		$object->socid = $socid;
+		$object->fetch_thirdparty();
 
-	$datep = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
-	$date_delivery = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year'));
-	$duration = GETPOST('duree_validite');
+		$datep = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
+		$date_delivery = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year'));
+		$duration = GETPOST('duree_validite');
 
-	if (empty($datep)) {
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors');
-		$action = 'create';
-		$error ++;
-	}
-	if (empty($duration)) {
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ValidityDuration")), 'errors');
-		$action = 'create';
-		$error ++;
-	}
-
-	if ($socid < 1) {
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors');
-		$action = 'create';
-		$error ++;
-	}
+		if (empty($datep)) {
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors');
+			$action = 'create';
+			$error ++;
+		}
+		if (empty($duration)) {
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ValidityDuration")), 'errors');
+			$action = 'create';
+			$error ++;
+		}
 
-	if (! $error) {
-		$db->begin();
+		if ($socid < 1) {
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors');
+			$action = 'create';
+			$error ++;
+		}
 
-		// Si on a selectionne une propal a copier, on realise la copie
-		if (GETPOST('createmode') == 'copy' && GETPOST('copie_propal')) {
-			if ($object->fetch(GETPOST('copie_propal')) > 0) {
+		if (! $error) {
+			$db->begin();
+
+			// Si on a selectionne une propal a copier, on realise la copie
+			if (GETPOST('createmode') == 'copy' && GETPOST('copie_propal')) {
+				if ($object->fetch(GETPOST('copie_propal')) > 0) {
+					$object->ref = GETPOST('ref');
+					$object->datep = $datep;
+					$object->date_livraison = $date_delivery;
+					$object->availability_id = GETPOST('availability_id');
+					$object->demand_reason_id = GETPOST('demand_reason_id');
+					$object->fk_delivery_address = GETPOST('fk_address');
+					$object->duree_validite = $duration;
+					$object->cond_reglement_id = GETPOST('cond_reglement_id');
+					$object->mode_reglement_id = GETPOST('mode_reglement_id');
+					$object->remise_percent = GETPOST('remise_percent');
+					$object->remise_absolue = GETPOST('remise_absolue');
+					$object->socid = GETPOST('socid');
+					$object->contactid = GETPOST('contactidp');
+					$object->fk_project = GETPOST('projectid');
+					$object->modelpdf = GETPOST('model');
+					$object->author = $user->id; // deprecated
+					$object->note = GETPOST('note');
+					$object->statut = 0;
+
+					$id = $object->create_from($user);
+				} else {
+					setEventMessage($langs->trans("ErrorFailedToCopyProposal", GETPOST('copie_propal')), 'errors');
+				}
+			} else {
 				$object->ref = GETPOST('ref');
+				$object->ref_client = GETPOST('ref_client');
 				$object->datep = $datep;
 				$object->date_livraison = $date_delivery;
 				$object->availability_id = GETPOST('availability_id');
 				$object->demand_reason_id = GETPOST('demand_reason_id');
 				$object->fk_delivery_address = GETPOST('fk_address');
-				$object->duree_validite = $duration;
+				$object->duree_validite = GETPOST('duree_validite');
 				$object->cond_reglement_id = GETPOST('cond_reglement_id');
 				$object->mode_reglement_id = GETPOST('mode_reglement_id');
-				$object->remise_percent = GETPOST('remise_percent');
-				$object->remise_absolue = GETPOST('remise_absolue');
-				$object->socid = GETPOST('socid');
+
 				$object->contactid = GETPOST('contactidp');
 				$object->fk_project = GETPOST('projectid');
 				$object->modelpdf = GETPOST('model');
 				$object->author = $user->id; // deprecated
 				$object->note = GETPOST('note');
-				$object->statut = 0;
 
-				$id = $object->create_from($user);
-			} else {
-				setEventMessage($langs->trans("ErrorFailedToCopyProposal", GETPOST('copie_propal')), 'errors');
-			}
-		} else {
-			$object->ref = GETPOST('ref');
-			$object->ref_client = GETPOST('ref_client');
-			$object->datep = $datep;
-			$object->date_livraison = $date_delivery;
-			$object->availability_id = GETPOST('availability_id');
-			$object->demand_reason_id = GETPOST('demand_reason_id');
-			$object->fk_delivery_address = GETPOST('fk_address');
-			$object->duree_validite = GETPOST('duree_validite');
-			$object->cond_reglement_id = GETPOST('cond_reglement_id');
-			$object->mode_reglement_id = GETPOST('mode_reglement_id');
-
-			$object->contactid = GETPOST('contactidp');
-			$object->fk_project = GETPOST('projectid');
-			$object->modelpdf = GETPOST('model');
-			$object->author = $user->id; // deprecated
-			$object->note = GETPOST('note');
-
-			$object->origin = GETPOST('origin');
-			$object->origin_id = GETPOST('originid');
+				$object->origin = GETPOST('origin');
+				$object->origin_id = GETPOST('originid');
 
-			for($i = 1; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i ++) {
-				if ($_POST ['idprod' . $i]) {
-					$xid = 'idprod' . $i;
-					$xqty = 'qty' . $i;
-					$xremise = 'remise' . $i;
-					$object->add_product($_POST [$xid], $_POST [$xqty], $_POST [$xremise]);
+				for($i = 1; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i ++) {
+					if ($_POST ['idprod' . $i]) {
+						$xid = 'idprod' . $i;
+						$xqty = 'qty' . $i;
+						$xremise = 'remise' . $i;
+						$object->add_product($_POST [$xid], $_POST [$xqty], $_POST [$xremise]);
+					}
 				}
-			}
 
-			// Fill array 'array_options' with data from add form
-			$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
-			if ($ret < 0) {
-				$error ++;
-				$action = 'create';
+				// Fill array 'array_options' with data from add form
+				$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
+				if ($ret < 0) {
+					$error ++;
+					$action = 'create';
+				}
 			}
-		}
 
-		if (! $error) {
-			$id = $object->create($user);
-
-			if ($id > 0) {
-				// Insertion contact par defaut si defini
-				if (GETPOST('contactidp') > 0) {
-					$result = $object->add_contact(GETPOST('contactidp'), 'CUSTOMER', 'external');
-					if ($result < 0) {
-						$error ++;
-						setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors');
-					}
-				}
+			if (! $error) {
+				$id = $object->create($user);
 
-				if (! $error) {
-					$db->commit();
-
-					if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-						// Define output language
-						$outputlangs = $langs;
-						if (! empty($conf->global->MAIN_MULTILANGS)) {
-							$outputlangs = new Translate("", $conf);
-							$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
-							$outputlangs->setDefaultLang($newlang);
+				if ($id > 0) {
+					// Insertion contact par defaut si defini
+					if (GETPOST('contactidp') > 0) {
+						$result = $object->add_contact(GETPOST('contactidp'), 'CUSTOMER', 'external');
+						if ($result < 0) {
+							$error ++;
+							setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors');
 						}
-						$ret = $object->fetch($id); // Reload to get new records
-						propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 					}
 
-					header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
-					exit();
+					if (! $error) {
+						$db->commit();
+
+						if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+							// Define output language
+							$outputlangs = $langs;
+							if (! empty($conf->global->MAIN_MULTILANGS)) {
+								$outputlangs = new Translate("", $conf);
+								$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
+								$outputlangs->setDefaultLang($newlang);
+							}
+							$ret = $object->fetch($id); // Reload to get new records
+							propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+						}
+
+						header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
+						exit();
+					} else {
+						$db->rollback();
+					}
 				} else {
+					dol_print_error($db, $object->error);
 					$db->rollback();
+					exit();
 				}
-			} else {
-				dol_print_error($db, $object->error);
-				$db->rollback();
-				exit();
 			}
 		}
 	}
-}
 
-// Classify billed
-else if ($action == 'classifybilled' && $user->rights->propal->cloturer) {
-	$object->cloture($user, 4, '');
-}
+	// Classify billed
+	else if ($action == 'classifybilled' && $user->rights->propal->cloturer) {
+		$object->cloture($user, 4, '');
+	}
 
-// Reopen proposal
-else if ($action == 'confirm_reopen' && $user->rights->propal->cloturer && ! GETPOST('cancel')) {
-	// prevent browser refresh from reopening proposal several times
-	if ($object->statut == 2 || $object->statut == 3) {
-		$object->reopen($user, 1);
+	// Reopen proposal
+	else if ($action == 'confirm_reopen' && $user->rights->propal->cloturer && ! GETPOST('cancel')) {
+		// prevent browser refresh from reopening proposal several times
+		if ($object->statut == 2 || $object->statut == 3) {
+			$object->reopen($user, 1);
+		}
 	}
-}
 
-// Close proposal
-else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST('cancel')) {
-	if (! GETPOST('statut')) {
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("CloseAs")), 'errors');
-		$action = 'statut';
-	} else {
-		// prevent browser refresh from closing proposal several times
-		if ($object->statut == 1) {
-			$object->cloture($user, GETPOST('statut'), GETPOST('note'));
+	// Close proposal
+	else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST('cancel')) {
+		if (! GETPOST('statut')) {
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("CloseAs")), 'errors');
+			$action = 'statut';
+		} else {
+			// prevent browser refresh from closing proposal several times
+			if ($object->statut == 1) {
+				$object->cloture($user, GETPOST('statut'), GETPOST('note'));
+			}
 		}
 	}
-}
 
-// Add file in email form
-if (GETPOST('addfile')) {
-	require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
+	// Add file in email form
+	if (GETPOST('addfile')) {
+		require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
+
+		// Set tmp user directory TODO Use a dedicated directory for temp mails files
+		$vardir = $conf->user->dir_output . "/" . $user->id;
+		$upload_dir_tmp = $vardir . '/temp';
 
-	// Set tmp user directory TODO Use a dedicated directory for temp mails files
-	$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 (GETPOST('removedfile')) {
+		require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
 
-// Remove file in email form
-if (GETPOST('removedfile')) {
-	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';
+	}
 
-	// TODO Delete only files that was uploaded from email form
-	dol_remove_file_process($_POST ['removedfile'], 0);
-	$action = 'presend';
-}
+	/*
+	 * Send mail
+	 */
+	if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! GETPOST('cancel')) {
+		$langs->load('mails');
 
-/*
- * Send mail
- */
-if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! GETPOST('cancel')) {
-	$langs->load('mails');
-
-	if ($object->id > 0) {
-		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;
+		if ($object->id > 0) {
+			if ($_POST ['sendto']) {
+				// Le destinataire a ete fourni via le champ libre
+				$sendto = $_POST ['sendto'];
 				$sendtoid = 0;
-			} else 			// Id du contact
-			{
-				$sendto = $object->client->contact_get_property($_POST ['receiver'], 'email');
-				$sendtoid = $_POST ['receiver'];
+			} 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");
+			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 (dol_strlen($_POST ['subject']))
-				$subject = $_POST ['subject'];
-			else
-				$subject = $langs->transnoentities('Propal') . ' ' . $object->ref;
-			$actiontypecode = 'AC_PROP';
-			$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'];
-
-			// Envoi de la propal
-			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) {
-				setEventMessage($mailfile->error, 'errors');
-			} else {
-				$result = $mailfile->sendfile();
-				if ($result) {
-					// Initialisation donnees
-					$object->sendtoid = $sendtoid;
-					$object->actiontypecode = $actiontypecode;
-					$object->actionmsg = $actionmsg;
-					$object->actionmsg2 = $actionmsg2;
-					$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('PROPAL_SENTBYMAIL', $object, $user, $langs, $conf);
-					if ($result < 0) {
-						$error++;
-						$object->errors = $interface->errors;
-					}
-					// Fin appel triggers
+				$from = $_POST ['fromname'] . ' <' . $_POST ['frommail'] . '>';
+				$replyto = $_POST ['replytoname'] . ' <' . $_POST ['replytomail'] . '>';
+				$message = $_POST ['message'];
+				$sendtocc = $_POST ['sendtocc'];
+				$deliveryreceipt = $_POST ['deliveryreceipt'];
 
-					if (! $error) {
-						// 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"] . '?id=' . $object->id);
-						exit();
-					} else {
-						dol_print_error($db);
-					}
+				if (dol_strlen($_POST ['subject']))
+					$subject = $_POST ['subject'];
+				else
+					$subject = $langs->transnoentities('Propal') . ' ' . $object->ref;
+				$actiontypecode = 'AC_PROP';
+				$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'];
+
+				// Envoi de la propal
+				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) {
+					setEventMessage($mailfile->error, 'errors');
 				} else {
-					$langs->load("other");
-					if ($mailfile->error) {
-						$mesg .= $langs->trans('ErrorFailedToSendMail', $from, $sendto);
-						$mesg .= '<br>' . $mailfile->error;
+					$result = $mailfile->sendfile();
+					if ($result) {
+						// Initialisation donnees
+						$object->sendtoid = $sendtoid;
+						$object->actiontypecode = $actiontypecode;
+						$object->actionmsg = $actionmsg;
+						$object->actionmsg2 = $actionmsg2;
+						$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('PROPAL_SENTBYMAIL', $object, $user, $langs, $conf);
+						if ($result < 0) {
+							$error++;
+							$object->errors = $interface->errors;
+						}
+						// Fin appel triggers
+
+						if (! $error) {
+							// 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"] . '?id=' . $object->id);
+							exit();
+						} else {
+							dol_print_error($db);
+						}
 					} else {
-						$mesg .= 'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
+						$langs->load("other");
+						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';
+						}
+						setEventMessage($mesg, 'errors');
 					}
-					setEventMessage($mesg, 'errors');
 				}
+			} else {
+				$langs->load("other");
+				setEventMessage($langs->trans('ErrorMailRecipientIsEmpty') . '!', 'errors');
+				dol_syslog($langs->trans('ErrorMailRecipientIsEmpty'));
 			}
 		} else {
 			$langs->load("other");
-			setEventMessage($langs->trans('ErrorMailRecipientIsEmpty') . '!', 'errors');
-			dol_syslog($langs->trans('ErrorMailRecipientIsEmpty'));
+			setEventMessage($langs->trans('ErrorFailedToReadEntity', $langs->trans("Proposal")), 'errors');
+			dol_syslog($langs->trans('ErrorFailedToReadEntity', $langs->trans("Proposal")));
 		}
-	} else {
-		$langs->load("other");
-		setEventMessage($langs->trans('ErrorFailedToReadEntity', $langs->trans("Proposal")), 'errors');
-		dol_syslog($langs->trans('ErrorFailedToReadEntity', $langs->trans("Proposal")));
 	}
-}
 
-// Go back to draft
-if ($action == 'modif' && $user->rights->propal->creer) {
-	$object->set_draft($user);
+	// Go back to draft
+	if ($action == 'modif' && $user->rights->propal->creer) {
+		$object->set_draft($user);
 
-	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-		// Define output language
-		$outputlangs = $langs;
-		if (! empty($conf->global->MAIN_MULTILANGS)) {
-			$outputlangs = new Translate("", $conf);
-			$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
-			$outputlangs->setDefaultLang($newlang);
+		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+			// Define output language
+			$outputlangs = $langs;
+			if (! empty($conf->global->MAIN_MULTILANGS)) {
+				$outputlangs = new Translate("", $conf);
+				$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
+				$outputlangs->setDefaultLang($newlang);
+			}
+			$ret = $object->fetch($id); // Reload to get new records
+			propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 		}
-		$ret = $object->fetch($id); // Reload to get new records
-		propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 	}
-}
 
-else if ($action == "setabsolutediscount" && $user->rights->propal->creer) {
-	if ($_POST ["remise_id"]) {
-		if ($object->id > 0) {
-			$result = $object->insert_discount($_POST ["remise_id"]);
-			if ($result < 0) {
-				setEventMessage($object->error, 'errors');
+	else if ($action == "setabsolutediscount" && $user->rights->propal->creer) {
+		if ($_POST ["remise_id"]) {
+			if ($object->id > 0) {
+				$result = $object->insert_discount($_POST ["remise_id"]);
+				if ($result < 0) {
+					setEventMessage($object->error, 'errors');
+				}
 			}
 		}
 	}
-}
 
-// Add line
-else if ($action == 'addline' && $user->rights->propal->creer) {
+	// Add line
+	else if ($action == 'addline' && $user->rights->propal->creer) {
 
-	// Set if we used free entry or predefined product
-	$predef='';
-	$product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
-	$price_ht = GETPOST('price_ht');
-	if (GETPOST('prod_entry_mode') == 'free')
-	{
-		$idprod=0;
-		$tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
-	}
-	else
-	{
-		$idprod=GETPOST('idprod', 'int');
-		$tva_tx = '';
-	}
-
-	$qty = GETPOST('qty' . $predef);
-	$remise_percent = GETPOST('remise_percent' . $predef);
-
-	// Extrafields
-	$extrafieldsline = new ExtraFields($db);
-	$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
-	$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
-	// Unset extrafield
-	if (is_array($extralabelsline)) {
-		// Get extra fields
-		foreach ($extralabelsline as $key => $value) {
-			unset($_POST ["options_" . $key]);
+		// Set if we used free entry or predefined product
+		$predef='';
+		$product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
+		$price_ht = GETPOST('price_ht');
+		if (GETPOST('prod_entry_mode') == 'free')
+		{
+			$idprod=0;
+			$tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
+		}
+		else
+		{
+			$idprod=GETPOST('idprod', 'int');
+			$tva_tx = '';
 		}
-	}
-
-	if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) {
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors');
-		$error ++;
-	}
 
-	if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && $price_ht == '') 	// Unit price can be 0 but not ''. Also price can be negative for proposal.
-	{
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors');
-		$error ++;
-	}
-	if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) {
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), 'errors');
-		$error ++;
-	}
+		$qty = GETPOST('qty' . $predef);
+		$remise_percent = GETPOST('remise_percent' . $predef);
+
+		// Extrafields
+		$extrafieldsline = new ExtraFields($db);
+		$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
+		$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
+		// Unset extrafield
+		if (is_array($extralabelsline)) {
+			// Get extra fields
+			foreach ($extralabelsline as $key => $value) {
+				unset($_POST ["options_" . $key]);
+			}
+		}
 
-	if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) {
-		$pu_ht = 0;
-		$pu_ttc = 0;
-		$price_min = 0;
-		$price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
+		if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) {
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors');
+			$error ++;
+		}
 
-		$db->begin();
+		if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && $price_ht == '') 	// Unit price can be 0 but not ''. Also price can be negative for proposal.
+		{
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors');
+			$error ++;
+		}
+		if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) {
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), 'errors');
+			$error ++;
+		}
 
-		// Ecrase $pu par celui du produit
-		// Ecrase $desc par celui du produit
-		// Ecrase $txtva par celui du produit
-		if (! empty($idprod)) {
-			$prod = new Product($db);
-			$prod->fetch($idprod);
+		if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) {
+			$pu_ht = 0;
+			$pu_ttc = 0;
+			$price_min = 0;
+			$price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
+
+			$db->begin();
+
+			// Ecrase $pu par celui du produit
+			// Ecrase $desc par celui du produit
+			// Ecrase $txtva 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') : '');
+
+				// If prices fields are update
+					$tva_tx = get_default_tva($mysoc, $object->client, $prod->id);
+					$tva_npr = get_default_npr($mysoc, $object->client, $prod->id);
+
+					// On defini prix unitaire
+					if (! empty($conf->global->PRODUIT_MULTIPRICES) && $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];
+						if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level];
+						if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level];
+					}
+					elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
+					{
+						require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
+
+						$prodcustprice = new Productcustomerprice($db);
+
+						$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
+
+						$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
+						if ($result >= 0) {
+							if (count($prodcustprice->lines) > 0) {
+								$found = true;
+								$pu_ht = price($prodcustprice->lines[0]->price);
+								$pu_ttc = price($prodcustprice->lines[0]->price_ttc);
+								$price_base_type = $prodcustprice->lines[0]->price_base_type;
+								$prod->tva_tx = $prodcustprice->lines[0]->tva_tx;
+							}else {
+								$pu_ht = $prod->price;
+								$pu_ttc = $prod->price_ttc;
+								$price_min = $prod->price_min;
+								$price_base_type = $prod->price_base_type;
+							}
+						}else {
+							setEventMessage($prodcustprice->error,'errors');
+						}
+					}
+					else
+					{
+						$pu_ht = $prod->price;
+						$pu_ttc = $prod->price_ttc;
+						$price_min = $prod->price_min;
+						$price_base_type = $prod->price_base_type;
+					}
 
-			$label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
+					// if price ht is forced (ie: calculated by margin rate and cost price)
+					if (! empty($price_ht)) {
+						$pu_ht = price2num($price_ht, 'MU');
+						$pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
+					}
 
-			// If prices fields are update
-				$tva_tx = get_default_tva($mysoc, $object->client, $prod->id);
-				$tva_npr = get_default_npr($mysoc, $object->client, $prod->id);
+					// 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).
+					elseif ($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');
+						}
+					}
 
-				// On defini prix unitaire
-				if (! empty($conf->global->PRODUIT_MULTIPRICES) && $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];
-					if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level];
-					if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level];
-				}
-				elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
-				{
-					require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
+					$desc = '';
 
-					$prodcustprice = new Productcustomerprice($db);
+					// 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);
+						}
 
-					$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
+						$desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
+					} else {
+						$desc = $prod->description;
+					}
 
-					$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
-					if ($result >= 0) {
-						if (count($prodcustprice->lines) > 0) {
-							$found = true;
-							$pu_ht = price($prodcustprice->lines[0]->price);
-							$pu_ttc = price($prodcustprice->lines[0]->price_ttc);
-							$price_base_type = $prodcustprice->lines[0]->price_base_type;
-							$prod->tva_tx = $prodcustprice->lines[0]->tva_tx;
-						}else {
-							$pu_ht = $prod->price;
-							$pu_ttc = $prod->price_ttc;
-							$price_min = $prod->price_min;
-							$price_base_type = $prod->price_base_type;
-						}
-					}else {
-						setEventMessage($prodcustprice->error,'errors');
+					$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);
 					}
-				}
-				else
-				{
-					$pu_ht = $prod->price;
-					$pu_ttc = $prod->price_ttc;
-					$price_min = $prod->price_min;
-					$price_base_type = $prod->price_base_type;
-				}
 
-				// if price ht is forced (ie: calculated by margin rate and cost price)
-				if (! empty($price_ht)) {
-					$pu_ht = price2num($price_ht, 'MU');
-					$pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
-				}
+				$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');
+			}
 
-				// 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).
-				elseif ($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');
-					}
-				}
+			// Margin
+			$fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
+			$buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : '');
 
-				$desc = '';
+			$date_start = dol_mktime(0, 0, 0, GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year'));
+			$date_end = dol_mktime(0, 0, 0, GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year'));
 
-				// 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);
+			// 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($remise_percent) / 100) < price2num($price_min))) {
+				$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
+				setEventMessage($mesg, 'errors');
+			} else {
+				// Insert line
+				$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_option);
+
+				if ($result > 0) {
+					$db->commit();
+
+					if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+						// Define output language
+						$outputlangs = $langs;
+						if (! empty($conf->global->MAIN_MULTILANGS)) {
+							$outputlangs = new Translate("", $conf);
+							$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
+							$outputlangs->setDefaultLang($newlang);
+						}
+						$ret = $object->fetch($id); // Reload to get new records
+						propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 					}
 
-					$desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
+					unset($_POST ['prod_entry_mode']);
+
+					unset($_POST ['qty']);
+					unset($_POST ['type']);
+					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']);
+					unset($_POST ['np_marginRate']);
+					unset($_POST ['np_markRate']);
+					unset($_POST ['dp_desc']);
+					unset($_POST ['idprod']);
+
+			        unset($_POST['date_starthour']);
+			        unset($_POST['date_startmin']);
+			        unset($_POST['date_startsec']);
+			        unset($_POST['date_startday']);
+			        unset($_POST['date_startmonth']);
+			        unset($_POST['date_startyear']);
+			        unset($_POST['date_endhour']);
+			        unset($_POST['date_endmin']);
+			        unset($_POST['date_endsec']);
+			        unset($_POST['date_endday']);
+			        unset($_POST['date_endmonth']);
+			        unset($_POST['date_endyear']);
 				} else {
-					$desc = $prod->description;
-				}
+					$db->rollback();
 
-				$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);
+					setEventMessage($object->error, 'errors');
 				}
+			}
+		}
+	}
 
-			$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');
+	// Mise a jour d'une ligne dans la propale
+	else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('save') == $langs->trans("Save")) {
+		// Define info_bits
+		$info_bits = 0;
+		if (preg_match('/\*/', GETPOST('tva_tx')))
+			$info_bits |= 0x01;
+
+			// Clean parameters
+		$description = dol_htmlcleanlastbr(GETPOST('product_desc'));
+
+		// Define vat_rate
+		$vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
+		$vat_rate = str_replace('*', '', $vat_rate);
+		$localtax1_rate = get_localtax($vat_rate, 1, $object->client);
+		$localtax2_rate = get_localtax($vat_rate, 2, $object->client);
+		$pu_ht = GETPOST('price_ht');
+
+		// Add buying price
+		$fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : '');
+		$buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : '');
+
+		$date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
+		$date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
+
+		// Extrafields
+		$extrafieldsline = new ExtraFields($db);
+		$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
+		$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline);
+		// Unset extrafield
+		if (is_array($extralabelsline)) {
+			// Get extra fields
+			foreach ($extralabelsline as $key => $value) {
+				unset($_POST ["options_" . $key]);
+			}
 		}
 
-		// Margin
-		$fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
-		$buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : '');
+		// Define special_code for special lines
+		$special_code=GETPOST('special_code');
+		if (! GETPOST('qty')) $special_code=3;
 
-		$date_start = dol_mktime(0, 0, 0, GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year'));
-		$date_end = dol_mktime(0, 0, 0, GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year'));
+		// Check minimum price
+		$productid = GETPOST('productid', 'int');
+		if (! empty($productid)) {
+			$product = new Product($db);
+			$res = $product->fetch($productid);
 
-		// Local Taxes
-		$localtax1_tx = get_localtax($tva_tx, 1, $object->client);
-		$localtax2_tx = get_localtax($tva_tx, 2, $object->client);
+			$type = $product->type;
 
-		$info_bits = 0;
-		if ($tva_npr)
-			$info_bits |= 0x01;
+			$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 (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) {
-			$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
-			setEventMessage($mesg, 'errors');
+			if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) {
+				setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors');
+				$error ++;
+			}
 		} else {
-			// Insert line
-			$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_option);
+			$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 ++;
+			}
+		}
+
+		if (! $error) {
+			$db->begin();
+
+			$result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_option);
 
-			if ($result > 0) {
+			if ($result >= 0) {
 				$db->commit();
 
 				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
@@ -751,10 +880,9 @@ else if ($action == 'addline' && $user->rights->propal->creer) {
 					propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 				}
 
-				unset($_POST ['prod_entry_mode']);
-
 				unset($_POST ['qty']);
 				unset($_POST ['type']);
+				unset($_POST ['productid']);
 				unset($_POST ['remise_percent']);
 				unset($_POST ['price_ht']);
 				unset($_POST ['price_ttc']);
@@ -764,23 +892,6 @@ else if ($action == 'addline' && $user->rights->propal->creer) {
 				unset($_POST ['product_desc']);
 				unset($_POST ['fournprice']);
 				unset($_POST ['buying_price']);
-				unset($_POST ['np_marginRate']);
-				unset($_POST ['np_markRate']);
-				unset($_POST ['dp_desc']);
-				unset($_POST ['idprod']);
-
-		    	unset($_POST['date_starthour']);
-		    	unset($_POST['date_startmin']);
-		    	unset($_POST['date_startsec']);
-		    	unset($_POST['date_startday']);
-		    	unset($_POST['date_startmonth']);
-		    	unset($_POST['date_startyear']);
-		    	unset($_POST['date_endhour']);
-		    	unset($_POST['date_endmin']);
-		    	unset($_POST['date_endsec']);
-		    	unset($_POST['date_endday']);
-		    	unset($_POST['date_endmonth']);
-		    	unset($_POST['date_endyear']);
 			} else {
 				$db->rollback();
 
@@ -788,303 +899,194 @@ else if ($action == 'addline' && $user->rights->propal->creer) {
 			}
 		}
 	}
-}
 
-// Mise a jour d'une ligne dans la propale
-else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('save') == $langs->trans("Save")) {
-	// Define info_bits
-	$info_bits = 0;
-	if (preg_match('/\*/', GETPOST('tva_tx')))
-		$info_bits |= 0x01;
-
-		// Clean parameters
-	$description = dol_htmlcleanlastbr(GETPOST('product_desc'));
-
-	// Define vat_rate
-	$vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
-	$vat_rate = str_replace('*', '', $vat_rate);
-	$localtax1_rate = get_localtax($vat_rate, 1, $object->client);
-	$localtax2_rate = get_localtax($vat_rate, 2, $object->client);
-	$pu_ht = GETPOST('price_ht');
-
-	// Add buying price
-	$fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : '');
-	$buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : '');
-
-	$date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
-	$date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
-
-	// Extrafields
-	$extrafieldsline = new ExtraFields($db);
-	$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
-	$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline);
-	// Unset extrafield
-	if (is_array($extralabelsline)) {
-		// Get extra fields
-		foreach ($extralabelsline as $key => $value) {
-			unset($_POST ["options_" . $key]);
-		}
+	else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('cancel') == $langs->trans('Cancel')) {
+		header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition
+		exit();
 	}
 
-	// Define special_code for special lines
-	$special_code=GETPOST('special_code');
-	if (! GETPOST('qty')) $special_code=3;
-
-	// Check minimum price
-	$productid = GETPOST('productid', 'int');
-	if (! empty($productid)) {
-		$product = new Product($db);
-		$res = $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", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors');
-			$error ++;
+	// Generation doc (depuis lien ou depuis cartouche doc)
+	else if ($action == 'builddoc' && $user->rights->propal->creer) {
+		if (GETPOST('model')) {
+			$object->setDocModel($user, GETPOST('model'));
 		}
-	} 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 ++;
+		// Define output language
+		$outputlangs = $langs;
+		if (! empty($conf->global->MAIN_MULTILANGS)) {
+			$outputlangs = new Translate("", $conf);
+			$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
+			$outputlangs->setDefaultLang($newlang);
 		}
-	}
-
-	if (! $error) {
-		$db->begin();
-
-		$result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_option);
-
-		if ($result >= 0) {
-			$db->commit();
-
-			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-				// Define output language
-				$outputlangs = $langs;
-				if (! empty($conf->global->MAIN_MULTILANGS)) {
-					$outputlangs = new Translate("", $conf);
-					$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
-					$outputlangs->setDefaultLang($newlang);
-				}
-				$ret = $object->fetch($id); // Reload to get new records
-				propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-			}
+		$ret = $object->fetch($id); // Reload to get new records
+		$result = propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 
-			unset($_POST ['qty']);
-			unset($_POST ['type']);
-			unset($_POST ['productid']);
-			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 ($result <= 0) {
+			dol_print_error($db, $result);
+			exit();
 		} else {
-			$db->rollback();
-
-			setEventMessage($object->error, 'errors');
+			header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (empty($conf->global->MAIN_JUMP_TAG) ? '' : '#builddoc'));
+			exit();
 		}
 	}
-}
 
-else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('cancel') == $langs->trans('Cancel')) {
-	header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition
-	exit();
-}
+	// Remove file in doc form
+	else if ($action == 'remove_file' && $user->rights->propal->creer) {
+		if ($object->id > 0) {
+			require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
 
-// Generation doc (depuis lien ou depuis cartouche doc)
-else if ($action == 'builddoc' && $user->rights->propal->creer) {
-	if (GETPOST('model')) {
-		$object->setDocModel($user, GETPOST('model'));
+			$langs->load("other");
+			$upload_dir = $conf->propal->dir_output;
+			$file = $upload_dir . '/' . GETPOST('file');
+			$ret = dol_delete_file($file, 0, 0, 0, $object);
+			if ($ret)
+				setEventMessage($langs->trans("FileWasRemoved", GETPOST('file')));
+			else
+				setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors');
+		}
 	}
 
-	// Define output language
-	$outputlangs = $langs;
-	if (! empty($conf->global->MAIN_MULTILANGS)) {
-		$outputlangs = new Translate("", $conf);
-		$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
-		$outputlangs->setDefaultLang($newlang);
+	// Set project
+	else if ($action == 'classin' && $user->rights->propal->creer) {
+		$object->setProject($_POST ['projectid']);
 	}
-	$ret = $object->fetch($id); // Reload to get new records
-	$result = propale_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"] . '?id=' . $object->id . (empty($conf->global->MAIN_JUMP_TAG) ? '' : '#builddoc'));
-		exit();
+	// Delai de livraison
+	else if ($action == 'setavailability' && $user->rights->propal->creer) {
+		$result = $object->availability($_POST ['availability_id']);
 	}
-}
-
-// Remove file in doc form
-else if ($action == 'remove_file' && $user->rights->propal->creer) {
-	if ($object->id > 0) {
-		require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
 
-		$langs->load("other");
-		$upload_dir = $conf->propal->dir_output;
-		$file = $upload_dir . '/' . GETPOST('file');
-		$ret = dol_delete_file($file, 0, 0, 0, $object);
-		if ($ret)
-			setEventMessage($langs->trans("FileWasRemoved", GETPOST('file')));
-		else
-			setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors');
+	// Origine de la propale
+	else if ($action == 'setdemandreason' && $user->rights->propal->creer) {
+		$result = $object->demand_reason($_POST ['demand_reason_id']);
 	}
-}
 
-// Set project
-else if ($action == 'classin' && $user->rights->propal->creer) {
-	$object->setProject($_POST ['projectid']);
-}
+	// Conditions de reglement
+	else if ($action == 'setconditions' && $user->rights->propal->creer) {
+		$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
+	}
 
-// Delai de livraison
-else if ($action == 'setavailability' && $user->rights->propal->creer) {
-	$result = $object->availability($_POST ['availability_id']);
-}
+	else if ($action == 'setremisepercent' && $user->rights->propal->creer) {
+		$result = $object->set_remise_percent($user, $_POST ['remise_percent']);
+	}
 
-// Origine de la propale
-else if ($action == 'setdemandreason' && $user->rights->propal->creer) {
-	$result = $object->demand_reason($_POST ['demand_reason_id']);
-}
+	else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) {
+		$result = $object->set_remise_absolue($user, $_POST ['remise_absolue']);
+	}
 
-// Conditions de reglement
-else if ($action == 'setconditions' && $user->rights->propal->creer) {
-	$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
-}
+	// Mode de reglement
+	else if ($action == 'setmode' && $user->rights->propal->creer) {
+		$result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
+	}
 
-else if ($action == 'setremisepercent' && $user->rights->propal->creer) {
-	$result = $object->set_remise_percent($user, $_POST ['remise_percent']);
-}
+	/*
+	 * Ordonnancement des lignes
+	*/
 
-else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) {
-	$result = $object->set_remise_absolue($user, $_POST ['remise_absolue']);
-}
+	else if ($action == 'up' && $user->rights->propal->creer) {
+		$object->line_up(GETPOST('rowid'));
 
-// Mode de reglement
-else if ($action == 'setmode' && $user->rights->propal->creer) {
-	$result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
-}
+		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+			// Define output language
+			$outputlangs = $langs;
+			if (! empty($conf->global->MAIN_MULTILANGS)) {
+				$outputlangs = new Translate("", $conf);
+				$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
+				$outputlangs->setDefaultLang($newlang);
+			}
+			$ret = $object->fetch($id); // Reload to get new records
+			propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+		}
 
-/*
- * Ordonnancement des lignes
-*/
+		header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid'));
+		exit();
+	}
 
-else if ($action == 'up' && $user->rights->propal->creer) {
-	$object->line_up(GETPOST('rowid'));
+	else if ($action == 'down' && $user->rights->propal->creer) {
+		$object->line_down(GETPOST('rowid'));
 
-	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-		// Define output language
-		$outputlangs = $langs;
-		if (! empty($conf->global->MAIN_MULTILANGS)) {
-			$outputlangs = new Translate("", $conf);
-			$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
-			$outputlangs->setDefaultLang($newlang);
+		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+			// Define output language
+			$outputlangs = $langs;
+			if (! empty($conf->global->MAIN_MULTILANGS)) {
+				$outputlangs = new Translate("", $conf);
+				$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
+				$outputlangs->setDefaultLang($newlang);
+			}
+			$ret = $object->fetch($id); // Reload to get new records
+			propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 		}
-		$ret = $object->fetch($id); // Reload to get new records
-		propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-	}
 
-	header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid'));
-	exit();
-}
-
-else if ($action == 'down' && $user->rights->propal->creer) {
-	$object->line_down(GETPOST('rowid'));
+		header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid'));
+		exit();
+	} else if ($action == 'update_extras') {
+		// Fill array 'array_options' with data from update form
+		$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
+		$ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute'));
+		if ($ret < 0)
+			$error ++;
 
-	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-		// Define output language
-		$outputlangs = $langs;
-		if (! empty($conf->global->MAIN_MULTILANGS)) {
-			$outputlangs = new Translate("", $conf);
-			$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang);
-			$outputlangs->setDefaultLang($newlang);
+		if (! $error) {
+			// Actions on extra fields (by external module or standard code)
+			// FIXME le hook fait double emploi avec le trigger !!
+			$hookmanager->initHooks(array('propaldao'));
+			$parameters = array('id' => $object->id);
+			$reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been
+			                                                                                           // modified by
+			                                                                                           // some hooks
+			if (empty($reshook)) {
+				$result = $object->insertExtraFields();
+				if ($result < 0) {
+					$error ++;
+				}
+			} else if ($reshook < 0)
+				$error ++;
 		}
-		$ret = $object->fetch($id); // Reload to get new records
-		propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-	}
 
-	header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid'));
-	exit();
-} else if ($action == 'update_extras') {
-	// Fill array 'array_options' with data from update form
-	$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
-	$ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute'));
-	if ($ret < 0)
-		$error ++;
-
-	if (! $error) {
-		// Actions on extra fields (by external module or standard code)
-		// FIXME le hook fait double emploi avec le trigger !!
-		$hookmanager->initHooks(array('propaldao'));
-		$parameters = array('id' => $object->id);
-		$reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been
-		                                                                                           // modified by
-		                                                                                           // some hooks
-		if (empty($reshook)) {
-			$result = $object->insertExtraFields();
-			if ($result < 0) {
-				$error ++;
-			}
-		} else if ($reshook < 0)
-			$error ++;
+		if ($error)
+			$action = 'edit_extras';
 	}
 
-	if ($error)
-		$action = 'edit_extras';
-}
-
-if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->propal->creer) {
-	if ($action == 'addcontact') {
-		if ($object->id > 0) {
-			$contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
-			$result = $object->add_contact($contactid, $_POST ["type"], $_POST ["source"]);
-		}
+	if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->propal->creer) {
+		if ($action == 'addcontact') {
+			if ($object->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();
-		} else {
-			if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
-				$langs->load("errors");
-				setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), 'errors');
+			if ($result >= 0) {
+				header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
+				exit();
 			} else {
-				setEventMessage($object->error, 'errors');
+				if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
+					$langs->load("errors");
+					setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), 'errors');
+				} else {
+					setEventMessage($object->error, 'errors');
+				}
 			}
 		}
-	}
 
-	// Bascule du statut d'un contact
-	else if ($action == 'swapstatut') {
-		if ($object->fetch($id) > 0) {
-			$result = $object->swapContactStatus(GETPOST('ligne'));
-		} else {
-			dol_print_error($db);
+		// Bascule du statut d'un contact
+		else if ($action == 'swapstatut') {
+			if ($object->fetch($id) > 0) {
+				$result = $object->swapContactStatus(GETPOST('ligne'));
+			} else {
+				dol_print_error($db);
+			}
 		}
-	}
 
-	// Efface un contact
-	else if ($action == 'deletecontact') {
-		$object->fetch($id);
-		$result = $object->delete_contact($lineid);
+		// Efface un contact
+		else if ($action == 'deletecontact') {
+			$object->fetch($id);
+			$result = $object->delete_contact($lineid);
 
-		if ($result >= 0) {
-			header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
-			exit();
-		} else {
-			dol_print_error($db);
+			if ($result >= 0) {
+				header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
+				exit();
+			} else {
+				dol_print_error($db);
+			}
 		}
 	}
 }
diff --git a/htdocs/comm/prospect/list.php b/htdocs/comm/prospect/list.php
index 58a384df6d0..fdfa2495411 100644
--- a/htdocs/comm/prospect/list.php
+++ b/htdocs/comm/prospect/list.php
@@ -162,11 +162,13 @@ $hookmanager->initHooks(array('prospectlist'));
 $parameters=array();
 $reshook=$hookmanager->executeHooks('doActions',$parameters);    // Note that $action and $object may have been modified by some hooks
 
-if ($action == 'cstc')
-{
-	$sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm = ".$_GET["pstcomm"];
-	$sql .= " WHERE rowid = ".$_GET["socid"];
-	$result=$db->query($sql);
+if (empty($reshook)) {
+	if ($action == 'cstc')
+	{
+		$sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm = ".$_GET["pstcomm"];
+		$sql .= " WHERE rowid = ".$_GET["socid"];
+		$result=$db->query($sql);
+	}
 }
 
 
diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php
index 1c01b975a3b..02e6c74c13c 100644
--- a/htdocs/commande/fiche.php
+++ b/htdocs/commande/fiche.php
@@ -101,633 +101,759 @@ $permissionnote = $user->rights->commande->creer; // Used by the include of acti
 $parameters = array('socid' => $socid);
 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
 
-include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once
+if (empty($reshook)) {
 
-// Action clone object
-if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->commande->creer)
-{
-	if (1==0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers'))
-	{
-		$mesg='<div class="error">'.$langs->trans("NoCloneOptionsSpecified").'</div>';
-	}
-	else
+	include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once
+
+	// Action clone object
+	if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->commande->creer)
 	{
-		if ($object->id > 0)
+		if (1==0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers'))
 		{
-			// Because createFromClone modifies the object, we must clone it so that we can restore it later
-			$orig = dol_clone($object);
+			$mesg='<div class="error">'.$langs->trans("NoCloneOptionsSpecified").'</div>';
+		}
+		else
+		{
+			if ($object->id > 0)
+			{
+				// Because createFromClone modifies the object, we must clone it so that we can restore it later
+				$orig = dol_clone($object);
+
+				$result=$object->createFromClone($socid);
+				if ($result > 0)
+				{
+					header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
+					exit;
+				}
+				else
+				{
+					setEventMessage($object->error, 'errors');
+					$object = $orig;
+					$action='';
+				}
+			}
+		}
+	}
 
-			$result=$object->createFromClone($socid);
+	// Reopen a closed order
+	else if ($action == 'reopen' && $user->rights->commande->creer) {
+		if ($object->statut == 3) {
+			$result = $object->set_reopen($user);
 			if ($result > 0)
 			{
-				header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
+				header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
 				exit;
 			}
 			else
 			{
 				setEventMessage($object->error, 'errors');
-				$object = $orig;
-				$action='';
 			}
 		}
 	}
-}
 
-// Reopen a closed order
-else if ($action == 'reopen' && $user->rights->commande->creer) {
-	if ($object->statut == 3) {
-		$result = $object->set_reopen($user);
-		if ($result > 0)
-		{
-			header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
+	// Suppression de la commande
+	else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->commande->supprimer) {
+		$result = $object->delete($user);
+		if ($result > 0) {
+			header('Location: index.php');
 			exit;
 		}
-		else
-		{
+		else {
 			setEventMessage($object->error, 'errors');
 		}
 	}
-}
 
-// Suppression de la commande
-else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->commande->supprimer) {
-	$result = $object->delete($user);
-	if ($result > 0) {
-		header('Location: index.php');
-		exit;
-	}
-	else {
-		setEventMessage($object->error, 'errors');
-	}
-}
+	// Remove a product line
+	else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->commande->creer) {
+		$result = $object->deleteline($lineid);
+		if ($result > 0) {
+			// 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);
+			}
+			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+				$ret = $object->fetch($object->id); // Reload to get new records
+				commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+			}
 
-// Remove a product line
-else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->commande->creer) {
-	$result = $object->deleteline($lineid);
-	if ($result > 0) {
-		// 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);
+			header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
+			exit;
 		}
-		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-			$ret = $object->fetch($object->id); // Reload to get new records
-			commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+		else
+		{
+			setEventMessage($object->error, 'errors');
 		}
-
-		header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
-		exit;
-	}
-	else
-	{
-		setEventMessage($object->error, 'errors');
 	}
-}
-
-// Categorisation dans projet
-else if ($action == 'classin' && $user->rights->commande->creer) {
-	$object->setProject(GETPOST('projectid'));
-}
-
-// Add order
-else if ($action == 'add' && $user->rights->commande->creer) {
-	$datecommande = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
-	$datelivraison = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year'));
 
-	if ($datecommande == '') {
-		$mesg = '<div class="error">' . $langs->trans('ErrorFieldRequired', $langs->transnoentities('Date')) . '</div>';
-		$action = 'create';
-		$error ++;
+	// Categorisation dans projet
+	else if ($action == 'classin' && $user->rights->commande->creer) {
+		$object->setProject(GETPOST('projectid'));
 	}
 
-	if ($socid < 1) {
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors');
-		$action = 'create';
-		$error ++;
-	}
+	// Add order
+	else if ($action == 'add' && $user->rights->commande->creer) {
+		$datecommande = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
+		$datelivraison = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year'));
 
-	if (! $error) {
-		$object->socid = $socid;
-		$object->fetch_thirdparty();
-
-		$db->begin();
-
-		$object->date_commande = $datecommande;
-		$object->note_private = GETPOST('note_private');
-		$object->note_public = GETPOST('note_public');
-		$object->source = GETPOST('source_id');
-		$object->fk_project = GETPOST('projectid');
-		$object->ref_client = GETPOST('ref_client');
-		$object->modelpdf = GETPOST('model');
-		$object->cond_reglement_id = GETPOST('cond_reglement_id');
-		$object->mode_reglement_id = GETPOST('mode_reglement_id');
-		$object->availability_id = GETPOST('availability_id');
-		$object->demand_reason_id = GETPOST('demand_reason_id');
-		$object->date_livraison = $datelivraison;
-		$object->fk_delivery_address = GETPOST('fk_address');
-		$object->contactid = GETPOST('contactidp');
-
-		// If creation from another object of another module (Example: origin=propal, originid=1)
-		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 ($datecommande == '') {
+			$mesg = '<div class="error">' . $langs->trans('ErrorFieldRequired', $langs->transnoentities('Date')) . '</div>';
+			$action = 'create';
+			$error ++;
+		}
 
-			// For compatibility
-			if ($element == 'order') {
-				$element = $subelement = 'commande';
-			}
-			if ($element == 'propal') {
-				$element = 'comm/propal';
-				$subelement = 'propal';
-			}
-			if ($element == 'contract') {
-				$element = $subelement = 'contrat';
-			}
+		if ($socid < 1) {
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors');
+			$action = 'create';
+			$error ++;
+		}
 
-			$object->origin = $origin;
-			$object->origin_id = $originid;
+		if (! $error) {
+			$object->socid = $socid;
+			$object->fetch_thirdparty();
+
+			$db->begin();
+
+			$object->date_commande = $datecommande;
+			$object->note_private = GETPOST('note_private');
+			$object->note_public = GETPOST('note_public');
+			$object->source = GETPOST('source_id');
+			$object->fk_project = GETPOST('projectid');
+			$object->ref_client = GETPOST('ref_client');
+			$object->modelpdf = GETPOST('model');
+			$object->cond_reglement_id = GETPOST('cond_reglement_id');
+			$object->mode_reglement_id = GETPOST('mode_reglement_id');
+			$object->availability_id = GETPOST('availability_id');
+			$object->demand_reason_id = GETPOST('demand_reason_id');
+			$object->date_livraison = $datelivraison;
+			$object->fk_delivery_address = GETPOST('fk_address');
+			$object->contactid = GETPOST('contactidp');
+
+			// If creation from another object of another module (Example: origin=propal, originid=1)
+			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];
+				}
 
-			// Possibility to add external linked objects with hooks
-			$object->linked_objects [$object->origin] = $object->origin_id;
-			$other_linked_objects = GETPOST('other_linked_objects', 'array');
-			if (! empty($other_linked_objects)) {
-				$object->linked_objects = array_merge($object->linked_objects, $other_linked_objects);
-			}
+				// For compatibility
+				if ($element == 'order') {
+					$element = $subelement = 'commande';
+				}
+				if ($element == 'propal') {
+					$element = 'comm/propal';
+					$subelement = 'propal';
+				}
+				if ($element == 'contract') {
+					$element = $subelement = 'contrat';
+				}
 
-			// Fill array 'array_options' with data from add form
-			$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
-			if ($ret < 0)
-				$error ++;
+				$object->origin = $origin;
+				$object->origin_id = $originid;
 
-			if (! $error)
-			{
-				$object_id = $object->create($user);
+				// Possibility to add external linked objects with hooks
+				$object->linked_objects [$object->origin] = $object->origin_id;
+				$other_linked_objects = GETPOST('other_linked_objects', 'array');
+				if (! empty($other_linked_objects)) {
+					$object->linked_objects = array_merge($object->linked_objects, $other_linked_objects);
+				}
 
-				if ($object_id > 0)
-				{
-					dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
+				// Fill array 'array_options' with data from add form
+				$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
+				if ($ret < 0)
+					$error ++;
 
-					$classname = ucfirst($subelement);
-					$srcobject = new $classname($db);
+				if (! $error)
+				{
+					$object_id = $object->create($user);
 
-					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)
+					if ($object_id > 0)
 					{
-						$lines = $srcobject->lines;
-						if (empty($lines) && method_exists($srcobject, 'fetch_lines'))
-						{
-							$srcobject->fetch_lines();
-							$lines = $srcobject->lines;
-						}
+						dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
 
-						$fk_parent_line = 0;
-						$num = count($lines);
+						$classname = ucfirst($subelement);
+						$srcobject = new $classname($db);
 
-						for($i = 0; $i < $num; $i ++)
+						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)
 						{
-							$label = (! empty($lines [$i]->label) ? $lines [$i]->label : '');
-							$desc = (! empty($lines [$i]->desc) ? $lines [$i]->desc : $lines [$i]->libelle);
-							$product_type = (! empty($lines [$i]->product_type) ? $lines [$i]->product_type : 0);
-
-							// Dates
-							// TODO mutualiser
-							$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 = $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;
-							}
-
-							// Extrafields
-							if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines [$i], 'fetch_optionals')) 							// For avoid conflicts if
-							                                                                                                      // trigger used
+							$lines = $srcobject->lines;
+							if (empty($lines) && method_exists($srcobject, 'fetch_lines'))
 							{
-								$lines [$i]->fetch_optionals($lines [$i]->rowid);
-								$array_option = $lines [$i]->array_options;
+								$srcobject->fetch_lines();
+								$lines = $srcobject->lines;
 							}
 
-							$result = $object->addline($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, $lines [$i]->info_bits, $lines [$i]->fk_remise_except, 'HT', 0, $date_start, $date_end, $product_type, $lines [$i]->rang, $lines [$i]->special_code, $fk_parent_line, $lines [$i]->fk_fournprice, $lines [$i]->pa_ht, $label, $array_option);
-
-							if ($result < 0) {
-								$error ++;
-								break;
-							}
+							$fk_parent_line = 0;
+							$num = count($lines);
 
-							// Defined the new fk_parent_line
-							if ($result > 0 && $lines [$i]->product_type == 9) {
-								$fk_parent_line = $result;
+							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);
+								$product_type = (! empty($lines [$i]->product_type) ? $lines [$i]->product_type : 0);
+
+								// Dates
+								// TODO mutualiser
+								$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 = $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;
+								}
+
+								// Extrafields
+								if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines [$i], 'fetch_optionals')) 							// For avoid conflicts if
+								                                                                                                      // trigger used
+								{
+									$lines [$i]->fetch_optionals($lines [$i]->rowid);
+									$array_option = $lines [$i]->array_options;
+								}
+
+								$result = $object->addline($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, $lines [$i]->info_bits, $lines [$i]->fk_remise_except, 'HT', 0, $date_start, $date_end, $product_type, $lines [$i]->rang, $lines [$i]->special_code, $fk_parent_line, $lines [$i]->fk_fournprice, $lines [$i]->pa_ht, $label, $array_option);
+
+								if ($result < 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)
+							// 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 {
+							$mesg = $srcobject->error;
 							$error ++;
+						}
 					} else {
-						$mesg = $srcobject->error;
+						$mesg = $object->error;
 						$error ++;
 					}
 				} else {
-					$mesg = $object->error;
-					$error ++;
+					// Required extrafield left blank, error message already defined by setOptionalsFromPost()
+					$action = 'create';
 				}
 			} else {
-				// Required extrafield left blank, error message already defined by setOptionalsFromPost()
-				$action = 'create';
-			}
-		} else {
-			// Fill array 'array_options' with data from add form
-			$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
-			if ($ret < 0)
-				$error ++;
+				// Fill array 'array_options' with data from add form
+				$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
+				if ($ret < 0)
+					$error ++;
 
-			if (! $error) {
-				$object_id = $object->create($user);
-
-				// If some invoice's lines already known
-				$NBLINES = 8;
-				for($i = 1; $i <= $NBLINES; $i ++) {
-					if ($_POST ['idprod' . $i]) {
-						$xid = 'idprod' . $i;
-						$xqty = 'qty' . $i;
-						$xremise = 'remise_percent' . $i;
-						$object->add_product($_POST [$xid], $_POST [$xqty], $_POST [$xremise]);
+				if (! $error) {
+					$object_id = $object->create($user);
+
+					// If some invoice's lines already known
+					$NBLINES = 8;
+					for($i = 1; $i <= $NBLINES; $i ++) {
+						if ($_POST ['idprod' . $i]) {
+							$xid = 'idprod' . $i;
+							$xqty = 'qty' . $i;
+							$xremise = 'remise_percent' . $i;
+							$object->add_product($_POST [$xid], $_POST [$xqty], $_POST [$xremise]);
+						}
 					}
 				}
 			}
-		}
 
-		// Insert default contacts if defined
-		if ($object_id > 0) {
-			if (GETPOST('contactidp')) {
-				$result = $object->add_contact(GETPOST('contactidp'), 'CUSTOMER', 'external');
-				if ($result < 0) {
-					$mesg = '<div class="error">' . $langs->trans("ErrorFailedToAddContact") . '</div>';
-					$error ++;
+			// Insert default contacts if defined
+			if ($object_id > 0) {
+				if (GETPOST('contactidp')) {
+					$result = $object->add_contact(GETPOST('contactidp'), 'CUSTOMER', 'external');
+					if ($result < 0) {
+						$mesg = '<div class="error">' . $langs->trans("ErrorFailedToAddContact") . '</div>';
+						$error ++;
+					}
 				}
+
+				$id = $object_id;
+				$action = '';
 			}
 
-			$id = $object_id;
-			$action = '';
+			// End of object creation, we show it
+			if ($object_id > 0 && ! $error) {
+				$db->commit();
+				header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object_id);
+				exit();
+			} else {
+				$db->rollback();
+				$action = 'create';
+				if (! $mesg)
+					$mesg = '<div class="error">' . $object->error . '</div>';
+			}
 		}
+	}
 
-		// End of object creation, we show it
-		if ($object_id > 0 && ! $error) {
-			$db->commit();
-			header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object_id);
-			exit();
-		} else {
-			$db->rollback();
-			$action = 'create';
-			if (! $mesg)
-				$mesg = '<div class="error">' . $object->error . '</div>';
+	else if ($action == 'classifybilled' && $user->rights->commande->creer)
+	{
+		$ret=$object->classifyBilled();
+
+		if ($ret < 0) {
+			setEventMessage($object->error, 'errors');
 		}
 	}
-}
 
-else if ($action == 'classifybilled' && $user->rights->commande->creer)
-{
-	$ret=$object->classifyBilled();
+	// Positionne ref commande client
+	else if ($action == 'set_ref_client' && $user->rights->commande->creer) {
+		$object->set_ref_client($user, GETPOST('ref_client'));
+	}
 
-	if ($ret < 0) {
-		setEventMessage($object->error, 'errors');
+	else if ($action == 'setremise' && $user->rights->commande->creer) {
+		$object->set_remise($user, GETPOST('remise'));
 	}
-}
 
-// Positionne ref commande client
-else if ($action == 'set_ref_client' && $user->rights->commande->creer) {
-	$object->set_ref_client($user, GETPOST('ref_client'));
-}
+	else if ($action == 'setabsolutediscount' && $user->rights->commande->creer) {
+		if (GETPOST('remise_id')) {
+			if ($object->id > 0) {
+				$object->insert_discount(GETPOST('remise_id'));
+			} else {
+				dol_print_error($db, $object->error);
+			}
+		}
+	}
 
-else if ($action == 'setremise' && $user->rights->commande->creer) {
-	$object->set_remise($user, GETPOST('remise'));
-}
+	else if ($action == 'setdate' && $user->rights->commande->creer) {
+		// print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year'];
+		$date = dol_mktime(0, 0, 0, GETPOST('order_month'), GETPOST('order_day'), GETPOST('order_year'));
 
-else if ($action == 'setabsolutediscount' && $user->rights->commande->creer) {
-	if (GETPOST('remise_id')) {
-		if ($object->id > 0) {
-			$object->insert_discount(GETPOST('remise_id'));
-		} else {
-			dol_print_error($db, $object->error);
+		$result = $object->set_date($user, $date);
+		if ($result < 0) {
+			$mesg = '<div class="error">' . $object->error . '</div>';
 		}
 	}
-}
 
-else if ($action == 'setdate' && $user->rights->commande->creer) {
-	// print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year'];
-	$date = dol_mktime(0, 0, 0, GETPOST('order_month'), GETPOST('order_day'), GETPOST('order_year'));
+	else if ($action == 'setdate_livraison' && $user->rights->commande->creer) {
+		// print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year'];
+		$datelivraison = dol_mktime(0, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year'));
 
-	$result = $object->set_date($user, $date);
-	if ($result < 0) {
-		$mesg = '<div class="error">' . $object->error . '</div>';
+		$result = $object->set_date_livraison($user, $datelivraison);
+		if ($result < 0) {
+			$mesg = '<div class="error">' . $object->error . '</div>';
+		}
 	}
-}
-
-else if ($action == 'setdate_livraison' && $user->rights->commande->creer) {
-	// print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year'];
-	$datelivraison = dol_mktime(0, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year'));
 
-	$result = $object->set_date_livraison($user, $datelivraison);
-	if ($result < 0) {
-		$mesg = '<div class="error">' . $object->error . '</div>';
+	else if ($action == 'setmode' && $user->rights->commande->creer) {
+		$result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
+		if ($result < 0)
+			dol_print_error($db, $object->error);
 	}
-}
 
-else if ($action == 'setmode' && $user->rights->commande->creer) {
-	$result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
-	if ($result < 0)
-		dol_print_error($db, $object->error);
-}
+	else if ($action == 'setavailability' && $user->rights->commande->creer) {
+		$result = $object->availability(GETPOST('availability_id'));
+		if ($result < 0)
+			dol_print_error($db, $object->error);
+	}
 
-else if ($action == 'setavailability' && $user->rights->commande->creer) {
-	$result = $object->availability(GETPOST('availability_id'));
-	if ($result < 0)
-		dol_print_error($db, $object->error);
-}
+	else if ($action == 'setdemandreason' && $user->rights->commande->creer) {
+		$result = $object->demand_reason(GETPOST('demand_reason_id'));
+		if ($result < 0)
+			dol_print_error($db, $object->error);
+	}
 
-else if ($action == 'setdemandreason' && $user->rights->commande->creer) {
-	$result = $object->demand_reason(GETPOST('demand_reason_id'));
-	if ($result < 0)
-		dol_print_error($db, $object->error);
-}
+	else if ($action == 'setconditions' && $user->rights->commande->creer) {
+		$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
+		if ($result < 0) {
+			dol_print_error($db, $object->error);
+		} else {
+			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+				// Define output language
+				$outputlangs = $langs;
+				$newlang = GETPOST('lang_id', 'alpha');
+				if ($conf->global->MAIN_MULTILANGS && empty($newlang))
+					$newlang = $object->client->default_lang;
+				if (! empty($newlang)) {
+					$outputlangs = new Translate("", $conf);
+					$outputlangs->setDefaultLang($newlang);
+				}
 
-else if ($action == 'setconditions' && $user->rights->commande->creer) {
-	$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
-	if ($result < 0) {
-		dol_print_error($db, $object->error);
-	} else {
-		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-			// Define output language
-			$outputlangs = $langs;
-			$newlang = GETPOST('lang_id', 'alpha');
-			if ($conf->global->MAIN_MULTILANGS && empty($newlang))
-				$newlang = $object->client->default_lang;
-			if (! empty($newlang)) {
-				$outputlangs = new Translate("", $conf);
-				$outputlangs->setDefaultLang($newlang);
+				$ret = $object->fetch($object->id); // Reload to get new records
+				commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 			}
-
-			$ret = $object->fetch($object->id); // Reload to get new records
-			commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 		}
 	}
-}
-
-else if ($action == 'setremisepercent' && $user->rights->commande->creer) {
-	$result = $object->set_remise($user, GETPOST('remise_percent'));
-}
 
-else if ($action == 'setremiseabsolue' && $user->rights->commande->creer) {
-	$result = $object->set_remise_absolue($user, GETPOST('remise_absolue'));
-}
-
-// Add a new line
-else if ($action == 'addline' && $user->rights->commande->creer) {
-	$langs->load('errors');
-	$error = 0;
-
-	// Set if we used free entry or predefined product
-	$predef='';
-	$product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
-	$price_ht = GETPOST('price_ht');
-	if (GETPOST('prod_entry_mode') == 'free')
-	{
-		$idprod=0;
-		$tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
+	else if ($action == 'setremisepercent' && $user->rights->commande->creer) {
+		$result = $object->set_remise($user, GETPOST('remise_percent'));
 	}
-	else
-	{
-		$idprod=GETPOST('idprod', 'int');
-		$tva_tx = '';
+
+	else if ($action == 'setremiseabsolue' && $user->rights->commande->creer) {
+		$result = $object->set_remise_absolue($user, GETPOST('remise_absolue'));
 	}
 
-	$qty = GETPOST('qty' . $predef);
-	$remise_percent = GETPOST('remise_percent' . $predef);
+	// Add a new line
+	else if ($action == 'addline' && $user->rights->commande->creer) {
+		$langs->load('errors');
+		$error = 0;
 
-	// Extrafields
-	$extrafieldsline = new ExtraFields($db);
-	$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
-	$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
-	// Unset extrafield
-	if (is_array($extralabelsline)) {
-		// Get extra fields
-		foreach ($extralabelsline as $key => $value) {
-			unset($_POST ["options_" . $key]);
+		// Set if we used free entry or predefined product
+		$predef='';
+		$product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
+		$price_ht = GETPOST('price_ht');
+		if (GETPOST('prod_entry_mode') == 'free')
+		{
+			$idprod=0;
+			$tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
+		}
+		else
+		{
+			$idprod=GETPOST('idprod', 'int');
+			$tva_tx = '';
+		}
+
+		$qty = GETPOST('qty' . $predef);
+		$remise_percent = GETPOST('remise_percent' . $predef);
+
+		// Extrafields
+		$extrafieldsline = new ExtraFields($db);
+		$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
+		$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
+		// Unset extrafield
+		if (is_array($extralabelsline)) {
+			// Get extra fields
+			foreach ($extralabelsline as $key => $value) {
+				unset($_POST ["options_" . $key]);
+			}
 		}
-	}
 
-	if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) {
-		setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors');
-		$error ++;
-	}
-	if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) {
-		setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors');
-		$error ++;
-	}
-	if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) 	// Unit price can be 0 but not ''
-	{
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors');
-		$error ++;
-	}
-	if ($qty == '') {
-		setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors');
-		$error ++;
-	}
-	if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) {
-		setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors');
-		$error ++;
-	}
+		if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) {
+			setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors');
+			$error ++;
+		}
+		if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) {
+			setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors');
+			$error ++;
+		}
+		if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) 	// Unit price can be 0 but not ''
+		{
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors');
+			$error ++;
+		}
+		if ($qty == '') {
+			setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors');
+			$error ++;
+		}
+		if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) {
+			setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors');
+			$error ++;
+		}
 
-	if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) {
-		// Clean parameters
-		$date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year'));
-		$date_end=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, 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');
+		if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) {
+			// Clean parameters
+			$date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year'));
+			$date_end=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), 0, 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');
 
-		// 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);
+			// 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') : '');
+				$label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
 
-			// Update if prices fields are defined
-				$tva_tx = get_default_tva($mysoc, $object->client, $prod->id);
-				$tva_npr = get_default_npr($mysoc, $object->client, $prod->id);
+				// Update if prices fields are defined
+					$tva_tx = get_default_tva($mysoc, $object->client, $prod->id);
+					$tva_npr = get_default_npr($mysoc, $object->client, $prod->id);
 
-				// multiprix
-				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];
-					if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level];
-					if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level];
-				}
-				elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
-				{
-					require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
+					// multiprix
+					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];
+						if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level];
+						if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level];
+					}
+					elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
+					{
+						require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
 
-					$prodcustprice = new Productcustomerprice($db);
+						$prodcustprice = new Productcustomerprice($db);
 
-					$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
+						$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
 
-					$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
-					if ($result >= 0) {
-						if (count($prodcustprice->lines) > 0) {
-							$found = true;
-							$pu_ht = price($prodcustprice->lines[0]->price);
-							$pu_ttc = price($prodcustprice->lines[0]->price_ttc);
-							$price_base_type = $prodcustprice->lines[0]->price_base_type;
-							$prod->tva_tx = $prodcustprice->lines[0]->tva_tx;
+						$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
+						if ($result >= 0) {
+							if (count($prodcustprice->lines) > 0) {
+								$found = true;
+								$pu_ht = price($prodcustprice->lines[0]->price);
+								$pu_ttc = price($prodcustprice->lines[0]->price_ttc);
+								$price_base_type = $prodcustprice->lines[0]->price_base_type;
+								$prod->tva_tx = $prodcustprice->lines[0]->tva_tx;
+							} else {
+								$pu_ht = $prod->price;
+								$pu_ttc = $prod->price_ttc;
+								$price_min = $prod->price_min;
+								$price_base_type = $prod->price_base_type;
+							}
 						} else {
-							$pu_ht = $prod->price;
-							$pu_ttc = $prod->price_ttc;
-							$price_min = $prod->price_min;
-							$price_base_type = $prod->price_base_type;
+							setEventMessage($prodcustprice->error,'errors');
 						}
-					} else {
-						setEventMessage($prodcustprice->error,'errors');
 					}
-				}
-				else
-				{
-					$pu_ht = $prod->price;
-					$pu_ttc = $prod->price_ttc;
-					$price_min = $prod->price_min;
-					$price_base_type = $prod->price_base_type;
-				}
-
-				// if price ht is forced (ie: calculated by margin rate and cost price)
-				if (! empty($price_ht)) {
-					$pu_ht = price2num($price_ht, 'MU');
-					$pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
-				}
+					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).
-				elseif ($tva_tx != $prod->tva_tx) {
-					if ($price_base_type != 'HT') {
-						$pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU');
-					} else {
+					// if price ht is forced (ie: calculated by margin rate and cost price)
+					if (! empty($price_ht)) {
+						$pu_ht = price2num($price_ht, 'MU');
 						$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);
+					// 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).
+					elseif ($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 = (! 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);
-				}
+					$desc = '';
 
-			$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');
-		}
+					// 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);
+						}
 
-		// Margin
-		$fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
-		$buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : '');
+						$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' . $predef) ? GETPOST('fournprice' . $predef) : '');
+			$buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : '');
+
+			// Local Taxes
+			$localtax1_tx = get_localtax($tva_tx, 1, $object->client);
+			$localtax2_tx = get_localtax($tva_tx, 2, $object->client);
+
+			$desc = dol_htmlcleanlastbr($desc);
 
-		// 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;
 
-		$desc = dol_htmlcleanlastbr($desc);
+			if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) {
+				$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
+				setEventMessage($mesg, 'errors');
+			} else {
+				// Insert line
+				$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option);
+
+				if ($result > 0) {
+					$ret = $object->fetch($object->id); // Reload to get new records
+
+					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);
+						}
+
+						commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+					}
+
+					unset($_POST ['prod_entry_mode']);
+
+					unset($_POST ['qty']);
+					unset($_POST ['type']);
+					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']);
+					unset($_POST ['np_marginRate']);
+					unset($_POST ['np_markRate']);
+					unset($_POST ['dp_desc']);
+					unset($_POST ['idprod']);
+
+			        unset($_POST['date_starthour']);
+			        unset($_POST['date_startmin']);
+			        unset($_POST['date_startsec']);
+			        unset($_POST['date_startday']);
+			        unset($_POST['date_startmonth']);
+			        unset($_POST['date_startyear']);
+			        unset($_POST['date_endhour']);
+			        unset($_POST['date_endmin']);
+			        unset($_POST['date_endsec']);
+			        unset($_POST['date_endday']);
+			        unset($_POST['date_endmonth']);
+			        unset($_POST['date_endyear']);
+				} else {
+					setEventMessage($object->error, 'errors');
+				}
+			}
+		}
+	}
 
+	/*
+	 *  Mise a jour d'une ligne dans la commande
+	*/
+	else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('save') == $langs->trans('Save')) {
+		// Clean parameters
+		$date_start='';
+		$date_end='';
+		$date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
+		$date_end=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, 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 ($tva_npr)
+		if (preg_match('/\*/', $vat_rate))
 			$info_bits |= 0x01;
 
-		if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) {
-			$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
-			setEventMessage($mesg, 'errors');
+			// 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') : '');
+
+		// Extrafields Lines
+		$extrafieldsline = new ExtraFields($db);
+		$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
+		$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline);
+		// Unset extrafield POST Data
+		if (is_array($extralabelsline)) {
+			foreach ($extralabelsline as $key => $value) {
+				unset($_POST ["options_" . $key]);
+			}
+		}
+
+		// 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", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors');
+				$error ++;
+			}
 		} else {
-			// Insert line
-			$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option);
+			$type = GETPOST('type');
+			$label = (GETPOST('product_label') ? GETPOST('product_label') : '');
 
-			if ($result > 0) {
-				$ret = $object->fetch($object->id); // Reload to get new records
+			// Check parameters
+			if (GETPOST('type') < 0) {
+				setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors');
+				$error ++;
+			}
+		}
+
+		if (! $error) {
+			$result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option);
 
+			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 = '';
+					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);
 					}
 
+					$ret = $object->fetch($object->id); // Reload to get new records
 					commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 				}
 
-				unset($_POST ['prod_entry_mode']);
-
 				unset($_POST ['qty']);
 				unset($_POST ['type']);
+				unset($_POST ['productid']);
 				unset($_POST ['remise_percent']);
 				unset($_POST ['price_ht']);
 				unset($_POST ['price_ttc']);
@@ -737,602 +863,479 @@ else if ($action == 'addline' && $user->rights->commande->creer) {
 				unset($_POST ['product_desc']);
 				unset($_POST ['fournprice']);
 				unset($_POST ['buying_price']);
-				unset($_POST ['np_marginRate']);
-				unset($_POST ['np_markRate']);
-				unset($_POST ['dp_desc']);
-				unset($_POST ['idprod']);
-
-		    	unset($_POST['date_starthour']);
-		    	unset($_POST['date_startmin']);
-		    	unset($_POST['date_startsec']);
-		    	unset($_POST['date_startday']);
-		    	unset($_POST['date_startmonth']);
-		    	unset($_POST['date_startyear']);
-		    	unset($_POST['date_endhour']);
-		    	unset($_POST['date_endmin']);
-		    	unset($_POST['date_endsec']);
-		    	unset($_POST['date_endday']);
-		    	unset($_POST['date_endmonth']);
-		    	unset($_POST['date_endyear']);
 			} else {
 				setEventMessage($object->error, 'errors');
 			}
 		}
 	}
-}
 
-/*
- *  Mise a jour d'une ligne dans la commande
-*/
-else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('save') == $langs->trans('Save')) {
-	// Clean parameters
-	$date_start='';
-	$date_end='';
-	$date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
-	$date_end=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, 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') : '');
-
-	// Extrafields Lines
-	$extrafieldsline = new ExtraFields($db);
-	$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
-	$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline);
-	// Unset extrafield POST Data
-	if (is_array($extralabelsline)) {
-		foreach ($extralabelsline as $key => $value) {
-			unset($_POST ["options_" . $key]);
-		}
+	else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('cancel') == $langs->trans('Cancel')) {
+		header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition
+		exit();
 	}
 
-	// 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') : '');
+	else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->commande->valider) {
+		$idwarehouse = GETPOST('idwarehouse');
 
-		if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) {
-			setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors');
-			$error ++;
+	    $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);
 		}
-	} 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 ++;
+		if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change)
+		{
+			if (! $idwarehouse || $idwarehouse == -1)
+			{
+				$error++;
+				$mesgs[]='<div class="error">'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'</div>';
+				$action='';
+			}
 		}
-	}
 
-	if (! $error) {
-		$result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option);
-
-		if ($result >= 0) {
-			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+		if (! $error) {
+			$result = $object->valid($user, $idwarehouse);
+			if ($result >= 0) {
 				// 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) && ! 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);
 				}
-
-				$ret = $object->fetch($object->id); // Reload to get new records
-				commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+					commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 			}
-
-			unset($_POST ['qty']);
-			unset($_POST ['type']);
-			unset($_POST ['productid']);
-			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']);
-		} else {
-			setEventMessage($object->error, 'errors');
 		}
 	}
-}
 
-else if ($action == 'updateligne' && $user->rights->commande->creer && GETPOST('cancel') == $langs->trans('Cancel')) {
-	header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition
-	exit();
-}
-
-else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->commande->valider) {
-	$idwarehouse = GETPOST('idwarehouse');
+	// Go back to draft status
+	else if ($action == 'confirm_modif' && $user->rights->commande->creer) {
+		$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);
-	}
+	    $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 (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change)
-	{
-		if (! $idwarehouse || $idwarehouse == -1)
+		// Check parameters
+		if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change)
 		{
-			$error++;
-			$mesgs[]='<div class="error">'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'</div>';
-			$action='';
+			if (! $idwarehouse || $idwarehouse == -1)
+			{
+				$error++;
+				$mesgs[]='<div class="error">'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'</div>';
+				$action='';
+			}
 		}
-	}
 
-	if (! $error) {
-		$result = $object->valid($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 (! $error) {
+			$result = $object->set_draft($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($object->id); // Reload to get new records
+					commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+				}
 			}
-			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
-				commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 		}
 	}
-}
 
-// Go back to draft status
-else if ($action == 'confirm_modif' && $user->rights->commande->creer) {
-	$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);
+	else if ($action == 'confirm_shipped' && $confirm == 'yes' && $user->rights->commande->cloturer) {
+		$result = $object->cloture($user);
+		if ($result < 0) {
+			setEventMessage($object->error, 'errors');
+		}
 	}
 
-	// Check parameters
-	if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change)
-	{
-		if (! $idwarehouse || $idwarehouse == -1)
+	else if ($action == 'confirm_cancel' && $confirm == 'yes' && $user->rights->commande->valider) {
+		$idwarehouse = GETPOST('idwarehouse');
+
+	    $qualified_for_stock_change=0;
+		if (empty($conf->global->STOCK_SUPPORTS_SERVICES))
 		{
-			$error++;
-			$mesgs[]='<div class="error">'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'</div>';
-			$action='';
+		    $qualified_for_stock_change=$object->hasProductsOrServices(2);
+		}
+		else
+		{
+		    $qualified_for_stock_change=$object->hasProductsOrServices(1);
 		}
-	}
 
-	if (! $error) {
-		$result = $object->set_draft($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($object->id); // Reload to get new records
-				commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+		// Check parameters
+		if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change)
+		{
+			if (! $idwarehouse || $idwarehouse == -1)
+			{
+				$error++;
+				$mesgs[]='<div class="error">'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'</div>';
+				$action='';
 			}
 		}
-	}
-}
 
-else if ($action == 'confirm_shipped' && $confirm == 'yes' && $user->rights->commande->cloturer) {
-	$result = $object->cloture($user);
-	if ($result < 0) {
-		setEventMessage($object->error, 'errors');
-	}
-}
+		if (! $error) {
+			$result = $object->cancel($idwarehouse);
 
-else if ($action == 'confirm_cancel' && $confirm == 'yes' && $user->rights->commande->valider) {
-	$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);
-	}
-
-	// Check parameters
-	if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change)
-	{
-		if (! $idwarehouse || $idwarehouse == -1)
-		{
-			$error++;
-			$mesgs[]='<div class="error">'.$langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")).'</div>';
-			$action='';
+			if ($result < 0) {
+				setEventMessage($object->error, 'errors');
+			}
 		}
 	}
 
-	if (! $error) {
-		$result = $object->cancel($idwarehouse);
+	/*
+	 * Ordonnancement des lignes
+	*/
 
-		if ($result < 0) {
-			setEventMessage($object->error, 'errors');
+	else if ($action == 'up' && $user->rights->commande->creer) {
+		$object->line_up(GETPOST('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);
 		}
-	}
-}
 
-/*
- * Ordonnancement des lignes
-*/
-
-else if ($action == 'up' && $user->rights->commande->creer) {
-	$object->line_up(GETPOST('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))
+			commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+
+		header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid'));
+		exit();
 	}
 
-	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
-		commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+	else if ($action == 'down' && $user->rights->commande->creer) {
+		$object->line_down(GETPOST('rowid'));
 
-	header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid'));
-	exit();
-}
+		// 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))
+			commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 
-else if ($action == 'down' && $user->rights->commande->creer) {
-	$object->line_down(GETPOST('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);
+		header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid'));
+		exit();
 	}
-	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
-		commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 
-	header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid'));
-	exit();
-}
+	else if ($action == 'builddoc') // In get or post
+	{
+		/*
+		 * Generate order document
+		 * define into /core/modules/commande/modules_commande.php
+		 */
 
-else if ($action == 'builddoc') // In get or post
-{
-	/*
-	 * Generate order document
-	 * define into /core/modules/commande/modules_commande.php
-	 */
+		// Save last template used to generate document
+		if (GETPOST('model'))
+			$object->setDocModel($user, GETPOST('model', 'alpha'));
 
-	// Save last template used to generate document
-	if (GETPOST('model'))
-		$object->setDocModel($user, GETPOST('model', 'alpha'));
+			// 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 = commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 
-		// 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 ($result <= 0) {
+			dol_print_error($db, $result);
+			exit();
+		}
 	}
-	$result = commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 
-	if ($result <= 0) {
-		dol_print_error($db, $result);
-		exit();
-	}
-}
+	// Remove file in doc form
+	else if ($action == 'remove_file') {
+		if ($object->id > 0) {
+			require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
 
-// Remove file in doc form
-else if ($action == 'remove_file') {
-	if ($object->id > 0) {
-		require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
+			$langs->load("other");
+			$upload_dir = $conf->commande->dir_output;
+			$file = $upload_dir . '/' . GETPOST('file');
+			$ret = dol_delete_file($file, 0, 0, 0, $object);
+			if ($ret)
+				setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile')));
+			else
+				setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors');
+			$action = '';
+		}
+	}
 
-		$langs->load("other");
-		$upload_dir = $conf->commande->dir_output;
-		$file = $upload_dir . '/' . GETPOST('file');
-		$ret = dol_delete_file($file, 0, 0, 0, $object);
-		if ($ret)
-			setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile')));
-		else
-			setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors');
+	// Print file
+	else if ($action == 'print_file' and $user->rights->printipp->read) {
+		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'));
+		setEventMessage($langs->trans("FileWasSentToPrinter", GETPOST('file')));
 		$action = '';
 	}
-}
 
-// Print file
-else if ($action == 'print_file' and $user->rights->printipp->read) {
-	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'));
-	setEventMessage($langs->trans("FileWasSentToPrinter", GETPOST('file')));
-	$action = '';
-}
-
-else if ($action == 'update_extras') {
-	// Fill array 'array_options' with data from update form
-	$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
-	$ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute'));
-	if ($ret < 0)
-		$error ++;
-
-	if (! $error) {
-		// Actions on extra fields (by external module or standard code)
-		// FIXME le hook fait double emploi avec le trigger !!
-		$hookmanager->initHooks(array('orderdao'));
-		$parameters = array('id' => $object->id);
-		$reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by
-		                                                                                      // some hooks
-		if (empty($reshook)) {
-			$result = $object->insertExtraFields();
-			if ($result < 0) {
-				$error ++;
-			}
-		} else if ($reshook < 0)
+	else if ($action == 'update_extras') {
+		// Fill array 'array_options' with data from update form
+		$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
+		$ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute'));
+		if ($ret < 0)
 			$error ++;
-	}
 
-	if ($error)
-		$action = 'edit_extras';
-}
+		if (! $error) {
+			// Actions on extra fields (by external module or standard code)
+			// FIXME le hook fait double emploi avec le trigger !!
+			$hookmanager->initHooks(array('orderdao'));
+			$parameters = array('id' => $object->id);
+			$reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by
+			                                                                                      // some hooks
+			if (empty($reshook)) {
+				$result = $object->insertExtraFields();
+				if ($result < 0) {
+					$error ++;
+				}
+			} else if ($reshook < 0)
+				$error ++;
+		}
 
-/*
- * Add file in email form
-*/
-if (GETPOST('addfile')) {
-	require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
+		if ($error)
+			$action = 'edit_extras';
+	}
 
-	// Set tmp user directory TODO Use a dedicated directory for temp mails files
-	$vardir = $conf->user->dir_output . "/" . $user->id;
-	$upload_dir_tmp = $vardir . '/temp';
+	/*
+	 * Add file in email form
+	*/
+	if (GETPOST('addfile')) {
+		require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
 
-	dol_add_file_process($upload_dir_tmp, 0, 0);
-	$action = 'presend';
-}
+		// Set tmp user directory TODO Use a dedicated directory for temp mails files
+		$vardir = $conf->user->dir_output . "/" . $user->id;
+		$upload_dir_tmp = $vardir . '/temp';
 
-/*
- * Remove file in email form
-*/
-if (GETPOST('removedfile')) {
-	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';
-
-	// TODO Delete only files that was uploaded from email form
-	dol_remove_file_process(GETPOST('removedfile'), 0);
-	$action = 'presend';
-}
+		dol_add_file_process($upload_dir_tmp, 0, 0);
+		$action = 'presend';
+	}
 
-/*
- * Send mail
-*/
-if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! GETPOST('cancel')) {
-	$langs->load('mails');
+	/*
+	 * Remove file in email form
+	*/
+	if (GETPOST('removedfile')) {
+		require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
 
-	if ($object->id > 0) {
-		// $ref = dol_sanitizeFileName($object->ref);
-		// $file = $conf->commande->dir_output . '/' . $ref . '/' . $ref . '.pdf';
-
-		// if (is_readable($file))
-		// {
-		if (GETPOST('sendto')) {
-			// Le destinataire a ete fourni via le champ libre
-			$sendto = GETPOST('sendto');
-			$sendtoid = 0;
-		} elseif (GETPOST('receiver') != '-1') {
-			// Recipient was provided from combo list
-			if (GETPOST('receiver') == 'thirdparty') 			// Id of third party
-			{
-				$sendto = $object->client->email;
-				$sendtoid = 0;
-			} else 			// Id du contact
-			{
-				$sendto = $object->client->contact_get_property(GETPOST('receiver'), 'email');
-				$sendtoid = GETPOST('receiver');
-			}
-		}
+		// Set tmp user directory
+		$vardir = $conf->user->dir_output . "/" . $user->id;
+		$upload_dir_tmp = $vardir . '/temp';
 
-		if (dol_strlen($sendto)) {
-			$langs->load("commercial");
+		// TODO Delete only files that was uploaded from email form
+		dol_remove_file_process(GETPOST('removedfile'), 0);
+		$action = 'presend';
+	}
 
-			$from = GETPOST('fromname') . ' <' . GETPOST('frommail') . '>';
-			$replyto = GETPOST('replytoname') . ' <' . GETPOST('replytomail') . '>';
-			$message = GETPOST('message');
-			$sendtocc = GETPOST('sendtocc');
-			$deliveryreceipt = GETPOST('deliveryreceipt');
+	/*
+	 * Send mail
+	*/
+	if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! GETPOST('cancel')) {
+		$langs->load('mails');
 
-			if ($action == 'send') {
-				if (dol_strlen(GETPOST('subject')))
-					$subject = GETPOST('subject');
-				else
-					$subject = $langs->transnoentities('Order') . ' ' . $object->ref;
-				$actiontypecode = 'AC_COM';
-				$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;
+		if ($object->id > 0) {
+			// $ref = dol_sanitizeFileName($object->ref);
+			// $file = $conf->commande->dir_output . '/' . $ref . '/' . $ref . '.pdf';
+
+			// if (is_readable($file))
+			// {
+			if (GETPOST('sendto')) {
+				// Le destinataire a ete fourni via le champ libre
+				$sendto = GETPOST('sendto');
+				$sendtoid = 0;
+			} elseif (GETPOST('receiver') != '-1') {
+				// Recipient was provided from combo list
+				if (GETPOST('receiver') == 'thirdparty') 			// Id of third party
+				{
+					$sendto = $object->client->email;
+					$sendtoid = 0;
+				} else 			// Id du contact
+				{
+					$sendto = $object->client->contact_get_property(GETPOST('receiver'), 'email');
+					$sendtoid = GETPOST('receiver');
 				}
-				$actionmsg2 = $langs->transnoentities('Action' . $actiontypecode);
 			}
 
-			// Create form object
-			include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
-			$formmail = new FormMail($db);
+			if (dol_strlen($sendto)) {
+				$langs->load("commercial");
+
+				$from = GETPOST('fromname') . ' <' . GETPOST('frommail') . '>';
+				$replyto = GETPOST('replytoname') . ' <' . GETPOST('replytomail') . '>';
+				$message = GETPOST('message');
+				$sendtocc = GETPOST('sendtocc');
+				$deliveryreceipt = GETPOST('deliveryreceipt');
+
+				if ($action == 'send') {
+					if (dol_strlen(GETPOST('subject')))
+						$subject = GETPOST('subject');
+					else
+						$subject = $langs->transnoentities('Order') . ' ' . $object->ref;
+					$actiontypecode = 'AC_COM';
+					$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);
+				}
 
-			$attachedfiles = $formmail->get_attached_files();
-			$filepath = $attachedfiles ['paths'];
-			$filename = $attachedfiles ['names'];
-			$mimetype = $attachedfiles ['mimes'];
+				// Create form object
+				include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
+				$formmail = new FormMail($db);
 
-			// 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) {
-				$mesg = '<div class="error">' . $mailfile->error . '</div>';
-			} else {
-				$result = $mailfile->sendfile();
-				if ($result) {
-					$mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2)); // Must not
-					                                                                                                                      // contains "
-
-					$error = 0;
-
-					// Initialisation donnees
-					$object->sendtoid = $sendtoid;
-					$object->actiontypecode = $actiontypecode;
-					$object->actionmsg = $actionmsg;
-					$object->actionmsg2 = $actionmsg2;
-					$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('ORDER_SENTBYMAIL', $object, $user, $langs, $conf);
-					if ($result < 0) {
-						$error ++;
-						$this->errors = $interface->errors;
-					}
-					// Fin appel triggers
+				$attachedfiles = $formmail->get_attached_files();
+				$filepath = $attachedfiles ['paths'];
+				$filename = $attachedfiles ['names'];
+				$mimetype = $attachedfiles ['mimes'];
 
-					if ($error) {
-						dol_print_error($db);
-					} else {
-						// Redirect here
-						// This avoid sending mail twice if going out and then back to page
-						header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&mesg=' . urlencode($mesg));
-						exit();
-					}
+				// 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) {
+					$mesg = '<div class="error">' . $mailfile->error . '</div>';
 				} else {
-					$langs->load("other");
-					$mesg = '<div class="error">';
-					if ($mailfile->error) {
-						$mesg .= $langs->trans('ErrorFailedToSendMail', $from, $sendto);
-						$mesg .= '<br>' . $mailfile->error;
+					$result = $mailfile->sendfile();
+					if ($result) {
+						$mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2)); // Must not
+						                                                                                                                      // contains "
+
+						$error = 0;
+
+						// Initialisation donnees
+						$object->sendtoid = $sendtoid;
+						$object->actiontypecode = $actiontypecode;
+						$object->actionmsg = $actionmsg;
+						$object->actionmsg2 = $actionmsg2;
+						$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('ORDER_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
+							header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&mesg=' . urlencode($mesg));
+							exit();
+						}
 					} else {
-						$mesg .= 'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
+						$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>';
 					}
-					$mesg .= '</div>';
 				}
+				/*            }
+				 else
+				{
+				$langs->load("other");
+				$mesg='<div class="error">'.$langs->trans('ErrorMailRecipientIsEmpty').' !</div>';
+				$action='presend';
+				dol_syslog('Recipient email is empty');
+				}*/
+			} else {
+				$langs->load("errors");
+				$mesg = '<div class="error">' . $langs->trans('ErrorCantReadFile', $file) . '</div>';
+				dol_syslog('Failed to read file: ' . $file);
 			}
-			/*            }
-			 else
-			{
-			$langs->load("other");
-			$mesg='<div class="error">'.$langs->trans('ErrorMailRecipientIsEmpty').' !</div>';
-			$action='presend';
-			dol_syslog('Recipient email is empty');
-			}*/
 		} else {
-			$langs->load("errors");
-			$mesg = '<div class="error">' . $langs->trans('ErrorCantReadFile', $file) . '</div>';
-			dol_syslog('Failed to read file: ' . $file);
+			$langs->load("other");
+			$mesg = '<div class="error">' . $langs->trans('ErrorFailedToReadEntity', $langs->trans("Order")) . '</div>';
+			dol_syslog($langs->trans('ErrorFailedToReadEntity', $langs->trans("Order")));
 		}
-	} else {
-		$langs->load("other");
-		$mesg = '<div class="error">' . $langs->trans('ErrorFailedToReadEntity', $langs->trans("Order")) . '</div>';
-		dol_syslog($langs->trans('ErrorFailedToReadEntity', $langs->trans("Order")));
 	}
-}
 
-if (! $error && ! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->commande->creer) {
-	if ($action == 'addcontact') {
-		if ($object->id > 0) {
-			$contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
-			$result = $object->add_contact($contactid, GETPOST('type'), GETPOST('source'));
-		}
+	if (! $error && ! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->commande->creer) {
+		if ($action == 'addcontact') {
+			if ($object->id > 0) {
+				$contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
+				$result = $object->add_contact($contactid, GETPOST('type'), GETPOST('source'));
+			}
 
-		if ($result >= 0) {
-			header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
-			exit();
-		} else {
-			if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
-				$langs->load("errors");
-				$mesg = '<div class="error">' . $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType") . '</div>';
+			if ($result >= 0) {
+				header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
+				exit();
 			} else {
-				$mesg = '<div class="error">' . $object->error . '</div>';
+				if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
+					$langs->load("errors");
+					$mesg = '<div class="error">' . $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType") . '</div>';
+				} else {
+					$mesg = '<div class="error">' . $object->error . '</div>';
+				}
 			}
 		}
-	}
 
-	// bascule du statut d'un contact
-	else if ($action == 'swapstatut') {
-		if ($object->id > 0) {
-			$result = $object->swapContactStatus(GETPOST('ligne'));
-		} else {
-			dol_print_error($db);
+		// bascule du statut d'un contact
+		else if ($action == 'swapstatut') {
+			if ($object->id > 0) {
+				$result = $object->swapContactStatus(GETPOST('ligne'));
+			} else {
+				dol_print_error($db);
+			}
 		}
-	}
 
-	// Efface un contact
-	else if ($action == 'deletecontact') {
-		$result = $object->delete_contact($lineid);
+		// Efface un contact
+		else if ($action == 'deletecontact') {
+			$result = $object->delete_contact($lineid);
 
-		if ($result >= 0) {
-			header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
-			exit();
-		} else {
-			dol_print_error($db);
+			if ($result >= 0) {
+				header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
+				exit();
+			} else {
+				dol_print_error($db);
+			}
 		}
 	}
 }
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index c6214f449cb..a3403e0d9dd 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -111,1170 +111,1303 @@ $permissionnote = $user->rights->facture->creer; // Used by the include of actio
 $parameters = array('socid' => $socid);
 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
 
-include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once
+if (empty($reshook)) {
 
-// 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);
+	include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once
+
+	// 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 {
+					setEventMessage($object->error, 'errors');
+					$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=' . $result);
+				header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
 				exit();
 			} else {
 				setEventMessage($object->error, 'errors');
-				$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);
+	// Delete invoice
+	else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->supprimer) {
+		$result = $object->fetch($id);
+		$object->fetch_thirdparty();
+
+		$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: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
+			header('Location: ' . DOL_URL_ROOT . '/compta/facture/list.php');
 			exit();
 		} else {
 			setEventMessage($object->error, 'errors');
+			$action='';
 		}
 	}
-}
-
-// Delete invoice
-else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->supprimer) {
-	$result = $object->fetch($id);
-	$object->fetch_thirdparty();
 
-	$idwarehouse = GETPOST('idwarehouse');
+	// Delete line
+	else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->facture->creer) {
+		$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);
+		$result = $object->deleteline($_GET ['lineid'], $user);
+		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
+				$result = facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+			}
+			if ($result >= 0) {
+				header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
+				exit();
+			}
+		} else {
+			setEventMessage($object->error, 'errors');
+			$action = '';
+		}
 	}
 
-	$result = $object->delete(0, 0, $idwarehouse);
-	if ($result > 0) {
-		header('Location: ' . DOL_URL_ROOT . '/compta/facture/list.php');
-		exit();
-	} else {
-		setEventMessage($object->error, 'errors');
-		$action='';
+	// 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();
 	}
-}
 
-// Delete line
-else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->facture->creer) {
-	$object->fetch($id);
-	$object->fetch_thirdparty();
+	// Validation
+	else if ($action == 'valid' && $user->rights->facture->creer) {
+		$object->fetch($id);
 
-	$result = $object->deleteline($_GET ['lineid'], $user);
-	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
-			$result = facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-		}
-		if ($result >= 0) {
-			header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
-			exit();
+		// On verifie signe facture
+		if ($object->type == Facture::TYPE_CREDIT_NOTE) {
+			// 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 {
-		setEventMessage($object->error, 'errors');
-		$action = '';
 	}
-}
-
-// 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();
-}
 
-// Validation
-else if ($action == 'valid' && $user->rights->facture->creer) {
-	$object->fetch($id);
+	else if ($action == 'set_thirdparty' && $user->rights->facture->creer) {
+		$object->fetch($id);
+		$object->setValueFrom('fk_soc', $socid);
 
-	// On verifie signe facture
-	if ($object->type == Facture::TYPE_CREDIT_NOTE) {
-		// 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 = '';
-		}
+		header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
+		exit();
 	}
-}
 
-else if ($action == 'set_thirdparty' && $user->rights->facture->creer) {
-	$object->fetch($id);
-	$object->setValueFrom('fk_soc', $socid);
+	else if ($action == 'classin' && $user->rights->facture->creer) {
+		$object->fetch($id);
+		$object->setProject($_POST['projectid']);
+	}
 
-	header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
-	exit();
-}
+	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);
+	}
 
-else if ($action == 'classin' && $user->rights->facture->creer) {
-	$object->fetch($id);
-	$object->setProject($_POST['projectid']);
-}
+	else if ($action == 'setinvoicedate' && $user->rights->facture->creer)
+	{
+		$object->fetch($id);
+		$old_date_lim_reglement = $object->date_lim_reglement;
+		$date = dol_mktime(12, 0, 0, $_POST['invoicedatemonth'], $_POST['invoicedateday'], $_POST['invoicedateyear']);
+		if (empty($date))
+		{
+		    setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
+		    header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id.'&action=editinvoicedate');
+		    exit;
+		}
+	    $object->date=$date;
+		$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 == '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);
-}
+	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);
 
-else if ($action == 'setinvoicedate' && $user->rights->facture->creer)
-{
-	$object->fetch($id);
-	$old_date_lim_reglement = $object->date_lim_reglement;
-	$date = dol_mktime(12, 0, 0, $_POST['invoicedatemonth'], $_POST['invoicedateday'], $_POST['invoicedateyear']);
-	if (empty($date))
-	{
-	    setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
-	    header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id.'&action=editinvoicedate');
-	    exit;
-	}
-    $object->date=$date;
-	$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);
-}
+		$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 == '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);
-}
+	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);
+	}
 
-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');
+	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);
 	}
-	$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);
-}
+	else if ($action == 'setremisepercent' && $user->rights->facture->creer) {
+		$object->fetch($id);
+		$result = $object->set_remise($user, $_POST['remise_percent']);
+	}
 
-else if ($action == 'setremisepercent' && $user->rights->facture->creer) {
-	$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"]);
 
-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"]);
+			$result = $discount->link_to_invoice(0, $id);
 			if ($result < 0) {
-				$mesgs [] = '<div class="error">' . $object->error . '</div>';
+				$mesgs [] = '<div class="error">' . $discount->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']);
 	}
-}
-
-else if ($action == 'set_ref_client' && $user->rights->facture->creer) {
-	$object->fetch($id);
-	$object->set_ref_client($_POST['ref_client']);
-}
 
-// Classify to validated
-else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider)
-{
-	$idwarehouse = GETPOST('idwarehouse');
+	// Classify to validated
+	else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider)
+	{
+		$idwarehouse = GETPOST('idwarehouse');
 
-	$object->fetch($id);
-	$object->fetch_thirdparty();
+		$object->fetch($id);
+		$object->fetch_thirdparty();
 
-	// Check parameters
+		// Check parameters
 
-	// Check for mandatory prof id
-	for($i = 1; $i < 6; $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 ++;
+		// Check for mandatory prof id
+		for($i = 1; $i < 6; $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');
+				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);
-	}
+		$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 != Facture::TYPE_DEPOSIT && ! 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 = '';
+		// Check for warehouse
+		if ($object->type != Facture::TYPE_DEPOSIT && ! 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)
+		if (! $error)
 		{
-			// 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);
+			$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 {
+				if (count($object->errors)) setEventMessage($object->errors, 'errors');
+				else setEventMessage($object->error, 'errors');
 			}
-		} else {
-			if (count($object->errors)) setEventMessage($object->errors, 'errors');
-			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');
+	// 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();
+		$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);
-	}
+		$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 != Facture::TYPE_DEPOSIT && ! 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 = '';
+		// Check parameters
+		if ($object->type != Facture::TYPE_DEPOSIT && ! 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;
+		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);
+			$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 ++;
+				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) {
+				$result=$object->set_draft($user, $idwarehouse);
+				if ($result<0) setEventMessage($object->error,'errors');
+
+				// 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);
+		if ($result<0) setEventMessage($object->error,'errors');
+	} // 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);
+			if ($result<0) setEventMessage($object->error,'errors');
+		} 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);
+			if ($result<0) setEventMessage($object->error,'errors');
 		} else {
-			dol_print_error($db, '');
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), 'errors');
 		}
+	}
 
-		$resteapayer = $object->total_ttc - $totalpaye;
+	// Convertir en reduc
+	else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer)
+	{
+		$object->fetch($id);
+		$object->fetch_thirdparty();
+		//$object->fetch_lines();	// Already done into fetch
 
-		// On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
-		$ventilExportCompta = $object->getVentilExportCompta();
+		// Check if there is already a discount (protection to avoid duplicate creation when resubmit post)
+		$discountcheck=new DiscountAbsolute($db);
+		$result=$discountcheck->fetch(0,$object->id);
 
-		// On verifie si aucun paiement n'a ete effectue
-		if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) {
-			$result=$object->set_draft($user, $idwarehouse);
-			if ($result<0) setEventMessage($object->error,'errors');
+		$canconvert=0;
+		if ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 1 && empty($discountcheck->id)) $canconvert=1;	// we can convert deposit into discount if deposit is payed completely and not already converted (see real condition into condition used to show button converttoreduc)
+		if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1;	// we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc)
+		if ($canconvert)
+		{
+			$db->begin();
 
-			// 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);
+			// 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 ++;
 			}
-			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);
+
+			// Insert one discount by VAT rate category
+			$discount = new DiscountAbsolute($db);
+			if ($object->type == Facture::TYPE_CREDIT_NOTE)
+				$discount->description = '(CREDIT_NOTE)';
+			elseif ($object->type == Facture::TYPE_DEPOSIT)
+				$discount->description = '(DEPOSIT)';
+			else {
+				setEventMessage($langs->trans('CantConvertToReducAnInvoiceOfThisType'),'errors');
+			}
+			$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 (empty($error))
+			{
+				// Classe facture
+				$result = $object->set_paid($user);
+				if ($result >= 0)
+				{
+					//$mesgs[]='OK'.$discount->id;
+					$db->commit();
+				}
+				else
+				{
+					setEventMessage($object->error,'errors');
+					$db->rollback();
+				}
+			}
+			else
+			{
+				setEventMessage($discount->error,'errors');
+				$db->rollback();
 			}
 		}
 	}
-}
-
-// Classify "paid"
-else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement) {
-	$object->fetch($id);
-	$result = $object->set_paid($user);
-	if ($result<0) setEventMessage($object->error,'errors');
-} // 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);
-		if ($result<0) setEventMessage($object->error,'errors');
-	} 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);
-		if ($result<0) setEventMessage($object->error,'errors');
-	} else {
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), 'errors');
-	}
-}
 
-// Convertir en reduc
-else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer)
-{
-	$object->fetch($id);
-	$object->fetch_thirdparty();
-	//$object->fetch_lines();	// Already done into fetch
-
-	// Check if there is already a discount (protection to avoid duplicate creation when resubmit post)
-	$discountcheck=new DiscountAbsolute($db);
-	$result=$discountcheck->fetch(0,$object->id);
-
-	$canconvert=0;
-	if ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 1 && empty($discountcheck->id)) $canconvert=1;	// we can convert deposit into discount if deposit is payed completely and not already converted (see real condition into condition used to show button converttoreduc)
-	if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1;	// we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc)
-	if ($canconvert)
+	/*
+	 * Insert new invoice in database
+	*/
+	else if ($action == 'add' && $user->rights->facture->creer)
 	{
+		if ($socid > 0) $object->socid = GETPOST('socid', 'int');
+
 		$db->begin();
 
-		// 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 ++;
-		}
+		$error = 0;
 
-		// Insert one discount by VAT rate category
-		$discount = new DiscountAbsolute($db);
-		if ($object->type == Facture::TYPE_CREDIT_NOTE)
-			$discount->description = '(CREDIT_NOTE)';
-		elseif ($object->type == Facture::TYPE_DEPOSIT)
-			$discount->description = '(DEPOSIT)';
-		else {
-			setEventMessage($langs->trans('CantConvertToReducAnInvoiceOfThisType'),'errors');
-		}
-		$discount->tva_tx = abs($object->total_ttc);
-		$discount->fk_soc = $object->socid;
-		$discount->fk_facture_source = $object->id;
+		// Fill array 'array_options' with data from add form
+		$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
+		$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
+		if ($ret < 0) $error ++;
 
-		$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)
+			// Replacement invoice
+		if ($_POST['type'] == Facture::TYPE_REPLACEMENT)
+		{
+			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			if (empty($dateinvoice))
 			{
 				$error++;
-				break;
+				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				= $dateinvoice;
+				$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 = Facture::TYPE_REPLACEMENT;
+
+				$id = $object->createFromCurrent($user);
+				if ($id <= 0)
+					$mesgs [] = $object->error;
 			}
 		}
 
-		if (empty($error))
+		// Credit note invoice
+		if ($_POST['type'] == Facture::TYPE_CREDIT_NOTE)
 		{
-			// Classe facture
-			$result = $object->set_paid($user);
-			if ($result >= 0)
+			if (! ($_POST['fac_avoir'] > 0))
 			{
-				//$mesgs[]='OK'.$discount->id;
-				$db->commit();
+				$error ++;
+				setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CorrectInvoice")), 'errors');
 			}
-			else
+
+			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			if (empty($dateinvoice))
 			{
-				setEventMessage($object->error,'errors');
-				$db->rollback();
+				$error ++;
+				setEventMessage($langs->trans("ErrorFieldRequired", $langs->trans("Date")), 'errors');
 			}
-		}
-		else
-		{
-			setEventMessage($discount->error,'errors');
-			$db->rollback();
-		}
-	}
-}
 
-/*
- * Insert new invoice in database
-*/
-else if ($action == 'add' && $user->rights->facture->creer)
-{
-	if ($socid > 0) $object->socid = GETPOST('socid', 'int');
+			if (! $error)
+			{
+				$object->socid				= GETPOST('socid','int');
+				$object->number				= $_POST['facnumber'];
+				$object->date				= $dateinvoice;
+				$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 = Facture::TYPE_CREDIT_NOTE;
 
-	$db->begin();
+				$id = $object->create($user);
 
-	$error = 0;
+				if (GETPOST('invoiceAvoirWithLines', 'int')==1 && $id>0)
+				{
+	                $facture_source = new Facture($db); // fetch origin object
+	                if ($facture_source->fetch($object->fk_facture_source)>0)
+	                {
 
-	// Fill array 'array_options' with data from add form
-	$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
-	$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
-	if ($ret < 0) $error ++;
+	                    foreach($facture_source->lines as $line)
+	                    {
+	                        $line->fk_facture = $object->id;
 
-		// Replacement invoice
-	if ($_POST['type'] == Facture::TYPE_REPLACEMENT)
-	{
-		$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-		if (empty($dateinvoice))
-		{
-			$error++;
-			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
-		}
+	                        $line->subprice =-$line->subprice; // invert price for object
+	                        $line->pa_ht = -$line->pa_ht;
+	                        $line->total_ht=-$line->total_ht;
+	                        $line->total_tva=-$line->total_tva;
+	                        $line->total_ttc=-$line->total_ttc;
+	                        $line->total_localtax1=-$line->total_localtax1;
+	                        $line->total_localtax2=-$line->total_localtax2;
 
-		if (! ($_POST['fac_replacement'] > 0)) {
-			$error ++;
-			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), 'errors');
-		}
+	                        $line->insert();
 
-		if (! $error) {
-			// This is a replacement invoice
-			$result = $object->fetch($_POST['fac_replacement']);
-			$object->fetch_thirdparty();
+	                        $object->lines[] = $line; // insert new line in current object
+	                    }
 
-			$object->date				= $dateinvoice;
-			$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'];
+	                    $object->update_price(1);
+	                }
 
-			// Proprietes particulieres a facture de remplacement
-			$object->fk_facture_source = $_POST['fac_replacement'];
-			$object->type = Facture::TYPE_REPLACEMENT;
+				}
 
-			$id = $object->createFromCurrent($user);
-			if ($id <= 0)
-				$mesgs [] = $object->error;
-		}
-	}
+	            if(GETPOST('invoiceAvoirWithPaymentRestAmount', 'int')==1 && $id>0) {
 
-	// Credit note invoice
-	if ($_POST['type'] == Facture::TYPE_CREDIT_NOTE)
-	{
-		if (! ($_POST['fac_avoir'] > 0))
-		{
-			$error ++;
-			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CorrectInvoice")), 'errors');
-		}
+	                $facture_source = new Facture($db); // fetch origin object if not previously defined
+	                if($facture_source->fetch($object->fk_facture_source)>0) {
+	                    $totalpaye = $facture_source->getSommePaiement();
+	                    $totalcreditnotes = $facture_source->getSumCreditNotesUsed();
+	                    $totaldeposits = $facture_source->getSumDepositsUsed();
+	                    $remain_to_pay = abs($facture_source->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits);
 
-		$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-		if (empty($dateinvoice))
-		{
-			$error ++;
-			setEventMessage($langs->trans("ErrorFieldRequired", $langs->trans("Date")), 'errors');
+	                    $object->addline($langs->trans('invoiceAvoirLineWithPaymentRestAmount'),$remain_to_pay,1,0,0,0,0,0,'','','TTC');
+	                }
+	            }
+
+				// Add predefined lines
+				/*
+	             TODO delete
+	             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($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);
+					}
+				}*/
+			}
 		}
 
-		if (! $error)
+		// Standard invoice or Deposit invoice created from a Predefined invoice
+		if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0)
 		{
-			$object->socid				= GETPOST('socid','int');
-			$object->number				= $_POST['facnumber'];
-			$object->date				= $dateinvoice;
-			$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 = Facture::TYPE_CREDIT_NOTE;
-
-			$id = $object->create($user);
-
-			if (GETPOST('invoiceAvoirWithLines', 'int')==1 && $id>0)
+			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			if (empty($dateinvoice))
 			{
-                $facture_source = new Facture($db); // fetch origin object
-                if ($facture_source->fetch($object->fk_facture_source)>0)
-                {
-
-                    foreach($facture_source->lines as $line)
-                    {
-                        $line->fk_facture = $object->id;
-
-                        $line->subprice =-$line->subprice; // invert price for object
-                        $line->pa_ht = -$line->pa_ht;
-                        $line->total_ht=-$line->total_ht;
-                        $line->total_tva=-$line->total_tva;
-                        $line->total_ttc=-$line->total_ttc;
-                        $line->total_localtax1=-$line->total_localtax1;
-                        $line->total_localtax2=-$line->total_localtax2;
-
-                        $line->insert();
-
-                        $object->lines[] = $line; // insert new line in current object
-                    }
-
-                    $object->update_price(1);
-                }
-
-			}
-
-            if(GETPOST('invoiceAvoirWithPaymentRestAmount', 'int')==1 && $id>0) {
-
-                $facture_source = new Facture($db); // fetch origin object if not previously defined
-                if($facture_source->fetch($object->fk_facture_source)>0) {
-                    $totalpaye = $facture_source->getSommePaiement();
-                    $totalcreditnotes = $facture_source->getSumCreditNotesUsed();
-                    $totaldeposits = $facture_source->getSumDepositsUsed();
-                    $remain_to_pay = abs($facture_source->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits);
-
-                    $object->addline($langs->trans('invoiceAvoirLineWithPaymentRestAmount'),$remain_to_pay,1,0,0,0,0,0,'','','TTC');
-                }
-            }
-
-			// Add predefined lines
-			/*
-             TODO delete
-             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($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);
-				}
-			}*/
-		}
-	}
+				$error++;
+				setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
+			}
 
-	// Standard invoice or Deposit invoice created from a Predefined invoice
-	if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0)
-	{
-		$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-		if (empty($dateinvoice))
-		{
-			$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           = $dateinvoice;
+				$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);
+			}
 		}
 
-		if (! $error)
+		// Standard or deposit or proforma invoice
+		if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0)
 		{
-			$object->socid			= GETPOST('socid','int');
-			$object->type           = $_POST['type'];
-			$object->number         = $_POST['facnumber'];
-			$object->date           = $dateinvoice;
-			$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'];
+			if (GETPOST('socid', 'int') < 1)
+			{
+				$error ++;
+				setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors');
+			}
 
-			// Source facture
-			$object->fac_rec = $_POST['fac_rec'];
+			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			if (empty($dateinvoice))
+			{
+				$error++;
+				setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
+			}
 
-			$id = $object->create($user);
-		}
-	}
+			if (! $error)
+			{
+				// Si facture standard
+				$object->socid				= GETPOST('socid','int');
+				$object->type				= GETPOST('type');
+				$object->number				= $_POST['facnumber'];
+				$object->date				= $dateinvoice;
+				$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];
+					}
 
-	// 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');
-		}
+					// 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';
+					}
 
-		$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-		if (empty($dateinvoice))
-		{
-			$error++;
-			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
-		}
+					$object->origin = $_POST['origin'];
+					$object->origin_id = $_POST['originid'];
 
-		if (! $error)
-		{
-			// Si facture standard
-			$object->socid				= GETPOST('socid','int');
-			$object->type				= GETPOST('type');
-			$object->number				= $_POST['facnumber'];
-			$object->date				= $dateinvoice;
-			$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'];
+					// 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']);
+					}
 
-			$object->fetch_thirdparty();
+					$id = $object->create($user);
 
-			// 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];
-				}
+					if ($id > 0)
+					{
+						// If deposit invoice
+						if ($_POST['type'] == 3)
+						{
+							$typeamount = GETPOST('typedeposit', 'alpha');
+							$valuedeposit = GETPOST('valuedeposit', 'int');
 
-				// 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';
-				}
+							if ($typeamount == 'amount')
+							{
+								$amountdeposit = $valuedeposit;
+							}
+							else
+							{
+								$amountdeposit = 0;
 
-				$object->origin = $_POST['origin'];
-				$object->origin_id = $_POST['originid'];
+								dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
 
-				// 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']);
-				}
+								$classname = ucfirst($subelement);
+								$srcobject = new $classname($db);
 
-				$id = $object->create($user);
+								dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add deposit lines");
+								$result = $srcobject->fetch($object->origin_id);
+								if ($result > 0)
+								{
+									$totalamount = 0;
+									$lines = $srcobject->lines;
+									$numlines=count($lines);
+									for ($i=0; $i<$numlines; $i++)
+									{
+										$qualified=1;
+										if (empty($lines[$i]->qty)) $qualified=0;	// We discard qty=0, it is an option
+										if (! empty($lines[$i]->special_code)) $qualified=0;	// We discard special_code (frais port, ecotaxe, option, ...)
+										if ($qualified) $totalamount += $lines[$i]->total_ht;
+									}
 
-				if ($id > 0)
-				{
-					// If deposit invoice
-					if ($_POST['type'] == 3)
-					{
-						$typeamount = GETPOST('typedeposit', 'alpha');
-						$valuedeposit = GETPOST('valuedeposit', 'int');
+									if ($totalamount != 0) {
+										$amountdeposit = ($totalamount * $valuedeposit) / 100;
+									}
+								} else {
+									$mesgs [] = $srcobject->error;
+									$error ++;
+								}
+							}
 
-						if ($typeamount == 'amount')
-						{
-							$amountdeposit = $valuedeposit;
+							$result = $object->addline(
+									$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
 						{
-							$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 lines");
+							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)
 							{
-								$totalamount = 0;
 								$lines = $srcobject->lines;
-								$numlines=count($lines);
-								for ($i=0; $i<$numlines; $i++)
+								if (empty($lines) && method_exists($srcobject, 'fetch_lines'))
 								{
-									$qualified=1;
-									if (empty($lines[$i]->qty)) $qualified=0;	// We discard qty=0, it is an option
-									if (! empty($lines[$i]->special_code)) $qualified=0;	// We discard special_code (frais port, ecotaxe, option, ...)
-									if ($qualified) $totalamount += $lines[$i]->total_ht;
+									$srcobject->fetch_lines();
+									$lines = $srcobject->lines;
 								}
 
-								if ($totalamount != 0) {
-									$amountdeposit = ($totalamount * $valuedeposit) / 100;
+								$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;
+										}
+
+										// Extrafields
+										if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines [$i], 'fetch_optionals')) {
+											$lines [$i]->fetch_optionals($lines [$i]->rowid);
+											$array_option = $lines [$i]->array_options;
+										}
+
+										$result = $object->addline($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, $array_option);
+
+										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 ++;
 							}
 						}
-
-						$result = $object->addline(
-								$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 {
+						$mesgs [] = $object->error;
+						$error ++;
 					}
-					else
-					{
+				} 			// 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($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);
+						}
+					}
+				}
+			}
+		}
 
-						dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
+		// 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>';
+		}
+	}
 
-						$classname = ucfirst($subelement);
-						$srcobject = new $classname($db);
+	// Add a new line
+	else if ($action == 'addline' && $user->rights->facture->creer)
+	{
+		$langs->load('errors');
+		$error = 0;
 
-						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'))
-							{
-								$srcobject->fetch_lines();
-								$lines = $srcobject->lines;
-							}
+		// Set if we used free entry or predefined product
+		$predef='';
+		$product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
+		$price_ht = GETPOST('price_ht');
+		if (GETPOST('prod_entry_mode') == 'free')
+		{
+			$idprod=0;
+			$tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
+		}
+		else
+		{
+			$idprod=GETPOST('idprod', 'int');
+			$tva_tx = '';
+		}
+
+		$qty = GETPOST('qty' . $predef);
+		$remise_percent = GETPOST('remise_percent' . $predef);
+
+		// Extrafields
+		$extrafieldsline = new ExtraFields($db);
+		$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
+		$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
+		// Unset extrafield
+		if (is_array($extralabelsline)) {
+			// Get extra fields
+			foreach ($extralabelsline as $key => $value) {
+				unset($_POST["options_" . $key . $predef]);
+			}
+		}
 
-							$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 (empty($idprod) && ($price_ht < 0) && ($qty < 0)) {
+			setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors');
+			$error ++;
+		}
+		if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) {
+			setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors');
+			$error ++;
+		}
+		if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) 	// Unit price can be 0 but not ''
+		{
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors');
+			$error ++;
+		}
+		if ($qty == '') {
+			setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors');
+			$error ++;
+		}
+		if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) {
+			setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors');
+			$error ++;
+		}
 
-								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;
-									}
+		if (! $error && ($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();
 
-									// Extrafields
-									if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines [$i], 'fetch_optionals')) {
-										$lines [$i]->fetch_optionals($lines [$i]->rowid);
-										$array_option = $lines [$i]->array_options;
-									}
+			// Clean parameters
+			$date_start = dol_mktime(GETPOST('date_start' . $predef . 'hour'), GETPOST('date_start' . $predef . 'min'), GETPOST('date_start' . $predef . 'sec'), GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year'));
+			$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');
 
-									$result = $object->addline($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, $array_option);
+			// Define special_code for special lines
+			$special_code = 0;
+			// if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices
 
-									if ($result > 0) {
-										$lineid = $result;
-									} else {
-										$lineid = 0;
-										$error ++;
-										break;
-									}
+			// 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);
 
-									// Defined the new fk_parent_line
-									if ($result > 0 && $lines [$i]->product_type == 9) {
-										$fk_parent_line = $result;
-									}
-								}
-							}
+				$label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
 
-							// 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 ++;
+				// Update if prices fields are defined
+					$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];
+						if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level];
+						if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level];
+					}
+					elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
+					{
+						require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
+
+						$prodcustprice = new Productcustomerprice($db);
+
+						$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
+
+						$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
+						if ($result >= 0) {
+							if (count($prodcustprice->lines) > 0) {
+								$found = true;
+								$pu_ht = price($prodcustprice->lines[0]->price);
+								$pu_ttc = price($prodcustprice->lines[0]->price_ttc);
+								$price_base_type = $prodcustprice->lines[0]->price_base_type;
+								$prod->tva_tx = $prodcustprice->lines[0]->tva_tx;
+							}else {
+								$pu_ht = $prod->price;
+								$pu_ttc = $prod->price_ttc;
+								$price_min = $prod->price_min;
+								$price_base_type = $prod->price_base_type;
+							}
 						} else {
-							$mesgs [] = $srcobject->error;
-							$error ++;
+							setEventMessage($prodcustprice->error,'errors');
 						}
 					}
-				} 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($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);
+					else
+					{
+						$pu_ht = $prod->price;
+						$pu_ttc = $prod->price_ttc;
+						$price_min = $prod->price_min;
+						$price_base_type = $prod->price_base_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' && $user->rights->facture->creer)
-{
-	$langs->load('errors');
-	$error = 0;
-
-	// Set if we used free entry or predefined product
-	$predef='';
-	$product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
-	$price_ht = GETPOST('price_ht');
-	if (GETPOST('prod_entry_mode') == 'free')
-	{
-		$idprod=0;
-		$tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
-	}
-	else
-	{
-		$idprod=GETPOST('idprod', 'int');
-		$tva_tx = '';
-	}
-
-	$qty = GETPOST('qty' . $predef);
-	$remise_percent = GETPOST('remise_percent' . $predef);
-
-	// Extrafields
-	$extrafieldsline = new ExtraFields($db);
-	$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
-	$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
-	// Unset extrafield
-	if (is_array($extralabelsline)) {
-		// Get extra fields
-		foreach ($extralabelsline as $key => $value) {
-			unset($_POST["options_" . $key . $predef]);
-		}
-	}
-
-	if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) {
-		setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors');
-		$error ++;
-	}
-	if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) {
-		setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors');
-		$error ++;
-	}
-	if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) 	// Unit price can be 0 but not ''
-	{
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors');
-		$error ++;
-	}
-	if ($qty == '') {
-		setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors');
-		$error ++;
-	}
-	if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) {
-		setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors');
-		$error ++;
-	}
 
-	if (! $error && ($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();
+					// if price ht is forced (ie: calculated by margin rate and cost price)
+					if (! empty($price_ht)) {
+						$pu_ht = price2num($price_ht, 'MU');
+						$pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
+					}
 
-		// Clean parameters
-		$date_start = dol_mktime(GETPOST('date_start' . $predef . 'hour'), GETPOST('date_start' . $predef . 'min'), GETPOST('date_start' . $predef . 'sec'), GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year'));
-		$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
-				$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];
-					if (isset($prod->multiprices_tva_tx[$object->client->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->client->price_level];
-					if (isset($prod->multiprices_recuperableonly[$object->client->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->client->price_level];
-				}
-				elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
-				{
-					require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
-
-					$prodcustprice = new Productcustomerprice($db);
-
-					$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
-
-					$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
-					if ($result >= 0) {
-						if (count($prodcustprice->lines) > 0) {
-							$found = true;
-							$pu_ht = price($prodcustprice->lines[0]->price);
-							$pu_ttc = price($prodcustprice->lines[0]->price_ttc);
-							$price_base_type = $prodcustprice->lines[0]->price_base_type;
-							$prod->tva_tx = $prodcustprice->lines[0]->tva_tx;
-						}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).
+					elseif ($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');
 						}
-					} else {
-						setEventMessage($prodcustprice->error,'errors');
 					}
-				}
-				else
-				{
-					$pu_ht = $prod->price;
-					$pu_ttc = $prod->price_ttc;
-					$price_min = $prod->price_min;
-					$price_base_type = $prod->price_base_type;
-				}
 
-				// if price ht is forced (ie: calculated by margin rate and cost price)
-				if (! empty($price_ht)) {
-					$pu_ht = price2num($price_ht, 'MU');
-					$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);
+						}
 
-				// 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).
-				elseif ($tva_tx != $prod->tva_tx) {
-					if ($price_base_type != 'HT') {
-						$pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU');
+						$desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
 					} else {
-						$pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
+						$desc = $prod->description;
 					}
-				}
 
-				$desc = '';
+					$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);
+					}
 
-				// 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);
+				$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 = price2num(GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
+			$buyingprice = price2num(GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : '');
+
+			// 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($remise_percent) / 100) < price2num($price_min))) {
+				$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
+				setEventMessage($mesg, 'errors');
+			} else {
+				// Insert line
+				$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $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, $array_option);
+
+				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);
 					}
 
-					$desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
+					unset($_POST ['prod_entry_mode']);
+
+					unset($_POST['qty']);
+					unset($_POST['type']);
+					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']);
+					unset($_POST['np_marginRate']);
+					unset($_POST['np_markRate']);
+					unset($_POST['dp_desc']);
+					unset($_POST['idprod']);
+
+			        unset($_POST['date_starthour']);
+			        unset($_POST['date_startmin']);
+			        unset($_POST['date_startsec']);
+			        unset($_POST['date_startday']);
+			        unset($_POST['date_startmonth']);
+			        unset($_POST['date_startyear']);
+			        unset($_POST['date_endhour']);
+			        unset($_POST['date_endmin']);
+			        unset($_POST['date_endsec']);
+			        unset($_POST['date_endday']);
+			        unset($_POST['date_endmonth']);
+			        unset($_POST['date_endyear']);
 				} 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);
+					setEventMessage($object->error, 'errors');
 				}
 
-			$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');
+				$action = '';
+			}
 		}
+	}
 
-		// Margin
-		$fournprice = price2num(GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
-		$buyingprice = price2num(GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : '');
-
-		// Local Taxes
-		$localtax1_tx = get_localtax($tva_tx, 1, $object->client);
-		$localtax2_tx = get_localtax($tva_tx, 2, $object->client);
+	elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel')) {
+		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 ($tva_npr)
+		if (preg_match('/\*/', $vat_rate))
 			$info_bits |= 0x01;
 
-		if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) {
-			$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
-			setEventMessage($mesg, 'errors');
+			// 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 = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : '');
+		$buyingprice = price2num(GETPOST('buying_price') ? GETPOST('buying_price') : '');
+
+		// Extrafields
+		$extrafieldsline = new ExtraFields($db);
+		$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
+		$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline);
+		// Unset extrafield
+		if (is_array($extralabelsline)) {
+			// Get extra fields
+			foreach ($extralabelsline as $key => $value) {
+				unset($_POST["options_" . $key]);
+			}
+		}
+
+		// 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') : '');
+
+			// Check price is not lower than minimum (check is done only for standard or replacement invoices)
+			if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) {
+				setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors');
+				$error ++;
+			}
 		} else {
-			// Insert line
-			$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $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, $array_option);
+			$type = GETPOST('type');
+			$label = (GETPOST('product_label') ? GETPOST('product_label') : '');
 
-			if ($result > 0) {
+			// 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, 0, $array_option);
+
+			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 = '';
+					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);
@@ -1285,10 +1418,9 @@ else if ($action == 'addline' && $user->rights->facture->creer)
 					facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 				}
 
-				unset($_POST ['prod_entry_mode']);
-
 				unset($_POST['qty']);
 				unset($_POST['type']);
+				unset($_POST['productid']);
 				unset($_POST['remise_percent']);
 				unset($_POST['price_ht']);
 				unset($_POST['price_ttc']);
@@ -1298,515 +1430,386 @@ else if ($action == 'addline' && $user->rights->facture->creer)
 				unset($_POST['product_desc']);
 				unset($_POST['fournprice']);
 				unset($_POST['buying_price']);
-				unset($_POST['np_marginRate']);
-				unset($_POST['np_markRate']);
-				unset($_POST['dp_desc']);
-				unset($_POST['idprod']);
-
-		    	unset($_POST['date_starthour']);
-		    	unset($_POST['date_startmin']);
-		    	unset($_POST['date_startsec']);
-		    	unset($_POST['date_startday']);
-		    	unset($_POST['date_startmonth']);
-		    	unset($_POST['date_startyear']);
-		    	unset($_POST['date_endhour']);
-		    	unset($_POST['date_endmin']);
-		    	unset($_POST['date_endsec']);
-		    	unset($_POST['date_endday']);
-		    	unset($_POST['date_endmonth']);
-		    	unset($_POST['date_endyear']);
 			} else {
 				setEventMessage($object->error, 'errors');
 			}
-
-			$action = '';
 		}
 	}
-}
-
-elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel')) {
-	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 = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : '');
-	$buyingprice = price2num(GETPOST('buying_price') ? GETPOST('buying_price') : '');
-
-	// Extrafields
-	$extrafieldsline = new ExtraFields($db);
-	$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
-	$array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline);
-	// Unset extrafield
-	if (is_array($extralabelsline)) {
-		// Get extra fields
-		foreach ($extralabelsline as $key => $value) {
-			unset($_POST["options_" . $key]);
-		}
-	}
-
-	// 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') : '');
-
-		// Check price is not lower than minimum (check is done only for standard or replacement invoices)
-		if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) {
-			setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $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 ++;
-		}
+	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();
 	}
 
-	// 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, 0, $array_option);
-
-		if ($result >= 0) {
-			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-				// 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);
-				}
+	// Modify line position (up)
+	else if ($action == 'up' && $user->rights->facture->creer) {
+		$object->fetch($id);
+		$object->fetch_thirdparty();
+		$object->line_up($_GET ['rowid']);
 
-				$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['productid']);
-			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']);
-		} else {
-			setEventMessage($object->error, 'errors');
+		// 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);
 
-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=' . $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']);
 
-// 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();
-} // 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();
-}
+		// 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);
 
-// Link invoice to order
-if (GETPOST('linkedOrder')) {
-	$object->fetch($id);
-	$object->fetch_thirdparty();
-	$result = $object->add_object_linked('commande', GETPOST('linkedOrder'));
-}
+		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';
+	// Link invoice to order
+	if (GETPOST('linkedOrder')) {
+		$object->fetch($id);
+		$object->fetch_thirdparty();
+		$result = $object->add_object_linked('commande', GETPOST('linkedOrder'));
+	}
 
-	// Set tmp user directory
-	$vardir = $conf->user->dir_output . "/" . $user->id;
-	$upload_dir_tmp = $vardir . '/temp';
+	/*
+	 * Add file in email form
+	 */
+	if (GETPOST('addfile')) {
+		require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
 
-	dol_add_file_process($upload_dir_tmp, 0, 0);
-	$action = 'presend';
-}
+		// Set tmp user directory
+		$vardir = $conf->user->dir_output . "/" . $user->id;
+		$upload_dir_tmp = $vardir . '/temp';
 
-/*
- * Remove file in email form
- */
-if (! empty($_POST['removedfile'])) {
-	require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
+		dol_add_file_process($upload_dir_tmp, 0, 0);
+		$action = 'presend';
+	}
 
-	// Set tmp user directory
-	$vardir = $conf->user->dir_output . "/" . $user->id;
-	$upload_dir_tmp = $vardir . '/temp';
+	/*
+	 * Remove file in email form
+	 */
+	if (! empty($_POST['removedfile'])) {
+		require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
 
-	// TODO Delete only files that was uploaded from email form
-	dol_remove_file_process($_POST['removedfile'], 0);
-	$action = 'presend';
-}
+		// Set tmp user directory
+		$vardir = $conf->user->dir_output . "/" . $user->id;
+		$upload_dir_tmp = $vardir . '/temp';
 
-/*
- * Send mail
- */
-if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_POST['removedfile'] && ! $_POST['cancel']) {
-	$langs->load('mails');
+		// TODO Delete only files that was uploaded from email form
+		dol_remove_file_process($_POST['removedfile'], 0);
+		$action = 'presend';
+	}
 
-	$actiontypecode = '';
-	$subject = '';
-	$actionmsg = '';
-	$actionmsg2 = '';
+	/*
+	 * Send mail
+	 */
+	if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_POST['removedfile'] && ! $_POST['cancel']) {
+		$langs->load('mails');
 
-	$result = $object->fetch($id);
-	$result = $object->fetch_thirdparty();
+		$actiontypecode = '';
+		$subject = '';
+		$actionmsg = '';
+		$actionmsg2 = '';
 
-	if ($result > 0) {
-		// $ref = dol_sanitizeFileName($object->ref);
-		// $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf';
+		$result = $object->fetch($id);
+		$result = $object->fetch_thirdparty();
 
-		// 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;
+		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;
-			} else 			// Id du contact
-			{
-				$sendto = $object->client->contact_get_property($_POST['receiver'], 'email');
-				$sendtoid = $_POST['receiver'];
+			} 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");
+			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'];
+				$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;
+				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);
 				}
-				// $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;
+				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);
 				}
-				// $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'];
+				// Create form object
+				include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
+				$formmail = new FormMail($db);
 
-			// 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++;
-						$object->errors = $interface->errors;
-					}
-					// Fin appel triggers
+				$attachedfiles = $formmail->get_attached_files();
+				$filepath = $attachedfiles ['paths'];
+				$filename = $attachedfiles ['names'];
+				$mimetype = $attachedfiles ['mimes'];
 
-					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();
-					}
+				// 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 {
-					$langs->load("other");
-					$mesg = '<div class="error">';
-					if ($mailfile->error) {
-						$mesg .= $langs->trans('ErrorFailedToSendMail', $from, $sendto);
-						$mesg .= '<br>' . $mailfile->error;
+					$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++;
+							$object->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 {
-						$mesg .= 'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
+						$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;
 					}
-					$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('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);
+			$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.');
 		}
-	} 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();
-
-	// Save last template used to generate document
-	if (GETPOST('model'))
-		$object->setDocModel($user, GETPOST('model', 'alpha'));
-	if (GETPOST('fk_bank'))	// this field may come from an external module
-		$object->fk_bank = GETPOST('fk_bank');
-
-	// 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);
+		$action = 'presend';
 	}
-	$result = facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-	if ($result <= 0)
+
+	/*
+	 * Generate document
+	 */
+	else if ($action == 'builddoc') // En get ou en post
 	{
-		dol_print_error($db, $result);
-		exit();
+		$object->fetch($id);
+		$object->fetch_thirdparty();
+
+		// Save last template used to generate document
+		if (GETPOST('model'))
+			$object->setDocModel($user, GETPOST('model', 'alpha'));
+		if (GETPOST('fk_bank'))	// this field may come from an external module
+			$object->fk_bank = GETPOST('fk_bank');
+
+		// 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();
+		}
 	}
-}
 
-// Remove file in doc form
-else if ($action == 'remove_file') {
-	if ($object->fetch($id)) {
-		require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
+	// 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();
+			$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');
+			$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 = '';
+		}
+	}
+
+	// Print file
+	else if ($action == 'print_file' and $user->rights->printipp->read) {
+		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'));
+		setEventMessage($langs->trans("FileWasSentToPrinter", GETPOST('file')));
 		$action = '';
 	}
-}
 
-// Print file
-else if ($action == 'print_file' and $user->rights->printipp->read) {
-	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'));
-	setEventMessage($langs->trans("FileWasSentToPrinter", GETPOST('file')));
-	$action = '';
-}
+	if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) {
+		if ($action == 'addcontact') {
+			$result = $object->fetch($id);
 
-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 && $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();
+			} else {
+				if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
+					$langs->load("errors");
+					$mesgs [] = '<div class="error">' . $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType") . '</div>';
+				} else {
+					$mesgs [] = '<div class="error">' . $object->error . '</div>';
+				}
+			}
 		}
 
-		if ($result >= 0) {
-			header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
-			exit();
-		} else {
-			if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
-				$langs->load("errors");
-				$mesgs [] = '<div class="error">' . $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType") . '</div>';
+		// bascule du statut d'un contact
+		else if ($action == 'swapstatut') {
+			if ($object->fetch($id)) {
+				$result = $object->swapContactStatus(GETPOST('ligne'));
 			} else {
-				$mesgs [] = '<div class="error">' . $object->error . '</div>';
+				dol_print_error($db);
 			}
 		}
-	}
 
-	// bascule du statut d'un contact
-	else if ($action == 'swapstatut') {
-		if ($object->fetch($id)) {
-			$result = $object->swapContactStatus(GETPOST('ligne'));
-		} else {
-			dol_print_error($db);
+		// Efface un contact
+		else if ($action == 'deletecontact') {
+			$object->fetch($id);
+			$result = $object->delete_contact($lineid);
+
+			if ($result >= 0) {
+				header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
+				exit();
+			} else {
+				dol_print_error($db);
+			}
 		}
 	}
 
-	// Efface un contact
-	else if ($action == 'deletecontact') {
-		$object->fetch($id);
-		$result = $object->delete_contact($lineid);
+	if ($action == 'update_extras') {
+		// Fill array 'array_options' with data from add form
+		$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
+		$ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute'));
+		if ($ret < 0)
+			$error ++;
 
-		if ($result >= 0) {
-			header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
-			exit();
-		} else {
-			dol_print_error($db);
+		if (! $error) {
+			// 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('id' => $object->id);
+			$reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by
+			                                                                                      // some hooks
+			if (empty($reshook)) {
+				$result = $object->insertExtraFields();
+				if ($result < 0) {
+					$error ++;
+				}
+			} else if ($reshook < 0)
+				$error ++;
 		}
-	}
-}
 
-if ($action == 'update_extras') {
-	// Fill array 'array_options' with data from add form
-	$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
-	$ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute'));
-	if ($ret < 0)
-		$error ++;
-
-	if (! $error) {
-		// 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('id' => $object->id);
-		$reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by
-		                                                                                      // some hooks
-		if (empty($reshook)) {
-			$result = $object->insertExtraFields();
-			if ($result < 0) {
-				$error ++;
-			}
-		} else if ($reshook < 0)
-			$error ++;
+		if ($error)
+			$action = 'edit_extras';
 	}
-
-	if ($error)
-		$action = 'edit_extras';
 }
 
 
diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php
index 3aafa1c165b..c96ddaa4b9f 100644
--- a/htdocs/compta/paiement.php
+++ b/htdocs/compta/paiement.php
@@ -71,182 +71,184 @@ $hookmanager->initHooks(array('paiementcard'));
 $parameters=array('socid'=>$socid);
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 
-/*
- * Actions
- */
-if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes'))
-{
-    $error = 0;
+if (empty($reshook)) {
 
-    $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
-    $paiement_id = 0;
-    $totalpayment = 0;
-    $atleastonepaymentnotnull = 0;
-
-    // Generate payment array and check if there is payment higher than invoice and payment date before invoice date
-    $tmpinvoice=new Facture($db);
-    foreach ($_POST as $key => $value)
+    /*
+     * Actions
+     */
+    if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes'))
     {
-        if (substr($key,0,7) == 'amount_')
+        $error = 0;
+
+        $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
+        $paiement_id = 0;
+        $totalpayment = 0;
+        $atleastonepaymentnotnull = 0;
+
+        // Generate payment array and check if there is payment higher than invoice and payment date before invoice date
+        $tmpinvoice=new Facture($db);
+        foreach ($_POST as $key => $value)
         {
-            $cursorfacid = substr($key,7);
-            $amounts[$cursorfacid] = price2num(trim(GETPOST($key)));
-            $totalpayment = $totalpayment + $amounts[$cursorfacid];
-            if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++;
-            $result=$tmpinvoice->fetch($cursorfacid);
-            if ($result <= 0) dol_print_error($db);
-            $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement());
-            if ($amounts[$cursorfacid])
+            if (substr($key,0,7) == 'amount_')
             {
-	            // Check amount
-	            if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid])))
-	            {
-	                $addwarning=1;
-	                $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPay")).' '.$langs->trans("HelpPaymentHigherThanReminderToPay");
-	            }
-	            // Check date
-	            if ($datepaye && ($datepaye < $tmpinvoice->date))
-	            {
-	            	$langs->load("errors");
-	                //$error++;
-	                setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings');
-	            }
+                $cursorfacid = substr($key,7);
+                $amounts[$cursorfacid] = price2num(trim(GETPOST($key)));
+                $totalpayment = $totalpayment + $amounts[$cursorfacid];
+                if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++;
+                $result=$tmpinvoice->fetch($cursorfacid);
+                if ($result <= 0) dol_print_error($db);
+                $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement());
+                if ($amounts[$cursorfacid])
+                {
+                    // Check amount
+                    if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid])))
+                    {
+                        $addwarning=1;
+                        $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPay")).' '.$langs->trans("HelpPaymentHigherThanReminderToPay");
+                    }
+                    // Check date
+                    if ($datepaye && ($datepaye < $tmpinvoice->date))
+                    {
+                        $langs->load("errors");
+                        //$error++;
+                        setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings');
+                    }
+                }
+
+                $formquestion[$i++]=array('type' => 'hidden','name' => $key,  'value' => $_POST[$key]);
             }
+        }
 
-            $formquestion[$i++]=array('type' => 'hidden','name' => $key,  'value' => $_POST[$key]);
+        // Check parameters
+        if (! GETPOST('paiementcode'))
+        {
+            setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors');
+            $error++;
         }
-    }
 
-    // Check parameters
-    if (! GETPOST('paiementcode'))
-    {
-        setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors');
-        $error++;
-    }
+        if (! empty($conf->banque->enabled))
+        {
+            // If bank module is on, account is required to enter a payment
+            if (GETPOST('accountid') <= 0)
+            {
+                setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors');
+                $error++;
+            }
+        }
 
-    if (! empty($conf->banque->enabled))
-    {
-        // If bank module is on, account is required to enter a payment
-        if (GETPOST('accountid') <= 0)
+        if (empty($totalpayment) && empty($atleastonepaymentnotnull))
         {
-            setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors');
+            setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors');
             $error++;
         }
-    }
 
-    if (empty($totalpayment) && empty($atleastonepaymentnotnull))
-    {
-        setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors');
-        $error++;
+        if (empty($datepaye))
+        {
+            setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors');
+            $error++;
+        }
     }
 
-    if (empty($datepaye))
+    /*
+     * Action add_paiement
+     */
+    if ($action == 'add_paiement')
     {
-        setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors');
-        $error++;
+        if ($error)
+        {
+            $action = 'create';
+        }
+        // Le reste propre a cette action s'affiche en bas de page.
     }
-}
 
-/*
- * Action add_paiement
- */
-if ($action == 'add_paiement')
-{
-    if ($error)
+    /*
+     * Action confirm_paiement
+     */
+    if ($action == 'confirm_paiement' && $confirm == 'yes')
     {
-        $action = 'create';
-    }
-    // Le reste propre a cette action s'affiche en bas de page.
-}
+        $error=0;
 
-/*
- * Action confirm_paiement
- */
-if ($action == 'confirm_paiement' && $confirm == 'yes')
-{
-    $error=0;
+        $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
 
-    $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
+        $db->begin();
 
-    $db->begin();
-
-    // Clean parameters amount if payment is for a credit note
-    if (GETPOST('type') == 2)
-    {
-	    foreach ($amounts as $key => $value)	// How payment is dispatch
-	    {
-	    	$newvalue = price2num($value,'MT');
-	    	$amounts[$key] = -$newvalue;
-	    }
-    }
+        // Clean parameters amount if payment is for a credit note
+        if (GETPOST('type') == 2)
+        {
+            foreach ($amounts as $key => $value)	// How payment is dispatch
+            {
+                $newvalue = price2num($value,'MT');
+                $amounts[$key] = -$newvalue;
+            }
+        }
 
-    if (! empty($conf->banque->enabled))
-    {
-    	// Si module bank actif, un compte est obligatoire lors de la saisie d'un paiement
-    	if (GETPOST('accountid') <= 0)
-    	{
-    		setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors');
-    		$error++;
-    	}
-    }
+        if (! empty($conf->banque->enabled))
+        {
+            // Si module bank actif, un compte est obligatoire lors de la saisie d'un paiement
+            if (GETPOST('accountid') <= 0)
+            {
+                setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors');
+                $error++;
+            }
+        }
 
-    // Creation of payment line
-    $paiement = new Paiement($db);
-    $paiement->datepaye     = $datepaye;
-    $paiement->amounts      = $amounts;   // Array with all payments dispatching
-    $paiement->paiementid   = dol_getIdFromCode($db,$_POST['paiementcode'],'c_paiement');
-    $paiement->num_paiement = $_POST['num_paiement'];
-    $paiement->note         = $_POST['comment'];
+        // Creation of payment line
+        $paiement = new Paiement($db);
+        $paiement->datepaye     = $datepaye;
+        $paiement->amounts      = $amounts;   // Array with all payments dispatching
+        $paiement->paiementid   = dol_getIdFromCode($db,$_POST['paiementcode'],'c_paiement');
+        $paiement->num_paiement = $_POST['num_paiement'];
+        $paiement->note         = $_POST['comment'];
 
-    if (! $error)
-    {
-    	$paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices')=='on'?1:0));
-    	if ($paiement_id < 0)
+        if (! $error)
         {
-            setEventMessage($paiement->error, 'errors');
-            $error++;
+            $paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices')=='on'?1:0));
+            if ($paiement_id < 0)
+            {
+                setEventMessage($paiement->error, 'errors');
+                $error++;
+            }
         }
-    }
 
-    if (! $error)
-    {
-    	$label='(CustomerInvoicePayment)';
-    	if (GETPOST('type') == 2) $label='(CustomerInvoicePaymentBack)';
-        $result=$paiement->addPaymentToBank($user,'payment',$label,GETPOST('accountid'),GETPOST('chqemetteur'),GETPOST('chqbank'));
-        if ($result < 0)
+        if (! $error)
         {
-            setEventMessage($paiement->error, 'errors');
-            $error++;
+            $label='(CustomerInvoicePayment)';
+            if (GETPOST('type') == 2) $label='(CustomerInvoicePaymentBack)';
+            $result=$paiement->addPaymentToBank($user,'payment',$label,GETPOST('accountid'),GETPOST('chqemetteur'),GETPOST('chqbank'));
+            if ($result < 0)
+            {
+                setEventMessage($paiement->error, 'errors');
+                $error++;
+            }
         }
-    }
-
-    if (! $error)
-    {
-        $db->commit();
 
-        // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card
-        $invoiceid=0;
-        foreach ($paiement->amounts as $key => $amount)
+        if (! $error)
         {
-            $facid = $key;
-            if (is_numeric($amount) && $amount <> 0)
+            $db->commit();
+
+            // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card
+            $invoiceid=0;
+            foreach ($paiement->amounts as $key => $amount)
             {
-                if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment
-                else $invoiceid=$facid;
+                $facid = $key;
+                if (is_numeric($amount) && $amount <> 0)
+                {
+                    if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment
+                    else $invoiceid=$facid;
+                }
             }
+            if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/compta/facture.php?facid='.$invoiceid;
+            else $loc = DOL_URL_ROOT.'/compta/paiement/fiche.php?id='.$paiement_id;
+            header('Location: '.$loc);
+            exit;
+        }
+        else
+        {
+            $db->rollback();
         }
-        if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/compta/facture.php?facid='.$invoiceid;
-        else $loc = DOL_URL_ROOT.'/compta/paiement/fiche.php?id='.$paiement_id;
-        header('Location: '.$loc);
-        exit;
-    }
-    else
-    {
-        $db->rollback();
     }
 }
 
-
 /*
  * View
  */
diff --git a/htdocs/expedition/fiche.php b/htdocs/expedition/fiche.php
index c11c1d549a9..7dd671d109f 100644
--- a/htdocs/expedition/fiche.php
+++ b/htdocs/expedition/fiche.php
@@ -89,474 +89,476 @@ $hookmanager->initHooks(array('expeditioncard'));
 $parameters=array();
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 
-if ($action == 'add')
-{
-    $error=0;
-
-    $db->begin();
-
-    $object->note				= GETPOST('note','alpha');
-    $object->origin				= $origin;
-    $object->origin_id			= $origin_id;
-    $object->weight				= GETPOST('weight','int')==''?"NULL":GETPOST('weight','int');
-    $object->sizeH				= GETPOST('sizeH','int')==''?"NULL":GETPOST('sizeH','int');
-    $object->sizeW				= GETPOST('sizeW','int')==''?"NULL":GETPOST('sizeW','int');
-    $object->sizeS				= GETPOST('sizeS','int')==''?"NULL":GETPOST('sizeS','int');
-    $object->size_units			= GETPOST('size_units','int');
-    $object->weight_units		= GETPOST('weight_units','int');
-
-    $date_delivery = dol_mktime(GETPOST('date_deliveryhour','int'), GETPOST('date_deliverymin','int'), 0, GETPOST('date_deliverymonth','int'), GETPOST('date_deliveryday','int'), GETPOST('date_deliveryyear','int'));
-
-    // On va boucler sur chaque ligne du document d'origine pour completer objet expedition
-    // avec info diverses + qte a livrer
-    $classname = ucfirst($object->origin);
-    $objectsrc = new $classname($db);
-    $objectsrc->fetch($object->origin_id);
-
-    $object->socid					= $objectsrc->socid;
-    $object->ref_customer			= $objectsrc->ref_client;
-    $object->date_delivery			= $date_delivery;	// Date delivery planed
-    $object->fk_delivery_address	= $objectsrc->fk_delivery_address;
-    $object->shipping_method_id		= GETPOST('shipping_method_id','int');
-    $object->tracking_number		= GETPOST('tracking_number','alpha');
-    $object->ref_int				= GETPOST('ref_int','alpha');
-    $object->note_private			= GETPOST('note_private');
-    $object->note_public			= GETPOST('note_public');
-
-    $num=count($objectsrc->lines);
-    $totalqty=0;
-    for ($i = 0; $i < $num; $i++)
-    {
-        $qty = "qtyl".$i;
-		$j=0;
-		$sub_qty=array();
-		$subtotalqty=0;
-		$idl="idl".$i;
-		$batch="batchl".$i."_0";
-		if (isset($_POST[$batch])) {
-			//shipment line with batch-enable product
-			$qty .= '_'.$j;
-			while (isset($_POST[$batch])) {
-				$sub_qty[$j]['q']=GETPOST($qty,'int');
-				$sub_qty[$j]['id_batch']=GETPOST($batch,'int');
-				$subtotalqty+=$sub_qty[$j]['q'];
-				$j++;
-				$batch="batchl".$i."_".$j;
-				$qty = "qtyl".$i.'_'.$j;
-
-			}
-			$batch_line[$i]['detail']=$sub_qty;
-			$batch_line[$i]['qty']=$subtotalqty;
-			$batch_line[$i]['ix_l']=GETPOST($idl,'int');
-			$totalqty+=$subtotalqty;
-		} else {
-			//Standard product
-			if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int');
-		}
-    }
+if (empty($reshook)) {
 
-    if ($totalqty > 0)
+    if ($action == 'add')
     {
-        //var_dump($_POST);exit;
+        $error=0;
+
+        $db->begin();
+
+        $object->note				= GETPOST('note','alpha');
+        $object->origin				= $origin;
+        $object->origin_id			= $origin_id;
+        $object->weight				= GETPOST('weight','int')==''?"NULL":GETPOST('weight','int');
+        $object->sizeH				= GETPOST('sizeH','int')==''?"NULL":GETPOST('sizeH','int');
+        $object->sizeW				= GETPOST('sizeW','int')==''?"NULL":GETPOST('sizeW','int');
+        $object->sizeS				= GETPOST('sizeS','int')==''?"NULL":GETPOST('sizeS','int');
+        $object->size_units			= GETPOST('size_units','int');
+        $object->weight_units		= GETPOST('weight_units','int');
+
+        $date_delivery = dol_mktime(GETPOST('date_deliveryhour','int'), GETPOST('date_deliverymin','int'), 0, GETPOST('date_deliverymonth','int'), GETPOST('date_deliveryday','int'), GETPOST('date_deliveryyear','int'));
+
+        // On va boucler sur chaque ligne du document d'origine pour completer objet expedition
+        // avec info diverses + qte a livrer
+        $classname = ucfirst($object->origin);
+        $objectsrc = new $classname($db);
+        $objectsrc->fetch($object->origin_id);
+
+        $object->socid					= $objectsrc->socid;
+        $object->ref_customer			= $objectsrc->ref_client;
+        $object->date_delivery			= $date_delivery;	// Date delivery planed
+        $object->fk_delivery_address	= $objectsrc->fk_delivery_address;
+        $object->shipping_method_id		= GETPOST('shipping_method_id','int');
+        $object->tracking_number		= GETPOST('tracking_number','alpha');
+        $object->ref_int				= GETPOST('ref_int','alpha');
+        $object->note_private			= GETPOST('note_private');
+        $object->note_public			= GETPOST('note_public');
+
+        $num=count($objectsrc->lines);
+        $totalqty=0;
         for ($i = 0; $i < $num; $i++)
         {
             $qty = "qtyl".$i;
-			if (! isset($batch_line[$i])) {
-				if (GETPOST($qty,'int') > 0)
-				{
-					$ent = "entl".$i;
-					$idl = "idl".$i;
-					$entrepot_id = is_numeric(GETPOST($ent,'int'))?GETPOST($ent,'int'):GETPOST('entrepot_id','int');
-					if ($entrepot_id < 0) $entrepot_id='';
+            $j=0;
+            $sub_qty=array();
+            $subtotalqty=0;
+            $idl="idl".$i;
+            $batch="batchl".$i."_0";
+            if (isset($_POST[$batch])) {
+                //shipment line with batch-enable product
+                $qty .= '_'.$j;
+                while (isset($_POST[$batch])) {
+                    $sub_qty[$j]['q']=GETPOST($qty,'int');
+                    $sub_qty[$j]['id_batch']=GETPOST($batch,'int');
+                    $subtotalqty+=$sub_qty[$j]['q'];
+                    $j++;
+                    $batch="batchl".$i."_".$j;
+                    $qty = "qtyl".$i.'_'.$j;
 
-					$ret=$object->addline($entrepot_id,GETPOST($idl,'int'),GETPOST($qty,'int'));
-					if ($ret < 0)
-					{
-						$mesg='<div class="error">'.$object->error.'</div>';
-						$error++;
-					}
-				}
-			} else {
-				if ($batch_line[$i]['qty']>0) {
-					$ret=$object->addline_batch($batch_line[$i]);
-					if ($ret < 0)
-					{
-						$mesg='<div class="error">'.$object->error.'</div>';
-						$error++;
-					}
-				}
-			}
+                }
+                $batch_line[$i]['detail']=$sub_qty;
+                $batch_line[$i]['qty']=$subtotalqty;
+                $batch_line[$i]['ix_l']=GETPOST($idl,'int');
+                $totalqty+=$subtotalqty;
+            } else {
+                //Standard product
+                if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int');
+            }
         }
 
-        if (! $error)
+        if ($totalqty > 0)
         {
-            $ret=$object->create($user);
-            if ($ret <= 0)
+            //var_dump($_POST);exit;
+            for ($i = 0; $i < $num; $i++)
             {
-                $mesg='<div class="error">'.$object->error.'</div>';
-                $error++;
+                $qty = "qtyl".$i;
+                if (! isset($batch_line[$i])) {
+                    if (GETPOST($qty,'int') > 0)
+                    {
+                        $ent = "entl".$i;
+                        $idl = "idl".$i;
+                        $entrepot_id = is_numeric(GETPOST($ent,'int'))?GETPOST($ent,'int'):GETPOST('entrepot_id','int');
+                        if ($entrepot_id < 0) $entrepot_id='';
+
+                        $ret=$object->addline($entrepot_id,GETPOST($idl,'int'),GETPOST($qty,'int'));
+                        if ($ret < 0)
+                        {
+                            $mesg='<div class="error">'.$object->error.'</div>';
+                            $error++;
+                        }
+                    }
+                } else {
+                    if ($batch_line[$i]['qty']>0) {
+                        $ret=$object->addline_batch($batch_line[$i]);
+                        if ($ret < 0)
+                        {
+                            $mesg='<div class="error">'.$object->error.'</div>';
+                            $error++;
+                        }
+                    }
+                }
+            }
+
+            if (! $error)
+            {
+                $ret=$object->create($user);
+                if ($ret <= 0)
+                {
+                    $mesg='<div class="error">'.$object->error.'</div>';
+                    $error++;
+                }
             }
         }
-    }
-    else
-    {
-        $mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Qty")).'</div>';
-        $error++;
-    }
+        else
+        {
+            $mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Qty")).'</div>';
+            $error++;
+        }
 
-    if (! $error)
-    {
-        $db->commit();
-        header("Location: fiche.php?id=".$object->id);
-        exit;
-    }
-    else
-    {
-        $db->rollback();
-        $_GET["commande_id"]=GETPOST('commande_id','int');
-        $action='create';
+        if (! $error)
+        {
+            $db->commit();
+            header("Location: fiche.php?id=".$object->id);
+            exit;
+        }
+        else
+        {
+            $db->rollback();
+            $_GET["commande_id"]=GETPOST('commande_id','int');
+            $action='create';
+        }
     }
-}
 
-/*
- * Build a receiving receipt
- */
-else if ($action == 'create_delivery' && $conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer)
-{
-    $result = $object->create_delivery($user);
-    if ($result > 0)
-    {
-        header("Location: ".DOL_URL_ROOT.'/livraison/fiche.php?id='.$result);
-        exit;
-    }
-    else
+    /*
+     * Build a receiving receipt
+     */
+    else if ($action == 'create_delivery' && $conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer)
     {
-        $mesg=$object->error;
+        $result = $object->create_delivery($user);
+        if ($result > 0)
+        {
+            header("Location: ".DOL_URL_ROOT.'/livraison/fiche.php?id='.$result);
+            exit;
+        }
+        else
+        {
+            $mesg=$object->error;
+        }
     }
-}
 
-else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->expedition->valider)
-{
-    $object->fetch_thirdparty();
+    else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->expedition->valider)
+    {
+        $object->fetch_thirdparty();
 
-    $result = $object->valid($user);
+        $result = $object->valid($user);
 
-    // Define output language
-    $outputlangs = $langs;
-    $newlang='';
-    if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id','alpha');
-    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
-        $result=expedition_pdf_create($db,$object,$object->modelpdf,$outputlangs);
+        // Define output language
+        $outputlangs = $langs;
+        $newlang='';
+        if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id','alpha');
+        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
+            $result=expedition_pdf_create($db,$object,$object->modelpdf,$outputlangs);
+        }
+        if ($result < 0)
+        {
+            dol_print_error($db,$result);
+            exit;
+        }
     }
-    if ($result < 0)
+
+    else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->expedition->supprimer)
     {
-        dol_print_error($db,$result);
-        exit;
+        $result = $object->delete();
+        if ($result > 0)
+        {
+            header("Location: ".DOL_URL_ROOT.'/expedition/index.php');
+            exit;
+        }
+        else
+        {
+            $langs->load("errors");
+            setEventMessage($langs->trans($object->error),'errors');
+        }
     }
-}
 
-else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->expedition->supprimer)
-{
-    $result = $object->delete();
-    if ($result > 0)
+    else if ($action == 'reopen' && $user->rights->expedition->valider)
     {
-        header("Location: ".DOL_URL_ROOT.'/expedition/index.php');
-        exit;
-    }
-    else
-	{
-		$langs->load("errors");
-        setEventMessage($langs->trans($object->error),'errors');
+        $result = $object->setStatut(0);
+        if ($result < 0)
+        {
+            $mesg = $object->error;
+        }
     }
-}
 
-else if ($action == 'reopen' && $user->rights->expedition->valider)
-{
-    $result = $object->setStatut(0);
-    if ($result < 0)
+    else if ($action == 'setdate_livraison' && $user->rights->expedition->creer)
     {
-        $mesg = $object->error;
-    }
-}
+        //print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year'];
+        $datedelivery=dol_mktime(GETPOST('liv_hour','int'), GETPOST('liv_min','int'), 0, GETPOST('liv_month','int'), GETPOST('liv_day','int'), GETPOST('liv_year','int'));
 
-else if ($action == 'setdate_livraison' && $user->rights->expedition->creer)
-{
-    //print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year'];
-    $datedelivery=dol_mktime(GETPOST('liv_hour','int'), GETPOST('liv_min','int'), 0, GETPOST('liv_month','int'), GETPOST('liv_day','int'), GETPOST('liv_year','int'));
+        $object->fetch($id);
+        $result=$object->set_date_livraison($user,$datedelivery);
+        if ($result < 0)
+        {
+            $mesg='<div class="error">'.$object->error.'</div>';
+        }
+    }
 
-    $object->fetch($id);
-    $result=$object->set_date_livraison($user,$datedelivery);
-    if ($result < 0)
+    // Action update description of emailing
+    else if ($action == 'settrackingnumber' || $action == 'settrackingurl'
+    || $action == 'settrueWeight'
+    || $action == 'settrueWidth'
+    || $action == 'settrueHeight'
+    || $action == 'settrueDepth'
+    || $action == 'setshipping_method_id')
     {
-        $mesg='<div class="error">'.$object->error.'</div>';
-    }
-}
+        $error=0;
 
-// Action update description of emailing
-else if ($action == 'settrackingnumber' || $action == 'settrackingurl'
-|| $action == 'settrueWeight'
-|| $action == 'settrueWidth'
-|| $action == 'settrueHeight'
-|| $action == 'settrueDepth'
-|| $action == 'setshipping_method_id')
-{
-    $error=0;
+        if ($action == 'settrackingnumber')		$object->tracking_number = trim(GETPOST('trackingnumber','alpha'));
+        if ($action == 'settrackingurl')		$object->tracking_url = trim(GETPOST('trackingurl','int'));
+        if ($action == 'settrueWeight')	{
+            $object->trueWeight = trim(GETPOST('trueWeight','int'));
+            $object->weight_units = GETPOST('weight_units','int');
+        }
+        if ($action == 'settrueWidth')			$object->trueWidth = trim(GETPOST('trueWidth','int'));
+        if ($action == 'settrueHeight'){
+                        $object->trueHeight = trim(GETPOST('trueHeight','int'));
+                        $object->size_units = GETPOST('size_units','int');
+        }
+        if ($action == 'settrueDepth')			$object->trueDepth = trim(GETPOST('trueDepth','int'));
+        if ($action == 'setshipping_method_id')	$object->shipping_method_id = trim(GETPOST('shipping_method_id','int'));
 
-    if ($action == 'settrackingnumber')		$object->tracking_number = trim(GETPOST('trackingnumber','alpha'));
-    if ($action == 'settrackingurl')		$object->tracking_url = trim(GETPOST('trackingurl','int'));
-    if ($action == 'settrueWeight')	{
-    	$object->trueWeight = trim(GETPOST('trueWeight','int'));
-		$object->weight_units = GETPOST('weight_units','int');
+        if (! $error)
+        {
+            if ($object->update($user) >= 0)
+            {
+                header("Location: fiche.php?id=".$object->id);
+                exit;
+            }
+            setEventMessage($object->error,'errors');
+        }
+
+        $action="";
     }
-    if ($action == 'settrueWidth')			$object->trueWidth = trim(GETPOST('trueWidth','int'));
-    if ($action == 'settrueHeight'){
-    				$object->trueHeight = trim(GETPOST('trueHeight','int'));
-					$object->size_units = GETPOST('size_units','int');
-	}
-    if ($action == 'settrueDepth')			$object->trueDepth = trim(GETPOST('trueDepth','int'));
-    if ($action == 'setshipping_method_id')	$object->shipping_method_id = trim(GETPOST('shipping_method_id','int'));
 
-    if (! $error)
+    // Build document
+    else if ($action == 'builddoc')	// En get ou en post
     {
-        if ($object->update($user) >= 0)
+
+        // Save last template used to generate document
+        if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha'));
+
+        // Define output language
+        $outputlangs = $langs;
+        $newlang='';
+        if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id','alpha');
+        if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$shipment->client->default_lang;
+        if (! empty($newlang))
         {
-            header("Location: fiche.php?id=".$object->id);
+            $outputlangs = new Translate("",$conf);
+            $outputlangs->setDefaultLang($newlang);
+        }
+        $result=expedition_pdf_create($db,$object,$object->modelpdf,$outputlangs);
+        if ($result <= 0)
+        {
+            dol_print_error($db,$result);
             exit;
         }
-        setEventMessage($object->error,'errors');
     }
 
-    $action="";
-}
-
-// Build document
-else if ($action == 'builddoc')	// En get ou en post
-{
-
-	// Save last template used to generate document
-	if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha'));
-
-    // Define output language
-    $outputlangs = $langs;
-    $newlang='';
-    if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id','alpha');
-    if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$shipment->client->default_lang;
-    if (! empty($newlang))
+    // Delete file in doc form
+    elseif ($action == 'remove_file')
     {
-        $outputlangs = new Translate("",$conf);
-        $outputlangs->setDefaultLang($newlang);
-    }
-    $result=expedition_pdf_create($db,$object,$object->modelpdf,$outputlangs);
-    if ($result <= 0)
-    {
-        dol_print_error($db,$result);
-        exit;
-    }
-}
-
-// Delete file in doc form
-elseif ($action == 'remove_file')
-{
-	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+        require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 
-	$upload_dir =	$conf->expedition->dir_output . "/sending";
-	$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');
-}
+        $upload_dir =	$conf->expedition->dir_output . "/sending";
+        $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');
+    }
 
-/*
- * Add file in email form
-*/
-if (GETPOST('addfile','alpha'))
-{
-    require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+    /*
+     * Add file in email form
+    */
+    if (GETPOST('addfile','alpha'))
+    {
+        require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 
-    // Set tmp user directory TODO Use a dedicated directory for temp mails files
-    $vardir=$conf->user->dir_output."/".$user->id;
-    $upload_dir_tmp = $vardir.'/temp';
+        // Set tmp user directory TODO Use a dedicated directory for temp mails files
+        $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 (GETPOST('removedfile','alpha'))
-{
-    require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+    /*
+     * Remove file in email form
+    */
+    if (GETPOST('removedfile','alpha'))
+    {
+        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(GETPOST('removedfile','int'),0);
-    $action ='presend';
-}
+        // TODO Delete only files that was uploaded from email form
+        dol_remove_file_process(GETPOST('removedfile','int'),0);
+        $action ='presend';
+    }
 
-/*
- * Send mail
-*/
-if ($action == 'send' && ! GETPOST('addfile','alpha') && ! GETPOST('removedfile','alpha') && ! GETPOST('cancel','alpha'))
-{
-    $langs->load('mails');
+    /*
+     * Send mail
+    */
+    if ($action == 'send' && ! GETPOST('addfile','alpha') && ! GETPOST('removedfile','alpha') && ! GETPOST('cancel','alpha'))
+    {
+        $langs->load('mails');
 
-//        $ref = dol_sanitizeFileName($object->ref);
-//        $file = $conf->expedition->dir_output . '/sending/' . $ref . '/' . $ref . '.pdf';
+    //        $ref = dol_sanitizeFileName($object->ref);
+    //        $file = $conf->expedition->dir_output . '/sending/' . $ref . '/' . $ref . '.pdf';
 
-//        if (is_readable($file))
-//        {
-            if (GETPOST('sendto','alpha'))
-            {
-                // Le destinataire a ete fourni via le champ libre
-                $sendto = GETPOST('sendto','alpha');
-                $sendtoid = 0;
-            }
-            elseif (GETPOST('receiver','alpha') != '-1')
-            {
-                // Recipient was provided from combo list
-                if (GETPOST('receiver','alpha') == 'thirdparty') // Id of third party
+    //        if (is_readable($file))
+    //        {
+                if (GETPOST('sendto','alpha'))
                 {
-                    $sendto = $object->client->email;
+                    // Le destinataire a ete fourni via le champ libre
+                    $sendto = GETPOST('sendto','alpha');
                     $sendtoid = 0;
                 }
-                else	// Id du contact
+                elseif (GETPOST('receiver','alpha') != '-1')
                 {
-                    $sendto = $object->client->contact_get_property(GETPOST('receiver','alpha'),'email');
-                    $sendtoid = GETPOST('receiver','alpha');
+                    // Recipient was provided from combo list
+                    if (GETPOST('receiver','alpha') == 'thirdparty') // Id of third party
+                    {
+                        $sendto = $object->client->email;
+                        $sendtoid = 0;
+                    }
+                    else	// Id du contact
+                    {
+                        $sendto = $object->client->contact_get_property(GETPOST('receiver','alpha'),'email');
+                        $sendtoid = GETPOST('receiver','alpha');
+                    }
                 }
-            }
 
-            if (dol_strlen($sendto))
-            {
-                $langs->load("commercial");
+                if (dol_strlen($sendto))
+                {
+                    $langs->load("commercial");
 
-                $from = GETPOST('fromname','alpha') . ' <' . GETPOST('frommail','alpha') .'>';
-                $replyto = GETPOST('replytoname','alpha'). ' <' . GETPOST('replytomail','alpha').'>';
-                $message = GETPOST('message');
-                $sendtocc = GETPOST('sendtocc','alpha');
-                $deliveryreceipt = GETPOST('deliveryreceipt','alpha');
+                    $from = GETPOST('fromname','alpha') . ' <' . GETPOST('frommail','alpha') .'>';
+                    $replyto = GETPOST('replytoname','alpha'). ' <' . GETPOST('replytomail','alpha').'>';
+                    $message = GETPOST('message');
+                    $sendtocc = GETPOST('sendtocc','alpha');
+                    $deliveryreceipt = GETPOST('deliveryreceipt','alpha');
 
-                if ($action == 'send')
-                {
-                    if (dol_strlen(GETPOST('subject','alpha'))) $subject=GETPOST('subject','alpha');
-                    else $subject = $langs->transnoentities('Shipping').' '.$object->ref;
-                    $actiontypecode='AC_SHIP';
-                    $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n";
-                    if ($message)
+                    if ($action == 'send')
                     {
-                        $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n";
-                        $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n";
-                        $actionmsg.=$message;
+                        if (dol_strlen(GETPOST('subject','alpha'))) $subject=GETPOST('subject','alpha');
+                        else $subject = $langs->transnoentities('Shipping').' '.$object->ref;
+                        $actiontypecode='AC_SHIP';
+                        $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);
                     }
-                    $actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
-                }
 
-                // Create form object
-                include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
-                $formmail = new FormMail($db);
+                    // 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'];
+                    $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)
-                {
-                    $mesg='<div class="error">'.$mailfile->error.'</div>';
-                }
-                else
-                {
-                    $result=$mailfile->sendfile();
-                    if ($result)
+                    // 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)
                     {
-                        $error=0;
-
-                        // Initialisation donnees
-                        $object->sendtoid		= $sendtoid;
-                        $object->actiontypecode	= $actiontypecode;
-                        $object->actionmsg		= $actionmsg;
-                        $object->actionmsg2		= $actionmsg2;
-                        $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('SHIPPING_SENTBYMAIL',$object,$user,$langs,$conf);
-                        if ($result < 0) {
-                            $error++; $object->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"].'?id='.$object->id);
-                            exit;
-                        }
+                        $mesg='<div class="error">'.$mailfile->error.'</div>';
                     }
                     else
                     {
-                        $langs->load("other");
-                        $mesg='<div class="error">';
-                        if ($mailfile->error)
+                        $result=$mailfile->sendfile();
+                        if ($result)
                         {
-                            $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto);
-                            $mesg.='<br>'.$mailfile->error;
+                            $error=0;
+
+                            // Initialisation donnees
+                            $object->sendtoid		= $sendtoid;
+                            $object->actiontypecode	= $actiontypecode;
+                            $object->actionmsg		= $actionmsg;
+                            $object->actionmsg2		= $actionmsg2;
+                            $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('SHIPPING_SENTBYMAIL',$object,$user,$langs,$conf);
+                            if ($result < 0) {
+                                $error++; $object->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"].'?id='.$object->id);
+                                exit;
+                            }
                         }
                         else
                         {
-                            $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
+                            $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>';
                         }
-                        $mesg.='</div>';
                     }
                 }
-            }
+                else
+                {
+                    $langs->load("other");
+                    $mesg='<div class="error">'.$langs->trans('ErrorMailRecipientIsEmpty').' !</div>';
+                    $action='presend';
+                    dol_syslog('Recipient email is empty');
+                }
+    /*        }
             else
             {
-                $langs->load("other");
-                $mesg='<div class="error">'.$langs->trans('ErrorMailRecipientIsEmpty').' !</div>';
-                $action='presend';
-                dol_syslog('Recipient email is empty');
-            }
-/*        }
-        else
-        {
-            $langs->load("errors");
-            $mesg='<div class="error">'.$langs->trans('ErrorCantReadFile',$file).'</div>';
-            dol_syslog('Failed to read file: '.$file);
-        }*/
-}
+                $langs->load("errors");
+                $mesg='<div class="error">'.$langs->trans('ErrorCantReadFile',$file).'</div>';
+                dol_syslog('Failed to read file: '.$file);
+            }*/
+    }
 
-else if ($action == 'classifybilled')
-{
-    $object->fetch($id);
-    $object->set_billed();
+    else if ($action == 'classifybilled')
+    {
+        $object->fetch($id);
+        $object->set_billed();
+    }
 }
 
-
 /*
  * View
  */
diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php
index bb84e279ba9..b6a4c5a7925 100644
--- a/htdocs/fourn/facture/paiement.php
+++ b/htdocs/fourn/facture/paiement.php
@@ -68,164 +68,166 @@ $hookmanager->initHooks(array('paymentsupplier'));
 $parameters=array('socid'=>$socid);
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 
-/*
- * Actions
- */
-if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes'))
-{
-    $error = 0;
+if (empty($reshook)) {
 
-    $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
-    $paiement_id = 0;
-    $totalpayment = 0;
-    $atleastonepaymentnotnull = 0;
-
-    // Generate payment array and check if there is payment higher than invoice and payment date before invoice date
-    $tmpinvoice=new FactureFournisseur($db);
-    foreach ($_POST as $key => $value)
+    /*
+     * Actions
+     */
+    if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes'))
     {
-        if (substr($key,0,7) == 'amount_')
+        $error = 0;
+
+        $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
+        $paiement_id = 0;
+        $totalpayment = 0;
+        $atleastonepaymentnotnull = 0;
+
+        // Generate payment array and check if there is payment higher than invoice and payment date before invoice date
+        $tmpinvoice=new FactureFournisseur($db);
+        foreach ($_POST as $key => $value)
         {
-            $cursorfacid = substr($key,7);
-            $amounts[$cursorfacid] = price2num(trim(GETPOST($key)));
-            $totalpayment = $totalpayment + $amounts[$cursorfacid];
-            if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++;
-            $result=$tmpinvoice->fetch($cursorfacid);
-            if ($result <= 0) dol_print_error($db);
-            $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement());
-            if ($amounts[$cursorfacid])
+            if (substr($key,0,7) == 'amount_')
             {
-	            // Check amount
-	            if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid])))
-	            {
-	                $addwarning=1;
-	                $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPaySupplier")).' '.$langs->trans("HelpPaymentHigherThanReminderToPaySupplier");
-	            }
-	            // Check date
-	            if ($datepaye && ($datepaye < $tmpinvoice->date))
-	            {
-	            	$langs->load("errors");
-	                //$error++;
-	                setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings');
-	            }
+                $cursorfacid = substr($key,7);
+                $amounts[$cursorfacid] = price2num(trim(GETPOST($key)));
+                $totalpayment = $totalpayment + $amounts[$cursorfacid];
+                if (! empty($amounts[$cursorfacid])) $atleastonepaymentnotnull++;
+                $result=$tmpinvoice->fetch($cursorfacid);
+                if ($result <= 0) dol_print_error($db);
+                $amountsresttopay[$cursorfacid]=price2num($tmpinvoice->total_ttc - $tmpinvoice->getSommePaiement());
+                if ($amounts[$cursorfacid])
+                {
+                    // Check amount
+                    if ($amounts[$cursorfacid] && (abs($amounts[$cursorfacid]) > abs($amountsresttopay[$cursorfacid])))
+                    {
+                        $addwarning=1;
+                        $formquestion['text'] = img_warning($langs->trans("PaymentHigherThanReminderToPaySupplier")).' '.$langs->trans("HelpPaymentHigherThanReminderToPaySupplier");
+                    }
+                    // Check date
+                    if ($datepaye && ($datepaye < $tmpinvoice->date))
+                    {
+                        $langs->load("errors");
+                        //$error++;
+                        setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings');
+                    }
+                }
+
+                $formquestion[$i++]=array('type' => 'hidden','name' => $key,  'value' => $_POST[$key]);
             }
+        }
 
-            $formquestion[$i++]=array('type' => 'hidden','name' => $key,  'value' => $_POST[$key]);
+        // Check parameters
+        if ($_POST['paiementid'] <= 0)
+        {
+            setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors');
+            $error++;
         }
-    }
 
-    // Check parameters
-    if ($_POST['paiementid'] <= 0)
-    {
-    	setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('PaymentMode')), 'errors');
-        $error++;
-    }
+        if (! empty($conf->banque->enabled))
+        {
+            // If bank module is on, account is required to enter a payment
+            if (GETPOST('accountid') <= 0)
+            {
+                setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors');
+                $error++;
+            }
+        }
 
-    if (! empty($conf->banque->enabled))
-    {
-        // If bank module is on, account is required to enter a payment
-        if (GETPOST('accountid') <= 0)
+        if (empty($totalpayment) && empty($atleastonepaymentnotnull))
         {
-        	setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors');
+            setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors');
             $error++;
         }
-    }
 
-    if (empty($totalpayment) && empty($atleastonepaymentnotnull))
-    {
-    	setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors');
-        $error++;
+        if (empty($datepaye))
+        {
+            setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors');
+            $error++;
+        }
     }
 
-    if (empty($datepaye))
+    /*
+     * Action add_paiement
+     */
+    if ($action == 'add_paiement')
     {
-    	setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors');
-        $error++;
-    }
-}
-
-/*
- * Action add_paiement
- */
-if ($action == 'add_paiement')
-{
-    if ($error)
-    {
-        $action = 'create';
+        if ($error)
+        {
+            $action = 'create';
+        }
+        // Le reste propre a cette action s'affiche en bas de page.
     }
-    // Le reste propre a cette action s'affiche en bas de page.
-}
 
 
-/*
- * Action confirm_paiement
- */
-if ($action == 'confirm_paiement' && $confirm == 'yes')
-{
-    $error=0;
+    /*
+     * Action confirm_paiement
+     */
+    if ($action == 'confirm_paiement' && $confirm == 'yes')
+    {
+        $error=0;
 
-    $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
+        $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
 
-    if (! $error)
-    {
-        $db->begin();
-
-        // Creation de la ligne paiement
-        $paiement = new PaiementFourn($db);
-        $paiement->datepaye     = $datepaye;
-        $paiement->amounts      = $amounts;   // Array of amounts
-        $paiement->paiementid   = $_POST['paiementid'];
-        $paiement->num_paiement = $_POST['num_paiement'];
-        $paiement->note         = $_POST['comment'];
         if (! $error)
         {
-            $paiement_id = $paiement->create($user,(GETPOST('closepaidinvoices')=='on'?1:0));
-            if ($paiement_id < 0)
+            $db->begin();
+
+            // Creation de la ligne paiement
+            $paiement = new PaiementFourn($db);
+            $paiement->datepaye     = $datepaye;
+            $paiement->amounts      = $amounts;   // Array of amounts
+            $paiement->paiementid   = $_POST['paiementid'];
+            $paiement->num_paiement = $_POST['num_paiement'];
+            $paiement->note         = $_POST['comment'];
+            if (! $error)
             {
-            	setEventMessage($paiement->error, 'errors');
-                $error++;
+                $paiement_id = $paiement->create($user,(GETPOST('closepaidinvoices')=='on'?1:0));
+                if ($paiement_id < 0)
+                {
+                    setEventMessage($paiement->error, 'errors');
+                    $error++;
+                }
             }
-        }
 
-        if (! $error)
-        {
-            $result=$paiement->addPaymentToBank($user,'payment_supplier','(SupplierInvoicePayment)',$_POST['accountid'],'','');
-            if ($result < 0)
+            if (! $error)
             {
-            	setEventMessage($paiement->error, 'errors');
-                $error++;
+                $result=$paiement->addPaymentToBank($user,'payment_supplier','(SupplierInvoicePayment)',$_POST['accountid'],'','');
+                if ($result < 0)
+                {
+                    setEventMessage($paiement->error, 'errors');
+                    $error++;
+                }
             }
-        }
-
-        if (! $error)
-        {
-            $db->commit();
 
-            // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card
-            $invoiceid=0;
-            foreach ($paiement->amounts as $key => $amount)
+            if (! $error)
             {
-                $facid = $key;
-                if (is_numeric($amount) && $amount <> 0)
+                $db->commit();
+
+                // If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card
+                $invoiceid=0;
+                foreach ($paiement->amounts as $key => $amount)
                 {
-                    if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment
-                    else $invoiceid=$facid;
+                    $facid = $key;
+                    if (is_numeric($amount) && $amount <> 0)
+                    {
+                        if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment
+                        else $invoiceid=$facid;
+                    }
                 }
+                if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/fourn/facture/fiche.php?facid='.$invoiceid;
+                else $loc = DOL_URL_ROOT.'/fourn/paiement/fiche.php?id='.$paiement_id;
+                header('Location: '.$loc);
+                exit;
+            }
+            else
+            {
+                $db->rollback();
             }
-            if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/fourn/facture/fiche.php?facid='.$invoiceid;
-            else $loc = DOL_URL_ROOT.'/fourn/paiement/fiche.php?id='.$paiement_id;
-            header('Location: '.$loc);
-            exit;
-        }
-        else
-        {
-            $db->rollback();
         }
     }
 }
 
 
-
 /*
  * View
  */
diff --git a/htdocs/fourn/fiche.php b/htdocs/fourn/fiche.php
index b4ceb2ae1b0..c98b855cdf9 100644
--- a/htdocs/fourn/fiche.php
+++ b/htdocs/fourn/fiche.php
@@ -54,40 +54,41 @@ $hookmanager->initHooks(array('suppliercard'));
 $parameters = array('id' => $id);
 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
 
-/*
- * Action
- */
+if (empty($reshook)) {
+	/*
+	 * Action
+	 */
 
-if ($action == 'setsupplieraccountancycode')
-{
-	$cancelbutton = GETPOST('cancel');
+	if ($action == 'setsupplieraccountancycode')
+	{
+		$cancelbutton = GETPOST('cancel');
 
-	if (!$cancelbutton) {
+		if (!$cancelbutton) {
 
-		$result = $object->fetch($id);
-		$object->code_compta_fournisseur = $_POST["supplieraccountancycode"];
-		$result = $object->update($object->id, $user, 1, 0, 1);
-		if ($result < 0) {
-			$mesg = join(',', $object->errors);
+			$result = $object->fetch($id);
+			$object->code_compta_fournisseur = $_POST["supplieraccountancycode"];
+			$result = $object->update($object->id, $user, 1, 0, 1);
+			if ($result < 0) {
+				$mesg = join(',', $object->errors);
+			}
+			$action = "";
 		}
-		$action = "";
+	}
+	// conditions de reglement
+	if ($action == 'setconditions' && $user->rights->societe->creer)
+	{
+		$object->fetch($id);
+		$result=$object->setPaymentTerms(GETPOST('cond_reglement_supplier_id','int'));
+		if ($result < 0) dol_print_error($db,$object->error);
+	}
+	// mode de reglement
+	if ($action == 'setmode' && $user->rights->societe->creer)
+	{
+		$object->fetch($id);
+		$result=$object->setPaymentMethods(GETPOST('mode_reglement_supplier_id','int'));
+		if ($result < 0) dol_print_error($db,$object->error);
 	}
 }
-// conditions de reglement
-if ($action == 'setconditions' && $user->rights->societe->creer)
-{
-	$object->fetch($id);
-	$result=$object->setPaymentTerms(GETPOST('cond_reglement_supplier_id','int'));
-	if ($result < 0) dol_print_error($db,$object->error);
-}
-// mode de reglement
-if ($action == 'setmode' && $user->rights->societe->creer)
-{
-	$object->fetch($id);
-	$result=$object->setPaymentMethods(GETPOST('mode_reglement_supplier_id','int'));
-	if ($result < 0) dol_print_error($db,$object->error);
-}
-
 
 /*
  * View
diff --git a/htdocs/product/document.php b/htdocs/product/document.php
index 1e8c7b7cd9a..24c8122a3a0 100644
--- a/htdocs/product/document.php
+++ b/htdocs/product/document.php
@@ -76,13 +76,13 @@ $modulepart='produit';
 $parameters=array('id'=>$id);
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 
+if (empty($reshook)) {
+	/*
+	 * Action envoie fichier
+	 */
 
-/*
- * Action envoie fichier
- */
-
-include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php';
-
+	include_once DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_pre_headers.tpl.php';
+}
 
 /*
  *	View
diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php
index 527615cc7c4..c5ebe50049a 100644
--- a/htdocs/product/fournisseurs.php
+++ b/htdocs/product/fournisseurs.php
@@ -83,125 +83,125 @@ $parameters=array('socid'=>$socid, 'id_prod'=>$id);
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 $error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->errors);
 
-if ($action == 'remove_pf')
-{
-	$product = new ProductFournisseur($db);
-	if ($product->fetch($id) > 0)
+if (empty($reshook)) {
+	if ($action == 'remove_pf')
 	{
-		if ($rowid)
+		$product = new ProductFournisseur($db);
+		if ($product->fetch($id) > 0)
 		{
-			$result=$product->remove_product_fournisseur_price($rowid);
-			$action = '';
-			$mesg = '<div class="ok">'.$langs->trans("PriceRemoved").'.</div>';
+			if ($rowid)
+			{
+				$result=$product->remove_product_fournisseur_price($rowid);
+				$action = '';
+				$mesg = '<div class="ok">'.$langs->trans("PriceRemoved").'.</div>';
+			}
 		}
 	}
-}
-
-if ($action == 'updateprice' && GETPOST('cancel') <> $langs->trans("Cancel"))
-{
-    $id_fourn=GETPOST("id_fourn");
-    if (empty($id_fourn)) $id_fourn=GETPOST("search_id_fourn");
-    $ref_fourn=GETPOST("ref_fourn");
-    if (empty($ref_fourn)) $ref_fourn=GETPOST("search_ref_fourn");
-    $quantity=GETPOST("qty");
-	$remise_percent=price2num(GETPOST('remise_percent','alpha'));
-    $npr = preg_match('/\*/', $_POST['tva_tx']) ? 1 : 0 ;
-    $tva_tx = str_replace('*','', GETPOST('tva_tx','alpha'));
-    $tva_tx = price2num($tva_tx);
-
-    if ($tva_tx == '')
-    {
-		$error++;
-		$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("VATRateForSupplierProduct")).'</div>';
-    }
-	if (empty($quantity))
-	{
-		$error++;
-		$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Qty")).'</div>';
-	}
-	if (empty($ref_fourn))
-	{
-		$error++;
-		$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("RefSupplier")).'</div>';
-	}
-	if ($id_fourn <= 0)
-	{
-		$error++;
-		$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Supplier")).'</div>';
-	}
-	if ($_POST["price"] < 0 || $_POST["price"] == '')
-	{
-		$error++;
-		$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Price")).'</div>';
-	}
 
-	$product = new ProductFournisseur($db);
-	$result=$product->fetch($id);
-	if ($result <= 0)
+	if ($action == 'updateprice' && GETPOST('cancel') <> $langs->trans("Cancel"))
 	{
-	    $error++;
-	    $mesg=$product->error;
-	}
+	    $id_fourn=GETPOST("id_fourn");
+	    if (empty($id_fourn)) $id_fourn=GETPOST("search_id_fourn");
+	    $ref_fourn=GETPOST("ref_fourn");
+	    if (empty($ref_fourn)) $ref_fourn=GETPOST("search_ref_fourn");
+	    $quantity=GETPOST("qty");
+		$remise_percent=price2num(GETPOST('remise_percent','alpha'));
+	    $npr = preg_match('/\*/', $_POST['tva_tx']) ? 1 : 0 ;
+	    $tva_tx = str_replace('*','', GETPOST('tva_tx','alpha'));
+	    $tva_tx = price2num($tva_tx);
+
+	    if ($tva_tx == '')
+	    {
+			$error++;
+			$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("VATRateForSupplierProduct")).'</div>';
+	    }
+		if (empty($quantity))
+		{
+			$error++;
+			$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Qty")).'</div>';
+		}
+		if (empty($ref_fourn))
+		{
+			$error++;
+			$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("RefSupplier")).'</div>';
+		}
+		if ($id_fourn <= 0)
+		{
+			$error++;
+			$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Supplier")).'</div>';
+		}
+		if ($_POST["price"] < 0 || $_POST["price"] == '')
+		{
+			$error++;
+			$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Price")).'</div>';
+		}
 
-	if (! $error)
-    {
-    	$db->begin();
+		$product = new ProductFournisseur($db);
+		$result=$product->fetch($id);
+		if ($result <= 0)
+		{
+		    $error++;
+		    $mesg=$product->error;
+		}
 
 		if (! $error)
-		{
-			$ret=$product->add_fournisseur($user, $id_fourn, $ref_fourn, $quantity);    // This insert record with no value for price. Values are update later with update_buyprice
-			if ($ret == -3)
+	    {
+	        $db->begin();
+
+			if (! $error)
 			{
-				$error++;
+				$ret=$product->add_fournisseur($user, $id_fourn, $ref_fourn, $quantity);    // This insert record with no value for price. Values are update later with update_buyprice
+				if ($ret == -3)
+				{
+					$error++;
 
-				$product->fetch($product->product_id_already_linked);
-				$productLink = $product->getNomUrl(1,'supplier');
+					$product->fetch($product->product_id_already_linked);
+					$productLink = $product->getNomUrl(1,'supplier');
 
-				$mesg='<div class="error">'.$langs->trans("ReferenceSupplierIsAlreadyAssociatedWithAProduct",$productLink).'</div>';
+					$mesg='<div class="error">'.$langs->trans("ReferenceSupplierIsAlreadyAssociatedWithAProduct",$productLink).'</div>';
+				}
+				else if ($ret < 0)
+				{
+					$error++;
+					$mesg='<div class="error">'.$product->error.'</div>';
+				}
 			}
-			else if ($ret < 0)
+
+			if (! $error)
 			{
-				$error++;
-				$mesg='<div class="error">'.$product->error.'</div>';
-			}
-		}
+				$supplier=new Fournisseur($db);
+				$result=$supplier->fetch($id_fourn);
+				if (isset($_POST['ref_fourn_price_id']))
+					$product->fetch_product_fournisseur_price($_POST['ref_fourn_price_id']);
 
-		if (! $error)
-		{
-			$supplier=new Fournisseur($db);
-			$result=$supplier->fetch($id_fourn);
-			if (isset($_POST['ref_fourn_price_id']))
-				$product->fetch_product_fournisseur_price($_POST['ref_fourn_price_id']);
+				$ret=$product->update_buyprice($quantity, $_POST["price"], $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx, $_POST["charges"], $remise_percent, $npr);
+				if ($ret < 0)
+				{
+					$error++;
+					$mesg='<div class="error">'.$product->error.'</div>';
+				}
+			}
 
-			$ret=$product->update_buyprice($quantity, $_POST["price"], $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx, $_POST["charges"], $remise_percent, $npr);
-			if ($ret < 0)
+			if (! $error)
 			{
-				$error++;
-				$mesg='<div class="error">'.$product->error.'</div>';
+				$db->commit();
+				$action='';
 			}
-		}
-
-		if (! $error)
-		{
-			$db->commit();
-			$action='';
-		}
-		else
-		{
-			$db->rollback();
-		}
-    }
-}
+			else
+			{
+				$db->rollback();
+			}
+	    }
+	}
 
-if (GETPOST('cancel') == $langs->trans("Cancel"))
-{
-	$action = '';
-	header("Location: fournisseurs.php?id=".$_GET["id"]);
-	exit;
+	if (GETPOST('cancel') == $langs->trans("Cancel"))
+	{
+		$action = '';
+		header("Location: fournisseurs.php?id=".$_GET["id"]);
+		exit;
+	}
 }
 
-
-
 /*
  * view
  */
diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php
index 38562557e3a..0dbf21ce881 100755
--- a/htdocs/resource/card.php
+++ b/htdocs/resource/card.php
@@ -61,58 +61,59 @@ $hookmanager->initHooks(array('resource_card'));
 $parameters=array('resource_id'=>$id);
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 
+if (empty($reshook)) {
 
-/*******************************************************************
-* ACTIONS
-*
-* Put here all code to do according to value of "action" parameter
-********************************************************************/
-
-if ($action == 'update' && ! $_POST["cancel"]  && $user->rights->resource->write )
-{
-	$error=0;
+	/*******************************************************************
+	* ACTIONS
+	*
+	* Put here all code to do according to value of "action" parameter
+	********************************************************************/
 
-	if (empty($ref))
+	if ($action == 'update' && ! $_POST["cancel"]  && $user->rights->resource->write )
 	{
-		$error++;
-		$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref")).'</div>';
-	}
+		$error=0;
 
-	if (! $error)
-	{
-		$res = $object->fetch($id);
-		if ( $res > 0 )
+		if (empty($ref))
 		{
-			$object->ref          			= $ref;
-			$object->description  			= $description;
-			$object->fk_code_type_resource  = $fk_code_type_resource;
-		
-			$result=$object->update($user);
-			if ($result > 0)
+			$error++;
+			$mesg='<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref")).'</div>';
+		}
+
+		if (! $error)
+		{
+			$res = $object->fetch($id);
+			if ( $res > 0 )
 			{
-				Header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
-				exit;
+				$object->ref          			= $ref;
+				$object->description  			= $description;
+				$object->fk_code_type_resource  = $fk_code_type_resource;
+
+				$result=$object->update($user);
+				if ($result > 0)
+				{
+					Header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
+					exit;
+				}
+				else
+				{
+					setEventMessage('<div class="error">'.$object->error.'</div>');
+					$action='edit';
+				}
+
 			}
 			else
 			{
-				setEventMessage('<div class="error">'.$object->error.'</div>');
+				setEventMessage($object->error,'errors');
 				$action='edit';
 			}
-			
 		}
-		else 
+		else
 		{
-			setEventMessage($object->error,'errors');
 			$action='edit';
 		}
 	}
-	else
-	{
-		$action='edit';
-	}
 }
 
-
 /***************************************************
 * VIEW
 *
-- 
GitLab