diff --git a/htdocs/admin/inventory.php b/htdocs/admin/inventory.php
deleted file mode 100644
index 2548494fc79b83bfeb8ae02d304afed01a7d80a4..0000000000000000000000000000000000000000
--- a/htdocs/admin/inventory.php
+++ /dev/null
@@ -1,152 +0,0 @@
-<?php
-/* <one line to give the program's name and a brief idea of what it does.>
- * Copyright (C) 2015 ATM Consulting <support@atm-consulting.fr>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * 	\file		admin/inventory.php
- * 	\ingroup	inventory
- * 	\brief		This file is an example module setup page
- * 				Put some comments here
- */
-// Dolibarr environment
-require '../main.inc.php';
-
-
-// Libraries
-require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
-require_once DOL_DOCUMENT_ROOT .'/inventory/lib/inventory.lib.php';
-
-// Translations
-$langs->load("stock");
-$langs->load("inventory");
-
-// Access control
-if (! $user->admin) {
-    accessforbidden();
-}
-
-// Parameters
-$action = GETPOST('action', 'alpha');
-
-/*
- * Actions
- */
-if (preg_match('/set_(.*)/',$action,$reg))
-{
-	$code=$reg[1];
-	if (dolibarr_set_const($db, $code, GETPOST($code), 'chaine', 0, '', $conf->entity) > 0)
-	{
-		header("Location: ".$_SERVER["PHP_SELF"]);
-		exit;
-	}
-	else
-	{
-		dol_print_error($db);
-	}
-}
-	
-if (preg_match('/del_(.*)/',$action,$reg))
-{
-	$code=$reg[1];
-	if (dolibarr_del_const($db, $code, 0) > 0)
-	{
-		Header("Location: ".$_SERVER["PHP_SELF"]);
-		exit;
-	}
-	else
-	{
-		dol_print_error($db);
-	}
-}
-
-/*
- * View
- */
-$page_name = "inventorySetup";
-llxHeader('', $langs->trans($page_name));
-
-// Subheader
-$linkback = '<a href="' . DOL_URL_ROOT . '/admin/modules.php">'
-    . $langs->trans("BackToModuleList") . '</a>';
-print_fiche_titre($langs->trans($page_name), $linkback);
-
-// Configuration header
-$head = inventoryAdminPrepareHead();
-dol_fiche_head(
-    $head,
-    'settings',
-    $langs->trans("Module104420Name"),
-    0,
-    "inventory@inventory"
-);
-
-// Setup page goes here
-$form=new Form($db);
-$var=false;
-print '<table class="noborder" width="100%">';
-print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("Parameters").'</td>'."\n";
-print '<td align="center" width="20">&nbsp;</td>';
-print '<td align="center" width="100">'.$langs->trans("Value").'</td>'."\n";
-
-// Example with a yes / no select
-$var=!$var;
-print '<tr '.$bc[$var].'>';
-print '<td>'.$langs->trans("INVENTORY_DISABLE_VIRTUAL").'</td>';
-print '<td align="center" width="20">&nbsp;</td>';
-print '<td align="right" width="300">';
-print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
-print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-print '<input type="hidden" name="action" value="set_INVENTORY_DISABLE_VIRTUAL">';
-print $form->selectyesno("INVENTORY_DISABLE_VIRTUAL",$conf->global->INVENTORY_DISABLE_VIRTUAL,1);
-print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
-print '</form>';
-print '</td></tr>';
-
-// Example with a yes / no select
-$var=!$var;
-print '<tr '.$bc[$var].'>';
-print '<td>'.$langs->trans("INVENTORY_USE_MIN_PA_IF_NO_LAST_PA").'</td>';
-print '<td align="center" width="20">&nbsp;</td>';
-print '<td align="right" width="300">';
-print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
-print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-print '<input type="hidden" name="action" value="set_INVENTORY_USE_MIN_PA_IF_NO_LAST_PA">';
-print $form->selectyesno("INVENTORY_USE_MIN_PA_IF_NO_LAST_PA",$conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA,1);
-print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
-print '</form>';
-print '</td></tr>';
-
-// Example with a yes / no select
-$var=!$var;
-print '<tr '.$bc[$var].'>';
-print '<td>'.$langs->trans("INVENTORY_USE_INVENTORY_DATE_FROM_DATEMVT").'</td>';
-print '<td align="center" width="20">&nbsp;</td>';
-print '<td align="right" width="300">';
-print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
-print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-print '<input type="hidden" name="action" value="set_INVENTORY_USE_INVENTORY_DATE_FROM_DATEMVT">';
-print $form->selectyesno("INVENTORY_USE_INVENTORY_DATE_FROM_DATEMVT",$conf->global->INVENTORY_USE_INVENTORY_DATE_FROM_DATEMVT,1);
-print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
-print '</form>';
-print '</td></tr>';
-
-print '</table>';
-
-llxFooter();
-
-$db->close();
\ No newline at end of file
diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php
index 1c5a92fb0e8240ba84f5cb4c4e7cacc79f775d98..c8204f213c250c1e98b49a91886a334e53423e44 100644
--- a/htdocs/admin/stock.php
+++ b/htdocs/admin/stock.php
@@ -432,6 +432,61 @@ if ($virtualdiffersfromphysical)
 }
 
 
+print '<br />';
+if ($conf->global->MAIN_LEVEL_FEATURES >= 2)
+{
+	$var=false;
+	print '<table class="noborder" width="100%">';
+	print '<tr class="liste_titre">';
+	print '<td>'.$langs->trans("Inventory").'</td>'."\n";
+	print '<td align="center" width="20">&nbsp;</td>';
+	print '<td align="center" width="100">&nbsp;</td>'."\n";
+	
+	// Example with a yes / no select
+	$var=!$var;
+	print '<tr '.$bc[$var].'>';
+	print '<td>'.$langs->trans("INVENTORY_DISABLE_VIRTUAL").'</td>';
+	print '<td align="center" width="20">&nbsp;</td>';
+	print '<td align="right" width="300">';
+	print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
+	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+	print '<input type="hidden" name="action" value="set_INVENTORY_DISABLE_VIRTUAL">';
+	print $form->selectyesno("INVENTORY_DISABLE_VIRTUAL",$conf->global->INVENTORY_DISABLE_VIRTUAL,1);
+	print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
+	print '</form>';
+	print '</td></tr>';
+	
+	// Example with a yes / no select
+	$var=!$var;
+	print '<tr '.$bc[$var].'>';
+	print '<td>'.$langs->trans("INVENTORY_USE_MIN_PA_IF_NO_LAST_PA").'</td>';
+	print '<td align="center" width="20">&nbsp;</td>';
+	print '<td align="right" width="300">';
+	print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
+	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+	print '<input type="hidden" name="action" value="set_INVENTORY_USE_MIN_PA_IF_NO_LAST_PA">';
+	print $form->selectyesno("INVENTORY_USE_MIN_PA_IF_NO_LAST_PA",$conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA,1);
+	print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
+	print '</form>';
+	print '</td></tr>';
+	
+	// Example with a yes / no select
+	$var=!$var;
+	print '<tr '.$bc[$var].'>';
+	print '<td>'.$langs->trans("INVENTORY_USE_INVENTORY_DATE_FROM_DATEMVT").'</td>';
+	print '<td align="center" width="20">&nbsp;</td>';
+	print '<td align="right" width="300">';
+	print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
+	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+	print '<input type="hidden" name="action" value="set_INVENTORY_USE_INVENTORY_DATE_FROM_DATEMVT">';
+	print $form->selectyesno("INVENTORY_USE_INVENTORY_DATE_FROM_DATEMVT",$conf->global->INVENTORY_USE_INVENTORY_DATE_FROM_DATEMVT,1);
+	print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
+	print '</form>';
+	print '</td></tr>';
+	
+	print '</table>';
+}
+
 $var=true;
 print '<table class="noborder" width="100%">';
 
@@ -508,6 +563,7 @@ if ($conf->global->PRODUIT_SOUSPRODUITS)
 
 print '</table>';
 
+
 llxFooter();
 
 $db->close();
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 5e5c13056e7a98269384ee221db3164a247a3990..582e00d29faf44e07f429a0c55ec19beacefdf6c 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -11,6 +11,7 @@
  * Copyright (C) 2012      Cedric Salvador      <csalvador@gpcsolutions.fr>
  * Copyright (C) 2015      Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
  * Copyright (C) 2016      Bahfir abbes         <dolipar@dolipar.org>
+ * Copyright (C) 2017      ATM Consulting       <support@atm-consulting.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -4662,7 +4663,159 @@ abstract class CommonObject
 		return $buyPrice;
 	}
 	
+	/**
+	 * Function test if type is date
+	 *
+	 * @param   array   $info   content informations of field
+	 * @return                  bool
+	 */
+	protected function is_date($info)
+	{
+		if(isset($info['type']) && $info['type']=='date') return true;
+		else return false;
+	}
+	
+	/**
+	 * Function test if type is array
+	 *
+	 * @param   array   $info   content informations of field
+	 * @return                  bool
+	 */
+	protected function is_array($info)
+	{
+		if(is_array($info))
+		{
+			if(isset($info['type']) && $info['type']=='array') return true;
+			else return false;
+		}
+		else return false;
+	}
+	
+	/**
+	 * Function test if type is null
+	 *
+	 * @param   array   $info   content informations of field
+	 * @return                  bool
+	 */
+	protected function is_null($info)
+	{
+		if(is_array($info))
+		{
+			if(isset($info['type']) && $info['type']=='null') return true;
+			else return false;
+		}
+		else return false;
+	}
+	
+	/**
+	 * Function test if type is integer
+	 *
+	 * @param   array   $info   content informations of field
+	 * @return                  bool
+	 */
+	protected function is_int($info)
+	{
+		if(is_array($info))
+		{
+			if(isset($info['type']) && ($info['type']=='int' || $info['type']=='integer' )) return true;
+			else return false;
+		}
+		else return false;
+	}
+	
+	/**
+	 * Function test if type is float
+	 *
+	 * @param   array   $info   content informations of field
+	 * @return                  bool
+	 */
+	protected function is_float($info)
+	{
+		if(is_array($info))
+		{
+			if(isset($info['type']) && $info['type']=='float') return true;
+			else return false;
+		}
+		else return false;
+	}
 	
+	/**
+	 * Function test if type is text
+	 *
+	 * @param   array   $info   content informations of field
+	 * @return                  bool
+	 */
+	protected function is_text($info)
+	{
+		if(is_array($info))
+		{
+			if(isset($info['type']) && $info['type']=='text') return true;
+			else return false;
+		}
+		else return false;
+	}
+	
+	/**
+	 * Function test if is indexed
+	 *
+	 * @param   array   $info   content informations of field
+	 * @return                  bool
+	 */
+	protected function is_index($info)
+	{
+		if(is_array($info))
+		{
+			if(isset($info['index']) && $info['index']==true) return true;
+			else return false;
+		}
+		else return false;
+	}
+	
+	/**
+	 * Function to prepare the values to insert
+	 *
+	 * @return array
+	 */
+	private function set_save_query()
+	{
+		$query=array();
+		foreach ($this->fields as $field=>$info)
+		{
+			if($this->is_date($info))
+			{
+				if(empty($this->{$field}))
+				{
+					$query[$field] = NULL;
+				}
+				else
+				{
+					$query[$field] = $this->db->idate($this->{$field});
+				}
+			}
+			else if($this->is_array($info))
+			{
+				$query[$field] = serialize($this->{$field});
+			}
+			else if($this->is_int($info))
+			{
+				$query[$field] = (int) price2num($this->{$field});
+			}
+			else if($this->is_float($info))
+			{
+				$query[$field] = (double) price2num($this->{$field});
+			}
+			elseif($this->is_null($info))
+			{
+				$query[$field] = (is_null($this->{$field}) || (empty($this->{$field}) && $this->{$field}!==0 && $this->{$field}!=='0') ? null : $this->{$field});
+			}
+			else
+			{
+				$query[$field] = $this->{$field};
+			}
+		}
+		
+		return $query;
+	}
 
 	/**
 	 * Create object into database
@@ -4674,28 +4827,82 @@ abstract class CommonObject
 	 */
 	public function createCommon(User $user, $notrigger = false)
 	{
-	    foreach ($this->fields as $k => $v) {
 	    
-	        $keys[] = $k;
-	        $values[] = $this->quote($v);
-	         
-	    }
+	    $fields = array_merge(array('datec'=>$this->db->idate(dol_now())), $this->set_save_query());
 	    
-	    $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$table.'
+	    foreach ($fields as $k => $v) {
+	    	
+	    	$keys[] = $k;
+	    	$values[] = $this->quote($v);
+	    	
+	    }
+	    $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'
 					( '.implode( ",", $keys ).' )
 					VALUES ( '.implode( ",", $values ).' ) ';
-	    
-	    $res = $this->query($sql);
+	    $res = $this->db->query( $sql );
 	    if($res===false) {
-	    
-	        return false;
+	    	
+	    	return false;
 	    }
 	    
 	    // TODO Add triggers
-	    	  
-	    return true;	    
+	    
+	    return true;
+	    
 	}
 	
+	/**
+	 * Function to load data into current object this
+	 *
+	 * @param   stdClass    $obj    Contain data of object from database
+	 */
+	private function set_vars_by_db(&$obj)
+	{
+		foreach ($this->fields as $field => $info)
+		{
+			if($this->is_date($info))
+			{
+				if(empty($obj->{$field}) || $obj->{$field} === '0000-00-00 00:00:00' || $obj->{$field} === '1000-01-01 00:00:00') $this->{$field} = 0;
+				else $this->{$field} = strtotime($obj->{$field});
+			}
+			elseif($this->is_array($info))
+			{
+				$this->{$field} = @unserialize($obj->{$field});
+				// Hack for data not in UTF8
+				if($this->{$field } === FALSE) @unserialize(utf8_decode($obj->{$field}));
+			}
+			elseif($this->is_int($info))
+			{
+				$this->{$field} = (int) $obj->{$field};
+			}
+			elseif($this->is_float($info))
+			{
+				$this->{$field} = (double) $obj->{$field};
+			}
+			elseif($this->is_null($info))
+			{
+				$val = $obj->{$field};
+				// zero is not null
+				$this->{$field} = (is_null($val) || (empty($val) && $val!==0 && $val!=='0') ? null : $val);
+			}
+			else
+			{
+				$this->{$field} = $obj->{$field};
+			}
+			
+		}
+	}
+	
+	/**
+	 * Function to concat keys of fields
+	 *
+	 * @return string
+	 */
+	private function get_field_list()
+	{
+		$keys = array_keys($this->fields);
+		return implode(',', $keys);
+	}
 	
 	/**
 	 * Load object in memory from the database
@@ -4708,6 +4915,32 @@ abstract class CommonObject
 	public function fetchCommon($id, $ref = null)
 	{
 	    
+		if (empty($id) && empty($ref)) return false;
+		
+		$sql = 'SELECT '.$this->get_field_list().', datec, tms';
+		$sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element;
+		
+		if(!empty($id)) $sql.= ' WHERE rowid = '.$id;
+		else  $sql.= ' WHERE ref = \''.$this->quote($ref).'\'';
+		
+		$res = $this->db->query($sql);
+		if($obj = $this->db->fetch_object($res))
+		{
+			$this->id = $id;
+			$this->set_vars_by_db($obj);
+			
+			$this->datec = $this->db->idate($obj->datec);
+			$this->tms = $this->db->idate($obj->tms);
+			
+			return $this->id;
+		}
+		else
+		{
+			$this->error = $this->db->lasterror();
+			$this->errors[] = $this->error;
+			return -1;
+		}
+		
 	}
 
 	/**
@@ -4720,34 +4953,36 @@ abstract class CommonObject
 	 */
 	public function updateCommon(User $user, $notrigger = false)
 	{
-	    foreach ($this->fields as $k => $v) {
-	    
-	        if (is_array($key)){
-	            $i=array_search($k, $key);
-	            if ( $i !== false) {
-	                $where[] = $key[$i].'=' . $this->quote( $v ) ;
-	                continue;
-	            }
-	        } else {
-	            if ( $k == $key) {
-	                $where[] = $k.'=' .$this->quote( $v ) ;
-	                continue;
-	            }
-	        }
-	    
-	        $tmp[] = $k.'='.$this->quote($v);
-	    }
-	    $sql = 'UPDATE '.MAIN_DB_PREFIX.$table.' SET '.implode( ',', $tmp ).' WHERE ' . implode(' AND ',$where) ;
-	    $res = $this->query( $sql );
-	    
-	    if($res===false) {
-	        //error
-	        return false;
-	    }
-	    
-	    // TODO Add triggers
-	    
-	    return true;	    
+		$fields = $this->set_save_query();
+		
+		foreach ($fields as $k => $v) {
+			
+			if (is_array($key)){
+				$i=array_search($k , $key );
+				if ( $i !== false) {
+					$where[] = $key[$i].'=' . $this->quote( $v ) ;
+					continue;
+				}
+			} else {
+				if ( $k == $key) {
+					$where[] = $k.'=' .$this->quote( $v ) ;
+					continue;
+				}
+			}
+			
+			$tmp[] = $k.'='.$this->quote($v);
+		}
+		$sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET '.implode( ',', $tmp ).' WHERE rowid='.$this->id ;
+		$res = $this->db->query( $sql );
+		
+		if($res===false) {
+			//error
+			return false;
+		}
+		
+		// TODO Add triggers
+		
+		return true;
 	}
 	
 	/**
@@ -4760,7 +4995,16 @@ abstract class CommonObject
 	 */
 	public function deleteCommon(User $user, $notrigger = false)
 	{
-	    
+		$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE rowid='.$this->id;
+		
+		$res = $this->db->query( $sql );
+		if($res===false) {
+			return false;
+		}
+		
+		// TODO Add triggers
+		
+		return true;
 	}
 
 	/**
@@ -4769,11 +5013,11 @@ abstract class CommonObject
 	 * @param string|int	$value	value to protect
 	 * @return string|int
 	 */
-	function quote($value) {
+	protected function quote($value) {
 	
 	    if(is_null($value)) return 'NULL';
 	    else if(is_numeric($value)) return $value;
-	    else return "'".$this->escape( $value )."'";
+	    else return "'".$this->db->escape( $value )."'";
 	
 	}
 	
diff --git a/htdocs/core/class/coreobject.class.php b/htdocs/core/class/coreobject.class.php
index 8aa0cfe2ad609f6b0cb3c885472745db23b68d33..c86a1083519f7f77fbb3921599a9df96d60ef9a8 100644
--- a/htdocs/core/class/coreobject.class.php
+++ b/htdocs/core/class/coreobject.class.php
@@ -97,216 +97,6 @@ class CoreObject extends CommonObject
         }
 	}
 
-    /**
-     * Function test if type is date
-     *
-     * @param   array   $info   content informations of field
-     * @return                  bool
-     */
-    private function is_date($info)
-    {
-		if(isset($info['type']) && $info['type']=='date') return true;
-		else return false;
-	}
-
-    /**
-     * Function test if type is array
-     *
-     * @param   array   $info   content informations of field
-     * @return                  bool
-     */
-	private function is_array($info)
-    {
-	  	if(is_array($info))
-	  	{
-			if(isset($info['type']) && $info['type']=='array') return true;
-			else return false;
-		}
-		else return false;
-	}
-
-    /**
-     * Function test if type is null
-     *
-     * @param   array   $info   content informations of field
-     * @return                  bool
-     */
-	private function is_null($info)
-    {
-		if(is_array($info))
-		{
-			if(isset($info['type']) && $info['type']=='null') return true;
-			else return false;
-		}
-		else return false;
-	}
-
-    /**
-     * Function test if type is integer
-     *
-     * @param   array   $info   content informations of field
-     * @return                  bool
-     */
-	private function is_int($info)
-    {
-		if(is_array($info))
-		{
-			if(isset($info['type']) && ($info['type']=='int' || $info['type']=='integer' )) return true;
-			else return false;
-		}
-		else return false;
-	}
-
-    /**
-     * Function test if type is float
-     *
-     * @param   array   $info   content informations of field
-     * @return                  bool
-     */
-	private function is_float($info)
-    {
-		if(is_array($info))
-		{
-			if(isset($info['type']) && $info['type']=='float') return true;
-			else return false;
-		}
-		else return false;
-	}
-
-    /**
-     * Function test if type is text
-     *
-     * @param   array   $info   content informations of field
-     * @return                  bool
-     */
-	private function is_text($info)
-    {
-	  	if(is_array($info))
-	  	{
-			if(isset($info['type']) && $info['type']=='text') return true;
-			else return false;
-		}
-		else return false;
-	}
-
-    /**
-     * Function test if is indexed
-     *
-     * @param   array   $info   content informations of field
-     * @return                  bool
-     */
-	private function is_index($info)
-    {
-	  	if(is_array($info))
-	  	{
-			if(isset($info['index']) && $info['index']==true) return true;
-			else return false;
-		}
-		else return false;
-	}
-
-
-    /**
-     * Function to prepare the values to insert
-     *
-     * @return array
-     */
-    private function set_save_query()
-    {
-		$query=array();
-		foreach ($this->fields as $field=>$info)
-		{
-			if($this->is_date($info))
-			{
-				if(empty($this->{$field}))
-				{
-					$query[$field] = NULL;
-				}
-				else
-                {
-					$query[$field] = $this->db->idate($this->{$field});
-				}
-		  	}
-		  	else if($this->is_array($info))
-		  	{
-                $query[$field] = serialize($this->{$field});
-		  	}
-		  	else if($this->is_int($info))
-		  	{
-		    	$query[$field] = (int) price2num($this->{$field});
-		  	}
-		  	else if($this->is_float($info))
-		  	{
-		    	$query[$field] = (double) price2num($this->{$field});
-		  	}
-		  	elseif($this->is_null($info))
-            {
-		  		$query[$field] = (is_null($this->{$field}) || (empty($this->{$field}) && $this->{$field}!==0 && $this->{$field}!=='0') ? null : $this->{$field});
-		    }
-		    else
-            {
-		       $query[$field] = $this->{$field};
-		    }
-	    }
-	
-		return $query;
-	}
-
-
-    /**
-     * Function to concat keys of fields
-     *
-     * @return string
-     */
-    private function get_field_list()
-    {
-		$keys = array_keys($this->fields);
-	    return implode(',', $keys);
-	}
-
-
-    /**
-     * Function to load data into current object this
-     *
-     * @param   stdClass    $obj    Contain data of object from database
-     */
-    private function set_vars_by_db(&$obj)
-    {
-		foreach ($this->fields as $field => $info)
-		{
-			if($this->is_date($info))
-			{
-				if(empty($obj->{$field}) || $obj->{$field} === '0000-00-00 00:00:00' || $obj->{$field} === '1000-01-01 00:00:00') $this->{$field} = 0;
-				else $this->{$field} = strtotime($obj->{$field});
-			}
-			elseif($this->is_array($info))
-            {
-				$this->{$field} = @unserialize($obj->{$field});
-				// Hack for data not in UTF8
-				if($this->{$field } === FALSE) @unserialize(utf8_decode($obj->{$field}));
-			}
-			elseif($this->is_int($info))
-            {
-				$this->{$field} = (int) $obj->{$field};
-			}
-			elseif($this->is_float($info))
-            {
-				$this->{$field} = (double) $obj->{$field};
-			}
-			elseif($this->is_null($info))
-            {
-				$val = $obj->{$field};
-				// zero is not null 
-				$this->{$field} = (is_null($val) || (empty($val) && $val!==0 && $val!=='0') ? null : $val);
-			}
-			else
-            {
-				$this->{$field} = $obj->{$field};
-			}
-
-		}
-	}
-
     /**
      *	Get object and children from database
      *
@@ -316,31 +106,14 @@ class CoreObject extends CommonObject
      */
 	public function fetch($id, $loadChild = true)
     {
-		if (empty($id)) return false;
-
-		$sql = 'SELECT '.$this->get_field_list().', datec, tms';
-		$sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element;
-        $sql.= ' WHERE rowid = '.$id;
 		
-		$res = $this->db->query($sql);
-		if($obj = $this->db->fetch_object($res))
-		{
-            $this->id = $id;
-            $this->set_vars_by_db($obj);
-
-            $this->datec = $this->db->idate($obj->datec);
-            $this->tms = $this->db->idate($obj->tms);
-
-            if ($loadChild) $this->fetchChild();
-
-            return $this->id;
-		}
-		else
-        {
-            $this->error = $this->db->lasterror();
-            $this->errors[] = $this->error;
-            return -1;
-		}
+    	$res = $this->fetchCommon($id);
+    	if($res>0) {
+    		if ($loadChild) $this->fetchChild();
+    	}
+    	
+    	return $res;
+		
 	}
 
 
@@ -473,10 +246,7 @@ class CoreObject extends CommonObject
         $error = 0;
         $this->db->begin();
 
-        $query = $this->set_save_query();
-        $query['rowid'] = $this->id;
-
-        $res = $this->db->update($this->table_element, $query, array('rowid'));
+        $res = $this->updateCommon($user);
         if ($res)
         {
             $result = $this->call_trigger(strtoupper($this->element). '_UPDATE', $user);
@@ -516,10 +286,7 @@ class CoreObject extends CommonObject
         $error = 0;
         $this->db->begin();
 
-		$query = $this->set_save_query();
-		$query['datec'] = date("Y-m-d H:i:s", dol_now());
-		
-		$res = $this->db->insert($this->table_element, $query);
+        $res = $this->createCommon($user);
 		if($res)
 		{
 			$this->id = $this->db->last_insert_id($this->table_element);
@@ -565,7 +332,7 @@ class CoreObject extends CommonObject
 
         if (!$error)
         {
-            $this->db->delete($this->table_element, array('rowid' => $this->id), array('rowid'));
+            $this->deleteCommon($user);
             if($this->withChild && !empty($this->childtables))
             {
                 foreach($this->childtables as &$childTable)
@@ -669,5 +436,5 @@ class CoreObject extends CommonObject
 
 		return 1;
 	}
-	
+
 }
diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php
index cfdc6db298cb45a3b2b95b9f3745954f4243ca29..ea181f72a4138a56328dec6290629aed87cbc834 100644
--- a/htdocs/core/modules/modStock.class.php
+++ b/htdocs/core/modules/modStock.class.php
@@ -117,91 +117,42 @@ class modStock extends DolibarrModules
 		$this->rights[4][4] = 'mouvement';
 		$this->rights[4][5] = 'creer';
 
-		/*
-		$this->rights[$r][0] = $this->numero + $r;	// Permission id (must not be already used)
+		
+		$this->rights[$r][0] = 1006;
 		$this->rights[$r][1] = 'inventoryReadPermission';	// Permission label
-		$this->rights[$r][3] = 1; 					// Permission by default for new user (0/1)
+		$this->rights[$r][3] = 0; 					// Permission by default for new user (0/1)
 		$this->rights[$r][4] = 'read';			// In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
 		$r++;
 		
-		$this->rights[$r][0] = $this->numero + $r;	// Permission id (must not be already used)
+		$this->rights[$r][0] = 1007;
 		$this->rights[$r][1] = 'inventoryCreatePermission';	// Permission label
 		$this->rights[$r][3] = 0; 					// Permission by default for new user (0/1)
 		$this->rights[$r][4] = 'create';			// In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
 		$r++;
 		
-		$this->rights[$r][0] = $this->numero + $r;	// Permission id (must not be already used)
+		$this->rights[$r][0] = 1008;
 		$this->rights[$r][1] = 'inventoryWritePermission';	// Permission label
 		$this->rights[$r][3] = 0; 					// Permission by default for new user (0/1)
 		$this->rights[$r][4] = 'write';			// In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
 		$r++;
 		
-		$this->rights[$r][0] = $this->numero + $r;	// Permission id (must not be already used)
+		$this->rights[$r][0] = 1009;
 		$this->rights[$r][1] = 'inventoryValidatePermission';	// Permission label
 		$this->rights[$r][3] = 0; 					// Permission by default for new user (0/1)
 		$this->rights[$r][4] = 'validate';			// In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
 		$r++;
 		
-		$this->rights[$r][0] = $this->numero + $r;	// Permission id (must not be already used)
+		$this->rights[$r][0] = 1010;
 		$this->rights[$r][1] = 'inventoryChangePMPPermission';	// Permission label
 		$this->rights[$r][3] = 0; 					// Permission by default for new user (0/1)
 		$this->rights[$r][4] = 'changePMP';			// In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
 		$r++;
-		*/
+		
 		
 		// Main menu entries
 		$this->menu = array();			// List of menus to add
 		$r=0;
 		
-		/*
-		$this->menu[$r]=array(
-		    'fk_menu'=>'fk_mainmenu=products',			                // Put 0 if this is a top menu
-		    'type'=>'left',			                // This is a Top menu entry
-		    'titre'=>'Inventory',
-		    'mainmenu'=>'products',
-		    'leftmenu'=>'inventory_left',
-		    'url'=>'/inventory/list.php',
-		    'langs'=>'inventory',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
-		    'position'=>100+$r,
-		    'enabled'=>'$conf->inventory->enabled',	// Define condition to show or hide menu entry. Use '$conf->inventory->enabled' if entry must be visible if module is enabled.
-		    'perms'=>'$user->rights->inventory->read',			                // Use 'perms'=>'$user->rights->inventory->level1->level2' if you want your menu with a permission rules
-		    'target'=>'',
-		    'user'=>2
-		);				                // 0=Menu for internal users, 1=external users, 2=both
-		$r++;
-		
-		$this->menu[$r]=array(
-		    'fk_menu'=>'fk_mainmenu=products,fk_leftmenu=inventory_left',			                // Put 0 if this is a top menu
-		    'type'=>'left',			                // This is a Top menu entry
-		    'titre'=>'NewInventory',
-		    'mainmenu'=>'products',
-		    'leftmenu'=>'inventory_left_create',
-		    'url'=>'/inventory/inventory.php?action=create',
-		    'position'=>100+$r,
-		    'enabled'=>'$conf->inventory->enabled',	// Define condition to show or hide menu entry. Use '$conf->inventory->enabled' if entry must be visible if module is enabled.
-		    'perms'=>'$user->rights->inventory->create',			                // Use 'perms'=>'$user->rights->inventory->level1->level2' if you want your menu with a permission rules
-		    'target'=>'',
-		    'user'=>2
-		);				                // 0=Menu for internal users, 1=external users, 2=both
-		$r++;
-		
-		$this->menu[$r]=array(
-		    'fk_menu'=>'fk_mainmenu=products,fk_leftmenu=inventory_left',			                // Put 0 if this is a top menu
-		    'type'=>'left',			                // This is a Top menu entry
-		    'titre'=>'ListInventory',
-		    'mainmenu'=>'products',
-		    'leftmenu'=>'inventory_left_list',
-		    'url'=>'/inventory/list.php',
-		    'langs'=>'inventory',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
-		    'position'=>100+$r,
-		    'enabled'=>'$conf->inventory->enabled',	// Define condition to show or hide menu entry. Use '$conf->inventory->enabled' if entry must be visible if module is enabled.
-		    'perms'=>'$user->rights->inventory->read',			                // Use 'perms'=>'$user->rights->inventory->level1->level2' if you want your menu with a permission rules
-		    'target'=>'',
-		    'user'=>2
-		);				                // 0=Menu for internal users, 1=external users, 2=both
-		$r++;
-		*/
-		
 		// Menus
 		//-------
 		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
diff --git a/htdocs/product/inventory/ajax/ajax.inventory.php b/htdocs/product/inventory/ajax/ajax.inventory.php
index c0d8443f4335f8547ed28a74154d06d165f9fbe1..4884d7ab06599ae8d995848ab60ebb0235e01ed1 100644
--- a/htdocs/product/inventory/ajax/ajax.inventory.php
+++ b/htdocs/product/inventory/ajax/ajax.inventory.php
@@ -2,14 +2,14 @@
 
     require '../../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php';
-    
+  
     $get = GETPOST('get');
     $put = GETPOST('put');
     
     switch ($put)
     {
         case 'qty':
-            if (empty($user->rights->stock->write)) { echo -1; exit; }
+        	if (empty($user->rights->stock->creer)) { echo -1; exit; }
             
             $fk_det_inventory = GETPOST('fk_det_inventory');
             
@@ -17,7 +17,7 @@
             if( $det->fetch( $fk_det_inventory))
             {
                 $det->qty_view+=GETPOST('qty');
-                $det->update($user);
+                $res = $det->update($user);
                 
                 echo $det->qty_view;
             }
@@ -25,11 +25,11 @@
             {
                 echo -2;
             }            
-            
+           
             break;
 			
         case 'pmp':
-            if (!$user->rights->stock->write || !$user->rights->stock->changePMP) { echo -1; exit; }
+        	if (empty($user->rights->stock->creer) || empty($user->rights->stock->changePMP)) { echo -1; exit; }
             
             $fk_det_inventory = GETPOST('fk_det_inventory');
             
diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php
index dc279cc09293041a2f52dd98fc1b1e344ed29489..ad53953290169530f1e88457cacc3ea01b69ee0c 100644
--- a/htdocs/product/inventory/card.php
+++ b/htdocs/product/inventory/card.php
@@ -66,7 +66,7 @@ $extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php';  // Must be include, not include_once  // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
 
 // Initialize technical object to manage hooks of modules. Note that conf->hooks_modules contains array array
-$hookmanager->initHooks(array('inventory'));
+$hookmanager->initHooks(array('inventorycard'));
 
 
 
@@ -84,7 +84,7 @@ if (empty($reshook))
     {
         if ($action != 'addlink')
         {
-            $urltogo=$backtopage?$backtopage:dol_buildpath('/mymodule/list.php',1);
+            $urltogo=$backtopage?$backtopage:dol_buildpath('/product/inventory/list.php',1);
             header("Location: ".$urltogo);
             exit;
         }
@@ -98,7 +98,7 @@ if (empty($reshook))
 	
 		if ($cancel)
 		{
-		    $urltogo=$backtopage?$backtopage:dol_buildpath('/mymodule/list.php',1);
+		    $urltogo=$backtopage?$backtopage:dol_buildpath('/product/inventory/list.php',1);
 		    header("Location: ".$urltogo);
 		    exit;
 		}
@@ -128,7 +128,6 @@ if (empty($reshook))
         	exit;
         }
         
-		break;
     }
     
     switch($action) {