From 7b5468067f8be75bb9bd389756a0dc824d0d4f9a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 25 Jan 2018 17:23:44 +0000 Subject: [PATCH] Initial implementation of the Paid status plugin. --- WEB-INF/lib/ttReportHelper.class.php | 50 +++++++++++++++++++ WEB-INF/resources/ca.lang.php | 2 +- WEB-INF/resources/da.lang.php | 5 +- WEB-INF/resources/de.lang.php | 2 + WEB-INF/resources/en.lang.php | 3 +- WEB-INF/resources/es.lang.php | 2 + WEB-INF/resources/fa.lang.php | 2 + WEB-INF/resources/fi.lang.php | 2 + WEB-INF/resources/fr.lang.php | 2 + WEB-INF/resources/he.lang.php | 2 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/pl.lang.php | 2 + WEB-INF/resources/pt-br.lang.php | 2 + WEB-INF/resources/ru.lang.php | 3 +- WEB-INF/resources/sk.lang.php | 2 + WEB-INF/resources/sr.lang.php | 2 + WEB-INF/resources/sv.lang.php | 2 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 25 ++++++---- report.php | 72 ++++++++++++++++++++++++++-- 20 files changed, 169 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 0a8e727c..31395184 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -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) { diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index b0373d4f..c7dff2ec 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -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', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 97273d49..20a26573 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -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). diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 21ca2947..31496852 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -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). diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index fedb0994..cb07711c 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -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). diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index ac50e5d0..7c7bfd18 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -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). diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 420f8f40..120e934a 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -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). diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index f5604da8..cb6f7772 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -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). diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index b5855a11..b56b33c3 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -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). diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 11a4712c..6ffb1284 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -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). diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 849b6bc5..2ae72d60 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -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). diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 376dbbaf..312fb1b4 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -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). diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 5cb100b7..4ffa3b2b 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -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). diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index a3e2d6f8..1635d0ff 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -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). diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 78852e0c..803aedc3 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -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). diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 2e817961..fcda2e4c 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -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). diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 2b66518e..4016e0c7 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -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). diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ee017c99..c7b26483 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} {if $bean->getAttribute('chcost')}{/if} {if $bean->getAttribute('chpaid')} - {if $use_checkboxes} - {if 1 == $item.type}{/if} - {if 2 == $item.type}{/if} - {/if} + {if $bean->getAttribute('chinvoice')}{/if} + {if $use_checkboxes} + {if 1 == $item.type}{/if} + {if 2 == $item.type}{/if} {/if} {$prev_date = $item.date} @@ -142,12 +140,23 @@
 Anuko Time Tracker 1.17.3.3781 | Copyright © Anuko | +  Anuko Time Tracker 1.17.4.3782 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 432159d4..e98e14ce 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -91,12 +91,10 @@ {if $bean->getAttribute('chnote')}{$item.note|escape}{if $user->canManageTeam() || $user->isClient()}{$item.cost}{else}{$item.expense}{/if}{if $item.paid == 1}{$i18n.label.yes}{else}{$i18n.label.no}{/if}{/if} - {if $bean->getAttribute('chinvoice')} - {$item.invoice|escape}{$item.invoice|escape}
-{if $use_checkboxes && $report_items} +{if $use_mark_paid && $report_items} + + + + +
+ + +
{$i18n.label.mark_paid}: {$forms.reportForm.mark_paid_select_options.control} {$forms.reportForm.mark_paid_action_options.control} {$forms.reportForm.btn_mark_paid.control}
+
+{/if} +{if $use_assign_to_invoice && $report_items} diff --git a/report.php b/report.php index 110d5ac4..f1bca310 100644 --- a/report.php +++ b/report.php @@ -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); -- 2.20.1
- +
{$forms.reportForm.recent_invoice.control} {$forms.reportForm.btn_submit.control}
{$i18n.form.report.assign_to_invoice}: {$forms.reportForm.recent_invoice.control} {$forms.reportForm.btn_assign.control}