From d5923832a32b1f43cbc6c5d74bbd064888761c80 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 3 Mar 2019 21:56:31 +0000 Subject: [PATCH] Added a mechanism to assign report items to timesheets. --- WEB-INF/lib/ttReportHelper.class.php | 20 ++++++++ WEB-INF/lib/ttTimesheetHelper.class.php | 62 +++++++++++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 13 +++++- report.php | 57 +++++++++++++++++++---- 5 files changed, 134 insertions(+), 20 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index abb5ab9e..ceaee4b0 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -629,6 +629,26 @@ class ttReportHelper { } } + // The assignToTimesheet assigns a set of tt_log records to a specific timesheet. + static function assignToTimesheet($timesheet_id, $time_log_ids) { + global $user; + $mdb2 = getConnection(); + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + if ($time_log_ids) { + $sql = "update tt_log l". + // TODO: inner join does not work properly for de-assignment. Improve. + // " inner join tt_timesheets ts on (ts.id = $timesheet_id and ts.approve_status is null)". + " set l.timesheet_id = ".$mdb2->quote($timesheet_id). + " where l.id in(".join(', ', $time_log_ids).") and l.user_id = $user_id and l.group_id = $group_id and l.org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); + } + } + // The markApproved marks a set of records as either approved or unapproved. static function markApproved($time_log_ids, $expense_item_ids, $approved = true) { global $user; diff --git a/WEB-INF/lib/ttTimesheetHelper.class.php b/WEB-INF/lib/ttTimesheetHelper.class.php index 22f12927..89571510 100644 --- a/WEB-INF/lib/ttTimesheetHelper.class.php +++ b/WEB-INF/lib/ttTimesheetHelper.class.php @@ -415,13 +415,59 @@ class ttTimesheetHelper { return false; } - // The canAssign function determines if we can show controls on a report page - // for timesheet assignment. + // The getMatchingTimesheets function retrieves a timesheet that "matches" + // a report for an option to assign report items to it. // - // Conditions: - // - Report date range, client_id, and project_id match an existing timesheet - // with approved_status null. - static function canAssign($options) { - return false; + // Condition: report range is fully enclosed in an existing timesheet with + // matching client_id and project_id and null approved_status. + static function getMatchingTimesheets($options) { + global $user; + $mdb2 = getConnection(); + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // Check users. + if (isset($options['users'])) { + $comma_separated = $options['users']; + $users = explode(',', $comma_separated); + if (count($users) > 1 || $users[0] != $user->getUser()) + return false; + } + + // No timesheets for expenses. + 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']; + + // Determine start and end dates. + $dateFormat = $user->getDateFormat(); + if ($options['period']) + $period = new Period($options['period'], new DateAndTime($dateFormat)); + else { + $period = new Period(); + $period->setPeriod( + new DateAndTime($dateFormat, $options['period_start']), + new DateAndTime($dateFormat, $options['period_end'])); + } + $start = $period->getStartDate(DB_DATEFORMAT); + $end = $period->getEndDate(DB_DATEFORMAT); + + $result = false; + $sql = "select id, name from tt_timesheets". + " where ".$mdb2->quote($start)." >= start_date and ".$mdb2->quote($end)." <= end_date". + "$client_part $project_part". + " and user_id = $user_id and group_id = $group_id and org_id = $org_id". + " and approve_status is null and status is not null"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; } -} \ No newline at end of file +} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f7a52196..da170551 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.18.52.4817 | Copyright © Anuko | +  Anuko Time Tracker 1.18.52.4818 | 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 44a6e337..9e215c4d 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -166,7 +166,7 @@
-{if $report_items && ($use_mark_approved || $use_mark_paid || $use_assign_to_invoice)} +{if $report_items && ($use_mark_approved || $use_mark_paid || $use_assign_to_invoice || $use_assign_to_timesheet)} {if $use_mark_approved} @@ -190,7 +190,16 @@ + + {/if} + {if $use_assign_to_timesheet} + + diff --git a/report.php b/report.php index b31394e2..4a29c320 100644 --- a/report.php +++ b/report.php @@ -31,6 +31,7 @@ import('form.Form'); import('form.ActionForm'); import('ttReportHelper'); import('ttGroupHelper'); +import('ttTimesheetHelper'); // Access check. if (!(ttAccessAllowed('view_own_reports') || ttAccessAllowed('view_reports') || ttAccessAllowed('view_all_reports') || ttAccessAllowed('view_client_reports'))) { @@ -56,6 +57,12 @@ if ($user->isPluginEnabled('iv')) { $cl_recent_invoice_option = $request->getParameter('recent_invoice', ($request->isPost() ? null : @$_SESSION['recent_invoice_option'])); $_SESSION['recent_invoice_option'] = $cl_recent_invoice_option; } +if ($user->isPluginEnabled('ts')) { + $cl_assign_timesheet_select_option = $request->getParameter('assign_timesheet_select_options', ($request->isPost() ? null : @$_SESSION['assign_timesheet_select_option'])); + $_SESSION['assign_timesheet_select_option'] = $cl_assign_timesheet_select_option; + $cl_timesheet_option = $request->getParameter('timesheet', ($request->isPost() ? null : @$_SESSION['timesheet_option'])); + $_SESSION['timesheet_option'] = $cl_timesheet_option; +} // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { @@ -72,6 +79,7 @@ $bean = new ActionForm('reportBean', new Form('reportForm'), $request); if ($request->isPost()) $bean->loadBean(); $client_id = $bean->getAttribute('client'); +$options = ttReportHelper::getReportOptions($bean); // Do we need to show checkboxes? We show them in the following 4 situations: // - We can approve items. @@ -85,10 +93,10 @@ if ($bean->getAttribute('chpaid') && $user->can('manage_invoices')) $useMarkPaid = true; if ($bean->getAttribute('chinvoice') && $client_id && 'no_grouping' == $bean->getAttribute('group_by1') && !$user->isClient() && $user->can('manage_invoices')) $useAssignToInvoice = true; -//if ($bean->getAttribute('chtimesheet') && ($user->can('track_own_time') || $user->can('track_time'))) -// $useAssignToTimesheet = true; // TODO: add a check for timesheet capability. -//if (ttTimesheetHelper::canAssign($options)) -// $useAssignToTimesheet = true; +if ($bean->getAttribute('chtimesheet')) { + $timesheets = ttTimesheetHelper::getMatchingTimesheets($options); + if ($timesheets) $useAssignToTimesheet = true; +} $use_checkboxes = $useMarkApproved || $useMarkPaid || $useAssignToInvoice || $useAssignToTimesheet; if ($use_checkboxes) @@ -142,17 +150,35 @@ if ($useAssignToInvoice) { 'datakeys'=>array('id','name'), 'value'=>$cl_recent_invoice_option, 'empty'=>array(''=>$i18n->get('dropdown.select_invoice')))); - $form->addInput(array('type'=>'submit','name'=>'btn_assign','value'=>$i18n->get('button.submit'))); + $form->addInput(array('type'=>'submit','name'=>'btn_assign_invoice','value'=>$i18n->get('button.submit'))); $smarty->assign('use_assign_to_invoice', true); } } +// Controls for "Assign to timesheet" block. +if ($useAssignToTimesheet) { + $assign_timesheet_select_options = array('1'=>$i18n->get('dropdown.all'),'2'=>$i18n->get('dropdown.select')); + $form->addInput(array('type'=>'combobox', + 'name'=>'assign_timesheet_select_options', + 'data'=>$assign_timesheet_select_options, + 'value'=>$cl_assign_timesheet_select_option)); + $form->addInput(array('type'=>'combobox', + 'name'=>'timesheet', + 'data'=>$timesheets, + 'datakeys'=>array('id','name'), + 'value'=>$cl_timesheet_option, + 'empty'=>array(''=>$i18n->get('dropdown.select_timesheet')))); + $form->addInput(array('type'=>'submit','name'=>'btn_assign_timesheet','value'=>$i18n->get('button.submit'))); + $smarty->assign('use_assign_to_timesheet', true); +} + if ($request->isPost()) { // Validate parameters and at the same time build arrays of record ids. if (($request->getParameter('btn_mark_approved') && 2 == $request->getParameter('mark_approved_select_options')) || ($request->getParameter('btn_mark_paid') && 2 == $request->getParameter('mark_paid_select_options')) - || ($request->getParameter('btn_assign') && 2 == $request->getParameter('assign_invoice_select_options'))) { + || ($request->getParameter('btn_assign_invoice') && 2 == $request->getParameter('assign_invoice_select_options')) + || ($request->getParameter('btn_assign_timesheet') && 2 == $request->getParameter('assign_timesheet_select_options'))) { // We act on selected records. Are there any? foreach($_POST as $key => $val) { if ('log_id_' == substr($key, 0, 7)) @@ -205,7 +231,7 @@ if ($request->isPost()) { exit(); } - if ($request->getParameter('btn_assign')) { + if ($request->getParameter('btn_assign_invoice')) { // User clicked the Submit button to assign all or some items to a recent invoice. // Determine invoice id. @@ -219,11 +245,24 @@ if ($request->isPost()) { header('Location: report.php'); exit(); } + + if ($request->getParameter('btn_assign_timesheet')) { + // User clicked the Submit button to assign all or some items to a timesheet. + + // Determine invoice id. + $timesheet_id = $request->getParameter('timesheet'); + + // Assign as requested. + if ($time_log_ids) { + ttReportHelper::assignToTimesheet($timesheet_id, $time_log_ids); + } + // Re-display this form. + header('Location: report.php'); + exit(); + } } } // isPost -$options = ttReportHelper::getReportOptions($bean); - $report_items = ttReportHelper::getItems($options); // Store record ids in session in case user wants to act on records such as marking them all paid. if ($request->isGet() && $use_checkboxes) -- 2.20.1
- + +
{$i18n.form.report.assign_to_invoice}: {$forms.reportViewForm.assign_invoice_select_options.control} {$forms.reportViewForm.recent_invoice.control} {$forms.reportViewForm.btn_assign.control}
{$i18n.form.report.assign_to_invoice}: {$forms.reportViewForm.assign_invoice_select_options.control} {$forms.reportViewForm.recent_invoice.control} {$forms.reportViewForm.btn_assign_invoice.control}
+
+ +
{$i18n.form.report.assign_to_timesheet}: {$forms.reportViewForm.assign_timesheet_select_options.control} {$forms.reportViewForm.timesheet.control} {$forms.reportViewForm.btn_assign_timesheet.control}