Merge pull request #13417 from FHenry/dev_tasklist_columnAndExtrafields
NEW : Project task list, add column selector and extrafields
This commit is contained in:
commit
ff549cad18
@ -354,12 +354,13 @@ function project_admin_prepare_head()
|
||||
* @param int $projectidfortotallink 0 or Id of project to use on total line (link to see all time consumed for project)
|
||||
* @param string $filterprogresscalc filter text
|
||||
* @param string $showbilltime Add the column 'TimeToBill' and 'TimeBilled'
|
||||
* @param array $arrayfields Array with displayed coloumn information
|
||||
* @return int Nb of tasks shown
|
||||
*/
|
||||
function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$taskrole, $projectsListId = '', $addordertick = 0, $projectidfortotallink = 0, $filterprogresscalc = '', $showbilltime = 0)
|
||||
function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$taskrole, $projectsListId = '', $addordertick = 0, $projectidfortotallink = 0, $filterprogresscalc = '', $showbilltime = 0, $arrayfields = array())
|
||||
{
|
||||
global $user, $langs, $conf, $db;
|
||||
global $projectstatic, $taskstatic;
|
||||
global $user, $langs, $conf, $db, $hookmanager;
|
||||
global $projectstatic, $taskstatic, $extrafields;
|
||||
|
||||
$lastprojectid = 0;
|
||||
|
||||
@ -375,7 +376,6 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t
|
||||
}
|
||||
$lines = array_values($lines);
|
||||
}
|
||||
|
||||
$numlines = count($lines);
|
||||
|
||||
// We declare counter as global because we want to edit them into recursive call
|
||||
@ -487,44 +487,56 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t
|
||||
}
|
||||
|
||||
// Ref of task
|
||||
print '<td class="nowraponall">';
|
||||
if ($showlineingray)
|
||||
{
|
||||
print '<i>'.img_object('', 'projecttask').' '.$lines[$i]->ref.'</i>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.ref']['checked'])) {
|
||||
print '<td class="nowraponall">';
|
||||
if ($showlineingray) {
|
||||
print '<i>' . img_object('', 'projecttask') . ' ' . $lines[$i]->ref . '</i>';
|
||||
} else {
|
||||
print $taskstatic->getNomUrl(1, 'withproject');
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
else
|
||||
{
|
||||
print $taskstatic->getNomUrl(1, 'withproject');
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
// Title of task
|
||||
print "<td>";
|
||||
if ($showlineingray) print '<i>';
|
||||
//else print '<a href="'.DOL_URL_ROOT.'/projet/tasks/task.php?id='.$lines[$i]->id.'&withproject=1">';
|
||||
for ($k = 0; $k < $level; $k++)
|
||||
{
|
||||
print '<div class="marginleftonly">';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.label']['checked'])) {
|
||||
print "<td>";
|
||||
if ($showlineingray)
|
||||
print '<i>';
|
||||
//else print '<a href="'.DOL_URL_ROOT.'/projet/tasks/task.php?id='.$lines[$i]->id.'&withproject=1">';
|
||||
for ($k = 0; $k < $level; $k++) {
|
||||
print '<div class="marginleftonly">';
|
||||
}
|
||||
print $lines[$i]->label;
|
||||
for ($k = 0; $k < $level; $k++) {
|
||||
print '</div>';
|
||||
}
|
||||
if ($showlineingray)
|
||||
print '</i>';
|
||||
//else print '</a>';
|
||||
print "</td>\n";
|
||||
}
|
||||
print $lines[$i]->label;
|
||||
for ($k = 0; $k < $level; $k++)
|
||||
{
|
||||
print '</div>';
|
||||
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.description']['checked'])) {
|
||||
print "<td>";
|
||||
print $lines[$i]->description;
|
||||
print "</td>\n";
|
||||
}
|
||||
if ($showlineingray) print '</i>';
|
||||
//else print '</a>';
|
||||
print "</td>\n";
|
||||
|
||||
// Date start
|
||||
print '<td class="center">';
|
||||
print dol_print_date($lines[$i]->date_start, 'dayhour');
|
||||
print '</td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.dateo']['checked'])) {
|
||||
print '<td class="center">';
|
||||
print dol_print_date($lines[$i]->date_start, 'dayhour');
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
// Date end
|
||||
print '<td class="center">';
|
||||
print dol_print_date($lines[$i]->date_end, 'dayhour');
|
||||
if ($taskstatic->hasDelay()) print img_warning($langs->trans("Late"));
|
||||
print '</td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.datee']['checked'])) {
|
||||
print '<td class="center">';
|
||||
print dol_print_date($lines[$i]->date_end, 'dayhour');
|
||||
if ($taskstatic->hasDelay())
|
||||
print img_warning($langs->trans("Late"));
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
$plannedworkloadoutputformat = 'allhourmin';
|
||||
$timespentoutputformat = 'allhourmin';
|
||||
@ -532,79 +544,88 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t
|
||||
if (!empty($conf->global->PROJECT_TIMES_SPENT_FORMAT)) $timespentoutputformat = $conf->global->PROJECT_TIME_SPENT_FORMAT;
|
||||
|
||||
// Planned Workload (in working hours)
|
||||
print '<td class="right">';
|
||||
$fullhour = convertSecondToTime($lines[$i]->planned_workload, $plannedworkloadoutputformat);
|
||||
$workingdelay = convertSecondToTime($lines[$i]->planned_workload, 'all', 86400, 7); // TODO Replace 86400 and 7 to take account working hours per day and working day per weeks
|
||||
if ($lines[$i]->planned_workload != '')
|
||||
{
|
||||
print $fullhour;
|
||||
// TODO Add delay taking account of working hours per day and working day per week
|
||||
//if ($workingdelay != $fullhour) print '<br>('.$workingdelay.')';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.planned_workload']['checked'])) {
|
||||
print '<td class="right">';
|
||||
$fullhour = convertSecondToTime($lines[$i]->planned_workload, $plannedworkloadoutputformat);
|
||||
$workingdelay = convertSecondToTime($lines[$i]->planned_workload, 'all', 86400, 7); // TODO Replace 86400 and 7 to take account working hours per day and working day per weeks
|
||||
if ($lines[$i]->planned_workload != '') {
|
||||
print $fullhour;
|
||||
// TODO Add delay taking account of working hours per day and working day per week
|
||||
//if ($workingdelay != $fullhour) print '<br>('.$workingdelay.')';
|
||||
}
|
||||
//else print '--:--';
|
||||
print '</td>';
|
||||
}
|
||||
//else print '--:--';
|
||||
print '</td>';
|
||||
|
||||
// Time spent
|
||||
print '<td class="right">';
|
||||
if ($showlineingray) print '<i>';
|
||||
else print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$lines[$i]->id.($showproject ? '' : '&withproject=1').'">';
|
||||
if ($lines[$i]->duration) print convertSecondToTime($lines[$i]->duration, $timespentoutputformat);
|
||||
else print '--:--';
|
||||
if ($showlineingray) print '</i>';
|
||||
else print '</a>';
|
||||
print '</td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.duration_effective']['checked'])) {
|
||||
print '<td class="right">';
|
||||
if ($showlineingray)
|
||||
print '<i>';
|
||||
else print '<a href="' . DOL_URL_ROOT . '/projet/tasks/time.php?id=' . $lines[$i]->id . ($showproject ? '' : '&withproject=1') . '">';
|
||||
if ($lines[$i]->duration)
|
||||
print convertSecondToTime($lines[$i]->duration, $timespentoutputformat);
|
||||
else print '--:--';
|
||||
if ($showlineingray)
|
||||
print '</i>';
|
||||
else print '</a>';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
// Progress calculated (Note: ->duration is time spent)
|
||||
print '<td class="right">';
|
||||
if ($lines[$i]->planned_workload || $lines[$i]->duration)
|
||||
{
|
||||
if ($lines[$i]->planned_workload) print round(100 * $lines[$i]->duration / $lines[$i]->planned_workload, 2).' %';
|
||||
else print '<span class="opacitymedium">'.$langs->trans('WorkloadNotDefined').'</span>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.progress_calculated']['checked'])) {
|
||||
print '<td class="right">';
|
||||
if ($lines[$i]->planned_workload || $lines[$i]->duration) {
|
||||
if ($lines[$i]->planned_workload)
|
||||
print round(100 * $lines[$i]->duration / $lines[$i]->planned_workload, 2) . ' %';
|
||||
else print '<span class="opacitymedium">' . $langs->trans('WorkloadNotDefined') . '</span>';
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
// Progress declared
|
||||
print '<td class="right">';
|
||||
if ($lines[$i]->progress != '')
|
||||
{
|
||||
print getTaskProgressBadge($taskstatic);
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.progress']['checked'])) {
|
||||
print '<td class="right">';
|
||||
if ($lines[$i]->progress != '') {
|
||||
print getTaskProgressBadge($taskstatic);
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
// resume
|
||||
print '<td class="right">';
|
||||
if ($lines[$i]->progress != '' && $lines[$i]->duration) {
|
||||
print getTaskProgressView($taskstatic, false, false);
|
||||
}
|
||||
print '</td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.progress_summary']['checked'])) {
|
||||
print '<td class="right">';
|
||||
if ($lines[$i]->progress != '' && $lines[$i]->duration) {
|
||||
print getTaskProgressView($taskstatic, false, false);
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
if ($showbilltime)
|
||||
{
|
||||
// Time not billed
|
||||
print '<td class="right">';
|
||||
if ($lines[$i]->usage_bill_time)
|
||||
{
|
||||
print convertSecondToTime($lines[$i]->tobill, 'allhourmin');
|
||||
$total_projectlinesa_tobill += $lines[$i]->tobill;
|
||||
}
|
||||
else
|
||||
{
|
||||
print '<span class="opacitymedium">'.$langs->trans("NA").'</span>';
|
||||
}
|
||||
print '</td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.tobill']['checked'])) {
|
||||
print '<td class="right">';
|
||||
if ($lines[$i]->usage_bill_time) {
|
||||
print convertSecondToTime($lines[$i]->tobill, 'allhourmin');
|
||||
$total_projectlinesa_tobill += $lines[$i]->tobill;
|
||||
} else {
|
||||
print '<span class="opacitymedium">' . $langs->trans("NA") . '</span>';
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
// Time billed
|
||||
print '<td class="right">';
|
||||
if ($lines[$i]->usage_bill_time)
|
||||
{
|
||||
print convertSecondToTime($lines[$i]->billed, 'allhourmin');
|
||||
$total_projectlinesa_billed += $lines[$i]->billed;
|
||||
}
|
||||
else
|
||||
{
|
||||
print '<span class="opacitymedium">'.$langs->trans("NA").'</span>';
|
||||
}
|
||||
print '</td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.billed']['checked'])) {
|
||||
print '<td class="right">';
|
||||
if ($lines[$i]->usage_bill_time) {
|
||||
print convertSecondToTime($lines[$i]->billed, 'allhourmin');
|
||||
$total_projectlinesa_billed += $lines[$i]->billed;
|
||||
} else {
|
||||
print '<span class="opacitymedium">' . $langs->trans("NA") . '</span>';
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
}
|
||||
|
||||
// Contacts of task
|
||||
@ -628,6 +649,15 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
// Extra fields
|
||||
$extrafieldsobjectkey=$taskstatic->table_element;
|
||||
$obj=$lines[$i];
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
|
||||
// Fields from hook
|
||||
$parameters=array('arrayfields'=>$arrayfields, 'obj'=>$lines[$i]);
|
||||
$reshook=$hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
|
||||
print $hookmanager->resPrint;
|
||||
|
||||
// Tick to drag and drop
|
||||
if ($addordertick)
|
||||
{
|
||||
@ -641,7 +671,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t
|
||||
if ($level >= 0) // Call sublevels
|
||||
{
|
||||
$level++;
|
||||
if ($lines[$i]->id) projectLinesa($inc, $lines[$i]->id, $lines, $level, $var, $showproject, $taskrole, $projectsListId, $addordertick, $projectidfortotallink, $filterprogresscalc, $showbilltime);
|
||||
if ($lines[$i]->id) projectLinesa($inc, $lines[$i]->id, $lines, $level, $var, $showproject, $taskrole, $projectsListId, $addordertick, $projectidfortotallink, $filterprogresscalc, $showbilltime, $arrayfields);
|
||||
$level--;
|
||||
}
|
||||
|
||||
@ -663,17 +693,23 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t
|
||||
print '<tr class="liste_total nodrag nodrop">';
|
||||
print '<td class="liste_total">'.$langs->trans("Total").'</td>';
|
||||
if ($showproject) print '<td></td><td></td>';
|
||||
print '<td></td>';
|
||||
print '<td></td>';
|
||||
print '<td></td>';
|
||||
print '<td class="nowrap liste_total right">';
|
||||
print convertSecondToTime($total_projectlinesa_planned, 'allhourmin');
|
||||
print '</td>';
|
||||
print '<td class="nowrap liste_total right">';
|
||||
if ($projectidfortotallink > 0) print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?projectid='.$projectidfortotallink.($showproject ? '' : '&withproject=1').'">';
|
||||
print convertSecondToTime($total_projectlinesa_spent, 'allhourmin');
|
||||
if ($projectidfortotallink > 0) print '</a>';
|
||||
print '</td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.label']['checked'])) print '<td></td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.dateo']['checked'])) print '<td></td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.datee']['checked'])) print '<td></td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.planned_workload']['checked'])) {
|
||||
print '<td class="nowrap liste_total right">';
|
||||
print convertSecondToTime($total_projectlinesa_planned, 'allhourmin');
|
||||
print '</td>';
|
||||
}
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.duration_effective']['checked'])) {
|
||||
print '<td class="nowrap liste_total right">';
|
||||
if ($projectidfortotallink > 0)
|
||||
print '<a href="' . DOL_URL_ROOT . '/projet/tasks/time.php?projectid=' . $projectidfortotallink . ($showproject ? '' : '&withproject=1') . '">';
|
||||
print convertSecondToTime($total_projectlinesa_spent, 'allhourmin');
|
||||
if ($projectidfortotallink > 0)
|
||||
print '</a>';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
if ($total_projectlinesa_planned) {
|
||||
$totalAverageDeclaredProgress = round(100 * $total_projectlinesa_declared_if_planned / $total_projectlinesa_planned, 2);
|
||||
@ -698,33 +734,45 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t
|
||||
}
|
||||
}
|
||||
|
||||
print '<td class="nowrap liste_total right">';
|
||||
if ($total_projectlinesa_planned) print $totalCalculatedProgress.' %';
|
||||
print '</td>';
|
||||
print '<td class="nowrap liste_total right">';
|
||||
if ($total_projectlinesa_planned) print '<span class="'.$badgeClass.'" >'.$totalAverageDeclaredProgress.' %</span>';
|
||||
print '</td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.progress_calculated']['checked'])) {
|
||||
print '<td class="nowrap liste_total right">';
|
||||
if ($total_projectlinesa_planned)
|
||||
print $totalCalculatedProgress . ' %';
|
||||
print '</td>';
|
||||
}
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.progress']['checked'])) {
|
||||
print '<td class="nowrap liste_total right">';
|
||||
if ($total_projectlinesa_planned)
|
||||
print '<span class="' . $badgeClass . '" >' . $totalAverageDeclaredProgress . ' %</span>';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
|
||||
// resume
|
||||
print '<td class="right">';
|
||||
if ($total_projectlinesa_planned) {
|
||||
print '</span>';
|
||||
print ' <div class="progress sm" title="'.$totalAverageDeclaredProgress.'%" >';
|
||||
print ' <div class="progress-bar '.$progressBarClass.'" style="width: '.$totalAverageDeclaredProgress.'%"></div>';
|
||||
print ' </div>';
|
||||
print '</div>';
|
||||
}
|
||||
print '</td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.progress_summary']['checked'])) {
|
||||
print '<td class="right">';
|
||||
if ($total_projectlinesa_planned) {
|
||||
print '</span>';
|
||||
print ' <div class="progress sm" title="' . $totalAverageDeclaredProgress . '%" >';
|
||||
print ' <div class="progress-bar ' . $progressBarClass . '" style="width: ' . $totalAverageDeclaredProgress . '%"></div>';
|
||||
print ' </div>';
|
||||
print '</div>';
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
if ($showbilltime)
|
||||
{
|
||||
print '<td class="nowrap liste_total right">';
|
||||
print convertSecondToTime($total_projectlinesa_tobill, 'allhourmin');
|
||||
print '</td>';
|
||||
print '<td class="nowrap liste_total right">';
|
||||
print convertSecondToTime($total_projectlinesa_billed, 'allhourmin');
|
||||
print '</td>';
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.tobill']['checked'])) {
|
||||
print '<td class="nowrap liste_total right">';
|
||||
print convertSecondToTime($total_projectlinesa_tobill, 'allhourmin');
|
||||
print '</td>';
|
||||
}
|
||||
if (count($arrayfields)>0 && !empty($arrayfields['t.billed']['checked'])) {
|
||||
print '<td class="nowrap liste_total right">';
|
||||
print convertSecondToTime($total_projectlinesa_billed, 'allhourmin');
|
||||
print '</td>';
|
||||
}
|
||||
}
|
||||
// Contacts of task
|
||||
if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST))
|
||||
|
||||
@ -8,6 +8,7 @@ if (empty($conf) || ! is_object($conf))
|
||||
}
|
||||
|
||||
if (empty($extrafieldsobjectkey) && is_object($object)) $extrafieldsobjectkey=$object->table_element;
|
||||
if (!isset($disablesortlink)) $disablesortlink=0;
|
||||
|
||||
// Loop to show all columns of extrafields for the title line
|
||||
if (! empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_element like 'societe', 'socpeople', ...
|
||||
@ -30,7 +31,7 @@ if (! empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_
|
||||
{
|
||||
$tooltip = empty($extrafields->attributes[$extrafieldsobjectkey]['help'][$key]) ? '' : $extrafields->attributes[$extrafieldsobjectkey]['help'][$key];
|
||||
|
||||
print getTitleFieldOfList($extrafields->attributes[$extrafieldsobjectkey]['label'][$key], 0, $_SERVER["PHP_SELF"], $sortonfield, "", $param, ($align?'align="'.$align.'" data-titlekey="'.$key.'"':'data-titlekey="'.$key.'"'), $sortfield, $sortorder, '', 0, $tooltip)."\n";
|
||||
print getTitleFieldOfList($extrafields->attributes[$extrafieldsobjectkey]['label'][$key], 0, $_SERVER["PHP_SELF"], $sortonfield, "", $param, ($align?'align="'.$align.'" data-titlekey="'.$key.'"':'data-titlekey="'.$key.'"'), $sortfield, $sortorder, '', $disablesortlink, $tooltip)."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,3 +266,4 @@ InvoiceToUse=Draft invoice to use
|
||||
NewInvoice=New invoice
|
||||
OneLinePerTask=One line per task
|
||||
OneLinePerPeriod=One line per period
|
||||
RefTaskParent=Ref. Parent Task
|
||||
|
||||
@ -743,11 +743,12 @@ class Task extends CommonObject
|
||||
* @param string $filterontaskuser Filter on user assigned to task
|
||||
* @param array $extrafields Show additional column from project or task
|
||||
* @param int $includebilltime Calculate also the time to bill and billed
|
||||
* @param array $search_array_options Array of search
|
||||
* @return array Array of tasks
|
||||
*/
|
||||
public function getTasksArray($usert = null, $userp = null, $projectid = 0, $socid = 0, $mode = 0, $filteronproj = '', $filteronprojstatus = '-1', $morewherefilter = '', $filteronprojuser = 0, $filterontaskuser = 0, $extrafields = array(), $includebilltime = 0)
|
||||
public function getTasksArray($usert = null, $userp = null, $projectid = 0, $socid = 0, $mode = 0, $filteronproj = '', $filteronprojstatus = '-1', $morewherefilter = '', $filteronprojuser = 0, $filterontaskuser = 0, $extrafields = array(), $includebilltime = 0, $search_array_options = array())
|
||||
{
|
||||
global $conf;
|
||||
global $conf, $hookmanager;
|
||||
|
||||
$tasks = array();
|
||||
|
||||
@ -759,6 +760,7 @@ class Task extends CommonObject
|
||||
$sql .= " p.rowid as projectid, p.ref, p.title as plabel, p.public, p.fk_statut as projectstatus, p.usage_bill_time,";
|
||||
$sql .= " t.rowid as taskid, t.ref as taskref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut as status,";
|
||||
$sql .= " t.dateo as date_start, t.datee as date_end, t.planned_workload, t.rang,";
|
||||
$sql .= " t.description, ";
|
||||
$sql .= " s.rowid as thirdparty_id, s.nom as thirdparty_name, s.email as thirdparty_email,";
|
||||
$sql .= " p.fk_opp_status, p.opp_amount, p.opp_percent, p.budget_amount";
|
||||
if (!empty($extrafields->attributes['projet']['label']))
|
||||
@ -853,12 +855,21 @@ class Task extends CommonObject
|
||||
if ($filteronproj) $sql .= natural_search(array("p.ref", "p.title"), $filteronproj);
|
||||
if ($filteronprojstatus && $filteronprojstatus != '-1') $sql .= " AND p.fk_statut IN (".$filteronprojstatus.")";
|
||||
if ($morewherefilter) $sql .= $morewherefilter;
|
||||
// Add where from extra fields
|
||||
$extrafieldsobjectkey='projet_task';
|
||||
$extrafieldsobjectprefix='efpt.';
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
|
||||
// Add where from hooks
|
||||
$parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
|
||||
$sql .= $hookmanager->resPrint;
|
||||
if ($includebilltime)
|
||||
{
|
||||
$sql .= " GROUP BY p.rowid, p.ref, p.title, p.public, p.fk_statut, p.usage_bill_time,";
|
||||
$sql .= " t.datec, t.dateo, t.datee, t.tms,";
|
||||
$sql .= " t.rowid, t.ref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut,";
|
||||
$sql .= " t.dateo, t.datee, t.planned_workload, t.rang,";
|
||||
$sql .= " t.description, ";
|
||||
$sql .= " s.rowid, s.nom, s.email,";
|
||||
$sql .= " p.fk_opp_status, p.opp_amount, p.opp_percent, p.budget_amount";
|
||||
if (!empty($extrafields->attributes['projet']['label']))
|
||||
@ -871,6 +882,7 @@ class Task extends CommonObject
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$sql .= " ORDER BY p.ref, t.rang, t.dateo";
|
||||
|
||||
//print $sql;exit;
|
||||
|
||||
@ -52,6 +52,7 @@ $cancel = GETPOST('cancel', 'alpha');
|
||||
$search_user_id = GETPOST('search_user_id', 'int');
|
||||
$search_taskref = GETPOST('search_taskref');
|
||||
$search_tasklabel = GETPOST('search_tasklabel');
|
||||
$search_taskdescription=GETPOST('search_taskdescription');
|
||||
$search_dtstartday = GETPOST('search_dtstartday');
|
||||
$search_dtstartmonth = GETPOST('search_dtstartmonth');
|
||||
$search_dtstartyear = GETPOST('search_dtstartyear');
|
||||
@ -63,6 +64,8 @@ $search_timespend = GETPOST('search_timespend');
|
||||
$search_progresscalc = GETPOST('search_progresscalc');
|
||||
$search_progressdeclare = GETPOST('search_progressdeclare');
|
||||
|
||||
$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'projecttasklist';
|
||||
|
||||
//if (! $user->rights->projet->all->lire) $mine=1; // Special for projects
|
||||
|
||||
$object = new Project($db);
|
||||
@ -78,6 +81,7 @@ if ($id > 0 || !empty($ref))
|
||||
$extrafields->fetch_name_optionals_label($object->table_element);
|
||||
}
|
||||
$extrafields->fetch_name_optionals_label($taskstatic->table_element);
|
||||
$search_array_options = $extrafields->getOptionalsFromPost($taskstatic->table_element, '', 'search_');
|
||||
|
||||
// Security check
|
||||
$socid = 0;
|
||||
@ -96,37 +100,36 @@ $planned_workloadhour = (GETPOST('planned_workloadhour', 'int') ?GETPOST('planne
|
||||
$planned_workloadmin = (GETPOST('planned_workloadmin', 'int') ?GETPOST('planned_workloadmin', 'int') : 0);
|
||||
$planned_workload = $planned_workloadhour * 3600 + $planned_workloadmin * 60;
|
||||
|
||||
// Definition of fields for list
|
||||
$arrayfields = array(
|
||||
't.ref'=>array('label'=>$langs->trans("RefTask"), 'checked'=>1, 'position'=>80),
|
||||
't.label'=>array('label'=>$langs->trans("LabelTask"), 'checked'=>1, 'position'=>80),
|
||||
't.dateo'=>array('label'=>$langs->trans("DateStart"), 'checked'=>1, 'position'=>100),
|
||||
't.datee'=>array('label'=>$langs->trans("DateEnd"), 'checked'=>1, 'position'=>101),
|
||||
'p.ref'=>array('label'=>$langs->trans("ProjectRef"), 'checked'=>1),
|
||||
'p.title'=>array('label'=>$langs->trans("ProjectLabel"), 'checked'=>0),
|
||||
's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>0),
|
||||
'p.fk_statut'=>array('label'=>$langs->trans("ProjectStatus"), 'checked'=>1),
|
||||
't.planned_workload'=>array('label'=>$langs->trans("PlannedWorkload"), 'checked'=>1, 'position'=>102),
|
||||
't.duration_effective'=>array('label'=>$langs->trans("TimeSpent"), 'checked'=>1, 'position'=>103),
|
||||
't.progress_calculated'=>array('label'=>$langs->trans("ProgressCalculated"), 'checked'=>1, 'position'=>104),
|
||||
't.progress'=>array('label'=>$langs->trans("ProgressDeclared"), 'checked'=>1, 'position'=>105),
|
||||
't.tobill'=>array('label'=>$langs->trans("TimeToBill"), 'checked'=>0, 'position'=>110),
|
||||
't.billed'=>array('label'=>$langs->trans("TimeBilled"), 'checked'=>0, 'position'=>111),
|
||||
't.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
|
||||
't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
|
||||
//'t.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
|
||||
't.ref'=>array('label'=>$langs->trans("RefTask"), 'checked'=>1, 'position'=>1),
|
||||
't.label'=>array('label'=>$langs->trans("LabelTask"), 'checked'=>1, 'position'=>2),
|
||||
't.description'=>array('label'=>$langs->trans("Description"), 'checked'=>0, 'position'=>3),
|
||||
't.dateo'=>array('label'=>$langs->trans("DateStart"), 'checked'=>1, 'position'=>4),
|
||||
't.datee'=>array('label'=>$langs->trans("DateEnd"), 'checked'=>1, 'position'=>5),
|
||||
't.planned_workload'=>array('label'=>$langs->trans("PlannedWorkload"), 'checked'=>1, 'position'=>6),
|
||||
't.duration_effective'=>array('label'=>$langs->trans("TimeSpent"), 'checked'=>1, 'position'=>7),
|
||||
't.progress_calculated'=>array('label'=>$langs->trans("ProgressCalculated"), 'checked'=>1, 'position'=>8),
|
||||
't.progress'=>array('label'=>$langs->trans("ProgressDeclared"), 'checked'=>1, 'position'=>9),
|
||||
't.progress_summary'=>array('label'=>$langs->trans("TaskProgressSummary"), 'checked'=>1, 'position'=>10),
|
||||
);
|
||||
// Extra fields project
|
||||
if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0)
|
||||
if ($object->usage_bill_time) {
|
||||
$arrayfields['t.tobill']=array('label'=>$langs->trans("TimeToBill"), 'checked'=>0, 'position'=>11);
|
||||
$arrayfields['t.billed']=array('label'=>$langs->trans("TimeBilled"), 'checked'=>0, 'position'=>12);
|
||||
}
|
||||
|
||||
// Extra fields
|
||||
if (is_array($extrafields->attributes[$taskstatic->table_element]['label']) && count($extrafields->attributes[$taskstatic->table_element]['label']) > 0)
|
||||
{
|
||||
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val)
|
||||
foreach ($extrafields->attributes[$taskstatic->table_element]['label'] as $key => $val)
|
||||
{
|
||||
if (!empty($extrafields->attributes[$object->table_element]['list'][$key]))
|
||||
$arrayfields["ef.".$key] = array('label'=>$extrafields->attributes[$object->table_element]['label'][$key], 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]));
|
||||
if (!empty($extrafields->attributes[$taskstatic->table_element]['list'][$key]))
|
||||
$arrayfields["ef.".$key] = array('label'=>$extrafields->attributes[$taskstatic->table_element]['label'][$key], 'checked'=>(($extrafields->attributes[$taskstatic->table_element]['list'][$key] < 0) ? 0 : 1), 'position'=>$extrafields->attributes[$taskstatic->table_element]['pos'][$key], 'enabled'=>(abs($extrafields->attributes[$taskstatic->table_element]['list'][$key]) != 3 && $extrafields->attributes[$taskstatic->table_element]['perms'][$key]));
|
||||
}
|
||||
}
|
||||
$object->fields = dol_sort_array($object->fields, 'position');
|
||||
$arrayfields = dol_sort_array($arrayfields, 'position');
|
||||
|
||||
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
|
||||
|
||||
/*
|
||||
* Actions
|
||||
@ -204,7 +207,6 @@ if (!empty($search_progressdeclare)) {
|
||||
$morewherefilterarray[] = natural_search('t.progress', $search_progressdeclare, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
$morewherefilter = '';
|
||||
if (count($morewherefilterarray) > 0) {
|
||||
$morewherefilter = ' AND '.implode(' AND ', $morewherefilterarray);
|
||||
@ -332,21 +334,18 @@ $projectstatic = new Project($db);
|
||||
$taskstatic = new Task($db);
|
||||
$userstatic = new User($db);
|
||||
|
||||
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
|
||||
$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
|
||||
|
||||
$title = $langs->trans("Project").' - '.$langs->trans("Tasks").' - '.$object->ref.' '.$object->name;
|
||||
if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) $title = $object->ref.' '.$object->name.' - '.$langs->trans("Tasks");
|
||||
$help_url = "EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos";
|
||||
llxHeader("", $title, $help_url);
|
||||
|
||||
|
||||
if ($id > 0 || !empty($ref))
|
||||
{
|
||||
$object->fetch($id, $ref);
|
||||
$object->fetch_thirdparty();
|
||||
$res = $object->fetch_optionals();
|
||||
|
||||
|
||||
// To verify role of users
|
||||
//$userAccess = $object->restrictedProjectArea($user,'read');
|
||||
$userWrite = $object->restrictedProjectArea($user, 'write');
|
||||
@ -359,8 +358,25 @@ if ($id > 0 || !empty($ref))
|
||||
$head = project_prepare_head($object);
|
||||
dol_fiche_head($head, $tab, $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
|
||||
|
||||
$param = '';
|
||||
if ($search_user_id > 0) $param .= '&search_user_id='.dol_escape_htmltag($search_user_id);
|
||||
$param = 'id='.$object->id;
|
||||
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage);
|
||||
if ($search_user_id) $param .= '&search_user_id='.urlencode($search_user_id);
|
||||
if ($search_taskref) $param .= '&search_taskref='.urlencode($search_taskref);
|
||||
if ($search_tasklabel) $param .= '&search_tasklabel='.urlencode($search_tasklabel);
|
||||
if ($search_taskdescription) $param .= '&search_taskdescription='.urlencode($search_taskdescription);
|
||||
if ($search_dtstartday) $param .= '&search_dtstartday='.urlencode($search_dtstartday);
|
||||
if ($search_dtstartmonth) $param .= '&search_dtstartmonth='.urlencode($search_dtstartmonth);
|
||||
if ($search_dtstartyear) $param .= '&search_dtstartyear='.urlencode($search_dtstartyear);
|
||||
if ($search_dtendday) $param .= '&search_dtendday='.urlencode($search_dtendday);
|
||||
if ($search_dtendmonth) $param .= '&search_dtendmonth='.urlencode($search_dtendmonth);
|
||||
if ($search_dtendyear) $param .= '&search_dtendyear='.urlencode($search_dtendyear);
|
||||
if ($search_planedworkload) $param .= '&search_planedworkload='.urlencode($search_planedworkload);
|
||||
if ($search_timespend) $param .= '&search_timespend='.urlencode($search_timespend);
|
||||
if ($search_progresscalc) $param .= '&search_progresscalc='.urlencode($search_progresscalc);
|
||||
if ($search_progressdeclare) $param .= '&search_progressdeclare='.urlencode($search_progressdeclare);
|
||||
if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss);
|
||||
// Add $param from extra fields
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
|
||||
|
||||
// Project card
|
||||
|
||||
@ -425,25 +441,6 @@ if ($id > 0 || !empty($ref))
|
||||
else print $langs->trans('PrivateProject');
|
||||
print '</td></tr>';
|
||||
|
||||
/*if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
|
||||
{
|
||||
// Opportunity status
|
||||
print '<tr><td>'.$langs->trans("OpportunityStatus").'</td><td>';
|
||||
$code = dol_getIdFromCode($db, $object->opp_status, 'c_lead_status', 'rowid', 'code');
|
||||
if ($code) print $langs->trans("OppStatus".$code);
|
||||
print '</td></tr>';
|
||||
|
||||
// Opportunity percent
|
||||
print '<tr><td>'.$langs->trans("OpportunityProbability").'</td><td>';
|
||||
if (strcmp($object->opp_percent,'')) print price($object->opp_percent,'',$langs,1,0).' %';
|
||||
print '</td></tr>';
|
||||
|
||||
// Opportunity Amount
|
||||
print '<tr><td>'.$langs->trans("OpportunityAmount").'</td><td>';
|
||||
if (strcmp($object->opp_amount,'')) print price($object->opp_amount,'',$langs,1,0,0,$conf->currency);
|
||||
print '</td></tr>';
|
||||
}*/
|
||||
|
||||
// Date start - end
|
||||
print '<tr><td>'.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").'</td><td>';
|
||||
$start = dol_print_date($object->date_start, 'day');
|
||||
@ -618,27 +615,12 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third
|
||||
}
|
||||
elseif ($id > 0 || !empty($ref))
|
||||
{
|
||||
$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
|
||||
|
||||
/*
|
||||
* Projet card in view mode
|
||||
*/
|
||||
|
||||
// Definition of fields for list
|
||||
$arrayfields = array();
|
||||
$arrayfields['t.task_ref'] = array('label'=>$langs->trans("RefTask"), 'checked'=>1);
|
||||
$arrayfields['t.task_label'] = array('label'=>$langs->trans("LabelTask"), 'checked'=>1);
|
||||
$arrayfields['t.task_date_start'] = array('label'=>$langs->trans("DateStart"), 'checked'=>1);
|
||||
$arrayfields['t.task_date_end'] = array('label'=>$langs->trans("DateEnd"), 'checked'=>1);
|
||||
// Extra fields
|
||||
if (is_array($extrafields->attributes[$taskstatic->table_element]['label']) && count($extrafields->attributes[$taskstatic->table_element]['label']) > 0)
|
||||
{
|
||||
foreach ($extrafields->attributes[$taskstatic->table_element]['label'] as $key => $val)
|
||||
{
|
||||
if (!empty($extrafields->attributes[$taskstatic->table_element]['list'][$key]))
|
||||
$arrayfields["ef.".$key] = array('label'=>$extrafields->attributes[$taskstatic->table_element]['label'][$key], 'checked'=>(($extrafields->attributes[$taskstatic->table_element]['list'][$key] < 0) ? 0 : 1), 'position'=>$extrafields->attributes[$taskstatic->table_element]['pos'][$key], 'enabled'=>(abs($extrafields->attributes[$taskstatic->table_element]['list'][$key]) != 3 && $extrafields->attributes[$taskstatic->table_element]['perms'][$key]));
|
||||
}
|
||||
}
|
||||
$arrayfields = dol_sort_array($arrayfields, 'position');
|
||||
|
||||
print '<br>';
|
||||
|
||||
// Link to create task
|
||||
@ -654,7 +636,6 @@ elseif ($id > 0 || !empty($ref))
|
||||
|
||||
$linktocreatetask = dolGetButtonTitle($langs->trans('AddTask'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id.'&action=create'.$param.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$object->id), '', $linktocreatetaskUserRight, $linktocreatetaskParam);
|
||||
|
||||
|
||||
print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'">';
|
||||
if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
@ -674,7 +655,7 @@ elseif ($id > 0 || !empty($ref))
|
||||
// Get list of tasks in tasksarray and taskarrayfiltered
|
||||
// We need all tasks (even not limited to a user because a task to user can have a parent that is not affected to him).
|
||||
$filteronthirdpartyid = $socid;
|
||||
$tasksarray = $taskstatic->getTasksArray(0, 0, $object->id, $filteronthirdpartyid, 0, '', -1, $morewherefilter, 0, 0, array(), 1);
|
||||
$tasksarray = $taskstatic->getTasksArray(0, 0, $object->id, $filteronthirdpartyid, 0, '', -1, $morewherefilter, 0, 0, $extrafields, 1, $search_array_options);
|
||||
// We load also tasks limited to a particular user
|
||||
$tmpuser = new User($db);
|
||||
if ($search_user_id > 0) $tmpuser->fetch($search_user_id);
|
||||
@ -704,64 +685,90 @@ elseif ($id > 0 || !empty($ref))
|
||||
print '</div>';
|
||||
}
|
||||
|
||||
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
|
||||
$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
|
||||
|
||||
print '<div class="div-table-responsive">';
|
||||
print '<table id="tablelines" class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">';
|
||||
|
||||
// Fields title search
|
||||
print '<tr class="liste_titre_filter">';
|
||||
|
||||
print '<td class="liste_titre">';
|
||||
print '<input class="flat searchstring maxwidth50" type="text" name="search_taskref" value="'.dol_escape_htmltag($search_taskref).'">';
|
||||
print '</td>';
|
||||
if (!empty($arrayfields['t.ref']['checked'])) {
|
||||
print '<td class="liste_titre">';
|
||||
print '<input class="flat searchstring maxwidth50" type="text" name="search_taskref" value="' . dol_escape_htmltag($search_taskref) . '">';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
print '<td class="liste_titre">';
|
||||
print '<input class="flat searchstring maxwidth100" type="text" name="search_tasklabel" value="'.dol_escape_htmltag($search_tasklabel).'">';
|
||||
print '</td>';
|
||||
if (!empty($arrayfields['t.label']['checked'])) {
|
||||
print '<td class="liste_titre">';
|
||||
print '<input class="flat searchstring maxwidth100" type="text" name="search_tasklabel" value="' . dol_escape_htmltag($search_tasklabel) . '">';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
print '<td class="liste_titre center">';
|
||||
print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_dtstartday" value="'.$search_dtstartday.'">';
|
||||
print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_dtstartmonth" value="'.$search_dtstartmonth.'">';
|
||||
$formother->select_year($search_dtstartyear ? $search_dtstartyear : -1, 'search_dtstartyear', 1, 20, 5);
|
||||
print '</td>';
|
||||
if (!empty($arrayfields['t.description']['checked'])) {
|
||||
print '<td class="liste_titre">';
|
||||
print '<input class="flat searchstring maxwidth100" type="text" name="search_taskdescription" value="' . dol_escape_htmltag($search_taskdescription) . '">';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
print '<td class="liste_titre center">';
|
||||
print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_dtendday" value="'.$search_dtendday.'">';
|
||||
print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_dtendmonth" value="'.$search_dtendmonth.'">';
|
||||
$formother->select_year($search_dtendyear ? $search_dtendyear : -1, 'search_dtendyear', 1, 20, 5);
|
||||
print '</td>';
|
||||
if (!empty($arrayfields['t.dateo']['checked'])) {
|
||||
print '<td class="liste_titre center">';
|
||||
print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_dtstartday" value="' . $search_dtstartday . '">';
|
||||
print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_dtstartmonth" value="' . $search_dtstartmonth . '">';
|
||||
$formother->select_year($search_dtstartyear ? $search_dtstartyear : -1, 'search_dtstartyear', 1, 20, 5);
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
print '<td class="liste_titre right">';
|
||||
print '<input class="flat" type="text" size="4" name="search_planedworkload" value="'.$search_planedworkload.'">';
|
||||
print '</td>';
|
||||
if (!empty($arrayfields['t.datee']['checked'])) {
|
||||
print '<td class="liste_titre center">';
|
||||
print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_dtendday" value="' . $search_dtendday . '">';
|
||||
print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_dtendmonth" value="' . $search_dtendmonth . '">';
|
||||
$formother->select_year($search_dtendyear ? $search_dtendyear : -1, 'search_dtendyear', 1, 20, 5);
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
print '<td class="liste_titre right">';
|
||||
print '<input class="flat" type="text" size="4" name="search_timespend" value="'.$search_timespend.'">';
|
||||
print '</td>';
|
||||
if (!empty($arrayfields['t.planned_workload']['checked'])) {
|
||||
print '<td class="liste_titre right">';
|
||||
print '<input class="flat" type="text" size="4" name="search_planedworkload" value="' . $search_planedworkload . '">';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
print '<td class="liste_titre right">';
|
||||
print '<input class="flat" type="text" size="4" name="search_progresscalc" value="'.$search_progresscalc.'">';
|
||||
print '</td>';
|
||||
if (!empty($arrayfields['t.duration_effective']['checked'])) {
|
||||
print '<td class="liste_titre right">';
|
||||
print '<input class="flat" type="text" size="4" name="search_timespend" value="' . $search_timespend . '">';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
print '<td class="liste_titre right">';
|
||||
print '<input class="flat" type="text" size="4" name="search_progressdeclare" value="'.$search_progressdeclare.'">';
|
||||
print '</td>';
|
||||
if (!empty($arrayfields['t.progress_calculated']['checked'])) {
|
||||
print '<td class="liste_titre right">';
|
||||
print '<input class="flat" type="text" size="4" name="search_progresscalc" value="' . $search_progresscalc . '">';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
if (!empty($arrayfields['t.progress']['checked'])) {
|
||||
print '<td class="liste_titre right">';
|
||||
print '<input class="flat" type="text" size="4" name="search_progressdeclare" value="' . $search_progressdeclare . '">';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
// progress resume not searchable
|
||||
print '<td class="liste_titre right"></td>';
|
||||
|
||||
if ($object->usage_bill_time)
|
||||
{
|
||||
print '<td class="liste_titre right">';
|
||||
print '</td>';
|
||||
if (!empty($arrayfields['t.tobill']['checked'])) {
|
||||
print '<td class="liste_titre right">';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
print '<td class="liste_titre right">';
|
||||
print '</td>';
|
||||
if (!empty($arrayfields['t.billed']['checked'])) {
|
||||
print '<td class="liste_titre right">';
|
||||
print '</td>';
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) print '<td></td>';
|
||||
if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) print '<td class="liste_titre"></td>';
|
||||
|
||||
$extrafieldsobjectkey=$taskstatic->table_element;
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
|
||||
|
||||
// Action column
|
||||
print '<td class="liste_titre maxwidthsearch">';
|
||||
@ -772,29 +779,37 @@ elseif ($id > 0 || !empty($ref))
|
||||
|
||||
print '<tr class="liste_titre nodrag nodrop">';
|
||||
// print '<td>'.$langs->trans("Project").'</td>';
|
||||
print_liste_field_titre("RefTask", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, '');
|
||||
print_liste_field_titre("LabelTask", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, '');
|
||||
print_liste_field_titre("DateStart", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center ');
|
||||
print_liste_field_titre("DateEnd", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center ');
|
||||
print_liste_field_titre("PlannedWorkload", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'right ');
|
||||
print_liste_field_titre("TimeSpent", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'right ');
|
||||
print_liste_field_titre("ProgressCalculated", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'right ');
|
||||
print_liste_field_titre("ProgressDeclared", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'right ');
|
||||
print_liste_field_titre("TaskProgressSummary", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '');
|
||||
if (!empty($arrayfields['t.label']['checked'])) print_liste_field_titre($arrayfields['t.label']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, '');
|
||||
if (!empty($arrayfields['t.description']['checked'])) print_liste_field_titre($arrayfields['t.description']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, '');
|
||||
if (!empty($arrayfields['t.dateo']['checked'])) print_liste_field_titre($arrayfields['t.dateo']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.datee']['checked'])) print_liste_field_titre($arrayfields['t.datee']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.planned_workload']['checked'])) print_liste_field_titre($arrayfields['t.planned_workload']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
|
||||
if (!empty($arrayfields['t.duration_effective']['checked'])) print_liste_field_titre($arrayfields['t.duration_effective']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
|
||||
if (!empty($arrayfields['t.progress_calculated']['checked'])) print_liste_field_titre($arrayfields['t.progress_calculated']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
|
||||
if (!empty($arrayfields['t.progress']['checked'])) print_liste_field_titre($arrayfields['t.progress']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
|
||||
if (!empty($arrayfields['t.progress_summary']['checked'])) print_liste_field_titre($arrayfields['t.progress_summary']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ');
|
||||
if ($object->usage_bill_time)
|
||||
{
|
||||
print_liste_field_titre("TimeToBill", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'right ');
|
||||
print_liste_field_titre("TimeBilled", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'right ');
|
||||
if (!empty($arrayfields['t.tobill']['checked'])) print_liste_field_titre($arrayfields['t.tobill']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
|
||||
if (!empty($arrayfields['t.billed']['checked'])) print_liste_field_titre($arrayfields['t.billed']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
|
||||
}
|
||||
if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) print_liste_field_titre("TaskRessourceLinks", $_SERVER["PHP_SELF"], '', '', '', $sortfield, $sortorder);
|
||||
print_liste_field_titre('', $_SERVER["PHP_SELF"], "", '', '', 'width="80"', $sortfield, $sortorder, 'center maxwidthsearch ');
|
||||
if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) print_liste_field_titre("TaskRessourceLinks", $_SERVER["PHP_SELF"], '', '', $param, $sortfield, $sortorder);
|
||||
// Extra fields
|
||||
$disablesortlink=1;
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
|
||||
// Hook fields
|
||||
$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
|
||||
$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
|
||||
print $hookmanager->resPrint;
|
||||
print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
|
||||
print "</tr>\n";
|
||||
|
||||
if (count($tasksarray) > 0)
|
||||
{
|
||||
// Show all lines in taskarray (recursive function to go down on tree)
|
||||
$j = 0; $level = 0;
|
||||
$nboftaskshown = projectLinesa($j, 0, $tasksarray, $level, true, 0, $tasksrole, $object->id, 1, $object->id, $filterprogresscalc, ($object->usage_bill_time ? 1 : 0));
|
||||
$nboftaskshown = projectLinesa($j, 0, $tasksarray, $level, true, 0, $tasksrole, $object->id, 1, $object->id, $filterprogresscalc, ($object->usage_bill_time ? 1 : 0), $arrayfields);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -56,6 +56,7 @@ $search_project_title = GETPOST('search_project_title');
|
||||
$search_task_ref = GETPOST('search_task_ref');
|
||||
$search_task_label = GETPOST('search_task_label');
|
||||
$search_task_description = GETPOST('search_task_description');
|
||||
$search_task_ref_parent = GETPOST('search_task_ref_parent');
|
||||
$search_project_user = GETPOST('search_project_user');
|
||||
$search_task_user = GETPOST('search_task_user');
|
||||
|
||||
@ -109,8 +110,10 @@ $fieldstosearchall = array(
|
||||
if (empty($user->socid)) $fieldstosearchall['t.note_private'] = "NotePrivate";
|
||||
|
||||
$arrayfields = array(
|
||||
't.fk_task_parent'=>array('label'=>$langs->trans("RefTaskParent"), 'checked'=>0, 'position'=>70),
|
||||
't.ref'=>array('label'=>$langs->trans("RefTask"), 'checked'=>1, 'position'=>80),
|
||||
't.label'=>array('label'=>$langs->trans("LabelTask"), 'checked'=>1, 'position'=>80),
|
||||
't.description'=>array('label'=>$langs->trans("Description"), 'checked'=>0, 'position'=>80),
|
||||
't.dateo'=>array('label'=>$langs->trans("DateStart"), 'checked'=>1, 'position'=>100),
|
||||
't.datee'=>array('label'=>$langs->trans("DateEnd"), 'checked'=>1, 'position'=>101),
|
||||
'p.ref'=>array('label'=>$langs->trans("ProjectRef"), 'checked'=>1),
|
||||
@ -169,6 +172,7 @@ if (empty($reshook))
|
||||
$search_task_ref = "";
|
||||
$search_task_label = "";
|
||||
$search_task_description = "";
|
||||
$search_task_ref_parent = "";
|
||||
$search_task_user = -1;
|
||||
$search_project_user = -1;
|
||||
$search_sday = '';
|
||||
@ -262,7 +266,8 @@ $distinct = 'DISTINCT'; // We add distinct until we are added a protection to be
|
||||
$sql = "SELECT ".$distinct." p.rowid as projectid, p.ref as projectref, p.title as projecttitle, p.fk_statut as projectstatus, p.datee as projectdatee, p.fk_opp_status, p.public, p.fk_user_creat as projectusercreate, p.usage_bill_time,";
|
||||
$sql .= " s.nom as name, s.rowid as socid,";
|
||||
$sql .= " t.datec as date_creation, t.dateo as date_start, t.datee as date_end, t.tms as date_update,";
|
||||
$sql .= " t.rowid as id, t.ref, t.label, t.planned_workload, t.duration_effective, t.progress, t.fk_statut";
|
||||
$sql .= " t.rowid as id, t.ref, t.label, t.planned_workload, t.duration_effective, t.progress, t.fk_statut, ";
|
||||
$sql .= " t.description, t.fk_task_parent";
|
||||
// We'll need these fields in order to filter by categ
|
||||
if ($search_categ) $sql .= ", cs.fk_categorie, cs.fk_project";
|
||||
// Add sum fields
|
||||
@ -302,6 +307,8 @@ if ($search_project_ref) $sql .= natural_search('p.ref', $search_project_ref);
|
||||
if ($search_project_title) $sql .= natural_search('p.title', $search_project_title);
|
||||
if ($search_task_ref) $sql .= natural_search('t.ref', $search_task_ref);
|
||||
if ($search_task_label) $sql .= natural_search('t.label', $search_task_label);
|
||||
if ($search_task_description) $sql .= natural_search('t.description', $search_task_description);
|
||||
if ($search_task_ref_parent) $sql .= ' AND t.fk_task_parent IN (SELECT ipt.rowid FROM '.MAIN_DB_PREFIX.'projet_task as ipt WHERE '.natural_search('ipt.ref', $search_task_ref_parent, 0, 1).')';
|
||||
if ($search_societe) $sql .= natural_search('s.nom', $search_societe);
|
||||
$sql .= dolSqlDateFilter('t.dateo', $search_sday, $search_smonth, $search_syear);
|
||||
$sql .= dolSqlDateFilter('t.datee', $search_eday, $search_emonth, $search_eyear);
|
||||
@ -385,8 +392,10 @@ if ($socid) $param .= '&socid='.urlencode($socid);
|
||||
if ($search_all != '') $param .= '&search_all='.urlencode($search_all);
|
||||
if ($search_project_ref != '') $param .= '&search_project_ref='.urlencode($search_project_ref);
|
||||
if ($search_project_title != '') $param .= '&search_project_title='.urlencode($search_project_title);
|
||||
if ($search_ref != '') $param .= '&search_ref='.urlencode($search_ref);
|
||||
if ($search_label != '') $param .= '&search_label='.urlencode($search_label);
|
||||
if ($search_task_ref != '') $param .= '&search_task_ref='.urlencode($search_ref);
|
||||
if ($search_task_label != '') $param .= '&search_task_label='.urlencode($search_label);
|
||||
if ($search_task_description != '') $param .= '&search_task_description='.urlencode($search_description);
|
||||
if ($search_task_ref_parent != '') $param .= '&search_task_ref_parent='.urlencode($search_task_ref_parent);
|
||||
if ($search_societe != '') $param .= '&search_societe='.urlencode($search_societe);
|
||||
if ($search_projectstatus != '') $param .= '&search_projectstatus='.urlencode($search_projectstatus);
|
||||
if ((is_numeric($search_opp_status) && $search_opp_status >= 0) || in_array($search_opp_status, array('all', 'none'))) $param .= '&search_opp_status='.urlencode($search_opp_status);
|
||||
@ -491,6 +500,12 @@ print '<div class="div-table-responsive">';
|
||||
print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'" id="tablelines3">'."\n";
|
||||
|
||||
print '<tr class="liste_titre_filter">';
|
||||
if (!empty($arrayfields['t.fk_task_parent']['checked']))
|
||||
{
|
||||
print '<td class="liste_titre">';
|
||||
print '<input type="text" class="flat" name="search_task_ref_parent" value="'.dol_escape_htmltag($search_task_ref_parent).'" size="4">';
|
||||
print '</td>';
|
||||
}
|
||||
if (!empty($arrayfields['t.ref']['checked']))
|
||||
{
|
||||
print '<td class="liste_titre">';
|
||||
@ -503,6 +518,13 @@ if (!empty($arrayfields['t.label']['checked']))
|
||||
print '<input type="text" class="flat" name="search_task_label" value="'.dol_escape_htmltag($search_task_label).'" size="8">';
|
||||
print '</td>';
|
||||
}
|
||||
//Task Description
|
||||
if (!empty($arrayfields['t.description']['checked']))
|
||||
{
|
||||
print '<td class="liste_titre">';
|
||||
print '<input type="text" class="flat" name="search_task_description" value="'.dol_escape_htmltag($search_task_description).'" size="8">';
|
||||
print '</td>';
|
||||
}
|
||||
// Start date
|
||||
if (!empty($arrayfields['t.dateo']['checked']))
|
||||
{
|
||||
@ -581,17 +603,19 @@ print '</td>';
|
||||
print "</tr>\n";
|
||||
|
||||
print '<tr class="liste_titre">';
|
||||
if (!empty($arrayfields['t.fk_task_parent']['checked'])) print_liste_field_titre($arrayfields['t.fk_task_parent']['label'], $_SERVER["PHP_SELF"], "t.fk_task_parent", "", $param, "", $sortfield, $sortorder);
|
||||
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['t.label']['checked'])) print_liste_field_titre($arrayfields['t.label']['label'], $_SERVER["PHP_SELF"], "t.label", "", $param, "", $sortfield, $sortorder);
|
||||
if (!empty($arrayfields['t.dateo']['checked'])) print_liste_field_titre($arrayfields['t.dateo']['label'], $_SERVER["PHP_SELF"], "t.dateo", "", $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.description']['checked'])) print_liste_field_titre($arrayfields['t.description']['label'], $_SERVER["PHP_SELF"], "t.description", "", $param, "", $sortfield, $sortorder);
|
||||
if (!empty($arrayfields['t.dateo']['checked'])) print_liste_field_titre($arrayfields['t.dateo']['label'], $_SERVER["PHP_SELF"], "t.dateo", "", $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.datee']['checked'])) print_liste_field_titre($arrayfields['t.datee']['label'], $_SERVER["PHP_SELF"], "t.datee", "", $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"], "p.ref", "", $param, "", $sortfield, $sortorder);
|
||||
if (!empty($arrayfields['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'], $_SERVER["PHP_SELF"], "p.title", "", $param, "", $sortfield, $sortorder);
|
||||
if (!empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"], "s.nom", "", $param, "", $sortfield, $sortorder);
|
||||
if (!empty($arrayfields['p.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'], $_SERVER["PHP_SELF"], "p.fk_statut", "", $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.planned_workload']['checked'])) print_liste_field_titre($arrayfields['t.planned_workload']['label'], $_SERVER["PHP_SELF"], "t.planned_workload", "", $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.duration_effective']['checked'])) print_liste_field_titre($arrayfields['t.duration_effective']['label'], $_SERVER["PHP_SELF"], "t.duration_effective", "", $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.progress_calculated']['checked'])) print_liste_field_titre($arrayfields['t.progress_calculated']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'center ');
|
||||
if (!empty($arrayfields['t.planned_workload']['checked'])) print_liste_field_titre($arrayfields['t.planned_workload']['label'], $_SERVER["PHP_SELF"], "t.planned_workload", "", $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.duration_effective']['checked'])) print_liste_field_titre($arrayfields['t.duration_effective']['label'], $_SERVER["PHP_SELF"], "t.duration_effective", "", $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.progress_calculated']['checked'])) print_liste_field_titre($arrayfields['t.progress_calculated']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'center ');
|
||||
if (!empty($arrayfields['t.progress']['checked'])) print_liste_field_titre($arrayfields['t.progress']['label'], $_SERVER["PHP_SELF"], "t.progress", "", $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.progress_summary']['checked'])) print_liste_field_titre($arrayfields['t.progress_summary']['label'], $_SERVER["PHP_SELF"], "t.progress", "", $param, '', $sortfield, $sortorder, 'center ');
|
||||
if (!empty($arrayfields['t.tobill']['checked'])) print_liste_field_titre($arrayfields['t.tobill']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'center ');
|
||||
@ -622,12 +646,14 @@ while ($i < min($num, $limit))
|
||||
$object->id = $obj->id;
|
||||
$object->ref = $obj->ref;
|
||||
$object->label = $obj->label;
|
||||
$object->description = $obj->description;
|
||||
$object->fk_statut = $obj->fk_statut;
|
||||
$object->progress = $obj->progress;
|
||||
$object->datee = $db->jdate($obj->date_end); // deprecated
|
||||
$object->date_end = $db->jdate($obj->date_end);
|
||||
$object->planned_workload = $obj->planned_workload;
|
||||
$object->duration_effective = $obj->duration_effective;
|
||||
$object->fk_task_parent = $obj->fk_task_parent;
|
||||
|
||||
|
||||
$projectstatic->id = $obj->projectid;
|
||||
@ -642,6 +668,23 @@ while ($i < min($num, $limit))
|
||||
{
|
||||
print '<tr data-rowid="'.$object->id.'" class="oddeven">';
|
||||
|
||||
// Ref Parent
|
||||
if (!empty($arrayfields['t.fk_task_parent']['checked'])) {
|
||||
print '<td class="nowraponall">';
|
||||
if (!empty($object->fk_task_parent)) {
|
||||
$object_parent = new Task($db);
|
||||
$result = $object_parent->fetch($object->fk_task_parent);
|
||||
if ($result < 0) {
|
||||
setEventMessage($object_parent->error, 'errors');
|
||||
} else {
|
||||
print $object_parent->getNomUrl(1, 'withproject');
|
||||
if ($object_parent->hasDelay())
|
||||
print img_warning("Late");
|
||||
}
|
||||
}
|
||||
print '</td>';
|
||||
if (!$i) $totalarray['nbfield']++;
|
||||
}
|
||||
// Ref
|
||||
if (!empty($arrayfields['t.ref']['checked']))
|
||||
{
|
||||
@ -659,6 +702,14 @@ while ($i < min($num, $limit))
|
||||
print '</td>';
|
||||
if (!$i) $totalarray['nbfield']++;
|
||||
}
|
||||
// Description
|
||||
if (!empty($arrayfields['t.description']['checked']))
|
||||
{
|
||||
print '<td>';
|
||||
print $object->description;
|
||||
print '</td>';
|
||||
if (!$i) $totalarray['nbfield']++;
|
||||
}
|
||||
// Date start
|
||||
if (!empty($arrayfields['t.dateo']['checked']))
|
||||
{
|
||||
@ -874,13 +925,11 @@ while ($i < min($num, $limit))
|
||||
|
||||
print "</tr>\n";
|
||||
|
||||
//print projectLinesa();
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
// Show total line
|
||||
//include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
|
||||
if (isset($totalarray['totaldurationeffectivefield']) || isset($totalarray['totalplannedworkloadfield']) || isset($totalarray['totalprogress_calculatedfield'])
|
||||
|| isset($totalarray['totaltobill']) || isset($totalarray['totalbilled']))
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user