diff --git a/htdocs/admin/resource.php b/htdocs/admin/resource.php
new file mode 100644
index 0000000000000000000000000000000000000000..d8fdddd2bb59a944682089256e8bf1573721baa2
--- /dev/null
+++ b/htdocs/admin/resource.php
@@ -0,0 +1,144 @@
+<?php
+/* Copyright (C) 2016  Florian HENRY	<florian.henry@atm-consulting.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * \file		htdocs/admin/resource.php
+ * \ingroup		resource
+ * \brief		Setup page to configure resource module
+ */
+
+require '../main.inc.php';
+
+// Class
+require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php';
+if (! empty($conf->resouce->enabled)) require_once DOL_DOCUMENT_ROOT . '/resource/class/html.formresource.class.php';
+
+$langs->load("admin");
+$langs->load("resource");
+
+// Security check
+if (!$user->admin)
+    accessforbidden();
+
+$action = GETPOST('action', 'alpha');
+
+
+/*
+ * Actions
+ */
+
+if ($action == 'updateoptions')
+{
+	if (GETPOST('activate_RESOURCE_USE_SEARCH_TO_SELECT'))
+	{
+		if (dolibarr_set_const($db, "RESOURCE_USE_SEARCH_TO_SELECT", GETPOST('activate_RESOURCE_USE_SEARCH_TO_SELECT'), 'chaine', 0, '', $conf->entity))
+		{
+			setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
+		} else {
+			setEventMessages($langs->trans("Error"), null, 'errors');
+		}
+	}
+}
+
+/*
+ * View
+ */
+
+llxHeader('',$langs->trans('ResourceSetup'));
+
+$form = new Form($db);
+
+$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
+print load_fiche_titre($langs->trans('ResourceSetup'),$linkback,'title_setup');
+
+$head=resource_admin_prepare_head();
+
+dol_fiche_head($head, 'general', $langs->trans("ResourceSingular"), 0, 'action');
+
+print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
+print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+print '<input type="hidden" name="action" value="updateoptions">';
+
+$var=true;
+print '<table class="noborder" width="100%">';
+print '<tr class="liste_titre">';
+print '<td>'.$langs->trans("Parameters").'</td>'."\n";
+print '<td align="right" width="60">'.$langs->trans("Value").'</td>'."\n";
+print '<td></td>';
+
+
+// Utilisation formulaire Ajax sur choix produit
+$var=!$var;
+print '<tr '.$bc[$var].'>';
+print '<td width="80%">'.$langs->trans("UseSearchToSelectResource").'</td>';
+if (empty($conf->use_javascript_ajax))
+{
+	print '<td class="nowrap" align="right" colspan="2">';
+	print $langs->trans("NotAvailableWhenAjaxDisabled");
+	print '</td>';
+}
+else
+{
+	print '<td width="60" align="right">';
+	$arrval=array(
+			'0'=>$langs->trans("No"),
+			'1'=>$langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch",1).')',
+			'2'=>$langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch",2).')',
+			'3'=>$langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch",3).')',
+	);
+	print $form->selectarray("activate_RESOURCE_USE_SEARCH_TO_SELECT",$arrval,$conf->global->RESOURCE_USE_SEARCH_TO_SELECT);
+	print '</td>';
+	print '<td align="right">';
+	print '<input type="submit" class="button" name="RESOURCE_USE_SEARCH_TO_SELECT" value="'.$langs->trans("Modify").'">';
+	print '</td>';
+}
+print '</tr>';
+
+$var=!$var;
+print '<tr '.$bc[$var].'>';
+print '<td>'.$langs->trans('DisabledResourceLinkUser').'</td>';
+print '<td>';
+echo ajax_constantonoff('RESOURCE_HIDE_ADD_CONTACT_USER');
+print '</td>';
+print '<td></td>';
+print '</tr>';
+
+$var=!$var;
+print '<tr '.$bc[$var].'>';
+print '<td>'.$langs->trans('DisabledResourceLinkContact').'</td>';
+print '<td>';
+echo ajax_constantonoff('RESOURCE_HIDE_ADD_CONTACT_THIPARTY');
+print '</td>';
+print '<td></td>';
+print '</tr>';
+
+print '</table>';
+
+print '</form>';
+
+
+//RESOURCE_HIDE_ADD_CONTACT_USER
+//RESOURCE_HIDE_ADD_CONTACT_THIPARTY
+
+dol_fiche_end();
+
+
+llxFooter();
+$db->close();
diff --git a/htdocs/admin/resource_extrafields.php b/htdocs/admin/resource_extrafields.php
new file mode 100644
index 0000000000000000000000000000000000000000..c3d90fac3e54d759fc9355f7cc5be057fef93c45
--- /dev/null
+++ b/htdocs/admin/resource_extrafields.php
@@ -0,0 +1,122 @@
+<?php
+/* Copyright (C) 2001-2002	Rodolphe Quiedeville	<rodolphe@quiedeville.org>
+ * Copyright (C) 2003		Jean-Louis Bergamo		<jlb@j1b.org>
+ * Copyright (C) 2004-2013	Laurent Destailleur		<eldy@users.sourceforge.net>
+ * Copyright (C) 2012		Regis Houssin			<regis.houssin@capnetworks.com>
+ * Copyright (C) 2016		Florian Henry			<florian.henry@open-concept.pro>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *      \file       htdocs/admin/resource_extrafields.php
+ *		\ingroup    agenda
+ *		\brief      Page to setup extra fields of resource
+ */
+
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
+
+
+if (!$user->admin)
+	accessforbidden();
+
+$langs->load("admin");
+$langs->load("other");
+$langs->load("resource");
+
+$extrafields = new ExtraFields($db);
+$form = new Form($db);
+
+// List of supported format
+$tmptype2label=ExtraFields::$type2label;
+$type2label=array('');
+foreach ($tmptype2label as $key => $val) $type2label[$key]=$langs->trans($val);
+
+$action=GETPOST('action', 'alpha');
+$attrname=GETPOST('attrname', 'alpha');
+$elementtype='resource'; //Must be the $table_element of the class that manage extrafield
+
+if (!$user->admin) accessforbidden();
+
+
+/*
+ * Actions
+ */
+
+require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php';
+
+
+
+/*
+ * View
+ */
+
+$textobject=$langs->transnoentitiesnoconv("ResourceSingular");
+
+llxHeader('',$langs->trans("ResourceSetup"));
+
+$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
+print load_fiche_titre($langs->trans("ResourceSetup"),$linkback,'title_setup');
+print "<br>\n";
+
+$head=resource_admin_prepare_head();
+
+dol_fiche_head($head, 'attributes', $langs->trans("ResourceSingular"), 0, 'action');
+
+require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php';
+
+dol_fiche_end();
+
+
+// Buttons
+if ($action != 'create' && $action != 'edit')
+{
+    print '<div class="tabsAction">';
+    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
+    print "</div>";
+}
+
+
+/* ************************************************************************** */
+/*                                                                            */
+/* Creation of an optional field											  */
+/*                                                                            */
+/* ************************************************************************** */
+
+if ($action == 'create')
+{
+    print "<br>";
+    print load_fiche_titre($langs->trans('NewAttribute'));
+
+    require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
+}
+
+/* ************************************************************************** */
+/*                                                                            */
+/* Edition of an optional field                                                */
+/*                                                                            */
+/* ************************************************************************** */
+if ($action == 'edit' && ! empty($attrname))
+{
+    print "<br>";
+    print load_fiche_titre($langs->trans("FieldEdition", $attrname));
+
+    require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
+}
+
+llxFooter();
+
+$db->close();
diff --git a/htdocs/core/lib/resource.lib.php b/htdocs/core/lib/resource.lib.php
index 58fffbae5b7105ab14120a62e90932150586e5c3..a6c63dc51e4fe2c98d3db23271c82bff6e2e4588 100644
--- a/htdocs/core/lib/resource.lib.php
+++ b/htdocs/core/lib/resource.lib.php
@@ -81,8 +81,37 @@ function resource_prepare_head($object)
 	$head[$h][1] = $langs->trans('Info');
 	$head[$h][2] = 'info';
 	$h++;*/
-	
+
 	complete_head_from_modules($conf,$langs,$object,$head,$h,'resource', 'remove');
 
 	return $head;
 }
+
+function resource_admin_prepare_head() {
+
+	global $langs, $conf, $user;
+
+	$h = 0;
+	$head = array();
+
+	$head[$h][0] = DOL_URL_ROOT.'/admin/resource.php';
+	$head[$h][1] = $langs->trans("ResourceSetup");
+	$head[$h][2] = 'general';
+	$h++;
+
+	// Show more tabs from modules
+	// Entries must be declared in modules descriptor with line
+	// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
+	// $this->tabs = array('entity:-tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to remove a tab
+	complete_head_from_modules($conf,$langs,null,$head,$h,'resource_admin');
+
+	$head[$h][0] = DOL_URL_ROOT.'/admin/resource_extrafields.php';
+	$head[$h][1] = $langs->trans("ExtraFields");
+	$head[$h][2] = 'attributes';
+	$h++;
+
+	complete_head_from_modules($conf,$langs,null,$head,$h,'resource_admin','remove');
+
+	return $head;
+
+}
diff --git a/htdocs/core/modules/modResource.class.php b/htdocs/core/modules/modResource.class.php
index ee6162569b1008463d942477f9348245d15ba5b9..d3aa3405d0bf2b73cf11c7f689cc0fa48fc5a933 100644
--- a/htdocs/core/modules/modResource.class.php
+++ b/htdocs/core/modules/modResource.class.php
@@ -48,7 +48,7 @@ class modResource extends DolibarrModules
 		// Use a free id here
 		// (See in Home -> System information -> Dolibarr for list of used modules id).
 		$this->numero = 63000;
-		
+
 		// Key text used to identify module (for permissions, menus, etc...)
 		$this->rights_class = 'resource';
 
@@ -109,7 +109,7 @@ class modResource extends DolibarrModules
 
 		// Config pages. Put here list of php pages
 		// stored into resource/admin directory, used to setup module.
-		//$this->config_page_url = array("admin_resource.php@resource");
+		$this->config_page_url = array("resource.php");
 
 		// Dependencies
 		// List of modules id that must be enabled if this module is enabled
@@ -199,8 +199,8 @@ class modResource extends DolibarrModules
 		// Menus
 		//-------
 		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
-		
-		
+
+
 		// Add here list of permission defined by
 		// an id, a label, a boolean and two constant strings.
 		// Example:
@@ -266,7 +266,7 @@ class modResource extends DolibarrModules
 			'target'=> '',
 			'user'=> 0
 		);
-		
+
 		// Exports
 		$r = 1;
 
diff --git a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql
index e81027fd22f8d588668ae7750fd9b8103bcfc901..8b1c554ee1a72430806d3da22108feaefc698603 100644
--- a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql
+++ b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql
@@ -139,6 +139,7 @@ ALTER TABLE llx_accounting_bookkeeping ADD COLUMN tms               timestamp;
 
 ALTER TABLE llx_accounting_account ADD UNIQUE INDEX uk_accounting_account (account_number, entity, fk_pcg_version);
 
+
 ALTER TABLE llx_c_payment_term change fdm type_cdr tinyint;
 
 
@@ -153,3 +154,13 @@ ALTER TABLE llx_c_payment_term change fdm type_cdr tinyint;
 
 ALTER TABLE llx_entrepot ADD COLUMN fk_parent integer DEFAULT 0;
 
+
+create table llx_resource_extrafields
+(
+  rowid                     integer AUTO_INCREMENT PRIMARY KEY,
+  tms                       timestamp,
+  fk_object                 integer NOT NULL,
+  import_key                varchar(14)                          		-- import key
+) ENGINE=innodb;
+
+ALTER TABLE llx_resource_extrafields ADD INDEX idx_resource_extrafields (fk_object);
diff --git a/htdocs/install/mysql/tables/llx_resource_extrafields.key.sql b/htdocs/install/mysql/tables/llx_resource_extrafields.key.sql
new file mode 100644
index 0000000000000000000000000000000000000000..af77b0c24744db1ff4c754c446fb5b92b73fbdb7
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_resource_extrafields.key.sql
@@ -0,0 +1,20 @@
+-- ===================================================================
+-- Copyright (C) 2016 Florian Henry  <florian.henry@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/>.
+--
+-- ===================================================================
+
+
+ALTER TABLE llx_resource_extrafields ADD INDEX idx_resource_extrafields (fk_object);
diff --git a/htdocs/install/mysql/tables/llx_resource_extrafields.sql b/htdocs/install/mysql/tables/llx_resource_extrafields.sql
new file mode 100644
index 0000000000000000000000000000000000000000..4bda4091de419bbd60ff13f0aade12aef6298983
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_resource_extrafields.sql
@@ -0,0 +1,26 @@
+-- ========================================================================
+-- Copyright (C) 2016 Florian Henry  <florian.henry@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/>.
+--
+-- ========================================================================
+
+create table llx_resource_extrafields
+(
+  rowid                     integer AUTO_INCREMENT PRIMARY KEY,
+  tms                       timestamp,
+  fk_object                 integer NOT NULL,
+  import_key                varchar(14)                          		-- import key
+) ENGINE=innodb;
+
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index 39281f48609fd105dc26a3c6636eb95c9cb544dc..ca53bc971a925c1c7a39c63628e0a4429e32c568 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -1631,4 +1631,9 @@ LandingPage=Landing page
 SamePriceAlsoForSharedCompanies=If you use a multicompany module, with the choice "Single price", price will be also the same for all companies if products are shared between environments
 ModuleEnabledAdminMustCheckRights=Module has been activated. Permissions for activated module(s) were given to admin users only. You may need to grant permissions to other users manually if necessary.
 UserHasNoPermissions=This user has no permission defined
-TypeCdr=Use "None" if the date of payment term is date of invoice plus a delta in days (delta is field "Nb of days")<br>Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "Offset" in days)<br>Use "Current/Next" to have payment term date being the first Nth of the month (N is stored into field "Nb of days") 
\ No newline at end of file
+TypeCdr=Use "None" if the date of payment term is date of invoice plus a delta in days (delta is field "Nb of days")<br>Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "Offset" in days)<br>Use "Current/Next" to have payment term date being the first Nth of the month (N is stored into field "Nb of days")
+##### Resource ####
+ResourceSetup=Configuration du module Resource 
+UseSearchToSelectResource=Use a search form to choose a resource (rather than a drop-down list).
+DisabledResourceLinkUser=Disabled resource link to user
+DisabledResourceLinkContact=Disabled resource link to contact
diff --git a/htdocs/resource/add.php b/htdocs/resource/add.php
index 7608e1b6cf356d8eae9ca8f5376d42fe0746779b..7c60bf8091de30525ea98e67904dd7ea26f3b77e 100644
--- a/htdocs/resource/add.php
+++ b/htdocs/resource/add.php
@@ -27,6 +27,7 @@ require '../main.inc.php';
 
 require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php';
 require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
 
 // Load traductions files required by page
 $langs->load("resource");
@@ -60,6 +61,11 @@ if ($user->societe_id > 0)
 
 $object = new DolResource($db);
 
+$extrafields = new ExtraFields($db);
+
+// fetch optionals attributes and labels
+$extralabels=$extrafields->fetch_name_optionals_label($object->table_element);
+
 if ($action == 'confirm_add_resource')
 {
         if (! $cancel)
@@ -84,6 +90,12 @@ if ($action == 'confirm_add_resource')
                         $object->description=$description;
                         $object->fk_code_type_resource=$fk_code_type_resource;
 
+                        // Fill array 'array_options' with data from add form
+                        $ret = $extrafields->setOptionalsFromPost($extralabels, $object);
+                        if ($ret < 0) {
+                        	$error ++;
+                        }
+
                         $result=$object->create($user);
                         if ($result > 0)
                         {
@@ -162,6 +174,15 @@ if (! $action)
         print '</td>';
         print '</tr>';
 
+        // Other attributes
+        $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"');
+        $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
+        if (empty($reshook) && ! empty($extrafields->attribute_label))
+        {
+        	print $object->showOptionals($extrafields,'edit');
+        }
+
+
         print '</table>';
 
         dol_fiche_end('');
diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php
index 95f5cf0574bd3f878050b6564fcd6fe364062434..d2ec14efd7164b568571092abdab7b10ddf93db0 100644
--- a/htdocs/resource/card.php
+++ b/htdocs/resource/card.php
@@ -29,9 +29,10 @@ if (! $res) $res=@include("../../main.inc.php");	// For "custom" directory
 if (! $res) die("Include of main fails");
 
 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
-require_once 'class/dolresource.class.php';
-require_once 'class/html.formresource.class.php';
+require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php';
+require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
 
 // Load traductions files requiredby by page
 $langs->load("resource");
@@ -58,6 +59,11 @@ if( ! $user->rights->resource->read)
 
 $object = new Dolresource($db);
 
+$extrafields = new ExtraFields($db);
+
+// fetch optionals attributes and labels
+$extralabels=$extrafields->fetch_name_optionals_label($object->table_element);
+
 $hookmanager->initHooks(array('resource_card','globalcard'));
 $parameters=array('resource_id'=>$id);
 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
@@ -88,6 +94,12 @@ if (empty($reshook))
 				$object->description  			= $description;
 				$object->fk_code_type_resource  = $fk_code_type_resource;
 
+				// Fill array 'array_options' with data from add form
+				$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
+				if ($ret < 0) {
+					$error ++;
+				}
+
 				$result=$object->update($user);
 				if ($result > 0)
 				{
@@ -126,7 +138,7 @@ if (empty($reshook))
 				Header('Location: '.DOL_URL_ROOT.'/resource/list.php');
 				exit;
 			}
-			else 
+			else
 			{
 				setEventMessages($object->error, $object->errors, 'errors');
 			}
@@ -188,6 +200,14 @@ if ( $object->fetch($id) > 0 )
 		print '<textarea name="description" cols="80" rows="'.ROWS_3.'">'.($_POST['description'] ? GETPOST('description','alpha') : $object->description).'</textarea>';
 		print '</td></tr>';
 
+		// Other attributes
+		$parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"');
+		$reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
+		if (empty($reshook) && ! empty($extrafields->attribute_label))
+		{
+			print $object->showOptionals($extrafields,'edit');
+		}
+
 		print '</table>';
 
 		dol_fiche_end();
@@ -235,6 +255,15 @@ if ( $object->fetch($id) > 0 )
 		print '<td>';
 		print $object->description;
 		print '</td>';
+
+		// Other attributes
+		$parameters=array();
+		$reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
+		if (empty($reshook) && ! empty($extrafields->attribute_label))
+		{
+			print $object->showOptionals($extrafields);
+		}
+
 		print '</tr>';
 
 		print '</table>';
diff --git a/htdocs/resource/class/dolresource.class.php b/htdocs/resource/class/dolresource.class.php
index 633be01aa1b2e46c8f11bbf4fcfd437b70815062..2cf93493739c7f31f0a59a8553dd90339470ee0a 100644
--- a/htdocs/resource/class/dolresource.class.php
+++ b/htdocs/resource/class/dolresource.class.php
@@ -63,7 +63,7 @@ class Dolresource extends CommonObject
      */
     function create($user, $notrigger=0)
     {
-    	global $conf, $langs;
+    	global $conf, $langs, $hookmanager;
     	$error=0;
 
     	// Clean parameters
@@ -107,14 +107,40 @@ class Dolresource extends CommonObject
     	if (! $error)
     	{
     		$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
+    	}
 
+    	if (! $error)
+    	{
+    		$action='create';
+
+    		// Actions on extra fields (by external module or standard code)
+    		// TODO le hook fait double emploi avec le trigger !!
+    		$hookmanager->initHooks(array('actioncommdao'));
+    		$parameters=array('actcomm'=>$this->id);
+    		$reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
+    		if (empty($reshook))
+    		{
+    			if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
+    			{
+    				$result=$this->insertExtraFields();
+    				if ($result < 0)
+    				{
+    					$error++;
+    				}
+    			}
+    		}
+    		else if ($reshook < 0) $error++;
+    	}
+
+    	if (! $error)
+    	{
     		if (! $notrigger)
     		{
     			//// Call triggers
-    			//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-    			//$interface=new Interfaces($this->db);
-    			//$result=$interface->run_triggers('RESOURCE_CREATE',$this,$user,$langs,$conf);
-    			//if ($result < 0) { $error++; $this->errors=$interface->errors; }
+    			include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+    			$interface=new Interfaces($this->db);
+    			$result=$interface->run_triggers('RESOURCE_CREATE',$this,$user,$langs,$conf);
+    			if ($result < 0) { $error++; $this->errors=$interface->errors; }
     			//// End call triggers
     		}
     	}
@@ -177,6 +203,13 @@ class Dolresource extends CommonObject
     			$this->note_private				=	$obj->note_private;
     			$this->type_label				=	$obj->type_label;
 
+    			// Retreive all extrafield for thirdparty
+    			// fetch optionals attributes and labels
+    			require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php');
+    			$extrafields=new ExtraFields($this->db);
+    			$extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true);
+    			$this->fetch_optionals($this->id,$extralabels);
+
     		}
     		$this->db->free($resql);
 
@@ -199,7 +232,7 @@ class Dolresource extends CommonObject
      */
     function update($user=null, $notrigger=0)
     {
-    	global $conf, $langs;
+    	global $conf, $langs, $hookmanager;
     	$error=0;
 
     	// Clean parameters
@@ -229,13 +262,35 @@ class Dolresource extends CommonObject
     			// want this action calls a trigger.
 
     			//// Call triggers
-    			//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
-    			//$interface=new Interfaces($this->db);
-    			//$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
-    			//if ($result < 0) { $error++; $this->errors=$interface->errors; }
+    			include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+    			$interface=new Interfaces($this->db);
+    			$result=$interface->run_triggers('RESOURCE_MODIFY',$this,$user,$langs,$conf);
+    			if ($result < 0) { $error++; $this->errors=$interface->errors; }
     			//// End call triggers
     		}
     	}
+    	if (! $error)
+    	{
+	    	$action='update';
+
+	    	// Actions on extra fields (by external module or standard code)
+	    	// TODO le hook fait double emploi avec le trigger !!
+	    	$hookmanager->initHooks(array('actioncommdao'));
+	    	$parameters=array('actcomm'=>$this->id);
+	    	$reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
+	    	if (empty($reshook))
+	    	{
+	    		if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
+	    		{
+	    			$result=$this->insertExtraFields();
+	    			if ($result < 0)
+	    			{
+	    				$error++;
+	    			}
+	    		}
+	    	}
+	    	else if ($reshook < 0) $error++;
+    	}
 
     	// Commit or rollback
     	if ($error)
@@ -294,10 +349,12 @@ class Dolresource extends CommonObject
     			$this->mandatory		=	$obj->mandatory;
     			$this->fk_user_create	=	$obj->fk_user_create;
 
-				if($obj->resource_id && $obj->resource_type)
+				if($obj->resource_id && $obj->resource_type) {
 					$this->objresource = fetchObjectByElement($obj->resource_id,$obj->resource_type);
-				if($obj->element_id && $obj->element_type)
+				}
+				if($obj->element_id && $obj->element_type) {
 					$this->objelement = fetchObjectByElement($obj->element_id,$obj->element_type);
+				}
 
     		}
     		$this->db->free($resql);
@@ -324,36 +381,57 @@ class Dolresource extends CommonObject
 
         $error=0;
 
-        if (! $notrigger)
-        {
-            // Call trigger
-            $result=$this->call_trigger('RESOURCE_DELETE',$user);
-            if ($result < 0) return -1;
-            // End call triggers
-        }
+        $this->db->begin();
 
         $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
         $sql.= " WHERE rowid =".$rowid;
 
-        dol_syslog(get_class($this)."::delete", LOG_DEBUG);
+        dol_syslog(get_class($this), LOG_DEBUG);
         if ($this->db->query($sql))
         {
             $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_resources";
             $sql.= " WHERE element_type='resource' AND resource_id =".$this->db->escape($rowid);
             dol_syslog(get_class($this)."::delete", LOG_DEBUG);
-            if ($this->db->query($sql))
+            $resql=$this->db->query($sql);
+            if (!$resql)
             {
-                return 1;
-            }
-            else {
-                $this->error=$this->db->lasterror();
-                return -1;
+            	$this->error=$this->db->lasterror();
+            	$error++;
             }
         }
         else
         {
             $this->error=$this->db->lasterror();
-            return -1;
+            $error++;
+        }
+
+        // Removed extrafields
+        if (! $error) {
+        	$result=$this->deleteExtraFields();
+        	if ($result < 0)
+        	{
+        		$error++;
+        		dol_syslog(get_class($this)."::delete error -3 ".$this->error, LOG_ERR);
+        	}
+        }
+
+        if (! $notrigger)
+        {
+        	// Call trigger
+        	$result=$this->call_trigger('RESOURCE_DELETE',$user);
+        	if ($result < 0) $error++;
+        	// End call triggers
+        }
+
+        if (! $error)
+        {
+        	$this->db->commit();
+        	return 1;
+        }
+        else
+        {
+        	$this->db->rollback();
+        	return -1;
         }
     }
 
@@ -377,9 +455,20 @@ class Dolresource extends CommonObject
     	$sql.= " t.description,";
     	$sql.= " t.fk_code_type_resource,";
     	$sql.= " t.tms,";
+
+    	require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php');
+    	$extrafields=new ExtraFields($this->db);
+    	$extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true);
+    	if (is_array($extralabels) && count($extralabels)>0) {
+    		foreach($extralabels as $label=>$code) {
+    			$sql.= " ef.".$code." as extra_".$code.",";
+    		}
+    	}
+
     	$sql.= " ty.label as type_label";
     	$sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
     	$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_type_resource as ty ON ty.code=t.fk_code_type_resource";
+    	$sql.= " LEFT JOIN ".MAIN_DB_PREFIX.$this->table_element."_extrafields as ef ON ef.fk_object=t.rowid";
     	$sql.= " WHERE t.entity IN (".getEntity('resource',1).")";
 
     	//Manage filter
@@ -388,6 +477,9 @@ class Dolresource extends CommonObject
     			if (strpos($key,'date')) {
     				$sql.= ' AND '.$key.' = \''.$this->db->idate($value).'\'';
     			}
+    			elseif (strpos($key,'ef.')!==false){
+    				$sql.= $value;
+    			}
     			else {
     				$sql.= ' AND '.$key.' LIKE \'%'.$value.'%\'';
     			}
@@ -419,6 +511,11 @@ class Dolresource extends CommonObject
     				$line->fk_code_type_resource	=	$obj->fk_code_type_resource;
     				$line->type_label				=	$obj->type_label;
 
+    				// Retreive all extrafield for thirdparty
+    				// fetch optionals attributes and labels
+
+    				$line->fetch_optionals($line->id,$extralabels);
+
     				$this->lines[] = $line;
     			}
     			$this->db->free($resql);
diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php
index 90eed12528426db683f298f1d151d86fc74436b3..3b6338f0fce1337f36b11930fdc3d8f6980dad0e 100644
--- a/htdocs/resource/list.php
+++ b/htdocs/resource/list.php
@@ -41,28 +41,103 @@ $resource_id            = GETPOST('resource_id','int');
 
 $sortorder      = GETPOST('sortorder','alpha');
 $sortfield      = GETPOST('sortfield','alpha');
-$page           = GETPOST('page','int');
+
+// Initialize context for list
+$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'resourcelist';
 
 $object = new Dolresource($db);
 
+$extrafields = new ExtraFields($db);
+
+// fetch optionals attributes and labels
+$extralabels=$extrafields->fetch_name_optionals_label($object->table_element);
+$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_');
+$search_ref=GETPOST("search_ref");
+$search_type=GETPOST("search_type");
+
+$filter=array();
+
+if ($search_ref != ''){
+	$param.='&search_ref='.$search_ref;
+	$filter['t.ref']=$search_ref;
+}
+if ($search_type != ''){
+	$param.='&search_type='.$search_type;
+	$filter['ty.label']=$search_type;
+}
+if ($search_label != '') 		$param.='&search_label='.$search_label;
+// Add $param from extra fields
+foreach ($search_array_options as $key => $val)
+{
+	$crit=$val;
+	$tmpkey=preg_replace('/search_options_/','',$key);
+	$typ=$extrafields->attribute_type[$tmpkey];
+	if ($val != '') {
+		$param.='&search_options_'.$tmpkey.'='.urlencode($val);
+	}
+	$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)))
+	{
+		$filter['ef.'.$tmpkey]=natural_search('ef.'.$tmpkey, $crit, $mode);
+	}
+}
+if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage;
+
+
 $hookmanager->initHooks(array('resource_list'));
 
 if (empty($sortorder)) $sortorder="ASC";
 if (empty($sortfield)) $sortfield="t.rowid";
 if (empty($arch)) $arch = 0;
 
+$page           = GETPOST('page','int');
 if ($page == -1) {
-        $page = 0 ;
+	$page = 0 ;
 }
-
-$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
-$offset = $limit * $page ;
+$page = is_numeric($page) ? $page : 0;
+$page = $page == -1 ? 0 : $page;
+if (! $sortfield) $sortfield="p.ref";
+if (! $sortorder) $sortorder="ASC";
+$offset = $conf->liste_limit * $page ;
 $pageprev = $page - 1;
 $pagenext = $page + 1;
 
-if( ! $user->rights->resource->read)
+if( ! $user->rights->resource->read) {
         accessforbidden();
+}
+$arrayfields = array(
+		't.ref' => array(
+				'label' => $langs->trans("Ref"),
+				'checked' => 1
+		),
+		'ty.label' => array(
+				'label' => $langs->trans("ResourceType"),
+				'checked' => 1
+		),
+);
+// 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]
+		);
+	}
+}
+
+include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
 
+// Do we click on purge search criteria ?
+if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers
+{
+	$search_ref="";
+	$search_label="";
+	$search_array_options=array();
+	$filter=array();
+}
 
 /*
  * Action
@@ -73,7 +148,6 @@ $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);
 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
 
 
-
 /*
  * View
  */
@@ -86,11 +160,11 @@ llxHeader('',$pagetitle,'');
 // Confirmation suppression resource line
 if ($action == 'delete_resource')
 {
-        print $form->formconfirm($_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_resource",'','',1);
+	print $form->formconfirm($_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_resource",'','',1);
 }
 
 // Load object list
-$ret = $object->fetch_all($sortorder, $sortfield, $limit, $offset);
+$ret = $object->fetch_all($sortorder, $sortfield, $limit, $offset, $filter);
 if($ret == -1) {
         dol_print_error($db,$object->error);
         exit;
@@ -100,11 +174,78 @@ if($ret == -1) {
 
 $var=true;
 
+$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
+$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);
+
+print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
+if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
+print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
+print '<input type="hidden" name="action" value="list">';
+print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
+print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
+print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
+
 print '<table class="noborder" width="100%">'."\n";
 print '<tr class="liste_titre">';
-print_liste_field_titre($langs->trans('Ref'),$_SERVER['PHP_SELF'],'t.ref','',$param,'',$sortfield,$sortorder);
-print_liste_field_titre($langs->trans('ResourceType'),$_SERVER['PHP_SELF'],'ty.code','',$param,'',$sortfield,$sortorder);
-print_liste_field_titre('',"","","","",'width="60" align="center"',"","");
+if (! empty($arrayfields['t.ref']['checked']))           print_liste_field_titre($arrayfields['t.ref']['label'],$_SERVER["PHP_SELF"],"t.ref","",$param,"",$sortfield,$sortorder);
+if (! empty($arrayfields['ty.label']['checked']))        print_liste_field_titre($arrayfields['ty.label']['label'],$_SERVER["PHP_SELF"],"t.code","",$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);
+		}
+	}
+}
+print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch ');
+print "</tr>\n";
+
+print '<tr class="liste_titre">';
+if (! empty($arrayfields['t.ref']['checked']))
+{
+	print '<td class="liste_titre">';
+	print '<input type="text" class="flat" name="search_ref" value="'.$search_ref.'" size="6">';
+	print '</td>';
+}
+if (! empty($arrayfields['ty.label']['checked']))
+{
+	print '<td class="liste_titre">';
+	print '<input type="text" class="flat" name="search_type" value="'.$search_type.'" size="6">';
+	print '</td>';
+}
+// 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 '<td class="liste_titre'.($align?' '.$align:'').'">';
+			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 '<input class="flat'.($searchclass?' '.$searchclass:'').'" size="4" type="text" name="search_options_'.$tmpkey.'" value="'.dol_escape_htmltag($search_array_options['search_options_'.$tmpkey]).'">';
+			}
+			print '</td>';
+		}
+	}
+}
+// Action column
+print '<td class="liste_titre" align="right">';
+$searchpitco=$form->showFilterAndCheckAddButtons(0);
+print $searchpitco;
+print '</td>';
 print "</tr>\n";
 
 if ($ret)
@@ -118,13 +259,37 @@ if ($ret)
 
                 print '<tr '.$bc[$var].' '.$style.'>';
 
-                print '<td>';
-                print $resource->getNomUrl(5);
-                print '</td>';
-
-                print '<td>';
-                print $resource->type_label;
-                print '</td>';
+                if (! empty($arrayfields['t.ref']['checked']))
+                {
+                	print '<td>';
+                	print $resource->getNomUrl(5);
+                	print '</td>';
+                }
+
+                if (! empty($arrayfields['ty.label']['checked']))
+                {
+                	print '<td>';
+                	print $resource->type_label;
+                	print '</td>';
+                }
+                // 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 '<td';
+                			$align=$extrafields->getAlignFlag($key);
+                			if ($align) print ' align="'.$align.'"';
+                			print '>';
+                			$tmpkey='options_'.$key;
+                			print $extrafields->showOutputField($key, $resource->array_options[$tmpkey], '', 1);
+                			print '</td>';
+                		}
+                	}
+                	if (! $i) $totalarray['nbfield']++;
+                }
 
                 print '<td align="center">';
                 print '<a href="./card.php?action=edit&id='.$resource->id.'">';
@@ -140,6 +305,7 @@ if ($ret)
         }
 
         print '</table>';
+        print "</form>\n";
 }
 else
 {