diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php
index c40e9ab677d1901faf6dd511f4e7b758fa2bd3b5..eda8b600b240ffa9e0e11389f3851f1e0a9aac5d 100644
--- a/htdocs/contrat/card.php
+++ b/htdocs/contrat/card.php
@@ -699,6 +699,11 @@ else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->contr
     $result = $object->validate($user);
 }
 
+else if ($action == 'reopen' && $user->rights->contrat->creer)
+{
+    $result = $object->reopen($user);
+}
+
 // Close all lines
 else if ($action == 'confirm_close' && $confirm == 'yes' && $user->rights->contrat->creer)
 {
@@ -1839,7 +1844,12 @@ else
                 if ($user->rights->contrat->creer) print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=valid">'.$langs->trans("Validate").'</a></div>';
                 else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans("Validate").'</a></div>';
             }
-
+            if ($object->statut == 1 && $nbofservices)
+            {
+                if ($user->rights->contrat->creer) print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=reopen">'.$langs->trans("Modify").'</a></div>';
+                else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans("Modify").'</a></div>';
+            }
+            
             if (! empty($conf->facture->enabled) && $object->statut > 0 && $object->nbofservicesclosed < $nbofservices)
             {
                 $langs->load("bills");
@@ -1899,6 +1909,12 @@ else
 
         print '</div><div class="fichehalfright"><div class="ficheaddleft">';
 
+		// List of actions on element
+		include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php';
+		$formactions = new FormActions($db);
+		$somethingshown = $formactions->showactions($object, 'contract', $socid);
+        
+        
         print '</div></div></div>';
     }
 }
diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php
index bb6ca1af9ff95c4f5111c73cbf22b328e1f0ad78..8f56ef532ef4651fcc60b36598a6cbf7547683e4 100644
--- a/htdocs/contrat/class/contrat.class.php
+++ b/htdocs/contrat/class/contrat.class.php
@@ -499,7 +499,71 @@ class Contrat extends CommonObject
 
 	}
 
+	/**
+	 * Unvalidate a contract
+	 *
+	 * @param	User	$user      		Objet User
+     * @param	int		$notrigger		1=Does not execute triggers, 0=execute triggers
+	 * @return	int						<0 if KO, >0 if OK
+	 */
+	function reopen($user, $notrigger=0)
+	{
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+		global $langs, $conf;
+
+		$now=dol_now();
+
+		$error=0;
+		dol_syslog(get_class($this).'::reopen user='.$user->id);
+
+		$this->db->begin();
+
+		$this->fetch_thirdparty();
+
+		$sql = "UPDATE ".MAIN_DB_PREFIX."contrat SET statut = 0";
+		//$sql.= ", fk_user_valid = null, date_valid = null";
+		$sql .= " WHERE rowid = ".$this->id . " AND statut = 1";
+
+		dol_syslog(get_class($this)."::validate", LOG_DEBUG);
+		$resql = $this->db->query($sql);
+		if (! $resql)
+		{
+			dol_print_error($this->db);
+			$error++;
+			$this->error=$this->db->lasterror();
+		}
+
+		// Trigger calls
+		if (! $error && ! $notrigger)
+		{
+			// Call trigger
+			$result=$this->call_trigger('CONTRACT_REOPEN',$user);
+			if ($result < 0) {
+				$error++;
+			}
+			// End call triggers
+		}
+
+		// Set new ref and define current statut
+		if (! $error)
+		{
+			$this->statut=0;
+			$this->brouillon=1;
+			$this->date_validation=$now;
+		}
 
+		if (! $error)
+		{
+			$this->db->commit();
+			return 1;
+		}
+		else
+		{
+			$this->db->rollback();
+			return -1;
+		}
+	}
+	
 	/**
 	 *    Load a contract from database
 	 *
diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang
index 4ed6ccfc2f5cf2ec68d813839213a7357e6af1c3..197da970fbbeb4d729caf112962d96a9bf38e5fe 100644
--- a/htdocs/langs/en_US/projects.lang
+++ b/htdocs/langs/en_US/projects.lang
@@ -164,6 +164,7 @@ ProjectsWithThisUserAsContact=Projects with this user as contact
 TasksWithThisUserAsContact=Tasks assigned to this user
 ResourceNotAssignedToProject=Not assigned to project
 ResourceNotAssignedToTask=Not assigned to task
+ResourceNotAssignedToTheTask=Not assigned to the task
 AssignTaskToMe=Assign task to me
 AssignTask=Assign
 ProjectOverview=Overview
diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php
index 93305dbc63cbe81f4880c12f7fdfd1db11714d5a..d829f2194df72b40d79600965312c53cc17731e2 100644
--- a/htdocs/projet/activity/perday.php
+++ b/htdocs/projet/activity/perday.php
@@ -108,6 +108,35 @@ if ($action == 'assign')
     {
     	$idfortaskuser=$user->id;
 		$result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal');
+
+    	if ($result >= 0 || $result == -2)	// Contact add ok or already contact of task
+    	{
+			// Test if we are already contact of the project (should be rare but sometimes we can add as task contact without being contact of project, like when admin user has been removed from contact of project)
+    		$sql='SELECT ec.rowid FROM '.MAIN_DB_PREFIX.'element_contact as ec, '.MAIN_DB_PREFIX.'c_type_contact as tc WHERE tc.rowid = ec.fk_c_type_contact';
+    		$sql.=' AND ec.fk_socpeople = '.$idfortaskuser." AND ec.element_id = '.$object->fk_project.' AND tc.element = 'project' AND source = 'internal'";
+    		$resql=$db->query($sql);
+    		if ($resql)
+    		{
+    			$obj=$db->fetch_object($resql);
+    			if (! $obj)	// User is not already linked to project, so we will create link to first type
+    			{
+    				$project = new Project($db);
+    				$project->fetch($object->fk_project);
+    				// Get type
+    				$listofprojcontact=$project->liste_type_contact('internal');
+    				
+    				if (count($listofprojcontact))
+    				{
+    					$typeforprojectcontact=reset(array_keys($listofprojcontact));
+    					$result = $project->add_contact($idfortaskuser, $typeforprojectcontact, 'internal');
+    				}
+    			}
+    		}
+    		else 
+    		{
+    			dol_print_error($db);
+    		}
+    	}
     }
 
 	if ($result < 0)
diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php
index 6201c601d180145de2f6ef21f2ac2f9d07243289..40cc9248b9f9168187e1840abecf93dbf0d9bd09 100644
--- a/htdocs/projet/activity/perweek.php
+++ b/htdocs/projet/activity/perweek.php
@@ -119,7 +119,36 @@ if ($action == 'assign')
     if (! $error)
     {
     	$idfortaskuser=$user->id;
-		$result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal');
+    	$result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal');
+
+    	if (! $result || $result == -2)	// Contact add ok or already contact of task
+    	{
+    		// Test if we are already contact of the project (should be rare but sometimes we can add as task contact without being contact of project, like when admin user has been removed from contact of project)
+    		$sql='SELECT ec.rowid FROM '.MAIN_DB_PREFIX.'element_contact as ec, '.MAIN_DB_PREFIX.'c_type_contact as tc WHERE tc.rowid = ec.fk_c_type_contact';
+    		$sql.=' AND ec.fk_socpeople = '.$idfortaskuser." AND ec.element_id = '.$object->fk_project.' AND tc.element = 'project' AND source = 'internal'";
+    		$resql=$db->query($sql);
+    		if ($resql)
+    		{
+    			$obj=$db->fetch_object($resql);
+    			if (! $obj)	// User is not already linked to project, so we will create link to first type
+    			{
+    				$project = new Project($db);
+    				$project->fetch($object->fk_project);
+    				// Get type
+    				$listofprojcontact=$project->liste_type_contact('internal');
+    				
+    				if (count($listofprojcontact))
+    				{
+    					$typeforprojectcontact=reset(array_keys($listofprojcontact));
+    					$result = $project->add_contact($idfortaskuser, $typeforprojectcontact, 'internal');
+    				}
+    			}
+    		}
+    		else 
+    		{
+    			dol_print_error($db);
+    		}
+    	}
     }
 
 	if ($result < 0)
diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php
index 7721633c4e82e3a11517cf930f1a54178321af84..e54eef4cf6eae9b96af50dcf1b4be9e1e1ce84bc 100644
--- a/htdocs/projet/tasks/time.php
+++ b/htdocs/projet/tasks/time.php
@@ -395,7 +395,7 @@ if ($id > 0 || ! empty($ref))
 			if (count($contactsoftask)>0)
 			{
 				$userid=$contactsoftask[0];
-				print $form->select_dolusers((GETPOST('userid')?GETPOST('userid'):$userid), 'userid', 0, '', 0, '', $contactsoftask, 0, 0, 0, '', 0, $langs->trans("ResourceNotAssignedToTask"));
+				print $form->select_dolusers((GETPOST('userid')?GETPOST('userid'):$userid), 'userid', 0, '', 0, '', $contactsoftask, 0, 0, 0, '', 0, $langs->trans("ResourceNotAssignedToTheTask"));
 			}
 			else
 			{
@@ -405,7 +405,7 @@ if ($id > 0 || ! empty($ref))
 
 			// Note
 			print '<td class="nowrap">';
-			print '<textarea name="timespent_note" cols="80" rows="'.ROWS_2.'">'.($_POST['timespent_note']?$_POST['timespent_note']:'').'</textarea>';
+			print '<textarea name="timespent_note" width="95%" rows="'.ROWS_2.'">'.($_POST['timespent_note']?$_POST['timespent_note']:'').'</textarea>';
 			print '</td>';
 
 			// Progress declared
@@ -528,7 +528,7 @@ if ($id > 0 || ! empty($ref))
 			print '<td align="left">';
 			if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid)
 			{
-				print '<textarea name="timespent_note_line" cols="80" rows="'.ROWS_2.'">'.$task_time->note.'</textarea>';
+				print '<textarea name="timespent_note_line" width="95%" rows="'.ROWS_2.'">'.$task_time->note.'</textarea>';
 			}
 			else
 			{