From 7d7200a2c98d1bb491b3f08629104ba50dea483b Mon Sep 17 00:00:00 2001
From: Regis Houssin <regis@dolibarr.fr>
Date: Tue, 4 Sep 2007 18:19:06 +0000
Subject: [PATCH] Fix: modification du fonctionnement des produits fournisseurs
 !!!

---
 htdocs/comm/propal.php                        |  11 +-
 htdocs/fourn/commande/fiche.php               | 129 +++++++++---------
 htdocs/fourn/fournisseur.commande.class.php   |  34 ++---
 htdocs/fourn/fournisseur.product.class.php    |  48 ++++---
 htdocs/html.form.class.php                    |  19 +--
 htdocs/product.class.php                      |  80 +++++++----
 htdocs/product/fournisseurs.php               |  15 +-
 mysql/migration/2.1.0-2.2.0.sql               |  28 +++-
 mysql/tables/llx_commande_fournisseurdet.sql  |  32 ++---
 .../llx_product_fournisseur_price.key.sql     |   6 +-
 .../tables/llx_product_fournisseur_price.sql  |  18 ++-
 .../llx_product_fournisseur_price_log.sql     |  13 +-
 mysql/tables/llx_product_price.sql            |   2 +-
 13 files changed, 249 insertions(+), 186 deletions(-)

diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php
index 9a763bcafab..856003a03e0 100644
--- a/htdocs/comm/propal.php
+++ b/htdocs/comm/propal.php
@@ -1126,11 +1126,18 @@ if ($_GET['propalid'] > 0)
 					}
 					print "</td>\n";
 				}
-				if ($conf->global->PRODUIT_USE_MARKUP)
+				if ($conf->global->PRODUIT_USE_MARKUP && $conf->use_ajax && $conf->global->MAIN_CONFIRM_AJAX)
 				{
+					print '<div id="calc_markup'.$i.'" style="display:none">';
+					print 'Produit '.$i;
+					print '</div>'."\n";
+					
 					print '<td align="right">';
 				  print '<table class="nobordernopadding" width="100%"><tr class="nocellnopadd">';
-          print '<td class="nobordernopadding" nowrap="nowrap" align="left">'.img_calc($langs->trans("ToCalculateMarkup")).'</td>';
+          print '<td class="nobordernopadding" nowrap="nowrap" align="left">';
+          print '<a href="#" onClick="dialogInfo($(\'calc_markup'.$i.'\').innerHTML)">';
+          print img_calc($langs->trans("ToCalculateMarkup"));
+          print '</a></td>';
           print '<td class="nobordernopadding" nowrap="nowrap" align="right">'.vatrate($objp->marge_tx).'% </td>';
           print '</tr></table>';
           print '</td>';
diff --git a/htdocs/fourn/commande/fiche.php b/htdocs/fourn/commande/fiche.php
index a63ec907122..94f2f31f743 100644
--- a/htdocs/fourn/commande/fiche.php
+++ b/htdocs/fourn/commande/fiche.php
@@ -30,6 +30,7 @@
 
 require('./pre.inc.php');
 require_once(DOL_DOCUMENT_ROOT.'/fourn/commande/modules/modules_commandefournisseur.php');
+require_once DOL_DOCUMENT_ROOT."/fourn/fournisseur.product.class.php";
 if ($conf->projet->enabled)	require_once(DOL_DOCUMENT_ROOT.'/project.class.php');
 
 $langs->load('orders');
@@ -90,71 +91,75 @@ if ($_REQUEST['action'] ==	'setremisepercent' && $user->rights->fournisseur->com
  */
 if ($_POST['action'] ==	'addligne' && $user->rights->fournisseur->commande->creer)
 {
-	if ($_POST['qty'] && (($_POST['pu'] && $_POST['desc']) || $_POST['idprod']))
+	if ($_POST['qty'] && (($_POST['pu'] && $_POST['desc']) || $_POST['idprodfournprice']))
+  {
+  	$commande =	new	CommandeFournisseur($db);
+    $ret=$commande->fetch($_POST["id"]);
+
+    $soc = new Societe($db,	$commande->socid);
+    $soc->fetch($commande->socid);
+    if ($ret < 0)
     {
-      $commande =	new	CommandeFournisseur($db);
-      $ret=$commande->fetch($_POST["id"]);
-
-      $soc = new Societe($db,	$commande->socid);
-      $soc->fetch($commande->socid);
-      if ($ret < 0)
-	{
-	  dolibarr_print_error($db,$commande->error);
-	  exit;
-	}
-
-      // Ecrase $pu par celui	du produit
-      // Ecrase $desc	par	celui du produit
-      // Ecrase $txtva  par celui du produit
-      if ($_POST["idprod"] > 0)
-	{
-	  $prod =	new	Product($db, $_POST['idprod']);
-	  $prod->fetch($_POST['idprod']);
-
-	  $libelle = $prod->libelle;
-
-	  // La description de la ligne est celle saisie ou
-	  // celle du	produit	si (non	saisi +	PRODUIT_CHANGE_PROD_DESC d�fini)
-	  // \todo Ne	faut-il	pas	rendre $conf->global->PRODUIT_CHANGE_PROD_DESC toujours	a on
-	  $desc=$_POST['np_desc'];
-	  if (! $desc	&& $conf->global->PRODUIT_CHANGE_PROD_DESC)
+    	dolibarr_print_error($db,$commande->error);
+    	exit;
+    }
+    
+    // Ecrase $pu par celui	du produit
+    // Ecrase $desc	par	celui du produit
+    // Ecrase $txtva  par celui du produit
+    if ($_POST["idprodfournprice"] > 0)
+    {
+    	$prodfournprice = new ProductFournisseur($db);
+    	$prodfournprice->fetch_product_fournisseur_price($_POST["idprodfournprice"]);
+    	
+    	$prod =	new	Product($db, $prodfournprice->product_id);
+    	$prod->fetch($prodfournprice->product_id);
+    	
+    	$libelle = $prod->libelle;
+    	
+    	// La description de la ligne est celle saisie ou
+	    // celle du	produit	si (non	saisi +	PRODUIT_CHANGE_PROD_DESC d�fini)
+	    // \todo Ne	faut-il	pas	rendre $conf->global->PRODUIT_CHANGE_PROD_DESC toujours	a on
+	    $desc=$_POST['np_desc'];
+	    if (! $desc	&& $conf->global->PRODUIT_CHANGE_PROD_DESC)
 	    {
 	      $desc =	$prod->description;
 	    }
 
-	  $tva_tx	= get_default_tva($soc,$mysoc,$prod->tva_tx);
-	}
-      else
-	{
-	  $pu=$_POST['pu'];
-	  $tva_tx=$_POST['tva_tx'];
-	  $desc=$_POST['desc'];
-	}
+	    $tva_tx	= get_default_tva($soc,$mysoc,$prod->tva_tx);
+	  }
+	  else
+	  {
+	  	$pu=$_POST['pu'];
+	    $tva_tx=$_POST['tva_tx'];
+	    $desc=$_POST['desc'];
+	  }
 
-      $result=$commande->addline(
+    $result=$commande->addline(
 				 $desc,
 				 $pu,
 				 $_POST['qty'],
 				 $tva_tx,
-				 $_POST['idprod'],
+				 $prodfournprice->product_id,
+				 $_POST['idprodfournprice'],
 				 $_POST['remise_percent'],
 				 'HT'
 				 );
 
-      if ($result > 0)
-	{
-	  if ($_REQUEST['lang_id'])
+    if ($result > 0)
+	  {
+	    if ($_REQUEST['lang_id'])
 	    {
 	      $outputlangs = new Translate(DOL_DOCUMENT_ROOT ."/langs",$conf);
 	      $outputlangs->setDefaultLang($_REQUEST['lang_id']);
 	    }
-	  supplier_order_pdf_create($db, $commande->id, $commande->modelpdf, $outputlangs);
-	}
-      else
-	{
-	  $mesg='<div class="error">'.$commande->error.'</div>';
-	}
-    }
+	    supplier_order_pdf_create($db, $commande->id, $commande->modelpdf, $outputlangs);
+	  }
+    else
+	  {
+	    $mesg='<div class="error">'.$commande->error.'</div>';
+	  }
+  }
 }
 
 /*
@@ -620,16 +625,16 @@ else
 	   */
 	  print '<table class="noborder" width="100%">';
 	
-	  $sql = "SELECT l.ref, l.fk_product,	l.description, l.price,	l.qty";
+	  $sql = "SELECT l.ref as ref_fourn, l.fk_prod_fourn_price,	l.description, l.price,	l.qty";
 	  $sql.= ", l.rowid, l.tva_tx, l.remise_percent, l.subprice";
-	  $sql.= ", p.label";
-	  //$sql.= ", pf.ref_fourn";
+	  $sql.= ", p.rowid as product_id, p.label, p.ref";
 	  $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet	as l";
-	  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as	p ON l.fk_product =	p.rowid";
-	  //$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur as	pf ON l.fk_product =	pf.fk_product";
+	  $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_fournisseur_price as pfp ON l.fk_prod_fourn_price = pfp.rowid';
+	  $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_fournisseur as pf ON pfp.fk_product_fournisseur = pf.rowid';
+		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pf.fk_product = p.rowid';
 	  $sql.= " WHERE l.fk_commande = ".$commande->id;
 	  $sql.= " ORDER BY l.rowid";
-	
+
 	  $resql = $db->query($sql);
 	  if ($resql)
 	    {
@@ -653,21 +658,21 @@ else
 		  $objp =	$db->fetch_object($resql);
 		  print "<tr $bc[$var]>";
 		  print '<td>';
-		  print '<a href="'.DOL_URL_ROOT.'/product/fournisseurs.php?id='.$objp->fk_product.'">'.img_object($langs->trans("ShowProduct"),'product').' '.$objp->ref.'</a>';
-		  //print ' ('.$objp->ref_fourn.') - '.$objp->label;
+		  print '<a href="'.DOL_URL_ROOT.'/product/fournisseurs.php?id='.$objp->product_id.'">'.img_object($langs->trans("ShowProduct"),'product').' '.$objp->ref_fourn.'</a>';
+		  print ' ('.$objp->ref.')';
 		  print ' - '.$objp->label;
 		  if ($objp->description) print '<br>'.nl2br($objp->description);
 		  print "</td>";
 		  print '<td align="center">'.vatrate($objp->tva_tx).'%</td>';
 		  print '<td align="center">'.$objp->qty.'</td>';
 		  if ($objp->remise_percent >	0)
-		    {
-		      print '<td align="right">'.$objp->remise_percent."%</td>\n";
-		    }
+		  {
+		    print '<td align="right">'.$objp->remise_percent."%</td>\n";
+		  }
 		  else
-		    {
-		      print '<td>&nbsp;</td>';
-		    }
+		  {
+		    print '<td>&nbsp;</td>';
+		  }
 		  print '<td align="right">'.price($objp->subprice)."</td>\n";
 		  if ($commande->statut == 0	&& $user->rights->fournisseur->commande->creer && $_GET["action"] <> 'valid' &&	$_GET["action"]	!= 'editline')
 		    {
@@ -734,7 +739,7 @@ else
 	
 	      $var=false;
 	      print "<tr $bc[$var]>".'<td colspan="2">';
-	      $html->select_produits_fournisseurs($commande->fourn_id,'','idprod',$filtre);
+	      $html->select_produits_fournisseurs($commande->fourn_id,'','idprodfournprice',$filtre);
 	      print '</td>';
 	      print '<td align="center"><input type="text" size="2" name="qty" value="1"></td>';
 	      print '<td align="right"><input	type="text"	size="3" name="remise_percent"	value="0">%</td>';
diff --git a/htdocs/fourn/fournisseur.commande.class.php b/htdocs/fourn/fournisseur.commande.class.php
index cf21451c74e..d63503035c2 100644
--- a/htdocs/fourn/fournisseur.commande.class.php
+++ b/htdocs/fourn/fournisseur.commande.class.php
@@ -112,10 +112,12 @@ class CommandeFournisseur extends Commande
 			// export pdf -----------
 			
 			$this->lignes = array();
-			$sql = 'SELECT l.fk_product, l.description, l.price, l.qty, l.rowid, l.tva_tx, l.remise_percent, l.subprice,';
+			$sql = 'SELECT l.fk_prod_fourn_price, l.description, l.price, l.qty, l.rowid, l.tva_tx, l.remise_percent, l.subprice,';
 			$sql.= ' p.label, p.description as product_desc, p.ref, p.rowid as prodid';
 			$sql.= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet as l';
-			$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product=p.rowid';
+			$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_fournisseur_price as pfp ON l.fk_prod_fourn_price = pfp.rowid';
+			$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_fournisseur as pf ON pfp.fk_product_fournisseur = pf.rowid';
+			$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pf.fk_product = p.rowid';
 			$sql.= ' WHERE l.fk_commande = '.$this->id;
 			$sql.= ' ORDER BY l.rowid';
 			$result = $this->db->query($sql);
@@ -130,17 +132,17 @@ class CommandeFournisseur extends Commande
 					
 					$ligne                 = new CommandeFournisseurLigne();
 					
-					$ligne->desc           = $objp->description;  // Description ligne
-					$ligne->qty            = $objp->qty;
-					$ligne->tva_tx         = $objp->tva_tx;
-					$ligne->subprice       = $objp->subprice;
-					$ligne->remise_percent = $objp->remise_percent;
-					$ligne->price          = $objp->price;
-					$ligne->fk_product     = $objp->fk_product;
+					$ligne->desc                = $objp->description;  // Description ligne
+					$ligne->qty                 = $objp->qty;
+					$ligne->tva_tx              = $objp->tva_tx;
+					$ligne->subprice            = $objp->subprice;
+					$ligne->remise_percent      = $objp->remise_percent;
+					$ligne->price               = $objp->price;
+					$ligne->fk_prod_fourn_price = $objp->fk_prod_fourn_price;
 					
-					$ligne->libelle        = $objp->label;        // Label produit
-					$ligne->product_desc   = $objp->product_desc; // Description produit
-					$ligne->ref            = $objp->ref;
+					$ligne->libelle             = $objp->label;        // Label produit
+					$ligne->product_desc        = $objp->product_desc; // Description produit
+					$ligne->ref                 = $objp->ref;
 					
 					$this->lignes[$i]      = $ligne;
 					//dolibarr_syslog("1 ".$ligne->desc);
@@ -648,7 +650,7 @@ class CommandeFournisseur extends Commande
 	*      \param      price_base_type	HT or TTC
 	*      \param      int             	<0 si ko, >0 si ok
 	*/
-	function addline($desc, $pu, $qty, $txtva, $fk_product=0, $remise_percent=0, $price_base_type='HT')
+	function addline($desc, $pu, $qty, $txtva, $fk_product=0, $fk_prod_fourn_price=0, $remise_percent=0, $price_base_type='HT')
 	{
 		global $langs;
 		
@@ -682,7 +684,7 @@ class CommandeFournisseur extends Commande
 						$desc  = $prod->description;
 						$txtva = $prod->tva_tx;
 						$pu    = $prod->fourn_pu;
-						$ref   = $prod->ref;
+						$ref   = $prod->ref_fourn;
 					}
 					if ($result == 0 || $result == -1)
 					{
@@ -717,8 +719,8 @@ class CommandeFournisseur extends Commande
 				$price = $pu - $remise;
 			}
 			
-			$sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseurdet (fk_commande,label,description,fk_product, price, qty, tva_tx, remise_percent, subprice, remise, ref)";
-			$sql .= " VALUES ($this->id, '" . addslashes($label) . "','" . addslashes($desc) . "',".$fk_product.",".price2num($price,'MU').", '$qty', $txtva, $remise_percent,'".price2num($subprice,'MU')."','".price2num($remise)."','".$ref."') ;";
+			$sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseurdet (fk_commande,label,description,fk_prod_fourn_price, price, qty, tva_tx, remise_percent, subprice, remise, ref)";
+			$sql .= " VALUES (".$this->id.", '" . addslashes($label) . "','" . addslashes($desc) . "',".$fk_prod_fourn_price.",".price2num($price,'MU').", '$qty', $txtva, $remise_percent,'".price2num($subprice,'MU')."','".price2num($remise)."','".$ref."') ;";
 			dolibarr_syslog('Fournisseur.commande.class::addline sql='.$sql);
 			$resql=$this->db->query($sql);
 			if ($resql)
diff --git a/htdocs/fourn/fournisseur.product.class.php b/htdocs/fourn/fournisseur.product.class.php
index c23f454a118..d98bfbaf7c5 100644
--- a/htdocs/fourn/fournisseur.product.class.php
+++ b/htdocs/fourn/fournisseur.product.class.php
@@ -42,6 +42,9 @@ class ProductFournisseur extends Product
 	var $id ;
 	var $fourn_ref;
 	var $fourn;
+	var $fourn_qty;
+	var $product_fourn_id;
+	var $product_fourn_price_id;
 
 
 	function ProductFournisseur($db)
@@ -125,7 +128,7 @@ class ProductFournisseur extends Product
 
 		/* Mise � jour du prix */
 
-		$this->update_buyprice($this->fourn->id, $qty, $buyprice, $user);
+		$this->update_buyprice($qty, $buyprice, $user);
 
 		/* Mise � jour de la r�f�rence */
 
@@ -146,25 +149,28 @@ class ProductFournisseur extends Product
 	*    \param  user            	Objet user de l'utilisateur qui modifie
 	*    \param  price_base_type	HT or TTC
 	*/
-	function update_buyprice($id_fourn, $qty, $buyprice, $user, $price_base_type='HT')
+	function update_buyprice($qty, $buyprice, $user, $price_base_type='HT')
 	{
 		$error=0;
 		$this->db->begin();
-
+		
 		// Supprime prix courant du fournisseur pour cette quantit�
 		$sql = "DELETE FROM  ".MAIN_DB_PREFIX."product_fournisseur_price ";
-		$sql .= " WHERE ";
-		$sql .= " fk_product = ".$this->id;
-		$sql .= " AND fk_soc = ".$id_fourn;
-		$sql .= " AND quantity = ".$qty;
-
+		if ($this->product_fourn_price_id)
+		{
+			$sql .= " WHERE rowid = ".$this->product_fourn_price_id;
+		}
+		else
+		{
+			$sql .= " WHERE fk_product_fournisseur = ".$this->product_fourn_id." AND quantity = ".$qty;
+		}
+		
 		if ($this->db->query($sql))
 		{
 			// Ajoute prix courant du fournisseur pour cette quantit�
 			$sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price";
 			$sql .= " SET datec = now()";
-			$sql .= " ,fk_product = ".$this->id;
-			$sql .= " ,fk_soc = ".$id_fourn;
+			$sql .= " ,fk_product_fournisseur = ".$this->product_fourn_id;
 			$sql .= " ,fk_user = ".$user->id;
 			$sql .= " ,price = ".price2num($buyprice);
 			$sql .= " ,quantity = ".$qty;
@@ -180,8 +186,7 @@ class ProductFournisseur extends Product
 				// Ajoute modif dans table log
 				$sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price_log ";
 				$sql .= " SET datec = now()";
-				$sql .= " ,fk_product = ".$this->id;
-				$sql .= " ,fk_soc = ".$id_fourn;
+				$sql .= " ,fk_product_fournisseur = ".$this->product_fourn_id;
 				$sql .= " ,fk_user = ".$user->id;
 				$sql .= " ,price = ".price2num($buyprice);
 				$sql .= " ,quantity = ".$qty;
@@ -264,6 +269,7 @@ class ProductFournisseur extends Product
 		{
 			$result = $this->db->fetch_array();
 			$this->ref_fourn = $result["ref_fourn"];
+			$this->product_fourn_id = $result["rowid"];
 			return 1;
 		}
 		else
@@ -281,19 +287,23 @@ class ProductFournisseur extends Product
 	*/
 	function fetch_product_fournisseur_price($rowid)
 	{
-		$sql = "SELECT rowid, fk_soc, ref_fourn, price, quantity, unitprice";
-		$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price";
-		$sql.= " WHERE rowid = ".$rowid;
+		$sql = "SELECT pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice";
+		$sql.= ", pf.rowid as product_fourn_id, pf.fk_soc, pf.ref_fourn, pf.fk_product";
+		$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."product_fournisseur as pf";
+		$sql.= " WHERE pfp.rowid = ".$rowid." AND pf.rowid = pfp.fk_product_fournisseur";
 
 		dolibarr_syslog("Product::fetch_product_fournisseur_price sql=".$sql);
 		$resql = $this->db->query($sql) ;
 		if ($resql)
 		{
 			$obj = $this->db->fetch_object($resql);
-			$this->fourn_ref       = $obj->ref_fourn;
-			$this->fourn_price     = $obj->price;
-			$this->fourn_qty       = $obj->qty;
-			$this->fourn_unitprice = $obj->unitprice;
+			$this->product_fourn_price_id = $rowid;
+			$this->product_fourn_id       = $obj->product_fourn_id;
+			$this->fourn_ref              = $obj->ref_fourn;
+			$this->fourn_price            = $obj->price;
+			$this->fourn_qty              = $obj->quantity;
+			$this->fourn_unitprice        = $obj->unitprice;
+			$this->product_id             = $obj->fk_product;
 			return 1;
 		}
 		else
diff --git a/htdocs/html.form.class.php b/htdocs/html.form.class.php
index 7880b84e62e..ce92d3a9ac6 100644
--- a/htdocs/html.form.class.php
+++ b/htdocs/html.form.class.php
@@ -1144,16 +1144,17 @@ class Form
 		global $langs,$conf;
 		
 		$sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration,";
-		$sql.= " pfp.price as fprice, pfp.quantity, pfp.unitprice";
+		$sql.= " pf.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.unitprice";
 		$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
-		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
+		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur as pf ON p.rowid = pf.fk_product";
+		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON pf.rowid = pfp.fk_product_fournisseur";
 		$sql.= " WHERE p.envente = 1";
-		if ($socid) $sql.= " AND pfp.fk_soc = ".$socid;
+		if ($socid) $sql.= " AND pf.fk_soc = ".$socid;
 		if ($filtretype && $filtretype != '') $sql.=" AND p.fk_product_type=".$filtretype;
 		if ($filtre) $sql.="$filtre";
-		if ($ajaxkeysearch && $ajaxkeysearch != '') $sql.=" AND p.ref like '%".$ajaxkeysearch."%' OR p.label like '%".$ajaxkeysearch."%'";
-		$sql.= " ORDER BY p.ref DESC";
-		
+		if ($ajaxkeysearch && $ajaxkeysearch != '') $sql.=" AND (pf.ref_fourn like '%".$ajaxkeysearch."%' OR p.label like '%".$ajaxkeysearch."%')";
+		$sql.= " ORDER BY pf.ref_fourn DESC";
+
 		dolibarr_syslog("Form::select_produits_fournisseurs sql=$sql",LOG_DEBUG);
 		
 		$result=$this->db->query($sql);
@@ -1187,10 +1188,10 @@ class Form
 			{
 				$objp = $this->db->fetch_object($result);
 				
-				$opt = '<option value="'.$objp->rowid.'"';
-				if ($selected == $objp->rowid) $opt.= ' selected="true"';
+				$opt = '<option value="'.$objp->idprodfournprice.'"';
+				if ($selected == $objp->idprodfournprice) $opt.= ' selected="true"';
 				if ($objp->fprice == '') $opt.=' disabled="disabled"';
-				$opt.= '>'.$objp->ref.' - ';
+				$opt.= '>'.$objp->ref_fourn.' - ';
 				$opt.= dolibarr_trunc($objp->label,18).' - ';
 				if ($objp->fprice != '') 
 				{
diff --git a/htdocs/product.class.php b/htdocs/product.class.php
index c2d34fdfbb1..0a4b4368d2f 100644
--- a/htdocs/product.class.php
+++ b/htdocs/product.class.php
@@ -93,6 +93,10 @@ class Product
   var $canvas; 
   //! Nombre de piece en commande, non expedie
   var $stock_in_command;
+  
+  //! Id du fournisseur
+  var $product_fourn_id;
+  
   /**
    *    \brief      Constructeur de la classe
    *    \param      DB          Handler acc�s base de donn�es
@@ -664,12 +668,13 @@ class Product
 	function get_buyprice($fourn_id, $qty)
 	{
 		$result = 0;
-		$sql = "SELECT pf.rowid, pf.price as price, pf.quantity as quantity";
-		$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pf";
-		$sql.= " WHERE pf.fk_soc = ".$fourn_id;
+		$sql = "SELECT pfp.rowid, pfp.price as price, pfp.quantity as quantity, pf.ref_fourn";
+		$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."product_fournisseur as pf";
+		$sql.= " WHERE pf.rowid = pfp.fk_product_fournisseur";
+		$sql.= " AND pf.fk_soc = ".$fourn_id;
 		$sql.= " AND pf.fk_product =" .$this->id;
-		$sql.= " AND quantity <= ".$qty;
-		$sql.= " ORDER BY quantity DESC";
+		$sql.= " AND pfp.quantity <= ".$qty;
+		$sql.= " ORDER BY pfp.quantity DESC";
 		$sql.= " LIMIT 1";
 	
 		dolibarr_syslog("Product::get_buyprice $fourn_id,$qty sql=$sql");
@@ -682,17 +687,19 @@ class Product
 			{
 				$this->buyprice = $obj->price;                      // \deprecated
 				$this->fourn_pu = $obj->price / $obj->quantity;     // Prix unitaire du produit pour le fournisseur $fourn_id
+				$this->ref_fourn = $obj->ref_fourn;
 				return 1;
 			}
 			else
 			{
 				// On refait le meme select mais sans critere de quantite
-				$sql = "SELECT pf.price as price, pf.quantity as quantity";
-				$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pf";
-				$sql.= " WHERE pf.fk_soc = ".$fourn_id;
+				$sql = "SELECT pfp.price as price, pfp.quantity as quantity, pf.fk_soc";
+				$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."product_fournisseur as pf";
+				$sql.= " WHERE pf.rowid = pfp.fk_product_fournisseur";
+				$sql.= " AND pf.fk_soc = ".$fourn_id;
 				$sql.= " AND pf.fk_product =" .$this->id;
 				//$sql.= " AND quantity <= ".$qty;
-				$sql.= " ORDER BY quantity DESC";
+				$sql.= " ORDER BY pfp.quantity DESC";
 				$sql.= " LIMIT 1";
 	
 				$resql = $this->db->query($sql);
@@ -1536,36 +1543,49 @@ class Product
   {
     $sql = "SELECT count(*) as nb";
     $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur";
-    $sql.= " WHERE fk_product = ".$this->id." AND fk_soc = ".$id_fourn;
-    //$sql.= " AND ref_fourn = '".$ref_fourn."'"; // cr�e des doublons
+    $sql.= " WHERE fk_product = ".$this->id." AND fk_soc = ".$id_fourn." AND ref_fourn = '".$ref_fourn."'";
 
     $resql=$this->db->query($sql);
     if ($resql)
-      {
-	$obj = $this->db->fetch_object($resql);
-	if ($obj->nb == 0)
-	  {
-	    $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur ";
-	    $sql .= " (datec, fk_product, fk_soc, ref_fourn, fk_user_author)";
-	    $sql .= " VALUES (now(), $this->id, $id_fourn, '$ref_fourn', $user->id)";
-
-	    if ($this->db->query($sql))
+    {
+    	$obj = $this->db->fetch_object($resql);
+    	if ($obj->nb == 0)
+    	{
+    		$sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur ";
+	      $sql .= " (datec, fk_product, fk_soc, ref_fourn, fk_user_author)";
+	      $sql .= " VALUES (now(), ".$this->id.", ".$id_fourn.", '".$ref_fourn."', ".$user->id.")";
+	      
+	      if ($this->db->query($sql))
 	      {
-		return 1;
+	      	$this->product_fourn_id = $this->db->last_insert_id(MAIN_DB_PREFIX."product_fournisseur");
+	      	return 1;
 	      }
-	    else
+	      else
 	      {
-		$this->error=$this->db->error();
-		return -1;
+	      	$this->error=$this->db->error();
+	      	return -1;
 	      }
+	    }
+	    else
+	    {
+	    	$sql = "SELECT rowid";
+	    	$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur";
+	    	$sql.= " WHERE fk_product = ".$this->id." AND fk_soc = ".$id_fourn." AND ref_fourn = '".$ref_fourn."'";
+   	
+	    	$resql=$this->db->query($sql);
+	    	if ($resql)
+	    	{
+	    		$obj = $this->db->fetch_object($resql);
+	    		$this->product_fourn_id = $obj->rowid;
+	    	}
+	    }
+	    $this->db->free($resql);
 	  }
-	$this->db->free($resql);
-      }
     else
-      {
-	$this->error=$this->db->error();
-	return -2;
-      }
+    {
+    	$this->error=$this->db->error();
+    	return -2;
+    }
   }
 
 
diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php
index 9bc32d376bc..2233ece5ecd 100644
--- a/htdocs/product/fournisseurs.php
+++ b/htdocs/product/fournisseurs.php
@@ -106,7 +106,7 @@ if ($_POST["action"] == 'updateprice' && $_POST["cancel"] <> $langs->trans("Canc
 			{
 				if ($_POST["price"] >= 0)
 				{
-					$ret=$product->update_buyprice($_POST["id_fourn"], $_POST["qty"], $_POST["price"], $user);
+					$ret=$product->update_buyprice($_POST["qty"], $_POST["price"], $user);
 					if ($ret < 0)
 					{
 						$error++;
@@ -228,6 +228,7 @@ if ($_GET["id"] || $_GET["ref"])
 				$langs->load("suppliers");
 				
 				if ($_GET["rowid"]) {
+					$product->fetch_product_fournisseur_price($_GET["rowid"]);
 					print_fiche_titre($langs->trans("ChangeSupplierPrice"));
 				} else {
 					print_fiche_titre($langs->trans("AddSupplierPrice"));
@@ -239,7 +240,8 @@ if ($_GET["id"] || $_GET["ref"])
 				if ($_GET["rowid"])
 				{
 					print '<input type="hidden" name="id_fourn" value="'.$_GET["socid"].'">';
-					print '<input type="hidden" name="ref_fourn" value="'.$product->ref_fourn.'">';
+					print '<input type="hidden" name="ref_fourn" value="'.$product->fourn_ref.'">';
+					print '<input type="hidden" name="ref_fourn_price_id" value="'.$_GET["rowid"].'">';
 				}
 				else
 				{
@@ -252,7 +254,7 @@ if ($_GET["id"] || $_GET["ref"])
 				print '<tr><td>'.$langs->trans("SupplierRef").'</td><td>';
 				if ($_GET["rowid"])
 				{
-					print $product->ref_fourn;
+					print $product->fourn_ref;
 				}
 				else
 				{
@@ -264,8 +266,8 @@ if ($_GET["id"] || $_GET["ref"])
 				print '<td>';
 				if ($_GET["rowid"])
 				{
-					print '<input type="hidden" name="qty" value="'.$quantity.'">';
-					print $quantity;
+					print '<input type="hidden" name="qty" value="'.$product->fourn_qty.'">';
+					print $product->fourn_qty;
 				}
 				else
 				{
@@ -273,7 +275,6 @@ if ($_GET["id"] || $_GET["ref"])
 				}
 				print '</td>';
 				print '<td>'.$langs->trans("PriceQtyHT").'</td>';
-				$product->fetch_product_fournisseur_price($_GET["rowid"]);
 				print '<td><input class="flat" name="price" size="8" value="'.price($product->fourn_price).'"></td></tr>';
 				
 				print '<tr><td colspan="6" align="center"><input class="button" type="submit" value="'.$langs->trans("Save").'">';
@@ -326,7 +327,7 @@ if ($_GET["id"] || $_GET["ref"])
 				$sql.= " pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice";
 				$sql.= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."product_fournisseur as pf";
 				$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp";
-				$sql.= " ON pf.fk_soc = pfp.fk_soc AND pf.fk_product = pfp.fk_product";
+				$sql.= " ON pf.rowid = pfp.fk_product_fournisseur";
 				$sql.= " WHERE pf.fk_soc = s.rowid AND pf.fk_product = ".$product->id;
 				$sql.= " ORDER BY lower(s.nom), pfp.quantity";
 
diff --git a/mysql/migration/2.1.0-2.2.0.sql b/mysql/migration/2.1.0-2.2.0.sql
index 0644de7103f..49539e3c2bf 100644
--- a/mysql/migration/2.1.0-2.2.0.sql
+++ b/mysql/migration/2.1.0-2.2.0.sql
@@ -720,7 +720,6 @@ ALTER TABLE `llx_osc_product` ADD UNIQUE KEY `fk_product` (`fk_product`);
 -- V4 ALTER TABLE llx_facture ADD CONSTRAINT fk_facture_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid);
 -- V4 ALTER TABLE llx_facture_fourn ADD CONSTRAINT fk_facture_fourn_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid);
 -- V4 ALTER TABLE llx_fichinter ADD CONSTRAINT fk_fichinter_fk_soc	FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid);
--- V4 ALTER TABLE llx_product_fournisseur_price ADD CONSTRAINT fk_product_fournisseur_price_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid);
 -- V4 ALTER TABLE llx_propal ADD CONSTRAINT fk_propal_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid);
 -- V4 ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid);
 -- V4 ALTER TABLE llx_categorie_societe ADD CONSTRAINT fk_categorie_societe_fk_soc   FOREIGN KEY (fk_societe) REFERENCES llx_societe (rowid);
@@ -753,7 +752,6 @@ drop table if exists `llx_accountingsystem_det`;
 update llx_bank set label='(InitialBankBalance)' where fk_type='SOLD' and label in ('Balance','(Balance)','Solde','(Solde)');
 
 alter table llx_product_fournisseur_price add unitprice double(16,8);
-alter table llx_product_fournisseur_price add ref_fourn varchar(30) after fk_soc;
 update llx_product_fournisseur_price set unitprice = ROUND(price/quantity,8) where unitprice IS NULL;
 
 update llx_fichinter set tms=datec where tms < datec;
@@ -849,4 +847,28 @@ ALTER TABLE llx_facturedet MODIFY special_code tinyint(4) unsigned default 0;
 ALTER TABLE llx_commandedet MODIFY special_code tinyint(4) unsigned default 0;
 
 ALTER TABLE llx_propaldet ADD COLUMN special_code tinyint(4) unsigned default 0 after marque_tx;
-ALTER TABLE llx_propaldet ADD COLUMN pa_ht double(16,8) DEFAULT 0 after info_bits;
\ No newline at end of file
+ALTER TABLE llx_propaldet ADD COLUMN pa_ht double(16,8) DEFAULT 0 after info_bits;
+
+-- Nouveau fonctionnement de la table llx_product_fournisseur_price
+-- V4 ALTER TABLE llx_product_fournisseur_price DROP FOREIGN KEY fk_product_fournisseur_price_fk_user;
+-- V4 ALTER TABLE llx_product_fournisseur_price DROP FOREIGN KEY fk_product_fournisseur_price_fk_soc;
+-- V4 ALTER TABLE llx_product_fournisseur_price DROP FOREIGN KEY fk_product_fournisseur_price_fk_product;
+ALTER TABLE llx_product_fournisseur_price DROP INDEX idx_product_fournisseur_price_fk_user;
+ALTER TABLE llx_product_fournisseur_price DROP INDEX idx_product_fournisseur_price_fk_soc;
+ALTER TABLE llx_product_fournisseur_price DROP INDEX idx_product_fournisseur_price_fk_product;
+ALTER TABLE llx_product_fournisseur_price DROP COLUMN ref_fourn;
+-- V4.1 UPDATE llx_product_fournisseur_price as pfp SET pfp.fk_product = (SELECT pf.rowid FROM llx_product_fournisseur AS pf WHERE pfp.fk_product = pf.fk_product AND pfp.fk_soc = pf.fk_soc);
+ALTER TABLE llx_product_fournisseur_price DROP COLUMN fk_soc;
+ALTER TABLE llx_product_fournisseur_price CHANGE fk_product fk_product_fournisseur integer NOT NULL;
+ALTER TABLE llx_product_fournisseur_price ADD INDEX idx_product_fournisseur_price_fk_user (fk_user);
+ALTER TABLE llx_product_fournisseur_price ADD INDEX idx_product_fournisseur_price_fk_product_fournisseur (fk_product_fournisseur);
+-- V4 ALTER TABLE llx_product_fournisseur_price ADD CONSTRAINT fk_product_fournisseur_price_fk_user    FOREIGN KEY (fk_user)    REFERENCES llx_user (rowid);
+-- V4 ALTER TABLE llx_product_fournisseur_price ADD CONSTRAINT fk_product_fournisseur_price_fk_product_fournisseur FOREIGN KEY (fk_product_fournisseur) REFERENCES llx_product_fournisseur (rowid);
+
+-- Nouveau fonctionnement de la table llx_product_fournisseur_price_log
+-- V4.1 UPDATE llx_product_fournisseur_price_log as pfpl SET pfpl.fk_product = (SELECT pf.rowid FROM llx_product_fournisseur AS pf WHERE pfpl.fk_product = pf.fk_product AND pfpl.fk_soc = pf.fk_soc);
+ALTER TABLE llx_product_fournisseur_price_log DROP COLUMN fk_soc;
+ALTER TABLE llx_product_fournisseur_price_log CHANGE fk_product fk_product_fournisseur integer NOT NULL;
+
+ALTER TABLE llx_commande_fournisseurdet MODIFY fk_commande integer NOT NULL;
+ALTER TABLE llx_commande_fournisseurdet CHANGE fk_product fk_prod_fourn_price integer NOT NULL;
\ No newline at end of file
diff --git a/mysql/tables/llx_commande_fournisseurdet.sql b/mysql/tables/llx_commande_fournisseurdet.sql
index 41a04a81d06..7ce2aef78ef 100644
--- a/mysql/tables/llx_commande_fournisseurdet.sql
+++ b/mysql/tables/llx_commande_fournisseurdet.sql
@@ -22,20 +22,20 @@
 
 create table llx_commande_fournisseurdet
 (
-  rowid          integer AUTO_INCREMENT PRIMARY KEY,
-  fk_commande    integer,
-  fk_product     integer,
-  ref            varchar(50),
-  label          varchar(255),
-  description    text,
-  tva_tx         double(6,3)  DEFAULT 0,    -- taux tva
-  qty            real,                      -- quantit�
-  remise_percent real         DEFAULT 0,    -- pourcentage de remise
-  remise         real         DEFAULT 0,    -- montant de la remise
-  price          real,                      -- prix final
-  subprice       double(16,8) DEFAULT 0,    -- prix unitaire
-  total_ht       double(16,8) DEFAULT 0,    -- Total HT de la ligne toute quantit� et incluant remise ligne et globale
-  total_tva      double(16,8) DEFAULT 0,	  -- Total TVA de la ligne toute quantit� et incluant remise ligne et globale
-  total_ttc      double(16,8) DEFAULT 0,	  -- Total TTC de la ligne toute quantit� et incluant remise ligne et globale
-  info_bits	     integer      DEFAULT 0     -- TVA NPR ou non
+  rowid                      integer AUTO_INCREMENT PRIMARY KEY,
+  fk_commande                integer      NOT NULL,
+  fk_prod_fourn_price        integer      NOT NULL,
+  ref                        varchar(50),
+  label                      varchar(255),
+  description                text,
+  tva_tx                     double(6,3)  DEFAULT 0,    -- taux tva
+  qty                        real,                      -- quantit�
+  remise_percent             real         DEFAULT 0,    -- pourcentage de remise
+  remise                     real         DEFAULT 0,    -- montant de la remise
+  price                      real,                      -- prix final
+  subprice                   double(16,8) DEFAULT 0,    -- prix unitaire
+  total_ht                   double(16,8) DEFAULT 0,    -- Total HT de la ligne toute quantit� et incluant remise ligne et globale
+  total_tva                  double(16,8) DEFAULT 0,	  -- Total TVA de la ligne toute quantit� et incluant remise ligne et globale
+  total_ttc                  double(16,8) DEFAULT 0,	  -- Total TTC de la ligne toute quantit� et incluant remise ligne et globale
+  info_bits	                 integer      DEFAULT 0     -- TVA NPR ou non
 )type=innodb;
diff --git a/mysql/tables/llx_product_fournisseur_price.key.sql b/mysql/tables/llx_product_fournisseur_price.key.sql
index 64ffd17a721..36d85c23871 100644
--- a/mysql/tables/llx_product_fournisseur_price.key.sql
+++ b/mysql/tables/llx_product_fournisseur_price.key.sql
@@ -23,11 +23,9 @@
 
 
 ALTER TABLE llx_product_fournisseur_price ADD INDEX idx_product_fournisseur_price_fk_user (fk_user);
-ALTER TABLE llx_product_fournisseur_price ADD INDEX idx_product_fournisseur_price_fk_soc (fk_soc);
-ALTER TABLE llx_product_fournisseur_price ADD INDEX idx_product_fournisseur_price_fk_product (fk_product);
+ALTER TABLE llx_product_fournisseur_price ADD INDEX idx_product_fournisseur_price_fk_product_fournisseur (fk_product_fournisseur);
 
 ALTER TABLE llx_product_fournisseur_price ADD CONSTRAINT fk_product_fournisseur_price_fk_user    FOREIGN KEY (fk_user)    REFERENCES llx_user (rowid);
-ALTER TABLE llx_product_fournisseur_price ADD CONSTRAINT fk_product_fournisseur_price_fk_soc     FOREIGN KEY (fk_soc)     REFERENCES llx_societe (rowid);
-ALTER TABLE llx_product_fournisseur_price ADD CONSTRAINT fk_product_fournisseur_price_fk_product FOREIGN KEY (fk_product) REFERENCES llx_product (rowid);
+ALTER TABLE llx_product_fournisseur_price ADD CONSTRAINT fk_product_fournisseur_price_fk_product_fournisseur FOREIGN KEY (fk_product_fournisseur) REFERENCES llx_product_fournisseur (rowid);
 
 
diff --git a/mysql/tables/llx_product_fournisseur_price.sql b/mysql/tables/llx_product_fournisseur_price.sql
index c25a828fdaf..cdf6ecd89f1 100644
--- a/mysql/tables/llx_product_fournisseur_price.sql
+++ b/mysql/tables/llx_product_fournisseur_price.sql
@@ -22,15 +22,13 @@
 
 create table llx_product_fournisseur_price
 (
-  rowid           integer AUTO_INCREMENT PRIMARY KEY,
-  datec           datetime,
-  tms             timestamp,
-  fk_product      integer,
-  fk_soc          integer,                 -- lien sur llx_societe
-  ref_fourn       varchar(30),
-  price           double(16,8) DEFAULT 0,
-  quantity        double,
-  unitprice       double(16,8) DEFAULT 0,
-  fk_user         integer
+  rowid                       integer AUTO_INCREMENT PRIMARY KEY,
+  datec                       datetime,
+  tms                         timestamp,
+  fk_product_fournisseur      integer      NOT NULL,
+  price                       double(16,8) DEFAULT 0,
+  quantity                    double,
+  unitprice                   double(16,8) DEFAULT 0,
+  fk_user                     integer
 
 )type=innodb;
diff --git a/mysql/tables/llx_product_fournisseur_price_log.sql b/mysql/tables/llx_product_fournisseur_price_log.sql
index ecfca7ca1ed..1976a7d722f 100644
--- a/mysql/tables/llx_product_fournisseur_price_log.sql
+++ b/mysql/tables/llx_product_fournisseur_price_log.sql
@@ -22,12 +22,11 @@
 
 create table llx_product_fournisseur_price_log
 (
-  rowid           integer AUTO_INCREMENT PRIMARY KEY,
-  datec           datetime,
-  fk_product      integer,
-  fk_soc          integer,                  -- lien sur llx_societe
-  price           double(16,8) DEFAULT 0,
-  quantity        double,
-  fk_user         integer
+  rowid                       integer AUTO_INCREMENT PRIMARY KEY,
+  datec                       datetime,
+  fk_product_fournisseur      integer      NOT NULL,
+  price                       double(16,8) DEFAULT 0,
+  quantity                    double,
+  fk_user                     integer
 
 )type=innodb;
diff --git a/mysql/tables/llx_product_price.sql b/mysql/tables/llx_product_price.sql
index d3982740e9e..0692937e114 100644
--- a/mysql/tables/llx_product_price.sql
+++ b/mysql/tables/llx_product_price.sql
@@ -26,7 +26,7 @@ create table llx_product_price
   tms             timestamp,
   fk_product      integer NOT NULL,
   date_price      datetime NOT NULL,
-  price_level	  tinyint(4) NULL DEFAULT 1,
+  price_level	    tinyint(4) NULL DEFAULT 1,
   price           double(16,8),
   price_ttc       double(16,8) DEFAULT 0,
   price_base_type varchar(3)  DEFAULT 'HT',
-- 
GitLab