forked from Wavyzz/dolibarr
708 lines
19 KiB
PHP
708 lines
19 KiB
PHP
<?php
|
|
/* Copyright (C) 2016 ATM Consulting <support@atm-consulting.fr>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/**
|
|
* \file htdocs/inventory/class/product.inventory.php
|
|
* \ingroup product
|
|
* \brief File of class to manage predefined products stock
|
|
*/
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/coreobject.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
|
|
|
class Inventory extends CoreObject
|
|
{
|
|
public $element='inventory';
|
|
public $table_element='inventory';
|
|
public $fk_element='fk_inventory';
|
|
protected $childtables=array('inventorydet'); // To test if we can delete object
|
|
protected $isnolinkedbythird = 1; // No field fk_soc
|
|
protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
|
|
|
|
/**
|
|
* Warehouse Id
|
|
* @var int
|
|
*/
|
|
public $fk_warehouse;
|
|
/**
|
|
* Entity Id
|
|
* @var int
|
|
*/
|
|
public $entity;
|
|
|
|
/**
|
|
* Status
|
|
* @var int
|
|
*/
|
|
public $status;
|
|
/**
|
|
* Inventory Date
|
|
* @var date
|
|
*/
|
|
public $date_inventory;
|
|
/**
|
|
* Inventory Title
|
|
* @var string
|
|
*/
|
|
public $title;
|
|
|
|
/**
|
|
* Attribute object linked with database
|
|
* @var array
|
|
*/
|
|
protected $__fields=array(
|
|
'fk_warehouse'=>array('type'=>'integer','index'=>true)
|
|
,'entity'=>array('type'=>'integer','index'=>true)
|
|
,'status'=>array('type'=>'integer','index'=>true)
|
|
,'date_inventory'=>array('type'=>'date')
|
|
,'title'=>array('type'=>'string')
|
|
);
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param DoliDB $db Database handler
|
|
*/
|
|
public function __construct(DoliDB &$db)
|
|
{
|
|
global $conf;
|
|
|
|
parent::__construct($db);
|
|
parent::init();
|
|
|
|
$this->status = 0;
|
|
$this->entity = $conf->entity;
|
|
$this->errors = array();
|
|
$this->amount = 0;
|
|
}
|
|
|
|
/**
|
|
* Function to sort children object
|
|
*/
|
|
public function sort_det()
|
|
{
|
|
if(!empty($this->Inventorydet)) usort($this->Inventorydet, array('Inventory', 'customSort'));
|
|
}
|
|
|
|
/**
|
|
* Get object and children from database
|
|
*
|
|
* @param int $id Id of object to load
|
|
* @param bool $loadChild used to load children from database
|
|
* @return int >0 if OK, <0 if KO, 0 if not found
|
|
*/
|
|
public function fetch($id, $loadChild = true)
|
|
{
|
|
if(!$loadChild) $this->withChild = false;
|
|
|
|
$res = parent::fetch($id, $loadChild);
|
|
if($res > 0)
|
|
{
|
|
$this->sort_det();
|
|
$this->amount = 0;
|
|
if(!empty($this->Inventorydet ))
|
|
{
|
|
foreach($this->Inventorydet as &$det)
|
|
{
|
|
$this->amount += $det->qty_view * $det->pmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* Custom function call by usort
|
|
*
|
|
* @param Inventorydet $objA first Inventorydet object
|
|
* @param Inventorydet $objB second Inventorydet object
|
|
* @return int
|
|
*/
|
|
private function customSort(&$objA, &$objB)
|
|
{
|
|
$r = strcmp(strtoupper(trim($objA->product->ref)), strtoupper(trim($objB->product->ref)));
|
|
|
|
if ($r < 0) $r = -1;
|
|
elseif ($r > 0) $r = 1;
|
|
else $r = 0;
|
|
|
|
return $r;
|
|
}
|
|
|
|
/**
|
|
* @param User $user user object
|
|
* @return int
|
|
*/
|
|
public function changePMP(User &$user)
|
|
{
|
|
$error = 0;
|
|
$this->db->begin();
|
|
|
|
if(!empty($this->Inventorydet))
|
|
{
|
|
foreach ($this->Inventorydet as $k => &$Inventorydet)
|
|
{
|
|
if($Inventorydet->new_pmp>0)
|
|
{
|
|
$Inventorydet->pmp = $Inventorydet->new_pmp;
|
|
$Inventorydet->new_pmp = 0;
|
|
|
|
$res = $this->db->query('UPDATE '.MAIN_DB_PREFIX.'product as p SET pmp = '.$Inventorydet->pmp.' WHERE rowid = '.$Inventorydet->fk_product );
|
|
if (!$res)
|
|
{
|
|
$error++;
|
|
$this->error = $this->db->lasterror();
|
|
$this->errors[] = $this->db->lasterror();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$res = parent::update($user);
|
|
if (!$res)
|
|
{
|
|
$error++;
|
|
$this->error = $this->db->lasterror();
|
|
$this->errors[] = $this->db->lasterror();
|
|
}
|
|
|
|
|
|
if (!$error)
|
|
{
|
|
$this->db->commit();
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to update object or create or delete if needed
|
|
*
|
|
* @param User $user user object
|
|
* @return < 0 if ko, > 0 if ok
|
|
*/
|
|
public function update(User &$user)
|
|
{
|
|
$error = 0;
|
|
$this->db->begin();
|
|
|
|
// if we valid the inventory we save the stock at the same time
|
|
if ($this->status)
|
|
{
|
|
$res = $this->regulate();
|
|
if ($res < 0)
|
|
{
|
|
$error++;
|
|
$this->error = $this->db->lasterror();
|
|
$this->errors[] = $this->db->lasterror();
|
|
}
|
|
}
|
|
|
|
$res = parent::update($user);
|
|
if (!$res)
|
|
{
|
|
$error++;
|
|
$this->error = $this->db->lasterror();
|
|
$this->errors[] = $this->db->lasterror();
|
|
}
|
|
|
|
if (!$error)
|
|
{
|
|
$this->db->commit();
|
|
return $this->id;
|
|
}
|
|
else
|
|
{
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to update current object
|
|
*
|
|
* @param array $Tab Array of values
|
|
* @return int
|
|
*/
|
|
public function set_values(&$Tab)
|
|
{
|
|
global $langs;
|
|
|
|
if (isset($Tab['qty_to_add']))
|
|
{
|
|
foreach ($Tab['qty_to_add'] as $k => $qty)
|
|
{
|
|
$qty = (float) price2num($qty);
|
|
|
|
if ($qty < 0)
|
|
{
|
|
$this->errors[] = $langs->trans('inventoryErrorQtyAdd');
|
|
return -1;
|
|
}
|
|
|
|
$product = new Product($this->db);
|
|
$product->fetch($this->Inventorydet[$k]->fk_product);
|
|
|
|
$this->Inventorydet[$k]->pmp = $product->pmp;
|
|
$this->Inventorydet[$k]->qty_view += $qty;
|
|
}
|
|
}
|
|
|
|
return parent::set_values($Tab);
|
|
}
|
|
|
|
/**
|
|
* Function to delete all Inventorydet
|
|
*
|
|
* @param User $user user object
|
|
* @return < 0 if ko, > 0 if ok
|
|
*/
|
|
public function deleteAllLine(User &$user)
|
|
{
|
|
foreach($this->Inventorydet as &$det)
|
|
{
|
|
$det->to_delete = true;
|
|
}
|
|
|
|
$res = $this->update($user);
|
|
|
|
if ($res > 0) $this->Inventorydet = array();
|
|
else return -1;
|
|
}
|
|
|
|
/**
|
|
* Function to add Inventorydet
|
|
*
|
|
* @param int $fk_product fk_product of Inventorydet
|
|
* @param int $fk_warehouse fk_warehouse target
|
|
* @return bool
|
|
*/
|
|
public function add_product($fk_product, $fk_warehouse=0)
|
|
{
|
|
$k = $this->addChild('Inventorydet');
|
|
$det = &$this->Inventorydet[$k];
|
|
|
|
$det->fk_inventory = $this->id;
|
|
$det->fk_product = $fk_product;
|
|
$det->fk_warehouse = empty($fk_warehouse) ? $this->fk_warehouse : $fk_warehouse;
|
|
|
|
$det->load_product();
|
|
|
|
$date = $this->get_date('date_inventory', 'Y-m-d');
|
|
if(empty($date)) $date = $this->get_date('datec', 'Y-m-d');
|
|
$det->setStockDate( $date , $fk_warehouse);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Duplication method product to add datem
|
|
* Adjust stock in a warehouse for product
|
|
*
|
|
* @param int $fk_product id of product
|
|
* @param int $fk_warehouse id of warehouse
|
|
* @param double $nbpiece nb of units
|
|
* @param int $movement 0 = add, 1 = remove
|
|
* @param string $label Label of stock movement
|
|
* @param double $price Unit price HT of product, used to calculate average weighted price (PMP in french). If 0, average weighted price is not changed.
|
|
* @param string $inventorycode Inventory code
|
|
* @return int <0 if KO, >0 if OK
|
|
*/
|
|
public function correct_stock($fk_product, $fk_warehouse, $nbpiece, $movement, $label='', $price=0, $inventorycode='')
|
|
{
|
|
global $conf, $user;
|
|
|
|
if ($fk_warehouse)
|
|
{
|
|
$this->db->begin();
|
|
|
|
require_once DOL_DOCUMENT_ROOT .'/product/stock/class/mouvementstock.class.php';
|
|
|
|
$op[0] = "+".trim($nbpiece);
|
|
$op[1] = "-".trim($nbpiece);
|
|
|
|
$datem = empty($conf->global->INVENTORY_USE_INVENTORY_DATE_FROM_DATEMVT) ? dol_now() : $this->date_inventory;
|
|
|
|
$movementstock=new MouvementStock($this->db);
|
|
$movementstock->origin = new stdClass();
|
|
$movementstock->origin->element = 'inventory';
|
|
$movementstock->origin->id = $this->id;
|
|
$result=$movementstock->_create($user,$fk_product,$fk_warehouse,$op[$movement],$movement,$price,$label,$inventorycode, $datem);
|
|
|
|
if ($result >= 0)
|
|
{
|
|
$this->db->commit();
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
$this->error=$movementstock->error;
|
|
$this->errors=$movementstock->errors;
|
|
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to regulate stock
|
|
*
|
|
* @return int
|
|
*/
|
|
public function regulate()
|
|
{
|
|
global $langs,$conf;
|
|
|
|
if($conf->global->INVENTORY_DISABLE_VIRTUAL)
|
|
{
|
|
$pdt_virtuel = false;
|
|
// Test if virtual product is enabled
|
|
if($conf->global->PRODUIT_SOUSPRODUITS)
|
|
{
|
|
$pdt_virtuel = true;
|
|
$conf->global->PRODUIT_SOUSPRODUITS = 0;
|
|
}
|
|
}
|
|
|
|
foreach ($this->Inventorydet as $k => $Inventorydet)
|
|
{
|
|
$product = new Product($this->db);
|
|
$product->fetch($Inventorydet->fk_product);
|
|
|
|
if ($Inventorydet->qty_view != $Inventorydet->qty_stock)
|
|
{
|
|
$Inventorydet->qty_regulated = $Inventorydet->qty_view - $Inventorydet->qty_stock;
|
|
$nbpiece = abs($Inventorydet->qty_regulated);
|
|
$movement = (int) ($Inventorydet->qty_view < $Inventorydet->qty_stock); // 0 = add ; 1 = remove
|
|
|
|
//$href = dol_buildpath('/inventory/inventory.php?id='.$this->id.'&action=view', 1);
|
|
|
|
$res = $this->correct_stock($product->id, $Inventorydet->fk_warehouse, $nbpiece, $movement, $langs->trans('inventoryMvtStock'));
|
|
if ($res < 0) return -1;
|
|
}
|
|
}
|
|
|
|
if($conf->global->INVENTORY_DISABLE_VIRTUAL)
|
|
{
|
|
// Test if virtual product was enabled before regulate
|
|
if($pdt_virtuel) $conf->global->PRODUIT_SOUSPRODUITS = 1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Get the title
|
|
* @return string
|
|
*/
|
|
public function getTitle()
|
|
{
|
|
global $langs;
|
|
|
|
return !empty($this->title) ? $this->title : $langs->trans('inventoryTitle').' '.$this->id;
|
|
}
|
|
|
|
|
|
/**
|
|
* Return clicable link of object (with eventually picto)
|
|
*
|
|
* @param int $withpicto Add picto into link
|
|
* @return string
|
|
*/
|
|
public function getNomUrl($withpicto = 1)
|
|
{
|
|
return '<a href="'.dol_buildpath('/inventory/inventory.php?id='.$this->id, 1).'">'.($withpicto ? img_picto('','object_list.png','',0).' ' : '').$this->getTitle().'</a>';
|
|
}
|
|
|
|
/**
|
|
* Function to add products by default from warehouse and children
|
|
*
|
|
* @param $fk_warehouse
|
|
* @param int $fk_category
|
|
* @param int $fk_supplier
|
|
* @param int $only_prods_in_stock
|
|
*
|
|
* @return int
|
|
*/
|
|
public function add_products_for($fk_warehouse,$fk_category=0,$fk_supplier=0,$only_prods_in_stock=0)
|
|
{
|
|
$warehouse = new Entrepot($this->db);
|
|
$warehouse->fetch($fk_warehouse);
|
|
$TChildWarehouses = array($fk_warehouse);
|
|
$warehouse->get_children_warehouses($fk_warehouse, $TChildWarehouses);
|
|
|
|
$sql = 'SELECT ps.fk_product, ps.fk_entrepot';
|
|
$sql.= ' FROM '.MAIN_DB_PREFIX.'product_stock ps';
|
|
$sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'product p ON (p.rowid = ps.fk_product)';
|
|
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product cp ON (cp.fk_product = p.rowid)';
|
|
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_fournisseur_price pfp ON (pfp.fk_product = p.rowid)';
|
|
$sql.= ' WHERE ps.fk_entrepot IN ('.implode(', ', $TChildWarehouses).')';
|
|
|
|
if ($fk_category>0) $sql.= ' AND cp.fk_categorie='.$fk_category;
|
|
if ($fk_supplier>0) $sql.= ' AND pfp.fk_soc = '.$fk_supplier;
|
|
if (!empty($only_prods_in_stock)) $sql.= ' AND ps.reel > 0';
|
|
|
|
$sql.=' GROUP BY ps.fk_product, ps.fk_entrepot ORDER BY p.ref ASC,p.label ASC';
|
|
|
|
$res = $this->db->query($sql);
|
|
if($res)
|
|
{
|
|
while($obj = $this->db->fetch_object($res))
|
|
{
|
|
$this->add_product($obj->fk_product, $obj->fk_entrepot);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
$this->error = $this->db->lasterror();
|
|
$this->errors[] = $this->db->lasterror();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return clicable link of inventory object
|
|
*
|
|
* @param int $id id of inventory
|
|
* @param int $withpicto Add picto into link
|
|
* @return string
|
|
*/
|
|
static function getLink($id, $withpicto=1)
|
|
{
|
|
global $langs,$db;
|
|
|
|
$inventory = new Inventory($db);
|
|
if($inventory->fetch($id, false) > 0) return $inventory->getNomUrl($withpicto);
|
|
else return $langs->trans('InventoryUnableToFetchObject');
|
|
}
|
|
|
|
/**
|
|
* Function to get the sql select of inventory
|
|
* @param string $type
|
|
* @return string
|
|
*/
|
|
static function getSQL($type)
|
|
{
|
|
global $conf;
|
|
|
|
$sql = '';
|
|
if($type == 'All')
|
|
{
|
|
$sql = 'SELECT i.rowid,i.title, e.label, i.date_inventory, i.fk_warehouse, i.datec, i.tms, i.status';
|
|
$sql.= ' FROM '.MAIN_DB_PREFIX.'inventory i';
|
|
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'entrepot e ON (e.rowid = i.fk_warehouse)';
|
|
$sql.= ' WHERE i.entity = '.(int) $conf->entity;
|
|
}
|
|
|
|
return $sql;
|
|
}
|
|
}
|
|
|
|
class Inventorydet extends CoreObject
|
|
{
|
|
public $element='inventorydet';
|
|
public $table_element='inventorydet';
|
|
protected $isnolinkedbythird = 1; // No field fk_soc
|
|
protected $ismultientitymanaged = 0; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
|
|
|
|
public $fk_inventory;
|
|
public $fk_warehouse;
|
|
public $fk_product;
|
|
public $entity;
|
|
public $qty_view;
|
|
public $qty_stock;
|
|
public $qty_regulated;
|
|
public $pmp;
|
|
public $pa;
|
|
public $new_pmp;
|
|
|
|
protected $__fields=array(
|
|
'fk_inventory'=>array('type'=>'int')
|
|
,'fk_warehouse'=>array('type'=>'int')
|
|
,'fk_product'=>array('type'=>'int')
|
|
,'entity'=>array('type'=>'int')
|
|
,'qty_view'=>array('type'=>'float')
|
|
,'qty_stock'=>array('type'=>'float')
|
|
,'qty_regulated'=>array('type'=>'float')
|
|
,'pmp'=>array('type'=>'float')
|
|
,'pa'=>array('type'=>'float')
|
|
,'new_pmp'=>array('type'=>'float')
|
|
);
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param DoliDB $db Database handler
|
|
*/
|
|
function __construct(DoliDB &$db)
|
|
{
|
|
global $conf;
|
|
|
|
parent::__construct($db);
|
|
parent::init();
|
|
|
|
$this->entity = $conf->entity;
|
|
$this->errors = array();
|
|
|
|
$this->product = null;
|
|
$this->current_pa = 0;
|
|
}
|
|
|
|
/**
|
|
* Get object and children from database
|
|
*
|
|
* @param int $id id of inventorydet object
|
|
* @param bool $loadChild load children
|
|
* @return int
|
|
*/
|
|
function fetch($id, $loadChild = true)
|
|
{
|
|
$res = parent::fetch($id);
|
|
$this->load_product();
|
|
$this->fetch_current_pa();
|
|
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* Function to get the unit buy price
|
|
*
|
|
* @return bool
|
|
*/
|
|
function fetch_current_pa()
|
|
{
|
|
global $db,$conf;
|
|
|
|
if(empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)) return false;
|
|
|
|
if($this->pa > 0)
|
|
{
|
|
$this->current_pa = $this->pa;
|
|
}
|
|
else
|
|
{
|
|
dol_include_once('/fourn/class/fournisseur.product.class.php');
|
|
$p= new ProductFournisseur($db);
|
|
$p->find_min_price_product_fournisseur($this->fk_product);
|
|
|
|
if($p->fourn_qty>0) $this->current_pa = $p->fourn_price / $p->fourn_qty;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Function to set pa attribute from date en fk_warehouse
|
|
*
|
|
* @param date $date date value
|
|
* @param int $fk_warehouse fk_warehouse target
|
|
*/
|
|
function setStockDate($date, $fk_warehouse)
|
|
{
|
|
list($pmp, $stock) = $this->getPmpStockFromDate($date, $fk_warehouse);
|
|
|
|
$this->qty_stock = $stock;
|
|
$this->pmp = $pmp;
|
|
|
|
$last_pa = 0;
|
|
$sql = 'SELECT price FROM '.MAIN_DB_PREFIX.'stock_mouvement';
|
|
$sql.= ' WHERE fk_entrepot = '.$fk_warehouse;
|
|
$sql.= ' AND fk_product = '.$this->fk_product;
|
|
$sql.= ' AND (origintype=\'order_supplier\' || origintype=\'invoice_supplier\')';
|
|
$sql.= ' AND price > 0';
|
|
$sql.= ' AND datem <= \''.$date.' 23:59:59\'';
|
|
$sql.= ' ORDER BY datem DESC LIMIT 1';
|
|
|
|
$res = $this->db->query($sql);
|
|
if($res && $obj = $this->db->fetch_object($res))
|
|
{
|
|
$last_pa = $obj->price;
|
|
}
|
|
|
|
$this->pa = $last_pa;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the last pmp and last stock from date and warehouse
|
|
*
|
|
* @param date $date date to check
|
|
* @param int $fk_warehouse id of warehouse
|
|
* @return array
|
|
*/
|
|
function getPmpStockFromDate($date, $fk_warehouse)
|
|
{
|
|
$res = $this->product->load_stock();
|
|
|
|
if($res>0)
|
|
{
|
|
$stock = isset($this->product->stock_warehouse[$fk_warehouse]->real) ? $this->product->stock_warehouse[$fk_warehouse]->real : 0;
|
|
$pmp = $this->product->pmp;
|
|
}
|
|
|
|
//All Stock mouvement between now and inventory date
|
|
$sql = 'SELECT value, price';
|
|
$sql.= ' FROM '.MAIN_DB_PREFIX.'stock_mouvement';
|
|
$sql.= ' WHERE fk_product = '.$this->product->id;
|
|
$sql.= ' AND fk_entrepot = '.$fk_warehouse;
|
|
$sql.= ' AND datem > \''.date('Y-m-d 23:59:59', strtotime($date)).'\'';
|
|
$sql.= ' ORDER BY datem DESC';
|
|
|
|
$res = $this->db->query($sql);
|
|
|
|
$laststock = $stock;
|
|
$lastpmp = $pmp;
|
|
|
|
if($res)
|
|
{
|
|
while($mouvement = $this->db->fetch_object($res))
|
|
{
|
|
$price = ($mouvement->price > 0 && $mouvement->value > 0) ? $mouvement->price : $lastpmp;
|
|
$stock_value = $laststock * $lastpmp;
|
|
$laststock -= $mouvement->value;
|
|
$last_stock_value = $stock_value - ($mouvement->value * $price);
|
|
$lastpmp = ($laststock != 0) ? $last_stock_value / $laststock : $lastpmp;
|
|
}
|
|
}
|
|
|
|
return array($lastpmp, $laststock);
|
|
}
|
|
|
|
/**
|
|
* Fetch the product linked with the line
|
|
* @return void
|
|
*/
|
|
function load_product()
|
|
{
|
|
global $db;
|
|
|
|
if($this->fk_product>0)
|
|
{
|
|
$this->product = new Product($db);
|
|
$this->product->fetch($this->fk_product);
|
|
}
|
|
}
|
|
}
|