diff --git a/ChangeLog b/ChangeLog
index 4d5f999e92f..9b287e18662 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -21,6 +21,7 @@ For users:
- New: Add link to third party into sells and purchase journal.
- New: Suggest a method to generate a backup file for user with no access
to mysqldump binary.
+- New: Can correct stock of a warehouse from warehouse card.
- Fix: No images into product description lines as PDF generation does
not work with this.
diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php
index 5797b3671a3..b4d2f06bd6b 100644
--- a/htdocs/product/stock/mouvement.php
+++ b/htdocs/product/stock/mouvement.php
@@ -27,6 +27,7 @@ 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/class/html.formother.class.php");
+require_once(DOL_DOCUMENT_ROOT."/product/class/html.formproduct.class.php");
require_once(DOL_DOCUMENT_ROOT."/core/lib/stock.lib.php");
require_once(DOL_DOCUMENT_ROOT."/core/lib/product.lib.php");
require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
@@ -37,6 +38,9 @@ $langs->load("stocks");
if (!$user->rights->produit->lire) accessforbidden();
$id=GETPOST('id','int');
+$product_id=GETPOST("product_id");
+$action=GETPOST('action');
+$cancel=GETPOST('cancel');
$idproduct = isset($_GET["idproduct"])?$_GET["idproduct"]:$_PRODUCT["idproduct"];
$year = isset($_GET["year"])?$_GET["year"]:$_POST["year"];
$month = isset($_GET["month"])?$_GET["month"]:$_POST["month"];
@@ -65,6 +69,39 @@ if (GETPOST("button_removefilter"))
}
+/*
+ * Actions
+ */
+
+if ($cancel) $action='';
+
+// Correct stock
+if ($action == "correct_stock" && ! $_POST["cancel"])
+{
+ if (is_numeric($_POST["nbpiece"]) && $product_id)
+ {
+ $product = new Product($db);
+ $result=$product->fetch($product_id);
+
+ $result=$product->correct_stock(
+ $user,
+ $id,
+ $_POST["nbpiece"],
+ $_POST["mouvement"],
+ $_POST["label"],
+ 0
+ ); // We do not change value of stock for a correction
+
+ if ($result > 0)
+ {
+ header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
+ exit;
+ }
+ }
+ else $action='';
+}
+
+
/*
* View
*/
@@ -74,6 +111,7 @@ $warehousestatic=new Entrepot($db);
$userstatic=new User($db);
$form=new Form($db);
$formother=new FormOther($db);
+$formproduct=new FormProduct($db);
$sql = "SELECT p.rowid, p.label as produit, p.fk_product_type as type,";
$sql.= " e.label as stock, e.rowid as entrepot_id,";
@@ -89,38 +127,38 @@ $sql.= " AND e.entity = ".$conf->entity;
if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) $sql.= " AND p.fk_product_type = 0";
if ($id)
{
- $sql.= " AND e.rowid ='".$id."'";
+ $sql.= " AND e.rowid ='".$id."'";
}
if ($month > 0)
{
- if ($year > 0)
- $sql.= " AND m.datem BETWEEN '".$db->idate(dol_get_first_day($year,$month,false))."' AND '".$db->idate(dol_get_last_day($year,$month,false))."'";
- else
- $sql.= " AND date_format(m.datem, '%m') = '$month'";
+ if ($year > 0)
+ $sql.= " AND m.datem BETWEEN '".$db->idate(dol_get_first_day($year,$month,false))."' AND '".$db->idate(dol_get_last_day($year,$month,false))."'";
+ else
+ $sql.= " AND date_format(m.datem, '%m') = '$month'";
}
else if ($year > 0)
{
- $sql.= " AND m.datem BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'";
+ $sql.= " AND m.datem BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'";
}
if (! empty($search_movement))
{
- $sql.= " AND m.label LIKE '%".$db->escape($search_movement)."%'";
+ $sql.= " AND m.label LIKE '%".$db->escape($search_movement)."%'";
}
if (! empty($search_product))
{
- $sql.= " AND p.label LIKE '%".$db->escape($search_product)."%'";
+ $sql.= " AND p.label LIKE '%".$db->escape($search_product)."%'";
}
if (! empty($search_warehouse))
{
- $sql.= " AND e.label LIKE '%".$db->escape($search_warehouse)."%'";
+ $sql.= " AND e.label LIKE '%".$db->escape($search_warehouse)."%'";
}
if (! empty($search_user))
{
- $sql.= " AND u.login LIKE '%".$db->escape($search_user)."%'";
+ $sql.= " AND u.login LIKE '%".$db->escape($search_user)."%'";
}
if (! empty($_GET['idproduct']))
{
- $sql.= " AND p.rowid = '".$idproduct."'";
+ $sql.= " AND p.rowid = '".$idproduct."'";
}
$sql.= $db->order($sortfield,$sortorder);
$sql.= $db->plimit($conf->liste_limit+1, $offset);
@@ -129,217 +167,321 @@ $sql.= $db->plimit($conf->liste_limit+1, $offset);
$resql = $db->query($sql);
if ($resql)
{
- $num = $db->num_rows($resql);
+ $num = $db->num_rows($resql);
- if ($idproduct)
- {
- $product = new Product($db);
- $product->fetch($idproduct);
- }
+ if ($idproduct)
+ {
+ $product = new Product($db);
+ $product->fetch($idproduct);
+ }
- if ($_GET["id"])
- {
- $entrepot = new Entrepot($db);
- $result = $entrepot->fetch($id);
- if ($result < 0)
- {
- dol_print_error($db);
- }
- }
+ if ($_GET["id"])
+ {
+ $entrepot = new Entrepot($db);
+ $result = $entrepot->fetch($id);
+ if ($result < 0)
+ {
+ dol_print_error($db);
+ }
+ }
- $i = 0;
+ $i = 0;
- $help_url='EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks';
- $texte = $langs->trans("ListOfStockMovements");
- llxHeader("",$texte,$help_url);
+ $help_url='EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks';
+ $texte = $langs->trans("ListOfStockMovements");
+ llxHeader("",$texte,$help_url);
- /*
- * Show tab only if we ask a particular warehouse
- */
- if ($id)
- {
- $head = stock_prepare_head($entrepot);
+ /*
+ * Show tab only if we ask a particular warehouse
+ */
+ if ($id)
+ {
+ $head = stock_prepare_head($entrepot);
- dol_fiche_head($head, 'movements', $langs->trans("Warehouse"), 0, 'stock');
+ dol_fiche_head($head, 'movements', $langs->trans("Warehouse"), 0, 'stock');
- print '
';
+ print '';
- // Ref
- print '| '.$langs->trans("Ref").' | ';
- print $form->showrefnav($entrepot,'id','',1,'rowid','libelle');
- print ' | ';
+ // Ref
+ print '
| '.$langs->trans("Ref").' | ';
+ print $form->showrefnav($entrepot,'id','',1,'rowid','libelle');
+ print ' | ';
- print '
| '.$langs->trans("LocationSummary").' | '.$entrepot->lieu.' |
';
+ print '| '.$langs->trans("LocationSummary").' | '.$entrepot->lieu.' |
';
- // Description
- print '| '.$langs->trans("Description").' | '.dol_htmlentitiesbr($entrepot->description).' |
';
+ // Description
+ print '| '.$langs->trans("Description").' | '.dol_htmlentitiesbr($entrepot->description).' |
';
- // Address
- print '| '.$langs->trans('Address').' | ';
- print $entrepot->address;
- print ' |
';
+ // Address
+ print '| '.$langs->trans('Address').' | ';
+ print $entrepot->address;
+ print ' |
';
- // Town
- print '| '.$langs->trans('Zip').' | '.$entrepot->zip.' | ';
- print ''.$langs->trans('Town').' | '.$entrepot->town.' |
';
+ // Town
+ print '| '.$langs->trans('Zip').' | '.$entrepot->zip.' | ';
+ print ''.$langs->trans('Town').' | '.$entrepot->town.' |
';
- // Country
- print '| '.$langs->trans('Country').' | ';
- $img=picto_from_langcode($entrepot->country_code);
- print ($img?$img.' ':'');
- print $entrepot->country;
- print ' |
';
+ // Country
+ print '| '.$langs->trans('Country').' | ';
+ $img=picto_from_langcode($entrepot->country_code);
+ print ($img?$img.' ':'');
+ print $entrepot->country;
+ print ' |
';
- // Status
- print '| '.$langs->trans("Status").' | '.$entrepot->getLibStatut(4).' |
';
+ // Status
+ print '| '.$langs->trans("Status").' | '.$entrepot->getLibStatut(4).' |
';
- $calcproducts=$entrepot->nb_products();
+ $calcproducts=$entrepot->nb_products();
- // Nb of products
- print '| '.$langs->trans("NumberOfProducts").' | ';
- print empty($calcproducts['nb'])?'0':$calcproducts['nb'];
- print " |
";
+ // Nb of products
+ print '| '.$langs->trans("NumberOfProducts").' | ';
+ print empty($calcproducts['nb'])?'0':$calcproducts['nb'];
+ print " |
";
- // Value
- print '| '.$langs->trans("EstimatedStockValueShort").' | ';
- print empty($calcproducts['value'])?'0':$calcproducts['value'];
- print " |
";
+ // Value
+ print '| '.$langs->trans("EstimatedStockValueShort").' | ';
+ print empty($calcproducts['value'])?'0':$calcproducts['value'];
+ print " |
";
- // Last movement
- $sql = "SELECT MAX(m.datem) as datem";
- $sql .= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m";
- $sql .= " WHERE m.fk_entrepot = '".$entrepot->id."'";
- $resqlbis = $db->query($sql);
- if ($resqlbis)
- {
- $obj = $db->fetch_object($resqlbis);
- $lastmovementdate=$db->jdate($obj->datem);
- }
- else
- {
- dol_print_error($db);
- }
+ // Last movement
+ $sql = "SELECT MAX(m.datem) as datem";
+ $sql .= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m";
+ $sql .= " WHERE m.fk_entrepot = '".$entrepot->id."'";
+ $resqlbis = $db->query($sql);
+ if ($resqlbis)
+ {
+ $obj = $db->fetch_object($resqlbis);
+ $lastmovementdate=$db->jdate($obj->datem);
+ }
+ else
+ {
+ dol_print_error($db);
+ }
- print '| '.$langs->trans("LastMovement").' | ';
- if ($lastmovementdate)
- {
- print dol_print_date($lastmovementdate,'dayhour');
- }
- else
- {
- print $langs->trans("None");
- }
- print " |
";
+ print '| '.$langs->trans("LastMovement").' | ';
+ if ($lastmovementdate)
+ {
+ print dol_print_date($lastmovementdate,'dayhour');
+ }
+ else
+ {
+ print $langs->trans("None");
+ }
+ print " |
";
- print "
";
+ print "
";
- print '';
- }
+ print '';
+ }
- $param='';
- if ($id) $param.='&id='.$id;
- if ($search_movement) $param.='&search_movement='.urlencode($search_movement);
- if ($search_product) $param.='&search_product='.urlencode($search_product);
- if ($search_warehouse) $param.='&search_warehouse='.urlencode($search_warehouse);
- if ($sref) $param.='&sref='.urlencode($sref);
- if ($snom) $param.='&snom='.urlencode($snom);
- if ($search_user) $param.='&search_user='.urlencode($search_user);
- if ($idproduct > 0) $param.='&idproduct='.$idproduct;
- if ($id) print_barre_liste($texte, $page, "mouvement.php", $param, $sortfield, $sortorder,'',$num,0,'');
- else print_barre_liste($texte, $page, "mouvement.php", $param, $sortfield, $sortorder,'',$num);
- print '';
- print "";
- //print_liste_field_titre($langs->trans("Id"),$_SERVER["PHP_SELF"], "m.rowid","",$param,"",$sortfield,$sortorder);
- print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"], "m.datem","",$param,"",$sortfield,$sortorder);
- print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"], "m.label","",$param,"",$sortfield,$sortorder);
- print_liste_field_titre($langs->trans("Product"),$_SERVER["PHP_SELF"], "p.ref","",$param,"",$sortfield,$sortorder);
- print_liste_field_titre($langs->trans("Warehouse"),$_SERVER["PHP_SELF"], "e.label","",$param,"",$sortfield,$sortorder);
- print_liste_field_titre($langs->trans("Author"),$_SERVER["PHP_SELF"], "m.fk_user_author","",$param,"",$sortfield,$sortorder);
- print_liste_field_titre($langs->trans("Units"),$_SERVER["PHP_SELF"], "m.value","",$param,'align="right"',$sortfield,$sortorder);
- print "
\n";
+ /*
+ * Correct stock
+ */
+ if ($action == "correction")
+ {
+ print_titre($langs->trans("StockCorrection"));
+ print '';
+ }
+
+ /*
+ * Transfer of units
+ */
+ /*
+ if ($action == "transfert")
+ {
+ print_titre($langs->trans("Transfer"));
+ print '';
+ }
+ */
+
+ /* ************************************************************************** */
+ /* */
+ /* Barre d'action */
+ /* */
+ /* ************************************************************************** */
+
+ if (empty($action) && $id)
+ {
+ print "
';
+ }
+
+
+ $param='';
+ if ($id) $param.='&id='.$id;
+ if ($search_movement) $param.='&search_movement='.urlencode($search_movement);
+ if ($search_product) $param.='&search_product='.urlencode($search_product);
+ if ($search_warehouse) $param.='&search_warehouse='.urlencode($search_warehouse);
+ if ($sref) $param.='&sref='.urlencode($sref);
+ if ($snom) $param.='&snom='.urlencode($snom);
+ if ($search_user) $param.='&search_user='.urlencode($search_user);
+ if ($idproduct > 0) $param.='&idproduct='.$idproduct;
+ if ($id) print_barre_liste($texte, $page, "mouvement.php", $param, $sortfield, $sortorder,'',$num,0,'');
+ else print_barre_liste($texte, $page, "mouvement.php", $param, $sortfield, $sortorder,'',$num);
+
+ print '';
+ print "";
+ //print_liste_field_titre($langs->trans("Id"),$_SERVER["PHP_SELF"], "m.rowid","",$param,"",$sortfield,$sortorder);
+ print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"], "m.datem","",$param,"",$sortfield,$sortorder);
+ print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"], "m.label","",$param,"",$sortfield,$sortorder);
+ print_liste_field_titre($langs->trans("Product"),$_SERVER["PHP_SELF"], "p.ref","",$param,"",$sortfield,$sortorder);
+ print_liste_field_titre($langs->trans("Warehouse"),$_SERVER["PHP_SELF"], "e.label","",$param,"",$sortfield,$sortorder);
+ print_liste_field_titre($langs->trans("Author"),$_SERVER["PHP_SELF"], "m.fk_user_author","",$param,"",$sortfield,$sortorder);
+ print_liste_field_titre($langs->trans("Units"),$_SERVER["PHP_SELF"], "m.value","",$param,'align="right"',$sortfield,$sortorder);
+ print "
\n";
+
+ // Lignes des champs de filtre
+ print '';
+ print '';
+ print "\n";
+ print '';
- $var=True;
- while ($i < min($num,$conf->liste_limit))
- {
- $objp = $db->fetch_object($resql);
- $var=!$var;
- print "";
- // Id movement
- //print '| '.$objp->mid.' | '; // This is primary not movement id
- // Date
- print ''.dol_print_date($db->jdate($objp->datem),'dayhour').' | ';
- // Label of movement
- print ''.$objp->label.' | ';
- // Product
- print '';
- $productstatic->id=$objp->rowid;
- $productstatic->ref=$objp->produit;
- $productstatic->type=$objp->type;
- print $productstatic->getNomUrl(1,'',16);
- print " | \n";
- // Warehouse
- print '';
- $warehousestatic->id=$objp->entrepot_id;
- $warehousestatic->libelle=$objp->stock;
- print $warehousestatic->getNomUrl(1);
- print " | \n";
- // Author
- print '';
- $userstatic->id=$objp->fk_user_author;
- $userstatic->lastname=$objp->login;
- print $userstatic->getNomUrl(1);
- print " | \n";
- // Value
- print '';
- if ($objp->value > 0) print '+';
- print $objp->value.' | ';
- print "
\n";
- $i++;
- }
- $db->free($resql);
+ $var=True;
+ while ($i < min($num,$conf->liste_limit))
+ {
+ $objp = $db->fetch_object($resql);
+ $var=!$var;
+ print "";
+ // Id movement
+ //print '| '.$objp->mid.' | '; // This is primary not movement id
+ // Date
+ print ''.dol_print_date($db->jdate($objp->datem),'dayhour').' | ';
+ // Label of movement
+ print ''.$objp->label.' | ';
+ // Product
+ print '';
+ $productstatic->id=$objp->rowid;
+ $productstatic->ref=$objp->produit;
+ $productstatic->type=$objp->type;
+ print $productstatic->getNomUrl(1,'',16);
+ print " | \n";
+ // Warehouse
+ print '';
+ $warehousestatic->id=$objp->entrepot_id;
+ $warehousestatic->libelle=$objp->stock;
+ print $warehousestatic->getNomUrl(1);
+ print " | \n";
+ // Author
+ print '';
+ $userstatic->id=$objp->fk_user_author;
+ $userstatic->lastname=$objp->login;
+ print $userstatic->getNomUrl(1);
+ print " | \n";
+ // Value
+ print '';
+ if ($objp->value > 0) print '+';
+ print $objp->value.' | ';
+ print "
\n";
+ $i++;
+ }
+ $db->free($resql);
- print "
";
+ print "
";
}
else
{
- dol_print_error($db);
+ dol_print_error($db);
}
llxFooter();
diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php
index 44e887b73cc..3410eec67c3 100644
--- a/htdocs/product/stock/product.php
+++ b/htdocs/product/stock/product.php
@@ -36,11 +36,12 @@ $langs->load("orders");
$langs->load("bills");
$langs->load("stocks");
+$action=GETPOST("action");
+$cancel=GETPOST('cancel');
+
// Security check
-if (isset($_GET["id"]) || isset($_GET["ref"]))
-{
- $id = isset($_GET["id"])?$_GET["id"]:(isset($_GET["ref"])?$_GET["ref"]:'');
-}
+$id = GETPOST('id')?GETPOST('id'):GETPOST('ref');
+$ref = GETPOST('ref');
$fieldid = isset($_GET["ref"])?'ref':'rowid';
if ($user->societe_id) $socid=$user->societe_id;
$result=restrictedArea($user,'produit&stock',$id,'product','','',$fieldid);
@@ -52,8 +53,10 @@ $mesg = '';
* Actions
*/
+if ($cancel) $action='';
+
// Set stock limit
-if ($_POST['action'] == 'setstocklimit')
+if ($action == 'setstocklimit')
{
$product = new Product($db);
$result=$product->fetch($_POST['id']);
@@ -69,12 +72,12 @@ if ($_POST['action'] == 'setstocklimit')
}
// Correct stock
-if ($_POST["action"] == "correct_stock" && ! $_POST["cancel"])
+if ($action == "correct_stock" && ! $_POST["cancel"])
{
- if (is_numeric($_POST["nbpiece"]))
+ if (is_numeric($_POST["nbpiece"]) && $id)
{
$product = new Product($db);
- $result=$product->fetch($_GET["id"]);
+ $result=$product->fetch($id);
$result=$product->correct_stock(
$user,
@@ -87,21 +90,21 @@ if ($_POST["action"] == "correct_stock" && ! $_POST["cancel"])
if ($result > 0)
{
- header("Location: product.php?id=".$product->id);
+ header("Location: ".$_SERVER["PHP_SELF"]."?id=".$product->id);
exit;
}
}
}
// Transfer stock from a warehouse to another warehouse
-if ($_POST["action"] == "transfert_stock" && ! $_POST["cancel"])
+if ($action == "transfert_stock" && ! $_POST["cancel"])
{
if ($_POST["id_entrepot_source"] <> $_POST["id_entrepot_destination"])
{
- if (is_numeric($_POST["nbpiece"]))
+ if (is_numeric($_POST["nbpiece"]) && $id)
{
$product = new Product($db);
- $result=$product->fetch($_GET["id"]);
+ $result=$product->fetch($id);
$db->begin();
@@ -321,10 +324,10 @@ if ($_GET["id"] || $_GET["ref"])
/*
* Correct stock
*/
- if ($_GET["action"] == "correction")
+ if ($action == "correction")
{
print_titre($langs->trans("StockCorrection"));
- print "