2004-10-20 00:24:10 +02:00
< ? php
2006-12-04 12:31:06 +01:00
/* Copyright ( C ) 2003 - 2006 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
2008-03-31 07:56:45 +02:00
* Copyright ( C ) 2004 - 2008 Laurent Destailleur < eldy @ users . sourceforge . net >
2018-10-27 14:43:12 +02:00
* Copyright ( C ) 2005 - 2009 Regis Houssin < regis . houssin @ inodbox . com >
2012-10-13 18:02:43 +02:00
* Copyright ( C ) 2012 Juanjo Menent < jmenent @ 2 byte . es >
2021-07-28 10:45:47 +02:00
* Copyright ( C ) 2021 Ferran Marcet < fmarcet @ 2 byte . es >
2003-11-13 16:12:07 +01:00
*
* 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
2013-01-16 15:36:08 +01:00
* the Free Software Foundation ; either version 3 of the License , or
2003-11-13 16:12:07 +01:00
* ( 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
2019-09-23 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2003-11-13 16:12:07 +01:00
*/
2005-04-01 00:17:49 +02:00
/**
2009-07-30 00:52:08 +02:00
* \defgroup stock Module stocks
2008-12-04 21:27:01 +01:00
* \brief Module pour gerer la tenue de stocks produits
2011-10-24 14:11:49 +02:00
* \file htdocs / core / modules / modStock . class . php
2008-12-04 21:27:01 +01:00
* \ingroup stock
2021-03-20 13:55:43 +01:00
* \brief Description and activation file for the module Stock
2008-10-01 21:10:17 +02:00
*/
2004-08-14 14:21:24 +02:00
2020-04-10 10:59:32 +02:00
include_once DOL_DOCUMENT_ROOT . '/core/modules/DolibarrModules.class.php' ;
2007-10-10 01:15:25 +02:00
2003-11-13 16:12:07 +01:00
2005-04-01 00:17:49 +02:00
/**
2015-09-07 15:55:26 +02:00
* Class to describe and enable module Stock
2008-10-01 21:10:17 +02:00
*/
2003-11-13 16:12:07 +01:00
class modStock extends DolibarrModules
{
2008-10-01 21:10:17 +02:00
/**
2011-09-26 16:22:35 +02:00
* Constructor . Define names , constants , directories , boxes , permissions
*
2012-01-04 21:23:50 +01:00
* @ param DoliDB $db Database handler
2008-10-01 21:10:17 +02:00
*/
2019-02-25 20:35:59 +01:00
public function __construct ( $db )
2008-10-01 21:10:17 +02:00
{
2015-04-08 18:40:10 +02:00
global $conf , $langs ;
2009-05-04 13:40:00 +02:00
2012-01-04 21:23:50 +01:00
$this -> db = $db ;
$this -> numero = 52 ;
2008-10-01 21:10:17 +02:00
$this -> family = " products " ;
2020-05-02 00:41:27 +02:00
$this -> module_position = '39' ;
2008-10-01 21:10:17 +02:00
// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
2019-01-27 11:55:16 +01:00
$this -> name = preg_replace ( '/^mod/i' , '' , get_class ( $this ));
2008-10-01 21:10:17 +02:00
$this -> description = " Gestion des stocks " ;
2008-12-15 23:25:59 +01:00
// Possible values for version are: 'development', 'experimental', 'dolibarr' or version
$this -> version = 'dolibarr' ;
2009-05-04 13:40:00 +02:00
2008-10-06 09:39:52 +02:00
$this -> const_name = 'MAIN_MODULE_' . strtoupper ( $this -> name );
2020-04-10 10:59:32 +02:00
$this -> picto = 'stock' ;
2008-10-01 21:10:17 +02:00
2009-05-04 13:40:00 +02:00
// Data directories to create when module is enabled
2018-05-05 14:33:34 +02:00
$this -> dirs = array ( " /stock/temp " );
2008-10-01 21:10:17 +02:00
$this -> config_page_url = array ( " stock.php " );
// Dependencies
2020-04-10 10:59:32 +02:00
$this -> hidden = false ; // A condition to hide module
$this -> depends = array ( " modProduct " ); // List of module class names as string that must be enabled if this module is enabled
$this -> requiredby = array ( " modProductBatch " ); // List of module ids to disable if this one is disabled
$this -> conflictwith = array (); // List of module class names as string this module is in conflict with
2021-02-06 13:48:31 +01:00
$this -> phpmin = array ( 5 , 6 ); // Minimum version of PHP required by module
2008-10-01 21:10:17 +02:00
$this -> langfiles = array ( " stocks " );
2009-05-04 13:40:00 +02:00
// Constants
2018-05-05 14:33:34 +02:00
$this -> const = array ();
2020-04-10 10:59:32 +02:00
$r = 0 ;
2018-10-06 11:57:53 +02:00
2020-04-10 10:59:32 +02:00
$this -> const [ $r ] = array ( 'STOCK_ALLOW_NEGATIVE_TRANSFER' , 'chaine' , '1' , '' , 1 );
2018-10-06 11:57:53 +02:00
2018-05-05 14:33:34 +02:00
$r ++ ;
$this -> const [ $r ][ 0 ] = " STOCK_ADDON_PDF " ;
$this -> const [ $r ][ 1 ] = " chaine " ;
2020-08-18 14:02:36 +02:00
$this -> const [ $r ][ 2 ] = " standard " ;
2018-05-05 14:33:34 +02:00
$this -> const [ $r ][ 3 ] = 'Name of PDF model of stock' ;
$this -> const [ $r ][ 4 ] = 0 ;
$r ++ ;
$this -> const [ $r ][ 0 ] = " MOUVEMENT_ADDON_PDF " ;
$this -> const [ $r ][ 1 ] = " chaine " ;
2020-08-18 14:02:36 +02:00
$this -> const [ $r ][ 2 ] = " stdmovement " ;
2018-05-05 14:33:34 +02:00
$this -> const [ $r ][ 3 ] = 'Name of PDF model of stock mouvement' ;
$this -> const [ $r ][ 4 ] = 0 ;
$r ++ ;
$this -> const [ $r ][ 0 ] = " STOCK_ADDON_PDF_ODT_PATH " ;
$this -> const [ $r ][ 1 ] = " chaine " ;
$this -> const [ $r ][ 2 ] = " DOL_DATA_ROOT/doctemplates/stocks " ;
$this -> const [ $r ][ 3 ] = " " ;
$this -> const [ $r ][ 4 ] = 0 ;
$r ++ ;
$this -> const [ $r ][ 0 ] = " MOUVEMENT_ADDON_PDF_ODT_PATH " ;
$this -> const [ $r ][ 1 ] = " chaine " ;
$this -> const [ $r ][ 2 ] = " DOL_DATA_ROOT/doctemplates/stocks/mouvements " ;
$this -> const [ $r ][ 3 ] = " " ;
$this -> const [ $r ][ 4 ] = 0 ;
2008-10-01 21:10:17 +02:00
// Boxes
$this -> boxes = array ();
// Permissions
$this -> rights = array ();
$this -> rights_class = 'stock' ;
$this -> rights [ 0 ][ 0 ] = 1001 ;
$this -> rights [ 0 ][ 1 ] = 'Lire les stocks' ;
$this -> rights [ 0 ][ 2 ] = 'r' ;
2016-12-11 14:11:28 +01:00
$this -> rights [ 0 ][ 3 ] = 0 ;
2008-10-01 21:10:17 +02:00
$this -> rights [ 0 ][ 4 ] = 'lire' ;
$this -> rights [ 0 ][ 5 ] = '' ;
$this -> rights [ 1 ][ 0 ] = 1002 ;
$this -> rights [ 1 ][ 1 ] = 'Creer/Modifier les stocks' ;
$this -> rights [ 1 ][ 2 ] = 'w' ;
$this -> rights [ 1 ][ 3 ] = 0 ;
$this -> rights [ 1 ][ 4 ] = 'creer' ;
$this -> rights [ 1 ][ 5 ] = '' ;
$this -> rights [ 2 ][ 0 ] = 1003 ;
$this -> rights [ 2 ][ 1 ] = 'Supprimer les stocks' ;
$this -> rights [ 2 ][ 2 ] = 'd' ;
$this -> rights [ 2 ][ 3 ] = 0 ;
$this -> rights [ 2 ][ 4 ] = 'supprimer' ;
$this -> rights [ 2 ][ 5 ] = '' ;
$this -> rights [ 3 ][ 0 ] = 1004 ;
$this -> rights [ 3 ][ 1 ] = 'Lire mouvements de stocks' ;
$this -> rights [ 3 ][ 2 ] = 'r' ;
2016-12-11 14:11:28 +01:00
$this -> rights [ 3 ][ 3 ] = 0 ;
2008-10-01 21:10:17 +02:00
$this -> rights [ 3 ][ 4 ] = 'mouvement' ;
$this -> rights [ 3 ][ 5 ] = 'lire' ;
$this -> rights [ 4 ][ 0 ] = 1005 ;
$this -> rights [ 4 ][ 1 ] = 'Creer/modifier mouvements de stocks' ;
$this -> rights [ 4 ][ 2 ] = 'w' ;
$this -> rights [ 4 ][ 3 ] = 0 ;
$this -> rights [ 4 ][ 4 ] = 'mouvement' ;
$this -> rights [ 4 ][ 5 ] = 'creer' ;
2021-07-28 10:45:47 +02:00
$this -> rights [ 5 ][ 0 ] = 1011 ;
$this -> rights [ 5 ][ 1 ] = 'inventoryReadPermission' ; // Permission label
$this -> rights [ 5 ][ 3 ] = 0 ; // Permission by default for new user (0/1)
$this -> rights [ 5 ][ 4 ] = 'inventory_advance' ; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
$this -> rights [ 5 ][ 5 ] = 'read' ; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
$this -> rights [ 6 ][ 0 ] = 1012 ;
$this -> rights [ 6 ][ 1 ] = 'inventoryCreatePermission' ; // Permission label
$this -> rights [ 6 ][ 3 ] = 0 ; // Permission by default for new user (0/1)
$this -> rights [ 6 ][ 4 ] = 'inventory_advance' ; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
$this -> rights [ 6 ][ 5 ] = 'write' ; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
2020-10-31 14:32:18 +01:00
2021-07-28 10:45:47 +02:00
if ( $conf -> global -> MAIN_FEATURES_LEVEL >= 2 ) {
2020-10-31 14:32:18 +01:00
$this -> rights [ 8 ][ 0 ] = 1014 ;
$this -> rights [ 8 ][ 1 ] = 'inventoryValidatePermission' ; // Permission label
$this -> rights [ 8 ][ 3 ] = 0 ; // Permission by default for new user (0/1)
$this -> rights [ 8 ][ 4 ] = 'inventory_advance' ; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
$this -> rights [ 8 ][ 5 ] = 'validate' ; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
$this -> rights [ 9 ][ 0 ] = 1015 ;
$this -> rights [ 9 ][ 1 ] = 'inventoryChangePMPPermission' ; // Permission label
$this -> rights [ 9 ][ 3 ] = 0 ; // Permission by default for new user (0/1)
$this -> rights [ 9 ][ 4 ] = 'inventory_advance' ; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
$this -> rights [ 9 ][ 5 ] = 'changePMP' ; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
2021-03-30 12:35:20 +02:00
$this -> rights [ 10 ][ 0 ] = 1016 ;
$this -> rights [ 10 ][ 1 ] = 'inventoryDeletePermission' ; // Permission label
$this -> rights [ 10 ][ 3 ] = 0 ; // Permission by default for new user (0/1)
$this -> rights [ 10 ][ 4 ] = 'inventory_advance' ; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
$this -> rights [ 10 ][ 5 ] = 'delete' ; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
2017-05-02 15:25:30 +02:00
}
2017-10-20 14:52:01 +02:00
2017-04-29 21:53:01 +02:00
// Main menu entries
2020-04-10 10:59:32 +02:00
$this -> menu = array (); // List of menus to add
$r = 0 ;
2017-10-20 14:52:01 +02:00
2016-09-30 13:02:13 +02:00
// Menus
//-------
2020-04-10 10:59:32 +02:00
$this -> menu = 1 ; // This module add menu entries. They are coded into menu manager.
2017-10-20 14:52:01 +02:00
2008-10-01 21:10:17 +02:00
// Exports
//--------
2020-04-10 10:59:32 +02:00
$r = 0 ;
2008-10-01 21:10:17 +02:00
2020-12-08 00:50:27 +01:00
// Export warehouses
$r ++ ;
2020-12-13 16:27:44 +01:00
$this -> export_code [ $r ] = $this -> rights_class . '_emplacement' ;
2020-12-08 00:50:27 +01:00
$this -> export_label [ $r ] = " Warehouses " ; // Translation key (used only if key ExportDataset_xxx_z not found)
$this -> export_icon [ $r ] = " warehouse " ;
$this -> export_permission [ $r ] = array ( array ( " stock " , " lire " ));
$this -> export_fields_array [ $r ] = array (
'e.rowid' => 'IdWarehouse' , 'e.ref' => 'LocationSummary' , 'e.description' => 'DescWareHouse' , 'e.lieu' => 'LieuWareHouse' , 'e.address' => 'Address' , 'e.zip' => 'Zip' , 'e.town' => 'Town' ,
'd.code_departement' => 'Departement' , 'c.code' => 'CountryCode' ,
'e.phone' => 'Phone' , 'e.fax' => 'Fax' , 'e.statut' => 'Status' , 'pe.rowid' => 'ParentWarehouse' , 'pe.ref' => 'LocationSummary'
);
$this -> export_TypeFields_array [ $r ] = array (
'e.ref' => 'Text' , 'e.description' => 'Text' , 'e.lieu' => 'Text' , 'e.address' => 'Text' , 'e.zip' => 'Text' , 'e.town' => 'Text' ,
'd.code_departement' => 'List:c_departements:code_departement:code_departement:' , 'c.code' => 'List:c_country:code:code:' ,
'e.phone' => 'Text' , 'e.fax' => 'Text' , 'e.statut' => 'Text' , 'pe.rowid' => 'List:entrepot:ref:rowid:stock' , 'pe.ref' => 'Text'
);
$this -> export_entities_array [ $r ] = array (); // We define here only fields that use another icon that the one defined into export_icon
$this -> export_aggregate_array [ $r ] = array ();
2021-03-01 20:37:16 +01:00
$keyforselect = 'warehouse' ;
$keyforelement = 'warehouse' ;
$keyforaliasextra = 'extra' ;
2020-12-08 00:50:27 +01:00
include DOL_DOCUMENT_ROOT . '/core/extrafieldsinexport.inc.php' ;
$this -> export_sql_start [ $r ] = 'SELECT DISTINCT ' ;
$this -> export_sql_end [ $r ] = ' FROM ' . MAIN_DB_PREFIX . 'entrepot as e' ;
$this -> export_sql_end [ $r ] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_departements as d ON d.rowid = e.fk_departement' ;
$this -> export_sql_end [ $r ] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_country as c ON c.rowid = e.fk_pays' ;
$this -> export_sql_end [ $r ] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'entrepot as pe ON pe.rowid = e.fk_parent' ;
$this -> export_sql_end [ $r ] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'entrepot_extrafields as extra ON extra.fk_object = e.rowid' ;
$this -> export_sql_end [ $r ] .= ' WHERE e.entity IN (' . getEntity ( 'stock' ) . ')' ;
2020-12-03 19:45:36 +01:00
// Export stock (without batch number)
2008-10-01 21:10:17 +02:00
$r ++ ;
2020-12-13 16:27:44 +01:00
$this -> export_code [ $r ] = $this -> rights_class . '_emplacement_product' ;
2020-12-03 19:45:36 +01:00
$this -> export_label [ $r ] = " Stocks " ; // Translation key (used only if key ExportDataset_xxx_z not found)
$this -> export_icon [ $r ] = " warehouse " ;
2020-04-10 10:59:32 +02:00
$this -> export_permission [ $r ] = array ( array ( " stock " , " lire " ));
$this -> export_fields_array [ $r ] = array (
2020-12-03 19:45:36 +01:00
'e.rowid' => 'IdWarehouse' , 'e.ref' => 'LocationSummary' , 'e.description' => 'DescWareHouse' , 'e.lieu' => 'LieuWareHouse' , 'e.address' => 'Address' , 'e.zip' => 'Zip' , 'e.town' => 'Town' ,
'p.rowid' => " ProductId " , '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.tosell' => " OnSell " , 'p.tobuy' => 'OnBuy' , 'p.duration' => " Duration " ,
'p.datec' => 'DateCreation' , 'p.tms' => 'DateModification' , 'p.pmp' => 'PMPValue' , 'p.cost_price' => 'CostPrice' ,
2022-01-26 10:18:44 +01:00
'p.seuil_stock_alerte' => 'StockLimit' ,
2018-05-27 15:04:12 +02:00
);
2020-04-10 10:59:32 +02:00
$this -> export_TypeFields_array [ $r ] = array (
2020-12-03 19:45:36 +01:00
'e.rowid' => 'List:entrepot:ref::stock' , 'e.ref' => 'Text' , 'e.lieu' => 'Text' , 'e.address' => 'Text' , 'e.zip' => 'Text' , 'e.town' => 'Text' ,
'p.rowid' => " List:product:label::product " , 'p.ref' => " Text " , 'p.fk_product_type' => " Text " , 'p.label' => " Text " , 'p.description' => " Text " , 'p.note' => " Text " ,
'p.price' => " Numeric " , 'p.tva_tx' => 'Numeric' , 'p.tosell' => " Boolean " , 'p.tobuy' => " Boolean " , 'p.duration' => " Duree " ,
'p.datec' => 'Date' , 'p.tms' => 'Date' , 'p.pmp' => 'Numeric' , 'p.cost_price' => 'Numeric' ,
2022-01-26 10:18:44 +01:00
'ps.reel' => 'Numeric' ,
'p.seuil_stock_alerte' => 'Numeric' ,
2018-05-27 15:04:12 +02:00
);
2020-04-10 10:59:32 +02:00
$this -> export_entities_array [ $r ] = array (
2020-12-03 19:45:36 +01:00
'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.tosell' => " product " , 'p.tobuy' => " product " , 'p.duration' => " product " ,
'p.datec' => 'product' , 'p.tms' => 'product' , 'p.pmp' => 'product' , 'p.cost_price' => 'product' ,
2022-01-26 10:18:44 +01:00
'ps.reel' => 'stock' ,
'p.seuil_stock_alerte' => 'product' ,
2020-12-03 19:45:36 +01:00
); // We define here only fields that use another icon that the one defined into export_icon
2020-04-10 10:59:32 +02:00
$this -> export_aggregate_array [ $r ] = array ( 'ps.reel' => 'SUM' ); // TODO Not used yet
$this -> export_dependencies_array [ $r ] = array ( 'stock' => array ( 'p.rowid' , 'e.rowid' )); // We must keep this until the aggregate_array is used. To have a unique key, if we ask a field of a child, to avoid the DISTINCT to discard them.
2021-03-01 20:37:16 +01:00
$keyforselect = 'product' ;
$keyforelement = 'product' ;
$keyforaliasextra = 'extra' ;
2018-05-23 17:48:18 +02:00
include DOL_DOCUMENT_ROOT . '/core/extrafieldsinexport.inc.php' ;
2020-04-10 10:59:32 +02:00
$this -> export_fields_array [ $r ] = array_merge ( $this -> export_fields_array [ $r ], array ( 'ps.reel' => 'Stock' ));
2018-05-23 18:00:27 +02:00
2020-04-10 10:59:32 +02:00
$this -> export_sql_start [ $r ] = 'SELECT DISTINCT ' ;
$this -> export_sql_end [ $r ] = ' FROM ' . MAIN_DB_PREFIX . 'product as p LEFT JOIN ' . MAIN_DB_PREFIX . 'product_extrafields as extra ON extra.fk_object = p.rowid, ' . MAIN_DB_PREFIX . 'product_stock as ps, ' . MAIN_DB_PREFIX . 'entrepot as e' ;
$this -> export_sql_end [ $r ] .= ' WHERE p.rowid = ps.fk_product AND ps.fk_entrepot = e.rowid' ;
$this -> export_sql_end [ $r ] .= ' AND e.entity IN (' . getEntity ( 'stock' ) . ')' ;
2020-12-03 19:45:36 +01:00
// Export stock including batch number
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> productbatch -> enabled )) {
2015-04-08 18:40:10 +02:00
$langs -> load ( " productbatch " );
// This request is same than previous but without field ps.stock (real stock in warehouse) and with link to subtable productbatch
$r ++ ;
2020-12-13 16:27:44 +01:00
$this -> export_code [ $r ] = $this -> rights_class . '_emplacement_product_lot' ;
2020-12-03 19:45:36 +01:00
$this -> export_label [ $r ] = " StocksWithBatch " ; // Translation key (used only if key ExportDataset_xxx_z not found)
$this -> export_icon [ $r ] = " warehouse " ;
2020-04-10 10:59:32 +02:00
$this -> export_permission [ $r ] = array ( array ( " stock " , " lire " ));
$this -> export_fields_array [ $r ] = array (
2020-12-03 19:45:36 +01:00
'e.rowid' => 'IdWarehouse' , 'e.ref' => 'LocationSummary' , 'e.description' => 'DescWareHouse' , 'e.lieu' => 'LieuWareHouse' , 'e.address' => 'Address' , 'e.zip' => 'Zip' , 'e.town' => 'Town' ,
'p.rowid' => " ProductId " , '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.tosell' => " OnSell " , 'p.tobuy' => 'OnBuy' , 'p.duration' => " Duration " ,
'p.datec' => 'DateCreation' , 'p.tms' => 'DateModification' , 'p.pmp' => 'PMPValue' , 'p.cost_price' => 'CostPrice' ,
'pb.rowid' => 'Id' , 'pb.batch' => 'Batch' , 'pb.qty' => 'Qty' ,
'pl.eatby' => 'EatByDate' , 'pl.sellby' => 'SellByDate'
2018-05-27 15:04:12 +02:00
);
2020-04-10 10:59:32 +02:00
$this -> export_TypeFields_array [ $r ] = array (
'e.rowid' => 'List:entrepot:ref::stock' , 'e.ref' => 'Text' , 'e.lieu' => 'Text' , 'e.description' => 'Text' , 'e.address' => 'Text' , 'e.zip' => 'Text' , 'e.town' => 'Text' ,
'p.rowid' => " List:product:label::product " , 'p.ref' => " Text " , 'p.fk_product_type' => " Text " , 'p.label' => " Text " , 'p.description' => " Text " , 'p.note' => " Text " ,
2020-12-03 19:45:36 +01:00
'p.price' => " Numeric " , 'p.tva_tx' => 'Numeric' , 'p.tosell' => " Boolean " , 'p.tobuy' => " Boolean " , 'p.duration' => " Duree " ,
'p.datec' => 'DateCreation' , 'p.tms' => 'DateModification' , 'p.pmp' => 'PMPValue' , 'p.cost_price' => 'CostPrice' ,
'pb.batch' => 'Text' , 'pb.qty' => 'Numeric' ,
'pl.eatby' => 'Date' , 'pl.sellby' => 'Date'
2018-05-27 15:04:12 +02:00
);
2020-04-10 10:59:32 +02:00
$this -> export_entities_array [ $r ] = array (
2020-12-03 19:45:36 +01:00
'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.tosell' => " product " , 'p.tobuy' => " product " , 'p.duration' => " product " ,
'p.datec' => 'product' , 'p.tms' => 'product' , 'p.pmp' => 'product' , 'p.cost_price' => 'product' ,
'pb.rowid' => 'batch' , 'pb.batch' => 'batch' , 'pb.qty' => 'batch' ,
'pl.eatby' => 'batch' , 'pl.sellby' => 'batch'
); // We define here only fields that use another icon that the one defined into export_icon
2020-04-10 10:59:32 +02:00
$this -> export_aggregate_array [ $r ] = array ( 'ps.reel' => 'SUM' ); // TODO Not used yet
$this -> export_dependencies_array [ $r ] = array ( 'stockbatch' => array ( 'pb.rowid' ), 'batch' => array ( 'pb.rowid' )); // We must keep this until the aggregate_array is used. To add unique key if we ask a field of a child to avoid the DISTINCT to discard them.
2021-03-01 20:37:16 +01:00
$keyforselect = 'product_lot' ;
$keyforelement = 'batch' ;
$keyforaliasextra = 'extra' ;
2017-11-24 17:44:19 +01:00
include DOL_DOCUMENT_ROOT . '/core/extrafieldsinexport.inc.php' ;
2020-12-03 19:45:36 +01:00
2020-04-10 10:59:32 +02:00
$this -> export_sql_start [ $r ] = 'SELECT DISTINCT ' ;
2020-12-23 16:13:45 +01:00
$this -> export_sql_end [ $r ] = ' FROM ' . MAIN_DB_PREFIX . 'product_batch as pb' ;
$this -> export_sql_end [ $r ] .= ' INNER JOIN ' . MAIN_DB_PREFIX . 'product_stock as ps ON ps.rowid = pb.fk_product_stock' ;
$this -> export_sql_end [ $r ] .= ' INNER JOIN ' . MAIN_DB_PREFIX . 'product as p ON p.rowid = ps.fk_product' ;
2020-04-10 10:59:32 +02:00
$this -> export_sql_end [ $r ] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product_lot as pl ON pl.fk_product = p.rowid AND pl.batch = pb.batch' ;
$this -> export_sql_end [ $r ] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product_lot_extrafields as extra ON extra.fk_object = pl.rowid,' ;
$this -> export_sql_end [ $r ] .= ' ' . MAIN_DB_PREFIX . 'entrepot as e' ;
2020-12-23 16:13:45 +01:00
$this -> export_sql_end [ $r ] .= ' WHERE ps.fk_entrepot = e.rowid' ;
$this -> export_sql_end [ $r ] .= ' AND e.entity IN (' . getEntity ( 'stock' ) . ')' ;
}
2012-10-25 22:30:17 +02:00
2020-12-03 19:45:36 +01:00
// Export of stock movements
2017-10-20 14:52:01 +02:00
$r ++ ;
2020-04-10 10:59:32 +02:00
$this -> export_code [ $r ] = $this -> rights_class . '_movement' ;
$this -> export_label [ $r ] = " StockMovements " ; // Translation key (used only if key ExportDataset_xxx_z not found)
2020-12-03 19:45:36 +01:00
$this -> export_icon [ $r ] = " movement " ;
2020-04-10 10:59:32 +02:00
$this -> export_permission [ $r ] = array ( array ( " stock " , " lire " ));
$this -> export_fields_array [ $r ] = array (
2020-12-03 19:45:36 +01:00
'sm.rowid' => 'MovementId' , 'sm.value' => 'Qty' , 'sm.datem' => 'DateMovement' , 'sm.label' => 'MovementLabel' , 'sm.inventorycode' => 'InventoryCode' ,
'e.rowid' => 'IdWarehouse' , 'e.ref' => 'LocationSummary' , 'e.description' => 'DescWareHouse' , 'e.lieu' => 'LieuWareHouse' , 'e.address' => 'Address' , 'e.zip' => 'Zip' , 'e.town' => 'Town' ,
'p.rowid' => " ProductId " , '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.tosell' => " OnSell " , 'p.tobuy' => 'OnBuy' , 'p.duration' => " Duration " , 'p.datec' => 'DateCreation' , 'p.tms' => 'DateModification'
2018-05-27 15:04:12 +02:00
);
2020-04-10 10:59:32 +02:00
$this -> export_TypeFields_array [ $r ] = array (
2020-12-03 19:45:36 +01:00
'sm.rowid' => 'Numeric' , 'sm.value' => 'Numeric' , 'sm.datem' => 'Date' , 'sm.batch' => 'Text' , 'sm.label' => 'Text' , 'sm.inventorycode' => 'Text' ,
2020-04-10 10:59:32 +02:00
'e.rowid' => 'List:entrepot:ref::stock' , 'e.ref' => 'Text' , 'e.description' => 'Text' , 'e.lieu' => 'Text' , 'e.address' => 'Text' , 'e.zip' => 'Text' , 'e.town' => 'Text' ,
'p.rowid' => " List:product:label::product " , 'p.ref' => " Text " , 'p.fk_product_type' => " Text " , 'p.label' => " Text " , 'p.description' => " Text " , 'p.note' => " Text " ,
2020-12-03 19:45:36 +01:00
'p.price' => " Numeric " , 'p.tva_tx' => 'Numeric' , 'p.tosell' => " Boolean " , 'p.tobuy' => " Boolean " , 'p.duration' => " Duree " , 'p.datec' => 'Date' , 'p.tms' => 'Date'
2018-05-27 15:04:12 +02:00
);
2020-04-10 10:59:32 +02:00
$this -> export_entities_array [ $r ] = array (
2020-12-03 19:45:36 +01:00
'e.rowid' => 'warehouse' , 'e.ref' => 'warehouse' , 'e.description' => 'warehouse' , 'e.lieu' => 'warehouse' , 'e.address' => 'warehouse' , 'e.zip' => 'warehouse' , 'e.town' => 'warehouse' ,
'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.tosell' => " product " , 'p.tobuy' => " product " , 'p.duration' => " product " , 'p.datec' => 'product' , 'p.tms' => 'product'
); // We define here only fields that use another icon that the one defined into export_icon
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> productbatch -> enabled )) {
2020-04-10 10:59:32 +02:00
$this -> export_fields_array [ $r ][ 'sm.batch' ] = 'Batch' ;
$this -> export_TypeFields_array [ $r ][ 'sm.batch' ] = 'Text' ;
$this -> export_entities_array [ $r ][ 'sm.batch' ] = 'movement' ;
2017-10-20 14:52:01 +02:00
}
2020-04-10 10:59:32 +02:00
$this -> export_aggregate_array [ $r ] = array ( 'sm.value' => 'SUM' ); // TODO Not used yet
$this -> export_dependencies_array [ $r ] = array ( 'movement' => array ( 'sm.rowid' )); // We must keep this until the aggregate_array is used. To add unique key if we ask a field of a child to avoid the DISTINCT to discard them.
2020-12-03 19:45:36 +01:00
2020-04-10 10:59:32 +02:00
$this -> export_sql_start [ $r ] = 'SELECT DISTINCT ' ;
$this -> export_sql_end [ $r ] = ' FROM ' . MAIN_DB_PREFIX . 'product as p, ' . MAIN_DB_PREFIX . 'stock_mouvement as sm, ' . MAIN_DB_PREFIX . 'entrepot as e' ;
$this -> export_sql_end [ $r ] .= ' WHERE p.rowid = sm.fk_product AND sm.fk_entrepot = e.rowid' ;
$this -> export_sql_end [ $r ] .= ' AND e.entity IN (' . getEntity ( 'stock' ) . ')' ;
2017-10-20 14:52:01 +02:00
2012-10-18 10:36:53 +02:00
// Imports
//--------
2012-10-25 22:30:17 +02:00
2020-04-10 10:59:32 +02:00
$r = 0 ;
2012-10-25 22:30:17 +02:00
2012-10-27 20:27:07 +02:00
// Import warehouses
2012-10-18 10:36:53 +02:00
$r ++ ;
2020-04-10 10:59:32 +02:00
$this -> import_code [ $r ] = $this -> rights_class . '_' . $r ;
$this -> import_label [ $r ] = " Warehouses " ; // Translation key
2020-12-03 19:45:36 +01:00
$this -> import_icon [ $r ] = " warehouse " ;
2020-04-10 10:59:32 +02:00
$this -> import_entities_array [ $r ] = array (); // We define here only fields that use another icon that the one defined into import_icon
$this -> import_tables_array [ $r ] = array ( 'e' => MAIN_DB_PREFIX . 'entrepot' );
$this -> import_tables_creator_array [ $r ] = array ( 'e' => 'fk_user_author' );
$this -> import_fields_array [ $r ] = array ( 'e.ref' => " LocationSummary* " ,
2020-12-03 19:45:36 +01:00
'e.description' => " DescWareHouse " ,
'e.lieu' => " LieuWareHouse " ,
'e.address' => " Address " ,
'e.zip' => 'Zip' ,
'e.fk_departement' => 'StateCode' ,
'e.fk_pays' => 'CountryCode' ,
'e.phone' => 'Phone' ,
'e.fax' => 'Fax' ,
2019-09-09 15:03:20 +02:00
'e.statut' => 'Status' ,
2020-10-31 14:32:18 +01:00
'e.fk_parent' => 'ParentWarehouse'
2012-10-18 10:36:53 +02:00
);
2012-10-25 22:30:17 +02:00
2020-04-10 10:59:32 +02:00
$this -> import_convertvalue_array [ $r ] = array (
2020-12-03 19:45:36 +01:00
'e.fk_departement' => array ( 'rule' => 'fetchidfromcodeid' , 'classfile' => '/core/class/cstate.class.php' , 'class' => 'Cstate' , 'method' => 'fetch' , 'dict' => 'DictionaryStateCode' ),
2020-04-10 10:59:32 +02:00
'e.fk_pays' => array ( 'rule' => 'fetchidfromcodeid' , 'classfile' => '/core/class/ccountry.class.php' , 'class' => 'Ccountry' , 'method' => 'fetch' , 'dict' => 'DictionaryCountry' ),
2020-10-31 14:32:18 +01:00
'e.fk_parent' => array ( 'rule' => 'fetchidfromref' , 'classfile' => '/product/stock/class/entrepot.class.php' , 'class' => 'Entrepot' , 'method' => 'fetch' , 'element' => 'ref' )
2012-10-18 10:36:53 +02:00
);
2020-04-10 10:59:32 +02:00
$this -> import_regex_array [ $r ] = array ( 'e.statut' => '^[0|1]' );
$this -> import_examplevalues_array [ $r ] = array ( 'e.ref' => " ALM001 " ,
2020-12-03 19:45:36 +01:00
'e.description' => " Central Warehouse " ,
'e.lieu' => " Central " ,
'e.address' => " Route 66 " ,
'e.zip' => '28080' ,
'e.fk_departement' => 'matches field "code_departement" in table "' . MAIN_DB_PREFIX . 'c_departements"' ,
'e.fk_pays' => 'US/FR/DE etc. matches field "code" in table "' . MAIN_DB_PREFIX . 'c_country"' ,
'e.phone' => '(+33)(0)123456789' ,
'e.fax' => '(+33)(0)123456790' ,
2019-09-09 15:03:20 +02:00
'e.statut' => '1' ,
2021-02-23 22:03:23 +01:00
'e.fk_parent' => 'id or ref of warehouse'
);
$this -> import_updatekeys_array [ $r ] = array ( 'p.ref' => 'Ref' );
2012-10-27 20:27:07 +02:00
2012-10-28 13:57:21 +01:00
// Import stocks
$r ++ ;
2020-04-10 10:59:32 +02:00
$this -> import_code [ $r ] = $this -> rights_class . '_' . $r ;
$this -> import_label [ $r ] = " Stocks " ; // Translation key
2020-12-03 19:45:36 +01:00
$this -> import_icon [ $r ] = " stock " ;
2020-04-10 10:59:32 +02:00
$this -> import_entities_array [ $r ] = array (); // We define here only fields that use another icon that the one defined into import_icon
$this -> import_tables_array [ $r ] = array ( 'ps' => MAIN_DB_PREFIX . 'product_stock' );
$this -> import_fields_array [ $r ] = array ( 'ps.fk_product' => " Product* " , 'ps.fk_entrepot' => " Warehouse* " , 'ps.reel' => " Stock* " );
$this -> import_convertvalue_array [ $r ] = array (
'ps.fk_product' => array ( 'rule' => 'fetchidfromref' , 'classfile' => '/product/class/product.class.php' , 'class' => 'Product' , 'method' => 'fetch' , 'element' => 'product' ),
'ps.fk_entrepot' => array ( 'rule' => 'fetchidfromref' , 'classfile' => '/product/stock/class/entrepot.class.php' , 'class' => 'Entrepot' , 'method' => 'fetch' , 'element' => 'ref' )
2016-04-11 18:08:03 +02:00
);
2020-04-10 10:59:32 +02:00
$this -> import_examplevalues_array [ $r ] = array (
2021-02-23 22:03:23 +01:00
'ps.fk_product' => " id or ref of product " , 'ps.fk_entrepot' => " id or ref of warehouse " , 'ps.reel' => " 10 "
2012-10-28 13:57:21 +01:00
);
2020-04-10 10:59:32 +02:00
$this -> import_updatekeys_array [ $r ] = array ( 'ps.fk_product' => 'Product' , 'ps.fk_entrepot' => " Warehouse " );
$this -> import_run_sql_after_array [ $r ] = array ( // Because we may change data that are denormalized, we must update dernormalized data after.
2021-10-28 00:12:41 +02:00
'UPDATE ' . MAIN_DB_PREFIX . 'product as p SET p.stock = (SELECT SUM(ps.reel) FROM ' . MAIN_DB_PREFIX . 'product_stock ps WHERE ps.fk_product = p.rowid);'
2012-10-28 13:57:21 +01:00
);
2008-10-01 21:10:17 +02:00
}
2018-10-06 11:57:53 +02:00
2018-05-05 14:33:34 +02:00
/**
2019-02-26 21:13:07 +01:00
* Function called when module is enabled .
* The init function add constants , boxes , permissions and menus ( defined in constructor ) into Dolibarr database .
* It also creates data directories
2018-05-05 14:33:34 +02:00
*
2019-02-26 21:13:07 +01:00
* @ param string $options Options when enabling module ( '' , 'noboxes' )
* @ return int 1 if OK , 0 if KO
2018-05-05 14:33:34 +02:00
*/
2019-02-26 21:13:07 +01:00
public function init ( $options = '' )
2018-05-05 14:33:34 +02:00
{
2020-04-10 10:59:32 +02:00
global $conf , $langs ;
2018-05-05 14:33:34 +02:00
2022-02-06 13:31:44 +01:00
$result = $this -> _load_tables ( '/install/mysql/tables/' , 'stock' );
if ( $result < 0 ) {
return - 1 ; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default')
}
2018-05-05 14:33:34 +02:00
// Permissions
$this -> remove ( $options );
//ODT template
2020-08-18 14:55:56 +02:00
$src = DOL_DOCUMENT_ROOT . '/install/doctemplates/stocks/template_warehouse.odt' ;
$dirodt = DOL_DATA_ROOT . '/doctemplates/stocks' ;
$dest = $dirodt . '/template_warehouse.odt' ;
2018-05-05 14:33:34 +02:00
2021-02-23 22:03:23 +01:00
if ( file_exists ( $src ) && ! file_exists ( $dest )) {
2018-05-05 14:33:34 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
dol_mkdir ( $dirodt );
2020-04-10 10:59:32 +02:00
$result = dol_copy ( $src , $dest , 0 , 0 );
2021-02-23 22:03:23 +01:00
if ( $result < 0 ) {
2018-05-05 14:33:34 +02:00
$langs -> load ( " errors " );
2020-04-10 10:59:32 +02:00
$this -> error = $langs -> trans ( 'ErrorFailToCopyFile' , $src , $dest );
2018-05-05 14:33:34 +02:00
return 0 ;
}
}
$sql = array ();
$sql = array (
2021-08-27 22:42:04 +02:00
" DELETE FROM " . MAIN_DB_PREFIX . " document_model WHERE nom = ' " . $this -> db -> escape ( $this -> const [ 1 ][ 2 ]) . " ' AND type = 'stock' AND entity = " . (( int ) $conf -> entity ),
" INSERT INTO " . MAIN_DB_PREFIX . " document_model (nom, type, entity) VALUES(' " . $this -> db -> escape ( $this -> const [ 1 ][ 2 ]) . " ','stock', " . (( int ) $conf -> entity ) . " ) " ,
" DELETE FROM " . MAIN_DB_PREFIX . " document_model WHERE nom = ' " . $this -> db -> escape ( $this -> const [ 2 ][ 2 ]) . " ' AND type = 'mouvement' AND entity = " . (( int ) $conf -> entity ),
" INSERT INTO " . MAIN_DB_PREFIX . " document_model (nom, type, entity) VALUES(' " . $this -> db -> escape ( $this -> const [ 2 ][ 2 ]) . " ','mouvement', " . (( int ) $conf -> entity ) . " ) " ,
2018-05-05 14:33:34 +02:00
);
2019-01-27 11:55:16 +01:00
return $this -> _init ( $sql , $options );
2018-05-05 14:33:34 +02:00
}
2003-11-13 16:12:07 +01:00
}