From 4a185ba063095269b08941f8966e82316b25eb11 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Fri, 12 Mar 2021 12:47:58 +0100 Subject: [PATCH 1/4] add warehouse quabtity + fix input new quantity --- htdocs/product/inventory/inventory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index dea3b46c946..6c8f6ab5256 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -505,10 +505,10 @@ if ($object->id > 0) { } print ''; - print 'TODO'; + print $obj->qty_stock; print ''; print ''; - print 'rowid).'">'; + print 'rowid).'">'; print ''; print ''; print ''.img_delete().''; From 966d3a6f30abb899216fdbe3d7a913586e8a36b8 Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Mon, 29 Mar 2021 15:18:34 +0200 Subject: [PATCH 2/4] add setrecorded and commit to db --- htdocs/langs/en_US/stocks.lang | 3 +- .../inventory/class/inventory.class.php | 21 +++++ htdocs/product/inventory/inventory.php | 89 ++++++++++++++++--- 3 files changed, 102 insertions(+), 11 deletions(-) diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 8e949661c49..a7205207cf9 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -242,4 +242,5 @@ InventoryRealQtyHelp=Set value to 0 to reset qty
Keep field empty, or remove UpdateByScaning=Update by scaning UpdateByScaningProductBarcode=Update by scan (product barcode) UpdateByScaningLot=Update by scan (lot|serial barcode) -DisableStockChangeOfSubProduct=Deactivate the stock change for all the subproducts of this Kit during this movement. \ No newline at end of file +DisableStockChangeOfSubProduct=Deactivate the stock change for all the subproducts of this Kit during this movement. +LabelOfInventoryMovemement=Inventory %s \ No newline at end of file diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php index ce585c51a10..dc1b46331fc 100644 --- a/htdocs/product/inventory/class/inventory.class.php +++ b/htdocs/product/inventory/class/inventory.class.php @@ -359,6 +359,27 @@ class Inventory extends CommonObject } } + /** + * Set to Recorded + * + * @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 setRecorded(User $user, $notrigger = false) + { + $this->db->begin(); + + $result = $this->setStatut($this::STATUS_RECORDED, null, '', 'INVENTORY_RECORDED'); + + if ($result > 0) { + $this->db->commit(); + } else { + $this->db->rollback(); + return -1; + } + } + /** * Clone and object into another one * diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 6c8f6ab5256..d8e76489ffc 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -27,6 +27,7 @@ include_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; include_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; include_once DOL_DOCUMENT_ROOT.'/product/inventory/lib/inventory.lib.php'; +include_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; // Load translation files required by the page $langs->loadLangs(array("stocks", "other", "productbatch")); @@ -98,6 +99,67 @@ $now = dol_now(); * Actions */ +if ($action == 'update' && $user->rights->stock->mouvement->creer) { + $stockmovment = new MouvementStock($db); + $stockmovment->origin = $object; + + $sql = 'SELECT id.rowid, id.datec as date_creation, id.tms as date_modification, id.fk_inventory, id.fk_warehouse,'; + $sql .= ' id.fk_product, id.batch, id.qty_stock, id.qty_view, id.qty_regulated'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'inventorydet as id'; + $sql .= ' WHERE id.fk_inventory = '.$object->id; + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + $totalarray = array(); + while ($i < $num) { + $line = $db->fetch_object($resql); + $qty_view = $line->qty_view; + $qty_stock = $line->qty_stock; + $stock_movement_qty = $qty_view - $qty_stock; + if ($stock_movement_qty != 0) { + if ($stock_movement_qty < 0) { + $movement_type = 1; + } else { + $movement_type = 0; + } + $idstockmove = $stockmovment->_create($user, $line->fk_product, $line->fk_warehouse, $stock_movement_qty, $movement_type, 0, $langs->trans('LabelOfInventoryMovemement', $object->id), 'INV'.$object->id); + if ($idstockmove < 0) { + $error++; + setEventMessages($stockmovment->error, $stockmovment->errors, 'errors'); + } + } + $i++; + } + if (!$error) { + $object->setRecorded($user); + } + } +} + +if ($action =='updateinventorylines' && $permissiontoadd) { + $sql = 'SELECT id.rowid, id.datec as date_creation, id.tms as date_modification, id.fk_inventory, id.fk_warehouse,'; + $sql .= ' id.fk_product, id.batch, id.qty_stock, id.qty_view, id.qty_regulated'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'inventorydet as id'; + $sql .= ' WHERE id.fk_inventory = '.$object->id; + + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + $totalarray = array(); + while ($i < $num) { + $line = $db->fetch_object($resql); + $lineid = $line->rowid; + $inventoryline = new InventoryLine($db); + $inventoryline->fetch($lineid); + $inventoryline->qty_view = GETPOST("id_".$inventoryline->id); + $inventoryline->update($user); + $i++; + } + } +} + $parameters = array(); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { @@ -419,10 +481,12 @@ if ($object->id > 0) { print ''; print $form->textwithpicto($langs->trans("RealQty"), $langs->trans("InventoryRealQtyHelp")); print ''; - // Actions - print ''; - print ''; - print ''; + if ($object->status == $object::STATUS_VALIDATED) { + // Actions + print ''; + print ''; + print ''; + } // Line to add a new line in inventory if ($object->status == $object::STATUS_VALIDATED) { @@ -508,12 +572,17 @@ if ($object->id > 0) { print $obj->qty_stock; print ''; print ''; - print 'rowid).'">'; - print ''; - print ''; - print ''.img_delete().''; - print ''; - + if ($object->status == $object::STATUS_VALIDATED) { + $qty_view = GETPOST("id_".$obj->rowid) ? GETPOST("id_".$obj->rowid) : $obj->qty_view; + print ''; + print ''; + print ''; + print ''.img_delete().''; + print ''; + } else { + print $obj->qty_view; + print ''; + } print ''; $i++; From 55560b7d38e3817f79e4448e5f265182958f861e Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Tue, 30 Mar 2021 12:35:20 +0200 Subject: [PATCH 3/4] Inventory module working --- htdocs/core/modules/modStock.class.php | 6 +++ htdocs/langs/en_US/stocks.lang | 5 ++- htdocs/product/inventory/card.php | 6 +++ .../inventory/class/inventory.class.php | 27 ++++++++++++- htdocs/product/inventory/inventory.php | 38 +++++++++---------- 5 files changed, 61 insertions(+), 21 deletions(-) diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php index 3d46d606265..c9379fb25d6 100644 --- a/htdocs/core/modules/modStock.class.php +++ b/htdocs/core/modules/modStock.class.php @@ -172,6 +172,12 @@ class modStock extends DolibarrModules $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) + + $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) } // Main menu entries diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index a7205207cf9..639f025425a 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -184,6 +184,7 @@ inventoryCreatePermission=Create new inventory inventoryReadPermission=View inventories inventoryWritePermission=Update inventories inventoryValidatePermission=Validate inventory +inventoryDeletePermission=Delete inventory inventoryTitle=Inventory inventoryListTitle=Inventories inventoryListEmpty=No inventory in progress @@ -243,4 +244,6 @@ UpdateByScaning=Update by scaning UpdateByScaningProductBarcode=Update by scan (product barcode) UpdateByScaningLot=Update by scan (lot|serial barcode) DisableStockChangeOfSubProduct=Deactivate the stock change for all the subproducts of this Kit during this movement. -LabelOfInventoryMovemement=Inventory %s \ No newline at end of file +LabelOfInventoryMovemement=Inventory %s +ReOpen=Reopen +ConfirmFinish=Confirm closing \ No newline at end of file diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index 92ad4c2176b..dda16746398 100644 --- a/htdocs/product/inventory/card.php +++ b/htdocs/product/inventory/card.php @@ -407,6 +407,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''.$langs->trans("SetToDraft").''; } } + // Back to validate + if ($object->status == $object::STATUS_RECORDED) { + if ($permissiontoadd) { + print ''.$langs->trans("ReOpen").''; + } + } // Modify if ($object->status == $object::STATUS_DRAFT) { diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php index dc1b46331fc..bf34dd04efc 100644 --- a/htdocs/product/inventory/class/inventory.class.php +++ b/htdocs/product/inventory/class/inventory.class.php @@ -52,7 +52,7 @@ class Inventory extends CommonObject /** * @var int Does object support extrafields ? 0=No, 1=Yes */ - public $isextrafieldmanaged = 1; + public $isextrafieldmanaged = 0; /** * @var string String with name of icon for inventory @@ -254,6 +254,7 @@ class Inventory extends CommonObject */ public function validate(User $user, $notrigger = false) { + global $conf; $this->db->begin(); $result = 0; @@ -380,6 +381,27 @@ class Inventory extends CommonObject } } + /** + * Set to Canceled + * + * @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 setCanceled(User $user, $notrigger = false) + { + $this->db->begin(); + + $result = $this->setStatut($this::STATUS_CANCELED, null, '', 'INVENTORY_CANCELED'); + + if ($result > 0) { + $this->db->commit(); + } else { + $this->db->rollback(); + return -1; + } + } + /** * Clone and object into another one * @@ -587,9 +609,11 @@ class Inventory extends CommonObject $labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); $labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated').' ('.$langs->trans('Started').')'; $labelStatus[self::STATUS_CANCELED] = $langs->trans('Canceled'); + $labelStatus[self::STATUS_RECORDED] = $langs->trans('Closed'); $labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); $labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Started'); $labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Canceled'); + $labelStatusShort[self::STATUS_RECORDED] = $langs->trans('Closed'); return dolGetStatus($labelStatus[$status], $labelStatusShort[$status], '', 'status'.$status, $mode); } @@ -649,6 +673,7 @@ class Inventory extends CommonObject public function initAsSpecimen() { $this->initAsSpecimenCommon(); + $this->title = ''; } } diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index d8e76489ffc..55f0ef51149 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -99,6 +99,10 @@ $now = dol_now(); * Actions */ +if ($action == 'cancel_record' && $permissiontoadd) { + $object->setCanceled($user); +} + if ($action == 'update' && $user->rights->stock->mouvement->creer) { $stockmovment = new MouvementStock($db); $stockmovment->origin = $object; @@ -285,6 +289,18 @@ if ($object->id > 0) { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneMyObject', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); } + // Confirmation to close + if ($action == 'record') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Close'), $langs->trans('ConfirmFinish'), 'update', '', 0, 1); + $action = 'view'; + } + + // Confirmation to close + if ($action == 'confirm_cancel') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Cancel'), $langs->trans('ConfirmCancel'), 'cancel_record', '', 0, 1); + $action = 'view'; + } + // Call Hook formConfirm $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook @@ -369,24 +385,7 @@ if ($object->id > 0) { // Buttons for actions - if ($action == 'record') { - print '
'; - print ''; - print ''; - print ''; - if ($backtopage) { - print ''; - } - - print '
'; - print ''.$langs->trans("InventoryDesc").'
'; - print ''; - print '   '; - print ''; - print '
'; - print '
'; - print '
'; - } else { + if ($action != 'record') { print '
'."\n"; $parameters = array(); $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook @@ -422,7 +421,8 @@ if ($object->id > 0) { if ($object->status == Inventory::STATUS_VALIDATED) { if ($permissiontoadd) { - print ''.$langs->trans("Finish").''."\n"; + print ''.$langs->trans("Cancel").''."\n"; + print ''.$langs->trans("Close").''."\n"; } else { print ''.$langs->trans('Finish').''."\n"; } From bf42a2ad87eefdbc2cbdb4778763f0f24383debe Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Tue, 30 Mar 2021 14:38:53 +0200 Subject: [PATCH 4/4] Close #4951 : Add TestUnit --- .../inventory/class/inventory.class.php | 4 + test/phpunit/InventoryTest.php | 382 ++++++++++++++++++ 2 files changed, 386 insertions(+) create mode 100644 test/phpunit/InventoryTest.php diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php index bf34dd04efc..e872d7e353a 100644 --- a/htdocs/product/inventory/class/inventory.class.php +++ b/htdocs/product/inventory/class/inventory.class.php @@ -329,6 +329,7 @@ class Inventory extends CommonObject } else { $this->db->rollback(); } + return $result; } /** @@ -358,6 +359,7 @@ class Inventory extends CommonObject } else { $this->db->rollback(); } + return $result; } /** @@ -379,6 +381,7 @@ class Inventory extends CommonObject $this->db->rollback(); return -1; } + return $result; } /** @@ -400,6 +403,7 @@ class Inventory extends CommonObject $this->db->rollback(); return -1; } + return $result; } /** diff --git a/test/phpunit/InventoryTest.php b/test/phpunit/InventoryTest.php new file mode 100644 index 00000000000..1d125a0311c --- /dev/null +++ b/test/phpunit/InventoryTest.php @@ -0,0 +1,382 @@ + + * Copyright (C) 2018 Frédéric France + * + * 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 . + * or see https://www.gnu.org/ + */ + +/** + * \file test/phpunit/InventoryTest.php + * \ingroup test + * \brief PHPUnit test + * \remarks To run this script as CLI: phpunit filename.php + */ + +global $conf,$user,$langs,$db; +//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver +//require_once 'PHPUnit/Autoload.php'; +require_once dirname(__FILE__).'/../../htdocs/master.inc.php'; +require_once dirname(__FILE__).'/../../htdocs/product/inventory/class/inventory.class.php'; + +if (empty($user->id)) { + print "Load permissions for admin user nb 1\n"; + $user->fetch(1); + $user->getrights(); +} +$conf->global->MAIN_DISABLE_ALL_MAILS=1; + + +/** + * Class for PHPUnit tests + * + * @backupGlobals disabled + * @backupStaticAttributes enabled + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. + */ +class InventoryTest extends PHPUnit\Framework\TestCase +{ + protected $savconf; + protected $savuser; + protected $savlangs; + protected $savdb; + + /** + * Constructor + * We save global variables into local variables + * + * @return InventoryTest + */ + public function __construct() + { + parent::__construct(); + + //$this->sharedFixture + global $conf,$user,$langs,$db; + $this->savconf=$conf; + $this->savuser=$user; + $this->savlangs=$langs; + $this->savdb=$db; + + print __METHOD__." db->type=".$db->type." user->id=".$user->id; + //print " - db ".$db->db; + print "\n"; + } + + /** + * setUpBeforeClass + * + * @return void + */ + public static function setUpBeforeClass():void + { + global $conf,$user,$langs,$db; + + $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. + + print __METHOD__."\n"; + } + + /** + * tearDownAfterClass + * + * @return void + */ + public static function tearDownAfterClass():void + { + global $conf,$user,$langs,$db; + $db->rollback(); + + print __METHOD__."\n"; + } + + /** + * Init phpunit tests + * + * @return void + */ + protected function setUp():void + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + print __METHOD__."\n"; + } + + /** + * End phpunit tests + * + * @return void + */ + protected function tearDown():void + { + print __METHOD__."\n"; + } + + /** + * testInventoryCreate + * + * @return int + */ + public function testInventoryCreate() + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $localobject=new Inventory($db); + $localobject->initAsSpecimen(); + $result=$localobject->create($user); + $this->assertLessThan($result, 0); + print __METHOD__." result=".$result."\n"; + return $result; + } + + /** + * testInventoryFetch + * + * @param int $id Id invoice + * @return int + * + * @depends testInventoryCreate + * The depends says test is run only if previous is ok + */ + public function testInventoryFetch($id) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $localobject=new Inventory($this->savdb); + $result=$localobject->fetch($id); + + $this->assertLessThan($result, 0); + print __METHOD__." id=".$id." result=".$result."\n"; + return $localobject; + } + + /** + * testInventoryUpdate + * + * @param Inventory $localobject Invoice + * @return int + * + * @depends testInventoryFetch + * The depends says test is run only if previous is ok + */ + public function testInventoryUpdate($localobject) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $localobject->status = 9; + $localobject->title = 'test'; + $result=$localobject->update($user, $user); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + $this->assertLessThan($result, 0); + return $localobject; + } + + + /** + * testInventoryValidate + * + * @param Inventory $localobject Invoice + * @return void + * + * @depends testInventoryUpdate + * The depends says test is run only if previous is ok + */ + public function testInventoryValidate($localobject) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $result=$localobject->validate($user); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + + $this->assertLessThan($result, 0); + $this->assertEquals($localobject->status, '1'); + return $localobject; + } + + /** + * testInventorySetDraft + * + * @param Inventory $localobject Invoice + * @return void + * + * @depends testInventoryValidate + * The depends says test is run only if previous is ok + */ + public function testInventorySetDraft($localobject) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $result=$localobject->setDraft($user); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + + $this->assertLessThan($result, 0); + $this->assertEquals($localobject->status, '0'); + return $localobject; + } + + /** + * testInventorySetRecorded + * + * @param Inventory $localobject Invoice + * @return void + * + * @depends testInventorySetDraft + * The depends says test is run only if previous is ok + */ + public function testInventorySetRecorded($localobject) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $result=$localobject->setRecorded($user); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + + $this->assertLessThan($result, 0); + $this->assertEquals($localobject->status, '2'); + return $localobject; + } + + /** + * testInventorySetCanceled + * + * @param Inventory $localobject Invoice + * @return void + * + * @depends testInventorySetRecorded + * The depends says test is run only if previous is ok + */ + public function testInventorySetCanceled($localobject) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $result=$localobject->setCanceled($user); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + + $this->assertLessThan($result, 0); + $this->assertEquals($localobject->status, '9'); + return $localobject; + } + + /** + * testInventoryOther + * + * @param Inventory $localobject Invoice + * @return int + * @depends testInventorySetRecorded + * The depends says test is run only if previous is ok + */ + public function testInventoryOther($localobject) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $localobject->info($localobject->id); + print __METHOD__." localobject->date_creation=".$localobject->date_creation."\n"; + $this->assertNotEquals($localobject->date_creation, ''); + return $localobject->id; + } + + /** + * testInventoryDelete + * + * @param int $id Id of invoice + * @return int + * @depends testInventoryOther + * The depends says test is run only if previous is ok + */ + public function testInventoryDelete($id) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $localobject=new Inventory($this->savdb); + $result=$localobject->fetch($id); + $result=$localobject->delete($user); + print __METHOD__." id=".$id." result=".$result."\n"; + $this->assertLessThan($result, 0); + + return $result; + } + + /** + * Compare all public properties values of 2 objects + * + * @param Object $oA Object operand 1 + * @param Object $oB Object operand 2 + * @param boolean $ignoretype False will not report diff if type of value differs + * @param array $fieldstoignorearray Array of fields to ignore in diff + * @return array Array with differences + */ + public function objCompare($oA, $oB, $ignoretype = true, $fieldstoignorearray = array('id')) + { + $retAr=array(); + + if (get_class($oA) !== get_class($oB)) { + $retAr[]="Supplied objects are not of same class."; + } else { + $oVarsA=get_object_vars($oA); + $oVarsB=get_object_vars($oB); + $aKeys=array_keys($oVarsA); + foreach ($aKeys as $sKey) { + if (in_array($sKey, $fieldstoignorearray)) { + continue; + } + if (! $ignoretype && ($oVarsA[$sKey] !== $oVarsB[$sKey])) { + $retAr[]=$sKey.' : '.(is_object($oVarsA[$sKey])?get_class($oVarsA[$sKey]):$oVarsA[$sKey]).' <> '.(is_object($oVarsB[$sKey])?get_class($oVarsB[$sKey]):$oVarsB[$sKey]); + } + if ($ignoretype && ($oVarsA[$sKey] != $oVarsB[$sKey])) { + $retAr[]=$sKey.' : '.(is_object($oVarsA[$sKey])?get_class($oVarsA[$sKey]):$oVarsA[$sKey]).' <> '.(is_object($oVarsB[$sKey])?get_class($oVarsB[$sKey]):$oVarsB[$sKey]); + } + } + } + return $retAr; + } +}