diff --git a/ChangeLog b/ChangeLog
index 8377c3d35d36ab6b7471ff1e7b8f018233a8d76e..c72f312e91895a7a73c555af61694fd14d201876 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,11 +16,12 @@ For users:
        to automatically add timestamp and user line into editionf field when editing a note.
 - New: Add button cancel into edition of notes.
 - New: Improved Opensurvey module and added options to disable comments and disable
-       public votes
+       public votes.
 - New: The box "balance of bank accounts" show all opened accounts.
 - New: Add option MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE.
 - New: Add warning if supplier payment is higher that due amount.
-- New increase length of url into bookmark module.
+- New: Increase length of url into bookmark module.
+- New: Add an admin page to make a mass init of barcode values for all products. 
 
 TODO
 - New: Predefined product and free product use same form.
@@ -79,6 +80,9 @@ Fix: Enable extrafields for customer order, proposal and invoice lines. This fea
      fix enough quickly for 3.5.0 release. 
 Fix: user right on Holiday for month report nor working.
 Fix: [ bug #1250 ] "Supplier Ref. product" sidebar search box does not work
+Fix: Bad space in predefined messages. 
+Fix: Signature was not added for email sent from thirdparty page.
+Fix: Action event SHIPPING_VALIDATE is not implemented
 
 ***** ChangeLog for 3.5 compared to 3.4.* *****
 For users:
diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php
index ec3faca6625ce97f46555331048e6e82288dd068..e29bea1a2e6d04d00ec186c69a5bd697253f70cd 100644
--- a/htdocs/admin/mails.php
+++ b/htdocs/admin/mails.php
@@ -132,7 +132,7 @@ if (! empty($_POST['removedfile']) || ! empty($_POST['removedfilehtml']))
 if (($action == 'send' || $action == 'sendhtml') && ! GETPOST('addfile') && ! GETPOST('addfilehtml') && ! GETPOST('removedfile') && ! GETPOST('cancel'))
 {
 	$error=0;
-	
+
 	$email_from='';
 	if (! empty($_POST["fromname"])) $email_from=$_POST["fromname"].' ';
 	if (! empty($_POST["frommail"])) $email_from.='<'.$_POST["frommail"].'>';
@@ -144,12 +144,12 @@ if (($action == 'send' || $action == 'sendhtml') && ! GETPOST('addfile') && ! GE
 	$subject    = $_POST['subject'];
 	$body       = $_POST['message'];
 	$deliveryreceipt= $_POST["deliveryreceipt"];
-	
+
 	//Check if we have to decode HTML
 	if (!empty($conf->global->FCKEDITOR_ENABLE_MAILING) && dol_textishtml(dol_html_entity_decode($body, ENT_COMPAT | ENT_HTML401))) {
 		$body=dol_html_entity_decode($body, ENT_COMPAT | ENT_HTML401);
 	}
-	
+
 	// Create form object
 	include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
 	$formmail = new FormMail($db);
@@ -693,7 +693,7 @@ else
 			$formmail->clear_attached_files();
 		}
 
-		$formmail->show_form(($action == 'testhtml'?'addfilehtml':'addfile'),($action == 'testhtml'?'removefilehtml':'removefile'));
+		print $formmail->get_form(($action == 'testhtml'?'addfilehtml':'addfile'),($action == 'testhtml'?'removefilehtml':'removefile'));
 
 		print '<br>';
 	}
diff --git a/htdocs/barcode/codeinit.php b/htdocs/barcode/codeinit.php
new file mode 100644
index 0000000000000000000000000000000000000000..bae8d90e589563c5993e0809f8f954f5468dac01
--- /dev/null
+++ b/htdocs/barcode/codeinit.php
@@ -0,0 +1,282 @@
+<?php
+/* Copyright (C) 2014 Laurent Destailleur  <eldy@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *	\file 		htdocs/barcode/codeinit.php
+ *	\ingroup    member
+ *	\brief      Page to make mass init of barcode
+ */
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
+require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+
+$langs->load("admin");
+$langs->load("members");
+$langs->load("errors");
+
+// Choix de l'annee d'impression ou annee courante.
+$now = dol_now();
+$year=dol_print_date($now,'%Y');
+$month=dol_print_date($now,'%m');
+$day=dol_print_date($now,'%d');
+$forbarcode=GETPOST('forbarcode');
+$fk_barcode_type=GETPOST('fk_barcode_type');
+$mode=GETPOST('mode');
+$modellabel=GETPOST("modellabel");	// Doc template to use
+$numberofsticker=GETPOST('numberofsticker','int');
+
+$mesg='';
+
+$action=GETPOST('action');
+
+$producttmp=new Product($db);
+$thirdpartytmp=new Societe($db);
+
+$modBarCodeProduct='';
+
+
+/*
+ * Actions
+ */
+
+// Define barcode template for products
+if (! empty($conf->global->BARCODE_PRODUCT_ADDON_NUM))
+{
+	$dirbarcodenum=array_merge(array('/core/modules/barcode/'),$conf->modules_parts['barcode']);
+
+	foreach ($dirbarcodenum as $dirroot)
+	{
+		$dir = dol_buildpath($dirroot,0);
+
+		$handle = @opendir($dir);
+	    if (is_resource($handle))
+	    {
+	    	while (($file = readdir($handle))!==false)
+	    	{
+	    		if (preg_match('/^mod_barcode_product_.*php$/', $file))
+	    		{
+	    			$file = substr($file, 0, dol_strlen($file)-4);
+
+	    		    try {
+	        			dol_include_once($dirroot.$file.'.php');
+	    			}
+	    			catch(Exception $e)
+	    			{
+	    			    dol_syslog($e->getMessage(), LOG_ERR);
+	    			}
+
+	    			$modBarCodeProduct = new $file();
+	    			break;
+	    		}
+	    	}
+	    	closedir($handle);
+	    }
+	}
+}
+
+if ($action == 'initbarcodeproducts')
+{
+	if (! is_object($modBarCodeProduct))
+	{
+		$error++;
+		setEventMessage($langs->trans("NoBarcodeNumberingTemplateDefined"),'errors');
+	}
+
+	if (! $error)
+	{
+		$productstatic=new Product($db);
+
+		$db->begin();
+
+		$sql="SELECT rowid, ref, fk_product_type FROM ".MAIN_DB_PREFIX."product where barcode IS NULL or barcode = ''";
+		$resql=$db->query($sql);
+		if ($resql)
+		{
+			$num=$db->num_rows($resql);
+
+			$i=0; $nbok=$nbtry=0;
+			while ($i < $num)
+			{
+				$obj=$db->fetch_object($resql);
+				if ($obj)
+				{
+					$productstatic->id=$obj->rowid;
+					$productstatic->ref=$obj->ref;
+					$productstatic->type=$obj->fk_product_type;
+					$nextvalue=$modBarCodeProduct->getNextValue($productstatic,'');
+
+					print 'Set value '.$nextvalue.' to product '.$productstatic->id." ".$productstatic->ref." ".$productstatic->type."<br>\n";
+					$result=$productstatic->setValueFrom('barcode', $nextvalue);
+
+					$nbtry++;
+					if ($result > 0) $nbok++;
+				}
+
+				$i++;
+			}
+		}
+		else
+		{
+			$error++;
+			dol_print_error($db);
+		}
+
+		if (! $error)
+		{
+			setEventMessage($langs->trans("RecordsModified",$nbok),'mesgs');
+
+			//$db->rollback();
+			$db->commit();
+		}
+		else
+		{
+			$db->rollback();
+		}
+	}
+
+	$action='';
+}
+
+
+
+/*
+ * View
+ */
+
+if (!$user->admin) accessforbidden();
+if (empty($conf->barcode->enabled)) accessforbidden();
+
+$form=new Form($db);
+
+llxHeader('',$langs->trans("MassBarcodeInit"));
+
+print_fiche_titre($langs->trans("MassBarcodeInit"));
+print '<br>';
+
+print $langs->trans("MassBarcodeInitDesc").'<br>';
+print '<br>';
+
+dol_htmloutput_errors($mesg);
+
+//print img_picto('','puce').' '.$langs->trans("PrintsheetForOneBarCode").'<br>';
+//print '<br>';
+
+print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
+print '<input type="hidden" name="mode" value="label">';
+print '<input type="hidden" name="action" value="initbarcodeproducts">';
+
+print '<br>';
+
+// For thirdparty
+if ($conf->societe->enabled)
+{
+	$nbno=$nbtotal=0;
+
+	print_fiche_titre($langs->trans("BarcodeInitForThirdparties"),'','').'<br>'."\n";
+	$sql="SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."societe where barcode IS NULL or barcode = ''";
+	$resql=$db->query($sql);
+	if ($resql)
+	{
+		$obj=$db->fetch_object($resql);
+		$nbno=$obj->nb;
+	}
+	else dol_print_error($db);
+
+	$sql="SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."societe";
+	$resql=$db->query($sql);
+	if ($resql)
+	{
+		$obj=$db->fetch_object($resql);
+		$nbtotal=$obj->nb;
+	}
+	else dol_print_error($db);
+
+	print $langs->trans("CurrentlyNWithoutBarCode", $nbno, $nbtotal, $langs->transnoentitiesnoconv("Thirdparties")).'<br>'."\n";
+
+	print '<br><input class="button" type="submit" id="submitformbarcodethirdpartygen" '.((GETPOST("selectorforbarcode") && GETPOST("selectorforbarcode"))?'':'disabled="checked" ').'value="'.$langs->trans("InitEmptyBarCode",$nbno).'"';
+	print ' title="'.dol_escape_htmltag($langs->trans("FeatureNotYetAvailable")).'" disabled="disabled"';
+	print '>';
+	print '<br><br><br>';
+}
+
+
+// For products
+if ($conf->product->enabled || $conf->product->service)
+{
+	$nbno=$nbtotal=0;
+
+	print_fiche_titre($langs->trans("BarcodeInitForProductsOrServices"),'','').'<br>'."\n";
+	$sql="SELECT count(rowid) as nb, fk_product_type FROM ".MAIN_DB_PREFIX."product where barcode IS NULL or barcode = '' GROUP BY fk_product_type";
+	$resql=$db->query($sql);
+	if ($resql)
+	{
+		$num=$db->num_rows($resql);
+
+		$i=0;
+		while($i < $num)
+		{
+			$obj=$db->fetch_object($resql);
+			$nbno+=$obj->nb;
+
+			$i++;
+		}
+	}
+	else dol_print_error($db);
+
+	$sql="SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."product";
+	$resql=$db->query($sql);
+	if ($resql)
+	{
+		$obj=$db->fetch_object($resql);
+		$nbtotal=$obj->nb;
+	}
+	else dol_print_error($db);
+
+	print $langs->trans("CurrentlyNWithoutBarCode", $nbno, $nbtotal, $langs->transnoentitiesnoconv("ProductsOrServices")).'<br>'."\n";
+
+	if (is_object($modBarCodeProduct))
+	{
+		print $langs->trans("BarCodeNumberManager").": ";
+		$objproduct=new Product($db);
+		print '<b>'.$modBarCodeProduct->nom.'</b> - '.$langs->trans("NextValue").': <b>'.$modBarCodeProduct->getNextValue($objproduct).'</b><br>';
+		$disabled=0;
+	}
+	else
+	{
+		$disabled=1;
+		$titleno=$langs->trans("NoBarcodeNumberingTemplateDefined");
+		print '<font class="warning">'.$langs->trans("NoBarcodeNumberingTemplateDefined").'</font><br>';
+	}
+	if (empty($nbno))
+	{
+		$disabled=1;
+		$titleno=$langs->trans("NoRecordWithoutBarcodeDefined");
+		print '<font class="ok">'.$langs->trans("NoRecordWithoutBarcodeDefined").'</font><br>';
+	}
+
+	print '<br><input class="button" type="submit" id="submitformbarcodeproductgen" value="'.$langs->trans("InitEmptyBarCode",$nbno).'"'.($disabled?' disabled="disabled" title="'.dol_escape_htmltag($titleno).'"':'').'>';
+	print '<br><br><br>';
+}
+
+
+print '</form>';
+print '<br>';
+
+llxFooter();
+
+$db->close();
+?>
diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php
index 5e2e52366fcb80531d3051822652ecc5e05d895c..aa2be8d136f82fb24bc8c58a1e9e22da4118014b 100644
--- a/htdocs/barcode/printsheet.php
+++ b/htdocs/barcode/printsheet.php
@@ -63,12 +63,12 @@ if (GETPOST('submitproduct') && GETPOST('submitproduct'))
 		$producttmp->fetch(GETPOST('productid'));
 		$forbarcode=$producttmp->barcode;
 		$fk_barcode_type=$thirdpartytmp->barcode_type_code;
-	
+
 		if (empty($fk_barcode_type) && ! empty($conf->global->PRODUIT_DEFAULT_BARCODE_TYPE)) $fk_barcode_type = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE;
-		
+
 		if (empty($forbarcode) || empty($fk_barcode_type))
 		{
-			setEventMessage($langs->trans("DefinitionOfBarCodeForProductNotComplete",$producttmp->getNomUrl()), 'warnings');	
+			setEventMessage($langs->trans("DefinitionOfBarCodeForProductNotComplete",$producttmp->getNomUrl()), 'warnings');
 		}
 	}
 }
@@ -80,12 +80,12 @@ if (GETPOST('submitthirdparty') && GETPOST('submitthirdparty'))
 		$thirdpartytmp->fetch(GETPOST('socid'));
 		$forbarcode=$thirdpartytmp->barcode;
 		$fk_barcode_type=$thirdpartytmp->barcode_type_code;
-	
+
 		if (empty($fk_barcode_type) && ! empty($conf->global->GENBARCODE_BARCODETYPE_THIRDPARTY)) $fk_barcode_type = $conf->global->GENBARCODE_BARCODETYPE_THIRDPARTY;
-		
+
 		if (empty($forbarcode) || empty($fk_barcode_type))
 		{
-			setEventMessage($langs->trans("DefinitionOfBarCodeForProductNotComplete",$thirdpartytmp->getNomUrl()), 'warnings');	
+			setEventMessage($langs->trans("DefinitionOfBarCodeForProductNotComplete",$thirdpartytmp->getNomUrl()), 'warnings');
 		}
 	}
 }
@@ -243,6 +243,8 @@ if ($action == 'builddoc')
  * View
  */
 
+if (empty($conf->barcode->enabled)) accessforbidden();
+
 $form=new Form($db);
 
 llxHeader('',$langs->trans("BarCodePrintsheet"));
@@ -329,7 +331,7 @@ jQuery(document).ready(function() {
 	jQuery(".radiobarcodeselect").click(function() {
 		init_selectors();
 	});
-	
+
 	function init_gendoc_button()
 	{
 		if (jQuery("#select_fk_barcode_type").val() > 0 && jQuery("#forbarcode").val())
diff --git a/htdocs/categories/categorie.php b/htdocs/categories/categorie.php
index 1750097b120dabd7001a2e9b967dec31c9a1eae2..8232da9498925a38e2c21e7680b2ed5f195ba46d 100644
--- a/htdocs/categories/categorie.php
+++ b/htdocs/categories/categorie.php
@@ -153,7 +153,7 @@ if (empty($reshook))
 			setEventMessage($cat->errors,'errors');
 		}
 	}
-	
+
 	// Add object into a category
 	if ($parent > 0)
 	{
@@ -310,13 +310,6 @@ if ($socid)
 	print '<tr><td>'.$langs->trans('Phone').'</td><td>'.dol_print_phone($soc->phone,$soc->country_code,0,$soc->id,'AC_TEL').'</td>';
 	print '<td>'.$langs->trans('Fax').'</td><td>'.dol_print_phone($soc->fax,$soc->country_code,0,$soc->id,'AC_FAX').'</td></tr>';
 
-	// Assujeti a TVA ou pas
-	print '<tr>';
-	print '<td class="nowrap">'.$langs->trans('VATIsUsed').'</td><td colspan="3">';
-	print yn($soc->tva_assuj);
-	print '</td>';
-	print '</tr>';
-
 	print '</table>';
 
 	dol_fiche_end();
@@ -631,7 +624,7 @@ function formCategory($db,$object,$typeid,$socid=0,$showclassifyform=1)
 
 	print '<br>';
 	print_fiche_titre($title,'','');
-	
+
 	// Form to add record into a category
 	if ($showclassifyform)
 	{
diff --git a/htdocs/comm/mailing/fiche.php b/htdocs/comm/mailing/fiche.php
index 8217727e2026d045bc28a8586d40f231cc11fd62..bc833b1895578598b539e2e7a031b319caea6eb8 100644
--- a/htdocs/comm/mailing/fiche.php
+++ b/htdocs/comm/mailing/fiche.php
@@ -947,7 +947,7 @@ else
 				$formmail->param["mailid"]=$object->id;
 				$formmail->param["returnurl"]=$_SERVER['PHP_SELF']."?id=".$object->id;
 
-				$formmail->show_form();
+				print $formmail->get_form();
 
 				print '<br>';
 			}
diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php
index a8dd4ab2a9e3ef50e13ffcf990068775f1852d75..4ad74c01af3820c6196a5123da2320fb0fa780f2 100644
--- a/htdocs/comm/propal.php
+++ b/htdocs/comm/propal.php
@@ -2149,14 +2149,14 @@ else
 				{
 					print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=modif">'.$langs->trans('Modify').'</a></div>';
 				}
-	
+
 				// ReOpen
 				if (($object->statut == 2 || $object->statut == 3) && $user->rights->propal->cloturer)
 				{
 					print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=reopen'.(empty($conf->global->MAIN_JUMP_TAG)?'':'#reopen').'"';
 					print '>'.$langs->trans('ReOpen').'</a></div>';
 				}
-	
+
 				// Send
 				if ($object->statut == 1 || $object->statut == 2)
 				{
@@ -2166,7 +2166,7 @@ else
 					}
 					else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">'.$langs->trans('SendByMail').'</a></div>';
 				}
-	
+
 				// Create an order
 				if (! empty($conf->commande->enabled) && $object->statut == 2)
 				{
@@ -2175,18 +2175,18 @@ else
 						print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/commande/fiche.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id.'&amp;socid='.$object->socid.'">'.$langs->trans("AddOrder").'</a></div>';
 					}
 				}
-	
+
 				// Create contract
 				if ($conf->contrat->enabled && $object->statut == 2)
 				{
 					$langs->load("contracts");
-	
+
 					if ($user->rights->contrat->creer)
 					{
 						print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/contrat/fiche.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id.'&amp;socid='.$object->socid.'">'.$langs->trans('AddContract').'</a></div>';
 					}
 				}
-	
+
 				// Create an invoice and classify billed
 				if ($object->statut == 2)
 				{
@@ -2194,37 +2194,37 @@ else
 					{
 						print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/facture.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id.'&amp;socid='.$object->socid.'">'.$langs->trans("AddBill").'</a></div>';
 					}
-	
+
 					$arraypropal=$object->getInvoiceArrayList();
 					if (is_array($arraypropal) && count($arraypropal) > 0)
 					{
 						print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=classifybilled&amp;socid='.$object->socid.'">'.$langs->trans("ClassifyBilled").'</a></div>';
 					}
 				}
-	
+
 				// Close
 				if ($object->statut == 1 && $user->rights->propal->cloturer)
 				{
 					print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=statut'.(empty($conf->global->MAIN_JUMP_TAG)?'':'#close').'"';
 					print '>'.$langs->trans('Close').'</a></div>';
 				}
-	
+
 				// Clone
 				if ($user->rights->propal->creer)
 				{
 					print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;socid='.$object->socid.'&amp;action=clone&amp;object='.$object->element.'">'.$langs->trans("ToClone").'</a></div>';
 				}
-	
+
 				// Delete
 				if ($user->rights->propal->supprimer)
 				{
 					print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete"';
 					print '>'.$langs->trans('Delete').'</a></div>';
 				}
-	
+
 			}
 		}
-		
+
 		print '</div>';
 	}
 	print "<br>\n";
@@ -2374,7 +2374,7 @@ else
 			$formmail->add_attached_files($file,basename($file),dol_mimetype($file));
 		}
 
-		$formmail->show_form();
+		print $formmail->get_form();
 
 		print '<br>';
 	}
diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php
index 760324d23e8c17654ada17026a21e1d6f6e9c85d..480fdb9584168a14602058bb2df623094f23333a 100644
--- a/htdocs/commande/fiche.php
+++ b/htdocs/commande/fiche.php
@@ -2676,7 +2676,7 @@ else
 			}
 
 			// Show form
-			$formmail->show_form();
+			print $formmail->get_form();
 
 			print '<br>';
 		}
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index c900b0d7ebb56f05240381afc98d6ac9b838efe2..de05b11a64cf325834b2d5594f6f529f8f51f73a 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -3914,8 +3914,8 @@ else if ($id > 0 || ! empty($ref))
 		{
 			$liste[$key]=$value;
 		}
-		$formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste;
-		$formmail->withtocc=$liste;
+		$formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste;	// List suggested for send to
+		$formmail->withtocc=$liste;	// List suggested for CC
 		$formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC;
 		if(empty($object->ref_client))
 		{
@@ -3972,7 +3972,7 @@ else if ($id > 0 || ! empty($ref))
 			$formmail->add_attached_files($file,basename($file),dol_mimetype($file));
 		}
 
-		$formmail->show_form();
+		print $formmail->get_form();
 
 		print '<br>';
 	}
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index 53adade47ab81418cf44bc4e1e3489828f065f2f..cf15d3f13fcdc109f0aa7bdf3078d53755edfc16 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -90,7 +90,7 @@ class Facture extends CommonInvoice
 	var $close_code;
 	//! Commentaire si mis a paye sans paiement complet
 	var $close_note;
-	//! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code
+	//! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code)
 	var $paye;
 	//! id of source invoice if replacement invoice or credit note
 	var $fk_facture_source;
diff --git a/htdocs/compta/facture/impayees.php b/htdocs/compta/facture/impayees.php
index dd374eb1a6f7e6e5e206ae0e38981447f77b1ffc..36cc7944105fff49c75755f43a74480c5f89f9e8 100644
--- a/htdocs/compta/facture/impayees.php
+++ b/htdocs/compta/facture/impayees.php
@@ -37,6 +37,7 @@ $langs->load("bills");
 $id = (GETPOST('facid','int') ? GETPOST('facid','int') : GETPOST('id','int'));
 $action = GETPOST('action','alpha');
 $option = GETPOST('option');
+$mode=GETPOST('mode');
 
 // Security check
 if ($user->societe_id) $socid=$user->societe_id;
@@ -45,11 +46,157 @@ $result = restrictedArea($user,'facture',$id,'');
 $diroutputpdf=$conf->facture->dir_output . '/unpaid/temp';
 if (! $user->rights->societe->client->voir || $socid) $diroutputpdf.='/private/'.$user->id;	// If user has no permission to see all, output dir is specific to user
 
+$resultmasssend='';
+
 
 /*
  * Action
  */
 
+// Send remind email
+if ($action == 'presend' && GETPOST('cancel')) $action='';
+
+if ($action == 'presend' && GETPOST('sendmail'))
+{
+	if (!isset($user->email))
+	{
+		$error++;
+		setEventMessage("NoSenderEmailDefined");
+	}
+
+	$countToSend = count($_POST['toSend']);
+	if (empty($countToSend))
+	{
+		$error++;
+		setEventMessage("InvoiceNotChecked","warnings");
+	}
+
+	if (! $error)
+	{
+		$compteEmailEnvoi = 0;
+		$nbignored = 0;
+
+		for ($i = 0; $i < $countToSend; $i++)
+		{
+			$object = new Facture($db);
+			$result = $object->fetch($_POST['toSend'][$i]);
+
+			if ($result > 0)	// Invoice was found
+			{
+				if ($object->statut != 1) continue; // Payment done or started or canceled
+
+				// Read PDF
+				$filename=dol_sanitizeFileName($object->ref);
+				$filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref);
+				$file = $filedir . '/' . $filename.'.pdf';			// TODO What if ODT ?
+
+				if (dol_is_file($file))
+				{
+					$object->fetch_thirdparty();
+					$sendto = $object->thirdparty->email;
+
+					if (empty($sendto)) $nbignored++;
+
+					if (dol_strlen($sendto))
+					{
+						$langs->load("commercial");
+						$from = $user->getFullName($langs) . ' <' . $user->email .'>';
+						$replyto = $from;
+						$message = $conf->global->RELANCES_MASSE_TEXTE_EMAIL;
+						$subject = $conf->global->RELANCES_MASSE_OBJET_EMAIL;
+
+						$substitutionarray=
+						make_substitutions($message, $substitutionarray);
+
+						$actiontypecode='AC_FAC';
+						$actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n";
+						if ($message)
+						{
+							$actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n";
+							$actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n";
+							$actionmsg.=$message;
+						}
+											// Create form object
+						include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php');
+						$formmail = new FormMail($db);
+						$formmail->clear_attached_files();
+						$formmail->add_attached_files($file,  $object->ref.'.pdf', 'application/pdf');
+						$attachedfiles=$formmail->get_attached_files();
+						$filepath = $attachedfiles['paths'];
+						$filename = $attachedfiles['names'];
+						$mimetype = $attachedfiles['mimes'];
+
+						// Send mail
+						require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php');
+						$mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1);
+						if ($mailfile->error)
+						{
+							$resultmasssend.='<div class="error">'.$mailfile->error.'</div>';
+						}
+						else
+						{
+							$result=$mailfile->sendfile();
+							if ($result)
+							{
+								$resultmasssend.=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2));		// Must not contain "
+
+								$error=0;
+
+								// Initialisation donnees
+								$object->sendtoid		= 0;
+								$object->actiontypecode	= $actiontypecode;
+								$object->actionmsg		= $actionmsg;  // Long text
+								$object->actionmsg2		= $actionmsg2; // Short text
+								$object->fk_element		= $object->id;
+								$object->elementtype	= $object->element;
+
+								// Appel des triggers
+								include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
+								$interface=new Interfaces($db);
+								$result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf);
+								if ($result < 0) { $error++; $this->errors=$interface->errors; }
+								// Fin appel triggers
+
+								if ($error)
+								{
+									dol_print_error($db);
+								}
+								$compteEmailEnvoi ++;
+
+							}
+							else
+							{
+								$langs->load("other");
+								$resultmasssend.='<div class="error">';
+								if ($mailfile->error)
+								{
+									$resultmasssend.=$langs->trans('ErrorFailedToSendMail',$from,$sendto);
+									$resultmasssend.='<br>'.$mailfile->error;
+								}
+								else
+								{
+									$resultmasssend.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
+								}
+								$resultmasssend.='</div>';
+							}
+						}
+					}
+				}
+				else
+				{
+					$langs->load("other");
+					print $resultmasssend='<div class="error">'.$langs->trans('ErrorCantReadFile',$file).'</div>';
+					dol_syslog('Failed to read file: '.$file);
+					break ;
+				}
+			}
+		}
+
+		setEventMessage($compteEmailEnvoi. '/'.$countToSend.' '.$langs->trans("RemindSent"));
+	}
+}
+
+
 if ($action == "builddoc" && $user->rights->facture->lire && ! GETPOST('button_search'))
 {
 	if (is_array($_POST['toGenerate']))
@@ -61,9 +208,12 @@ if ($action == "builddoc" && $user->rights->facture->lire && ! GETPOST('button_s
 		// liste les fichiers
 		$files = array();
 		$factures_bak = $factures ;
-		foreach($_POST['toGenerate'] as $basename){
-			foreach($factures as $facture){
-				if(strstr($facture["name"],$basename)){
+		foreach($_POST['toGenerate'] as $basename)
+		{
+			foreach($factures as $facture)
+			{
+				if(strstr($facture["name"],$basename))
+				{
 					$files[] = $conf->facture->dir_output.'/'.$basename.'/'.$facture["name"];
 				}
 			}
@@ -121,12 +271,12 @@ if ($action == "builddoc" && $user->rights->facture->lire && ! GETPOST('button_s
 		}
 		else
 		{
-			$mesg='<div class="error">'.$langs->trans('NoPDFAvailableForChecked').'</div>';
+			setEventMessage($langs->trans('NoPDFAvailableForChecked'),'errors');
 		}
 	}
 	else
 	{
-		$mesg='<div class="error">'.$langs->trans('InvoiceNotChecked').'</div>' ;
+		setEventMessage($langs->trans('InvoiceNotChecked'), 'warnings');
 	}
 }
 
@@ -167,6 +317,12 @@ $(document).ready(function() {
 	$("#checknone").click(function() {
 		$(".checkformerge").attr('checked', false);
 	});
+	$("#checkallsend").click(function() {
+		$(".checkforsend").attr('checked', true);
+	});
+	$("#checknonesend").click(function() {
+		$(".checkforsend").attr('checked', false);
+	});
 });
 </script>
 <?php
@@ -268,6 +424,7 @@ if ($resql)
 
 	print '<form id="form_generate_pdf" method="POST" action="'.$_SERVER["PHP_SELF"].'?sortfield='. $sortfield .'&sortorder='. $sortorder .'">';
 	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+	print '<input type="hidden" name="mode" value="'.$mode.'">';
 	if ($late) print '<input type="hidden" name="late" value="'.dol_escape_htmltag($late).'">';
 
 	$i = 0;
@@ -283,7 +440,14 @@ if ($resql)
 	print_liste_field_titre($langs->trans("Received"),$_SERVER["PHP_SELF"],"am","",$param,'align="right"',$sortfield,$sortorder);
 	print_liste_field_titre($langs->trans("Rest"),$_SERVER["PHP_SELF"],"am","",$param,'align="right"',$sortfield,$sortorder);
 	print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"fk_statut,paye,am","",$param,'align="right"',$sortfield,$sortorder);
-	print_liste_field_titre($langs->trans("Merge"),$_SERVER["PHP_SELF"],"","",$param,'align="center"',$sortfield,$sortorder);
+	if (empty($mode))
+	{
+		print_liste_field_titre($langs->trans("PDFMerge"),$_SERVER["PHP_SELF"],"","",$param,'align="center"',$sortfield,$sortorder);
+	}
+	else
+	{
+		print_liste_field_titre($langs->trans("Remind"),$_SERVER["PHP_SELF"],"","",$param,'align="center"',$sortfield,$sortorder);
+	}
 	print "</tr>\n";
 
 	// Lignes des champs de filtre
@@ -302,9 +466,18 @@ if ($resql)
 	print '<td class="liste_titre" align="right">';
 	print '<input type="image" class="liste_titre" name="button_search" src="'.img_picto($langs->trans("Search"),'search.png','','',1).'" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
 	print '</td>';
-	print '<td class="liste_titre" align="center">';
-	if ($conf->use_javascript_ajax) print '<a href="#" id="checkall">'.$langs->trans("All").'</a> / <a href="#" id="checknone">'.$langs->trans("None").'</a>';
-	print '</td>';
+	if (empty($mode))
+	{
+		print '<td class="liste_titre" align="center">';
+		if ($conf->use_javascript_ajax) print '<a href="#" id="checkall">'.$langs->trans("All").'</a> / <a href="#" id="checknone">'.$langs->trans("None").'</a>';
+		print '</td>';
+	}
+	else
+	{
+		print '<td class="liste_titre" align="center">';
+		if ($conf->use_javascript_ajax) print '<a href="#" id="checkallsend">'.$langs->trans("All").'</a> / <a href="#" id="checknonesend">'.$langs->trans("None").'</a>';
+		print '</td>';
+	}
 	print "</tr>\n";
 
 	if ($num > 0)
@@ -384,13 +557,23 @@ if ($resql)
 			print $facturestatic->LibStatut($objp->paye,$objp->fk_statut,5,$objp->am);
 			print '</td>';
 
-			// Checkbox
-			print '<td align="center">';
-			if (! empty($formfile->numoffiles))
-				print '<input id="cb'.$objp->facid.'" class="flat checkformerge" type="checkbox" name="toGenerate[]" value="'.$objp->facnumber.'">';
+			if (empty($mode))
+			{
+				// Checkbox to merge
+				print '<td align="center">';
+				if (! empty($formfile->numoffiles))
+					print '<input id="cb'.$objp->facid.'" class="flat checkformerge" type="checkbox" name="toGenerate[]" value="'.$objp->facnumber.'">';
+				else
+					print '&nbsp;';
+				print '</td>' ;
+			}
 			else
-				print '&nbsp;';
-			print '</td>' ;
+			{
+				// Checkbox to send remind
+				print '<td align="center">';
+				print '<input class="flat checkforsend" type="checkbox" name="toSend[]" value="'.$objp->facid.'">';
+				print '</td>' ;
+			}
 
 			print "</tr>\n";
 			$total_ht+=$objp->total_ht;
@@ -415,17 +598,85 @@ if ($resql)
 
 	print "</table>";
 
-	/*
-	 * Show list of available documents
-	 */
-	$filedir=$diroutputpdf;
-	$genallowed=$user->rights->facture->lire;
-	$delallowed=$user->rights->facture->lire;
-
-	print '<br>';
-	print '<input type="hidden" name="option" value="'.$option.'">';
-	// We disable multilang because we concat already existing pdf.
-	$formfile->show_documents('unpaid','',$filedir,$urlsource,$genallowed,$delallowed,'',1,1,0,48,1,$param,$langs->trans("PDFMerge"),$langs->trans("PDFMerge"));
+
+	if (empty($mode))
+	{
+		/*
+		 * Show list of available documents
+		 */
+		$filedir=$diroutputpdf;
+		$genallowed=$user->rights->facture->lire;
+		$delallowed=$user->rights->facture->lire;
+
+		print '<br>';
+		print '<input type="hidden" name="option" value="'.$option.'">';
+		// We disable multilang because we concat already existing pdf.
+		$formfile->show_documents('unpaid','',$filedir,$urlsource,$genallowed,$delallowed,'',1,1,0,48,1,$param,$langs->trans("PDFMerge"),$langs->trans("PDFMerge"));
+	}
+	else
+	{
+		$langs->load("mails");
+
+		if ($action != 'presend')
+		{
+			print '<div class="tabsAction">';
+			print '<a href="'.$_SERVER["PHP_SELF"].'?mode=sendremind&action=presend" class="butAction" name="buttonsendremind" value="'.dol_escape_htmltag($langs->trans("SendRemind")).'">'.$langs->trans("SendRemind").'</a>';
+			print '</div>';
+		}
+		else
+		{
+			include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
+			$formmail = new FormMail($db);
+
+			print '<br>';
+			print_fiche_titre($langs->trans("SendRemind"),'','').'<br>';
+
+			$topicmail="MailTopicSendRemindUnpaidInvoices";
+			$modelmail="facture_relance";
+
+			// Cree l'objet formulaire mail
+			include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
+			$formmail = new FormMail($db);
+			$formmail->fromtype = 'user';
+			$formmail->fromid   = $user->id;
+			$formmail->fromname = $user->getFullName($langs);
+			$formmail->frommail = $user->email;
+			$formmail->withfrom=1;
+			$liste=array();
+			$formmail->withto='';
+			$formmail->withtocc=1;
+			$formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC;
+			$formmail->withtopic=$langs->transnoentities($topicmail, '__FACREF__', '__REFCLIENT__');
+			$formmail->withfile=$langs->trans("EachInvoiceWillBeAttachedToEmail");
+			$formmail->withbody=1;
+			$formmail->withdeliveryreceipt=1;
+			$formmail->withcancel=1;
+			// Tableau des substitutions
+			//$formmail->substit['__FACREF__']='';
+			$formmail->substit['__SIGNATURE__']=$user->signature;
+			//$formmail->substit['__REFCLIENT__']='';
+			$formmail->substit['__PERSONALIZED__']='';
+			$formmail->substit['__CONTACTCIVNAME__']='';
+
+			// Tableau des parametres complementaires du post
+			$formmail->param['action']=$action;
+			$formmail->param['models']=$modelmail;
+			$formmail->param['facid']=$object->id;
+			$formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id;
+
+			print $formmail->get_form();
+
+
+		}
+
+		if ($resultmasssend)
+		{
+			print '<br><strong>'.$langs->trans("ResultOfMassSending").':</strong><br>'."\n";
+			print $resultmasssend;
+			print '<br>';
+		}
+	}
+
 	print '</form>';
 
 	$db->free($resql);
diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
index 66fd945c01d8d2909c67ca320909c4847dbffe21..7746d178e676b21f9c22e9d4e09c5547f638ccc9 100644
--- a/htdocs/core/class/html.formmail.class.php
+++ b/htdocs/core/class/html.formmail.class.php
@@ -76,7 +76,7 @@ class FormMail
      *  @param	DoliDB	$db      Database handler
      */
     function __construct($db)
-    {    	
+    {
         $this->db = $db;
 
         $this->withform=1;
@@ -503,39 +503,47 @@ class FormMail
         	{
         		$out.= '<tr>';
         		$out.= '<td width="180">'.$langs->trans("MailFile").'</td>';
+
         		$out.= '<td>';
-        		// TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
-        		$out.= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
-        		$out.= '<script type="text/javascript" language="javascript">';
-        		$out.= 'jQuery(document).ready(function () {';
-        		$out.= '    jQuery(".removedfile").click(function() {';
-        		$out.= '        jQuery(".removedfilehidden").val(jQuery(this).val());';
-        		$out.= '    });';
-        		$out.= '})';
-        		$out.= '</script>'."\n";
-        		if (count($listofpaths))
+        		if (is_numeric($this->withfile))
         		{
-        			foreach($listofpaths as $key => $val)
-        			{
-        				$out.= '<div id="attachfile_'.$key.'">';
-        				$out.= img_mime($listofnames[$key]).' '.$listofnames[$key];
-        				if (! $this->withfilereadonly)
-        				{
-        					$out.= ' <input type="image" style="border: 0px;" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/delete.png" value="'.($key+1).'" class="removedfile" id="removedfile_'.$key.'" name="removedfile_'.$key.'" />';
-        					//$out.= ' <a href="'.$_SERVER["PHP_SELF"].'?removedfile='.($key+1).' id="removedfile_'.$key.'">'.img_delete($langs->trans("Delete").'</a>';
-        				}
-        				$out.= '<br></div>';
-        			}
+	        		// TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
+	        		$out.= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
+	        		$out.= '<script type="text/javascript" language="javascript">';
+	        		$out.= 'jQuery(document).ready(function () {';
+	        		$out.= '    jQuery(".removedfile").click(function() {';
+	        		$out.= '        jQuery(".removedfilehidden").val(jQuery(this).val());';
+	        		$out.= '    });';
+	        		$out.= '})';
+	        		$out.= '</script>'."\n";
+	        		if (count($listofpaths))
+	        		{
+	        			foreach($listofpaths as $key => $val)
+	        			{
+	        				$out.= '<div id="attachfile_'.$key.'">';
+	        				$out.= img_mime($listofnames[$key]).' '.$listofnames[$key];
+	        				if (! $this->withfilereadonly)
+	        				{
+	        					$out.= ' <input type="image" style="border: 0px;" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/delete.png" value="'.($key+1).'" class="removedfile" id="removedfile_'.$key.'" name="removedfile_'.$key.'" />';
+	        					//$out.= ' <a href="'.$_SERVER["PHP_SELF"].'?removedfile='.($key+1).' id="removedfile_'.$key.'">'.img_delete($langs->trans("Delete").'</a>';
+	        				}
+	        				$out.= '<br></div>';
+	        			}
+	        		}
+	        		else
+	        		{
+	        			$out.= $langs->trans("NoAttachedFiles").'<br>';
+	        		}
+	        		if ($this->withfile == 2)	// Can add other files
+	        		{
+	        			$out.= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
+	        			$out.= ' ';
+	        			$out.= '<input type="submit" class="button" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
+	        		}
         		}
         		else
         		{
-        			$out.= $langs->trans("NoAttachedFiles").'<br>';
-        		}
-        		if ($this->withfile == 2)	// Can add other files
-        		{
-        			$out.= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
-        			$out.= ' ';
-        			$out.= '<input type="submit" class="button" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
+        			$out.=$this->withfile;
         		}
         		$out.= "</td></tr>\n";
         	}
@@ -554,7 +562,8 @@ class FormMail
         		elseif ($this->param["models"]=='invoice_supplier_send')	{ $defaultmessage=$langs->transnoentities("PredefinedMailContentSendSupplierInvoice"); }
         		elseif ($this->param["models"]=='shipping_send')			{ $defaultmessage=$langs->transnoentities("PredefinedMailContentSendShipping"); }
         		elseif ($this->param["models"]=='fichinter_send')			{ $defaultmessage=$langs->transnoentities("PredefinedMailContentSendFichInter"); }
-        		elseif (! is_numeric($this->withbody))                      { $defaultmessage=$this->withbody; }
+        	    elseif ($this->param["models"]=='thirdparty')				{ $defaultmessage=$langs->transnoentities("PredefinedMailContentThirdparty"); }
+        		elseif (! is_numeric($this->withbody))						{ $defaultmessage=$this->withbody; }
 
         		// Complete substitution array
         		if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_ADD_PAYMENT_URL))
@@ -576,14 +585,14 @@ class FormMail
         		}
 
 				$defaultmessage=str_replace('\n',"\n",$defaultmessage);
-				
+
 				// Deal with format differences between message and signature (text / HTML)
 				if(dol_textishtml($defaultmessage) && !dol_textishtml($this->substit['__SIGNATURE__'])) {
 					$this->substit['__SIGNATURE__'] = dol_nl2br($this->substit['__SIGNATURE__']);
 				} else if(!dol_textishtml($defaultmessage) && dol_textishtml($this->substit['__SIGNATURE__'])) {
 					$defaultmessage = dol_nl2br($defaultmessage);
 				}
-				
+
         		$defaultmessage=make_substitutions($defaultmessage,$this->substit);
         		if (isset($_POST["message"])) $defaultmessage=$_POST["message"];
 
diff --git a/htdocs/core/js/lib_head.js b/htdocs/core/js/lib_head.js
index cfb2977c37022167a4cb6266c8db166c1fa87957..a9b7f9e4c18685e83755c5c1dc8ec37964bdca36 100644
--- a/htdocs/core/js/lib_head.js
+++ b/htdocs/core/js/lib_head.js
@@ -899,6 +899,24 @@ function confirmConstantAction(action, url, code, input, box, entity, yesButton,
     });
 })( jQuery );
 
+
+/*
+ * Function to output a dialog bog for copy/paste
+ * 
+ * @param	string	text	Text to put into copy/paste area
+ * @param	string	text2	Text to put under the copy/paste area
+ */
+function copyToClipboard(text,text2) 
+{
+	text = text.replace(/<br>/g,"\n");
+	var newElem = "<textarea id=\"coords\" style=\"border: none; width: 90%; height: 120px;\">"+text+"</textarea><br><br>"+text2;
+	$("#dialog").html(newElem);
+	$("#dialog").dialog();
+	$("#coords").select();
+	return false;
+}
+
+
 /* 
  * Timer for delayed keyup function
  * 
diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php
index 849b8901ab30aa74d415b65b00a8fdf2945ed0fc..42da0b04d38fa9bf30085292e390c571fac68ea8 100644
--- a/htdocs/core/lib/company.lib.php
+++ b/htdocs/core/lib/company.lib.php
@@ -637,12 +637,12 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='')
     print "</tr>";
 
 
-    $sql = "SELECT p.rowid, p.lastname, p.firstname, p.fk_pays, p.poste, p.phone, p.phone_mobile, p.fax, p.email, p.skype, p.statut ";
+    $sql = "SELECT p.rowid, p.lastname, p.firstname, p.fk_pays as country_id, p.poste, p.phone, p.phone_mobile, p.fax, p.email, p.skype, p.statut ";
     $sql .= ", p.civilite, p.address, p.zip, p.town";
     $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as p";
     $sql .= " WHERE p.fk_soc = ".$object->id;
     if ($search_status!='') $sql .= " AND p.statut = ".$db->escape($search_status);
-    if ($search_name)   $sql .= " AND (p.lastname LIKE '%".$db->escape(strtolower($search_name))."%' OR p.firstname LIKE '%".$db->escape(strtolower($search_name))."%')";
+    if ($search_name)       $sql .= " AND (p.lastname LIKE '%".$db->escape($search_name)."%' OR p.firstname LIKE '%".$db->escape($search_name)."%')";
     $sql.= " ORDER BY $sortfield $sortorder";
 
     dol_syslog('core/lib/company.lib.php :: show_contacts sql='.$sql,LOG_DEBUG);
@@ -665,12 +665,13 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='')
             $contactstatic->statut = $obj->statut;
             $contactstatic->lastname = $obj->lastname;
             $contactstatic->firstname = $obj->firstname;
+            $contactstatic->civilite = $obj->civilite;
             print $contactstatic->getNomUrl(1);
             print '</td>';
 
             print '<td>'.$obj->poste.'</td>';
 
-            $country_code = getCountry($obj->fk_pays, 'all');
+            $country_code = getCountry($obj->country_id, 'all');
 
             // Lien click to dial
             print '<td>';
@@ -695,41 +696,26 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='')
             // Status
 			print '<td>'.$contactstatic->getLibStatut(5).'</td>';
 
-			// Copy to clipboard
-			$coords = '';
-			if (!empty($object->name))
-				$coords .= addslashes($object->name)."<br />";
-			if (!empty($obj->civilite))
-				$coords .= addslashes($obj->civilite).' ';
-			if (!empty($obj->firstname))
-				$coords .= addslashes($obj->firstname).' ';
-			if (!empty($obj->lastname))
-				$coords .= addslashes($obj->lastname);
-			$coords .= "<br />";
-			if (!empty($obj->address))
-			{
-				$coords .= addslashes(dol_nl2br($obj->address,1,true))."<br />";
-				if (!empty($obj->cp))
-					$coords .= addslashes($obj->zip).' ';
-				if (!empty($obj->ville))
-					$coords .= addslashes($obj->town);
-				if (!empty($obj->pays))
-					$coords .= "<br />".addslashes($country_code['label']);
-			}
-			elseif (!empty($object->address))
-			{
-				$coords .= addslashes(dol_nl2br($object->address,1,true))."<br />";
-				if (!empty($object->zip))
-					$coords .= addslashes($object->zip).' ';
-				if (!empty($object->town))
-					$coords .= addslashes($object->town);
-				if (!empty($object->country))
-					$coords .= "<br />".addslashes($object->country);
-			}
-
-            print '<td align="center"><a href="#" onclick="return copyToClipboard(\''.$coords.'\');">';
-            print img_picto($langs->trans("Address"), 'object_address.png');
-            print '</a></td>';
+            print '<td align="center">';
+            if (! empty($conf->use_javascript_ajax))
+            {
+       			// Copy to clipboard
+				$coords = '';
+				if (!empty($object->name))   $coords .= $object->name."<br>";
+				$coords .= $contactstatic->getFullName($langs,1).' ';
+				$coords .= "<br>";
+				if (!empty($obj->address))
+				{
+					$coords .= dol_nl2br($obj->address,1,true)."<br>";
+					if (!empty($obj->zip))  $coords .= $obj->zip.' ';
+					if (!empty($obj->town)) $coords .= $obj->town;
+					if (!empty($obj->country_id)) $coords .= "<br>".$country_code['label'];
+				}
+            	print '<a href="#" onclick="return copyToClipboard(\''.dol_escape_js($coords).'\',\''.dol_escape_js($langs->trans("HelpCopyToClipboard")).'\');">';
+            	print img_picto($langs->trans("Address"), 'object_address.png');
+            	print '</a>';
+            }
+            print '</td>';
 
             // Add to agenda
             if (! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create)
@@ -761,7 +747,7 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='')
         }
     }
     else
-    {
+	{
         print "<tr ".$bc[$var].">";
         print '<td colspan="'.$colspan.'">'.$langs->trans("None").'</td>';
         print "</tr>\n";
@@ -775,16 +761,6 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='')
 <div id="dialog" title="<?php echo dol_escape_htmltag($langs->trans('Address')); ?>" style="display: none;">
 </div>
 <?php
-	print '<script type="text/javascript">
-			function copyToClipboard (text) {
-			  text = text.replace(/<br \/>/g,"\n");
-			  var newElem = "<textarea id=\"coords\" style=\"border: none; width: 90%; height: 120px;\">"+text+"</textarea><br/><br/>'.$langs->trans('HelpCopyToClipboard').'";
-			  $("#dialog").html(newElem);
-			  $( "#dialog" ).dialog();
-			  $("#coords").select();
-			  return false;
-			}
-	</script>';
 
     return $i;
 }
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index b9e25aa58f1b3e1244cf5a28cff44de9f29c53c2..19d2adeea9346ca347aba43db11675846d252e76 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -438,7 +438,7 @@ function dol_string_nospecial($str,$newstr='_',$badchars='')
  *  Returns text escaped for inclusion into javascript code
  *
  *  @param      string		$stringtoescape		String to escape
- *  @param		string		$mode				0=Escape also ' and " into ', 1=Escape ' but not " for usage into 'string', 2=Escape " but not ' for usage into "string"
+ *  @param		string		$mode				0=Escape also ' and " into ', 1=Escape ' but not " for usage into 'string', 2=Escape " but not ' for usage into "string", 3=Escape ' and " with \
  *  @return     string     		 				Escaped string. Both ' and " are escaped into ' if they are escaped.
  */
 function dol_escape_js($stringtoescape, $mode=0)
@@ -449,6 +449,7 @@ function dol_escape_js($stringtoescape, $mode=0)
 	if (empty($mode)) { $substitjs["'"]="\\'"; $substitjs['"']="\\'"; }
 	else if ($mode == 1) $substitjs["'"]="\\'";
 	else if ($mode == 2) { $substitjs['"']='\\"'; }
+	else if ($mode == 3) { $substitjs["'"]="\\'"; $substitjs['"']="\\\""; }
 	return strtr($stringtoescape, $substitjs);
 }
 
diff --git a/htdocs/core/menus/standard/auguria_menu.php b/htdocs/core/menus/standard/auguria_menu.php
index 74612aa57fdf76bad2cf83581a7ba25c1fa3351b..ac84a0713f39f5260e85edd293f873267551e43d 100644
--- a/htdocs/core/menus/standard/auguria_menu.php
+++ b/htdocs/core/menus/standard/auguria_menu.php
@@ -110,12 +110,12 @@ class MenuManager
 
     	// Modules system tools
     	// TODO Find a way to add parent menu only if child menu exists. For the moment, no other method than hard coded methods.
-    	if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->global->MAIN_MENU_ENABLE_MODULETOOLS))
+    	if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->barcode->enabled)		// TODO We should enabled module system tools entry without hardcoded test, but when at least one modules bringing such entries are on
+    		|| ! empty($conf->global->MAIN_MENU_ENABLE_MODULETOOLS))
     	{
     		if (empty($user->societe_id))
     		{
-    		    //$newmenu->add("/admin/tools/index.php?mainmenu=home&leftmenu=modulesadmintools", $langs->trans("ModulesSystemTools"), 0, 1, '', 'home', 'modulesadmintools');
-    			if ($leftmenu=="modulesadmintools" && $user->admin)
+    			if ((! empty($conf->product->enabled) || ! empty($conf->service->enabled)) && ($leftmenu=="modulesadmintools" && $user->admin))
     			{
     				$langs->load("products");
     				$array_menu_product=array(
@@ -131,9 +131,9 @@ class MenuManager
 			    			'type'=>'left',
 			    			'position'=>20
 			    	);
-			    	array_unshift($tabMenu,$array_menu_product);
-    				//$newmenu->add("/product/admin/product_tools.php?mainmenu=home&leftmenu=modulesadmintools", $langs->trans("ProductVatMassChange"), 1, $user->admin);
+			    	array_unshift($tabMenu,$array_menu_product);	// add at beginning of array
     			}
+    			// Main menu title
     			$array_menu_product=array(
 		    		'url'=>"/admin/tools/index.php?mainmenu=home&leftmenu=modulesadmintools",
 		    		'titre'=>$langs->trans("ModulesSystemTools"),
@@ -146,7 +146,7 @@ class MenuManager
 		    		'type'=>'left',
 		    		'position'=>20
 				);
-    			array_unshift($tabMenu,$array_menu_product);
+    			array_unshift($tabMenu,$array_menu_product);	// add at beginning of array
     		}
     	}
 
diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php
index 14de23b298f76c624bb3faf2903e16651e3b0f33..6c7e64d118a3c0198376b1e00a17c182498f16a6 100644
--- a/htdocs/core/menus/standard/eldy.lib.php
+++ b/htdocs/core/menus/standard/eldy.lib.php
@@ -539,11 +539,13 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
 				}
 
 				// Modules system tools
-				if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->global->MAIN_MENU_ENABLE_MODULETOOLS))
+				if (! empty($conf->product->enabled) || ! empty($conf->service->enabled) || ! empty($conf->barcode->enabled)	// TODO We should enabled module system tools entry without hardcoded test, but when at least one modules bringing such entries are on
+					|| ! empty($conf->global->MAIN_MENU_ENABLE_MODULETOOLS))	// Some external modules may need to force to have this entry on.
 				{
 					if (empty($user->societe_id))
 					{
 						$newmenu->add("/admin/tools/index.php?mainmenu=home&amp;leftmenu=modulesadmintools", $langs->trans("ModulesSystemTools"), 0, 1, '', $mainmenu, 'modulesadmintools');
+						// Special case: This entry can't be embedded into modules because we need it for both module service and products and we don't want duplicate lines.
 						if ((empty($leftmenu) || $leftmenu=="modulesadmintools") && $user->admin)
 						{
 							$langs->load("products");
diff --git a/htdocs/core/modules/barcode/mod_barcode_product_standard.php b/htdocs/core/modules/barcode/mod_barcode_product_standard.php
index d20c7502f4a72f49837af8d2bc2c61e62d1d2ab5..c7a48c80b2ff294bdc8c77747951f4c4e5f44e9c 100644
--- a/htdocs/core/modules/barcode/mod_barcode_product_standard.php
+++ b/htdocs/core/modules/barcode/mod_barcode_product_standard.php
@@ -190,15 +190,29 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode
 		}
 		else
 		{
-			// Get Mask value
-			$mask = empty($conf->global->BARCODE_STANDARD_PRODUCT_MASK)?'':$conf->global->BARCODE_STANDARD_PRODUCT_MASK;
-			if (! $mask)
+			if ($this->verif_syntax($code) >= 0)
 			{
-				$this->error='NotConfigured';
-				return '';
+				$is_dispo = $this->verif_dispo($db, $code, $product);
+				if ($is_dispo <> 0)
+				{
+					$result=-3;
+				}
+				else
+				{
+					$result=0;
+				}
+			}
+			else
+			{
+				if (dol_strlen($code) == 0)
+				{
+					$result=-2;
+				}
+				else
+				{
+					$result=-1;
+				}
 			}
-
-			$result=check_value($mask,$code);
 		}
 
 		dol_syslog(get_class($this)."::verif type=".$type." result=".$result);
@@ -216,8 +230,8 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode
 	 */
 	function verif_dispo($db, $code, $product)
 	{
-		$sql = "SELECT ref FROM ".MAIN_DB_PREFIX."product";
-		$sql.= " WHERE ref = '".$code."'";
+		$sql = "SELECT barcode FROM ".MAIN_DB_PREFIX."product";
+		$sql.= " WHERE barcode = '".$code."'";
 		if ($product->id > 0) $sql.= " AND rowid <> ".$product->id;
 
 		$resql=$db->query($sql);
@@ -239,6 +253,31 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode
 
 	}
 
+	/**
+	 *	Renvoi si un code respecte la syntaxe
+	 *
+	 *	@param	string		$code		Code a verifier
+	 *	@return	int						0 if OK, <0 if KO
+	 */
+	function verif_syntax($code)
+	{
+		global $conf;
+
+		$res = 0;
+
+		// Get Mask value
+		$mask = empty($conf->global->BARCODE_STANDARD_PRODUCT_MASK)?'':$conf->global->BARCODE_STANDARD_PRODUCT_MASK;
+		if (! $mask)
+		{
+			$this->error='NotConfigured';
+			return '';
+		}
+
+		$result=check_value($mask,$code);
+
+		return $result;
+	}
+
 }
 
 ?>
diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php
index 283d62e2700326fd90df6a4f5e764850ab05e676..bbc16750dd6abd0fe37ea067b6c62d75a77eb396 100644
--- a/htdocs/core/modules/modBarcode.class.php
+++ b/htdocs/core/modules/modBarcode.class.php
@@ -101,14 +101,26 @@ class modBarcode extends DolibarrModules
         						'leftmenu'=>'barcodeprint',
         						'type'=>'left',			                // This is a Left menu entry
 						        'titre'=>'BarCodePrintsheet',
-						        'url'=>'/barcode/printsheet.php',
+						        'url'=>'/barcode/printsheet.php?mainmenu=home&amp;leftmenu=modulesadmintools',
 						        'langs'=>'products',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
 						        'position'=>200,
 						        'enabled'=>'$conf->barcode->enabled',  // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
         				        'perms'=>'1',			    // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
 						        'target'=>'',
 						        'user'=>2);				                // 0=Menu for internal users, 1=external users, 2=both
-        $r++;
+		$r++;
+
+		$this->menu[$r]=array(	'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools',		    // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+								'type'=>'left',			                // This is a Left menu entry
+								'titre'=>'MassBarcodeInit',
+								'url'=>'/barcode/codeinit.php?mainmenu=home&leftmenu=modulesadmintools',
+								'langs'=>'products',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+								'position'=>300,
+								'enabled'=>'$conf->barcode->enabled && $leftmenu=="modulesadmintools"',   // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+								'perms'=>'1',			                // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
+								'target'=>'',
+								'user'=>0);				                // 0=Menu for internal users, 1=external users, 2=both
+		$r++;
 	}
 
 
diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php
index 43cab4f72cff63dde4b638ad94251dca94e6a54c..b9185624209eaa0f4ace98a4c2cc157d6bb23d0b 100644
--- a/htdocs/core/modules/modProduct.class.php
+++ b/htdocs/core/modules/modProduct.class.php
@@ -129,6 +129,20 @@ class modProduct extends DolibarrModules
 		$this->rights[$r][4] = 'export';
         $r++;
 
+		/* We can't enable this here because it must be enabled in both product and service module and this create duplicate insert
+		$r=0;
+		$this->menu[$r]=array(	'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools',		    // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+								'type'=>'left',			                // This is a Left menu entry
+								'titre'=>'ProductVatMassChange',
+								'url'=>'/product/admin/product_tools.php?mainmenu=home&leftmenu=modulesadmintools',
+								'langs'=>'products',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+								'position'=>300,
+								'enabled'=>'$conf->product->enabled && $leftmenu=="modulesadmintools"',   // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+								'perms'=>'1',			                // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
+								'target'=>'',
+								'user'=>0);				                // 0=Menu for internal users, 1=external users, 2=both
+		$r++;
+		*/
 
 		// Exports
 		//--------
diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php
index eb472a257992826809b3d47bd65c41497e0ebde4..695ff596e6eec74cfc79a4fe30b75344dd30705b 100644
--- a/htdocs/core/modules/modService.class.php
+++ b/htdocs/core/modules/modService.class.php
@@ -114,6 +114,22 @@ class modService extends DolibarrModules
         $r++;
 
 
+		/* We can't enable this here because it must be enabled in both product and service module and this create duplicate insert
+		$r=0;
+		$this->menu[$r]=array(	'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools',		    // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
+								'type'=>'left',			                // This is a Left menu entry
+								'titre'=>'ProductVatMassChange',
+								'url'=>'/product/admin/product_tools.php?mainmenu=home&leftmenu=modulesadmintools',
+								'langs'=>'products',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+								'position'=>300,
+								'enabled'=>'$conf->product->enabled && $leftmenu=="modulesadmintools"',   // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+								'perms'=>'1',			                // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
+								'target'=>'',
+								'user'=>0);				                // 0=Menu for internal users, 1=external users, 2=both
+		$r++;
+		*/
+
+
 		// Exports
 		//--------
 		$r=0;
diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
index b089b5487a74e93f10b31cd1efb158520f0624f5..6ab80b6ad883a3986f990bdc09e2ea8fcac95e24 100644
--- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
+++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
@@ -1,7 +1,7 @@
 <?php
 /* Copyright (C) 2005-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2009-2011 Regis Houssin        <regis.houssin@capnetworks.com>
- * Copyright (C) 2011	   Juanjo Menent        <jmenent@2byte.es>
+ * Copyright (C) 2011-2013 Juanjo Menent        <jmenent@2byte.es>
  * Copyright (C) 2013	   Cedric GROSS         <c.gross@kreiz-it.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -373,6 +373,25 @@ class InterfaceActionsAuto
             // Parameters $object->sendotid defined by caller
             //$object->sendtoid=0;
             $ok=1;
+        }
+    	elseif ($action == 'SHIPPING_VALIDATE')
+        {
+        	dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
+        	$langs->load("other");
+        	$langs->load("sendings");
+        	$langs->load("agenda");
+        
+        	$object->actiontypecode='AC_OTH_AUTO';
+        	if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ShippingValidated",$object->ref);
+        	if (empty($object->actionmsg))
+        	{
+        		$object->actionmsg=$langs->transnoentities("ShippingValidated",$object->ref);
+        		$object->actionmsg.="\n".$langs->transnoentities("Author").': '.$user->login;
+        	}
+        
+        	// Parameters $object->sendtoid defined by caller
+        	//$object->sendtoid=0;
+        	$ok=1;
         }
 		elseif ($action == 'SHIPPING_SENTBYMAIL')
         {
diff --git a/htdocs/expedition/fiche.php b/htdocs/expedition/fiche.php
index 0a5d3d0cfcf5438689fd9102e27aadce18f28967..c04c4966efe9a86fa3a6bd1f67875329219be4a1 100644
--- a/htdocs/expedition/fiche.php
+++ b/htdocs/expedition/fiche.php
@@ -1542,7 +1542,7 @@ else if ($id || $ref)
 		}
 
 		// Show form
-		$formmail->show_form();
+		print $formmail->get_form();
 
 		print '<br>';
 	}
diff --git a/htdocs/fichinter/fiche.php b/htdocs/fichinter/fiche.php
index e40d2b44daab3536a7a8ec2a62b94d756108c28d..15e08bad60494b08180247adcb8771ae4daf7279 100644
--- a/htdocs/fichinter/fiche.php
+++ b/htdocs/fichinter/fiche.php
@@ -1709,7 +1709,7 @@ else if ($id > 0 || ! empty($ref))
 			$formmail->add_attached_files($file,basename($file),dol_mimetype($file));
 		}
 
-		$formmail->show_form();
+		print $formmail->get_form();
 
 		print '<br>';
 	}
diff --git a/htdocs/fourn/commande/fiche.php b/htdocs/fourn/commande/fiche.php
index ffa72ecf9ac2b13b85b8ff05f701b7d830ca3009..8da53a67477471eed95d35c2200b2c008e1d34e1 100644
--- a/htdocs/fourn/commande/fiche.php
+++ b/htdocs/fourn/commande/fiche.php
@@ -1634,13 +1634,13 @@ elseif (! empty($object->id))
 			}
 
 			print '<td align="right" class="nowrap">'.price($line->total_ht).'</td>';
-			
+
 			if (is_object($hookmanager))
 			{
 				$parameters=array('line'=>$line,'num'=>$num,'i'=>$i);
 				$reshook=$hookmanager->executeHooks('printObjectLine',$parameters,$object,$action);
 			}
-			
+
 			if ($object->statut == 0	&& $user->rights->fournisseur->commande->creer)
 			{
 				print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=edit_line&amp;rowid='.$line->id.'#'.$line->id.'">';
@@ -2132,7 +2132,7 @@ elseif (! empty($object->id))
 		}
 
 		// Show form
-		$formmail->show_form();
+		print $formmail->get_form();
 
 		print '<br>';
 	}
diff --git a/htdocs/fourn/facture/fiche.php b/htdocs/fourn/facture/fiche.php
index 3722ceaac5114c601f16c442f867defe507321d0..6d095e48b93520a3fd54f05f9220242395a3c0de 100644
--- a/htdocs/fourn/facture/fiche.php
+++ b/htdocs/fourn/facture/fiche.php
@@ -1996,13 +1996,13 @@ else
                 print '<td align="right" class="nowrap">'.price($object->lines[$i]->total_ht).'</td>';
 
                 print '<td align="right" class="nowrap">'.price($object->lines[$i]->total_ttc).'</td>';
-				
+
 				if (is_object($hookmanager))
 				{
 					$parameters=array('line'=>$object->lines[$i],'num'=>$num,'i'=>$i);
 					$reshook=$hookmanager->executeHooks('printObjectLine',$parameters,$object,$action);
 				}
-				
+
                 print '<td align="center" width="16">';
                 if ($object->statut == 0) print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=edit_line&amp;etat=0&amp;lineid='.$object->lines[$i]->rowid.'">'.img_edit().'</a>';
                 else print '&nbsp;';
@@ -2370,7 +2370,7 @@ else
             }
 
             // Show form
-            $formmail->show_form();
+            print $formmail->get_form();
 
             print '<br>';
         }
diff --git a/htdocs/fourn/facture/impayees.php b/htdocs/fourn/facture/impayees.php
index f7d62f8692e03a91cb2b0320cfc54ce38093f1c0..1d81ae01230182b28c2d8c7c216eac039f639b17 100644
--- a/htdocs/fourn/facture/impayees.php
+++ b/htdocs/fourn/facture/impayees.php
@@ -146,10 +146,8 @@ if ($user->rights->fournisseur->facture->lire)
 
 	$sql.= " GROUP BY s.rowid, s.nom, f.rowid, f.ref, f.ref_supplier, f.total_ht, f.total_ttc, f.datef, f.date_lim_reglement, f.paye, f.fk_statut, s.rowid, s.nom";
 	if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", sc.fk_soc, sc.fk_user ";
-	$sql.= " ORDER BY ";
-	$listfield=explode(',',$sortfield);
-	foreach ($listfield as $key => $value) $sql.=$listfield[$key]." ".$sortorder.",";
-	$sql.= " f.ref_supplier DESC";
+	$sql.=$db->order($sortfield,$sortorder);
+	if (! in_array("f.ref_supplier",explode(',',$sortfield))) $sql.= ", f.ref_supplier DESC";
 
 	$resql = $db->query($sql);
 	if ($resql)
diff --git a/htdocs/langs/ca_ES/agenda.lang b/htdocs/langs/ca_ES/agenda.lang
index 238911047e316a9ea66d7db453c94775433d0a54..f0612d4abe2b0b10aeb1d756880f7a3b3adc68a5 100644
--- a/htdocs/langs/ca_ES/agenda.lang
+++ b/htdocs/langs/ca_ES/agenda.lang
@@ -52,6 +52,7 @@ InvoiceSentByEMail=Factura a client %s enviada per e-mail
 SupplierOrderSentByEMail=Comanda a proveïdor %s enviada per e-mail
 SupplierInvoiceSentByEMail=Factura de proveïdor %s enviada per e-mail
 ShippingSentByEMail=Expedició %s enviada per e-mail
+ShippingValidated=Expedició %s validada
 InterventionSentByEMail=Intervenció %s enviada per e-mail
 NewCompanyToDolibarr= Tercer creat
 DateActionPlannedStart= Data d'inici prevista
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index 19192574369cc6f33f819f95f59e388bdbf801e9..794d5f05c4a1c8999094fc80e8a41eaba4eaa2ce 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -345,8 +345,6 @@ SecurityTokenIsUnique=Use a unique securekey parameter for each URL
 EnterRefToBuildUrl=Enter reference for object %s
 GetSecuredUrl=Get calculated URL
 ButtonHideUnauthorized=Hide buttons for unauthorized actions instead of showing disabled buttons
-ProductVatMassChange=Mass VAT change
-ProductVatMassChangeDesc=This page can be used to modify a VAT rate defined on products or services from a value to another. Warning, this change is done on all database.
 OldVATRates=Old VAT rate
 NewVATRates=New VAT rate
 PriceBaseTypeToChange=Modify on prices with base reference value defined on
@@ -381,6 +379,12 @@ KeepEmptyToUseDefault=Keep empty to use default value
 DefaultLink=Default link
 ValueOverwrittenByUserSetup=Warning, this value may be overwritten by user specific setup (each user can set his own clicktodial url)
 ExternalModule=External module - Installed into directory %s
+BarcodeInitForThirdparties=Mass barcode init for thirdparties
+BarcodeInitForProductsOrServices=Mass barcode init for products or services
+CurrentlyNWithoutBarCode=Currently, you have <strong>%s</strong> records on <strong>%s</strong> %s without barcode defined.
+InitEmptyBarCode=Init the %s barcode
+NoBarcodeNumberingTemplateDefined=No numbering barcode template enabled into barcode module setup.
+NoRecordWithoutBarcodeDefined=No record with no barcode value defined.
 
 # Modules
 Module0Name=Users & groups
diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang
index 187f818210ebd972d369b85b4ff04307a1f9cd10..0e37d3290f7f50aee6c6e2859762eb83b6f66b9b 100644
--- a/htdocs/langs/en_US/agenda.lang
+++ b/htdocs/langs/en_US/agenda.lang
@@ -52,6 +52,7 @@ InvoiceSentByEMail=Customer invoice %s sent by EMail
 SupplierOrderSentByEMail=Supplier order %s sent by EMail
 SupplierInvoiceSentByEMail=Supplier invoice %s sent by EMail
 ShippingSentByEMail=Shipping %s sent by EMail
+ShippingValidated= Shipping %s validated
 InterventionSentByEMail=Intervention %s sent by EMail
 NewCompanyToDolibarr= Third party created
 DateActionPlannedStart= Planned start date
diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang
index 5dd292aa10b6c70177f81d1f1fc5708547e224ac..fa0b87cc506c2d1193a0e203f9f572c412fb9e64 100644
--- a/htdocs/langs/en_US/errors.lang
+++ b/htdocs/langs/en_US/errors.lang
@@ -26,8 +26,11 @@ ErrorFromToAccountsMustDiffers=Source and targets bank accounts must be differen
 ErrorBadThirdPartyName=Bad value for third party name
 ErrorProdIdIsMandatory=The %s is mandatory
 ErrorBadCustomerCodeSyntax=Bad syntax for customer code
+ErrorBadBarCodeSyntax=Bad syntax for bar code
 ErrorCustomerCodeRequired=Customer code required
+ErrorBarCodeRequired=Bar code required
 ErrorCustomerCodeAlreadyUsed=Customer code already used
+ErrorBarCodeAlreadyUsed=Bar code already used
 ErrorPrefixRequired=Prefix required
 ErrorUrlNotValid=The website address is incorrect
 ErrorBadSupplierCodeSyntax=Bad syntax for supplier code
diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang
index c16827bbdee510736f380987185411e67184e1d6..88d499ac7e0161068debbfd7cd2722522e3e395e 100644
--- a/htdocs/langs/en_US/mails.lang
+++ b/htdocs/langs/en_US/mails.lang
@@ -79,6 +79,10 @@ MailtoEMail=Hyper link to email
 ActivateCheckRead=Allow to use the "Unsubcribe" link
 ActivateCheckReadKey=Key use to encrypt URL use for "Read Receipt" and "Unsubcribe" feature
 EMailSentToNRecipients=EMail sent to %s recipients.
+EachInvoiceWillBeAttachedToEmail=A document using default invoice document template will be created and attached to each email.
+MailTopicSendRemindUnpaidInvoices=Remind of invoice %s (%s)
+SendRemind=Send remind by EMails
+RemindSent=%S remind(s) sent
 
 # Libelle des modules de liste de destinataires mailing
 MailingModuleDescContactCompanies=Contacts/addresses of all third parties (customer, prospect, supplier, ...)
diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang
index c0fed3de5efee6626b1aa73525f83408a6d8391c..8ad1d0b0adfc996bb346ce8bd4abce08530743ee 100644
--- a/htdocs/langs/en_US/other.lang
+++ b/htdocs/langs/en_US/other.lang
@@ -49,14 +49,15 @@ Miscellaneous=Miscellaneous
 NbOfActiveNotifications=Number of notifications
 PredefinedMailTest=This is a test mail.\nThe two lines are separated by a carriage return.\n\n__SIGNATURE__
 PredefinedMailTestHtml=This is a <b>test</b> mail (the word test must be in bold).<br>The two lines are separated by a carriage return.<br><br>__SIGNATURE__
-PredefinedMailContentSendInvoice=__CONTACTCIVNAME__ \n\n You will find here the invoice __FACREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
-PredefinedMailContentSendInvoiceReminder=__CONTACTCIVNAME__ \n\n We would like to warn you that the invoice  __FACREF__ seems to not being payed. So this is the invoice in attachment again, as a reminder.\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
-PredefinedMailContentSendProposal=__CONTACTCIVNAME__ \n\n You will find here the commercial proposal __PROPREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
-PredefinedMailContentSendOrder=__CONTACTCIVNAME__ \n\n You will find here the order __ORDERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
-PredefinedMailContentSendSupplierOrder=__CONTACTCIVNAME__ \n\n You will find here our order __ORDERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
-PredefinedMailContentSendSupplierInvoice=__CONTACTCIVNAME__ \n\n You will find here the invoice __FACREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
-PredefinedMailContentSendShipping=__CONTACTCIVNAME__ \n\n You will find here the shipping __SHIPPINGREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
-PredefinedMailContentSendFichInter=__CONTACTCIVNAME__ \n\n You will find here the intervention __FICHINTERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
+PredefinedMailContentSendInvoice=__CONTACTCIVNAME__\n\nYou will find here the invoice __FACREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
+PredefinedMailContentSendInvoiceReminder=__CONTACTCIVNAME__\n\nWe would like to warn you that the invoice  __FACREF__ seems to not being payed. So this is the invoice in attachment again, as a reminder.\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
+PredefinedMailContentSendProposal=__CONTACTCIVNAME__\n\nYou will find here the commercial proposal __PROPREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
+PredefinedMailContentSendOrder=__CONTACTCIVNAME__\n\nYou will find here the order __ORDERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
+PredefinedMailContentSendSupplierOrder=__CONTACTCIVNAME__\n\nYou will find here our order __ORDERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
+PredefinedMailContentSendSupplierInvoice=__CONTACTCIVNAME__\n\nYou will find here the invoice __FACREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
+PredefinedMailContentSendShipping=__CONTACTCIVNAME__\n\nYou will find here the shipping __SHIPPINGREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
+PredefinedMailContentSendFichInter=__CONTACTCIVNAME__\n\nYou will find here the intervention __FICHINTERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__
+PredefinedMailContentThirdparty=__CONTACTCIVNAME__\n\n__PERSONALIZED__\n\n__SIGNATURE__
 DemoDesc=Dolibarr is a compact ERP/CRM composed by several functional modules. A demo that includes all modules does not mean anything as this never occurs. So, several demo profiles are available.
 ChooseYourDemoProfil=Choose the demo profile that match your activity...
 DemoFundation=Manage members of a foundation
diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
index 96fdf76379b5abba6397ec9bc60f95280bfbf4f4..fa3144d047504e17b5369cee42772883bbd5c04e 100644
--- a/htdocs/langs/en_US/products.lang
+++ b/htdocs/langs/en_US/products.lang
@@ -13,6 +13,10 @@ NewProduct=New product
 NewService=New service
 ProductCode=Product code
 ServiceCode=Service code
+ProductVatMassChange=Mass VAT change
+ProductVatMassChangeDesc=This page can be used to modify a VAT rate defined on products or services from a value to another. Warning, this change is done on all database.
+MassBarcodeInit=Mass barcode init
+MassBarcodeInitDesc=This page can be used to initialize a barcode on objects that does not have barcode defined. Check before that setup of module barcode is complete.
 ProductAccountancyBuyCode=Accountancy code (buy)
 ProductAccountancySellCode=Accountancy code (sell)
 ProductOrService=Product or Service
@@ -217,4 +221,4 @@ DefinitionOfBarCodeForThirdpartyNotComplete=Definition of type or value of bar c
 BarCodeDataForProduct=Barcode information of product %s :
 BarCodeDataForThirdparty=Barcode information of thirdparty %s :
 BarcodeStickersMask=xxx
- 
+
diff --git a/htdocs/langs/es_ES/agenda.lang b/htdocs/langs/es_ES/agenda.lang
index 7abb1dd277b9bf9456a4e1aa69dff5dd0de7a33b..d832ae6afb5dec0fdb40b7267f6c6fca8af87dfc 100644
--- a/htdocs/langs/es_ES/agenda.lang
+++ b/htdocs/langs/es_ES/agenda.lang
@@ -52,6 +52,7 @@ InvoiceSentByEMail=Factura a cliente %s enviada por e-mail
 SupplierOrderSentByEMail=Pedido a proveedor %s enviada por e-mail
 SupplierInvoiceSentByEMail=Factura de proveedor %s enviada por e-mail
 ShippingSentByEMail=Expedición %s enviada por e-mail
+ShippingValidated= Expedición %s validada
 InterventionSentByEMail=Intervención %s enviada por e-mail
 NewCompanyToDolibarr= Tercero creado
 DateActionPlannedStart= Fecha de inicio prevista
diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang
index 190c08ad2acce87aaa40e359422c0ec1be3ed886..d21617fde47ffd55c0ad937fcd8d7c1ebabc99ea 100644
--- a/htdocs/langs/fr_FR/agenda.lang
+++ b/htdocs/langs/fr_FR/agenda.lang
@@ -52,6 +52,7 @@ InvoiceSentByEMail=Facture client %s envoyée par EMail
 SupplierOrderSentByEMail=Commande fournisseur %s envoyée par EMail
 SupplierInvoiceSentByEMail=Facture fournisseur %s envoyée par Email
 ShippingSentByEMail=Bon d'expédition %s envoyé par Email
+ShippingValidated=Bon d'expédition %s validée
 InterventionSentByEMail=Intervention %s envoyée par Email
 NewCompanyToDolibarr= Tiers créé
 DateActionPlannedStart= Date de début de réalisation prévue
diff --git a/htdocs/langs/fr_FR/other.lang b/htdocs/langs/fr_FR/other.lang
index 9814d4f37044aa54b98744583d3dec62a84007d0..355dadad2ba0305e7723007446213d5cc73c2303 100644
--- a/htdocs/langs/fr_FR/other.lang
+++ b/htdocs/langs/fr_FR/other.lang
@@ -49,14 +49,15 @@ Miscellaneous=Divers
 NbOfActiveNotifications=Nombre de notifications
 PredefinedMailTest=Ceci est un message de test.\nLes 2 lignes sont séparées par un retour à la ligne.\n\n__SIGNATURE__
 PredefinedMailTestHtml=Ceci est un message de <b>test</b> (le mot test doit être en gras).<br>Les 2 lignes sont séparées par un retour à la ligne.<br><br>__SIGNATURE__
-PredefinedMailContentSendInvoice=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint la facture __FACREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
-PredefinedMailContentSendInvoiceReminder=__CONTACTCIVNAME__ \n\nNous voudrions porter à votre connaissance que la facture  __FACREF__ ne semble pas avoir été réglée. La voici donc, pour rappel, en pièce jointe.\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
-PredefinedMailContentSendProposal=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint la proposition commerciale __PROPREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
-PredefinedMailContentSendOrder=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint la commande __ORDERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
-PredefinedMailContentSendSupplierOrder=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint notre commande __ORDERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
-PredefinedMailContentSendSupplierInvoice=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint la facture __FACREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
-PredefinedMailContentSendShipping=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint le bon d'expédition __SHIPPINGREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
-PredefinedMailContentSendFichInter=__CONTACTCIVNAME__ \n\n Veuillez trouver ci-joint la fiche d'intervention __FICHINTERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
+PredefinedMailContentSendInvoice=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint la facture __FACREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
+PredefinedMailContentSendInvoiceReminder=__CONTACTCIVNAME__\n\nNous voudrions porter à votre connaissance que la facture  __FACREF__ ne semble pas avoir été réglée. La voici donc, pour rappel, en pièce jointe.\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
+PredefinedMailContentSendProposal=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint la proposition commerciale __PROPREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
+PredefinedMailContentSendOrder=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint la commande __ORDERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
+PredefinedMailContentSendSupplierOrder=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint notre commande __ORDERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
+PredefinedMailContentSendSupplierInvoice=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint la facture __FACREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
+PredefinedMailContentSendShipping=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint le bon d'expédition __SHIPPINGREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
+PredefinedMailContentSendFichInter=__CONTACTCIVNAME__\n\nVeuillez trouver ci-joint la fiche d'intervention __FICHINTERREF__\n\n__PERSONALIZED__Cordialement\n\n__SIGNATURE__
+PredefinedMailContentThirdparty=__CONTACTCIVNAME__\n\n__PERSONALIZED__\n\n__SIGNATURE__
 DemoDesc=Dolibarr est un logiciel de gestion d'activité (professionnelle ou associative) composé de modules fonctionnels indépendants et optionnels. Une démonstration qui inclut tous ces modules n'a pas de sens car les modules ne sont jamais tous utilisés en même temps. Aussi, plusieurs profils de démonstration type sont disponibles.
 ChooseYourDemoProfil=Veuillez choisir le profil de démonstration qui correspond le mieux à votre activité…
 DemoFundation=Gestion des adhérents d'une association
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index f5070cf3edad1879901be48389aef95d9c8471fe..42209bbcca1877ab33a71fdd061944f645221b4d 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2004-2014 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005-2013 Regis Houssin        <regis.houssin@capnetworks.com>
  * Copyright (C) 2006      Andre Cianfarani     <acianfa@free.fr>
  * Copyright (C) 2007-2011 Jean Heimburger      <jean@tiaris.info>
@@ -202,7 +202,7 @@ class Product extends CommonObject
 	 *
 	 *	@param	User	$user     		User making insert
 	 *  @param	int		$notrigger		Disable triggers
-	 *	@return int			     		Id of product/service if OK or number of error < 0
+	 *	@return int			     		Id of product/service if OK, < 0 if KO
 	 */
 	function create($user,$notrigger=0)
 	{
@@ -300,141 +300,230 @@ class Product extends CommonObject
         // For automatic creation during create action (not used by Dolibarr GUI, can be used by scripts)
         if ($this->barcode == -1)  $this->get_barcode($this,$this->barcode_type_code);
 
-		$sql = "SELECT count(*) as nb";
-		$sql.= " FROM ".MAIN_DB_PREFIX."product";
-		$sql.= " WHERE entity IN (".getEntity('product', 1).")";
-		$sql.= " AND ref = '" .$this->ref."'";
+        // Check more parameters
+        // If error, this->errors[] is filled
+        $result = $this->verify();
 
-		$result = $this->db->query($sql);
-		if ($result)
-		{
-			$obj = $this->db->fetch_object($result);
-			if ($obj->nb == 0)
-			{
-				// Produit non deja existant
-				$sql = "INSERT INTO ".MAIN_DB_PREFIX."product (";
-				$sql.= "datec";
-				$sql.= ", entity";
-				$sql.= ", ref";
-				$sql.= ", ref_ext";
-				$sql.= ", price_min";
-				$sql.= ", price_min_ttc";
-				$sql.= ", label";
-				$sql.= ", fk_user_author";
-				$sql.= ", fk_product_type";
-				$sql.= ", price";
-				$sql.= ", price_ttc";
-				$sql.= ", price_base_type";
-				$sql.= ", tobuy";
-				$sql.= ", tosell";
-				$sql.= ", accountancy_code_buy";
-				$sql.= ", accountancy_code_sell";
-				$sql.= ", canvas";
-				$sql.= ", finished";
-				$sql.= ") VALUES (";
-				$sql.= "'".$this->db->idate($now)."'";
-				$sql.= ", ".$conf->entity;
-				$sql.= ", '".$this->db->escape($this->ref)."'";
-				$sql.= ", ".(! empty($this->ref_ext)?"'".$this->db->escape($this->ref_ext)."'":"null");
-				$sql.= ", ".price2num($price_min_ht);
-				$sql.= ", ".price2num($price_min_ttc);
-				$sql.= ", ".(! empty($this->libelle)?"'".$this->db->escape($this->libelle)."'":"null");
-				$sql.= ", ".$user->id;
-				$sql.= ", ".$this->type;
-				$sql.= ", ".price2num($price_ht);
-				$sql.= ", ".price2num($price_ttc);
-				$sql.= ", '".$this->price_base_type."'";
-				$sql.= ", ".$this->status;
-				$sql.= ", ".$this->status_buy;
-				$sql.= ", '".$this->accountancy_code_buy."'";
-				$sql.= ", '".$this->accountancy_code_sell."'";
-				$sql.= ", '".$this->canvas."'";
-				$sql.= ", ".((! isset($this->finished) || $this->finished < 0 || $this->finished == '') ? 'null' : $this->finished);
-				$sql.= ")";
+        if ($result >= 0)
+        {
+			$sql = "SELECT count(*) as nb";
+			$sql.= " FROM ".MAIN_DB_PREFIX."product";
+			$sql.= " WHERE entity IN (".getEntity('product', 1).")";
+			$sql.= " AND ref = '" .$this->ref."'";
 
-				dol_syslog(get_class($this)."::Create sql=".$sql);
-				$result = $this->db->query($sql);
-				if ( $result )
+			$result = $this->db->query($sql);
+			if ($result)
+			{
+				$obj = $this->db->fetch_object($result);
+				if ($obj->nb == 0)
 				{
-					$id = $this->db->last_insert_id(MAIN_DB_PREFIX."product");
-
-					if ($id > 0)
+					// Produit non deja existant
+					$sql = "INSERT INTO ".MAIN_DB_PREFIX."product (";
+					$sql.= "datec";
+					$sql.= ", entity";
+					$sql.= ", ref";
+					$sql.= ", ref_ext";
+					$sql.= ", price_min";
+					$sql.= ", price_min_ttc";
+					$sql.= ", label";
+					$sql.= ", fk_user_author";
+					$sql.= ", fk_product_type";
+					$sql.= ", price";
+					$sql.= ", price_ttc";
+					$sql.= ", price_base_type";
+					$sql.= ", tobuy";
+					$sql.= ", tosell";
+					$sql.= ", accountancy_code_buy";
+					$sql.= ", accountancy_code_sell";
+					$sql.= ", canvas";
+					$sql.= ", finished";
+					$sql.= ") VALUES (";
+					$sql.= "'".$this->db->idate($now)."'";
+					$sql.= ", ".$conf->entity;
+					$sql.= ", '".$this->db->escape($this->ref)."'";
+					$sql.= ", ".(! empty($this->ref_ext)?"'".$this->db->escape($this->ref_ext)."'":"null");
+					$sql.= ", ".price2num($price_min_ht);
+					$sql.= ", ".price2num($price_min_ttc);
+					$sql.= ", ".(! empty($this->libelle)?"'".$this->db->escape($this->libelle)."'":"null");
+					$sql.= ", ".$user->id;
+					$sql.= ", ".$this->type;
+					$sql.= ", ".price2num($price_ht);
+					$sql.= ", ".price2num($price_ttc);
+					$sql.= ", '".$this->price_base_type."'";
+					$sql.= ", ".$this->status;
+					$sql.= ", ".$this->status_buy;
+					$sql.= ", '".$this->accountancy_code_buy."'";
+					$sql.= ", '".$this->accountancy_code_sell."'";
+					$sql.= ", '".$this->canvas."'";
+					$sql.= ", ".((! isset($this->finished) || $this->finished < 0 || $this->finished == '') ? 'null' : $this->finished);
+					$sql.= ")";
+
+					dol_syslog(get_class($this)."::Create sql=".$sql);
+					$result = $this->db->query($sql);
+					if ( $result )
 					{
-						$this->id				= $id;
-						$this->price			= $price_ht;
-						$this->price_ttc		= $price_ttc;
-						$this->price_min		= $price_min_ht;
-						$this->price_min_ttc	= $price_min_ttc;
-
-						$result = $this->_log_price($user);
-						if ($result > 0)
+						$id = $this->db->last_insert_id(MAIN_DB_PREFIX."product");
+
+						if ($id > 0)
 						{
-							if ($this->update($id, $user, true, 'add') <= 0)
+							$this->id				= $id;
+							$this->price			= $price_ht;
+							$this->price_ttc		= $price_ttc;
+							$this->price_min		= $price_min_ht;
+							$this->price_min_ttc	= $price_min_ttc;
+
+							$result = $this->_log_price($user);
+							if ($result > 0)
+							{
+								if ($this->update($id, $user, true, 'add') <= 0)
+								{
+								    $error++;
+								}
+							}
+							else
 							{
-							    $error++;
+								$error++;
+							    $this->error=$this->db->lasterror();
 							}
 						}
 						else
 						{
 							$error++;
-						    $this->error=$this->db->lasterror();
+						    $this->error='ErrorFailedToGetInsertedId';
 						}
 					}
 					else
 					{
 						$error++;
-					    $this->error='ErrorFailedToGetInsertedId';
+					    $this->error=$this->db->lasterror();
 					}
 				}
 				else
 				{
+					// Product already exists with this ref
+					$langs->load("products");
 					$error++;
-				    $this->error=$this->db->lasterror();
+					$this->error = "ErrorProductAlreadyExists";
 				}
 			}
 			else
 			{
-				// Product already exists with this ref
-				$langs->load("products");
 				$error++;
-				$this->error = "ErrorProductAlreadyExists";
+			    $this->error=$this->db->lasterror();
 			}
-		}
-		else
-		{
-			$error++;
-		    $this->error=$this->db->lasterror();
-		}
 
-		if (! $error && ! $notrigger)
-		{
-			// Appel des triggers
-			include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-			$interface=new Interfaces($this->db);
-			$result=$interface->run_triggers('PRODUCT_CREATE',$this,$user,$langs,$conf);
-			if ($result < 0) { $error++; $this->errors=$interface->errors; }
-			// Fin appel triggers
-		}
+			if (! $error && ! $notrigger)
+			{
+				// Appel des triggers
+				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+				$interface=new Interfaces($this->db);
+				$result=$interface->run_triggers('PRODUCT_CREATE',$this,$user,$langs,$conf);
+				if ($result < 0) { $error++; $this->errors=$interface->errors; }
+				// Fin appel triggers
+			}
+
+			if (! $error)
+			{
+				$this->db->commit();
+				return $this->id;
+			}
+			else
+			{
+				$this->db->rollback();
+				return -$error;
+			}
+        }
+        else
+       {
+            $this->db->rollback();
+            dol_syslog(get_class($this)."::Create fails verify ".join(',',$this->errors), LOG_WARNING);
+            return -3;
+        }
 
-		if (! $error)
-		{
-			$this->db->commit();
-			return $this->id;
-		}
-		else
-		{
-			$this->db->rollback();
-			return -$error;
-		}
 	}
 
+
+    /**
+     *    Check properties of product are ok (like name, barcode, ...)
+     *
+     *    @return     int		0 if OK, <0 if KO
+     */
+    function verify()
+    {
+        $this->errors=array();
+
+        $result = 0;
+        $this->ref = trim($this->ref);
+
+        if (! $this->ref)
+        {
+            $this->errors[] = 'ErrorBadRef';
+            $result = -2;
+        }
+
+        $rescode = $this->check_barcode($this->barcode);
+        if ($rescode <> 0)
+        {
+        	if ($rescode == -1)
+        	{
+        		$this->errors[] = 'ErrorBadBarCodeSyntax';
+        	}
+        	if ($rescode == -2)
+        	{
+        		$this->errors[] = 'ErrorBarCodeRequired';
+        	}
+        	if ($rescode == -3)
+        	{
+        		$this->errors[] = 'ErrorBarCodeAlreadyUsed';
+        	}
+        	$result = -3;
+        }
+
+        return $result;
+    }
+
+    /**
+     *  Check customer code
+     *
+     *	@param	string	$valuetotest	Value to test
+     *  @return int						0 if OK
+     * 									-1 ErrorBadBarCodeSyntax
+     * 									-2 ErrorBarCodeRequired
+     * 									-3 ErrorBarCodeAlreadyUsed
+     */
+    function check_barcode($valuetotest)
+    {
+        global $conf;
+        if (! empty($conf->barcode->enabled) && ! empty($conf->global->BARCODE_PRODUCT_ADDON_NUM))
+        {
+        	$module=strtolower($conf->global->BARCODE_PRODUCT_ADDON_NUM);
+
+            $dirsociete=array_merge(array('/core/modules/barcode/'),$conf->modules_parts['barcode']);
+            foreach ($dirsociete as $dirroot)
+            {
+                $res=dol_include_once($dirroot.$module.'.php');
+                if ($res) break;
+            }
+
+            $mod = new $module();
+
+            dol_syslog(get_class($this)."::check_barcode barcode=".$valuetotest." module=".$module);
+            $result = $mod->verif($this->db, $valuetotest, $this, 0);
+            return $result;
+        }
+        else
+		{
+            return 0;
+        }
+    }
+
 	/**
 	 *	Update a record into database
 	 *
 	 *	@param	int		$id         Id of product
 	 *	@param  User	$user       Object user making update
 	 *	@param	int		$notrigger	Disable triggers
-	 *	@param	string	$action		Current action for hookmanager
+	 *	@param	string	$action		Current action for hookmanager ('add' or 'update')
 	 *	@return int         		1 if OK, -1 if ref already exists, -2 if other error
 	 */
 	function update($id, $user, $notrigger=false, $action='update')
@@ -443,9 +532,7 @@ class Product extends CommonObject
 
 		$error=0;
 
-		$this->db->begin();
-
-		// Verification parametres
+		// Check parameters
 		if (! $this->libelle) $this->libelle = 'MISSING LABEL';
 
 		// Clean parameters
@@ -473,135 +560,154 @@ class Product extends CommonObject
         //Gencod
         $this->barcode=trim($this->barcode);
 
-        // For automatic creation
-        if ($this->barcode == -1) $this->get_barcode($this,$this->barcode_type_code);
-
 		$this->accountancy_code_buy = trim($this->accountancy_code_buy);
 		$this->accountancy_code_sell= trim($this->accountancy_code_sell);
 
-		$sql = "UPDATE ".MAIN_DB_PREFIX."product";
-		$sql.= " SET label = '" . $this->db->escape($this->libelle) ."'";
-		$sql.= ", ref = '" . $this->ref ."'";
-		$sql.= ", ref_ext = ".(! empty($this->ref_ext)?"'".$this->db->escape($this->ref_ext)."'":"null");
-		$sql.= ", tva_tx = " . $this->tva_tx;
-		$sql.= ", recuperableonly = " . $this->tva_npr;
-		$sql.= ", localtax1_tx = " . $this->localtax1_tx;
-		$sql.= ", localtax2_tx = " . $this->localtax2_tx;
-
-		$sql.= ", barcode = ". (empty($this->barcode)?"null":"'".$this->db->escape($this->barcode)."'");
-		$sql.= ", fk_barcode_type = ". (empty($this->barcode_type)?"null":$this->db->escape($this->barcode_type));
-
-		$sql.= ", tosell = " . $this->status;
-		$sql.= ", tobuy = " . $this->status_buy;
-		$sql.= ", finished = " . ((! isset($this->finished) || $this->finished < 0) ? "null" : $this->finished);
-		$sql.= ", weight = " . ($this->weight!='' ? "'".$this->weight."'" : 'null');
-		$sql.= ", weight_units = " . ($this->weight_units!='' ? "'".$this->weight_units."'": 'null');
-		$sql.= ", length = " . ($this->length!='' ? "'".$this->length."'" : 'null');
-		$sql.= ", length_units = " . ($this->length_units!='' ? "'".$this->length_units."'" : 'null');
-		$sql.= ", surface = " . ($this->surface!='' ? "'".$this->surface."'" : 'null');
-		$sql.= ", surface_units = " . ($this->surface_units!='' ? "'".$this->surface_units."'" : 'null');
-		$sql.= ", volume = " . ($this->volume!='' ? "'".$this->volume."'" : 'null');
-		$sql.= ", volume_units = " . ($this->volume_units!='' ? "'".$this->volume_units."'" : 'null');
-		$sql.= ", seuil_stock_alerte = " . ((isset($this->seuil_stock_alerte) && $this->seuil_stock_alerte != '') ? "'".$this->seuil_stock_alerte."'" : "null");
-		$sql.= ", description = '" . $this->db->escape($this->description) ."'";
-        $sql.= ", customcode = '" .        $this->db->escape($this->customcode) ."'";
-        $sql.= ", fk_country = " . ($this->country_id > 0 ? $this->country_id : 'null');
-        $sql.= ", note = '" .        $this->db->escape($this->note) ."'";
-		$sql.= ", duration = '" . $this->duration_value . $this->duration_unit ."'";
-		$sql.= ", accountancy_code_buy = '" . $this->accountancy_code_buy."'";
-		$sql.= ", accountancy_code_sell= '" . $this->accountancy_code_sell."'";
-		$sql.= ", desiredstock = " . ((isset($this->desiredstock) && $this->desiredstock != '') ? $this->desiredstock : "null");
-		$sql.= " WHERE rowid = " . $id;
-
-		dol_syslog(get_class($this)."update sql=".$sql);
-		$resql=$this->db->query($sql);
-		if ($resql)
-		{
-			$this->id = $id;
 
-			// Multilangs
-			if (! empty($conf->global->MAIN_MULTILANGS))
+        $this->db->begin();
+
+        // Check name is required and codes are ok or unique.
+        // If error, this->errors[] is filled
+        if ($action != 'add')
+        {
+        	$result = $this->verify();	// We don't check when update called during a create because verify was already done
+        }
+
+        if ($result >= 0)
+        {
+	        // For automatic creation
+	        if ($this->barcode == -1) $this->get_barcode($this,$this->barcode_type_code);
+
+			$sql = "UPDATE ".MAIN_DB_PREFIX."product";
+			$sql.= " SET label = '" . $this->db->escape($this->libelle) ."'";
+			$sql.= ", ref = '" . $this->ref ."'";
+			$sql.= ", ref_ext = ".(! empty($this->ref_ext)?"'".$this->db->escape($this->ref_ext)."'":"null");
+			$sql.= ", tva_tx = " . $this->tva_tx;
+			$sql.= ", recuperableonly = " . $this->tva_npr;
+			$sql.= ", localtax1_tx = " . $this->localtax1_tx;
+			$sql.= ", localtax2_tx = " . $this->localtax2_tx;
+
+			$sql.= ", barcode = ". (empty($this->barcode)?"null":"'".$this->db->escape($this->barcode)."'");
+			$sql.= ", fk_barcode_type = ". (empty($this->barcode_type)?"null":$this->db->escape($this->barcode_type));
+
+			$sql.= ", tosell = " . $this->status;
+			$sql.= ", tobuy = " . $this->status_buy;
+			$sql.= ", finished = " . ((! isset($this->finished) || $this->finished < 0) ? "null" : $this->finished);
+			$sql.= ", weight = " . ($this->weight!='' ? "'".$this->weight."'" : 'null');
+			$sql.= ", weight_units = " . ($this->weight_units!='' ? "'".$this->weight_units."'": 'null');
+			$sql.= ", length = " . ($this->length!='' ? "'".$this->length."'" : 'null');
+			$sql.= ", length_units = " . ($this->length_units!='' ? "'".$this->length_units."'" : 'null');
+			$sql.= ", surface = " . ($this->surface!='' ? "'".$this->surface."'" : 'null');
+			$sql.= ", surface_units = " . ($this->surface_units!='' ? "'".$this->surface_units."'" : 'null');
+			$sql.= ", volume = " . ($this->volume!='' ? "'".$this->volume."'" : 'null');
+			$sql.= ", volume_units = " . ($this->volume_units!='' ? "'".$this->volume_units."'" : 'null');
+			$sql.= ", seuil_stock_alerte = " . ((isset($this->seuil_stock_alerte) && $this->seuil_stock_alerte != '') ? "'".$this->seuil_stock_alerte."'" : "null");
+			$sql.= ", description = '" . $this->db->escape($this->description) ."'";
+	        $sql.= ", customcode = '" .        $this->db->escape($this->customcode) ."'";
+	        $sql.= ", fk_country = " . ($this->country_id > 0 ? $this->country_id : 'null');
+	        $sql.= ", note = '" .        $this->db->escape($this->note) ."'";
+			$sql.= ", duration = '" . $this->duration_value . $this->duration_unit ."'";
+			$sql.= ", accountancy_code_buy = '" . $this->accountancy_code_buy."'";
+			$sql.= ", accountancy_code_sell= '" . $this->accountancy_code_sell."'";
+			$sql.= ", desiredstock = " . ((isset($this->desiredstock) && $this->desiredstock != '') ? $this->desiredstock : "null");
+			$sql.= " WHERE rowid = " . $id;
+
+			dol_syslog(get_class($this)."update sql=".$sql);
+			$resql=$this->db->query($sql);
+			if ($resql)
 			{
-				if ( $this->setMultiLangs() < 0)
+				$this->id = $id;
+
+				// Multilangs
+				if (! empty($conf->global->MAIN_MULTILANGS))
 				{
-					$this->error=$langs->trans("Error")." : ".$this->db->error()." - ".$sql;
-					return -2;
+					if ( $this->setMultiLangs() < 0)
+					{
+						$this->error=$langs->trans("Error")." : ".$this->db->error()." - ".$sql;
+						return -2;
+					}
 				}
-			}
 
-			// Actions on extra fields (by external module or standard code)
-			$hookmanager->initHooks(array('productdao'));
-			$parameters=array('id'=>$this->id);
-			$reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
-			if (empty($reshook))
-			{
-				if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
+				// Actions on extra fields (by external module or standard code)
+				$hookmanager->initHooks(array('productdao'));
+				$parameters=array('id'=>$this->id);
+				$reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
+				if (empty($reshook))
 				{
-					$result=$this->insertExtraFields();
-					if ($result < 0)
+					if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
 					{
-						$error++;
+						$result=$this->insertExtraFields();
+						if ($result < 0)
+						{
+							$error++;
+						}
 					}
 				}
-			}
-			else if ($reshook < 0) $error++;
+				else if ($reshook < 0) $error++;
 
-			if (! $error && ! $notrigger)
-			{
-				// Appel des triggers
-				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-				$interface=new Interfaces($this->db);
-				$result=$interface->run_triggers('PRODUCT_MODIFY',$this,$user,$langs,$conf);
-				if ($result < 0) { $error++; $this->errors=$interface->errors; }
-				// Fin appel triggers
-			}
+				if (! $error && ! $notrigger)
+				{
+					// Appel des triggers
+					include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+					$interface=new Interfaces($this->db);
+					$result=$interface->run_triggers('PRODUCT_MODIFY',$this,$user,$langs,$conf);
+					if ($result < 0) { $error++; $this->errors=$interface->errors; }
+					// Fin appel triggers
+				}
 
-			if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref != $this->ref))
-			{
-				// We remove directory
-				if ($conf->product->dir_output)
+				if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref != $this->ref))
 				{
-					$olddir = $conf->product->dir_output . "/" . dol_sanitizeFileName($this->oldcopy->ref);
-					$newdir = $conf->product->dir_output . "/" . dol_sanitizeFileName($this->ref);
-					if (file_exists($olddir))
+					// We remove directory
+					if ($conf->product->dir_output)
 					{
-						include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
-						$res=@dol_move($olddir, $newdir);
-						if (! $res)
+						$olddir = $conf->product->dir_output . "/" . dol_sanitizeFileName($this->oldcopy->ref);
+						$newdir = $conf->product->dir_output . "/" . dol_sanitizeFileName($this->ref);
+						if (file_exists($olddir))
 						{
-							$this->error='ErrorFailToMoveDir';
-							$error++;
+							include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
+							$res=@dol_move($olddir, $newdir);
+							if (! $res)
+							{
+								$this->error='ErrorFailToMoveDir';
+								$error++;
+							}
 						}
 					}
 				}
-			}
 
-			if (! $error)
-			{
-				$this->db->commit();
-				return 1;
-			}
-			else
-			{
-				$this->db->rollback();
-				return -$error;
-			}
-		}
-		else
-		{
-			if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
-			{
-				$this->error=$langs->trans("Error")." : ".$langs->trans("ErrorProductAlreadyExists",$this->ref);
-				$this->db->rollback();
-				return -1;
+				if (! $error)
+				{
+					$this->db->commit();
+					return 1;
+				}
+				else
+				{
+					$this->db->rollback();
+					return -$error;
+				}
 			}
 			else
 			{
-				$this->error=$langs->trans("Error")." : ".$this->db->error()." - ".$sql;
-				$this->db->rollback();
-				return -2;
+				if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
+				{
+					$this->error=$langs->trans("Error")." : ".$langs->trans("ErrorProductAlreadyExists",$this->ref);
+					$this->db->rollback();
+					return -1;
+				}
+				else
+				{
+					$this->error=$langs->trans("Error")." : ".$this->db->error()." - ".$sql;
+					$this->db->rollback();
+					return -2;
+				}
 			}
-		}
+        }
+        else
+       {
+            $this->db->rollback();
+            dol_syslog(get_class($this)."::Update fails verify ".join(',',$this->errors), LOG_WARNING);
+            return -3;
+        }
 	}
 
 	/**
@@ -3156,6 +3262,8 @@ class Product extends CommonObject
         $this->tobuy=1;
         $this->type=0;
         $this->note='This is a comment (private)';
+
+        $this->barcode=-1;	// Create barcode automatically
     }
 }
 ?>
diff --git a/htdocs/product/fiche.php b/htdocs/product/fiche.php
index ca47227e1f078e31edcd1dcf62c306f50bc9e90c..6a86dbe3217768d778ff0523cd16f101f76ef823 100644
--- a/htdocs/product/fiche.php
+++ b/htdocs/product/fiche.php
@@ -117,10 +117,25 @@ if (empty($reshook))
     // Barcode value
     if ($action ==	'setbarcode' && $user->rights->barcode->creer)
     {
-    	//Todo: ajout verification de la validite du code barre en fonction du type
-    	$result = $object->setValueFrom('barcode', GETPOST('barcode'));
-    	header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
-    	exit;
+    	$result=$object->check_barcode(GETPOST('barcode'));
+
+		if ($result >= 0)
+		{
+	    	$result = $object->setValueFrom('barcode', GETPOST('barcode'));
+	    	header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
+	    	exit;
+		}
+		else
+		{
+			$langs->load("errors");
+        	if ($result == -1) $errors[] = 'ErrorBadBarCodeSyntax';
+        	else if ($result == -2) $errors[] = 'ErrorBarCodeRequired';
+        	else if ($result == -3) $errors[] = 'ErrorBarCodeAlreadyUsed';
+        	else $errors[] = 'FailedToValidateBarCode';
+
+			$error++;
+			setEventMessage($errors,'errors');
+		}
     }
 
     if ($action == 'setaccountancy_code_buy')
@@ -236,8 +251,9 @@ if (empty($reshook))
                 exit;
             }
             else
-            {
-            	setEventMessage($langs->trans($object->error), 'errors');
+			{
+            	if (count($object->errors)) setEventMessage($object->errors, 'errors');
+				else setEventMessage($langs->trans($object->error), 'errors');
                 $action = "create";
             }
         }
@@ -279,7 +295,11 @@ if (empty($reshook))
                 $object->volume_units           = GETPOST('volume_units');
                 $object->finished               = GETPOST('finished');
                 $object->hidden                 = GETPOST('hidden')=='yes'?1:0;
-                $object->accountancy_code_sell  = GETPOST('accountancy_code_sell');
+
+	            $object->barcode_type           = GETPOST('fk_barcode_type');
+    	        $object->barcode		        = GETPOST('barcode');
+
+            	$object->accountancy_code_sell  = GETPOST('accountancy_code_sell');
                 $object->accountancy_code_buy   = GETPOST('accountancy_code_buy');
 
                 // Fill array 'array_options' with data from add form
@@ -292,14 +312,16 @@ if (empty($reshook))
                         $action = 'view';
                     }
                     else
-                    {
-                    	setEventMessage($langs->trans($object->error), 'errors');
+					{
+						if (count($object->errors)) setEventMessage($object->errors, 'errors');
+                    	else setEventMessage($langs->trans($object->error), 'errors');
                         $action = 'edit';
                     }
                 }
                 else
-                {
-                	setEventMessage($langs->trans("ErrorProductBadRefOrLabel"), 'errors');
+				{
+					if (count($object->errors)) setEventMessage($object->errors, 'errors');
+                	else setEventMessage($langs->trans("ErrorProductBadRefOrLabel"), 'errors');
                     $action = 'edit';
                 }
             }
@@ -762,8 +784,8 @@ else
 	        print $formbarcode->select_barcode_type($fk_barcode_type, 'fk_barcode_type', 1);
 	        print '</td><td>'.$langs->trans("BarcodeValue").'</td><td>';
 	        $tmpcode=isset($_POST['barcode'])?GETPOST('barcode'):$object->barcode;
-	        if (! empty($modBarCodeProduct->code_auto)) $tmpcode=$modBarCodeProduct->getNextValue($object,$type);
-	        print '<input size="40" type="text" name="barcode" value="'.$tmpcode.'">';
+	        if (empty($tmpcode) && ! empty($modBarCodeProduct->code_auto)) $tmpcode=$modBarCodeProduct->getNextValue($object,$type);
+	        print '<input size="40" type="text" name="barcode" value="'.dol_escape_htmltag($tmpcode).'">';
 	        print '</td></tr>';
         }
 
@@ -871,7 +893,7 @@ else
             // We must set them on prices tab.
         }
         else
-        {
+		{
             print '<table class="border" width="100%">';
 
             // PRIX
@@ -955,7 +977,7 @@ else
             // Label
             print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td colspan="3"><input name="libelle" size="40" maxlength="255" value="'.$object->libelle.'"></td></tr>';
 
-            // Status
+            // Status To sell
             print '<tr><td class="fieldrequired">'.$langs->trans("Status").' ('.$langs->trans("Sell").')</td><td colspan="3">';
             print '<select class="flat" name="statut">';
             if ($object->status)
@@ -971,7 +993,7 @@ else
             print '</select>';
             print '</td></tr>';
 
-            // To Buy
+            // Status To Buy
             print '<tr><td class="fieldrequired">'.$langs->trans("Status").' ('.$langs->trans("Buy").')</td><td colspan="3">';
             print '<select class="flat" name="statut_buy">';
             if ($object->status_buy)
@@ -987,6 +1009,30 @@ else
             print '</select>';
             print '</td></tr>';
 
+            // Barcode
+            $showbarcode=(! empty($conf->barcode->enabled) && $user->rights->barcode->lire);
+
+	        if ($showbarcode)
+	        {
+		        print '<tr><td>'.$langs->trans('BarcodeType').'</td><td>';
+		        if (isset($_POST['fk_barcode_type']))
+		        {
+		         	$fk_barcode_type=GETPOST('fk_barcode_type');
+		        }
+		        else
+		        {
+		        	if (empty($fk_barcode_type) && ! empty($conf->global->PRODUIT_DEFAULT_BARCODE_TYPE)) $fk_barcode_type = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE;
+		        }
+		        require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbarcode.class.php';
+	            $formbarcode = new FormBarCode($db);
+		        print $formbarcode->select_barcode_type($fk_barcode_type, 'fk_barcode_type', 1);
+		        print '</td><td>'.$langs->trans("BarcodeValue").'</td><td>';
+		        $tmpcode=isset($_POST['barcode'])?GETPOST('barcode'):$object->barcode;
+		        if (empty($tmpcode) && ! empty($modBarCodeProduct->code_auto)) $tmpcode=$modBarCodeProduct->getNextValue($object,$type);
+		        print '<input size="40" type="text" name="barcode" value="'.dol_escape_htmltag($tmpcode).'">';
+		        print '</td></tr>';
+	        }
+
             // Description (used in invoice, propal...)
             print '<tr><td valign="top">'.$langs->trans("Description").'</td><td colspan="3">';
 
@@ -1100,7 +1146,7 @@ else
                 print '<table class="border" width="100%">';
 
                 // Accountancy_code_sell
-                print '<tr><td>'.$langs->trans("ProductAccountancySellCode").'</td>';
+                print '<tr><td width="20%">'.$langs->trans("ProductAccountancySellCode").'</td>';
                 print '<td><input name="accountancy_code_sell" size="16" value="'.$object->accountancy_code_sell.'">';
                 print '</td></tr>';
 
@@ -1121,7 +1167,7 @@ else
         }
         // Fiche en mode visu
         else
-        {
+		{
             $head=product_prepare_head($object, $user);
             $titre=$langs->trans("CardProduct".$object->type);
             $picto=($object->type==1?'service':'product');
diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
index 93befedfc769a8254ac22e0967212db6a8ed92f2..225a2dab5c8f5bf5852325fd0b31f44739198a1d 100644
--- a/htdocs/societe/class/societe.class.php
+++ b/htdocs/societe/class/societe.class.php
@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2002-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2010 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2004-2014 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2004      Eric Seigne          <eric.seigne@ryxeo.com>
  * Copyright (C) 2003      Brian Fraval         <brian@fraval.org>
  * Copyright (C) 2006      Andre Cianfarani     <acianfa@free.fr>
@@ -208,8 +208,8 @@ class Societe extends CommonObject
         $this->db->begin();
 
         // For automatic creation during create action (not used by Dolibarr GUI, can be used by scripts)
-        if ($this->code_client == -1)      $this->get_codeclient($this->prefix_comm,0);
-        if ($this->code_fournisseur == -1) $this->get_codefournisseur($this->prefix_comm,1);
+        if ($this->code_client == -1)      $this->get_codeclient($this,0);
+        if ($this->code_fournisseur == -1) $this->get_codefournisseur($this,1);
 
         // Check more parameters
         // If error, this->errors[] is filled
@@ -290,14 +290,21 @@ class Societe extends CommonObject
 
         }
         else
-        {
+       {
             $this->db->rollback();
             dol_syslog(get_class($this)."::Create fails verify ".join(',',$this->errors), LOG_WARNING);
             return -3;
         }
     }
 
-    function create_individual($user) {
+    /**
+     * Create a contact/address from thirdparty
+     *
+     * @param 	User	$user		Object user
+     * @return 	int					<0 if KO, >0 if OK
+     */
+    function create_individual($user)
+    {
         require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
         $contact=new Contact($this->db);
 
@@ -313,11 +320,13 @@ class Societe extends CommonObject
         $contact->zip               = $this->zip;
         $contact->town              = $this->town;
         $contact->phone_pro         = $this->phone;
+
         $result = $contact->create($user);
-        if ($result < 0) {
+        if ($result < 0)
+        {
             $this->error = $contact->error;
             $this->errors = $contact->errors;
-            dol_syslog("Societe::create_individual ERROR:" . $this->error, LOG_ERR);
+            dol_syslog(get_class($this)."::create_individual ERROR:" . $this->error, LOG_ERR);
         }
 
         return $result;
@@ -325,6 +334,7 @@ class Societe extends CommonObject
 
     /**
      *    Check properties of third party are ok (like name, third party codes, ...)
+     *    Used before an add or update.
      *
      *    @return     int		0 if OK, <0 if KO
      */
@@ -342,10 +352,8 @@ class Societe extends CommonObject
             $result = -2;
         }
 
-        if ($this->client && $this->codeclient_modifiable())
+        if ($this->client)
         {
-            // On ne verifie le code client que si la societe est un client / prospect et que le code est modifiable
-            // Si il n'est pas modifiable il n'est pas mis a jour lors de l'update
             $rescode = $this->check_codeclient();
             if ($rescode <> 0)
             {
@@ -369,10 +377,8 @@ class Societe extends CommonObject
             }
         }
 
-        if ($this->fournisseur && $this->codefournisseur_modifiable())
+        if ($this->fournisseur)
         {
-            // On ne verifie le code fournisseur que si la societe est un fournisseur et que le code est modifiable
-            // Si il n'est pas modifiable il n'est pas mis a jour lors de l'update
             $rescode = $this->check_codefournisseur();
             if ($rescode <> 0)
             {
@@ -407,7 +413,7 @@ class Societe extends CommonObject
      *      @param  int		$call_trigger    			0=non, 1=oui
      *		@param	int		$allowmodcodeclient			Inclut modif code client et code compta
      *		@param	int		$allowmodcodefournisseur	Inclut modif code fournisseur et code compta fournisseur
-     *		@param	string	$action						'create' or 'update'
+     *		@param	string	$action						'add' or 'update'
      *		@param	int		$nosyncmember				Do not synchronize info of linked member
      *      @return int  			           			<0 if KO, >=0 if OK
      */
@@ -467,8 +473,8 @@ class Societe extends CommonObject
         $this->barcode=trim($this->barcode);
 
         // For automatic creation
-        if ($this->code_client == -1) $this->get_codeclient($this->prefix_comm,0);
-        if ($this->code_fournisseur == -1) $this->get_codefournisseur($this->prefix_comm,1);
+        if ($this->code_client == -1) $this->get_codeclient($this,0);
+        if ($this->code_fournisseur == -1) $this->get_codefournisseur($this,1);
 
         $this->code_compta=trim($this->code_compta);
         $this->code_compta_fournisseur=trim($this->code_compta_fournisseur);
@@ -517,7 +523,7 @@ class Societe extends CommonObject
 
         // Check name is required and codes are ok or unique.
         // If error, this->errors[] is filled
-        $result = $this->verify();
+        if ($action != 'add') $result = $this->verify();	// We don't check when update called during a create because verify was already done
 
         if ($result >= 0)
         {
@@ -574,16 +580,12 @@ class Societe extends CommonObject
 
             if ($customer)
             {
-                //$this->check_codeclient();
-
                 $sql .= ", code_client = ".(! empty($this->code_client)?"'".$this->db->escape($this->code_client)."'":"null");
                 $sql .= ", code_compta = ".(! empty($this->code_compta)?"'".$this->db->escape($this->code_compta)."'":"null");
             }
 
             if ($supplier)
             {
-                //$this->check_codefournisseur();
-
                 $sql .= ", code_fournisseur = ".(! empty($this->code_fournisseur)?"'".$this->db->escape($this->code_fournisseur)."'":"null");
                 $sql .= ", code_compta_fournisseur = ".(! empty($this->code_compta_fournisseur)?"'".$this->db->escape($this->code_compta_fournisseur)."'":"null");
             }
@@ -621,7 +623,7 @@ class Societe extends CommonObject
 		            		//$lmember->lastname=$this->lastname?$this->lastname:$lmember->lastname;		// We keep firstname and lastname of member unchanged
 		            		$lmember->address=$this->address;
 		            		$lmember->email=$this->email;
-                    $lmember->skype=$this->skype;
+                    		$lmember->skype=$this->skype;
 		            		$lmember->phone=$this->phone;
 
 		            		$result=$lmember->update($user,0,1,1,1);	// Use nosync to 1 to avoid cyclic updates
@@ -700,7 +702,7 @@ class Societe extends CommonObject
             }
         }
         else
-        {
+       {
             $this->db->rollback();
             dol_syslog(get_class($this)."::Update fails verify ".join(',',$this->errors), LOG_WARNING);
             return -3;
@@ -1815,19 +1817,20 @@ class Societe extends CommonObject
         global $conf;
         if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
         {
+        	$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
+
             $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
             foreach ($dirsociete as $dirroot)
             {
-                $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php');
+                $res=dol_include_once($dirroot.$module.'.php');
                 if ($res) break;
             }
-            $var = $conf->global->SOCIETE_CODECLIENT_ADDON;
-            $mod = new $var;
+            $mod = new $module();
 
             $this->code_client = $mod->getNextValue($objsoc,$type);
             $this->prefixCustomerIsRequired = $mod->prefixIsRequired;
 
-            dol_syslog(get_class($this)."::get_codeclient code_client=".$this->code_client." module=".$var);
+            dol_syslog(get_class($this)."::get_codeclient code_client=".$this->code_client." module=".$module);
         }
     }
 
@@ -1844,18 +1847,19 @@ class Societe extends CommonObject
         global $conf;
         if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
         {
+			$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
+
             $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
             foreach ($dirsociete as $dirroot)
             {
-                $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php');
+                $res=dol_include_once($dirroot.$module.'.php');
                 if ($res) break;
             }
-            $var = $conf->global->SOCIETE_CODECLIENT_ADDON;
-            $mod = new $var;
+            $mod = new $module();
 
             $this->code_fournisseur = $mod->getNextValue($objsoc,$type);
 
-            dol_syslog(get_class($this)."::get_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$var);
+            dol_syslog(get_class($this)."::get_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$module);
         }
     }
 
@@ -1863,25 +1867,25 @@ class Societe extends CommonObject
      *    Verifie si un code client est modifiable en fonction des parametres
      *    du module de controle des codes.
      *
-     *    @return     int		0=Non, 1=Oui
+     *    @return     int		0=No, 1=Yes
      */
     function codeclient_modifiable()
     {
         global $conf;
         if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
         {
+        	$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
+
             $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
             foreach ($dirsociete as $dirroot)
             {
-                $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php');
+                $res=dol_include_once($dirroot.$module.'.php');
                 if ($res) break;
             }
 
-            $var = $conf->global->SOCIETE_CODECLIENT_ADDON;
+            $mod = new $module();
 
-            $mod = new $var;
-
-            dol_syslog(get_class($this)."::codeclient_modifiable code_client=".$this->code_client." module=".$var);
+            dol_syslog(get_class($this)."::codeclient_modifiable code_client=".$this->code_client." module=".$module);
             if ($mod->code_modifiable_null && ! $this->code_client) return 1;
             if ($mod->code_modifiable_invalide && $this->check_codeclient() < 0) return 1;
             if ($mod->code_modifiable) return 1;	// A mettre en dernier
@@ -1897,25 +1901,25 @@ class Societe extends CommonObject
     /**
      *    Verifie si un code fournisseur est modifiable dans configuration du module de controle des codes
      *
-     *    @return     int		0=Non, 1=Oui
+     *    @return     int		0=No, 1=Yes
      */
     function codefournisseur_modifiable()
     {
         global $conf;
         if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
         {
+        	$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
+
             $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
             foreach ($dirsociete as $dirroot)
             {
-                $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php');
+                $res=dol_include_once($dirroot.$module.'.php');
                 if ($res) break;
             }
 
-            $var = $conf->global->SOCIETE_CODECLIENT_ADDON;
+            $mod = new $module();
 
-            $mod = new $var;
-
-            dol_syslog(get_class($this)."::codefournisseur_modifiable code_founisseur=".$this->code_fournisseur." module=".$var);
+            dol_syslog(get_class($this)."::codefournisseur_modifiable code_founisseur=".$this->code_fournisseur." module=".$module);
             if ($mod->code_modifiable_null && ! $this->code_fournisseur) return 1;
             if ($mod->code_modifiable_invalide && $this->check_codefournisseur() < 0) return 1;
             if ($mod->code_modifiable) return 1;	// A mettre en dernier
@@ -1929,36 +1933,36 @@ class Societe extends CommonObject
 
 
     /**
-     *    Check customer code
+     *  Check customer code
      *
-     *    @return     int		0 if OK
-     * 							-1 ErrorBadCustomerCodeSyntax
-     * 							-2 ErrorCustomerCodeRequired
-     * 							-3 ErrorCustomerCodeAlreadyUsed
-     * 							-4 ErrorPrefixRequired
+     *  @return     int				0 if OK
+     * 								-1 ErrorBadCustomerCodeSyntax
+     * 								-2 ErrorCustomerCodeRequired
+     * 								-3 ErrorCustomerCodeAlreadyUsed
+     * 								-4 ErrorPrefixRequired
      */
     function check_codeclient()
     {
         global $conf;
         if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
         {
-            $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
+        	$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
+
+        	$dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
             foreach ($dirsociete as $dirroot)
             {
-                $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php');
+                $res=dol_include_once($dirroot.$module.'.php');
                 if ($res) break;
             }
 
-            $var = $conf->global->SOCIETE_CODECLIENT_ADDON;
+            $mod = new $module();
 
-            $mod = new $var;
-
-            dol_syslog(get_class($this)."::check_codeclient code_client=".$this->code_client." module=".$var);
-            $result = $mod->verif($this->db, $this->code_client, $this, 0);
+           	dol_syslog(get_class($this)."::check_codeclient code_client=".$this->code_client." module=".$module);
+           	$result = $mod->verif($this->db, $this->code_client, $this, 0);
             return $result;
         }
         else
-        {
+		{
             return 0;
         }
     }
@@ -1977,23 +1981,23 @@ class Societe extends CommonObject
         global $conf;
         if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
         {
-            $dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
+        	$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
+
+        	$dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
             foreach ($dirsociete as $dirroot)
             {
-                $res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECLIENT_ADDON.'.php');
+                $res=dol_include_once($dirroot.$module.'.php');
                 if ($res) break;
             }
 
-            $var = $conf->global->SOCIETE_CODECLIENT_ADDON;
-
-            $mod = new $var;
+            $mod = new $module();
 
-            dol_syslog(get_class($this)."::check_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$var);
+            dol_syslog(get_class($this)."::check_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$module);
             $result = $mod->verif($this->db, $this->code_fournisseur, $this, 1);
             return $result;
         }
         else
-        {
+		{
             return 0;
         }
     }
diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php
index ab753855b4c8a1eb7d457aff5fbf40b83e21f650..5731ce0196a14e06931cfa4271d0997920b84349 100644
--- a/htdocs/societe/soc.php
+++ b/htdocs/societe/soc.php
@@ -789,8 +789,8 @@ else
         print '<td width="25%">'.$langs->trans('CustomerCode').'</td><td width="25%">';
         print '<table class="nobordernopadding"><tr><td>';
         $tmpcode=$object->code_client;
-        if ($modCodeClient->code_auto) $tmpcode=$modCodeClient->getNextValue($object,0);
-        print '<input type="text" name="code_client" size="16" value="'.$tmpcode.'" maxlength="15">';
+        if (empty($tmpcode) && ! empty($modCodeClient->code_auto)) $tmpcode=$modCodeClient->getNextValue($object,0);
+        print '<input type="text" name="code_client" size="16" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
         print '</td><td>';
         $s=$modCodeClient->getToolTip($langs,$object,0);
         print $form->textwithpicto('',$s,1);
@@ -807,8 +807,8 @@ else
             print '<td>'.$langs->trans('SupplierCode').'</td><td>';
             print '<table class="nobordernopadding"><tr><td>';
             $tmpcode=$object->code_fournisseur;
-            if ($modCodeFournisseur->code_auto) $tmpcode=$modCodeFournisseur->getNextValue($object,1);
-            print '<input type="text" name="code_fournisseur" size="16" value="'.$tmpcode.'" maxlength="15">';
+            if (empty($tmpcode) && ! empty($modCodeFournisseur->code_auto)) $tmpcode=$modCodeFournisseur->getNextValue($object,1);
+            print '<input type="text" name="code_fournisseur" size="16" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
             print '</td><td>';
             $s=$modCodeFournisseur->getToolTip($langs,$object,1);
             print $form->textwithpicto('',$s,1);
@@ -1189,8 +1189,8 @@ else
             if ((!$object->code_client || $object->code_client == -1) && $modCodeClient->code_auto)
             {
                 $tmpcode=$object->code_client;
-                if (empty($tmpcode) && $modCodeClient->code_auto) $tmpcode=$modCodeClient->getNextValue($object,0);
-                print '<input type="text" name="code_client" size="16" value="'.$tmpcode.'" maxlength="15">';
+                if (empty($tmpcode) && ! empty($modCodeClient->code_auto)) $tmpcode=$modCodeClient->getNextValue($object,0);
+                print '<input type="text" name="code_client" size="16" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
             }
             else if ($object->codeclient_modifiable())
             {
@@ -1221,8 +1221,8 @@ else
                 if ((!$object->code_fournisseur || $object->code_fournisseur == -1) && $modCodeFournisseur->code_auto)
                 {
                     $tmpcode=$object->code_fournisseur;
-                    if (empty($tmpcode) && $modCodeFournisseur->code_auto) $tmpcode=$modCodeFournisseur->getNextValue($object,1);
-                    print '<input type="text" name="code_fournisseur" size="16" value="'.$tmpcode.'" maxlength="15">';
+                    if (empty($tmpcode) && ! empty($modCodeFournisseur->code_auto)) $tmpcode=$modCodeFournisseur->getNextValue($object,1);
+                    print '<input type="text" name="code_fournisseur" size="16" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
                 }
                 else if ($object->codefournisseur_modifiable())
                 {
@@ -1830,7 +1830,7 @@ else
 	        else
 			{
 	        	$langs->load("mails");
-	       		print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NoEmail")).'">'.$langs->trans('SendMail').'</a></div>';
+	       		print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NoEMail")).'">'.$langs->trans('SendMail').'</a></div>';
 	        }
 
 	        if ($user->rights->societe->creer)
@@ -1840,7 +1840,7 @@ else
 
 	        if ($user->rights->societe->supprimer)
 	        {
-	            if ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile))	// We can(t use preloaded confirm form with jmobile
+	            if ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile))	// We can't use preloaded confirm form with jmobile
 	            {
 	                print '<div class="inline-block divButAction"><span id="action-delete" class="butActionDelete">'.$langs->trans('Delete').'</span></div>'."\n";
 	            }
@@ -1856,85 +1856,85 @@ else
 
 		if ($action == 'presend')
 		{
-        		/*
-				 * Affiche formulaire mail
-				 */
-
-				// By default if $action=='presend'
-				$titreform='SendMail';
-				$topicmail='';
-				$action='send';
-				$modelmail='thirdparty';
-
-				print '<br>';
-				print_titre($langs->trans($titreform));
-
-				// Cree l'objet formulaire mail
-				include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
-				$formmail = new FormMail($db);
-				$formmail->fromtype = 'user';
-				$formmail->fromid   = $user->id;
-				$formmail->fromname = $user->getFullName($langs);
-				$formmail->frommail = $user->email;
-				$formmail->withfrom=1;
-				$formmail->withtopic=1;
-				$liste=array();
-				foreach ($object->thirdparty_and_contact_email_array(1) as $key=>$value)	$liste[$key]=$value;
-				$formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste;
-				$formmail->withtofree=0;
-				$formmail->withtocc=$liste;
-				$formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC;
-				$formmail->withfile=2;
-				$formmail->withbody=1;
-				$formmail->withdeliveryreceipt=1;
-				$formmail->withcancel=1;
-				// Tableau des substitutions
-				$formmail->substit['__SIGNATURE__']=$user->signature;
-				$formmail->substit['__PERSONALIZED__']='';
-				$formmail->substit['__CONTACTCIVNAME__']='';
-
-				//Find the good contact adress
-				/*
-				$custcontact='';
-				$contactarr=array();
-				$contactarr=$object->liste_contact(-1,'external');
-
-				if (is_array($contactarr) && count($contactarr)>0)
-				{
-					foreach($contactarr as $contact)
-					{
-						if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) {
+			/*
+			 * Affiche formulaire mail
+			*/
+
+			// By default if $action=='presend'
+			$titreform='SendMail';
+			$topicmail='';
+			$action='send';
+			$modelmail='thirdparty';
+
+			print '<br>';
+			print_titre($langs->trans($titreform));
+
+			// Cree l'objet formulaire mail
+			include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
+			$formmail = new FormMail($db);
+			$formmail->fromtype = 'user';
+			$formmail->fromid   = $user->id;
+			$formmail->fromname = $user->getFullName($langs);
+			$formmail->frommail = $user->email;
+			$formmail->withfrom=1;
+			$formmail->withtopic=1;
+			$liste=array();
+			foreach ($object->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value;
+			$formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste;
+			$formmail->withtofree=0;
+			$formmail->withtocc=$liste;
+			$formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC;
+			$formmail->withfile=2;
+			$formmail->withbody=1;
+			$formmail->withdeliveryreceipt=1;
+			$formmail->withcancel=1;
+			// Tableau des substitutions
+			$formmail->substit['__SIGNATURE__']=$user->signature;
+			$formmail->substit['__PERSONALIZED__']='';
+			$formmail->substit['__CONTACTCIVNAME__']='';
+
+			//Find the good contact adress
+			/*
+			$custcontact='';
+			$contactarr=array();
+			$contactarr=$object->liste_contact(-1,'external');
+
+			if (is_array($contactarr) && count($contactarr)>0)
+			{
+			foreach($contactarr as $contact)
+			{
+			if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) {
 
-							require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
+			require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
 
-							$contactstatic=new Contact($db);
-							$contactstatic->fetch($contact['id']);
-							$custcontact=$contactstatic->getFullName($langs,1);
-						}
-					}
+			$contactstatic=new Contact($db);
+			$contactstatic->fetch($contact['id']);
+			$custcontact=$contactstatic->getFullName($langs,1);
+			}
+			}
 
-					if (!empty($custcontact)) {
-						$formmail->substit['__CONTACTCIVNAME__']=$custcontact;
-					}
-				}*/
+			if (!empty($custcontact)) {
+			$formmail->substit['__CONTACTCIVNAME__']=$custcontact;
+			}
+			}*/
 
 
-				// Tableau des parametres complementaires du post
-				$formmail->param['action']=$action;
-				$formmail->param['models']=$modelmail;
-				$formmail->param['socid']=$object->id;
-				$formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?socid='.$object->id;
+			// Tableau des parametres complementaires du post
+			$formmail->param['action']=$action;
+			$formmail->param['models']=$modelmail;
+			$formmail->param['socid']=$object->id;
+			$formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?socid='.$object->id;
 
-				// Init list of files
-				if (GETPOST("mode")=='init')
-				{
-					$formmail->clear_attached_files();
-					$formmail->add_attached_files($file,basename($file),dol_mimetype($file));
-				}
+			// Init list of files
+			if (GETPOST("mode")=='init')
+			{
+				$formmail->clear_attached_files();
+				$formmail->add_attached_files($file,basename($file),dol_mimetype($file));
+			}
 
-				$formmail->show_form();
+			print $formmail->get_form();
 
-				print '<br>';
+			print '<br>';
 		}
 		else
 		{
diff --git a/htdocs/theme/cameleo/style.css.php b/htdocs/theme/cameleo/style.css.php
index f76702c7b327e5888ac265604bb38debef9ab4e4..3743a95f3421885a23e06108d1f54668082379ba 100644
--- a/htdocs/theme/cameleo/style.css.php
+++ b/htdocs/theme/cameleo/style.css.php
@@ -1306,7 +1306,7 @@ span.tabspan {
 
 div.divButAction { margin-bottom: 1.4em; }
 
-.butAction:link, .butAction:visited, .butAction:hover, .butAction:active, .butActionDelete, .butActionRefused, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active {
+.butAction, .butAction:link, .butAction:visited, .butAction:hover, .butAction:active, .butActionDelete, .butActionRefused, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active {
 	font-family: <?php print $fontlist ?>;
 	font-weight: bold;
 	/*background: url(<?php echo dol_buildpath($path.'/theme/bureau2crea/img/bg_btnBlue.jpg',1); ?>) repeat-x;*/