diff --git a/ChangeLog b/ChangeLog
index a009533f07a4efd57e07bd2e02f263a444dac13f..21d3ebc66b306938111e4648770a3a475679db17 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,8 +6,8 @@ WARNING:
 
 Do not try to make any Dolibarr upgrade if you are running Mysql version 5.5.40.
 Mysql version 5.5.40 has a very critical bug making your data beeing definitely lost.
-You may also experience troubles with Mysql 5.5.41/42/43 with error "Lost connection"
-during migration.
+You may also experience troubles with Mysql 5.5.41/42/43 with error "Lost connection" during
+migration.
 Upgrading to any other version or any other database system is abolutely required BEFORE trying
 make a Dolibarr upgrade.
 
@@ -25,6 +25,8 @@ Dolibarr 4.0 should be compatible with PHP 7 but more feedbacks are still expect
 Following changes may create regression for some external modules, but were necessary to make
 Dolibarr better:
 - Function log() of class CommandeFournisseur has been removed. Using it is no more required.
+- Class Resource was renamed into DolResource to avoid conflict with a reserved PHP word.
+- Method commonobject->add_thumb() has been renamed into commonobject->addThumbs().
 - Method select_type_comptes_financiers() has been renamed into selectTypeOfBankAccount() 
 - Property ->client that was deprecated 6 years ago, is replaced in all core code with ->thirdparty.
 - File '/core/tpl/document_actions_pre_headers.tpl.php' were renamed into '/core/actions_linkedfiles.inc.php'.
@@ -33,7 +35,6 @@ So if you included it into your module, change your code like this to be compati
   if (! $res) include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php';
 
 
-
 ***** ChangeLog for 3.9.1 compared to 3.9.* *****
 FIX: #3815 Call to undefined function local_by_date()
 FIX: #4424 Missing email of user popup in supplier orders area
diff --git a/build/exe/doliwamp/doliwamp.bmp b/build/exe/doliwamp/doliwamp.bmp
index 52b1320d1113e36e744c5ebb2f1aaa5b397e5b0f..87191204d8c3c761212b3b902091a976bc9a495e 100644
Binary files a/build/exe/doliwamp/doliwamp.bmp and b/build/exe/doliwamp/doliwamp.bmp differ
diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl
index b8c4f2fb475c967c2527a724e6c357273575b20d..8a70ea73f2ccc8cdf0c4a4ceb960fdb8953fb02e 100755
--- a/build/makepack-dolibarr.pl
+++ b/build/makepack-dolibarr.pl
@@ -379,7 +379,7 @@ if ($nboftargetok) {
 			
 		print 'Run git tag -a -m "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'" "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'"'."\n";
 		$ret=`git tag -a -m "$MAJOR.$MINOR.$BUILD" "$MAJOR.$MINOR.$BUILD" 2>&1`;
-		if ($ret =~ /already exists/)
+		if ($ret =~ /(already exists|existe déjà)/)
 		{
 			print "WARNING: Tag ".$MAJOR.'.'.$MINOR.'.'.$BUILD." already exists. Overwrite (y/N) ? ";
 			$QUESTIONOVERWRITETAG=<STDIN>; 
diff --git a/doc/images/dolibarr_screenshot1_1280x800.png b/doc/images/dolibarr_screenshot1_1280x800.png
index 9aa799a10a7653e30fc982fec526a39b2ad1981b..684feb62390ef1084bbfc9aa407de83b39c00bf8 100644
Binary files a/doc/images/dolibarr_screenshot1_1280x800.png and b/doc/images/dolibarr_screenshot1_1280x800.png differ
diff --git a/doc/images/dolibarr_screenshot1_300x188.png b/doc/images/dolibarr_screenshot1_300x188.png
index 9fab4daa8ef1b419d2c135dd9a71008d65c8a0cc..b849e20220668168fe1792ce2f13be1b228a960e 100644
Binary files a/doc/images/dolibarr_screenshot1_300x188.png and b/doc/images/dolibarr_screenshot1_300x188.png differ
diff --git a/doc/images/dolibarr_screenshot1_640x400.png b/doc/images/dolibarr_screenshot1_640x400.png
index 3f0d38832e1f06c5fd28eef667140e8c3b94e811..9efefcc2405a29c62482a310fc1a947f602eff1c 100644
Binary files a/doc/images/dolibarr_screenshot1_640x400.png and b/doc/images/dolibarr_screenshot1_640x400.png differ
diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php
index c32846ae22effd6178ddb8359723e1b0e9271f2b..c990465bacf7a078b1f13b297a726fdf05823ff2 100644
--- a/htdocs/accountancy/journal/bankjournal.php
+++ b/htdocs/accountancy/journal/bankjournal.php
@@ -238,7 +238,7 @@ if ($result) {
 					$paymentsalstatic->ref = $links[$key]['url_id'];
 					$paymentsalstatic->label = $links[$key]['label'];
 					$tabpay[$obj->rowid]["lib"] .= ' ' . $paymentsalstatic->getNomUrl(2);
-					$tabtp[$obj->rowid][$account_employee ] += $obj->amount;
+					$tabtp[$obj->rowid][$account_employee] += $obj->amount;
 				} else if ($links[$key]['type'] == 'banktransfert') {
 					$tabpay[$obj->rowid]["lib"] .= ' ' . $langs->trans("BankTransfer");
 					$tabtp[$obj->rowid][$account_transfer] += $obj->amount;
@@ -418,12 +418,27 @@ if ($action == 'export_csv') {
 		foreach ( $tabpay as $key => $val ) {
 			$date = dol_print_date($db->jdate($val["date"]), '%d%m%Y');
 
+			$reflabel = $val["ref"];
+			if ($reflabel == '(SupplierInvoicePayment)') {
+				$reflabel = $langs->trans('Supplier');
+			}
+			if ($reflabel == '(CustomerInvoicePayment)') {
+				$reflabel = $langs->trans('Customer');
+			}		
+			if ($reflabel == '(SocialContributionPayment)') {
+				$reflabel = $langs->trans('SocialContribution');
+			}
+			if ($reflabel == '(DonationPayment)') {
+				$reflabel = $langs->trans('Donation');
+			}
+			if ($reflabel == '(SubscriptionPayment)') {
+				$reflabel = $langs->trans('Donation');
+			}
+			
 			$companystatic->id = $tabcompany[$key]['id'];
 			$companystatic->name = $tabcompany[$key]['name'];
 			$companystatic->client = $tabcompany[$key]['code_client'];
 
-			$date = dol_print_date($db->jdate($val["date"]), '%d%m%Y');
-
 			// Bank
 			foreach ( $tabbq[$key] as $k => $mt ) {
 				print $date . $sep;
@@ -432,8 +447,12 @@ if ($action == 'export_csv') {
 				print $sep;
 				print ($mt < 0 ? 'C' : 'D') . $sep;
 				print ($mt <= 0 ? price(- $mt) : $mt) . $sep;
-				print $val["type_payment"] . $sep;
-				print utf8_decode($val["ref"]) . $sep;
+				if ($companystatic->name == '') {
+					print $langs->trans('Bank')." - ". utf8_decode($val["ref"]) . $sep;
+				} else {
+					print $langs->trans("Bank") .' - '.utf8_decode($companystatic->name) . $sep;
+				}
+				print utf8_decode($reflabel) . $sep;
 				print "\n";
 			}
 
@@ -443,33 +462,45 @@ if ($action == 'export_csv') {
 					if ($mt) {
 						print $date . $sep;
 						print $journal . $sep;
-						if ($val["lib"] == '(SupplierInvoicePayment)') {
+						if ($tabtype[$key] == 'payment') {
+							print length_accountg($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) . $sep;
+							print length_accounta(html_entity_decode($k)) . $sep;
+						} else if ($tabtype[$key] == 'payment_supplier') {
 							print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) . $sep;
+							print length_accounta(html_entity_decode($k)) . $sep;
 						} else {
-							print length_accountg($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) . $sep;
+							print length_accountg(html_entity_decode($k)) . $sep;
+							print $sep;
 						}
-						print length_accounta(html_entity_decode($k)) . $sep;
 						print ($mt < 0 ? 'D' : 'C') . $sep;
 						print ($mt <= 0 ? price(- $mt) : $mt) . $sep;
-						print $val["type_payment"] . $sep;
-						print utf8_decode($val["ref"]) . $sep;
+						if ($companystatic->name == '') {
+							print $langs->trans('ThirdParty')." - ". utf8_decode($val["ref"]) . $sep;
+						} else {
+							print $langs->trans('ThirdParty')." - ". utf8_decode($companystatic->name) . $sep;
+						}
+						print utf8_decode($reflabel) . $sep;
 						print "\n";
 					}
 				}
 			} else {
 				foreach ( $tabbq[$key] as $k => $mt ) {
-						print $date . $sep;
-						print $journal . $sep;
-						print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . $sep;
-						print $sep;
-						print ($mt < 0 ? 'D' : 'C') . $sep;
-						print ($mt <= 0 ? price(- $mt) : $mt) . $sep;
-						print $val["type_payment"] . $sep;
-					print utf8_decode($val["ref"]) . $sep;
-						print "\n";
+					print $date . $sep;
+					print $journal . $sep;
+					print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . $sep;
+					print $sep;
+					print ($mt < 0 ? 'D' : 'C') . $sep;
+					print ($mt <= 0 ? price(- $mt) : $mt) . $sep;
+					if ($companystatic->name == '') {
+						print $langs->trans('ThirdParty')." - ". utf8_decode($val["ref"]) . $sep;
+					} else {
+						print $langs->trans('ThirdParty')." - ". utf8_decode($companystatic->name) . $sep;
 					}
+					print utf8_decode($reflabel) . $sep;
+					print "\n";
 				}
 			}
+		}
 	} else {
 		// Model Classic Export
 		foreach ( $tabpay as $key => $val ) {
@@ -480,6 +511,7 @@ if ($action == 'export_csv') {
 
 			// Bank
 			foreach ( $tabbq[$key] as $k => $mt ) {
+				print '"' . $journal . '"' . $sep;
 				print '"' . $date . '"' . $sep;
 				print '"' . $val["type_payment"] . '"' . $sep;
 				print '"' . length_accountg(html_entity_decode($k)) . '"' . $sep;
@@ -488,7 +520,6 @@ if ($action == 'export_csv') {
 				} else {
 					print '"' . $langs->trans("Bank") . ' - ' . utf8_decode($companystatic->name) . '"' . $sep;
 				}
-				// print '"' . $langs->trans("Bank") . '"' . $sep;
 				print '"' . ($mt >= 0 ? price($mt) : '') . '"' . $sep;
 				print '"' . ($mt < 0 ? price(- $mt) : '') . '"';
 				print "\n";
@@ -498,10 +529,10 @@ if ($action == 'export_csv') {
 			if (is_array($tabtp[$key])) {
 				foreach ( $tabtp[$key] as $k => $mt ) {
 					if ($mt) {
+						print '"' . $journal . '"' . $sep;
 						print '"' . $date . '"' . $sep;
 						print '"' . $val["type_payment"] . '"' . $sep;
 						print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep;
-						// print '"' . $companystatic->name . '"' . $sep;
 						if ($companystatic->name == '') {
 							print '"' . $langs->trans('ThirdParty') . " - " . utf8_decode($val["ref"]) . '"' . $sep;
 						} else {
@@ -514,10 +545,10 @@ if ($action == 'export_csv') {
 				}
 			} else {
 				foreach ( $tabbq[$key] as $k => $mt ) {
+					print '"' . $journal . '"' . $sep;
 					print '"' . $date . '"' . $sep;
 					print '"' . $val["ref"] . '"' . $sep;
 					print '"' . length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . '"' . $sep;
-					// print '"' . $langs->trans("Bank") . '"' . $sep;
 					if ($companystatic->name == '') {
 						print '"' . $langs->trans("Bank") . ' - ' . utf8_decode($val["ref"]) . '"' . $sep;
 					} else {
@@ -599,6 +630,9 @@ else {
 		if ($reflabel == '(DonationPayment)') {
 			$reflabel = $langs->trans('Donation');
 		}
+		if ($reflabel == '(SubscriptionPayment)') {
+			$reflabel = $langs->trans('SubscriptionPayment');
+		}
 
 		// Bank
 		foreach ( $tabbq[$key] as $k => $mt ) {
diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php
index c9e07677512afcab91c8582c863a8e3f67914e53..ee6cbac057f2008c3b77d5ba04686a430123bd07 100644
--- a/htdocs/admin/company.php
+++ b/htdocs/admin/company.php
@@ -731,7 +731,9 @@ else
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("CompanyCurrency").'</td><td>';
 	print currency_name($conf->currency,1);
-	print ' ('.$langs->getCurrencySymbol($conf->currency).')';
+	print ' ('.$conf->currency;
+	print ($conf->currency != $langs->getCurrencySymbol($conf->currency) ? ' - '.$langs->getCurrencySymbol($conf->currency) : '');
+	print ')';
 	print '</td></tr>';
 
 	$var=!$var;
diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php
index ea745e45df7d59c6195032cb7f3e638311fc180a..f51a2994c606f7ced21cfbb1e76f47e4820ae8ce 100644
--- a/htdocs/admin/dict.php
+++ b/htdocs/admin/dict.php
@@ -189,7 +189,7 @@ $tabsql[28]= "SELECT h.rowid as rowid, h.code, h.label, h.affect, h.delay, h.new
 $tabsql[29]= "SELECT rowid   as rowid, code, label, percent, position, active FROM ".MAIN_DB_PREFIX."c_lead_status";
 $tabsql[30]= "SELECT rowid, code, name, paper_size, orientation, metric, leftmargin, topmargin, nx, ny, spacex, spacey, width, height, font_size, custom_x, custom_y, active FROM ".MAIN_DB_PREFIX."c_format_cards";
 $tabsql[31]= "SELECT s.rowid as rowid, pcg_version, s.fk_pays as country_id, c.code as country_code, c.label as country, s.label, s.active FROM ".MAIN_DB_PREFIX."accounting_system as s, ".MAIN_DB_PREFIX."c_country as c WHERE s.fk_pays=c.rowid and c.active=1";
-$tabsql[32]= "SELECT a.rowid as rowid, a.code as code, a.label, a.range_account, a.position, a.fk_country as country_id, c.code as country_code, c.label as country, a.active FROM ".MAIN_DB_PREFIX."c_accounting_category as a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_country=c.rowid and c.active=1";
+$tabsql[32]= "SELECT a.rowid as rowid, a.code as code, a.label, a.range_account, a.sens, a.category_type, a.formula, a.position as position, a.fk_country as country_id, c.code as country_code, c.label as country, a.active FROM ".MAIN_DB_PREFIX."c_accounting_category as a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_country=c.rowid and c.active=1";
 $tabsql[33]= "SELECT rowid, pos, code, label, active FROM ".MAIN_DB_PREFIX."c_hrm_department";
 $tabsql[34]= "SELECT rowid, pos, code, label, c_level, active FROM ".MAIN_DB_PREFIX."c_hrm_function";
 
@@ -226,7 +226,7 @@ $tabsqlsort[28]="country ASC, code ASC";
 $tabsqlsort[29]="position ASC";
 $tabsqlsort[30]="code ASC";
 $tabsqlsort[31]="pcg_version ASC";
-$tabsqlsort[32]="code ASC, label ASC";
+$tabsqlsort[32]="position ASC";
 $tabsqlsort[33]="code ASC";
 $tabsqlsort[34]="code ASC";
 
@@ -263,7 +263,7 @@ $tabfield[28]= "code,label,affect,delay,newbymonth,country_id,country";
 $tabfield[29]= "code,label,percent,position";
 $tabfield[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y";
 $tabfield[31]= "pcg_version,country_id,country,label";
-$tabfield[32]= "code,label,range,position,country_id,country";
+$tabfield[32]= "code,label,range_account,sens,category_type,formula,position,country_id,country";
 $tabfield[33]= "code,label";
 $tabfield[34]= "code,label";
 
@@ -300,7 +300,7 @@ $tabfieldvalue[28]= "code,label,affect,delay,newbymonth,country";
 $tabfieldvalue[29]= "code,label,percent,position";
 $tabfieldvalue[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y";
 $tabfieldvalue[31]= "pcg_version,country,label";
-$tabfieldvalue[32]= "code,label,range_account,position,country";
+$tabfieldvalue[32]= "code,label,range_account,sens,category_type,formula,position,country";
 $tabfieldvalue[33]= "code,label";
 $tabfieldvalue[34]= "code,label";
 
@@ -337,7 +337,7 @@ $tabfieldinsert[28]= "code,label,affect,delay,newbymonth,fk_country";
 $tabfieldinsert[29]= "code,label,percent,position";
 $tabfieldinsert[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y";
 $tabfieldinsert[31]= "pcg_version,fk_pays,label";
-$tabfieldinsert[32]= "code,label,range_account,position,fk_country";
+$tabfieldinsert[32]= "code,label,range_account,sens,category_type,formula,position,fk_country";
 $tabfieldinsert[33]= "code,label";
 $tabfieldinsert[34]= "code,label";
 
@@ -524,6 +524,7 @@ if ($id == 11)
 			'propal'            => $langs->trans('Proposal'),
 			'commande'          => $langs->trans('Order'),
 			'facture'           => $langs->trans('Bill'),
+			'resource'           => $langs->trans('Resource'),
 //			'facture_fourn'     => $langs->trans('SupplierBill'),
 			'fichinter'         => $langs->trans('InterventionCard')
 	);
@@ -585,6 +586,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
         if ($value == 'localtax1' && empty($_POST['localtax1_type'])) continue;
         if ($value == 'localtax2' && empty($_POST['localtax2_type'])) continue;
         if ($value == 'color' && empty($_POST['color'])) continue;
+		if ($value == 'formula' && empty($_POST['formula'])) continue;
         if ((! isset($_POST[$value]) || $_POST[$value]=='')
         	&& (! in_array($listfield[$f], array('decalage','module','accountancy_code','accountancy_code_sell','accountancy_code_buy')))  // Fields that are not mandatory
 		)
@@ -605,6 +607,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
             if ($fieldnamekey == 'unicode') $fieldnamekey = 'Unicode';
             if ($fieldnamekey == 'deductible') $fieldnamekey = 'Deductible';
             if ($fieldnamekey == 'sortorder') $fieldnamekey = 'SortOrder';
+			if ($fieldnamekey == 'category_type') $fieldnamekey = 'Calculated';
 
             setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors');
         }
@@ -999,6 +1002,9 @@ if ($id)
 	        if ($fieldlist[$field]=='short_label')     { $valuetoshow=$langs->trans("ShortLabel"); }
             if ($fieldlist[$field]=='type_template')   { $valuetoshow=$langs->trans("TypeOfTemplate"); }
 			if ($fieldlist[$field]=='range_account')   { $valuetoshow=$langs->trans("Range"); }
+			if ($fieldlist[$field]=='sens')            { $valuetoshow=$langs->trans("Sens"); }
+			if ($fieldlist[$field]=='category_type')   { $valuetoshow=$langs->trans("Calculated"); }
+			if ($fieldlist[$field]=='formula')         { $valuetoshow=$langs->trans("Formula"); }
 
             if ($id == 2)	// Special cas for state page
             {
@@ -1167,6 +1173,9 @@ if ($id)
 	            if ($fieldlist[$field]=='short_label')     { $valuetoshow=$langs->trans("ShortLabel"); }
             	if ($fieldlist[$field]=='type_template')   { $valuetoshow=$langs->trans("TypeOfTemplate"); }
 				if ($fieldlist[$field]=='range_account')   { $valuetoshow=$langs->trans("Range"); }
+				if ($fieldlist[$field]=='sens')            { $valuetoshow=$langs->trans("Sens"); }
+				if ($fieldlist[$field]=='category_type')   { $valuetoshow=$langs->trans("Calculated"); }
+				if ($fieldlist[$field]=='formula')         { $valuetoshow=$langs->trans("Formula"); }
 
                 // Affiche nom du champ
                 if ($showfield)
@@ -1248,7 +1257,7 @@ if ($id)
                                     $valuetoshow=($key != "Country".strtoupper($obj->country_code)?$obj->country_code." - ".$key:$obj->country);
                                 }
                             }
-                            else if ($fieldlist[$field]=='recuperableonly' || $fieldlist[$field]=='fdm' || $fieldlist[$field] == 'deductible') {
+                            else if ($fieldlist[$field]=='recuperableonly' || $fieldlist[$field]=='fdm' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') {
                                 $valuetoshow=yn($valuetoshow);
                                 $align="center";
                             }
@@ -1618,7 +1627,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 			print 'user<input type="hidden" name="type" value="user">';
 			print '</td>';
 		}
-		elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'fdm' || $fieldlist[$field] == 'deductible') {
+		elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'fdm' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') {
 			print '<td>';
 			print $form->selectyesno($fieldlist[$field],(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''),1);
 			print '</td>';
@@ -1697,7 +1706,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
 			if ($fieldlist[$field]=='position') $size='size="4" ';
 			if ($fieldlist[$field]=='libelle') $size='centpercent';
 			if ($fieldlist[$field]=='tracking') $class='centpercent';
-			if ($fieldlist[$field]=='sortorder') $size='size="2" ';
+			if ($fieldlist[$field]=='sortorder' || $fieldlist[$field]=='sens' || $fieldlist[$field]=='category_type') $size='size="2" ';
 			print '<input type="text" '.$size.' class="flat'.($class?' '.$class:'').'" value="'.(isset($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" name="'.$fieldlist[$field].'">';
 			print '</td>';
 		}
diff --git a/htdocs/admin/fckeditor.php b/htdocs/admin/fckeditor.php
index b5bd4d045f69e6cad38e1f1c54b7974b719ceccb..e244941ff58e80ea1c09f2dd8ce74094c1ad2adf 100644
--- a/htdocs/admin/fckeditor.php
+++ b/htdocs/admin/fckeditor.php
@@ -189,7 +189,19 @@ else
     show_skin(null,1);
     print '<br>'."\n";
     
-	print load_fiche_titre($langs->trans("TestSubmitForm"),'(mode='.$mode.')','');
+    $listofmodes=array('dolibarr_mailings','dolibarr_notes','dolibarr_details','Full');
+    $linkstomode='';
+    foreach($listofmodes as $newmode)
+    {
+        if ($linkstomode) $linkstomode.=' - ';
+        $linkstomode.='<a href="'.$_SERVER["PHP_SELF"].'?mode='.$newmode.'">';
+        if ($mode == $newmode) $linkstomode.='<strong>';
+        $linkstomode.=$newmode;
+        if ($mode == $newmode) $linkstomode.='</strong>';
+        $linkstomode.='</a>';
+    }
+    $linkstomode.='';
+	print load_fiche_titre($langs->trans("TestSubmitForm"),$linkstomode,'');
     print '<input type="hidden" name="mode" value="'.dol_escape_htmltag($mode).'">';
     $uselocalbrowser=true;
     $readonly=($mode=='dolibarr_readonly'?1:0);
diff --git a/htdocs/admin/loan.php b/htdocs/admin/loan.php
index 1cc55bd5a366cd65a133c7370ea85d01f08cd61c..3213503835d250ce5549771349e329692ebaf654 100644
--- a/htdocs/admin/loan.php
+++ b/htdocs/admin/loan.php
@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) 2014		Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
+/* Copyright (C) 2014-2016	Alexandre Spangaro	<aspangaro.dolibarr@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
@@ -26,6 +26,7 @@ require '../main.inc.php';
 	
 // Class
 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/html.formventilation.class.php';
 
 $langs->load("admin");
 $langs->load("loan");
@@ -76,6 +77,7 @@ if ($action == 'update')
 llxHeader();
 
 $form = new Form($db);
+if (! empty($conf->accounting->enabled)) $formaccountancy = New FormVentilation($db);
 
 $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
 print load_fiche_titre($langs->trans('ConfigLoan'),$linkback,'title_setup');
@@ -104,7 +106,14 @@ foreach ($list as $key)
 
 	// Value
 	print '<td>';
-	print '<input type="text" size="20" id="'.$key.'" name="'.$key.'" value="'.$conf->global->$key.'">';
+	if (! empty($conf->accounting->enabled))
+	{
+		print $formaccountancy->select_account($conf->global->$key, $key, 1, '', 1, 1);
+	}
+	else
+	{
+		print '<input type="text" size="20" id="'.$key.'" name="'.$key.'" value="'.$conf->global->$key.'">';
+	}
 	print '</td></tr>';
 }
 
diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php
index f4f1bbb96bf70caa0b0645736aeee28940f8f92c..5fc39432c8e6b78afe1f51cb0c229f36b9b2c316 100644
--- a/htdocs/admin/menus/edit.php
+++ b/htdocs/admin/menus/edit.php
@@ -75,6 +75,7 @@ if ($action == 'update')
             $menu->perms=$_POST['perms'];
             $menu->target=$_POST['target'];
             $menu->user=$_POST['user'];
+            $menu->fk_menu=$_POST['fk_menu'];
             $result=$menu->update($user);
             if ($result > 0)
             {
@@ -275,6 +276,8 @@ if ($action == 'create')
     print '<form action="./edit.php?action=add&menuId='.$_GET['menuId'].'" method="post" name="formmenucreate">';
     print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
 
+    dol_fiche_head();
+    
     print '<table class="border" width="100%">';
 
     // Id
@@ -368,8 +371,10 @@ if ($action == 'create')
 
     print '</table>';
 
+    dol_fiche_end();
+    
     // Boutons
-    print '<br><div class="center">';
+    print '<div class="center">';
 	print '<input type="submit" class="button" name="save" value="'.$langs->trans("Save").'">';
     print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
     print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
@@ -387,6 +392,8 @@ elseif ($action == 'edit')
     print '<input type="hidden" name="handler_origine" value="'.$menu_handler.'">';
     print '<input type="hidden" name="menuId" value="'.$_GET['menuId'].'">';
 
+    dol_fiche_head();
+    
     print '<table class="border" width="100%">';
 
     $menu = new Menubase($db);
@@ -416,9 +423,9 @@ elseif ($action == 'edit')
 
     // MenuId Parent
     print '<tr><td class="fieldrequired">'.$langs->trans('MenuIdParent').'</td>';
+    print '<td><input type="text" name="fk_menu" value="'.$menu->fk_menu.'" size=10></td>';
     //$menu_handler
     //print '<td><input type="text" size="50" name="handler" value="all"></td>';
-    print '<td>'.$menu->fk_menu.'</td>';
     print '<td>'.$langs->trans('DetailMenuIdParent').'</td></tr>';
 
     // Niveau
@@ -454,8 +461,10 @@ elseif ($action == 'edit')
 
     print '</table>';
 
+    dol_fiche_end();
+    
     // Bouton
-    print '<br><div class="center">';
+    print '<div class="center">';
 	print '<input type="submit" class="button" name="save" value="'.$langs->trans("Save").'">';
     print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
     print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
diff --git a/htdocs/api/admin/explorer.php b/htdocs/api/admin/explorer.php
index 44a14f9967569d2ebb9c6811a3fd28c9317e7d8f..66d06e91679da2eaaeb28663aef80e156adddf37 100644
--- a/htdocs/api/admin/explorer.php
+++ b/htdocs/api/admin/explorer.php
@@ -150,12 +150,30 @@ $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToM
 print load_fiche_titre($langs->trans("ApiSetup"),$linkback,'title_setup');
 
 
+// Define $urlwithroot
+$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
+$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;		// This is to use external domain name found into config file
+//$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
+
+// Show message
+print '<br>';
+$message='';
+$url='<a href="'.$urlwithroot.'/api/index.php/login?login='.urlencode($user->login).'&password=yourpassword" target="_blank">'.$urlwithroot.'/api/index.php/login?login='.urlencode($user->login).'&password=yourpassword</a>';
+$message.=$langs->trans("UrlToGetKeyToUseAPIs").':<br>';
+$message.=img_picto('','object_globe.png').' '.$url;
+print $message;
+print '<br>';
+print '<br>';
+
+print $langs->trans("ListOfAvailableAPIs").':<br>';
 foreach($listofapis['v1'] as $key => $val)
 {
+    if ($key == 'login') continue;
     if ($key)
     {
         //print $key.' - '.$val['classname'].' - '.$val['fullpath']." - ".DOL_MAIN_URL_ROOT.'/api/index.php/'.strtolower(preg_replace('/Api$/','',$val['classname']))."/xxx<br>\n";
-        $url=DOL_MAIN_URL_ROOT.'/api/index.php/'.$key;
+        $url=$urlwithroot.'/api/index.php/'.$key;
+        $url.='?api_key=token';
         print img_picto('','object_globe.png').' <a href="'.$url.'" target="_blank">'.$url."</a><br>\n";
         
     }
diff --git a/htdocs/api/class/api_access.class.php b/htdocs/api/class/api_access.class.php
index 9d29c60e26ae0b671cc8a843e11a3c718f94907d..67f8c710bb77a7182589d1fc5142ed05340e3974 100644
--- a/htdocs/api/class/api_access.class.php
+++ b/htdocs/api/class/api_access.class.php
@@ -116,16 +116,13 @@ class DolibarrApiAccess implements iAuthenticate
 		else
 		{
 		    throw new RestException(401, "Failed to login to API. No parameter 'api_key' provided");
-		    //dol_syslog("Failed to login to API. No parameter key provided", LOG_DEBUG);
-			//return false;
 		}
 
-        $userClass::setCacheIdentifier(static::$role);
-        Resources::$accessControlFunction = 'DolibarrApiAccess::verifyAccess';
-        
-        $requirefortest = static::$requires;
-        if (! is_array($requirefortest)) $requirefortest=explode(',',$requirefortest);
-        return in_array(static::$role, (array) static::$requirefortest) || static::$role == 'admin';
+    $userClass::setCacheIdentifier(static::$role);
+    Resources::$accessControlFunction = 'DolibarrApiAccess::verifyAccess';
+    $requirefortest = static::$requires;
+    if (! is_array($requirefortest)) $requirefortest=explode(',',$requirefortest);
+    return in_array(static::$role, (array) $requirefortest) || static::$role == 'admin';
 	}
 
 	/**
diff --git a/htdocs/api/index.php b/htdocs/api/index.php
index d7bcedb5fd7c22737be6c80a2eb93d7d85d0e26f..55a45aea4b933f8949b7de7bc50320112dff1ab7 100644
--- a/htdocs/api/index.php
+++ b/htdocs/api/index.php
@@ -141,6 +141,8 @@ foreach ($modulesdir as $dir)
 
 // TODO If not found, redirect to explorer
 
+
+// Call API (we suppose we found it)
 $api->r->handle();
 
 
diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php
index 5265f73e59571d0c571a69e977968cc09cf39999..f1bf108f14c8ab91328ae4b869768cd0c49e0003 100644
--- a/htdocs/comm/index.php
+++ b/htdocs/comm/index.php
@@ -87,6 +87,11 @@ if (! empty($conf->commande->enabled) && $user->rights->commande->lire)
 {
 	$listofsearchfields['search_customer_order']=array('text'=>'CustomerOrder');
 }
+// Search supplier proposal
+if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire)
+{
+    $listofsearchfields['search_supplier_proposal']=array('text'=>'SupplierProposalShort');
+}
 // Search supplier order
 if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande->lire)
 {
@@ -100,12 +105,7 @@ if (! empty($conf->ficheinter->enabled) && $user->rights->ficheinter->lire)
 // Search contract
 if (! empty($conf->contrat->enabled) && $user->rights->contrat->lire)
 {
-    $listofsearchfields['search_contract']=array('text'=>'Contrat');
-}
-// Search supplier proposal
-if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire)
-{
-    $listofsearchfields['search_supplier_proposal']=array('text'=>'SupplierProposalShort');
+    $listofsearchfields['search_contract']=array('text'=>'Contract');
 }
 
 if (count($listofsearchfields))
diff --git a/htdocs/commande/class/api_commande.class.php b/htdocs/commande/class/api_commande.class.php
index 04d78f30a1da5e8b0107c234f1b513580cc101b8..d6a2a3d0f82fa281b9a9e4464924f58c441c4bae 100644
--- a/htdocs/commande/class/api_commande.class.php
+++ b/htdocs/commande/class/api_commande.class.php
@@ -207,9 +207,9 @@ class CommandeApi extends DolibarrApi
      */
     function post($request_data = NULL)
     {
-        if(! DolibarrApiAccess::$user->rights->commande->creer) {
-			throw new RestException(401);
-		}
+      if(! DolibarrApiAccess::$user->rights->commande->creer) {
+			  throw new RestException(401, "Insuffisant rights");
+		  }
         // Check mandatory fields
         $result = $this->_validate($request_data);
 
@@ -224,7 +224,7 @@ class CommandeApi extends DolibarrApi
           $this->commande->lines = $lines;
         }
         if(! $this->commande->create(DolibarrApiAccess::$user) ) {
-            throw new RestException(401);
+            throw new RestException(500, "Error while creating order");
         }
         
         return $this->commande->id;
diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
index c4569418968e606987bdcb926236adbb2092e0cf..a0babc4d972efc17d269787c840faa282dda9efd 100644
--- a/htdocs/commande/class/commande.class.php
+++ b/htdocs/commande/class/commande.class.php
@@ -9,6 +9,7 @@
  * Copyright (C) 2012      Cedric Salvador      <csalvador@gpcsolutions.fr>
  * Copyright (C) 2013      Florian Henry		<florian.henry@open-concept.pro>
  * Copyright (C) 2014-2015 Marcos García        <marcosgdf@gmail.com>
+ * Copyright (C) 2016      Ferran Marcet        <fmarcet@2byte.es>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -2516,7 +2517,7 @@ class Commande extends CommonOrder
      */
 	function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0,$txlocaltax2=0.0, $price_base_type='HT', $info_bits=0, $date_start='', $date_end='', $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_options=0, $fk_unit=null)
     {
-        global $conf, $mysoc;
+        global $conf, $mysoc, $langs;
 
         dol_syslog(get_class($this)."::updateline id=$rowid, desc=$desc, pu=$pu, qty=$qty, remise_percent=$remise_percent, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, price_base_type=$price_base_type, info_bits=$info_bits, date_start=$date_start, date_end=$date_end, type=$type, fk_parent_line=$fk_parent_line, pa_ht=$pa_ht, special_code=$special_code");
         include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
@@ -2585,6 +2586,26 @@ class Commande extends CommonOrder
             $line = new OrderLine($this->db);
             $line->fetch($rowid);
 
+            if (!empty($line->fk_product))
+            {
+                $product=new Product($this->db);
+                $result=$product->fetch($line->fk_product);
+                $product_type=$product->type;
+
+                if (! empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_ORDER) && $product_type == 0 && $product->stock_reel < $qty)
+                {
+                    $this->error=$langs->trans('ErrorStockIsNotEnough');
+                    dol_syslog(get_class($this)."::addline error=Product ".$product->ref.": ".$this->error, LOG_ERR);
+                    $this->db->rollback();
+                    unset($_POST['productid']);
+                    unset($_POST['tva_tx']);
+                    unset($_POST['price_ht']);
+                    unset($_POST['qty']);
+                    unset($_POST['buying_price']);
+                    return self::STOCK_NOT_ENOUGH_FOR_ORDER;
+                }
+            }
+
             $staticline = clone $line;
 
             $line->oldline = $staticline;
diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php
index 7aa1dc481e979c316bb31bfb4841436235935334..bad7fdbd4bf24b0e99b6b34ec93540177648fe15 100644
--- a/htdocs/commande/list.php
+++ b/htdocs/commande/list.php
@@ -673,6 +673,12 @@ if ($resql)
         $var=!$var;
         print '<tr '.$bc[$var].'>';
 
+        $notshippable=0;
+        $warning = 0;
+        $text_info='';
+        $text_warning='';
+        $nbprod=0;
+                
         if (! empty($arrayfields['c.ref']['checked']))
         {
             print '<td class="nowrap">';
@@ -694,17 +700,11 @@ if ($resql)
             print '</td>';
     		
             // Show shippable Icon (create subloop, so may be slow)
-            if ($conf->stock->enabled) 
+            if ($conf->stock->enabled)
             {
-                $langs->load("stocks");
-                if (($obj->fk_statut > 0) && ($obj->fk_statut < 3))
-                {
-                    $notshippable=0;
-                    $warning = 0;
-                    $text_info='';
-                    $text_warning='';
-                    $nbprod=0;
-                    
+            	$langs->load("stocks");
+	            if (($obj->fk_statut > 0) && ($obj->fk_statut < 3))
+    	        {
                     $numlines = count($generic_commande->lines); // Loop on each line of order
                     for ($lig=0; $lig < $numlines; $lig++) 
                     {
@@ -712,17 +712,19 @@ if ($resql)
                         {
                             $nbprod++; // order contains real products
                             $generic_product->id = $generic_commande->lines[$lig]->fk_product;
+
+                            // Get local and virtual stock and store it into cache
                             if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product])) {
-                                $generic_product->load_stock();
-                                $generic_product->load_virtual_stock();
+                                $generic_product->load_stock('nobatch');
+                                //$generic_product->load_virtual_stock();   Already included into load_stock
                                 $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_reel;
                                 $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique;
                             } else {
                                 $generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'];
                                 $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique;
                             }
-                            
-                            if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST))  // Default code is when this option is not set, setting it create strange result
+
+                            if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST))  // Default code. Default is when this option is not set, setting it create strange result
                             {
                                 $text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->ref.'&nbsp;'.dol_trunc($generic_commande->lines[$lig]->product_label, 25);
                                 $text_info .= ' - '.$langs->trans("Stock").': '.$generic_product->stock_reel;
@@ -795,7 +797,7 @@ if ($resql)
                 {
                     print $form->textwithtooltip('',$text_info,2,1,$text_icon,'',2);
                 }
-                if ($warning) {
+                if ($warning) {     // Always false in default mode
                     print $form->textwithtooltip('', $langs->trans('NotEnoughForAllOrders').'<br>'.$text_warning, 2, 1, img_picto('', 'error'),'',2);
                 }
                 print '</td>';
diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php
index e2cecacb83cdbc0541a703e62c82c29ae9835909..102e6a6861a72c39fd65739e88e2e1ac430b6373 100644
--- a/htdocs/compta/bank/card.php
+++ b/htdocs/compta/bank/card.php
@@ -3,7 +3,7 @@
  * Copyright (C) 2003		Jean-Louis Bergamo	<jlb@j1b.org>
  * Copyright (C) 2004-2015	Laurent Destailleur	<eldy@users.sourceforge.net>
  * Copyright (C) 2005-2009	Regis Houssin		<regis.houssin@capnetworks.com>
- * Copyright (C) 2014-2015	Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2014-2016	Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2015       Jean-François Ferry	<jfefe@aternatik.fr>
  * Copyright (C) 2016       Marcos García       <marcosgdf@gmail.com>
  *
@@ -34,8 +34,8 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php';
 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formbank.class.php';
 require_once DOL_DOCUMENT_ROOT . '/compta/bank/class/account.class.php';
 require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
-require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
-if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/html.formventilation.class.php';
+if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
+if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/html.formventilation.class.php';
 
 $langs->load("banks");
 $langs->load("bills");
@@ -675,7 +675,13 @@ else
 		print '<table class="border" width="100%">';
 		// Accountancy code
 		print '<tr><td class="titlefield">'.$langs->trans("AccountancyCode").'</td>';
-		print '<td colspan="3">'.length_accountg($account->account_number).'</td></tr>';
+		print '<td colspan="3">';
+		if (! empty($conf->accounting->enabled)) {
+			print length_accountg($account->account_number).'</td></tr>';
+		} else {
+			print $account->account_number;
+		}
+		print '</td></tr>';
 
 		// Accountancy journal
 		if (! empty($conf->accounting->enabled))
diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php
index 123f4537a583a5fb7210cc34dc5718a7b994c027..478633490f824de66f902a072100a781b9831263 100644
--- a/htdocs/compta/bank/class/account.class.php
+++ b/htdocs/compta/bank/class/account.class.php
@@ -7,6 +7,7 @@
  * Copyright (C) 2013		Florian Henry			<florian.henry@open-concept.pro>
  * Copyright (C) 2015-2016	Marcos García			<marcosgdf@gmail.com>
  * Copyright (C) 2015		Alexandre Spangaro		<aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2016		Ferran Marcet   		<fmarcet@2byte.es>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -588,7 +589,7 @@ class Account extends CommonObject
         {
             $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
 
-            $result=$this->update();
+            $result=$this->update($user);
             if ($result > 0)
             {
 				$accline = new AccountLine($this->db);
@@ -1100,15 +1101,19 @@ class Account extends CommonObject
      */
     public static function countAccountToReconcile()
     {
-        global $db, $conf, $langs;
-    
-        if ($user->societe_id) return 0;   // protection pour eviter appel par utilisateur externe
+        global $db, $conf, $user;
+
+        //Protection against external users
+        if ($user->societe_id) {
+            return 0;
+        }
     
         $nb=0;
         
         $sql = "SELECT COUNT(ba.rowid) as nb";
         $sql.= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
         $sql.= " WHERE ba.rappro > 0 and ba.clos = 0";
+        $sql.= " AND ba.entity IN (".getEntity('bank_account', 1).")";
         if (empty($conf->global->BANK_CAN_RECONCILIATE_CASHACCOUNT)) $sql.= " AND ba.courant != 2";
         $resql=$db->query($sql);
         if ($resql)
diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php
index db7f37cb3e50f71c53a321cdf5eb3d31389f1935..0cee6211b493a5177014edfeda4f8fe221620f98 100644
--- a/htdocs/compta/bank/treso.php
+++ b/htdocs/compta/bank/treso.php
@@ -136,7 +136,7 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
 	print '</tr>';
 
 	$var=!$var;
-	print '<tr class="liste_total">';
+	print '<tr class="liste_titre">';
 	print '<td align="left" colspan="5">'.$langs->trans("RemainderToPay").'</td>';
 	print '<td align="right" class="nowrap">&nbsp;</td>';
 	print '</tr>';
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index 55f259aa2fe1c5462a73879aef525daf8b19bc39..27ba03499c830311435b3473faaa127a52553dae 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -1,7 +1,7 @@
 <?php
 /* Copyright (C) 2002-2006 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
  * Copyright (C) 2004      Eric Seigne           <eric.seigne@ryxeo.com>
- * Copyright (C) 2004-2014 Laurent Destailleur   <eldy@users.sourceforge.net>
+ * Copyright (C) 2004-2016 Laurent Destailleur   <eldy@users.sourceforge.net>
  * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
  * Copyright (C) 2005-2015 Regis Houssin         <regis.houssin@capnetworks.com>
  * Copyright (C) 2006      Andre Cianfarani      <acianfa@free.fr>
@@ -83,6 +83,7 @@ $search_montant_ht = GETPOST('search_montant_ht', 'alpha');
 $search_montant_ttc = GETPOST('search_montant_ttc', 'alpha');
 $origin = GETPOST('origin', 'alpha');
 $originid = (GETPOST('originid', 'int') ? GETPOST('originid', 'int') : GETPOST('origin_id', 'int')); // For backward compatibility
+$fac_rec=GETPOST('fac_rec','int');
 
 // PDF
 $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
@@ -2082,8 +2083,9 @@ if ($action == 'create')
 			$(document).ready(function() {
 				$("#socid").change(function() {
 					var socid = $(this).val();
+			        var fac_rec = $(\'#fac_rec\').val();
 					// reload page
-					window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid;
+        			window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&fac_rec="+fac_rec;
 				});
 			});
 			</script>';
@@ -2098,6 +2100,8 @@ if ($action == 'create')
 	    $invoice_predefined = new FactureRec($db);
 	    $invoice_predefined->fetch(GETPOST('fac_rec','int'));
 	    
+	    $dateinvoice = $invoice_predefined->date_when;     // To use next gen date by default later
+	    
 		$sql = 'SELECT r.rowid, r.titre, r.total_ttc';
 		$sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture_rec as r';
 		$sql .= ' WHERE r.fk_soc = ' . $invoice_predefined->socid;
@@ -2111,7 +2115,7 @@ if ($action == 'create')
 			if ($num > 0)
 			{
 				print '<tr><td>' . $langs->trans('CreateFromRepeatableInvoice') . '</td><td>';
-				print '<select class="flat" name="fac_rec">';
+				print '<select class="flat" id="fac_rec" name="fac_rec">';
 				print '<option value="0" selected></option>';
 				while ($i < $num)
 				{
@@ -2122,7 +2126,22 @@ if ($action == 'create')
 					print '>' . $objp->titre . ' (' . price($objp->total_ttc) . ' ' . $langs->trans("TTC") . ')</option>';
 					$i ++;
 				}
-				print '</select></td></tr>';
+				print '</select>';
+				// Option to reload page to retrieve customer informations. Note, this clear other input
+        		if (!empty($conf->global->RELOAD_PAGE_ON_TEMPLATE_CHANGE))
+        		{
+        			print '<script type="text/javascript">
+        			$(document).ready(function() {
+        				$("#fac_rec").change(function() {
+        					var fac_rec = $(this).val();
+        			        var socid = $(\'#socid\').val();
+        					// reload page
+        					window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&fac_rec="+fac_rec;
+        				});
+        			});
+        			</script>';
+        		}
+				print '</td></tr>';
 			}
 			$db->free($resql);
 		} else {
@@ -2402,7 +2421,7 @@ if ($action == 'create')
 		$langs->load('projects');
 		print '<tr><td>' . $langs->trans('Project') . '</td><td colspan="2">';
 		$numprojet = $formproject->select_projects($socid, $projectid, 'projectid', 0);
-		print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid=' . $soc->id . '&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id).'">' . $langs->trans("AddProject") . '</a>';
+		print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid=' . $soc->id . '&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id.($fac_rec?'&fac_rec='.$fac_rec:'')).'">' . $langs->trans("AddProject") . '</a>';
 		print '</td></tr>';
 	}
 
@@ -3548,7 +3567,7 @@ else if ($id > 0 || ! empty($ref))
 	print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
 	print $langs->trans('BankAccount');
 	print '<td>';
-	if (($action != 'editbankaccount') && $user->rights->commande->creer && ! empty($object->brouillon))
+	if (($action != 'editbankaccount') && $user->rights->facture->creer && ! empty($object->brouillon))
 	    print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&amp;id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'),1).'</a></td>';
 	print '</tr></table>';
 	print '</td><td colspan="3">';
diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php
index 0acd58f0202dc21fda28ab57d65ee555e204eee6..cddd511dbe4c59c2c02b46ebe9d93d010328c15f 100644
--- a/htdocs/compta/facture/class/facture-rec.class.php
+++ b/htdocs/compta/facture/class/facture-rec.class.php
@@ -53,7 +53,7 @@ class FactureRec extends CommonInvoice
 	var $propalid;
 
 	var $date_last_gen;
-	var $next_gen;
+	var $date_when;
 	var $nb_gen_done;
 	var $nb_gen_max;
 	
@@ -341,6 +341,17 @@ class FactureRec extends CommonInvoice
 	}
 
 
+	/**
+	 * 	Create an array of invoice lines
+	 *
+	 * 	@return int		>0 if OK, <0 if KO
+	 */
+	function getLinesArray()
+	{
+	    return $this->fetch_lines();
+	}
+	
+	
 	/**
 	 *	Recupere les lignes de factures predefinies dans this->lines
 	 *
@@ -348,16 +359,23 @@ class FactureRec extends CommonInvoice
  	 */
 	function fetch_lines()
 	{
+		$this->lines=array();
+
 		$sql = 'SELECT l.rowid, l.fk_product, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.tva_tx, ';
 		$sql.= ' l.remise, l.remise_percent, l.subprice,';
-		$sql.= ' l.total_ht, l.total_tva, l.total_ttc,';
+		$sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_ttc,';
+		//$sql.= ' l.situation_percent, l.fk_prev_id,';
+		//$sql.= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise_percent, l.fk_remise_except, l.subprice,';
 		$sql.= ' l.rang, l.special_code,';
+		//$sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
 		$sql.= ' l.fk_unit, l.fk_contract_line,';
+		//$sql.= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
 		$sql.= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
 		$sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet_rec as l';
 		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
 		$sql.= ' WHERE l.fk_facture = '.$this->id;
-
+		$sql.= ' ORDER BY l.rang';
+		
 		dol_syslog('FactureRec::fetch_lines', LOG_DEBUG);
 		$result = $this->db->query($sql);
 		if ($result)
@@ -387,10 +405,6 @@ class FactureRec extends CommonInvoice
 				$line->remise_percent   = $objp->remise_percent;
 				$line->fk_remise_except = $objp->fk_remise_except;
 				$line->fk_product       = $objp->fk_product;
-				$line->date_start       = $objp->date_start;
-				$line->date_end         = $objp->date_end;
-				$line->date_start       = $objp->date_start;
-				$line->date_end         = $objp->date_end;
 				$line->info_bits        = $objp->info_bits;
 				$line->total_ht         = $objp->total_ht;
 				$line->total_tva        = $objp->total_tva;
@@ -415,7 +429,7 @@ class FactureRec extends CommonInvoice
 		}
 		else
 		{
-			$this->error=$this->db->error();
+			$this->error=$this->db-lasterror();
 			return -3;
 		}
 	}
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index 4dbf4b9020a89d953eb26474b453497825cb0cf5..8fee9cc575837ccc3efcaf3635be263bf0f48762 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -14,6 +14,7 @@
  * Copyright (C) 2012-2014 Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
  * Copyright (C) 2013      Cedric Gross          <c.gross@kreiz-it.fr>
  * Copyright (C) 2013      Florian Henry		  	<florian.henry@open-concept.pro>
+ * Copyright (C) 2016      Ferran Marcet        <fmarcet@2byte.es>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -280,24 +281,27 @@ class Facture extends CommonInvoice
 
 			$this->socid 		     = $_facrec->socid;
 			
+			// Fields coming from GUI (priority on template). TODO Value of template should be used as default value on GUI so we can use here always value from GUI
 			$this->fk_project        = GETPOST('projectid','int') > 0 ? GETPOST('projectid','int') : $_facrec->fk_project;
-			$this->fk_account        = $_facrec->fk_account;
-			$this->cond_reglement_id = $_facrec->cond_reglement_id;
-			$this->mode_reglement_id = $_facrec->mode_reglement_id;
+			$this->note_public       = GETPOST('note_public') ? GETPOST('note_public') : $_facrec->note_public;
+			$this->note_private      = GETPOST('note_private') ? GETPOST('note_private') : $_facrec->note_private;
+			$this->modelpdf          = GETPOST('model') ? GETPOST('model') : $_facrec->modelpdf;
+			$this->cond_reglement_id = GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $_facrec->cond_reglement_id;
+			$this->mode_reglement_id = GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $_facrec->mode_reglement_id;
+			$this->fk_account        = GETPOST('fk_account') > 0 ? GETPOST('fk_account') : $_facrec->fk_account;
+				
+			// Fields always coming from template
 			$this->remise_absolue    = $_facrec->remise_absolue;
 			$this->remise_percent    = $_facrec->remise_percent;
 			$this->fk_incoterms		 = $_facrec->fk_incoterms;
 			$this->location_incoterms= $_facrec->location_incoterms;
 
-			$this->note_public       = $_facrec->note_public;
-			$this->note_private      = $_facrec->note_private;
-			
 			// Clean parameters
 			if (! $this->type) $this->type = self::TYPE_STANDARD;
 			$this->ref_client=trim($this->ref_client);
 			$this->note_public=trim($this->note_public);
 			$this->note_private=trim($this->note_private);
-		    $this->note_private=dol_concatdesc($facture->note_private, $langs->trans("GeneratedFromRecurringInvoice", $_facrec->ref));
+		    $this->note_private=dol_concatdesc($this->note_private, $langs->trans("GeneratedFromRecurringInvoice", $_facrec->ref));
 		    
 			//if (! $this->remise) $this->remise = 0;
 			if (! $this->mode_reglement_id) $this->mode_reglement_id = 0;
@@ -2537,6 +2541,19 @@ class Facture extends CommonInvoice
 			$line = new FactureLigne($this->db);
 			$line->fetch($rowid);
 
+			if (!empty($line->fk_product))
+			{
+				$product=new Product($this->db);
+				$result=$product->fetch($line->fk_product);
+				$product_type=$product->type;
+
+				if (! empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) {
+					$this->error=$langs->trans('ErrorStockIsNotEnough');
+					$this->db->rollback();
+					return -3;
+				}
+			}
+
 			$staticline = clone $line;
 
 			$line->oldline = $staticline;
@@ -2589,7 +2606,7 @@ class Facture extends CommonInvoice
 				$this->line->array_options=$array_options;
 			}
 
-			$result=$this->line->update();
+			$result=$this->line->update($user);
 			if ($result > 0)
 			{
 				// Reorder if child line
@@ -2663,7 +2680,7 @@ class Facture extends CommonInvoice
 		$line->total_ttc = $tabprice[2];
 		$line->total_localtax1 = $tabprice[9];
 		$line->total_localtax2 = $tabprice[10];
-		$line->update();
+		$line->update($user);
 		$this->update_price(1);
 		$this->db->commit();
 	}
diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php
index ad9626718c643e75787ae85d61ed3dfcdf05d02e..b826e4f266d7aa1d7a51134418fee460b436567e 100644
--- a/htdocs/compta/facture/fiche-rec.php
+++ b/htdocs/compta/facture/fiche-rec.php
@@ -33,6 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
 
 $langs->load('bills');
 $langs->load('compta');
@@ -50,18 +51,29 @@ if ($action == "create" || $action == "add") $objecttype = '';
 $result = restrictedArea($user, 'facture', $id, $objecttype);
 $projectid = GETPOST('projectid','int');
 
-if ($page == -1)
-{
-	$page = 0 ;
-}
-$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
-$offset = $limit * $page ;
+$search_ref=GETPOST('search_ref');
+$search_societe=GETPOST('search_societe');
+$search_montant_ht=GETPOST('search_montant_ht');
+$search_montant_vat=GETPOST('search_montant_vat');
+$search_montant_ttc=GETPOST('search_montant_ttc');
+$day=GETPOST('day');
+$year=GETPOST('year');
+$month=GETPOST('month');
+$day_date_when=GETPOST('day_date_when');
+$year_date_when=GETPOST('year_date_when');
+$month_date_when=GETPOST('month_date_when');
+$search_frequency=GETPOST('search_frequency');
 
-if ($sortorder == "")
-$sortorder="DESC";
-
-if ($sortfield == "")
-$sortfield="f.datef";
+$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
+$sortfield = GETPOST("sortfield",'alpha');
+$sortorder = GETPOST("sortorder",'alpha');
+$page = GETPOST("page",'int');
+if ($page == -1) { $page = 0; }
+$offset = $limit * $page;
+if (! $sortorder) $sortorder='DESC';
+if (! $sortfield) $sortfield='f.titre';
+$pageprev = $page - 1;
+$pagenext = $page + 1;
 
 $object = new FactureRec($db);
 if (($id > 0 || $ref) && $action != 'create' && $action != 'add')
@@ -73,13 +85,45 @@ if (($id > 0 || $ref) && $action != 'create' && $action != 'add')
 	}
 }
 
+// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
+$hookmanager->initHooks(array('invoicecard','globalcard'));
+$extrafields = new ExtraFields($db);
+
+// fetch optionals attributes and labels
+$extralabels = $extrafields->fetch_name_optionals_label('facturerec');
+$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_');
+
+$permissionnote = $user->rights->facture->creer; // Used by the include of actions_setnotes.inc.php
+$permissiondellink=$user->rights->facture->creer;	// Used by the include of actions_dellink.inc.php
+$permissiontoedit = $user->rights->facture->creer; // Used by the include of actions_lineupdonw.inc.php
+
+$arrayfields=array(
+    'f.titre'=>array('label'=>$langs->trans("Ref"), 'checked'=>1),
+    's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1),
+    'f.total'=>array('label'=>$langs->trans("AmountHT"), 'checked'=>1),
+    'f.tva'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>1),
+    'f.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>1),
+    'f.frequency'=>array('label'=>$langs->trans("RecurringInvoiceTemplate"), 'checked'=>1),
+    'f.date_last_gen'=>array('label'=>$langs->trans("DateLastGeneration"), 'checked'=>1),
+    'f.date_when'=>array('label'=>$langs->trans("NextDateToExecution"), 'checked'=>1),
+    'f.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
+    'f.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
+);
+// Extra fields
+if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
+{
+    foreach($extrafields->attribute_label as $key => $val)
+    {
+        $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]);
+    }
+}
+
 
 /*
  * Actions
  */
 
 // Set note
-$permissionnote=$user->rights->facture->creer;	// Used by the include of actions_setnotes.inc.php
 include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php';	// Must be include, not include_once
 
 include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php';	// Must be include, not include_once
@@ -101,7 +145,7 @@ if ($action == 'add')
 	$rehour=GETPOST('rehour');
 	$remin=GETPOST('remin');
 	$nb_gen_max=GETPOST('nb_gen_max', 'int');
-	if (empty($nb_gen_max)) $nb_gen_max =0;
+	//if (empty($nb_gen_max)) $nb_gen_max =0;
 	
 	if (GETPOST('frequency'))
 	{
@@ -111,7 +155,7 @@ if ($action == 'add')
 			$action = "create";
 			$error++;	
 		}
-		if ($nb_gen_max == '')
+		if ($nb_gen_max === '')
 		{
 			setEventMessages($langs->transnoentities("ErrorFieldRequired",$langs->trans("MaxPeriodNumber")), null, 'errors');
 			$action = "create";
@@ -122,7 +166,8 @@ if ($action == 'add')
 	if (! $error)
 	{
 		$object->titre = GETPOST('titre', 'alpha');
-		$object->note_private  = GETPOST('note_private');
+		$object->note_private = GETPOST('note_private');
+		$object->note_public  = GETPOST('note_public');
 		$object->usenewprice = GETPOST('usenewprice');
 		
 		$object->frequency = $frequency;
@@ -570,6 +615,24 @@ if ($action == 'addline' && $user->rights->facture->creer)
     }
 }
 
+// Do we click on purge search criteria ?
+if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers
+{
+    $search_ref='';
+    $search_societe='';
+    $search_montant_ht='';
+    $search_montant_vat='';
+    $search_montant_ttc='';
+    $day='';
+    $year='';
+    $month='';
+    $day_date_when='';
+    $year_date_when='';
+    $month_date_when='';
+    $search_frequency='';
+    $search_array_options=array();
+}
+
 
 
 /*
@@ -579,6 +642,7 @@ if ($action == 'addline' && $user->rights->facture->creer)
 llxHeader('',$langs->trans("RepeatableInvoices"),'ch-facture.html#s-fac-facture-rec');
 
 $form = new Form($db);
+$formother = new FormOther($db);
 $companystatic = new Societe($db);
 
 $now = dol_now();
@@ -599,7 +663,9 @@ if ($action == 'create')
 	
 	if ($object->fetch($id, $ref) > 0)
 	{
-		print '<form action="fiche-rec.php" method="post">';
+		$result = $object->getLinesArray();
+				
+	    print '<form action="fiche-rec.php" method="post">';
 		print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
 		print '<input type="hidden" name="action" value="add">';
 		print '<input type="hidden" name="facid" value="'.$object->id.'">';
@@ -616,20 +682,23 @@ if ($action == 'create')
 
 		// Third party
 		print '<tr><td class="titlefieldcreate">'.$langs->trans("Customer").'</td><td>'.$object->thirdparty->getNomUrl(1,'customer').'</td>';
-		print '<td>';
-		print $langs->trans("Comment");
-		print '</td></tr>';
+		print '</tr>';
 
 		// Title
 		print '<tr><td class="fieldrequired">'.$langs->trans("Title").'</td><td>';
 		print '<input class="flat quatrevingtpercent" type="text" name="titre" value="'.$_POST["titre"].'">';
-		print '</td>';
+		print '</td></tr>';
 
-		// Note
-		print '<td rowspan="'.$rowspan.'" valign="top">';
-		print '<textarea class="flat centpercent" name="note_private" wrap="soft" rows="'.ROWS_4.'"></textarea>';
+		// Note public
+		print '<tr><td>'.$langs->trans("NotePublic").'</td><td valign="top">';
+		print '<textarea class="flat centpercent" name="note_public" wrap="soft" rows="'.ROWS_4.'"></textarea>';
 		print '</td></tr>';
 
+		// Note private
+		print '<tr><td>'.$langs->trans("NotePrivate").'</td><td valign="top">';
+		print '<textarea class="flat centpercent" name="note_private" wrap="soft" rows="'.ROWS_4.'"></textarea>';
+		print '</td></tr>';
+		
 		// Author
 		print "<tr><td>".$langs->trans("Author")."</td><td>".$user->getFullName($langs)."</td></tr>";
 
@@ -648,7 +717,7 @@ if ($action == 'create')
     	{
     	    $projectid = $object->fk_project;
     		$langs->load('projects');
-    		print '<tr><td>' . $langs->trans('Project') . '</td><td colspan="2">';
+    		print '<tr><td>' . $langs->trans('Project') . '</td><td>';
     		$numprojet = $formproject->select_projects($socid, $projectid, 'projectid', 0);
     		print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid=' . $soc->id . '&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id).'">' . $langs->trans("AddProject") . '</a>';
     		print '</td></tr>';
@@ -707,10 +776,22 @@ if ($action == 'create')
 
 		print load_fiche_titre($title, '', '');
 
-		
 		/*
 		 * Invoice lines
 		 */
+		print '<table id="tablelines" class="noborder noshadow" width="100%">';
+		// Show object lines
+		if (! empty($object->lines))
+		{
+		    $disableedit=1;
+		    $disablemove=1;
+		    $disableremove=1;
+		    $ret = $object->printObjectLines('', $mysoc, $soc, $lineid, 0);      // No date selector for template invoice
+		}
+		
+		print "</table>\n";
+		
+		/*
 		print '<table class="notopnoleftnoright" width="100%">';
 		print '<tr><td colspan="3">';
 
@@ -877,7 +958,8 @@ if ($action == 'create')
 			print $db->error();
 		}
 		print "</table>";
-
+        */
+					
 		print '</td></tr>';
 
 		if ($flag_price_may_change)
@@ -1007,7 +1089,15 @@ else
 		}
 		print '</td></tr>';
 
+		// Note public
+		print '<tr><td>';
+		print $form->editfieldkey($langs->trans("NotePublic"), 'note_public', $object->note_public, $object, $user->rights->facture->creer);
+		print '</td><td colspan="5">';
+		print $form->editfieldval($langs->trans("NotePublic"), 'note_public', $object->note_public, $object, $user->rights->facture->creer, 'textarea:'.ROWS_4.':60');
+		print '</td>';
+		print '</tr>';
 		
+		// Note private
 		print '<tr><td>';
 		print $form->editfieldkey($langs->trans("NotePrivate"), 'note_private', $object->note_private, $object, $user->rights->facture->creer);
 		print '</td><td colspan="5">';
@@ -1208,7 +1298,7 @@ else
 		if (! empty($object->lines))
 		{
 		    $disableedit=1;
-		    $disablemove=1;
+		    //$disablemove=1;
 		    $ret = $object->printObjectLines($action, $mysoc, $soc, $lineid, 0);      // No date selector for template invoice
 		}
 		
@@ -1287,15 +1377,47 @@ else
 		$sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture_rec as f";
 		$sql.= " WHERE f.fk_soc = s.rowid";
 		$sql.= " AND f.entity = ".$conf->entity;
-		if ($socid)	$sql .= " AND s.rowid = ".$socid;
+		if ($search_ref) $sql .= natural_search('f.titre', $search_ref);
+		if ($search_societe) $sql .= natural_search('s.nom', $search_societe);
+		if ($search_frequency) $sql .= natural_search('f.frequency', $search_frequency);
+		if ($search_montant_ht != '') $sql.= natural_search('f.total', $search_montant_ht, 1);
+		if ($search_montant_vat != '') $sql.= natural_search('f.tva', $search_montant_vat, 1);
+		if ($search_montant_ttc != '') $sql.= natural_search('f.total_ttc', $search_montant_ttc, 1);
+		if ($month > 0)
+		{
+		    if ($year > 0 && empty($day))
+		        $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_get_first_day($year,$month,false))."' AND '".$db->idate(dol_get_last_day($year,$month,false))."'";
+		        else if ($year > 0 && ! empty($day))
+		            $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year))."'";
+		            else
+		                $sql.= " AND date_format(f.date_last_gen, '%m') = '".$month."'";
+		}
+		else if ($year > 0)
+		{
+		    $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'";
+		}
+		if ($month_date_when > 0)
+		{
+		    if ($year_date_when > 0 && empty($day_date_when))
+		        $sql.= " AND f.date_when BETWEEN '".$db->idate(dol_get_first_day($year_date_when,$month_date_when,false))."' AND '".$db->idate(dol_get_last_day($year_date_when,$month_date_when,false))."'";
+		        else if ($year_date_when > 0 && ! empty($day_date_when))
+		            $sql.= " AND f.date_date_when_reglement BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_date_when, $day_date_when, $year_date_when))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month_date_when, $day_date_when, $year_date_when))."'";
+		            else
+		                $sql.= " AND date_format(f.date_when, '%m') = '".$month_date_when."'";
+		}
+		else if ($year_date_when > 0)
+		{
+		    $sql.= " AND f.date_when BETWEEN '".$db->idate(dol_get_first_day($year_date_when,1,false))."' AND '".$db->idate(dol_get_last_day($year_date_when,12,false))."'";
+		}        
 
-        $nbtotalofrecords = 0;
+		$nbtotalofrecords = 0;
         if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
         {
         	$result = $db->query($sql);
         	$nbtotalofrecords = $db->num_rows($result);
         }
-        
+      
+        $sql.= $db->order($sortfield, $sortorder);
         $sql.= $db->plimit($limit+1,$offset);
 		
 		$resql = $db->query($sql);
@@ -1305,6 +1427,29 @@ else
 			
 			$param='&socid='.$socid;
 			if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
+			if ($day)                $param.='&day='.$day;
+			if ($month)              $param.='&month='.$month;
+			if ($year)               $param.='&year=' .$year;
+			if ($day_date_when)      $param.='&day_date_when='.$day_date_when;
+			if ($month_date_when)    $param.='&month_date_when='.$month_date_when;
+			if ($year_date_when)     $param.='&year_date_when=' .$year_date_when;
+			if ($search_ref)         $param.='&search_ref=' .$search_ref;
+			if ($search_societe)     $param.='&search_societe=' .$search_societe;
+			if ($search_montant_ht != '')  $param.='&search_montant_ht='.$search_montant_ht;
+			if ($search_montant_vat != '')  $param.='&search_montant_vat='.$search_montant_vat;
+			if ($search_montant_ttc != '') $param.='&search_montant_ttc='.$search_montant_ttc;
+			if ($search_frequency)         $param.='&search_frequency=' .$search_frequency;
+			if ($option)             $param.="&option=".$option;
+			if ($optioncss != '')    $param.='&optioncss='.$optioncss;
+			// Add $param from extra fields
+			foreach ($search_array_options as $key => $val)
+			{
+			    $crit=$val;
+			    $tmpkey=preg_replace('/search_options_/','',$key);
+			    if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val);
+			}
+			
+			$massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge")));
 				
             print '<form method="POST" name="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
             if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
@@ -1313,25 +1458,133 @@ else
         	print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
         	print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
         	print '<input type="hidden" name="viewstatut" value="'.$viewstatut.'">';
-            
-	        print_barre_liste($langs->trans("RepeatableInvoices"),$page,$_SERVER['PHP_SELF'],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecord,'title_accountancy.png',0,'','',$limit);
+
+	        print_barre_liste($langs->trans("RepeatableInvoices"),$page,$_SERVER['PHP_SELF'],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecords,'title_accountancy.png',0,'','',$limit);
 
 			print $langs->trans("ToCreateAPredefinedInvoice", $langs->transnoentitiesnoconv("ChangeIntoRepeatableInvoice")).'<br><br>';
 
 			$i = 0;
 			print '<table class="noborder" width="100%">';
 			print '<tr class="liste_titre">';
-			print_liste_field_titre($langs->trans("Ref"));
-			print_liste_field_titre($langs->trans("Company"),$_SERVER['PHP_SELF'],"s.nom","","&socid=$socid","",$sortfiled,$sortorder);
-			print_liste_field_titre($langs->trans("AmountHT"),'','','','','align="right"');
-			print_liste_field_titre($langs->trans("AmountVAT"),'','','','','align="right"');
-			print_liste_field_titre($langs->trans("AmountTTC"),'','','','','align="right"');
-			print_liste_field_titre($langs->trans("RecurringInvoiceTemplate"),'','','','','align="center"');
-			print_liste_field_titre($langs->trans("DateLastGeneration"),'','','','','align="center"');
-			print_liste_field_titre($langs->trans("NextDateToExecution"),'','','','','align="center"');
+			print_liste_field_titre($langs->trans("Ref"),$_SERVER['PHP_SELF'],"f.titre","",$param,"",$sortfield,$sortorder);
+			print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER['PHP_SELF'],"s.nom","",$param,"",$sortfield,$sortorder);
+			print_liste_field_titre($langs->trans("AmountHT"),$_SERVER['PHP_SELF'],"f.total","",$param,'align="right"',$sortfield,$sortorder);
+			print_liste_field_titre($langs->trans("AmountVAT"),$_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("RecurringInvoiceTemplate"),$_SERVER['PHP_SELF'],"f.frequency","",$param,'align="center"',$sortfield,$sortorder);
+			print_liste_field_titre($langs->trans("DateLastGeneration"),$_SERVER['PHP_SELF'],"f.date_last_gen","",$param,'align="center"',$sortfield,$sortorder);
+			print_liste_field_titre($langs->trans("NextDateToExecution"),$_SERVER['PHP_SELF'],"f.date_when","",$param,'align="center"',$sortfield,$sortorder);
 			print_liste_field_titre('');		// Field may contains ling text
 			print "</tr>\n";
 
+			
+			// Filters lines
+			print '<tr class="liste_titre">';
+			// Ref
+			if (! empty($arrayfields['f.titre']['checked']))
+			{
+			    print '<td class="liste_titre" align="left">';
+			    print '<input class="flat" size="6" type="text" name="search_ref" value="'.$search_ref.'">';
+			    print '</td>';
+			}
+			// Thirpdarty
+			if (! empty($arrayfields['s.nom']['checked']))
+			{
+			    print '<td class="liste_titre" align="left"><input class="flat" type="text" size="8" name="search_societe" value="'.$search_societe.'"></td>';
+			}
+			if (! empty($arrayfields['f.total']['checked']))
+			{
+			    // Amount
+			    print '<td class="liste_titre" align="right">';
+			    print '<input class="flat" type="text" size="5" name="search_montant_ht" value="'.$search_montant_ht.'">';
+			    print '</td>';
+			}
+			if (! empty($arrayfields['f.tva']['checked']))
+			{
+			    // Amount
+			    print '<td class="liste_titre" align="right">';
+			    print '<input class="flat" type="text" size="5" name="search_montant_vat" value="'.$search_montant_vat.'">';
+			    print '</td>';
+			}
+			if (! empty($arrayfields['f.total_ttc']['checked']))
+			{
+			    // Amount
+			    print '<td class="liste_titre" align="right">';
+			    print '<input class="flat" type="text" size="5" name="search_montant_ttc" value="'.$search_montant_ttc.'">';
+			    print '</td>';
+			}
+			if (! empty($arrayfields['f.frequency']['checked']))
+			{
+			    // Amount
+			    print '<td class="liste_titre" align="right">';
+			    //print '<input class="flat" type="text" size="5" name="search_frequency" value="'.$search_frequency.'">';
+			    print '</td>';
+			}
+			// Date invoice
+			if (! empty($arrayfields['f.date_last_gen']['checked']))
+			{
+			    print '<td class="liste_titre" align="center">';
+			    if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="day" value="'.$day.'">';
+			    print '<input class="flat" type="text" size="1" maxlength="2" name="month" value="'.$month.'">';
+			    $formother->select_year($year?$year:-1,'year',1, 20, 5);
+			    print '</td>';
+			}
+			// Date due
+			if (! empty($arrayfields['f.date_when']['checked']))
+			{
+			    print '<td class="liste_titre" align="center">';
+			    if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="day_date_when" value="'.$day_date_when.'">';
+			    print '<input class="flat" type="text" size="1" maxlength="2" name="month_date_when" value="'.$month_date_when.'">';
+			    $formother->select_year($year_date_when?$year_date_when:-1,'year_date_when',1, 20, 5);
+			    print '</td>';
+			}
+			// Extra fields
+			if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
+			{
+			    foreach($extrafields->attribute_label as $key => $val)
+			    {
+			        if (! empty($arrayfields["ef.".$key]['checked']))
+			        {
+			            $align=$extrafields->getAlignFlag($key);
+			            $typeofextrafield=$extrafields->attribute_type[$key];
+			            print '<td class="liste_titre'.($align?' '.$align:'').'">';
+			            if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select')))
+			            {
+			                $crit=$val;
+			                $tmpkey=preg_replace('/search_options_/','',$key);
+			                $searchclass='';
+			                if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring';
+			                if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum';
+			                print '<input class="flat'.($searchclass?' '.$searchclass:'').'" size="4" type="text" name="search_options_'.$tmpkey.'" value="'.dol_escape_htmltag($search_array_options['search_options_'.$tmpkey]).'">';
+			            }
+			            print '</td>';
+			        }
+			    }
+			}
+			// Fields from hook
+			$parameters=array('arrayfields'=>$arrayfields);
+			$reshook=$hookmanager->executeHooks('printFieldListOption',$parameters);    // Note that $action and $object may have been modified by hook
+			print $hookmanager->resPrint;
+			// Date creation
+			if (! empty($arrayfields['f.datec']['checked']))
+			{
+			    print '<td class="liste_titre">';
+			    print '</td>';
+			}
+			// Date modification
+			if (! empty($arrayfields['f.tms']['checked']))
+			{
+			    print '<td class="liste_titre">';
+			    print '</td>';
+			}
+			// Action column
+			print '<td class="liste_titre" align="middle">';
+			$searchpitco=$form->showFilterAndCheckAddButtons(0, 'checkforselect', 1);
+			print $searchpitco;
+			print '</td>';
+			print "</tr>\n";
+			
+			
 			if ($num > 0)
 			{
 				$var=true;
diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php
index e2883081452d8336738a4203de901d7622fd9202..68eb424022645f6dd62157efa9a433bfaaa4dbfe 100644
--- a/htdocs/compta/facture/list.php
+++ b/htdocs/compta/facture/list.php
@@ -153,6 +153,7 @@ $arrayfields=array(
     'f.total_vat'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>0),
     'f.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>0),
     'am'=>array('label'=>$langs->trans("Received"), 'checked'=>0),
+    'rtp'=>array('label'=>$langs->trans("Rest"), 'checked'=>0),
     'f.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
     'f.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
     'f.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
@@ -694,7 +695,7 @@ if ($search_country) $sql .= " AND s.fk_pays IN (".$search_country.')';
 if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$search_type_thirdparty.')';
 if ($search_company) $sql .= natural_search('s.nom', $search_company);
 if ($search_montant_ht != '') $sql.= natural_search('f.total', $search_montant_ht, 1);
-if ($search_montant_vat != '') $sql.= natural_search('f.total', $search_montant_vat, 1);
+if ($search_montant_vat != '') $sql.= natural_search('f.total_vat', $search_montant_vat, 1);
 if ($search_montant_ttc != '') $sql.= natural_search('f.total_ttc', $search_montant_ttc, 1);
 if ($search_status != '' && $search_status >= 0) $sql.= " AND f.fk_statut = ".$db->escape($search_status);
 if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$search_paymentmode."";
@@ -997,6 +998,7 @@ if ($resql)
     if (! empty($arrayfields['f.total_vat']['checked']))          print_liste_field_titre($arrayfields['f.total_vat']['label'],$_SERVER['PHP_SELF'],'f.tva','',$param,'align="right"',$sortfield,$sortorder);
     if (! empty($arrayfields['f.total_ttc']['checked']))          print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],'f.total_ttc','',$param,'align="right"',$sortfield,$sortorder);
     if (! empty($arrayfields['am']['checked']))                   print_liste_field_titre($arrayfields['am']['label'],$_SERVER['PHP_SELF'],'am','',$param,'align="right"',$sortfield,$sortorder);
+	if (! empty($arrayfields['rtp']['checked']))                  print_liste_field_titre($arrayfields['rtp']['label'],$_SERVER['PHP_SELF'],'rtp','',$param,'align="right"',$sortfield,$sortorder);
     // Extra fields
     if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
     {
@@ -1117,6 +1119,11 @@ if ($resql)
         print '<td class="liste_titre" align="right">';
         print '</td>';
     }
+    if (! empty($arrayfields['rtp']['checked']))
+    {
+        print '<td class="liste_titre" align="right">';
+        print '</td>';
+    }
     // Extra fields
 	if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
 	{
@@ -1195,6 +1202,7 @@ if ($resql)
                 $facturestatic->date_lim_reglement=$db->jdate($obj->datelimite);
                 $notetoshow=dol_string_nohtmltag(($user->societe_id>0?$obj->note_public:$obj->note_private),1);
                 $paiement = $facturestatic->getSommePaiement();
+				$remaintopay = $obj->total_ttc - $paiement;
     
                 print '<table class="nobordernopadding"><tr class="nocellnopadd">';
     
@@ -1347,6 +1355,14 @@ if ($resql)
     		    if (! $i) $totalarray['totalamfield']=$totalarray['nbfield'];
     		    $totalarray['totalam'] += $paiement;
             }
+
+            if (! empty($arrayfields['rtp']['checked']))
+            {
+                print '<td align="right">'.(! empty($remaintopay)?price($remaintopay,0,$langs):'&nbsp;').'</td>';
+                if (! $i) $totalarray['nbfield']++;
+    		    if (! $i) $totalarray['totalrtpfield']=$totalarray['nbfield'];
+    		    $totalarray['totalrtp'] += $remaintopay;
+            }
             
             // Extra fields
             if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
@@ -1425,6 +1441,7 @@ if ($resql)
     		   elseif ($totalarray['totalvatfield'] == $i) print '<td align="right">'.price($totalarray['totalvat']).'</td>';
     		   elseif ($totalarray['totalttcfield'] == $i) print '<td align="right">'.price($totalarray['totalttc']).'</td>';
     		   elseif ($totalarray['totalamfield'] == $i)  print '<td align="right">'.price($totalarray['totalam']).'</td>';
+			   elseif ($totalarray['totalrtpfield'] == $i)  print '<td align="right">'.price($totalarray['totalrtp']).'</td>';
     		   else print '<td></td>';
     		}
     		print '</tr>';
diff --git a/htdocs/compta/resultat/clientfourn.php b/htdocs/compta/resultat/clientfourn.php
index 6a31fc02b4cae47f55485f6f515c123540db79fb..2d9241301a6d390e26cd6f3c5c22a228140e61cc 100644
--- a/htdocs/compta/resultat/clientfourn.php
+++ b/htdocs/compta/resultat/clientfourn.php
@@ -382,7 +382,7 @@ print '</tr>';
  * Charges sociales non deductibles
  */
 
-print '<tr><td colspan="4">'.$langs->trans("SocialContributions").' ('.$langs->trans("Type").' 0)</td></tr>';
+print '<tr><td colspan="4">'.$langs->trans("SocialContributionsNondeductibles").'</td></tr>';
 
 if ($modecompta == 'CREANCES-DETTES')
 {
@@ -456,7 +456,7 @@ print '</tr>';
  * Charges sociales deductibles
  */
 
-print '<tr><td colspan="4">'.$langs->trans("SocialContributions").' ('.$langs->trans("Type").' 1)</td></tr>';
+print '<tr><td colspan="4">'.$langs->trans("SocialContributionsDeductibles").'</td></tr>';
 
 if ($modecompta == 'CREANCES-DETTES')
 {
diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php
index ca58ff334b5048fe70b0f504da07e89b3b45276b..8e4aabd93390b64f4c9c8a89561a51d58b726843 100644
--- a/htdocs/compta/stats/cabyprodserv.php
+++ b/htdocs/compta/stats/cabyprodserv.php
@@ -181,6 +181,8 @@ report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportl
 
 // SQL request
 $catotal=0;
+$catotal_ht=0;
+$qtytotal=0;
 
 if ($modecompta == 'CREANCES-DETTES')
 {
@@ -401,6 +403,8 @@ if ($modecompta == 'CREANCES-DETTES')
 		// Total
 		print '<tr class="liste_total">';
 		print '<td>'.$langs->trans("Total").'</td>';
+		print '<td align="right">'.price($qtytotal).'</td>';
+		print '<td>&nbsp;</td>';
 		print '<td align="right">'.price($catotal_ht).'</td>';
 		print '<td align="right">'.price($catotal).'</td>';
 		print '<td>&nbsp;</td>';
diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php
index 88cd24af359cdc6361406a66cc1b0a917b084c1a..259918c5aa9b3ba9b27c79bc5b753cccb689b41f 100644
--- a/htdocs/contact/class/contact.class.php
+++ b/htdocs/contact/class/contact.class.php
@@ -107,6 +107,47 @@ class Contact extends CommonObject
 		$this->db = $db;
 		$this->statut = 1;	// By default, status is enabled
 	}
+	
+	/**
+	 *  Load indicators into this->nb for board
+	 *
+	 *  @return     int         <0 if KO, >0 if OK
+	 */
+	function load_state_board()
+	{
+		global $user;
+	
+		$this->nb=array();
+		$clause = "WHERE";
+	
+		$sql = "SELECT count(sp.rowid) as nb";
+		$sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp";
+		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON (sp.fk_soc = s.rowid)";
+		if (!$user->rights->societe->client->voir && !$user->societe_id)
+		{
+			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
+			$sql.= " WHERE sc.fk_user = " .$user->id;
+			$clause = "AND";
+		}
+		$sql.= ' '.$clause.' s.entity IN ('.getEntity($this->element, 1).')';
+	
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
+			while ($obj=$this->db->fetch_object($resql))
+			{
+				$this->nb["contacts"]=$obj->nb;
+			}
+			$this->db->free($resql);
+			return 1;
+		}
+		else
+		{
+			dol_print_error($this->db);
+			$this->error=$this->db->lasterror();
+			return -1;
+		}
+	}
 
 	/**
 	 *  Add a contact into database
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index ec02fce3daeb99b52cbe9b12597f4edd69f634ee..049ccbd1bc965494f3e0eb1eadfb8ae462ddd81d 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -3236,8 +3236,9 @@ abstract class CommonObject
 	 */
 	function printObjectLines($action, $seller, $buyer, $selected=0, $dateSelector=0)
 	{
-		global $conf, $hookmanager, $inputalsopricewithtax, $usemargins, $disableedit, $disablemove, $langs, $user;
-
+		global $conf, $hookmanager, $langs, $user;
+		global $inputalsopricewithtax, $usemargins, $disableedit, $disablemove, $disableremove;   // TODO We should not use global var for this !
+		
 		// Define usemargins
 		$usemargins=0;
 		if (! empty($conf->margin->enabled) && ! empty($this->element) && in_array($this->element,array('facture','propal','commande'))) $usemargins=1;
@@ -3366,7 +3367,7 @@ abstract class CommonObject
 	{
 		global $conf,$langs,$user,$object,$hookmanager;
 		global $form,$bc,$bcdd;
-		global $object_rights, $disableedit, $disablemove;   // TODO We should not use global var for this !
+		global $object_rights, $disableedit, $disablemove, $disableremove;   // TODO We should not use global var for this !
 
 		$object_rights = $this->getRights();
 
@@ -4559,7 +4560,7 @@ abstract class CommonObject
 					$productFournisseur = new ProductFournisseur($this->db);
 					if (($result = $productFournisseur->find_min_price_product_fournisseur($fk_product)) > 0)
 					{
-						$buyPrice = $productFournisseur->fourn_price;
+						$buyPrice = $productFournisseur->fourn_unitprice;
 					}
 					else if ($result < 0)
 					{
diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php
index 8564a18822e3e3a8cf8a4ef661a81cc2cc3041d6..ff31823976e769354dc103c7571cd282a9b49df5 100644
--- a/htdocs/core/class/doleditor.class.php
+++ b/htdocs/core/class/doleditor.class.php
@@ -52,7 +52,7 @@ class DolEditor
      *      @param 	string	$content		        Content of WYSIWIG field
      *      @param	int		$width					Width in pixel of edit area (auto by default)
      *      @param 	int		$height			        Height in pixel of edit area (200px by default)
-     *      @param 	string	$toolbarname	        Name of bar set to use ('Full', 'dolibarr_notes[_encoded]', 'dolibarr_details[_encoded]'=the less featured, 'dolibarr_mailings[_encoded]', ')
+     *      @param 	string	$toolbarname	        Name of bar set to use ('Full', 'dolibarr_notes[_encoded]', 'dolibarr_details[_encoded]'=the less featured, 'dolibarr_mailings[_encoded]', 'dolibarr_readonly')
      *      @param  string	$toolbarlocation       	Where bar is stored :
      *                       		             	'In' each window has its own toolbar
      *                              		      	'Out:name' share toolbar into the div called 'name'
@@ -148,7 +148,10 @@ class DolEditor
     {
     	global $conf,$langs;
 
-        $found=0;
+    	$fullpage=False;
+    	$disallowAnyContent=empty($conf->global->FCKEDITOR_ALLOW_ANY_CONTENT); // Only predefined list of html tags are allowed
+    	
+    	$found=0;
 		$out='';
 
         if ($this->tool == 'fckeditor')
@@ -186,7 +189,8 @@ class DolEditor
             						customConfig : ckeditorConfig,
             						readOnly : '.($this->readonly?'true':'false').',
                             		htmlEncodeOutput :'.$htmlencode_force.',
-            						allowedContent :'.(empty($conf->global->FCKEDITOR_ALLOW_ANY_CONTENT)?'false':'true').',
+            						allowedContent :'.($disallowAnyContent?'false':'true').',
+            						fullPage : '.($fullpage?'true':'false').', 
                             		toolbar: \''.$this->toolbarname.'\',
             						toolbarStartupExpanded: '.($this->toolbarstartexpanded ? 'true' : 'false').',
             						width: '.($this->width ? '\''.$this->width.'\'' : '\'\'').',
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 697e5e8bdeb2e6df9373f995e3aed8f429cbb3a6..c65fcb1bdc5851e804fe9c118fadd1a28c30e9d0 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -390,6 +390,7 @@ class Form
      *	@param	int			$noencodehtmltext	Do not encode into html entity the htmltext
      *	@return	string							Code html du tooltip (texte+picto)
      *	@see	Use function textwithpicto if you can.
+     *  TODO Move this as static as soon as everybody use textwithpicto or @Form::textwithtooltip
      */
     function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 2, $incbefore = '', $noencodehtmltext = 0)
     {
@@ -2057,17 +2058,27 @@ class Form
     {
         global $langs,$conf;
         global $price_level, $status, $finished;
-
+        
+        $selected_input_value='';
         if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
         {
+            if ($selected > 0)
+            {
+                require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+                $producttmpselect = new Product($this->db);
+                $producttmpselect->fetch($selected);
+                $selected_input_value=$producttmpselect->ref;
+                unset($producttmpselect);
+            }
+
         	if (!empty($conf->global->SUPPLIER_ORDER_WITH_NOPRICEDEFINED))
 			{
 				print '<input type="hidden" id="idprod" name="idprod" value="0" />';
 			}
 			// mode=2 means suppliers products
             $urloption=($socid > 0?'socid='.$socid.'&':'').'htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=2&status='.$status.'&finished='.$finished;
-            print ajax_autocompleter('', $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
-            print ($hidelabel?'':$langs->trans("RefOrLabel").' : ').'<input type="text" size="20" name="search_'.$htmlname.'" id="search_'.$htmlname.'">';
+            print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
+            print ($hidelabel?'':$langs->trans("RefOrLabel").' : ').'<input type="text" size="20" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'">';
         }
         else
         {
@@ -2089,7 +2100,7 @@ class Form
      *  @param	string	$filtertype     Filter on product type (''=nofilter, 0=product, 1=service)
      *	@param  string	$filtre         Pour filtre sql
      *	@param  string	$filterkey      Filtre des produits
-     *  @param  int		$statut         -1=Return all products, 0=Products not on sell, 1=Products on sell
+     *  @param  int		$statut         -1=Return all products, 0=Products not on sell, 1=Products on sell (not used here, a filter on tobuy is already hard coded in request)
      *  @param  int		$outputmode     0=HTML select string, 1=Array
      *  @param  int     $limit          Limit of line number
      *  @return array           		Array of keys for json
@@ -2106,7 +2117,7 @@ class Form
         $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, p.fk_product_type,";
         $sql.= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,";
         $sql.= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,";
-	$sql.= " pfp.supplier_reputation";
+        $sql.= " pfp.supplier_reputation";
         $sql.= " FROM ".MAIN_DB_PREFIX."product as p";
         $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
         if ($socid) $sql.= " AND pfp.fk_soc = ".$socid;
@@ -2390,10 +2401,10 @@ class Form
                     $form.= $opt;
                     $i++;
                 }
-                $form.= '</select>';
-
-                $this->db->free($result);
             }
+
+            $form.= '</select>';
+            $this->db->free($result);
             return $form;
         }
         else
diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php
index 5af984ba659b372e9f3533952f2ea02bc127ee62..f446caa12a2c07afb110ab0880cdebaa6623bb8f 100644
--- a/htdocs/core/class/html.formother.class.php
+++ b/htdocs/core/class/html.formother.class.php
@@ -805,6 +805,7 @@ class FormOther
                 $select_week .= '<option value="'.$key.'">';
             }
             $select_week .= $val;
+            $select_week .= '</option>';
         }
         $select_week .= '</select>';
         return $select_week;
@@ -844,6 +845,7 @@ class FormOther
                 $select_month .= '<option value="'.$key.'">';
             }
             $select_month .= $val;
+            $select_month .= '</option>';
         }
         $select_month .= '</select>';
         return $select_month;
diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php
index 866b746362bd596e9c5b400b00835a30f19b72d3..34858bc32346b7505b80cd343a63335f6b9afbfd 100644
--- a/htdocs/core/class/translate.class.php
+++ b/htdocs/core/class/translate.class.php
@@ -908,7 +908,8 @@ class Translate
 	}
 
 	/**
-	 *	Return a currency code into its symbol
+	 *	Return a currency code into its symbol. 
+	 *  If mb_convert_encoding is not available, return currency code.
 	 *
 	 *  @param	string	$currency_code		Currency code
 	 *  @param	integer	$forceloadall		1=Force to load all currencies into cache. We know we need to use all of them. By default read and cache only required currency.
diff --git a/htdocs/core/filemanagerdol/browser/default/browser.php b/htdocs/core/filemanagerdol/browser/default/browser.php
index f542bdf59b6478e00919aad885c79d530cf1fcd1..15e44621bcfbfa964b0f81405beb159ee867b1f5 100644
--- a/htdocs/core/filemanagerdol/browser/default/browser.php
+++ b/htdocs/core/filemanagerdol/browser/default/browser.php
@@ -19,15 +19,20 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-define('NOTOKENRENEWAL',1); // Disables token renewal
+//define('NOTOKENRENEWAL',1); // Disables token renewal
+//require '../../../../main.inc.php';
+require '../../connectors/php/config.php';      // This include the define('NOTOKENRENEWAL',1) and the require main.in.php
+
+global $Config;
+
+
 
-require '../../../../main.inc.php';
 ?>
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
    "http://www.w3.org/TR/html4/frameset.dtd">
 <html>
 	<head>
-		<title>FCKeditor - Resources Browser</title>
+		<title><?php echo $langs->trans("MediaBrowser").' - '.$Config['UserFilesAbsolutePathRelative']; ?></title>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 		<script type="text/javascript" src="js/fckxml.js"></script>
 		<script type="text/javascript">
diff --git a/htdocs/core/filemanagerdol/connectors/php/config.php b/htdocs/core/filemanagerdol/connectors/php/config.php
index 0c3b0a4884c3654d9546c0150f36513e6e72249e..8733e6a7c1706dfc086c8f1a7d89fd431724fa7e 100644
--- a/htdocs/core/filemanagerdol/connectors/php/config.php
+++ b/htdocs/core/filemanagerdol/connectors/php/config.php
@@ -23,6 +23,7 @@
  */
 
 global $Config ;
+global $website;
 
 define('NOTOKENRENEWAL',1); // Disables token renewal
 
@@ -44,13 +45,15 @@ $Config['Enabled'] = true ;
 
 
 // Path to user files relative to the document root.
-$Config['UserFilesPath'] = DOL_URL_ROOT.'/viewimage.php?modulepart=fckeditor&file=' ;
+$Config['UserFilesPath'] = DOL_URL_ROOT.'/viewimage.php?modulepart=medias'.(empty($website)?'':'_'.$website).'&file=' ;
+
+$Config['UserFilesAbsolutePathRelative'] = (empty($website) ? ((!empty($entity) ? '/' . $entity : '') . '/medias/') : ('/websites/'.$website));
 
 // Fill the following value it you prefer to specify the absolute path for the
 // user files directory. Useful if you are using a virtual directory, symbolic
 // link or alias. Examples: 'C:\\MySite\\userfiles\\' or '/root/mysite/userfiles/'.
 // Attention: The above 'UserFilesPath' must point to the same directory.
-$Config['UserFilesAbsolutePath'] = $dolibarr_main_data_root . (!empty($entity) ? '/' . $entity : '') . '/fckeditor/';
+$Config['UserFilesAbsolutePath'] = $dolibarr_main_data_root . $Config['UserFilesAbsolutePathRelative'];
 
 // Due to security issues with Apache modules, it is recommended to leave the
 // following setting enabled.
@@ -64,7 +67,7 @@ $Config['SecureImageUploads'] = true;
 $Config['ConfigAllowedCommands'] = array('QuickUpload', 'FileUpload', 'GetFolders', 'GetFoldersAndFiles', 'CreateFolder');
 
 // Allowed Resource Types.
-$Config['ConfigAllowedTypes'] = array('File', 'Image', 'Flash', 'Media');
+$Config['ConfigAllowedTypes'] = array('File', 'Image', 'Media');
 
 // For security, HTML is allowed in the first Kb of data for files having the
 // following extensions only.
@@ -75,11 +78,19 @@ $Config['HtmlExtensions'] = array("html", "htm", "xml", "xsd", "txt", "js");
 // If possible, it is recommended to set more restrictive permissions, like 0755.
 // Set to 0 to disable this feature.
 // Note: not needed on Windows-based servers.
-$Config['ChmodOnUpload'] = 0775 ;
+$newmask = '0644';
+if (! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
+$Config['ChmodOnUpload'] = $newmask;
 
 // See comments above.
 // Used when creating folders that does not exist.
-$Config['ChmodOnFolderCreate'] = 0775 ;
+$newmask = '0755';
+$dirmaskdec=octdec($newmask);
+if (! empty($conf->global->MAIN_UMASK)) $dirmaskdec=octdec($conf->global->MAIN_UMASK);
+$dirmaskdec |= octdec('0200');  // Set w bit required to be able to create content for recursive subdirs files
+$newmask = decoct($dirmaskdec);
+
+$Config['ChmodOnFolderCreate'] = $newmask;
 
 /*
 	Configuration settings for each Resource Type
diff --git a/htdocs/core/filemanagerdol/connectors/php/upload.php b/htdocs/core/filemanagerdol/connectors/php/upload.php
index eb9600b20a9e459d269fd67c9c34fad508a0f1ab..dc7235dc8a8f35bccf87f84b61a1f21cde664687 100644
--- a/htdocs/core/filemanagerdol/connectors/php/upload.php
+++ b/htdocs/core/filemanagerdol/connectors/php/upload.php
@@ -42,7 +42,7 @@ function SendError($number, $text)
 
 // Check if this uploader has been enabled.
 if ( !$Config['Enabled'] )
-	SendUploadResults('1', '', '', 'This file uploader is disabled. Please check the "editor/filemanager/connectors/php/config.php" file');
+	SendUploadResults('1', '', '', 'This file uploader is disabled. Please check the "filemanagerdol/connectors/php/config.php" file');
 
 $sCommand = 'QuickUpload' ;
 
diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php
index ce495a771d880d2ec9ad00eb735e83d2d31a2421..4f08650e56b7ee2856b7d39b83d22fedae1b30c0 100644
--- a/htdocs/core/lib/admin.lib.php
+++ b/htdocs/core/lib/admin.lib.php
@@ -346,7 +346,8 @@ function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$oker
 					'DB_ERROR_NO_INDEX_TO_DROP',
 					'DB_ERROR_CANNOT_CREATE',    		// Qd contrainte deja existante
 					'DB_ERROR_CANT_DROP_PRIMARY_KEY',
-					'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS'
+					'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS',
+            		'DB_ERROR_22P02'
 				);
                 if ($okerror == 'none') $okerrors=array();
 
@@ -928,7 +929,7 @@ function complete_dictionary_with_modules(&$taborder,&$tabname,&$tablib,&$tabsql
                                 foreach($objMod->dictionaries['tabcond'] as $val)        { $nbtabcond++; $tabcond[] = $val; }
                                 if (! empty($objMod->dictionaries['tabhelp']))       foreach($objMod->dictionaries['tabhelp'] as $val)       { $nbtabhelp++; $tabhelp[] = $val; }
                                 if (! empty($objMod->dictionaries['tabfieldcheck'])) foreach($objMod->dictionaries['tabfieldcheck'] as $val) { $nbtabfieldcheck++; $tabfieldcheck[] = $val; }
-                                
+
                                 if ($nbtabname != $nbtablib || $nbtablib != $nbtabsql || $nbtabsql != $nbtabsqlsort)
                                 {
                                     print 'Error in descriptor of module '.$const_name.'. Array ->dictionaries has not same number of record for key "tabname", "tablib", "tabsql" and "tabsqlsort"';
diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php
index 4b3ab3b32f41b920887743d310e86060b2954c78..4b0ae91ee3f0fbd1984048ff5e2196aaceb6ddb2 100644
--- a/htdocs/core/lib/ajax.lib.php
+++ b/htdocs/core/lib/ajax.lib.php
@@ -136,7 +136,8 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLengt
     					minLength: '.$minLength.',
     					select: function( event, ui ) {		// Function ran once new value has been selected into javascript combo
     						console.log("Call change on input '.$htmlname.' because of select definition of autocomplete select call on input#search_'.$htmlname.'");
-    					    $("#'.$htmlname.'").val(ui.item.id).trigger("change");	// Select new value
+    					    console.log("Selected id = "+ui.item.id+" - If this value is null, it means you select a record with key that is null so selection is not effective");
+    						$("#'.$htmlname.'").val(ui.item.id).trigger("change");	// Select new value
     						// Disable an element
     						if (options.option_disabled) {
     							if (ui.item.disabled) {
@@ -179,7 +180,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLengt
 									}
     							});
     						}
-    						console.log("ajax_autocompleter new value selected, we trigger change on original component");
+    						console.log("ajax_autocompleter new value selected, we trigger change on original component so field #search_'.$htmlname.'");
     						$("#search_'.$htmlname.'").trigger("change");	// We have changed value of the combo select, we must be sure to trigger all js hook binded on this event. This is required to trigger other javascript change method binded on original field by other code.
     					}
     					,delay: 500
@@ -290,14 +291,15 @@ function ajax_multiautocompleter($htmlname, $fields, $url, $option='', $minLengt
 								    	needtotrigger="#" + fields[i];
 									}
 								}
-							}
-							if (needtotrigger != "")	// To force select2 to refresh visible content
-							{
-								// We introduce a delay so hand is back to js and all other js change can be done before the trigger that may execute a submit is done
-								// This is required for example when changing zip with autocomplete that change the country
-								jQuery(needtotrigger).delay(500).queue(function() {
-    								jQuery(needtotrigger).trigger("change");
-								});
+							
+								if (needtotrigger != "")	// To force select2 to refresh visible content
+								{
+									// We introduce a delay so hand is back to js and all other js change can be done before the trigger that may execute a submit is done
+									// This is required for example when changing zip with autocomplete that change the country
+									jQuery(needtotrigger).delay(500).queue(function() {
+	    								jQuery(this).trigger("change");
+									});
+								}
 							}
     					}
 					});
diff --git a/htdocs/core/lib/fichinter.lib.php b/htdocs/core/lib/fichinter.lib.php
index 162aca37c8ab8727196030d4449f6a0782195166..25f8c2c98aaa46080fdbc7298e54a2d1ba40fa70 100644
--- a/htdocs/core/lib/fichinter.lib.php
+++ b/htdocs/core/lib/fichinter.lib.php
@@ -2,6 +2,8 @@
 /* Copyright (C) 2006-2007	Laurent Destailleur		<eldy@users.sourceforge.net>
  * Copyright (C) 2007		Rodolphe Quiedeville	<rodolphe@quiedeville.org>
  * Copyright (C) 2012		Regis Houssin			<regis.houssin@capnetworks.com>
+ * Copyright (C) 2016		   Gilles Poirier 		   <glgpoirier@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
@@ -67,6 +69,15 @@ function fichinter_prepare_head($object)
     // $this->tabs = array('entity:-tabname);   												to remove a tab
     complete_head_from_modules($conf,$langs,$object,$head,$h,'intervention');
 
+	// Tab to link resources
+	if ($conf->resource->enabled)
+	{
+		$head[$h][0] = DOL_URL_ROOT.'/resource/element_resource.php?element=fichinter&element_id='.$object->id;
+		$head[$h][1] = $langs->trans("Resources");
+		$head[$h][2] = 'resource';
+		$h++;
+	}
+
     if (empty($conf->global->MAIN_DISABLE_NOTES_TAB))
     {
     	$nbNote = 0;
diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
index 9be021b975e67f772f021bfbfc3a04c36ccf1e20..95cb980e7543368460e4aa47f69306543368f8a1 100644
--- a/htdocs/core/lib/files.lib.php
+++ b/htdocs/core/lib/files.lib.php
@@ -2213,8 +2213,6 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu
 	// Wrapping for import module
 	else if ($modulepart == 'import')
 	{
-		// Aucun test necessaire car on force le rep de download sur
-		// le rep export qui est propre a l'utilisateur
 		$accessallowed=1;
 		$original_file=$conf->import->dir_temp.'/'.$original_file;
 	}
@@ -2222,13 +2220,19 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu
 	// Wrapping pour l'editeur wysiwyg
 	else if ($modulepart == 'editor')
 	{
-		// Aucun test necessaire car on force le rep de download sur
-		// le rep export qui est propre a l'utilisateur
 		$accessallowed=1;
 		$original_file=$conf->fckeditor->dir_output.'/'.$original_file;
 	}
-
-	// Wrapping pour les backups
+	
+	// Wrapping for miscellaneous medias files
+	elseif ($modulepart == 'medias')
+	{
+	    $accessallowed=1;
+	    global $dolibarr_main_data_root;
+	    $original_file=$dolibarr_main_data_root.'/medias/'.$original_file;
+	}
+	
+	// Wrapping for backups
 	else if ($modulepart == 'systemtools')
 	{
 		if ($fuser->admin)
diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php
index 5de04c6718e77dcc789f746b1d7b3144dfe7a5a4..85ebe30dec66e94443e68e42700be2e812635a4b 100644
--- a/htdocs/core/lib/functions2.lib.php
+++ b/htdocs/core/lib/functions2.lib.php
@@ -1963,6 +1963,11 @@ function getElementProperties($element_type)
         $module='ficheinter';
         $subelement='fichinter';
     }
+    if ($element_type == 'dolresource') {
+        $classpath = 'resource/class';
+        $module='resource';
+        $subelement='dolresource';
+    }
     $classfile = strtolower($subelement);
     $classname = ucfirst($subelement);
 
diff --git a/htdocs/core/lib/resource.lib.php b/htdocs/core/lib/resource.lib.php
index e92d59dcac763bca69104d7f81b2054b217a4741..621cf800d9995930e70d042809738973784b49d3 100644
--- a/htdocs/core/lib/resource.lib.php
+++ b/htdocs/core/lib/resource.lib.php
@@ -1,6 +1,7 @@
 <?php
 /* Module to manage locations, buildings, floors and rooms into Dolibarr ERP/CRM
  * Copyright (C) 2013	Jean-François Ferry	<jfefe@aternatik.fr>
+ * Copyright (C) 2016	Gilles Poirier		<glgpoirier@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
@@ -28,7 +29,7 @@
  * @param	Object	$object		Object
  * @return	array				Array of head entries
  */
-function resourcePrepareHead($object)
+function resource_prepare_head($object)
 {
 	global $langs, $conf, $user;
 	$h = 0;
@@ -36,15 +37,50 @@ function resourcePrepareHead($object)
 
 	$head[$h][0] = dol_buildpath('/resource/card.php',1).'?id='.$object->id;
 	$head[$h][1] = $langs->trans("ResourceCard");
-    $head[$h][2] = 'resource';
+    	$head[$h][2] = 'resource';
 	$h++;
 
+	if (empty($conf->global->MAIN_DISABLE_CONTACTS_TAB))
+	{
+		$head[$h][0] = DOL_URL_ROOT.'/resource/contact.php?id='.$object->id;
+		$head[$h][1] = $langs->trans('Contact');
+		$head[$h][2] = 'contact';
+		$h++;
+	}
+
 	// Show more tabs from modules
 	// Entries must be declared in modules descriptor with line
 	// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
 	// $this->tabs = array('entity:-tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to remove a tab
 	complete_head_from_modules($conf,$langs,$object,$head,$h,'resource');
 
+	if (empty($conf->global->MAIN_DISABLE_NOTES_TAB))
+	{
+		$nbNote = 0;
+		if(!empty($object->note_private)) $nbNote++;
+		if(!empty($object->note_public)) $nbNote++;
+		$head[$h][0] = DOL_URL_ROOT.'/resource/note.php?id='.$object->id;
+		$head[$h][1] = $langs->trans('Notes');
+		if ($nbNote > 0) $head[$h][1].= ' <span class="badge">'.$nbNote.'</span>';
+		$head[$h][2] = 'note';
+		$h++;
+	}
+
+	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+	$upload_dir = $conf->resource->dir_output . "/" . dol_sanitizeFileName($object->ref);
+	$nbFiles = count(dol_dir_list($upload_dir,'files',0,'','(\.meta|_preview\.png)$'));
+	$head[$h][0] = DOL_URL_ROOT.'/resource/document.php?id='.$object->id;
+	$head[$h][1] = $langs->trans("Documents");
+	if($nbFiles > 0) $head[$h][1].= ' <span class="badge">'.$nbFiles.'</span>';
+	$head[$h][2] = 'documents';
+	$h++;
+
+	/*$head[$h][0] = DOL_URL_ROOT.'/resource/info.php?id='.$object->id;
+	$head[$h][1] = $langs->trans('Info');
+	$head[$h][2] = 'info';
+	$h++;*/
+	
+	complete_head_from_modules($conf,$langs,$object,$head,$h,'resource', 'remove');
 
 	return $head;
 }
diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php
index 9a3fe6ff1f37755ae01e9bc3d8539b4c81e7e297..d682aa2db97b2535c6c9108465c5b03e5fad5fa2 100644
--- a/htdocs/core/modules/DolibarrModules.class.php
+++ b/htdocs/core/modules/DolibarrModules.class.php
@@ -1009,7 +1009,12 @@ class DolibarrModules           // Can not be abstract, because we need to insta
 
                         if (! $err)
                         {
-                            $sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob (module_name, datec, datestart, label, jobtype, classesname, objectname, methodename, command, params, note, frequency, unitfrequency, priority, status, entity, test)";
+                            $sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob (module_name, datec, datestart, label, jobtype, classesname, objectname, methodename, command, params, note,";
+                            if(is_int($frequency)){ $sql.= ' frequency,'; }
+                            if(is_int($unitfrequency)){ $sql.= ' unitfrequency,'; }
+                            if(is_int($priority)){ $sql.= ' priority,'; }
+                            if(is_int($status)){ $sql.= ' status,'; }
+                            $sql.= " entity, test)";
                             $sql.= " VALUES (";
                             $sql.= "'".$this->db->escape($this->rights_class)."', ";
                             $sql.= "'".$this->db->idate($now)."', ";
@@ -1022,10 +1027,10 @@ class DolibarrModules           // Can not be abstract, because we need to insta
                             $sql.= ($command?"'".$this->db->escape($command)."'":"null").",";
                             $sql.= ($parameters?"'".$this->db->escape($parameters)."'":"null").",";
                             $sql.= ($comment?"'".$this->db->escape($comment)."'":"null").",";
-                            $sql.= "'".$this->db->escape($frequency)."', ";
-                            $sql.= "'".$this->db->escape($unitfrequency)."', ";
-                            $sql.= "'".$this->db->escape($priority)."', ";
-                            $sql.= "'".$this->db->escape($status)."', ";
+                            if(is_int($frequency)){ $sql.= "'".$this->db->escape($frequency)."', "; }
+                            if(is_int($unitfrequency)){ $sql.= "'".$this->db->escape($unitfrequency)."', "; }
+                            if(is_int($priority)) {$sql.= "'".$this->db->escape($priority)."', ";}
+                            if(is_int($status)){ $sql.= "'".$this->db->escape($status)."', "; }
                             $sql.= $conf->entity.",";
                             $sql.= "'".$this->db->escape($test)."'";
                             $sql.= ")";
diff --git a/htdocs/core/modules/export/export_csv.modules.php b/htdocs/core/modules/export/export_csv.modules.php
index 3da80b1cc966ce9923d8dbe2710f47270741ba02..e8977c1178910fd25249463aef53d081ee978b8c 100644
--- a/htdocs/core/modules/export/export_csv.modules.php
+++ b/htdocs/core/modules/export/export_csv.modules.php
@@ -240,7 +240,7 @@ class ExportCsv extends ModeleExports
 		$this->col=0;
 		foreach($array_selected_sorted as $code => $value)
 		{
-			if (strpos($code,' as ') == 0) $alias=str_replace(array('.','-'),'_',$code);
+			if (strpos($code,' as ') == 0) $alias=str_replace(array('.','-','(',')'),'_',$code);
 			else $alias=substr($code, strpos($code, ' as ') + 4);
 			if (empty($alias)) dol_print_error('','Bad value for field with key='.$code.'. Try to redefine export.');
 
diff --git a/htdocs/core/modules/export/export_excel.modules.php b/htdocs/core/modules/export/export_excel.modules.php
index ede00733695cfdfd4b682a8ff4860fc33bc140a2..91f7852297308088c089fa8dd142a120f6a02b38 100644
--- a/htdocs/core/modules/export/export_excel.modules.php
+++ b/htdocs/core/modules/export/export_excel.modules.php
@@ -319,7 +319,7 @@ class ExportExcel extends ModeleExports
 
 		foreach($array_selected_sorted as $code => $value)
 		{
-			if (strpos($code,' as ') == 0) $alias=str_replace(array('.','-'),'_',$code);
+			if (strpos($code,' as ') == 0) $alias=str_replace(array('.','-','(',')'),'_',$code);
 			else $alias=substr($code, strpos($code, ' as ') + 4);
             if (empty($alias)) dol_print_error('','Bad value for field with code='.$code.'. Try to redefine export.');
             $newvalue=$objp->$alias;
diff --git a/htdocs/core/modules/export/export_tsv.modules.php b/htdocs/core/modules/export/export_tsv.modules.php
index dad3a4b67f98986a4dc0916c462a87fea78a4f41..2945c5095b8cace11a1198232c558055e36c5f17 100644
--- a/htdocs/core/modules/export/export_tsv.modules.php
+++ b/htdocs/core/modules/export/export_tsv.modules.php
@@ -215,7 +215,7 @@ class ExportTsv extends ModeleExports
 		$this->col=0;
  		foreach($array_selected_sorted as $code => $value)
         {
-			if (strpos($code,' as ') == 0) $alias=str_replace(array('.','-'),'_',$code);
+			if (strpos($code,' as ') == 0) $alias=str_replace(array('.','-','(',')'),'_',$code);
 			else $alias=substr($code, strpos($code, ' as ') + 4);
             if (empty($alias)) dol_print_error('','Bad value for field with code='.$code.'. Try to redefine export.');
 
diff --git a/htdocs/core/modules/modFckeditor.class.php b/htdocs/core/modules/modFckeditor.class.php
index 31b3fafff167990db73f86359685d802655572bd..ec7ce4dda14926b0ef0805e67f7b9b08c343f36a 100644
--- a/htdocs/core/modules/modFckeditor.class.php
+++ b/htdocs/core/modules/modFckeditor.class.php
@@ -57,7 +57,7 @@ class modFckeditor extends DolibarrModules
 		$this->picto='list';
 
 		// Data directories to create when module is enabled
-		$this->dirs = array("/fckeditor/temp","/fckeditor/image");
+		$this->dirs = array("/medias/temp","/medias/image");
 
 		// Config pages
 		$this->config_page_url = array("fckeditor.php");
@@ -65,7 +65,7 @@ class modFckeditor extends DolibarrModules
 		// Dependencies
 		$this->disabled = (in_array(constant('JS_CKEDITOR'),array('disabled','disabled/'))?1:0);	// A condition to disable module (used for native debian packages)
 		$this->depends = array();
-		$this->requiredby = array();
+		$this->requiredby = array('modWebsites');
 
 		// Constants
 		$this->const = array();
diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php
index b775f3dcb159df0f745f0047136c530147b4c880..a36abbf0b0f884de2079147e2f047f06bf636eb7 100644
--- a/htdocs/core/modules/modProduct.class.php
+++ b/htdocs/core/modules/modProduct.class.php
@@ -164,6 +164,7 @@ class modProduct extends DolibarrModules
 		if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product'));
 		if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product','pf.ref_fourn'=>'product','pf.unitprice'=>'product'));
 		if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation'));
+                if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('group_concat(cat.label)'=>'Categories'));
 		$keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra';
 		include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
 		$this->export_sql_start[$r]='SELECT DISTINCT ';
diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php
index f2ce7ebf0da0a5655f736d85a321c46f36cd691c..baf680f0352ee7ea9e9e173ea189cf7716a9705a 100644
--- a/htdocs/core/modules/modSociete.class.php
+++ b/htdocs/core/modules/modSociete.class.php
@@ -260,6 +260,7 @@ class modSociete extends DolibarrModules
 		$this->export_fields_array[$r]+=array('u.login'=>'SaleRepresentativeLogin','u.firstname'=>'SaleRepresentativeFirstname', 'u.lastname'=>'SaleRepresentativeLastname');
 		//$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>"Text",'s.status'=>"Text",'s.client'=>"Boolean",'s.fournisseur'=>"Boolean",'s.datec'=>"Date",'s.tms'=>"Date",'s.code_client'=>"Text",'s.code_fournisseur'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'c.label'=>"List:c_country:label:label",'c.code'=>"Text",'s.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text",'s.default_lang'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text",'s.idprof4'=>"Text",'s.idprof5'=>"Text",'s.idprof6'=>"Text",'s.tva_intra'=>"Text",'s.capital'=>"Numeric",'s.note'=>"Text",'t.libelle'=>"Text",'ce.code'=>"List:c_effectif:libelle:code","cfj.libelle"=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code','s.fk_stcomm'=>'List:c_stcomm:libelle:code','d.nom'=>'List:c_departements:nom:rowid');
 		$this->export_TypeFields_array[$r]=array('s.nom'=>"Text",'s.status'=>"Numeric",'s.client'=>"Numeric",'s.fournisseur'=>"Boolean",'s.datec'=>"Date",'s.tms'=>"Date",'s.code_client'=>"Text",'s.code_fournisseur'=>"Text",'s.code_compta'=>"Text",'s.code_compta_fournisseur'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'c.label'=>"List:c_country:label:label",'c.code'=>"Text",'s.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text",'s.default_lang'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text",'s.idprof4'=>"Text",'s.idprof5'=>"Text",'s.idprof6'=>"Text",'s.tva_intra'=>"Text",'s.capital'=>"Numeric",'s.note_private'=>"Text",'s.note_public'=>"Text",'t.libelle'=>"Text",'ce.code'=>"List:c_effectif:libelle:code","cfj.libelle"=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code','st.code'=>'List:c_stcomm:libelle:code','d.nom'=>'Text','u.login'=>'Text','u.firstname'=>'Text','u.lastname'=>'Text');
+
 		$this->export_entities_array[$r]=array('u.login'=>'user','u.firstname'=>'user','u.lastname'=>'user');	// We define here only fields that use another picto
 		$this->export_examplevalues_array[$r]=array('s.client'=>'0 (no customer no prospect)/1 (customer)/2 (prospect)/3 (customer and prospect)','s.fournisseur'=>'0 (not a supplier) or 1 (supplier)');
 		$this->export_sql_start[$r]='SELECT DISTINCT ';
diff --git a/htdocs/core/modules/modWebsites.class.php b/htdocs/core/modules/modWebsites.class.php
index e3b500b0e0d25cddeaaff1681f2a0e71b80559a7..30795c6c0fabb97e27ff7015575b8b4717455dbb 100644
--- a/htdocs/core/modules/modWebsites.class.php
+++ b/htdocs/core/modules/modWebsites.class.php
@@ -58,8 +58,8 @@ class modWebsites extends DolibarrModules
         // Name of image file used for this module.
         $this->picto='globe';
 
-        // Data directories to create when module is enabled
-        $this->dirs = array();
+		// Data directories to create when module is enabled
+		$this->dirs = array("/websites/temp");
 
         // Config pages
         //-------------
@@ -68,7 +68,7 @@ class modWebsites extends DolibarrModules
         // Dependancies
         //-------------
 		$this->hidden = ! empty($conf->global->WEBSITE_MODULE_DISABLED);	// A condition to disable module
-		$this->depends = array();		// List of modules id that must be enabled if this module is enabled
+		$this->depends = array('modFckeditor');		// List of modules id that must be enabled if this module is enabled
         $this->requiredby = array();	// List of modules id to disable if this one is disabled
 		$this->conflictwith = array();	// List of modules id this module is in conflict with
         $this->langfiles = array("websites");
diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php
index 6d39cfc836bf3b2185dc2b63ae1dce8a39671417..1f0756a666cdbf77b7b2ea4a98a391fbf3a68b96 100644
--- a/htdocs/core/tpl/objectline_edit.tpl.php
+++ b/htdocs/core/tpl/objectline_edit.tpl.php
@@ -255,12 +255,15 @@ $coldisplay=-1; // We remove first td
 
 <script type="text/javascript">
 
-<?php
-if (! empty($conf->margin->enabled))
+jQuery(document).ready(function()
 {
-?>
-	jQuery(document).ready(function()
-	{
+	jQuery("#price_ht").keyup(function() { jQuery("#price_ttc").val(''); });
+	jQuery("#price_ttc").keyup(function() { jQuery("#price_ht").val(''); });
+
+    <?php
+    if (! empty($conf->margin->enabled))
+    {
+    ?>
 		/* Add rule to clear margin when we change some data, so when we change sell or buy price, margin will be recalculated after submitting form */
 		jQuery("#tva_tx").click(function() {						/* somtimes field is a text, sometimes a combo */
 			jQuery("input[name='np_marginRate']:first").val('');
@@ -323,86 +326,10 @@ if (! empty($conf->margin->enabled))
 			$('#buying_price').show();
 		}
 		}, 'json');
-
-		/* Add rules to reset price_ht from margin info */
-		<?php
-		if (! empty($conf->global->DISPLAY_MARGIN_RATES) && !empty($conf->global->MARGIN_RESET_HT_FROM_MARGIN_FIELD))
-		{
-		?>
-			/* Disabled. We must be able to click on button 'cancel'. Check must be done only on button 'save'.
-			$("input[name='np_marginRate']:first").blur(function(e) {
-				return checkEditLine(e, "np_marginRate");
-			});*/
-		<?php
-		}
-		if (! empty($conf->global->DISPLAY_MARK_RATES) && !empty($conf->global->MARGIN_RESET_HT_FROM_MARGIN_FIELD))
-		{
-		?>
-			/* Disabled. We must be able to click on button 'cancel'. Check must be done only on button 'save'.
-			$("input[name='np_markRate']:first").blur(function(e) {
-				return checkEditLine(e, "np_markRate");
-			});*/
-		<?php
-		}
-	?>
-	});
-
-
-	/* If margin rate field empty, do nothing. */
-	/* Force content of price_ht to 0 or if a discount is set, recalculate it from margin rate */
-	/* TODO This function seems no more used */
-	function checkEditLine(e, npRate)
-	{
-		var buying_price = $("input[name='buying_price']:first");
-		var remise = $("input[name='remise_percent']:first");
-
-		var rate = $("input[name='"+npRate+"']:first");
-		if (rate.val() == '' || (typeof rate.val()) == 'undefined' ) return true;
-
-		if (! $.isNumeric(rate.val().replace(' ','').replace(',','.')))
-		{
-			alert('<?php echo $langs->transnoentitiesnoconv("rateMustBeNumeric"); ?>');
-			e.stopPropagation();
-			setTimeout(function () { rate.focus() }, 50);
-			return false;
-		}
-		if (npRate == "np_markRate" && rate.val() > 100)
-		{
-			alert('<?php echo $langs->transnoentitiesnoconv("markRateShouldBeLesserThan100"); ?>');
-			e.stopPropagation();
-			setTimeout(function () { rate.focus() }, 50);
-			return false;
-		}
-
-		var price = 0;
-		remisejs=price2numjs(remise.val());
-
-		if (remisejs != 100)
-		{
-			bpjs=price2numjs(buying_price.val());
-			ratejs=price2numjs(rate.val());
-			/* console.log(npRate+" - "+bpjs+" - "+ratejs); */
-
-			if (npRate == "np_marginRate")
-				price = ((bpjs * (1 + (ratejs / 100))) / (1 - remisejs / 100));
-			else if (npRate == "np_markRate")
-			{
-				if (ratejs != 100)	// If markRate is 100, it means buying price is 0, so it is not possible to retreive price from it and markRate. We keep it unchange
-				{
-					price = ((bpjs / (1 - (ratejs / 100))) / (1 - remisejs / 100));
-				}
-				else price=$("input[name='price_ht']:first").val();
-			}
-		}
-		/* console.log("new price ht = "+price); */
-		$("input[name='price_ht']:first").val(price);	// TODO Must use a function like php price to have here a formated value
-
-		return true;
-	}
-
-<?php
-}
-?>
+    <?php
+    }
+    ?>
+});
 
 </script>
 <!-- END PHP TEMPLATE objectline_edit.tpl.php -->
diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php
index 967d9f8197010cb5acf085599bb45bb0c5656269..559cae91464a0580f67c42069205bc9c4baf6b4a 100644
--- a/htdocs/core/tpl/objectline_view.tpl.php
+++ b/htdocs/core/tpl/objectline_view.tpl.php
@@ -31,7 +31,7 @@
  * $inputalsopricewithtax (0 by default, 1 to also show column with unit price including tax)
  * $usemargins (0 to disable all margins columns, 1 to show according to margin setup)
  * $object_rights->creer initialized from = $object->getRights()
- * $disableedit, $disablemove
+ * $disableedit, $disablemove, $disableremove
  * 
  * $type, $text, $description, $line
  */
@@ -46,7 +46,6 @@ if (empty($forceall)) $forceall=0;
 if (empty($senderissupplier)) $senderissupplier=0;
 if (empty($inputalsopricewithtax)) $inputalsopricewithtax=0;
 if (empty($usemargins)) $usemargins=0;
-
 ?>
 <?php $coldisplay=0; ?>
 <!-- BEGIN PHP TEMPLATE objectline_view.tpl.php -->
@@ -216,7 +215,7 @@ if (empty($usemargins)) $usemargins=0;
 
 	<td class="linecoldelete" align="center"><?php $coldisplay++; ?>
 		<?php
-		if ($this->situation_counter == 1 || !$this->situation_cycle_ref) {
+		if (($this->situation_counter == 1 || !$this->situation_cycle_ref) && empty($disableremove)) {
 			print '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $this->id . '&amp;action=ask_deleteline&amp;lineid=' . $line->id . '">';
 			print img_delete();
 			print '</a>';
diff --git a/htdocs/core/tpl/resource_add.tpl.php b/htdocs/core/tpl/resource_add.tpl.php
index e2add5fb26663a98ee2d0bca5531d59445d04a71..482dad50085ddcafe81688f65950a10d5e10de09 100644
--- a/htdocs/core/tpl/resource_add.tpl.php
+++ b/htdocs/core/tpl/resource_add.tpl.php
@@ -13,7 +13,7 @@ $out .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
 $out .= '<input type="hidden" name="action" value="add_element_resource">';
 $out .= '<input type="hidden" name="element" value="'.$element.'">';
 $out .= '<input type="hidden" name="element_id" value="'.$element_id.'">';
-$out .= '<input type="hidden" name="resource_type" value="'.(empty($resource_type) ? 'resource' : $resource_type).'">';
+$out .= '<input type="hidden" name="resource_type" value="'.(empty($resource_type) ? 'dolresource' : $resource_type).'">';
 
 
 // Place
diff --git a/htdocs/custom/README.md b/htdocs/custom/README.md
index 5f15148f685ac123b259d847dce2ef863e829717..82f92dfbeffd2d4a7352b913cb25dddb9660f0ae 100644
--- a/htdocs/custom/README.md
+++ b/htdocs/custom/README.md
@@ -14,11 +14,9 @@ Then create the symbolic link
 ln -fs ~/git/newmodule/htdocs /path_to_dolibarr/htdocs/custom/newmodule 
 
 WARNING !!!
-You must also enable the custom directory into dolibarr conf/conf.php file by adding the following 
+Check also that the custom directory into dolibarr conf/conf.php file by adding the following 
 two lines, so dolibarr will also scan this directories to find external external modules:
 
 $dolibarr_main_url_root_alt='/custom';
 $dolibarr_main_document_root_alt='/path_to_dolibarr/htdocs/custom/';
 
-(This is not enabled by default because enabling external module may slow down application)
-
diff --git a/htdocs/document.php b/htdocs/document.php
index 1b3d494d1a126b36c70d356965cecf6838e77ae8..52b1584e7af31b279a381feb34964591e155d5c9 100644
--- a/htdocs/document.php
+++ b/htdocs/document.php
@@ -65,6 +65,7 @@ $entity=GETPOST('entity')?GETPOST('entity','int'):$conf->entity;
 
 // Security check
 if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart');
+if ($modulepart == 'fckeditor') $modulepart='medias';   // For backward compatibility
 
 $socid=0;
 if ($user->societe_id > 0) $socid = $user->societe_id;
@@ -97,7 +98,7 @@ if (preg_match('/\.(html|htm)$/i',$original_file)) $attachment = false;
 if (isset($_GET["attachment"])) $attachment = GETPOST("attachment")?true:false;
 if (! empty($conf->global->MAIN_DISABLE_FORCE_SAVEAS)) $attachment=false;
 
-// Suppression de la chaine de caractere ../ dans $original_file
+// Security: Delete string ../ into $original_file
 $original_file = str_replace("../","/", $original_file);
 
 // Find the subdirectory name as the reference
@@ -169,7 +170,6 @@ if (! file_exists($original_file_osencoded))
 }
 
 // Permissions are ok and file found, so we return it
-
 header('Content-Description: File Transfer');
 if ($encoding)   header('Content-Encoding: '.$encoding);
 if ($type)       header('Content-Type: '.$type.(preg_match('/text/',$type)?'; charset="'.$conf->file->character_set_client:''));
@@ -183,7 +183,7 @@ header('Pragma: public');
 
 //ob_clean();
 //flush();
-
+    
 readfile($original_file_osencoded);
 
 if (is_object($db)) $db->close();
diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php
index 4547a94566afb5a64d6a7eaf106c4bd2dd845af7..c52c72ff5097131f6995a180a7bceefde7933fda 100644
--- a/htdocs/expedition/card.php
+++ b/htdocs/expedition/card.php
@@ -533,6 +533,12 @@ if (empty($reshook))
 	    $object->set_billed();
 	}
 
+	elseif ($action == 'classifyclosed')
+	{
+	    $object->fetch($id);
+	    $object->setClosed();
+	}
+
 	include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
 
 	// Actions to send emails
@@ -885,6 +891,7 @@ if ($action == 'create')
 					//ship from preselected location
 					$stock = + $product->stock_warehouse[$warehouse_id]->real; // Convert to number
 					$deliverableQty=min($quantityToBeDelivered, $stock);
+					if ($deliverableQty < 0) $deliverableQty = 0;
 					if (empty($conf->productbatch->enabled) || ! ($product->hasbatch() && is_object($product->stock_warehouse[$warehouse_id])))
 					{
 						// Quantity to send
@@ -1774,16 +1781,19 @@ else if ($id || $ref)
 		{
 			print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=create_delivery">'.$langs->trans("CreateDeliveryOrder").'</a>';
 		}
-
 		// Close
 		if (! empty($conf->facture->enabled) && $object->statut > 0)
 		{
 			if ($user->rights->expedition->creer && $object->statut > 0 && ! $object->billed)
 			{
-				$label="Close";
+				$label="Close"; $paramaction='classifyclosed';       // = Transferred/Received
 				// Label here should be "Close" or "ClassifyBilled" if we decided to make bill on shipments instead of orders
-				if (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) $label="ClassifyBilled";
-				print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=classifybilled">'.$langs->trans($label).'</a>';
+				if (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))  // TODO Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close.
+				{
+				    $label="ClassifyBilled";
+				    $paramaction='classifybilled';
+				}
+				print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action='.$paramaction.'">'.$langs->trans($label).'</a>';
 			}
 		}
 
diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php
index a0ba1567c2442f4f9e593bbe51a970b464e05971..18b3d4d7ebc265cc9dc954d4fd9cf43849f67349 100644
--- a/htdocs/expedition/class/expedition.class.php
+++ b/htdocs/expedition/class/expedition.class.php
@@ -664,7 +664,7 @@ class Expedition extends CommonObject
 			$langs->load("agenda");
 
 			// Loop on each product line to add a stock movement
-			// TODO possibilite d'expedier a partir d'une propale ou autre origine
+			// TODO in future, shipment lines may not be linked to order line
 			$sql = "SELECT cd.fk_product, cd.subprice,";
 			$sql.= " ed.rowid, ed.qty, ed.fk_entrepot,";
 			$sql.= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock";
@@ -738,7 +738,7 @@ class Expedition extends CommonObject
 		if (! $error && ! $notrigger)
 		{
             // Call trigger
-            $result=$this->call_trigger('SHIPPING_VALIDATE',$user);
+            $result=$this->call_trigger('SHIPPING_VALIDATE',$user);     // TODO Add option in workflow module on this trigger to close order if sum of shipment = product to ship of order
             if ($result < 0) { $error++; }
             // End call triggers
 		}
@@ -878,16 +878,14 @@ class Expedition extends CommonObject
 				$product=new Product($this->db);
 				$result=$product->fetch($fk_product);
 
-				$product_type=$product->type;
 				if ($entrepot_id > 0) {
-                    $product->load_stock();
-				    $product_stock = $product->stock_warehouse[$entrepot_id]->real;
-				}
-				else 
-				{
-				    $product_stock = $product->stock_reel;
+					$product->load_stock();
+					$product_stock = $product->stock_warehouse[$entrepot_id]->real;
 				}
-				
+				else
+					$product_stock = $product->stock_reel;
+
+				$product_type=$product->type;
 				if ($product_type == 0 && $product_stock < $qty)
 				{
 					$this->error=$langs->trans('ErrorStockIsNotEnough');
@@ -1795,11 +1793,11 @@ class Expedition extends CommonObject
 	}
 
 	/**
-	 *	Classify the shipping as invoiced
+	 *	Classify the shipping as closed
 	 *
 	 *	@return     int     <0 if ko, >0 if ok
 	 */
-	function set_billed()
+	function setClosed()
 	{
 		global $conf;
 
@@ -1809,7 +1807,32 @@ class Expedition extends CommonObject
 		$resql=$this->db->query($sql);
 		if ($resql)
 		{
-			//TODO: Add option/checkbox to set order billed if 100% of order is shipped
+			// TODO: Add option/checkbox to set order billed if 100% of order is shipped
+			$this->statut=2;
+			return 1;
+		}
+		else
+		{
+			dol_print_error($this->db);
+			return -1;
+		}
+	}
+
+	/**
+	 *	Classify the shipping as invoiced (used when WORKFLOW_BILL_ON_SHIPMENT is on)
+	 *
+	 *	@return     int     <0 if ko, >0 if ok
+	 */
+	function set_billed()
+	{
+		global $conf;
+
+		$sql = 'UPDATE '.MAIN_DB_PREFIX.'expedition SET fk_statut=2, billed=1';    // TODO Update only billed
+		$sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > 0';
+
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
 			$this->statut=2;
 			$this->billed=1;
 			return 1;
diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php
index be9d8ab49bdd39504b30548d2a750dbe393fb142..a946649592a85b613cf3a719b51bc2f86223deab 100644
--- a/htdocs/expensereport/card.php
+++ b/htdocs/expensereport/card.php
@@ -1625,7 +1625,7 @@ else
 				$sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
 				$sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
 				$sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde';
-				$sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
+				$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
 				$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as pjt ON fde.fk_projet=pjt.rowid';
 				$sql.= ' WHERE fde.fk_expensereport = '.$object->id;
 
@@ -1691,7 +1691,7 @@ else
     								}
     								print '</td>';
 								}
-								print '<td style="text-align:center;">'.$langs->trans("TF_".strtoupper($objp->type_fees_libelle)).'</td>';
+								print '<td style="text-align:center;">'.$langs->trans("TF_".strtoupper(empty($objp->type_fees_libelle)?'OTHER':$objp->type_fees_libelle)).'</td>';
 								print '<td style="text-align:left;">'.$objp->comments.'</td>';
 								print '<td style="text-align:right;">'.vatrate($objp->vatrate,true).'</td>';
 								print '<td style="text-align:right;">'.price($objp->value_unit).'</td>';
diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php
index 2a281bda595f3a1cfd2ae72794a481439c6c15a7..07c3e598818827715b2c7c9966323c93f00909c4 100644
--- a/htdocs/expensereport/class/expensereport.class.php
+++ b/htdocs/expensereport/class/expensereport.class.php
@@ -746,7 +746,7 @@ class ExpenseReport extends CommonObject
         $sql.= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees,';
         $sql.= ' p.ref as ref_projet, p.title as title_projet';
         $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as de';
-        $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
+        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
         $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as p ON de.fk_projet = p.rowid';
         $sql.= ' WHERE de.'.$this->fk_element.' = '.$this->id;
 
@@ -776,7 +776,7 @@ class ExpenseReport extends CommonObject
                 $deplig->total_tva      = $objp->total_tva;
                 $deplig->total_ttc      = $objp->total_ttc;
 
-                $deplig->type_fees_code     = $objp->code_type_fees;
+                $deplig->type_fees_code     = empty($objp->code_type_fees)?'TF_OTHER':$objp->code_type_fees;
                 $deplig->type_fees_libelle  = $objp->libelle_type_fees;
 				$deplig->tva_tx			    = $objp->tva_tx;
                 $deplig->vatrate            = $objp->tva_tx;
@@ -850,12 +850,9 @@ class ExpenseReport extends CommonObject
     {
         global $conf,$langs;
 
+        $this->oldref = $this->ref;
         $expld_car = (empty($conf->global->NDF_EXPLODE_CHAR))?"-":$conf->global->NDF_EXPLODE_CHAR;
 
-        // Sélection du numéro de ref suivant
-        $ref_next = $this->getNextNumRef();
-        $ref_number_int = ($this->ref+1)-1;
-
         // Sélection de la date de début de la NDF
         $sql = 'SELECT date_debut';
         $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element;
@@ -864,21 +861,59 @@ class ExpenseReport extends CommonObject
         $objp = $this->db->fetch_object($result);
         $this->date_debut = $this->db->jdate($objp->date_debut);
 
-        // Création du ref_number suivant
-        if($ref_next)
+        $update_number_int = false;
+
+        // Create next ref if ref is PROVxx
+        // Rename directory if dir was a temporary ref
+        if (preg_match('/^[\(]?PROV/i', $this->ref))
         {
-            $prefix="ER";
-            if (! empty($conf->global->EXPENSE_REPORT_PREFIX)) $prefix=$conf->global->EXPENSE_REPORT_PREFIX;
-            $this->ref = strtoupper($fuser->login).$expld_car.$prefix.$this->ref.$expld_car.dol_print_date($this->date_debut,'%y%m%d');
+            // Sélection du numéro de ref suivant
+            $ref_next = $this->getNextNumRef();
+            $ref_number_int = ($this->ref+1)-1;
+            $update_number_int = true;
+            // Création du ref_number suivant
+            if($ref_next)
+            {
+                $prefix="ER";
+                if (! empty($conf->global->EXPENSE_REPORT_PREFIX)) $prefix=$conf->global->EXPENSE_REPORT_PREFIX;
+                $this->ref = strtoupper($fuser->login).$expld_car.$prefix.$this->ref.$expld_car.dol_print_date($this->date_debut,'%y%m%d');
+            }
+            require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+            // We rename directory in order to avoid losing the attachments
+            $oldref = dol_sanitizeFileName($this->oldref);
+            $newref = dol_sanitizeFileName($this->ref);
+            $dirsource = $conf->expensereport->dir_output.'/'.$oldref;
+            $dirdest = $conf->expensereport->dir_output.'/'.$newref;
+            if (file_exists($dirsource))
+            {
+                dol_syslog(get_class($this)."::valid() rename dir ".$dirsource." into ".$dirdest);
+
+                if (@rename($dirsource, $dirdest))
+                {
+                    dol_syslog("Rename ok");
+                    // Rename docs starting with $oldref with $newref
+                    $listoffiles=dol_dir_list($conf->expensereport->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/'));
+                    foreach($listoffiles as $fileentry)
+                    {
+                        $dirsource=$fileentry['name'];
+                        $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource);
+                        $dirsource=$fileentry['path'].'/'.$dirsource;
+                        $dirdest=$fileentry['path'].'/'.$dirdest;
+                        @rename($dirsource, $dirdest);
+                    }
+                }
+            }
         }
 
         if ($this->fk_statut != 2)
         {
         	$now = dol_now();
-        	
+
             $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
-            $sql.= " SET ref = '".$this->ref."', fk_statut = 2, fk_user_valid = ".$fuser->id.", date_valid='".$this->db->idate($now)."',";
-            $sql.= " ref_number_int = ".$ref_number_int;
+            $sql.= " SET ref = '".$this->ref."', fk_statut = 2, fk_user_valid = ".$fuser->id.", date_valid='".$this->db->idate($now)."'";
+            if ($update_number_int) {
+                $sql.= ", ref_number_int = ".$ref_number_int;
+            }
             $sql.= ' WHERE rowid = '.$this->id;
 
             $resql=$this->db->query($sql);
@@ -1265,7 +1300,9 @@ class ExpenseReport extends CommonObject
             $sql.= " FROM ".MAIN_DB_PREFIX."projet as p";
             $sql.= " WHERE p.rowid = ".$projet_id;
             $result = $this->db->query($sql);
-            $objp_projet = $this->db->fetch_object($result);
+            if ($result) {
+            	$objp_projet = $this->db->fetch_object($result);
+            }
             $ligne->projet_ref          = $objp_projet->ref_projet;
             $ligne->projet_title        = $objp_projet->title_projet;
 
diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php
index 7912b4f189fcf867d8895883e556fcecc9886dc2..6632f05055029061811de0244295e523d49f75b3 100644
--- a/htdocs/exports/class/export.class.php
+++ b/htdocs/exports/class/export.class.php
@@ -225,7 +225,7 @@ class Export
 			else $i++;
 
 			if (strpos($key, ' as ')===false) {
-				$newfield=$key.' as '.str_replace(array('.', '-'),'_',$key);
+				$newfield=$key.' as '.str_replace(array('.', '-','(',')'),'_',$key);
 			} else {
 				$newfield=$key;
 			}
@@ -587,14 +587,14 @@ class Export
 							if ($this->array_export_special[$indice][$key]=='NULLIFNEG')
 							{
 								//$alias=$this->array_export_alias[$indice][$key];
-								$alias=str_replace(array('.', '-'),'_',$key);
+								$alias=str_replace(array('.', '-','(',')'),'_',$key);
 								if ($objp->$alias < 0) $objp->$alias='';
 							}
 							// Operation ZEROIFNEG
 							if ($this->array_export_special[$indice][$key]=='ZEROIFNEG')
 							{
 								//$alias=$this->array_export_alias[$indice][$key];
-								$alias=str_replace(array('.', '-'),'_',$key);
+								$alias=str_replace(array('.', '-','(',')'),'_',$key);
 								if ($objp->$alias < 0) $objp->$alias='0';
 							}
 						}
diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php
index d78a2564e7c09a231bae6e97922e70e45425477c..50ca1e09a91b4c5ee8f2720c94bcc9a938bec37f 100644
--- a/htdocs/exports/export.php
+++ b/htdocs/exports/export.php
@@ -35,6 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 $langs->load("exports");
 $langs->load("users");
 $langs->load("companies");
+$langs->load("projects");
 
 // Everybody should be able to go on this page
 //if (! $user->admin)
diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php
index 69f01613f50bae11b302a45d2394438780e25938..66fb1031d6e4df5bf6bfecde9e96b2fc71c00edb 100644
--- a/htdocs/fichinter/class/fichinter.class.php
+++ b/htdocs/fichinter/class/fichinter.class.php
@@ -89,6 +89,46 @@ class Fichinter extends CommonObject
 		$this->statuts_logo[3]='statut4';
 	}
 
+	/**
+	 *  Load indicators into this->nb for board
+	 *
+	 *  @return     int         <0 if KO, >0 if OK
+	 */
+	function load_state_board()
+	{
+		global $user;
+
+		$this->nb=array();
+		$clause = "WHERE";
+
+		$sql = "SELECT count(fi.rowid) as nb";
+		$sql.= " FROM ".MAIN_DB_PREFIX."fichinter as fi";
+		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON fi.fk_soc = s.rowid";
+		if (!$user->rights->societe->client->voir && !$user->societe_id)
+		{
+			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
+			$sql.= " WHERE sc.fk_user = " .$user->id;
+			$clause = "AND";
+		}
+		$sql.= " ".$clause." fi.entity IN (".getEntity($this->element, 1).")";
+
+		$resql=$this->db->query($sql);
+		if ($resql)
+		{
+			while ($obj=$this->db->fetch_object($resql))
+			{
+				$this->nb["fichinters"]=$obj->nb;
+			}
+			$this->db->free($resql);
+			return 1;
+		}
+		else
+		{
+			dol_print_error($this->db);
+			$this->error=$this->db->error();
+			return -1;
+		}
+	}
 
 	/**
 	 *	Create an intervention into data base
diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
index e209dd741d63392fe9d5303cfb4ff961e625e089..30296bc2e2251f76118e496fd31648880cccbcd1 100644
--- a/htdocs/fourn/class/fournisseur.facture.class.php
+++ b/htdocs/fourn/class/fournisseur.facture.class.php
@@ -7,7 +7,7 @@
  * Copyright (C) 2010-2015	Juanjo Menent			<jmenent@2byte.es>
  * Copyright (C) 2013		Philippe Grand			<philippe.grand@atoo-net.com>
  * Copyright (C) 2013       Florian Henry		  	<florian.henry@open-concept.pro>
- * Copyright (C) 2014-2015  Marcos García           <marcosgdf@gmail.com>
+ * Copyright (C) 2014-2016  Marcos García           <marcosgdf@gmail.com>
  * Copyright (C) 2015       Bahfir Abbes            <bafbes@gmail.com>
  * Copyright (C) 2015       Ferran Marcet           <fmarcet@2byte.es>
  *
@@ -694,7 +694,16 @@ class FactureFournisseur extends CommonInvoice
 
         dol_syslog(get_class($this)."::update", LOG_DEBUG);
         $resql = $this->db->query($sql);
-        if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
+
+        if (!$resql) {
+            $error++;
+
+            if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
+                $this->errors[] = $langs->trans('ErrorRefAlreadyExists');
+            } else {
+                $this->errors[] = "Error ".$this->db->lasterror();
+            }
+        }
 
         if (! $error)
         {
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index c1346c357d55172c2198629d2b05f3de54a31e58..eb6392eba06cd3d6979ca3f72b32d796b37dcb15 100644
--- a/htdocs/fourn/facture/card.php
+++ b/htdocs/fourn/facture/card.php
@@ -247,8 +247,11 @@ if (empty($reshook))
 	// Set supplier ref
 	if ($action == 'setref_supplier' && $user->rights->fournisseur->commande->creer)
 	{
-	    $result=$object->setValueFrom('ref_supplier',GETPOST('ref_supplier','alpha'));
-	    if ($result < 0) dol_print_error($db, $object->error);
+		$object->ref_supplier = GETPOST('ref_supplier', 'alpha');
+		
+		if ($object->update($user) < 0) {
+			setEventMessages($object->error, $object->errors, 'errors');
+		}
 	}
 
 	// payments conditions
diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php
index dafe95e419dd65575abf3f79f93f2ca8a7cc7437..428109622750e7bf6aa40f681dae50e4fb586887 100644
--- a/htdocs/fourn/facture/list.php
+++ b/htdocs/fourn/facture/list.php
@@ -225,10 +225,19 @@ if ($search_amount_all_tax != '')
 	$sql .= natural_search('fac.total_ttc', $search_amount_all_tax, 1);
 }
 
-if ($search_status != '')
+if ($search_status != '' && $search_status>=0)
 {
 	$sql.= " AND fac.fk_statut = ".$search_status;
 }
+if ($filter && $filter != -1)
+{
+	$aFilter = explode(',', $filter);
+	foreach ($aFilter as $fil)
+	{
+		$filt = explode(':', $fil);
+		$sql .= ' AND ' . trim($filt[0]) . ' = ' . trim($filt[1]);
+	}
+}
 
 $nbtotalofrecords = 0;
 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
@@ -265,7 +274,7 @@ if ($resql)
 	if ($search_amount_no_tax)	$param.='&search_amount_no_tax='.urlencode($search_amount_no_tax);
 	if ($search_amount_all_tax)	$param.='&search_amount_all_tax='.urlencode($search_amount_all_tax);
 	if ($filter && $filter != -1) $param.='&filtre='.urlencode($filter);
-	if ($optioncss != '') $param.='&optioncss='.$optioncss;
+	if ($optioncss != '')       $param.='&optioncss='.$optioncss;
 	if ($search_status >= 0)  	$param.="&search_status=".$search_status;
 
 	print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
diff --git a/htdocs/hrm/establishment/card.php b/htdocs/hrm/establishment/card.php
index fb6f41f4f3939aa76f4b18776168951660ccb69c..11179d218f869d5784828b01e4bd73e08c543dd3 100644
--- a/htdocs/hrm/establishment/card.php
+++ b/htdocs/hrm/establishment/card.php
@@ -136,7 +136,7 @@ else if ($action == 'update')
 			$object->country_id     = $_POST["country_id"];
 			$object->fk_user_mod	= $user->id;
 
-			$result = $object->update();
+			$result = $object->update($user);
 
             if ($result > 0)
             {
diff --git a/htdocs/index.php b/htdocs/index.php
index 332e2ea448300f023cdd683600b8c2f977df5510..5e9492d9b5074579ba9b53fd054432b198fd1407 100644
--- a/htdocs/index.php
+++ b/htdocs/index.php
@@ -162,6 +162,7 @@ if (empty($user->societe_id))
 	    ! empty($conf->societe->enabled) && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS),
 	    ! empty($conf->societe->enabled) && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS),
 	    ! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_STATS),
+	    ! empty($conf->societe->enabled) && $user->rights->societe->contact->lire,
 	    ! empty($conf->adherent->enabled) && $user->rights->adherent->lire,
 	    ! empty($conf->product->enabled) && $user->rights->produit->lire,
 	    ! empty($conf->service->enabled) && $user->rights->service->lire,
@@ -169,6 +170,7 @@ if (empty($user->societe_id))
 	    ! empty($conf->commande->enabled) && $user->rights->commande->lire,
 	    ! empty($conf->facture->enabled) && $user->rights->facture->lire,
 	    ! empty($conf->contrat->enabled) && $user->rights->contrat->activer,
+	    ! empty($conf->ficheinter->enabled) && $user->rights->ficheinter->lire,
 		! empty($conf->supplier_order->enabled) && $user->rights->fournisseur->commande->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_ORDERS_STATS),
 		! empty($conf->supplier_invoice->enabled) && $user->rights->fournisseur->facture->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_INVOICES_STATS),
 		! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_PROPOSAL_STATS),
@@ -181,6 +183,7 @@ if (empty($user->societe_id))
 	        DOL_DOCUMENT_ROOT."/societe/class/client.class.php",
 	        DOL_DOCUMENT_ROOT."/societe/class/client.class.php",
     	    DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.class.php",
+    	    DOL_DOCUMENT_ROOT."/contact/class/contact.class.php",
     	    DOL_DOCUMENT_ROOT."/adherents/class/adherent.class.php",
     	    DOL_DOCUMENT_ROOT."/product/class/product.class.php",
     	    DOL_DOCUMENT_ROOT."/product/class/service.class.php",
@@ -188,6 +191,7 @@ if (empty($user->societe_id))
     	    DOL_DOCUMENT_ROOT."/commande/class/commande.class.php",
     	    DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php",
     	    DOL_DOCUMENT_ROOT."/contrat/class/contrat.class.php",
+    	    DOL_DOCUMENT_ROOT."/fichinter/class/fichinter.class.php",
     	    DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.commande.class.php",
     	    DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.facture.class.php",
     	    DOL_DOCUMENT_ROOT."/supplier_proposal/class/supplier_proposal.class.php",
@@ -199,6 +203,7 @@ if (empty($user->societe_id))
 	                   'Client',
 	                   'Client',
 	                   'Fournisseur',
+	                   'Contact',
 	                   'Adherent',
 	                   'Product',
 	                   'Service',
@@ -206,6 +211,7 @@ if (empty($user->societe_id))
 	                   'Commande',
 	                   'Facture',
 	                   'Contrat',
+	                   'Fichinter',
 	                   'CommandeFournisseur',
 	                   'FactureFournisseur',
             	       'SupplierProposal',
@@ -217,6 +223,7 @@ if (empty($user->societe_id))
 	                'customers',
 	                'prospects',
 	                'suppliers',
+	                'contacts',
 	                'members',
 	                'products',
 	                'services',
@@ -224,6 +231,7 @@ if (empty($user->societe_id))
 	                'orders',
 	                'invoices',
 	                'Contracts',
+	                'fichinters',
 	                'supplier_orders',
 	                'supplier_invoices',
 	                'askprice',
@@ -235,6 +243,7 @@ if (empty($user->societe_id))
 	                 'company',
 	                 'company',
 	                 'company',
+	                 'contact',
 	                 'user',
 	                 'product',
 	                 'service',
@@ -243,6 +252,7 @@ if (empty($user->societe_id))
 	                 'bill',
 	                 'order',
 	                 'order',
+	                 'order',
 	                 'bill',
 	                 'propal',
 					 'trip',
@@ -253,6 +263,7 @@ if (empty($user->societe_id))
 	                  "ThirdPartyCustomersStats",
 	                  "ThirdPartyProspectsStats",
 	                  "Suppliers",
+	                  "Contacts",
 	                  "Members",
 	                  "Products",
 	                  "Services",
@@ -260,6 +271,7 @@ if (empty($user->societe_id))
 	                  "CustomersOrders",
 	                  "BillsCustomers",
 	                  "Contracts",
+	                  "Interventions",
 	                  "SuppliersOrders",
                       "SuppliersInvoices",
 	                  "SupplierProposalShort",
@@ -272,6 +284,7 @@ if (empty($user->societe_id))
     	    DOL_URL_ROOT.'/societe/list.php?type=c',
     	    DOL_URL_ROOT.'/societe/list.php?type=p',
     	    DOL_URL_ROOT.'/societe/list.php?type=f',
+    	    DOL_URL_ROOT.'/contact/list.php',
     	    DOL_URL_ROOT.'/adherents/list.php?statut=1&mainmenu=members',
     	    DOL_URL_ROOT.'/product/list.php?type=0&mainmenu=products',
     	    DOL_URL_ROOT.'/product/list.php?type=1&mainmenu=products',
@@ -279,6 +292,7 @@ if (empty($user->societe_id))
     	    DOL_URL_ROOT.'/commande/list.php?mainmenu=commercial',
     	    DOL_URL_ROOT.'/compta/facture/list.php?mainmenu=accountancy',
     	    DOL_URL_ROOT.'/contrat/list.php',
+    	    DOL_URL_ROOT.'/fichinter/list.php',
     	    DOL_URL_ROOT.'/fourn/commande/list.php',
 	        DOL_URL_ROOT.'/fourn/facture/list.php',
 	        DOL_URL_ROOT.'/supplier_proposal/list.php',
@@ -290,6 +304,7 @@ if (empty($user->societe_id))
 	                    "companies",
 	                    "prospects",
 	                    "suppliers",
+	                    "companies",
 	                    "members",
 	                    "products",
 	                    "produts",
@@ -298,6 +313,7 @@ if (empty($user->societe_id))
             	        "bills",
             	        "supplier_proposal",
 						"contracts",
+						"interventions",
 						"trips",
 	                    "projects"
 	    );
diff --git a/htdocs/install/mysql/data/llx_accounting_category.sql b/htdocs/install/mysql/data/llx_accounting_category.sql
new file mode 100644
index 0000000000000000000000000000000000000000..5769d291563fdebb683878e0effd821cc8d80f1e
--- /dev/null
+++ b/htdocs/install/mysql/data/llx_accounting_category.sql
@@ -0,0 +1,29 @@
+-- Copyright (C) 2016 		Alexandre Spangaro   <aspangaro.dolibarr@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
+-- 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/>.
+--
+--
+
+--
+-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors
+-- de l'install et tous les sigles '--' sont supprimés.
+--
+
+--
+-- Categories compte de résultat Français
+--
+
+INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES (  1,'VTE','Ventes de marchandises', '707xxx', 0, 0, '', '10', 1, 1);
+INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES (  2,'MAR','Coût d\'achats marchandises vendues', '603xxx | 607xxx | 609xxx', 0, 0, '', '20', 1, 1);
+INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES (  3,'MARGE','Marge commerciale', '', 0, 1, '1 + 2', '30', 1, 1);
\ No newline at end of file
diff --git a/htdocs/install/mysql/migration/3.9.0-4.0.0.sql b/htdocs/install/mysql/migration/3.9.0-4.0.0.sql
index 002930c276c29033364f5361d2417b556a074056..a429ef5c7cfdc36eaf816ddd57b9d9b0541917f2 100644
--- a/htdocs/install/mysql/migration/3.9.0-4.0.0.sql
+++ b/htdocs/install/mysql/migration/3.9.0-4.0.0.sql
@@ -36,6 +36,8 @@ ALTER TABLE llx_product_customer_price_log ADD COLUMN localtax1_type varchar(10)
 ALTER TABLE llx_product_customer_price_log ADD COLUMN localtax2_type varchar(10)  NOT NULL DEFAULT '0' after localtax2_tx; 
 
 
+ALTER TABLE llx_expedition ADD COLUMN billed smallint DEFAULT 0;
+
 CREATE TABLE llx_product_lot (
   rowid integer AUTO_INCREMENT PRIMARY KEY,
   tms timestamp,
@@ -64,6 +66,8 @@ ALTER TABLE llx_product ADD COLUMN height_units tinyint      DEFAULT NULL;
 
 ALTER TABLE llx_product ADD COLUMN default_vat_code	varchar(10) after cost_price;
 
+ALTER TABLE llx_product MODIFY COLUMN stock	real;
+
 CREATE TABLE llx_categorie_user 
 (
   fk_categorie 	integer NOT NULL,
@@ -301,19 +305,15 @@ ALTER TABLE llx_contratdet ADD COLUMN multicurrency_total_ht double(24,8) DEFAUL
 ALTER TABLE llx_contratdet ADD COLUMN multicurrency_total_tva double(24,8) DEFAULT 0;
 ALTER TABLE llx_contratdet ADD COLUMN multicurrency_total_ttc double(24,8) DEFAULT 0;
 
-
-
 ALTER TABLE llx_paiement ADD COLUMN multicurrency_amount double(24,8) DEFAULT 0;
 ALTER TABLE llx_paiement_facture ADD COLUMN multicurrency_amount double(24,8) DEFAULT 0;
 ALTER TABLE llx_paiementfourn ADD COLUMN multicurrency_amount double(24,8) DEFAULT 0;
 ALTER TABLE llx_paiementfourn_facturefourn ADD COLUMN multicurrency_amount double(24,8) DEFAULT 0;
 
-ALTER TABLE llx_societe_remise_except ADD COLUMN multicurrency_amount_ht double(24,8) NOT NULL;
+ALTER TABLE llx_societe_remise_except ADD COLUMN multicurrency_amount_ht double(24,8) DEFAULT 0 NOT NULL;
 ALTER TABLE llx_societe_remise_except ADD COLUMN multicurrency_amount_tva double(24,8) DEFAULT 0 NOT NULL;
 ALTER TABLE llx_societe_remise_except ADD COLUMN multicurrency_amount_ttc double(24,8) DEFAULT 0 NOT NULL;
 
-
-
 ALTER TABLE llx_supplier_proposal ADD COLUMN fk_multicurrency integer;
 ALTER TABLE llx_supplier_proposal ADD COLUMN multicurrency_code varchar(255);
 ALTER TABLE llx_supplier_proposal ADD COLUMN multicurrency_tx double(24,8) DEFAULT 1;
@@ -364,11 +364,18 @@ CREATE TABLE llx_c_accounting_category (
 ) ENGINE=innodb;
 
 ALTER TABLE llx_c_accounting_category ADD UNIQUE INDEX uk_c_accounting_category(code);
+
+INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES (  1,'VTE',"Ventes de marchandises", '707xxx', 0, 0, '', '10', 1, 1);
+INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES (  2,'MAR',"Coût d'achats marchandises vendues", '603xxx | 607xxx | 609xxx', 0, 0, '', '20', 1, 1);
+INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES (  3,'MARGE',"Marge commerciale", '', 0, 1, '1 + 2', '30', 1, 1);
+
 UPDATE llx_accounting_account SET account_parent = '0' WHERE account_parent = '';
-ALTER TABLE llx_accounting_account MODIFY COLUMN account_parent integer DEFAULT 0;
+-- VMYSQL4.1 ALTER TABLE llx_accounting_account MODIFY COLUMN account_parent integer DEFAULT 0;
+-- VPGSQL8.2 ALTER TABLE llx_accounting_account ALTER COLUMN account_parent TYPE integer USING account_parent::integer;
 
 
-DROP INDEX uk_bordereau_cheque ON llx_bordereau_cheque;
+-- VMYSQL4.1 DROP INDEX uk_bordereau_cheque ON llx_bordereau_cheque;
+-- VPGSQL8.2 DROP INDEX uk_bordereau_cheque;
 ALTER TABLE llx_bordereau_cheque CHANGE COLUMN number ref VARCHAR(30) NOT NULL;
 CREATE UNIQUE INDEX uk_bordereau_cheque ON llx_bordereau_cheque (ref, entity);
 
@@ -389,3 +396,18 @@ ALTER TABLE llx_product ADD COLUMN default_vat_code varchar(10) after cost_price
 
 -- Delete old deprecated field
 ALTER TABLE llx_product_stock DROP COLUMN pmp;
+
+-- VMYSQL4.1 ALTER TABLE llx_c_type_resource CHANGE COLUMN rowid rowid integer NOT NULL AUTO_INCREMENT;
+
+ALTER TABLE llx_resource ADD COLUMN asset_number    varchar(255) after ref;
+ALTER TABLE llx_resource ADD COLUMN datec           datetime DEFAULT NULL;
+ALTER TABLE llx_resource ADD COLUMN date_valid      datetime DEFAULT NULL;
+ALTER TABLE llx_resource ADD COLUMN fk_user_author  integer DEFAULT NULL;
+ALTER TABLE llx_resource ADD COLUMN fk_user_modif   integer DEFAULT NULL;
+ALTER TABLE llx_resource ADD COLUMN fk_user_valid   integer DEFAULT NULL;
+ALTER TABLE llx_resource ADD COLUMN fk_statut       smallint NOT NULL DEFAULT '0';
+ALTER TABLE llx_resource ADD COLUMN import_key			varchar(14);
+ALTER TABLE llx_resource ADD COLUMN extraparams			varchar(255);	
+ 
+ALTER TABLE llx_element_resources ADD COLUMN duree real;          -- total duration of using ressource
+
diff --git a/htdocs/install/mysql/tables/llx_accounting_account.sql b/htdocs/install/mysql/tables/llx_accounting_account.sql
index d74c1b75105046c786981ae1e57830444bf3253d..51346cc63f6ebcd96fd88646b7e1b634608b9839 100644
--- a/htdocs/install/mysql/tables/llx_accounting_account.sql
+++ b/htdocs/install/mysql/tables/llx_accounting_account.sql
@@ -29,7 +29,7 @@ create table llx_accounting_account
   pcg_type        			varchar(20)  NOT NULL,
   pcg_subtype     			varchar(20)  NOT NULL,
   account_number  			varchar(32)  NOT NULL,
-  account_parent  			integer,							-- Hierarchic parent
+  account_parent  			integer DEFAULT 0,							-- Hierarchic parent
   label           			varchar(255) NOT NULL,
   fk_accounting_category 	integer DEFAULT 0,
   fk_user_author  			integer DEFAULT NULL,
diff --git a/htdocs/install/mysql/tables/llx_element_resources.sql b/htdocs/install/mysql/tables/llx_element_resources.sql
index 9c67a0d52afa851c891400778299c9dd890cf975..d619626d3d79c222a8e22d0fb313fc33f53f3813 100644
--- a/htdocs/install/mysql/tables/llx_element_resources.sql
+++ b/htdocs/install/mysql/tables/llx_element_resources.sql
@@ -26,6 +26,7 @@ CREATE TABLE llx_element_resources
   resource_type	  varchar(64),		-- resource or user
   busy			  integer,
   mandatory		  integer,
+  duree				real,               -- total duration of using ressource
   fk_user_create  integer,
   tms             timestamp
 )ENGINE=innodb;
diff --git a/htdocs/install/mysql/tables/llx_expedition.sql b/htdocs/install/mysql/tables/llx_expedition.sql
index 8421bb1649cf04357ea9358f35f3952d8358a82e..12dba35f89d5896f7ac39df4b76cba412699b61a 100644
--- a/htdocs/install/mysql/tables/llx_expedition.sql
+++ b/htdocs/install/mysql/tables/llx_expedition.sql
@@ -40,8 +40,9 @@ create table llx_expedition
   fk_address  			integer		DEFAULT NULL, 		-- delivery address (deprecated)
   fk_shipping_method    integer,
   tracking_number       varchar(50),
-  fk_statut             smallint	DEFAULT 0,
-
+  fk_statut             smallint	DEFAULT 0,			-- 0 = draft, 1 = validated, 2 = billed or closed depending on WORKFLOW_BILL_ON_SHIPMENT option
+  billed                smallint    DEFAULT 0,
+  
   height                float,							-- height
   width                 float,							-- with
   size_units            integer,						-- unit of all sizes (height, width, depth)
diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql
index 9d3446d696d20a8998cf43daf82ea0547ef09eef..8b43844498e43c6ff2ce6dcacbe155ec8981faaa 100755
--- a/htdocs/install/mysql/tables/llx_product.sql
+++ b/htdocs/install/mysql/tables/llx_product.sql
@@ -79,7 +79,7 @@ create table llx_product
   surface_units				tinyint      DEFAULT NULL,
   volume					float        DEFAULT NULL,
   volume_units				tinyint      DEFAULT NULL,
-  stock						integer,						-- Current physical stock (dernormalized field)
+  stock						real,							-- Current physical stock (dernormalized field)
   pmp						double(24,8) DEFAULT 0 NOT NULL,		-- To store valuation of stock calculated using average price method, for this product
   fifo						double(24,8),							-- To store valuation of stock calculated using fifo method, for this product
   lifo						double(24,8),							-- To store valuation of stock calculated using lifo method, for this product
diff --git a/htdocs/install/mysql/tables/llx_resource.sql b/htdocs/install/mysql/tables/llx_resource.sql
index 0d67075f1ea6323ebb43bbe0d12ea4f0bd32125e..afb73e9fd5f87991096d4055c96dbd8735582195 100755
--- a/htdocs/install/mysql/tables/llx_resource.sql
+++ b/htdocs/install/mysql/tables/llx_resource.sql
@@ -1,5 +1,6 @@
 -- Module to manage resources into Dolibarr ERP/CRM
--- Copyright (C) 2013	Jean-François Ferry	<jfefe@aternatik.fr>
+-- Copyright (C) 2013       Jean-François Ferry   <jfefe@aternatik.fr>
+-- Copyright (C) 2016		    Gilles Poirier		    <glgpoirier@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
@@ -16,12 +17,21 @@
 
 CREATE TABLE llx_resource
 (
-  rowid           		integer AUTO_INCREMENT PRIMARY KEY,
-  entity          		integer DEFAULT 1 NOT NULL,
-  ref             		varchar(255),
-  description     		text,
+  rowid           		  integer AUTO_INCREMENT PRIMARY KEY,
+  entity          		  integer DEFAULT 1 NOT NULL,
+  ref             		  varchar(255),
+  asset_number          varchar(255),
+  description     		  text,
   fk_code_type_resource varchar(32),
-  note_public     		text,
-  note_private    		text,
-  tms         			timestamp
-)ENGINE=innodb;
\ No newline at end of file
+  datec                 datetime DEFAULT NULL,
+  date_valid            datetime DEFAULT NULL,
+  fk_user_author        integer DEFAULT NULL,
+  fk_user_modif         integer DEFAULT NULL,
+  fk_user_valid         integer DEFAULT NULL,
+  fk_statut             smallint NOT NULL DEFAULT '0',
+  note_public     		  text,
+  note_private    		  text,
+  import_key			varchar(14),
+  extraparams			varchar(255),					-- for stock other parameters with json format
+  tms         			  timestamp
+)ENGINE=innodb;
diff --git a/htdocs/install/mysql/tables/llx_societe_remise_except.sql b/htdocs/install/mysql/tables/llx_societe_remise_except.sql
index ef84e0081d62bc4674cae175a544a422dd119619..f17d17670d22c405eaa229280afba5d0b9139ac6 100644
--- a/htdocs/install/mysql/tables/llx_societe_remise_except.sql
+++ b/htdocs/install/mysql/tables/llx_societe_remise_except.sql
@@ -33,7 +33,7 @@ create table llx_societe_remise_except
   fk_facture			integer,
   fk_facture_source		integer,
   description			text NOT NULL,
-  multicurrency_amount_ht	double(24,8) NOT NULL,
+  multicurrency_amount_ht	double(24,8) DEFAULT 0 NOT NULL,
   multicurrency_amount_tva	double(24,8) DEFAULT 0 NOT NULL,
   multicurrency_amount_ttc	double(24,8) DEFAULT 0 NOT NULL
 )ENGINE=innodb;
diff --git a/htdocs/install/mysql/tables/llx_stock_mouvement.sql b/htdocs/install/mysql/tables/llx_stock_mouvement.sql
index 3db9a4475cda39e7fac46be03d4423c9f2cff25b..3ac42c0c8529e25290112d9437799c1b999b0bda 100644
--- a/htdocs/install/mysql/tables/llx_stock_mouvement.sql
+++ b/htdocs/install/mysql/tables/llx_stock_mouvement.sql
@@ -24,8 +24,8 @@ create table llx_stock_mouvement
   datem           datetime,							-- Date and hour of movement
   fk_product      integer NOT NULL,				-- Id of product
   batch           varchar(30) DEFAULT NULL,		-- Lot or serial number
-  eatby           date DEFAULT NULL,				-- Eatby date
-  sellby          date DEFAULT NULL,				-- Sellby date
+  eatby           date DEFAULT NULL,			-- Eatby date (deprecated, we should get value from batch number in table llx_product_lot)
+  sellby          date DEFAULT NULL,			-- Sellby date (deprecated, we should get value from batch number in table llx_product_lot) 
   fk_entrepot     integer NOT NULL,				-- Id warehouse
   value			  real,								-- Qty of movement
   price           double(24,8) DEFAULT 0,			-- Entry price (used to calculate PMP, FIFO or LIFO value)
diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php
index c9fa2ba39a6ecf23c1f4f8f167896b4404518de2..9ee3d842e51d1f4a7c853665cd326ed550546382 100644
--- a/htdocs/install/upgrade2.php
+++ b/htdocs/install/upgrade2.php
@@ -401,6 +401,8 @@ if (! GETPOST("action") || preg_match('/upgrade/i',GETPOST('action')))
         $beforeversionarray=explode('.','4.0.9');
         if (versioncompare($versiontoarray,$afterversionarray) >= 0 && versioncompare($versiontoarray,$beforeversionarray) <= 0)
         {
+            migrate_directories($db,$langs,$conf,'/fckeditor','/medias');
+            
         	// Reload modules (this must be always and only into last targeted version)
         	$listofmodule=array(
         	    'MAIN_MODULE_BARCODE'=>'newboxdefonly',
diff --git a/htdocs/langs/ar_SA/projects.lang b/htdocs/langs/ar_SA/projects.lang
index bdd7967374a2a45f29beaf7d6ce3d075bdbffb85..ab322a4bd051af554c2c34f6a38e828ec119f3ca 100644
--- a/htdocs/langs/ar_SA/projects.lang
+++ b/htdocs/langs/ar_SA/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=المؤهل العلمى
 OppStatusPROPO=مقترح
 OppStatusNEGO=Negociation
 OppStatusPENDING=بانتظار
-OppStatusWIN=فاز
+OppStatusWON=فاز
 OppStatusLOST=ضائع
 Budget=Budget
diff --git a/htdocs/langs/bn_BD/projects.lang b/htdocs/langs/bn_BD/projects.lang
index b4a21befd803b9b7925b8e26d9f52402eb4b8694..982ec36b26b0b0015b5e64c8e7f39e5bc393a91d 100644
--- a/htdocs/langs/bn_BD/projects.lang
+++ b/htdocs/langs/bn_BD/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/bs_BA/projects.lang b/htdocs/langs/bs_BA/projects.lang
index 0b25f6ea67a06258f08cbd25953c272e985df6e1..fdfcbd408e587cecedbe6b415d5aa566599ec5c9 100644
--- a/htdocs/langs/bs_BA/projects.lang
+++ b/htdocs/langs/bs_BA/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/ca_ES/projects.lang b/htdocs/langs/ca_ES/projects.lang
index 5c2f18593cbb4e352b8c14345a6466b78bf1523e..91c1a7cc9dbe2570a23eed99dd72431ce1a2e658 100644
--- a/htdocs/langs/ca_ES/projects.lang
+++ b/htdocs/langs/ca_ES/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualificació
 OppStatusPROPO=Pressupost
 OppStatusNEGO=Negociació
 OppStatusPENDING=Pendent
-OppStatusWIN=Guanyat
+OppStatusWON=Guanyat
 OppStatusLOST=Perdut
 Budget=Budget
diff --git a/htdocs/langs/cs_CZ/projects.lang b/htdocs/langs/cs_CZ/projects.lang
index 14b67dbb918f5966796ef5b44cadf63b214a27e2..cdc3743aee4ebd38cad1b7a43769a82b40e9b68c 100644
--- a/htdocs/langs/cs_CZ/projects.lang
+++ b/htdocs/langs/cs_CZ/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/da_DK/projects.lang b/htdocs/langs/da_DK/projects.lang
index 0c7ed16673bd062428e9285cc391d08b4600fc2f..618a6e5dc47aeb8ffddf91d1bd24aefe91f0d102 100644
--- a/htdocs/langs/da_DK/projects.lang
+++ b/htdocs/langs/da_DK/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/de_DE/projects.lang b/htdocs/langs/de_DE/projects.lang
index 15fc408019094aa06801351c0ab9a0a9b5954093..c1d58f6d3d6afe4ab2b12daca8bdf04acefc9cbf 100644
--- a/htdocs/langs/de_DE/projects.lang
+++ b/htdocs/langs/de_DE/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualifikation
 OppStatusPROPO=Angebot
 OppStatusNEGO=Verhandlung
 OppStatusPENDING=Anstehend
-OppStatusWIN=Gewonnen
+OppStatusWON=Gewonnen
 OppStatusLOST=Verloren
 Budget=Budget
diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang
index 9fe7c6544fb679a48e0e357fb77fe62b712bfeb3..64c0d88df482c95cabed529862e8e4248c33dda9 100644
--- a/htdocs/langs/en_US/accountancy.lang
+++ b/htdocs/langs/en_US/accountancy.lang
@@ -174,6 +174,9 @@ OptionModeProductBuyDesc=Show all products with no accounting account defined fo
 
 ## Dictionary
 Range=Range of accounting account
+Sens=Sens
+Calculated=Calculated
+Formula=Formula
 
 ## Error
 ErrorNoAccountingCategoryForThisCountry=No accounting category are available for this country
\ No newline at end of file
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index b37083ca0912a0ad3d8eb9c02805b79cb4017d2b..9122546a1f3b618d6f28260d1ed3af9ad89f7e95 100755
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -521,7 +521,7 @@ Module1520Desc=Mass mail document generation
 Module1780Name=Tags/Categories
 Module1780Desc=Create tags/category (products, customers, suppliers, contacts or members)
 Module2000Name=WYSIWYG editor
-Module2000Desc=Allow to edit some text area using an advanced editor
+Module2000Desc=Allow to edit some text area using an advanced editor (Based on CKEditor)
 Module2200Name=Dynamic Prices
 Module2200Desc=Enable the usage of math expressions for prices
 Module2300Name=Cron
@@ -1602,7 +1602,7 @@ ApiDesc=By enabling this module, Dolibarr become a REST server to provide miscel
 KeyForApiAccess=Key to use API (parameter "api_key")
 ApiProductionMode=Enable production mode (this will activate use of a caches for services management)
 ApiEndPointIs=You can access to the API at url
-ApiExporerIs=You can explore the API at url
+ApiExporerIs=You can explore the APIs at url
 OnlyActiveElementsAreExposed=Only elements from enabled modules are exposed
 ApiKey=Key for API
 ##### Bank #####
@@ -1740,3 +1740,5 @@ AddOtherPagesOrServices=Add other pages or services
 AddModels=Add document or numbering templates
 AddSubstitutions=Add keys substitutions
 DetectionNotPossible=Detection not possible
+UrlToGetKeyToUseAPIs=Url to get token to use API (once token has been received it is saved on database user table and will be checked on each future access) 
+ListOfAvailableAPIs=List of available APIs
\ No newline at end of file
diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang
index e3c0b5108fc06a782c017914f23502a191101b0f..c6526b51d288e0abe8285ca1e460efadbc86c34d 100644
--- a/htdocs/langs/en_US/compta.lang
+++ b/htdocs/langs/en_US/compta.lang
@@ -59,6 +59,8 @@ SpecialExpensesArea=Area for all special payments
 TaxAndDividendsArea=Sale taxes, social/fiscal taxes contributions and dividends area
 SocialContribution=Social or fiscal tax
 SocialContributions=Social or fiscal taxes
+SocialContributionsDeductibles=Deductible social or fiscal taxes
+SocialContributionsNondeductibles=Nondeductible social or fiscal taxes
 MenuSpecialExpenses=Special expenses
 MenuTaxAndDividends=Taxes and dividends
 MenuSalaries=Salaries
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index 4b69e2c0ddef60ce7d7116d14f23864f9dbcc223..90ccde2474a6a1bc15b83ba6aace71578733d34c 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -120,6 +120,7 @@ Home=Home
 Help=Help
 OnlineHelp=Online help
 PageWiki=Wiki page
+MediaBrowser=Media browser
 Always=Always
 Never=Never
 Under=under
diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang
index 607b28d9f06d7192432ca2b6e8c6500192f1dfda..42c05d0cd079547fa89a8fa3511616c4c8fd3f1b 100644
--- a/htdocs/langs/en_US/projects.lang
+++ b/htdocs/langs/en_US/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
\ No newline at end of file
diff --git a/htdocs/langs/en_US/supplier_proposal.lang b/htdocs/langs/en_US/supplier_proposal.lang
index 3d12ad57612e6815d895481c21a162824a8f246f..a1ede43437d52d5343bd6abf55e647dbe024c593 100644
--- a/htdocs/langs/en_US/supplier_proposal.lang
+++ b/htdocs/langs/en_US/supplier_proposal.lang
@@ -1,7 +1,6 @@
 # Dolibarr language file - Source file is en_US - supplier_proposal
 SupplierProposal=Supplier commercial proposals
 supplier_proposalDESC=Manage price requests to suppliers
-SupplierProposalShort=Supplier proposals
 SupplierProposalNew=New request
 CommRequest=Price request
 CommRequests=Price requests
diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang
index 13659bc5954a03eeeb1fd545c4f74462bcfac0e7..a0b2106ac63a70a9b2b6d670f2bdca5d03cdbe5a 100644
--- a/htdocs/langs/en_US/website.lang
+++ b/htdocs/langs/en_US/website.lang
@@ -4,11 +4,17 @@ WebsiteSetupDesc=Create here as much entry as number of different websites you n
 DeleteWebsite=Delete website
 ConfirmDeleteWebsite=Are you sure you want to delete this web site. All its pages and content will also be removed. 
 WEBSITE_PAGENAME=Page name/alias
-WEBSITE_URL=Page real URL
+WEBSITE_URL=Web site URL
+WEBSITE_CSS_URL=URL of external CSS file
+WEBSITE_CSS_INLINE=CSS content
+MediaFiles=Media library
+EditCss=Edit Style/CSS
 EditMenu=Edit menu
 EditPageMeta=Edit Meta
 EditPageContent=Edit Content
 Website=Web site
 AddPage=Add page
 Page=Page
-PreviewOfSiteNotYetAvailable=Preview of your website <strong>%s</strong> not yet available. You must first add a page.
\ No newline at end of file
+PreviewOfSiteNotYetAvailable=Preview of your website <strong>%s</strong> not yet available. You must first add a page.
+PageDeleted=Page %s of website %s deleted
+ViewInNewTab=View in new tab
\ No newline at end of file
diff --git a/htdocs/langs/es_ES/projects.lang b/htdocs/langs/es_ES/projects.lang
index b0965bd080cf1b65825a12419d58af5331eea8ac..3a9fd407875464c909e0bb234e013d5742f3b003 100644
--- a/htdocs/langs/es_ES/projects.lang
+++ b/htdocs/langs/es_ES/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Cualificación
 OppStatusPROPO=Presupuesto
 OppStatusNEGO=Negociación
 OppStatusPENDING=Pendiente
-OppStatusWIN=Ganado
+OppStatusWON=Ganado
 OppStatusLOST=Perdido
 Budget=Budget
diff --git a/htdocs/langs/et_EE/projects.lang b/htdocs/langs/et_EE/projects.lang
index 7c53e51f80d72824806dc4b74ea085e3052a8ff8..31f516ada14801d70a43aa30e62366140984a144 100644
--- a/htdocs/langs/et_EE/projects.lang
+++ b/htdocs/langs/et_EE/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/eu_ES/projects.lang b/htdocs/langs/eu_ES/projects.lang
index b4a21befd803b9b7925b8e26d9f52402eb4b8694..982ec36b26b0b0015b5e64c8e7f39e5bc393a91d 100644
--- a/htdocs/langs/eu_ES/projects.lang
+++ b/htdocs/langs/eu_ES/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/fi_FI/projects.lang b/htdocs/langs/fi_FI/projects.lang
index fea93953f69193bad1bb26c6a72cb2b54b005290..50177fda449d3f45e311a783eb41d25d0c813149 100644
--- a/htdocs/langs/fi_FI/projects.lang
+++ b/htdocs/langs/fi_FI/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/fr_FR/projects.lang b/htdocs/langs/fr_FR/projects.lang
index b95fbb3cd56b941f30d2f39865618c29203dd174..6389d10abbfdc33df33c9ab224d73309025c1989 100644
--- a/htdocs/langs/fr_FR/projects.lang
+++ b/htdocs/langs/fr_FR/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposition
 OppStatusNEGO=Négociation
 OppStatusPENDING=En attente
-OppStatusWIN=Gagné
+OppStatusWON=Gagné
 OppStatusLOST=Perdu
 Budget=Budget
diff --git a/htdocs/langs/he_IL/projects.lang b/htdocs/langs/he_IL/projects.lang
index fb939aef16971d04c62afb11ab0169314006c825..ee8785e63978794de8a06795c1df3cdf846cabe8 100644
--- a/htdocs/langs/he_IL/projects.lang
+++ b/htdocs/langs/he_IL/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/hr_HR/projects.lang b/htdocs/langs/hr_HR/projects.lang
index 7dae3662584dfe351d8ab4d42bf13e7d6c41800e..bd83a40224dfa61cecf6900b59793d16f9bc75e0 100644
--- a/htdocs/langs/hr_HR/projects.lang
+++ b/htdocs/langs/hr_HR/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/hu_HU/projects.lang b/htdocs/langs/hu_HU/projects.lang
index 9ab8ab13b053f96d2701f8616b4c116fc3fd88f6..20a6f143d2af6bd8938804053bcf577023f79c67 100644
--- a/htdocs/langs/hu_HU/projects.lang
+++ b/htdocs/langs/hu_HU/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/id_ID/projects.lang b/htdocs/langs/id_ID/projects.lang
index 83a284cc58cf7113a773713df69064c683cd9f37..13798a28b3c0c3c6b9dbf0e43daa8b562e5e93eb 100644
--- a/htdocs/langs/id_ID/projects.lang
+++ b/htdocs/langs/id_ID/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/is_IS/projects.lang b/htdocs/langs/is_IS/projects.lang
index d41a345caf3b112c42c060a1860e24be419f4a40..517ab7e2e84730a3ab664dd416a126fc2d3360ba 100644
--- a/htdocs/langs/is_IS/projects.lang
+++ b/htdocs/langs/is_IS/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/it_IT/projects.lang b/htdocs/langs/it_IT/projects.lang
index 9954fb68fd20edc07a903abe5a952b1bd0979206..8599f5089b59bf0d02132efec86f39bf8a5951fd 100644
--- a/htdocs/langs/it_IT/projects.lang
+++ b/htdocs/langs/it_IT/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualificazione
 OppStatusPROPO=Proposta
 OppStatusNEGO=Negoziazione
 OppStatusPENDING=In attesa
-OppStatusWIN=Vinto
+OppStatusWON=Vinto
 OppStatusLOST=Perso
 Budget=Budget
diff --git a/htdocs/langs/ka_GE/projects.lang b/htdocs/langs/ka_GE/projects.lang
index b4a21befd803b9b7925b8e26d9f52402eb4b8694..982ec36b26b0b0015b5e64c8e7f39e5bc393a91d 100644
--- a/htdocs/langs/ka_GE/projects.lang
+++ b/htdocs/langs/ka_GE/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/kn_IN/projects.lang b/htdocs/langs/kn_IN/projects.lang
index b4a21befd803b9b7925b8e26d9f52402eb4b8694..982ec36b26b0b0015b5e64c8e7f39e5bc393a91d 100644
--- a/htdocs/langs/kn_IN/projects.lang
+++ b/htdocs/langs/kn_IN/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/ko_KR/projects.lang b/htdocs/langs/ko_KR/projects.lang
index b4a21befd803b9b7925b8e26d9f52402eb4b8694..982ec36b26b0b0015b5e64c8e7f39e5bc393a91d 100644
--- a/htdocs/langs/ko_KR/projects.lang
+++ b/htdocs/langs/ko_KR/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/lo_LA/projects.lang b/htdocs/langs/lo_LA/projects.lang
index 56cc02c9e82795c424a96a64c999db3776a52a3a..52ca66a2763af7085419981cad526a5a0db3d76c 100644
--- a/htdocs/langs/lo_LA/projects.lang
+++ b/htdocs/langs/lo_LA/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/lt_LT/projects.lang b/htdocs/langs/lt_LT/projects.lang
index 6398f58b129776b99639f48c3ef0bf0302a377b7..bc9adc0ef7fe2f5b9d0aa922613b2546650788ca 100644
--- a/htdocs/langs/lt_LT/projects.lang
+++ b/htdocs/langs/lt_LT/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/lv_LV/projects.lang b/htdocs/langs/lv_LV/projects.lang
index d04ece7b84f33e1455cc42718e8be6c5d8ff76d8..000139e853cf3371eba8627fcc1d11cd671e44fc 100644
--- a/htdocs/langs/lv_LV/projects.lang
+++ b/htdocs/langs/lv_LV/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Kvalifikācija
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/mk_MK/projects.lang b/htdocs/langs/mk_MK/projects.lang
index b4a21befd803b9b7925b8e26d9f52402eb4b8694..982ec36b26b0b0015b5e64c8e7f39e5bc393a91d 100644
--- a/htdocs/langs/mk_MK/projects.lang
+++ b/htdocs/langs/mk_MK/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/nb_NO/projects.lang b/htdocs/langs/nb_NO/projects.lang
index c57648d77d147e5fca5ce550a8a5ed525205cb1b..c69d3c47ee4feb71532a975c87c62de20f500aa6 100644
--- a/htdocs/langs/nb_NO/projects.lang
+++ b/htdocs/langs/nb_NO/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Kvalifikasjon
 OppStatusPROPO=Tilbud
 OppStatusNEGO=Forhandling
 OppStatusPENDING=Venter
-OppStatusWIN=Vunnet
+OppStatusWON=Vunnet
 OppStatusLOST=Tapt
 Budget=Budget
diff --git a/htdocs/langs/nl_NL/projects.lang b/htdocs/langs/nl_NL/projects.lang
index 93514bd41081c1b2ed3e5a6422961aa0cc77dea3..8cf1a0d46846e0e81a90a026d702251c04313cd2 100644
--- a/htdocs/langs/nl_NL/projects.lang
+++ b/htdocs/langs/nl_NL/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/pl_PL/projects.lang b/htdocs/langs/pl_PL/projects.lang
index 1479193a7ccc5d5d257fd7b6988c4e20d0a83f00..429a664d293b494e5a64087b8a4fb7e56773ae53 100644
--- a/htdocs/langs/pl_PL/projects.lang
+++ b/htdocs/langs/pl_PL/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Kwalifikacja
 OppStatusPROPO=Wniosek
 OppStatusNEGO=Negocjacje
 OppStatusPENDING=W oczekiwaniu
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Zagubiony
 Budget=Budget
diff --git a/htdocs/langs/pt_BR/projects.lang b/htdocs/langs/pt_BR/projects.lang
index f8ae458330b7fd01737409aac4f47ce8a1281932..ab92118d1e4c4309814a23e28f9f71f12ff130b5 100644
--- a/htdocs/langs/pt_BR/projects.lang
+++ b/htdocs/langs/pt_BR/projects.lang
@@ -125,5 +125,5 @@ OppStatusQUAL=Qualificação
 OppStatusPROPO=Proposta
 OppStatusNEGO=Negociação
 OppStatusPENDING=Pendente
-OppStatusWIN=Ganhou
+OppStatusWON=Ganhou
 OppStatusLOST=Perdido
diff --git a/htdocs/langs/pt_PT/projects.lang b/htdocs/langs/pt_PT/projects.lang
index c6bc715fada0999f9998b3c46e7d39ea6d097e79..2df744a5013abde79107a6d764c5155d31b3638d 100644
--- a/htdocs/langs/pt_PT/projects.lang
+++ b/htdocs/langs/pt_PT/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/ro_RO/projects.lang b/htdocs/langs/ro_RO/projects.lang
index 301c6242d249d2479f03f5c9908a50fbf0d3cc70..c6fc6cb74e0f27a9ca9a9ee354571d93af037d12 100644
--- a/htdocs/langs/ro_RO/projects.lang
+++ b/htdocs/langs/ro_RO/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Calificare
 OppStatusPROPO=Ofertă 
 OppStatusNEGO=Negociere
 OppStatusPENDING=In asteptarea
-OppStatusWIN=Castigat
+OppStatusWON=Castigat
 OppStatusLOST=Pierdut
 Budget=Budget
diff --git a/htdocs/langs/ru_RU/projects.lang b/htdocs/langs/ru_RU/projects.lang
index 27c4995d20d58cd76370d5a93575a8ea16e921f4..bdee2d2d019be51b8273684af06feaa29a3a9e48 100644
--- a/htdocs/langs/ru_RU/projects.lang
+++ b/htdocs/langs/ru_RU/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/sk_SK/projects.lang b/htdocs/langs/sk_SK/projects.lang
index 6453fec2772d85c0a61dce5084180462911cb381..579d69f13236f8cee3f8bcc30fa133b51ffe57ba 100644
--- a/htdocs/langs/sk_SK/projects.lang
+++ b/htdocs/langs/sk_SK/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/sl_SI/projects.lang b/htdocs/langs/sl_SI/projects.lang
index 81c1c01c46d84088ad54ff279c1a6a477f628be2..38c773a95bb16daed742624fd8162bed4e1a1b7f 100644
--- a/htdocs/langs/sl_SI/projects.lang
+++ b/htdocs/langs/sl_SI/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/sq_AL/projects.lang b/htdocs/langs/sq_AL/projects.lang
index b4a21befd803b9b7925b8e26d9f52402eb4b8694..982ec36b26b0b0015b5e64c8e7f39e5bc393a91d 100644
--- a/htdocs/langs/sq_AL/projects.lang
+++ b/htdocs/langs/sq_AL/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/sr_RS/projects.lang b/htdocs/langs/sr_RS/projects.lang
index 8ba6046454e070d19a576bc10ccaee3af078dccd..553b7ec80af0c0e47e9df6b42526c9e9d472602a 100644
--- a/htdocs/langs/sr_RS/projects.lang
+++ b/htdocs/langs/sr_RS/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Kvalifikacija
 OppStatusPROPO=Ponuda
 OppStatusNEGO=Pregovaranje
 OppStatusPENDING=Na čekanju
-OppStatusWIN=Dobijeno
+OppStatusWON=Dobijeno
 OppStatusLOST=Izgubljeno
 Budget=Budget
diff --git a/htdocs/langs/sv_SE/projects.lang b/htdocs/langs/sv_SE/projects.lang
index 77be1874eb2fb97e93847579bad44f2198101430..a75da531dd30b6ae0da31520dba6c18402f1a121 100644
--- a/htdocs/langs/sv_SE/projects.lang
+++ b/htdocs/langs/sv_SE/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/sw_SW/projects.lang b/htdocs/langs/sw_SW/projects.lang
index b4a21befd803b9b7925b8e26d9f52402eb4b8694..982ec36b26b0b0015b5e64c8e7f39e5bc393a91d 100644
--- a/htdocs/langs/sw_SW/projects.lang
+++ b/htdocs/langs/sw_SW/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/tr_TR/projects.lang b/htdocs/langs/tr_TR/projects.lang
index dbdfcadfce7e40ec98d6aca7994ae7159502c887..b4a54871c5a8c849e3223eb6ebb809b5a59bf9ea 100644
--- a/htdocs/langs/tr_TR/projects.lang
+++ b/htdocs/langs/tr_TR/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Nitelendirme
 OppStatusPROPO=Teklif
 OppStatusNEGO=Pazarlık
 OppStatusPENDING=Beklemede
-OppStatusWIN=Kazanç
+OppStatusWON=Kazanç
 OppStatusLOST=Kayıp
 Budget=Budget
diff --git a/htdocs/langs/uk_UA/projects.lang b/htdocs/langs/uk_UA/projects.lang
index b4a21befd803b9b7925b8e26d9f52402eb4b8694..982ec36b26b0b0015b5e64c8e7f39e5bc393a91d 100644
--- a/htdocs/langs/uk_UA/projects.lang
+++ b/htdocs/langs/uk_UA/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/uz_UZ/projects.lang b/htdocs/langs/uz_UZ/projects.lang
index b4a21befd803b9b7925b8e26d9f52402eb4b8694..982ec36b26b0b0015b5e64c8e7f39e5bc393a91d 100644
--- a/htdocs/langs/uz_UZ/projects.lang
+++ b/htdocs/langs/uz_UZ/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/vi_VN/projects.lang b/htdocs/langs/vi_VN/projects.lang
index 174b4a88dc1d3d8c6df4808b7c566dfc9d4493b4..7af08a9a5bcad751e872c40914c6655ae13f1fe8 100644
--- a/htdocs/langs/vi_VN/projects.lang
+++ b/htdocs/langs/vi_VN/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/zh_CN/projects.lang b/htdocs/langs/zh_CN/projects.lang
index bbd8b5cf27d80e3553d46a206294f58796c68650..070c15647e69451086315792a06df949f0a33ac3 100644
--- a/htdocs/langs/zh_CN/projects.lang
+++ b/htdocs/langs/zh_CN/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/langs/zh_TW/projects.lang b/htdocs/langs/zh_TW/projects.lang
index 2599ab48413d6339c622e1bab6cf89a1f61b2aa1..2519f38c954252b51c57d5c655caae110f57c178 100644
--- a/htdocs/langs/zh_TW/projects.lang
+++ b/htdocs/langs/zh_TW/projects.lang
@@ -199,6 +199,6 @@ OppStatusQUAL=Qualification
 OppStatusPROPO=Proposal
 OppStatusNEGO=Negociation
 OppStatusPENDING=Pending
-OppStatusWIN=Won
+OppStatusWON=Won
 OppStatusLOST=Lost
 Budget=Budget
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index b0f4585d888007a9d94734ca5e0b6e34e86f5b0a..bea4a20afcd77581da6c05f3e27876e209e6c483 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -866,7 +866,7 @@ else
     define('ROWS_9',8);
 }
 
-$heightforframes=52;
+$heightforframes=48;
 
 // Init menu manager
 if (! defined('NOREQUIREMENU'))
@@ -1464,7 +1464,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a
 	        $text ='<a href="'.$_SERVER["PHP_SELF"].'?'.$qs.($qs?'&':'').'optioncss=print" target="_blank">';
 	        $text.= img_picto(":".$langs->trans("PrintContentArea"), 'printer_top.png', 'class="printer"');
 	        $text.='</a>';
-	        $toprightmenu.=Form::textwithtooltip('',$langs->trans("PrintContentArea"),2,1,$text,'login_block_elem',2);
+	        $toprightmenu.=@Form::textwithtooltip('',$langs->trans("PrintContentArea"),2,1,$text,'login_block_elem',2);
 	    }
 
 	    // Link to Dolibarr wiki pages
@@ -1501,12 +1501,12 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a
 	            //if ($mode == 'wiki') $text.=' ('.dol_trunc(strtr($helppage,'_',' '),8).')';
 	            $text.='</a>';
 	            //$toprightmenu.='</div>'."\n";
-	            $toprightmenu.=Form::textwithtooltip('',$title,2,1,$text,'login_block_elem',2);
+	            $toprightmenu.=@Form::textwithtooltip('',$title,2,1,$text,'login_block_elem',2);
 	        }
 	    }
 
 		// Logout link
-	    $toprightmenu.=Form::textwithtooltip('',$logouthtmltext,2,1,$logouttext,'login_block_elem',2);
+	    $toprightmenu.=@Form::textwithtooltip('',$logouthtmltext,2,1,$logouttext,'login_block_elem',2);
 
 	    $toprightmenu.='</div>';
 
diff --git a/htdocs/product/card.php b/htdocs/product/card.php
index 841d1b1b73a7acd13caa80db4cd164da8c97414c..92d8a7f42885334c8bd35a961dc1ed8c3bbf5393 100644
--- a/htdocs/product/card.php
+++ b/htdocs/product/card.php
@@ -8,12 +8,12 @@
  * Copyright (C) 2010-2015	Juanjo Menent			<jmenent@2byte.es>
  * Copyright (C) 2013-2014	Marcos García			<marcosgdf@gmail.com>
  * Copyright (C) 2012-2013	Cédric Salvador			<csalvador@gpcsolutions.fr>
- * Copyright (C) 2011-2015	Alexandre Spangaro		<aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2011-2016	Alexandre Spangaro		<aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2014		Cédric Gross			<c.gross@kreiz-it.fr>
  * Copyright (C) 2014-2015	Ferran Marcet			<fmarcet@2byte.es>
  * Copyright (C) 2015       Jean-François Ferry     <jfefe@aternatik.fr>
  * Copyright (C) 2015       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
- * Copyright (C) 2016		Charlie Benke		 <charlie@patas-monkey.com>
+ * Copyright (C) 2016		Charlie Benke           <charlie@patas-monkey.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
@@ -1477,22 +1477,24 @@ else
 
             // Accountancy sell code
 			print '<tr><td class="nowrap">';
-            print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
             print $langs->trans("ProductAccountancySellCode");
-            print '</td>';
-			print '</tr></table>';
             print '</td><td colspan="2">';
-			print length_accountg($object->accountancy_code_sell);
-            print '</td></tr>';
+			if (! empty($conf->accounting->enabled)) {
+				print length_accountg($object->accountancy_code_sell);
+            } else {
+				print $object->accountancy_code_sell;
+			}
+			print '</td></tr>';
 
             // Accountancy buy code
 			print '<tr><td class="nowrap">';
-            print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
             print $langs->trans("ProductAccountancyBuyCode");
-            print '</td>';
-			print '</tr></table>';
             print '</td><td colspan="2">';
-			print length_accountg($object->accountancy_code_buy);
+			if (! empty($conf->accounting->enabled)) {
+				print length_accountg($object->accountancy_code_buy);
+            } else {
+				print $object->accountancy_code_buy;
+			}
             print '</td></tr>';
 
             // Status (to sell)
diff --git a/htdocs/product/class/api_product.class.php b/htdocs/product/class/api_product.class.php
index 1ce63411cd31eeb17e845fa0dc04601f1f321e21..1e485fd6733d76219a26f4c38b09f01e70d86eff 100644
--- a/htdocs/product/class/api_product.class.php
+++ b/htdocs/product/class/api_product.class.php
@@ -18,6 +18,7 @@
  use Luracast\Restler\RestException;
  
  require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+ require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
 
 /**
  * API class for product object
@@ -165,6 +166,91 @@ class ProductApi extends DolibarrApi
         }
 		return $obj_ret;
     }
+
+
+    /**
+     * List products in a category
+     * 
+     * Get a list of products
+     * 
+     * @param int		$mode		Use this param to filter list (0 for all, 1 for only product, 2 for only service)
+     * @param int		$category		Use this param to filter list by category
+     * @param mixed     $to_sell    Filter products to sell (1) or not to sell (0)  
+     * @param mixed     $to_buy     Filter products to nuy (1) or not to buy (0)  
+     * @param string	$sortfield	Sort field
+     * @param string	$sortorder	Sort order
+     * @param int		$limit		Limit for list
+     * @param int		$page		Page number
+     *
+     * @return array Array of product objects
+     *
+     * @url	GET /product/list/category/{category}
+     */
+    function getByCategory($mode=0, $category=0, $to_sell='', $to_buy='', $sortfield = "p.ref", $sortorder = 'ASC', $limit = 0, $page = 0) {
+        global $db, $conf;
+        
+        $obj_ret = array();
+        
+        $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : '';
+
+        $sql = "SELECT rowid, ref, ref_ext";
+        $sql.= " FROM ".MAIN_DB_PREFIX."product as p, ";
+        $sql.= MAIN_DB_PREFIX."categorie_product as c";
+        $sql.= ' WHERE p.entity IN ('.getEntity('product', 1).')';
+
+        // Select products of given category
+        $sql.= " AND c.fk_categorie = ".$db->escape($category);
+        $sql.= " AND c.fk_product = p.rowid ";
+		
+        // Show products
+        if ($mode == 1) $sql.= " AND p.fk_product_type = 0";
+        // Show services
+        if ($mode == 2) $sql.= " AND p.fk_product_type = 1";
+        // Show product on sell
+        if ($to_sell) $sql.= " AND p.to_sell = ".$db->escape($to_sell);
+        // Show product on buy
+        if ($to_buy) $sql.= " AND p.to_nuy = ".$db->escape($to_nuy);
+
+        $nbtotalofrecords = 0;
+        if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
+        {
+            $result = $db->query($sql);
+            $nbtotalofrecords = $db->num_rows($result);
+        }
+
+        $sql.= $db->order($sortfield, $sortorder);
+        if ($limit)	{
+            if ($page < 0)
+            {
+                $page = 0;
+            }
+            $offset = $limit * $page;
+
+            $sql.= $db->plimit($limit + 1, $offset);
+        }
+
+        $result = $db->query($sql);
+        if ($result)
+        {
+            $num = $db->num_rows($result);
+            while ($i < $num)
+            {
+                $obj = $db->fetch_object($result);
+                $product_static = new Product($db);
+                if($product_static->fetch($obj->rowid)) {
+                    $obj_ret[] = parent::_cleanObjectDatas($product_static);
+                }
+                $i++;
+            }
+        }
+        else {
+            throw new RestException(503, 'Error when retrieve product list');
+        }
+        if( ! count($obj_ret)) {
+            throw new RestException(404, 'No product found');
+        }
+        return $obj_ret;
+    }
     
     /**
      * Create product object
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index 819a5438eda863a555128ac7bea7fdd9b0d74e46..6919d722cebee1554a2cccd9ab6d17c0bb0d3106 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -109,8 +109,10 @@ class Product extends CommonObject
 	var $localtax1_type;
 	var $localtax2_type;
 	
-	//! Stock
+	//! Stock real
 	var $stock_reel;
+	//! Stock virtual
+	var $stock_theorique;
 	//! Cost price
 	var $cost_price;
 	//! Average price value for product entry into stock (PMP)
@@ -1416,7 +1418,7 @@ class Product extends CommonObject
 
 		$id=$this->id;
 
-		dol_syslog(get_class($this)."::update_price id=".$id." newprice=".$newprice." newpricebase=".$newpricebase." newminprice=".$newminprice." level=".$level." npr=".$newnpr," newdefaultvatcode=".$newdefaultvatcode);
+		dol_syslog(get_class($this)."::update_price id=".$id." newprice=".$newprice." newpricebase=".$newpricebase." newminprice=".$newminprice." level=".$level." npr=".$newnpr." newdefaultvatcode=".$newdefaultvatcode);
 
 		// Clean parameters
 		if (empty($this->tva_tx))  $this->tva_tx=0;
@@ -1848,7 +1850,7 @@ class Product extends CommonObject
                     }
                 }
 
-				// We should not load stock at each fetch. If someone need stock, he must call load_stock after fetch.
+				// We should not load stock during the fetch. If someone need stock of product, he must call load_stock after fetching product.
 				//$res=$this->load_stock();
 				// instead we just init the stock_warehouse array
 				$this->stock_warehouse = array();
@@ -2845,7 +2847,7 @@ class Product extends CommonObject
 
 				//print "XXX We add id=".$id." - label=".$label." - nb=".$nb." - multiply=".$multiply." fullpath=".$compl_path.$label."\n";
 				$this->fetch($id);		// Load product
-				$this->load_stock();	// Load stock
+				$this->load_stock('nobatch,novirtual');	// Load stock to get true this->stock_reel
 				$this->res[]= array(
 					'id'=>$id,					// Id product
 					'id_parent'=>$id_parent,
@@ -3339,15 +3341,18 @@ class Product extends CommonObject
 
 	/**
 	 *    Load information about stock of a product into stock_reel, stock_warehouse[] (including stock_warehouse[idwarehouse]->detail_batch for batch products)
+	 *    This function need a lot of load. If you use it on list, use a cache to execute it one for each product id. 
 	 *
-	 *    @return     	int             < 0 if KO, > 0 if OK
-	 *    @see			load_virtual_stock, getBatchInfo
+	 *    @param      string   $option     '', 'nobatch' = Do not load batch information, 'novirtual' = Do not load virtual stock
+	 *    @return     int                  < 0 if KO, > 0 if OK
+	 *    @see		  load_virtual_stock, getBatchInfo
 	 */
-	function load_stock()
+	function load_stock($option='')
 	{
 		$this->stock_reel = 0;
 		$this->stock_warehouse = array();
-
+		$this->stock_theorique = 0;
+		
 		$sql = "SELECT ps.rowid, ps.reel, ps.fk_entrepot";
 		$sql.= " FROM ".MAIN_DB_PREFIX."product_stock as ps";
 		$sql.= ", ".MAIN_DB_PREFIX."entrepot as w";
@@ -3369,14 +3374,17 @@ class Product extends CommonObject
 					$this->stock_warehouse[$row->fk_entrepot] = new stdClass();
 					$this->stock_warehouse[$row->fk_entrepot]->real = $row->reel;
 					$this->stock_warehouse[$row->fk_entrepot]->id = $row->rowid;
-					if ($this->hasbatch()) $this->stock_warehouse[$row->fk_entrepot]->detail_batch=Productbatch::findAll($this->db,$row->rowid,1);
+					if ((! preg_match('/nobatch/', $option)) && $this->hasbatch()) $this->stock_warehouse[$row->fk_entrepot]->detail_batch=Productbatch::findAll($this->db,$row->rowid,1);
 					$this->stock_reel+=$row->reel;
 					$i++;
 				}
 			}
 			$this->db->free($result);
 
-			$this->load_virtual_stock();		// This also load stats_commande_fournisseur, ...
+			if (! preg_match('/novirtual/', $option)) 
+			{
+			    $this->load_virtual_stock();		// This also load stats_commande_fournisseur, ...
+			}
 
 			return 1;
 		}
@@ -3388,7 +3396,8 @@ class Product extends CommonObject
 	}
 
 	/**
-	 *    Load information about objects that are delat between physical and virtual stock of a product
+	 *    Load value ->stock_theorique of a product. Property this->id must be defined.
+	 *    This function need a lot of load. If you use it on list, use a cache to execute it one for each product id. 
 	 *
 	 *    @return   int             < 0 if KO, > 0 if OK
 	 *    @see		load_stock, getBatchInfo
@@ -3712,7 +3721,7 @@ class Product extends CommonObject
     			}
             }
 
-			if ($size==1 || $size='small')
+			if ($size==1 || $size=='small')
 			{
 				if ($nbbyrow > 0)
 				{
diff --git a/htdocs/product/class/productbatch.class.php b/htdocs/product/class/productbatch.class.php
index d0554309539036d9914e6d7f159ef9199225c79d..749da6d86e259e15289c8f2f5aa644f92a0abb8b 100644
--- a/htdocs/product/class/productbatch.class.php
+++ b/htdocs/product/class/productbatch.class.php
@@ -408,8 +408,8 @@ class Productbatch extends CommonObject
      *  Find first detail record that match eather eat-by or sell-by or batch within given warehouse
      *
      *  @param	int			$fk_product_stock   id product_stock for objet
-     *  @param	date		$eatby    			eat-by date for objet
-     *  @param	date		$sellby   			sell-by date for objet
+     *  @param	date		$eatby    			eat-by date for objet - deprecated: a search must be done on batch number
+     *  @param	date		$sellby   			sell-by date for objet - deprecated: a search must be done on batch number
      *  @param	string		$batch_number   	batch number for objet
      *  @return int          					<0 if KO, >0 if OK
      */
diff --git a/htdocs/product/list.php b/htdocs/product/list.php
index 51e453393a05bd5ab4000753a75574b19f24fd21..1d63964be1ce17f0cf65a41b1863ee73f8a23d71 100644
--- a/htdocs/product/list.php
+++ b/htdocs/product/list.php
@@ -103,6 +103,13 @@ if ($type=='0') $result=restrictedArea($user,'produit','','','','','',$objcanvas
 else if ($type=='1') $result=restrictedArea($user,'service','','','','','',$objcanvas);
 else $result=restrictedArea($user,'produit|service','','','','','',$objcanvas);
 
+// Define virtualdiffersfromphysical
+$virtualdiffersfromphysical=0;
+if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
+{
+    $virtualdiffersfromphysical=1;		// According to increase/decrease stock options, virtual and physical stock may differs.
+}
+
 // List of fields to search into when doing a "search in all"
 $fieldstosearchall = array(
 	'p.ref'=>"Ref",
@@ -140,9 +147,11 @@ $arrayfields=array(
     'p.duration'=>array('label'=>$langs->trans("Duration"), 'checked'=>($contextpage != 'productlist'), 'enabled'=>(! empty($conf->service->enabled))),
 	'p.sellprice'=>array('label'=>$titlesellprice, 'checked'=>1, 'enabled'=>empty($conf->global->PRODUIT_MULTIPRICES)),
     'p.minbuyprice'=>array('label'=>$langs->trans("BuyingPriceMinShort"), 'checked'=>1, 'enabled'=>(! empty($user->rights->fournisseur->lire))),
-	'p.desiredstock'=>array('label'=>$langs->trans("DesiredStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
-	'p.tobatch'=>array('label'=>$langs->trans("ManageLotSerial"), 'checked'=>0, 'enabled'=>(! empty($conf->productbatch->enabled))),
+	'p.seuil_stock_alerte'=>array('label'=>$langs->trans("StockLimit"), 'checked'=>0, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
+    'p.desiredstock'=>array('label'=>$langs->trans("DesiredStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
     'p.stock'=>array('label'=>$langs->trans("PhysicalStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')),
+    'stock_virtual'=>array('label'=>$langs->trans("VirtualStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service' && $virtualdiffersfromphysical)),
+    'p.tobatch'=>array('label'=>$langs->trans("ManageLotSerial"), 'checked'=>0, 'enabled'=>(! empty($conf->productbatch->enabled))),
 	'p.accountancy_code_sell'=>array('label'=>$langs->trans("ProductAccountancySellCode"), 'checked'=>0),
 	'p.accountancy_code_buy'=>array('label'=>$langs->trans("ProductAccountancyBuyCode"), 'checked'=>0),
 	'p.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
@@ -159,6 +168,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab
    }
 }
 
+
 		    
 /*
  * Actions
@@ -425,9 +435,11 @@ else
     		if (! empty($arrayfields['p.duration']['checked']))  print_liste_field_titre($arrayfields['p.duration']['label'], $_SERVER["PHP_SELF"],"p.duration","",$param,"",$sortfield,$sortorder);
     		if (! empty($arrayfields['p.sellprice']['checked']))  print_liste_field_titre($arrayfields['p.sellprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
     		if (! empty($arrayfields['p.minbuyprice']['checked']))  print_liste_field_titre($arrayfields['p.minbuyprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
+    		if (! empty($arrayfields['p.seuil_stock_alerte']['checked']))  print_liste_field_titre($arrayfields['p.seuil_stock_alerte']['label'], $_SERVER["PHP_SELF"],"p.seuil_stock_alerte","",$param,'align="right"',$sortfield,$sortorder);
     		if (! empty($arrayfields['p.desiredstock']['checked']))  print_liste_field_titre($arrayfields['p.desiredstock']['label'], $_SERVER["PHP_SELF"],"p.desiredstock","",$param,'align="right"',$sortfield,$sortorder);
-    		if (! empty($arrayfields['p.tobatch']['checked']))  print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder);
     		if (! empty($arrayfields['p.stock']['checked']))  print_liste_field_titre($arrayfields['p.stock']['label'], $_SERVER["PHP_SELF"],"p.stock","",$param,'align="right"',$sortfield,$sortorder);
+    		if (! empty($arrayfields['stock_virtual']['checked']))  print_liste_field_titre($arrayfields['stock_virtual']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
+    		if (! empty($arrayfields['p.tobatch']['checked']))  print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder);
     		if (! empty($arrayfields['p.accountancy_code_sell']['checked']))  print_liste_field_titre($arrayfields['p.accountancy_code_sell']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_sell","",$param,'',$sortfield,$sortorder);
     		if (! empty($arrayfields['p.accountancy_code_buy']['checked']))  print_liste_field_titre($arrayfields['p.accountancy_code_buy']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_buy","",$param,'',$sortfield,$sortorder);
     		if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
@@ -499,6 +511,13 @@ else
     			print '&nbsp;';
     			print '</td>';
     		}
+    	    // Limit for alert
+			if (! empty($arrayfields['p.seuil_stock_alerte']['checked']))
+    		{
+    			print '<td class="liste_titre">';
+    			print '&nbsp;';
+    			print '</td>';
+    		}
     		// Desired stock
 			if (! empty($arrayfields['p.desiredstock']['checked']))
     		{
@@ -506,11 +525,13 @@ else
     			print '&nbsp;';
     			print '</td>';
     		}
-    		// To batch
-			if (! empty($arrayfields['p.tobatch']['checked'])) print '<td class="liste_titre center">'.$form->selectyesno($search_tobatch, '', '', '', 1).'</td>';
     		// Stock
 			if (! empty($arrayfields['p.stock']['checked'])) print '<td class="liste_titre">&nbsp;</td>';
-    	    // Accountancy code sell
+    		// Stock
+			if (! empty($arrayfields['stock_virtual']['checked'])) print '<td class="liste_titre">&nbsp;</td>';
+			// To batch
+			if (! empty($arrayfields['p.tobatch']['checked'])) print '<td class="liste_titre center">'.$form->selectyesno($search_tobatch, '', '', '', 1).'</td>';
+			// Accountancy code sell
     		if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" name="search_accountancy_code_sell" size="6" value="'.dol_escape_htmltag($search_accountancy_code_sell).'"></td>';
     	    // Accountancy code sell
     		if (! empty($arrayfields['p.accountancy_code_buy']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" name="search_accountancy_code_buy" size="6" value="'.dol_escape_htmltag($search_accountancy_code_buy).'"></td>';
@@ -591,7 +612,16 @@ else
     			$product_static->status_buy = $objp->tobuy;
                 $product_static->status     = $objp->tosell;
 				$product_static->entity = $objp->entity;
-
+				
+				if (! empty($conf->stock->enabled) && $user->rights->stock->lire && $type != 1)	// To optimize call of load_stock
+				{
+				    if ($objp->fk_product_type != 1)    // Not a service
+				    {
+				        $product_static->load_stock('nobatch');             // Load stock_reel + stock_warehouse. This also call load_virtual_stock()
+				    }
+				}
+				 
+				
     			$var=!$var;
     			print '<tr '.$bc[$var].'>';
 
@@ -672,15 +702,16 @@ else
         			print '</td>';
     			}
 
-        		if (! empty($conf->stock->enabled) && $user->rights->stock->lire && $type != 1)	// To optimize call of load_stock
-    			{
+    		    // Limit alert
+		        if (! empty($arrayfields['p.seuil_stock_alerte']['checked']))
+        		{
+                    print '<td align="right">';
     				if ($objp->fk_product_type != 1)
     				{
-    					$product_static->id = $objp->rowid;
-    					$product_static->load_stock();
+                        print $objp->seuil_stock_alerte;
     				}
-    			}
-    			
+    				print '</td>';
+        		}
     			// Desired stock
 		        if (! empty($arrayfields['p.desiredstock']['checked']))
         		{
@@ -691,24 +722,35 @@ else
     				}
     				print '</td>';
         		}
-    		    // Desired stock
-		        if (! empty($arrayfields['p.tobatch']['checked']))
-        		{
-                    print '<td align="center">';
-    				print yn($objp->tobatch);
-    				print '</td>';
-        		}        		
 				// Stock
 		        if (! empty($arrayfields['p.stock']['checked']))
         		{
    					print '<td align="right">';
     				if ($objp->fk_product_type != 1)
     				{
-   						if ($product_static->stock_reel < $objp->seuil_stock_alerte) print img_warning($langs->trans("StockTooLow")).' ';
+   						if ($objp->seuil_stock_alerte != '' && $product_static->stock_reel < (float) $objp->seuil_stock_alerte) print img_warning($langs->trans("StockTooLow")).' ';
       					print $product_static->stock_reel;
     				}
     				print '</td>';
     			}
+    			// Stock
+		        if (! empty($arrayfields['stock_virtual']['checked']))
+        		{
+   					print '<td align="right">';
+    				if ($objp->fk_product_type != 1)
+    				{
+   						if ($objp->seuil_stock_alerte != '' && $product_static->stock_theorique < (float) $objp->seuil_stock_alerte) print img_warning($langs->trans("StockTooLow")).' ';
+      					print $product_static->stock_theorique;
+    				}
+    				print '</td>';
+    			}
+    			// Lot/Serial
+		        if (! empty($arrayfields['p.tobatch']['checked']))
+        		{
+                    print '<td align="center">';
+    				print yn($objp->tobatch);
+    				print '</td>';
+        		}        		
     			// Accountancy code sell
 		        if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print '<td>'.$objp->accountancy_code_sell.'</td>';
     			// Accountancy code sell
diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php
index 6642c1e35502f66c4140a2ff229297ad151e88e5..15a93d8070c6212776259ce801b93cfd2fbcf357 100644
--- a/htdocs/product/reassort.php
+++ b/htdocs/product/reassort.php
@@ -85,6 +85,13 @@ if (! empty($_POST["button_removefilter_x"]))
     $toolowstock='';
 }
 
+// Define virtualdiffersfromphysical
+$virtualdiffersfromphysical=0;
+if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
+{
+    $virtualdiffersfromphysical=1;		// According to increase/decrease stock options, virtual and physical stock may differs.
+}
+
 
 
 /*
@@ -193,11 +200,11 @@ if ($resql)
 
 	if ($sref || $snom || $sall || GETPOST('search'))
 	{
-		print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&amp;sall=".$sall."&amp;tosell=".$tosell."&amp;tobuy=".$tobuy.(!empty($search_categ) ? '&amp;search_categ='.$search_categ : '').(!empty($toolowstock) ? '&amp;toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num);
+		print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&amp;sall=".$sall."&amp;tosell=".$tosell."&amp;tobuy=".$tobuy.(!empty($search_categ) ? '&amp;search_categ='.$search_categ : '').(!empty($toolowstock) ? '&amp;toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, 'title_products');
 	}
 	else
 	{
-		print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&amp;type=$type":"").(!empty($search_categ) ? '&amp;search_categ='.$search_categ : '').(!empty($toolowstock) ? '&amp;toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num);
+		print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&amp;type=$type":"").(!empty($search_categ) ? '&amp;search_categ='.$search_categ : '').(!empty($toolowstock) ? '&amp;toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, 'title_products');
 	}
 
 	if (! empty($catid))
@@ -272,8 +279,7 @@ if ($resql)
 		
 	} 
 	
-	// TODO Add info of running suppliers/customers orders
-	//print_liste_field_titre($langs->trans("TheoreticalStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder);
+	if ($virtualdiffersfromphysical) print_liste_field_titre($langs->trans("VirtualStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder);
 	print_liste_field_titre('');
 	print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell",$param,"",'align="right"',$sortfield,$sortorder);
     print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"], "p.tobuy",$param,"",'align="right"',$sortfield,$sortorder);
@@ -287,16 +293,18 @@ if ($resql)
 	print '<td class="liste_titre">';
 	print '<input class="flat" type="text" name="snom" size="8" value="'.$snom.'">';
 	print '</td>';
+	// Duration
 	if (! empty($conf->service->enabled) && $type == 1)
 	{
 		print '<td class="liste_titre">';
 		print '&nbsp;';
 		print '</td>';
 	}
-	// Lot/Serial
+	// Stock limit
 	print '<td class="liste_titre">&nbsp;</td>';
 	print '<td class="liste_titre" align="right">&nbsp;</td>';
 	print '<td class="liste_titre">&nbsp;</td>';
+	if ($virtualdiffersfromphysical) print '<td class="liste_titre">&nbsp;</td>';
 	print '<td class="liste_titre">&nbsp;</td>';
 	print '<td class="liste_titre" colspan="'.$colspan_warehouse.'">&nbsp;</td>';
 	print '<td class="liste_titre" align="right">';
@@ -334,9 +342,10 @@ if ($resql)
 		//print '<td align="right">'.$objp->stock_theorique.'</td>';
 		print '<td align="right">'.$objp->seuil_stock_alerte.'</td>';
 		print '<td align="right">'.$objp->desiredstock.'</td>';
+		// Real stock
 		print '<td align="right">';
-        	if ($objp->seuil_stock_alerte && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
-		print $product->stock_reel;
+        if ($objp->seuil_stock_alerte != '' && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
+		print $objp->stock_physique;
 		print '</td>';
 		
 		/*
@@ -356,7 +365,14 @@ if ($resql)
 		
 			
 		
-		
+		// Virtual stock
+		if ($virtualdiffersfromphysical)
+		{
+	    		print '<td align="right">';
+			if ($objp->seuil_stock_alerte != '' && ($product->stock_theorique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
+	    		print $product->stock_theorique;
+	    		print '</td>';
+		}
 		print '<td align="right"><a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?idproduct='.$product->id.'">'.$langs->trans("Movements").'</a></td>';
 		print '<td align="right" class="nowrap">'.$product->LibStatut($objp->statut,5,0).'</td>';
         	print '<td align="right" class="nowrap">'.$product->LibStatut($objp->tobuy,5,1).'</td>';
diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php
index 3b77f9c5ba7e31d76f96cdce242b2a679b009e05..b0e4904715ed0ed50f8ef6bcc46efdc35de08f5d 100644
--- a/htdocs/product/reassortlot.php
+++ b/htdocs/product/reassortlot.php
@@ -204,11 +204,11 @@ if ($resql)
 
 	if ($sref || $snom || $sall || GETPOST('search'))
 	{
-		print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&amp;sall=".$sall."&amp;tosell=".$tosell."&amp;tobuy=".$tobuy, $sortfield, $sortorder,'',$num);
+		print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&amp;sall=".$sall."&amp;tosell=".$tosell."&amp;tobuy=".$tobuy, $sortfield, $sortorder,'',$num, 0, 'title_products');
 	}
 	else
 	{
-		print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&amp;type=$type":""), $sortfield, $sortorder,'',$num);
+		print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&amp;type=$type":""), $sortfield, $sortorder,'',$num, 0, 'title_products');
 	}
 
 	if (! empty($catid))
diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php
index 652c6d9dc363b5fdeb0ab67fe904793fc0ba255c..944fb3f8dfb62f61fa80a5d2d51f174acd6982db 100644
--- a/htdocs/product/stock/class/mouvementstock.class.php
+++ b/htdocs/product/stock/class/mouvementstock.class.php
@@ -220,10 +220,9 @@ class MouvementStock extends CommonObject
 			$oldqty=$product->stock_reel;
 			$oldpmp=$product->pmp;
 			$oldqtywarehouse=0;
-			//$oldpmpwarehouse=0;
 
 			// Test if there is already a record for couple (warehouse / product)
-			$num = 0;
+			$alreadyarecord = 0;
 			if (! $error)
 			{
 				$sql = "SELECT rowid, reel FROM ".MAIN_DB_PREFIX."product_stock";
@@ -236,9 +235,8 @@ class MouvementStock extends CommonObject
 					$obj = $this->db->fetch_object($resql);
 					if ($obj)
 					{
-						$num = 1;
+						$alreadyarecord = 1;
 						$oldqtywarehouse = $obj->reel;
-						//$oldpmpwarehouse = $obj->pmp;
 						$fk_product_stock = $obj->rowid;
 					}
 					$this->db->free($resql);
@@ -252,25 +250,12 @@ class MouvementStock extends CommonObject
 
 			// Calculate new PMP.
 			$newpmp=0;
-			//$newpmpwarehouse=0;
 			if (! $error)
 			{
 				// Note: PMP is calculated on stock input only (type of movement = 0 or 3). If type == 0 or 3, qty should be > 0.
 				// Note: Price should always be >0 or 0. PMP should be always >0 (calculated on input)
 				if (($type == 0 || $type == 3) && $price > 0)
 				{
-					// If we will change PMP for the warehouse we edit and the product, we must first check/clean that PMP is defined
-					// on every stock entry with old value (so global updated value will match recalculated value from product_stock)
-			/*		$sql = "UPDATE ".MAIN_DB_PREFIX."product_stock SET pmp = ".($oldpmp?$oldpmp:'0');
-					$sql.= " WHERE pmp = 0 AND fk_product = ".$fk_product;
-					dol_syslog(get_class($this)."::_create", LOG_DEBUG);
-					$resql=$this->db->query($sql);
-					if (! $resql)
-					{
-						$this->errors[]=$this->db->lasterror();
-						$error = -4;
-					}
-			*/
 					$oldqtytouse=($oldqty >= 0?$oldqty:0);
 					// We make a test on oldpmp>0 to avoid to use normal rule on old data with no pmp field defined
 					if ($oldpmp > 0) $newpmp=price2num((($oldqtytouse * $oldpmp) + ($qty * $price)) / ($oldqtytouse + $qty), 'MU');
@@ -278,13 +263,8 @@ class MouvementStock extends CommonObject
 					{
 						$newpmp=$price; // For this product, PMP was not yet set. We set it to input price.
 					}
-			/*
-					$oldqtywarehousetouse=$oldqtywarehouse;
-					if ($oldpmpwarehouse > 0) $newpmpwarehouse=price2num((($oldqtywarehousetouse * $oldpmpwarehouse) + ($qty * $price)) / ($oldqtywarehousetouse + $qty), 'MU');
-					else $newpmpwarehouse=$price;
-			*/
-					//print "oldqtytouse=".$oldqtytouse." oldpmp=".$oldpmp." oldqtywarehousetouse=".$oldqtywarehousetouse." oldpmpwarehouse=".$oldpmpwarehouse." ";
-					//print "qty=".$qty." newpmp=".$newpmp." newpmpwarehouse=".$newpmpwarehouse;
+					//print "oldqtytouse=".$oldqtytouse." oldpmp=".$oldpmp." oldqtywarehousetouse=".$oldqtywarehousetouse." ";
+					//print "qty=".$qty." newpmp=".$newpmp;
 					//exit;
 				}
 				else if ($type == 1 || $type == 2)
@@ -295,14 +275,13 @@ class MouvementStock extends CommonObject
 				else
 				{
 					$newpmp = $oldpmp;
-					//$newpmpwarehouse = $oldpmpwarehouse;
 				}
 			}
 
 			// Update stock quantity
 			if (! $error)
 			{
-				if ($num > 0)
+				if ($alreadyarecord > 0)
 				{
 					$sql = "UPDATE ".MAIN_DB_PREFIX."product_stock SET reel = reel + ".$qty;
 					$sql.= " WHERE fk_entrepot = ".$entrepot_id." AND fk_product = ".$fk_product;
@@ -339,11 +318,13 @@ class MouvementStock extends CommonObject
 			// Update PMP and denormalized value of stock qty at product level
 			if (! $error)
 			{
-				$sql = "UPDATE ".MAIN_DB_PREFIX."product SET pmp = ".$newpmp.", stock = ".$this->db->ifsql("stock IS NULL", 0, "stock") . " + ".$qty;
+				// $sql = "UPDATE ".MAIN_DB_PREFIX."product SET pmp = ".$newpmp.", stock = ".$this->db->ifsql("stock IS NULL", 0, "stock") . " + ".$qty;
+				// $sql.= " WHERE rowid = ".$fk_product;
+    			// Update pmp + denormalized fields because we change content of produt_stock. Warning: Do not use "SET p.stock", does not works with pgsql
+				$sql = "UPDATE ".MAIN_DB_PREFIX."product as p SET p.pmp = ".$newpmp.", ";
+				$sql.= " stock=(SELECT SUM(ps.reel) FROM ".MAIN_DB_PREFIX."product_stock ps WHERE ps.fk_product = p.rowid)";
 				$sql.= " WHERE rowid = ".$fk_product;
-				// May be this request is better:
-				// UPDATE llx_product p SET p.stock= (SELECT SUM(ps.reel) FROM llx_product_stock ps WHERE ps.fk_product = p.rowid);
-
+				print $sql;
 				dol_syslog(get_class($this)."::_create", LOG_DEBUG);
 				$resql=$this->db->query($sql);
 				if (! $resql)
@@ -352,6 +333,12 @@ class MouvementStock extends CommonObject
 					$error = -4;
 				}
 			}
+			
+		    // If stock is now 0, we can remove entry into llx_stock_product, but only if there is no child lines into llx_product_batch (detail of batch, because we can imagine
+		    // having a lot1/qty=X and lot2/qty=-X, so 0 but we must not loose repartition of different lot.
+		    $sql="DELETE FROM ".MAIN_DB_PREFIX."product_stock WHERE reel = 0 AND rowid NOT IN (SELECT fk_product_stock FROM ".MAIN_DB_PREFIX."product_batch as pb)";
+		    $resql=$this->db->query($sql);
+		    // We do not test error, it can fails if there is child in batch details
 		}
 
 		// Add movement for sub products (recursive call)
@@ -543,7 +530,7 @@ class MouvementStock extends CommonObject
 	 * Create or update batch record (update table llx_product_batch)
 	 *
 	 * @param	array|int	$dluo	Could be either 
-	 *                              - int if id of product_batch
+	 *                              - int if row id of product_batch table
 	 *                              - or complete array('fk_product_stock'=>, 'eatby'=>, 'sellby'=> , 'batchnumber'=>)
 	 * @param	int			$qty	Quantity of product with batch number. May be a negative amount.
 	 * @return 	int   				<0 if KO, else return productbatch id
diff --git a/htdocs/product/stock/massstockmove.php b/htdocs/product/stock/massstockmove.php
index 7d62699b425a05de90000fe6474f0eae3605ac82..c7b7ed41034bac885845ff9c124767be68f9f81e 100644
--- a/htdocs/product/stock/massstockmove.php
+++ b/htdocs/product/stock/massstockmove.php
@@ -185,7 +185,7 @@ if ($action == 'createmovements')
 			{
 				$result=$product->fetch($id_product);
 
-				$product->load_stock();	// Load array product->stock_warehouse
+				$product->load_stock('novirtual');	// Load array product->stock_warehouse
 
 				// Define value of products moved
 				$pricesrc=0;
diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php
index 190bf676c8a62ab75e209613f651fee92e1825ed..29ee33c56eb346da6dd4598444770ce31af70176 100644
--- a/htdocs/product/stock/mouvement.php
+++ b/htdocs/product/stock/mouvement.php
@@ -207,11 +207,10 @@ if ($action == "transfert_stock" && ! $cancel)
 
             $db->begin();
 
-            $product->load_stock();	// Load array product->stock_warehouse
+            $product->load_stock('novirtual');	// Load array product->stock_warehouse
 
             // Define value of products moved
             $pricesrc=0;
-            //if (isset($product->stock_warehouse[GETPOST("id_entrepot_source")]->pmp)) $pricesrc=$product->stock_warehouse[GETPOST("id_entrepot_source")]->pmp;
             if (isset($product->pmp)) $pricesrc=$product->pmp;
             $pricedest=$pricesrc;
             
diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php
index de30bc3d0b6008a6bab3f226e296cf2d81477436..05b0aecf5b61e57f3dee3f5d52f7d4aeaa2d67f1 100644
--- a/htdocs/product/stock/product.php
+++ b/htdocs/product/stock/product.php
@@ -185,7 +185,7 @@ if ($action == "correct_stock" && ! $cancel)
 // Transfer stock from a warehouse to another warehouse
 if ($action == "transfert_stock" && ! $cancel)
 {
-	if (! (GETPOST("id_entrepot_source",'int') > 0) || ! (GETPOST("id_entrepot_destination",'int') > 0))
+	if (! (GETPOST("id_entrepot",'int') > 0) || ! (GETPOST("id_entrepot_destination",'int') > 0))
 	{
 		setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
 		$error++;
@@ -197,7 +197,7 @@ if ($action == "transfert_stock" && ! $cancel)
 		$error++;
 		$action='transfert';
 	}
-	if (GETPOST("id_entrepot_source",'int') == GETPOST("id_entrepot_destination",'int'))
+	if (GETPOST("id_entrepot",'int') == GETPOST("id_entrepot_destination",'int'))
 	{
 		setEventMessages($langs->trans("ErrorSrcAndTargetWarehouseMustDiffers"), null, 'errors');
 		$error++;
@@ -225,7 +225,7 @@ if ($action == "transfert_stock" && ! $cancel)
 
 			$db->begin();
 
-			$object->load_stock();	// Load array product->stock_warehouse
+			$object->load_stock('novirtual');	// Load array product->stock_warehouse
 
 			// Define value of products moved
 			$pricesrc=0;
@@ -254,7 +254,7 @@ if ($action == "transfert_stock" && ! $cancel)
 				}
 				else
 				{
-					$srcwarehouseid=GETPOST('id_entrepot_source','int');
+					$srcwarehouseid=GETPOST('id_entrepot','int');
 					$batch=GETPOST('batch_number');
 					$eatby=$d_eatby;
 					$sellby=$d_sellby;
@@ -291,7 +291,7 @@ if ($action == "transfert_stock" && ! $cancel)
 				// Remove stock
 				$result1=$object->correct_stock(
 					$user,
-					GETPOST("id_entrepot_source"),
+					GETPOST("id_entrepot"),
 					GETPOST("nbpiece"),
 					1,
 					GETPOST("label"),
@@ -390,6 +390,7 @@ if ($id > 0 || $ref)
 {
 	$object = new Product($db);
 	$result = $object->fetch($id,$ref);
+	
 	$object->load_stock();
 
 	$help_url='EN:Module_Stocks_En|FR:Module_Stock|ES:M&oacute;dulo_Stocks';
@@ -480,7 +481,6 @@ if ($id > 0 || $ref)
         print '</td></tr>';
 
         // Real stock
-        $object->load_stock();
         $text_stock_options = '';
         $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)?$langs->trans("DeStockOnShipment").'<br>':'');
         $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)?$langs->trans("DeStockOnValidateOrder").'<br>':'');
@@ -702,9 +702,10 @@ if ($resql)
 		$entrepotstatic->id=$obj->rowid;
 		$entrepotstatic->libelle=$obj->label;
 		$entrepotstatic->lieu=$obj->lieu;
+		$stock_real = round($obj->reel, 10);
 		print '<tr '.$bc[$var].'>';
 		print '<td colspan="4">'.$entrepotstatic->getNomUrl(1).'</td>';
-		print '<td align="right">'.$obj->reel.($obj->reel<0?' '.img_warning():'').'</td>';
+		print '<td align="right">'.$stock_real.($stock_real < 0 ?' '.img_warning():'').'</td>';
 		// PMP
 		print '<td align="right">'.(price2num($object->pmp)?price2num($object->pmp,'MU'):'').'</td>';
 		// Value purchase
diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php
index c31699a12ef8b4e2a88de985dd2a2d6ded35fff3..7af08ee6575e7bc70131c0f664a2f28f690c28c8 100644
--- a/htdocs/product/stock/replenish.php
+++ b/htdocs/product/stock/replenish.php
@@ -69,6 +69,13 @@ if (!$sortorder) {
     $sortorder = 'ASC';
 }
 
+// Define virtualdiffersfromphysical
+$virtualdiffersfromphysical=0;
+if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
+{
+    $virtualdiffersfromphysical=1;		// According to increase/decrease stock options, virtual and physical stock may differs.
+}
+
 
 /*
  * Actions
@@ -227,20 +234,6 @@ if ($action == 'order' && isset($_POST['valid']))
 
 $form = new Form($db);
 
-$virtualdiffersfromphysical=0;
-if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
-{
-	$virtualdiffersfromphysical=1;		// According to increase/decrease stock options, virtual and physical stock may differs.
-}
-
-$usevirtualstock=-1;
-if ($virtualdiffersfromphysical)
-{
-	$usevirtualstock=(! empty($conf->global->STOCK_USE_VIRTUAL_STOCK)?1:0);
-	if ($mode=='virtual') $usevirtualstock=1;
-	if ($mode=='physical') $usevirtualstock=0;
-}
-
 $title = $langs->trans('Status');
 
 $sql = 'SELECT p.rowid, p.ref, p.label, p.price,';
@@ -557,7 +550,7 @@ while ($i < ($limit ? min($num, $limit) : $num))
 		//print '<td><input type="checkbox" class="check" name="' . $i . '"' . $disabled . '></td>';
 		print '<td><input type="checkbox" class="check" name="'.$i.'"></td>';
 
-		print '<td class="nowrap">'.$prod->getNomUrl(1, '', 16).'</td>';
+		print '<td class="nowrap">'.$prod->getNomUrl(1, '').'</td>';
 
 		print '<td>' . $objp->label . '<input type="hidden" name="desc' . $i . '" value="' . $objp->label . '" ></td>';
 
diff --git a/htdocs/public/websites/index.php b/htdocs/public/websites/index.php
index fb3133df7cc4d86af5f44cbfd479ede404c08730..b54a69e90f9e40b16d5eca43d685f043ecf160d7 100644
--- a/htdocs/public/websites/index.php
+++ b/htdocs/public/websites/index.php
@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) 2009 Laurent Destailleur  <eldy@users.sourceforge.net>
+/* 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
@@ -16,16 +16,122 @@
  */
 
 /**
- *     	\file       htdocs/public/paypal/index.php
+ *     	\file       htdocs/public/websites/index.php
  *		\ingroup    core
  *		\brief      A redirect page to an error
  *		\author	    Laurent Destailleur
  */
 
+define('NOTOKENRENEWAL',1); // Disables token renewal
+define("NOLOGIN",1);
+define("NOCSRFCHECK",1);	// We accept to go on this page from external web site.
+if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1');
+if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1');
+if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
+
+/**
+ * Header empty
+ *
+ * @return	void
+ */
+function llxHeader() { }
+/**
+ * Footer empty
+ *
+ * @return	void
+ */
+function llxFooter() { }
+
 require '../../master.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+
+$error=0;
+$website=GETPOST('website', 'alpha');
+$page=GETPOST('page', 'alpha');
+$pageid=GETPOST('pageid', 'alpha');
+
+$accessallowed = 1;
+$type='';
+
+
+/*
+ * View
+ */
 
 $appli=constant('DOL_APPLICATION_TITLE');
 if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE;
 
-print 'Directory with '.$appli.' websites.<br>';
+//print 'Directory with '.$appli.' websites.<br>';
+
+if (empty($pageid))
+{
+    require_once DOL_DOCUMENT_ROOT.'/websites/class/website.class.php';
+    require_once DOL_DOCUMENT_ROOT.'/websites/class/websitepage.class.php';
+    
+    $object=new Website($db);
+    $object->fetch(0, $website);
+    
+    $objectpage=new WebsitePage($db);
+    $array=$objectpage->fetchAll($object->id);
+    
+    if (count($array) > 0)
+    {
+        $firstrep=reset($array);
+        $pageid=$firstrep->id;
+    }
+}
+
+
+// Security: Delete string ../ into $original_file
+global $dolibarr_main_data_root;
+
+if ($pageid == 'css')
+{
+    $original_file=$dolibarr_main_data_root.'/websites/'.$website.'/styles.css';
+}
+else
+{
+    $original_file=$dolibarr_main_data_root.'/websites/'.$website.'/page'.$pageid.'.tpl.php';
+}
+
+// Find the subdirectory name as the reference
+$refname=basename(dirname($original_file)."/");
+
+// Security:
+// Limite acces si droits non corrects
+if (! $accessallowed)
+{
+    accessforbidden();
+}
+
+// Security:
+// On interdit les remontees de repertoire ainsi que les pipe dans
+// les noms de fichiers.
+if (preg_match('/\.\./',$original_file) || preg_match('/[<>|]/',$original_file))
+{
+    dol_syslog("Refused to deliver file ".$original_file);
+    $file=basename($original_file);		// Do no show plain path of original_file in shown error message
+    dol_print_error(0,$langs->trans("ErrorFileNameInvalid",$file));
+    exit;
+}
+
+clearstatcache();
+
+$filename = basename($original_file);
+
+// Output file on browser
+dol_syslog("index.php include $original_file $filename content-type=$type");
+$original_file_osencoded=dol_osencode($original_file);	// New file name encoded in OS encoding charset
+
+// This test if file exists should be useless. We keep it to find bug more easily
+if (! file_exists($original_file_osencoded))
+{
+    dol_print_error(0,$langs->trans("ErrorFileDoesNotExists",$original_file));
+    exit;
+}
+
+include_once $original_file_osencoded;
+
+if (is_object($db)) $db->close();
 
diff --git a/htdocs/resource/add.php b/htdocs/resource/add.php
index 679ef5454422d5b8b3292d927dc47e25558b7543..cf13c79560ff64b1f86e4bc8dc78e0adba8a32d9 100644
--- a/htdocs/resource/add.php
+++ b/htdocs/resource/add.php
@@ -1,7 +1,7 @@
 <?php
-/* Copyright (C) 2013	Jean-François Ferry	 <jfefe@aternatik.fr>
- * Copyright (C) 2015	Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
- * Copyright (C) 2015	Laurent Destailleur  <eldy@users.sourceforge.net>
+/* Copyright (C) 2013   Jean-François Ferry      <jfefe@aternatik.fr>
+ * Copyright (C) 2015   Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
+ * Copyright (C) 2015   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
@@ -18,15 +18,14 @@
  */
 
 /**
- *   	\file       resource/add.php
- *		\ingroup    resource
- *		\brief      Page to manage resource object
- *					Initialy built by build_class_from_table on 2013-07-24 16:03
+ *  \file       resource/add.php
+ *  \ingroup    resource
+ *  \brief      Page to manage resource object
  */
 
 require '../main.inc.php';
 
-require_once DOL_DOCUMENT_ROOT.'/resource/class/resource.class.php';
+require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php';
 require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php';
 
 // Load traductions files required by page
@@ -36,15 +35,15 @@ $langs->load("other");
 $langs->load("resource");
 
 // Get parameters
-$id			= GETPOST('id','int');
-$action		= GETPOST('action','alpha');
-$cancel		= GETPOST('cancel','alpha');
+$id                     = GETPOST('id','int');
+$action         = GETPOST('action','alpha');
+$cancel         = GETPOST('cancel','alpha');
 if (empty($sortorder)) $sortorder="DESC";
 if (empty($sortfield)) $sortfield="t.rowid";
 if (empty($arch)) $arch = 0;
 
 if ($page == -1) {
-	$page = 0 ;
+        $page = 0 ;
 }
 
 $limit = $conf->global->limit;
@@ -56,60 +55,60 @@ $pagenext = $page + 1;
 // Protection if external user
 if ($user->societe_id > 0)
 {
-	accessforbidden();
+        accessforbidden();
 }
 
-$object = new Resource($db);
+$object = new DolResource($db);
 
 if ($action == 'confirm_add_resource')
 {
-	if (! $cancel)
-	{
-		$error='';
-
-		$ref=GETPOST('ref','alpha');
-		$description=GETPOST('description','alpha');
-		$fk_code_type_resource=GETPOST('fk_code_type_resource','alpha');
-
-		if (empty($ref))
-		{
-			$mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref"));
-			setEventMessages($mesg, null, 'errors');
-			$error++;
-		}
-
-		if (! $error)
-		{
-			$object=new Resource($db);
-			$object->ref=$ref;
-			$object->description=$description;
-			$object->fk_code_type_resource=$fk_code_type_resource;
-
-			$result=$object->create($user);
-			if ($result > 0)
-			{
-				// Creation OK
-				$db->commit();
-				setEventMessages($langs->trans('ResourceCreatedWithSuccess'), null, 'mesgs');
-				Header("Location: card.php?id=" . $object->id);
-				return;
-			}
-			else
-			{
-				// Creation KO
-				setEventMessages($object->error, $object->errors, 'errors');
-				$action = '';
-			}
-		}
-		else
-		{
-			$action = '';
-		}
-	}
-	else
-	{
-		Header("Location: list.php");
-	}
+        if (! $cancel)
+        {
+                $error='';
+
+                $ref=GETPOST('ref','alpha');
+                $description=GETPOST('description','alpha');
+                $fk_code_type_resource=GETPOST('fk_code_type_resource','alpha');
+
+                if (empty($ref))
+                {
+                        $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref"));
+                        setEventMessages($mesg, null, 'errors');
+                        $error++;
+                }
+
+                if (! $error)
+                {
+                        $object=new Dolresource($db);
+                        $object->ref=$ref;
+                        $object->description=$description;
+                        $object->fk_code_type_resource=$fk_code_type_resource;
+
+                        $result=$object->create($user);
+                        if ($result > 0)
+                        {
+                                // Creation OK
+                                $db->commit();
+                                setEventMessages($langs->trans('ResourceCreatedWithSuccess'), null, 'mesgs');
+                                Header("Location: card.php?id=" . $object->id);
+                                return;
+                        }
+                        else
+                        {
+                                // Creation KO
+                                setEventMessages($object->error, $object->errors, 'errors');
+                                $action = '';
+                        }
+                }
+                else
+                {
+                        $action = '';
+                }
+        }
+        else
+        {
+                Header("Location: list.php");
+        }
 }
 
 
@@ -122,58 +121,58 @@ $formresource = new FormResource($db);
 
 if (! $action)
 {
-	$pagetitle=$langs->trans('AddResource');
-	llxHeader('',$pagetitle,'');
-	print load_fiche_titre($pagetitle,'','title_generic');
-
-	print '<form method="post" action="'.$_SERVER['PHP_SELF'].'" name="add_resource">';
-	print '<input type="hidden" name="action" value="confirm_add_resource" />';
-
-	dol_fiche_head('');
-
-	print '<table class="border" width="100%">';
-
-	// Ref / label
-	$field = 'ref';
-	print '<tr>';
-	print '<td class="fieldrequired">';
-	print $langs->trans('ResourceFormLabel_'.$field);
-	print '</td>';
-	print '<td>';
-	print '<input type="text" name="'.$field.'" value="'.$$field.'" />';
-	print '</td>';
-	print '</tr>';
-
-	// Type
-	print '<tr><td width="20%">'.$langs->trans("ResourceType").'</td>';
-	print '<td>';
-	$ret = $formresource->select_types_resource($object->fk_code_type_resource, 'fk_code_type_resource', '', 2, 1);
-	print '</td></tr>';
-
-	// Description
-	$field = 'description';
-	print '<tr>';
-	print '<td class="tdtop">';
-	print $langs->trans('ResourceFormLabel_'.$field);
-	print '</td>';
-	print '<td>';
-	require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-	$doleditor = new DolEditor($field, $$field, 160, '', '', false);
-	$doleditor->Create();
-	print '</td>';
-	print '</tr>';
-
-	print '</table>';
-
-	dol_fiche_end('');
-
-	echo '<div align="center">',
-	'<input type="submit" class="button" name="add" value="'.$langs->trans('Save').'" />',
-	' &nbsp; ',
-	'<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'" />',
-	'</div>';
-
-	print '</form>';
+        $pagetitle=$langs->trans('AddResource');
+        llxHeader('',$pagetitle,'');
+        print load_fiche_titre($pagetitle,'','title_generic');
+
+        print '<form method="post" action="'.$_SERVER['PHP_SELF'].'" name="add_resource">';
+        print '<input type="hidden" name="action" value="confirm_add_resource" />';
+
+        dol_fiche_head('');
+
+        print '<table class="border" width="100%">';
+
+        // Ref / label
+        $field = 'ref';
+        print '<tr>';
+        print '<td class="fieldrequired">';
+        print $langs->trans('ResourceFormLabel_'.$field);
+        print '</td>';
+        print '<td>';
+        print '<input type="text" name="'.$field.'" value="'.$$field.'" />';
+        print '</td>';
+        print '</tr>';
+
+        // Type
+        print '<tr><td width="20%">'.$langs->trans("ResourceType").'</td>';
+        print '<td>';
+        $ret = $formresource->select_types_resource($object->fk_code_type_resource, 'fk_code_type_resource', '', 2, 1);
+        print '</td></tr>';
+
+        // Description
+        $field = 'description';
+        print '<tr>';
+        print '<td class="tdtop">';
+        print $langs->trans('ResourceFormLabel_'.$field);
+        print '</td>';
+        print '<td>';
+        require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
+        $doleditor = new DolEditor($field, $$field, 160, '', '', false);
+        $doleditor->Create();
+        print '</td>';
+        print '</tr>';
+
+        print '</table>';
+
+        dol_fiche_end('');
+
+        echo '<div align="center">',
+        '<input type="submit" class="button" name="add" value="'.$langs->trans('Save').'" />',
+        ' &nbsp; ',
+        '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'" />',
+        '</div>';
+
+        print '</form>';
 }
 
 
diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php
index 31fb6a955b17b8c8d16a471bb9fcf02a4519d6d9..163eeab13ce83d6c61f82c41360e8298e794d601 100644
--- a/htdocs/resource/card.php
+++ b/htdocs/resource/card.php
@@ -29,7 +29,7 @@ if (! $res) $res=@include("../../main.inc.php");	// For "custom" directory
 if (! $res) die("Include of main fails");
 
 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
-require_once 'class/resource.class.php';
+require_once 'class/dolresource.class.php';
 require_once 'class/html.formresource.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php';
 
@@ -56,7 +56,7 @@ if ($user->societe_id > 0)
 if( ! $user->rights->resource->read)
 	accessforbidden();
 
-$object = new Resource($db);
+$object = new Dolresource($db);
 
 $hookmanager->initHooks(array('resource_card','globalcard'));
 $parameters=array('resource_id'=>$id);
@@ -152,7 +152,7 @@ $formresource = new FormResource($db);
 
 if ( $object->fetch($id) > 0 )
 {
-	$head=resourcePrepareHead($object);
+	$head=resource_prepare_head($object);
 
 
 	if ($action == 'edit' )
diff --git a/htdocs/resource/class/resource.class.php b/htdocs/resource/class/dolresource.class.php
similarity index 99%
rename from htdocs/resource/class/resource.class.php
rename to htdocs/resource/class/dolresource.class.php
index bfd4f04c3e5ab1b0964949e0abc6c8bb941297c9..b6b4eec8be23a3daa23dd846272d4ae67da3e426 100644
--- a/htdocs/resource/class/resource.class.php
+++ b/htdocs/resource/class/dolresource.class.php
@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) 2013	Jean-François Ferry	<jfefe@aternatik.fr>
+/* Copyright (C) 2013-2015	Jean-François Ferry	<jfefe@aternatik.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@ require_once DOL_DOCUMENT_ROOT."/core/lib/functions2.lib.php";
 /**
  *	DAO Resource object
  */
-class Resource extends CommonObject
+class Dolresource extends CommonObject
 {
 	var $element='resource';			//!< Id that identify managed objects
 	var $table_element='resource';	//!< Name of table without prefix where object is stored
@@ -414,7 +414,7 @@ class Resource extends CommonObject
     			while ($i < $num)
     			{
     				$obj = $this->db->fetch_object($resql);
-    				$line = new Resource($this->db);
+    				$line = new Dolresource($this->db);
     				$line->id						=	$obj->rowid;
     				$line->ref						=	$obj->ref;
     				$line->description				=	$obj->description;
@@ -488,7 +488,7 @@ class Resource extends CommonObject
    				while ($i < $num)
    				{
    					$obj = $this->db->fetch_object($resql);
-   					$line = new Resource($this->db);
+   					$line = new Dolresource($this->db);
    					$line->id				=	$obj->rowid;
    					$line->resource_id		=	$obj->resource_id;
    					$line->resource_type	=	$obj->resource_type;
@@ -574,7 +574,7 @@ class Resource extends CommonObject
     			while ($i < $num)
     			{
     				$obj = $this->db->fetch_object($resql);
-    				$line = new Resource($this->db);
+    				$line = new Dolresource($this->db);
     				$line->id				=	$obj->rowid;
     				$line->resource_id		=	$obj->resource_id;
     				$line->resource_type	=	$obj->resource_type;
diff --git a/htdocs/resource/class/html.formresource.class.php b/htdocs/resource/class/html.formresource.class.php
index 4128de6feadff9c0cac0bd104bba4d9085b6d1fa..82b0ebe7d1ac314d8e525a61ecd96285b8aebaa6 100644
--- a/htdocs/resource/class/html.formresource.class.php
+++ b/htdocs/resource/class/html.formresource.class.php
@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) - 2013	Jean-François FERRY	<jfefe@aternatik.fr>
+/* Copyright (C) - 2013-2015 Jean-François FERRY	<jfefe@aternatik.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
  */
 
 /**
- *       \file       place/class/html.place.class.php
+ *       \file       place/class/html.formresource.class.php
  *       \ingroup    core
  *       \brief      Class file to manage forms into resource module
  */
@@ -75,7 +75,7 @@ class FormResource
     	$out='';
     	$outarray=array();
 
-    	$resourcestat = new Resource($this->db);
+    	$resourcestat = new Dolresource($this->db);
 
     	$resources_used = $resourcestat->fetch_all('ASC', 't.rowid', $limit, $offset, $filter='');
 
@@ -159,7 +159,7 @@ class FormResource
     {
     	global $langs,$user;
 
-    	$resourcestat = new Resource($this->db);
+    	$resourcestat = new Dolresource($this->db);
 
     	dol_syslog(get_class($this)."::select_types_resource ".$selected.", ".$htmlname.", ".$filtertype.", ".$format,LOG_DEBUG);
 
diff --git a/htdocs/resource/contact.php b/htdocs/resource/contact.php
new file mode 100644
index 0000000000000000000000000000000000000000..d635ee2e1e6ad1dc4d099458cfd64f0d14a73ba1
--- /dev/null
+++ b/htdocs/resource/contact.php
@@ -0,0 +1,159 @@
+<?php
+/* Copyright (C) 2005-2012  Regis Houssin        <regis.houssin@capnetworks.com>
+ * Copyright (C) 2007-2009  Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2012       Juanjo Menent        <jmenent@2byte.es>
+ * Copyright (C) 2016		    Gilles Poirier		   <glgpoirier@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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *       \file       htdocs/resource/contact.php
+ *       \ingroup    resource
+ *       \brief      Onglet de gestion des contacts des resources
+ */
+
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php';
+require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
+
+$langs->load("resource");
+$langs->load("sendings");
+$langs->load("companies");
+
+$id = GETPOST('id','int');
+$ref = GETPOST('ref', 'alpha');
+$action = GETPOST('action','alpha');
+
+// Security check
+if ($user->societe_id) $socid=$user->societe_id;
+$result = restrictedArea($user, 'resource', $id, 'resource');
+
+$object = new DolResource($db);
+$result = $object->fetch($id,$ref);
+
+
+/*
+ * Ajout d'un nouveau contact
+ */
+
+if ($action == 'addcontact' && $user->rights->resource->write)
+{
+    if ($result > 0 && $id > 0)
+    {
+    	$contactid = (GETPOST('userid','int') ? GETPOST('userid','int') : GETPOST('contactid','int'));
+  		$result = $object->add_contact($contactid, GETPOST('type','int'), GETPOST('source','alpha'));
+    }
+
+	if ($result >= 0)
+	{
+		header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
+		exit;
+	}
+	else
+	{
+		if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
+			$langs->load("errors");
+			$mesg = $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType");
+		} else {
+			$mesg = $object->error;
+		}
+
+		setEventMessage($mesg, 'errors');
+	}
+}
+
+// bascule du statut d'un contact
+else if ($action == 'swapstatut' && $user->rights->resource->write)
+{
+    $result=$object->swapContactStatus(GETPOST('ligne','int'));
+}
+
+// Efface un contact
+else if ($action == 'deletecontact' && $user->rights->resource->write)
+{
+	$result = $object->delete_contact(GETPOST('lineid','int'));
+
+	if ($result >= 0)
+	{
+		header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
+		exit;
+	}
+	else {
+		dol_print_error($db);
+	}
+}
+
+
+/*
+ * View
+ */
+
+$form = new Form($db);
+$formcompany = new FormCompany($db);
+$contactstatic=new Contact($db);
+$userstatic=new User($db);
+
+llxHeader('',$langs->trans("Resource"));
+
+// Mode vue et edition
+
+if ($id > 0 || ! empty($ref))
+{
+	$soc = new Societe($db);
+	$soc->fetch($object->socid);
+
+
+	$head = resource_prepare_head($object);
+	dol_fiche_head($head, 'contact', $langs->trans("ResourceSingular"), 0, 'resource@resource');
+
+
+	/*
+	*   Resource synthese pour rappel
+	*/
+	print '<table width="100%" class="border">';
+
+	print '<tr><td style="width:35%">'.$langs->trans("ResourceFormLabel_ref").'</td><td>';
+	$linkback = $objet->ref.' <a href="list.php">'.$langs->trans("BackToList").'</a>';
+	print $form->showrefnav($object, 'id', $linkback,1,"rowid");
+	print '</td>';
+	print '</tr>';
+
+	// Resource type
+	print '<tr>';
+	print '<td>' . $langs->trans("ResourceType") . '</td>';
+	print '<td>';
+	print $object->type_label;
+	print '</td>';
+	print '</tr>';
+
+	print '</table>';
+	print '</div>';
+
+	print '<br>';
+
+	if (! empty($conf->global->RESOURCE_HIDE_ADD_CONTACT_USER))     $hideaddcontactforuser=1;
+	if (! empty($conf->global->RESOURCE_HIDE_ADD_CONTACT_THIPARTY)) $hideaddcontactforthirdparty=1;
+
+	$permission=1;
+	// Contacts lines
+	include DOL_DOCUMENT_ROOT.'/core/tpl/contacts.tpl.php';
+}
+
+
+llxFooter();
+$db->close();
diff --git a/htdocs/resource/document.php b/htdocs/resource/document.php
new file mode 100644
index 0000000000000000000000000000000000000000..a21bc88c31967e98ffa5112ab060d6ff69ec8978
--- /dev/null
+++ b/htdocs/resource/document.php
@@ -0,0 +1,141 @@
+<?php
+/* Copyright (C) 2003-2007 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
+ * Copyright (C) 2004-2010 Laurent Destailleur   <eldy@users.sourceforge.net>
+ * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
+ * Copyright (C) 2005-2009 Regis Houssin         <regis.houssin@capnetworks.com>
+ * Copyright (C) 2005      Simon TOSSER          <simon@kornog-computing.com>
+ * Copyright (C) 2011-2012 Juanjo Menent         <jmenent@2byte.es>
+ * Copyright (C) 2013      Cédric Salvador       <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2016		   Gilles Poirier 		   <glgpoirier@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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *       \file       htdocs/resource/document.php
+ *       \ingroup    resource
+ *       \brief      Page des documents joints sur les resources
+ */
+
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
+
+$langs->load("other");
+$langs->load("resource");
+$langs->load("companies");
+
+$id = GETPOST('id','int');
+$ref = GETPOST('ref', 'alpha');
+$action = GETPOST('action','alpha');
+$confirm = GETPOST('confirm','alpha');
+
+// Security check
+if ($user->societe_id) $socid=$user->societe_id;
+$result = restrictedArea($user, 'resource', $id, 'resource');
+
+
+// Get parameters
+$sortfield = GETPOST('sortfield','alpha');
+$sortorder = GETPOST('sortorder','alpha');
+$page = GETPOST('page','int');
+if ($page == -1) { $page = 0; }
+$offset = $conf->liste_limit * $page;
+$pageprev = $page - 1;
+$pagenext = $page + 1;
+if (! $sortorder) $sortorder="ASC";
+if (! $sortfield) $sortfield="name";
+
+
+$object = new DolResource($db);
+$object->fetch($id, $ref);
+
+$upload_dir = $conf->resource->dir_output.'/'.dol_sanitizeFileName($object->ref);
+$modulepart='resource';
+
+
+/*
+ * Actions
+ */
+
+include_once DOL_DOCUMENT_ROOT . '/core/actions_linkedfiles.inc.php';
+
+
+/*
+ * View
+ */
+
+$form = new Form($db);
+
+llxHeader('',$langs->trans("Resource"));
+
+if ($object->id)
+{
+	$object->fetch_thirdparty();
+
+	$head=resource_prepare_head($object);
+
+	dol_fiche_head($head, 'documents',  $langs->trans("ResourceSingular"), 0, 'resource');
+
+
+	// Construit liste des fichiers
+	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
+	$totalsize=0;
+	foreach($filearray as $key => $file)
+	{
+		$totalsize+=$file['size'];
+	}
+
+
+    print '<table class="border" width="100%">';
+
+
+	print '<tr><td style="width:35%">'.$langs->trans("ResourceFormLabel_ref").'</td><td>';
+	$linkback = $objet->ref.' <a href="list.php">'.$langs->trans("BackToList").'</a>';
+	print $form->showrefnav($object, 'id', $linkback,1,"rowid");
+	print '</td>';
+	print '</tr>';
+
+	// Resource type
+	print '<tr>';
+	print '<td>' . $langs->trans("ResourceType") . '</td>';
+	print '<td>';
+	print $object->type_label;
+	print '</td>';
+	print '</tr>';
+
+    print '<tr><td>'.$langs->trans("NbOfAttachedFiles").'</td><td colspan="3">'.count($filearray).'</td></tr>';
+    print '<tr><td>'.$langs->trans("TotalSizeOfAttachedFiles").'</td><td colspan="3">'.$totalsize.' '.$langs->trans("bytes").'</td></tr>';
+    print '</table>';
+
+    print '</div>';
+
+    $modulepart = 'dolresource';
+    $permission = $user->rights->resource->write;
+    $param = '&id=' . $object->id;
+    include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
+
+}
+else
+{
+	print $langs->trans("ErrorUnknown");
+}
+
+
+llxFooter();
+
+$db->close();
diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php
index e4477e1674ad9f0386a610a1ed400af60652411f..59a95f6f57a6a1736f7f78d17d8a0f1f5b3e6d77 100644
--- a/htdocs/resource/element_resource.php
+++ b/htdocs/resource/element_resource.php
@@ -1,5 +1,6 @@
 <?php
-/* Copyright (C) 2013	Jean-François Ferry	<jfefe@aternatik.fr>
+/* Copyright (C) 2013		Jean-François Ferry	<jfefe@aternatik.fr>
+ * Copyright (C) 2016		Gilles Poirier 		<glgpoirier@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
@@ -16,18 +17,18 @@
  */
 
 /**
- *   	\file       resource/element_resource.php
- *		\ingroup    resource
- *		\brief      Page to show and manage linked resources to an element
+ *      \file       resource/element_resource.php
+ *      \ingroup    resource
+ *      \brief      Page to show and manage linked resources to an element
  */
 
 
 $res=0;
-$res=@include("../main.inc.php");				// For root directory
-if (! $res) $res=@include("../../main.inc.php");	// For "custom" directory
+$res=@include("../main.inc.php");                               // For root directory
+if (! $res) $res=@include("../../main.inc.php");        // For "custom" directory
 if (! $res) die("Include of main fails");
 
-require 'class/resource.class.php';
+require 'class/dolresource.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 
 // Load traductions files requiredby by page
@@ -35,92 +36,92 @@ $langs->load("resource");
 $langs->load("other");
 
 /*
-$sortorder			= GETPOST('sortorder','alpha');
-$sortfield			= GETPOST('sortfield','alpha');
-$page				= GETPOST('page','int');
+$sortorder                      = GETPOST('sortorder','alpha');
+$sortfield                      = GETPOST('sortfield','alpha');
+$page                           = GETPOST('page','int');
 */
 
 if( ! $user->rights->resource->read)
-	accessforbidden();
+        accessforbidden();
 
-$object=new Resource($db);
+$object=new Dolresource($db);
 
 $hookmanager->initHooks(array('element_resource'));
-$object->available_resources = array('resource');
+$object->available_resources = array('dolresource');
 
 // Get parameters
-$id			    = GETPOST('id','int');
-$action			= GETPOST('action','alpha');
-$mode			= GETPOST('mode','alpha');
-$lineid			= GETPOST('lineid','int');
-$element 		= GETPOST('element','alpha');			// element_type
-$element_id		= GETPOST('element_id','int');
-$resource_id 	= GETPOST('fk_resource','int');
-$resource_type	= GETPOST('resource_type','alpha');
-$busy 			= GETPOST('busy','int');
-$mandatory 		= GETPOST('mandatory','int');
-$cancel			= GETPOST('cancel','alpha');
-$confirm        = GETPOST('confirm','alpha');
-$socid          = GETPOST('socid','int');
-
-if ($socid > 0) 
+$id                         = GETPOST('id','int');
+$action                 = GETPOST('action','alpha');
+$mode                   = GETPOST('mode','alpha');
+$lineid                 = GETPOST('lineid','int');
+$element                = GETPOST('element','alpha');                   // element_type
+$element_id             = GETPOST('element_id','int');
+$resource_id            = GETPOST('fk_resource','int');
+$resource_type          = GETPOST('resource_type','alpha');
+$busy                   = GETPOST('busy','int');
+$mandatory              = GETPOST('mandatory','int');
+$cancel                 = GETPOST('cancel','alpha');
+$confirm                = GETPOST('confirm','alpha');
+$socid                  = GETPOST('socid','int');
+
+if ($socid > 0)
 {
     $element_id = $socid;
     $element = 'societe';
 }
 
-    
-    
+
+
 /*
  * Actions
  */
 
 if ($action == 'add_element_resource' && ! $cancel)
 {
-	$error++;
-	$res = 0;
-	if (! ($resource_id > 0))
-	{
-	    $error++;
+        $error++;
+        $res = 0;
+        if (! ($resource_id > 0))
+        {
+            $error++;
         setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Resource")), null, 'errors');
         $action='';
-	}
-	else
-	{
+        }
+        else
+        {
         $objstat = fetchObjectByElement($element_id, $element);
-	   
+
         $res = $objstat->add_element_resource($resource_id, $resource_type, $busy, $mandatory);
-	}
-	if (! $error && $res > 0)
-	{
-		setEventMessages($langs->trans('ResourceLinkedWithSuccess'), null, 'mesgs');
-		header("Location: ".$_SERVER['PHP_SELF'].'?element='.$element.'&element_id='.$element_id);
-		exit;
-	}
+        }
+        if (! $error && $res > 0)
+        {
+                setEventMessages($langs->trans('ResourceLinkedWithSuccess'), null, 'mesgs');
+                header("Location: ".$_SERVER['PHP_SELF'].'?element='.$element.'&element_id='.$element_id);
+                exit;
+        }
 }
 
 // Update ressource
 if ($action == 'update_linked_resource' && $user->rights->resource->write && !GETPOST('cancel') )
 {
-	$res = $object->fetch_element_resource($lineid);
-	if($res)
-	{
-		$object->busy = $busy;
-		$object->mandatory = $mandatory;
-
-		$result = $object->update_element_resource($user);
-
-		if ($result >= 0)
-		{
-			setEventMessages($langs->trans('RessourceLineSuccessfullyUpdated'), null, 'mesgs');
-			header("Location: ".$_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id);
-			exit;
-		}
-		else 
-		{
-			setEventMessages($object->error, $object->errors, 'errors');
-		}
-	}
+        $res = $object->fetch_element_resource($lineid);
+        if($res)
+        {
+                $object->busy = $busy;
+                $object->mandatory = $mandatory;
+
+                $result = $object->update_element_resource($user);
+
+                if ($result >= 0)
+                {
+                        setEventMessages($langs->trans('RessourceLineSuccessfullyUpdated'), null, 'mesgs');
+                        header("Location: ".$_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id);
+                        exit;
+                }
+                else
+                {
+                        setEventMessages($object->error, $object->errors, 'errors');
+                }
+        }
 }
 
 // Delete a resource linked to an element
@@ -134,7 +135,7 @@ if ($action == 'confirm_delete_linked_resource' && $user->rights->resource->dele
         header("Location: ".$_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id);
         exit;
     }
-    else 
+    else
     {
         setEventMessages($object->error, $object->errors, 'errors');
     }
@@ -164,149 +165,190 @@ llxHeader('',$pagetitle,'');
 // Load available resource, declared by modules
 $ret = count($object->available_resources);
 if($ret == -1) {
-	dol_print_error($db,$object->error);
-	exit;
+        dol_print_error($db,$object->error);
+        exit;
 }
 if(!$ret) {
-	print '<div class="warning">'.$langs->trans('NoResourceInDatabase').'</div>';
+        print '<div class="warning">'.$langs->trans('NoResourceInDatabase').'</div>';
 }
 else
 {
-	// Confirmation suppression resource line
-	if ($action == 'delete_resource')
-	{
-		print $form->formconfirm("element_resource.php?element=".$element."&element_id=".$element_id."&id=".$id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_linked_resource",'','',1);
-	}
+        // Confirmation suppression resource line
+        if ($action == 'delete_resource')
+        {
+                print $form->formconfirm("element_resource.php?element=".$element."&element_id=".$element_id."&id=".$id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_linked_resource",'','',1);
+        }
 
 
-	/*
-	 * Specific to agenda module
-	 */
-	if ($element_id && $element == 'action')
-	{
-		require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
+        /*
+         * Specific to agenda module
+         */
+        if ($element_id && $element == 'action')
+        {
+                require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
 
-		$act = fetchObjectByElement($element_id,$element);
-		if (is_object($act)) 
-		{
+                $act = fetchObjectByElement($element_id,$element);
+                if (is_object($act))
+                {
 
-			$head=actions_prepare_head($act);
+                        $head=actions_prepare_head($act);
 
-			dol_fiche_head($head, 'resources', $langs->trans("Action"),0,'action');
+                        dol_fiche_head($head, 'resources', $langs->trans("Action"),0,'action');
 
-			// Affichage fiche action en mode visu
-			print '<table class="border" width="100%">';
+                        // Affichage fiche action en mode visu
+                        print '<table class="border" width="100%">';
 
-			$linkback = '<a href="'.DOL_URL_ROOT.'/comm/action/listactions.php">'.$langs->trans("BackToList").'</a>';
+                        $linkback = '<a href="'.DOL_URL_ROOT.'/comm/action/listactions.php">'.$langs->trans("BackToList").'</a>';
 
-			// Ref
-			print '<tr><td width="30%">'.$langs->trans("Ref").'</td><td colspan="3">';
-			print $form->showrefnav($act, 'id', $linkback, ($user->societe_id?0:1), 'id', 'ref', '');
-			print '</td></tr>';
+                        // Ref
+                        print '<tr><td width="30%">'.$langs->trans("Ref").'</td><td colspan="3">';
+                        print $form->showrefnav($act, 'id', $linkback, ($user->societe_id?0:1), 'id', 'ref', '');
+                        print '</td></tr>';
 
-			// Type
-			if (! empty($conf->global->AGENDA_USE_EVENT_TYPE))
-			{
-				print '<tr><td>'.$langs->trans("Type").'</td><td colspan="3">'.$act->type.'</td></tr>';
-			}
+                        // Type
+                        if (! empty($conf->global->AGENDA_USE_EVENT_TYPE))
+                        {
+                                print '<tr><td>'.$langs->trans("Type").'</td><td colspan="3">'.$act->type.'</td></tr>';
+                        }
 
-			// Title
-			print '<tr><td>'.$langs->trans("Title").'</td><td colspan="3">'.$act->label.'</td></tr>';
-			print '</table>';
+                        // Title
+                        print '<tr><td>'.$langs->trans("Title").'</td><td colspan="3">'.$act->label.'</td></tr>';
+                        print '</table>';
 
-			dol_fiche_end();
-		}
-	}
+                        dol_fiche_end();
+                }
+        }
+
+        /*
+         * Specific to thirdparty module
+         */
+        if ($element_id && $element == 'societe')
+        {
+                $socstatic = fetchObjectByElement($element_id,$element);
+                if (is_object($socstatic))
+                {
+                    $savobject = $object;
+
+                    $object = $socstatic;
+
+                        require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
+                        $head = societe_prepare_head($socstatic);
+
+                        dol_fiche_head($head, 'resources', $langs->trans("ThirdParty"),0,'company');
+
+            dol_banner_tab($socstatic, 'socid', '', ($user->societe_id?0:1), 'rowid', 'nom');
+
+                print '<div class="fichecenter">';
+
+            print '<div class="underbanner clearboth"></div>';
+                print '<table class="border" width="100%">';
+
+                // Alias name (commercial, trademark or alias name)
+                print '<tr><td class="titelfield">'.$langs->trans('AliasNames').'</td><td colspan="3">';
+                print $socstatic->name_alias;
+                print "</td></tr>";
+
+                        print '</table>';
+
+                        print '</div>';
+
+                        dol_fiche_end();
+
+                        $object = $savobject;
+                }
+        }
 
 	/*
-	 * Specific to thirdparty module
+	 * Specific to fichinter module
 	 */
-	if ($element_id && $element == 'societe')
+	if ($element_id && $element == 'fichinter')
 	{
-		$socstatic = fetchObjectByElement($element_id,$element);
-		if (is_object($socstatic)) 
-		{
-		    $savobject = $object;
-		    
-		    $object = $socstatic;
-		    
-			require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
-			$head = societe_prepare_head($socstatic);
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/fichinter.lib.php';
 
-			dol_fiche_head($head, 'resources', $langs->trans("ThirdParty"),0,'company');
+		$fichinter = fetchObjectByElement($element_id, $element);
+		if (is_object($fichinter)) 
+		{
+			$head=fichinter_prepare_head($fichinter);
+			dol_fiche_head($head, 'resource', $langs->trans("InterventionCard"),0,'intervention');
 
-            dol_banner_tab($socstatic, 'socid', '', ($user->societe_id?0:1), 'rowid', 'nom');
-                
-        	print '<div class="fichecenter">';
-        
-            print '<div class="underbanner clearboth"></div>';
-        	print '<table class="border" width="100%">';
-        
-        	// Alias name (commercial, trademark or alias name)
-        	print '<tr><td class="titelfield">'.$langs->trans('AliasNames').'</td><td colspan="3">';
-        	print $socstatic->name_alias;
-        	print "</td></tr>";
+			// Affichage fiche action en mode visu
+			print '<table class="border" width="100%">';
 			
-			print '</table>';
+			$linkback = '<a href="'.DOL_URL_ROOT.'/fichinter/list.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
+
+			// Ref
+			print '<tr><td width="30%">'.$langs->trans("Ref").'</td><td colspan="3">';
+			print $form->showrefnav($fichinter, 'id', $linkback, ($user->societe_id?0:1), 'ref', 'ref', '');
+			print '</td></tr>';
+
+
+			// Customer
+			if ( is_null($fichinter->client) )
+				$fichinter->fetch_thirdparty();
+		
+			print "<tr><td>".$langs->trans("Company")."</td>";
+			print '<td colspan="3">'.$fichinter->client->getNomUrl(1).'</td></tr>';
+			print "</table>";
 
-			print '</div>';
-			
 			dol_fiche_end();
-			
-			$object = $savobject;
 		}
 	}
 
 
+	// hook for other elements linked
+	$parameters=array('element'=>$element, 'element_id'=>$element_id );
+	$reshook=$hookmanager->executeHooks('printElementTab',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
+	if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
-	//print load_fiche_titre($langs->trans('ResourcesLinkedToElement'),'','');
 
+        //print load_fiche_titre($langs->trans('ResourcesLinkedToElement'),'','');
 
 
-	foreach ($object->available_resources as $modresources => $resources)
-	{
-		$resources=(array) $resources;	// To be sure $resources is an array
-		foreach($resources as $resource_obj)
-		{
-			$element_prop = getElementProperties($resource_obj);
 
-			//print '/'.$modresources.'/class/'.$resource_obj.'.class.php<br />';
+        foreach ($object->available_resources as $modresources => $resources)
+        {
+                $resources=(array) $resources;  // To be sure $resources is an array
+                foreach($resources as $resource_obj)
+                {
+                        $element_prop = getElementProperties($resource_obj);
+
+                        //print '/'.$modresources.'/class/'.$resource_obj.'.class.php<br />';
 
-			$path = '';
-			if(strpos($resource_obj,'@'))
-				$path .= '/'.$element_prop['module'];
+                        $path = '';
+                        if(strpos($resource_obj,'@'))
+                                $path .= '/'.$element_prop['module'];
 
-			$linked_resources = $object->getElementResources($element,$element_id,$resource_obj);
+                        $linked_resources = $object->getElementResources($element,$element_id,$resource_obj);
 
 
-			// If we have a specific template we use it
-			if(file_exists(dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_add.tpl.php')))
-			{
-				$res=include dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_add.tpl.php');
-			}
-			else
-			{
-				$res=include DOL_DOCUMENT_ROOT . '/core/tpl/resource_add.tpl.php';
-			}
+                        // If we have a specific template we use it
+                        if(file_exists(dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_add.tpl.php')))
+                        {
+                                $res=include dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_add.tpl.php');
+                        }
+                        else
+                        {
+                                $res=include DOL_DOCUMENT_ROOT . '/core/tpl/resource_add.tpl.php';
+                        }
             //var_dump($element_id);
 
-			if ($mode != 'add' || $resource_obj != $resource_type)
-			{
-				//print load_fiche_titre($langs->trans(ucfirst($element_prop['element']).'Singular'));
-
-				// If we have a specific template we use it
-				if(file_exists(dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_view.tpl.php')))
-				{
-					$res=@include dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_view.tpl.php');
-
-				}
-				else
-				{
-					$res=include DOL_DOCUMENT_ROOT . '/core/tpl/resource_view.tpl.php';
-				}
-			}
-		}
-	}
+                        if ($mode != 'add' || $resource_obj != $resource_type)
+                        {
+                                //print load_fiche_titre($langs->trans(ucfirst($element_prop['element']).'Singular'));
+
+                                // If we have a specific template we use it
+                                if(file_exists(dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_view.tpl.php')))
+                                {
+                                        $res=@include dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_view.tpl.php');
+
+                                }
+                                else
+                                {
+                                        $res=include DOL_DOCUMENT_ROOT . '/core/tpl/resource_view.tpl.php';
+                                }
+                        }
+                }
+        }
 }
 
 llxFooter();
diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php
index 9bfa7309167237447cadc4883c216e4da97951e5..b33bbec259e7527dc62527d0cd0c047982d5d937 100644
--- a/htdocs/resource/list.php
+++ b/htdocs/resource/list.php
@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) 2013-2014	Jean-François Ferry	<jfefe@aternatik.fr>
+/* Copyright (C) 2013-2014      Jean-François Ferry     <jfefe@aternatik.fr>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,34 +16,34 @@
  */
 
 /**
- *   	\file       resource/index.php
- *		\ingroup    resource
- *		\brief      Page to manage resource objects
+ *      \file       resource/index.php
+ *              \ingroup    resource
+ *              \brief      Page to manage resource objects
  */
 
 
 require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/resource/class/resource.class.php';
+require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php';
 
-// Load translations files requiredby by page
+// Load translations files required by page
 $langs->load("resource");
 $langs->load("companies");
 $langs->load("other");
 
 // Get parameters
-$id			= GETPOST('id','int');
-$action		= GETPOST('action','alpha');
+$id                     = GETPOST('id','int');
+$action         = GETPOST('action','alpha');
 
-$lineid				= GETPOST('lineid','int');
-$element 			= GETPOST('element','alpha');
-$element_id			= GETPOST('element_id','int');
-$resource_id		= GETPOST('resource_id','int');
+$lineid                         = GETPOST('lineid','int');
+$element                        = GETPOST('element','alpha');
+$element_id                     = GETPOST('element_id','int');
+$resource_id            = GETPOST('resource_id','int');
 
-$sortorder	= GETPOST('sortorder','alpha');
-$sortfield	= GETPOST('sortfield','alpha');
-$page		= GETPOST('page','int');
+$sortorder      = GETPOST('sortorder','alpha');
+$sortfield      = GETPOST('sortfield','alpha');
+$page           = GETPOST('page','int');
 
-$object = new Resource($db);
+$object = new Dolresource($db);
 
 $hookmanager->initHooks(array('resource_list'));
 
@@ -52,7 +52,7 @@ if (empty($sortfield)) $sortfield="t.rowid";
 if (empty($arch)) $arch = 0;
 
 if ($page == -1) {
-	$page = 0 ;
+        $page = 0 ;
 }
 
 $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
@@ -61,7 +61,7 @@ $pageprev = $page - 1;
 $pagenext = $page + 1;
 
 if( ! $user->rights->resource->read)
-	accessforbidden();
+        accessforbidden();
 
 
 /*
@@ -86,72 +86,69 @@ llxHeader('',$pagetitle,'');
 // Confirmation suppression resource line
 if ($action == 'delete_resource')
 {
-	print $form->formconfirm($_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_resource",'','',1);
+        print $form->formconfirm($_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_resource",'','',1);
 }
 
 // Load object list
 $ret = $object->fetch_all($sortorder, $sortfield, $limit, $offset);
 if($ret == -1) {
-	dol_print_error($db,$object->error);
-	exit;
+        dol_print_error($db,$object->error);
+        exit;
 } else {
     print_barre_liste($pagetitle, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $ret+1, $object->num_all,'title_generic.png');
 }
 if(!$ret) {
-	print '<div class="warning">'.$langs->trans('NoResourceInDatabase').'</div>';
+        print '<div class="warning">'.$langs->trans('NoResourceInDatabase').'</div>';
 }
 else
 {
-	$var=true;
-
-	print '<table class="noborder" width="100%">'."\n";
-	print '<tr class="liste_titre">';
-	print_liste_field_titre($langs->trans('Id'),$_SERVER['PHP_SELF'],'t.rowid','',$param,'',$sortfield,$sortorder);
-	print_liste_field_titre($langs->trans('Ref'),$_SERVER['PHP_SELF'],'t.ref','',$param,'',$sortfield,$sortorder);
-	print_liste_field_titre($langs->trans('ResourceType'),$_SERVER['PHP_SELF'],'ty.code','',$param,'',$sortfield,$sortorder);
-	print_liste_field_titre($langs->trans('Action'),"","","","",'width="60" align="center"',"","");
-	print "</tr>\n";
-
-	foreach ($object->lines as $resource)
-	{
-		$var=!$var;
-
-		$style='';
-		if($resource->id == GETPOST('lineid'))
-			$style='style="background: orange;"';
-
-		print '<tr '.$bc[$var].' '.$style.'><td>';
-		print '<a href="./card.php?id='.$resource->id.'">'.$resource->id.'</a>';
-		print '</td>';
-
-		print '<td>';
-		print $resource->ref;
-		print '</td>';
-
-		print '<td>';
-		print $resource->type_label;
-		print '</td>';
-
-		print '<td align="center">';
-		print '<a href="./card.php?action=edit&id='.$resource->id.'">';
-		print img_edit();
-		print '</a>';
-		print '&nbsp;';
-		print '<a href="./card.php?action=delete&id='.$resource->id.'">';
-		print img_delete();
-		print '</a>';
-		print '</td>';
-
-		print '</tr>';
-	}
-
-	print '</table>';
+        $var=true;
+
+        print '<table class="noborder" width="100%">'."\n";
+        print '<tr class="liste_titre">';
+        print_liste_field_titre($langs->trans('Id'),$_SERVER['PHP_SELF'],'t.rowid','',$param,'',$sortfield,$sortorder);
+        print_liste_field_titre($langs->trans('Ref'),$_SERVER['PHP_SELF'],'t.ref','',$param,'',$sortfield,$sortorder);
+        print_liste_field_titre($langs->trans('ResourceType'),$_SERVER['PHP_SELF'],'ty.code','',$param,'',$sortfield,$sortorder);
+        print_liste_field_titre($langs->trans('Action'),"","","","",'width="60" align="center"',"","");
+        print "</tr>\n";
+
+        foreach ($object->lines as $resource)
+        {
+                $var=!$var;
+
+                $style='';
+                if($resource->id == GETPOST('lineid'))
+                        $style='style="background: orange;"';
+
+                print '<tr '.$bc[$var].' '.$style.'><td>';
+                print '<a href="./card.php?id='.$resource->id.'">'.$resource->id.'</a>';
+                print '</td>';
+
+                print '<td>';
+                print $resource->ref;
+                print '</td>';
+
+                print '<td>';
+                print $resource->type_label;
+                print '</td>';
+
+                print '<td align="center">';
+                print '<a href="./card.php?action=edit&id='.$resource->id.'">';
+                print img_edit();
+                print '</a>';
+                print '&nbsp;';
+                print '<a href="./card.php?action=delete&id='.$resource->id.'">';
+                print img_delete();
+                print '</a>';
+                print '</td>';
+
+                print '</tr>';
+        }
+
+        print '</table>';
 
 }
 
-
 llxFooter();
 
 $db->close();
-
-
diff --git a/htdocs/resource/note.php b/htdocs/resource/note.php
new file mode 100644
index 0000000000000000000000000000000000000000..e404a3bdef812c63b577c0dde1965368a2252c76
--- /dev/null
+++ b/htdocs/resource/note.php
@@ -0,0 +1,91 @@
+<?php
+/* Copyright (C) 2005-2012	Regis Houssin	  <regis.houssin@capnetworks.com>
+ * Copyright (C) 2011-2012	Juanjo Menent	  <jmenent@2byte.es>
+ * Copyright (C) 2013       Florian Henry   <florian.henry@open-concept.pro>
+ * Copyright (C) 2016	  	  Gilles Poirier  <glgpoirier@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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *	\file       htdocs/resource/note.php
+ *	\ingroup    fichinter
+ *	\brief      Fiche d'information sur une resource
+ */
+
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php';
+
+$langs->load('companies');
+$langs->load("interventions");
+
+$id = GETPOST('id','int');
+$ref = GETPOST('ref', 'alpha');
+$action=GETPOST('action','alpha');
+
+// Security check
+if ($user->societe_id) $socid=$user->societe_id;
+$result = restrictedArea($user, 'resource', $id, 'resource');
+
+$object = new DolResource($db);
+$object->fetch($id,$ref);
+
+$permissionnote=$user->rights->resource->write;	// Used by the include of actions_setnotes.inc.php
+
+/*
+ * Actions
+ */
+
+include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php';	// Must be include, not includ_once
+
+
+/*
+ * View
+ */
+
+llxHeader();
+
+$form = new Form($db);
+
+if ($id > 0 || ! empty($ref))
+{
+	$head = resource_prepare_head($object);
+	dol_fiche_head($head, 'note', $langs->trans('ResourceSingular'), 0, 'resource@resource');
+
+	print '<table class="border" width="100%">';
+	print '<tr><td class="titlefield">'.$langs->trans("ResourceFormLabel_ref").'</td><td>';
+	$linkback = $objet->ref.' <a href="list.php">'.$langs->trans("BackToList").'</a>';
+	print $form->showrefnav($object, 'id', $linkback,1,"rowid");
+	print '</td>';
+	print '</tr>';
+
+	// Resource type
+	print '<tr>';
+	print '<td>' . $langs->trans("ResourceType") . '</td>';
+	print '<td>';
+	print $object->type_label;
+	print '</td>';
+	print '</tr>';		print "</table>";
+
+	print '<br>';
+	$permission=$user->rights->resource->write;
+	$cssclass='titlefield';
+	include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php';
+
+	dol_fiche_end();
+}
+
+llxFooter();
+$db->close();
diff --git a/htdocs/societe/class/api_contact.class.php b/htdocs/societe/class/api_contact.class.php
index ba7c0d4a2119dfae640ac9111dcc33f2f06e4695..5144c000b4d634ba9aa2ba21bf0b574b89432a1a 100644
--- a/htdocs/societe/class/api_contact.class.php
+++ b/htdocs/societe/class/api_contact.class.php
@@ -251,7 +251,7 @@ class ContactApi extends DolibarrApi
 	 *
 	 * @param   int     $id Contact ID
 	 * @return  integer
-     * 
+   * 
 	 * @url	DELETE contact/{id}
 	 */
 	function delete($id) {
diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
index 17f96a93c3c912a6c160949dab7baa88bb9bcdd4..62364c57644c9524c68226e32a257c8172cd1048 100644
--- a/htdocs/societe/class/societe.class.php
+++ b/htdocs/societe/class/societe.class.php
@@ -832,7 +832,10 @@ class Societe extends CommonObject
             $sql .= ",prefix_comm = ".(! empty($this->prefix_comm)?"'".$this->db->escape($this->prefix_comm)."'":"null");
 
             $sql .= ",fk_effectif = ".(! empty($this->effectif_id)?"'".$this->db->escape($this->effectif_id)."'":"null");
-            $sql .= ",fk_stcomm='".$this->stcomm_id."'";
+            if (isset($this->stcomm_id))
+            {
+                $sql .= ",fk_stcomm='".$this->stcomm_id."'";
+            }
             $sql .= ",fk_typent = ".(! empty($this->typent_id)?"'".$this->db->escape($this->typent_id)."'":"0");
 
             $sql .= ",fk_forme_juridique = ".(! empty($this->forme_juridique_code)?"'".$this->db->escape($this->forme_juridique_code)."'":"null");
@@ -848,7 +851,7 @@ class Societe extends CommonObject
             $sql .= ",barcode = ".(! empty($this->barcode)?"'".$this->db->escape($this->barcode)."'":"null");
             $sql .= ",default_lang = ".(! empty($this->default_lang)?"'".$this->db->escape($this->default_lang)."'":"null");
             $sql .= ",logo = ".(! empty($this->logo)?"'".$this->db->escape($this->logo)."'":"null");
-            $sql .= ",outstanding_limit= '".($this->outstanding_limit!=''?$this->outstanding_limit:'null')."'";
+            $sql .= ",outstanding_limit= ".($this->outstanding_limit!=''?$this->outstanding_limit:'null');
             $sql .= ",fk_prospectlevel='".$this->fk_prospectlevel."'";
 
             $sql .= ",webservices_url = ".(! empty($this->webservices_url)?"'".$this->db->escape($this->webservices_url)."'":"null");
diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php
index eedcd449c0df86e9a1f898ca50f3aab7c92e431c..02543d469933691da8c8147bf936e8b0d69cbfa1 100644
--- a/htdocs/societe/soc.php
+++ b/htdocs/societe/soc.php
@@ -783,10 +783,14 @@ else
         $modCodeFournisseur = new $module;
 
         // Define if customer/prospect or supplier status is set or not
-        if (GETPOST("type")!='f' && empty($conf->global->THIRDPARTY_NOTCUSTOMERPROSPECT_BY_DEFAULT))  { $object->client=3; }
-        if (GETPOST("type")=='c')  { $object->client=1; }
+        if (GETPOST("type")!='f')
+        {
+            $object->client=-1;
+            if (! empty($conf->global->THIRDPARTY_CUSTOMERPROSPECT_BY_DEFAULT))  { $object->client=3; }
+        }
+        if (GETPOST("type")=='c')  { $object->client=3; }   // Prospect / Customer
         if (GETPOST("type")=='p')  { $object->client=2; }
-        if (! empty($conf->fournisseur->enabled) && (GETPOST("type")=='f' || (GETPOST("type")=='' && empty($conf->global->THIRDPARTY_NOTSUPPLIER_BY_DEFAULT))))  { $object->fournisseur=1; }
+        if (! empty($conf->fournisseur->enabled) && (GETPOST("type")=='f' || (GETPOST("type")=='' && ! empty($conf->global->THIRDPARTY_SUPPLIER_BY_DEFAULT))))  { $object->fournisseur=1; }
 
         $object->name				= GETPOST('name', 'alpha');
         $object->firstname			= GETPOST('firstname', 'alpha');
@@ -983,8 +987,9 @@ else
 
         // Prospect/Customer
         print '<tr><td width="25%">'.fieldLabel('ProspectCustomer','customerprospect',1).'</td>';
-	    print '<td width="25%" class="maxwidthonsmartphone"><select class="flat" name="client" id="customerprospect">';
-        $selected=isset($_POST['client'])?GETPOST('client'):$object->client;
+	    print '<td width="25%" class="maxwidthonsmartphone">';
+	    $selected=isset($_POST['client'])?GETPOST('client'):$object->client;
+        print '<select class="flat" name="client" id="customerprospect">';
         if (GETPOST("type") == '') print '<option value="-1"></option>';
         if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) print '<option value="2"'.($selected==2?' selected':'').'>'.$langs->trans('Prospect').'</option>';
         if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print '<option value="3"'.($selected==3?' selected':'').'>'.$langs->trans('ProspectCustomer').'</option>';
@@ -1008,7 +1013,9 @@ else
             // Supplier
             print '<tr>';
             print '<td>'.fieldLabel('Supplier','fournisseur',1).'</td><td>';
-            print $form->selectyesno("fournisseur", (isset($_POST['fournisseur'])?GETPOST('fournisseur'):(GETPOST("type") == '' ? -1 : $object->fournisseur)), 1, 0, (GETPOST("type") == '' ? 1 : 0));
+            $default = -1;
+            if (! empty($conf->global->THIRDPARTY_SUPPLIER_BY_DEFAULT)) $default=1;
+            print $form->selectyesno("fournisseur", (isset($_POST['fournisseur'])?GETPOST('fournisseur'):(GETPOST("type") == '' ? $default : $object->fournisseur)), 1, 0, (GETPOST("type") == '' ? 1 : 0));
             print '</td>';
             print '<td>'.fieldLabel('SupplierCode','supplier_code').'</td><td>';
             print '<table class="nobordernopadding"><tr><td>';
diff --git a/htdocs/theme/eldy/ckeditor/config.js b/htdocs/theme/eldy/ckeditor/config.js
index cffaadfba6e1f918383228a884880da8c1cae6ed..cf7163671a36f00385f07a275d568377c5999c6a 100644
--- a/htdocs/theme/eldy/ckeditor/config.js
+++ b/htdocs/theme/eldy/ckeditor/config.js
@@ -32,14 +32,12 @@ CKEDITOR.editorConfig = function( config )
 	    ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'],
 	    ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
 	    ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
-	    '/',
 	    ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
 	    ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'],
 	    ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
 	    ['BidiLtr', 'BidiRtl'],
 	    ['Link','Unlink','Anchor'],
 	    ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'],
-	    '/',
 	    ['Styles','Format','Font','FontSize'],
 	    ['TextColor','BGColor'],
 	    ['Maximize', 'ShowBlocks','-','About']
diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php
index 59238e786f1af99e4c1d0cc995a12ca32be03e65..162310f4697f2d2b8fd3847468f5a852abfbbd3f 100644
--- a/htdocs/theme/eldy/style.css.php
+++ b/htdocs/theme/eldy/style.css.php
@@ -350,7 +350,7 @@ legend { margin-bottom: 8px; }
 fieldset { border: 1px solid #AAAAAA !important; }
 
 
-.button, input[name="sbmtConnexion"] {
+.button, .buttonDelete, input[name="sbmtConnexion"] {
     font-family: <?php print $fontlist ?>;
 	border-color: #c5c5c5;
 	border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);
@@ -383,17 +383,17 @@ fieldset { border: 1px solid #AAAAAA !important; }
 	-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
 	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
 }
-.button:focus  {
+.button:focus, .buttonDelete:focus  {
 	-moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 60, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
 	-webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 60, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
 	box-shadow: 0px 0px 6px 1px rgba(0, 0, 60, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
 }
-.button:hover   {
+.button:hover, .buttonDelete:hover   {
 	-moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
 	-webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
 	box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
 }
-.button:disabled {
+.button:disabled, .buttonDelete:disabled {
 	opacity: 0.4;
     filter: alpha(opacity=40); /* For IE8 and earlier */
     box-shadow: none;
@@ -1907,31 +1907,16 @@ span.butAction, span.butActionDelete {
 }
 
 .butAction:hover   {
-/*  for bootstrap look
-  color: #fff;
-  background-color: #286090;
-  border-color: #204d74;
-*/
   -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
   -webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
   box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
 }
 
-.butActionDelete, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active {
-/* for bootstrap look
-  color: #fff;
-  background-color: #d9534f;
-  border-color: #d43f3a;
-*/
-   color: #800;
+.butActionDelete, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active, .buttonDelete {
+   color: #800 !important;
 }
 
 .butActionDelete:hover {
-/*  for bootstrap look
-  color: #fff;
-  background-color: #c9302c;
-  border-color: #ac2925;
-*/
   -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
   -webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
   box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1);
@@ -3126,19 +3111,27 @@ td.hidden {
 
 .websitebar {
 	border-bottom: 1px solid #888;
-	height: 30px; 
+	background: #eee;
+}
+.websitebar .button, .websitebar .buttonDelete 
+{
+	padding: 2px 5px 3px 5px !important;
+	margin: 2px 4px 2px 4px  !important;
+    line-height: normal;
 }
 .websiteselection {
 	display: inline-block;
 	padding-left: 10px;
 	vertical-align: middle; 
-	margin-bottom: 5px;
 	line-height: 29px;
 }
 .websitetools {
 	float: right;
 	padding-top: 2px;
 }
+.websiteiframenoborder {
+	border: 0px;
+}
 
 
 /* ============================================================================== */
diff --git a/htdocs/theme/md/ckeditor/config.js b/htdocs/theme/md/ckeditor/config.js
index cffaadfba6e1f918383228a884880da8c1cae6ed..cf7163671a36f00385f07a275d568377c5999c6a 100644
--- a/htdocs/theme/md/ckeditor/config.js
+++ b/htdocs/theme/md/ckeditor/config.js
@@ -32,14 +32,12 @@ CKEDITOR.editorConfig = function( config )
 	    ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'],
 	    ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
 	    ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
-	    '/',
 	    ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
 	    ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'],
 	    ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
 	    ['BidiLtr', 'BidiRtl'],
 	    ['Link','Unlink','Anchor'],
 	    ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'],
-	    '/',
 	    ['Styles','Format','Font','FontSize'],
 	    ['TextColor','BGColor'],
 	    ['Maximize', 'ShowBlocks','-','About']
diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
index c45055a96f5476f410c78de1d5e439cf68630829..3de39efb50fbc1aa147a6160fca966eb1945f32b 100644
--- a/htdocs/theme/md/style.css.php
+++ b/htdocs/theme/md/style.css.php
@@ -1913,7 +1913,7 @@ span.butAction, span.butActionDelete {
     background-repeat: repeat-x    
 }
    
-.butActionDelete {
+.butActionDelete, .buttonDelete {
 	color: #ffffff !important;
 	text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
 	background-color: #cc6d00;
@@ -2988,19 +2988,27 @@ td.hidden {
 
 .websitebar {
 	border-bottom: 1px solid #888;
-	height: 30px; 
+	background: #eee;
+}
+.websitebar .button, .websitebar .buttonDelete 
+{
+	padding: 2px 4px 2px 4px !important;
+	margin: 2px 4px 2px 4px  !important;
+    line-height: normal;
 }
 .websiteselection {
 	display: inline-block;
 	padding-left: 10px;
 	vertical-align: middle; 
-	margin-bottom: 5px;
 	line-height: 29px;
 }
 .websitetools {
 	float: right;
 	padding-top: 2px;
 }
+.websiteiframenoborder {
+	border: 0px;
+}
 
 
 /* ============================================================================== */
diff --git a/htdocs/user/class/api_user.class.php b/htdocs/user/class/api_user.class.php
index d09785d3ccb0e805c246f0f02ee06c44e1e826b0..af0db5bfb2db1bd18862333d8304d752a67b70e1 100644
--- a/htdocs/user/class/api_user.class.php
+++ b/htdocs/user/class/api_user.class.php
@@ -159,8 +159,35 @@ class UserApi extends DolibarrApi
 		if ($this->useraccount->update($id, DolibarrApiAccess::$user, 1, '', '', 'update'))
 			return $this->get($id);
 
-		return false;
-	}
+    return false;
+  }
+
+  /**
+	 * add user to group
+	 *
+	 * @param   int     $id User ID
+	 * @param   int     $group Group ID
+	 * @return  int
+     * 
+	 * @url	GET user/{id}/setGroup/{group}
+	 */
+	function setGroup($id,$group) {
+		//if (!DolibarrApiAccess::$user->rights->user->user->supprimer) {
+			//throw new RestException(401);
+		//}
+    $result = $this->useraccount->fetch($id);
+    if (!$result)
+    {
+      throw new RestException(404, 'User not found');
+    }
+
+    if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user'))
+    {
+      throw new RestException(401, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
+    }
+
+    return $this->useraccount->SetInGroup($group,1);
+  }
 
 	/**
 	 * Delete account
diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php
index 949884df6e95b2fd95df17a2f4bc8b639f88daa3..585db4c343e0e07905494126e0e2875f4b4c0019 100644
--- a/htdocs/viewimage.php
+++ b/htdocs/viewimage.php
@@ -62,7 +62,7 @@ $entity=GETPOST('entity')?GETPOST('entity','int'):$conf->entity;
 
 // Security check
 if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart');
-
+if ($modulepart == 'fckeditor') $modulepart='medias';   // For backward compatibility
 
 
 /*
@@ -95,7 +95,7 @@ $type = 'application/octet-stream';
 if (! empty($_GET["type"])) $type=$_GET["type"];
 else $type=dol_mimetype($original_file);
 
-// Suppression de la chaine de caractere ../ dans $original_file
+// Security: Delete string ../ into $original_file
 $original_file = str_replace("../","/", $original_file);
 
 // Find the subdirectory name as the reference
diff --git a/htdocs/webservices/server_productorservice.php b/htdocs/webservices/server_productorservice.php
index 43facbb24fad379e32478a7d2dd4097cc4ceda77..aa43dbb185c0ed1e3d24d00ab364001cc5f65446 100644
--- a/htdocs/webservices/server_productorservice.php
+++ b/htdocs/webservices/server_productorservice.php
@@ -411,7 +411,8 @@ function getProductOrService($authentication,$id='',$ref='',$ref_ext='',$lang=''
 	            	'localtax1_tx' => $product->localtax1_tx,
 	            	'localtax2_tx' => $product->localtax2_tx,
 
-	            	'stock_real' => $product->stock_reel,
+            	    'stock_real' => $product->stock_reel,
+            	    'stock_virtual' => $product->stock_theorique,
 	            	'stock_alert' => $product->seuil_stock_alerte,
 	            	'pmp' => $product->pmp,
 	            	'import_key' => $product->import_key,
@@ -572,7 +573,7 @@ function createProductOrService($authentication,$product)
 				require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
 
 				$savstockreal=$newobject->stock_reel;
-				$newobject->load_stock();		// This overwrite ->stock_reel
+				$newobject->load_stock('novirtual,nobatch');		// This overwrite ->stock_reel, surely 0 because we have just created product
 				$getstockreal = $newobject->stock_reel;
 
 				if ($savstockreal != $getstockreal)
@@ -741,7 +742,7 @@ function updateProductOrService($authentication,$product)
 				require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
 
 				$savstockreal=$newobject->stock_reel;
-				$newobject->load_stock();		// This overwrite ->stock_reel
+				$newobject->load_stock('novirtual,nobatch');		// This overwrite ->stock_reel
 				$getstockreal = $newobject->stock_reel;
 
 				if ($savstockreal != $getstockreal)
diff --git a/htdocs/websites/class/websitepage.class.php b/htdocs/websites/class/websitepage.class.php
index ac9adf8f480f322be6d777208524cf073386966a..b363687765f3252ac4de5f9dd28785fba88c509b 100644
--- a/htdocs/websites/class/websitepage.class.php
+++ b/htdocs/websites/class/websitepage.class.php
@@ -253,13 +253,13 @@ class WebsitePage extends CommonObject
 	/**
 	 * Load object in memory from the database
 	 *
+	 * @param string $website_id   Web site id
 	 * @param string $sortorder    Sort Order
 	 * @param string $sortfield    Sort field
 	 * @param int    $limit        limit
 	 * @param int    $offset       Offset
 	 * @param array  $filter       Filter array
 	 * @param string $filtermode   Filter mode (AND or OR)
-	 *
 	 * @return array|int           int <0 if KO, array of pages if OK
 	 */
 	public function fetchAll($website_id, $sortorder='', $sortfield='', $limit=0, $offset=0, array $filter = array(), $filtermode='AND')
@@ -307,7 +307,7 @@ class WebsitePage extends CommonObject
 
 			while ($obj = $this->db->fetch_object($resql)) 
 			{
-				$record = new Websitepage($this->db);
+				$record = new WebsitePage($this->db);
 
 				$record->id = $obj->rowid;
 				$record->fk_website = $obj->fk_website;
@@ -320,7 +320,7 @@ class WebsitePage extends CommonObject
 				$record->date_creation = $this->db->jdate($obj->date_creation);
 				$record->date_modification = $this->db->jdate($obj->date_modification);
 				$record->tms = $this->db->jdate($obj->tms);
-
+				//var_dump($record->id);
 				$records[$record->id] = $record;
 			}
 			$this->db->free($resql);
diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php
index 58a2981d2da507616977d62843979d0abe30842a..98efd23f45b27f9df04a8f32f67ebf8a0a82fd73 100644
--- a/htdocs/websites/index.php
+++ b/htdocs/websites/index.php
@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) 2004-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
+/* 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
@@ -16,11 +16,14 @@
  */
 
 /**
- *   	\file       htdocs/admin/website.php
+ *   	\file       htdocs/website/index.php
  *		\ingroup    website
- *		\brief      Page to setup the module Website
+ *		\brief      Page to website view/edit
  */
 
+define('NOSCANPOSTFORINJECTION',1);
+define('NOSTYLECHECK',1);
+
 
 /**
  *	Show HTML header HTML + BODY + Top menu + left menu + DIV
@@ -63,6 +66,7 @@ function llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0,
 
 require '../main.inc.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/websites/class/website.class.php';
 require_once DOL_DOCUMENT_ROOT.'/websites/class/websitepage.class.php';
 
@@ -77,11 +81,14 @@ $conf->dol_hide_leftmenu = 1;
 $error=0;
 $website=GETPOST('website', 'alpha');
 $page=GETPOST('page', 'alpha');
-$pageid=GETPOST('pageid', 'alpha');
+$pageid=GETPOST('pageid', 'int');
 $action=GETPOST('action','alpha');
 
+if (GETPOST('delete')) { $action='delete'; }
 if (GETPOST('preview')) $action='preview';
 if (GETPOST('create')) { $action='create'; }
+if (GETPOST('editmedia')) { $action='editmedia'; }
+if (GETPOST('editcss')) { $action='editcss'; }
 if (GETPOST('editmenu')) { $action='editmenu'; }
 if (GETPOST('editmeta')) { $action='editmeta'; }
 if (GETPOST('editcontent')) { $action='editcontent'; }
@@ -91,15 +98,34 @@ if (empty($action)) $action='preview';
 $object=new Website($db);
 $objectpage=new WebsitePage($db);
 
+$object->fetchAll();    // Init $object->records
+
+// If website not defined, we take first found
+if (empty($website))
+{
+    foreach($object->records as $key => $valwebsite)
+    {
+        $website=$valwebsite->ref;
+        break;
+    }
+}
 if ($website)
 {
     $res = $object->fetch(0, $website);
 }
-if ($pageid)
+
+if ($pageid < 0) $pageid = 0;
+if ($pageid > 0 && $action != 'add')
 {
     $res = $objectpage->fetch($pageid);
 }
 
+global $dolibarr_main_data_root;
+$pathofwebsite=$dolibarr_main_data_root.'/websites/'.$website;
+$filecss=$pathofwebsite.'/styles.css';
+$filetpl=$pathofwebsite.'/page'.$pageid.'.tpl.php';
+
+
 
 /*
  * Actions
@@ -115,7 +141,7 @@ if ($action == 'add')
     $objectpage->title = GETPOST('WEBSITE_TITLE');
     $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
     $objectpage->description = GETPOST('WEBSITE_DESCRIPTION');
-    $objectpage->keyword = GETPOST('WEBSITE_KEYWORD');
+    $objectpage->keywords = GETPOST('WEBSITE_KEYWORD');
     
     if (empty($objectpage->title))
     {
@@ -187,21 +213,128 @@ if ($action == 'update')
 }
 
 // Update page
-if ($action == 'updatecontent')
+if ($action == 'delete')
+{
+    $db->begin();
+
+    $res = $object->fetch(0, $website);
+
+    $res = $objectpage->fetch($pageid, $object->fk_website);
+
+    if ($res > 0)
+    {
+        $res = $objectpage->delete($user);
+        if (! $res > 0)
+        {
+            $error++;
+            setEventMessages($objectpage->error, $objectpage->errors, 'errors');
+        }
+
+        if (! $error)
+        {
+            $db->commit();
+            setEventMessages($langs->trans("PageDeleted", $objectpage->pageurl, $website), null, 'mesgs');
+            
+            header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website);
+            exit;
+        }
+        else
+        {
+            $db->rollback();
+        }
+    }
+    else
+    {
+        dol_print_error($db);
+    }
+}
+
+// Update css
+if ($action == 'updatecss')
 {
     $db->begin();
+
+    $res = $object->fetch(0, $website);
+    /*
+    $res = $object->update($user);
+    if ($res > 0)
+    {
+        $db->commit();
+        setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
+        $action='';
+    }
+    else
+    {
+       $db->rollback();
+    }*/
     
-    $object->fetch(0, $website);
+    $csscontent = GETPOST('WEBSITE_CSS_INLINE');
     
-    $objectpage->fk_website = $object->id;
-    $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
+    dol_mkdir($pathofwebsite);
+    file_put_contents($filecss, $csscontent);
+    if (! empty($conf->global->MAIN_UMASK))
+        @chmod($filecss, octdec($conf->global->MAIN_UMASK));
     
-    $res = $objectpage->fetch(0, $object->fk_website, $objectpage->pageurl);
+    $action='preview';
+}
+
+// Update page
+if ($action == 'updatemeta')
+{
+    $db->begin();
+    $object->fetch(0, $website);
+
+    $objectpage->fk_website = $object->id;
+
+    $res = $objectpage->fetch($pageid, $object->fk_website);
+    if ($res > 0)
+    {
+        $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
+        $objectpage->title = GETPOST('WEBSITE_TITLE');
+        $objectpage->description = GETPOST('WEBSITE_DESCRIPTION');
+        $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS');
+
+        $res = $objectpage->update($user);
+        if (! $res > 0)
+        {
+            $error++;
+            setEventMessages($objectpage->error, $objectpage->errors, 'errors');
+        }
+
+        if (! $error)
+        {
+            $db->commit();
+            setEventMessages($langs->trans("Saved"), null, 'mesgs');
+            $action='preview';
+        }
+        else
+        {
+            $db->rollback();
+        }
+    }
+    else
+    {
+        dol_print_error($db, 'Page not found');
+    }
+}
+
+// Update page
+if ($action == 'updatecontent')
+{
+    $db->begin();
+    $object->fetch(0, $website);
+
+    $objectpage->fk_website = $object->id;
     
+    $res = $objectpage->fetch($pageid, $object->fk_website);
     if ($res > 0)
     {
         $objectpage->content = GETPOST('PAGE_CONTENT');
         
+        // Clean data. We remove all the head section.
+        $objectpage->content = preg_replace('/<head.*<\/head>/s', '', $objectpage->content);
+        /* $objectpage->content = preg_replace('/<base\s+href=[\'"][^\'"]+[\'"]\s/?>/s', '', $objectpage->content); */
+        
         $res = $objectpage->update($user);
         if (! $res > 0)
         {
@@ -213,7 +346,15 @@ if ($action == 'updatecontent')
     	{
     		$db->commit();
     	    setEventMessages($langs->trans("Saved"), null, 'mesgs');
-    	    $action='';
+    	    
+    	    dol_mkdir($pathofwebsite);
+    	    dol_delete_file($filetpl);
+    	    file_put_contents($filetpl, $objectpage->content);
+    	    if (! empty($conf->global->MAIN_UMASK))
+    	        @chmod($filetpl, octdec($conf->global->MAIN_UMASK));
+    	    
+   	        header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid);
+   	        exit;
     	}
     	else
     	{
@@ -222,7 +363,7 @@ if ($action == 'updatecontent')
     }
     else
     {
-        dol_print_error($db);
+        dol_print_error($db, 'Page not found');
     }
 }
 
@@ -244,6 +385,18 @@ if ($action == 'create')
 {
     print '<input type="hidden" name="action" value="add">';
 }
+if ($action == 'editcss')
+{
+    print '<input type="hidden" name="action" value="updatecss">';
+}
+if ($action == 'editmenu')
+{
+    print '<input type="hidden" name="action" value="updatemenu">';
+}
+if ($action == 'editmeta')
+{
+    print '<input type="hidden" name="action" value="updatemeta">';
+}
 if ($action == 'editcontent')
 {
     print '<input type="hidden" name="action" value="updatecontent">';
@@ -252,7 +405,6 @@ if ($action == 'edit')
 {
     print '<input type="hidden" name="action" value="update">';
 }
-if ($website) print '<input type="hidden" name="website" value="'.dol_escape_htmltag($website).'">';
 
 
 // Add a margin under toolbar ?
@@ -262,32 +414,41 @@ if ($action != 'preview' && $action != 'editcontent') $style=' margin-bottom: 5p
 
 print '<div class="centpercent websitebar">';
 
-$tmp = $object->fetchAll();
 if (count($object->records) > 0)
 {
     print '<div class="websiteselection">';
     print $langs->trans("Website").': ';
     print '</div>';
     
+    // List of websites
     print '<div class="websiteselection">';
+    $out='';
+    $out.='<select name="website">';
+    if (empty($object->records)) $out.='<option value="-1">&nbsp;</option>';
     // Loop on each sites
     $i=0;
     foreach($object->records as $key => $valwebsite)
     {
         if (empty($website)) $website=$valwebsite->ref;
 
-        if ($i) print ' - ';
-        print '<a href="'.$_SERVER["PHP_SELF"].'?website='.urlencode($valwebsite->ref).'">';
-        if ($valwebsite->ref == $website) print '<strong>';
-        print $valwebsite->ref;
-        if ($valwebsite->ref == $website) print '</strong>';
-        print '</a>';
-        
+        $out.='<option value="'.$valwebsite->ref.'"';
+        if ($website == $valwebsite->ref) $out.=' selected';		// To preselect a value
+        $out.='>';
+        $out.=$valwebsite->ref;
+        $out.='</option>';
         $i++;    
     }
+    $out.='</select>';
+    print $out;
+    print '<input type="submit" class="button" name="refresh" value="'.$langs->trans("Refresh").'">';
     
+    if ($website)
+    {
+        print '<a href="'.DOL_URL_ROOT.'/public/websites/index.php?website='.$website.'" target="tab'.$website.'">'.$langs->trans("ViewInNewTab").'</a>';
+    }
     print '</div>';
     
+    // Button for websites
     print '<div class="websitetools">';
     
     if ($action == 'preview') 
@@ -295,10 +456,18 @@ if (count($object->records) > 0)
         $disabled='';
         if (empty($user->rights->websites->create)) $disabled=' disabled="disabled"';
 
+        //print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("MediaFiles")).'" name="editmedia">';
+        print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditCss")).'" name="editcss">';
         print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditMenu")).'" name="editmenu">';
         print '<input type="submit"'.$disabled.' class="button" value="'.dol_escape_htmltag($langs->trans("AddPage")).'" name="create">';
     }
-    //else print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="preview">';
+    
+    if (in_array($action, array('editcss','editmenu','create')))
+    {
+        if ($action != 'preview') print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="preview">';
+        if (preg_match('/^create/',$action)) print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
+        if (preg_match('/^edit/',$action)) print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
+    }
     
     print '</div>';
     
@@ -317,19 +486,24 @@ if (count($object->records) > 0)
         print '<div class="websiteselection">';
         $out='';
         $out.='<select name="pageid">';
-        foreach($array as $key => $valpage)
+        if (is_array($array) && count($array) > 0)
         {
-            if (empty($pageid) && $action != 'create') $pageid=$valpage->id;
-            
-            $out.='<option value="'.$key.'"';
-            if ($pageid > 0 && $pageid == $key) $out.=' selected';		// To preselect a value
-            $out.='>';
-            $out.=$valpage->title;
-            $out.='</option>';
+            foreach($array as $key => $valpage)
+            {
+                if (empty($pageid) && $action != 'create') $pageid=$valpage->id;
+                
+                $out.='<option value="'.$key.'"';
+                if ($pageid > 0 && $pageid == $key) $out.=' selected';		// To preselect a value
+                $out.='>';
+                $out.=$valpage->title;
+                $out.='</option>';
+            }
         }
+        else $out.='<option value="-1">&nbsp;</option>';
         $out.='</select>';
         print $out;
         print '<input type="submit" class="button" name="refresh" value="'.$langs->trans("Refresh").'">';
+        print '<input type="submit" class="buttonDelete" name="delete" value="'.$langs->trans("Delete").'">';
         //print $form->selectarray('page', $array);
         print '</div>';
         print '<div class="websiteselection">';
@@ -344,13 +518,19 @@ if (count($object->records) > 0)
         
             if ($pageid > 0)
             {
-                print '<input type="submit" class="button"'.$disabled.'  value="'.dol_escape_htmltag($langs->trans("EditPageMeta")).'" name="editmeta">';
-                print '<input type="submit" class="button"'.$disabled.'  value="'.dol_escape_htmltag($langs->trans("EditPageContent")).'" name="editcontent">';
+                print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditPageMeta")).'" name="editmeta">';
+                print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditPageContent")).'" name="editcontent">';
+                //print '<a href="'.$_SERVER["PHP_SELF"].'?action=editmeta&website='.urlencode($website).'&pageid='.urlencode($pageid).'" class="button">'.dol_escape_htmltag($langs->trans("EditPageMeta")).'</a>';
+                //print '<a href="'.$_SERVER["PHP_SELF"].'?action=editcontent&website='.urlencode($website).'&pageid='.urlencode($pageid).'" class="button">'.dol_escape_htmltag($langs->trans("EditPageContent")).'</a>';
             }
         }
-        else print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="preview">';
-        if (preg_match('/^create/',$action)) print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
-        if (preg_match('/^edit/',$action)) print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
+        
+        if (! in_array($action, array('editcss','editmenu','create')))
+        {
+            if ($action != 'preview') print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="preview">';
+            if (preg_match('/^create/',$action)) print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
+            if (preg_match('/^edit/',$action)) print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
+        }
         
         print '</div>';
         
@@ -375,45 +555,96 @@ $head = array();
  * Edit mode
  */
 
-if ($action == 'editmeta' || $action == 'create')
+if ($action == 'editcss')
 {
     print '<div class="fiche">';
-    
+
+    print '<br>';
+
+    $csscontent = @file_get_contents($filecss);
+        
     dol_fiche_head();
-    
+
     print '<table class="border" width="100%">';
-    
+
     print '<tr><td>';
-    print $langs->trans('WEBSITE_PAGENAME');
+    print $langs->trans('WebSite');
     print '</td><td>';
-    print '<input type="text" class="flat" size="96" name="WEBSITE_PAGENAME" value="'.dol_escape_htmltag($page).'">';
+    print $website;
     print '</td></tr>';
+
+    print '<tr><td valign="top">';
+    print $langs->trans('WEBSITE_CSS_INLINE');
+    print '</td><td>';
+    print '<textarea class="flat centpercent" rows="32" name="WEBSITE_CSS_INLINE">';
+    print $csscontent;
+    print '</textarea>';
+    print '</td></tr>';
+
+    /*print '<tr><td>';
+    print $langs->trans('WEBSITE_CSS_URL');
+    print '</td><td>';
+    print '<input type="text" class="flat" size="96" name="WEBSITE_CSS_URL" value="'.dol_escape_htmltag($obj->WEBSITE_CSS_URL).'">';
+    print '</td></tr>';*/
+
+    print '</table>';
+
+    dol_fiche_end();
+
+    print '</div>';
+
+    print '<br>';
+}
+
+if ($action == 'editmeta' || $action == 'create')
+{
+    print '<div class="fiche">';
+ 
+    print '<br>';
+    
+    dol_fiche_head();
+    
+    print '<table class="border" width="100%">';
     
     if ($action != 'create')
     {
         print '<tr><td>';
-        print $langs->trans('WEBSITE_URL');
+        print $langs->trans('WEBSITE_PAGEURL');
         print '</td><td>';
-        print '/public/websites/'.$website.'/index.php?pageid='.urlencode($pageid);
+        print '/public/websites/index.php?website='.urlencode($website).'&pageid='.urlencode($pageid);
         print '</td></tr>';
+        $pageurl=dol_escape_htmltag($objectpage->pageurl);
+        $pagetitle=dol_escape_htmltag($objectpage->title);
+        $pagedescription=dol_escape_htmltag($objectpage->description);
+        $pagekeywords=dol_escape_htmltag($objectpage->keywords);
     }
+    if (GETPOST('WEBSITE_PAGENAME'))    $pageurl=GETPOST('WEBSITE_PAGENAME');
+    if (GETPOST('WEBSITE_TITLE'))       $pagetitle=GETPOST('WEBSITE_TITLE');
+    if (GETPOST('WEBSITE_DESCRIPTION')) $pagedescription=GETPOST('WEBSITE_DESCRIPTION');
+    if (GETPOST('WEBSITE_KEYWORDS'))    $pagekeywords=GETPOST('WEBSITE_KEYWORDS');
+    
+    print '<tr><td>';
+    print $langs->trans('WEBSITE_PAGENAME');
+    print '</td><td>';
+    print '<input type="text" class="flat" size="96" name="WEBSITE_PAGENAME" value="'.$pageurl.'">';
+    print '</td></tr>';
     
     print '<tr><td>';
     print $langs->trans('WEBSITE_TITLE');
     print '</td><td>';
-    print '<input type="text" class="flat" size="96" name="WEBSITE_TITLE" value="'.dol_escape_htmltag($obj->WEBSITE_TITLE).'">';
+    print '<input type="text" class="flat" size="96" name="WEBSITE_TITLE" value="'.$pagetitle.'">';
     print '</td></tr>';
     
     print '<tr><td>';
     print $langs->trans('WEBSITE_DESCRIPTION');
     print '</td><td>';
-    print '<input type="text" class="flat" size="96" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($obj->WEBSITE_DESCRIPTION).'">';
+    print '<input type="text" class="flat" size="96" name="WEBSITE_DESCRIPTION" value="'.$pagedescription.'">';
     print '</td></tr>';
     
     print '<tr><td>';
     print $langs->trans('WEBSITE_KEYWORDS');
     print '</td><td>';
-    print '<input type="text" class="flat" size="128" name="WEBSITE_KEYWORDS" value="'.dol_escape_htmltag($obj->WEBSITE_KEYWORDS).'">';
+    print '<input type="text" class="flat" size="128" name="WEBSITE_KEYWORDS" value="'.$pagekeywords.'">';
     print '</td></tr>';
     
     print '</table>';
@@ -425,6 +656,11 @@ if ($action == 'editmeta' || $action == 'create')
     print '<br>';
 }
 
+if ($action == 'editmedia')
+{
+    print '<div class="center">'.$langs->trans("FeatureNotYetAvailable").'</center>';
+}
+
 if ($action == 'editmenu')
 {
     print '<div class="center">'.$langs->trans("FeatureNotYetAvailable").'</center>';
@@ -436,7 +672,7 @@ if ($action == 'editcontent')
      * Editing global variables not related to a specific theme
      */
     require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-    $doleditor=new DolEditor('PAGE_CONTENT',$obj->value,'',160,'dolibarr_notes','',false,false,$conf->fckeditor->enabled,5,60);
+    $doleditor=new DolEditor('PAGE_CONTENT',$objectpage->content,'',500,'Full','',true,true,true,5,60);
     $doleditor->Create();
 }
 
@@ -450,10 +686,45 @@ if ($action == 'preview')
     {
         $objectpage->fetch($pageid);
         
-        print '<!-- Page content -->'."\n";
-        print '<div class="websitecontent">';
-        print $objectpage->content;
-        print '</div>';
+        print "\n".'<!-- Page content '.$filetpl.' c-->'."\n";
+
+        
+        $csscontent = @file_get_contents($filecss);
+        
+        $out='';
+        
+        $out.='<div id="websitecontent" class="websitecontent">'."\n";
+        
+        $out.='<style scoped>'."\n";        // "scoped" means "apply to parent element only". Not yet supported by browsers
+        $out.=$csscontent;
+        $out.='</style>'."\n";
+        
+        $out.=$objectpage->content."\n";
+        
+        $out.='</div>';
+        
+        print $out;
+        
+        /*file_put_contents($filetpl, $out);
+        if (! empty($conf->global->MAIN_UMASK))
+            @chmod($filetpl, octdec($conf->global->MAIN_UMASK));
+
+        // Output file on browser
+        dol_syslog("index.php include $filetpl $filename content-type=$type");
+        $original_file_osencoded=dol_osencode($filetpl);	// New file name encoded in OS encoding charset
+        
+        // This test if file exists should be useless. We keep it to find bug more easily
+        if (! file_exists($original_file_osencoded))
+        {
+            dol_print_error(0,$langs->trans("ErrorFileDoesNotExists",$original_file));
+            exit;
+        }
+        
+        //include_once $original_file_osencoded;
+        */
+        
+        /*print '<iframe class="websiteiframenoborder centpercent" src="'.DOL_URL_ROOT.'/public/websites/index.php?website='.$website.'&pageid='.$pageid.'"/>';
+        print '</iframe>';*/
     }
     else
     {