diff --git a/htdocs/includes/modules/modProduit.class.php b/htdocs/includes/modules/modProduit.class.php index e5532ebf4cf..291ebef11a5 100644 --- a/htdocs/includes/modules/modProduit.class.php +++ b/htdocs/includes/modules/modProduit.class.php @@ -74,7 +74,7 @@ class modProduit extends DolibarrModules // Config pages $this->config_page_url = array("produit.php"); - $this->langfiles = array("products","companies"); + $this->langfiles = array("products","companies","stocks"); // Constantes $this->const = array(); @@ -140,9 +140,9 @@ class modProduit extends DolibarrModules $this->export_code[$r]=$this->rights_class.'_'.$r; $this->export_label[$r]="ProductsOrServices"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r]=array(array("produit","export")); - $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",'p.fk_product_type'=>"Type",'p.label'=>"Label",'p.description'=>"Description",'p.note'=>"Note",'p.price'=>"Price",'p.tva_tx'=>'VAT','p.envente'=>"OnSell",'p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification'); - $this->export_entities_array[$r]=array('p.rowid'=>"product",'p.ref'=>"product",'p.fk_product_type'=>"product",'p.label'=>"product",'p.description'=>"product",'p.note'=>"product",'p.price'=>"product",'p.tva_tx'=>'product','p.envente'=>"product",'p.duration'=>"product",'p.datec'=>'product','p.tms'=>'product'); - $this->export_alias_array[$r]=array('p.rowid'=>"id",'p.ref'=>"ref",'p.fk_product_type'=>"type",'p.label'=>"label",'p.description'=>"description",'p.note'=>"note",'p.price'=>"price",'p.tva_tx'=>'vat','p.envente'=>"onsell",'p.duration'=>"duration",'p.datec'=>'datecreation','p.tms'=>'datemodification'); + $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",'p.fk_product_type'=>"Type",'p.label'=>"Label",'p.description'=>"Description",'p.note'=>"Note",'p.price'=>"Price",'p.tva_tx'=>'VAT','p.envente'=>"OnSell",'p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification','p.stock'=>'Stock','p.pmp'=>'PMPValue'); + $this->export_entities_array[$r]=array('p.rowid'=>"product",'p.ref'=>"product",'p.fk_product_type'=>"product",'p.label'=>"product",'p.description'=>"product",'p.note'=>"product",'p.price'=>"product",'p.tva_tx'=>'product','p.envente'=>"product",'p.duration'=>"product",'p.datec'=>'product','p.tms'=>'product','p.stock'=>'product','p.pmp'=>'product'); + $this->export_alias_array[$r]=array('p.rowid'=>"id",'p.ref'=>"ref",'p.fk_product_type'=>"type",'p.label'=>"label",'p.description'=>"description",'p.note'=>"note",'p.price'=>"price",'p.tva_tx'=>'vat','p.envente'=>"onsell",'p.duration'=>"duration",'p.datec'=>'datecreation','p.tms'=>'datemodification','p.stock'=>'stock','p.pmp'=>'pmp'); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php index 7b9de7bf47b..c6014b5d2cd 100644 --- a/htdocs/install/upgrade2.php +++ b/htdocs/install/upgrade2.php @@ -195,6 +195,10 @@ if (isset($_POST['action']) && $_POST['action'] == 'upgrade') migrate_module_menus($db,$langs,$conf); + // Script pour V2.5 -> V2.6 + migrate_stocks($db,$langs,$conf); + + // On commit dans tous les cas. // La procedure etant concue pour pouvoir passer plusieurs fois quelquesoit la situation. $db->commit(); @@ -1887,6 +1891,76 @@ function migrate_detail_livraison($db,$langs,$conf) print ''; } + + +/* + * Migration du champ stock dans produits + */ +function migrate_stocks($db,$langs,$conf) +{ + print ''; + + print '
'; + print ''.$langs->trans('MigrationStockDetail')."
\n"; + + $error = 0; + + $db->begin(); + + $sql = "SELECT SUM(reel) as total, fk_product"; + $sql.= " FROM ".MAIN_DB_PREFIX."product_stock as ps"; + $sql.= " GROUP BY fk_product"; + $resql = $db->query($sql); + if ($resql) + { + $i = 0; + $num = $db->num_rows($resql); + + if ($num) + { + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + $sql = "UPDATE ".MAIN_DB_PREFIX."product SET"; + $sql.= " stock = '".$obj->total."'"; + $sql.= " WHERE rowid=".$obj->fk_product; + + $resql2=$db->query($sql); + if ($resql2) + { + + } + else + { + $error++; + dolibarr_print_error($db); + } + print ". "; + $i++; + } + + } + + if ($error == 0) + { + $db->commit(); + } + else + { + $db->rollback(); + } + } + else + { + dolibarr_print_error($db); + $db->rollback(); + } + + print ''; +} + + /* A faire egalement: Modif statut paye et fk_facture des factures payes completement On recherche facture incorrecte: diff --git a/htdocs/langs/en_US/install.lang b/htdocs/langs/en_US/install.lang index dead39930df..7d637064d7e 100644 --- a/htdocs/langs/en_US/install.lang +++ b/htdocs/langs/en_US/install.lang @@ -186,3 +186,5 @@ MigrationShipmentOrderMatching=Sendings receipt update MigrationDeliveryOrderMatching=Delivery receipt update MigrationDeliveryDetail=Delivery update +# Migration stock +MigrationStockDetail=Update stock value of products diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index b92ccf009cf..83c46e5361d 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -35,7 +35,8 @@ NumberOfUnit=Number of units TotalStock=Total in stock StockTooLow=Stock too low EnhancedValue=Value -PMPValue=Value +PMPValue=Weighted average price +PMPValueShort=WAP EnhancedValueOfWarehouses=Warehouses value UserWarehouseAutoCreate=Create a stock automatically when creating a user QtyDispatched=Quantity dispatched diff --git a/htdocs/langs/fr_FR/install.lang b/htdocs/langs/fr_FR/install.lang index 14680db2e80..c71cc625714 100644 --- a/htdocs/langs/fr_FR/install.lang +++ b/htdocs/langs/fr_FR/install.lang @@ -187,3 +187,7 @@ MigrationShipmentOrderMatching=Mise a jour bon expedition MigrationDeliveryOrderMatching=Mise a jour bon reception MigrationDeliveryDetail=Mise a jour bon reception +# Migration stock +MigrationStockDetail=Mise a jour valeur en stock des produits + + diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index 092ff0be2a2..76b633c30ec 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -36,6 +36,7 @@ TotalStock=Total en stock StockTooLow=Stock insuffisant EnhancedValue=Valorisation PMPValue=Valorisation (PMP) +PMPValueShort=PMP EnhancedValueOfWarehouses=Valorisation des stocks UserWarehouseAutoCreate=Créer un stock automatiquement à la création d'un utilisateur QtyDispatched=Quantité ventilée diff --git a/htdocs/oscommerce_ws/produits/fiche.php b/htdocs/oscommerce_ws/produits/fiche.php index 002effd0ac3..cd9ffd8a0cf 100644 --- a/htdocs/oscommerce_ws/produits/fiche.php +++ b/htdocs/oscommerce_ws/produits/fiche.php @@ -26,144 +26,144 @@ llxHeader(); if ($action == '' && !$cancel) { - if ($_GET['id']) - { - $osc_prod = new Osc_product($db, $_GET['id']); - $result = $osc_prod->fetch($_GET['id']); + if ($_GET['id']) + { + $osc_prod = new Osc_product($db, $_GET['id']); + $result = $osc_prod->fetch($_GET['id']); - if ( !$result) - { - print '
Fiche article OSC : '.$osc_prod->osc_name.'

'; + if ( !$result) + { + print '
Fiche article OSC : '.$osc_prod->osc_name.'

'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "
Descrption'.$osc_prod->osc_desc.'
ref'.$osc_prod->osc_ref.'
Id'.$osc_prod->osc_id.'
Prix'.$osc_prod->osc_price.'
Four_id'.$osc_prod->osc_four.'
"; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "
Descrption'.$osc_prod->osc_desc.'
ref'.$osc_prod->osc_ref.'
Id'.$osc_prod->osc_id.'
Prix'.$osc_prod->osc_price.'
Four_id'.$osc_prod->osc_four.'
"; - /* ************************************************************************** */ - /* */ - /* Barre d'action */ - /* */ - /* ************************************************************************** */ - print "\n
\n"; + /* ************************************************************************** */ + /* */ + /* Barre d'action */ + /* */ + /* ************************************************************************** */ + print "\n
\n"; if ( $user->rights->produit->creer) { - print ''.$langs->trans("Import").''; - } + print ''.$langs->trans("Import").''; + } - print ''.$langs->trans("Retour").''; - print "\n

\n"; -// seule action importer - - } - else - { - print "

ERROR 1

\n"; - dolibarr_print_error('',"erreur webservice ".$osc_prod->error); - } - } - else - { - print "

ERROR 1

\n"; - print "Error"; - } -} -/* action Import création de l'objet product de dolibarr -* -*/ + print ''.$langs->trans("Retour").''; + print "\n

\n"; + // seule action importer - if (($_GET["action"] == 'import' ) && ( $_GET["id"] != '' ) && $user->rights->produit->creer) - { - $osc_prod = new Osc_product($db, $_GET['id']); - $result = $osc_prod->fetch($_GET['id']); - - if ( !$result ) - { - $product = new Product($db); - if ($_error == 1) - { - print '
erreur 1
'; - // exit; - } - $product = $osc_prod->osc2dolibarr($_GET['id']); - - } + } else { - print "

erreur $osc_prod->fetch

"; + print "

ERROR 1

\n"; + dolibarr_print_error('',"erreur webservice ".$osc_prod->error); } + } + else + { + print "

ERROR 1

\n"; + print "Error"; + } +} +/* action Import création de l'objet product de dolibarr + * + */ -/* utilisation de la table de transco*/ - if ($osc_prod->get_productid($osc_prod->osc_id)>0) +if (($_GET["action"] == 'import' ) && ( $_GET["id"] != '' ) && $user->rights->produit->creer) +{ + $osc_prod = new Osc_product($db, $_GET['id']); + $result = $osc_prod->fetch($_GET['id']); + + if ( !$result ) + { + $product = new Product($db); + if ($_error == 1) { - print '

Ce produit existe déjà

'; + print '
erreur 1
'; + // exit; } - else + $product = $osc_prod->osc2dolibarr($_GET['id']); + + } + else + { + print "

erreur $osc_prod->fetch

"; + } + + /* utilisation de la table de transco*/ + if ($osc_prod->get_productid($osc_prod->osc_id)>0) + { + print '

Ce produit existe déjà

'; + } + else + { + + $id = $product->create($user); + + if ($id > 0) { + print "\n
\n"; + $prod = new Product($db); + $res = $prod->fetch($id); - $id = $product->create($user); - - if ($id > 0) - { - print "\n
\n"; - $prod = new Product($db); - $res = $prod->fetch($id); + $prod->add_photo_web($conf->produit->dir_output,$osc_prod->osc_image); + print '

création réussie produit '.$id.' référence : '.$product->ref; + $res = $osc_prod->transcode($osc_prod->osc_id,$product->id); - $prod->add_photo_web($conf->produit->dir_output,$osc_prod->osc_image); - print '

création réussie produit '.$id.' référence : '.$product->ref; - $res = $osc_prod->transcode($osc_prod->osc_id,$product->id); + print ' Id osc : '.$osc_prod->osc_id.'

'; + print ''.$langs->trans("Retour").''; - print ' Id osc : '.$osc_prod->osc_id.'

'; - print ''.$langs->trans("Retour").''; - - print "\n

\n"; - $id_entrepot = OSC_ENTREPOT; - $id = $product->create_stock($id_entrepot,$osc_prod->osc_stock); -// if ($id > 0) exit; - } - else - { - print "

On a une erreur".$id."

"; - if ($id == -3) - { - $_error = 1; - $_GET["action"] = "create"; - $_GET["type"] = $_POST["type"]; - } - if ($id == -2) - { - /* la référence existe on fait un update */ - $product_control = new Product($db); - if ($_error == 1) - { - print '
erreur 1
'; - // exit; - } - $id = $product_control->fetch($ref = $osc_prod->osc_ref); - - if ($id > 0) - { - $id = $product->update($id, $user); - if ($id > 0) - { - $id_entrepot = 1; - $id = $product->correct_stock($user, $id_entrepot,$osc_prod->osc_stock, 0); - } - else print '
Erreur update '.$product->error().'
'; - } - else print '
update impossible $id : '.$product_control->error().'
'; - } - if ($id == -1) - { - print '

erreur'.$product->error().'

'; - } - print '

'.$langs->trans("Retour").'

'; + print "\n

\n"; + $id_entrepot = OSC_ENTREPOT; + $id = $product->create_stock($user, $id_entrepot,$osc_prod->osc_stock); + // if ($id > 0) exit; + } + else + { + print "

On a une erreur".$id."

"; + if ($id == -3) + { + $_error = 1; + $_GET["action"] = "create"; + $_GET["type"] = $_POST["type"]; } + if ($id == -2) + { + /* la référence existe on fait un update */ + $product_control = new Product($db); + if ($_error == 1) + { + print '
erreur 1
'; + // exit; + } + $id = $product_control->fetch($ref = $osc_prod->osc_ref); + + if ($id > 0) + { + $id = $product->update($id, $user); + if ($id > 0) + { + $id_entrepot = 1; + $id = $product->correct_stock($user, $id_entrepot,$osc_prod->osc_stock, 0); + } + else print '
Erreur update '.$product->error().'
'; + } + else print '
update impossible $id : '.$product_control->error().'
'; + } + if ($id == -1) + { + print '

erreur'.$product->error().'

'; + } + print '

'.$langs->trans("Retour").'

'; } - } + } +} llxFooter('$Date$ - $Revision$'); ?> diff --git a/htdocs/product.class.php b/htdocs/product.class.php index 478bcca51b7..e397b4cf36d 100644 --- a/htdocs/product.class.php +++ b/htdocs/product.class.php @@ -940,6 +940,7 @@ class Product extends CommonObject $this->barcode_type = $result["fk_barcode_type"]; $this->stock_in_command = 0; // TODO + $this->stock_in_propal = 0; // TODO $this->label_url = ''.$this->libelle.''; @@ -2110,68 +2111,25 @@ class Product extends CommonObject return ''; } - /** - * \brief Entre un nombre de piece du produit en stock dans un entrep�t - * \param id_entrepot id de l'entrepot - * \param nbpiece nombre de pieces - */ - function create_stock($id_entrepot, $nbpiece) - { - global $user; - - $op[0] = "+".trim($nbpiece); - $op[1] = "-".trim($nbpiece); - $mouvement=0; // We add pieces - - $this->db->begin(); - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_stock "; - $sql .= " (fk_product, fk_entrepot, reel)"; - $sql .= " VALUES ($this->id, $id_entrepot, $nbpiece)"; - - dolibarr_syslog("Product::create_stock sql=".$sql); - $resql=$this->db->query($sql); - if ($resql) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."stock_mouvement (datem, fk_product, fk_entrepot, value, type_mouvement, fk_user_author)"; - $sql .= " VALUES (".$this->db->idate(mktime()).", ".$this->id.", ".$id_entrepot.", ".$nbpiece.", 0, ".$user->id.")"; - - dolibarr_syslog("Product::create_stock sql=".$sql); - $resql=$this->db->query($sql); - if ($resql) - { - $this->db->commit(); - return 1; - } - else - { - dolibarr_print_error($this->db); - $this->db->rollback(); - return -2; - } - } - else - { - dolibarr_print_error($this->db); - return -1; - } - } - /** - * \brief Ajuste le stock d'un entrepot pour le produit a une valeure donnee - * \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 + * \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 + * \return int <0 if KO, >0 if OK */ function correct_stock($user, $id_entrepot, $nbpiece, $mouvement) { if ($id_entrepot) { + $this->db->begin(); + $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."product_stock"; $sql .= " WHERE fk_product = ".$this->id." AND fk_entrepot = ".$id_entrepot; + dol_syslog("Product::correct_stock sql=".$sql, LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { @@ -2179,14 +2137,20 @@ class Product extends CommonObject if ($row->nb > 0) { // Record already exists, we make an update - return $this->ajust_stock($user, $id_entrepot, $nbpiece, $mouvement); + $result=$this->ajust_stock($user, $id_entrepot, $nbpiece, $mouvement); } else { // Record not yet available, we make an insert - return $this->create_stock($id_entrepot, $nbpiece); + $result=$this->create_stock($user, $id_entrepot, $nbpiece, $mouvement); } } + + if ($result >= 0) + { + $this->db->commit(); + return 1; + } else { dolibarr_print_error($this->db); @@ -2201,51 +2165,47 @@ class Product extends CommonObject * \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 movement 0 = ajout, 1 = suppression + * \return int <0 if KO, >0 if OK * \remarks Called by correct_stock */ - function ajust_stock($user, $id_entrepot, $nbpiece, $mouvement) + function ajust_stock($user, $id_entrepot, $nbpiece, $movement) { + require_once(DOL_DOCUMENT_ROOT ."/product/stock/mouvementstock.class.php"); + $op[0] = "+".trim($nbpiece); $op[1] = "-".trim($nbpiece); - $this->db->begin(); + $movementstock=new MouvementStock($this->db); + $result=$movementstock->_create($user,$this->id,$id_entrepot,$op[$movement],0,0); - $sql = "UPDATE ".MAIN_DB_PREFIX."product_stock"; - $sql.= " SET reel = reel ".$op[$mouvement]; - $sql.= " WHERE fk_product = ".$this->id." AND fk_entrepot = ".$id_entrepot; - - dolibarr_syslog("Product::ajust_stock sql=".$sql); - $resql=$this->db->query($sql); - if ($resql) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."stock_mouvement (datem, fk_product, fk_entrepot, value, type_mouvement, fk_user_author)"; - $sql .= " VALUES (".$this->db->idate(mktime()).", ".$this->id.", ".$id_entrepot.", ".$op[$mouvement].", 0, ".$user->id.")"; - - dolibarr_syslog("Product::ajust_stock sql=".$sql); - $resql=$this->db->query($sql); - if ($resql) - { - $this->db->commit(); - return 1; - } - else - { - dolibarr_print_error($this->db); - $this->db->rollback(); - return -2; - } - } - else - { - dolibarr_print_error($this->db); - $this->db->rollback(); - return -1; - } + return $result; } /** - * \brief Charge les informations en stock du produit + * \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 + * \return int <0 if KO, >0 if OK + * \remarks Called by correct_stock + */ + function create_stock($user, $id_entrepot, $nbpiece, $movement=0) + { + require_once(DOL_DOCUMENT_ROOT ."/product/stock/mouvementstock.class.php"); + + $op[0] = "+".trim($nbpiece); + $op[1] = "-".trim($nbpiece); + + $movementstock=new MouvementStock($this->db); + $result=$movementstock->_create($user,$this->id,$id_entrepot,$op[$movement],0,0); + + return $result; + } + + /** + * \brief Charge les informations en stock du produit dans stock_entrepot[] et stock_reel * \return int < 0 si erreur, > 0 si ok */ function load_stock() @@ -2255,6 +2215,8 @@ class Product extends CommonObject $sql = "SELECT reel, fk_entrepot"; $sql.= " FROM ".MAIN_DB_PREFIX."product_stock"; $sql.= " WHERE fk_product = '".$this->id."'"; + + dol_syslog("Product::load_stock sql=".$sql); $result = $this->db->query($sql) ; if ($result) { @@ -2288,11 +2250,11 @@ class Product extends CommonObject /** - * \brief D�place fichier upload� sous le nom $files dans le r�pertoire sdir - * \param sdir R�pertoire destination finale - * \param $file Nom du fichier upload� - * \param maxWidth Largeur maximum que dois faire la miniature (160 par d�faut) - * \param maxHeight Hauteur maximum que dois faire la miniature (120 par d�faut) + * \brief Deplace fichier uploade sous le nom $files dans le repertoire sdir + * \param sdir Repertoire destination finale + * \param $file Nom du fichier uploade + * \param maxWidth Largeur maximum que dois faire la miniature (160 par defaut) + * \param maxHeight Hauteur maximum que dois faire la miniature (120 par defaut) */ function add_photo($sdir, $file, $maxWidth = 160, $maxHeight = 120) { @@ -2301,7 +2263,7 @@ class Product extends CommonObject if (! file_exists($dir)) { - dolibarr_syslog("Product Create $dir"); + dol_syslog("Product Create $dir"); create_exdir($dir); } @@ -2350,7 +2312,7 @@ class Product extends CommonObject if (! file_exists($dir)) { - dolibarr_syslog("Product Create $dir"); + dol_syslog("Product Create $dir"); create_exdir($dir); } @@ -2553,7 +2515,7 @@ class Product extends CommonObject } /** - * \brief R�cup�re la taille de l'image + * \brief Recupere la taille de l'image * \param file Chemin de l'image */ function get_image_size($file) @@ -2603,7 +2565,7 @@ class Product extends CommonObject } /** - * \brief Mise � jour du code barre + * \brief Mise a jour du code barre * \param user Utilisateur qui fait la modification */ function update_barcode($user) @@ -2612,7 +2574,7 @@ class Product extends CommonObject $sql .= " SET barcode = '".$this->barcode."'"; $sql .= " WHERE rowid = ".$this->id; - dolibarr_syslog("Product::update_barcode sql=".$sql); + dol_syslog("Product::update_barcode sql=".$sql); $resql=$this->db->query($sql); if ($resql) { @@ -2626,7 +2588,7 @@ class Product extends CommonObject } /** - * \brief Mise � jour du type de code barre + * \brief Mise a jour du type de code barre * \param user Utilisateur qui fait la modification */ function update_barcode_type($user) @@ -2635,7 +2597,7 @@ class Product extends CommonObject $sql .= " SET fk_barcode_type = '".$this->barcode_type."'"; $sql .= " WHERE rowid = ".$this->id; - dolibarr_syslog("Product::update_barcode_type sql=".$sql); + dol_syslog("Product::update_barcode_type sql=".$sql); $resql=$this->db->query($sql); if ($resql) { diff --git a/htdocs/product/stock/mouvementstock.class.php b/htdocs/product/stock/mouvementstock.class.php index 98f585ce492..79bd9eda19d 100644 --- a/htdocs/product/stock/mouvementstock.class.php +++ b/htdocs/product/stock/mouvementstock.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2005 Laurent Destailleur + * Copyright (C) 2005-2009 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,7 +38,7 @@ class MouvementStock } /** - * \brief Add a mouvement in stock (in one direction only) + * \brief Add a movement 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 */ @@ -47,17 +47,15 @@ class MouvementStock global $conf; $error = 0; - dolibarr_syslog("MouvementStock::_Create $user->id, $fk_product, $entrepot_id, qty=$qty, type=$type, $price"); + dolibarr_syslog("MouvementStock::_create $user->id, $fk_product, $entrepot_id, qty=$qty, type=$type, $price"); $this->db->begin(); - // $nbOfSubproduct=$this->nbOfSubProdcuts(); - - if (1 == 1) // Always change stock for current product + if (1 == 1) // Always change stock for current product, change for subproduct 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(mktime()).", ".$fk_product.", ".$entrepot_id.", ".$qty.", ".$type.", ".$user->id; + $sql.= " VALUES (".$this->db->idate(gmmktime()).", ".$fk_product.", ".$entrepot_id.", ".$qty.", ".$type.", ".$user->id; $sql.= ",'".price2num($price)."')"; dolibarr_syslog("MouvementStock::_create sql=".$sql, LOG_DEBUG); @@ -67,7 +65,7 @@ class MouvementStock } else { - dolibarr_syslog("MouvementStock::_Create ".$this->error); + dolibarr_syslog("MouvementStock::_create ".$this->error); $error = -1; } @@ -85,12 +83,12 @@ class MouvementStock } else { - dolibarr_syslog("MouvementStock::_Create echec update ".$this->error); + dolibarr_syslog("MouvementStock::_create echec update ".$this->error); $error = -2; } } - // Update value + // Update denormalized value of stock in product_stock and product if ($error == 0) { if ($num > 0) @@ -105,16 +103,29 @@ class MouvementStock $sql.= " (".$qty.",".$entrepot_id.",".$fk_product.")"; } - dolibarr_syslog("MouvementStock::_Create sql=".$sql, LOG_DEBUG); + dolibarr_syslog("MouvementStock::_create sql=".$sql, LOG_DEBUG); if ($this->db->query($sql)) { - // TODO - // Update value of PMP in product_stock - + $sql = "UPDATE ".MAIN_DB_PREFIX."product SET stock = stock + ".$qty; + $sql.= " WHERE rowid = ".$fk_product; + + dolibarr_syslog("MouvementStock::_create sql=".$sql, LOG_DEBUG); + if ($this->db->query($sql)) + { + + // TODO + // Update value of PMP in product_stock + } + else + { + dolibarr_syslog("MouvementStock::_create ".$this->error, LOG_ERR); + $error = -4; + } + } else { - dolibarr_syslog("MouvementStock::_Create ".$this->error, LOG_ERR); + dolibarr_syslog("MouvementStock::_create ".$this->error, LOG_ERR); $error = -3; } } @@ -144,7 +155,7 @@ class MouvementStock { $error = $this->_createProductComposition($user, $fk_product, $entrepot_id, $qty, $type, $price=0); } - + if ($error == 0) { $this->db->commit(); @@ -153,8 +164,8 @@ class MouvementStock else { $this->db->rollback(); - $this->error=$this->db->error(); - dolibarr_syslog("MouvementStock::_Create ".$this->error); + $this->error=$this->db->lasterror(); + dolibarr_syslog("MouvementStock::_create ".$this->error); return -2; } } @@ -202,15 +213,13 @@ class MouvementStock return $error; } - + /** * \brief Crée un mouvement en base pour toutes les compositions de produits * \return int <0 si ko, 0 si ok */ function _createProductComposition($user, $fk_product, $entrepot_id, $qty, $type, $price=0) { - - dolibarr_syslog("MouvementStock::_createComposition $user->id, $fk_product, $entrepot_id, $qty, $type, $price"); $products_compo = array(); @@ -242,7 +251,7 @@ class MouvementStock return 0; } - + /** * \brief Decrease stock for product and subproducts * \return int <0 if KO, >0 if OK @@ -283,7 +292,7 @@ class MouvementStock $this->db->free($resql); return $nbSP; } - + /** * \brief Calcul ??? * \return int <0 si ko, >0 si ok @@ -302,7 +311,7 @@ class MouvementStock { $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) ) @@ -339,7 +348,7 @@ class MouvementStock $sql.= " VALUES (".$this->db->idate(mktime()).", ".$entrepot_id; $sql.= ",'".price2num($new_value)."')"; } - + if ($this->db->query($sql)) { @@ -356,7 +365,7 @@ class MouvementStock $sql = "UPDATE ".MAIN_DB_PREFIX."entrepot"; $sql.= " SET valo_pmp='".price2num($new_value)."'"; $sql.= " WHERE rowid = $entrepot_id "; - + if ($this->db->query($sql)) { @@ -449,7 +458,7 @@ class MouvementStock $new_stock_qty = $qty_stock + $qty; $new_stock_value_pmp = $stock_value_pmp + $value_ope; - + // Fin calcul if ($error === 0) { diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 98677c35f77..f0e51c99c1c 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -52,7 +52,7 @@ if ($_POST["action"] == "create_stock" && ! $_POST["cancel"]) { $product = new Product($db); $product->id = $_GET["id"]; - $product->create_stock($_POST["id_entrepot"], $_POST["nbpiece"]); + $product->create_stock($user, $_POST["id_entrepot"], $_POST["nbpiece"]); } if ($_POST["action"] == "correct_stock" && ! $_POST["cancel"]) @@ -74,19 +74,30 @@ if ($_POST["action"] == "transfert_stock" && ! $_POST["cancel"]) { if (is_numeric($_POST["nbpiece"])) { - - $product = new Product($db); - $product->id = $_GET["id"]; + $product = new Product($db); + $product->id = $_GET["id"]; - $product->correct_stock($user, - $_POST["id_entrepot_source"], - $_POST["nbpiece"], - 1); + $db->begin(); - $product->correct_stock($user, - $_POST["id_entrepot_destination"], - $_POST["nbpiece"], - 0); + $result1=$product->correct_stock($user, + $_POST["id_entrepot_source"], + $_POST["nbpiece"], + 1); + + $result2=$product->correct_stock($user, + $_POST["id_entrepot_destination"], + $_POST["nbpiece"], + 0); + + if ($result1 >= 0 && $result2 >= 0) + { + $db->commit(); + } + else + { + $mesg=$product->error; + $db->rollback(); + } } } } @@ -152,11 +163,11 @@ if ($_GET["id"] || $_GET["ref"]) print ''.$product->stock_reel.''; print ''; - // Calculating a theorical value of stock if stock increment is done on real sending + // 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'); @@ -169,9 +180,9 @@ if ($_GET["id"] || $_GET["ref"]) if ($result < 0) dolibarr_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 ''.$langs->trans("VirtualStock").''; print "".$product->stock_theorique; @@ -181,7 +192,7 @@ if ($_GET["id"] || $_GET["ref"]) } print ''; print ''; - + print ''; if ($product->stock_theorique != $product->stock_reel) print $langs->trans("StockDiffPhysicTeoric"); else print $langs->trans("RunningOrders"); @@ -189,7 +200,7 @@ if ($_GET["id"] || $_GET["ref"]) print ''; $found=0; - + // Nbre de commande clients en cours if ($conf->commande->enabled) { @@ -213,7 +224,7 @@ if ($_GET["id"] || $_GET["ref"]) } print ''; } - + // Stock print ''.$langs->trans("StockLimit").''; print ''.$product->seuil_stock_alerte.''; @@ -336,7 +347,7 @@ print ''.$langs->trans("Warehouse").''.$langs->trans("NumberOfUnit").''; $sql = "SELECT e.rowid, e.label, ps.reel FROM ".MAIN_DB_PREFIX."entrepot as e, ".MAIN_DB_PREFIX."product_stock as ps"; -$sql .= " WHERE ps.fk_entrepot = e.rowid AND ps.fk_product = ".$product->id; +$sql .= " WHERE ps.reel != 0 AND ps.fk_entrepot = e.rowid AND ps.fk_product = ".$product->id; $sql .= " ORDER BY lower(e.label)"; $entrepotstatic=new Entrepot($db); diff --git a/mysql/migration/2.5.0-2.6.0.sql b/mysql/migration/2.5.0-2.6.0.sql index 56940f50c77..262aef5f81a 100644 --- a/mysql/migration/2.5.0-2.6.0.sql +++ b/mysql/migration/2.5.0-2.6.0.sql @@ -38,6 +38,7 @@ ALTER TABLE llx_categorie ADD INDEX idx_categorie_type (type); ALTER TABLE llx_product drop column stock_propale; ALTER TABLE llx_product drop column stock_commande; +ALTER TABLE llx_product add column stock integer after import_key; ALTER TABLE llx_adherent drop index login; ALTER TABLE llx_adherent ADD UNIQUE INDEX uk_adherent_login (login); diff --git a/mysql/tables/llx_product.sql b/mysql/tables/llx_product.sql index c24b065dda7..aa5d79d2ad9 100644 --- a/mysql/tables/llx_product.sql +++ b/mysql/tables/llx_product.sql @@ -47,6 +47,7 @@ create table llx_product weight_units tinyint DEFAULT NULL, volume float DEFAULT NULL, volume_units tinyint DEFAULT NULL, + stock integer, -- physical stock pmp double(24,8) default 0 NOT NULL; canvas varchar(15) DEFAULT '', finished tinyint DEFAULT NULL,