diff --git a/COPYRIGHT b/COPYRIGHT
index 2e1c6e921b9e00bde56be633d38b557b7709afab..c6a629c5c7abb186221f8c21b4f1d78f252e86a7 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -52,6 +52,9 @@ http://www.fsf.org/licensing/licenses/index_html
 Copyright
 ---------
 
+Copyright (C) 2015
+- Marcos García <marcosgdf@gmail.com>
+
 Copyright (C) 2014
 - Laurent Destailleur <eldy@users.sourceforge.net>
 - Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
diff --git a/ChangeLog b/ChangeLog
index 6691ddb2007f61a8faa01d996492181d343351f3..d9c89622b706140077deb52b50239d96d2432b87 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -193,6 +193,18 @@ Dolibarr better:
 - Fix: ref_ext was not saved when recording a customer order from web service
 - 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 #1788 ] Duplicated doActions hook in product/fournisseurs.php
+- 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 #1802 ] SQL error when updating a task with PostgreSQL database
+- Fix: [ bug #1785 ] Start date is lost in Project > Linked objects
+- Fix: [ bug #1804 ] SQL error when sending email without addresee
+- Fix: [ bug #1803 ] AJAX company contact input is not aligned
+- Fix: [ bug #1787 ] Incorrect behaviour of doActions hook
+- Fix: [ bug #1796 ] Unable to use numeration modules from an external module
+- Fix: [ bug #1783 ] SQL error when enabling 3rd party module with PostgreSQL and MySQL strict mode ON
+- Fix: [ bug #1717 ] Sorting unpaid invoices by amount received brings due amount
+- Fix: [ bug #1784 ] MOTD doesn't show up in Amarok theme
 
 ***** ChangeLog for 3.6.2 compared to 3.6.1 *****
 - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice.
@@ -357,6 +369,8 @@ Fix: Paypal link were broken dur to SSL v3 closed.
 Fix: [ bug #1769 ] Error when installing to a PostgreSQL DB that contains numbers
 Fix: [ bug #1752 ] Date filter of margins module, filters since 12H instead of 00H
 Fix: [ bug #1757 ] Sorting breaks product/service statistics
+Fix: [ bug #1797 ] Tulip supplier invoice module takes creation date instead of invoice date
+Fix: [ bug #1792 ] Users are not allowed to see margins module index page when no product view permission is enabled
 
 ***** ChangeLog for 3.5.6 compared to 3.5.5 *****
 Fix: Avoid missing class error for fetch_thirdparty method #1973
diff --git a/build/makepack-howto.txt b/build/makepack-howto.txt
index 40b0e5180bc6ec11674c10e4fc05f929c5da675c..9e5004f4ba7c9852cc4c79fc846110d37800da53 100644
--- a/build/makepack-howto.txt
+++ b/build/makepack-howto.txt
@@ -11,7 +11,6 @@ beta version of Dolibarr, step by step.
 - Update version/info in /ChangeLog
 - Update version number with x.y.z-w in htdocs/filefunc.inc.php
 - Update version number with x.y.z-w in build/debian/changelog
-- Update version number with x.y.z-w in build/exe/doliwamp/doliwamp.iss
 - Update version number with x.y.z-w in build/rpm/*.spec
 - Commit all changes.
 - Add a Tag (x.y.betaz_YYYYMMDD) and push it: git push --tags
@@ -30,10 +29,9 @@ This files describe steps made by Dolibarr packaging team to make a
 complete release of Dolibarr, step by step.
 
 - Check all files are commited.
-- Update version/info in ChangeLog
+- Update version/info in ChangeLog. To generate a changelog, you can do "git log x.y.z..HEAD --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^Fix\|New\|Sec'"
 - Update version number with x.y.z in htdocs/filefunc.inc.php
 - Update version number with x.y.z in build/debian/changelog
-- Update version number with x.y.z in build/exe/doliwamp/doliwamp.iss
 - Update version number with x.y.z in build/rpm/*.spec
 - Commit all changes.
 
diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php
index a4463766278978f7c2c8cbeebe32ab10e24342ae..478f1c9e1cd1476305c1e41de9b38fa7a62aa5b1 100644
--- a/htdocs/adherents/card.php
+++ b/htdocs/adherents/card.php
@@ -119,572 +119,574 @@ $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 ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-if ($action == 'setuserid' && ($user->rights->user->self->creer || $user->rights->user->user->creer))
+if (empty($reshook))
 {
-	$error=0;
-	if (empty($user->rights->user->user->creer))	// If can edit only itself user, we can link to itself only
+	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++;
-			setEventMessage($langs->trans("ErrorUserPermissionAllowsToLinksToItselfOnly"), 'errors');
+			if ($userid != $user->id && $userid != $object->user_id)
+			{
+				$error++;
+				setEventMessage($langs->trans("ErrorUserPermissionAllowsToLinksToItselfOnly"), 'errors');
+			}
 		}
-	}
 
-	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++;
-					setEventMessage($langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty",$othermember->getFullName($langs),$othermember->login,$thirdparty->name), 'errors');
+					$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++;
+						setEventMessage($langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty",$othermember->getFullName($langs),$othermember->login,$thirdparty->name), 'errors');
+					}
 				}
-			}
 
-			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");
+				setEventMessage($langs->trans($nuser->error), 'errors');
+			}
+		}
+		else
 		{
-			$langs->load("errors");
-			setEventMessage($langs->trans($nuser->error), 'errors');
+			setEventMessage($object->error, 'errors');
 		}
 	}
-	else
-	{
-		setEventMessage($object->error, 'errors');
-	}
-}
 
-// 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");
+				setEventMessage($langs->trans($company->error), 'errors');
+				setEventMessage($company->errors, 'errors');
+			}
+		}
+		else
 		{
-			$langs->load("errors");
-			setEventMessage($langs->trans($company->error), 'errors');
-			setEventMessage($company->errors, 'errors');
+			setEventMessage($object->error, 'errors');
 		}
 	}
-	else
-	{
-		setEventMessage($object->error, 'errors');
-	}
-}
 
-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");
-		setEventMessage($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");
-		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname")), 'errors');
-	}
-	if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) {
-		$error++;
-		$langs->load("errors");
-		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname")), 'errors');
+			$langs->load("mails");
+			setEventMessage($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"]);
-
-		$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"];
-
-		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);
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 
-		// 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");
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname")), 'errors');
+		}
+		if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) {
+			$error++;
+			$langs->load("errors");
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname")), 'errors');
 		}
 
-		$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"];
+
+			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
+			}
 
-				if (image_format_supported($_FILES['photo']['name']) > 0)
+			// 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
+			}
+
+			$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)
-						{
-							setEventMessage($langs->trans("ErrorFailedToSaveFile"), 'errors');
-						}
-						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)
+							{
+								setEventMessage($langs->trans("ErrorFailedToSaveFile"), 'errors');
+							}
+							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
+					{
+						setEventMessage("ErrorBadImageFormat", 'errors');
+					}
 				}
 				else
 				{
-					setEventMessage("ErrorBadImageFormat", 'errors');
+					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) {
+					setEventMessage($object->error, 'errors');
+				} else {
+					setEventMessage($object->errors, 'errors');
+				}
+				$action='';
 			}
 		}
 		else
 		{
-			if ($object->error) {
-				setEventMessage($object->error, 'errors');
-			} else {
-				setEventMessage($object->errors, '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->birth       = $birthdate;
+		$object->photo       = $photo;
+		$object->typeid      = $typeid;
+		//$object->note        = $comment;
+		$object->morphy      = $morphy;
+		$object->user_id     = $userid;
+		$object->fk_soc      = $socid;
+		$object->public      = $public;
 
-	$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->birth       = $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++;
-		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Nature")), 'errors');
-	}
-	// Test si le login existe deja
-	if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
-	{
-		if (empty($login)) {
+		// Fill array 'array_options' with data from add form
+		$ret = $extrafields->setOptionalsFromPost($extralabels,$object);
+
+		// Check parameters
+		if (empty($morphy) || $morphy == "-1") {
 			$error++;
-			setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("Login")), 'errors');
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Nature")), 'errors');
 		}
-		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++;
+				setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("Login")), 'errors');
 			}
-			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");
+					setEventMessage($langs->trans("ErrorLoginAlreadyExists",$login), 'errors');
+				}
+			}
+			if (empty($pass)) {
 				$error++;
-				$langs->load("errors");
-				setEventMessage($langs->trans("ErrorLoginAlreadyExists",$login), 'errors');
+				setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Password")), 'errors');
 			}
 		}
-		if (empty($pass)) {
+		if ($morphy != 'mor' && empty($lastname)) {
 			$error++;
-			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Password")), 'errors');
+			$langs->load("errors");
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname")), 'errors');
 		}
-	}
-	if ($morphy != 'mor' && empty($lastname)) {
-		$error++;
-		$langs->load("errors");
-		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Lastname")), 'errors');
-	}
-	if ($morphy != 'mor' && (!isset($firstname) || $firstname=='')) {
-		$error++;
-		$langs->load("errors");
-		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname")), 'errors');
-	}
-	if (! ($typeid > 0)) {	// Keep () before !
-		$error++;
-		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors');
-	}
-	if ($conf->global->ADHERENT_MAIL_REQUIRED && ! isValidEMail($email)) {
-		$error++;
-		$langs->load("errors");
-		setEventMessage($langs->trans("ErrorBadEMail",$email), 'errors');
-	}
-	$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");
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Firstname")), 'errors');
 		}
-		else
+		if (! ($typeid > 0)) {	// Keep () before !
+			$error++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors');
+		}
+		if ($conf->global->ADHERENT_MAIL_REQUIRED && ! isValidEMail($email)) {
+			$error++;
+			$langs->load("errors");
+			setEventMessage($langs->trans("ErrorBadEMail",$email), 'errors');
+		}
+		$public=0;
+		if (isset($public)) $public=1;
+
+		if (! $error)
 		{
-			$db->rollback();
+			$db->begin();
 
-			if ($object->error) {
-				setEventMessage($object->error, 'errors');
-			} else {
-				setEventMessage($object->errors, '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();
 
-			$action = 'create';
-		}
-	}
-	else {
-		$action = 'create';
-	}
-}
+				if ($object->error) {
+					setEventMessage($object->error, 'errors');
+				} else {
+					setEventMessage($object->errors, 'errors');
+				}
 
-if ($user->rights->adherent->supprimer && $action == 'confirm_delete' && $confirm == 'yes')
-{
-	$result=$object->delete($rowid);
-	if ($result > 0)
-	{
-		if (! empty($backtopage))
-		{
-			header("Location: ".$backtopage);
-			exit;
+				$action = 'create';
+			}
 		}
-		else
-		{
-			header("Location: list.php");
-			exit;
+		else {
+			$action = 'create';
 		}
 	}
-	else
-	{
-		$errmesg=$object->error;
-	}
-}
-
-if ($user->rights->adherent->creer && $action == 'confirm_valid' && $confirm == 'yes')
-{
-	$error=0;
-
-	$db->begin();
-
-	$adht = new AdherentType($db);
-	$adht->fetch($object->typeid);
-
-	$result=$object->validate($user);
 
-	if ($result >= 0 && ! count($object->errors))
+	if ($user->rights->adherent->supprimer && $action == 'confirm_delete' && $confirm == 'yes')
 	{
-		// Send confirmation Email (selon param du type adherent sinon generique)
-		if ($object->email && GETPOST("send_mail"))
+		$result=$object->delete($rowid);
+		if ($result > 0)
 		{
-			$result=$object->send_an_email($adht->getMailOnValid(),$conf->global->ADHERENT_MAIL_VALID_SUBJECT,array(),array(),array(),"","",0,2);
-			if ($result < 0)
+			if (! empty($backtopage))
 			{
-				$error++;
-				setEventMessage($object->error, 'errors');
+				header("Location: ".$backtopage);
+				exit;
+			}
+			else
+			{
+				header("Location: list.php");
+				exit;
 			}
 		}
-	}
-	else
-	{
-		$error++;
-		if ($object->error) {
-			setEventMessage($object->error, 'errors');
-		} else {
-			setEventMessage($object->errors, 'errors');
+		else
+		{
+			$errmesg=$object->error;
 		}
 	}
 
-	if (! $error)
+	if ($user->rights->adherent->creer && $action == 'confirm_valid' && $confirm == 'yes')
 	{
-		$db->commit();
-	}
-	else
-	{
-		$db->rollback();
-	}
-	$action='';
-}
+		$error=0;
 
-if ($user->rights->adherent->supprimer && $action == 'confirm_resign')
-{
-	$error = 0;
+		$db->begin();
 
-	if ($confirm == 'yes')
-	{
 		$adht = new AdherentType($db);
 		$adht->fetch($object->typeid);
 
-		$result=$object->resiliate($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"))
 			{
-				$result=$object->send_an_email($adht->getMailOnResiliate(),$conf->global->ADHERENT_MAIL_RESIL_SUBJECT,array(),array(),array(),"","",0,-1);
-			}
-			if ($result < 0)
-			{
-				$error++;
-				setEventMessage($object->error, 'errors');
+				$result=$object->send_an_email($adht->getMailOnValid(),$conf->global->ADHERENT_MAIL_VALID_SUBJECT,array(),array(),array(),"","",0,2);
+				if ($result < 0)
+				{
+					$error++;
+					setEventMessage($object->error, 'errors');
+				}
 			}
 		}
 		else
 		{
 			$error++;
-
 			if ($object->error) {
 				setEventMessage($object->error, 'errors');
 			} else {
 				setEventMessage($object->errors, 'errors');
 			}
-			$action='';
 		}
+
+		if (! $error)
+		{
+			$db->commit();
+		}
+		else
+		{
+			$db->rollback();
+		}
+		$action='';
 	}
-	if (! empty($backtopage) && ! $error)
+
+	if ($user->rights->adherent->supprimer && $action == 'confirm_resign')
 	{
-		header("Location: ".$backtopage);
-		exit;
+		$error = 0;
+
+		if ($confirm == 'yes')
+		{
+			$adht = new AdherentType($db);
+			$adht->fetch($object->typeid);
+
+			$result=$object->resiliate($user);
+
+			if ($result >= 0 && ! count($object->errors))
+			{
+				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)
+				{
+					$error++;
+					setEventMessage($object->error, 'errors');
+				}
+			}
+			else
+			{
+				$error++;
+
+				if ($object->error) {
+					setEventMessage($object->error, 'errors');
+				} else {
+					setEventMessage($object->errors, 'errors');
+				}
+				$action='';
+			}
+		}
+		if (! empty($backtopage) && ! $error)
+		{
+			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))
 		{
-			setEventMessage($langs->trans('DeleteIntoSpipError').': '.$mailmanspip->error, 'errors');
+			if (!$mailmanspip->del_to_spip($object))
+			{
+				setEventMessage($langs->trans('DeleteIntoSpipError').': '.$mailmanspip->error, 'errors');
+			}
 		}
 	}
-}
 
-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))
 		{
-			setEventMessage($langs->trans('AddIntoSpipError').': '.$mailmanspip->error, 'errors');
+			if (!$mailmanspip->add_to_spip($object))
+			{
+				setEventMessage($langs->trans('AddIntoSpipError').': '.$mailmanspip->error, 'errors');
+			}
 		}
 	}
 }
 
 
-
 /*
  * View
  */
diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php
index b58123578dd8e7e8c8750775cb796bc5fa4c1275..7c828f4fa59385299e46ddf54fc15c2505f7ccc0 100644
--- a/htdocs/comm/action/class/actioncomm.class.php
+++ b/htdocs/comm/action/class/actioncomm.class.php
@@ -118,6 +118,13 @@ class ActionComm extends CommonObject
         $error=0;
         $now=dol_now();
 
+        // Check parameters
+        if (empty($this->userownerid)) 
+        {
+        	$this->errors[]='ErrorPropertyUserowneridNotDefined';
+        	return -1;
+        }
+        
         // Clean parameters
         $this->label=dol_trunc(trim($this->label),128);
         $this->location=dol_trunc(trim($this->location),128);
@@ -148,8 +155,9 @@ class ActionComm extends CommonObject
         $userownerid=$this->userownerid;
         $userdoneid=$this->userdoneid;
 
-        // Be sure assigned user array is not empty.
-        if (count($this->userassigned) == 0) $this->userassigned = array('id'=>$userownerid);
+        // Be sure assigned user is defined as an array of array('id'=>,'mandatory'=>,...).
+        if (empty($this->userassigned) || count($this->userassigned) == 0 || ! is_array($this->userassigned)) 
+        	$this->userassigned = array($userownerid=>array('id'=>$userownerid));
 
         if (! $this->type_id || ! $this->type_code)
         {
@@ -236,6 +244,12 @@ class ActionComm extends CommonObject
 			{
 				foreach($this->userassigned as $key => $val)
 				{
+			        if (! is_array($val))	// For backward compatibility when val=id
+			        {
+			        	$tmpid=$val;
+			        	$val=array('id'=>$val);
+			        }
+					
 					$sql ="INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
 					$sql.=" VALUES(".$this->id.", 'user', ".$val['id'].", ".($val['mandatory']?$val['mandatory']:'0').", ".($val['transparency']?$val['transparency']:'0').", ".($val['answer_status']?$val['answer_status']:'0').")";
 
diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php
index ecb171c65700f06bfc08d55cfe83bba0a49b5469..a775408e9a806908b434a2930d8b1732f0cb4ec2 100644
--- a/htdocs/comm/card.php
+++ b/htdocs/comm/card.php
@@ -66,6 +66,7 @@ $pageprev = $page - 1;
 $pagenext = $page + 1;
 if (! $sortorder) $sortorder="ASC";
 if (! $sortfield) $sortfield="nom";
+$cancelbutton = GETPOST('cancel');
 
 // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
 $hookmanager->initHooks(array('commcard','globalcard'));
@@ -80,12 +81,14 @@ $parameters = array('socid' => $id);
 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-//Some actions show a "cancel" input submit button with name="cancel"
-$cancelbutton = GETPOST('cancel');
-
-if ($action == 'setcustomeraccountancycode')
+if (empty($reshook))
 {
-	if (! $cancelbutton)
+	if ($cancelbutton)
+	{
+		$action="";
+	}
+
+	if ($action == 'setcustomeraccountancycode')
 	{
 		$result=$object->fetch($id);
 		$object->code_compta=$_POST["customeraccountancycode"];
@@ -95,56 +98,52 @@ if ($action == 'setcustomeraccountancycode')
 			setEventMessage($object->errors, 'errors');
 		}
 	}
-	$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);
-}
+	// 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);
-}
+	// 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'];
-	$result=$object->update($object->id);
-	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'];
+		$result=$object->update($object->id);
+		if ($result < 0) dol_print_error($db,$object->error);
+	}
 
-// 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');
-}
+	// 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 prospect 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');
-}
+	// update prospect 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');
+	}
 
-// update outstandng limit
-if ($action == 'setOutstandingBill')
-{
-	if (!$cancelbutton)
+	// update outstandng limit
+	if ($action == 'setOutstandingBill')
 	{
 		$object->fetch($id);
 		$object->outstanding_limit=GETPOST('OutstandingBill');
diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php
index ca4c27bfdbcd206dc36c4944853e0022e6424cce..509b26ae1043e88d23bbd31bc2f4662d8b825c8c 100644
--- a/htdocs/comm/mailing/card.php
+++ b/htdocs/comm/mailing/card.php
@@ -110,559 +110,560 @@ $parameters=array();
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-// Action clone object
-if ($action == 'confirm_clone' && $confirm == 'yes')
+if (empty($reshook))
 {
-	if (empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"]))
+	// Action clone object
+	if ($action == 'confirm_clone' && $confirm == 'yes')
 	{
-		setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors');
-	}
-	else
-	{
-		$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;
+			setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors');
 		}
 		else
 		{
-			setEventMessage($object->error, 'errors');
+			$result=$object->createFromClone($object->id,$_REQUEST["clone_content"],$_REQUEST["clone_receivers"]);
+			if ($result > 0)
+			{
+				header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
+				exit;
+			}
+			else
+			{
+				setEventMessage($object->error, 'errors');
+			}
 		}
+	    $action='';
 	}
-    $action='';
-}
 
-// Action send emailing for everybody
-if ($action == 'sendallconfirmed' && $confirm == 'yes')
-{
-	if (empty($conf->global->MAILING_LIMIT_SENDBYWEB))
-	{
-		//TODO: What is this for?
-		// Pour des raisons de securite, on ne permet pas cette fonction via l'IHM,
-		// on affiche donc juste un message
-		setEventMessage($langs->trans("MailingNeedCommand"), 'warnings');
-		setEventMessage('<textarea cols="70" rows="'.ROWS_2.'" wrap="soft">php ./scripts/emailings/mailing-send.php '.$object->id.'</textarea>', 'warnings');
-		setEventMessage($langs->trans("MailingNeedCommand2"), 'warnings');
-		$action='';
-	}
-	else if ($conf->global->MAILING_LIMIT_SENDBYWEB < 0)
-	{
-		setEventMessage($langs->trans("NotEnoughPermissions"), 'warnings');
-		$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;
+			//TODO: What is this for?
+			// Pour des raisons de securite, on ne permet pas cette fonction via l'IHM,
+			// on affiche donc juste un message
+			setEventMessage($langs->trans("MailingNeedCommand"), 'warnings');
+			setEventMessage('<textarea cols="70" rows="'.ROWS_2.'" wrap="soft">php ./scripts/emailings/mailing-send.php '.$object->id.'</textarea>', 'warnings');
+			setEventMessage($langs->trans("MailingNeedCommand2"), 'warnings');
+			$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("card.php: select targets", 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
+			setEventMessage($langs->trans("NotEnoughPermissions"), 'warnings');
+			$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/card.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("card.php: select targets", 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/card.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/card.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("card.php: set prospect thirdparty status", 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("card.php: set prospect contact status", LOG_DEBUG);
+							dol_syslog("comm/mailing/card.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("card.php: set prospect thirdparty status", 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("card.php: set prospect contact status", 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/card.php: error for #".$i.($mail->error?' - '.$mail->error:''), LOG_WARNING);
+							dol_syslog("comm/mailing/card.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/card.php: update global status", LOG_DEBUG);
-			$resql2=$db->query($sql);
-			if (! $resql2)
-			{
-				dol_print_error($db);
+				$sql="UPDATE ".MAIN_DB_PREFIX."mailing SET statut=".$statut." WHERE rowid=".$object->id;
+				dol_syslog("comm/mailing/card.php: update global status", LOG_DEBUG);
+				$resql2=$db->query($sql);
+				if (! $resql2)
+				{
+					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)
-	{
-		setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("MailTo")), 'errors');
-		$error++;
-	}
-
-	if (! $error)
-	{
-		// 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)
+			else
 			{
-				$arr_file[]=$listofpaths[$key]['fullname'];
-				$arr_mime[]=dol_mimetype($listofpaths[$key]['name']);
-				$arr_name[]=$listofpaths[$key]['name'];
+				dol_syslog($db->error());
+				dol_print_error($db);
 			}
-		}
 
-		$mailfile = new CMailFile($tmpsujet,$object->sendto,$object->email_from,$tmpbody, $arr_file,$arr_mime,$arr_name,'', '', 0, $msgishtml,$object->email_errorsto,$arr_css);
-
-		$result=$mailfile->sendfile();
-		if ($result)
-		{
-			setEventMessage($langs->trans("MailSuccessfulySent",$mailfile->getValidAddress($object->email_from,2),$mailfile->getValidAddress($object->sendto,2)));
-		}
-		else
-		{
-			setEventMessage($langs->trans("ResultKo").'<br>'.$mailfile->error.' '.$result, 'errors');
+			$action = '';
 		}
-
-		$action='';
-	}
-}
-
-// Action add emailing
-if ($action == 'add')
-{
-	$mesgs = array();
-
-	$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) {
-		$mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle"));
-	}
-	if (! $object->sujet) {
-		$mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic"));
-	}
-	if (! $object->body)  {
-		$mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage"));
 	}
 
-	if (!count($mesgs))
+	// Action send test emailing
+	if ($action == 'send' && empty($_POST["cancel"]))
 	{
-		if ($object->create($user) >= 0)
-		{
-			header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
-			exit;
-		}
-		$mesgs[] = $object->error;
-	}
+		$error=0;
 
-	setEventMessage($mesgs, 'errors');
-	$action="create";
-}
-
-// Action update description of emailing
-if ($action == 'settitre' || $action == 'setemail_from' || $action == 'setreplyto' || $action == 'setemail_errorsto')
-{
-	$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 = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle"));
-	}
-	else if ($action == 'setfrom' && empty($object->email_from)) {
-		$mesg = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailFrom"));
-	}
+		$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
 
-	if (! $mesg)
-	{
-		if ($object->update($user) >= 0)
+		$object->sendto = $_POST["sendto"];
+		if (! $object->sendto)
 		{
-			header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
-			exit;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("MailTo")), 'errors');
+			$error++;
 		}
-		$mesg = $object->error;
-	}
-
-	setEventMessage($mesg, 'errors');
-	$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);
+		if (! $error)
+		{
+			// Le message est-il en html
+			$msgishtml=-1;	// Inconnu par defaut
+			if (preg_match('/[\s\t]*<html>/i',$object->body)) $msgishtml=1;
 
-	$action="edit";
-}
+			// Pratique les substitutions sur le sujet et message
+			$tmpsujet=make_substitutions($object->sujet,$object->substitutionarrayfortest);
+			$tmpbody=make_substitutions($object->body,$object->substitutionarrayfortest);
 
-// Action remove file
-if (! empty($_POST["removedfile"]))
-{
-	$upload_dir = $conf->mailing->dir_output . "/" . get_exdir($object->id,2,0,1);
+			$arr_file = array();
+			$arr_mime = array();
+			$arr_name = array();
+			$arr_css  = array();
 
-	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+	        // Ajout CSS
+	        if (!empty($object->bgcolor)) $arr_css['bgcolor'] = (preg_match('/^#/',$object->bgcolor)?'':'#').$object->bgcolor;
+	        if (!empty($object->bgimage)) $arr_css['bgimage'] = $object->bgimage;
 
-    dol_remove_file_process($_POST['removedfile'],0);
+	        // 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'];
+				}
+			}
 
-	$action="edit";
-}
+			$mailfile = new CMailFile($tmpsujet,$object->sendto,$object->email_from,$tmpbody, $arr_file,$arr_mime,$arr_name,'', '', 0, $msgishtml,$object->email_errorsto,$arr_css);
 
-// Action update emailing
-if ($action == 'update' && empty($_POST["removedfile"]) && empty($_POST["cancel"]))
-{
-	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+			$result=$mailfile->sendfile();
+			if ($result)
+			{
+				setEventMessage($langs->trans("MailSuccessfulySent",$mailfile->getValidAddress($object->email_from,2),$mailfile->getValidAddress($object->sendto,2)));
+			}
+			else
+			{
+				setEventMessage($langs->trans("ResultKo").'<br>'.$mailfile->error.' '.$result, 'errors');
+			}
 
-	$isupload=0;
+			$action='';
+		}
+	}
 
-	if (! $isupload)
+	// Action add emailing
+	if ($action == 'add')
 	{
 		$mesgs = array();
 
+		$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) {
+			$mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle"));
+		}
 		if (! $object->sujet) {
 			$mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic"));
 		}
-		if (! $object->body) {
+		if (! $object->body)  {
 			$mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage"));
 		}
 
 		if (!count($mesgs))
 		{
-			if ($object->update($user) >= 0)
+			if ($object->create($user) >= 0)
 			{
 				header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
 				exit;
 			}
-			$mesgs[] =$object->error;
+			$mesgs[] = $object->error;
 		}
 
 		setEventMessage($mesgs, 'errors');
-		$action="edit";
+		$action="create";
 	}
-	else
+
+	// Action update description of emailing
+	if ($action == 'settitre' || $action == 'setemail_from' || $action == '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 = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTitle"));
+		}
+		else if ($action == 'setfrom' && empty($object->email_from)) {
+			$mesg = $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;
+		}
+
+		setEventMessage($mesg, 'errors');
+		$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';
 
-		$result=$object->valid($user);
-		if ($result > 0)
+		$isupload=0;
+
+		if (! $isupload)
 		{
-			$result=$object->reset_targets_status($user);
+			$mesgs = array();
+
+			$object->sujet          = trim($_POST["sujet"]);
+			$object->body           = trim($_POST["body"]);
+			$object->bgcolor        = trim($_POST["bgcolor"]);
+			$object->bgimage        = trim($_POST["bgimage"]);
+
+			if (! $object->sujet) {
+				$mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailTopic"));
+			}
+			if (! $object->body) {
+				$mesgs[] = $langs->trans("ErrorFieldRequired",$langs->transnoentities("MailMessage"));
+			}
+
+			if (!count($mesgs))
+			{
+				if ($object->update($user) >= 0)
+				{
+					header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
+					exit;
+				}
+				$mesgs[] =$object->error;
+			}
+
+			setEventMessage($mesgs, 'errors');
+			$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
 		{
-			setEventMessage($object->error, 'errors');
-			$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
+			{
+				setEventMessage($object->error, 'errors');
+				$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 : 'list.php');
-		header("Location: ".$url);
-		exit;
+		if ($object->delete($object->id))
+		{
+			$url= (! empty($urlfrom) ? $urlfrom : 'list.php');
+			header("Location: ".$url);
+			exit;
+		}
 	}
-}
 
-if (! empty($_POST["cancel"]))
-{
-	$action = '';
+	if (! empty($_POST["cancel"]))
+	{
+		$action = '';
+	}
 }
 
 
-
 /*
  * View
  */
 
+$form = new Form($db);
+$htmlother = new FormOther($db);
 
 $help_url='EN:Module_EMailing|FR:Module_Mailing|ES:M&oacute;dulo_Mailing';
 llxHeader('',$langs->trans("Mailing"),$help_url);
 
-$form = new Form($db);
-$htmlother = new FormOther($db);
-
 if ($action == 'create')
 {
 	// EMailing in creation mode
diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php
index 3efc6ba53253d44eb7b75b63f596b213fcf93683..50b3306e3f291d5e6652d554b2b07d16c5721c99 100644
--- a/htdocs/comm/propal.php
+++ b/htdocs/comm/propal.php
@@ -26,9 +26,9 @@
  */
 
 /**
- * \file htdocs/comm/propal.php
- * \ingroup propale
- * \brief Page of commercial proposals card and list
+ * \file 		htdocs/comm/propal.php
+ * \ingroup 	propale
+ * \brief 		Page of commercial proposals card and list
  */
 require '../main.inc.php';
 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
@@ -108,681 +108,837 @@ $parameters = array('socid' => $socid);
 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-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 (empty($reshook))
 {
-	if (1 == 0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers'))
-	{
-		setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors');
-	}
-	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')
 	{
-		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 = '';
+		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');
+	// 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->thirdparty->default_lang);
-			$outputlangs->setDefaultLang($newlang);
+	// 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->thirdparty->default_lang);
+				$outputlangs->setDefaultLang($newlang);
+			}
+			$ret = $object->fetch($id); // Reload to get new records
+			$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 		}
-		$ret = $object->fetch($id); // Reload to get new records
-		$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-	}
 
-	header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id);
-	exit();
-}
+		header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id);
+		exit();
+	}
 
-// Validation
-else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->propal->valider)
-{
-	$result = $object->valid($user);
-	if ($result >= 0)
+	// Validation
+	else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->propal->valider)
 	{
-		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+		$result = $object->valid($user);
+		if ($result >= 0)
 		{
-					// Define output language
 			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
 			{
-				$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->thirdparty->default_lang;
-				if (! empty($newlang)) {
-					$outputlangs = new Translate("", $conf);
-					$outputlangs->setDefaultLang($newlang);
-				}
-				$model=$object->modelpdf;
-				$ret = $object->fetch($id); // Reload to get new records
+						// Define output language
+				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+				{
+					$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->thirdparty->default_lang;
+					if (! empty($newlang)) {
+						$outputlangs = new Translate("", $conf);
+						$outputlangs->setDefaultLang($newlang);
+					}
+					$model=$object->modelpdf;
+					$ret = $object->fetch($id); // Reload to get new records
 
-				$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
+					$object->generateDocument($model, $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 {
-		$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']);
+	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 (empty($datep)) {
+			$error ++;
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), 'errors');
+		}
 
-	if (! $error) {
-		$result = $object->set_date($user, $datep);
+		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 == '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']);
-}
-
-// 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');
-
-	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 ++;
+	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);
 	}
 
-	if ($socid < 1) {
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors');
-		$action = 'create';
-		$error ++;
+	// Positionne ref client
+	else if ($action == 'set_ref_client' && $user->rights->propal->creer)
+	{
+		$object->set_ref_client($user, $_POST['ref_client']);
 	}
 
-	if (! $error)
+	// Create proposal
+	else if ($action == 'add' && $user->rights->propal->creer)
 	{
-		$db->begin();
+		$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');
 
-		// Si on a selectionne une propal a copier, on realise la copie
-		if (GETPOST('createmode') == 'copy' && GETPOST('copie_propal'))
+		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 (! $error)
 		{
-			if ($object->fetch(GETPOST('copie_propal')) > 0) {
+			$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->shipping_method_id = GETPOST('shipping_method_id', 'int');
+					$object->duree_validite = $duration;
+					$object->cond_reglement_id = GETPOST('cond_reglement_id');
+					$object->mode_reglement_id = GETPOST('mode_reglement_id');
+	                $object->fk_account = GETPOST('fk_account', 'int');
+					$object->remise_percent = GETPOST('remise_percent');
+					$object->remise_absolue = GETPOST('remise_absolue');
+					$object->socid = GETPOST('socid');
+					$object->contactid = GETPOST('contactid');
+					$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->shipping_method_id = GETPOST('shipping_method_id', 'int');
-				$object->duree_validite = $duration;
+	            $object->shipping_method_id = GETPOST('shipping_method_id', 'int');
+				$object->duree_validite = GETPOST('duree_validite');
 				$object->cond_reglement_id = GETPOST('cond_reglement_id');
 				$object->mode_reglement_id = GETPOST('mode_reglement_id');
-                $object->fk_account = GETPOST('fk_account', 'int');
-				$object->remise_percent = GETPOST('remise_percent');
-				$object->remise_absolue = GETPOST('remise_absolue');
-				$object->socid = GETPOST('socid');
+	            $object->fk_account = GETPOST('fk_account', 'int');
 				$object->contactid = GETPOST('contactid');
 				$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->shipping_method_id = GETPOST('shipping_method_id', 'int');
-			$object->duree_validite = GETPOST('duree_validite');
-			$object->cond_reglement_id = GETPOST('cond_reglement_id');
-			$object->mode_reglement_id = GETPOST('mode_reglement_id');
-            $object->fk_account = GETPOST('fk_account', 'int');
-			$object->contactid = GETPOST('contactid');
-			$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');
-
-			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]);
+				$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]);
+					}
 				}
-			}
 
-			// 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)
-		{
-			if ($origin && $originid)
+			if (! $error)
 			{
-				// Parse element/subelement (ex: project_task)
-				$element = $subelement = $origin;
-				if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
-					$element = $regs [1];
-					$subelement = $regs [2];
-				}
+				if ($origin && $originid)
+				{
+					// Parse element/subelement (ex: project_task)
+					$element = $subelement = $origin;
+					if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
+						$element = $regs [1];
+						$subelement = $regs [2];
+					}
 
-				// For compatibility
-				if ($element == 'order') {
-					$element = $subelement = 'commande';
-				}
-				if ($element == 'propal') {
-					$element = 'comm/propal';
-					$subelement = 'propal';
-				}
-				if ($element == 'contract') {
-					$element = $subelement = 'contrat';
-				}
-				if ($element == 'inter') {
-					$element = $subelement = 'ficheinter';
-				}
-				if ($element == 'shipping') {
-					$element = $subelement = 'expedition';
-				}
+					// For compatibility
+					if ($element == 'order') {
+						$element = $subelement = 'commande';
+					}
+					if ($element == 'propal') {
+						$element = 'comm/propal';
+						$subelement = 'propal';
+					}
+					if ($element == 'contract') {
+						$element = $subelement = 'contrat';
+					}
+					if ($element == 'inter') {
+						$element = $subelement = 'ficheinter';
+					}
+					if ($element == 'shipping') {
+						$element = $subelement = 'expedition';
+					}
 
-				$object->origin = $origin;
-				$object->origin_id = $originid;
+					$object->origin = $origin;
+					$object->origin_id = $originid;
 
-				// Possibility to add external linked objects with hooks
-				$object->linked_objects [$object->origin] = $object->origin_id;
-				if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) {
-					$object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
-				}
+					// Possibility to add external linked objects with hooks
+					$object->linked_objects [$object->origin] = $object->origin_id;
+					if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) {
+						$object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
+					}
 
-				$id = $object->create($user);
-				if ($id > 0)
-				{
-						dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
+					$id = $object->create($user);
+					if ($id > 0)
+					{
+							dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
 
-						$classname = ucfirst($subelement);
-						$srcobject = new $classname($db);
+							$classname = ucfirst($subelement);
+							$srcobject = new $classname($db);
 
-						dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines");
-						$result = $srcobject->fetch($object->origin_id);
+							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'))
+							if ($result > 0)
 							{
-								$srcobject->fetch_lines();
 								$lines = $srcobject->lines;
-							}
-
-							$fk_parent_line=0;
-							$num=count($lines);
-							for ($i=0;$i<$num;$i++)
-							{
-								$label=(! empty($lines[$i]->label)?$lines[$i]->label:'');
-								$desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle);
-
-									// 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;
-									}
-
-									$tva_tx=get_default_tva($mysoc, $object->thirdparty);
-
-									$result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, 'HT', 0, $lines[$i]->info_bits, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $date_start, $date_end, $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)
+								if (empty($lines) && method_exists($srcobject, 'fetch_lines'))
+								{
+									$srcobject->fetch_lines();
+									$lines = $srcobject->lines;
+								}
+
+								$fk_parent_line=0;
+								$num=count($lines);
+								for ($i=0;$i<$num;$i++)
+								{
+									$label=(! empty($lines[$i]->label)?$lines[$i]->label:'');
+									$desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle);
+
+										// 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;
+										}
+
+										$tva_tx=get_default_tva($mysoc, $object->thirdparty);
+
+										$result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, 'HT', 0, $lines[$i]->info_bits, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $date_start, $date_end, $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 {
+								setEventMessages($srcobject->error, $srcobject->errors, 'errors');
 								$error ++;
-						} else {
-							setEventMessages($srcobject->error, $srcobject->errors, 'errors');
-							$error ++;
-						}
-				} else {
-					setEventMessages($object->error, $object->errors, 'errors');
-					$error ++;
+							}
+					} else {
+						setEventMessages($object->error, $object->errors, 'errors');
+						$error ++;
+					}
+				} 			// Standard creation
+				else
+				{
+					$id = $object->create($user);
 				}
-			} 			// Standard creation
-			else
-			{
-				$id = $object->create($user);
-			}
 
-			if ($id > 0)
-			{
-				// Insertion contact par defaut si defini
-				if (GETPOST('contactid') > 0)
+				if ($id > 0)
 				{
-					$result = $object->add_contact(GETPOST('contactid'), 'CUSTOMER', 'external');
-					if ($result < 0)
+					// Insertion contact par defaut si defini
+					if (GETPOST('contactid') > 0)
 					{
-						$error++;
-						setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors');
+						$result = $object->add_contact(GETPOST('contactid'), 'CUSTOMER', 'external');
+						if ($result < 0)
+						{
+							$error++;
+							setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors');
+						}
 					}
-				}
-
-				if (! $error)
-				{
-					$db->commit();
 
-			        // Define output language
-			    	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
-			    	{
-			    		$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->thirdparty->default_lang;
-			    		if (! empty($newlang)) {
-			    			$outputlangs = new Translate("", $conf);
-			    			$outputlangs->setDefaultLang($newlang);
-			    		}
-			    		$model=$object->modelpdf;
-
-			    		$ret = $object->fetch($id); // Reload to get new records
-			    		$result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
-			    		if ($result < 0) dol_print_error($db,$result);
-			    	}
-
-					header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
-					exit();
+					if (! $error)
+					{
+						$db->commit();
+
+				        // Define output language
+				    	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+				    	{
+				    		$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->thirdparty->default_lang;
+				    		if (! empty($newlang)) {
+				    			$outputlangs = new Translate("", $conf);
+				    			$outputlangs->setDefaultLang($newlang);
+				    		}
+				    		$model=$object->modelpdf;
+
+				    		$ret = $object->fetch($id); // Reload to get new records
+				    		$result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
+				    		if ($result < 0) dol_print_error($db,$result);
+				    	}
+
+						header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
+						exit();
+					}
+					else
+					{
+						$db->rollback();
+						$action='create';
+					}
 				}
 				else
 				{
+					setEventMessages($object->error, $object->errors, 'errors');
 					$db->rollback();
 					$action='create';
 				}
 			}
-			else
-			{
-				setEventMessages($object->error, $object->errors, 'errors');
-				$db->rollback();
-				$action='create';
-			}
 		}
 	}
-}
 
-// 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->statut == 4) {
-		$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->statut == 4) {
+			$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'));
+			}
 		}
 	}
-}
 
-include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
+	// 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->statut == 4) {
+			$object->reopen($user, 1);
+		}
+	}
 
-/*
- * Send mail
- */
+	// 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'));
+			}
+		}
+	}
 
-// Actions to send emails
-$actiontypecode='AC_PROP';
-$trigger_name='PROPAL_SENTBYMAIL';
-$paramname='id';
-$mode='emailfromproposal';
-include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
+	include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
 
 
+	/*
+	 * Send mail
+	 */
+
+	// Actions to send emails
+	$actiontypecode='AC_PROP';
+	$trigger_name='PROPAL_SENTBYMAIL';
+	$paramname='id';
+	$mode='emailfromproposal';
+	include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
+
 
-// Go back to draft
-if ($action == 'modif' && $user->rights->propal->creer)
-{
-	$object->set_draft($user);
 
-	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+	// Go back to draft
+	if ($action == 'modif' && $user->rights->propal->creer)
 	{
-		// Define output language
-		$outputlangs = $langs;
-		if (! empty($conf->global->MAIN_MULTILANGS)) {
-			$outputlangs = new Translate("", $conf);
-			$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang);
-			$outputlangs->setDefaultLang($newlang);
-		}
-		$ret = $object->fetch($id); // Reload to get new records
-		$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-	}
-}
+		$object->set_draft($user);
 
-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');
+		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->thirdparty->default_lang);
+				$outputlangs->setDefaultLang($newlang);
 			}
+			$ret = $object->fetch($id); // Reload to get new records
+			$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 		}
 	}
-}
 
-// 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]);
+	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');
+				}
+			}
 		}
 	}
 
-	if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) {
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors');
-		$error ++;
-	}
+	// Add line
+	else if ($action == 'addline' && $user->rights->propal->creer) {
 
-	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 ++;
-	}
+		// 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 (! $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');
+		$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]);
+			}
+		}
 
-		$db->begin();
+		if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) {
+			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), '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 (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 ++;
+		}
 
-			$label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
+		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->thirdparty, $prod->id);
+					$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
+					$pu_ht = $prod->price;
+					$pu_ttc = $prod->price_ttc;
+					$price_min = $prod->price_min;
+					$price_base_type = $prod->price_base_type;
+
+					// On defini prix unitaire
+					if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->thirdparty->price_level)
+					{
+						$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
+						$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
+						$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
+						$price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
+						if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level];
+						if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level];
+					}
+					elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
+					{
+						require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
 
-			// If prices fields are update
-				$tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
-				$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
-				$pu_ht = $prod->price;
-				$pu_ttc = $prod->price_ttc;
-				$price_min = $prod->price_min;
-				$price_base_type = $prod->price_base_type;
+						$prodcustprice = new Productcustomerprice($db);
 
-				// On defini prix unitaire
-				if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->thirdparty->price_level)
-				{
-					$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
-					$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
-					$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
-					$price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
-					if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level];
-					if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level];
-				}
-				elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
-				{
-					require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
+						$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
 
-					$prodcustprice = new Productcustomerprice($db);
+						$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
+						if ($result) {
+							if (count($prodcustprice->lines) > 0) {
+								$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;
+							}
+						}
+					}
 
-					$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
+					// 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');
+					}
 
-					$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
-					if ($result) {
-						if (count($prodcustprice->lines) > 0) {
-							$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;
+					// 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');
 						}
 					}
-				}
 
-				// 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->thirdparty->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->thirdparty->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 = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
+			$buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : '');
+
+			$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'));
+
+			// Local Taxes
+			$localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty);
+			$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty);
+
+			$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->thirdparty->default_lang);
+							$outputlangs->setDefaultLang($newlang);
+						}
+						$ret = $object->fetch($id); // Reload to get new records
+						$object->generateDocument($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->thirdparty);
+		$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
+		$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->thirdparty);
-		$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty);
+			$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->thirdparty->price_level))
+				$price_min = $product->multiprices_min [$object->thirdparty->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)) {
@@ -797,10 +953,9 @@ else if ($action == 'addline' && $user->rights->propal->creer) {
 					$object->generateDocument($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']);
@@ -810,23 +965,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();
 
@@ -834,315 +972,206 @@ 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->thirdparty);
-	$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
-	$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->thirdparty->price_level))
-			$price_min = $product->multiprices_min [$object->thirdparty->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->thirdparty->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->thirdparty->default_lang);
-					$outputlangs->setDefaultLang($newlang);
-				}
-				$ret = $object->fetch($id); // Reload to get new records
-				$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-			}
+		$ret = $object->fetch($id); // Reload to get new records
+		$result = $object->generateDocument($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();
-}
-
-// Generation doc (depuis lien ou depuis cartouche doc)
-else if ($action == 'builddoc' && $user->rights->propal->creer) {
-	if (GETPOST('model')) {
-		$object->setDocModel($user, GETPOST('model'));
+	// 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');
+		}
 	}
 
-	// Define output language
-	$outputlangs = $langs;
-	if (! empty($conf->global->MAIN_MULTILANGS)) {
-		$outputlangs = new Translate("", $conf);
-		$newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->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 = $object->generateDocument($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']);
-}
 
-// Delai de livraison
-else if ($action == 'setavailability' && $user->rights->propal->creer) {
-	$result = $object->availability($_POST['availability_id']);
-}
-
-// Origine de la propale
-else if ($action == 'setdemandreason' && $user->rights->propal->creer) {
-	$result = $object->demand_reason($_POST['demand_reason_id']);
-}
+	// Conditions de reglement
+	else if ($action == 'setconditions' && $user->rights->propal->creer) {
+		$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
+	}
 
-// Conditions de reglement
-else if ($action == 'setconditions' && $user->rights->propal->creer) {
-	$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
-}
+	else if ($action == 'setremisepercent' && $user->rights->propal->creer) {
+		$result = $object->set_remise_percent($user, $_POST['remise_percent']);
+	}
 
-else if ($action == 'setremisepercent' && $user->rights->propal->creer) {
-	$result = $object->set_remise_percent($user, $_POST['remise_percent']);
-}
+	else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) {
+		$result = $object->set_remise_absolue($user, $_POST['remise_absolue']);
+	}
 
-else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) {
-	$result = $object->set_remise_absolue($user, $_POST['remise_absolue']);
-}
+	// Mode de reglement
+	else if ($action == 'setmode' && $user->rights->propal->creer) {
+		$result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
+	}
 
-// Mode de reglement
-else if ($action == 'setmode' && $user->rights->propal->creer) {
-	$result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
-}
+	// bank account
+	else if ($action == 'setbankaccount' && $user->rights->propal->creer) {
+	    $result=$object->setBankAccount(GETPOST('fk_account', 'int'));
+	}
 
-// bank account
-else if ($action == 'setbankaccount' && $user->rights->propal->creer) {
-    $result=$object->setBankAccount(GETPOST('fk_account', 'int'));
-}
+	// shipping method
+	else if ($action == 'setshippingmethod' && $user->rights->propal->creer) {
+	    $result=$object->setShippingMethod(GETPOST('shipping_method_id', 'int'));
+	}
 
-// shipping method
-else if ($action == 'setshippingmethod' && $user->rights->propal->creer) {
-    $result=$object->setShippingMethod(GETPOST('shipping_method_id', 'int'));
-}
+	/*
+	 * Ordonnancement des lignes
+	*/
+
+	else if ($action == 'up' && $user->rights->propal->creer) {
+		$object->line_up(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->thirdparty->default_lang);
+				$outputlangs->setDefaultLang($newlang);
+			}
+			$ret = $object->fetch($id); // Reload to get new records
+			$object->generateDocument($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->thirdparty->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->thirdparty->default_lang);
+				$outputlangs->setDefaultLang($newlang);
+			}
+			$ret = $object->fetch($id); // Reload to get new records
+			$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 		}
-		$ret = $object->fetch($id); // Reload to get new records
-		$object->generateDocument($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->thirdparty->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
-		$object->generateDocument($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 (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->propal->creer)
 	{
-		if ($object->id > 0) {
-			$contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
-			$result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]);
-		}
+		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);
+			}
 		}
 	}
 }
@@ -1239,7 +1268,7 @@ if ($action == 'create')
 	}
 
 	dol_fiche_head();
-	
+
 	print '<table class="border" width="100%">';
 
 	// Reference
@@ -1512,7 +1541,7 @@ if ($action == 'create')
 	if (! empty($conf->global->PROPAL_CLONE_ON_CREATE_PAGE) || ! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) print '</table>';
 
 	dol_fiche_end();
-	
+
 	$langs->load("bills");
 	print '<div class="center">';
 	print '<input type="submit" class="button" value="' . $langs->trans("CreateDraft") . '">';
diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php
index 724a3ebe45c88de1ca261cc4fd2ca005a4d21cba..410b6f2dafbc2ebd63d18db7550db162de1774fa 100644
--- a/htdocs/comm/propal/class/propal.class.php
+++ b/htdocs/comm/propal/class/propal.class.php
@@ -2550,21 +2550,18 @@ class Propal extends CommonObject
         {
         	$mybool=false;
 
-		$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
-		foreach ($dirmodels as $reldir)
-		{
-	            $file = $conf->global->PROPALE_ADDON.".php";
-	            $classname = $conf->global->PROPALE_ADDON;
-
-	            // Include file with class
-	            foreach ($conf->file->dol_document_root as $dirroot)
-	            {
-	            	$dir = $dirroot.$reldir."/core/modules/propale/";
-	            	// Load file with numbering class (if found)
-	            	$mybool|=@include_once $dir.$file;
-	            }
-		}
+            $file = $conf->global->PROPALE_ADDON.".php";
+            $classname = $conf->global->PROPALE_ADDON;
+
+            // Include file with class
+            $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+            foreach ($dirmodels as $reldir) {
 
+                $dir = dol_buildpath($reldir."core/modules/propale/");
+
+                // Load file with numbering class (if found)
+                $mybool|=@include_once $dir.$file;
+            }
 
             if (! $mybool)
             {
@@ -2581,14 +2578,14 @@ class Propal extends CommonObject
                 return $numref;
             }
             else
-            {
+			{
                 $this->error=$obj->error;
                 //dol_print_error($db,"Propale::getNextNumRef ".$obj->error);
                 return "";
             }
         }
         else
-        {
+		{
             $langs->load("errors");
             print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete");
             return "";
diff --git a/htdocs/comm/prospect/list.php b/htdocs/comm/prospect/list.php
index dcebc06a43df73e26a00a73d04a0a1c5173663ef..896168baa801e79b6c32423cf573795030f5bb4e 100644
--- a/htdocs/comm/prospect/list.php
+++ b/htdocs/comm/prospect/list.php
@@ -177,11 +177,13 @@ $parameters=array();
 $reshook=$hookmanager->executeHooks('doActions',$parameters);    // Note that $action and $object may have been modified by some hooks
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-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/card.php b/htdocs/commande/card.php
index 4c2e279418b8adbf9242feadadecc948847513e1..2296e8bd0a0776bc8cb9b5faead093b4839e5a73 100644
--- a/htdocs/commande/card.php
+++ b/htdocs/commande/card.php
@@ -102,641 +102,767 @@ $parameters = array('socid' => $socid);
 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-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 (empty($reshook))
 {
-	if (1==0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers'))
-	{
-		setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors');
-	}
-	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);
+			setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors');
+		}
+		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);
+				$result=$object->createFromClone($socid);
+				if ($result > 0)
+				{
+					header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
+					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='.$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->thirdparty->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
+				$object->generateDocument($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->thirdparty->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
-			$object->generateDocument($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 == '') {
-		setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentities('Date')), 'errors');
-		$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->fk_account = GETPOST('fk_account', 'int');
-		$object->availability_id = GETPOST('availability_id');
-		$object->demand_reason_id = GETPOST('demand_reason_id');
-		$object->date_livraison = $datelivraison;
-        $object->shipping_method_id = GETPOST('shipping_method_id', 'int');
-		$object->fk_delivery_address = GETPOST('fk_address');
-		$object->contactid = GETPOST('contactid');
-
-		// 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 == '') {
+			setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentities('Date')), 'errors');
+			$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->fk_account = GETPOST('fk_account', 'int');
+			$object->availability_id = GETPOST('availability_id');
+			$object->demand_reason_id = GETPOST('demand_reason_id');
+			$object->date_livraison = $datelivraison;
+	        $object->shipping_method_id = GETPOST('shipping_method_id', 'int');
+			$object->fk_delivery_address = GETPOST('fk_address');
+			$object->contactid = GETPOST('contactid');
+
+			// 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 {
+							setEventMessage($srcobject->error, 'errors');
 							$error ++;
+						}
 					} else {
-						setEventMessage($srcobject->error, 'errors');
+						setEventMessage($object->error, 'errors');
 						$error ++;
 					}
 				} else {
-					setEventMessage($object->error, 'errors');
-					$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('contactid')) {
-				$result = $object->add_contact(GETPOST('contactid'), 'CUSTOMER', 'external');
-				if ($result < 0) {
-					setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors');
-					$error ++;
+			// Insert default contacts if defined
+			if ($object_id > 0) {
+				if (GETPOST('contactid')) {
+					$result = $object->add_contact(GETPOST('contactid'), 'CUSTOMER', 'external');
+					if ($result < 0) {
+						setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors');
+						$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';
+				setEventMessage($object->error, 'errors');
+			}
 		}
+	}
 
-		// 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';
+	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) {
+			setEventMessage($object->error, 'errors');
 		}
 	}
-}
 
-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) {
-		setEventMessage($object->error, 'errors');
+		$result = $object->set_date_livraison($user, $datelivraison);
+		if ($result < 0) {
+			setEventMessage($object->error, 'errors');
+		}
 	}
-}
-
-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) {
-		setEventMessage($object->error, 'errors');
+	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->thirdparty->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->thirdparty->default_lang;
-			if (! empty($newlang)) {
-				$outputlangs = new Translate("", $conf);
-				$outputlangs->setDefaultLang($newlang);
+				$ret = $object->fetch($object->id); // Reload to get new records
+				$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 			}
-
-			$ret = $object->fetch($object->id); // Reload to get new records
-			$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 		}
 	}
-}
-
-// bank account
-else if ($action == 'setbankaccount' && $user->rights->commande->creer) {
-    $result=$object->setBankAccount(GETPOST('fk_account', 'int'));
-}
-
-// shipping method
-else if ($action == 'setshippingmethod' && $user->rights->commande->creer) {
-    $result = $object->setShippingMethod(GETPOST('shipping_method_id', 'int'));
-}
-
-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'));
-}
+	// bank account
+	else if ($action == 'setbankaccount' && $user->rights->commande->creer) {
+	    $result=$object->setBankAccount(GETPOST('fk_account', 'int'));
+	}
 
-// Add a new line
-else if ($action == 'addline' && $user->rights->commande->creer) {
-	$langs->load('errors');
-	$error = 0;
+	// shipping method
+	else if ($action == 'setshippingmethod' && $user->rights->commande->creer) {
+	    $result = $object->setShippingMethod(GETPOST('shipping_method_id', 'int'));
+	}
 
-	// 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 (! $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);
-
-			$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->thirdparty, $prod->id);
-				$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
-				$pu_ht = $prod->price;
-				$pu_ttc = $prod->price_ttc;
-				$price_min = $prod->price_min;
-				$price_base_type = $prod->price_base_type;
+		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 ++;
+		}
 
-				// multiprix
-				if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level))
-				{
-					$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
-					$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
-					$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
-					$price_base_type = $prod->multiprices_base_type[$object->thirdparty->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];
-					$tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level];
-					$tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level];
-				}
-				elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
-				{
-					require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
+		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);
+
+				$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->thirdparty, $prod->id);
+					$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
+					$pu_ht = $prod->price;
+					$pu_ttc = $prod->price_ttc;
+					$price_min = $prod->price_min;
+					$price_base_type = $prod->price_base_type;
+
+					// multiprix
+					if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level))
+					{
+						$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
+						$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
+						$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
+						$price_base_type = $prod->multiprices_base_type[$object->thirdparty->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];
+						$tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level];
+						$tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->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)
+						$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
+						if ($result >= 0)
+						{
+							if (count($prodcustprice->lines) > 0)
+							{
+								$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 = 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;
+							setEventMessage($prodcustprice->error,'errors');
 						}
 					}
-					else
-					{
-						setEventMessage($prodcustprice->error,'errors');
+
+					// 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 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');
-				}
+					// 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 = '';
+
+					// 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->thirdparty->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);
+					}
+
+				$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->thirdparty);
+			$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty);
+
+			$desc = dol_htmlcleanlastbr($desc);
+
+			$info_bits = 0;
+			if ($tva_npr)
+				$info_bits |= 0x01;
 
-				// 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->thirdparty->default_lang;
-					if (! empty($newlang)) {
-						$outputlangs = new Translate("", $conf);
-						$outputlangs->setDefaultLang($newlang);
+			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->thirdparty->default_lang;
+						if (! empty($newlang)) {
+							$outputlangs = new Translate("", $conf);
+							$outputlangs->setDefaultLang($newlang);
+						}
+
+						$object->generateDocument($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;
+					setEventMessage($object->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);
-				}
+	/*
+	 *  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;
 
-			$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 vat_rate
+		$vat_rate = str_replace('*', '', $vat_rate);
+		$localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty);
+		$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
+
+		// 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]);
+			}
 		}
 
-		// Margin
-		$fournprice = (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
-		$buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : '');
+		// Check minimum price
+		$productid = GETPOST('productid', 'int');
+		if (! empty($productid)) {
+			$product = new Product($db);
+			$product->fetch($productid);
 
-		// Local Taxes
-		$localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty);
-		$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty);
+			$type = $product->type;
 
-		$desc = dol_htmlcleanlastbr($desc);
+			$price_min = $product->price_min;
+			if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level))
+				$price_min = $product->multiprices_min [$object->thirdparty->price_level];
 
-		$info_bits = 0;
-		if ($tva_npr)
-			$info_bits |= 0x01;
+			$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, $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->thirdparty->default_lang;
 					if (! empty($newlang)) {
 						$outputlangs = new Translate("", $conf);
 						$outputlangs->setDefaultLang($newlang);
 					}
 
+					$ret = $object->fetch($object->id); // Reload to get new records
 					$object->generateDocument($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']);
@@ -746,459 +872,337 @@ 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->thirdparty);
-	$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
-
-	// 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;
+	else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->commande->valider) {
+		$idwarehouse = GETPOST('idwarehouse');
 
-		$price_min = $product->price_min;
-		if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level))
-			$price_min = $product->multiprices_min [$object->thirdparty->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 ++;
+	    $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++;
+				setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors');
+				$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))
-					$newlang = $object->thirdparty->default_lang;
-				if (! empty($newlang)) {
-					$outputlangs = new Translate("", $conf);
-					$outputlangs->setDefaultLang($newlang);
-				}
+				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+				{
+					$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->thirdparty->default_lang;
+					if (! empty($newlang)) {
+						$outputlangs = new Translate("", $conf);
+						$outputlangs->setDefaultLang($newlang);
+					}
+					$model=$object->modelpdf;
+					$ret = $object->fetch($id); // Reload to get new records
 
-				$ret = $object->fetch($object->id); // Reload to get new records
-				$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+					$object->generateDocument($model, $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');
-
-    $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);
-	}
+	// Go back to draft status
+	else if ($action == 'confirm_modif' && $user->rights->commande->creer) {
+		$idwarehouse = GETPOST('idwarehouse');
 
-	// Check parameters
-	if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change)
-	{
-		if (! $idwarehouse || $idwarehouse == -1)
+	    $qualified_for_stock_change=0;
+		if (empty($conf->global->STOCK_SUPPORTS_SERVICES))
 		{
-			$error++;
-			setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors');
-			$action='';
+		   	$qualified_for_stock_change=$object->hasProductsOrServices(2);
+		}
+		else
+		{
+		   	$qualified_for_stock_change=$object->hasProductsOrServices(1);
 		}
-	}
 
-	if (! $error) {
-		$result = $object->valid($user, $idwarehouse);
-		if ($result >= 0)
+		// Check parameters
+		if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change)
 		{
-			// Define output language
-			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+			if (! $idwarehouse || $idwarehouse == -1)
 			{
-				$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->thirdparty->default_lang;
-				if (! empty($newlang)) {
-					$outputlangs = new Translate("", $conf);
-					$outputlangs->setDefaultLang($newlang);
-				}
-				$model=$object->modelpdf;
-				$ret = $object->fetch($id); // Reload to get new records
-
-				$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
+				$error++;
+				setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors');
+				$action='';
 			}
 		}
-	}
-}
 
-// Go back to draft status
-else if ($action == 'confirm_modif' && $user->rights->commande->creer) {
-	$idwarehouse = GETPOST('idwarehouse');
+		if (! $error) {
+			$result = $object->set_draft($user, $idwarehouse);
+			if ($result >= 0)
+			{
+				// Define output language
+				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+				{
+					$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->thirdparty->default_lang;
+					if (! empty($newlang)) {
+						$outputlangs = new Translate("", $conf);
+						$outputlangs->setDefaultLang($newlang);
+					}
+					$model=$object->modelpdf;
+					$ret = $object->fetch($id); // Reload to get new records
 
-    $qualified_for_stock_change=0;
-	if (empty($conf->global->STOCK_SUPPORTS_SERVICES))
-	{
-	   	$qualified_for_stock_change=$object->hasProductsOrServices(2);
+					$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
+				}
+			}
+		}
 	}
-	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++;
-			setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors');
-			$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)
+		// Check parameters
+		if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change)
 		{
-			// Define output language
-			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+			if (! $idwarehouse || $idwarehouse == -1)
 			{
-				$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->thirdparty->default_lang;
-				if (! empty($newlang)) {
-					$outputlangs = new Translate("", $conf);
-					$outputlangs->setDefaultLang($newlang);
-				}
-				$model=$object->modelpdf;
-				$ret = $object->fetch($id); // Reload to get new records
-
-				$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
+				$error++;
+				setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors');
+				$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);
+
+			if ($result < 0) {
+				setEventMessage($object->error, 'errors');
+			}
+		}
 	}
-}
 
-else if ($action == 'confirm_cancel' && $confirm == 'yes' && $user->rights->commande->valider) {
-	$idwarehouse = GETPOST('idwarehouse');
+	/*
+	 * Ordonnancement des lignes
+	*/
 
-    $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 == 'up' && $user->rights->commande->creer) {
+		$object->line_up(GETPOST('rowid'));
 
-	// Check parameters
-	if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $qualified_for_stock_change)
-	{
-		if (! $idwarehouse || $idwarehouse == -1)
-		{
-			$error++;
-			setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")), 'errors');
-			$action='';
+		// 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->thirdparty->default_lang;
+		if (! empty($newlang)) {
+			$outputlangs = new Translate("", $conf);
+			$outputlangs->setDefaultLang($newlang);
 		}
-	}
 
-	if (! $error) {
-		$result = $object->cancel($idwarehouse);
-
-		if ($result < 0) {
-			setEventMessage($object->error, 'errors');
+		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+			$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 		}
-	}
-}
 
-/*
- * 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->thirdparty->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)) {
-		$object->generateDocument($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->thirdparty->default_lang;
+		if (! empty($newlang)) {
+			$outputlangs = new Translate("", $conf);
+			$outputlangs->setDefaultLang($newlang);
+		}
+		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+			$object->generateDocument($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->thirdparty->default_lang;
-	if (! empty($newlang)) {
-		$outputlangs = new Translate("", $conf);
-		$outputlangs->setDefaultLang($newlang);
-	}
-	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-		$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+		header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#' . GETPOST('rowid'));
+		exit();
 	}
 
-	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->thirdparty->default_lang;
+		if (! empty($newlang)) {
+			$outputlangs = new Translate("", $conf);
+			$outputlangs->setDefaultLang($newlang);
+		}
+		$result = $object->generateDocument($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->thirdparty->default_lang;
-	if (! empty($newlang)) {
-		$outputlangs = new Translate("", $conf);
-		$outputlangs->setDefaultLang($newlang);
+		if ($result <= 0) {
+			dol_print_error($db, $result);
+			exit();
+		}
 	}
-	$result = $object->generateDocument($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';
+
+			$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 = '';
+		}
 	}
-}
 
-// 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 = '';
-	}
-}
+	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 ++;
 
-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) {
+		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 ++;
-			}
-		} else if ($reshook < 0)
-			$error ++;
-	}
+		}
 
-	if ($error)
-		$action = 'edit_extras';
-}
+		if ($error)
+			$action = 'edit_extras';
+	}
 
-include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
+	include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php';
 
 
-/*
- * Send mail
- */
+	/*
+	 * Send mail
+	 */
 
-// Actions to send emails
-$actiontypecode='AC_COM';
-$trigger_name='ORDER_SENTBYMAIL';
-$paramname='id';
-$mode='emailfromorder';
-include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
+	// Actions to send emails
+	$actiontypecode='AC_COM';
+	$trigger_name='ORDER_SENTBYMAIL';
+	$paramname='id';
+	$mode='emailfromorder';
+	include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
 
 
 
-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");
-				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->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);
+			}
 		}
 	}
 }
 
+
 /*
  *	View
  */
diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
index 967402b8d947d83fb9609f14d9a7e3bc9ed32560..8a7005c9feae3ed8b8eff3f92ba51ea2e31df024 100644
--- a/htdocs/commande/class/commande.class.php
+++ b/htdocs/commande/class/commande.class.php
@@ -140,26 +140,25 @@ class Commande extends CommonOrder
 
         if (! empty($conf->global->COMMANDE_ADDON))
         {
-		$mybool=false;
-		$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
-		foreach ($dirmodels as $reldir)
-		{
-	            $file = $conf->global->COMMANDE_ADDON.".php";
-	            $classname = $conf->global->COMMANDE_ADDON;
-
-	            // Include file with class
-	            foreach ($conf->file->dol_document_root as $dirroot)
-	            {
-	            	$dir = $dirroot.$reldir."/core/modules/commande/";
-	            	// Load file with numbering class (if found)
-	            	$mybool|=@include_once $dir.$file;
-	            }
-		}
+        	$mybool=false;
+
+        	$file = $conf->global->COMMANDE_ADDON.".php";
+			$classname = $conf->global->COMMANDE_ADDON;
+
+			// Include file with class
+			$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
+			foreach ($dirmodels as $reldir)
+			{
+                $dir = dol_buildpath($reldir."core/modules/commande/");
+
+                // Load file with numbering class (if found)
+                $mybool|=@include_once $dir.$file;
+            }
 
             if (! $mybool)
             {
-            	dol_print_error('',"Failed to include file ".$file);
-            	return '';
+                dol_print_error('',"Failed to include file ".$file);
+                return '';
             }
 
             $obj = new $classname();
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index 82b2b56d1eea2224d4da2c11b7499089d2f24ab7..13e8fa381feda40577eabe9c3f9be7df71e056b3 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -106,6 +106,7 @@ $hookmanager->initHooks(array('invoicecard','globalcard'));
 
 $permissionnote = $user->rights->facture->creer; // Used by the include of actions_setnotes.inc.php
 
+
 /*
  * Actions
  */
@@ -114,1274 +115,1430 @@ $parameters = array('socid' => $socid);
 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-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' && $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 = '';
+				}
+			}
+	//	}
+	}
 
-// 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);
+	// 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 = '';
 			}
 		}
-//	}
-}
+	}
+
+	// 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);
+		}
 
-// 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);
+		$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(GETPOST('lineid'));
+		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->thirdparty->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 = $object->generateDocument($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(GETPOST("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(GETPOST('lineid'));
-	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->thirdparty->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 = $object->generateDocument($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) {
+				setEventMessage($langs->trans("ErrorInvoiceAvoirMustBeNegative"), 'errors');
+				$action = '';
+			}
+		} else {
+			// Si non avoir, le signe doit etre positif
+			if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) {
+				setEventMessage($langs->trans("ErrorInvoiceOfThisTypeMustBePositive"), 'errors');
+				$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(GETPOST("discountid"));
-	$discount->unlink_invoice();
-}
+	else if ($action == 'set_thirdparty' && $user->rights->facture->creer)
+	{
+		$object->fetch($id);
+		$object->setValueFrom('fk_soc', $socid);
 
-// Validation
-else if ($action == 'valid' && $user->rights->facture->creer)
-{
-	$object->fetch($id);
+		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) {
-			setEventMessage($langs->trans("ErrorInvoiceAvoirMustBeNegative"), 'errors');
-			$action = '';
-		}
-	} else {
-		// Si non avoir, le signe doit etre positif
-		if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) {
-			setEventMessage($langs->trans("ErrorInvoiceOfThisTypeMustBePositive"), 'errors');
-			$action = '';
-		}
+	else if ($action == 'classin' && $user->rights->facture->creer)
+	{
+		$object->fetch($id);
+		$object->setProject($_POST['projectid']);
 	}
-}
 
-else if ($action == 'set_thirdparty' && $user->rights->facture->creer)
-{
-	$object->fetch($id);
-	$object->setValueFrom('fk_soc', $socid);
+	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);
+	}
 
-	header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
-	exit();
-}
+	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 == 'classin' && $user->rights->facture->creer)
-{
-	$object->fetch($id);
-	$object->setProject($_POST['projectid']);
-}
+	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 == '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);
-}
+		$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 == '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))
+	else if ($action == 'setpaymentterm' && $user->rights->facture->creer)
 	{
-	    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 == 'setconditions' && $user->rights->facture->creer)
-{
-	$object->fetch($id);
-	$object->cond_reglement_code = 0; // To clean property
-	$object->cond_reglement_id = 0; // To clean property
-	$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
-	if ($result < 0) dol_print_error($db, $object->error);
-
-	$old_date_lim_reglement = $object->date_lim_reglement;
-	$new_date_lim_reglement = $object->calculate_date_lim_reglement();
-	if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement = $new_date_lim_reglement;
-	if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement = $object->date;
-	$result = $object->update($user);
-	if ($result < 0) dol_print_error($db, $object->error);
-}
+		$object->fetch($id);
+		$object->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');
-	}
-	$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 == '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);
-}
+	// bank account
+	else if ($action == 'setbankaccount' && $user->rights->facture->creer)
+	{
+	    $result=$object->setBankAccount(GETPOST('fk_account', 'int'));
+	}
 
-// bank account
-else if ($action == 'setbankaccount' && $user->rights->facture->creer)
-{
-    $result=$object->setBankAccount(GETPOST('fk_account', 'int'));
-}
+	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) {
+					setEventMessage($object->error, 'errors');
+				}
+			} 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) {
-				setEventMessage($object->error, 'errors');
+				setEventMessage($discount->error, 'errors');
 			}
-		} 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) {
-			setEventMessage($discount->error, 'errors');
-		}
+	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))
+		// Check for mandatory prof id
+		for($i = 1; $i < 6; $i ++)
 		{
-			if (! $error)
-				$langs->load("errors");
-			$error ++;
+			$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
-			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+			$result = $object->validate($user, '', $idwarehouse);
+			if ($result >= 0)
 			{
-				$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->thirdparty->default_lang;
-				if (! empty($newlang)) {
-					$outputlangs = new Translate("", $conf);
-					$outputlangs->setDefaultLang($newlang);
-				}
-				$model=$object->modelpdf;
-				$ret = $object->fetch($id); // Reload to get new records
+				// Define output language
+				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+				{
+					$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->thirdparty->default_lang;
+					if (! empty($newlang)) {
+						$outputlangs = new Translate("", $conf);
+						$outputlangs->setDefaultLang($newlang);
+					}
+					$model=$object->modelpdf;
+					$ret = $object->fetch($id); // Reload to get new records
 
-				$result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
-    			if ($result < 0) dol_print_error($db,$result);
+					$result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
+	    			if ($result < 0) dol_print_error($db,$result);
+				}
+			}
+			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, '');
 			}
-		} else {
-			dol_print_error($db, '');
-		}
 
-		$resteapayer = $object->total_ttc - $totalpaye;
+			$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 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');
+			// 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
-			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
-			{
-				$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->thirdparty->default_lang;
-				if (! empty($newlang)) {
-					$outputlangs = new Translate("", $conf);
-					$outputlangs->setDefaultLang($newlang);
-				}
-				$model=$object->modelpdf;
-				$ret = $object->fetch($id); // Reload to get new records
+				// Define output language
+				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+				{
+					$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->thirdparty->default_lang;
+					if (! empty($newlang)) {
+						$outputlangs = new Translate("", $conf);
+						$outputlangs->setDefaultLang($newlang);
+					}
+					$model=$object->modelpdf;
+					$ret = $object->fetch($id); // Reload to get new records
 
-				$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
+					$object->generateDocument($model, $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);
+	// 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');
-	} else {
-		setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), '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)
+	// Convertir en reduc
+	else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer)
 	{
-		$db->begin();
+		$object->fetch($id);
+		$object->fetch_thirdparty();
+		//$object->fetch_lines();	// Already done into fetch
 
-		// 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 ++;
-		}
+		// 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);
 
-		// 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;
+		$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();
 
-		$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;
+			// 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($error))
-		{
-			// Classe facture
-			$result = $object->set_paid($user);
-			if ($result >= 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;
+
+			$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))
 			{
-				$db->commit();
+				// Classe facture
+				$result = $object->set_paid($user);
+				if ($result >= 0)
+				{
+					$db->commit();
+				}
+				else
+				{
+					setEventMessage($object->error,'errors');
+					$db->rollback();
+				}
 			}
 			else
 			{
-				setEventMessage($object->error,'errors');
+				setEventMessage($discount->error,'errors');
 				$db->rollback();
 			}
 		}
-		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');
+	/*
+	 * Insert new invoice in database
+	*/
+	else if ($action == 'add' && $user->rights->facture->creer)
+	{
+		if ($socid > 0) $object->socid = GETPOST('socid', 'int');
 
-	$db->begin();
+		$db->begin();
 
-	$error = 0;
+		$error = 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 ++;
+		// 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 ++;
 
-	// Replacement invoice
-	if ($_POST['type'] == Facture::TYPE_REPLACEMENT)
-	{
-		$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-		if (empty($dateinvoice))
+		// Replacement invoice
+		if ($_POST['type'] == Facture::TYPE_REPLACEMENT)
 		{
-			$error++;
-			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
-		}
-
-		if (! ($_POST['fac_replacement'] > 0)) {
-			$error ++;
-			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), 'errors');
-		}
+			$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) {
-			// This is a replacement invoice
-			$result = $object->fetch($_POST['fac_replacement']);
-			$object->fetch_thirdparty();
+			if (! ($_POST['fac_replacement'] > 0)) {
+				$error ++;
+				setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), 'errors');
+			}
 
-			$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->fk_account         = GETPOST('fk_account', 'int');
-			$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) {
-				setEventMessage($object->error, '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->fk_account         = GETPOST('fk_account', 'int');
+				$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) {
+					setEventMessage($object->error, 'errors');
+				}
 			}
 		}
-	}
 
-	// Credit note invoice
-	if ($_POST['type'] == Facture::TYPE_CREDIT_NOTE)
-	{
-		if (! ($_POST['fac_avoir'] > 0))
+		// Credit note invoice
+		if ($_POST['type'] == Facture::TYPE_CREDIT_NOTE)
 		{
-			$error ++;
-			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CorrectInvoice")), 'errors');
-		}
+			if (! ($_POST['fac_avoir'] > 0))
+			{
+				$error ++;
+				setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CorrectInvoice")), 'errors');
+			}
 
-		$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-		if (empty($dateinvoice))
-		{
-			$error ++;
-			setEventMessage($langs->trans("ErrorFieldRequired", $langs->trans("Date")), 'errors');
-		}
+			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			if (empty($dateinvoice))
+			{
+				$error ++;
+				setEventMessage($langs->trans("ErrorFieldRequired", $langs->trans("Date")), 'errors');
+			}
 
-		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->fk_account         = GETPOST('fk_account', 'int');
-			$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)
+			if (! $error)
 			{
-                $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);
-				}
-			}*/
-		}
-	}
+				$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->fk_account         = GETPOST('fk_account', 'int');
+				$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;
 
-	// Standard invoice or Deposit invoice created from a Predefined invoice
-	if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT) && $_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');
-		}
+				$id = $object->create($user);
 
-		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'];
+				if (GETPOST('invoiceAvoirWithLines', 'int')==1 && $id>0)
+				{
+	                $facture_source = new Facture($db); // fetch origin object
+	                if ($facture_source->fetch($object->fk_facture_source)>0)
+	                {
 
-			// Source facture
-			$object->fac_rec = $_POST['fac_rec'];
+	                    foreach($facture_source->lines as $line)
+	                    {
+	                        $line->fk_facture = $object->id;
 
-			$id = $object->create($user);
-		}
-	}
+	                        $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;
 
-	// Standard or deposit or proforma invoice
-	if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT || $_POST['type'] == Facture::TYPE_PROFORMA || ($_POST['type'] == Facture::TYPE_SITUATION && empty($_POST['situations']))) && $_POST['fac_rec'] <= 0)
-	{
-		if (GETPOST('socid', 'int') < 1)
-		{
-			$error ++;
-			setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors');
+	                        $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);
+					}
+				}*/
+			}
 		}
 
-		$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-		if (empty($dateinvoice))
+		// Standard invoice or Deposit invoice created from a Predefined invoice
+		if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT) && $_POST['fac_rec'] > 0)
 		{
-			$error++;
-			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors');
+			$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'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT || $_POST['type'] == Facture::TYPE_PROFORMA || ($_POST['type'] == Facture::TYPE_SITUATION && empty($_POST['situations']))) && $_POST['fac_rec'] <= 0)
 		{
-			// 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->fk_account         = GETPOST('fk_account', 'int');
-			$object->amount				= $_POST['amount'];
-			$object->remise_absolue		= $_POST['remise_absolue'];
-			$object->remise_percent		= $_POST['remise_percent'];
-
-			if($_POST['type'] == Facture::TYPE_SITUATION) {
-				$object->situation_counter = 1;
-				$object->situation_final = 0;
-				$object->situation_cycle_ref = $object->newCycle();
+			if (GETPOST('socid', 'int') < 1)
+			{
+				$error ++;
+				setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors');
 			}
 
-			$object->fetch_thirdparty();
-
-			// If creation from another object of another module (Example: origin=propal, originid=1)
-			if ($origin && $originid)
+			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			if (empty($dateinvoice))
 			{
-				// Parse element/subelement (ex: project_task)
-				$element = $subelement = $origin;
-				if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
-					$element = $regs [1];
-					$subelement = $regs [2];
-				}
+				$error++;
+				setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'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';
+			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->fk_account         = GETPOST('fk_account', 'int');
+				$object->amount				= $_POST['amount'];
+				$object->remise_absolue		= $_POST['remise_absolue'];
+				$object->remise_percent		= $_POST['remise_percent'];
+
+				if (GETPOST('type') == Facture::TYPE_SITUATION)
+				{
+					$object->situation_counter = 1;
+					$object->situation_final = 0;
+					$object->situation_cycle_ref = $object->newCycle();
 				}
 
-				$object->origin = $origin;
-				$object->origin_id = $originid;
+				$object->fetch_thirdparty();
 
-				// Possibility to add external linked objects with hooks
-				$object->linked_objects[$object->origin] = $object->origin_id;
-				// link with order if it is a shipping invoice
-				if ($object->origin == 'shipping')
+				// If creation from another object of another module (Example: origin=propal, originid=1)
+				if ($origin && $originid)
 				{
-					require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
-					$exp = new Expedition($db);
-					$exp->fetch($object->origin_id);
-					$exp->fetchObjectLinked();
-					if (count($exp->linkedObjectsIds['commande']) > 0) $object->linked_objects['commande'] = $exp->linkedObjectsIds['commande'][0];
-				}
+					// Parse element/subelement (ex: project_task)
+					$element = $subelement = $origin;
+					if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
+						$element = $regs [1];
+						$subelement = $regs [2];
+					}
 
-				if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects']))
-				{
-					$object->linked_objects = array_merge($object->linked_objects, $_POST['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';
+					}
+					if ($element == 'inter') {
+						$element = $subelement = 'ficheinter';
+					}
+					if ($element == 'shipping') {
+						$element = $subelement = 'expedition';
+					}
 
-				$id = $object->create($user);
+					$object->origin = $origin;
+					$object->origin_id = $originid;
 
-				if ($id > 0)
-				{
-					// If deposit invoice
-					if ($_POST['type'] == Facture::TYPE_DEPOSIT)
+					// Possibility to add external linked objects with hooks
+					$object->linked_objects[$object->origin] = $object->origin_id;
+					// link with order if it is a shipping invoice
+					if ($object->origin == 'shipping')
+					{
+						require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
+						$exp = new Expedition($db);
+						$exp->fetch($object->origin_id);
+						$exp->fetchObjectLinked();
+						if (count($exp->linkedObjectsIds['commande']) > 0) $object->linked_objects['commande'] = $exp->linkedObjectsIds['commande'][0];
+					}
+
+					if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects']))
 					{
-						$typeamount = GETPOST('typedeposit', 'alpha');
-						$valuedeposit = GETPOST('valuedeposit', 'int');
+						$object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
+					}
+
+					$id = $object->create($user);
 
-						if ($typeamount == 'amount')
+					if ($id > 0)
+					{
+						// If deposit invoice
+						if ($_POST['type'] == Facture::TYPE_DEPOSIT)
 						{
-							$amountdeposit = $valuedeposit;
+							$typeamount = GETPOST('typedeposit', 'alpha');
+							$valuedeposit = GETPOST('valuedeposit', 'int');
+
+							if ($typeamount == 'amount')
+							{
+								$amountdeposit = $valuedeposit;
+							}
+							else
+							{
+								$amountdeposit = 0;
+
+								dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
+
+								$classname = ucfirst($subelement);
+								$srcobject = new $classname($db);
+
+								dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add deposit 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 ($totalamount != 0) {
+										$amountdeposit = ($totalamount * $valuedeposit) / 100;
+									}
+								} else {
+									setEventMessage($srcobject->error, 'errors');
+									$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
 						{
-							$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++)
+								{
+									// Don't add lines with qty 0 when coming from a shipment including all order lines
+									if($srcobject->element == 'shipping' && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS && $lines[$i]->qty == 0) continue;
+
+									$label=(! empty($lines[$i]->label)?$lines[$i]->label:'');
+									$desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle);
+									if ($object->situation_counter == 1) $lines[$i]->situation_percent =  0;
+
+									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 {
+											setEventMessage($discount->error, 'errors');
+											$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, $lines[$i]->situation_percent, $lines[$i]->fk_prev_id);
+
+										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 {
 								setEventMessage($srcobject->error, 'errors');
 								$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 {
+						setEventMessage($object->error, 'errors');
+						$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');
+		if (GETPOST('type') == Facture::TYPE_SITUATION && (!empty($_POST['situations'])))
+		{
+			$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			if (empty($datefacture)) {
+				$error++;
+				$mesg = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
+			}
 
-						$classname = ucfirst($subelement);
-						$srcobject = new $classname($db);
+			if (!($_POST['situations'] > 0)) {
+				$error++;
+				$mesg = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceSituation")) . '</div>';
+			}
 
-						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;
-							}
+			if (!$error) {
+				$result = $object->fetch($_POST['situations']);
+				$object->fk_facture_source = $_POST['situations'];
+				$object->type = Facture::TYPE_SITUATION;
+
+				$object->fetch_thirdparty();
+				$object->date = $datefacture;
+				$object->note_public = trim($_POST['note_public']);
+				$object->note = trim($_POST['note']);
+				$object->ref_client = $_POST['ref_client'];
+				$object->ref_int = $_POST['ref_int'];
+				$object->modelpdf = $_POST['model'];
+				$object->fk_project = $_POST['projectid'];
+				$object->cond_reglement_id = $_POST['cond_reglement_id'];
+				$object->mode_reglement_id = $_POST['mode_reglement_id'];
+				$object->remise_absolue = $_POST['remise_absolue'];
+				$object->remise_percent = $_POST['remise_percent'];
+
+				// Proprietes particulieres a facture de remplacement
+
+				$object->situation_counter = $object->situation_counter + 1;
+				$id = $object->createFromCurrent($user);
+				if ($id <= 0) $mesg = $object->error;
+			}
+		}
 
-							$fk_parent_line=0;
-							$num=count($lines);
-							for ($i=0;$i<$num;$i++)
-							{
-								// Don't add lines with qty 0 when coming from a shipment including all order lines
-								if($srcobject->element == 'shipping' && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS && $lines[$i]->qty == 0) continue;
+		// 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"];
+			setEventMessages($object->error, $object->errors, 'errors');
+		}
+	}
 
-								$label=(! empty($lines[$i]->label)?$lines[$i]->label:'');
-								$desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle);
-								if ($object->situation_counter == 1) $lines[$i]->situation_percent =  0;
+	// Add a new line
+	else if ($action == 'addline' && $user->rights->facture->creer)
+	{
+		$langs->load('errors');
+		$error = 0;
 
-								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 {
-										setEventMessage($discount->error, 'errors');
-										$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;
-									}
+		// 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]);
+			}
+		}
 
-									// 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;
-									}
+		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 ($qty < 0) {
+			$langs->load("errors");
+			setEventMessage($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), '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();
+
+			// 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->thirdparty, $prod->id);
+					$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
+					$pu_ht = $prod->price;
+					$pu_ttc = $prod->price_ttc;
+					$price_min = $prod->price_min;
+					$price_base_type = $prod->price_base_type;
+
+					// We define price for product
+					if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level))
+					{
+						$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
+						$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
+						$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
+						$price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
+						if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level];
+						if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level];
+					}
+					elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
+					{
+						require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
 
-									$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, $lines[$i]->situation_percent, $lines[$i]->fk_prev_id);
+						$prodcustprice = new Productcustomerprice($db);
 
-									if ($result > 0) {
-										$lineid = $result;
-									} else {
-										$lineid = 0;
-										$error ++;
-										break;
-									}
+						$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
 
-									// Defined the new fk_parent_line
-									if ($result > 0 && $lines[$i]->product_type == 9) {
-										$fk_parent_line = $result;
-									}
-								}
+						$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
+						if ($result) {
+							if (count($prodcustprice->lines) > 0) {
+								$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;
 							}
+						}
+					}
 
-							// 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 ++;
+					// 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');
+					}
+
+					// 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 {
-							setEventMessage($srcobject->error, 'errors');
-							$error ++;
+							$pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
 						}
 					}
-				} else {
-					setEventMessage($object->error, 'errors');
-					$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);
-					}
-				}
-			}
-		}
-	}
+					$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->thirdparty->default_lang;
+						if (! empty($newlang)) {
+							$outputlangs = new Translate("", $conf);
+							$outputlangs->setDefaultLang($newlang);
+						}
 
-	if ($_POST['type'] == Facture::TYPE_SITUATION && (!empty($_POST['situations']))) {
-		$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
-		if (empty($datefacture)) {
-			$error++;
-			$mesg = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
-		}
+						$desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
+					} else {
+						$desc = $prod->description;
+					}
 
-		if (!($_POST['situations'] > 0)) {
-			$error++;
-			$mesg = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceSituation")) . '</div>';
-		}
+					$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);
+					}
 
-		if (!$error) {
-			$result = $object->fetch($_POST['situations']);
-			$object->fk_facture_source = $_POST['situations'];
-			$object->type = Facture::TYPE_SITUATION;
+				$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');
+			}
 
-			$object->fetch_thirdparty();
-			$object->date = $datefacture;
-			$object->note_public = trim($_POST['note_public']);
-			$object->note = trim($_POST['note']);
-			$object->ref_client = $_POST['ref_client'];
-			$object->ref_int = $_POST['ref_int'];
-			$object->modelpdf = $_POST['model'];
-			$object->fk_project = $_POST['projectid'];
-			$object->cond_reglement_id = $_POST['cond_reglement_id'];
-			$object->mode_reglement_id = $_POST['mode_reglement_id'];
-			$object->remise_absolue = $_POST['remise_absolue'];
-			$object->remise_percent = $_POST['remise_percent'];
+			// Margin
+			$fournprice = price2num(GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
+			$buyingprice = price2num(GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : '');
 
-			// Proprietes particulieres a facture de remplacement
+			// Local Taxes
+			$localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty);
+			$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty);
 
-			$object->situation_counter = $object->situation_counter + 1;
-			$id = $object->createFromCurrent($user);
-			if ($id <= 0) $mesg = $object->error;
-		}
-	}
+			$info_bits = 0;
+			if ($tva_npr)
+				$info_bits |= 0x01;
 
-	// 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"];
-		setEventMessages($object->error, $object->errors, 'errors');
-	}
-}
+			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, $_POST['progress']);
 
-// 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 = '';
-	}
+				if ($result > 0)
+				{
+					// Define output language
+					if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+					{
+						$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->thirdparty->default_lang;
+						if (! empty($newlang)) {
+							$outputlangs = new Translate("", $conf);
+							$outputlangs->setDefaultLang($newlang);
+						}
+						$model=$object->modelpdf;
+						$ret = $object->fetch($id); // Reload to get new records
+
+						$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
+					}
 
-	$qty = GETPOST('qty' . $predef);
-	$remise_percent = GETPOST('remise_percent' . $predef);
+					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']);
+
+					unset($_POST['situations']);
+					unset($_POST['progress']);
+				} else {
+					setEventMessage($object->error, 'errors');
+				}
 
-	// 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]);
+				$action = '';
+			}
 		}
 	}
 
-	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 ''
+	elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel'))
 	{
-		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 ($qty < 0) {
-		$langs->load("errors");
-		setEventMessage($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), '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 (! $object->fetch($id) > 0)	dol_print_error($db);
+		$object->fetch_thirdparty();
 
 		// 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->thirdparty, $prod->id);
-				$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
-				$pu_ht = $prod->price;
-				$pu_ttc = $prod->price_ttc;
-				$price_min = $prod->price_min;
-				$price_base_type = $prod->price_base_type;
-
-				// We define price for product
-				if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level))
-				{
-					$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
-					$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
-					$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
-					$price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
-					if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level];
-					if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->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);
+		$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);
+		$qty = GETPOST('qty');
+
+		// Define info_bits
+		$info_bits = 0;
+		if (preg_match('/\*/', $vat_rate))
+			$info_bits |= 0x01;
 
-					$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
-					if ($result) {
-						if (count($prodcustprice->lines) > 0) {
-							$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;
-						}
-					}
-				}
+			// Define vat_rate
+		$vat_rate = str_replace('*', '', $vat_rate);
+		$localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty);
+		$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
+
+		// 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]);
+			}
+		}
 
-				// 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');
-				}
+		$line = new FactureLigne($db);
+		$line->fetch(GETPOST('lineid'));
+		$percent = $line->get_prev_progress();
 
-				// 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');
-					}
-				}
+		if (GETPOST('progress') < $percent)
+		{
+			$mesg = '<div class="warning">' . $langs->trans("CantBeLessThanMinPercent") . '</div>';
+			setEventMessages($mesg, null, 'warnings');
+			$error++;
+			$result = -1;
+		}
 
-				$desc = '';
+		// Check minimum price
+		$productid = GETPOST('productid', 'int');
+		if (! empty($productid))
+		{
+			$product = new Product($db);
+			$product->fetch($productid);
 
-				// 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->thirdparty->default_lang;
-					if (! empty($newlang)) {
-						$outputlangs = new Translate("", $conf);
-						$outputlangs->setDefaultLang($newlang);
-					}
+			$type = $product->type;
 
-					$desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
-				} else {
-					$desc = $prod->description;
-				}
+			$price_min = $product->price_min;
+			if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level))
+				$price_min = $product->multiprices_min [$object->thirdparty->price_level];
 
-				$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);
-				}
+			$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
 
-			$type = $prod->type;
+			// 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 {
-			$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->thirdparty);
-		$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty);
+			$label = (GETPOST('product_label') ? GETPOST('product_label') : '');
 
-		$info_bits = 0;
-		if ($tva_npr)
-			$info_bits |= 0x01;
+			// Check parameters
+			if (GETPOST('type') < 0) {
+				setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors');
+				$error ++;
+			}
+		}
+		if ($qty < 0) {
+			$langs->load("errors");
+			setEventMessage($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), 'errors');
+			$error ++;
+		}
 
-		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, $_POST['progress']);
+		// Update line
+		if (! $error) {
+			$result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $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, GETPOST('progress'));
 
-			if ($result > 0)
-			{
-				// Define output language
-				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
-				{
+			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','alpha');
-					if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $object->thirdparty->default_lang;
+					if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id'))
+						$newlang = GETPOST('lang_id');
+					if ($conf->global->MAIN_MULTILANGS && empty($newlang))
+						$newlang = $object->thirdparty->default_lang;
 					if (! empty($newlang)) {
 						$outputlangs = new Translate("", $conf);
 						$outputlangs->setDefaultLang($newlang);
 					}
-					$model=$object->modelpdf;
-					$ret = $object->fetch($id); // Reload to get new records
 
-					$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
+					$ret = $object->fetch($id); // Reload to get new records
+					$object->generateDocument($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']);
@@ -1393,6 +1550,7 @@ else if ($action == 'addline' && $user->rights->facture->creer)
 				unset($_POST['buying_price']);
 				unset($_POST['np_marginRate']);
 				unset($_POST['np_markRate']);
+
 				unset($_POST['dp_desc']);
 				unset($_POST['idprod']);
 
@@ -1414,294 +1572,163 @@ else if ($action == 'addline' && $user->rights->facture->creer)
 			} 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);
-	$qty = GETPOST('qty');
-
-	// 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->thirdparty);
-	$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
-
-	// 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]);
-		}
-	}
-
-	$line = new FactureLigne($db);
-	$line->fetch(GETPOST('lineid'));
-	$percent = $line->get_prev_progress();
-
-	if (GETPOST('progress') < $percent) {
-		$mesg = '<div class="warning">' . $langs->trans("CantBeLessThanMinPercent") . '</div>';
-		setEventMessages($mesg, null, 'warnings');
-		$error++;
-		$result = -1;
-	}
-
-	// 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->thirdparty->price_level))
-			$price_min = $product->multiprices_min [$object->thirdparty->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 == 'updatealllines' && $user->rights->facture->creer && $_POST['all_percent'] == $langs->trans('Modifier'))
+	{
+		if (!$object->fetch($id) > 0) dol_print_error($db);
+		if (!is_null(GETPOST('all_progress')) && GETPOST('all_progress') != "")
+		{
+			foreach ($object->lines as $line)
+			{
+				$percent = $line->get_prev_progress();
+				if (GETPOST('all_progress') < $percent) {
+					$mesg = '<div class="warning">' . $langs->trans("CantBeLessThanMinPercent") . '</div>';
+					$result = -1;
+				} else
+					$object->update_percent($line, $_POST['all_progress']);
+			}
 		}
 	}
-	if ($qty < 0) {
-		$langs->load("errors");
-		setEventMessage($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), 'errors');
-		$error ++;
-	}
 
-	// Update line
-	if (! $error) {
-		$result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $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, GETPOST('progress'));
+	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();
+	}
 
-		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->thirdparty->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
-				$object->generateDocument($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']);
-			unset($_POST['np_marginRate']);
-			unset($_POST['np_markRate']);
-			unset($_POST['situations']);
-			unset($_POST['progress']);
-		} 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->thirdparty->default_lang;
+		if (! empty($newlang)) {
+			$outputlangs = new Translate("", $conf);
+			$outputlangs->setDefaultLang($newlang);
 		}
-	}
-}
+		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+			$object->generateDocument($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']);
 
-else if ($action == 'updatealllines' && $user->rights->facture->creer && $_POST['all_percent'] == $langs->trans('Modifier')) {
-	if (!$object->fetch($id) > 0) dol_print_error($db);
-	if (!is_null(GETPOST('all_progress')) && GETPOST('all_progress') != "") {
-		foreach ($object->lines as $line) {
-			$percent = $line->get_prev_progress();
-			if (GETPOST('all_progress') < $percent) {
-				$mesg = '<div class="warning">' . $langs->trans("CantBeLessThanMinPercent") . '</div>';
-				$result = -1;
-			} else
-				$object->update_percent($line, $_POST['all_progress']);
+		// 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->thirdparty->default_lang;
+		if (! empty($newlang)) {
+			$outputlangs = new Translate("", $conf);
+			$outputlangs->setDefaultLang($newlang);
 		}
+		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+			$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+		}
+
+		header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']);
+		exit();
 	}
-}
 
-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();
-}
+	// Link invoice to order
+	if (GETPOST('linkedOrder')) {
+		$object->fetch($id);
+		$object->fetch_thirdparty();
+		$result = $object->add_object_linked('commande', GETPOST('linkedOrder'));
+	}
 
-// 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->thirdparty->default_lang;
-	if (! empty($newlang)) {
-		$outputlangs = new Translate("", $conf);
-		$outputlangs->setDefaultLang($newlang);
-	}
-	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-		$object->generateDocument($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->thirdparty->default_lang;
-	if (! empty($newlang)) {
-		$outputlangs = new Translate("", $conf);
-		$outputlangs->setDefaultLang($newlang);
-	}
-	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
-		$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-	}
-
-	header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']);
-	exit();
-}
 
-// Link invoice to order
-if (GETPOST('linkedOrder')) {
-	$object->fetch($id);
-	$object->fetch_thirdparty();
-	$result = $object->add_object_linked('commande', GETPOST('linkedOrder'));
-}
+	/*
+	 * Send mail
+	 */
 
+	// Actions to send emails
+	if (empty($id)) $id=$facid;
+	$actiontypecode='AC_FAC';
+	$trigger_name='BILL_SENTBYMAIL';
+	$paramname='id';
+	$mode='emailfrominvoice';
+	include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
 
-/*
- * Send mail
- */
 
-// Actions to send emails
-if (empty($id)) $id=$facid;
-$actiontypecode='AC_FAC';
-$trigger_name='BILL_SENTBYMAIL';
-$paramname='id';
-$mode='emailfrominvoice';
-include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
+	/*
+	 * Generate document
+	 */
+	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');
 
-/*
- * Generate document
- */
-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->thirdparty->default_lang;
-	if (! empty($newlang))
-	{
-		$outputlangs = new Translate("", $conf);
-		$outputlangs->setDefaultLang($newlang);
-	}
-	$result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
-	if ($result <= 0)
-	{
-		dol_print_error($db, $result);
-		exit();
+		// 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->thirdparty->default_lang;
+		if (! empty($newlang))
+		{
+			$outputlangs = new Translate("", $conf);
+			$outputlangs->setDefaultLang($newlang);
+		}
+		$result = $object->generateDocument($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');
-		$action = '';
+			$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 = '';
+		}
 	}
-}
 
-include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
+	include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
 
-if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer)
-{
-	if ($action == 'addcontact')
+	if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer)
 	{
-		$result = $object->fetch($id);
+		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);
@@ -1717,16 +1744,18 @@ if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture-
 	}
 
 	// bascule du statut d'un contact
-	else if ($action == 'swapstatut') {
+	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') {
+	else if ($action == 'deletecontact')
+	{
 		$object->fetch($id);
 		$result = $object->delete_contact($lineid);
 
@@ -1737,35 +1766,37 @@ if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture-
 			dol_print_error($db);
 		}
 	}
-}
 
-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)
+
+	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)
-		$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('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';
+		}
+	}
+}
 
 
 /*
@@ -2038,6 +2069,8 @@ if ($action == 'create')
 
 	if ($socid > 0)
 	{
+		if (! empty($conf->global->INVOICE_USE_SITUATION))
+		{
 		// First situation invoice
 		print '<tr height="18"><td width="16px" valign="middle">';
 		print '<input type="radio" name="type" value="5"' . (GETPOST('type') == 5 ? ' checked="checked"' : '') . '>';
@@ -2060,7 +2093,8 @@ if ($action == 'create')
 		$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceSituationDesc"), 1);
 		print $desc;
 		print '</td></tr>' . "\n";
-
+		}
+		
 		// Replacement
 		print '<tr height="18"><td valign="middle">';
 		print '<input type="radio" name="type" id="radio_replacement" value="1"' . (GETPOST('type') == 1 ? ' checked="checked"' : '');
@@ -2372,7 +2406,7 @@ if ($action == 'create')
 	// Button "Create Draft"
 	print '<br><div class="center">';
 	print '<input type="submit" class="button" name="bouton" value="' . $langs->trans('CreateDraft') . '">';
-	print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+	print '&nbsp; &nbsp; &nbsp;';
 	print '<input type="button" class="button" value="' . $langs->trans("Cancel") . '" onClick="javascript:history.go(-1)">';
 	print '</div>';
 
@@ -3194,7 +3228,10 @@ if ($action == 'create')
 	print '</tr>';
 
 	// Situations
-	if ($object->type == 5 && ($object->situation_counter > 1)) {
+	if (! empty($conf->global->INVOICE_US_SITUATION))
+	{
+	if ($object->type == 5 && ($object->situation_counter > 1)) 
+	{
 		$prevsits = $object->get_prev_sits();
 		print '<tr><td>';
 		print $langs->trans('SituationAmount');
@@ -3236,7 +3273,8 @@ if ($action == 'create')
 			print '<td>' . $langs->trans('Currency' . $conf->currency) . '</td></tr>';
 		}
 	}
-
+	}
+	
 	// Amount
 	print '<tr><td>' . $langs->trans('AmountHT') . '</td>';
 	print '<td align="right" colspan="3" nowrap>' . price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency) . '</td></tr>';
@@ -3334,6 +3372,13 @@ if ($action == 'create')
 	// Lines
 	$result = $object->getLinesArray();
 
+	print '	<form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (($action != 'editline') ? '#add' : '#line_' . GETPOST('lineid')) . '" method="POST">
+	<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">
+	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateligne') . '">
+	<input type="hidden" name="mode" value="">
+	<input type="hidden" name="id" value="' . $object->id . '">
+	';
+
 	if (! empty($conf->use_javascript_ajax) && $object->statut == 0) {
 		include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
 	}
@@ -3341,6 +3386,8 @@ if ($action == 'create')
 	print '<table id="tablelines" class="noborder noshadow" width="100%">';
 
 	// Show global modifiers
+	if (! empty($conf->global->INVOICE_US_SITUATION))
+	{
 	if ($object->situation_cycle_ref && $object->statut == 0) {
 		print '<tr class="liste_titre nodrag nodrop">';
 		print '<form name="updatealllines" id="updatealllines" action="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '"#updatealllines" method="POST">';
@@ -3385,14 +3432,8 @@ if ($action == 'create')
 		print '</tr>';
 		print '</form>';
 	}
-
-	print '	<form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (($action != 'editline') ? '#add' : '#line_' . GETPOST('lineid')) . '" method="POST">
-	<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">
-	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateligne') . '">
-	<input type="hidden" name="mode" value="">
-	<input type="hidden" name="id" value="' . $object->id . '">
-	';
-
+	}
+	
 	// Show object lines
 	if (! empty($object->lines))
 		$ret = $object->printObjectLines($action, $mysoc, $soc, $lineid, 1);
@@ -3465,7 +3506,7 @@ if ($action == 'create')
 			}
 
 			// Validate
-			if ($object->statut == 0 && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA|| $object->type == Facture::TYPE_SITUATION) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) {
+			if ($object->statut == 0 && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) {
 				if ($user->rights->facture->valider) {
 					print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&amp;action=valid">' . $langs->trans('Validate') . '</a></div>';
 				}
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index a6cf04715f274cd0a1acfcf0b396740a9d265e51..278d8ca70e406c4c58c72c896a4f29f9dc369270 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -2609,52 +2609,64 @@ class Facture extends CommonInvoice
 		else if ($conf->global->FACTURE_ADDON=='terre') $conf->global->FACTURE_ADDON='mod_facture_terre';
 		else if ($conf->global->FACTURE_ADDON=='mercure') $conf->global->FACTURE_ADDON='mod_facture_mercure';
 
-		$mybool=false;
-
-		$file = $conf->global->FACTURE_ADDON.".php";
-		$classname = $conf->global->FACTURE_ADDON;
-		// Include file with class
-		foreach ($conf->file->dol_document_root as $dirroot)
+		if (! empty($conf->global->FACTURE_ADDON))
 		{
-			$dir = $dirroot."/core/modules/facture/";
-			// Load file with numbering class (if found)
-			$mybool|=@include_once $dir.$file;
-		}
+			$mybool=false;
+
+			$file = $conf->global->FACTURE_ADDON.".php";
+			$classname = $conf->global->FACTURE_ADDON;
 
-		// For compatibility
-		if (! $mybool)
-		{
-			$file = $conf->global->FACTURE_ADDON."/".$conf->global->FACTURE_ADDON.".modules.php";
-			$classname = "mod_facture_".$conf->global->FACTURE_ADDON;
-			$classname = preg_replace('/\-.*$/','',$classname);
 			// Include file with class
-			foreach ($conf->file->dol_document_root as $dirroot)
-			{
-				$dir = $dirroot."/core/modules/facture/";
+			$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+
+			foreach ($dirmodels as $reldir) {
+
+				$dir = dol_buildpath($reldir."core/modules/facture/");
+
 				// Load file with numbering class (if found)
 				$mybool|=@include_once $dir.$file;
 			}
-		}
-		//print "xx".$mybool.$dir.$file."-".$classname;
 
-		if (! $mybool)
-		{
-			dol_print_error('',"Failed to include file ".$file);
-			return '';
-		}
+			// For compatibility
+			if (! $mybool)
+			{
+				$file = $conf->global->FACTURE_ADDON."/".$conf->global->FACTURE_ADDON.".modules.php";
+				$classname = "mod_facture_".$conf->global->FACTURE_ADDON;
+				$classname = preg_replace('/\-.*$/','',$classname);
+				// Include file with class
+				foreach ($conf->file->dol_document_root as $dirroot)
+				{
+					$dir = $dirroot."/core/modules/facture/";
+					// Load file with numbering class (if found)
+					$mybool|=@include_once $dir.$file;
+				}
+			}
 
-		$obj = new $classname();
-		$numref = "";
-		$numref = $obj->getNumRef($soc,$this,$mode);
+			if (! $mybool)
+			{
+				dol_print_error('',"Failed to include file ".$file);
+				return '';
+			}
 
-		if ($numref != "")
-		{
-			return $numref;
+			$obj = new $classname();
+			$numref = "";
+			$numref = $obj->getNextValue($soc,$this,$mode);
+
+			if ($numref != "")
+			{
+				return $numref;
+			}
+			else
+			{
+				dol_print_error($db,"Facture::getNextNumRef ".$obj->error);
+				return "";
+			}
 		}
 		else
 		{
-			//dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error);
-			return false;
+			$langs->load("errors");
+			print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete");
+			return "";
 		}
 	}
 
diff --git a/htdocs/compta/facture/impayees.php b/htdocs/compta/facture/impayees.php
index 0c6b2af84f0f0836847f1ed1f1112fb2054b6b5f..13190ce6e1016674fe465c89dd67f37a8984aca5 100644
--- a/htdocs/compta/facture/impayees.php
+++ b/htdocs/compta/facture/impayees.php
@@ -553,7 +553,7 @@ if ($resql)
 	print_liste_field_titre($langs->trans("Taxes"),$_SERVER["PHP_SELF"],"f.tva","",$param,'align="right"',$sortfield,$sortorder);
 	print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER["PHP_SELF"],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder);
 	print_liste_field_titre($langs->trans("Received"),$_SERVER["PHP_SELF"],"am","",$param,'align="right"',$sortfield,$sortorder);
-	print_liste_field_titre($langs->trans("Rest"),$_SERVER["PHP_SELF"],"am","",$param,'align="right"',$sortfield,$sortorder);
+	print_liste_field_titre($langs->trans("Rest"),$_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
 	print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"fk_statut,paye,am","",$param,'align="right"',$sortfield,$sortorder);
 	if (empty($mode))
 	{
diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php
index fabf656c89543bef36bce13292fb799de24e5fb1..7432a7d14fd3f9fc09de4a1810e5256057d227ce 100644
--- a/htdocs/compta/paiement.php
+++ b/htdocs/compta/paiement.php
@@ -71,185 +71,188 @@ if ($facid > 0)
 // Initialize technical object to manage hooks of paiements. Note that conf->hooks_modules contains array array
 $hookmanager->initHooks(array('paiementcard','globalcard'));
 
-$parameters=array('socid'=>$socid);
-$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
-if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
-
 
 /*
  * Actions
  */
 
-if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes'))
+$parameters=array('socid'=>$socid);
+$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
+if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+
+if (empty($reshook))
 {
-    $error = 0;
+	if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes'))
+	{
+	    $error = 0;
 
-    $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
-    $paiement_id = 0;
-    $totalpayment = 0;
-    $atleastonepaymentnotnull = 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)
-    {
-        if (substr($key,0,7) == 'amount_')
-        {
-            $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))
+	    // 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)
+	    {
+	        if (substr($key,0,7) == 'amount_')
+	        {
+	            $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])
 	            {
-	            	$langs->load("errors");
-	                //$error++;
-	                setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings');
+		            // 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)
+	        {
+	            setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('AccountToCredit')), 'errors');
+	            $error++;
+	        }
+	    }
 
-    if (empty($totalpayment) && empty($atleastonepaymentnotnull))
-    {
-        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))
+	    {
+	        setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors');
+	        $error++;
+	    }
+	}
 
-/*
- * Action add_paiement
- */
-if ($action == 'add_paiement')
-{
-    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 = 'create';
+	    }
+	    // 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'));
 
-    $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
+	    // Clean parameters amount if payment is for a credit note
+	    if (GETPOST('type') == 2)
 	    {
-	    	$newvalue = price2num($value,'MT');
-	    	$amounts[$key] = -$newvalue;
+		    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++;
-    	}
-    }
-
-    // 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 (! 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 (! $error)
-    {
-    	$paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices')=='on'?1:0));
-    	if ($paiement_id < 0)
-        {
-            setEventMessage($paiement->error, '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'];
 
-    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)
-        {
-            setEventMessage($paiement->error, 'errors');
-            $error++;
-        }
-    }
+	    if (! $error)
+	    {
+	    	$paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices')=='on'?1:0));
+	    	if ($paiement_id < 0)
+	        {
+	            setEventMessage($paiement->error, 'errors');
+	            $error++;
+	        }
+	    }
 
-    if (! $error)
-    {
-        $db->commit();
+	    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)
+	        {
+	            setEventMessage($paiement->error, 'errors');
+	            $error++;
+	        }
+	    }
 
-        // 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)
-        {
-            $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/card.php?id='.$paiement_id;
-        header('Location: '.$loc);
-        exit;
-    }
-    else
-    {
-        $db->rollback();
-    }
+	    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)
+	        {
+	            $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/card.php?id='.$paiement_id;
+	        header('Location: '.$loc);
+	        exit;
+	    }
+	    else
+	    {
+	        $db->rollback();
+	    }
+	}
 }
 
 
diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php
index e4fa1e05d290c095d9892c1e2a1a0973917f3ce8..db4c436dfa69cdd4991e8f0fc4f534dfdcab722a 100644
--- a/htdocs/compta/prelevement/class/bonprelevement.class.php
+++ b/htdocs/compta/prelevement/class/bonprelevement.class.php
@@ -736,7 +736,7 @@ class BonPrelevement extends CommonObject
     function Create($banque=0, $agence=0, $mode='real')
     {
         global $conf,$langs;
-        
+
         dol_syslog(__METHOD__."::Bank=".$banque." Office=".$agence, LOG_DEBUG);
 
         require_once (DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php");
@@ -782,7 +782,7 @@ class BonPrelevement extends CommonObject
             //if ($agence) $sql.= " AND sr.code_guichet = '".$conf->global->PRELEVEMENT_CODE_GUICHET."'";
 
             dol_syslog(__METHOD__."::Read invoices, sql=".$sql, LOG_DEBUG);
-            
+
             $resql = $this->db->query($sql);
             if ($resql)
             {
@@ -894,24 +894,23 @@ class BonPrelevement extends CommonObject
             if (!$error)
             {
 				$ref = substr($year,-2).$month;
-				
+
 				$sql = "SELECT substring(ref from char_length(ref) - 1)";
 				$sql.= " FROM ".MAIN_DB_PREFIX."prelevement_bons";
 				$sql.= " WHERE ref LIKE '%".$ref."%'";
 				$sql.= " AND entity = ".$conf->entity;
 				$sql.= " ORDER BY ref DESC LIMIT 1";
-				
+
 				dol_syslog(get_class($this)."::Create sql=".$sql, LOG_DEBUG);
-				dol_syslog(__METHOD__."::Treatments", LOG_DEBUG);
 				$resql = $this->db->query($sql);
 
 				if ($resql)
 				{
 					$row = $this->db->fetch_row($resql);
 					$ref = "T".$ref.str_pad(dol_substr("00".intval($row[0])+1),2,"0",STR_PAD_LEFT);
-	
+
 					$filebonprev = $ref;
-	                
+
 	                // Create withdraw receipt in database
 	                $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_bons (";
 	                $sql.= " ref, entity, datec";
@@ -920,18 +919,16 @@ class BonPrelevement extends CommonObject
 	                $sql.= ", ".$conf->entity;
 	                $sql.= ", '".$this->db->idate($now)."'";
 	                $sql.= ")";
-	
-	                dol_syslog(__METHOD__, LOG_DEBUG);
+
 	                $resql = $this->db->query($sql);
-	
 	                if ($resql)
 	                {
 	                    $prev_id = $this->db->last_insert_id(MAIN_DB_PREFIX."prelevement_bons");
-	
+
 	                    $dir=$conf->prelevement->dir_output.'/receipts';
 	                    $file=$filebonprev;
 	                    if (! is_dir($dir)) dol_mkdir($dir);
-	
+
 	                    $bonprev = new BonPrelevement($this->db, $dir."/".$file);
 	                    $bonprev->id = $prev_id;
 	                }
@@ -946,8 +943,6 @@ class BonPrelevement extends CommonObject
 					$error++;
 					dol_syslog(__METHOD__."::Get last withdraw receipt ".$this->db->error(), LOG_ERR);
 				}
-
-				
             }
 
             /*
@@ -1011,7 +1006,7 @@ class BonPrelevement extends CommonObject
                  */
 
             	dol_syslog(__METHOD__."::Init withdraw receipt for ".count($factures_prev)." invoices", LOG_DEBUG);
-              
+
                 if (count($factures_prev) > 0)
                 {
                     $bonprev->date_echeance = $datetimeprev;
@@ -1045,13 +1040,10 @@ class BonPrelevement extends CommonObject
             $sql.= " WHERE rowid = ".$prev_id;
             $sql.= " AND entity = ".$conf->entity;
 
-            dol_syslog(__METHOD__."::Update total, sql=".$sql, LOG_DEBUG);
-            
             $resql=$this->db->query($sql);
             if (! $resql)
             {
                 $error++;
-                dol_syslog("Erreur mise a jour du total - $sql");
                 dol_syslog(__METHOD__."::Error update total: ".$this->db->error(), LOG_ERR);
             }
 
diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php
index bbba602fa02f9b8d2e7a7e26fd7f22c74f2f130f..1417047b26968f0aba7c40082679f8affbbcba79 100644
--- a/htdocs/contrat/class/contrat.class.php
+++ b/htdocs/contrat/class/contrat.class.php
@@ -211,23 +211,31 @@ class Contrat extends CommonObject
 		global $db, $langs, $conf;
 		$langs->load("contracts");
 
-		$dir = DOL_DOCUMENT_ROOT . "/core/modules/contract";
-
-		if (empty($conf->global->CONTRACT_ADDON))
+		if (!empty($conf->global->CONTRACT_ADDON))
 		{
-		    $conf->global->CONTRACT_ADDON='mod_contract_serpis';
-		}
+			$mybool = false;
 
-		$file = $conf->global->CONTRACT_ADDON.".php";
+			$file = $conf->global->CONTRACT_ADDON.".php";
+			$classname = $conf->global->CONTRACT_ADDON;
 
-		// Chargement de la classe de numerotation
-		$classname = $conf->global->CONTRACT_ADDON;
+			// Include file with class
+			$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
 
-		$result=include_once $dir.'/'.$file;
-		if ($result)
-		{
-			$obj = new $classname();
+			foreach ($dirmodels as $reldir) {
+
+				$dir = dol_buildpath($reldir."core/modules/contract/");
+
+				// Load file with numbering class (if found)
+				$mybool|=@include_once $dir.$file;
+			}
+
+			if (! $mybool)
+			{
+				dol_print_error('',"Failed to include file ".$file);
+				return '';
+			}
 
+			$obj = new $classname();
 			$numref = "";
 			$numref = $obj->getNextValue($soc,$this);
 
@@ -237,15 +245,17 @@ class Contrat extends CommonObject
 			}
 			else
 			{
+				$this->error = $obj->error;
 				dol_print_error($db,get_class($this)."::getNextValue ".$obj->error);
 				return "";
 			}
 		}
 		else
 		{
-			print $langs->trans("Error")." ".$langs->trans("Error_CONTRACT_ADDON_NotDefined");
+			$langs->load("errors");
+			print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete");
 			return "";
-			}
+		}
 	}
 
 	/**
diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php
index 49de15293215d86b77a13fd0b0589d2c2790cdad..80385d3473585d98e2f6bc934a66cd1a3a461f81 100644
--- a/htdocs/core/actions_sendmails.inc.php
+++ b/htdocs/core/actions_sendmails.inc.php
@@ -103,7 +103,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
 			}
 			else	// Id du contact
 			{
-				$sendto = $thirdparty->contact_get_property($_POST['receiver'],'email');
+				$sendto = $thirdparty->contact_get_property((int) $_POST['receiver'],'email');
 				$sendtoid = $_POST['receiver'];
 			}
 		}
@@ -120,7 +120,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
 			}
 			else	// Id du contact
 			{
-				$sendtocc = $thirdparty->contact_get_property($_POST['receivercc'],'email');
+				$sendtocc = $thirdparty->contact_get_property((int) $_POST['receivercc'],'email');
 			}
 		}
 
diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php
index 30f5960e0ceec3ad6386de00ef03cae3bdb708b1..0f0f715922e840ebeba39908bfec4d6089e212d3 100644
--- a/htdocs/core/class/menubase.class.php
+++ b/htdocs/core/class/menubase.class.php
@@ -152,7 +152,7 @@ class Menubase
         $sql.= " '".$this->fk_menu."',";
         $sql.= " ".($this->fk_mainmenu?"'".$this->fk_mainmenu."'":"null").",";
         $sql.= " ".($this->fk_leftmenu?"'".$this->fk_leftmenu."'":"null").",";
-        $sql.= " '".$this->position."',";
+        $sql.= " '".(int) $this->position."',";
         $sql.= " '".$this->db->escape($this->url)."',";
         $sql.= " '".$this->db->escape($this->target)."',";
         $sql.= " '".$this->db->escape($this->titre)."',";
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index bd195e27eabf82d228c13a03baa6edcc0c33fb66..f8a43030dbcb5969213b155c5410f01d66478f57 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -2456,19 +2456,22 @@ function dol_print_error($db='',$error='')
 	if ($_SERVER['DOCUMENT_ROOT'])    // Mode web
 	{
 		$out.=$langs->trans("DolibarrHasDetectedError").".<br>\n";
-		if (! empty($conf->global->MAIN_FEATURES_LEVEL))
-		$out.="You use an experimental level of features, so please do NOT report any bugs, anywhere, until going back to MAIN_FEATURES_LEVEL = 0.<br>\n";
+		if (! empty($conf->global->MAIN_FEATURES_LEVEL)) $out.="You use an experimental level of features, so please do NOT report any bugs, anywhere, until going back to MAIN_FEATURES_LEVEL = 0.<br>\n";
 		$out.=$langs->trans("InformationToHelpDiagnose").":<br>\n";
 
-		$out.="<b>".$langs->trans("Date").":</b> ".dol_print_date(time(),'dayhourlog')."<br>\n";;
-		$out.="<b>".$langs->trans("Dolibarr").":</b> ".DOL_VERSION."<br>\n";;
-		if (isset($conf->global->MAIN_FEATURES_LEVEL)) $out.="<b>".$langs->trans("LevelOfFeature").":</b> ".$conf->global->MAIN_FEATURES_LEVEL."<br>\n";;
+		$out.="<b>".$langs->trans("Date").":</b> ".dol_print_date(time(),'dayhourlog')."<br>\n";
+		$out.="<b>".$langs->trans("Dolibarr").":</b> ".DOL_VERSION."<br>\n";
+		if (isset($conf->global->MAIN_FEATURES_LEVEL)) $out.="<b>".$langs->trans("LevelOfFeature").":</b> ".$conf->global->MAIN_FEATURES_LEVEL."<br>\n";
 		if (function_exists("phpversion"))
 		{
 			$out.="<b>".$langs->trans("PHP").":</b> ".phpversion()."<br>\n";
-			//phpinfo();       // This is to show location of php.ini file
 		}
 		$out.="<b>".$langs->trans("Server").":</b> ".$_SERVER["SERVER_SOFTWARE"]."<br>\n";
+		if (function_exists("php_uname"))
+		{
+			$out.="<b>".$langs->trans("OS").":</b> ".php_uname()."<br>\n";
+		}
+		$out.="<b>".$langs->trans("UserAgent").":</b> ".$_SERVER["HTTP_USER_AGENT"]."<br>\n";
 		$out.="<br>\n";
 		$out.="<b>".$langs->trans("RequestedUrl").":</b> ".dol_htmlentities($_SERVER["REQUEST_URI"],ENT_COMPAT,'UTF-8')."<br>\n";
 		$out.="<b>".$langs->trans("Referer").":</b> ".(isset($_SERVER["HTTP_REFERER"])?dol_htmlentities($_SERVER["HTTP_REFERER"],ENT_COMPAT,'UTF-8'):'')."<br>\n";
diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php
index 69dabf04219044c749516cf987971eb7dcecc257..e78e24c316a29955d8ea1156e85c26d0a1841cd2 100644
--- a/htdocs/core/modules/DolibarrModules.class.php
+++ b/htdocs/core/modules/DolibarrModules.class.php
@@ -344,7 +344,8 @@ abstract class DolibarrModules
 
 
     /**
-     * Gives the translated module name if translation exists in admin.lang or the default module name.
+     * Gives the translated module name if translation exists in admin.lang or into language files of module.
+     * Otherwise return the module key name.
      *
      * @return  string  Translated module name
      */
@@ -359,9 +360,16 @@ abstract class DolibarrModules
             return $langs->trans("Module".$this->numero."Name");
         }
         else
-        {
-            // If module name translation using it's unique id does not exists, we take its name
-            return $this->name;
+       {
+            // If module name translation using it's unique id does not exists, we take use its name to find translation
+            if (is_array($this->langfiles))
+            {
+            	foreach($this->langfiles as $val)
+            	{
+            		if ($val) $langs->load($val);
+            	}
+            }
+       		return $langs->trans($this->name);
         }
     }
 
@@ -382,9 +390,16 @@ abstract class DolibarrModules
             return $langs->trans("Module".$this->numero."Desc");
         }
         else
-        {
-	        // If module description translation using it's unique id does not exists, we take its description
-            return $this->description;
+		{
+            // If module description translation using it's unique id does not exists, we take use its name to find translation
+            if (is_array($this->langfiles))
+            {
+            	foreach($this->langfiles as $val)
+            	{
+            		if ($val) $langs->load($val);
+            	}
+            }
+       		return $langs->trans($this->description);
         }
     }
 
@@ -868,6 +883,8 @@ abstract class DolibarrModules
 
         $err=0;
 
+        if (empty($this->const)) return 0;
+
         foreach ($this->const as $key => $value)
         {
             $name      = $this->const[$key][0];
@@ -935,6 +952,8 @@ abstract class DolibarrModules
 
         $err=0;
 
+        if (empty($this->const)) return 0;
+
         foreach ($this->const as $key => $value)
         {
             $name      = $this->const[$key][0];
diff --git a/htdocs/core/modules/modDeplacement.class.php b/htdocs/core/modules/modDeplacement.class.php
index 75d3ab328c85f43622b94da644ac38e930daf85d..c536553ac4bcd2893912f3cbcd25a431a1826d6d 100644
--- a/htdocs/core/modules/modDeplacement.class.php
+++ b/htdocs/core/modules/modDeplacement.class.php
@@ -95,17 +95,17 @@ class modDeplacement extends DolibarrModules
 		$this->rights[3][3] = 0;
 		$this->rights[3][4] = 'supprimer';
 
-    	$this->rights[3][0] = 174;
-		$this->rights[3][1] = 'Lire toutes les notes de frais';
-		$this->rights[3][2] = 'd';
-		$this->rights[3][3] = 0;
-		$this->rights[3][4] = 'readall';
-
-		$this->rights[6][0] = 178;
-		$this->rights[6][1] = 'Exporter les notes de frais et deplacements';
-		$this->rights[6][2] = 'd';
-		$this->rights[6][3] = 0;
-		$this->rights[6][4] = 'export';
+    	$this->rights[4][0] = 174;
+		$this->rights[4][1] = 'Lire toutes les notes de frais';
+		$this->rights[4][2] = 'd';
+		$this->rights[4][3] = 0;
+		$this->rights[4][4] = 'readall';
+
+		$this->rights[5][0] = 178;
+		$this->rights[5][1] = 'Exporter les notes de frais et deplacements';
+		$this->rights[5][2] = 'd';
+		$this->rights[5][3] = 0;
+		$this->rights[5][4] = 'export';
 
 		// Exports
 		$r=0;
diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
index eca0da0f9a5de03540bc972a6d4abb2ac523ad36..15bef66bf8fe4da65b7828ff313a9ed3aa794fad 100644
--- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
+++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
@@ -125,7 +125,8 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
 			return 0;
 		}
 
-		$numFinal=get_next_value($db,$mask,'facture_fourn','ref','',$objsoc->code_fournisseur,$object->datef);
+	    //Supplier invoices take invoice date instead of creation date for the mask
+		$numFinal=get_next_value($db,$mask,'facture_fourn','ref','',$objsoc->code_fournisseur,$object->date);
 
 		return  $numFinal;
 	}
diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php
index 4c3ac6b69284ecc9a0722f882164199cca20f260..34d201c91440b92fced78924f18feffef09da6c4 100644
--- a/htdocs/cron/card.php
+++ b/htdocs/cron/card.php
@@ -353,16 +353,20 @@ if (($action=="create") || ($action=="edit"))
 	print "<tr><td>";
 	print $langs->trans('CronEvery')."</td>";
 	print "<td><select name=\"nbfrequency\">";
-	for($i=1; $i<=60; $i++){
-		if(($object->frequency/$object->unitfrequency) == $i){
+	for($i=1; $i<=60; $i++)
+	{
+		if (! empty($object->unitfrequency) && ($object->frequency/$object->unitfrequency) == $i)
+		{
 			print "<option value='".$i."' selected='selected'>".$i."</option>";
 		}
-		else{
+		else
+		{
 			print "<option value='".$i."'>".$i."</option>";
 		}
 	}
 	$input = "<input type=\"radio\" name=\"unitfrequency\" value=\"60\" id=\"frequency_minute\" ";
-	if($object->unitfrequency=="60"){
+	if($object->unitfrequency=="60")
+	{
 		$input .= ' checked="checked" />';
 	}
 	else{
diff --git a/htdocs/custom/.gitignore b/htdocs/custom/.gitignore
index 9420e8c61eb20b5a5e5003e42f1c99d41adffdd3..89ebd12182c93511c5f79e5e0a78e5197f401fa9 100644
--- a/htdocs/custom/.gitignore
+++ b/htdocs/custom/.gitignore
@@ -1,4 +1,4 @@
 /*
 !.gitignore
 !README.md
-!index.html
+!index.html
\ No newline at end of file
diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php
index 29260ba3bb61b7f72cf519ea45229f90fa16209b..c93ec795dec4138013a0186e12aceeb782e5e0b2 100644
--- a/htdocs/expedition/card.php
+++ b/htdocs/expedition/card.php
@@ -108,479 +108,313 @@ $parameters=array();
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-if ($action == 'add')
+if (empty($reshook))
 {
-    $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 ($totalqty > 0)
-    {
-        //var_dump($_POST);exit;
-        for ($i = 0; $i < $num; $i++)
-        {
-            $qty = "qtyl".$i;
-			if (! isset($batch_line[$i])) {
-				if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS))
-				{
-					$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='';
+	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;
 
-					$ret=$object->addline($entrepot_id,GETPOST($idl,'int'),GETPOST($qty,'int'));
-					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 {
-				if ($batch_line[$i]['qty']>0) {
-					$ret=$object->addline_batch($batch_line[$i]);
-					if ($ret < 0)
+				//Standard product
+				if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int');
+			}
+	    }
+
+	    if ($totalqty > 0)
+	    {
+	        //var_dump($_POST);exit;
+	        for ($i = 0; $i < $num; $i++)
+	        {
+	            $qty = "qtyl".$i;
+				if (! isset($batch_line[$i])) {
+					if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS))
 					{
-						$mesg='<div class="error">'.$object->error.'</div>';
-						$error++;
+						$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++;
-    }
-
-    if (! $error)
-    {
-        $db->commit();
-        header("Location: card.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/card.php?id='.$result);
-        exit;
-    }
-    else
-    {
-        $mesg=$object->error;
-    }
-}
-
-else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->expedition->valider)
-{
-    $object->fetch_thirdparty();
-
-    $result = $object->valid($user);
-
-    if ($result < 0)
-    {
-		$langs->load("errors");
-        setEventMessage($langs->trans($object->error),'errors');
-    }
-    else
-    {
-    	// Define output language
-    	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
-    	{
-    		$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->thirdparty->default_lang;
-    		if (! empty($newlang)) {
-    			$outputlangs = new Translate("", $conf);
-    			$outputlangs->setDefaultLang($newlang);
-    		}
-    		$model=$object->modelpdf;
-    		$ret = $object->fetch($id); // Reload to get new records
-
-    		$result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
-    		if ($result < 0) dol_print_error($db,$result);
-    	}
-    }
-}
+	        }
+
+	        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++;
+	    }
+
+	    if (! $error)
+	    {
+	        $db->commit();
+	        header("Location: card.php?id=".$object->id);
+	        exit;
+	    }
+	    else
+	    {
+	        $db->rollback();
+	        $_GET["commande_id"]=GETPOST('commande_id','int');
+	        $action='create';
+	    }
+	}
 
-else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->expedition->supprimer)
-{
-    $result = $object->delete();
-    if ($result > 0)
-    {
-        header("Location: ".DOL_URL_ROOT.'/expedition/index.php');
-        exit;
-    }
-    else
+	/*
+	 * Build a receiving receipt
+	 */
+	else if ($action == 'create_delivery' && $conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer)
 	{
-		$langs->load("errors");
-        setEventMessage($langs->trans($object->error),'errors');
-    }
-}
-
-else if ($action == 'reopen' && $user->rights->expedition->valider)
-{
-    $result = $object->setStatut(0);
-    if ($result < 0)
-    {
-        $mesg = $object->error;
-    }
-}
-
-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>';
-    }
-}
-
-// 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');
+	    $result = $object->create_delivery($user);
+	    if ($result > 0)
+	    {
+	        header("Location: ".DOL_URL_ROOT.'/livraison/card.php?id='.$result);
+	        exit;
+	    }
+	    else
+	    {
+	        $mesg=$object->error;
+	    }
 	}
-    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)
-    {
-        if ($object->update($user) >= 0)
-        {
-            header("Location: card.php?id=".$object->id);
-            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))
-    {
-        $outputlangs = new Translate("",$conf);
-        $outputlangs->setDefaultLang($newlang);
-    }
-	$result = $object->generateDocument($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';
-
-	$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';
-
-    // 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';
-}
-
-/*
- * Remove file in email form
-*/
-if (GETPOST('removedfile','alpha'))
-{
-    require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+	else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->expedition->valider)
+	{
+	    $object->fetch_thirdparty();
 
-    // Set tmp user directory
-    $vardir=$conf->user->dir_output."/".$user->id;
-    $upload_dir_tmp = $vardir.'/temp';
+	    $result = $object->valid($user);
 
-    // TODO Delete only files that was uploaded from email form
-    dol_remove_file_process(GETPOST('removedfile','int'),0);
-    $action ='presend';
-}
+	    if ($result < 0)
+	    {
+			$langs->load("errors");
+	        setEventMessage($langs->trans($object->error),'errors');
+	    }
+	    else
+	    {
+	    	// Define output language
+	    	if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+	    	{
+	    		$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->thirdparty->default_lang;
+	    		if (! empty($newlang)) {
+	    			$outputlangs = new Translate("", $conf);
+	    			$outputlangs->setDefaultLang($newlang);
+	    		}
+	    		$model=$object->modelpdf;
+	    		$ret = $object->fetch($id); // Reload to get new records
+
+	    		$result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
+	    		if ($result < 0) dol_print_error($db,$result);
+	    	}
+	    }
+	}
 
-include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
+	else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->expedition->supprimer)
+	{
+	    $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');
+	    }
+	}
 
-/*
- * Send mail
-*/
-if ($action == 'send' && ! GETPOST('addfile','alpha') && ! GETPOST('removedfile','alpha') && ! GETPOST('cancel','alpha'))
-{
-    $langs->load('mails');
+	else if ($action == 'reopen' && $user->rights->expedition->valider)
+	{
+	    $result = $object->setStatut(0);
+	    if ($result < 0)
+	    {
+	        $mesg = $object->error;
+	    }
+	}
 
-//        $ref = dol_sanitizeFileName($object->ref);
-//        $file = $conf->expedition->dir_output . '/sending/' . $ref . '/' . $ref . '.pdf';
+	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>';
+	    }
+	}
 
-//        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
-                {
-                    $sendto = $object->client->email;
-                    $sendtoid = 0;
-                }
-                else	// Id du contact
-                {
-                    $sendto = $object->client->contact_get_property(GETPOST('receiver','alpha'),'email');
-                    $sendtoid = GETPOST('receiver','alpha');
-                }
-            }
+	// 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 (! $error)
+	    {
+	        if ($object->update($user) >= 0)
+	        {
+	            header("Location: card.php?id=".$object->id);
+	            exit;
+	        }
+	        setEventMessage($object->error,'errors');
+	    }
+
+	    $action="";
+	}
 
-            if (dol_strlen($sendto))
-            {
-                $langs->load("commercial");
+	// 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))
+	    {
+	        $outputlangs = new Translate("",$conf);
+	        $outputlangs->setDefaultLang($newlang);
+	    }
+		$result = $object->generateDocument($object->modelpdf, $outputlangs);
+	    if ($result <= 0)
+	    {
+	        dol_print_error($db,$result);
+	        exit;
+	    }
+	}
 
-                $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');
+	// Delete file in doc form
+	elseif ($action == 'remove_file')
+	{
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 
-                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;
-                    if ($message)
-                    {
-						if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc);
-						$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject);
-						$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
-						$actionmsg = dol_concatdesc($actionmsg, $message);
-                    }
-                    $actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
-                }
+		$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');
+	}
 
-                // Create form object
-                include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
-                $formmail = new FormMail($db);
+	elseif ($action == 'classifybilled')
+	{
+	    $object->fetch($id);
+	    $object->set_billed();
+	}
 
-                $attachedfiles=$formmail->get_attached_files();
-                $filepath = $attachedfiles['paths'];
-                $filename = $attachedfiles['names'];
-                $mimetype = $attachedfiles['mimes'];
+	include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
 
-                // 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)
-                    {
-                        $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
-                    {
-                        $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>';
-                    }
-                }
-            }
-            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);
-        }*/
-}
+	// Actions to send emails
+	if (empty($id)) $id=$facid;
+	$actiontypecode='AC_SHIP';
+	$trigger_name='SHIPPING_SENTBYMAIL';
+	$paramname='id';
+	$mode='emailfromshipment';
+	include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
 
-else if ($action == 'classifybilled')
-{
-    $object->fetch($id);
-    $object->set_billed();
 }
 
 
diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php
index 46f2cbc70fe753bc47c43391669496a4ed8cf003..74d5251a191c834574169476e986aee93741e44b 100644
--- a/htdocs/expedition/class/expedition.class.php
+++ b/htdocs/expedition/class/expedition.class.php
@@ -121,21 +121,30 @@ class Expedition extends CommonObject
 		global $db, $langs, $conf;
 		$langs->load("sendings");
 
-		$dir = DOL_DOCUMENT_ROOT . "/core/modules/expedition";
-
-	    if (empty($conf->global->EXPEDITION_ADDON_NUMBER))
+	    if (!empty($conf->global->EXPEDITION_ADDON_NUMBER))
         {
-            $conf->global->EXPEDITION_ADDON_NUMBER='mod_expedition_safor';
-        }
+			$mybool = false;
 
-		$file = $conf->global->EXPEDITION_ADDON_NUMBER.".php";
+			$file = $conf->global->EXPEDITION_ADDON_NUMBER.".php";
+			$classname = $conf->global->EXPEDITION_ADDON_NUMBER;
 
-		// Chargement de la classe de numerotation
-		$classname = $conf->global->EXPEDITION_ADDON_NUMBER;
+	        // Include file with class
+	        $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+
+	        foreach ($dirmodels as $reldir) {
+
+		        $dir = dol_buildpath($reldir."core/modules/expedition/");
+
+		        // Load file with numbering class (if found)
+		        $mybool|=@include_once $dir.$file;
+	        }
+
+	        if (! $mybool)
+	        {
+		        dol_print_error('',"Failed to include file ".$file);
+		        return '';
+	        }
 
-		$result=include_once $dir.'/'.$file;
-		if ($result)
-		{
 			$obj = new $classname();
 			$numref = "";
 			$numref = $obj->getNextValue($soc,$this);
@@ -149,12 +158,12 @@ class Expedition extends CommonObject
 				dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error);
 				return "";
 			}
-		}
-		else
-		{
-			print $langs->trans("Error")." ".$langs->trans("Error_EXPEDITION_ADDON_NUMBER_NotDefined");
-			return "";
-		}
+        }
+	    else
+	    {
+		    print $langs->trans("Error")." ".$langs->trans("Error_EXPEDITION_ADDON_NUMBER_NotDefined");
+		    return "";
+	    }
 	}
 
 	/**
diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php
index b7887c252789145f863293383fcab76d77221eda..0f91e976da8884e871aa7b6157bdd4012d104ec7 100644
--- a/htdocs/fichinter/class/fichinter.class.php
+++ b/htdocs/fichinter/class/fichinter.class.php
@@ -574,25 +574,33 @@ class Fichinter extends CommonObject
 		global $conf, $db, $langs;
 		$langs->load("interventions");
 
-		$dir = DOL_DOCUMENT_ROOT . "/core/modules/fichinter/";
-
 		if (! empty($conf->global->FICHEINTER_ADDON))
 		{
-			$file = $conf->global->FICHEINTER_ADDON.".php";
-			$classname = $conf->global->FICHEINTER_ADDON;
-			if (! file_exists($dir.$file))
-			{
-				$file='mod_'.$file;
-				$classname='mod_'.$classname;
+			$mybool = false;
+
+			$file = "mod_".$conf->global->FICHEINTER_ADDON.".php";
+			$classname = "mod_".$conf->global->FICHEINTER_ADDON;
+
+			// Include file with class
+			$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+
+			foreach ($dirmodels as $reldir) {
+
+				$dir = dol_buildpath($reldir."core/modules/fichinter/");
+
+				// Load file with numbering class (if found)
+				$mybool|=@include_once $dir.$file;
 			}
 
-			// Chargement de la classe de numerotation
-			require_once $dir.$file;
+			if (! $mybool)
+			{
+				dol_print_error('',"Failed to include file ".$file);
+				return '';
+			}
 
 			$obj = new $classname();
-
 			$numref = "";
-			$numref = $obj->getNumRef($soc,$this);
+			$numref = $obj->getNextValue($soc,$this);
 
 			if ( $numref != "")
 			{
@@ -606,6 +614,7 @@ class Fichinter extends CommonObject
 		}
 		else
 		{
+			$langs->load("errors");
 			print $langs->trans("Error")." ".$langs->trans("Error_FICHEINTER_ADDON_NotDefined");
 			return "";
 		}
diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php
index 0447bd0a75870d133a70bd267cc2f4e0071a77bb..205d1a89ea61cb44db1b1f06d0d250d0b023f49b 100644
--- a/htdocs/fourn/card.php
+++ b/htdocs/fourn/card.php
@@ -41,6 +41,7 @@ $langs->load('companies');
 $langs->load('commercial');
 
 $action	= GETPOST('action');
+$cancelbutton = GETPOST('cancel');
 
 // Security check
 $id = (GETPOST('socid','int') ? GETPOST('socid','int') : GETPOST('id','int'));
@@ -60,10 +61,14 @@ $parameters=array('socid'=>$socid);
 $reshook=$hookmanager->executeHooks('doActions', $parameters, $object, $action);    // Note that $action and $object may have been modified by some hooks
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-if ($action == 'setsupplieraccountancycode')
+if (empty($reshook))
 {
-	$cancelbutton = GETPOST('cancel');
-	if (! $cancelbutton)
+	if ($cancelbutton)
+	{
+		$action = "";
+	}
+
+	if ($action == 'setsupplieraccountancycode')
 	{
 		$result=$object->fetch($id);
    		$object->code_compta_fournisseur=$_POST["supplieraccountancycode"];
@@ -73,21 +78,20 @@ if ($action == 'setsupplieraccountancycode')
 	        $mesg=join(',',$object->errors);
 	    }
 	}
-    $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);
+	}
 }
 
 
diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php
index b8c14f2879ef0a4aaba36c2b8da1e32c7f3ea4e0..77f131b912ba43c55eca49a90a04b5cb0e3c4094 100644
--- a/htdocs/fourn/class/fournisseur.commande.class.php
+++ b/htdocs/fourn/class/fournisseur.commande.class.php
@@ -557,44 +557,48 @@ class CommandeFournisseur extends CommonOrder
         global $db, $langs, $conf;
         $langs->load("orders");
 
-        $dir = DOL_DOCUMENT_ROOT .'/core/modules/supplier_order/';
-
         if (! empty($conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER))
         {
+            $mybool = false;
+
             $file = $conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER.'.php';
+            $classname=$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER;
 
-            if (is_readable($dir.'/'.$file))
-            {
-                // Definition du nom de modele de numerotation de commande fournisseur
-                $modName=$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER;
-                require_once $dir.'/'.$file;
+            // Include file with class
+            $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
 
-                // Recuperation de la nouvelle reference
-                $objMod = new $modName($this->db);
+            foreach ($dirmodels as $reldir) {
 
-                $numref = "";
-                $numref = $objMod->commande_get_num($soc,$this);
+                $dir = dol_buildpath($reldir."core/modules/supplier_order/");
 
-                if ( $numref != "")
-                {
-                    return $numref;
-                }
-                else
-                {
-                    dol_print_error($db, get_class($this)."::getNextNumRef ".$obj->error);
-                    return -1;
-                }
+                // Load file with numbering class (if found)
+                $mybool|=@include_once $dir.$file;
             }
-            else
+
+            if (! $mybool)
             {
-                print $langs->trans("Error")." ".$langs->trans("Error_FailedToLoad_COMMANDE_SUPPLIER_ADDON_File",$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER);
-                return -2;
+                dol_print_error('',"Failed to include file ".$file);
+                return '';
+            }
+
+            $obj = new $classname();
+            $numref = $obj->getNextValue($soc,$this);
+
+            if ( $numref != "")
+            {
+                return $numref;
+            }
+            else
+			{
+                $this->error = $obj->error;
+                dol_print_error($db, get_class($this)."::getNextNumRef ".$obj->error);
+                return -1;
             }
         }
         else
-        {
-            print $langs->trans("Error")." ".$langs->trans("Error_COMMANDE_SUPPLIER_ADDON_NotDefined");
-            return -3;
+		{
+            $this->error = "Error_COMMANDE_SUPPLIER_ADDON_NotDefined";
+            return -2;
         }
     }
 
diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
index b931b566a61613c74640c27505da7041f4992696..7370bc3769a42ab1f3fce46014d615425cbe6abe 100644
--- a/htdocs/fourn/class/fournisseur.facture.class.php
+++ b/htdocs/fourn/class/fournisseur.facture.class.php
@@ -1514,10 +1514,14 @@ class FactureFournisseur extends CommonInvoice
 
         $file = $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER.".php";
         $classname = $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER;
+
         // Include file with class
-        foreach ($conf->file->dol_document_root as $dirroot)
-        {
-            $dir = $dirroot."/core/modules/supplier_invoice/";
+        $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+
+        foreach ($dirmodels as $reldir) {
+
+            $dir = dol_buildpath($reldir."core/modules/supplier_invoice/");
+
             // Load file with numbering class (if found)
             $mybool|=@include_once $dir.$file;
         }
diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php
index b90bd275e4ccfbf6f8382111c145ec2a797ed4a6..57696363289746f2a1aecd09245c5e198e5cf01a 100644
--- a/htdocs/fourn/commande/card.php
+++ b/htdocs/fourn/commande/card.php
@@ -479,14 +479,16 @@ else if ($action == 'confirm_deleteproductline' && $confirm == 'yes' && $user->r
     $result = $object->deleteline(GETPOST('lineid'));
     if ($result	>= 0)
     {
-        $outputlangs = $langs;
-        if (GETPOST('lang_id'))
-        {
-            $outputlangs = new Translate("",$conf);
-            $outputlangs->setDefaultLang(GETPOST('lang_id'));
-        }
         if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
         {
+            $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->thirdparty->default_lang;
+            if (! empty($newlang)) {
+                $outputlangs = new Translate("", $conf);
+                $outputlangs->setDefaultLang($newlang);
+            }
             $ret=$object->fetch($object->id);    // Reload to get new records
 	        $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
         }
@@ -571,6 +573,14 @@ else if ($action == 'confirm_approve' && $confirm == 'yes' && $user->rights->fou
         if ($result > 0)
         {
             if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+                $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->thirdparty->default_lang;
+                if (! empty($newlang)) {
+                    $outputlangs = new Translate("", $conf);
+                    $outputlangs->setDefaultLang($newlang);
+                }
 	            $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
             }
             header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id);
diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php
index afd914546a66400ec4b2f45b6da9face7d1b1e59..0864a0bc2a59ad940c1f8b5403dda3682ffe4cb3 100644
--- a/htdocs/fourn/facture/paiement.php
+++ b/htdocs/fourn/facture/paiement.php
@@ -66,170 +66,173 @@ if ($user->societe_id > 0)
 // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
 $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
-if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
 
 /*
  * Actions
  */
 
-if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes'))
-{
-    $error = 0;
-
-    $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
-    $paiement_id = 0;
-    $totalpayment = 0;
-    $atleastonepaymentnotnull = 0;
+$parameters=array('socid'=>$socid);
+$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
+if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-    // 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)
-    {
-        if (substr($key,0,7) == 'amount_')
-        {
-            $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))
+if (empty($reshook))
+{
+	if ($action == 'add_paiement' || ($action == 'confirm_paiement' && $confirm=='yes'))
+	{
+	    $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)
+	    {
+	        if (substr($key,0,7) == 'amount_')
+	        {
+	            $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])
 	            {
-	            	$langs->load("errors");
-	                //$error++;
-	                setEventMessage($langs->transnoentities("WarningPaymentDateLowerThanInvoiceDate", dol_print_date($datepaye,'day'), dol_print_date($tmpinvoice->date, 'day'), $tmpinvoice->ref), 'warnings');
+		            // 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]);
-        }
-    }
-
-    // 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($totalpayment) && empty($atleastonepaymentnotnull))
-    {
-    	setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors');
-        $error++;
-    }
-
-    if (empty($datepaye))
-    {
-    	setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors');
-        $error++;
-    }
-}
-
-/*
- * Action add_paiement
- */
-if ($action == 'add_paiement')
-{
-    if ($error)
-    {
-        $action = 'create';
-    }
-    // Le reste propre a cette action s'affiche en bas de page.
-}
 
+	            $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++;
+	    }
+
+	    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($totalpayment) && empty($atleastonepaymentnotnull))
+	    {
+	    	setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->trans('PaymentAmount')), 'errors');
+	        $error++;
+	    }
+
+	    if (empty($datepaye))
+	    {
+	    	setEventMessage($langs->transnoentities('ErrorFieldRequired',$langs->transnoentities('Date')), 'errors');
+	        $error++;
+	    }
+	}
 
-/*
- * Action confirm_paiement
- */
-if ($action == 'confirm_paiement' && $confirm == 'yes')
-{
-    $error=0;
+	/*
+	 * Action add_paiement
+	 */
+	if ($action == 'add_paiement')
+	{
+	    if ($error)
+	    {
+	        $action = 'create';
+	    }
+	    // Le reste propre a cette action s'affiche en bas de page.
+	}
 
-    $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)
-            {
-            	setEventMessage($paiement->error, 'errors');
-                $error++;
-            }
-        }
+	/*
+	 * Action confirm_paiement
+	 */
+	if ($action == 'confirm_paiement' && $confirm == 'yes')
+	{
+	    $error=0;
+
+	    $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)
+	            {
+	            	setEventMessage($paiement->error, 'errors');
+	                $error++;
+	            }
+	        }
 
-        if (! $error)
-        {
-            $result=$paiement->addPaymentToBank($user,'payment_supplier','(SupplierInvoicePayment)',$_POST['accountid'],'','');
-            if ($result < 0)
-            {
-            	setEventMessage($paiement->error, 'errors');
-                $error++;
-            }
-        }
+	        if (! $error)
+	        {
+	            $result=$paiement->addPaymentToBank($user,'payment_supplier','(SupplierInvoicePayment)',$_POST['accountid'],'','');
+	            if ($result < 0)
+	            {
+	            	setEventMessage($paiement->error, 'errors');
+	                $error++;
+	            }
+	        }
 
-        if (! $error)
-        {
-            $db->commit();
+	        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)
-            {
-                $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/card.php?facid='.$invoiceid;
-            else $loc = DOL_URL_ROOT.'/fourn/paiement/card.php?id='.$paiement_id;
-            header('Location: '.$loc);
-            exit;
-        }
-        else
-        {
-            $db->rollback();
-        }
-    }
+	            // 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)
+	            {
+	                $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/card.php?facid='.$invoiceid;
+	            else $loc = DOL_URL_ROOT.'/fourn/paiement/card.php?id='.$paiement_id;
+	            header('Location: '.$loc);
+	            exit;
+	        }
+	        else
+	        {
+	            $db->rollback();
+	        }
+	    }
+	}
 }
 
 
-
 /*
  * View
  */
@@ -458,7 +461,7 @@ if (empty($action))
     $search_paymenttype=GETPOST('search_paymenttype');
     $search_amount=GETPOST('search_amount');
     $search_company=GETPOST('search_company');
-	
+
 	if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers
 	{
 		$search_ref="";
@@ -596,7 +599,7 @@ if (empty($action))
             print '<td class="nowrap">';
             print $invoicesupplierstatic->getNomUrl(1);
             print '</td>';*/
-			
+
 			print '<td>&nbsp;</td>';
             print '</tr>';
             $i++;
diff --git a/htdocs/install/mysql/tables/llx_contrat.sql b/htdocs/install/mysql/tables/llx_contrat.sql
index 5efbcdfe1fa9a3dfbd71be4c5040ddad0de1e1db..0e75c50305b2bb40d0346b63b3f70d730e88e709 100644
--- a/htdocs/install/mysql/tables/llx_contrat.sql
+++ b/htdocs/install/mysql/tables/llx_contrat.sql
@@ -23,6 +23,7 @@ create table llx_contrat
   rowid						integer AUTO_INCREMENT PRIMARY KEY,
   ref						varchar(30),		            -- contrat reference
   ref_supplier				varchar(30),		            -- suplier contract ref
+  ref_ext				varchar(30),		            -- external contract ref
   entity					integer DEFAULT 1 NOT NULL,	-- multi company id
   tms						timestamp,
   datec						datetime,                   -- creation date
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index 0b328e705a7d86930efb8e8e31e0cc9d176241d1..6fe021494d69d4fc03dd5300f5cce3fcea817dbb 100755
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -1038,7 +1038,7 @@ SendingMailSetup=Setup of sendings by email
 SendmailOptionNotComplete=Warning, on some Linux systems, to send email from your email, sendmail execution setup must contains option -ba (parameter mail.force_extra_parameters into your php.ini file). If some recipients never receive emails, try to edit this PHP parameter with mail.force_extra_parameters = -ba).
 PathToDocuments=Path to documents
 PathDirectory=Directory
-SendmailOptionMayHurtBuggedMTA=Feature to send mails using method "PHP mail direct" will generate a mail message that might be not correctly parsed by some receiving mail servers. Result is that some mails can't be read by people hosted by thoose bugged platforms. It's case for some Internet providers (Ex: Orange in France). This is not a problem into Dolibarr nor into PHP but onto receiving mail server. You can however add option MAIN_FIX_FOR_BUGGED_MTA to 1 into setup - other to modify Dolibarr to avoid this. However, you may experience problem with other servers that respect strictly the SMTP standard. The other solution (recommanded) is to use the method "SMTP socket library" that has no disadvantages.
+SendmailOptionMayHurtBuggedMTA=Feature to send mails using method "PHP mail direct" will generate a mail message that might be not correctly parsed by some receiving mail servers. Result is that some mails can't be read by people hosted by those bugged platforms. It's case for some Internet providers (Ex: Orange in France). This is not a problem into Dolibarr nor into PHP but onto receiving mail server. You can however add option MAIN_FIX_FOR_BUGGED_MTA to 1 into setup - other to modify Dolibarr to avoid this. However, you may experience problem with other servers that respect strictly the SMTP standard. The other solution (recommended) is to use the method "SMTP socket library" that has no disadvantages.
 TranslationSetup=Configuration de la traduction
 TranslationDesc=Choice of language visible on screen can be modified:<br>* Globally from menu <strong>Home - Setup - Display</strong><br>* For user only from tab <strong>User display</strong> of user card (click on login on top of screen). 
 TotalNumberOfActivatedModules=Total number of activated feature modules: <b>%s</b>
@@ -1415,7 +1415,7 @@ AdvancedEditor=Advanced editor
 ActivateFCKeditor=Activate advanced editor for:
 FCKeditorForCompany=WYSIWIG creation/edition of elements description and note (except products/services)
 FCKeditorForProduct=WYSIWIG creation/edition of products/services description and note
-FCKeditorForProductDetails=WYSIWIG creation/edition of products details lines for all entities (proposals, orders, invoices, etc...). <font class="warning">Warning: Using this option for this case is seriously not recommanded as it can create problems with special characters and page formating when building PDF files.</font>
+FCKeditorForProductDetails=WYSIWIG creation/edition of products details lines for all entities (proposals, orders, invoices, etc...). <font class="warning">Warning: Using this option for this case is seriously not recommended as it can create problems with special characters and page formating when building PDF files.</font>
 FCKeditorForMailing= WYSIWIG creation/edition for mass eMailings (Tools->eMailing)
 FCKeditorForUserSignature=WYSIWIG creation/edition of user signature
 FCKeditorForMail=WYSIWIG creation/edition for all mail (except Outils->eMailing)
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index 5562002b58ba6e2274a2371cab42d6fb4924634c..0f41a43c90fa1741e2f5b9f5003d978072b40931 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -260,6 +260,7 @@ days=days
 Hours=Hours
 Minutes=Minutes
 Seconds=Seconds
+Weeks=Weeks
 Today=Today
 Yesterday=Yesterday
 Tomorrow=Tomorrow
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index 48f788c96fa7d12c0116c54d3c7b232bb4459c38..b6244802318004ab948b86ac80ed4c3cc276f4ba 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -736,7 +736,7 @@ if ((! empty($conf->browser->layout) && $conf->browser->layout == 'phone')
 // If we force to use jmobile, then we reenable javascript
 if (! empty($conf->dol_use_jmobile)) $conf->use_javascript_ajax=1;
 // Replace themes bugged with jmobile with eldy
-if (! empty($conf->dol_use_jmobile) && in_array($conf->theme,array('bureau2crea','cameleo')))
+if (! empty($conf->dol_use_jmobile) && in_array($conf->theme,array('bureau2crea','cameleo','amarok')))
 {
 	$conf->theme='eldy';
 	$conf->css  =  "/theme/".$conf->theme."/style.css.php";
diff --git a/htdocs/margin/index.php b/htdocs/margin/index.php
index d3897faa5515cf15307cad5c0090245aac40c17e..04a2ba0d544aa3ba85e7e03cff19f21691e47883 100644
--- a/htdocs/margin/index.php
+++ b/htdocs/margin/index.php
@@ -1,5 +1,6 @@
 <?php
 /* Copyright (C) 2012	Christophe Battarel	<christophe.battarel@altairis.fr>
+ * Copyright (C) 2014   Marcos García       <marcosgdf@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,5 +22,15 @@
  *	\brief      Page d'index du module margin
  */
 
-require 'productMargins.php';
+require '../main.inc.php';
+
+if ($user->rights->produit->lire) {
+	$page = 'productMargins';
+} elseif ($user->rights->societe->lire) {
+	$page = 'customerMargins';
+} else {
+	$page = 'agentMargins';
+}
+
+header('Location: '.dol_buildpath('/margin/'.$page.'.php', 1));
 
diff --git a/htdocs/margin/lib/margins.lib.php b/htdocs/margin/lib/margins.lib.php
index d3ffd9c1bf46390910a5bc6c987262e1ef5bd1f4..1f904c44f2dc7e7577bf430f8ecbf87fb3036277 100644
--- a/htdocs/margin/lib/margins.lib.php
+++ b/htdocs/margin/lib/margins.lib.php
@@ -1,5 +1,6 @@
 <?php
 /* Copyright (C) 2012	Christophe Battarel	<christophe.battarel@altairis.fr>
+ * Copyright (C) 2014   Marcos García       <marcosgdf@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,21 +57,25 @@ function marges_admin_prepare_head()
  */
 function marges_prepare_head()
 {
-	global $langs, $conf;
+	global $langs, $conf, $user;
 	$langs->load("marges@marges");
 
 	$h = 0;
 	$head = array();
 
-	$head[$h][0] = DOL_URL_ROOT."/margin/productMargins.php";
-	$head[$h][1] = $langs->trans("ProductMargins");
-	$head[$h][2] = 'productMargins';
-	$h++;
+	if ($user->rights->produit->lire) {
+		$head[$h][0] = DOL_URL_ROOT."/margin/productMargins.php";
+		$head[$h][1] = $langs->trans("ProductMargins");
+		$head[$h][2] = 'productMargins';
+		$h++;
+	}
 
-	$head[$h][0] = DOL_URL_ROOT."/margin/customerMargins.php";
-	$head[$h][1] = $langs->trans("CustomerMargins");
-	$head[$h][2] = 'customerMargins';
-	$h++;
+	if ($user->rights->societe->lire) {
+		$head[$h][0] = DOL_URL_ROOT."/margin/customerMargins.php";
+		$head[$h][1] = $langs->trans("CustomerMargins");
+		$head[$h][2] = 'customerMargins';
+		$h++;
+	}
 
 	$head[$h][0] = DOL_URL_ROOT."/margin/agentMargins.php";
 	$head[$h][1] = $langs->trans("SalesRepresentativeMargins");
diff --git a/htdocs/product/document.php b/htdocs/product/document.php
index 6ca92968e8d6948f7a0da6f33709e11dfd354e5c..e46dc0384b2d96101e6542bf7faf565b9a133323 100644
--- a/htdocs/product/document.php
+++ b/htdocs/product/document.php
@@ -73,16 +73,20 @@ if ($id > 0 || ! empty($ref))
 }
 $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 ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
-
 
 /*
- * Action envoie fichier
+ * Actions
  */
 
-include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php';
+$parameters=array('id'=>$id);
+$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
+if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+
+if (empty($reshook))
+{
+	// Action sending file
+	include_once DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_pre_headers.tpl.php';
+}
 
 
 /*
diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php
index 4f382d3b7f8503ae8b6acbbf22f034c2f0fed265..5adc79f3f659a60dbe27fc64cad64c5c140cbf11 100755
--- a/htdocs/product/fournisseurs.php
+++ b/htdocs/product/fournisseurs.php
@@ -5,7 +5,7 @@
  * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
  * Copyright (C) 2010-2012 Juanjo Menent        <jmenent@2byte.es>
  * Copyright (C) 2012      Christophe Battarel  <christophe.battarel@altairis.fr>
- * Copyright (C) 2014      Ion Agorria          <ion@agorria.com> 
+ * Copyright (C) 2014      Ion Agorria          <ion@agorria.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -81,152 +81,155 @@ $parameters=array('socid'=>$socid, 'id_prod'=>$id);
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$product,$action);    // Note that $action and $object may have been modified by some hooks
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-if ($action == 'remove_pf')
+if (empty($reshook))
 {
-	$product = new ProductFournisseur($db);
-	if ($product->fetch($id) > 0)
+	if ($action == 'remove_pf')
 	{
-		if ($rowid)
+		$product = new ProductFournisseur($db);
+		if ($product->fetch($id) > 0)
 		{
-			$result=$product->remove_product_fournisseur_price($rowid);
-			$action = '';
-			setEventMessage($langs->trans("PriceRemoved"));
+			if ($rowid)
+			{
+				$result=$product->remove_product_fournisseur_price($rowid);
+				$action = '';
+				setEventMessage($langs->trans("PriceRemoved"));
+			}
 		}
 	}
-}
 
-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);
-    $price_expression = GETPOST('eid', 'int') == 0 ? 'NULL' : GETPOST('eid', 'int'); //Discard expression if not in expression mode
-
-    if ($tva_tx == '')
-    {
-		$error++;
-	    setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("VATRateForSupplierProduct")), 'errors');
-    }
-	if (empty($quantity))
+	if ($action == 'updateprice' && GETPOST('cancel') <> $langs->trans("Cancel"))
 	{
-		$error++;
-		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Qty")), 'errors');
-	}
-	if (empty($ref_fourn))
-	{
-		$error++;
-		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("RefSupplier")), 'errors');
-	}
-	if ($id_fourn <= 0)
-	{
-		$error++;
-		setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Supplier")), 'errors');
-	}
-	if ($_POST["price"] < 0 || $_POST["price"] == '')
-	{
-		if ($price_expression == 'NULL') { //This is not because of using expression instead of numeric price
+		$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);
+		$price_expression = GETPOST('eid', 'int') == 0 ? 'NULL' : GETPOST('eid', 'int'); //Discard expression if not in expression mode
+
+		if ($tva_tx == '')
+		{
 			$error++;
-			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Price")), 'errors');
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("VATRateForSupplierProduct")), 'errors');
 		}
-		else
+		if (empty($quantity))
 		{
-			$_POST["price"] = 0;
+			$error++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Qty")), 'errors');
 		}
-	}
-
-	$product = new ProductFournisseur($db);
-	$result=$product->fetch($id);
-	if ($result <= 0)
-	{
-	    $error++;
-		setEventMessage($product->error, 'errors');
-	}
-
-	if (! $error)
-    {
-    	$db->begin();
-
-		if (! $error)
+		if (empty($ref_fourn))
 		{
-			$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++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("RefSupplier")), 'errors');
+		}
+		if ($id_fourn <= 0)
+		{
+			$error++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Supplier")), 'errors');
+		}
+		if ($_POST["price"] < 0 || $_POST["price"] == '')
+		{
+			if ($price_expression == 'NULL') { //This is not because of using expression instead of numeric price
 				$error++;
-
-				$product->fetch($product->product_id_already_linked);
-				$productLink = $product->getNomUrl(1,'supplier');
-
-				setEventMessage($langs->trans("ReferenceSupplierIsAlreadyAssociatedWithAProduct",$productLink), 'errors');
+				setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Price")), 'errors');
 			}
-			else if ($ret < 0)
+			else
 			{
-				$error++;
-				setEventMessage($product->error, 'errors');
+				$_POST["price"] = 0;
 			}
 		}
 
+		$product = new ProductFournisseur($db);
+		$result=$product->fetch($id);
+		if ($result <= 0)
+		{
+			$error++;
+			setEventMessage($product->error, 'errors');
+		}
+
 		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']);
+			$db->begin();
 
-			$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++;
-				setEventMessage($product->error, 'errors');
-			} 
-			else 
+				$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');
+
+					setEventMessage($langs->trans("ReferenceSupplierIsAlreadyAssociatedWithAProduct",$productLink), 'errors');
+				}
+				else if ($ret < 0)
+				{
+					$error++;
+					setEventMessage($product->error, 'errors');
+				}
+			}
+
+			if (! $error)
 			{
-				if ($price_expression != 'NULL') {
-					//Check the expression validity by parsing it
-	                $priceparser = new PriceParser($db);
-	                $price_result = $priceparser->parseProductSupplier($id, $price_expression, $quantity, $tva_tx);
-	                if ($price_result < 0) { //Expression is not valid
-						$error++;
-						setEventMessage($priceparser->translatedError(), 'errors');
-					}
+				$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++;
+					setEventMessage($product->error, 'errors');
 				}
-				if (! $error && ! empty($conf->dynamicprices->enabled)) {
-					$ret=$product->setPriceExpression($price_expression);
-					if ($ret < 0)
-					{
-						$error++;
-						setEventMessage($product->error, 'errors');
+				else
+				{
+					if ($price_expression != 'NULL') {
+						//Check the expression validity by parsing it
+						$priceparser = new PriceParser($db);
+						$price_result = $priceparser->parseProductSupplier($id, $price_expression, $quantity, $tva_tx);
+						if ($price_result < 0) { //Expression is not valid
+							$error++;
+							setEventMessage($priceparser->translatedError(), 'errors');
+						}
+					}
+					if (! $error && ! empty($conf->dynamicprices->enabled)) {
+						$ret=$product->setPriceExpression($price_expression);
+						if ($ret < 0)
+						{
+							$error++;
+							setEventMessage($product->error, 'errors');
+						}
 					}
 				}
 			}
-		}
 
-		if (! $error)
-		{
-			$db->commit();
-			$action='';
-		}
-		else
-		{
-			$db->rollback();
+			if (! $error)
+			{
+				$db->commit();
+				$action='';
+			}
+			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
  */
@@ -398,7 +401,8 @@ if ($id || $ref)
 				print '<input type="text" class="flat" size="5" name="tva_tx" value="'.(GETPOST("tva_tx")?vatrate(GETPOST("tva_tx")):($default_vat!=''?vatrate($default_vat):'')).'">';
 				print '</td></tr>';
 
-				if (! empty($conf->dynamicprices->enabled)) { //Only show price mode and expression selector if module is enabled
+				if (! empty($conf->dynamicprices->enabled)) //Only show price mode and expression selector if module is enabled
+				{ 
 					// Price mode selector
 					print '<tr><td class="fieldrequired">'.$langs->trans("PriceMode").'</td><td>';
 					$price_expression = new PriceExpression($db);
@@ -456,7 +460,7 @@ if ($id || $ref)
 						print '</tr>';
 					}
 				}
-				
+
 				if (is_object($hookmanager))
 				{
 					$parameters=array('id_fourn'=>$id_fourn,'prod_id'=>$product->id);
@@ -467,7 +471,7 @@ if ($id || $ref)
 
 				print '<br><div class="center">';
 				print '<input class="button" type="submit" value="'.$langs->trans("Save").'">';
-				print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+				print '&nbsp; &nbsp;';
 				print '<input class="button" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
 				print '</div>';
 
@@ -568,7 +572,7 @@ if ($id || $ref)
 
 						// Charges ????
 						if ($conf->global->PRODUCT_CHARGES)
-						{	
+						{
 							if (! empty($conf->margin->enabled))
 							{
 								print '<td align="right">';
@@ -576,7 +580,7 @@ if ($id || $ref)
 								print '</td>';
 							}
 						}
-						
+
 						// Unit price
 						print '<td align="right">';
 						print price($productfourn->fourn_unitprice);
@@ -598,7 +602,7 @@ if ($id || $ref)
 								print '</td>';
 							}
 						}
-						
+
 						if (is_object($hookmanager))
 						{
 							$parameters=array('id_pfp'=>$productfourn->product_fourn_price_id,'id_fourn'=>$id_fourn,'prod_id'=>$product->id);
diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php
index bc7478a0dbb4f1eb5951d09e1298f1480662ce41..e30a5bfffdc80457f4c6439afa224cc418a46219 100644
--- a/htdocs/projet/element.php
+++ b/htdocs/projet/element.php
@@ -145,12 +145,12 @@ print '<tr><td>'.$langs->trans("Status").'</td><td>'.$project->getLibStatut(4).'
 
 // Date start
 print '<tr><td>'.$langs->trans("DateStart").'</td><td>';
-print dol_print_date($object->date_start,'day');
+print dol_print_date($project->date_start,'day');
 print '</td></tr>';
 
 // Date end
 print '<tr><td>'.$langs->trans("DateEnd").'</td><td>';
-print dol_print_date($object->date_end,'day');
+print dol_print_date($project->date_end,'day');
 print '</td></tr>';
 
 print '</table>';
diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php
index 33a27796aaf05a8dd8ac60db59f4b50cd34adab2..0863cad9c52c74aa5c6c7f42ba48f437d22c8e57 100644
--- a/htdocs/resource/card.php
+++ b/htdocs/resource/card.php
@@ -62,58 +62,57 @@ $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 ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-
-/*******************************************************************
-* ACTIONS
-*
-* Put here all code to do according to value of "action" parameter
-********************************************************************/
-
-if ($action == 'update' && ! $_POST["cancel"]  && $user->rights->resource->write )
+if (empty($reshook))
 {
-	$error=0;
+	/*******************************************************************
+	* ACTIONS
+	********************************************************************/
 
-	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;
+			$error++;
+			setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref")), 'errors');
+		}
 
-			$result=$object->update($user);
-			if ($result > 0)
+		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($object->error, 'errors');
+					$action='edit';
+				}
+
 			}
 			else
 			{
-				setEventMessage('<div class="error">'.$object->error.'</div>');
+				setEventMessage($object->error,'errors');
 				$action='edit';
 			}
-
 		}
 		else
 		{
-			setEventMessage($object->error,'errors');
 			$action='edit';
 		}
 	}
-	else
-	{
-		$action='edit';
-	}
 }
 
-
 /***************************************************
 * VIEW
 *
diff --git a/scripts/odt2pdf/odt2pdf.sh b/scripts/odt2pdf/odt2pdf.sh
index 9d9bf18a8c7482b24926eae2aa2925f3a7ee1588..c7c768a12449307bbc465a23a1515d9ed632c464 100755
--- a/scripts/odt2pdf/odt2pdf.sh
+++ b/scripts/odt2pdf/odt2pdf.sh
@@ -1,8 +1,12 @@
 #!/bin/bash
 # @copyright  GPL License 2010 -  Vikas Mahajan - http://vikasmahajan.wordpress.com
 # @copyright  GPL License 2013 -  Florian HEnry - florian.henry@open-concept.pro
-
 #
+# Convert an ODT into a PDF using "jodconverter" tool.
+# Dolibarr variable MAIN_ODT_AS_PDF must be defined to have this script called after ODT generation.
+# Dolibarr variable MAIN_DOL_SCRIPTS_ROOT must be defined to path of script directories (otherwise dolibarr will try to guess).
+ 
+
 #if [ -f "$1.odt" ]
 # then
 #    soffice --invisible --convert-to pdf:writer_pdf_Export --outdir $2 "$1.odt"