diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php
index 5b43a9b120a..1f261b1a1a8 100644
--- a/htdocs/admin/stock.php
+++ b/htdocs/admin/stock.php
@@ -19,10 +19,10 @@
/**
\file htdocs/admin/stock.php
- \ingroup stock
- \brief Page d'administration/configuration du module gestion de stock
- \version $Id$
-*/
+ \ingroup stock
+ \brief Page d'administration/configuration du module gestion de stock
+ \version $Id$
+ */
require("./pre.inc.php");
require_once(DOL_DOCUMENT_ROOT."/lib/admin.lib.php");
@@ -30,32 +30,32 @@ $langs->load("admin");
$langs->load("stocks");
if (!$user->admin)
- accessforbidden();
+accessforbidden();
/*
-* Actions
-*/
+ * Actions
+ */
if ($_POST["action"] == 'stock_userstock')
{
- dolibarr_set_const($db, "STOCK_USERSTOCK", $_POST["stock_userstock"]);
- //On d�sactive l'autocr�ation si l'option "stock personnel" est d�sactiv�e
- if ($_POST["stock_userstock"] == 0)
- {
- dolibarr_set_const($db, "STOCK_USERSTOCK_AUTOCREATE", 0);
- }
- Header("Location: stock.php");
- exit;
+ dolibarr_set_const($db, "STOCK_USERSTOCK", $_POST["stock_userstock"]);
+ //On d�sactive l'autocr�ation si l'option "stock personnel" est d�sactiv�e
+ if ($_POST["stock_userstock"] == 0)
+ {
+ dolibarr_set_const($db, "STOCK_USERSTOCK_AUTOCREATE", 0);
+ }
+ Header("Location: stock.php");
+ exit;
}
elseif ($_POST["action"] == 'stock_userstock_autocreate')
{
- dolibarr_set_const($db, "STOCK_USERSTOCK_AUTOCREATE", $_POST["stock_userstock_autocreate"]);
- Header("Location: stock.php");
- exit;
+ dolibarr_set_const($db, "STOCK_USERSTOCK_AUTOCREATE", $_POST["stock_userstock_autocreate"]);
+ Header("Location: stock.php");
+ exit;
}
-// Mode of stock changement
+// Mode of stock changement
elseif ( $_POST["action"] == 'stock_bill'
- || $_POST["action"] == 'stock_validateorder'
- || $_POST["action"] == 'stock_shipment')
+|| $_POST["action"] == 'stock_validateorder'
+|| $_POST["action"] == 'stock_shipment')
{
$count=0;
$db->begin();
@@ -68,15 +68,15 @@ elseif ( $_POST["action"] == 'stock_bill'
if ($count == 4)
{
$db->commit();
- Header("Location: stock.php");
- exit;
+ Header("Location: stock.php");
+ exit;
}
else
- {
+ {
$db->rollback();
- dolibarr_print_error("Error in some requests", LOG_ERR);
+ dolibarr_print_error("Error in some requests", LOG_ERR);
}
-}
+}
@@ -116,25 +116,26 @@ print "\n\n\n";
if ($conf->global->STOCK_USERSTOCK == 1)
{
- $var=!$var;
+ $var=!$var;
- print "
';
print '';
@@ -336,11 +336,12 @@ if ($_GET["id"] > 0)
*/
print '';
- $sql = "SELECT cd.rowid, cd.fk_product, cd.description, cd.price, cd.qty, cd.tva_tx, cd.subprice";
+ $sql = "SELECT cd.fk_product, cd.description, cd.price, sum(cd.qty) as qty, cd.rowid, cd.tva_tx, cd.subprice";
$sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid";
$sql.= " WHERE cd.fk_commande = ".$commande->id;
// $sql.= " AND p.fk_product_type <> 1"; Why this line ?
+ $sql.= " group by (cd.fk_product)";
$sql.= " ORDER BY cd.rowid";
dolibarr_syslog("commande.php sql=".$sql, LOG_DEBUG);
@@ -370,7 +371,7 @@ if ($_GET["id"] > 0)
while ($i < $num)
{
$objp = $db->fetch_object($resql);
-
+
$var=!$var;
print "";
if ($objp->fk_product > 0)
@@ -390,6 +391,7 @@ if ($_GET["id"] > 0)
print '| '.$objp->qty.' | ';
+ $qtyProdCom=$objp->qty;
print '';
// Nb of sending products for this line of order
$quantite_livree = $commande->expeditions[$objp->rowid];
@@ -418,6 +420,17 @@ if ($_GET["id"] > 0)
}
print " | ";
+ // associations sous produits
+ $product->get_sousproduits_arbo ();
+ $prods_arbo = $product->get_arbo_each_prod($qtyProdCom);
+ if(sizeof($prods_arbo) > 0)
+ {
+ foreach($prods_arbo as $key => $value)
+ {
+ print $value[0];
+ }
+ }
+
$i++;
$var=!$var;
}
@@ -445,7 +458,7 @@ if ($_GET["id"] > 0)
if ($user->societe_id == 0)
{
print '';
-
+
// Bouton expedier sans gestion des stocks
if (! $conf->stock->enabled && $reste_a_livrer_total > 0 && ! $commande->brouillon && $user->rights->expedition->creer)
{
@@ -472,11 +485,11 @@ if ($_GET["id"] > 0)
$entrepot = new Entrepot($db);
$langs->load("stocks");
-
+
print ' ';
print '| '.$langs->trans("Warehouse").' | ';
print '';
-
+
if (sizeof($user->entrepots) === 1)
{
$uentrepot = array();
@@ -506,7 +519,7 @@ if ($_GET["id"] > 0)
print " | ";
print "\n";
-
+
$somethingshown=1;
}
diff --git a/htdocs/expedition/fiche.php b/htdocs/expedition/fiche.php
index 4577c3a5e8d..434499f590c 100644
--- a/htdocs/expedition/fiche.php
+++ b/htdocs/expedition/fiche.php
@@ -354,6 +354,7 @@ if ($_GET["action"] == 'create')
}
print ' | '.$ligne->qty.' | ';
+ $qtyProdCom=$ligne->qty;
print '';
$quantityDelivered = $object->expeditions[$ligne->id];
@@ -423,6 +424,7 @@ if ($_GET["action"] == 'create')
$html->select_array('entl'.$i,$array,'',1,0,0);
print ' | ';
}
+
}
else
{
@@ -435,6 +437,17 @@ if ($_GET["action"] == 'create')
print " \n";
+ // associations sous produits
+ $product->get_sousproduits_arbo ();
+ $prods_arbo = $product->get_arbo_each_prod($qtyProdCom);
+ if(sizeof($prods_arbo) > 0)
+ {
+ foreach($prods_arbo as $key => $value)
+ {
+ print $value[0];
+ }
+ }
+
$indiceAsked++;
}
@@ -448,7 +461,7 @@ if ($_GET["action"] == 'create')
}
else
{
- dolibarr_print_error($db);
+ dolibarr_print_error($db);
}
}
}
@@ -506,7 +519,7 @@ else
*/
if ($_GET["action"] == 'delete')
{
- $html->form_confirm($_SERVER['PHP_SELF'].'?id='.$expedition->id,$langs->trans('DeleteSending'),'Etes-vous sûr de vouloir supprimer cette expedition ?','confirm_delete');
+ $html->form_confirm($_SERVER['PHP_SELF'].'?id='.$expedition->id,$langs->trans('DeleteSending'),$langs->trans("ConfirmDeleteSending",$expedition->ref),'confirm_delete');
print ' ';
}
@@ -516,7 +529,7 @@ else
*/
if ($_GET["action"] == 'valid')
{
- $html->form_confirm($_SERVER['PHP_SELF'].'?id='.$expedition->id,$langs->trans('ValidateSending'),'Etes-vous sûr de vouloir valider cette expédition ?','confirm_valid');
+ $html->form_confirm($_SERVER['PHP_SELF'].'?id='.$expedition->id,$langs->trans('ValidateSending'),$langs->trans("ConfirmValidateSending",$expedition->ref),'confirm_valid');
print ' ';
}
/*
@@ -525,7 +538,7 @@ else
*/
if ($_GET["action"] == 'annuler')
{
- $html->form_confirm($_SERVER['PHP_SELF'].'?id='.$expedition->id,$langs->trans('CancelSending'),'Etes-vous sûr de vouloir annuler cette commande ?','confirm_cancel');
+ $html->form_confirm($_SERVER['PHP_SELF'].'?id='.$expedition->id,$langs->trans('CancelSending'),$langs->trans("ConfirmCancelSending",$expedition->ref),'confirm_cancel');
print ' ';
}
@@ -741,7 +754,7 @@ else
print ' ';
//show_list_sending_receive($expedition->origin,$expedition->origin_id," AND e.rowid <> ".$expedition->id);
show_list_sending_receive($expedition->origin,$expedition->origin_id);
-
+
}
else
{
diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
index ab062af0c3f..05ea0e0d68e 100644
--- a/htdocs/langs/en_US/products.lang
+++ b/htdocs/langs/en_US/products.lang
@@ -99,7 +99,7 @@ MultiPriceLevelsName=Price categories
AssociatedProductsAbility=Activate the associated products
AssociatedProducts=Associated products
AssociatedProductsNumber=Number of associated products
-EditAssociate=Associated
+EditAssociate=Associate
Translation=Translation
KeywordFilter=Keyword filter
CategoryFilter=Category filter
diff --git a/htdocs/langs/en_US/sendings.lang b/htdocs/langs/en_US/sendings.lang
index 91814da1ded..10b1ecd8068 100644
--- a/htdocs/langs/en_US/sendings.lang
+++ b/htdocs/langs/en_US/sendings.lang
@@ -34,4 +34,7 @@ SendingSheet=Sending sheet
Carriers=Carriers
Carrier=Carrier
CarriersArea=Carriers area
-NewCarrier=New carrier
\ No newline at end of file
+NewCarrier=New carrier
+ConfirmDeleteSending=Are you sure you want to delete this sending ?
+ConfirmValidateSending=Are you sure you want to valdate this sending ?
+ConfirmCancelSending=Are you sure you want to cancel this sending ?
diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang
index 9e767ed629a..c01b80ebfcf 100644
--- a/htdocs/langs/en_US/stocks.lang
+++ b/htdocs/langs/en_US/stocks.lang
@@ -38,7 +38,8 @@ EnhancedValueOfWarehouses=Warehouses value
UserWarehouseAutoCreate=Create a stock automatically when creating a user
QtyDispatched=Quantity dispatched
OrderDispatch=Order dispatching
-RuleForStockManagement=Rule for stock management
+RuleForStockManagementDecrease=Rule for stock management decrease
+RuleForStockManagementIncrease=Rule for stock management increase
DeStockReStockOnBill=Decrease/increase real stocks on invoices/credit notes (warning, in this version, it's only in warehouse number 1 that stock is modified)
DeStockReStockOnValidateOrder=Decrease/increase real stocks on orders notes (warning, in this version, it's only in warehouse number 1 that stock is modified)
DeStockReStockOnShipment=Decrease/increase real stocks on shipment (recommanded)
diff --git a/htdocs/langs/es_ES/products.lang b/htdocs/langs/es_ES/products.lang
index ba67fe2b395..0f8af1560ff 100644
--- a/htdocs/langs/es_ES/products.lang
+++ b/htdocs/langs/es_ES/products.lang
@@ -100,7 +100,7 @@ MultiPriceLevelsName=Categor
AssociatedProductsAbility=Activar productos asociados
AssociatedProducts=Productos asociados
AssociatedProductsNumber=Nº de productos asociados
-EditAssociate=Asociar a
+EditAssociate=Asociar
Translation=Traducción
KeywordFilter=Filtro por clave
CategoryFilter=Filtro por categoría
diff --git a/htdocs/langs/fr_BE/products.lang b/htdocs/langs/fr_BE/products.lang
index 4be3c3afab9..d88dbadf42c 100644
--- a/htdocs/langs/fr_BE/products.lang
+++ b/htdocs/langs/fr_BE/products.lang
@@ -89,7 +89,7 @@ MultiPriceLevelsName=Cat
AssociatedProductsAbility=Activer les produits associés
AssociatedProducts=Produits associés
AssociatedProductsNumber=Nombre de produits associés
-EditAssociate=Associé
+EditAssociate=Associer
Translation=Traduction
KeywordFilter=Filtre par mot-clé
CategoryFilter=Filtre par catégorie
diff --git a/htdocs/langs/fr_FR/orders.lang b/htdocs/langs/fr_FR/orders.lang
index 7c9a0f8c2ce..f9f7147efc2 100755
--- a/htdocs/langs/fr_FR/orders.lang
+++ b/htdocs/langs/fr_FR/orders.lang
@@ -74,7 +74,7 @@ NumberOfOrdersByMonth=Nombre de commandes par mois
AmountOfOrdersByMonthHT=Montant total de commandes par mois (HT)
ListOfOrders=Liste des commandes
CloseOrder=Cloturer commande
-ConfirmCloseOrder=Êtes-vous sur de vouloir cloturer cette commande ? Une fois une commande cloturée, elle doit être facturée.
+ConfirmCloseOrder=Êtes-vous sur de vouloir cloturer cette commande ? Une fois une commande cloturée, elle peut être facturée.
ConfirmCloseOrderIfSending=Êtes-vous sur de vouloir cloturer cette commande ? Vous ne devez cloturer une commande qu'une fois les produits expédiés.
ConfirmDeleteOrder=Êtes-vous sur de vouloir effacer cette commande ?
ConfirmValidateOrder=Êtes-vous sur de vouloir valider cette commande sous la référence %s ?
diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang
index 581593c4d03..94bd22b375f 100644
--- a/htdocs/langs/fr_FR/products.lang
+++ b/htdocs/langs/fr_FR/products.lang
@@ -103,7 +103,7 @@ MultiPriceLevelsName=Cat
AssociatedProductsAbility=Prise en charges des produits associés
AssociatedProducts=Produits associés
AssociatedProductsNumber=Nbre de produits associés
-EditAssociate=Associer au
+EditAssociate=Associer
Translation=Traduction
KeywordFilter=Filtre par mot-clé
CategoryFilter=Filtre par catégorie
diff --git a/htdocs/langs/fr_FR/sendings.lang b/htdocs/langs/fr_FR/sendings.lang
index bc218afa927..438e7af4e53 100644
--- a/htdocs/langs/fr_FR/sendings.lang
+++ b/htdocs/langs/fr_FR/sendings.lang
@@ -34,4 +34,7 @@ SendingSheet=Bordereau d'exp
Carriers=Transporteurs
Carrier=Transporteur
CarriersArea=Espace transporteurs
-NewCarrier=Nouveau transporteur
\ No newline at end of file
+NewCarrier=Nouveau transporteur
+ConfirmDeleteSending=Etes-vous sûr de vouloir supprimer cette expedition ?
+ConfirmValidateSending=Etes-vous sûr de vouloir valider cette expédition ?
+ConfirmCancelSending=Etes-vous sûr de vouloir annuler cette expédition ?
diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang
index 140d215395d..51a1a96b323 100644
--- a/htdocs/langs/fr_FR/stocks.lang
+++ b/htdocs/langs/fr_FR/stocks.lang
@@ -38,7 +38,8 @@ EnhancedValueOfWarehouses=Valorisation des stocks
UserWarehouseAutoCreate=Créer un stock automatiquement à la création d'un utilisateur
QtyDispatched=Quantité ventilée
OrderDispatch=Ventilation commande
-RuleForStockManagement=Règle de gestion de stock
+RuleForStockManagementDecrease=Règle de gestion des décrémentations de stock
+RuleForStockManagementIncrease=Règle de gestion des incrémentations de stock
DeStockReStockOnBill=Décrémente/Incrémente les stocks physiques sur les factures/avoirs (attention, dans cette version, c'est toujours dans le premier entrepot numero 1 que se fait l'ajustement)
DeStockReStockOnValidateOrder=Décrémente/Incrémente les stocks physiques sur les commandes (attention, dans cette version, c'est toujours dans le premier entrepot numero 1 que se fait l'ajustement)
DeStockReStockOnShipment=Décrémente/Incrémente les stocks physiques sur les expéditions (recommandé)
diff --git a/htdocs/langs/it_IT/stocks.lang b/htdocs/langs/it_IT/stocks.lang
index 9040e319462..b3f25a0697f 100644
--- a/htdocs/langs/it_IT/stocks.lang
+++ b/htdocs/langs/it_IT/stocks.lang
@@ -38,7 +38,7 @@ EnhancedValueOfWarehouses =Valore magazzini
UserWarehouseAutoCreate =Creare uno stock automaticamente durante la creazione di un utente
QtyDispatched =Quantità spedita
OrderDispatch =Spedizione dell'ordine
-RuleForStockManagement =Regola per gestione delle scorte
+RuleForStockManagementDecrease =Regola per gestione delle scorte
DeStockReStockOnBill =Diminuzione / aumento reale delle scorte sulle fatture / note di credito (attenzione, in questa versione, è solo nel magazzino numero 1 che viene modificata)
DeStockReStockOnValidateOrder =Diminuzione / aumento reale delle scorte per ordini note (avviso, in questa versione, è solo nel magazzino numero 1 che viene modificata)
DeStockReStockOnShipment =Diminuzione / aumento reale delle scorte sulla spedizione (Raccomandato)
diff --git a/htdocs/product.class.php b/htdocs/product.class.php
index 67a61f8329d..6cd4305d24a 100644
--- a/htdocs/product.class.php
+++ b/htdocs/product.class.php
@@ -182,7 +182,7 @@ class Product extends CommonObject
$price_ht = price2num($this->price,'MU');
$price_ttc = price2num($this->price * (1 + ($this->tva_tx / 100)),'MU');
}
-
+
if (($this->price_min_ttc > 0)&&($this->price_base_type == 'TTC'))
{
$price_min_ttc = price2num($this->price_min_ttc,'MU');
@@ -220,13 +220,13 @@ class Product extends CommonObject
$sql = "INSERT INTO ".MAIN_DB_PREFIX."product";
$sql.= " (datec, ";
if ($this->ref) $sql.= "ref, ";
- $sql.= "price_min, price_min_ttc, ";
+ $sql.= "price_min, price_min_ttc, ";
$sql.= "label, ";
$sql.= "fk_user_author, fk_product_type, price, price_ttc, price_base_type, canvas)";
$sql.= " VALUES (".$this->db->idate(mktime()).", ";
if ($this->ref) $sql.= "'".$this->ref."',";
- $sql.= price2num($price_min_ht).",";
- $sql.= price2num($price_min_ttc).",";
+ $sql.= price2num($price_min_ht).",";
+ $sql.= price2num($price_min_ttc).",";
$sql.= " ".($this->libelle?"'".addslashes($this->libelle)."'":"null").",";
$sql.= $user->id.",";
$sql.= " ".$this->type.",";
@@ -248,7 +248,7 @@ class Product extends CommonObject
$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)
{
@@ -509,7 +509,7 @@ class Product extends CommonObject
$sqlb = "DELETE from ".MAIN_DB_PREFIX."product_price";
$sqlb.= " WHERE fk_product = ".$id;
$resultb = $this->db->query($sqlb);
-
+
$sqlb = "DELETE from ".MAIN_DB_PREFIX."product_price_min";
$sqlb.= " WHERE fk_product = ".$id;
$resultb = $this->db->query($sqlb);
@@ -699,7 +699,7 @@ class Product extends CommonObject
else
{
$queryError = false;
-
+
// On ajoute nouveau tarif
$sql = "INSERT INTO ".MAIN_DB_PREFIX."product_price(date_price,fk_product,fk_user_author,price,price_ttc,price_base_type,envente,tva_tx,price_min,price_min_ttc) ";
$sql.= " VALUES(".$this->db->idate(mktime()).",".$this->id.",".$user->id.",".$this->price.",".$this->price_ttc.",'".$this->price_base_type."',".$this->status.",".$this->tva_tx;
@@ -709,8 +709,8 @@ class Product extends CommonObject
dolibarr_syslog("Product::_log_price sql=".$sql);
$resql=$this->db->query($sql);
if (!$resql)
- $queryError = true;
-
+ $queryError = true;
+
if($queryError)
{
dolibarr_print_error($this->db);
@@ -718,8 +718,8 @@ class Product extends CommonObject
}
else
return 1;
-
-
+
+
}
}
@@ -825,7 +825,7 @@ class Product extends CommonObject
$price_ttc = price2num($newprice,'MU');
$price = price2num($newprice) / (1 + ($newvat / 100));
$price = price2num($price,'MU');
-
+
if($newminprice!=''){
$price_min_ttc = price2num($newminprice,'MU');
$price_min = price2num($newminprice) / (1 + ($newvat / 100));
@@ -837,7 +837,7 @@ class Product extends CommonObject
$price = price2num($newprice,'MU');
$price_ttc = price2num($newprice) * (1 + ($newvat / 100));
$price_ttc = price2num($price_ttc,'MU');
-
+
if($newminprice!=''){
$price_min = price2num($newminprice,'MU');
$price_min_ttc = price2num($newminprice) * (1 + ($newvat / 100));
@@ -852,7 +852,7 @@ class Product extends CommonObject
$sql.= " price=".$price.",";
$sql.= " price_ttc=".$price_ttc.",";
$sql.= " price_min=".$price_min.",";
- $sql.= " price_min_ttc=".$price_min_ttc.",";
+ $sql.= " price_min_ttc=".$price_min_ttc.",";
$sql.= " tva_tx='".price2num($newvat)."'";
$sql.= " WHERE rowid = " . $id;
@@ -1043,9 +1043,9 @@ class Product extends CommonObject
}
}
- }
+ }
- $res=$this->load_stock();
+ $res=$this->load_stock();
return $res;
}
@@ -1099,7 +1099,7 @@ class Product extends CommonObject
/**
* \brief Charge tableau des stats commande client pour le produit/service
- * \param socid Id societe pour filtrer sur une soci�t�
+ * \param socid Id societe pour filtrer sur une societe
* \param filtrestatut Id statut pour filtrer sur un statut
* \return array Tableau des stats
*/
@@ -1184,6 +1184,50 @@ class Product extends CommonObject
}
}
+ /**
+ * \brief Charge tableau des stats expedition client pour le produit/service
+ * \param socid Id societe pour filtrer sur une societe
+ * \param filtrestatut Id statut pour filtrer sur un statut
+ * \return array Tableau des stats
+ */
+ function load_stats_sending($socid=0,$filtrestatut='')
+ {
+ global $conf,$user;
+
+ $sql = "SELECT COUNT(DISTINCT c.fk_soc) as nb_customers, COUNT(DISTINCT c.rowid) as nb,";
+ $sql.= " COUNT(ed.rowid) as nb_rows, SUM(ed.qty) as qty";
+ $sql.= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed, ".MAIN_DB_PREFIX."commandedet as cd,";
+ $sql.= " ".MAIN_DB_PREFIX."expedition as c";
+ if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql.= " WHERE c.rowid = ed.fk_expedition AND ed.fk_origin_line = cd.rowid AND cd.fk_product = ".$this->id;
+ if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND c.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id;
+ if ($socid > 0)
+ {
+ $sql.= " AND c.fk_soc = ".$socid;
+ }
+
+ if ($filtrestatut <> '')
+ {
+ $sql.= " AND c.fk_statut in (".$filtrestatut.")";
+ }
+
+ $result = $this->db->query($sql) ;
+ if ( $result )
+ {
+ $obj=$this->db->fetch_object($result);
+ $this->stats_expedition['customers']=$obj->nb_customers;
+ $this->stats_expedition['nb']=$obj->nb;
+ $this->stats_expedition['rows']=$obj->nb_rows;
+ $this->stats_expedition['qty']=$obj->qty?$obj->qty:0;
+ return 1;
+ }
+ else
+ {
+ $this->error=$this->db->error();
+ return -1;
+ }
+ }
+
/**
* \brief Charge tableau des stats contrat pour le produit/service
* \param socid Id societe
@@ -1810,29 +1854,55 @@ class Product extends CommonObject
$db->commit();
return 1;
}
+
/**
- * \brief fonction r�cursive uniquement utilis�e par get_arbo_each_prod, recompose l'arborescence des sousproduits
+ * \brief fonction recursive uniquement utilisee par get_arbo_each_prod, recompose l'arborescence des sousproduits
* \return void
*/
- function fetch_prod_arbo($prod,$compl_path="")
+ function fetch_prod_arbo($prod,$compl_path="",$multiply="")
{
+ global $langs;
+
$this->res;
$this->pere_encours;
foreach($prod as $nom_pere => $desc_pere)
{
- // on est dans une sous-cat�gorie
+ // on est dans une sous-categorie
if(is_array($desc_pere))
- $this->res[]= array($compl_path.stripslashes($nom_pere)." (".$desc_pere[1].")",$desc_pere[0]);
- else if($nom_pere != "0" && $nom_pere != "1")
- $this->res[]= array($compl_path.stripslashes($nom_pere),$desc_pere);
- if(sizeof($desc_pere) >1)
- {
- $this ->fetch_prod_arbo($desc_pere,stripslashes($nom_pere)." -> ");
- }
+ {
+ if($multiply)
+ {
+ $img="";
+ $trueValue=$desc_pere[1]*$multiply;
+ $product = new Product($this->db);
+ $this->fetch($desc_pere[0]);
+ $this->load_stock();
+ if ($this->stock_entrepot[1] < $this->seuil_stock_alerte)
+ {
+ $img=img_warning($langs->trans("StockTooLow"));
+ }
+ $this->res[]= array("|
+ ".$compl_path.stripslashes($nom_pere)."
+ | ".$trueValue." |   |   |
+ ".$this->stock_entrepot[1]." ".$img." | ",
+ $desc_pere[0]);
+ }
+ else
+ {
+ $this->res[]= array($compl_path.$nom_pere." (".$desc_pere[1].")",$desc_pere[0]);
+ }
+ }
+ else if($nom_pere != "0" && $nom_pere != "1")
+ $this->res[]= array($compl_path.$nom_pere,$desc_pere);
+ if(sizeof($desc_pere) >1)
+ {
+ $this ->fetch_prod_arbo($desc_pere,$nom_pere." -> ");
+ }
}
}
+
/**
- * \brief fonction r�cursive uniquement utilis�e par get_each_prod, ajoute chaque sousproduits dans le tableau res
+ * \brief fonction recursive uniquement utilisee par get_each_prod, ajoute chaque sousproduits dans le tableau res
* \return void
*/
function fetch_prods($prod)
@@ -1840,34 +1910,35 @@ class Product extends CommonObject
$this->res;
foreach($prod as $nom_pere => $desc_pere)
{
- // on est dans une sous-cat�gorie
+ // on est dans une sous-categorie
if(is_array($desc_pere))
- $this->res[]= array($desc_pere[1],$desc_pere[0]);
- if(sizeof($desc_pere) >1)
- {
- $this ->fetch_prods($desc_pere);
- }
+ $this->res[]= array($desc_pere[1],$desc_pere[0]);
+ if(sizeof($desc_pere) >1)
+ {
+ $this ->fetch_prods($desc_pere);
+ }
}
}
+
/**
- * \brief reconstruit l'arborescence des cat�gorie sous la forme d'un tableau
+ * \brief reconstruit l'arborescence des categorie sous la forme d'un tableau
* \return array $this->res
*/
- function get_arbo_each_prod()
+ function get_arbo_each_prod($multiply="")
{
$this->res = array();
if(is_array($this -> sousprods))
{
foreach($this -> sousprods as $nom_pere => $desc_pere)
- {
- if(sizeof($desc_pere) >1)
- $this ->fetch_prod_arbo($desc_pere);
-
- }
- sort($this->res);
+ {
+ if(sizeof($desc_pere) >1)
+ $this ->fetch_prod_arbo($desc_pere,"",$multiply);
+ }
+ sort($this->res);
}
return $this->res;
}
+
/**
* \brief renvoie tous les sousproduits dans le tableau res, chaque ligne de res contient : id -> qty
* \return array $this->res
@@ -1878,12 +1949,12 @@ class Product extends CommonObject
if(is_array($this -> sousprods))
{
foreach($this -> sousprods as $nom_pere => $desc_pere)
- {
- if(sizeof($desc_pere) >1)
- $this ->fetch_prods($desc_pere);
+ {
+ if(sizeof($desc_pere) >1)
+ $this ->fetch_prods($desc_pere);
- }
- sort($this->res);
+ }
+ sort($this->res);
}
return $this->res;
}
diff --git a/htdocs/product/sousproduits/fiche.php b/htdocs/product/sousproduits/fiche.php
index f211a5c77d6..d7b447966db 100644
--- a/htdocs/product/sousproduits/fiche.php
+++ b/htdocs/product/sousproduits/fiche.php
@@ -31,7 +31,7 @@ require("./pre.inc.php");
require_once(DOL_DOCUMENT_ROOT."/lib/product.lib.php");
require_once(DOL_DOCUMENT_ROOT."/product.class.php");
require_once(DOL_DOCUMENT_ROOT."/categories/categorie.class.php");
-
+
$langs->load("bills");
$langs->load("products");
@@ -44,55 +44,55 @@ $action=isset($_GET["action"])?$_GET["action"]:$_POST["action"];
$cancel=isset($_GET["cancel"])?$_GET["cancel"]:$_POST["cancel"];
if ($action <> 're-edit')
- {
- $product = new Product($db);
- if ($id) $result = $product->fetch($id);
- if ($ref) $result = $product->fetch($ref);
- if ($_GET["ref"]) $result = $product->fetch('',$_GET["ref"]);
- if ($_GET["id"]) $result = $product->fetch($_GET["id"]);
- }
+{
+ $product = new Product($db);
+ if ($id) $result = $product->fetch($id);
+ if ($ref) $result = $product->fetch($ref);
+ if ($_GET["ref"]) $result = $product->fetch('',$_GET["ref"]);
+ if ($_GET["id"]) $result = $product->fetch($_GET["id"]);
+}
+
-
if (!$user->rights->produit->lire) accessforbidden();
$html = new Form($db);
// Action association d'un sousproduit
-if ($action == 'add_prod' &&
- $cancel <> $langs->trans("Cancel") &&
- $user->rights->produit->creer)
+if ($action == 'add_prod' &&
+$cancel <> $langs->trans("Cancel") &&
+$user->rights->produit->creer)
{
-
- for($i=0;$i<$_POST["max_prod"];$i++)
+
+ for($i=0;$i<$_POST["max_prod"];$i++)
+ {
+ // print " : ".$_POST["prod_id_chk".$i];
+ if($_POST["prod_id_chk".$i] != "")
{
- // print " : ".$_POST["prod_id_chk".$i];
- if($_POST["prod_id_chk".$i] != "")
- {
- if($product->add_sousproduit($id, $_POST["prod_id_".$i],$_POST["prod_qty_".$i]) > 0)
- {
- $action = 'edit';
- }
- else
- {
- $action = 're-edit';
- if($product->error == "isFatherOfThis")
- $mesg = $langs->trans("ErrorAssociationIsFatherOfThis");
- }
- }
- else
- {
- if($product->del_sousproduit($id, $_POST["prod_id_".$i]))
- {
- $action = 'edit';
- }
- else
- {
- $action = 're-edit';
- }
-
-
- }
- }
+ if($product->add_sousproduit($id, $_POST["prod_id_".$i],$_POST["prod_qty_".$i]) > 0)
+ {
+ $action = 'edit';
+ }
+ else
+ {
+ $action = 're-edit';
+ if($product->error == "isFatherOfThis")
+ $mesg = $langs->trans("ErrorAssociationIsFatherOfThis");
+ }
+ }
+ else
+ {
+ if($product->del_sousproduit($id, $_POST["prod_id_".$i]))
+ {
+ $action = 'edit';
+ }
+ else
+ {
+ $action = 're-edit';
+ }
+
+
+ }
+ }
}
// action recherche des produits par mot-cle et/ou par categorie
if($action == 'search' )
@@ -100,16 +100,16 @@ if($action == 'search' )
#$sql = 'SELECT p.rowid, p.ref, p.label, p.price, p.fk_product_type';
$sql = 'SELECT p.rowid, p.ref, p.label, p.price';
$sql.= ' FROM '.MAIN_DB_PREFIX.'product as p';
- $sql.= ' left join '.MAIN_DB_PREFIX.'categorie_product as cp on p.rowid=cp.fk_product';
+ $sql.= ' left join '.MAIN_DB_PREFIX.'categorie_product as cp on p.rowid=cp.fk_product';
$sql.= " WHERE 1=1";
if($key != "")
{
$sql .= " AND (p.ref like '%".$key."%'";
$sql .= " OR p.label like '%".$key."%')";
}
- if ($conf->categorie->enabled && $catMere != -1 and $catMere)
+ if ($conf->categorie->enabled && $catMere != -1 and $catMere)
{
- $sql .= "AND cp.fk_categorie ='".$catMere."'";
+ $sql .= "AND cp.fk_categorie ='".$catMere."'";
}
$sql .= " ORDER BY p.ref ASC ";
// $sql .= $db->plimit($limit + 1 ,$offset);
@@ -118,9 +118,9 @@ if($action == 'search' )
if ($cancel == $langs->trans("Cancel"))
{
- $action = '';
- Header("Location: fiche.php?id=".$_POST["id"]);
- exit;
+ $action = '';
+ Header("Location: fiche.php?id=".$_POST["id"]);
+ exit;
}
@@ -131,6 +131,12 @@ if ($cancel == $langs->trans("Cancel"))
llxHeader("","",$langs->trans("CardProduct".$product->type));
$html = new Form($db);
+$productstatic = new Product($db);
+
+if ($mesg) {
+ print '
'.$mesg.' ';
+}
+
$head=product_prepare_head($product, $user);
$titre=$langs->trans("CardProduct".$product->type);
dolibarr_fiche_head($head, 'subproduct', $titre);
@@ -141,217 +147,209 @@ dolibarr_fiche_head($head, 'subproduct', $titre);
if ($id || $ref)
{
- if ( $result )
- {
-
- if ($action <> 'edit' &&$action <> 'search' && $action <> 're-edit')
+
+ if ( $result )
{
- /*
- * En mode visu
- */
-
- print($mesg);
-
- print '';
-
- print "";
-
- $nblignes=6;
- if ($product->isproduct() && $conf->stock->enabled) $nblignes++;
- if ($product->isservice()) $nblignes++;
-
- // Reference
- print '| '.$langs->trans("Ref").' | ';
- print $html->showrefnav($product,'ref','',1,'ref');
- print ' | ';
-
- // Libelle
- print '| '.$langs->trans("Label").' | '.$product->libelle.' | ';
- print ' ';
-
- $product->get_sousproduits_arbo ();
- print '| '.$langs->trans("AssociatedProductsNumber").' | '.sizeof($product->get_arbo_each_prod()).' | ';
-
- // associations sousproduits
- $prods_arbo = $product->get_arbo_each_prod();
- if(sizeof($prods_arbo) > 0)
- {
- print ' ';
- print ''.$langs->trans("ProductAssociationList").' ';
- foreach($prods_arbo as $key => $value)
+
+ if ($action <> 'edit' &&$action <> 'search' && $action <> 're-edit')
{
- print '- '.$value[0].' ';
- }
-
-
- print ' | ';
- }
-
- print " \n";
-
- print "\n";
- }
- }
-
- /*
- * Fiche en mode edition
- */
- if (($action == 'edit' || $action == 'search' || $action == 're-edit') && $user->rights->produit->creer)
- {
+ /*
+ * En mode visu
+ */
- if ($product->isservice()) {
- print_fiche_titre($langs->trans('EditAssociate').' '.$langs->trans('Service').' : '.$product->ref, "");
- } else {
- print_fiche_titre($langs->trans('EditAssociate').' '.$langs->trans('Product').' : '.$product->ref, "");
- }
+ print '';
- if ($mesg) {
- print '
'.$mesg.' ';
- }
+ print "";
- print '';
+ $nblignes=6;
+ if ($product->isproduct() && $conf->stock->enabled) $nblignes++;
+ if ($product->isservice()) $nblignes++;
- print "";
+ // Reference
+ print '| '.$langs->trans("Ref").' | ';
+ print $html->showrefnav($product,'ref','',1,'ref');
+ print ' | ';
- $nblignes=6;
- if ($product->isproduct() && $conf->stock->enabled) $nblignes++;
- if ($product->isservice()) $nblignes++;
+ // Libelle
+ print '| '.$langs->trans("Label").' | '.$product->libelle.' | ';
+ print ' ';
- // Reference
- print ''.$langs->trans("Ref").' | ';
- print 'id.'">'.$product->ref.'';
- print ' | ';
-
- if ($product->is_photo_available($conf->produit->dir_output))
- {
- // Photo
- print '';
- $nbphoto=$product->show_photos($conf->produit->dir_output,1,1,0);
- print ' | ';
- }
-
- print '';
-
- // Libelle
- print '| '.$langs->trans("Label").' | '.$product->libelle.' | ';
- print ' ';
- // Nombre de sousproduits associ�s
$product->get_sousproduits_arbo ();
- print '| '.$langs->trans("AssociatedProductsNumber").' | '.sizeof($product->get_arbo_each_prod()).' | ';
- print ' ';
- print ''.$langs->trans("ProductToAddSearch").'';
- print '';
+ }
}
/* ************************************************************************** */
-/* */
-/* Barre d'action */
-/* */
+/* */
+/* Barre d'action */
+/* */
/* ************************************************************************** */
print "\n\n";
if ($action == '')
{
-
- if ( $user->rights->produit->creer)
- {
- print ' '.$langs->trans("Modify").'';
- }
+ if ( $user->rights->produit->creer)
+ {
+ print ' '.$langs->trans("EditAssociate").'';
+
+ }
}
diff --git a/htdocs/product/stock/mouvementstock.class.php b/htdocs/product/stock/mouvementstock.class.php
index 119734a659b..aa01a1dd7bc 100644
--- a/htdocs/product/stock/mouvementstock.class.php
+++ b/htdocs/product/stock/mouvementstock.class.php
@@ -21,390 +21,422 @@
*/
/**
- \file htdocs/product/stock/mouvementstock.class.php
- \ingroup stock
- \brief Fichier de la classe de gestion des mouvements de stocks
- \version $Revision$
-*/
+ \file htdocs/product/stock/mouvementstock.class.php
+ \ingroup stock
+ \brief Fichier de la classe de gestion des mouvements de stocks
+ \version $Revision$
+ */
/**
- \class MouvementStock
- \brief Classe permettant la gestion des mouvements de stocks
-*/
+ \class MouvementStock
+ \brief Classe permettant la gestion des mouvements de stocks
+ */
class MouvementStock
{
- function MouvementStock($DB)
- {
- $this->db = $DB;
- }
-
- /**
- * \brief Crée un mouvement en base
- * \return int <0 si ko, >0 si ok
- */
- function _create($user, $fk_product, $entrepot_id, $qty, $type, $price=0)
- {
- $error = 0;
- dolibarr_syslog("MouvementStock::_Create $user->id, $fk_product, $entrepot_id, $qty, $type, $price");
-
- $this->db->begin();
-
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."stock_mouvement";
- $sql.= " (datem, fk_product, fk_entrepot, value, type_mouvement, fk_user_author, price)";
- $sql.= " VALUES (".$this->db->idate(mktime()).", ".$fk_product.", ".$entrepot_id.", ".$qty.", ".$type.", ".$user->id;
- $sql.= ",'".price2num($price)."')";
-
- if ($resql = $this->db->query($sql))
- {
- $mvid = $this->db->last_insert_id($resql);
- }
- else
- {
- dolibarr_syslog("MouvementStock::_Create echec insert ".$this->error);
- $error = -1;
- }
-
- $num = 0;
-
- if ($error === 0)
- {
- $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."product_stock";
- $sql.= " WHERE fk_entrepot = ".$entrepot_id." AND fk_product = ".$fk_product;
-
- if ($this->db->query($sql))
- {
- $num = $this->db->num_rows($resql);
- $this->db->free($resql);
- }
- else
- {
- dolibarr_syslog("MouvementStock::_Create echec update ".$this->error);
- $error = -2;
- }
- }
-
- if ($error === 0)
- {
- if ($num > 0)
- {
- $sql = "UPDATE ".MAIN_DB_PREFIX."product_stock SET reel = reel + ".$qty;
- $sql.= " WHERE fk_entrepot = ".$entrepot_id." AND fk_product = ".$fk_product;
- }
- else
- {
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_stock";
- $sql.= " (reel, fk_entrepot, fk_product) VALUES ";
- $sql.= " (".$qty.",".$entrepot_id.",".$fk_product.")";
- }
-
- if ($this->db->query($sql))
- {
-
- }
- else
- {
- dolibarr_syslog("MouvementStock::_Create echec update ".$this->error);
- $error = -3;
- }
- }
-
- if ($error === 0)
- {
- $valo_mouvement = 0;
- $error = $this->CalculateValoPmp($mvid, $fk_product, $qty, $price, $valo_mouvement);
- }
-
- if ($error === 0)
- {
- $error = $this->CalculateEntrepotValoPmp($user, $entrepot_id, $valo_mouvement);
- }
-
- if ($error === 0)
- {
- $error = $this->_createSubProduct($user, $fk_product, $entrepot_id, $qty, $type, $price=0);
- }
-
- if ($error === 0)
- {
- $this->db->commit();
- return 1;
- }
- else
- {
- $this->db->rollback();
- $this->error=$this->db->error() . " - $sql";
- dolibarr_syslog("MouvementStock::_Create ERROR : ".$this->error);
- return -2;
- }
- }
-
-
- /**
- * \brief Crée un mouvement en base pour tous les sous-produits
- * \return int <0 si ko, 0 si ok
- */
- function _createSubProduct($user, $fk_product, $entrepot_id, $qty, $type, $price=0)
- {
- $error = 0;
- dolibarr_syslog("MouvementStock::_CreateSubProduct $user->id, $fk_product, $entrepot_id, $qty, $type, $price");
- $pids = array();
-
- $sql = "SELECT fk_product_subproduct FROM ".MAIN_DB_PREFIX."product_subproduct";
- $sql.= " WHERE fk_product = $fk_product;";
-
- if ($this->db->query($sql))
- {
- while ($row = $this->db->fetch_row($resql) )
- {
- array_push($row[0]);
- }
- $this->db->free($resql);
- }
- else
- {
- dolibarr_syslog("MouvementStock::_Create echec update ".$this->error);
- $error = -2;
- }
-
- foreach($pids as $pid)
- {
- $this->_create($user, $pid, $entrepot_id, $qty, $type, $price=0);
- }
-
- return $error;
- }
-
-
-
- /**
- * \brief Calcul ???
- * \return int <0 si ko, >0 si ok
- */
- function CalculateEntrepotValoPmp($user, $entrepot_id, $valo_mouvement)
- {
- $error = 0;
- dolibarr_syslog("MouvementStock::CalculateEntrepotValoPmp $user->id, $entrepot_id, $valo_mouvement");
-
- if ( $valo_mouvement <> 0 )
+ function MouvementStock($DB)
{
+ $this->db = $DB;
+ }
+
+ /**
+ * \brief Add a mouvement in stock (in one direction only)
+ * \param type Direction of movement: 2=output (stock decrease), 3=input (stock increase)
+ * \return int <0 if KO, >0 if OK
+ */
+ function _create($user, $fk_product, $entrepot_id, $qty, $type, $price=0)
+ {
+ $error = 0;
+ dolibarr_syslog("MouvementStock::_Create $user->id, $fk_product, $entrepot_id, $qty, $type, $price");
+
+ $this->db->begin();
+
+ // $nbOfSubproduct=$this->nbOfSubProdcuts();
+
+ if (1 == 1) // Always change stock for current product
+ {
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."stock_mouvement";
+ $sql.= " (datem, fk_product, fk_entrepot, value, type_mouvement, fk_user_author, price)";
+ $sql.= " VALUES (".$this->db->idate(mktime()).", ".$fk_product.", ".$entrepot_id.", ".$qty.", ".$type.", ".$user->id;
+ $sql.= ",'".price2num($price)."')";
+
+ dolibarr_syslog("MouvementStock::_create sql=".$sql, LOG_DEBUG);
+ if ($resql = $this->db->query($sql))
+ {
+ $mvid = $this->db->last_insert_id($resql);
+ }
+ else
+ {
+ dolibarr_syslog("MouvementStock::_Create echec insert ".$this->error);
+ $error = -1;
+ }
+
+ // Get current value of stock
+ $num = 0;
+ if ($error == 0)
+ {
+ $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."product_stock";
+ $sql.= " WHERE fk_entrepot = ".$entrepot_id." AND fk_product = ".$fk_product;
+
+ if ($this->db->query($sql))
+ {
+ $num = $this->db->num_rows($resql);
+ $this->db->free($resql);
+ }
+ else
+ {
+ dolibarr_syslog("MouvementStock::_Create echec update ".$this->error);
+ $error = -2;
+ }
+ }
+
+ // Update value
+ if ($error == 0)
+ {
+ if ($num > 0)
+ {
+ $sql = "UPDATE ".MAIN_DB_PREFIX."product_stock SET reel = reel + ".$qty;
+ $sql.= " WHERE fk_entrepot = ".$entrepot_id." AND fk_product = ".$fk_product;
+ }
+ else
+ {
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_stock";
+ $sql.= " (reel, fk_entrepot, fk_product) VALUES ";
+ $sql.= " (".$qty.",".$entrepot_id.",".$fk_product.")";
+ }
+
+ dolibarr_syslog("MouvementStock::_create sql=".$sql, LOG_DEBUG);
+ if ($this->db->query($sql))
+ {
+
+ }
+ else
+ {
+ dolibarr_syslog("MouvementStock::_Create echec update ".$this->error);
+ $error = -3;
+ }
+ }
+
+ if ($error == 0)
+ {
+ $valo_mouvement = 0;
+ $error = $this->CalculateValoPmp($mvid, $fk_product, $qty, $price, $valo_mouvement);
+ }
+
+ if ($error == 0)
+ {
+ $error = $this->CalculateEntrepotValoPmp($user, $entrepot_id, $valo_mouvement);
+ }
+ }
+
+ // Add movement for sub products
+ $error = $this->_createSubProduct($user, $fk_product, $entrepot_id, $qty, $type, $price=0);
+
+ if ($error == 0)
+ {
+ $this->db->commit();
+ return 1;
+ }
+ else
+ {
+ $this->db->rollback();
+ $this->error=$this->db->error() . " - $sql";
+ dolibarr_syslog("MouvementStock::_Create ERROR : ".$this->error);
+ return -2;
+ }
+ }
+
+
+ /**
+ * \brief Crée un mouvement en base pour tous les sous-produits
+ * \return int <0 si ko, 0 si ok
+ */
+ function _createSubProduct($user, $idProduct, $entrepot_id, $qty, $type, $price=0)
+ {
+ $error = 0;
+ $pids = array();
+
+ $sql = "SELECT fk_product_pere, fk_product_fils, qty";
+ $sql.= " FROM ".MAIN_DB_PREFIX."product_association";
+ $sql.= " WHERE fk_product_pere = ".$idProduct;
+
+ dolibarr_syslog("MouvementStock::_createSubProduct sql=".$sql, LOG_DEBUG);
+ $resql=$this->db->query($sql);
+ if ($resql)
+ {
+ while ($obj=$this->db->fetch_object($resql))
+ {
+ $pids[]=$obj->fk_product_fils;
+ }
+ $this->db->free($resql);
+ }
+ else
+ {
+ dolibarr_syslog("MouvementStock::_createSubProduct echec update ".$this->error, LOG_ERROR);
+ $error = -2;
+ }
+
+ // Create movement for each subproduct
+ foreach($pids as $pid)
+ {
+ $this->_create($user, $pid, $entrepot_id, $qty, $type, $price);
+ }
+
+ return $error;
+ }
+
+
+
+ /**
+ * \brief Calcul ???
+ * \return int <0 si ko, >0 si ok
+ */
+ function CalculateEntrepotValoPmp($user, $entrepot_id, $valo_mouvement)
+ {
+ $error = 0;
+ dolibarr_syslog("MouvementStock::CalculateEntrepotValoPmp $user->id, $entrepot_id, $valo_mouvement");
+
+ if ( $valo_mouvement <> 0 )
+ {
$entrepot_value_pmp = 0;
-
+
if ($error === 0)
- {
- $sql = "SELECT valo_pmp,".$this->db->pdate("date_calcul")." FROM ".MAIN_DB_PREFIX."entrepot_valorisation";
- $sql.= " WHERE fk_entrepot = $entrepot_id ORDER BY date_calcul DESC LIMIT 1;";
-
- if ($this->db->query($sql))
- {
- while ($row = $this->db->fetch_row($resql) )
- {
- $entrepot_value_pmp = $row[0];
- $entrepot_value_date = $row[1];
- }
- $this->db->free($resql);
- }
- else
- {
- $error = -26;
- dolibarr_syslog("MouvementStock::CalculateEntrepotValoPmp ERRORSQL[$error]");
- }
- }
+ {
+ $sql = "SELECT valo_pmp,".$this->db->pdate("date_calcul")." FROM ".MAIN_DB_PREFIX."entrepot_valorisation";
+ $sql.= " WHERE fk_entrepot = $entrepot_id ORDER BY date_calcul DESC LIMIT 1;";
+
+ if ($this->db->query($sql))
+ {
+ while ($row = $this->db->fetch_row($resql) )
+ {
+ $entrepot_value_pmp = $row[0];
+ $entrepot_value_date = $row[1];
+ }
+ $this->db->free($resql);
+ }
+ else
+ {
+ $error = -26;
+ dolibarr_syslog("MouvementStock::CalculateEntrepotValoPmp ERRORSQL[$error]");
+ }
+ }
$new_value = $entrepot_value_pmp + $valo_mouvement;
$now = time();
if ($error === 0)
- {
- if ( strftime('%Y%m%d',$entrepot_value_date) == strftime('%Y%m%d',$now) )
- {
- $sql = "UPDATE ".MAIN_DB_PREFIX."entrepot_valorisation";
- $sql.= " SET valo_pmp='".ereg_replace(",",".",$new_value)."'";
- $sql.= " WHERE fk_entrepot = $entrepot_id ";
- $sql.= " AND ".$this->db->pdate("date_calcul")."='".$entrepot_value_date."';";
- }
- else
- {
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."entrepot_valorisation";
- $sql.= " (date_calcul, fk_entrepot, valo_pmp)";
- $sql.= " VALUES (".$this->db->idate(mktime()).", ".$entrepot_id;
- $sql.= ",'".ereg_replace(",",".",$new_value)."');";
- }
-
- if ($this->db->query($sql))
- {
-
- }
- else
- {
- $error = -27;
- dolibarr_syslog("MouvementStock::CalculateEntrepotValoPmp ERRORSQL[$error]");
- }
- }
+ {
+ if ( strftime('%Y%m%d',$entrepot_value_date) == strftime('%Y%m%d',$now) )
+ {
+ $sql = "UPDATE ".MAIN_DB_PREFIX."entrepot_valorisation";
+ $sql.= " SET valo_pmp='".ereg_replace(",",".",$new_value)."'";
+ $sql.= " WHERE fk_entrepot = $entrepot_id ";
+ $sql.= " AND ".$this->db->pdate("date_calcul")."='".$entrepot_value_date."';";
+ }
+ else
+ {
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."entrepot_valorisation";
+ $sql.= " (date_calcul, fk_entrepot, valo_pmp)";
+ $sql.= " VALUES (".$this->db->idate(mktime()).", ".$entrepot_id;
+ $sql.= ",'".ereg_replace(",",".",$new_value)."');";
+ }
+
+ if ($this->db->query($sql))
+ {
+
+ }
+ else
+ {
+ $error = -27;
+ dolibarr_syslog("MouvementStock::CalculateEntrepotValoPmp ERRORSQL[$error]");
+ }
+ }
if ($error === 0)
- {
- $sql = "UPDATE ".MAIN_DB_PREFIX."entrepot";
- $sql.= " SET valo_pmp='".ereg_replace(",",".",$new_value)."'";
- $sql.= " WHERE rowid = $entrepot_id ";
-
- if ($this->db->query($sql))
- {
-
- }
- else
- {
- $error = -28;
- dolibarr_syslog("MouvementStock::CalculateEntrepotValoPmp ERRORSQL[$error]");
- }
- }
-
+ {
+ $sql = "UPDATE ".MAIN_DB_PREFIX."entrepot";
+ $sql.= " SET valo_pmp='".ereg_replace(",",".",$new_value)."'";
+ $sql.= " WHERE rowid = $entrepot_id ";
+
+ if ($this->db->query($sql))
+ {
+
+ }
+ else
+ {
+ $error = -28;
+ dolibarr_syslog("MouvementStock::CalculateEntrepotValoPmp ERRORSQL[$error]");
+ }
+ }
+
if ($error === 0)
- {
- return 0;
- }
+ {
+ return 0;
+ }
else
- {
- dolibarr_syslog("MouvementStock::CalculateEntrepotValoPmp RETURN IN ERROR[$error]");
- return $error;
- }
- }
- else
- {
+ {
+ dolibarr_syslog("MouvementStock::CalculateEntrepotValoPmp RETURN IN ERROR[$error]");
+ return $error;
+ }
+ }
+ else
+ {
return 0;
+ }
}
- }
-
-
- /**
- * \brief ???
- * \param mvid int Id du mouvement
- * \param fk_product int Id produit
- * \param qty float Quantité
- * \param price float Prix unitaire du produit
- * \param value_ope float Valeur du mouvement en retour
- * \return int <0 si ko, 0 si ok
- */
- function CalculateValoPmp($mvid, $fk_product, $qty, $price=0, &$value_ope)
- {
- $error = 0;
- dolibarr_syslog("MouvementStock::CalculateValoPmp $mvid, $fk_product, $qty, $price");
- if ( $qty <> 0 )
+
+ /**
+ * \brief ???
+ * \param mvid int Id du mouvement
+ * \param fk_product int Id produit
+ * \param qty float Quantité
+ * \param price float Prix unitaire du produit
+ * \param value_ope float Valeur du mouvement en retour
+ * \return int <0 si ko, 0 si ok
+ */
+ function CalculateValoPmp($mvid, $fk_product, $qty, $price=0, &$value_ope)
{
- $price_pmp = 0;
- $qty_stock = 0;
- $stock_value_pmp = 0;
-
- if ($error === 0)
- {
- $sql = "SELECT price_pmp, qty_stock, valo_pmp FROM ".MAIN_DB_PREFIX."stock_valorisation";
- $sql.= " WHERE fk_product = $fk_product ORDER BY date_valo DESC LIMIT 1;";
-
- if ($this->db->query($sql))
- {
- while ($row = $this->db->fetch_row($resql) )
- {
- $price_pmp = $row[0];
- $qty_stock = $row[1];
- $stock_value_pmp = $row[2];
- }
- $this->db->free($resql);
- }
- else
- {
- dolibarr_syslog("MouvementStock::CalculateValoPmp ERRORSQL[1] ".$this->error);
- $error = -16;
- }
- }
+ $error = 0;
+ dolibarr_syslog("MouvementStock::CalculateValoPmp $mvid, $fk_product, $qty, $price");
- /*
- * Calcul
- */
- if ($qty > 0)
- {
- // on stock
- if (($qty + $qty_stock) <> 0)
- $new_pmp = ( ($qty * $price) + ($qty_stock * $price_pmp ) ) / ($qty + $qty_stock);
-
- $value_ope = $qty * $price;
- $new_stock_qty = $qty_stock + $qty;
- $new_stock_value_pmp = $stock_value_pmp + $value_ope;
- }
- else
- {
- // on destock
- $new_pmp = $price_pmp;
- $price = $price_pmp;
- $value_ope = $qty * $price_pmp;
- }
-
- $new_stock_qty = $qty_stock + $qty;
- $new_stock_value_pmp = $stock_value_pmp + $value_ope;
- /*
- * Fin calcul
- */
- if ($error === 0)
- {
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."stock_valorisation";
- $sql.= " (date_valo, fk_product, fk_stock_mouvement, qty_ope, price_ope, valo_ope, price_pmp, qty_stock, valo_pmp)";
- $sql.= " VALUES (".$this->db->idate(mktime()).", $fk_product, $mvid";
- $sql.= ",'".price2num($qty)."'";
- $sql.= ",'".price2num($price)."'";
- $sql.= ",'".price2num($value_ope)."'";
- $sql.= ",'".price2num($new_pmp)."'";
- $sql.= ",'".price2num($new_stock_qty)."'";
- $sql.= ",'".price2num($new_stock_value_pmp)."')";
-
- if ($this->db->query($sql))
+ if ( $qty <> 0 )
{
-
+ $price_pmp = 0;
+ $qty_stock = 0;
+ $stock_value_pmp = 0;
+
+ if ($error === 0)
+ {
+ $sql = "SELECT price_pmp, qty_stock, valo_pmp FROM ".MAIN_DB_PREFIX."stock_valorisation";
+ $sql.= " WHERE fk_product = $fk_product ORDER BY date_valo DESC LIMIT 1;";
+
+ if ($this->db->query($sql))
+ {
+ while ($row = $this->db->fetch_row($resql) )
+ {
+ $price_pmp = $row[0];
+ $qty_stock = $row[1];
+ $stock_value_pmp = $row[2];
+ }
+ $this->db->free($resql);
+ }
+ else
+ {
+ dolibarr_syslog("MouvementStock::CalculateValoPmp ERRORSQL[1] ".$this->error);
+ $error = -16;
+ }
+ }
+
+ /*
+ * Calcul
+ */
+ if ($qty > 0)
+ {
+ // on stock
+ if (($qty + $qty_stock) <> 0)
+ $new_pmp = ( ($qty * $price) + ($qty_stock * $price_pmp ) ) / ($qty + $qty_stock);
+
+ $value_ope = $qty * $price;
+ $new_stock_qty = $qty_stock + $qty;
+ $new_stock_value_pmp = $stock_value_pmp + $value_ope;
+ }
+ else
+ {
+ // on destock
+ $new_pmp = $price_pmp;
+ $price = $price_pmp;
+ $value_ope = $qty * $price_pmp;
+ }
+
+ $new_stock_qty = $qty_stock + $qty;
+ $new_stock_value_pmp = $stock_value_pmp + $value_ope;
+ /*
+ * Fin calcul
+ */
+ if ($error === 0)
+ {
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."stock_valorisation";
+ $sql.= " (date_valo, fk_product, fk_stock_mouvement, qty_ope, price_ope, valo_ope, price_pmp, qty_stock, valo_pmp)";
+ $sql.= " VALUES (".$this->db->idate(mktime()).", $fk_product, $mvid";
+ $sql.= ",'".price2num($qty)."'";
+ $sql.= ",'".price2num($price)."'";
+ $sql.= ",'".price2num($value_ope)."'";
+ $sql.= ",'".price2num($new_pmp)."'";
+ $sql.= ",'".price2num($new_stock_qty)."'";
+ $sql.= ",'".price2num($new_stock_value_pmp)."')";
+
+ if ($this->db->query($sql))
+ {
+
+ }
+ else
+ {
+ dolibarr_syslog("MouvementStock::CalculateValoPmp ERRORSQL[2] insert ".$this->error);
+ $error = -17;
+ }
+ }
+
+ if ($error === 0)
+ {
+ return 0;
+ }
+ else
+ {
+ dolibarr_syslog("MouvementStock::CalculateValoPmp ERROR : $error");
+ return -21;
+ }
}
- else
- {
- dolibarr_syslog("MouvementStock::CalculateValoPmp ERRORSQL[2] insert ".$this->error);
- $error = -17;
+ else
+ {
+ return 0;
}
- }
-
- if ($error === 0)
- {
- return 0;
- }
- else
- {
- dolibarr_syslog("MouvementStock::CalculateValoPmp ERROR : $error");
- return -21;
- }
}
- else
+
+
+ /**
+ * \brief Decrease stock for product and subproducts
+ *
+ */
+ function livraison($user, $fk_product, $entrepot_id, $qty)
{
- return 0;
+ return $this->_create($user, $fk_product, $entrepot_id, (0 - $qty), 2);
+ }
+
+
+ /**
+ * \brief Increase stock for product and subproducts
+ *
+ */
+ function reception($user, $fk_product, $entrepot_id, $qty, $price=0)
+ {
+ return $this->_create($user, $fk_product, $entrepot_id, $qty, 3, $price);
+ }
+
+
+ /**
+ * Return nb of subproducts for a product
+ *
+ * @param unknown_type $id
+ * @return unknown
+ */
+ function nbOfSubProdcuts($id)
+ {
+ $nbSP=0;
+
+ $resql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."product_association";
+ $resql.= " WHERE fk_product_pere = ".$id;
+ if ($this->db->query($resql))
+ {
+ $obj=$this->db->fetch_object($resql);
+ $nbSP=$obj->nb;
+ }
+ $this->db->free($resql);
+ return $nbSP;
}
- }
-
-
- /*
- *
- *
- */
- function livraison($user, $fk_product, $entrepot_id, $qty)
- {
- return $this->_create($user, $fk_product, $entrepot_id, (0 - $qty), 2);
- }
-
-
- /*
- *
- *
- */
- function reception($user, $fk_product, $entrepot_id, $qty, $price=0)
- {
- return $this->_create($user, $fk_product, $entrepot_id, $qty, 3, $price);
- }
}
?>
diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php
index fcfa18ccdfd..43a8ffcbefe 100644
--- a/htdocs/product/stock/product.php
+++ b/htdocs/product/stock/product.php
@@ -147,15 +147,14 @@ if ($_GET["id"] || $_GET["ref"])
print ' '.$product->stock_reel.' | ';
print ' | ';
-
- // Calculating a theorical value of stock if stock increment is done on order
- if ($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)
+ // Calculating a theorical value of stock if stock increment is done on real sending
+ if ($conf->global->STOCK_CALCULATE_ON_SHIPMENT)
{
$stock_commande_client=$stock_commande_fournisseur=0;
if ($conf->commande->enabled)
{
- $result=$product->load_stats_commande(0,'2');
+ $result=$product->load_stats_commande(0,'1,2');
if ($result < 0) dolibarr_print_error($db,$product->error);
$stock_commande_client=$product->stats_commande['qty'];
}
@@ -166,7 +165,7 @@ if ($_GET["id"] || $_GET["ref"])
$stock_commande_fournisseur=$product->stats_commande_fournisseur['qty'];
}
- $product->stock_theorique=$product->stock_reel-$stock_commande_client+$stock_commande_fournisseur;
+ $product->stock_theorique=$product->stock_reel-($stock_commande_client+$stock_sending_client)+$stock_commande_fournisseur;
// Stock theorique
print '| '.$langs->trans("VirtualStock").' | ';
@@ -190,10 +189,12 @@ if ($_GET["id"] || $_GET["ref"])
if ($conf->commande->enabled)
{
if ($found) print ' '; else $found=1;
- print $langs->trans("CustomersOrdersRunning").': '.$stock_commande_client;
- $result=$product->load_stats_commande(0,'0,1');
+ print $langs->trans("CustomersOrdersRunning").': '.($stock_commande_client+$stock_sending_client);
+ $result=$product->load_stats_commande(0,'0');
if ($result < 0) dolibarr_print_error($db,$product->error);
- print ' ('.$langs->trans("DraftOrWaitingShipped").': '.$product->stats_commande['qty'].')';
+ print ' ('.$langs->trans("Draft").': '.$product->stats_commande['qty'].')';
+ //print ' ';
+ //print $langs->trans("CustomersSendingRunning").': '.$stock_sending_client;
}
// Nbre de commande fournisseurs en cours
|