From f2b99f6c76ea5684968ac22300c98eae0777f540 Mon Sep 17 00:00:00 2001
From: Nik Okuntseff <support@anuko.com>
Date: Mon, 4 Mar 2019 17:13:44 +0000
Subject: [PATCH] Improvements to timesheet assignment algorithm.

---
 WEB-INF/lib/ttReportHelper.class.php    | 13 +++++++++++--
 WEB-INF/lib/ttTimesheetHelper.class.php |  5 ++---
 WEB-INF/templates/footer.tpl            |  2 +-
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php
index 0fa00d13..0cc2702c 100644
--- a/WEB-INF/lib/ttReportHelper.class.php
+++ b/WEB-INF/lib/ttReportHelper.class.php
@@ -639,9 +639,18 @@ class ttReportHelper {
     $org_id = $user->org_id;
 
     if ($time_log_ids) {
-      if ($timesheet_id)
+      // Use inner join as a protection mechanism not to do anything with "acted upon" timesheets.
+      // Allow oprations only with pending timesheets.
+      if ($timesheet_id) {
+        // Assigning a timesheet to records.
         $inner_join = " inner join tt_timesheets ts on (ts.id = $timesheet_id".
-          " and ts.user_id = $user_id and ts.approve_status is null)";
+          " and ts.user_id = $user_id and ts.approve_status is null". // Timesheet to assign to is pending.
+          // Part below: existing timesheet either not exists or is also pending.
+          " and (l.timesheet_id is null or (l.timesheet_id = ts.id and ts.approve_status is null)))";
+      } else {
+        $inner_join = " inner join tt_timesheets ts on (ts.id = l.timesheet_id".
+          " and ts.user_id = $user_id and ts.approve_status is null)"; // Do not deassign from acted-upon timesheets.
+      }
 
       $sql = "update tt_log l $inner_join".
         " set l.timesheet_id = ".$mdb2->quote($timesheet_id).
diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php
index a348cb57..c2841c88 100644
--- a/WEB-INF/lib/ttTimesheetHelper.class.php
+++ b/WEB-INF/lib/ttTimesheetHelper.class.php
@@ -440,9 +440,8 @@ class ttTimesheetHelper {
     if ($options['show_cost'] && $user->isPluginEnabled('ex')) return false;
     
     // Parts for client and project.
-    if ($options['client_id']) $client_part = ' and client_id = '.(int)$options['client_id'];
-    if ($options['project_id']) $project_part = ' and project_id = '.(int)$options['project_id'];
-    // TODO: test and fix the above for NULL client and project ids...
+    if ($options['client_id']) $client_part = ' and (client_id is null or client_id = '.(int)$options['client_id'].')';
+    if ($options['project_id']) $project_part = ' and (project_id is null or project_id = '.(int)$options['project_id'].')';
 
     // Determine start and end dates.
     $dateFormat = $user->getDateFormat();
diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl
index 9ce9723f..fea07f59 100644
--- a/WEB-INF/templates/footer.tpl
+++ b/WEB-INF/templates/footer.tpl
@@ -12,7 +12,7 @@
       <br>
       <table cellspacing="0" cellpadding="4" width="100%" border="0">
         <tr>
-          <td align="center">&nbsp;Anuko Time Tracker 1.18.52.4820 | Copyright &copy; <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
+          <td align="center">&nbsp;Anuko Time Tracker 1.18.52.4821 | Copyright &copy; <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
             <a href="https://www.anuko.com/lp/tt_4.htm" target="_blank">{$i18n.footer.credits}</a> |
             <a href="https://www.anuko.com/lp/tt_5.htm" target="_blank">{$i18n.footer.license}</a> |
             <a href="https://www.anuko.com/lp/tt_7.htm" target="_blank">{$i18n.footer.improve}</a>
-- 
2.20.1