diff --git a/htdocs/html.form.class.php b/htdocs/html.form.class.php
index fe112f366d0..d70c855db57 100644
--- a/htdocs/html.form.class.php
+++ b/htdocs/html.form.class.php
@@ -686,9 +686,10 @@ class Form
* \param filtertype Filter on product type (''=nofilter, 0=product, 1=service)
* \param limit Limite sur le nombre de lignes retournées
* \param price_level Niveau de prix en fonction du client
- * \param status -1=Return all products, 0=Products not on sell, 1=Products on sell
+ * \param status -1=Return all products, 0=Products not on sell, 1=Products on sell
+ * \param finished 2=all, 1=finished, 0=raw material
*/
- function select_produits($selected='',$htmlname='productid',$filtertype='',$limit=20,$price_level=0,$status=1)
+ function select_produits($selected='',$htmlname='productid',$filtertype='',$limit=20,$price_level=0,$status=1,$finished=2)
{
global $langs,$conf;
@@ -705,13 +706,13 @@ class Form
print '';
print '
';
print '';
- print ajax_updater($htmlname,'keysearch','/product/ajaxproducts.php','&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status,'');
+ print ajax_updater($htmlname,'keysearch','/product/ajaxproducts.php','&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status.'&finished='.$finished,'');
print ' ';
print '';
}
else
{
- $this->select_produits_do($selected,$htmlname,$filtertype,$limit,$price_level,'',$status);
+ $this->select_produits_do($selected,$htmlname,$filtertype,$limit,$price_level,'',$status,$finished);
}
}
@@ -725,7 +726,7 @@ class Form
* \param ajaxkeysearch Filtre des produits si ajax est utilisé
* \param status -1=Return all products, 0=Products not on sell, 1=Products on sell
*/
- function select_produits_do($selected='',$htmlname='productid',$filtertype='',$limit=20,$price_level=0,$ajaxkeysearch='',$status=1)
+ function select_produits_do($selected='',$htmlname='productid',$filtertype='',$limit=20,$price_level=0,$ajaxkeysearch='',$status=1,$finished=2)
{
global $langs,$conf,$user;
@@ -741,7 +742,19 @@ class Form
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie as c ON cp.fk_categorie = c.rowid";
}
- if ($status >= 0) $sql.= " WHERE p.envente = ".$status;
+ if($finished == 0)
+ {
+ $sql.= " WHERE p.finished = ".$finished;
+ }
+ elseif($finished == 1)
+ {
+ $sql.= " WHERE p.finished = ".$finished;
+ if ($status >= 0) $sql.= " AND p.envente = ".$status;
+ }
+ elseif($status >= 0)
+ {
+ $sql.= " WHERE p.envente = ".$status;
+ }
else $sql.= " WHERE 1 = 1";
if ($conf->categorie->enabled && ! $user->rights->categorie->voir)
{
diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
index 501c277a613..de9795ab905 100644
--- a/htdocs/langs/en_US/products.lang
+++ b/htdocs/langs/en_US/products.lang
@@ -136,4 +136,6 @@ RecordedProductsAndServices=Products/services recorded
GenerateThumb=Generate thumb
ProductCanvasAbility=Use special "canvas" addons
ServiceNb=Service #%s
-ListProductByPopularity=List of products/services by popularity
\ No newline at end of file
+ListProductByPopularity=List of products/services by popularity
+Finished=Manufactured product
+RowMaterial=First material
\ No newline at end of file
diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang
index 77f08cfc80a..3af1a9117c3 100644
--- a/htdocs/langs/fr_FR/products.lang
+++ b/htdocs/langs/fr_FR/products.lang
@@ -138,4 +138,6 @@ RecordedProductsAndServices=Produits/services en vente
GenerateThumb=Générer la vignette
ProductCanvasAbility=Utiliser les extensions speciales "canvas"
ServiceNb=Service no %s
-ListProductByPopularity=Liste des produits/services par popularité
\ No newline at end of file
+ListProductByPopularity=Liste des produits/services par popularité
+Finished=Produit manufacturé
+RowMaterial=Matière première
\ No newline at end of file
diff --git a/htdocs/product.class.php b/htdocs/product.class.php
index f2cf977e7f8..d3597a8f44a 100644
--- a/htdocs/product.class.php
+++ b/htdocs/product.class.php
@@ -71,6 +71,8 @@ class Product extends CommonObject
var $duration_unit;
// Statut indique si le produit est en vente '1' ou non '0'
var $status;
+ // Statut indique si le produit est un produit finis '1' ou une matiere premi�re '0'
+ var $finished;
//! Unites de mesure
var $weight;
@@ -118,6 +120,7 @@ class Product extends CommonObject
$this->db = $DB;
$this->id = $id ;
$this->status = 0;
+ $this->finished = 1;
$this->stock_reel = 0;
$this->seuil_stock_alerte = 0;
@@ -167,7 +170,8 @@ class Product extends CommonObject
if ($this->price=='') $this->price = 0;
if ($this->price_min=='') $this->price_min = 0;
if ($this->status=='') $this->status = 0;
-
+ if ($this->finished=='') $this->finished = 1;
+
$price_ht=0;
$price_ttc=0;
$price_min_ht=0;
@@ -222,7 +226,7 @@ class Product extends CommonObject
if ($this->ref) $sql.= "ref, ";
$sql.= "price_min, price_min_ttc, ";
$sql.= "label, ";
- $sql.= "fk_user_author, fk_product_type, price, price_ttc, price_base_type, canvas)";
+ $sql.= "fk_user_author, fk_product_type, price, price_ttc, price_base_type, canvas, finished)";
$sql.= " VALUES (".$this->db->idate(mktime()).", ";
if ($this->ref) $sql.= "'".$this->ref."',";
$sql.= price2num($price_min_ht).",";
@@ -233,7 +237,8 @@ class Product extends CommonObject
$sql.= price2num($price_ht).",";
$sql.= price2num($price_ttc).",";
$sql.= "'".$this->price_base_type."',";
- $sql.= "'".$this->canvas."')";
+ $sql.= "'".$this->canvas."',";
+ $sql.= " ".$this->finished.")";
dolibarr_syslog("Product::Create sql=".$sql);
$result = $this->db->query($sql);
@@ -372,6 +377,7 @@ class Product extends CommonObject
if ($this->ref) $sql .= ",ref = '" . $this->ref ."'";
$sql .= ",tva_tx = " . $this->tva_tx;
$sql .= ",envente = " . $this->status;
+ $sql .= ",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 .= ",volume = " . ($this->volume!='' ? "'".$this->volume."'" : 'null');
@@ -951,7 +957,7 @@ class Product extends CommonObject
$sql = "SELECT rowid, ref, label, description, note, price, price_ttc, price_min, price_min_ttc, price_base_type, tva_tx, envente,";
$sql.= " fk_product_type, duration, seuil_stock_alerte,canvas,";
- $sql.= " stock_commande, stock_loc, weight, weight_units, volume, volume_units, barcode, fk_barcode_type";
+ $sql.= " stock_commande, stock_loc, weight, weight_units, volume, volume_units, barcode, fk_barcode_type, finished";
$sql.= " FROM ".MAIN_DB_PREFIX."product";
if ($id) $sql.= " WHERE rowid = '".$id."'";
if ($ref) $sql.= " WHERE ref = '".addslashes($ref)."'";
@@ -975,6 +981,7 @@ class Product extends CommonObject
$this->tva_tx = $result["tva_tx"];
$this->type = $result["fk_product_type"];
$this->status = $result["envente"];
+ $this->finished = $result["finished"];
$this->duration = $result["duration"];
$this->duration_value = substr($result["duration"],0,strlen($result["duration"])-1);
$this->duration_unit = substr($result["duration"],-1);
@@ -2152,6 +2159,21 @@ class Product extends CommonObject
}
return $langs->trans('Unknown');
}
+
+
+ /**
+ * \brief Retourne le libell� du finished du produit
+ * \return string Libelle
+ */
+ function getLibFinished()
+ {
+ global $langs;
+ $langs->load('products');
+
+ if ($this->finished == '0') return $langs->trans("RowMaterial");
+ if ($this->finished == '1') return $langs->trans("Finished");
+ return '';
+ }
/**
* \brief Entre un nombre de piece du produit en stock dans un entrep�t
diff --git a/htdocs/product/fiche.php b/htdocs/product/fiche.php
index 7b5900e3d96..e078fc9b01f 100644
--- a/htdocs/product/fiche.php
+++ b/htdocs/product/fiche.php
@@ -104,6 +104,7 @@ if ($_POST["action"] == 'add' && $user->rights->produit->creer)
$product->weight_units = $_POST["weight_units"];
$product->volume = $_POST["volume"];
$product->volume_units = $_POST["volume_units"];
+ $product->finished = $_POST["finished"];
// MultiPrix
if($conf->global->PRODUIT_MULTIPRICES == 1)
{
@@ -166,6 +167,7 @@ $user->rights->produit->creer)
$product->weight_units = $_POST["weight_units"];
$product->volume = $_POST["volume"];
$product->volume_units = $_POST["volume_units"];
+ $product->finished = $_POST["finished"];
if ($product->check())
{
@@ -214,6 +216,7 @@ if ($_GET["action"] == 'clone' && $user->rights->produit->creer)
{
$product->ref = "Clone ".$product->ref;
$product->status = 0;
+ $product->finished = 1;
$product->id = null;
if ($product->check())
@@ -225,7 +228,7 @@ if ($_GET["action"] == 'clone' && $user->rights->produit->creer)
$db->commit();
$db->close();
-
+
Header("Location: fiche.php?id=$id");
exit;
}
@@ -234,10 +237,10 @@ if ($_GET["action"] == 'clone' && $user->rights->produit->creer)
if ($product->error == 'ErrorProductAlreadyExists')
{
$db->rollback();
-
+
$_error = 1;
$_GET["action"] = "";
-
+
$mesg=''.$langs->trans("ErrorProductAlreadyExists",$product->ref).'
';
//dolibarr_print_error($product->db);
}
@@ -630,6 +633,16 @@ if ($_GET["action"] == 'create' && $user->rights->produit->creer)
print "";
+ // Nature
+ if ($_GET["type"] != 1)
+ {
+ print ''.$langs->trans("Nature").' ';
+ $statutarray=array('1' => $langs->trans("Finished"), '0' => $langs->trans("RowMaterial"));
+ $html->select_array('finished',$statutarray,$_POST["finished"]);
+ print ' ';
+ }
+
+ //Duration
if ($_GET["type"] == 1)
{
print ''.$langs->trans("Duration").' ';
@@ -640,7 +653,9 @@ if ($_GET["action"] == 'create' && $user->rights->produit->creer)
print ' '.$langs->trans("Year").' ';
print ' ';
}
- else
+
+ // Weight - Volume
+ if ($_GET["type"] != 1)
{
// Le poids et le volume ne concerne que les produits et pas les services
print ''.$langs->trans("Weight").' ';
@@ -699,7 +714,7 @@ if ($_GET["action"] == 'create' && $user->rights->produit->creer)
print ' '.$langs->trans("MinPrice").' ';
print ' ';
print ' ';
-
+
// VAT
print ''.$langs->trans("VATRate").' ';
print $html->select_tva("tva_tx",$conf->defaulttx,$mysoc,'');
@@ -883,7 +898,7 @@ if ($_GET["id"] || $_GET["ref"])
}
print ' ';
}
-
+
// Prix mini
print ''.$langs->trans("MinPrice").' ';
if ($product->price_base_type == 'TTC')
@@ -903,10 +918,18 @@ if ($_GET["id"] || $_GET["ref"])
print ' '.$langs->trans("Status").' ';
print $product->getLibStatut(2);
print ' ';
-
+
// Description
print ''.$langs->trans("Description").' '.nl2br($product->description).' ';
+ // Nature
+ if($product->type!=1)
+ {
+ print ''.$langs->trans("Nature").' ';
+ print $product->getLibFinished();
+ print ' ';
+ }
+
if ($product->isservice())
{
// Duration
@@ -936,7 +959,7 @@ if ($_GET["id"] || $_GET["ref"])
print ' ';
}
print "\n";
-
+
print ''.$langs->trans("Volume").' ';
if ($product->volume != '')
{
@@ -948,7 +971,7 @@ if ($_GET["id"] || $_GET["ref"])
}
print " \n";
}
-
+
// Note
print ''.$langs->trans("Note").' '.nl2br($product->note).' ';
@@ -998,18 +1021,7 @@ if ($_GET["id"] || $_GET["ref"])
}
print '';
print '';
-
- if ($product->isproduct() && $conf->stock->enabled)
- {
- print "".''.$langs->trans("StockLimit").' ';
- print ' ';
- print ' ';
- }
- else
- {
- print ' ';
- }
-
+
// Description (utilisé dans facture, propale...)
print ''.$langs->trans("Description").' ';
print "\n";
@@ -1028,6 +1040,26 @@ if ($_GET["id"] || $_GET["ref"])
print " ";
print "\n";
+ // Nature
+ if($product->type!=1)
+ {
+ print ''.$langs->trans("Nature").' ';
+ $statutarray=array('-1'=>' ', '1' => $langs->trans("Finished"), '0' => $langs->trans("RowMaterial"));
+ $html->select_array('finished',$statutarray,$product->finished);
+ print ' ';
+ }
+
+ if ($product->isproduct() && $conf->stock->enabled)
+ {
+ print "".''.$langs->trans("StockLimit").' ';
+ print ' ';
+ print ' ';
+ }
+ else
+ {
+ print ' ';
+ }
+
if ($product->isservice())
{
// Duration
diff --git a/htdocs/product/stock/mouvementstock.class.php b/htdocs/product/stock/mouvementstock.class.php
index aa1cf8bb44c..7b9bbb5c18f 100644
--- a/htdocs/product/stock/mouvementstock.class.php
+++ b/htdocs/product/stock/mouvementstock.class.php
@@ -201,6 +201,46 @@ class MouvementStock
/**
+ * \brief Crée un mouvement en base pour toutes les compositions de produits
+ * \return int <0 si ko, 0 si ok
+ */
+ function _createProductComposition($user, $fk_product, $entrepot_id, $qty, $type, $price=0)
+ {
+
+
+ dolibarr_syslog("MouvementStock::_createComposition $user->id, $fk_product, $entrepot_id, $qty, $type, $price");
+ $products_compo = array();
+
+ $sql = "SELECT fk_product_composition, qte, etat_stock";
+ $sql.= " FROM ".MAIN_DB_PREFIX."product_composition";
+ $sql.= " WHERE fk_product = $fk_product;";
+
+ $all = $this->db->query($sql);
+
+ if ($all)
+ {
+ while($item = $this->db->fetch_object($all) )
+ {
+ if($item->etat_stock != 0) array_push($products_compo,$item);
+ }
+ $this->db->free($resql);
+ }
+ else
+ {
+ dolibarr_syslog("MouvementStock::_Create echec update ".$this->error);
+ return -1;
+ }
+
+ foreach($products_compo as $product)
+ {
+ $this->_create($user, $product->fk_product_composition, $entrepot_id, ($qty*$product->qte), $type, $price=0);
+ }
+
+ return 0;
+ }
+
+
+ /**
* \brief Calcul ???
* \return int <0 si ko, >0 si ok
*/
diff --git a/mysql/migration/2.4.0-2.5.0.sql b/mysql/migration/2.4.0-2.5.0.sql
index c3ac4686d36..38455b36f59 100644
--- a/mysql/migration/2.4.0-2.5.0.sql
+++ b/mysql/migration/2.4.0-2.5.0.sql
@@ -8,6 +8,7 @@
alter table llx_product add column price_min double(24,8) DEFAULT 0;
alter table llx_product add column price_min_ttc double(24,8) DEFAULT 0;
+alter table llx_product add column finished tinyint DEFAULT NULL after canvas;
alter table llx_product_price add column price_min double(24,8) default NULL;
alter table llx_product_price add column price_min_ttc double(24,8) default NULL;
diff --git a/mysql/tables/llx_product.sql b/mysql/tables/llx_product.sql
index f9ef57974fc..3d4ee54ba4e 100644
--- a/mysql/tables/llx_product.sql
+++ b/mysql/tables/llx_product.sql
@@ -1,5 +1,6 @@
-- ============================================================================
-- Copyright (C) 2002-2006 Rodolphe Quiedeville
+-- Copyright (C) 2008 Laurent Destailleur
--
-- 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
@@ -49,6 +50,7 @@ create table llx_product
volume float DEFAULT NULL,
volume_units tinyint DEFAULT NULL,
canvas varchar(15) DEFAULT '',
+ finished tinyint DEFAULT NULL,
import_key varchar(14)
)type=innodb;