New: Add label for stock movements

This commit is contained in:
Laurent Destailleur 2009-12-09 18:13:47 +00:00
parent 2d673dcfae
commit 03f11bf481
7 changed files with 96 additions and 44 deletions

View File

@ -10,10 +10,11 @@ For users:
- New: Can use {tttt} in numbering mask setup. It will be replaced
with third party type.
- New: VAT number is stored in one field. This is more "international".
- New: task #9782 : Add possibility to delete a warehouse
- Fix: bug #28055 : Unable to modify the date of a cloned command
- Fix: bug #27891
- Fix: Change of numbering module was not effective
- New: task #9782 : Add possibility to delete a warehouse.
- New: Add label for stock movements.
- Fix: bug #28055 : Unable to modify the date of a cloned command.
- Fix: bug #27891.
- Fix: Change of numbering module was not effective.
***** ChangeLog for 2.7 compared to 2.6 *****

View File

@ -9,3 +9,5 @@
ALTER TABLE llx_don ADD COLUMN ref varchar(30) DEFAULT NULL AFTER rowid;
ALTER TABLE llx_don ADD COLUMN entity integer DEFAULT 1 NOT NULL AFTER ref;
ALTER TABLE llx_stock_mouvement ADD COLUMN label varchar(128);

View File

@ -1,5 +1,6 @@
-- ============================================================================
-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
-- Copyright (C) 2009 Laurent Destailleur <eldy@users.sourceofrge.net>
--
-- 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
@ -28,6 +29,6 @@ create table llx_stock_mouvement
value integer,
price float(13,4) DEFAULT 0,
type_mouvement smallint,
fk_user_author integer
fk_user_author integer,
label varchar(128)
)type=innodb;

View File

@ -2161,12 +2161,13 @@ class Product extends CommonObject
/**
* \brief Ajuste le stock d'un entrepot pour le produit d'un delta donne
* \param user utilisateur qui demande l'ajustement
* \param id_entrepot id de l'entrepot
* \param nbpiece nombre de pieces
* \param mouvement 0 = ajout, 1 = suppression
* \param id_entrepot id of warehouse
* \param nbpiece nb of units
* \param mouvement 0 = add, 1 = remove
* \param label Label of stock movment
* \return int <0 if KO, >0 if OK
*/
function correct_stock($user, $id_entrepot, $nbpiece, $mouvement)
function correct_stock($user, $id_entrepot, $nbpiece, $mouvement, $label='')
{
if ($id_entrepot)
{
@ -2183,12 +2184,12 @@ class Product extends CommonObject
if ($row->nb > 0)
{
// Record already exists, we make an update
$result=$this->ajust_stock($user, $id_entrepot, $nbpiece, $mouvement);
$result=$this->ajust_stock($user, $id_entrepot, $nbpiece, $mouvement, $label);
}
else
{
// Record not yet available, we make an insert
$result=$this->create_stock($user, $id_entrepot, $nbpiece, $mouvement);
$result=$this->create_stock($user, $id_entrepot, $nbpiece, $mouvement, $label);
}
}
@ -2208,14 +2209,15 @@ class Product extends CommonObject
/**
* \brief Augmente ou reduit la valeur de stock pour le produit
* \param user utilisateur qui demande l'ajustement
* \param id_entrepot id de l'entrepot
* \param nbpiece nombre de pieces
* \param movement 0 = ajout, 1 = suppression
* \param user user that make change
* \param id_entrepot id of warehouse
* \param nbpiece nb of units
* \param movement 0 = add, 1 = remove
* \param label Label of stock movment
* \return int <0 if KO, >0 if OK
* \remarks Called by correct_stock
*/
function ajust_stock($user, $id_entrepot, $nbpiece, $movement)
function ajust_stock($user, $id_entrepot, $nbpiece, $movement, $label='')
{
require_once(DOL_DOCUMENT_ROOT ."/product/stock/mouvementstock.class.php");
@ -2223,21 +2225,22 @@ class Product extends CommonObject
$op[1] = "-".trim($nbpiece);
$movementstock=new MouvementStock($this->db);
$result=$movementstock->_create($user,$this->id,$id_entrepot,$op[$movement],0,0);
$result=$movementstock->_create($user,$this->id,$id_entrepot,$op[$movement],0,0,$label);
return $result;
}
/**
* \brief Entre un nombre de piece du produit en stock dans un entrepot
* \param user utilisateur qui demande l'ajustement
* \param id_entrepot id de l'entrepot
* \param nbpiece nombre de pieces
* \param movement 0 = ajout, 1 = suppression
* \param user user that make change
* \param id_entrepot id of warehouse
* \param nbpiece nb of units
* \param movement 0 = add, 1 = remove
* \param label Label of stock movment
* \return int <0 if KO, >0 if OK
* \remarks Called by correct_stock
*/
function create_stock($user, $id_entrepot, $nbpiece, $movement=0)
function create_stock($user, $id_entrepot, $nbpiece, $movement=0, $label='')
{
require_once(DOL_DOCUMENT_ROOT ."/product/stock/mouvementstock.class.php");
@ -2245,7 +2248,7 @@ class Product extends CommonObject
$op[1] = "-".trim($nbpiece);
$movementstock=new MouvementStock($this->db);
$result=$movementstock->_create($user,$this->id,$id_entrepot,$op[$movement],0,0);
$result=$movementstock->_create($user,$this->id,$id_entrepot,$op[$movement],0,0,$label);
return $result;
}

View File

@ -21,7 +21,7 @@
/**
* \file htdocs/product/stock/mouvement.php
* \ingroup stock
* \brief Page liste des mouvements de stocks
* \brief Page to list stock movements
* \version $Id$
*/
@ -40,6 +40,7 @@ if (!$user->rights->produit->lire) accessforbidden();
$idproduct = isset($_GET["idproduct"])?$_GET["idproduct"]:$_PRODUCT["idproduct"];
$year = isset($_GET["year"])?$_GET["year"]:$_POST["year"];
$month = isset($_GET["month"])?$_GET["month"]:$_POST["month"];
$search_movment = isset($_REQUEST["search_movment"])?$_REQUEST["search_movment"]:'';
$search_product = isset($_REQUEST["search_product"])?$_REQUEST["search_product"]:'';
$search_warehouse = isset($_REQUEST["search_warehouse"])?$_REQUEST["search_warehouse"]:'';
$search_user = isset($_REQUEST["search_user"])?$_REQUEST["search_user"]:'';
@ -56,6 +57,7 @@ if ($_REQUEST["button_removefilter"])
{
$year='';
$month='';
$search_movment="";
$search_product="";
$search_warehouse="";
$search_user="";
@ -74,7 +76,7 @@ $form=new Form($db);
$sql = "SELECT p.rowid, p.label as produit, p.fk_product_type as type,";
$sql.= " s.label as stock, s.rowid as entrepot_id,";
$sql.= " m.rowid as mid, m.value, m.datem, m.fk_user_author,";
$sql.= " m.rowid as mid, m.value, m.datem, m.fk_user_author, m.label,";
$sql.= " u.login";
$sql.= " FROM ".MAIN_DB_PREFIX."entrepot as s,";
$sql.= " ".MAIN_DB_PREFIX."stock_mouvement as m,";
@ -107,6 +109,10 @@ else if ($year > 0)
{
$sql.= " AND m.datem between '".dol_get_first_day($year)."' AND '".dol_get_last_day($year)."'";
}
if (! empty($search_movment))
{
$sql.= " AND m.label LIKE '%".addslashes($search_movment)."%'";
}
if (! empty($search_product))
{
$sql.= " AND p.label LIKE '%".addslashes($search_product)."%'";
@ -232,9 +238,13 @@ if ($resql)
$param='';
if ($_GET["id"]) $param.='&id='.$_GET["id"];
if ($search_movment) $param.='&search_movment='.urlencode($search_movment);
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 ($idproduct > 0) $param.='&idproduct='.$idproduct;
if ($search_user) $param.='&search_user='.urlencode($search_user);
if ($idproduct > 0) $param.='&idproduct='.$idproduct;
if ($_GET["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);
@ -242,6 +252,7 @@ if ($resql)
print "<tr class=\"liste_titre\">";
//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"], "s.label","",$param,"",$sortfield,$sortorder);
print_liste_field_titre($langs->trans("Author"),$_SERVER["PHP_SELF"], "m.fk_user_author","",$param,"",$sortfield,$sortorder);
@ -259,8 +270,13 @@ if ($resql)
$syear = $year;
$form->select_year($syear,'year',1, '', $max_year);
print '</td>';
// Label of movment
print '<td class="liste_titre" align="left">';
print '<input class="flat" type="text" size="20" name="search_product" value="'.($idproduct?$product->libelle:$_GET['search_product']).'">';
print '<input class="flat" type="text" size="12" name="search_movment" value="'.$search_movment.'">';
print '</td>';
// Product
print '<td class="liste_titre" align="left">';
print '<input class="flat" type="text" size="12" name="search_product" value="'.($idproduct?$product->libelle:$search_product).'">';
print '</td>';
print '<td class="liste_titre" align="left">';
print '<input class="flat" type="text" size="10" name="search_warehouse" value="'.($search_warehouse).'">';
@ -284,6 +300,8 @@ if ($resql)
//print '<td>'.$objp->mid.'</td>'; // This is primary not movement id
// Date
print '<td>'.dol_print_date($db->jdate($objp->datem),'dayhour').'</td>';
// Lbale of movment
print '<td>'.$objp->label.'</td>';
// Product
print '<td>';
$productstatic->id=$objp->rowid;

View File

@ -45,14 +45,15 @@ class MouvementStock
* \param qty Qty of movement (can be <0 or >0)
* \param type Direction of movement: 2=output (stock decrease), 3=input (stock increase)
* \param type Unit price HT of product
* \pamam label Label of stock movment
* \return int <0 if KO, >0 if OK
*/
function _create($user, $fk_product, $entrepot_id, $qty, $type, $price=0)
function _create($user, $fk_product, $entrepot_id, $qty, $type, $price=0, $label='')
{
global $conf;
$error = 0;
dol_syslog("MouvementStock::_create start userid=$user->id, fk_product=$fk_product, warehouse=$entrepot_id, qty=$qty, type=$type, price=$price");
dol_syslog("MouvementStock::_create start userid=$user->id, fk_product=$fk_product, warehouse=$entrepot_id, qty=$qty, type=$type, price=$price label=$label");
$this->db->begin();
@ -67,9 +68,11 @@ class MouvementStock
if (1 == 1) // Always change stock for current product, change for subproduct is done after
{
$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(gmmktime()).", ".$fk_product.", ".$entrepot_id.", ".$qty.", ".$type.", ".$user->id;
$sql.= ",'".price2num($price)."')";
$sql.= " (datem, fk_product, fk_entrepot, value, type_mouvement, fk_user_author, label, price)";
$sql.= " VALUES (".$this->db->idate(gmmktime()).", ".$fk_product.", ".$entrepot_id.", ".$qty.", ".$type.",";
$sql.= " ".$user->id.",";
$sql.= " '".addslashes($label)."',";
$sql.= " '".price2num($price)."')";
dol_syslog("MouvementStock::_create sql=".$sql, LOG_DEBUG);
if ($resql = $this->db->query($sql))

View File

@ -58,6 +58,7 @@ if ($_POST["action"] == "create_stock" && ! $_POST["cancel"])
$product->create_stock($user, $_POST["id_entrepot"], $_POST["nbpiece"]);
}
// Transfer stock
if ($_POST["action"] == "correct_stock" && ! $_POST["cancel"])
{
if (is_numeric($_POST["nbpiece"]))
@ -67,10 +68,12 @@ if ($_POST["action"] == "correct_stock" && ! $_POST["cancel"])
$product->correct_stock($user,
$_POST["id_entrepot"],
$_POST["nbpiece"],
$_POST["mouvement"]);
$_POST["mouvement"],
$_POST["label"]);
}
}
// Correct stock
if ($_POST["action"] == "transfert_stock" && ! $_POST["cancel"])
{
if ($_POST["id_entrepot_source"] <> $_POST["id_entrepot_destination"])
@ -85,12 +88,14 @@ if ($_POST["action"] == "transfert_stock" && ! $_POST["cancel"])
$result1=$product->correct_stock($user,
$_POST["id_entrepot_source"],
$_POST["nbpiece"],
1);
1,
$_POST["label"]);
$result2=$product->correct_stock($user,
$_POST["id_entrepot_destination"],
$_POST["nbpiece"],
0);
0,
$_POST["label"]);
if ($result1 >= 0 && $result2 >= 0)
{
@ -268,10 +273,11 @@ if ($_GET["id"] || $_GET["ref"])
print "<form action=\"product.php?id=$product->id\" method=\"post\">\n";
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="correct_stock">';
print '<table class="border" width="100%"><tr>';
print '<td width="20%">'.$langs->trans("Warehouse").'</td>';
print '<table class="border" width="100%">';
// Entrepot
// Warehouse
print '<tr>';
print '<td width="20%">'.$langs->trans("Warehouse").'</td>';
print '<td width="20%">';
$formproduct->selectWarehouses($_GET["dwid"],'id_entrepot','',1);
print '</td>';
@ -281,8 +287,16 @@ if ($_GET["id"] || $_GET["ref"])
print '<option value="1">'.$langs->trans("Delete").'</option>';
print '</select></td>';
print '<td width="20%">'.$langs->trans("NumberOfUnit").'</td><td width="20%"><input class="flat" name="nbpiece" size="10" value=""></td>';
print '</tr>';
// Label
print '<tr>';
print '<td width="20%">'.$langs->trans("Label").'</td>';
print '<td colspan="4">';
print '<input type="text" name="label" size="40" value="">';
print '</td>';
print '</tr>';
print '<tr><td colspan="5" align="center"><input type="submit" class="button" value="'.$langs->trans('Save').'">&nbsp;';
print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'"></td></tr>';
print '</table>';
@ -291,7 +305,7 @@ if ($_GET["id"] || $_GET["ref"])
}
/*
* Transfert of units
* Transfer of units
*/
if ($_GET["action"] == "transfert")
{
@ -299,16 +313,26 @@ if ($_GET["id"] || $_GET["ref"])
print "<form action=\"product.php?id=$product->id\" method=\"post\">\n";
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="transfert_stock">';
print '<table class="border" width="100%"><tr>';
print '<table class="border" width="100%">';
print '<tr>';
print '<td width="20%">'.$langs->trans("WarehouseSource").'</td><td width="20%">';
$formproduct->selectWarehouses($_GET["dwid"],'id_entrepot_source','',1);
print '</td>';
print '<td width="20%">'.$langs->trans("WarehouseTarget").'</td><td width="20%">';
$formproduct->selectWarehouses('','id_entrepot_destination','',1);
print '</td>';
print '<td width="20%">'.$langs->trans("NumberOfUnit").'</td><td width="20%"><input name="nbpiece" size="10" value=""></td>';
print '</tr>';
// Label
print '<tr>';
print '<td width="20%">'.$langs->trans("Label").'</td>';
print '<td colspan="5">';
print '<input type="text" name="label" size="40" value="">';
print '</td>';
print '</tr>';
print '<td width="20%">'.$langs->trans("NumberOfUnit").'</td><td width="20%"><input name="nbpiece" size="10" value=""></td></tr>';
print '<tr><td colspan="6" align="center"><input type="submit" class="button" value="'.$langs->trans('Save').'">&nbsp;';
print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'"></td></tr>';
print '</table>';