Browse Source

Several bug fixes:
missing import_key field, ref generator parameter must be task not
project, import must use css, serious database integrity problem
accepting duplicate tasks.

Laurent Destailleur 8 years ago
parent
commit
e9b78db1ac

+ 4 - 2
htdocs/core/class/commonobject.class.php

@@ -2885,11 +2885,13 @@ abstract class CommonObject
      *  Function to check if an object is used by others.
      *  Check is done into this->childtables. There is no check into llx_element_element.
      *
-     *  @param	int		$id			Id of object
+     *  @param	int		$id			Force id of object
      *  @return	int					<0 if KO, 0 if not used, >0 if already used
      */
-    function isObjectUsed($id)
+    function isObjectUsed($id=0)
     {
+        if (empty($id)) $id=$this->id;
+        
         // Check parameters
         if (! isset($this->childtables) || ! is_array($this->childtables) || count($this->childtables) == 0)
         {

+ 1 - 1
htdocs/core/class/html.formcompany.class.php

@@ -702,7 +702,7 @@ class FormCompany
 		if (is_object($object) && method_exists($object, 'liste_type_contact'))
 		{
 			$lesTypes = $object->liste_type_contact($source, $sortorder, 0, 1);
-			print '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">';
+			print '<select class="flat valignmiddle" name="'.$htmlname.'" id="'.$htmlname.'">';
 			if ($showempty) print '<option value="0"></option>';
 			foreach($lesTypes as $key=>$value)
 			{

+ 22 - 1
htdocs/core/modules/import/import_csv.modules.php

@@ -381,7 +381,12 @@ class ImportCsv extends ModeleImports
                                         }
                                         else
 										{
-                                            dol_include_once($file);
+                                            $resultload = dol_include_once($file);
+                                            if (empty($resultload))
+                                            {
+                                                dol_print_error('', 'Error trying to call file='.$file.', class='.$class.', method='.$method);
+                                                break;
+                                            }
                                             $classinstance=new $class($this->db);
                                             // Try the fetch from code or ref
                                             call_user_func_array(array($classinstance, $method),array('', $newval));
@@ -454,6 +459,22 @@ class ImportCsv extends ModeleImports
                                     }
                                     if (empty($newval)) $arrayrecord[($key-1)]['type']=-1;	// If we get empty value, we will use "null"
                                 }
+                                elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='getrefifauto')
+                                {
+                                    $defaultref='';
+                                    // TODO provide the $modTask (module of generation of ref) as parameter of import_insert function
+                                    $obj = empty($conf->global->PROJECT_TASK_ADDON)?'mod_task_simple':$conf->global->PROJECT_TASK_ADDON;
+                                    if (! empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.".php"))
+                                    {
+                                        require_once DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.'.php';
+                                        $modTask = new $obj;
+                                        $defaultref = $modTask->getNextValue(null,null);
+                                    }
+                                    if (is_numeric($defaultref) && $defaultref <= 0) $defaultref='';
+                                    $newval=$defaultref;
+                                }                                
+                                
+                                
                                 elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='numeric')
                                 {
                                     $newval = price2num($newval);

+ 35 - 1
htdocs/core/modules/modProjet.class.php

@@ -206,7 +206,7 @@ class modProjet extends DolibarrModules
 		// Menus
 		//-------
 		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
-		
+
 		
 		//Exports
 		//--------
@@ -322,6 +322,40 @@ class modProjet extends DolibarrModules
 		$this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX."projet_task_time as ptt ON pt.rowid = ptt.fk_task";
 		$this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON p.fk_soc = s.rowid';
 		$this->export_sql_end[$r] .=' WHERE p.entity = '.$conf->entity;
+		
+		
+		// Import list of tasks
+		if (empty($conf->global->PROJECT_HIDE_TASKS))
+		{
+    		$r++;
+    		$this->import_code[$r]='tasksofprojects';
+    		$this->import_label[$r]='ImportDatasetTasks';
+    		$this->import_icon[$r]='task';
+    		$this->import_entities_array[$r]=array('t.fk_projet'=>'project');	// We define here only fields that use another icon that the one defined into import_icon
+    		$this->import_tables_array[$r]=array('t'=>MAIN_DB_PREFIX.'projet_task','extra'=>MAIN_DB_PREFIX.'projet_task_extrafields');	// List of tables to insert into (insert done in same order)
+    		$this->import_fields_array[$r]=array('t.fk_projet'=>'ProjectRef*','t.ref'=>'RefTask*','t.label'=>'LabelTask*','t.dateo'=>"DateStart",'t.datee'=>"DateEnd",'t.planned_workload'=>"PlannedWorkload",'t.progress'=>"Progress",'t.note_private'=>"NotePrivate",'t.note_public'=>"NotePublic",'t.datec'=>"DateCreation");
+    		// Add extra fields
+    		$sql="SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'projet_task' AND entity = ".$conf->entity;
+    		$resql=$this->db->query($sql);
+    		if ($resql)    // This can fail when class is used on old database (during migration for example)
+    		{
+    		    while ($obj=$this->db->fetch_object($resql))
+    		    {
+    		        $fieldname='extra.'.$obj->name;
+    		        $fieldlabel=ucfirst($obj->label);
+    		        $this->import_fields_array[$r][$fieldname]=$fieldlabel.($obj->fieldrequired?'*':'');
+    		    }
+    		}
+    		// End add extra fields
+    		$this->import_fieldshidden_array[$r]=array('t.fk_user_creat'=>'user->id','extra.fk_object'=>'lastrowid-'.MAIN_DB_PREFIX.'projet_task');    // aliastable.field => ('user->id' or 'lastrowid-'.tableparent)
+    		$this->import_convertvalue_array[$r]=array(
+    		    't.fk_projet'=>array('rule'=>'fetchidfromref','classfile'=>'/projet/class/project.class.php','class'=>'Project','method'=>'fetch','element'=>'Project'),
+    		    't.ref'=>array('rule'=>'getrefifauto')
+    		);
+    		//$this->import_convertvalue_array[$r]=array('s.fk_soc'=>array('rule'=>'lastrowid',table='t');
+    		$this->import_regex_array[$r]=array('t.dateo'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','t.datee'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','t.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]( [0-9][0-9]:[0-9][0-9]:[0-9][0-9])?$');
+    		$this->import_examplevalues_array[$r]=array('t.fk_projet'=>'MyProjectRef','t.ref'=>"auto or TK2010-1234",'t.label'=>"My task",'t.progress'=>"0 (not started) to 100 (finished)",'t.datec'=>'1972-10-10','t.note_private'=>"My private note",'t.note_public'=>"My public note");
+		}		
 	}
 
 

+ 6 - 6
htdocs/core/modules/project/task/mod_task_simple.php

@@ -101,10 +101,10 @@ class mod_task_simple extends ModeleNumRefTask
 	*  Return next value
 	*
 	*  @param   Societe	$objsoc		Object third party
-	*  @param   Task	$task		Object Task
+	*  @param   Task	$object		Object Task
 	*  @return	string				Value if OK, 0 if KO
 	*/
-    function getNextValue($objsoc,$task)
+    function getNextValue($objsoc,$object)
     {
 		global $db,$conf;
 
@@ -127,7 +127,7 @@ class mod_task_simple extends ModeleNumRefTask
 			return -1;
 		}
 
-		$date=empty($task->date_c)?dol_now():$task->date_c;
+		$date=empty($object->date_c)?dol_now():$object->date_c;
 
 		//$yymm = strftime("%y%m",time());
 		$yymm = strftime("%y%m",$date);
@@ -144,12 +144,12 @@ class mod_task_simple extends ModeleNumRefTask
      * 	Return next reference not yet used as a reference
      *
      *  @param	Societe	$objsoc     Object third party
-     *  @param  Task	$task		Object task
+     *  @param  Task	$object		Object task
      *  @return string      		Next not used reference
      */
-    function task_get_num($objsoc=0,$task='')
+    function task_get_num($objsoc=0,$object='')
     {
-        return $this->getNextValue($objsoc,$task);
+        return $this->getNextValue($objsoc,$object);
     }
 }
 

+ 7 - 7
htdocs/core/modules/project/task/mod_task_universal.php

@@ -102,10 +102,10 @@ class mod_task_universal extends ModeleNumRefTask
 	*  Return next value
 	*
 	*  @param	Societe		$objsoc		Object third party
-	*  @param   Project		$project	Object project
+	*  @param   Task		$object	    Object task
 	*  @return  string					Value if OK, 0 if KO
 	*/
-    function getNextValue($objsoc,$project)
+    function getNextValue($objsoc,$object)
     {
 		global $db,$conf;
 
@@ -120,8 +120,8 @@ class mod_task_universal extends ModeleNumRefTask
 			return 0;
 		}
 
-		$date=empty($project->date_c)?dol_now():$project->date_c;
-		$numFinal=get_next_value($db,$mask,'projet_task','ref','',$objsoc->code_client,$date);
+		$date=empty($object->date_c)?dol_now():$object->date_c;
+		$numFinal=get_next_value($db,$mask,'projet_task','ref','',(is_object($objsoc)?$objsoc->code_client:''),$date);
 
 		return  $numFinal;
 	}
@@ -131,12 +131,12 @@ class mod_task_universal extends ModeleNumRefTask
      *  Return next reference not yet used as a reference
      *
      *  @param	Societe		$objsoc     Object third party
-     *  @param  Project		$project	Object project
+     *  @param  Task		$object	    Object task
      *  @return string      			Next not used reference
      */
-    function project_get_num($objsoc=0,$project='')
+    function project_get_num($objsoc=0,$object='')
     {
-        return $this->getNextValue($objsoc,$project);
+        return $this->getNextValue($objsoc,$object);
     }
 }
 

+ 41 - 36
htdocs/imports/import.php

@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) 2005-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
+/* Copyright (C) 2005-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
  * Copyright (C) 2012      Christophe Battarel	<christophe.battarel@altairis.fr>
  *
@@ -342,8 +342,6 @@ if ($step == 1 || ! $datatoimport)
 	dol_fiche_head($head, 'step1', $langs->trans("NewImport"));
 
 
-	print '<table class="notopnoleftnoright" width="100%">';
-
 	print $langs->trans("SelectImportDataSet").'<br>';
 
 	// Affiche les modules d'imports
@@ -387,10 +385,7 @@ if ($step == 1 || ! $datatoimport)
 	}
 	print '</table>';
 
-	print '</table>';
-
     dol_fiche_end();
-
 }
 
 
@@ -413,7 +408,7 @@ if ($step == 2 && $datatoimport)
 	print '<table width="100%" class="border">';
 
 	// Module
-	print '<tr><td width="25%">'.$langs->trans("Module").'</td>';
+	print '<tr><td class="titlefield">'.$langs->trans("Module").'</td>';
 	print '<td>';
 	$titleofmodule=$objimport->array_import_module[0]->getName();
 	// Special cas for import common to module/services
@@ -422,15 +417,16 @@ if ($step == 2 && $datatoimport)
 	print '</td></tr>';
 
 	// Lot de donnees a importer
-	print '<tr><td width="25%">'.$langs->trans("DatasetToImport").'</td>';
+	print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
 	print '<td>';
 	print img_object($objimport->array_import_module[0]->getName(),$objimport->array_import_icon[0]).' ';
 	print $objimport->array_import_label[0];
 	print '</td></tr>';
 
 	print '</table>';
-	print '<br>'."\n";
 
+	dol_fiche_end();
+	
 
 	print '<form name="userfile" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" METHOD="POST">';
 	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
@@ -463,9 +459,6 @@ if ($step == 2 && $datatoimport)
 	}
 
 	print '</table></form>';
-
-    dol_fiche_end();
-
 }
 
 
@@ -498,7 +491,7 @@ if ($step == 3 && $datatoimport)
 	print '<table width="100%" class="border">';
 
 	// Module
-	print '<tr><td width="25%">'.$langs->trans("Module").'</td>';
+	print '<tr><td class="titlefield">'.$langs->trans("Module").'</td>';
 	print '<td>';
 	$titleofmodule=$objimport->array_import_module[0]->getName();
 	// Special cas for import common to module/services
@@ -507,7 +500,7 @@ if ($step == 3 && $datatoimport)
 	print '</td></tr>';
 
 	// Lot de donnees a importer
-	print '<tr><td width="25%">'.$langs->trans("DatasetToImport").'</td>';
+	print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
 	print '<td>';
 	print img_object($objimport->array_import_module[0]->getName(),$objimport->array_import_icon[0]).' ';
 	print $objimport->array_import_label[0];
@@ -519,7 +512,7 @@ if ($step == 3 && $datatoimport)
 	//print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnSourceFile").'</b></td></tr>';
 
 	// Source file format
-	print '<tr><td width="25%">'.$langs->trans("SourceFileFormat").'</td>';
+	print '<tr><td class="titlefield">'.$langs->trans("SourceFileFormat").'</td>';
 	print '<td>';
     $text=$objmodelimport->getDriverDescForKey($format);
     print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
@@ -528,9 +521,11 @@ if ($step == 3 && $datatoimport)
 	print '</td></tr>';
 
 	print '</table>';
-	print '<br>'."\n";
-
+	
+	dol_fiche_end();
 
+    print '<br>';
+    
 	print '<form name="userfile" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" METHOD="POST">';
 	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
 	print '<input type="hidden" name="max_file_size" value="'.$conf->maxfilesize.'">';
@@ -542,7 +537,7 @@ if ($step == 3 && $datatoimport)
 
 	print '<tr><td colspan="6">'.$langs->trans("ChooseFileToImport",img_picto('','filenew')).'</td></tr>';
 
-	print '<tr class="liste_titre"><td colspan="6">'.$langs->trans("FileWithDataToImport").'</td></tr>';
+	//print '<tr class="liste_titre"><td colspan="6">'.$langs->trans("FileWithDataToImport").'</td></tr>';
 
 	// Input file name box
 	$var=false;
@@ -602,8 +597,6 @@ if ($step == 3 && $datatoimport)
 	}
 
 	print '</table></form>';
-
-    dol_fiche_end();
 }
 
 
@@ -719,7 +712,7 @@ if ($step == 4 && $datatoimport)
 	print '<table width="100%" class="border">';
 
 	// Module
-	print '<tr><td width="25%">'.$langs->trans("Module").'</td>';
+	print '<tr><td class="titlefield">'.$langs->trans("Module").'</td>';
 	print '<td>';
 	$titleofmodule=$objimport->array_import_module[0]->getName();
 	// Special cas for import common to module/services
@@ -728,7 +721,7 @@ if ($step == 4 && $datatoimport)
 	print '</td></tr>';
 
 	// Lot de donnees a importer
-	print '<tr><td width="25%">'.$langs->trans("DatasetToImport").'</td>';
+	print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
 	print '<td>';
 	print img_object($objimport->array_import_module[0]->getName(),$objimport->array_import_icon[0]).' ';
 	print $objimport->array_import_label[0];
@@ -740,7 +733,7 @@ if ($step == 4 && $datatoimport)
 	//print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnSourceFile").'</b></td></tr>';
 
 	// Source file format
-	print '<tr><td width="25%">'.$langs->trans("SourceFileFormat").'</td>';
+	print '<tr><td class="titlefield">'.$langs->trans("SourceFileFormat").'</td>';
 	print '<td>';
     $text=$objmodelimport->getDriverDescForKey($format);
     print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
@@ -748,7 +741,7 @@ if ($step == 4 && $datatoimport)
 
 	// Separator and enclosure
     if ($model == 'csv') {
-		print '<tr><td width="25%">'.$langs->trans("CsvOptions").'</td>';
+		print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
 		print '<td>';
 		print '<form>';
 		print '<input type="hidden" value="'.$step.'" name="step">';
@@ -767,7 +760,7 @@ if ($step == 4 && $datatoimport)
     }
 
 	// File to import
-	print '<tr><td width="25%">'.$langs->trans("FileToImport").'</td>';
+	print '<tr><td>'.$langs->trans("FileToImport").'</td>';
 	print '<td>';
 	$modulepart='import';
 	$relativepath=GETPOST('filetoimport');
@@ -777,6 +770,9 @@ if ($step == 4 && $datatoimport)
 	print '</td></tr>';
 
 	print '</table>';
+	
+	dol_fiche_end();
+	
 	print '<br>'."\n";
 
 
@@ -801,7 +797,7 @@ if ($step == 4 && $datatoimport)
     print '</form>';
 
 	// Title of array with fields
-	print '<table class="nobordernopadding" width="100%">';
+	print '<table class="noborder" width="100%">';
 	print '<tr class="liste_titre">';
 	print '<td>'.$langs->trans("FieldsInSourceFile").'</td>';
 	print '<td>'.$langs->trans("FieldsInTargetDatabase").'</td>';
@@ -999,8 +995,6 @@ if ($step == 4 && $datatoimport)
 
 	print '</table>';
 
-    dol_fiche_end();
-
 
 	if ($conf->use_javascript_ajax)
 	{
@@ -1183,7 +1177,7 @@ if ($step == 5 && $datatoimport)
 	print '<table width="100%" class="border">';
 
 	// Module
-	print '<tr><td width="25%">'.$langs->trans("Module").'</td>';
+	print '<tr><td class="titlefield">'.$langs->trans("Module").'</td>';
 	print '<td>';
 	$titleofmodule=$objimport->array_import_module[0]->getName();
 	// Special cas for import common to module/services
@@ -1204,7 +1198,7 @@ if ($step == 5 && $datatoimport)
 	//print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnSourceFile").'</b></td></tr>';
 
 	// Source file format
-	print '<tr><td width="25%">'.$langs->trans("SourceFileFormat").'</td>';
+	print '<tr><td class="titlefield">'.$langs->trans("SourceFileFormat").'</td>';
 	print '<td>';
     $text=$objmodelimport->getDriverDescForKey($format);
     print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
@@ -1212,7 +1206,7 @@ if ($step == 5 && $datatoimport)
 
 	// Separator and enclosure
 	if ($model == 'csv') {
-	    print '<tr><td width="25%">'.$langs->trans("CsvOptions").'</td>';
+	    print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
 	    print '<td>';
 	    print $langs->trans("Separator").' : ';
 	    print htmlentities($separator);
@@ -1441,9 +1435,9 @@ if ($step == 5 && $datatoimport)
         $db->rollback();    // We force rollback because this was just a simulation.
 
         // Show OK
-        if (! count($arrayoferrors) && ! count($arrayofwarnings)) print img_picto($langs->trans("OK"),'tick').' <b>'.$langs->trans("NoError").'</b><br><br>';
-        else print $langs->trans("NbOfLinesOK",$nbok).'</b><br><br>';
-
+        if (! count($arrayoferrors) && ! count($arrayofwarnings)) print '<center>'.img_picto($langs->trans("OK"),'tick').' <b>'.$langs->trans("NoError").'</b></center><br><br>';
+        else print '<b>'.$langs->trans("NbOfLinesOK",$nbok).'</b><br><br>';
+        
         // Show Errors
         //var_dump($arrayoferrors);
         if (count($arrayoferrors))
@@ -1585,7 +1579,7 @@ if ($step == 6 && $datatoimport)
 	print '<table width="100%" class="border">';
 
 	// Module
-	print '<tr><td width="25%">'.$langs->trans("Module").'</td>';
+	print '<tr><td class="titlefield">'.$langs->trans("Module").'</td>';
 	print '<td>';
 	$titleofmodule=$objimport->array_import_module[0]->getName();
 	// Special cas for import common to module/services
@@ -1606,12 +1600,23 @@ if ($step == 6 && $datatoimport)
 	//print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnSourceFile").'</b></td></tr>';
 
 	// Source file format
-	print '<tr><td width="25%">'.$langs->trans("SourceFileFormat").'</td>';
+	print '<tr><td class="titlefield">'.$langs->trans("SourceFileFormat").'</td>';
 	print '<td>';
     $text=$objmodelimport->getDriverDescForKey($format);
     print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
 	print '</td></tr>';
 
+	// Separator and enclosure
+	if ($model == 'csv') {
+	    print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
+	    print '<td>';
+	    print $langs->trans("Separator").' : ';
+	    print htmlentities($separator);
+	    print '&nbsp;&nbsp;&nbsp;&nbsp;'.$langs->trans("Enclosure").' : ';
+	    print htmlentities($enclosure);
+	    print '</td></tr>';
+	}
+	
 	// File to import
 	print '<tr><td>'.$langs->trans("FileToImport").'</td>';
 	print '<td>';

+ 9 - 1
htdocs/install/mysql/migration/4.0.0-5.0.0.sql

@@ -183,10 +183,16 @@ ALTER TABLE llx_bank_account ADD COLUMN note_public     		text;
 ALTER TABLE llx_bank_account ADD COLUMN model_pdf       		varchar(255);
 ALTER TABLE llx_bank_account ADD COLUMN import_key      		varchar(14);
 
+ALTER TABLE llx_projet ADD COLUMN import_key      	        	varchar(14);
+ALTER TABLE llx_projet_task ADD COLUMN import_key      		    varchar(14);
+ALTER TABLE llx_projet_task_time ADD COLUMN import_key      	varchar(14);
+
+
 ALTER TABLE llx_overwrite_trans ADD COLUMN entity integer DEFAULT 1 NOT NULL AFTER rowid;
 
 ALTER TABLE llx_mailing_cibles ADD COLUMN error_text varchar(255);
 
+ALTER TABLE llx_c_actioncomm MODIFY COLUMN type varchar(50) DEFAULT 'system' NOT NULL;
 
 create table llx_user_employment
 (
@@ -209,6 +215,7 @@ create table llx_user_employment
 )ENGINE=innodb;
 
 
+
 -- Sequence to removed duplicated values of llx_links. Use serveral times if you still have duplicate.
 drop table tmp_links_double;
 --select objectid, label, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_links where label is not null group by objectid, label having count(rowid) >= 2;
@@ -219,4 +226,5 @@ drop table tmp_links_double;
 
 ALTER TABLE llx_links ADD UNIQUE INDEX uk_links (objectid,label);
 
-ALTER TABLE llx_c_actioncomm MODIFY COLUMN type varchar(50) DEFAULT 'system' NOT NULL;
+UPDATE llx_projet_task SET ref = NULL WHERE ref = '';
+ALTER TABLE llx_projet_task ADD UNIQUE INDEX uk_projet_task_ref (ref, entity);

+ 2 - 1
htdocs/install/mysql/tables/llx_projet.sql

@@ -41,5 +41,6 @@ create table llx_projet
   --budget_days      real,                      -- budget in days is sum of field planned_workload of tasks
   opp_amount       double(24,8),
   budget_amount    double(24,8),				
-  model_pdf        varchar(255)
+  model_pdf        varchar(255),
+  import_key	   varchar(14)					-- Import key
 )ENGINE=innodb;

+ 1 - 0
htdocs/install/mysql/tables/llx_projet_task.key.sql

@@ -17,6 +17,7 @@
 --
 -- ============================================================================
 
+ALTER TABLE llx_projet_task ADD UNIQUE INDEX uk_projet_task_ref (ref, entity);
 
 ALTER TABLE llx_projet_task ADD INDEX idx_projet_task_fk_projet (fk_projet);
 ALTER TABLE llx_projet_task ADD INDEX idx_projet_task_fk_user_creat (fk_user_creat);

+ 2 - 1
htdocs/install/mysql/tables/llx_projet_task.sql

@@ -41,5 +41,6 @@ create table llx_projet_task
   note_private			text,
   note_public			text,
   rang                  integer DEFAULT 0,
-  model_pdf        		varchar(255)
+  model_pdf        		varchar(255),
+  import_key			varchar(14)						-- Import key
 )ENGINE=innodb;

+ 2 - 1
htdocs/install/mysql/tables/llx_projet_task_time.sql

@@ -28,5 +28,6 @@ create table llx_projet_task_time
   thm			   double(24,8),
   invoice_id       integer DEFAULT NULL,				-- If we need to invoice each line of timespent, we can save invoice id here
   invoice_line_id  integer DEFAULT NULL,                -- If we need to invoice each line of timespent, we can save invoice line id here
-  note             text
+  import_key	   varchar(14),					-- Import key
+  note             text,
 )ENGINE=innodb;

+ 2 - 2
htdocs/langs/en_US/compta.lang

@@ -200,7 +200,7 @@ BasedOnTwoFirstLettersOfVATNumberBeingDifferentFromYourCompanyCountry=Based on t
 SameCountryCustomersWithVAT=National customers report
 BasedOnTwoFirstLettersOfVATNumberBeingTheSameAsYourCompanyCountry=Based on the two first letters of the VAT number being the same as your own company's country code
 LinkedFichinter=Link to an intervention
-ImportDataset_tax_contrib=Import social/fiscal taxes
-ImportDataset_tax_vat=Import vat payments
+ImportDataset_tax_contrib=Social/fiscal taxes
+ImportDataset_tax_vat=Vat payments
 ErrorBankAccountNotFound=Error: Bank account not found
 FiscalPeriod=Accounting period

+ 1 - 0
htdocs/langs/en_US/projects.lang

@@ -22,6 +22,7 @@ TasksPublicDesc=This view presents all projects and tasks you are allowed to rea
 TasksDesc=This view presents all projects and tasks (your user permissions grant you permission to view everything).
 AllTaskVisibleButEditIfYouAreAssigned=All tasks for such project are visible, but you can enter time only for task you are assigned on. Assign task to you if you want to enter time on it.
 OnlyYourTaskAreVisible=Only tasks you are assigned on are visible. Assign task to you if you want to enter time on it.
+ImportDatasetTasks=Tasks of projects
 NewProject=New project
 AddProject=Create project
 DeleteAProject=Delete a project

+ 2 - 2
htdocs/projet/activity/perday.php

@@ -382,11 +382,11 @@ print "\n";
 
 print '<div class="floatright">'.$nav.'</div>';     // We move this before the assign to components so, the default submit button is not the assign to.
 
-print '<div class="float">';
+print '<div class="float valignmiddle">';
 print $langs->trans("AssignTaskToMe").'<br>';
 $formproject->selectTasks($socid?$socid:-1, $taskid, 'taskid', 32, 0, 1, 1);
 print $formcompany->selectTypeContact($object, '', 'type','internal','rowid', 0);
-print '<input type="submit" class="button" name="assigntask" value="'.$langs->trans("AssignTask").'">';
+print '<input type="submit" class="button valignmiddle" name="assigntask" value="'.$langs->trans("AssignTask").'">';
 //print '</form>';
 print '</div>';
 

+ 2 - 2
htdocs/projet/activity/perweek.php

@@ -377,11 +377,11 @@ print "\n";
 
 print '<div class="floatright">'.$nav.'</div>';     // We move this before the assign to components so, the default submit button is not the assign to.
 
-print '<div class="float">';
+print '<div class="float valignmiddle">';
 print $langs->trans("AssignTaskToMe").'<br>';
 $formproject->selectTasks($socid?$socid:-1, $taskid, 'taskid', 32, 0, 1, 1);
 print $formcompany->selectTypeContact($object, '', 'type','internal','rowid', 0);
-print '<input type="submit" class="button" name="assigntask" value="'.$langs->trans("AssignTask").'">';
+print '<input type="submit" class="button valignmiddle" name="assigntask" value="'.$langs->trans("AssignTask").'">';
 //print '</form>';
 print '</div>';
 

+ 6 - 2
htdocs/projet/card.php

@@ -615,12 +615,12 @@ if ($action == 'create' && $user->rights->projet->creer)
         });
         </script>';
 }
-else
+elseif ($object->id > 0) 
 {
     /*
      * Show or edit
      */
-
+    
     $res=$object->fetch_optionals($object->id,$extralabels);
 
     // To verify role of users
@@ -1127,6 +1127,10 @@ else
     $parameters=array();
     $reshook=$hookmanager->executeHooks('mainCardTabAddMore',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
 }
+else
+{
+    print $langs->trans("RecordNotFound");
+}
 
 llxFooter();
 

+ 12 - 1
htdocs/projet/class/task.class.php

@@ -33,7 +33,9 @@ class Task extends CommonObject
 {
     public $element='project_task';		//!< Id that identify managed objects
     public $table_element='projet_task';	//!< Name of table without prefix where object is stored
+    public $fk_element='fk_task';
     public $picto = 'task';
+    protected $childtables=array('projet_task_time');    // To test if we can delete object
     
     var $fk_task_parent;
     var $label;
@@ -383,13 +385,22 @@ class Task extends CommonObject
         $this->db->begin();
 
         if ($this->hasChildren() > 0)
+        {
+            dol_syslog(get_class($this)."::delete Can't delete record as it has some sub tasks", LOG_WARNING);
+            $this->error='ErrorRecordHasSubTasks';
+            $this->db->rollback();
+            return 0;
+        }
+
+        $objectisused = $this->isObjectUsed($this->id);
+        if (! empty($objectisused))
         {
             dol_syslog(get_class($this)."::delete Can't delete record as it has some child", LOG_WARNING);
             $this->error='ErrorRecordHasChildren';
             $this->db->rollback();
             return 0;
         }
-
+        
         if (! $error)
         {
             // Delete linked contacts

+ 2 - 2
htdocs/projet/tasks.php

@@ -339,7 +339,7 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third
 	{
 		require_once DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.'.php';
 		$modTask = new $obj;
-		$defaultref = $modTask->getNextValue($soc,$object);
+		$defaultref = $modTask->getNextValue($object->thirdparty,null);
 	}
 
 	if (is_numeric($defaultref) && $defaultref <= 0) $defaultref='';
@@ -351,7 +351,7 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third
 	print '</td></tr>';
 
 	print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td>';
-	print '<input type="text" size="25" name="label" class="flat" value="'.$label.'">';
+	print '<input type="text" name="label" class="flat minwidth300" value="'.$label.'">';
 	print '</td></tr>';
 
 	// List of projects