Initial implementation of the Paid status plugin.
authorNik Okuntseff <support@anuko.com>
Thu, 25 Jan 2018 17:23:44 +0000 (17:23 +0000)
committerNik Okuntseff <support@anuko.com>
Thu, 25 Jan 2018 17:23:44 +0000 (17:23 +0000)
20 files changed:
WEB-INF/lib/ttReportHelper.class.php
WEB-INF/resources/ca.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/fa.lang.php
WEB-INF/resources/fi.lang.php
WEB-INF/resources/fr.lang.php
WEB-INF/resources/he.lang.php
WEB-INF/resources/nl.lang.php
WEB-INF/resources/pl.lang.php
WEB-INF/resources/pt-br.lang.php
WEB-INF/resources/ru.lang.php
WEB-INF/resources/sk.lang.php
WEB-INF/resources/sr.lang.php
WEB-INF/resources/sv.lang.php
WEB-INF/templates/footer.tpl
WEB-INF/templates/report.tpl
report.php

index 0a8e727..3139518 100644 (file)
@@ -437,6 +437,39 @@ class ttReportHelper {
     return $report_items;
   }
 
+  // putInSession stores tt_log and tt_expense_items ids from a report in user session
+  // as 2 comma-separated lists.
+  static function putInSession($report_items) {
+    unset($_SESSION['report_item_ids']);
+    unset($_SESSION['report_item_expense_ids']);
+
+    // Iterate through records and build 2 comma-separated lists.
+    foreach($report_items as $item) {
+      if ($item['type'] == 1)
+        $report_item_ids .= ','.$item['id'];
+      else if ($item['type'] == 2)
+         $report_item_expense_ids .= ','.$item['id'];
+    }
+    $report_item_ids = trim($report_item_ids, ',');
+    $report_item_expense_ids = trim($report_item_expense_ids, ',');
+
+    // The lists are reqdy. Put them in session.
+    if ($report_item_ids) $_SESSION['report_item_ids'] = $report_item_ids;
+    if ($report_item_expense_ids) $_SESSION['report_item_expense_ids'] = $report_item_expense_ids;
+  }
+
+  // getFromSession obtains tt_log and tt_expense_items ids stored in user session.
+  static function getFromSession() {
+    $items = array();
+    $report_item_ids = $_SESSION['report_item_ids'];
+    if ($report_item_ids)
+      $items['report_item_ids'] = explode(',', $report_item_ids);
+    $report_item_expense_ids = $_SESSION['report_item_expense_ids'];
+    if ($report_item_expense_ids)
+      $items['report_item_expense_ids'] = explode(',', $report_item_expense_ids);
+    return $items;
+  }
+
   // getFavItems retrieves all items associated with a favorite report.
   // It combines tt_log and tt_expense_items in one array for presentation in one table using mysql union all.
   // Expense items use the "note" field for item name.
@@ -1057,6 +1090,23 @@ class ttReportHelper {
     }
   }
 
+  // The markPaid marks a set of records as either paid or unpaid.
+  static function markPaid($time_log_ids, $expense_item_ids, $paid = true)
+  {
+    $mdb2 = getConnection();
+    $paid_val = (int) $paid;
+    if ($time_log_ids) {
+      $sql = "update tt_log set paid = $paid_val where id in(".join(', ', $time_log_ids).")";
+      $affected = $mdb2->exec($sql);
+      if (is_a($affected, 'PEAR_Error')) die($affected->getMessage());
+    }
+    if ($expense_item_ids) {
+      $sql = "update tt_expense_items set paid = $paid_val where id in(".join(', ', $expense_item_ids).")";
+      $affected = $mdb2->exec($sql);
+      if (is_a($affected, 'PEAR_Error')) die($affected->getMessage());
+    }
+  }
+
   // prepareReportBody - prepares an email body for report.
   static function prepareReportBody($bean, $comment)
   {
index b0373d4..c7dff2e 100644 (file)
@@ -135,7 +135,6 @@ $i18n_key_words = array(
 // TODO: translate the following.
 // 'button.close' => 'Close',
 // 'button.stop' => 'Stop',
-// 'button.mark_paid' => 'Mark paid',
 
 // Labels for controls on forms. Labels in this section are used on multiple forms.
 // TODO: translate the following.
@@ -232,6 +231,7 @@ $i18n_key_words = array(
 // 'label.quantity' => 'Quantity',
 // 'label.paid_status' => 'Paid status',
 // 'label.paid' => 'Paid',
+// 'label.mark_paid' => 'Mark paid',
 
 // Form titles.
 'title.login' => 'Sessió iniciada',
index 97273d4..20a2657 100644 (file)
@@ -118,8 +118,6 @@ $i18n_key_words = array(
 'button.import' => 'Importer team',
 'button.close' => 'Luk',
 'button.stop' => 'Stop',
-// TODO: translate the following.
-// 'button.mark_paid' => 'Mark paid',
 
 // Labels for controls on forms. Labels in this section are used on multiple forms.
 'label.team_name' => 'Team navn',
@@ -215,6 +213,7 @@ $i18n_key_words = array(
 // TODO: translate the following.
 // 'label.paid_status' => 'Paid status',
 // 'label.paid' => 'Paid',
+// 'label.mark_paid' => 'Mark paid',
 
 // Form titles.
 'title.login' => 'Login',
@@ -360,6 +359,8 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Eksport',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index 21ca294..3149685 100644 (file)
@@ -347,6 +347,8 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Exportiere',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index fedb099..cb07711 100644 (file)
@@ -118,7 +118,6 @@ $i18n_key_words = array(
 'button.import' => 'Import team',
 'button.close' => 'Close',
 'button.stop' => 'Stop',
-'button.mark_paid' => 'Mark paid',
 
 // Labels for controls on forms. Labels in this section are used on multiple forms.
 'label.team_name' => 'Team name',
@@ -209,6 +208,7 @@ $i18n_key_words = array(
 'label.quantity' => 'Quantity',
 'label.paid_status' => 'Paid status',
 'label.paid' => 'Paid',
+'label.mark_paid' => 'Mark paid',
 
 // Form titles.
 'title.login' => 'Login',
@@ -357,6 +357,7 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Export',
+'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index ac50e5d..7c7bfd1 100644 (file)
@@ -417,6 +417,8 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Exportar',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index 420f8f4..120e934 100644 (file)
@@ -386,6 +386,8 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'پشتیبانی',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index f5604da..cb6f777 100644 (file)
@@ -361,6 +361,8 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Vie',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index b5855a1..b56b33c 100644 (file)
@@ -352,6 +352,8 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Exporter',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index 11a4712..6ffb128 100644 (file)
@@ -387,6 +387,8 @@ $i18n_key_words = array(
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 // TODO: form.report.export is just "Export" now in the English file. Shorten this translation.
 'form.report.export' => 'ייצא נתונים בתבנית',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index 849b6bc..2ae72d6 100644 (file)
@@ -354,6 +354,8 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Exporteer',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index 376dbba..312fb1b 100644 (file)
@@ -369,6 +369,8 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Eksport',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index 5cb100b..4ffa3b2 100644 (file)
@@ -361,6 +361,8 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Exportar',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index a3e2d6f..1635d0f 100644 (file)
@@ -118,7 +118,6 @@ $i18n_key_words = array(
 'button.import' => 'Импортировать команду',
 'button.close' => 'Закрыть',
 'button.stop' => 'Завершить',
-'button.mark_paid' => 'Отметить оплату',
 
 // Labels for controls on forms. Labels in this section are used on multiple forms.
 'label.team_name' => 'Название команды',
@@ -209,6 +208,7 @@ $i18n_key_words = array(
 'label.quantity' => 'Количество',
 'label.paid_status' => 'Статус оплаты',
 'label.paid' => 'Оплачено',
+'label.mark_paid' => 'Отметить оплату',
 
 // Form titles.
 'title.login' => 'Вход в систему',
@@ -355,6 +355,7 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Экспортировать',
+'form.report.assign_to_invoice' => 'Включить в счёт',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index 78852e0..803aedc 100644 (file)
@@ -384,6 +384,8 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Exportovať',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index 2e81796..fcda2e4 100644 (file)
@@ -367,6 +367,8 @@ $i18n_key_words = array(
 // Forma izveštaja. Pogledajte primer na https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Izvoz',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Forma izveštaja. Pogledajte primer na https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index 2b66518..4016e0c 100644 (file)
@@ -364,6 +364,8 @@ $i18n_key_words = array(
 // Report form. See example at https://timetracker.anuko.com/report.php
 // (after generating a report at https://timetracker.anuko.com/reports.php).
 'form.report.export' => 'Exportera som',
+// TODO: translate the following.
+// 'form.report.assign_to_invoice' => 'Assign to invoice',
 
 // Invoice form. See example at https://timetracker.anuko.com/invoice.php
 // (you can get to this form after generating a report).
index ee017c9..c7b2648 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.3.3781 | 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.4.3782 | 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 432159d..e98e14c 100644 (file)
     {if $bean->getAttribute('chnote')}<td class="cellLeftAligned">{$item.note|escape}</td>{/if}
     {if $bean->getAttribute('chcost')}<td class="cellRightAligned">{if $user->canManageTeam() || $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('chinvoice')}
-        <td class="cellRightAligned">{$item.invoice|escape}</td>
-      {if $use_checkboxes}
-        {if 1 == $item.type}<td bgcolor="white"><input type="checkbox" name="log_id_{$item.id}"></td>{/if}
-        {if 2 == $item.type}<td bgcolor="white"><input type="checkbox" name="item_id_{$item.id}"></td>{/if}
-      {/if}
+    {if $bean->getAttribute('chinvoice')}<td class="cellRightAligned">{$item.invoice|escape}</td>{/if}
+    {if $use_checkboxes}
+      {if 1 == $item.type}<td bgcolor="white"><input type="checkbox" name="log_id_{$item.id}"></td>{/if}
+      {if 2 == $item.type}<td bgcolor="white"><input type="checkbox" name="item_id_{$item.id}"></td>{/if}
     {/if}
       </tr>
     {$prev_date = $item.date}
   </td>
 </tr>
 </table>
-{if $use_checkboxes && $report_items}
+{if $use_mark_paid && $report_items}
+<table width="720" cellspacing="4" cellpadding="4" border="0">
+  <tr>
+    <td align="right">
+      <table>
+        <tr><td>{$i18n.label.mark_paid}: {$forms.reportForm.mark_paid_select_options.control} {$forms.reportForm.mark_paid_action_options.control} {$forms.reportForm.btn_mark_paid.control}</td></tr>
+      </table>
+    </td>
+  </tr>
+</table>
+{/if}
+{if $use_assign_to_invoice && $report_items}
 <table width="720" cellspacing="4" cellpadding="4" border="0">
   <tr>
     <td align="right">
       <table>
-        <tr><td>{$forms.reportForm.recent_invoice.control} {$forms.reportForm.btn_submit.control}</td></tr>
+        <tr><td>{$i18n.form.report.assign_to_invoice}: {$forms.reportForm.recent_invoice.control} {$forms.reportForm.btn_assign.control}</td></tr>
       </table>
     </td>
   </tr>
index 110d5ac..f1bca31 100644 (file)
@@ -38,6 +38,13 @@ if (!ttAccessCheck(right_view_reports)) {
   exit();
 }
 
+if ($user->isPluginEnabled('ps')) {
+  $cl_mark_paid_select_option = $request->getParameter('mark_paid_select_options', ($request->isPost() ? null : @$_SESSION['mark_paid_select_option']));
+  $_SESSION['mark_paid_select_option'] = $cl_mark_paid_select_option;
+  $cl_mark_paid_action_option = $request->getParameter('mark_paid_action_options', ($request->isPost() ? null : @$_SESSION['mark_paid_action_option']));
+  $_SESSION['mark_paid_action_option'] = $cl_mark_paid_action_option;
+}
+
 // Use custom fields plugin if it is enabled.
 if ($user->isPluginEnabled('cf')) {
   require_once('plugins/CustomFields.class.php');
@@ -50,6 +57,30 @@ $form = new Form('reportForm');
 // Report settings are stored in session bean before we get here from reports.php.
 $bean = new ActionForm('reportBean', $form, $request);
 $client_id = $bean->getAttribute('client');
+
+// Do we need to show checkboxes?
+if ($bean->getAttribute('chpaid') ||
+   ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by')) && !$user->isClient())) {
+  $smarty->assign('use_checkboxes', true);
+}
+
+// Controls for "Mark paid" block.
+if ($bean->getAttribute('chpaid')) {
+  $mark_paid_select_options = array('1'=>$i18n->getKey('dropdown.all'),'2'=>$i18n->getKey('dropdown.select'));
+  $form->addInput(array('type'=>'combobox',
+    'name'=>'mark_paid_select_options',
+    'data'=>$mark_paid_select_options,
+    'value'=>$cl_mark_paid_select_option));
+  $mark_paid_action_options = array('1'=>$i18n->getKey('dropdown.paid'),'2'=>$i18n->getKey('dropdown.not_paid'));
+  $form->addInput(array('type'=>'combobox',
+    'name'=>'mark_paid_action_options',
+    'data'=>$mark_paid_action_options,
+    'value'=>$cl_mark_paid_action_option));
+  $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->getKey('button.submit')));
+  $smarty->assign('use_mark_paid', true);
+}
+
+// Controls for "Assign to invoice" block.
 if ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->getAttribute('group_by')) && !$user->isClient()) {
   // Client is selected and we are displaying the invoice column.
   $recent_invoices = ttTeamHelper::getRecentInvoices($user->team_id, $client_id);
@@ -59,13 +90,44 @@ if ($client_id && $bean->getAttribute('chinvoice') && ('no_grouping' == $bean->g
       'data'=>$recent_invoices,
       'datakeys'=>array('id','name'),
       'empty'=>array(''=>$i18n->getKey('dropdown.select_invoice'))));
-    $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.submit')));
-    $smarty->assign('use_checkboxes', true);
+    $form->addInput(array('type'=>'submit','name'=>'btn_assign','value'=>$i18n->getKey('button.submit')));
   }
+  $smarty->assign('use_assign_to_invoice', true);
 }
 
 if ($request->isPost()) {
-  if ($request->getParameter('btn_submit')) {
+  if ($request->getParameter('btn_mark_paid')) {
+    // User clicked the "Mark paid" button to mark some or all items either paid or not paid.
+
+    // Determine user action.
+    $mark_paid = $request->getParameter('mark_paid_action_options') == 1 ? true : false;
+
+    // Obtain 2 arrays or record ids, one for log, another for expense items.
+    if (1 == $request->getParameter('mark_paid_select_options')) {
+      // We are marking all report items. Get the arrays from session.
+      $item_ids = ttReportHelper::getFromSession();
+      $time_log_ids = $item_ids['report_item_ids'];
+      $expense_item_ids = $item_ids['report_item_expense_ids'];
+    } else if (2 == $request->getParameter('mark_paid_select_options')) {
+      // We are marking only selected items. Get the arrays from $_POST.
+      foreach($_POST as $key => $val) {
+        if ('log_id_' == substr($key, 0, 7))
+          $time_log_ids[] = substr($key, 7);
+        if ('item_id_' == substr($key, 0, 8))
+          $expense_item_ids[] = substr($key, 8);
+      }
+    }
+    // Mark as requested.
+    if ($time_log_ids || $expense_item_ids) {
+      ttReportHelper::markPaid($time_log_ids, $expense_item_ids, $mark_paid);
+    }
+
+    // Re-display this form.
+    header('Location: report.php');
+    exit();
+  }
+
+  if ($request->getParameter('btn_assign')) {
     // User clicked the Submit button to assign some items to a recent invoice.
     foreach($_POST as $key => $val) {
       if ('log_id_' == substr($key, 0, 7))
@@ -88,6 +150,10 @@ if ($request->isPost()) {
 $group_by = $bean->getAttribute('group_by');
 
 $report_items = ttReportHelper::getItems($bean);
+// Store record ids in session in case user wants to act on records such as marking them all paid.
+if ($request->isGet() && $user->isPluginEnabled('ps'))
+  ttReportHelper::putInSession($report_items);
+
 if ('no_grouping' != $group_by)
   $subtotals = ttReportHelper::getSubtotals($bean);
 $totals = ttReportHelper::getTotals($bean);