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.
This commit is contained in:
parent
7ac96da0d4
commit
e9b78db1ac
@ -2885,11 +2885,13 @@ abstract class CommonObject
|
|||||||
* Function to check if an object is used by others.
|
* Function to check if an object is used by others.
|
||||||
* Check is done into this->childtables. There is no check into llx_element_element.
|
* 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
|
* @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
|
// Check parameters
|
||||||
if (! isset($this->childtables) || ! is_array($this->childtables) || count($this->childtables) == 0)
|
if (! isset($this->childtables) || ! is_array($this->childtables) || count($this->childtables) == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -702,7 +702,7 @@ class FormCompany
|
|||||||
if (is_object($object) && method_exists($object, 'liste_type_contact'))
|
if (is_object($object) && method_exists($object, 'liste_type_contact'))
|
||||||
{
|
{
|
||||||
$lesTypes = $object->liste_type_contact($source, $sortorder, 0, 1);
|
$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>';
|
if ($showempty) print '<option value="0"></option>';
|
||||||
foreach($lesTypes as $key=>$value)
|
foreach($lesTypes as $key=>$value)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -381,7 +381,12 @@ class ImportCsv extends ModeleImports
|
|||||||
}
|
}
|
||||||
else
|
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);
|
$classinstance=new $class($this->db);
|
||||||
// Try the fetch from code or ref
|
// Try the fetch from code or ref
|
||||||
call_user_func_array(array($classinstance, $method),array('', $newval));
|
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"
|
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')
|
elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='numeric')
|
||||||
{
|
{
|
||||||
$newval = price2num($newval);
|
$newval = price2num($newval);
|
||||||
|
|||||||
@ -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."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] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON p.fk_soc = s.rowid';
|
||||||
$this->export_sql_end[$r] .=' WHERE p.entity = '.$conf->entity;
|
$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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -101,10 +101,10 @@ class mod_task_simple extends ModeleNumRefTask
|
|||||||
* Return next value
|
* Return next value
|
||||||
*
|
*
|
||||||
* @param Societe $objsoc Object third party
|
* @param Societe $objsoc Object third party
|
||||||
* @param Task $task Object Task
|
* @param Task $object Object Task
|
||||||
* @return string Value if OK, 0 if KO
|
* @return string Value if OK, 0 if KO
|
||||||
*/
|
*/
|
||||||
function getNextValue($objsoc,$task)
|
function getNextValue($objsoc,$object)
|
||||||
{
|
{
|
||||||
global $db,$conf;
|
global $db,$conf;
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ class mod_task_simple extends ModeleNumRefTask
|
|||||||
return -1;
|
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",time());
|
||||||
$yymm = strftime("%y%m",$date);
|
$yymm = strftime("%y%m",$date);
|
||||||
@ -144,12 +144,12 @@ class mod_task_simple extends ModeleNumRefTask
|
|||||||
* Return next reference not yet used as a reference
|
* Return next reference not yet used as a reference
|
||||||
*
|
*
|
||||||
* @param Societe $objsoc Object third party
|
* @param Societe $objsoc Object third party
|
||||||
* @param Task $task Object task
|
* @param Task $object Object task
|
||||||
* @return string Next not used reference
|
* @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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -102,10 +102,10 @@ class mod_task_universal extends ModeleNumRefTask
|
|||||||
* Return next value
|
* Return next value
|
||||||
*
|
*
|
||||||
* @param Societe $objsoc Object third party
|
* @param Societe $objsoc Object third party
|
||||||
* @param Project $project Object project
|
* @param Task $object Object task
|
||||||
* @return string Value if OK, 0 if KO
|
* @return string Value if OK, 0 if KO
|
||||||
*/
|
*/
|
||||||
function getNextValue($objsoc,$project)
|
function getNextValue($objsoc,$object)
|
||||||
{
|
{
|
||||||
global $db,$conf;
|
global $db,$conf;
|
||||||
|
|
||||||
@ -120,8 +120,8 @@ class mod_task_universal extends ModeleNumRefTask
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$date=empty($project->date_c)?dol_now():$project->date_c;
|
$date=empty($object->date_c)?dol_now():$object->date_c;
|
||||||
$numFinal=get_next_value($db,$mask,'projet_task','ref','',$objsoc->code_client,$date);
|
$numFinal=get_next_value($db,$mask,'projet_task','ref','',(is_object($objsoc)?$objsoc->code_client:''),$date);
|
||||||
|
|
||||||
return $numFinal;
|
return $numFinal;
|
||||||
}
|
}
|
||||||
@ -131,12 +131,12 @@ class mod_task_universal extends ModeleNumRefTask
|
|||||||
* Return next reference not yet used as a reference
|
* Return next reference not yet used as a reference
|
||||||
*
|
*
|
||||||
* @param Societe $objsoc Object third party
|
* @param Societe $objsoc Object third party
|
||||||
* @param Project $project Object project
|
* @param Task $object Object task
|
||||||
* @return string Next not used reference
|
* @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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?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) 2005-2009 Regis Houssin <regis.houssin@capnetworks.com>
|
||||||
* Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
|
* 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"));
|
dol_fiche_head($head, 'step1', $langs->trans("NewImport"));
|
||||||
|
|
||||||
|
|
||||||
print '<table class="notopnoleftnoright" width="100%">';
|
|
||||||
|
|
||||||
print $langs->trans("SelectImportDataSet").'<br>';
|
print $langs->trans("SelectImportDataSet").'<br>';
|
||||||
|
|
||||||
// Affiche les modules d'imports
|
// Affiche les modules d'imports
|
||||||
@ -387,10 +385,7 @@ if ($step == 1 || ! $datatoimport)
|
|||||||
}
|
}
|
||||||
print '</table>';
|
print '</table>';
|
||||||
|
|
||||||
print '</table>';
|
|
||||||
|
|
||||||
dol_fiche_end();
|
dol_fiche_end();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -413,7 +408,7 @@ if ($step == 2 && $datatoimport)
|
|||||||
print '<table width="100%" class="border">';
|
print '<table width="100%" class="border">';
|
||||||
|
|
||||||
// Module
|
// Module
|
||||||
print '<tr><td width="25%">'.$langs->trans("Module").'</td>';
|
print '<tr><td class="titlefield">'.$langs->trans("Module").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
$titleofmodule=$objimport->array_import_module[0]->getName();
|
$titleofmodule=$objimport->array_import_module[0]->getName();
|
||||||
// Special cas for import common to module/services
|
// Special cas for import common to module/services
|
||||||
@ -422,14 +417,15 @@ if ($step == 2 && $datatoimport)
|
|||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Lot de donnees a importer
|
// Lot de donnees a importer
|
||||||
print '<tr><td width="25%">'.$langs->trans("DatasetToImport").'</td>';
|
print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
print img_object($objimport->array_import_module[0]->getName(),$objimport->array_import_icon[0]).' ';
|
print img_object($objimport->array_import_module[0]->getName(),$objimport->array_import_icon[0]).' ';
|
||||||
print $objimport->array_import_label[0];
|
print $objimport->array_import_label[0];
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
print '</table>';
|
print '</table>';
|
||||||
print '<br>'."\n";
|
|
||||||
|
dol_fiche_end();
|
||||||
|
|
||||||
|
|
||||||
print '<form name="userfile" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" METHOD="POST">';
|
print '<form name="userfile" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" METHOD="POST">';
|
||||||
@ -463,9 +459,6 @@ if ($step == 2 && $datatoimport)
|
|||||||
}
|
}
|
||||||
|
|
||||||
print '</table></form>';
|
print '</table></form>';
|
||||||
|
|
||||||
dol_fiche_end();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -498,7 +491,7 @@ if ($step == 3 && $datatoimport)
|
|||||||
print '<table width="100%" class="border">';
|
print '<table width="100%" class="border">';
|
||||||
|
|
||||||
// Module
|
// Module
|
||||||
print '<tr><td width="25%">'.$langs->trans("Module").'</td>';
|
print '<tr><td class="titlefield">'.$langs->trans("Module").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
$titleofmodule=$objimport->array_import_module[0]->getName();
|
$titleofmodule=$objimport->array_import_module[0]->getName();
|
||||||
// Special cas for import common to module/services
|
// Special cas for import common to module/services
|
||||||
@ -507,7 +500,7 @@ if ($step == 3 && $datatoimport)
|
|||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Lot de donnees a importer
|
// Lot de donnees a importer
|
||||||
print '<tr><td width="25%">'.$langs->trans("DatasetToImport").'</td>';
|
print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
print img_object($objimport->array_import_module[0]->getName(),$objimport->array_import_icon[0]).' ';
|
print img_object($objimport->array_import_module[0]->getName(),$objimport->array_import_icon[0]).' ';
|
||||||
print $objimport->array_import_label[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>';
|
//print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnSourceFile").'</b></td></tr>';
|
||||||
|
|
||||||
// Source file format
|
// Source file format
|
||||||
print '<tr><td width="25%">'.$langs->trans("SourceFileFormat").'</td>';
|
print '<tr><td class="titlefield">'.$langs->trans("SourceFileFormat").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
$text=$objmodelimport->getDriverDescForKey($format);
|
$text=$objmodelimport->getDriverDescForKey($format);
|
||||||
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
|
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
|
||||||
@ -528,8 +521,10 @@ if ($step == 3 && $datatoimport)
|
|||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
print '</table>';
|
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 '<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="token" value="'.$_SESSION['newtoken'].'">';
|
||||||
@ -542,7 +537,7 @@ if ($step == 3 && $datatoimport)
|
|||||||
|
|
||||||
print '<tr><td colspan="6">'.$langs->trans("ChooseFileToImport",img_picto('','filenew')).'</td></tr>';
|
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
|
// Input file name box
|
||||||
$var=false;
|
$var=false;
|
||||||
@ -602,8 +597,6 @@ if ($step == 3 && $datatoimport)
|
|||||||
}
|
}
|
||||||
|
|
||||||
print '</table></form>';
|
print '</table></form>';
|
||||||
|
|
||||||
dol_fiche_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -719,7 +712,7 @@ if ($step == 4 && $datatoimport)
|
|||||||
print '<table width="100%" class="border">';
|
print '<table width="100%" class="border">';
|
||||||
|
|
||||||
// Module
|
// Module
|
||||||
print '<tr><td width="25%">'.$langs->trans("Module").'</td>';
|
print '<tr><td class="titlefield">'.$langs->trans("Module").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
$titleofmodule=$objimport->array_import_module[0]->getName();
|
$titleofmodule=$objimport->array_import_module[0]->getName();
|
||||||
// Special cas for import common to module/services
|
// Special cas for import common to module/services
|
||||||
@ -728,7 +721,7 @@ if ($step == 4 && $datatoimport)
|
|||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// Lot de donnees a importer
|
// Lot de donnees a importer
|
||||||
print '<tr><td width="25%">'.$langs->trans("DatasetToImport").'</td>';
|
print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
print img_object($objimport->array_import_module[0]->getName(),$objimport->array_import_icon[0]).' ';
|
print img_object($objimport->array_import_module[0]->getName(),$objimport->array_import_icon[0]).' ';
|
||||||
print $objimport->array_import_label[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>';
|
//print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnSourceFile").'</b></td></tr>';
|
||||||
|
|
||||||
// Source file format
|
// Source file format
|
||||||
print '<tr><td width="25%">'.$langs->trans("SourceFileFormat").'</td>';
|
print '<tr><td class="titlefield">'.$langs->trans("SourceFileFormat").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
$text=$objmodelimport->getDriverDescForKey($format);
|
$text=$objmodelimport->getDriverDescForKey($format);
|
||||||
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
|
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
|
||||||
@ -748,7 +741,7 @@ if ($step == 4 && $datatoimport)
|
|||||||
|
|
||||||
// Separator and enclosure
|
// Separator and enclosure
|
||||||
if ($model == 'csv') {
|
if ($model == 'csv') {
|
||||||
print '<tr><td width="25%">'.$langs->trans("CsvOptions").'</td>';
|
print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
print '<form>';
|
print '<form>';
|
||||||
print '<input type="hidden" value="'.$step.'" name="step">';
|
print '<input type="hidden" value="'.$step.'" name="step">';
|
||||||
@ -767,7 +760,7 @@ if ($step == 4 && $datatoimport)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// File to import
|
// File to import
|
||||||
print '<tr><td width="25%">'.$langs->trans("FileToImport").'</td>';
|
print '<tr><td>'.$langs->trans("FileToImport").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
$modulepart='import';
|
$modulepart='import';
|
||||||
$relativepath=GETPOST('filetoimport');
|
$relativepath=GETPOST('filetoimport');
|
||||||
@ -777,6 +770,9 @@ if ($step == 4 && $datatoimport)
|
|||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
||||||
print '</table>';
|
print '</table>';
|
||||||
|
|
||||||
|
dol_fiche_end();
|
||||||
|
|
||||||
print '<br>'."\n";
|
print '<br>'."\n";
|
||||||
|
|
||||||
|
|
||||||
@ -801,7 +797,7 @@ if ($step == 4 && $datatoimport)
|
|||||||
print '</form>';
|
print '</form>';
|
||||||
|
|
||||||
// Title of array with fields
|
// Title of array with fields
|
||||||
print '<table class="nobordernopadding" width="100%">';
|
print '<table class="noborder" width="100%">';
|
||||||
print '<tr class="liste_titre">';
|
print '<tr class="liste_titre">';
|
||||||
print '<td>'.$langs->trans("FieldsInSourceFile").'</td>';
|
print '<td>'.$langs->trans("FieldsInSourceFile").'</td>';
|
||||||
print '<td>'.$langs->trans("FieldsInTargetDatabase").'</td>';
|
print '<td>'.$langs->trans("FieldsInTargetDatabase").'</td>';
|
||||||
@ -999,8 +995,6 @@ if ($step == 4 && $datatoimport)
|
|||||||
|
|
||||||
print '</table>';
|
print '</table>';
|
||||||
|
|
||||||
dol_fiche_end();
|
|
||||||
|
|
||||||
|
|
||||||
if ($conf->use_javascript_ajax)
|
if ($conf->use_javascript_ajax)
|
||||||
{
|
{
|
||||||
@ -1183,7 +1177,7 @@ if ($step == 5 && $datatoimport)
|
|||||||
print '<table width="100%" class="border">';
|
print '<table width="100%" class="border">';
|
||||||
|
|
||||||
// Module
|
// Module
|
||||||
print '<tr><td width="25%">'.$langs->trans("Module").'</td>';
|
print '<tr><td class="titlefield">'.$langs->trans("Module").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
$titleofmodule=$objimport->array_import_module[0]->getName();
|
$titleofmodule=$objimport->array_import_module[0]->getName();
|
||||||
// Special cas for import common to module/services
|
// 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>';
|
//print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnSourceFile").'</b></td></tr>';
|
||||||
|
|
||||||
// Source file format
|
// Source file format
|
||||||
print '<tr><td width="25%">'.$langs->trans("SourceFileFormat").'</td>';
|
print '<tr><td class="titlefield">'.$langs->trans("SourceFileFormat").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
$text=$objmodelimport->getDriverDescForKey($format);
|
$text=$objmodelimport->getDriverDescForKey($format);
|
||||||
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
|
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
|
||||||
@ -1212,7 +1206,7 @@ if ($step == 5 && $datatoimport)
|
|||||||
|
|
||||||
// Separator and enclosure
|
// Separator and enclosure
|
||||||
if ($model == 'csv') {
|
if ($model == 'csv') {
|
||||||
print '<tr><td width="25%">'.$langs->trans("CsvOptions").'</td>';
|
print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
print $langs->trans("Separator").' : ';
|
print $langs->trans("Separator").' : ';
|
||||||
print htmlentities($separator);
|
print htmlentities($separator);
|
||||||
@ -1441,8 +1435,8 @@ if ($step == 5 && $datatoimport)
|
|||||||
$db->rollback(); // We force rollback because this was just a simulation.
|
$db->rollback(); // We force rollback because this was just a simulation.
|
||||||
|
|
||||||
// Show OK
|
// Show OK
|
||||||
if (! count($arrayoferrors) && ! count($arrayofwarnings)) print img_picto($langs->trans("OK"),'tick').' <b>'.$langs->trans("NoError").'</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 $langs->trans("NbOfLinesOK",$nbok).'</b><br><br>';
|
else print '<b>'.$langs->trans("NbOfLinesOK",$nbok).'</b><br><br>';
|
||||||
|
|
||||||
// Show Errors
|
// Show Errors
|
||||||
//var_dump($arrayoferrors);
|
//var_dump($arrayoferrors);
|
||||||
@ -1585,7 +1579,7 @@ if ($step == 6 && $datatoimport)
|
|||||||
print '<table width="100%" class="border">';
|
print '<table width="100%" class="border">';
|
||||||
|
|
||||||
// Module
|
// Module
|
||||||
print '<tr><td width="25%">'.$langs->trans("Module").'</td>';
|
print '<tr><td class="titlefield">'.$langs->trans("Module").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
$titleofmodule=$objimport->array_import_module[0]->getName();
|
$titleofmodule=$objimport->array_import_module[0]->getName();
|
||||||
// Special cas for import common to module/services
|
// 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>';
|
//print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnSourceFile").'</b></td></tr>';
|
||||||
|
|
||||||
// Source file format
|
// Source file format
|
||||||
print '<tr><td width="25%">'.$langs->trans("SourceFileFormat").'</td>';
|
print '<tr><td class="titlefield">'.$langs->trans("SourceFileFormat").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
$text=$objmodelimport->getDriverDescForKey($format);
|
$text=$objmodelimport->getDriverDescForKey($format);
|
||||||
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
|
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format),$text);
|
||||||
print '</td></tr>';
|
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 ' '.$langs->trans("Enclosure").' : ';
|
||||||
|
print htmlentities($enclosure);
|
||||||
|
print '</td></tr>';
|
||||||
|
}
|
||||||
|
|
||||||
// File to import
|
// File to import
|
||||||
print '<tr><td>'.$langs->trans("FileToImport").'</td>';
|
print '<tr><td>'.$langs->trans("FileToImport").'</td>';
|
||||||
print '<td>';
|
print '<td>';
|
||||||
|
|||||||
@ -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 model_pdf varchar(255);
|
||||||
ALTER TABLE llx_bank_account ADD COLUMN import_key varchar(14);
|
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_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_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
|
create table llx_user_employment
|
||||||
(
|
(
|
||||||
@ -209,6 +215,7 @@ create table llx_user_employment
|
|||||||
)ENGINE=innodb;
|
)ENGINE=innodb;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Sequence to removed duplicated values of llx_links. Use serveral times if you still have duplicate.
|
-- Sequence to removed duplicated values of llx_links. Use serveral times if you still have duplicate.
|
||||||
drop table tmp_links_double;
|
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;
|
--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_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);
|
||||||
|
|||||||
@ -41,5 +41,6 @@ create table llx_projet
|
|||||||
--budget_days real, -- budget in days is sum of field planned_workload of tasks
|
--budget_days real, -- budget in days is sum of field planned_workload of tasks
|
||||||
opp_amount double(24,8),
|
opp_amount double(24,8),
|
||||||
budget_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;
|
)ENGINE=innodb;
|
||||||
|
|||||||
@ -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_projet (fk_projet);
|
||||||
ALTER TABLE llx_projet_task ADD INDEX idx_projet_task_fk_user_creat (fk_user_creat);
|
ALTER TABLE llx_projet_task ADD INDEX idx_projet_task_fk_user_creat (fk_user_creat);
|
||||||
|
|||||||
@ -41,5 +41,6 @@ create table llx_projet_task
|
|||||||
note_private text,
|
note_private text,
|
||||||
note_public text,
|
note_public text,
|
||||||
rang integer DEFAULT 0,
|
rang integer DEFAULT 0,
|
||||||
model_pdf varchar(255)
|
model_pdf varchar(255),
|
||||||
|
import_key varchar(14) -- Import key
|
||||||
)ENGINE=innodb;
|
)ENGINE=innodb;
|
||||||
|
|||||||
@ -28,5 +28,6 @@ create table llx_projet_task_time
|
|||||||
thm double(24,8),
|
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_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
|
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;
|
)ENGINE=innodb;
|
||||||
|
|||||||
@ -200,7 +200,7 @@ BasedOnTwoFirstLettersOfVATNumberBeingDifferentFromYourCompanyCountry=Based on t
|
|||||||
SameCountryCustomersWithVAT=National customers report
|
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
|
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
|
LinkedFichinter=Link to an intervention
|
||||||
ImportDataset_tax_contrib=Import social/fiscal taxes
|
ImportDataset_tax_contrib=Social/fiscal taxes
|
||||||
ImportDataset_tax_vat=Import vat payments
|
ImportDataset_tax_vat=Vat payments
|
||||||
ErrorBankAccountNotFound=Error: Bank account not found
|
ErrorBankAccountNotFound=Error: Bank account not found
|
||||||
FiscalPeriod=Accounting period
|
FiscalPeriod=Accounting period
|
||||||
|
|||||||
@ -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).
|
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.
|
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.
|
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
|
NewProject=New project
|
||||||
AddProject=Create project
|
AddProject=Create project
|
||||||
DeleteAProject=Delete a project
|
DeleteAProject=Delete a project
|
||||||
|
|||||||
@ -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="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>';
|
print $langs->trans("AssignTaskToMe").'<br>';
|
||||||
$formproject->selectTasks($socid?$socid:-1, $taskid, 'taskid', 32, 0, 1, 1);
|
$formproject->selectTasks($socid?$socid:-1, $taskid, 'taskid', 32, 0, 1, 1);
|
||||||
print $formcompany->selectTypeContact($object, '', 'type','internal','rowid', 0);
|
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 '</form>';
|
||||||
print '</div>';
|
print '</div>';
|
||||||
|
|
||||||
|
|||||||
@ -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="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>';
|
print $langs->trans("AssignTaskToMe").'<br>';
|
||||||
$formproject->selectTasks($socid?$socid:-1, $taskid, 'taskid', 32, 0, 1, 1);
|
$formproject->selectTasks($socid?$socid:-1, $taskid, 'taskid', 32, 0, 1, 1);
|
||||||
print $formcompany->selectTypeContact($object, '', 'type','internal','rowid', 0);
|
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 '</form>';
|
||||||
print '</div>';
|
print '</div>';
|
||||||
|
|
||||||
|
|||||||
@ -615,7 +615,7 @@ if ($action == 'create' && $user->rights->projet->creer)
|
|||||||
});
|
});
|
||||||
</script>';
|
</script>';
|
||||||
}
|
}
|
||||||
else
|
elseif ($object->id > 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Show or edit
|
* Show or edit
|
||||||
@ -1127,6 +1127,10 @@ else
|
|||||||
$parameters=array();
|
$parameters=array();
|
||||||
$reshook=$hookmanager->executeHooks('mainCardTabAddMore',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
|
$reshook=$hookmanager->executeHooks('mainCardTabAddMore',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print $langs->trans("RecordNotFound");
|
||||||
|
}
|
||||||
|
|
||||||
llxFooter();
|
llxFooter();
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,9 @@ class Task extends CommonObject
|
|||||||
{
|
{
|
||||||
public $element='project_task'; //!< Id that identify managed objects
|
public $element='project_task'; //!< Id that identify managed objects
|
||||||
public $table_element='projet_task'; //!< Name of table without prefix where object is stored
|
public $table_element='projet_task'; //!< Name of table without prefix where object is stored
|
||||||
|
public $fk_element='fk_task';
|
||||||
public $picto = 'task';
|
public $picto = 'task';
|
||||||
|
protected $childtables=array('projet_task_time'); // To test if we can delete object
|
||||||
|
|
||||||
var $fk_task_parent;
|
var $fk_task_parent;
|
||||||
var $label;
|
var $label;
|
||||||
@ -383,6 +385,15 @@ class Task extends CommonObject
|
|||||||
$this->db->begin();
|
$this->db->begin();
|
||||||
|
|
||||||
if ($this->hasChildren() > 0)
|
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);
|
dol_syslog(get_class($this)."::delete Can't delete record as it has some child", LOG_WARNING);
|
||||||
$this->error='ErrorRecordHasChildren';
|
$this->error='ErrorRecordHasChildren';
|
||||||
|
|||||||
@ -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';
|
require_once DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.'.php';
|
||||||
$modTask = new $obj;
|
$modTask = new $obj;
|
||||||
$defaultref = $modTask->getNextValue($soc,$object);
|
$defaultref = $modTask->getNextValue($object->thirdparty,null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_numeric($defaultref) && $defaultref <= 0) $defaultref='';
|
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 '</td></tr>';
|
||||||
|
|
||||||
print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td>';
|
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>';
|
print '</td></tr>';
|
||||||
|
|
||||||
// List of projects
|
// List of projects
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user