diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
index 52f7a473bed51c73e9df338a6d684bbc3e8a9510..2d828298b51bad25b38680f5e9816e2a51b8d364 100644
--- a/htdocs/accountancy/class/bookkeeping.class.php
+++ b/htdocs/accountancy/class/bookkeeping.class.php
@@ -1079,22 +1079,26 @@ class BookKeeping extends CommonObject
 	 * @param  string  $mode           Mode
 	 * @return number                  <0 if KO, >0 if OK
 	 */
-	public function updateByMvt($piece_num='', $field='', $value='', $mode='') {
+	public function updateByMvt($piece_num='', $field='', $value='', $mode='')
+	{
+		$error=0;
+
 		$this->db->begin();
+
 		$sql = "UPDATE " . MAIN_DB_PREFIX .  $this->table_element . $mode . " as ab";
 		$sql .= ' SET ab.' . $field . '=' . (is_numeric($value)?$value:"'".$value."'");
 		$sql .= ' WHERE ab.piece_num=' . $piece_num ;
 		$resql = $this->db->query($sql);
 
 		if (! $resql) {
-			$error ++;
+			$error++;
 			$this->errors[] = 'Error ' . $this->db->lasterror();
 			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
 		}
 		if ($error) {
 			$this->db->rollback();
 
-			return - 1 * $error;
+			return -1 * $error;
 		} else {
 			$this->db->commit();
 
@@ -1521,11 +1525,16 @@ class BookKeeping extends CommonObject
 	 * @param  string   $piece_num     Piece num
 	 * @return void
 	 */
-	public function transformTransaction($direction=0,$piece_num='') {
+	public function transformTransaction($direction=0,$piece_num='')
+	{
+		$error = 0;
+
 		$this->db->begin();
-		if ($direction==0) {
+
+		if ($direction==0)
+		{
 			$next_piecenum=$this->getNextNumMvt();
-			if ($result < 0) {
+			if ($next_piecenum < 0) {
 				$error++;
 			}
 			$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element.'(doc_date, doc_type,';
diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php
index 0e3e71c15270752490ae74b30aba7ca836179f46..13602160c48d2d42a4b30efe19a81797fede4c00 100644
--- a/htdocs/accountancy/customer/lines.php
+++ b/htdocs/accountancy/customer/lines.php
@@ -32,6 +32,8 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
 require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
+require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
+require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
 
 // Langs
 $langs->load("bills");
@@ -51,6 +53,9 @@ $search_desc = GETPOST('search_desc', 'alpha');
 $search_amount = GETPOST('search_amount', 'alpha');
 $search_account = GETPOST('search_account', 'alpha');
 $search_vat = GETPOST('search_vat', 'alpha');
+$search_day=GETPOST("search_day","int");
+$search_month=GETPOST("search_month","int");
+$search_year=GETPOST("search_year","int");
 $search_country = GETPOST('search_country', 'alpha');
 $search_tvaintra = GETPOST('search_tvaintra', 'alpha');
 
@@ -95,6 +100,9 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
 	$search_amount = '';
 	$search_account = '';
 	$search_vat = '';
+	$search_day = '';
+	$search_month = '';
+	$search_year = '';
 	$search_country = '';
 	$search_tvaintra = '';
 }
@@ -131,6 +139,7 @@ if (is_array($changeaccount) && count($changeaccount) > 0) {
  */
 
 $form = new Form($db);
+$formother = new FormOther($db);
 
 llxHeader('', $langs->trans("CustomersVentilation") . ' - ' . $langs->trans("Dispatched"));
 
@@ -197,6 +206,19 @@ if (strlen(trim($search_account))) {
 if (strlen(trim($search_vat))) {
 	$sql .= natural_search("fd.tva_tx", $search_vat);
 }
+if ($search_month > 0)
+{
+	if ($search_year > 0 && empty($search_day))
+		$sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,$search_month,false))."' AND '".$db->idate(dol_get_last_day($search_year,$search_month,false))."'";
+		else if ($search_year > 0 && ! empty($search_day))
+			$sql.= " AND f.datef BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month, $search_day, $search_year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month, $search_day, $search_year))."'";
+			else
+				$sql.= " AND date_format(f.datef, '%m') = '".$db->escape($search_month)."'";
+}
+else if ($search_year > 0)
+{
+	$sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'";
+}
 if (strlen(trim($search_country))) {
 	$sql .= natural_search("co.label", $search_country);
 }
@@ -237,6 +259,9 @@ if ($result) {
 		$param .= "&search_account=" . $search_account;
 	if ($search_vat)
 		$param .= "&search_vat=" . $search_vat;
+	if ($search_day)         $param.='&search_day='.urlencode($search_day);
+	if ($search_month)       $param.='&search_month='.urlencode($search_month);
+	if ($search_year)        $param.='&search_year='.urlencode($search_year);
 	if ($search_country)
 		$param .= "&search_country=" . $search_country;
 	if ($search_tvaintra)
@@ -267,7 +292,11 @@ if ($result) {
 	print '<tr class="liste_titre_filter">';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_lineid" value="' . dol_escape_htmltag($search_lineid) . '""></td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="' . dol_escape_htmltag($search_invoice) . '"></td>';
-	print '<td class="liste_titre"></td>';
+	print '<td class="liste_titre center">';
+   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="search_day" value="'.$search_day.'">';
+   	print '<input class="flat" type="text" size="1" maxlength="2" name="search_month" value="'.$search_month.'">';
+   	$formother->select_year($search_year,'search_year',1, 20, 5);
+	print '</td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="' . dol_escape_htmltag($search_ref) . '"></td>';
 	//print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="' . dol_escape_htmltag($search_label) . '"></td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php
index 51f62ecabf66b0636249cb80a4bd25ce25e489c0..2d26a2d06d87767a619ea974af9633e31e4552ee 100644
--- a/htdocs/accountancy/customer/list.php
+++ b/htdocs/accountancy/customer/list.php
@@ -115,6 +115,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
 	$search_amount = '';
 	$search_account = '';
 	$search_vat = '';
+	$search_day = '';
 	$search_month = '';
 	$search_year = '';
 }
diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php
index 156d80f09e495ec48f8172b35a2fd6f4aefd9955..750a5bc9f257b060c44b822ef094cb9baa242765 100644
--- a/htdocs/accountancy/expensereport/lines.php
+++ b/htdocs/accountancy/expensereport/lines.php
@@ -31,6 +31,8 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
 require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
+require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
+require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
 
 // Langs
 $langs->load("compta");
@@ -50,6 +52,9 @@ $search_desc = GETPOST('search_desc', 'alpha');
 $search_amount = GETPOST('search_amount', 'alpha');
 $search_account = GETPOST('search_account', 'alpha');
 $search_vat = GETPOST('search_vat', 'alpha');
+$search_day=GETPOST("search_day","int");
+$search_month=GETPOST("search_month","int");
+$search_year=GETPOST("search_year","int");
 
 // Load variable for pagination
 $limit = GETPOST('limit','int')?GETPOST('limit', 'int'):(empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION)?$conf->liste_limit:$conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
@@ -90,6 +95,9 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
 	$search_amount = '';
 	$search_account = '';
 	$search_vat = '';
+	$search_day = '';
+	$search_month = '';
+	$search_year = '';
 }
 
 if (is_array($changeaccount) && count($changeaccount) > 0) {
@@ -123,6 +131,9 @@ if (is_array($changeaccount) && count($changeaccount) > 0) {
  * View
  */
 
+$form = new Form($db);
+$formother = new FormOther($db);
+
 llxHeader('', $langs->trans("ExpenseReportsVentilation") . ' - ' . $langs->trans("Dispatched"));
 
 print '<script type="text/javascript">
@@ -173,6 +184,19 @@ if (strlen(trim($search_account))) {
 if (strlen(trim($search_vat))) {
 	$sql .= " AND (erd.tva_tx like '" . $search_vat . "%')";
 }
+if ($search_month > 0)
+{
+	if ($search_year > 0 && empty($search_day))
+		$sql.= " AND erd.date BETWEEN '".$db->idate(dol_get_first_day($search_year,$search_month,false))."' AND '".$db->idate(dol_get_last_day($search_year,$search_month,false))."'";
+		else if ($search_year > 0 && ! empty($search_day))
+			$sql.= " AND erd.date BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month, $search_day, $search_year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month, $search_day, $search_year))."'";
+			else
+				$sql.= " AND date_format(erd.date, '%m') = '".$db->escape($search_month)."'";
+}
+else if ($search_year > 0)
+{
+	$sql.= " AND erd.date BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'";
+}
 $sql .= " AND er.entity IN (" . getEntity('expensereport', 0) . ")";  // We don't share object for accountancy
 
 $sql .= $db->order($sortfield, $sortorder);
@@ -207,6 +231,9 @@ if ($result) {
 		$param .= "&search_account=" . $search_account;
 	if ($search_vat)
 		$param .= "&search_vat=" . $search_vat;
+	if ($search_day)         $param.='&search_day='.urlencode($search_day);
+	if ($search_month)       $param.='&search_month='.urlencode($search_month);
+	if ($search_year)        $param.='&search_year='.urlencode($search_year);
 	if ($search_country)
 		$param .= "&search_country=" . $search_country;
 	if ($search_tvaintra)
@@ -237,7 +264,11 @@ if ($result) {
 	print '<tr class="liste_titre_filter">';
 	print '<td class="liste_titre"></td>';
 	print '<td><input type="text" class="flat maxwidth50" name="search_expensereport" value="' . dol_escape_htmltag($search_expensereport) . '"></td>';
-	print '<td class="liste_titre" align="right"></td>';
+	print '<td class="liste_titre center">';
+   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="search_day" value="'.$search_day.'">';
+   	print '<input class="flat" type="text" size="1" maxlength="2" name="search_month" value="'.$search_month.'">';
+   	$formother->select_year($search_year,'search_year',1, 20, 5);
+	print '</td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="' . dol_escape_htmltag($search_label) . '"></td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
 	print '<td class="liste_titre" align="right"><input type="text" class="flat maxwidth50" name="search_amount" value="' . dol_escape_htmltag($search_amount) . '"></td>';
diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php
index c7ebb5ed5af725dbb11fa74765fdf2701545444d..b7fe591708ecdfba434f286c64fd400fbbe0bce7 100644
--- a/htdocs/accountancy/expensereport/list.php
+++ b/htdocs/accountancy/expensereport/list.php
@@ -109,6 +109,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
     $search_amount = '';
     $search_account = '';
     $search_vat = '';
+    $search_day = '';
     $search_month = '';
     $search_year = '';
 }
diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php
index 66e6928da07ac017d1bf606d5a7833164dea3523..78b9320fdb162fcb1666c9b336fc7eac4dcfb3eb 100644
--- a/htdocs/accountancy/supplier/lines.php
+++ b/htdocs/accountancy/supplier/lines.php
@@ -32,6 +32,8 @@ require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture.class.php';
 require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
 require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
+require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
+require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
 
 // Langs
 $langs->load("compta");
@@ -52,6 +54,9 @@ $search_desc = GETPOST('search_desc', 'alpha');
 $search_amount = GETPOST('search_amount', 'alpha');
 $search_account = GETPOST('search_account', 'alpha');
 $search_vat = GETPOST('search_vat', 'alpha');
+$search_day=GETPOST("search_day","int");
+$search_month=GETPOST("search_month","int");
+$search_year=GETPOST("search_year","int");
 $search_country = GETPOST('search_country', 'alpha');
 $search_tvaintra = GETPOST('search_tvaintra', 'alpha');
 
@@ -96,6 +101,9 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
 	$search_amount = '';
 	$search_account = '';
 	$search_vat = '';
+	$search_day = '';
+	$search_month = '';
+	$search_year = '';
 	$search_country = '';
 	$search_tvaintra = '';
 }
@@ -131,6 +139,9 @@ if (is_array($changeaccount) && count($changeaccount) > 0) {
  * View
  */
 
+$form = new Form($db);
+$formother = new FormOther($db);
+
 llxHeader('', $langs->trans("SuppliersVentilation") . ' - ' . $langs->trans("Dispatched"));
 
 print '<script type="text/javascript">
@@ -189,6 +200,19 @@ if (strlen(trim($search_account))) {
 if (strlen(trim($search_vat))) {
 	$sql .= natural_search("l.tva_tx", $search_vat, 1);
 }
+if ($search_month > 0)
+{
+	if ($search_year > 0 && empty($search_day))
+		$sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,$search_month,false))."' AND '".$db->idate(dol_get_last_day($search_year,$search_month,false))."'";
+		else if ($search_year > 0 && ! empty($search_day))
+			$sql.= " AND f.datef BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month, $search_day, $search_year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month, $search_day, $search_year))."'";
+			else
+				$sql.= " AND date_format(f.datef, '%m') = '".$db->escape($search_month)."'";
+}
+else if ($search_year > 0)
+{
+	$sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'";
+}
 if (strlen(trim($search_country))) {
 	$sql .= " AND (co.label like'" . $search_country . "%')";
 }
@@ -231,6 +255,9 @@ if ($result) {
 		$param .= "&search_account=" . $search_account;
 	if ($search_vat)
 		$param .= "&search_vat=" . $search_vat;
+	if ($search_day)         $param.='&search_day='.urlencode($search_day);
+	if ($search_month)       $param.='&search_month='.urlencode($search_month);
+	if ($search_year)        $param.='&search_year='.urlencode($search_year);
 	if ($search_country)
 		$param .= "&search_country=" . $search_country;
 	if ($search_tvaintra)
@@ -262,7 +289,11 @@ if ($result) {
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_lineid" value="' . dol_escape_htmltag($search_lineid) . '""></td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="' . dol_escape_htmltag($search_invoice) . '"></td>';
 	print '<td class="liste_titre"></td>';
-	print '<td class="liste_titre"></td>';
+	print '<td class="liste_titre center">';
+   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="search_day" value="'.$search_day.'">';
+   	print '<input class="flat" type="text" size="1" maxlength="2" name="search_month" value="'.$search_month.'">';
+   	$formother->select_year($search_year,'search_year',1, 20, 5);
+	print '</td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="' . dol_escape_htmltag($search_ref) . '"></td>';
 	//print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="' . dol_escape_htmltag($search_label) . '"></td>';
 	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php
index 0ebf66f12151c73488a90e574578d721d45e7520..f154d0b77d0f82b0f9c5bf4647fe4a9089cdd5bc 100644
--- a/htdocs/accountancy/supplier/list.php
+++ b/htdocs/accountancy/supplier/list.php
@@ -116,6 +116,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
     $search_amount = '';
     $search_account = '';
     $search_vat = '';
+    $search_day = '';
     $search_month = '';
     $search_year = '';
 }
diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php
index c197d1a23622db7cc02737723fb9167929e2cec4..33be4abb8e60f2cb99c7b3376d81c55cf588be80 100644
--- a/htdocs/adherents/class/adherent.class.php
+++ b/htdocs/adherents/class/adherent.class.php
@@ -1563,7 +1563,7 @@ class Adherent extends CommonObject
 	 *	@param	int		$withpictoimg				0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small)
 	 *	@param	int		$maxlen						length max label
 	 *	@param	string	$option						Page for link ('card', 'category', 'subscription', ...)
-	 *  @param  string  $mode           			''=Show firstname and lastname, 'firstname'=Show only firstname, 'login'=Show login, 'ref'=Show ref
+	 *  @param  string  $mode           			''=Show firstname+lastname as label (using default order), 'firstname'=Show only firstname, 'login'=Show login, 'ref'=Show ref
 	 *  @param  string  $morecss        			Add more css on link
 	 *  @param  int     $save_lastsearch_value    	-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
 	 *	@return	string								Chaine avec URL
@@ -1574,6 +1574,8 @@ class Adherent extends CommonObject
 
 		if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0;
 
+		$notooltip=0;
+
 		$result=''; $label='';
 		$link=''; $linkstart=''; $linkend='';
 
diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php
index 99c343a1ff02fd4b8c719415a0ee6d397c94eb1e..f65e363cef95fb2fb88f14a8a7d40a6887bea8c1 100644
--- a/htdocs/adherents/class/adherent_type.class.php
+++ b/htdocs/adherents/class/adherent_type.class.php
@@ -167,7 +167,7 @@ class AdherentType extends CommonObject
 		$sql.= "libelle = '".$this->db->escape($this->label) ."',";
 		$sql.= "subscription = '".$this->db->escape($this->subscription)."',";
 		$sql.= "note = '".$this->db->escape($this->note)."',";
-		$sql.= "vote = '".$this->db->escape($this->vote)."',";
+		$sql.= "vote = ".(integer) $this->db->escape($this->vote).",";
 		$sql.= "mail_valid = '".$this->db->escape($this->mail_valid)."'";
 		$sql.= " WHERE rowid =".$this->id;
 
diff --git a/htdocs/adherents/class/subscription.class.php b/htdocs/adherents/class/subscription.class.php
index bdb43dd41d32724c2cfd1a7b15246a882c9273d9..397be6ee8da40ac6e6c0e38fdf23bbfa191dc8f6 100644
--- a/htdocs/adherents/class/subscription.class.php
+++ b/htdocs/adherents/class/subscription.class.php
@@ -216,7 +216,7 @@ class Subscription extends CommonObject
 				$result=$member->fetch($this->fk_adherent);
 				$result=$member->update_end_date($user);
 
-				if (is_object($accountline) && $accountline->id > 0)						// If we found bank account line (this means this->fk_bank defined)
+				if ($this->fk_bank > 0 && is_object($accountline) && $accountline->id > 0)	// If we found bank account line (this means this->fk_bank defined)
 				{
 					$result=$accountline->delete($user);		// Return false if refused because line is conciliated
 					if ($result > 0)
diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php
index c9edce35f60afdb9ee9e252ecc3966f2ef8f8050..7eaefa6fc3390d987341ed024e9a9003816b502c 100644
--- a/htdocs/adherents/type.php
+++ b/htdocs/adherents/type.php
@@ -107,7 +107,7 @@ if ($action == 'add' && $user->rights->adherent->configurer)
 	$object->subscription	= (int) trim($subscription);
 	$object->note			= trim($comment);
 	$object->mail_valid		= trim($mail_valid);
-	$object->vote			= (boolean) trim($vote);
+	$object->vote			= trim($vote);
 
 	// Fill array 'array_options' with data from add form
 	$ret = $extrafields->setOptionalsFromPost($extralabels,$object);
@@ -160,7 +160,7 @@ if ($action == 'update' && $user->rights->adherent->configurer)
 	$object->subscription	= (int) trim($subscription);
 	$object->note			= trim($comment);
 	$object->mail_valid		= trim($mail_valid);
-	$object->vote			= (boolean) trim($vote);
+	$object->vote			= trim($vote);
 
 	// Fill array 'array_options' with data from add form
 	$ret = $extrafields->setOptionalsFromPost($extralabels,$object);
diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php
index 111084388ce10cf4b7cc3e2e2a913a4f7132127c..4e25e93084bc9ba8dec24916154dacb939792092 100644
--- a/htdocs/admin/mails_templates.php
+++ b/htdocs/admin/mails_templates.php
@@ -1019,9 +1019,9 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 			}
 			print '</td>';
 		}
-		elseif ($context == 'add' & in_array($fieldlist[$field], array('topic', 'joinfiles', 'content', 'content_lines'))) continue;
-		elseif ($context == 'edit' & in_array($fieldlist[$field], array('topic', 'joinfiles', 'content', 'content_lines'))) continue;
-		elseif ($context == 'hide' & in_array($fieldlist[$field], array('topic', 'joinfiles', 'content', 'content_lines'))) continue;
+		elseif ($context == 'add' && in_array($fieldlist[$field], array('topic', 'joinfiles', 'content', 'content_lines'))) continue;
+		elseif ($context == 'edit' && in_array($fieldlist[$field], array('topic', 'joinfiles', 'content', 'content_lines'))) continue;
+		elseif ($context == 'hide' && in_array($fieldlist[$field], array('topic', 'joinfiles', 'content', 'content_lines'))) continue;
 		else
 		{
 			$size=''; $class=''; $classtd='';
diff --git a/htdocs/api/class/api_access.class.php b/htdocs/api/class/api_access.class.php
index b2dcfefa49ff65483367f85cfcf22f77c1262b21..5848620f7352d51a4db309d1b40a5331db41434f 100644
--- a/htdocs/api/class/api_access.class.php
+++ b/htdocs/api/class/api_access.class.php
@@ -83,10 +83,10 @@ class DolibarrApiAccess implements iAuthenticate
 
 		// api key can be provided in url with parameter api_key=xxx or ni header with header DOLAPIKEY:xxx
 		$api_key = '';
-		if (isset($_GET['api_key']))
+		if (isset($_GET['api_key']))	// For backward compatibility
 		{
 		    // TODO Add option to disable use of api key on url. Return errors if used.
-		    $api_key = $_GET['api_key'];                         // For backward compatibility
+		    $api_key = $_GET['api_key'];
 		}
 		if (isset($_GET['DOLAPIKEY']))
 		{
diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php
index 397910a6e2ffd01c100e39e8559cabe9aebef668..92b48dfd0c69c2ee43f9d1dda826b03684a99a88 100644
--- a/htdocs/api/class/api_documents.class.php
+++ b/htdocs/api/class/api_documents.class.php
@@ -130,18 +130,20 @@ class Documents extends DolibarrApi
 	}
 
 	/**
-	 * Return the list of documents of an element
+	 * Return the list of documents of a dedicated element (from its ID or Ref)
 	 *
-	 * @param   string 	$modulepart	Name of module or area concerned ('facture', 'project', 'member', ...)
-	 * @param	int		$id			ID of element
+	 * @param   string 	$modulepart		Name of module or area concerned ('facture', 'project', 'member', ...)
+	 * @param	int		$id				ID of element
 	 * @param	string	$ref			Ref of element
-	 * @return	array				Array of documents with path
+	 * @param	string	$sortfield		Sort criteria ('','fullname','relativename','name','date','size')
+	 * @param	string	$sortorder		Sort order ('asc' or 'desc')
+	 * @return	array					Array of documents with path
 	 *
 	 * @throws RestException
 	 *
 	 * @url GET list
 	 */
-	function getDocumentsListByElement($modulepart, $id=0, $ref='')
+	function getDocumentsListByElement($modulepart, $id=0, $ref='', $sortfield='', $sortorder='')
 	{
 		global $conf;
 
@@ -254,9 +256,11 @@ class Documents extends DolibarrApi
 
 		// Define $uploadir
 		$object = null;
-		$entity = $user->entity;
+		$entity = DolibarrApiAccess::$user->entity;
 		if ($ref)
 		{
+			$tmpreldir='';
+
 			if ($modulepart == 'facture' || $modulepart == 'invoice')
 			{
 				$modulepart='facture';
diff --git a/htdocs/api/index.php b/htdocs/api/index.php
index 2730c6c0242423b56e8e85ca1df1f8a8c26df319..248b1541f6ce1a3980462fcde1acb5c11bb34604 100644
--- a/htdocs/api/index.php
+++ b/htdocs/api/index.php
@@ -241,6 +241,7 @@ if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/resources.json'
     else
     {
         $classfile = str_replace('_', '', $module);
+        if ($module == 'contracts')        $moduledirforclass = 'contrat';
         if ($module == 'supplierinvoices') $classfile = 'supplier_invoices';
         if ($module == 'supplierorders')   $classfile = 'supplier_orders';
         $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_'.$classfile.'.class.php');
diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php
index 8a1508b7a04d6fc75f7155a781fc143c7f433a7a..4bce16fb79639fc3515e7f411d79fbc5cf1c82c9 100644
--- a/htdocs/blockedlog/class/blockedlog.class.php
+++ b/htdocs/blockedlog/class/blockedlog.class.php
@@ -21,13 +21,15 @@
 
 class BlockedLog
 {
-
 	/**
 	 * Id of the log
 	 * @var int
 	 */
 	public $id;
 
+	public $error = '';
+	public $errors = array();
+
 	/**
 	 * Unique fingerprint of the log
 	 * @var string
@@ -78,7 +80,7 @@ class BlockedLog
 
 	public $object_data = null;
 
-	public $error = 0;
+
 
 	/**
 	 *      Constructor
@@ -126,7 +128,7 @@ class BlockedLog
 
 	/**
 	 *      try to retrieve user author
-	*/
+	 */
 	public function getUser() {
 		global $langs, $cachedUser;
 
@@ -188,8 +190,6 @@ class BlockedLog
 			$this->object_data->amounts = $object->amounts;
 
 		}
-
-
 	}
 
 	/**
@@ -231,7 +231,7 @@ class BlockedLog
 				$this->action			= $obj->action;
 				$this->element			= $obj->element;
 
-				$this->fk_object		= trim($obj->fk_object);
+				$this->fk_object		= $obj->fk_object;
 				$this->date_object		= $this->db->jdate($obj->date_object);
 				$this->ref_object		= $obj->ref_object;
 
@@ -432,10 +432,10 @@ class BlockedLog
 	/**
 	 *	return log object for a element.
 	 *
-	 *	@param	string $element      	element to search
-	 *	@param	int $fk_object			id of object to search
-	 *	@param	int $limit      		max number of element, 0 for all
-	 *	@param	string $order      		sort of query
+	 *	@param	string 	$element      	element to search
+	 *	@param	int 	$fk_object		id of object to search
+	 *	@param	int 	$limit      	max number of element, 0 for all
+	 *	@param	string 	$order      	sort of query
 	 *	@return	array					array of object log
 	 */
 	public function getLog($element, $fk_object, $limit = 0, $order = -1) {
diff --git a/htdocs/cashdesk/class/Facturation.class.php b/htdocs/cashdesk/class/Facturation.class.php
index b55524a874a2b087e4515f38a8bf3e6144065eb9..8bfd1d3082c037903c43acff9e784b3c37c8f4e5 100644
--- a/htdocs/cashdesk/class/Facturation.class.php
+++ b/htdocs/cashdesk/class/Facturation.class.php
@@ -117,7 +117,7 @@ class Facturation
         }
 
         // Define part of HT, VAT, TTC
-        $resultarray=calcul_price_total($this->qte, $this->prix(), $this->remisePercent(), $txtva, -1, -1, 0, 'HT', $use_npr, $product->type, $mysoc, $localtaxarray);
+        $resultarray=calcul_price_total($this->qte, $this->prix(), $this->remisePercent(), $txtva, -1, -1, 0, 'HT', $vat_npr, $product->type, $mysoc, $localtaxarray);
 
         // Calcul du total ht sans remise
         $total_ht = $resultarray[0];
@@ -207,6 +207,9 @@ class Facturation
 
         $total_ht=0;
         $total_ttc=0;
+        $total_vat = 0;
+        $total_localtax1 = 0;
+        $total_localtax2 = 0;
 
         $tab=array();
         $tab = $_SESSION['poscart'];
@@ -309,7 +312,7 @@ class Facturation
     public function ref($aRef=null)
      {
 
-        if ( !$aRef )
+        if (is_null($aRef))
         {
             return $this->ref;
         }
@@ -330,9 +333,9 @@ class Facturation
      * @param	int		$aQte		Qty
      * @return	int					Qty
      */
-    public function qte( $aQte=null )
+    public function qte($aQte=null)
     {
-        if ( !$aQte )
+        if (is_null($aQte))
         {
             return $this->qte;
         }
@@ -357,7 +360,7 @@ class Facturation
     public function stock($aStock=null)
     {
 
-        if ( !$aStock )
+        if (is_null($aStock))
         {
             return $this->stock;
         }
@@ -381,7 +384,7 @@ class Facturation
     public function remisePercent($aRemisePercent=null)
     {
 
-        if ( !$aRemisePercent )
+        if (is_null($aRemisePercent))
         {
             return $this->remise_percent;
         }
@@ -405,7 +408,7 @@ class Facturation
     public function montantRemise($aMontantRemise=null)
     {
 
-        if ( !$aMontantRemise ) {
+        if (is_null($aMontantRemise)) {
 
             return $this->montant_remise;
 
@@ -427,10 +430,10 @@ class Facturation
      * @param	int		$aPrix		Price
      * @return	string				Stock
      */
-    public function prix ( $aPrix=null )
+    public function prix($aPrix=null)
     {
 
-        if ( !$aPrix ) {
+        if (is_null($aPrix)) {
 
             return $this->prix;
 
@@ -454,7 +457,7 @@ class Facturation
      */
     public function tva($aTva=null)
     {
-        if ( !$aTva ) {
+        if (is_null($aTva)) {
 
             return $this->tva;
 
@@ -478,7 +481,7 @@ class Facturation
      */
     public function numInvoice($aNumFacture=null)
     {
-        if ( !$aNumFacture ) {
+        if (is_null($aNumFacture)) {
 
             return $this->num_facture;
 
@@ -499,10 +502,10 @@ class Facturation
      * @param	int		$aModeReglement		Payment mode
      * @return	int							Payment mode
      */
-    public function getSetPaymentMode( $aModeReglement=null )
+    public function getSetPaymentMode($aModeReglement=null)
     {
 
-        if ( !$aModeReglement ) {
+        if (is_null($aModeReglement)) {
 
             return $this->mode_reglement;
 
@@ -524,10 +527,10 @@ class Facturation
      * @param	int		$aMontantEncaisse		Amount
      * @return	int								Amount
      */
-    public function montantEncaisse( $aMontantEncaisse=null )
+    public function montantEncaisse($aMontantEncaisse=null)
     {
 
-        if ( !$aMontantEncaisse ) {
+        if (is_null($aMontantEncaisse)) {
 
             return $this->montant_encaisse;
 
@@ -549,10 +552,10 @@ class Facturation
      * @param	int			$aMontantRendu		Amount
      * @return	int								Amount
      */
-    public function montantRendu( $aMontantRendu=null )
+    public function montantRendu($aMontantRendu=null)
     {
 
-        if ( !$aMontantRendu ) {
+        if (is_null($aMontantRendu)) {
 
             return $this->montant_rendu;
         } else if ( $aMontantRendu == 'RESET' ) {
@@ -573,9 +576,9 @@ class Facturation
      * @param	date		$aPaiementLe		Date
      * @return	date							Date
      */
-    public function paiementLe( $aPaiementLe=null )
+    public function paiementLe($aPaiementLe=null)
     {
-        if ( !$aPaiementLe ) {
+        if (is_null($aPaiementLe)) {
 
             return $this->paiement_le;
 
@@ -596,9 +599,9 @@ class Facturation
      * @param	int		$aTotalHt		Total amount
      * @return	int						Total amount
      */
-    public function prixTotalHt( $aTotalHt=null )
+    public function prixTotalHt($aTotalHt=null)
     {
-        if ( !$aTotalHt ) {
+        if (is_null($aTotalHt)) {
 
             return $this->prix_total_ht;
 
@@ -619,9 +622,9 @@ class Facturation
      * @param	int		$aMontantTva	Amount vat
      * @return	int						Amount vat
      */
-    public function montantTva( $aMontantTva=null )
+    public function montantTva($aMontantTva=null)
     {
-        if ( !$aMontantTva ) {
+        if (is_null($aMontantTva)) {
 
             return $this->montant_tva;
 
@@ -643,9 +646,9 @@ class Facturation
      * @param	int		$aTotalTtc		Amount ttc
      * @return	int						Amount ttc
      */
-    public function prixTotalTtc( $aTotalTtc=null )
+    public function prixTotalTtc($aTotalTtc=null)
     {
-        if ( !$aTotalTtc )
+        if (is_null($aTotalTtc))
         {
             return $this->prix_total_ttc;
         }
diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php
index 6242691d1f14914827148f728b60f1b9cbb23a78..7a7a6f06a1f4473ba59f60a0b5c33952d70a35e1 100644
--- a/htdocs/categories/class/categorie.class.php
+++ b/htdocs/categories/class/categorie.class.php
@@ -163,7 +163,7 @@ class Categorie extends CommonObject
 	 */
 	public $socid;
 	/**
-	 * @var int Category type
+	 * @var string	Category type
 	 *
 	 * @see Categorie::TYPE_PRODUCT
 	 * @see Categorie::TYPE_SUPPLIER
@@ -1327,6 +1327,7 @@ class Categorie extends CommonObject
 		{
 			$w = array();
 			$i = 0;
+			$forced_color='';
 			foreach ($way as $cat)
 			{
 			    $i++;
@@ -1340,12 +1341,7 @@ class Categorie extends CommonObject
     			        $forced_color='categtextwhite';
     			        if ($cat->color)
     			        {
-    			            $hex=$cat->color;
-    			            $r = hexdec($hex[0].$hex[1]);
-    			            $g = hexdec($hex[2].$hex[3]);
-    			            $b = hexdec($hex[4].$hex[5]);
-    			            $bright = (max($r, $g, $b) + min($r, $g, $b)) / 510.0;    // HSL algorithm
-    			            if ($bright >= 0.5) $forced_color='categtextblack';        // Higher than 60%
+    			            if (colorIsLight($cat->color)) $forced_color='categtextblack';
     			        }
     			    }
 			    }
@@ -1602,12 +1598,7 @@ class Categorie extends CommonObject
 		$forced_color='categtextwhite';
 		if ($this->color)
 		{
-    		$hex=$this->color;
-    		$r = hexdec($hex[0].$hex[1]);
-    		$g = hexdec($hex[2].$hex[3]);
-    		$b = hexdec($hex[4].$hex[5]);
-    		$bright = (max($r, $g, $b) + min($r, $g, $b)) / 510.0;    // HSL algorithm
-    		if ($bright >= 0.5) $forced_color='categtextblack';        // Higher than 60%
+			if (colorIsLight($this->color)) $forced_color='categtextblack';
 		}
 
         $link = '<a href="'.DOL_URL_ROOT.'/categories/viewcat.php?id='.$this->id.'&type='.$this->type.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip '.$forced_color .'">';
diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php
index 325fad1a3264ff9824101b4bd015f21e4b4005da..b49baf164cadd3a271f505d78b061a6a155f8d32 100644
--- a/htdocs/comm/propal/class/api_proposals.class.php
+++ b/htdocs/comm/propal/class/api_proposals.class.php
@@ -287,7 +287,7 @@ class Proposals extends DolibarrApi
 	  );
 
 	  if ($updateRes > 0) {
-		return $this->get($id)->line->rowid;
+		return $updateRes;
 
 	  }
 	  return false;
diff --git a/htdocs/commande/class/api_deprecated_commande.class.php b/htdocs/commande/class/api_deprecated_commande.class.php
index d41fd9cee1d3b6554ff7f58fdfe2ddd7de24a137..1b84876c3afc1994e36419d4a0758e480ae3cbda 100644
--- a/htdocs/commande/class/api_deprecated_commande.class.php
+++ b/htdocs/commande/class/api_deprecated_commande.class.php
@@ -316,7 +316,7 @@ class CommandeApi extends DolibarrApi
       );
 
       if ($updateRes > 0) {
-        return $this->get($id)->line->rowid;
+        return $updateRes;
 
       }
       return false;
diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php
index 6ffca33a4ce2f86a07b465efd3fda54ce2b6c1e3..17ff8ae22f160c2fb3de429dea8eeeaf092c63ce 100644
--- a/htdocs/commande/class/api_orders.class.php
+++ b/htdocs/commande/class/api_orders.class.php
@@ -286,7 +286,7 @@ class Orders extends DolibarrApi
       );
 
       if ($updateRes > 0) {
-        return $this->get($id)->line->rowid;
+        return $updateRes;
 
       }
       return false;
diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
index 1ad2d87647833770351bb5185c4a2641efb9cfd4..79109ff511a59ef188830bae5a078b5497343c52 100644
--- a/htdocs/commande/class/commande.class.php
+++ b/htdocs/commande/class/commande.class.php
@@ -1240,7 +1240,7 @@ class Commande extends CommonOrder
     {
     	global $mysoc, $conf, $langs, $user;
 
-        dol_syslog(get_class($this)."::addline commandeid=$this->id, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_percent=$remise_percent, info_bits=$info_bits, fk_remise_except=$fk_remise_except, price_base_type=$price_base_type, pu_ttc=$pu_ttc, date_start=$date_start, date_end=$date_end, type=$type special_code=$special_code, fk_unit=$fk_unit", LOG_DEBUG);
+        dol_syslog(get_class($this)."::addline commandeid=$this->id, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_percent=$remise_percent, info_bits=$info_bits, fk_remise_except=$fk_remise_except, price_base_type=$price_base_type, pu_ttc=$pu_ttc, date_start=$date_start, date_end=$date_end, type=$type special_code=$special_code, fk_unit=$fk_unit, origin=$origin, origin_id=$origin_id, pu_ht_devise=$pu_ht_devise", LOG_DEBUG);
 
         include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
 
diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php
index d8a5a231593ab5d9a775abe55b3bc79557685fce..3d94595f558c35275321aa1eacd144ead454ff7a 100644
--- a/htdocs/compta/facture/class/api_invoices.class.php
+++ b/htdocs/compta/facture/class/api_invoices.class.php
@@ -421,7 +421,7 @@ class Invoices extends DolibarrApi
       );
 
       if ($updateRes > 0) {
-        return $this->get($id)->line->rowid;
+        return $updateRes;
 
       }
       throw new RestException(400, 'Unable to insert the new line. Check your inputs.');
diff --git a/htdocs/compta/paiement_charge.php b/htdocs/compta/paiement_charge.php
index 398f70ad36aeb6ff3fb412572a054dce4269a04f..95426b824a1104b7e8971752a420eac5eb89d210 100644
--- a/htdocs/compta/paiement_charge.php
+++ b/htdocs/compta/paiement_charge.php
@@ -169,6 +169,20 @@ if ($action == 'create')
     $charge->paiementtype=$charge->mode_reglement_id?$charge->mode_reglement_id:$charge->paiementtype;
 
 	$total = $charge->amount;
+		if (! empty($conf->use_javascript_ajax))
+		{
+			print "\n".'<script type="text/javascript" language="javascript">';
+
+			//Add js for AutoFill
+			print ' $(document).ready(function () {';
+			print ' 	$(".AutoFillAmount").on(\'click touchstart\', function(){
+                            var amount = $(this).data("value");
+							document.getElementById($(this).data(\'rowid\')).value = amount ;
+						});';
+			print '	});'."\n";
+
+			print '	</script>'."\n";
+		}
 
 	print load_fiche_titre($langs->trans("DoPayment"));
 	print "<br>\n";
@@ -294,7 +308,12 @@ if ($action == 'create')
 		if ($sumpaid < $objp->amount)
 		{
 			$namef = "amount_".$objp->id;
-			print '<input type="text" size="8" name="'.$namef.'">';
+			$nameRemain = "remain_".$objp->id;
+			if (!empty($conf->use_javascript_ajax))
+					print img_picto("Auto fill",'rightarrow', "class='AutoFillAmount' data-rowid='".$namef."' data-value='".($objp->amount - $sumpaid)."'");
+			$remaintopay=$objp->amount - $sumpaid;
+			print '<input type=hidden class="sum_remain" name="'.$nameRemain.'" value="'.$remaintopay.'">';
+			print '<input type="text" size="8" name="'.$namef.'" id="'.$namef.'">';
 		}
 		else
 		{
diff --git a/htdocs/contrat/class/api_contracts.class.php b/htdocs/contrat/class/api_contracts.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..7e92b8d6efe754a4e47ada958d02741f6b1cbfea
--- /dev/null
+++ b/htdocs/contrat/class/api_contracts.class.php
@@ -0,0 +1,532 @@
+<?php
+/* Copyright (C) 2015   Jean-François Ferry     <jfefe@aternatik.fr>
+ * Copyright (C) 2016	Laurent Destailleur		<eldy@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ use Luracast\Restler\RestException;
+
+ require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
+
+/**
+ * API class for contracts
+ *
+ * @access protected
+ * @class  DolibarrApiAccess {@requires user,external}
+ */
+class Contracts extends DolibarrApi
+{
+
+    /**
+     * @var array   $FIELDS     Mandatory fields, checked when create and update object
+     */
+    static $FIELDS = array(
+        'socid',
+    	'date_contrat',
+    	'commercial_signature_id',
+    	'commercial_suivi_id'
+    );
+
+    /**
+     * @var Contract $contract {@type Contrat}
+     */
+    public $contract;
+
+    /**
+     * Constructor
+     */
+    function __construct()
+    {
+		global $db, $conf;
+		$this->db = $db;
+        $this->contract = new Contrat($this->db);
+    }
+
+    /**
+     * Get properties of a contrat object
+     *
+     * Return an array with contrat informations
+     *
+     * @param       int         $id         ID of contract
+     * @return 	array|mixed data without useless information
+	 *
+     * @throws 	RestException
+     */
+    function get($id)
+    {
+		if(! DolibarrApiAccess::$user->rights->contrat->lire) {
+			throw new RestException(401);
+		}
+
+        $result = $this->contract->fetch($id);
+        if( ! $result ) {
+            throw new RestException(404, 'Contract not found');
+        }
+
+		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
+			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+		}
+
+        $this->contract->fetchObjectLinked();
+		return $this->_cleanObjectDatas($this->contract);
+    }
+
+
+
+    /**
+     * List contracts
+     *
+     * Get a list of contracts
+     *
+     * @param string	       $sortfield	        Sort field
+     * @param string	       $sortorder	        Sort order
+     * @param int		       $limit		        Limit for list
+     * @param int		       $page		        Page number
+     * @param string   	       $thirdparty_ids	    Thirdparty ids to filter contracts of. {@example '1' or '1,2,3'} {@pattern /^[0-9,]*$/i}
+     * @param string           $sqlfilters          Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
+     * @return  array                               Array of contract objects
+     *
+	 * @throws RestException
+     */
+    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
+        global $db, $conf;
+
+        $obj_ret = array();
+
+        // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
+        $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids;
+
+        // If the internal user must only see his customers, force searching by him
+        $search_sale = 0;
+        if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
+
+        $sql = "SELECT t.rowid";
+        if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
+        $sql.= " FROM ".MAIN_DB_PREFIX."contrat as t";
+
+        if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
+
+        $sql.= ' WHERE t.entity IN ('.getEntity('contrat').')';
+        if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc";
+        if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")";
+        if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc";		// Join for the needed table to filter by sale
+        // Insert sale filter
+        if ($search_sale > 0)
+        {
+            $sql .= " AND sc.fk_user = ".$search_sale;
+        }
+        // Add sql filters
+        if ($sqlfilters)
+        {
+            if (! DolibarrApi::_checkFilters($sqlfilters))
+            {
+                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
+            }
+	        $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
+            $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
+        }
+
+        $sql.= $db->order($sortfield, $sortorder);
+        if ($limit)	{
+            if ($page < 0)
+            {
+                $page = 0;
+            }
+            $offset = $limit * $page;
+
+            $sql.= $db->plimit($limit + 1, $offset);
+        }
+
+        dol_syslog("API Rest request");
+        $result = $db->query($sql);
+
+        if ($result)
+        {
+            $num = $db->num_rows($result);
+            $min = min($num, ($limit <= 0 ? $num : $limit));
+            while ($i < $min)
+            {
+                $obj = $db->fetch_object($result);
+                $contrat_static = new Contrat($db);
+                if($contrat_static->fetch($obj->rowid)) {
+                    $obj_ret[] = $this->_cleanObjectDatas($contrat_static);
+                }
+                $i++;
+            }
+        }
+        else {
+            throw new RestException(503, 'Error when retrieve contrat list : '.$db->lasterror());
+        }
+        if( ! count($obj_ret)) {
+            throw new RestException(404, 'No contract found');
+        }
+		return $obj_ret;
+    }
+
+    /**
+     * Create contract object
+     *
+     * @param   array   $request_data   Request data
+     * @return  int     ID of contrat
+     */
+    function post($request_data = NULL)
+    {
+      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
+			  throw new RestException(401, "Insuffisant rights");
+		  }
+        // Check mandatory fields
+        $result = $this->_validate($request_data);
+
+        foreach($request_data as $field => $value) {
+            $this->contract->$field = $value;
+        }
+        /*if (isset($request_data["lines"])) {
+          $lines = array();
+          foreach ($request_data["lines"] as $line) {
+            array_push($lines, (object) $line);
+          }
+          $this->contract->lines = $lines;
+        }*/
+        if ($this->contract->create(DolibarrApiAccess::$user) < 0) {
+            throw new RestException(500, "Error creating contract", array_merge(array($this->contract->error), $this->contract->errors));
+        }
+
+        return $this->contract->id;
+    }
+
+    /**
+     * Get lines of an contract
+     *
+     * @param int   $id             Id of contract
+     *
+     * @url	GET {id}/lines
+     *
+     * @return int
+     */
+    function getLines($id) {
+      if(! DolibarrApiAccess::$user->rights->contrat->lire) {
+		  	throw new RestException(401);
+		  }
+
+      $result = $this->contract->fetch($id);
+      if( ! $result ) {
+         throw new RestException(404, 'Contract not found');
+      }
+
+		  if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
+			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+      }
+      $this->contract->getLinesArray();
+      $result = array();
+      foreach ($this->contract->lines as $line) {
+        array_push($result,$this->_cleanObjectDatas($line));
+      }
+      return $result;
+    }
+
+    /**
+     * Add a line to given contract
+     *
+     * @param int   $id             Id of contrat to update
+     * @param array $request_data   Contractline data
+     *
+     * @url	POST {id}/lines
+     *
+     * @return int
+     */
+    function postLine($id, $request_data = NULL) {
+      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
+		  	throw new RestException(401);
+		  }
+
+      $result = $this->contract->fetch($id);
+      if( ! $result ) {
+         throw new RestException(404, 'Contract not found');
+      }
+
+		  if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
+			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+      }
+			$request_data = (object) $request_data;
+      $updateRes = $this->contract->addline(
+                        $request_data->desc,
+                        $request_data->subprice,
+                        $request_data->qty,
+                        $request_data->tva_tx,
+                        $request_data->localtax1_tx,
+                        $request_data->localtax2_tx,
+                        $request_data->fk_product,
+                        $request_data->remise_percent,
+                        $request_data->date_start,			// date ouverture = date_start_real
+                        $request_data->date_end,			// date_cloture = date_end_real
+                        $request_data->HT,
+      					$request_data->subprice_excl_tax,
+      					$request_data->info_bits,
+                        $request_data->fk_fournprice,
+				      	$request_data->pa_ht,
+      					$request_data->array_options,
+      					$request_data->fk_unit,
+      					$request_data->rang
+      );
+
+      if ($updateRes > 0) {
+        return $updateRes;
+
+      }
+      return false;
+    }
+
+    /**
+     * Update a line to given contract
+     *
+     * @param int   $id             Id of contrat to update
+     * @param int   $lineid         Id of line to update
+     * @param array $request_data   Contractline data
+     *
+     * @url	PUT {id}/lines/{lineid}
+     *
+     * @return object
+     */
+    function putLine($id, $lineid, $request_data = NULL) {
+      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
+		  	throw new RestException(401);
+		  }
+
+      $result = $this->contract->fetch($id);
+      if( ! $result ) {
+         throw new RestException(404, 'Contrat not found');
+      }
+
+		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
+			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+		}
+
+      $request_data = (object) $request_data;
+
+      $updateRes = $this->contract->updateline(
+                        $lineid,
+                        $request_data->desc,
+                        $request_data->subprice,
+                        $request_data->qty,
+                        $request_data->remise_percent,
+                        $request_data->date_ouveture_prevue,
+                        $request_data->date_fin_validite,
+      					$request_data->tva_tx,
+                        $request_data->localtax1_tx,
+                        $request_data->localtax2_tx,
+                        $request_data->date_ouverture,
+                        $request_data->date_cloture,
+      					'HT',
+                        $request_data->info_bits,
+                        $request_data->fk_fourn_price,
+                        $request_data->pa_ht,
+                        $request_data->array_options,
+                        $request_data->fk_unit
+      );
+
+      if ($updateRes > 0) {
+        $result = $this->get($id);
+        unset($result->line);
+        return $this->_cleanObjectDatas($result);
+      }
+
+      return false;
+    }
+
+    /**
+     * Delete a line to given contract
+     *
+     *
+     * @param int   $id             Id of contract to update
+     * @param int   $lineid         Id of line to delete
+     *
+     * @url	DELETE {id}/lines/{lineid}
+     *
+     * @return int
+     * @throws 401
+     * @throws 404
+     */
+    function deleteLine($id, $lineid) {
+      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
+		  	throw new RestException(401);
+		  }
+
+      $result = $this->contract->fetch($id);
+      if( ! $result ) {
+         throw new RestException(404, 'Contrat not found');
+      }
+
+		  if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
+			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+      }
+
+      $request_data = (object) $request_data;
+      $updateRes = $this->contract->deleteline($lineid, DolibarrApiAccess::$user);
+      if ($updateRes > 0) {
+        return $this->get($id);
+      }
+      return false;
+    }
+
+    /**
+     * Update contract general fields (won't touch lines of contract)
+     *
+     * @param int   $id             Id of contrat to update
+     * @param array $request_data   Datas
+     *
+     * @return int
+     */
+    function put($id, $request_data = NULL) {
+      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
+		  	throw new RestException(401);
+		  }
+
+        $result = $this->contract->fetch($id);
+        if( ! $result ) {
+            throw new RestException(404, 'Contrat not found');
+        }
+
+		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
+			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+		}
+        foreach($request_data as $field => $value) {
+            if ($field == 'id') continue;
+            $this->contract->$field = $value;
+        }
+
+        if($this->contract->update(DolibarrApiAccess::$user, 0))
+            return $this->get($id);
+
+        return false;
+    }
+
+    /**
+     * Delete contract
+     *
+     * @param   int     $id         Contract ID
+     *
+     * @return  array
+     */
+    function delete($id)
+    {
+        if(! DolibarrApiAccess::$user->rights->contrat->supprimer) {
+			throw new RestException(401);
+		}
+        $result = $this->contract->fetch($id);
+        if( ! $result ) {
+            throw new RestException(404, 'Contract not found');
+        }
+
+		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
+			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+		}
+
+        if( ! $this->contract->delete(DolibarrApiAccess::$user)) {
+            throw new RestException(500, 'Error when delete contract : '.$this->contract->error);
+        }
+
+        return array(
+            'success' => array(
+                'code' => 200,
+                'message' => 'Contract deleted'
+            )
+        );
+
+    }
+
+    /**
+     * Validate an contract
+     *
+     * @param   int $id             Contract ID
+     * @param   int $idwarehouse    Warehouse ID
+     * @param   int $notrigger      1=Does not execute triggers, 0= execute triggers
+     *
+     * @url POST    {id}/validate
+     *
+     * @return  array
+     * FIXME An error 403 is returned if the request has an empty body.
+     * Error message: "Forbidden: Content type `text/plain` is not supported."
+     * Workaround: send this in the body
+     * {
+     *   "idwarehouse": 0,
+     *   "notrigger": 0
+     * }
+     */
+    /*
+    function validate($id, $idwarehouse=0, $notrigger=0)
+    {
+        if(! DolibarrApiAccess::$user->rights->contrat->creer) {
+			throw new RestException(401);
+		}
+        $result = $this->contract->fetch($id);
+        if( ! $result ) {
+            throw new RestException(404, 'Contract not found');
+        }
+
+		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
+			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+		}
+
+		$result = $this->contract->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger);
+		if ($result == 0) {
+		    throw new RestException(500, 'Error nothing done. May be object is already validated');
+		}
+		if ($result < 0) {
+		    throw new RestException(500, 'Error when validating Contract: '.$this->contract->error);
+		}
+
+        return array(
+            'success' => array(
+                'code' => 200,
+                'message' => 'Contract validated (Ref='.$this->contract->ref.')'
+            )
+        );
+    }
+    */
+
+    /**
+     * Clean sensible object datas
+     *
+     * @param   object  $object    Object to clean
+     * @return    array    Array of cleaned object properties
+     */
+    function _cleanObjectDatas($object) {
+
+        $object = parent::_cleanObjectDatas($object);
+
+        unset($object->address);
+
+        return $object;
+    }
+
+    /**
+     * Validate fields before create or update object
+     *
+     * @param   array           $data   Array with data to verify
+     * @return  array
+     * @throws  RestException
+     */
+    function _validate($data)
+    {
+        $contrat = array();
+        foreach (Contracts::$FIELDS as $field) {
+            if (!isset($data[$field]))
+                throw new RestException(400, "$field field missing");
+            $contrat[$field] = $data[$field];
+
+        }
+        return $contrat;
+    }
+}
diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php
index 071ae75e5b7d36885f3dea8ad330a553f024e783..d54c2b521ffd5110b7a3856c387f7f644d8e3eca 100644
--- a/htdocs/contrat/class/contrat.class.php
+++ b/htdocs/contrat/class/contrat.class.php
@@ -1400,13 +1400,14 @@ class Contrat extends CommonObject
 	 *  @param  int			$pa_ht				Buying price HT
 	 *  @param	array		$array_options		extrafields array
 	 * 	@param 	string		$fk_unit 			Code of the unit to use. Null to use the default one
-	 *  @return int             				<0 si erreur, >0 si ok
+	 * 	@param 	string		$rang 				Position
+	 *  @return int             				<0 if KO, >0 if OK
 	 */
-	function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $date_start, $date_end, $price_base_type='HT', $pu_ttc=0.0, $info_bits=0, $fk_fournprice=null, $pa_ht = 0,$array_options=0, $fk_unit = null)
+	function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $date_start, $date_end, $price_base_type='HT', $pu_ttc=0.0, $info_bits=0, $fk_fournprice=null, $pa_ht = 0,$array_options=0, $fk_unit = null, $rang=0)
 	{
 		global $user, $langs, $conf, $mysoc;
 
-		dol_syslog(get_class($this)."::addline $desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $date_start, $date_end, $price_base_type, $pu_ttc, $info_bits");
+		dol_syslog(get_class($this)."::addline $desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $date_start, $date_end, $price_base_type, $pu_ttc, $info_bits, $rang");
 
 		if ($this->statut >= 0)
 		{
@@ -1616,7 +1617,7 @@ class Contrat extends CommonObject
 	{
 		global $user, $conf, $langs, $mysoc;
 
-		// Nettoyage parametres
+		// Clean parameters
 		$qty=trim($qty);
 		$desc=trim($desc);
 		$desc=trim($desc);
@@ -1625,6 +1626,7 @@ class Contrat extends CommonObject
 		$localtax1tx = price2num($localtax1tx);
 		$localtax2tx = price2num($localtax2tx);
 		$pa_ht=price2num($pa_ht);
+		if (empty($fk_fournprice)) $fk_fournprice=0;
 
 		$subprice = $price;
 		$remise = 0;
@@ -1701,7 +1703,7 @@ class Contrat extends CommonObject
 		$sql.= ", total_localtax1='".price2num($total_localtax1)."'";
 		$sql.= ", total_localtax2='".price2num($total_localtax2)."'";
 		$sql.= ", total_ttc='".      price2num($total_ttc)."'";
-		$sql.= ", fk_product_fournisseur_price='".$fk_fournprice."'";
+		$sql.= ", fk_product_fournisseur_price=".($fk_fournprice > 0 ? $fk_fournprice : "null");
 		$sql.= ", buy_price_ht='".price2num($pa_ht)."'";
 		if ($date_start > 0) { $sql.= ",date_ouverture_prevue='".$this->db->idate($date_start)."'"; }
 		else { $sql.=",date_ouverture_prevue=null"; }
@@ -1772,7 +1774,7 @@ class Contrat extends CommonObject
 	 *	@param  User	$user       User that delete
 	 *  @return int         		>0 if OK, <0 if KO
 	 */
-	function deleteline($idline,$user)
+	function deleteline($idline, User $user)
 	{
 		global $conf, $langs;
 
@@ -2343,7 +2345,17 @@ class Contrat extends CommonObject
 		}
 	}
 
-	/**
+    /**
+	 * 	Create an array of order lines
+	 *
+	 * 	@return int		>0 if OK, <0 if KO
+     */
+    function getLinesArray()
+    {
+        return $this->fetch_lines();
+    }
+
+    /**
 	 *  Create a document onto disk according to template module.
 	 *
 	 * 	@param	    string		$modele			Force model to use ('' to not force)
@@ -3033,7 +3045,7 @@ class ContratLigne extends CommonObjectLine
 		$sql.= " info_bits,";
 		$sql.= " price_ht, remise, fk_product_fournisseur_price, buy_price_ht";
 		if ($this->date_ouverture_prevue > 0) { $sql.= ",date_ouverture_prevue"; }
-		if ($this->date_fin_validite > 0)   { $sql.= ",date_fin_validite"; }
+		if ($this->date_fin_validite > 0)     { $sql.= ",date_fin_validite"; }
 		$sql.= ") VALUES ($this->fk_contrat, '', '" . $this->db->escape($this->description) . "',";
 		$sql.= ($this->fk_product>0 ? $this->fk_product : "null").",";
 		$sql.= " '".$this->db->escape($this->qty)."',";
@@ -3051,8 +3063,8 @@ class ContratLigne extends CommonObjectLine
 		else $sql.= ' null,';
 		if ($this->pa_ht > 0) $sql.= ' '.price2num($this->pa_ht);
 		else $sql.= ' null';
-		if ($this->date_ouverture_prevue > 0) { $sql.= ",'".$this->db->idate($this->date_ouverture_prevue)."'"; }
-		if ($this->date_fin_validite > 0) { $sql.= ",'".$this->db->idate($this->date_fin_validite)."'"; }
+		if ($this->date_ouverture > 0) { $sql.= ",'".$this->db->idate($this->date_ouverture)."'"; }
+		if ($this->date_cloture > 0)   { $sql.= ",'".$this->db->idate($this->date_cloture)."'"; }
 		$sql.= ")";
 
 		dol_syslog(get_class($this)."::insert", LOG_DEBUG);
diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php
index e382f5c81982ccb1dbc407e074d845613a97e43d..39487cf6fea968080443eab11af2e8e40cf8c268 100644
--- a/htdocs/core/class/CMailFile.class.php
+++ b/htdocs/core/class/CMailFile.class.php
@@ -275,7 +275,8 @@ class CMailFile
 			// comme des injections mail par les serveurs de messagerie.
 			$this->headers = preg_replace("/([\r\n]+)$/i","",$this->headers);
 
-			$this->message = $this->eol.'This is a message with multiple parts in MIME format.'.$this->eol;
+			//$this->message = $this->eol.'This is a message with multiple parts in MIME format.'.$this->eol;
+			$this->message = 'This is a message with multiple parts in MIME format.'.$this->eol;
 			$this->message.= $text_body . $files_encoded;
 			$this->message.= "--" . $this->mixed_boundary . "--" . $this->eol;
 		}
@@ -961,8 +962,8 @@ class CMailFile
 
 		//$out.= "From: ".$this->getValidAddress($this->addr_from,3,1).$this->eol;
 
-		$out.= "Content-Type: multipart/mixed; boundary=\"".$this->mixed_boundary."\"".$this->eol2;
-		$out.= "Content-Transfer-Encoding: 8bit".$this->eol2;
+		$out.= "Content-Type: multipart/mixed;".$this->eol2." boundary=\"".$this->mixed_boundary."\"".$this->eol2;
+		$out.= "Content-Transfer-Encoding: 8bit".$this->eol2;		// TODO Seems to be ignored. Header is 7bit once received.
 
 		dol_syslog("CMailFile::write_smtpheaders smtp_header=\n".$out);
 		return $out;
@@ -1014,23 +1015,23 @@ class CMailFile
 
 		if ($this->atleastoneimage)
 		{
-			$out.= "Content-Type: multipart/alternative; boundary=\"".$this->alternative_boundary."\"".$this->eol;
+			$out.= "Content-Type: multipart/alternative;".$this->eol." boundary=\"".$this->alternative_boundary."\"".$this->eol;
 			$out.= $this->eol;
 			$out.= "--" . $this->alternative_boundary . $this->eol;
 		}
 
 		// Make RFC821 Compliant, replace bare linefeeds
-		$strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $msgtext);
+		$strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $msgtext);	// PCRE modifier /s means new lines are common chars
 		if (! empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA))
 		{
-			$strContent = preg_replace("/\r\n/si", "\n", $strContent);
+			$strContent = preg_replace("/\r\n/si", "\n", $strContent);	// PCRE modifier /s means new lines are common chars
 		}
 
 		$strContentAltText = '';
 		if ($this->msgishtml)
 		{
 			$strContentAltText = html_entity_decode(strip_tags($strContent));
-			$strContentAltText = rtrim(wordwrap($strContentAltText, 75, "\r\n"));
+			$strContentAltText = rtrim(wordwrap($strContentAltText, 75, empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA)?"\r\n":"\n"));
 
 			// Check if html header already in message, if not complete the message
 			$strContent = $this->checkIfHTML($strContent);
@@ -1038,31 +1039,35 @@ class CMailFile
 
 		// Make RFC2045 Compliant, split lines
 		//$strContent = rtrim(chunk_split($strContent));    // Function chunck_split seems ko if not used on a base64 content
-		$strContent = rtrim(wordwrap($strContent));   // TODO Using this method creates unexpected line break on text/plain content.
+		// TODO Encode main content into base64 and use the chunk_split, or quoted-printable
+		$strContent = rtrim(wordwrap($strContent, 75, empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA)?"\r\n":"\n"));   // TODO Using this method creates unexpected line break on text/plain content.
 
 		if ($this->msgishtml)
 		{
 			if ($this->atleastoneimage)
 			{
 				$out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol;
+				//$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
 				$out.= $this->eol.($strContentAltText?$strContentAltText:strip_tags($strContent)).$this->eol; // Add plain text message
 				$out.= "--" . $this->alternative_boundary . $this->eol;
-				$out.= "Content-Type: multipart/related; boundary=\"".$this->related_boundary."\"".$this->eol;
+				$out.= "Content-Type: multipart/related;".$this->eol." boundary=\"".$this->related_boundary."\"".$this->eol;
 				$out.= $this->eol;
 				$out.= "--" . $this->related_boundary . $this->eol;
 			}
 
 			if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART))    // Add plain text message part before html part
 			{
-				$out.= "Content-Type: multipart/alternative; boundary=\"".$this->alternative_boundary."\"".$this->eol;
+				$out.= "Content-Type: multipart/alternative;".$this->eol." boundary=\"".$this->alternative_boundary."\"".$this->eol;
 				$out.= $this->eol;
 				$out.= "--" . $this->alternative_boundary . $this->eol;
 				$out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol;
+				//$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
 				$out.= $this->eol.$strContentAltText.$this->eol;
 				$out.= "--" . $this->alternative_boundary . $this->eol;
 			}
 
 			$out.= "Content-Type: text/html; charset=".$conf->file->character_set_client.$this->eol;
+			//$out.= "Content-Transfer-Encoding: 7bit".$this->eol;	// TODO Use base64
 			$out.= $this->eol.$strContent.$this->eol;
 
 			if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART))    // Add plain text message part after html part
@@ -1073,6 +1078,7 @@ class CMailFile
 		else
 		{
 			$out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol;
+			//$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
 			$out.= $this->eol.$strContent.$this->eol;
 		}
 
diff --git a/htdocs/core/class/emailsenderprofile.class.php b/htdocs/core/class/emailsenderprofile.class.php
index d2082bfba01969bb4f098d6df0d449e8e3ad6aed..f211a0b1670568034a744eb78c622fc8b29e9bea 100644
--- a/htdocs/core/class/emailsenderprofile.class.php
+++ b/htdocs/core/class/emailsenderprofile.class.php
@@ -273,7 +273,9 @@ class EmailSenderProfile extends CommonObject
 		$result = '';
 		$companylink = '';
 
-		$url='';
+    $label=$this->label;
+
+    $url='';
 		//$url = dol_buildpath('/monmodule/emailsenderprofile_card.php',1).'?id='.$this->id;
 
 		$linkstart = '';
diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php
index 9fc1739334cbca48ef6c666168af434ba18a21a0..99b799d5d6e0ca6f3b5079ac6fb153cb0b32810e 100644
--- a/htdocs/core/db/DoliDB.class.php
+++ b/htdocs/core/db/DoliDB.class.php
@@ -59,7 +59,7 @@ abstract class DoliDB implements Database
 	public $lastqueryerror;
 	/** @var string Last error message */
 	public $lasterror;
-	/** @var int Last error number */
+	/** @var string Last error number. For example: 'DB_ERROR_RECORD_ALREADY_EXISTS', '12345', ... */
 	public $lasterrno;
 
 	/** @var bool Status */
@@ -238,16 +238,16 @@ abstract class DoliDB implements Database
 				else $return.=', ';
 
 				$return.=preg_replace('/[^0-9a-z_\.]/i','',$val);
-				
+
 				$tmpsortorder = trim($orders[$i]);
-				
+
 				// Only ASC and DESC values are valid SQL
 				if (strtoupper($tmpsortorder) === 'ASC') {
 					$return .= ' ASC';
 				} elseif (strtoupper($tmpsortorder) === 'DESC') {
 					$return .= ' DESC';
 				}
-				
+
 				$i++;
 			}
 			return $return;
diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
index 44a404c6c672a1892402b5198859edce0b33bb5a..2f59c7e388c7305d53d1a8dce98c121ca7c77865 100644
--- a/htdocs/core/lib/files.lib.php
+++ b/htdocs/core/lib/files.lib.php
@@ -47,7 +47,7 @@ function dol_basename($pathfile)
  *  @param	string		$filter        	Regex filter to restrict list. This regex value must be escaped for '/' by doing preg_quote($var,'/'), since this char is used for preg_match function,
  *                                      but must not contains the start and end '/'. Filter is checked into basename only.
  *  @param	array		$excludefilter  Array of Regex for exclude filter (example: array('(\.meta|_preview.*\.png)$','^\.')). Exclude is checked into fullpath.
- *  @param	string		$sortcriteria	Sort criteria ("","fullname","relativename","name","date","size")
+ *  @param	string		$sortcriteria	Sort criteria ('','fullname','relativename','name','date','size')
  *  @param	string		$sortorder		Sort order (SORT_ASC, SORT_DESC)
  *	@param	int			$mode			0=Return array minimum keys loaded (faster), 1=Force all keys like date and size to be loaded (slower), 2=Force load of date only, 3=Force load of size only
  *  @param	int			$nohook			Disable all hooks
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index f56cd2f523d84b085caa90a98fc2c9ee47f7b115..2626e917460637dd9cdb40b0e197d9851146cecb 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -6791,3 +6791,37 @@ function getDictvalue($tablename, $field, $id, $checkentity=false, $rowidfield='
 		return '';
 	}
 }
+
+/**
+ *	Return true if the color is light
+ *
+ *  @param	string	$stringcolor		String with hex (FFFFFF) or comma RGB ('255,255,255')
+ *  @return	int							-1 : Error with argument passed |0 : color is dark | 1 : color is light
+ */
+function colorIsLight($stringcolor)
+{
+	$res = -1;
+	if (!empty($stringcolor))
+	{
+		$res = 0;
+		$tmp=explode(',', $stringcolor);
+		if (count($tmp) > 1)   // This is a comma RGB ('255','255','255')
+		{
+			$r = $tmp[0];
+			$g = $tmp[1];
+			$b = $tmp[2];
+		}
+		else
+		{
+			$hexr=$stringcolor[0].$stringcolor[1];
+			$hexg=$stringcolor[2].$stringcolor[3];
+			$hexb=$stringcolor[4].$stringcolor[5];
+			$r = hexdec($hexr);
+			$g = hexdec($hexg);
+			$b = hexdec($hexb);
+		}
+		$bright = (max($r, $g, $b) + min($r, $g, $b)) / 510.0;    // HSL algorithm
+		if ($bright > 0.6) $res = 1;
+	}
+	return $res;
+}
diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php
index 3d2e2bb359b1df18d0055d0134bd160156fbe936..7697c4e56a9ef6cf8c6c60673d1582261ea681b5 100644
--- a/htdocs/core/lib/functions2.lib.php
+++ b/htdocs/core/lib/functions2.lib.php
@@ -1606,7 +1606,8 @@ function getListOfModels($db,$type,$maxfilenamelength=0)
                     if (! $tmpdir) { unset($listofdir[$key]); continue; }
                     if (is_dir($tmpdir))
                     {
-                        $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.od(s|t)$','','name',SORT_ASC,0);
+			// all type of template is allowed
+			$tmpfiles=dol_dir_list($tmpdir, 'files', 0, '', '', 'name', SORT_ASC, 0);  
                         if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles);
                     }
                 }
@@ -2153,40 +2154,6 @@ function colorStringToArray($stringcolor,$colorifnotfound=array(88,88,88))
 	return array(hexdec($reg[1]),hexdec($reg[2]),hexdec($reg[3]));
 }
 
-/**
- *	Return true if the color is light
- *
- *  @param	string	$stringcolor		String with hex (FFFFFF) or comma RGB ('255,255,255')
- *  @return	int							-1 : Error with argument passed |0 : color is dark | 1 : color is light
- */
-function colorIsLight($stringcolor)
-{
-	$res = -1;
-	if (!empty($stringcolor))
-	{
-		$res = 0;
-		$tmp=explode(',', $stringcolor);
-		if (count($tmp) > 1)   // This is a comma RGB ('255','255','255')
-		{
-			$r = $tmp[0];
-			$g = $tmp[1];
-			$b = $tmp[2];
-		}
-		else
-		{
-			$hexr=$stringcolor[0].$stringcolor[1];
-			$hexg=$stringcolor[2].$stringcolor[3];
-			$hexb=$stringcolor[4].$stringcolor[5];
-			$r = hexdec($hexr);
-			$g = hexdec($hexg);
-			$b = hexdec($hexb);
-		}
-		$bright = (max($r, $g, $b) + min($r, $g, $b)) / 510.0;    // HSL algorithm
-		if ($bright > 0.6) $res = 1;
-	}
-	return $res;
-}
-
 /**
  * Applies the Cartesian product algorithm to an array
  * Source: http://stackoverflow.com/a/15973172
diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php
index d1f123b791f5e236ba8c0c93a338c807f52c55c7..3085c3659becbeffb20d96f182e27786e33502a5 100644
--- a/htdocs/expensereport/class/api_expensereports.class.php
+++ b/htdocs/expensereport/class/api_expensereports.class.php
@@ -271,7 +271,7 @@ class ExpenseReports extends DolibarrApi
       );
 
       if ($updateRes > 0) {
-        return $this->get($id)->line->rowid;
+        return $updateRes;
 
       }
       return false;
diff --git a/htdocs/modulebuilder/template/class/api_myobject.class.php b/htdocs/modulebuilder/template/class/api_myobject.class.php
index e3e38cefd3802077b99fe96143d4af273789abd8..e4a02468557f63a5f1695e33ae3f29d375b76667 100644
--- a/htdocs/modulebuilder/template/class/api_myobject.class.php
+++ b/htdocs/modulebuilder/template/class/api_myobject.class.php
@@ -231,7 +231,7 @@ class MyObjectApi extends DolibarrApi
         }
 
         if($this->myobject->update($id, DolibarrApiAccess::$user))
-            return $this->get ($id);
+            return $this->get($id);
 
         return false;
     }
diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php
index c63c4cfbd23efd36faad895fa0ab0b653e8d58aa..6fcdfde7ca2994d50c7a55acdc2ef37252f716df 100644
--- a/htdocs/projet/class/api_projects.class.php
+++ b/htdocs/projet/class/api_projects.class.php
@@ -342,7 +342,7 @@ class Projects extends DolibarrApi
       );
 
       if ($updateRes > 0) {
-        return $this->get($id)->line->rowid;
+        return $updateRes;
 
       }
       return false;
diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php
index 168afc2cb0cd95ffa2b3ef17854186380f040e28..f00a536df87ce035ae431b2ea51340416a968cd3 100644
--- a/htdocs/projet/class/api_tasks.class.php
+++ b/htdocs/projet/class/api_tasks.class.php
@@ -20,7 +20,7 @@
 
  require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
  require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
- 
+
 /**
  * API class for projects
  *
@@ -88,12 +88,12 @@ class Tasks extends DolibarrApi
 		    // TODO
 		    // Add class for timespent records and loop and fill $line->lines with records of timespent
 		}
-		
+
 		return $this->_cleanObjectDatas($this->task);
     }
 
-    
-   
+
+
     /**
      * List tasks
      *
@@ -110,7 +110,7 @@ class Tasks extends DolibarrApi
         global $db, $conf;
 
         $obj_ret = array();
-        
+
         // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
         $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids;
 
@@ -134,7 +134,7 @@ class Tasks extends DolibarrApi
             $sql .= " AND sc.fk_user = ".$search_sale;
         }
         // Add sql filters
-        if ($sqlfilters) 
+        if ($sqlfilters)
         {
             if (! DolibarrApi::_checkFilters($sqlfilters))
             {
@@ -143,7 +143,7 @@ class Tasks extends DolibarrApi
 	        $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
             $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
         }
-        
+
         $sql.= $db->order($sortfield, $sortorder);
         if ($limit)	{
             if ($page < 0)
@@ -236,7 +236,7 @@ class Tasks extends DolibarrApi
       }
       $this->project->getLinesArray(DolibarrApiAccess::$user);
       $result = array();
-      foreach ($this->project->lines as $line)      // $line is a task 
+      foreach ($this->project->lines as $line)      // $line is a task
       {
           if ($includetimespent == 1)
           {
@@ -252,7 +252,7 @@ class Tasks extends DolibarrApi
       return $result;
     }
     */
-    
+
     /**
      * Get roles a user is assigned to a task with
      *
@@ -265,20 +265,20 @@ class Tasks extends DolibarrApi
      */
     function getRoles($id, $userid=0) {
         global $db;
-        
+
         if(! DolibarrApiAccess::$user->rights->projet->lire) {
             throw new RestException(401);
         }
-    
+
         $result = $this->task->fetch($id);
         if( ! $result ) {
             throw new RestException(404, 'Task not found');
         }
-    
+
         if( ! DolibarrApi::_checkAccessToResource('task',$this->task->id)) {
             throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
         }
-        
+
         $usert = DolibarrApiAccess::$user;
         if ($userid > 0)
         {
@@ -292,8 +292,8 @@ class Tasks extends DolibarrApi
         }
         return $result;
     }
-    
-    
+
+
     /**
      * Add a task to given project
      *
@@ -348,13 +348,13 @@ class Tasks extends DolibarrApi
       );
 
       if ($updateRes > 0) {
-        return $this->get($id)->line->rowid;
+        return $updateRes;
 
       }
       return false;
     }
     */
-    
+
     /**
      * Update a task to given project
      *
@@ -412,8 +412,8 @@ class Tasks extends DolibarrApi
       }
       return false;
     }*/
-    
-    
+
+
     /**
      * Update task general fields (won't touch time spent of task)
      *
@@ -484,7 +484,7 @@ class Tasks extends DolibarrApi
 
     }
 
-    
+
     /**
      * Add time spent to a task of a project.
      * You can test this API with the following input message
@@ -495,15 +495,15 @@ class Tasks extends DolibarrApi
      * @param   int         $duration           Duration in seconds (3600 = 1h)
      * @param   int         $user_id            User (Use 0 for connected user)
      * @param   string      $note               Note
-     * 
+     *
      * @url POST    {id}/addtimespent
      *
      * @return  array
      */
     function addTimeSpent($id, $date, $duration, $user_id=0, $note='')
     {
-    	
-    	
+
+
         if( ! DolibarrApiAccess::$user->rights->projet->creer) {
             throw new RestException(401);
         }
@@ -511,22 +511,22 @@ class Tasks extends DolibarrApi
         if ($result <= 0) {
             throw new RestException(404, 'Task not found');
         }
-        
+
         if( ! DolibarrApi::_checkAccessToResource('project', $this->task->fk_project)) {
             throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
         }
-        
+
         $uid = $user_id;
         if (empty($uid)) $uid = DolibarrApiAccess::$user->id;
 
-        $newdate = dol_stringtotime($date, 1);    
+        $newdate = dol_stringtotime($date, 1);
         $this->task->timespent_date = $newdate;
         $this->task->timespent_datehour = $newdate;
         $this->task->timespent_withhour = 1;
         $this->task->timespent_duration = $duration;
         $this->task->timespent_fk_user  = $user_id;
-        $this->task->timespent_note     = $note; 
-        
+        $this->task->timespent_note     = $note;
+
         $result = $this->task->addTimeSpent(DolibarrApiAccess::$user, 0);
         if ($result == 0) {
             throw new RestException(500, 'Error nothing done. May be object is already validated');
@@ -534,7 +534,7 @@ class Tasks extends DolibarrApi
         if ($result < 0) {
             throw new RestException(500, 'Error when adding time: '.$this->task->error);
         }
-    
+
         return array(
             'success' => array(
                 'code' => 200,
@@ -542,8 +542,8 @@ class Tasks extends DolibarrApi
             )
         );
     }
-    
-    
+
+
     /**
      * Clean sensible object datas
      *
@@ -551,9 +551,9 @@ class Tasks extends DolibarrApi
      * @return    array    Array of cleaned object properties
      */
     function _cleanObjectDatas($object) {
-    
+
         $object = parent::_cleanObjectDatas($object);
-    
+
         unset($object->barcode_type);
         unset($object->barcode_type_code);
         unset($object->barcode_type_label);
@@ -575,21 +575,21 @@ class Tasks extends DolibarrApi
         unset($object->country);
         unset($object->country_id);
         unset($object->country_code);
-        
+
         unset($object->weekWorkLoad);
         unset($object->weekWorkLoad);
-        
+
         //unset($object->lines);            // for task we use timespent_lines, but for project we use lines
-        
+
         unset($object->total_ht);
         unset($object->total_tva);
         unset($object->total_localtax1);
         unset($object->total_localtax2);
         unset($object->total_ttc);
-        
+
         return $object;
     }
-    
+
     /**
      * Validate fields before create or update object
      *
@@ -608,8 +608,8 @@ class Tasks extends DolibarrApi
         }
         return $object;
     }
-    
-    
+
+
     // TODO
     // getSummaryOfTimeSpent
 }