* Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005 Simon TOSSER * Copyright (C) 2005-2009 Regis Houssin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /** * \file htdocs/product/stock/product.php * \ingroup product stock * \brief Page to list detailed stock of a product */ require("../../main.inc.php"); require_once(DOL_DOCUMENT_ROOT."/product/stock/class/entrepot.class.php"); require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php"); require_once(DOL_DOCUMENT_ROOT."/core/lib/product.lib.php"); require_once(DOL_DOCUMENT_ROOT."/product/class/html.formproduct.class.php"); $langs->load("products"); $langs->load("orders"); $langs->load("bills"); $langs->load("stocks"); // Security check if (isset($_GET["id"]) || isset($_GET["ref"])) { $id = isset($_GET["id"])?$_GET["id"]:(isset($_GET["ref"])?$_GET["ref"]:''); } $fieldid = isset($_GET["ref"])?'ref':'rowid'; if ($user->societe_id) $socid=$user->societe_id; $result=restrictedArea($user,'produit&stock',$id,'product&product','','',$fieldid); $mesg = ''; /* * Actions */ // Set stock limit if ($_POST['action'] == 'setstocklimit') { $product = new Product($db); $result=$product->fetch($_POST['id']); $product->seuil_stock_alerte=$_POST["stocklimit"]; $result=$product->update($product->id,$user,1,0,1); if ($result < 0) { $mesg=join(',',$product->errors); } $POST["action"]=""; $id=$_POST["id"]; $_GET["id"]=$_POST["id"]; } // Correct stock if ($_POST["action"] == "correct_stock" && ! $_POST["cancel"]) { if (is_numeric($_POST["nbpiece"])) { $product = new Product($db); $result=$product->fetch($_GET["id"]); $result=$product->correct_stock( $user, $_POST["id_entrepot"], $_POST["nbpiece"], $_POST["mouvement"], $_POST["label"], 0 ); // We do not change value of stock for a correction if ($result > 0) { header("Location: product.php?id=".$product->id); exit; } } } // Transfer stock from a warehouse to another warehouse if ($_POST["action"] == "transfert_stock" && ! $_POST["cancel"]) { if ($_POST["id_entrepot_source"] <> $_POST["id_entrepot_destination"]) { if (is_numeric($_POST["nbpiece"])) { $product = new Product($db); $result=$product->fetch($_GET["id"]); $db->begin(); $product->load_stock(); // Load array product->stock_warehouse // Define value of products moved $pricesrc=0; if (isset($product->stock_warehouse[$_POST["id_entrepot_source"]]->pmp)) $pricesrc=$product->stock_warehouse[$_POST["id_entrepot_source"]]->pmp; $pricedest=$pricesrc; //print 'price src='.$pricesrc.', price dest='.$pricedest;exit; // Remove stock $result1=$product->correct_stock( $user, $_POST["id_entrepot_source"], $_POST["nbpiece"], 1, $_POST["label"], $pricesrc ); // Add stock $result2=$product->correct_stock( $user, $_POST["id_entrepot_destination"], $_POST["nbpiece"], 0, $_POST["label"], $pricedest ); if ($result1 >= 0 && $result2 >= 0) { $db->commit(); header("Location: product.php?id=".$product->id); exit; } else { $mesg=$product->error; $db->rollback(); } } } } /* * View */ $formproduct=new FormProduct($db); if ($_GET["id"] || $_GET["ref"]) { $product = new Product($db); if ($_GET["ref"]) $result = $product->fetch('',$_GET["ref"]); if ($_GET["id"]) $result = $product->fetch($_GET["id"]); $help_url='EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks'; llxHeader("",$langs->trans("CardProduct".$product->type),$help_url); if ($result > 0) { $head=product_prepare_head($product, $user); $titre=$langs->trans("CardProduct".$product->type); $picto=($product->type==1?'service':'product'); dol_fiche_head($head, 'stock', $titre, 0, $picto); $form = new Form($db); print($mesg); print ''; // Ref print ''; print ''; print ''; // Label print ''; print ''; // Status (to sell) print ''; // Status (to buy) print ''; // PMP print ''; print ''; print ''; // Sell price print ''; print ''; print ''; // Real stock $product->load_stock(); print ''; print ''; print ''; // 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,'1,2'); if ($result < 0) dol_print_error($db,$product->error); $stock_commande_client=$product->stats_commande['qty']; } if ($conf->fournisseur->enabled) { $result=$product->load_stats_commande_fournisseur(0,'3'); if ($result < 0) dol_print_error($db,$product->error); $stock_commande_fournisseur=$product->stats_commande_fournisseur['qty']; } $product->stock_theorique=$product->stock_reel-($stock_commande_client+$stock_sending_client)+$stock_commande_fournisseur; // Stock theorique print ''; print "'; print ''; print ''; print ''; } // Stock print ''; // Last movement $sql = "SELECT max(m.datem) as datem"; $sql.= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m"; $sql.= " WHERE m.fk_product = '".$product->id."'"; $resqlbis = $db->query($sql); if ($resqlbis) { $obj = $db->fetch_object($resqlbis); $lastmovementdate=$db->jdate($obj->datem); } else { dol_print_error($db); } print '"; print "
'.$langs->trans("Ref").''; print $form->showrefnav($product,'ref','',1,'ref'); print '
'.$langs->trans("Label").''.$product->libelle.'
'.$langs->trans("Status").' ('.$langs->trans("Sell").')'; print $product->getLibStatut(2,0); print '
'.$langs->trans("Status").' ('.$langs->trans("Buy").')'; print $product->getLibStatut(2,1); print '
'.$langs->trans("AverageUnitPricePMP").''.price($product->pmp).' '.$langs->trans("HT").'
'.$langs->trans("SellPriceMin").''; if (empty($conf->global->PRODUIT_MULTIPRICES)) print price($product->price).' '.$langs->trans("HT"); else print $langs->trans("Variable"); print '
'.$langs->trans("PhysicalStock").''.$product->stock_reel; if ($product->seuil_stock_alerte && ($product->stock_reel < $product->seuil_stock_alerte)) print ' '.img_warning($langs->trans("StockTooLow")); print '
'.$langs->trans("VirtualStock").'".$product->stock_theorique; if ($product->stock_theorique < $product->seuil_stock_alerte) { print ' '.img_warning($langs->trans("StockTooLow")); } print '
'; if ($product->stock_theorique != $product->stock_reel) print $langs->trans("StockDiffPhysicTeoric"); else print $langs->trans("RunningOrders"); print ''; $found=0; // Nbre de commande clients en cours if ($conf->commande->enabled) { if ($found) print '
'; else $found=1; print $langs->trans("CustomersOrdersRunning").': '.($stock_commande_client+$stock_sending_client); $result=$product->load_stats_commande(0,'0'); if ($result < 0) dol_print_error($db,$product->error); print ' ('.$langs->trans("Draft").': '.$product->stats_commande['qty'].')'; //print '
'; //print $langs->trans("CustomersSendingRunning").': '.$stock_sending_client; } // Nbre de commande fournisseurs en cours if ($conf->fournisseur->enabled) { if ($found) print '
'; else $found=1; print $langs->trans("SuppliersOrdersRunning").': '.$stock_commande_fournisseur; $result=$product->load_stats_commande_fournisseur(0,'0,1,2'); if ($result < 0) dol_print_error($db,$product->error); print ' ('.$langs->trans("DraftOrWaitingApproved").': '.$product->stats_commande_fournisseur['qty'].')'; } print '
'.$form->editfieldkey("StockLimit",'stocklimit',$product->seuil_stock_alerte,$product,$user->rights->produit->creer).''; print $form->editfieldval("StockLimit",'stocklimit',$product->seuil_stock_alerte,$product,$user->rights->produit->creer); print '
'.$langs->trans("LastMovement").''; if ($lastmovementdate) { print dol_print_date($lastmovementdate,'dayhour').' '; print '('.$langs->trans("FullList").')'; } else { print ''.$langs->trans("None").''; } print "
"; } print ''; /* * Correct stock */ if ($_GET["action"] == "correction") { print_titre($langs->trans("StockCorrection")); print "
id\" method=\"post\">\n"; print ''; print ''; print ''; // Warehouse print ''; print ''; print ''; print ''; print ''; print ''; // Label print ''; print ''; print ''; print ''; print '
'.$langs->trans("Warehouse").''; print $formproduct->selectWarehouses($_GET["dwid"],'id_entrepot','',1); print ''; print ''.$langs->trans("NumberOfUnit").'
'.$langs->trans("Label").''; print ''; print '
'; print '
 '; print '
'; print '
'; } /* * Transfer of units */ if ($_GET["action"] == "transfert") { print_titre($langs->trans("Transfer")); print "
id\" method=\"post\">\n"; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; // Label print ''; print ''; print ''; print ''; print '
'.$langs->trans("WarehouseSource").''; print $formproduct->selectWarehouses($_GET["dwid"],'id_entrepot_source','',1); print ''.$langs->trans("WarehouseTarget").''; print $formproduct->selectWarehouses('','id_entrepot_destination','',1); print ''.$langs->trans("NumberOfUnit").'
'.$langs->trans("Label").''; print ''; print '
'; print '
 '; print '
'; print '
'; } /* * Set initial stock */ /* if ($_GET["action"] == "definir") { print_titre($langs->trans("SetStock")); print "
id\" method=\"post\">\n"; print ''; print ''; print ''; print ''; print ''; print '
'.$langs->trans("Warehouse").''; print $formproduct->selectWarehouses('','id_entrepot','',1); print ''.$langs->trans("NumberOfUnit").'
 '; print '
'; print '
'; } */ } else { dol_print_error(); } /* ************************************************************************** */ /* */ /* Barre d'action */ /* */ /* ************************************************************************** */ print "
\n"; //if (empty($_GET["action"])) //{ if ($user->rights->stock->creer) { print ''.$langs->trans("StockCorrection").''; } if ($user->rights->stock->mouvement->creer) { print ''.$langs->trans("StockMovement").''; } //} print '
'; /* * Contenu des stocks */ print '
'; print ''; print ''; print ''; print ''; print ''; print ''; print ''; $sql = "SELECT e.rowid, e.label, ps.reel, ps.pmp"; $sql.= " FROM ".MAIN_DB_PREFIX."entrepot as e,"; $sql.= " ".MAIN_DB_PREFIX."product_stock as ps"; $sql.= " WHERE ps.reel != 0"; $sql.= " AND ps.fk_entrepot = e.rowid"; $sql.= " AND e.entity = ".$conf->entity; $sql.= " AND ps.fk_product = ".$product->id; $sql.= " ORDER BY e.label"; $entrepotstatic=new Entrepot($db); $total=0; $totalvalue=$totalvaluesell=0; $resql=$db->query($sql); if ($resql) { $num = $db->num_rows($resql); $total=$totalwithpmp; $i=0; $var=false; while ($i < $num) { $obj = $db->fetch_object($resql); $entrepotstatic->id=$obj->rowid; $entrepotstatic->libelle=$obj->label; print ''; print ''; print ''; // PMP print ''; // Ditto : Show PMP from movement or from product print ''; // Ditto : Show PMP from movement or from product // Sell price print ''; // Ditto : Show PMP from movement or from product print ''; // Ditto : Show PMP from movement or from product else print $langs->trans("Variable"); print ''; ; $total += $obj->reel; if (price2num($obj->pmp)) $totalwithpmp += $obj->reel; $totalvalue = $totalvalue + price2num($obj->pmp*$obj->reel,'MU'); // Ditto : Show PMP from movement or from product $totalvaluesell = $totalvaluesell + price2num($product->price*$obj->reel,'MU'); // Ditto : Show PMP from movement or from product $i++; $var=!$var; } } else dol_print_error($db); print ''; print ''; print ''; print ''; print ''; print ''; print ""; print "
'.$langs->trans("Warehouse").''.$langs->trans("NumberOfUnit").''.$langs->trans("AverageUnitPricePMPShort").''.$langs->trans("EstimatedStockValueShort").''.$langs->trans("SellPriceMin").''.$langs->trans("EstimatedStockValueSellShort").'
'.$entrepotstatic->getNomUrl(1).''.$obj->reel.($obj->reel<0?' '.img_warning():'').''.(price2num($obj->pmp)?price2num($obj->pmp,'MU'):'').''.(price2num($obj->pmp)?price(price2num($obj->pmp*$obj->reel,'MT')):'').''; if (empty($conf->global->PRODUIT_MUTLI_PRICES)) print price(price2num($product->price,'MU')); else print $langs->trans("Variable"); print ''; if (empty($conf->global->PRODUIT_MUTLI_PRICES)) print price(price2num($product->price*$obj->reel,'MT')).'
'.$langs->trans("Total").':'.$total.''; print ($totalwithpmp?price($totalvalue/$totalwithpmp):' '); print ''; print price(price2num($totalvalue,'MT')); print ''; if (empty($conf->global->PRODUIT_MUTLI_PRICES)) print ($total?price($totalvaluesell/$total):' '); else print $langs->trans("Variable"); print ''; if (empty($conf->global->PRODUIT_MUTLI_PRICES)) print price(price2num($totalvaluesell,'MT')); else print $langs->trans("Variable"); print '
"; $db->close(); llxFooter(); ?>