Initial work done on Work units plugin. Still in debug mode.
authorNik Okuntseff <support@anuko.com>
Fri, 20 Jul 2018 16:06:16 +0000 (16:06 +0000)
committerNik Okuntseff <support@anuko.com>
Fri, 20 Jul 2018 16:06:16 +0000 (16:06 +0000)
37 files changed:
WEB-INF/lib/ttConfigHelper.class.php
WEB-INF/lib/ttReportHelper.class.php
WEB-INF/lib/ttUser.class.php
WEB-INF/resources/ca.lang.php
WEB-INF/resources/cs.lang.php
WEB-INF/resources/da.lang.php
WEB-INF/resources/de.lang.php
WEB-INF/resources/en.lang.php
WEB-INF/resources/es.lang.php
WEB-INF/resources/et.lang.php
WEB-INF/resources/fa.lang.php
WEB-INF/resources/fi.lang.php
WEB-INF/resources/fr.lang.php
WEB-INF/resources/gr.lang.php
WEB-INF/resources/he.lang.php
WEB-INF/resources/hu.lang.php
WEB-INF/resources/it.lang.php
WEB-INF/resources/ja.lang.php
WEB-INF/resources/ko.lang.php
WEB-INF/resources/nl.lang.php
WEB-INF/resources/no.lang.php
WEB-INF/resources/pl.lang.php
WEB-INF/resources/pt-br.lang.php
WEB-INF/resources/pt.lang.php
WEB-INF/resources/ro.lang.php
WEB-INF/resources/ru.lang.php
WEB-INF/resources/sk.lang.php
WEB-INF/resources/sl.lang.php
WEB-INF/resources/sv.lang.php
WEB-INF/resources/tr.lang.php
WEB-INF/resources/zh-cn.lang.php
WEB-INF/resources/zh-tw.lang.php
WEB-INF/templates/footer.tpl
WEB-INF/templates/report.tpl
WEB-INF/templates/reports.tpl
reports.php
work_units.php

index 95cd121..b33734c 100644 (file)
@@ -44,7 +44,7 @@ class ttConfigHelper {
 
   // getDefinedValue determines if a value identified by name is defined.
   function getDefinedValue($name) {
-    return in_array($name, $this->$config_array);
+    return in_array($name, $this->config_array);
   }
 
   // The getIntValue parses an integer value from the source config string.
index 67f1da2..daaad46 100644 (file)
@@ -303,6 +303,10 @@ class ttReportHelper {
     if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice'))
       array_push($fields, 'i.name as invoice');
 
+    // Add work units.
+    if ($bean->getAttribute('chunits'))
+      array_push($fields, "if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit)) as units");
+
     // Prepare sql query part for left joins.
     $left_joins = null;
     if ($bean->getAttribute('chclient') || 'client' == $group_by_option)
@@ -380,6 +384,10 @@ class ttReportHelper {
       if (($canViewReports || $isClient) && $bean->getAttribute('chinvoice'))
         array_push($fields, 'i.name as invoice');
 
+      // Add work units.
+      if ($bean->getAttribute('chunits'))
+        array_push($fields, 'null'); // null for work units.
+
       // Prepare sql query part for left joins.
       $left_joins = null;
       if ($canViewReports || $isClient)
@@ -769,21 +777,25 @@ class ttReportHelper {
       if (MODE_TIME == $user->tracking_mode) {
         if ($group_by_option != 'user')
           $left_join = 'left join tt_users u on (l.user_id = u.id)';
-        $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, 
+        $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time,
+          sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units,
           sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost,
           null as expenses from tt_log l
           $group_join $left_join $where group by $group_field";
       } else {
         // If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table.
-        $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, 
+        $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time,
+          sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units,
           sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost,
           null as expenses from tt_log l
           $group_join
           left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where group by $group_field";
       }
     } else {
-      $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, null as expenses from tt_log l
-         $group_join $where group by $group_field";
+      $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time,
+        sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units,
+        null as expenses from tt_log l
+        $group_join $where group by $group_field";
     }
     // By now we have sql for time items.
 
@@ -813,13 +825,13 @@ class ttReportHelper {
       }
 
       $where = ttReportHelper::getExpenseWhere($bean);
-      $sql_for_expenses = "select $group_field as group_field, null as time, sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei 
+      $sql_for_expenses = "select $group_field as group_field, null as time, null as units, sum(ei.cost) as cost, sum(ei.cost) as expenses from tt_expense_items ei 
         $group_join $where";
       // Add a "group by" clause if we are grouping.
       if ('null' != $group_field) $sql_for_expenses .= " group by $group_field";
 
       // Create a combined query.
-      $sql = "select group_field, sum(time) as time, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field";
+      $sql = "select group_field, sum(time) as time, sum(units) as units, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field";
     }
 
     // Execute query.
@@ -839,9 +851,9 @@ class ttReportHelper {
           $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']);
           $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']);
         }
-        $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time,'cost'=>$val['cost'],'expenses'=>$val['expenses']);
+        $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time, 'units'=> $val['units'],'cost'=>$val['cost'],'expenses'=>$val['expenses']);
       } else
-        $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time);
+        $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time, 'units'=> $val['units']);
     }
 
     return $subtotals;
@@ -984,30 +996,37 @@ class ttReportHelper {
 
     $where = ttReportHelper::getWhere($bean);
 
+    // TODO: build query in parts so the work units inclusion is conditional.
+
     // Start with a query for time items.
     if ($bean->getAttribute('chcost')) {
       if (MODE_TIME == $user->tracking_mode) {
         $sql = "select sum(time_to_sec(l.duration)) as time,
+          sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units,
           sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost,
           null as expenses 
           from tt_log l
           left join tt_users u on (l.user_id = u.id) $where";
       } else {
         $sql = "select sum(time_to_sec(l.duration)) as time,
+          sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units,
           sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost,
           null as expenses
           from tt_log l
           left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where";
       }
     } else
-      $sql = "select sum(time_to_sec(l.duration)) as time, null as cost, null as expenses from tt_log l $where";
+      $sql = "select sum(time_to_sec(l.duration)) as time,"
+            ." sum(if(time_to_sec(duration)/60 < $user->first_unit_threshold, 0, ceil(time_to_sec(duration)/60/$user->minutes_in_unit))) as units,"
+            ." null as cost, null as expenses from tt_log l $where";
 
     // If we have expenses, query becomes a bit more complex.
     if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) {
       $where = ttReportHelper::getExpenseWhere($bean);
-      $sql_for_expenses = "select null as time, sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where";
+      $sql_for_expenses = "select null as time, null as units, sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where";
+
       // Create a combined query.
-      $sql = "select sum(time) as time, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t";
+      $sql = "select sum(time) as time, sum(units) as units, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t";
     }
 
     // Execute query.
@@ -1039,6 +1058,7 @@ class ttReportHelper {
     $totals['start_date'] = $period->getStartDate();
     $totals['end_date'] = $period->getEndDate();
     $totals['time'] = $total_time;
+    $totals['units'] = $val['units'];
     $totals['cost'] = $total_cost;
     $totals['expenses'] = $total_expenses;
 
index 07d810b..2816593 100644 (file)
@@ -26,6 +26,8 @@
 // | https://www.anuko.com/time_tracker/credits.htm
 // +----------------------------------------------------------------------+
 
+import('ttConfigHelper');
+
 class ttUser {
   var $login = null;            // User login.
   var $name = null;             // User name.
@@ -64,6 +66,8 @@ class ttUser {
   var $workday_minutes = 480;   // Number of work minutes in a regular day.
   var $rights = array();        // An array of user rights such as 'track_own_time', etc.
   var $is_client = false;       // Whether user is a client as determined by missing 'track_own_time' right.
+  var $minutes_in_unit = 15;    // Number of minutes in unit for Work units plugin.
+  var $first_unit_threshold = 0;// Threshold for 1st unit for Work units plugin.
 
   // Constructor.
   function __construct($login, $id = null) {
@@ -123,15 +127,20 @@ class ttUser {
       $this->custom_logo = $val['custom_logo'];
 
       $this->config = $val['config'];
-      $config_array = explode(',', $this->config);
-
+      $config = new ttConfigHelper($this->config);
       // Set user config options.
-      $this->show_holidays = in_array('show_holidays', $config_array);
-      $this->punch_mode = in_array('punch_mode', $config_array);
-      $this->allow_overlap = in_array('allow_overlap', $config_array);
-      $this->future_entries = in_array('future_entries', $config_array);
-      $this->uncompleted_indicators = in_array('uncompleted_indicators', $config_array);
-
+      $this->show_holidays = $config->getDefinedValue('show_holidays');
+      $this->punch_mode = $config->getDefinedValue('punch_mode');
+      $this->allow_overlap = $config->getDefinedValue('allow_overlap');
+      $this->future_entries = $config->getDefinedValue('future_entries');
+      $this->uncompleted_indicators = $config->getDefinedValue('uncompleted_indicators');
+      if ($this->isPluginEnabled('wu')) {
+        $minutes_in_unit = $config->getIntValue('minutes_in_unit');
+        if ($minutes_in_unit) $this->minutes_in_unit = $minutes_in_unit;
+        $first_unit_threshold = $config->getIntValue('1st_unit_threshold');
+        if ($first_unit_threshold) $this->first_unit_threshold = $first_unit_threshold;
+      }
+      
       // Set "on behalf" id and name.
       if (isset($_SESSION['behalf_id'])) {
           $this->behalf_id = $_SESSION['behalf_id'];
index 6f499dd..0e909ab 100644 (file)
@@ -244,6 +244,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 // TODO: Improve titles for consistency, so that each title explains correctly what each
index 21e16a6..282296e 100644 (file)
@@ -254,6 +254,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 // TODO: Improve titles for consistency, so that each title explains correctly what each
index 3b6487e..38e9f43 100644 (file)
@@ -225,6 +225,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Login',
index cf112e9..613bdc7 100644 (file)
@@ -221,6 +221,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Anmelden',
index 7e57b2f..e4abce9 100644 (file)
@@ -212,6 +212,7 @@ $i18n_key_words = array(
 'label.week_note' => 'Week note',
 'label.week_list' => 'Week list',
 'label.work_units' => 'Work units',
+'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Login',
index d3ab0e8..5a040b8 100644 (file)
@@ -247,6 +247,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Sesión iniciada',
index 8547caf..2b1bdde 100644 (file)
@@ -250,6 +250,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 // TODO: Improve titles for consistency, so that each title explains correctly what each
index 9b06bb1..c567d07 100644 (file)
@@ -237,6 +237,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'ورود',
index cf4d0b8..48b5089 100644 (file)
@@ -229,6 +229,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Kirjautuminen',
index 010d679..888e0ee 100644 (file)
@@ -223,6 +223,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Connexion',
index 42b7986..e8f03b0 100644 (file)
@@ -214,6 +214,7 @@ $i18n_key_words = array(
 'label.week_list' => 'Λίστα εβδομάδων',
 // TODO: translate the following.
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Σύνδεση',
index 646e12a..e513d5f 100644 (file)
@@ -247,6 +247,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'כניסה',
index 74c3bd2..cf6b087 100644 (file)
@@ -247,6 +247,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Bejelentkezés',
index ed335fe..ae1dae4 100644 (file)
@@ -219,6 +219,7 @@ $i18n_key_words = array(
 'label.week_list' => 'Lista settimanale',
 // TODO: translate the following.
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 // TODO: Improve titles for consistency, so that each title explains correctly what each
index 7902dec..fa4b4be 100644 (file)
@@ -252,6 +252,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'ログイン',
index 4128eb6..b4c79c2 100644 (file)
@@ -252,6 +252,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => '로그인',
index 25b8148..0107a70 100644 (file)
@@ -212,6 +212,7 @@ $i18n_key_words = array(
 'label.week_list' => 'Week overzicht',
 // TODO: translate the following.
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Aanmelden',
index 3bd4cc2..1bfc053 100644 (file)
@@ -250,6 +250,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Innlogging',
index 5a6150e..ec6b784 100644 (file)
@@ -230,6 +230,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Logowanie',
index c4f9f6a..db390eb 100644 (file)
@@ -227,6 +227,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Login',
index 5e43040..4b9727f 100644 (file)
@@ -239,6 +239,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Login',
index 002a38c..b9c1220 100644 (file)
@@ -251,6 +251,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 // TODO: Improve titles for consistency, so that each title explains correctly what each
index 804d9cd..114ecc5 100644 (file)
@@ -211,6 +211,7 @@ $i18n_key_words = array(
 'label.week_note' => 'Комментарий недели',
 'label.week_list' => 'Список недели',
 'label.work_units' => 'Единицы работы',
+'label.work_units_short' => 'Единицы',
 
 // Form titles.
 'title.login' => 'Вход в систему',
index 45d16c8..87beb6f 100644 (file)
@@ -237,6 +237,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Prihlásenie',
index 8dc9a6d..732286b 100644 (file)
@@ -234,6 +234,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => 'Prijava',
index 1e05671..11eff19 100644 (file)
@@ -223,6 +223,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Rubriker för formulär
 'title.login' => 'Logga in',
index 6449a7c..ee3b445 100644 (file)
@@ -258,6 +258,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 // Form titles.
index cbd7de3..1cb84d7 100644 (file)
@@ -241,6 +241,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => '登录',
index 6a77cff..fc3ec99 100644 (file)
@@ -248,6 +248,7 @@ $i18n_key_words = array(
 // 'label.week_note' => 'Week note',
 // 'label.week_list' => 'Week list',
 // 'label.work_units' => 'Work units',
+// 'label.work_units_short' => 'Units',
 
 // Form titles.
 'title.login' => '登錄',
index 3f71f0e..3ad220b 100644 (file)
@@ -12,7 +12,7 @@
       <br>
       <table cellspacing="0" cellpadding="4" width="100%" border="0">
         <tr>
-          <td align="center">&nbsp;Anuko Time Tracker 1.17.91.4275 | Copyright &copy; <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
+          <td align="center">&nbsp;Anuko Time Tracker 1.17.92.4276 | 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>
index ddea591..5543842 100644 (file)
       <tr>
         <td class="tableHeader">{$group_by_header|escape}</td>
         {if $bean->getAttribute('chduration')}<td class="tableHeaderCentered" width="5%">{$i18n.label.duration}</td>{/if}
+        {if $bean->getAttribute('chunits')}<td class="tableHeaderCentered" width="5%">{$i18n.label.work_units_short}</td>{/if}
         {if $bean->getAttribute('chcost')}<td class="tableHeaderCentered" width="5%">{$i18n.label.cost}</td>{/if}
       </tr>
   {foreach $subtotals as $subtotal}
       <tr class="rowReportSubtotal">
         <td class="cellLeftAlignedSubtotal">{if $subtotal['name']}{$subtotal['name']|escape}{else}&nbsp;{/if}</td>
         {if $bean->getAttribute('chduration')}<td class="cellRightAlignedSubtotal">{$subtotal['time']}</td>{/if}
+        {if $bean->getAttribute('chunits')}<td class="cellRightAlignedSubtotal">{$subtotal['units']}</td>{/if}
         {if $bean->getAttribute('chcost')}<td class="cellRightAlignedSubtotal">{if $user->can('manage_invoices') || $user->isClient()}{$subtotal['cost']}{else}{$subtotal['expenses']}{/if}</td>{/if}
       </tr>
   {/foreach}
@@ -30,6 +32,7 @@
       <tr class="rowReportSubtotal">
         <td class="cellLeftAlignedSubtotal">{$i18n.label.total}</td>
         {if $bean->getAttribute('chduration')}<td nowrap class="cellRightAlignedSubtotal">{$totals['time']}</td>{/if}
+        {if $bean->getAttribute('chunits')}<td nowrap class="cellRightAlignedSubtotal">{$totals['units']}</td>{/if}
         {if $bean->getAttribute('chcost')}<td nowrap class="cellRightAlignedSubtotal">{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}</td>{/if}
       </tr>
 {else}
@@ -44,6 +47,7 @@
   {if $bean->getAttribute('chstart')}<td class="tableHeaderCentered" width="5%">{$i18n.label.start}</td>{/if}
   {if $bean->getAttribute('chfinish')}<td class="tableHeaderCentered" width="5%">{$i18n.label.finish}</td>{/if}
   {if $bean->getAttribute('chduration')}<td class="tableHeaderCentered" width="5%">{$i18n.label.duration}</td>{/if}
+  {if $bean->getAttribute('chunits')}<td class="tableHeaderCentered" width="5%">{$i18n.label.work_units_short}</td>{/if}
   {if $bean->getAttribute('chnote')}<td class="tableHeader">{$i18n.label.note}</td>{/if}
   {if $bean->getAttribute('chcost')}<td class="tableHeaderCentered" width="5%">{$i18n.label.cost}</td>{/if}
   {if $bean->getAttribute('chpaid')}<td class="tableHeader">{$i18n.label.paid}</td>{/if}
@@ -66,6 +70,7 @@
         {if $bean->getAttribute('chstart')}<td></td>{/if}
         {if $bean->getAttribute('chfinish')}<td></td>{/if}
         {if $bean->getAttribute('chduration')}<td class="cellRightAlignedSubtotal">{$subtotals[$prev_grouped_by]['time']}</td>{/if}
+        {if $bean->getAttribute('chunits')}<td class="cellRightAlignedSubtotal">{$subtotals[$prev_grouped_by]['units']}</td>{/if}
         {if $bean->getAttribute('chnote')}<td></td>{/if}
         {if $bean->getAttribute('chcost')}<td class="cellRightAlignedSubtotal">{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$prev_grouped_by]['cost']}{else}{$subtotals[$prev_grouped_by]['expenses']}{/if}</td>{/if}
         {if $bean->getAttribute('chpaid')}<td></td>{/if}
@@ -91,6 +96,7 @@
     {if $bean->getAttribute('chstart')}<td nowrap class="cellRightAligned">{$item.start}</td>{/if}
     {if $bean->getAttribute('chfinish')}<td nowrap class="cellRightAligned">{$item.finish}</td>{/if}
     {if $bean->getAttribute('chduration')}<td class="cellRightAligned">{$item.duration}</td>{/if}
+    {if $bean->getAttribute('chunits')}<td class="cellRightAligned">{$item.units}</td>{/if}
     {if $bean->getAttribute('chnote')}<td class="cellLeftAligned">{$item.note|escape}</td>{/if}
     {if $bean->getAttribute('chcost')}<td class="cellRightAligned">{if $user->can('manage_invoices') || $user->isClient()}{$item.cost}{else}{$item.expense}{/if}</td>{/if}
     {if $bean->getAttribute('chpaid')}<td class="cellRightAligned">{if $item.paid == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{/if}
     {if $bean->getAttribute('chstart')}<td></td>{/if}
     {if $bean->getAttribute('chfinish')}<td></td>{/if}
     {if $bean->getAttribute('chduration')}<td class="cellRightAlignedSubtotal">{$subtotals[$cur_grouped_by]['time']}</td>{/if}
+    {if $bean->getAttribute('chunits')}<td class="cellRightAlignedSubtotal">{$subtotals[$cur_grouped_by]['units']}</td>{/if}
     {if $bean->getAttribute('chnote')}<td></td>{/if}
     {if $bean->getAttribute('chcost')}<td class="cellRightAlignedSubtotal">{if $user->can('manage_invoices') || $user->isClient()}{$subtotals[$cur_grouped_by]['cost']}{else}{$subtotals[$cur_grouped_by]['expenses']}{/if}</td>{/if}
     {if $bean->getAttribute('chpaid')}<td></td>{/if}
     {if $bean->getAttribute('chstart')}<td></td>{/if}
     {if $bean->getAttribute('chfinish')}<td></td>{/if}
     {if $bean->getAttribute('chduration')}<td class="cellRightAlignedSubtotal">{$totals['time']}</td>{/if}
+    {if $bean->getAttribute('chunits')}<td class="cellRightAlignedSubtotal">{$totals['units']}</td>{/if}
     {if $bean->getAttribute('chnote')}<td></td>{/if}
     {if $bean->getAttribute('chcost')}<td nowrap class="cellRightAlignedSubtotal">{$user->currency|escape} {if $user->can('manage_invoices') || $user->isClient()}{$totals['cost']}{else}{$totals['expenses']}{/if}</td>{/if}
     {if $bean->getAttribute('chpaid')}<td></td>{/if}
index a70a3f0..b57ba84 100644 (file)
@@ -284,6 +284,14 @@ function handleCheckboxes() {
                 <td></td>
 {/if}
               </tr>
+{if $user->isPluginEnabled('wu')}
+              <tr>
+                <td></td>
+                <td></td>
+                <td width="25%"><label>{$forms.reportForm.chunits.control}&nbsp;{$i18n.label.work_units}</label></td>
+                <td></td>
+              </tr>
+{/if}
             </table>
           </td>
         </tr>
index fcefd04..0565cf7 100644 (file)
@@ -214,6 +214,9 @@ $form->addInput(array('type'=>'checkbox','name'=>'chcost'));
 // If we have a custom field - add a checkbox for it.
 if ($custom_fields && $custom_fields->fields[0])
   $form->addInput(array('type'=>'checkbox','name'=>'chcf_1'));
+if ($user->isPluginEnabled('wu'))
+  $form->addInput(array('type'=>'checkbox','name'=>'chunits'));
+
 // Add group by control.
 $group_by_options['no_grouping'] = $i18n->get('form.reports.group_by_no');
 $group_by_options['date'] = $i18n->get('form.reports.group_by_date');
@@ -260,6 +263,7 @@ if ($request->isGet() && !$bean->isSaved()) {
   $form->setValueByElement('chfinish', '1');
   $form->setValueByElement('chnote', '1');
   $form->setValueByElement('chcf_1', '0');
+  $form->setValueByElement('chunits', '0');
   $form->setValueByElement('chtotalsonly', '0');
 }
 
index 3340ec1..dd01488 100644 (file)
@@ -46,8 +46,8 @@ if ($request->isPost()) {
   $cl_minutes_in_unit = $request->getParameter('minutes_in_unit');
   $cl_1st_unit_threshold = $request->getParameter('1st_unit_threshold');
 } else {
-  $cl_minutes_in_unit = $config->getIntValue('minutes_in_unit');
-  $cl_1st_unit_threshold = $config->getIntValue('1st_unit_threshold');
+  $cl_minutes_in_unit = $user->minutes_in_unit;
+  $cl_1st_unit_threshold = $user->first_unit_threshold;
 }
 
 $form = new Form('workUnitsForm');