From 3b99fb01ee2bb61b94f1452d87ee1bc5c56d9aa2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 17 May 2016 10:33:27 +0200 Subject: [PATCH] Fix duplicate table --- dev/skeletons/build_class_from_table.php | 10 +- htdocs/comm/card.php | 4 +- htdocs/fourn/card.php | 2 +- .../install/mysql/migration/3.9.0-4.0.0.sql | 24 +- .../install/mysql/tables/llx_product_lot.sql | 21 +- .../mysql/tables/llx_stock_lotserial.sql | 34 - .../stock/class/mouvementstock.class.php | 64 +- .../product/stock/class/productlot.class.php | 671 ++++++++++++++++++ htdocs/product/stock/productlot_card.php | 376 ++++++++++ htdocs/product/stock/productlot_list.php | 549 ++++++++++++++ 10 files changed, 1676 insertions(+), 79 deletions(-) delete mode 100644 htdocs/install/mysql/tables/llx_stock_lotserial.sql create mode 100644 htdocs/product/stock/class/productlot.class.php create mode 100644 htdocs/product/stock/productlot_card.php create mode 100644 htdocs/product/stock/productlot_list.php diff --git a/dev/skeletons/build_class_from_table.php b/dev/skeletons/build_class_from_table.php index 4de319dabc9..800bafe6318 100755 --- a/dev/skeletons/build_class_from_table.php +++ b/dev/skeletons/build_class_from_table.php @@ -180,7 +180,7 @@ if (! $sourcecontent) } // Define output variables -$outfile='out.'.$classmin.'.class.php'; +$outfile=$classmin.'.class.php'; $targetcontent=$sourcecontent; // Substitute module name @@ -455,9 +455,9 @@ else $error++; //-------------------------------------------------------------------- $skeletonfiles=array( - $path.'skeleton_script.php' => 'out.'.$classmin.'_script.php', - $path.'skeleton_list.php' => 'out.'.$classmin.'_list.php', - $path.'skeleton_card.php' => 'out.'.$classmin.'_card.php' + $path.'skeleton_script.php' => $classmin.'_script.php', + $path.'skeleton_list.php' => $classmin.'_list.php', + $path.'skeleton_card.php' => $classmin.'_card.php' ); foreach ($skeletonfiles as $skeletonfile => $outfile) @@ -670,5 +670,5 @@ foreach ($skeletonfiles as $skeletonfile => $outfile) // -------------------- END OF BUILD_CLASS_FROM_TABLE SCRIPT -------------------- -print "You can now rename generated files by removing the 'out.' prefix in their name and store them into directory /yourmodule/class (for .class.php file) or /yourmodule.\n"; +print "You can now move generated files to store them into directory /yourmodule/class (for .class.php file) or /yourmodule.\n"; return $error; diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index ce611528a62..e1828e911c7 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -456,8 +456,8 @@ if ($id > 0) } // Categories - if (!empty( $conf->categorie->enabled ) && !empty( $user->rights->categorie->lire )) { - print '' . $langs->trans( "Categories" ) . ''; + if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { + print '' . $langs->trans("CustomersCategoriesShort") . ''; print ''; print $form->showCategories( $object->id, 'customer', 1 ); print ""; diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index b64a8ee77e4..8c533f0f547 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -231,7 +231,7 @@ if ($object->id > 0) // Categories if (! empty($conf->categorie->enabled)) { - print '' . $langs->trans("Categories") . ''; + print '' . $langs->trans("SuppliersCategoriesShort") . ''; print ''; print $form->showCategories($object->id, 'supplier', 1); print ""; diff --git a/htdocs/install/mysql/migration/3.9.0-4.0.0.sql b/htdocs/install/mysql/migration/3.9.0-4.0.0.sql index c72ec02ca51..93469ff5a8f 100644 --- a/htdocs/install/mysql/migration/3.9.0-4.0.0.sql +++ b/htdocs/install/mysql/migration/3.9.0-4.0.0.sql @@ -39,19 +39,23 @@ ALTER TABLE llx_opensurvey_sondage ADD COLUMN status integer DEFAULT 1 after dat ALTER TABLE llx_expedition ADD COLUMN billed smallint DEFAULT 0; +-- DROP TABLE llx_product_lot; CREATE TABLE llx_product_lot ( - rowid integer AUTO_INCREMENT PRIMARY KEY, - tms timestamp, - fk_product integer NOT NULL, - batch varchar(30) NOT NULL, - eatby datetime DEFAULT NULL, - sellby datetime DEFAULT NULL, - note_public text, - note_private text, - qty double NOT NULL DEFAULT 0, - import_key varchar(14) DEFAULT NULL + rowid integer AUTO_INCREMENT PRIMARY KEY, + entity integer, + fk_product integer NOT NULL, -- Id of product + batch varchar(30) DEFAULT NULL, -- Lot or serial number + eatby date DEFAULT NULL, -- Eatby date + sellby date DEFAULT NULL, -- Sellby date + datec datetime, + tms timestamp, + fk_user_creat integer, + fk_user_modif integer, + import_key integer ) ENGINE=InnoDB; +DROP TABLE llx_stock_serial; + ALTER TABLE llx_product ADD COLUMN note_public text; ALTER TABLE llx_user ADD COLUMN note_public text; diff --git a/htdocs/install/mysql/tables/llx_product_lot.sql b/htdocs/install/mysql/tables/llx_product_lot.sql index 718cb11744c..498b6039977 100644 --- a/htdocs/install/mysql/tables/llx_product_lot.sql +++ b/htdocs/install/mysql/tables/llx_product_lot.sql @@ -18,14 +18,15 @@ -- ============================================================================ CREATE TABLE llx_product_lot ( - rowid integer AUTO_INCREMENT PRIMARY KEY, - tms timestamp, - fk_product integer NOT NULL, - batch varchar(30) NOT NULL, - eatby datetime DEFAULT NULL, - sellby datetime DEFAULT NULL, - note_public text, - note_private text, - qty double NOT NULL DEFAULT 0, - import_key varchar(14) DEFAULT NULL + rowid integer AUTO_INCREMENT PRIMARY KEY, + entity integer, + fk_product integer NOT NULL, -- Id of product + batch varchar(30) DEFAULT NULL, -- Lot or serial number + eatby date DEFAULT NULL, -- Eatby date + sellby date DEFAULT NULL, -- Sellby date + datec datetime, + tms timestamp, + fk_user_creat integer, + fk_user_modif integer, + import_key integer ) ENGINE=InnoDB; diff --git a/htdocs/install/mysql/tables/llx_stock_lotserial.sql b/htdocs/install/mysql/tables/llx_stock_lotserial.sql deleted file mode 100644 index ed8a14e49d0..00000000000 --- a/htdocs/install/mysql/tables/llx_stock_lotserial.sql +++ /dev/null @@ -1,34 +0,0 @@ --- ============================================================================ --- Copyright (C) 2015 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 --- 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 . --- --- This table may be used to store eatby and sellby date for a couple --- product-batch number. --- ============================================================================ - -create table llx_stock_lotserial -( - rowid integer AUTO_INCREMENT PRIMARY KEY, - entity integer, - fk_product integer NOT NULL, -- Id of product - batch varchar(30) DEFAULT NULL, -- Lot or serial number - eatby date DEFAULT NULL, -- Eatby date - sellby date DEFAULT NULL, -- Sellby date - datec datetime, - tms timestamp, - fk_user_creat integer, - fk_user_modif integer, - import_key integer -) ENGINE=innodb; diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index f1542d593b6..9b6db71be9e 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -73,6 +73,7 @@ class MouvementStock extends CommonObject global $conf, $langs; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; $error = 0; dol_syslog(get_class($this)."::_create start userid=$user->id, fk_product=$fk_product, warehouse=$entrepot_id, qty=$qty, type=$type, price=$price, label=$label, inventorycode=$inventorycode, datem=".$datem.", eatby=".$eatby.", sellby=".$sellby.", batch=".$batch.", skip_batch=".$skip_batch); @@ -140,24 +141,53 @@ class MouvementStock extends CommonObject { $num = $this->db->num_rows($resql); $i=0; - while ($i < $num) + if ($num > 0) { - $obj = $this->db->fetch_object($resql); - if ($this->db->jdate($obj->eatby) != $eatby) - { - $this->errors[]=$langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby)), dol_print_date($eatby)); - dol_syslog($langs->transnoentities("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby)), dol_print_date($eatby)), LOG_ERR); - $this->db->rollback(); - return -3; - } - if ($this->db->jdate($obj->sellby) != $sellby) - { - $this->errors[]=$langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->sellby)), dol_print_date($sellby)); - dol_syslog($langs->transnoentities("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->sellby)), dol_print_date($sellby)), LOG_ERR); - $this->db->rollback(); - return -3; - } - $i++; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + if ($obj->eatby) + { + if ($eatby) + { + if ($this->db->jdate($obj->eatby) != $eatby) // If found and eatby/sellby defined into table and provided and differs, return error + { + $this->errors[]=$langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby)), dol_print_date($eatby)); + dol_syslog($langs->transnoentities("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby)), dol_print_date($eatby)), LOG_ERR); + $this->db->rollback(); + return -3; + } + } + } + if ($obj->sellby) + { + if ($sellby) + { + if ($this->db->jdate($obj->sellby) != $sellby) // If found and eatby/sellby defined into table and provided and differs, return error + { + $this->errors[]=$langs->trans("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->sellby)), dol_print_date($sellby)); + dol_syslog($langs->transnoentities("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->sellby)), dol_print_date($sellby)), LOG_ERR); + $this->db->rollback(); + return -3; + } + } + } + $i++; + } + } + else + { + $productlot = new Productlot($this->db); + $productlot->fk_product = $fk_product; + $productlot->batch = $batch; + $result = $productlot->create($user); + if (! $result) + { + $this->error = $productlot->error; + $this->errors = $productlot->errors; + $this->db->rollback(); + return -4; + } } } else diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php new file mode 100644 index 00000000000..26970a68e85 --- /dev/null +++ b/htdocs/product/stock/class/productlot.class.php @@ -0,0 +1,671 @@ + + * Copyright (C) 2014 Juanjo Menent + * Copyright (C) 2015 Florian Henry + * Copyright (C) 2015 Raphaƫl Doursenaud + * Copyright (C) ---Put here your own copyright and developer email--- + * + * 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 stock/productlot.class.php + * \ingroup stock + * \brief This file is an example for a CRUD class file (Create/Read/Update/Delete) + * Put some comments here + */ + +// Put here all includes required by your class file +require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + +/** + * Class Productlot + * + * Put here description of your class + * @see CommonObject + */ +class Productlot extends CommonObject +{ + /** + * @var string Id to identify managed objects + */ + public $element = 'productlot'; + /** + * @var string Name of table without prefix where object is stored + */ + public $table_element = 'product_lot'; + + /** + * @var ProductlotLine[] Lines + */ + public $lines = array(); + + /** + */ + + public $tms = ''; + public $fk_product; + public $batch; + public $eatby = ''; + public $sellby = ''; + public $note_public; + public $note_private; + public $qty; + public $import_key; + + /** + */ + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } + + /** + * Create object into database + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, Id of created object if OK + */ + public function create(User $user, $notrigger = false) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $error = 0; + + // Clean parameters + + if (isset($this->fk_product)) { + $this->fk_product = trim($this->fk_product); + } + if (isset($this->batch)) { + $this->batch = trim($this->batch); + } + if (isset($this->note_public)) { + $this->note_public = trim($this->note_public); + } + if (isset($this->note_private)) { + $this->note_private = trim($this->note_private); + } + if (isset($this->qty)) { + $this->qty = trim($this->qty); + } + if (isset($this->import_key)) { + $this->import_key = trim($this->import_key); + } + + + + // Check parameters + // Put here code to add control on parameters values + + // Insert request + $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '('; + + $sql.= 'fk_product,'; + $sql.= 'batch,'; + $sql.= 'eatby,'; + $sql.= 'sellby,'; + $sql.= 'note_public,'; + $sql.= 'note_private,'; + $sql.= 'qty'; + $sql.= 'import_key'; + + + $sql .= ') VALUES ('; + + $sql .= ' '.(! isset($this->fk_product)?'NULL':$this->fk_product).','; + $sql .= ' '.(! isset($this->batch)?'NULL':"'".$this->db->escape($this->batch)."'").','; + $sql .= ' '.(! isset($this->eatby) || dol_strlen($this->eatby)==0?'NULL':"'".$this->db->idate($this->eatby)."'").','; + $sql .= ' '.(! isset($this->sellby) || dol_strlen($this->sellby)==0?'NULL':"'".$this->db->idate($this->sellby)."'").','; + $sql .= ' '.(! isset($this->note_public)?'NULL':"'".$this->db->escape($this->note_public)."'").','; + $sql .= ' '.(! isset($this->note_private)?'NULL':"'".$this->db->escape($this->note_private)."'").','; + $sql .= ' '.(! isset($this->qty)?'NULL':"'".$this->qty."'").','; + $sql .= ' '.(! isset($this->import_key)?'NULL':"'".$this->db->escape($this->import_key)."'"); + + + $sql .= ')'; + + $this->db->begin(); + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + } + + if (!$error) { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element); + + if (!$notrigger) { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action to call a trigger. + + //// Call triggers + //$result=$this->call_trigger('MYOBJECT_CREATE',$user); + //if ($result < 0) $error++; + //// 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 + * @param string $ref Ref + * + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetch($id, $ref = null) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = 'SELECT'; + $sql .= ' t.rowid,'; + + $sql .= " t.tms,"; + $sql .= " t.fk_product,"; + $sql .= " t.batch,"; + $sql .= " t.eatby,"; + $sql .= " t.sellby,"; + $sql .= " t.note_public,"; + $sql .= " t.note_private,"; + $sql .= " t.qty,"; + $sql .= " t.import_key"; + + + $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t'; + if (null !== $ref) { + $sql .= ' WHERE t.ref = ' . '\'' . $ref . '\''; + } else { + $sql .= ' WHERE t.rowid = ' . $id; + } + + $resql = $this->db->query($sql); + if ($resql) { + $numrows = $this->db->num_rows($resql); + if ($numrows) { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; + + $this->tms = $this->db->jdate($obj->tms); + $this->fk_product = $obj->fk_product; + $this->batch = $obj->batch; + $this->eatby = $this->db->jdate($obj->eatby); + $this->sellby = $this->db->jdate($obj->sellby); + $this->note_public = $obj->note_public; + $this->note_private = $obj->note_private; + $this->qty = $obj->qty; + $this->import_key = $obj->import_key; + + + } + $this->db->free($resql); + + if ($numrows) { + return 1; + } else { + return 0; + } + } else { + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + + return - 1; + } + } + + /** + * Load object in memory from the database + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit offset limit + * @param int $offset offset limit + * @param array $filter filter array + * @param string $filtermode filter mode (AND or OR) + * + * @return int <0 if KO, >0 if OK + */ + public function fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter = array(), $filtermode='AND') + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = 'SELECT'; + $sql .= ' t.rowid,'; + + $sql .= " t.tms,"; + $sql .= " t.fk_product,"; + $sql .= " t.batch,"; + $sql .= " t.eatby,"; + $sql .= " t.sellby,"; + $sql .= " t.note_public,"; + $sql .= " t.note_private,"; + $sql .= " t.qty,"; + $sql .= " t.import_key"; + + + $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element. ' as t'; + + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + $sqlwhere [] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\''; + } + } + if (count($sqlwhere) > 0) { + $sql .= ' WHERE ' . implode(' '.$filtermode.' ', $sqlwhere); + } + + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield,$sortorder); + } + if (!empty($limit)) { + $sql .= ' ' . $this->db->plimit($limit + 1, $offset); + } + $this->lines = array(); + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + + while ($obj = $this->db->fetch_object($resql)) { + $line = new ProductlotLine(); + + $line->id = $obj->rowid; + + $line->tms = $this->db->jdate($obj->tms); + $line->fk_product = $obj->fk_product; + $line->batch = $obj->batch; + $line->eatby = $this->db->jdate($obj->eatby); + $line->sellby = $this->db->jdate($obj->sellby); + $line->note_public = $obj->note_public; + $line->note_private = $obj->note_private; + $line->qty = $obj->qty; + $line->import_key = $obj->import_key; + + + + $this->lines[$line->id] = $line; + } + $this->db->free($resql); + + return $num; + } else { + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + + return - 1; + } + } + + /** + * Update object into database + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = false) + { + $error = 0; + + dol_syslog(__METHOD__, LOG_DEBUG); + + // Clean parameters + + if (isset($this->fk_product)) { + $this->fk_product = trim($this->fk_product); + } + if (isset($this->batch)) { + $this->batch = trim($this->batch); + } + if (isset($this->note_public)) { + $this->note_public = trim($this->note_public); + } + if (isset($this->note_private)) { + $this->note_private = trim($this->note_private); + } + if (isset($this->qty)) { + $this->qty = trim($this->qty); + } + if (isset($this->import_key)) { + $this->import_key = trim($this->import_key); + } + + + + // Check parameters + // Put here code to add a control on parameters values + + // Update request + $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET'; + + $sql .= ' tms = '.(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : "'".$this->db->idate(dol_now())."'").','; + $sql .= ' fk_product = '.(isset($this->fk_product)?$this->fk_product:"null").','; + $sql .= ' batch = '.(isset($this->batch)?"'".$this->db->escape($this->batch)."'":"null").','; + $sql .= ' eatby = '.(! isset($this->eatby) || dol_strlen($this->eatby) != 0 ? "'".$this->db->idate($this->eatby)."'" : 'null').','; + $sql .= ' sellby = '.(! isset($this->sellby) || dol_strlen($this->sellby) != 0 ? "'".$this->db->idate($this->sellby)."'" : 'null').','; + $sql .= ' note_public = '.(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").','; + $sql .= ' note_private = '.(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"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; + + $this->db->begin(); + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + } + + if (!$error && !$notrigger) { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action calls a trigger. + + //// Call triggers + //$result=$this->call_trigger('MYOBJECT_MODIFY',$user); + //if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} + //// End call triggers + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return - 1 * $error; + } else { + $this->db->commit(); + + return 1; + } + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $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 + //$result=$this->call_trigger('MYOBJECT_DELETE',$user); + //if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} + //// End call triggers + } + } + + if (!$error) { + $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element; + $sql .= ' WHERE rowid=' . $this->id; + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + } + } + + // Commit or rollback + if ($error) { + $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 + */ + public function createFromClone($fromid) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + global $user; + $error = 0; + $object = new Productlot($this->db); + + $this->db->begin(); + + // Load source object + $object->fetch($fromid); + // Reset object + $object->id = 0; + + // Clear fields + // ... + + // Create clone + $result = $object->create($user); + + // Other options + if ($result < 0) { + $error ++; + $this->errors = $object->errors; + dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + } + + // End + if (!$error) { + $this->db->commit(); + + return $object->id; + } else { + $this->db->rollback(); + + return - 1; + } + } + + /** + * Return a link to the user card (with optionaly the picto) + * Use this->id,this->lastname, this->firstname + * + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to + * @param integer $notooltip 1=Disable tooltip + * @param int $maxlen Max length of visible user name + * @param string $morecss Add more css on link + * @return string String with URL + */ + function getNomUrl($withpicto=0, $option='', $notooltip=0, $maxlen=24, $morecss='') + { + global $langs, $conf, $db; + global $dolibarr_main_authentication, $dolibarr_main_demo; + global $menumanager; + + + $result = ''; + $companylink = ''; + + $label = '' . $langs->trans("MyModule") . ''; + $label.= '
'; + $label.= '' . $langs->trans('Ref') . ': ' . $this->ref; + + $link = 'ref . $linkend; + return $result; + } + + /** + * Retourne le libelle du status d'un user (actif, inactif) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->status,$mode); + } + + /** + * Renvoi le libelle d'un status donne + * + * @param int $status Id status + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status + */ + function LibStatut($status,$mode=0) + { + global $langs; + + if ($mode == 0) + { + $prefix=''; + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($mode == 1) + { + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($mode == 2) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled'); + } + if ($mode == 3) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5'); + } + if ($mode == 4) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled'); + } + if ($mode == 5) + { + if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4'); + if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5'); + } + } + + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + $this->id = 0; + + $this->tms = ''; + $this->fk_product = ''; + $this->batch = ''; + $this->eatby = ''; + $this->sellby = ''; + $this->note_public = ''; + $this->note_private = ''; + $this->qty = ''; + $this->import_key = ''; + + + } + +} + +/** + * Class ProductlotLine + */ +class ProductlotLine +{ + /** + * @var int ID + */ + public $id; + /** + * @var mixed Sample line property 1 + */ + + public $tms = ''; + public $fk_product; + public $batch; + public $eatby = ''; + public $sellby = ''; + public $note_public; + public $note_private; + public $qty; + public $import_key; + + /** + * @var mixed Sample line property 2 + */ + +} diff --git a/htdocs/product/stock/productlot_card.php b/htdocs/product/stock/productlot_card.php new file mode 100644 index 00000000000..2e8620797c7 --- /dev/null +++ b/htdocs/product/stock/productlot_card.php @@ -0,0 +1,376 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * 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 stock/productlot_card.php + * \ingroup stock + * \brief This file is an example of a php page + * Initialy built by build_class_from_table on 2016-05-17 10:33 + */ + +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) + +// Change this following line to use the correct relative path (../, ../../, etc) +$res=0; +if (! $res && file_exists("../main.inc.php")) $res=@include '../main.inc.php'; // to work if your module directory is into dolibarr root htdocs directory +if (! $res && file_exists("../../main.inc.php")) $res=@include '../../main.inc.php'; // to work if your module directory is into a subdir of root htdocs directory +if (! $res && file_exists("../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../dolibarr/htdocs/main.inc.php'; // Used on dev env only +if (! $res && file_exists("../../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../../dolibarr/htdocs/main.inc.php'; // Used on dev env only +if (! $res) die("Include of main fails"); +// Change this following line to use the correct relative path from htdocs +include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); +dol_include_once('/stock/class/productlot.class.php'); + +// Load traductions files requiredby by page +$langs->load("stock"); +$langs->load("other"); + +// Get parameters +$id = GETPOST('id','int'); +$action = GETPOST('action','alpha'); +$backtopage = GETPOST('backtopage'); +$myparam = GETPOST('myparam','alpha'); + + +$search_fk_product=GETPOST('search_fk_product','int'); +$search_batch=GETPOST('search_batch','alpha'); +$search_note_public=GETPOST('search_note_public','alpha'); +$search_note_private=GETPOST('search_note_private','alpha'); +$search_qty=GETPOST('search_qty','alpha'); +$search_import_key=GETPOST('search_import_key','alpha'); + + + +// Protection if external user +if ($user->societe_id > 0) +{ + //accessforbidden(); +} + +if (empty($action) && empty($id) && empty($ref)) $action='list'; + +// Load object if id or ref is provided as parameter +$object=new Productlot($db); +if (($id > 0 || ! empty($ref)) && $action != 'add') +{ + $result=$object->fetch($id,$ref); + if ($result < 0) dol_print_error($db); +} + +// Initialize technical object to manage hooks of modules. Note that conf->hooks_modules contains array array +$hookmanager->initHooks(array('productlot')); +$extrafields = new ExtraFields($db); + + + +/******************************************************************* +* ACTIONS +* +* Put here all code to do according to value of "action" parameter +********************************************************************/ + +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + // Action to add record + if ($action == 'add') + { + if (GETPOST('cancel')) + { + $urltogo=$backtopage?$backtopage:dol_buildpath('/stock/list.php',1); + header("Location: ".$urltogo); + exit; + } + + $error=0; + + /* object_prop_getpost_prop */ + + $object->fk_product=GETPOST('fk_product','int'); + $object->batch=GETPOST('batch','alpha'); + $object->note_public=GETPOST('note_public','alpha'); + $object->note_private=GETPOST('note_private','alpha'); + $object->qty=GETPOST('qty','alpha'); + $object->import_key=GETPOST('import_key','alpha'); + + + + if (empty($object->ref)) + { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors'); + } + + if (! $error) + { + $result=$object->create($user); + if ($result > 0) + { + // Creation OK + $urltogo=$backtopage?$backtopage:dol_buildpath('/stock/list.php',1); + header("Location: ".$urltogo); + exit; + } + { + // Creation KO + if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors'); + else setEventMessages($object->error, null, 'errors'); + $action='create'; + } + } + else + { + $action='create'; + } + } + + // Cancel + if ($action == 'update' && GETPOST('cancel')) $action='view'; + + // Action to update record + if ($action == 'update' && ! GETPOST('cancel')) + { + $error=0; + + + $object->fk_product=GETPOST('fk_product','int'); + $object->batch=GETPOST('batch','alpha'); + $object->note_public=GETPOST('note_public','alpha'); + $object->note_private=GETPOST('note_private','alpha'); + $object->qty=GETPOST('qty','alpha'); + $object->import_key=GETPOST('import_key','alpha'); + + + + if (empty($object->ref)) + { + $error++; + setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired",$langs->transnoentitiesnoconv("Ref")), null, 'errors'); + } + + if (! $error) + { + $result=$object->update($user); + if ($result > 0) + { + $action='view'; + } + else + { + // Creation KO + if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors'); + else setEventMessages($object->error, null, 'errors'); + $action='edit'; + } + } + else + { + $action='edit'; + } + } + + // Action to delete + if ($action == 'confirm_delete') + { + $result=$object->delete($user); + if ($result > 0) + { + // Delete OK + setEventMessages("RecordDeleted", null, 'mesgs'); + header("Location: ".dol_buildpath('/stock/list.php',1)); + exit; + } + else + { + if (! empty($object->errors)) setEventMessages(null, $object->errors, 'errors'); + else setEventMessages($object->error, null, 'errors'); + } + } +} + + + + +/*************************************************** +* VIEW +* +* Put here all code to build page +****************************************************/ + +llxHeader('','MyPageName',''); + +$form=new Form($db); + + +// Put here content of your page + +// Example : Adding jquery code +print ''; + + +// Part to create +if ($action == 'create') +{ + print load_fiche_titre($langs->trans("NewMyModule")); + + print '
'; + print ''; + print ''; + + dol_fiche_head(); + + print ''."\n"; + // print ''; + // +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + + print '
'.$langs->trans("Label").'
'.$langs->trans("Fieldfk_product").'
'.$langs->trans("Fieldbatch").'
'.$langs->trans("Fieldnote_public").'
'.$langs->trans("Fieldnote_private").'
'.$langs->trans("Fieldqty").'
'.$langs->trans("Fieldimport_key").'
'."\n"; + + dol_fiche_end(); + + print '
 
'; + + print '
'; +} + + + +// Part to edit record +if (($id || $ref) && $action == 'edit') +{ + print load_fiche_titre($langs->trans("MyModule")); + + print '
'; + print ''; + print ''; + print ''; + + dol_fiche_head(); + + print ''."\n"; + // print ''; + // +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + + print '
'.$langs->trans("Label").'
'.$langs->trans("Fieldfk_product").'
'.$langs->trans("Fieldbatch").'
'.$langs->trans("Fieldnote_public").'
'.$langs->trans("Fieldnote_private").'
'.$langs->trans("Fieldqty").'
'.$langs->trans("Fieldimport_key").'
'; + + dol_fiche_end(); + + print '
'; + print '   '; + print '
'; + + print '
'; +} + + + +// Part to show record +if ($id && (empty($action) || $action == 'view' || $action == 'delete')) +{ + print load_fiche_titre($langs->trans("MyModule")); + + dol_fiche_head(); + + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteMyOjbect'), $langs->trans('ConfirmDeleteMyObject'), 'confirm_delete', '', 0, 1); + print $formconfirm; + } + + print ''."\n"; + // print ''; + // +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + + print '
'.$langs->trans("Label").'
'.$langs->trans("Fieldfk_product").'$object->fk_product
'.$langs->trans("Fieldbatch").'$object->batch
'.$langs->trans("Fieldnote_public").'$object->note_public
'.$langs->trans("Fieldnote_private").'$object->note_private
'.$langs->trans("Fieldqty").'$object->qty
'.$langs->trans("Fieldimport_key").'$object->import_key
'; + + dol_fiche_end(); + + + // Buttons + print '
'."\n"; + + + // Example 2 : Adding links to objects + //$somethingshown=$form->showLinkedObjectBlock($object); + //$linktoelem = $form->showLinkToObjectBlock($object); + //if ($linktoelem) print '
'.$linktoelem; + +} + + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php new file mode 100644 index 00000000000..ded98827e31 --- /dev/null +++ b/htdocs/product/stock/productlot_list.php @@ -0,0 +1,549 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * 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 stock/productlot_list.php + * \ingroup stock + * \brief This file is an example of a php page + * Initialy built by build_class_from_table on 2016-05-17 10:33 + */ + +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) + +// Change this following line to use the correct relative path (../, ../../, etc) +$res=0; +if (! $res && file_exists("../main.inc.php")) $res=@include '../main.inc.php'; // to work if your module directory is into dolibarr root htdocs directory +if (! $res && file_exists("../../main.inc.php")) $res=@include '../../main.inc.php'; // to work if your module directory is into a subdir of root htdocs directory +if (! $res && file_exists("../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../dolibarr/htdocs/main.inc.php'; // Used on dev env only +if (! $res && file_exists("../../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../../dolibarr/htdocs/main.inc.php'; // Used on dev env only +if (! $res) die("Include of main fails"); +// Change this following line to use the correct relative path from htdocs +require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +dol_include_once('/stock/class/productlot.class.php'); + +// Load traductions files requiredby by page +$langs->load("stock"); +$langs->load("other"); + +// Get parameters +$id = GETPOST('id','int'); +$action = GETPOST('action','alpha'); +$backtopage = GETPOST('backtopage'); +$myparam = GETPOST('myparam','alpha'); + + +$search_fk_product=GETPOST('search_fk_product','int'); +$search_batch=GETPOST('search_batch','alpha'); +$search_note_public=GETPOST('search_note_public','alpha'); +$search_note_private=GETPOST('search_note_private','alpha'); +$search_qty=GETPOST('search_qty','alpha'); +$search_import_key=GETPOST('search_import_key','alpha'); + + +$search_myfield=GETPOST('search_myfield'); +$optioncss = GETPOST('optioncss','alpha'); + +// Load variable for pagination +$limit = GETPOST("limit")?GETPOST("limit","int"):$conf->liste_limit; +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if ($page == -1) { $page = 0; } +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortfield) $sortfield="t.rowid"; // Set here default search field +if (! $sortorder) $sortorder="ASC"; + +// Protection if external user +$socid=0; +if ($user->societe_id > 0) +{ + $socid = $user->societe_id; + //accessforbidden(); +} + +// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array +$hookmanager->initHooks(array('productlotlist')); +$extrafields = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label('stock'); +$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_'); + +// Load object if id or ref is provided as parameter +$object=new Productlot($db); +if (($id > 0 || ! empty($ref)) && $action != 'add') +{ + $result=$object->fetch($id,$ref); + if ($result < 0) dol_print_error($db); +} + +// Definition of fields for list +$arrayfields=array( + +'t.fk_product'=>array('label'=>$langs->trans("Fieldfk_product"), 'checked'=>1), +'t.batch'=>array('label'=>$langs->trans("Fieldbatch"), 'checked'=>1), +'t.note_public'=>array('label'=>$langs->trans("Fieldnote_public"), 'checked'=>1), +'t.note_private'=>array('label'=>$langs->trans("Fieldnote_private"), 'checked'=>1), +'t.qty'=>array('label'=>$langs->trans("Fieldqty"), 'checked'=>1), +'t.import_key'=>array('label'=>$langs->trans("Fieldimport_key"), 'checked'=>1), + + + //'t.entity'=>array('label'=>$langs->trans("Entity"), 'checked'=>1, 'enabled'=>(! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode))), + 't.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), + 't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), + //'t.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), +); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + } +} + + + + +/******************************************************************* +* ACTIONS +* +* Put here all code to do according to value of "action" parameter +********************************************************************/ + +if (GETPOST('cancel')) { $action='list'; $massaction=''; } +if (! GETPOST('confirmmassaction')) { $massaction=''; } + +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") ||GETPOST("button_removefilter")) // All test are required to be compatible with all browsers +{ + +$search_fk_product=''; +$search_batch=''; +$search_note_public=''; +$search_note_private=''; +$search_qty=''; +$search_import_key=''; + + + $search_date_creation=''; + $search_date_update=''; + $search_array_options=array(); +} + + +if (empty($reshook)) +{ + // Mass actions. Controls on number of lines checked + $maxformassaction=1000; + if (! empty($massaction) && count($toselect) < 1) + { + $error++; + setEventMessages($langs->trans("NoLineChecked"), null, "warnings"); + } + if (! $error && count($toselect) > $maxformassaction) + { + setEventMessages($langs->trans('TooManyRecordForMassAction',$maxformassaction), null, 'errors'); + $error++; + } + + // Action to delete + if ($action == 'confirm_delete') + { + $result=$object->delete($user); + if ($result > 0) + { + // Delete OK + setEventMessages("RecordDeleted", null, 'mesgs'); + header("Location: ".dol_buildpath('/stock/list.php',1)); + exit; + } + else + { + if (! empty($object->errors)) setEventMessages(null,$object->errors,'errors'); + else setEventMessages($object->error,null,'errors'); + } + } +} + + + + +/*************************************************** +* VIEW +* +* Put here all code to build page +****************************************************/ + +llxHeader('','MyPageName',''); + +$form=new Form($db); + +// Put here content of your page +$title = $langs->trans('MyModuleListTitle'); + +// Example : Adding jquery code +print ''; + + +$sql = "SELECT"; +$sql.= " t.rowid,"; + + $sql .= " t.tms,"; + $sql .= " t.fk_product,"; + $sql .= " t.batch,"; + $sql .= " t.eatby,"; + $sql .= " t.sellby,"; + $sql .= " t.note_public,"; + $sql .= " t.note_private,"; + $sql .= " t.qty,"; + $sql .= " t.import_key"; + + +// Add fields for extrafields +foreach ($extrafields->attribute_list as $key => $val) $sql.=",ef.".$key.' as options_'.$key; +// Add fields from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; +$sql.= " FROM ".MAIN_DB_PREFIX."product_lot as t"; +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lot_extrafields as ef on (u.rowid = ef.fk_object)"; +$sql.= " WHERE 1 = 1"; +//$sql.= " WHERE u.entity IN (".getEntity('mytable',1).")"; + +if ($search_fk_product) $sql.= natural_search("fk_product",$search_fk_product); +if ($search_batch) $sql.= natural_search("batch",$search_batch); +if ($search_note_public) $sql.= natural_search("note_public",$search_note_public); +if ($search_note_private) $sql.= natural_search("note_private",$search_note_private); +if ($search_qty) $sql.= natural_search("qty",$search_qty); +if ($search_import_key) $sql.= natural_search("import_key",$search_import_key); + + +if ($sall) $sql.= natural_search(array_keys($fieldstosearchall), $sall); +// Add where from extra fields +foreach ($search_array_options as $key => $val) +{ + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $typ=$extrafields->attribute_type[$tmpkey]; + $mode=0; + if (in_array($typ, array('int','double'))) $mode=1; // Search on a numeric + if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit))) + { + $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); + } +} +// Add where from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; +$sql.=$db->order($sortfield,$sortorder); +//$sql.= $db->plimit($conf->liste_limit+1, $offset); + +// Count total nb of records +$nbtotalofrecords = 0; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); +} + +$sql.= $db->plimit($limit+1, $offset); + + +dol_syslog($script_file, LOG_DEBUG); +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + + $params=''; + if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; + +if ($search_fk_product != '') $params.= '&search_fk_product='.urlencode($search_fk_product); +if ($search_batch != '') $params.= '&search_batch='.urlencode($search_batch); +if ($search_note_public != '') $params.= '&search_note_public='.urlencode($search_note_public); +if ($search_note_private != '') $params.= '&search_note_private='.urlencode($search_note_private); +if ($search_qty != '') $params.= '&search_qty='.urlencode($search_qty); +if ($search_import_key != '') $params.= '&search_import_key='.urlencode($search_import_key); + + + if ($optioncss != '') $param.='&optioncss='.$optioncss; + // Add $param from extra fields + foreach ($search_array_options as $key => $val) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); + } + + print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $params, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit); + + + print '
'; + if ($optioncss != '') print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + if ($sall) + { + foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); + print $langs->trans("FilterOnInto", $all) . join(', ',$fieldstosearchall); + } + + $moreforfilter = ''; + $moreforfilter.='
'; + $moreforfilter.= $langs->trans('MyFilter') . ': '; + $moreforfilter.= '
'; + + if (! empty($moreforfilter)) + { + print '
'; + print $moreforfilter; + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print '
'; + } + + $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; + $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields + + print ''; + + // Fields title + print ''; + if (! empty($arrayfields['t.field1']['checked'])) print_liste_field_titre($arrayfields['t.field1']['label'],$_SERVER['PHP_SELF'],'t.field1','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['t.field2']['checked'])) print_liste_field_titre($arrayfields['t.field2']['label'],$_SERVER['PHP_SELF'],'t.field2','',$param,'',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'],$_SERVER["PHP_SELF"],"t.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'],$_SERVER["PHP_SELF"],"t.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + //if (! empty($arrayfields['t.status']['checked'])) print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"t.status","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch '); + print ''."\n"; + + // Fields title search + print ''; + +if (! empty($arrayfields['t.fk_product']['checked'])) print ''; +if (! empty($arrayfields['t.batch']['checked'])) print ''; +if (! empty($arrayfields['t.note_public']['checked'])) print ''; +if (! empty($arrayfields['t.note_private']['checked'])) print ''; +if (! empty($arrayfields['t.qty']['checked'])) print ''; +if (! empty($arrayfields['t.import_key']['checked'])) print ''; + + + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print ''; + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['t.datec']['checked'])) + { + // Date creation + print ''; + } + if (! empty($arrayfields['t.tms']['checked'])) + { + // Date modification + print ''; + } + /*if (! empty($arrayfields['u.statut']['checked'])) + { + // Status + print ''; + }*/ + // Action column + print ''; + print ''."\n"; + + + $i=0; + $var=true; + $totalarray=array(); + while ($i < min($num, $limit)) + { + $obj = $db->fetch_object($resql); + if ($obj) + { + // You can use here results + print ''; + if (! empty($arrayfields['t.field1']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['t.field2']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + print 'getAlignFlag($key); + if ($align) print ' align="'.$align.'"'; + print '>'; + $tmpkey='options_'.$key; + print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); + print ''; + if (! $i) $totalarray['nbfield']++; + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Date creation + if (! empty($arrayfields['t.datec']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Date modification + if (! empty($arrayfields['t.tms']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Status + /* + if (! empty($arrayfields['u.statut']['checked'])) + { + $userstatic->statut=$obj->statut; + print ''; + }*/ + + // Action column + print ''; + if (! $i) $totalarray['nbfield']++; + + print ''; + } + $i++; + } + + $db->free($resql); + + $parameters=array('sql' => $sql); + $reshook=$hookmanager->executeHooks('printFieldListFooter',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + + print "
'; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $searchclass=''; + if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; + if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; + print ''; + } + print ''; + print ''; + print ''; + print $form->selectarray('search_statut', array('-1'=>'','0'=>$langs->trans('Disabled'),'1'=>$langs->trans('Enabled')),$search_statut); + print ''; + $searchpitco=$form->showFilterAndCheckAddButtons(0); + print $searchpitco; + print '
'.$obj->field1.''.$obj->field2.''; + print dol_print_date($db->jdate($obj->date_creation), 'dayhour'); + print ''; + print dol_print_date($db->jdate($obj->date_update), 'dayhour'); + print ''.$userstatic->getLibStatut(3).'
\n"; + print "
\n"; + + $db->free($result); +} +else +{ + $error++; + dol_print_error($db); +} + + +// End of page +llxFooter(); +$db->close();