From 6733d278d8775cab97e49afb47348c595e00510b Mon Sep 17 00:00:00 2001
From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com>
Date: Tue, 8 Jun 2021 18:13:18 +0200
Subject: [PATCH 1/3] NEW: project time spent: conf to prevent recording time
after X months
---
htdocs/core/lib/project.lib.php | 50 ++++++++++++++++++++++++++----
htdocs/langs/en_US/admin.lang | 1 +
htdocs/langs/en_US/projects.lang | 1 +
htdocs/projet/admin/project.php | 15 +++++++++
htdocs/projet/class/task.class.php | 12 +++++++
5 files changed, 73 insertions(+), 6 deletions(-)
diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php
index aaa1e144202..d48d37a9539 100644
--- a/htdocs/core/lib/project.lib.php
+++ b/htdocs/core/lib/project.lib.php
@@ -1076,6 +1076,13 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr
$oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT) ? 0 : -1); // 0 to start break , -1 no break
}
+ $restrictBefore = null;
+
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+ }
+
//dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
for ($i = 0; $i < $numlines; $i++)
{
@@ -1307,6 +1314,10 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr
$disabledtask = 1;
}
+ if ($restrictBefore && $preselectedday < $restrictBefore) {
+ $disabledtask = 1;
+ }
+
// Form to add new time
print '
';
$tableCell = $form->selectDate($preselectedday, $lines[$i]->id, 1, 1, 2, "addtime", 0, 0, $disabledtask);
@@ -1451,6 +1462,13 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$
$oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT) ? 0 : -1); // 0 = start break, -1 = never break
}
+ $restrictBefore = null;
+
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+ }
+
for ($i = 0; $i < $numlines; $i++)
{
if ($parent == 0) $level = 0;
@@ -1708,6 +1726,12 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$
$cssweekend = 'weekend';
}
+ $disabledtaskday = $disabledtask;
+
+ if (! $disabledtask && $restrictBefore && $tmpday < $restrictBefore) {
+ $disabledtaskday = 1;
+ }
+
$tableCell = ' ';
//$tableCell .= 'idw='.$idw.' '.$conf->global->MAIN_START_WEEK.' '.$numstartworkingday.'-'.$numendworkingday;
$placeholder = '';
@@ -1717,7 +1741,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$
//$placeholder=' placeholder="00:00"';
//$tableCell.='+';
}
- $tableCell .= ' ';
@@ -1812,6 +1836,13 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
$oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT) ? 0 : -1); // 0 = start break, -1 = never break
}
+ $restrictBefore = null;
+
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+ }
+
for ($i = 0; $i < $numlines; $i++)
{
if ($parent == 0) $level = 0;
@@ -1954,10 +1985,11 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
$tableCell = ''; $modeinput = 'hours';
$TFirstDay = getFirstDayOfEachWeek($TWeek, date('Y', $firstdaytoshow));
$TFirstDay[reset($TWeek)] = 1;
- foreach ($TFirstDay as &$fday) {
- $fday--;
- }
- foreach ($TWeek as $weekNb)
+
+ $firstdaytoshowarray = dol_getdate($firstdaytoshow);
+ $year = $firstdaytoshowarray['year'];
+ $month = $firstdaytoshowarray['mon'];
+ foreach ($TWeek as $weekIndex => $weekNb)
{
$weekWorkLoad = $projectstatic->monthWorkLoadPerTask[$weekNb][$lines[$i]->id];
$totalforeachweek[$weekNb] += $weekWorkLoad;
@@ -1966,6 +1998,12 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
if ($weekWorkLoad > 0) $alreadyspent = convertSecondToTime($weekWorkLoad, 'allhourmin');
$alttitle = $langs->trans("AddHereTimeSpentForWeek", $weekNb);
+ $disabledtaskweek = $disabledtask;
+ $firstdayofweek = dol_mktime(0, 0, 0, $month, $TFirstDay[$weekIndex], $year);
+
+ if (! $disabledtask && $restrictBefore && $firstdayofweek < $restrictBefore) {
+ $disabledtaskweek = 1;
+ }
$tableCell = ' ';
$placeholder = '';
@@ -1976,7 +2014,7 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
//$tableCell.='+';
}
- $tableCell .= ' ';
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index f5770bad737..446f01a5446 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -81,6 +81,7 @@ NumberOfBytes=Number of Bytes
SearchString=Search string
NotAvailableWhenAjaxDisabled=Not available when Ajax disabled
AllowToSelectProjectFromOtherCompany=On document of a third party, can choose a project linked to another third party
+TimesheetPreventAfterFollowingMonths=Prevent recording time spent after the following number of months
JavascriptDisabled=JavaScript disabled
UsePreviewTabs=Use preview tabs
ShowPreview=Show preview
diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang
index 2aedbd53377..9fea85e7d1e 100644
--- a/htdocs/langs/en_US/projects.lang
+++ b/htdocs/langs/en_US/projects.lang
@@ -139,6 +139,7 @@ NoTasks=No tasks for this project
LinkedToAnotherCompany=Linked to other third party
TaskIsNotAssignedToUser=Task not assigned to user. Use button '%s ' to assign task now.
ErrorTimeSpentIsEmpty=Time spent is empty
+TimeRecordingRestrictedToNMonthsBack=Time recording is restricted to %s months back
ThisWillAlsoRemoveTasks=This action will also delete all tasks of project (%s tasks at the moment) and all inputs of time spent.
IfNeedToUseOtherObjectKeepEmpty=If some objects (invoice, order, ...), belonging to another third party, must be linked to the project to create, keep this empty to have the project being multi third parties.
CloneTasks=Clone tasks
diff --git a/htdocs/projet/admin/project.php b/htdocs/projet/admin/project.php
index f36aae34c4f..143f75b72ab 100644
--- a/htdocs/projet/admin/project.php
+++ b/htdocs/projet/admin/project.php
@@ -242,6 +242,11 @@ elseif ($action == 'setdoc')
$projectToSelect = GETPOST('projectToSelect', 'alpha');
dolibarr_set_const($db, 'PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY', $projectToSelect, 'chaine', 0, '', $conf->entity); //Allow to disable this configuration if empty value
}
+ if (GETPOST('PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS'))
+ {
+ $timesheetFreezeDuration = GETPOST('timesheetFreezeDuration', 'alpha');
+ dolibarr_set_const($db, 'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS', intval($timesheetFreezeDuration), 'chaine', 0, '', $conf->entity); //Allow to disable this configuration if empty value
+ }
}
@@ -839,6 +844,16 @@ print ' ';
print ' ';
+print '';
+
+print '';
+print ''.$langs->trans("TimesheetPreventAfterFollowingMonths").' ';
+
+print '';
+print ' ';
+print ' ';
+print ' ';
+print ' ';
print '';
diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php
index b4733de05ae..1b64f0d9a66 100644
--- a/htdocs/projet/class/task.class.php
+++ b/htdocs/projet/class/task.class.php
@@ -1095,6 +1095,18 @@ class Task extends CommonObject
if (isset($this->timespent_note)) $this->timespent_note = trim($this->timespent_note);
if (empty($this->timespent_datehour)) $this->timespent_datehour = $this->timespent_date;
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+
+ if ($this->timespent_date < $restrictBefore) {
+ $this->error = $langs->trans('TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
+ $this->errors[] = $this->error;
+ return -1;
+ }
+ }
+
+
$this->db->begin();
$sql = "INSERT INTO ".MAIN_DB_PREFIX."projet_task_time (";
From 7317aad41f76c944b21618df2caf3346788520e8 Mon Sep 17 00:00:00 2001
From: Marc de Lima Lucio <68746600+marc-dll@users.noreply.github.com>
Date: Wed, 9 Jun 2021 11:08:38 +0200
Subject: [PATCH 2/3] FIX: projet time spent: also restrict to X months back
for update and delete
---
htdocs/projet/class/task.class.php | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php
index 1b64f0d9a66..e974532f545 100644
--- a/htdocs/projet/class/task.class.php
+++ b/htdocs/projet/class/task.class.php
@@ -1465,6 +1465,17 @@ class Task extends CommonObject
if (empty($this->timespent_datehour)) $this->timespent_datehour = $this->timespent_date;
if (isset($this->timespent_note)) $this->timespent_note = trim($this->timespent_note);
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+
+ if ($this->timespent_date < $restrictBefore) {
+ $this->error = $langs->trans('TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
+ $this->errors[] = $this->error;
+ return -1;
+ }
+ }
+
$this->db->begin();
$sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_time SET";
@@ -1530,6 +1541,17 @@ class Task extends CommonObject
$error = 0;
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+
+ if ($this->timespent_date < $restrictBefore) {
+ $this->error = $langs->trans('TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
+ $this->errors[] = $this->error;
+ return -1;
+ }
+ }
+
$this->db->begin();
$sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_time";
From c62c668c68e9456cd36864de6ecbf3c5d95af2e0 Mon Sep 17 00:00:00 2001
From: stickler-ci
Date: Wed, 9 Jun 2021 09:29:22 +0000
Subject: [PATCH 3/3] Fixing style errors.
---
htdocs/projet/class/task.class.php | 54 +++++++++++++++---------------
1 file changed, 27 insertions(+), 27 deletions(-)
diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php
index f46869382a5..05ce98b8896 100644
--- a/htdocs/projet/class/task.class.php
+++ b/htdocs/projet/class/task.class.php
@@ -1158,16 +1158,16 @@ class Task extends CommonObject
$this->timespent_datehour = $this->timespent_date;
}
- if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
- require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
- $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
- if ($this->timespent_date < $restrictBefore) {
- $this->error = $langs->trans('TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
- $this->errors[] = $this->error;
- return -1;
- }
- }
+ if ($this->timespent_date < $restrictBefore) {
+ $this->error = $langs->trans('TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
+ $this->errors[] = $this->error;
+ return -1;
+ }
+ }
$this->db->begin();
@@ -1531,16 +1531,16 @@ class Task extends CommonObject
$this->timespent_note = trim($this->timespent_note);
}
- if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
- require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
- $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
- if ($this->timespent_date < $restrictBefore) {
- $this->error = $langs->trans('TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
- $this->errors[] = $this->error;
- return -1;
- }
- }
+ if ($this->timespent_date < $restrictBefore) {
+ $this->error = $langs->trans('TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
+ $this->errors[] = $this->error;
+ return -1;
+ }
+ }
$this->db->begin();
@@ -1608,16 +1608,16 @@ class Task extends CommonObject
$error = 0;
- if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
- require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
- $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
- if ($this->timespent_date < $restrictBefore) {
- $this->error = $langs->trans('TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
- $this->errors[] = $this->error;
- return -1;
- }
- }
+ if ($this->timespent_date < $restrictBefore) {
+ $this->error = $langs->trans('TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
+ $this->errors[] = $this->error;
+ return -1;
+ }
+ }
$this->db->begin();