* Copyright (C) 2013-2014 Cedric GROSS * * 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 . */ /** * \file product/class/productbatch.class.php * \ingroup productbatch * \brief Manage record and specific data for batch number management */ require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php"); /** * Manage record for batch number management */ class Productbatch extends CommonObject { var $element='productbatch'; //!< Id that identify managed objects private static $_table_element='product_batch'; //!< Name of table without prefix where object is stored var $id; var $tms=''; var $fk_product_stock; var $sellby=''; var $eatby=''; var $batch=''; var $qty; var $import_key; public $warehouseid; /** * Constructor * * @param DoliDb $db Database handler */ function __construct($db) { $this->db = $db; return 1; } /** * Create object into database * * @param User $user User that creates * @param int $notrigger 0=launch triggers after, 1=disable triggers * @return int <0 if KO, Id of created object if OK */ function create($user, $notrigger=0) { global $conf, $langs; $error=0; // Clean parameters $this->clean_param(); // Check parameters // Put here code to add control on parameters values // Insert request $sql = "INSERT INTO ".MAIN_DB_PREFIX.self::$_table_element." ("; $sql.= "fk_product_stock,"; $sql.= "sellby,"; $sql.= "eatby,"; $sql.= "batch,"; $sql.= "qty,"; $sql.= "import_key"; $sql.= ") VALUES ("; $sql.= " ".(! isset($this->fk_product_stock)?'NULL':$this->fk_product_stock).","; $sql.= " ".(! isset($this->sellby) || dol_strlen($this->sellby)==0?'NULL':"'".$this->db->idate($this->sellby)."'").","; $sql.= " ".(! isset($this->eatby) || dol_strlen($this->eatby)==0?'NULL':"'".$this->db->idate($this->eatby)."'").","; $sql.= " ".(! isset($this->batch)?'NULL':"'".$this->db->escape($this->batch)."'").","; $sql.= " ".(! isset($this->qty)?'NULL':$this->qty).","; $sql.= " ".(! isset($this->import_key)?'NULL':"'".$this->db->escape($this->import_key)."'").""; $sql.= ")"; $this->db->begin(); dol_syslog(get_class($this)."::create", LOG_DEBUG); $resql=$this->db->query($sql); if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } if (! $error) { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.self::$_table_element); if (! $notrigger) { // Uncomment this and change MYOBJECT to your own tag if you // want this action calls a trigger. //// Call triggers //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; //$interface=new Interfaces($this->db); //$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf); //if ($result < 0) { $error++; $this->errors=$interface->errors; } //// End call triggers } } // Commit or rollback if ($error) { $this->db->rollback(); return -1*$error; } else { $this->db->commit(); return $this->id; } } /** * Load object in memory from the database * * @param int $id Id object * @return int <0 if KO, >0 if OK */ function fetch($id) { global $langs; $sql = "SELECT"; $sql.= " t.rowid,"; $sql.= " t.tms,"; $sql.= " t.fk_product_stock,"; $sql.= " t.sellby,"; $sql.= " t.eatby,"; $sql.= " t.batch,"; $sql.= " t.qty,"; $sql.= " t.import_key,"; $sql.= " w.fk_entrepot"; $sql.= " FROM ".MAIN_DB_PREFIX.self::$_table_element." as t"; $sql.= " INNER JOIN ".MAIN_DB_PREFIX."product_stock w on t.fk_product_stock=w.rowid"; $sql.= " WHERE t.rowid = ".$id; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { if ($this->db->num_rows($resql)) { $obj = $this->db->fetch_object($resql); $this->id = $obj->rowid; $this->tms = $this->db->jdate($obj->tms); $this->fk_product_stock = $obj->fk_product_stock; $this->sellby = $this->db->jdate($obj->sellby); $this->eatby = $this->db->jdate($obj->eatby); $this->batch = $obj->batch; $this->qty = $obj->qty; $this->import_key = $obj->import_key; $this->warehouseid= $obj->fk_entrepot; } $this->db->free($resql); return 1; } else { $this->error = "Error ".$this->db->lasterror(); return -1; } } /** * Update object into database * * @param User $user User that modifies * @param int $notrigger 0=launch triggers after, 1=disable triggers * @return int <0 if KO, >0 if OK */ function update($user=null, $notrigger=0) { global $conf, $langs; $error=0; // Clean parameters $this->clean_param(); // TODO Check qty is ok for stock move. Negative may not be allowed. if ($this->qty < 0) { } // Update request $sql = "UPDATE ".MAIN_DB_PREFIX.self::$_table_element." SET"; $sql.= " fk_product_stock=".(isset($this->fk_product_stock)?$this->fk_product_stock:"null").","; $sql.= " sellby=".(dol_strlen($this->sellby)!=0 ? "'".$this->db->idate($this->sellby)."'" : 'null').","; $sql.= " eatby=".(dol_strlen($this->eatby)!=0 ? "'".$this->db->idate($this->eatby)."'" : 'null').","; $sql.= " batch=".(isset($this->batch)?"'".$this->db->escape($this->batch)."'":"null").","; $sql.= " qty=".(isset($this->qty)?$this->qty:"null").","; $sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null").""; $sql.= " WHERE rowid=".$this->id." AND tms='".$this->db->idate($this->tms)."'"; $this->db->begin(); dol_syslog(get_class($this)."::update", LOG_DEBUG); $resql = $this->db->query($sql); if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } if (! $error) { if (! $notrigger) { // Uncomment this and change MYOBJECT to your own tag if you // want this action calls a trigger. //// Call triggers //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; //$interface=new Interfaces($this->db); //$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf); //if ($result < 0) { $error++; $this->errors=$interface->errors; } //// End call triggers } } // Commit or rollback if ($error) { foreach($this->errors as $errmsg) { dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); $this->error.=($this->error?', '.$errmsg:$errmsg); } $this->db->rollback(); return -1*$error; } else { $this->db->commit(); return 1; } } /** * Delete object in database * * @param User $user User that deletes * @param int $notrigger 0=launch triggers after, 1=disable triggers * @return int <0 if KO, >0 if OK */ function delete($user, $notrigger=0) { global $conf, $langs; $error=0; $this->db->begin(); if (! $error) { if (! $notrigger) { // Uncomment this and change MYOBJECT to your own tag if you // want this action calls a trigger. //// Call triggers //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; //$interface=new Interfaces($this->db); //$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf); //if ($result < 0) { $error++; $this->errors=$interface->errors; } //// End call triggers } } if (! $error) { $sql = "DELETE FROM ".MAIN_DB_PREFIX.self::$_table_element.""; $sql.= " WHERE rowid=".$this->id; dol_syslog(get_class($this)."::delete", LOG_DEBUG); $resql = $this->db->query($sql); if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } } // Commit or rollback if ($error) { foreach($this->errors as $errmsg) { dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); $this->error.=($this->error?', '.$errmsg:$errmsg); } $this->db->rollback(); return -1*$error; } else { $this->db->commit(); return 1; } } /** * Load an object from its id and create a new one in database * * @param int $fromid Id of object to clone * @return int New id of clone */ function createFromClone($fromid) { global $user,$langs; $error=0; $object=new Productbatch($this->db); $object->context['createfromclone']='createfromclone'; $this->db->begin(); // Load source object $object->fetch($fromid); $object->id=0; $object->statut=0; // Clear fields // ... // Create clone $result=$object->create($user); // Other options if ($result < 0) { $this->error=$object->error; $error++; } if (! $error) { } unset($object->context['createfromclone']); // End if (! $error) { $this->db->commit(); return $object->id; } else { $this->db->rollback(); return -1; } } /** * Initialise object with example values * Id must be 0 if object instance is a specimen * * @return void */ function initAsSpecimen() { $this->id=0; $this->tms=''; $this->fk_product_stock=''; $this->sellby=''; $this->eatby=''; $this->batch=''; $this->import_key=''; } /** * Clean fields (triming) * * @return void */ private function clean_param() { if (isset($this->fk_product_stock)) $this->fk_product_stock=(int) trim($this->fk_product_stock); if (isset($this->batch)) $this->batch=trim($this->batch); if (isset($this->qty)) $this->qty=(float) trim($this->qty); if (isset($this->import_key)) $this->import_key=trim($this->import_key); } /** * Find first detail record that match eather eat-by or sell-by or batch within given warehouse * * @param int $fk_product_stock id product_stock for objet * @param date $eatby eat-by date for objet * @param date $sellby sell-by date for objet * @param string $batch_number batch number for objet * @return int <0 if KO, >0 if OK */ function find($fk_product_stock=0, $eatby='',$sellby='',$batch_number='') { global $langs; $where = array(); $sql = "SELECT"; $sql.= " t.rowid,"; $sql.= " t.tms,"; $sql.= " t.fk_product_stock,"; $sql.= " t.sellby,"; $sql.= " t.eatby,"; $sql.= " t.batch,"; $sql.= " t.qty,"; $sql.= " t.import_key"; $sql.= " FROM ".MAIN_DB_PREFIX.self::$_table_element." as t"; $sql.= " WHERE fk_product_stock=".$fk_product_stock; if (! empty($eatby)) array_push($where," eatby = '".$this->db->idate($eatby)."'"); if (! empty($sellby)) array_push($where," sellby = '".$this->db->idate($sellby)."'"); if (! empty($batch_number)) $sql.= " AND batch = '".$this->db->escape($batch_number)."'"; if (! empty($where)) $sql.= " AND (".implode(" OR ",$where).")"; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { if ($this->db->num_rows($resql)) { $obj = $this->db->fetch_object($resql); $this->id = $obj->rowid; $this->tms = $this->db->jdate($obj->tms); $this->fk_product_stock = $obj->fk_product_stock; $this->sellby = $this->db->jdate($obj->sellby); $this->eatby = $this->db->jdate($obj->eatby); $this->batch = $obj->batch; $this->qty = $obj->qty; $this->import_key = $obj->import_key; } $this->db->free($resql); return 1; } else { $this->error="Error ".$this->db->lasterror(); return -1; } } /** * Return all batch detail records for given product and warehouse * * @param DoliDB $db database object * @param int $fk_product_stock id product_stock for objet * @param int $with_qty doesn't return line with 0 quantity * @return int <0 if KO, >0 if OK */ public static function findAll($db,$fk_product_stock,$with_qty=0) { global $langs; $ret = array(); $sql = "SELECT"; $sql.= " t.rowid,"; $sql.= " t.tms,"; $sql.= " t.fk_product_stock,"; $sql.= " t.sellby,"; $sql.= " t.eatby,"; $sql.= " t.batch,"; $sql.= " t.qty,"; $sql.= " t.import_key"; $sql.= " FROM ".MAIN_DB_PREFIX."product_batch as t"; $sql.= " WHERE fk_product_stock=".$fk_product_stock; if ($with_qty) $sql.= " AND qty<>0"; dol_syslog("productbatch::findAll", LOG_DEBUG); $resql=$db->query($sql); if ($resql) { $num = $db->num_rows($resql); $i=0; while ($i < $num) { $obj = $db->fetch_object($resql); $tmp = new productbatch($db); $tmp->id = $obj->rowid; $tmp->tms = $db->jdate($obj->tms); $tmp->fk_product_stock = $obj->fk_product_stock; $tmp->sellby = $db->jdate($obj->sellby); $tmp->eatby = $db->jdate($obj->eatby); $tmp->batch = $obj->batch; $tmp->qty = $obj->qty; $tmp->import_key = $obj->import_key; array_push($ret,$tmp); $i++; } $db->free($resql); return $ret; } else { $error="Error ".$db->lasterror(); return -1; } } }