diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php
index 6b2c626da39b2808e1df97a8b3a8756b46c20605..0592b738fddfa7b8ad0ae264a997d253ffedec08 100644
--- a/htdocs/admin/stock.php
+++ b/htdocs/admin/stock.php
@@ -87,6 +87,9 @@ if($action)
 	if($action == 'STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT') {
 	    $res = dolibarr_set_const($db, "STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT", GETPOST('STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT','alpha'),'chaine',0,'',$conf->entity);
 	}
+	if($action == 'INDEPENDANT_SUBPRODUCT_STOCK') {
+	    $res = dolibarr_set_const($db, "INDEPENDANT_SUBPRODUCT_STOCK", GETPOST('INDEPENDANT_SUBPRODUCT_STOCK','alpha'),'chaine',0,'',$conf->entity);
+	}
 
 	if (! $res > 0) $error++;
 
@@ -339,9 +342,29 @@ print '</form>';
 print "</td>\n";
 print "</tr>\n";
 print '<br>';
-print '</table>';
-print '<br>';
 
+/* I keep the option/feature, but hidden to end users for the moment. If feature is used by module, no need to have users see it.
+If not used by a module, I still need to understand in which case user may need this now we can set rule on product page.
+if ($conf->global->PRODUIT_SOUSPRODUITS) 
+{
+	$var=!$var;
+	
+	print "<tr ".$bc[$var].">";
+	print '<td width="60%">'.$langs->trans("IndependantSubProductStock").'</td>';
+	
+	print '<td width="160" align="right">';
+	print "<form method=\"post\" action=\"stock.php\">";
+	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+	print "<input type=\"hidden\" name=\"action\" value=\"INDEPENDANT_SUBPRODUCT_STOCK\">";
+	print $form->selectyesno("INDEPENDANT_SUBPRODUCT_STOCK",$conf->global->INDEPENDANT_SUBPRODUCT_STOCK,1);
+	print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
+	print '</form>';
+	print "</td>\n";
+	print "</tr>\n";
+}
+*/
+
+print '</table>';
 
 llxFooter();
 
diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
index b896dc955e6585130f31c303345eca48c7ce65b0..3d52da2cd03d5cd76c3a082e7680b314e50aab8e 100755
--- a/htdocs/langs/en_US/products.lang
+++ b/htdocs/langs/en_US/products.lang
@@ -250,4 +250,7 @@ PriceExpressionEditorHelp3=In both product/service and supplier prices there are
 PriceExpressionEditorHelp4=In product/service price only: <b>#supplier_min_price#</b><br>In supplier prices only: <b>#supplier_quantity# and #supplier_tva_tx#</b>
 PriceMode=Price mode
 PriceNumeric=Number
-DefaultPrice=Default price
\ No newline at end of file
+DefaultPrice=Default price
+ComposedProductDecreaseStock=Decrease Stock for sub-product
+ComposedProduct=Sub-product
+MinSupplierPrice=Minimun supplier price
diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang
index 10fcf353fd44c002355572bb574511363a80943e..7025176c9f1db0e74bae60e5d952470acb190c31 100644
--- a/htdocs/langs/en_US/stocks.lang
+++ b/htdocs/langs/en_US/stocks.lang
@@ -47,6 +47,7 @@ PMPValue=Weighted average price
 PMPValueShort=WAP
 EnhancedValueOfWarehouses=Warehouses value
 UserWarehouseAutoCreate=Create a warehouse automatically when creating a user
+IndependantSubProductStock=Product stock and subproduct stock are independant
 QtyDispatched=Quantity dispatched
 QtyDispatchedShort=Qty dispatched
 QtyToDispatchShort=Qty to dispatch
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index 3f3786016e5d0e84f5a2ae8bb72edfb512601a76..fe67938766d0514a5c7f6cd3294c58b1d41c5786 100755
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -2306,6 +2306,40 @@ class Product extends CommonObject
 		}
 	}
 
+	/**
+	 *  Modify composed product
+	 *
+	 *  @param      int	$id_pere    Id of master product
+	 *  @param      int	$id_fils    Id of linked product
+	 *  @param		int	$qty		Quantity
+	 *  @param		int	$incdec		increase/descrease stock or not
+	 * 	 *  @return     int        		< 0 if KO, > 0 if OK
+	 */
+	function update_sousproduit($id_pere, $id_fils,$qty, $incdec=1)
+	{
+		// Clean parameters
+		if (! is_numeric($id_pere)) $id_pere=0;
+		if (! is_numeric($id_fils)) $id_fils=0;
+		if (! is_numeric($incdec)) $incdec=1;
+		if (! is_numeric($qty)) $qty=1;
+		
+		$sql = 'UPDATE '.MAIN_DB_PREFIX.'product_association SET ';
+		$sql.= 'qty='.$qty;
+		$sql.= ',incdec='.$incdec;
+		$sql .= ' WHERE fk_product_pere='.$id_pere.' AND fk_product_fils='.$id_fils;
+		
+		if (!$this->db->query($sql))
+		{
+			dol_print_error($this->db);
+			return -1;
+		}
+		else
+		{
+			return 1;
+		}
+		
+	}
+
 	/**
 	 *  Retire le lien entre un sousproduit et un produit/service
 	 *
@@ -2633,6 +2667,8 @@ class Product extends CommonObject
 				$nb=(! empty($desc_pere[1]) ? $desc_pere[1] :'');
 				$type=(! empty($desc_pere[2]) ? $desc_pere[2] :'');
 				$label=(! empty($desc_pere[3]) ? $desc_pere[3] :'');
+				$incdec=!empty($desc_pere[4]) ? $desc_pere[4] : 0;
+				
 				if ($multiply < 1) $multiply=1;
 
 				//print "XXX We add id=".$id." - label=".$label." - nb=".$nb." - multiply=".$multiply." fullpath=".$compl_path.$label."\n";
@@ -2649,7 +2685,8 @@ class Product extends CommonObject
 					'fullpath'=>$compl_path.$label,			// Label
 					'type'=>$type,				// Nb of units that compose parent product
 					'desiredstock'=>$this->desiredstock,
-					'level'=>$level
+					'level'=>$level,
+					'incdec'=>$incdec
 				);
 
 				// Recursive call if there is childs to child
@@ -2798,7 +2835,7 @@ class Product extends CommonObject
 	 */
 	function getChildsArbo($id)
 	{
-		$sql = "SELECT p.rowid, p.label as label, pa.qty as qty, pa.fk_product_fils as id, p.fk_product_type";
+		$sql = "SELECT p.rowid, p.label as label, pa.qty as qty, pa.fk_product_fils as id, p.fk_product_type, pa.incdec";
 		$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
 		$sql.= ", ".MAIN_DB_PREFIX."product_association as pa";
 		$sql.= " WHERE p.rowid = pa.fk_product_fils";
@@ -2812,7 +2849,13 @@ class Product extends CommonObject
 			$prods = array();
 			while ($rec = $this->db->fetch_array($res))
 			{
-				$prods[$rec['rowid']]= array(0=>$rec['id'],1=>$rec['qty'],2=>$rec['fk_product_type'],3=>$this->db->escape($rec['label']));
+				$prods[$rec['rowid']]= array(
+					0=>$rec['id'],
+					1=>$rec['qty'],
+					2=>$rec['fk_product_type'],
+					3=>$this->db->escape($rec['label']),
+					4=>$rec['incdec']
+				);
 				//$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty'],2=>$rec['fk_product_type']);
 				//$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty']);
 				$listofchilds=$this->getChildsArbo($rec['id']);
diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php
index 12553ada59ac7ddf32dd225e0ea8ddccb73377fb..9efa7772cb0b0be55f9c9d5a22f4d15c57cad702 100644
--- a/htdocs/product/composition/card.php
+++ b/htdocs/product/composition/card.php
@@ -109,6 +109,19 @@ $cancel <> $langs->trans("Cancel") &&
 		exit;
 	}
 }
+else if($action==='save_composed_product') {
+	
+	$TProduct = GETPOST('TProduct', 'array');
+	if(!empty($TProduct)) {
+		
+		foreach ($TProduct as $id_product => $row) {
+			$product->update_sousproduit($id, $id_product,$row['qty'], isset($row['incdec']) ? 1 : 0 );
+		}
+		
+	}
+	
+	
+}
 
 if ($cancel == $langs->trans("Cancel"))
 {
@@ -175,97 +188,6 @@ dol_fiche_head($head, 'subproduct', $titre, 0, $picto);
 
 if ($id > 0 || ! empty($ref))
 {
-/*	if ($result)
-	{
-		if ($action <> 'edit' && $action <> 'search' && $action <> 're-edit')
-		{
-			// mode visu
-
-			print '<table class="border" width="100%">';
-
-			print "<tr>";
-
-			$nblignes=6;
-			if ($product->isproduct() && ! empty($conf->stock->enabled)) $nblignes++;
-			if ($product->isservice()) $nblignes++;
-
-			// Reference
-			print '<td width="25%">'.$langs->trans("Ref").'</td><td>';
-			print $form->showrefnav($product,'ref','',1,'ref');
-			print '</td></tr>';
-
-			// Libelle
-			print '<tr><td>'.$langs->trans("Label").'</td><td>'.$product->libelle.'</td>';
-			print '</tr>';
-
-			// Number of subproducts
-			$prodsfather = $product->getFather(); // Parent Products
-			$product->get_sousproduits_arbo();
-			$prods_arbo=$product->get_arbo_each_prod();
-			$nbofsubproducts=count($prods_arbo);
-			print '<tr><td>'.$langs->trans("AssociatedProductsNumber").'</td><td>';
-			print $form->textwithpicto($nbofsubproducts, $langs->trans('IfZeroItIsNotAVirtualProduct'));
-			print '</td>';
-
-			dol_fiche_end();
-
-
-			// List of products into this virtual product
-			if (count($prods_arbo) > 0)
-			{
-				print '<tr><td colspan="2">';
-				print '<b>'.$langs->trans("ProductAssociationList").'</b><br>';
-				print '<table class="nobordernopadding">';
-				foreach($prods_arbo as $value)
-				{
-					$productstatic->id=$value['id'];
-					$productstatic->type=$value['type'];
-					$productstatic->ref=$value['fullpath'];
-					if (! empty($conf->stock->enabled)) $productstatic->load_stock();
-					//var_dump($value);
-					//print '<pre>'.$productstatic->ref.'</pre>';
-					//print $productstatic->getNomUrl(1).'<br>';
-					//print $value[0];	// This contains a tr line.
-					print '<tr>';
-					//print '<td>'.$productstatic->getNomUrl(1,'composition').' ('.$value['nb'].($value['nb_total'] > $value['nb']?'->'.$value['nb_total']:'').') &nbsp &nbsp</td>';
-					print '<td>'.$productstatic->getNomUrl(1,'composition').' ('.$value['nb'].') &nbsp &nbsp</td>';
-					if (! empty($conf->stock->enabled)) print '<td>'.$langs->trans("Stock").' : <b>'.$productstatic->stock_reel.'</b></td>';
-					print '</tr>';
-				}
-				print '</table>';
-				print '</td></tr>';
-			}
-
-			// Number of parent virtual products
-			print '<tr><td>'.$langs->trans("ParentProductsNumber").'</td><td>';
-			print $form->textwithpicto(count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct'));
-			print '</td>';
-
-			if (count($prodsfather) > 0)
-			{
-				print '<tr><td colspan="2">';
-				print '<b>'.$langs->trans("ProductParentList").'</b><br>';
-				print '<table class="nobordernopadding">';
-				foreach($prodsfather as $value)
-				{
-					$idprod= $value["id"];
-					$productstatic->id=$idprod;// $value["id"];
-					$productstatic->type=$value["fk_product_type"];
-					$productstatic->ref=$value['label'];
-					print '<tr>';
-					print '<td>'.$productstatic->getNomUrl(1,'composition').'</td>';;
-					print '</tr>';
-				}
-				print '</table>';
-				print '</td></tr>';
-			}
-
-			print "</table>\n";
-
-			dol_fiche_end();
-		}
-	}
-*/
 	/*
 	 * Fiche en mode edition
 	 */
@@ -333,20 +255,43 @@ if ($id > 0 || ! empty($ref))
 			$atleastonenotdefined=0;
 			print '<tr><td colspan="2">';
 			print $langs->trans("ProductAssociationList").'<br>';
-			print '<table class="nobordernopadding centpercent">';
+			
+			print '<form name="formComposedProduct" action="'.$_SERVER['PHP_SELF'].'" method="post" ">';
+			print '<input type="hidden" name="action" value="save_composed_product" />';
+			print '<input type="hidden" name="id" value="'.$id.'" />';
+			
+			print '<table class="centpercent nobordernopadding">';
+			
+			print '<tr class="liste_titre"><td>'.$langs->trans('ComposedProduct').'</td><td>'.$langs->trans('Qty').'</td><td>'.$langs->trans('ComposedProductDecreaseStock').'</td><td>'.$langs->trans('MinSupplierPrice').'</td><td>'.$langs->trans('Price').'</td><td>'.$langs->trans('Stock').'</td></tr>';
+			
 			foreach($prods_arbo as $value)
 			{
 				$productstatic->id=$value['id'];
 				$productstatic->type=$value['type'];
-				//print '<pre>'.$productstatic->ref.'</pre>';
-				//print $productstatic->getNomUrl(1).'<br>';
-				//var_dump($value);
-				print '<tr>';
+				
+				$class=($class=='impair')?'pair':'impair';
+				
+				print '<tr class="'.$class.'">';
 				if ($value['level'] <= 1)
 				{
 					$notdefined=0;
 					$productstatic->ref=$value['fullpath'];
-					print '<td>'.$productstatic->getNomUrl(1,'composition').' ('.$value['nb'].')</td>';
+					$nb_of_subproduct = $value['nb'];
+					
+					print '<td>'.$productstatic->getNomUrl(1,'composition').'</td>';
+					
+					if($user->rights->produit->creer || $user->rights->service->creer) {
+						print '<td><input type="text" value="'.$nb_of_subproduct.'" name="TProduct['.$productstatic->id.'][qty]" size="4" /></td>';	
+						print '<td><input type="checkbox"  name="TProduct['.$productstatic->id.'][incdec]" value="1" '.($value['incdec']==1?'checked="checked"':''  ).' /></td>';
+					
+					}
+					else{
+						print '<td>'.$nb_of_subproduct.'</td>';
+						print '<td>'.($value['incdec']==1?'x':''  ).'</td>';
+					}
+					
+					
+					
 					print '<td align="right">';
 					if ($product_fourn->find_min_price_product_fournisseur($productstatic->id) > 0)
 					{
@@ -367,26 +312,35 @@ if ($id > 0 || ! empty($ref))
 					{
 						print ' &nbsp; &nbsp; ';
 					}
-					print $productstatic->getNomUrl(1,'composition').' ('.$value['nb'].')</td>';
-					print '<td><td>';
-					print '<td><td>';
+					print $productstatic->getNomUrl(1,'composition').'</td>';
+					print '<td>'.$value['nb'].'</td>';
+					print '<td>&nbsp;</td>';
+					print '<td>&nbsp;<td>';
+					print '<td>&nbsp;<td>';
 					if (! empty($conf->stock->enabled)) print '<td align="right"></td>';	// Real stock
 				}
 				print '</tr>';
 			}
-			print '<tr>';
-			print '<td colspan="2">'.$langs->trans("TotalBuyingPriceMin").': ';
+			print '<tr class="liste_total">';
+			print '<td colspan="3" align="right">'.$langs->trans("TotalBuyingPriceMin").': ';
 			if ($atleastonenotdefined) print $langs->trans("Unknown").' ('.$langs->trans("SomeSubProductHaveNoPrices").')';
 			print '</td>';
-			print '<td align="right">'.($atleastonenotdefined?'':price($total,'','',0,0,-1,$conf->currency)).'</td>';
+			print '<td align="right" class="liste_total">'.($atleastonenotdefined?'':price($total,'','',0,0,-1,$conf->currency)).'</td>';
 			if (! empty($conf->stock->enabled)) print '<td class="liste_total" align="right">&nbsp;</td>';
 			print '</tr>';
 			print '</table>';
+			
+			if($user->rights->produit->creer || $user->rights->service->creer) {
+				print '<div class="tabsAction"><input type="submit" value="'.$langs->trans('Save').'" /></div>';
+			}
+			
+			print '</form>';
+			
 			print '</td></tr>';
 		}
 
 		// Number of parent virtual products
-		print '<tr><td>'.$langs->trans("ParentProductsNumber").'</td><td>';
+		print '<tr class="pair"><td>'.$langs->trans("ParentProductsNumber").'</td><td>';
 		print $form->textwithpicto(count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct'));
 		print '</td>';
 
diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php
index f175d75db6fb29a65eadeb8cfbb927dcaa36a871..39dd2ff5f673bbbbea4bcf52d77d1638759380ef 100644
--- a/htdocs/product/stock/class/mouvementstock.class.php
+++ b/htdocs/product/stock/class/mouvementstock.class.php
@@ -292,7 +292,7 @@ class MouvementStock extends CommonObject
 		}
 
 		// Add movement for sub products (recursive call)
-		if (! $error && ! empty($conf->global->PRODUIT_SOUSPRODUITS))
+		if (! $error && ! empty($conf->global->PRODUIT_SOUSPRODUITS) && empty($conf->global->INDEPENDANT_SUBPRODUCT_STOCK))
 		{
 			$error = $this->_createSubProduct($user, $fk_product, $entrepot_id, $qty, $type, 0, $label, $inventorycode);	// we use 0 as price, because pmp is not changed for subproduct
 		}
@@ -341,8 +341,7 @@ class MouvementStock extends CommonObject
 		$sql = "SELECT fk_product_pere, fk_product_fils, qty";
 		$sql.= " FROM ".MAIN_DB_PREFIX."product_association";
 		$sql.= " WHERE fk_product_pere = ".$idProduct;
-		// TODO Select only subproduct with incdec tag
-		//$sql.= " AND incdec = 1";
+		$sql.= " AND incdec = 1";
 
 		dol_syslog(get_class($this)."::_createSubProduct", LOG_DEBUG);
 		$resql=$this->db->query($sql);