X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=WEB-INF%2Flib%2FttReportHelper.class.php;h=5fd2253177e36ad094b0c54a6ba1104cf1757d73;hb=87a40bf7dc910c008aa6aadf8882b070ad120c39;hp=c455486104d63537e73a6a9b489966d3dae6a188;hpb=9857411f4fd9eb9275d0df54565db6aa7edcd029;p=timetracker.git diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index c4554861..5fd22531 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -30,6 +30,7 @@ import('ttClientHelper'); import('DateAndTime'); import('Period'); import('ttTimeHelper'); +import('ttConfigHelper'); require_once(dirname(__FILE__).'/../../plugins/CustomFields.class.php'); @@ -107,12 +108,6 @@ class ttReportHelper { $group_id = $user->getGroup(); $org_id = $user->org_id; - // A shortcut for timesheets. - if ($options['timesheet_id']) { - $where = " where ei.timesheet_id = ".$options['timesheet_id']." and ei.group_id = $group_id and ei.org_id = $org_id"; - return $where; - } - // Prepare dropdown parts. $dropdown_parts = ''; if ($options['client_id']) @@ -122,8 +117,9 @@ class ttReportHelper { if ($options['project_id']) $dropdown_parts .= ' and ei.project_id = '.$options['project_id']; if ($options['invoice']=='1') $dropdown_parts .= ' and ei.invoice_id is not null'; if ($options['invoice']=='2') $dropdown_parts .= ' and ei.invoice_id is null'; - if ($options['timesheet']==TIMESHEET_NOT_ASSIGNED) $dropdown_parts .= ' and ei.timesheet_id is null'; - if ($options['timesheet']==TIMESHEET_ASSIGNED) $dropdown_parts .= ' and ei.timesheet_id is not null'; + if (isset($options['timesheet']) && ($options['timesheet']!=TIMESHEET_ALL && $options['timesheet']!=TIMESHEET_NOT_ASSIGNED)) { + $dropdown_parts .= ' and 0 = 1'; // Expense items do not have a timesheet_id. + } if ($options['approved']=='1') $dropdown_parts .= ' and ei.approved = 1'; if ($options['approved']=='2') $dropdown_parts .= ' and ei.approved = 0'; if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; @@ -159,6 +155,9 @@ class ttReportHelper { global $user; $mdb2 = getConnection(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + // Determine these once as they are used in multiple places in this function. $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); $isClient = $user->isClient(); @@ -256,6 +255,9 @@ class ttReportHelper { // Add timesheet name if it is selected. if ($options['show_timesheet']) array_push($fields, 'ts.name as timesheet_name'); + // Add has_files. + if ($options['show_files']) + array_push($fields, 'if(Sub1.entity_id is null, 0, 1) as has_files'); // Prepare sql query part for left joins. $left_joins = null; @@ -279,17 +281,22 @@ class ttReportHelper { } if ($includeCost && MODE_TIME != $trackingMode) $left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; + if ($options['show_files']) { + $left_joins .= " left join (select distinct entity_id from tt_files". + " where entity_type = 'time' and group_id = $group_id and org_id = $org_id and status = 1) Sub1". + " on (l.id = Sub1.entity_id)"; + } // Prepare sql query part for inner joins. $inner_joins = null; if ($user->isPluginEnabled('ts')) { $timesheet_option = $options['timesheet']; if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 1)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 1)"; else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 0)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 0)"; else if ($options['show_timesheet']) $inner_joins .= " left join tt_timesheets ts on (l.timesheet_id = ts.id)"; // Left join for timesheet nme. } @@ -353,7 +360,10 @@ class ttReportHelper { if (($canViewReports || $isClient) && $options['show_invoice']) array_push($fields, 'i.name as invoice'); if ($options['show_timesheet']) - array_push($fields, 'ts.name as timesheet_name'); + array_push($fields, 'null as timesheet_name'); + // Add has_files. + if ($options['show_files']) + array_push($fields, 'if(Sub1.entity_id is null, 0, 1) as has_files'); // Prepare sql query part for left joins. $left_joins = null; @@ -365,25 +375,16 @@ class ttReportHelper { $left_joins .= " left join tt_projects p on (p.id = ei.project_id)"; if (($canViewReports || $isClient) && $options['show_invoice']) $left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)"; - - // Prepare sql query part for inner joins. - $inner_joins = null; - if ($user->isPluginEnabled('ts')) { - $timesheet_option = $options['timesheet']; - if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; - else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 1)"; - else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 0)"; - else if ($options['show_timesheet']) - $inner_joins .= " left join tt_timesheets ts on (ei.timesheet_id = ts.id)"; // Left join for timesheet name. + if ($options['show_files']) { + $left_joins .= " left join (select distinct entity_id from tt_files". + " where entity_type = 'expense' and group_id = $group_id and org_id = $org_id and status = 1) Sub1". + " on (ei.id = Sub1.entity_id)"; } $where = ttReportHelper::getExpenseWhere($options); // Construct sql query for expense items. - $sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $inner_joins $where"; + $sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $where"; // Construct a union. $sql = "($sql) union all ($sql_for_expense_items)"; @@ -512,7 +513,7 @@ class ttReportHelper { $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) die($res->getMessage()); while ($val = $res->fetchRow()) { - $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null; + $time = $val['time'] ? ttTimeHelper::minutesToDuration($val['time'] / 60) : null; $rowLabel = ttReportHelper::makeGroupByLabel($val['group_field'], $options); if ($options['show_cost']) { $decimalMark = $user->getDecimalMark(); @@ -566,32 +567,21 @@ class ttReportHelper { if ($user->isPluginEnabled('ts') && $options['timesheet']) { $timesheet_option = $options['timesheet']; if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 1)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 1)"; else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 0)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 0)"; } // Prepare a query for time items. $sql = "select $time_part $units_part $cost_part from tt_log l $left_joins $inner_joins $where"; // If we have expenses, query becomes a bit more complex. if ($options['show_cost'] && $user->isPluginEnabled('ex')) { - // Prepare sql query part for inner joins. - $inner_joins = null; - if ($user->isPluginEnabled('ts') && $options['timesheet']) { - $timesheet_option = $options['timesheet']; - if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; - else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 1)"; - else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 0)"; - } $where = ttReportHelper::getExpenseWhere($options); $sql_for_expenses = "select null as time"; if ($options['show_work_units']) $sql_for_expenses .= ", null as units"; - $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $inner_joins $where"; + $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; // Create a combined query. $combined = "select sum(time) as time"; @@ -605,7 +595,7 @@ class ttReportHelper { if (is_a($res, 'PEAR_Error')) die($res->getMessage()); $val = $res->fetchRow(); - $total_time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null; + $total_time = $val['time'] ? ttTimeHelper::minutesToDuration($val['time'] / 60) : null; if ($options['show_cost']) { $total_cost = $val['cost']; if (!$total_cost) $total_cost = '0.00'; @@ -659,6 +649,37 @@ 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) { + // 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". // 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). + " 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; @@ -715,6 +736,10 @@ class ttReportHelper { $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); $isClient = $user->isClient(); + $config = new ttConfigHelper($user->getConfig()); + $show_note_column = $options['show_note'] && !$config->getDefinedValue('report_note_on_separate_row'); + $show_note_row = $options['show_note'] && $config->getDefinedValue('report_note_on_separate_row'); + $items = ttReportHelper::getItems($options); $grouping = ttReportHelper::grouping($options); if ($grouping) @@ -737,6 +762,24 @@ class ttReportHelper { $cellLeftAlignedSubtotal = 'font-weight: bold; text-align: left; vertical-align: top;'; $cellRightAlignedSubtotal = 'font-weight: bold; text-align: right; vertical-align: top;'; + // Determine column span for note field. + $colspan = 1; + if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $colspan++; + if ($options['show_client']) $colspan++; + if ($options['show_project']) $colspan++; + if ($options['show_task']) $colspan++; + if ($options['show_custom_field_1']) $colspan++; + if ($options['show_start']) $colspan++; + if ($options['show_end']) $colspan++; + if ($options['show_duration']) $colspan++; + if ($options['show_work_units']) $colspan++; + if ($options['show_cost']) $colspan++; + if ($options['show_approved']) $colspan++; + if ($options['show_paid']) $colspan++; + if ($options['show_ip']) $colspan++; + if ($options['show_invoice']) $colspan++; + if ($options['show_timesheet']) $colspan++; + // Start creating email body. $body = ''; $body .= ''; @@ -830,7 +873,7 @@ class ttReportHelper { $body .= ''.$i18n->get('label.duration').''; if ($options['show_work_units']) $body .= ''.$i18n->get('label.work_units_short').''; - if ($options['show_note']) + if ($show_note_column) $body .= ''.$i18n->get('label.note').''; if ($options['show_cost']) $body .= ''.$i18n->get('label.cost').''; @@ -878,7 +921,7 @@ class ttReportHelper { if ($options['show_end']) $body .= ''; if ($options['show_duration']) $body .= ''.$subtotals[$prev_grouped_by]['time'].''; if ($options['show_work_units']) $body .= ''.$subtotals[$prev_grouped_by]['units'].''; - if ($options['show_note']) $body .= ''; + if ($show_note_column) $body .= ''; if ($options['show_cost']) { $body .= ''; $body .= ($canViewReports || $isClient) ? $subtotals[$prev_grouped_by]['cost'] : $subtotals[$prev_grouped_by]['expenses']; @@ -918,7 +961,7 @@ class ttReportHelper { $body .= ''.$record['duration'].''; if ($options['show_work_units']) $body .= ''.$record['units'].''; - if ($options['show_note']) + if ($show_note_column) $body .= ''.htmlspecialchars($record['note']).''; if ($options['show_cost']) $body .= ''.$record['cost'].''; @@ -942,7 +985,12 @@ class ttReportHelper { if ($options['show_timesheet']) $body .= ''.htmlspecialchars($record['timesheet']).''; $body .= ''; - + if ($show_note_row && $record['note']) { + $body .= ''; + $body .= ''.$i18n->get('label.note').':'; + $body .= ''.$record['note'].''; + $body .= ''; + } $prev_date = $record['date']; if ($print_subtotals) $prev_grouped_by = $record['grouped_by']; @@ -963,7 +1011,7 @@ class ttReportHelper { if ($options['show_end']) $body .= ''; if ($options['show_duration']) $body .= ''.$subtotals[$cur_grouped_by]['time'].''; if ($options['show_work_units']) $body .= ''.$subtotals[$cur_grouped_by]['units'].''; - if ($options['show_note']) $body .= ''; + if ($show_note_column) $body .= ''; if ($options['show_cost']) { $body .= ''; $body .= ($canViewReports || $isClient) ? $subtotals[$cur_grouped_by]['cost'] : $subtotals[$cur_grouped_by]['expenses']; @@ -990,7 +1038,7 @@ class ttReportHelper { if ($options['show_end']) $body .= ''; if ($options['show_duration']) $body .= ''.$totals['time'].''; if ($options['show_work_units']) $body .= ''.$totals['units'].''; - if ($options['show_note']) $body .= ''; + if ($show_note_column) $body .= ''; if ($options['show_cost']) { $body .= ''.htmlspecialchars($user->currency).' '; $body .= ($canViewReports || $isClient) ? $totals['cost'] : $totals['expenses']; @@ -1107,7 +1155,18 @@ class ttReportHelper { if ($user->isPluginEnabled('ap') && $user->isClient() && !$user->can('view_client_unapproved')) $options['approved'] = 1; // Restrict clients to approved records only. $options['timesheet'] = $bean->getAttribute('timesheet'); - if (is_array($bean->getAttribute('users'))) $options['users'] = join(',', $bean->getAttribute('users')); + + $active_users_in_bean = $bean->getAttribute('users_active'); + if ($active_users_in_bean && is_array($active_users_in_bean)) { + $users = join(',', $active_users_in_bean); + } + $inactive_users_in_bean = $bean->getAttribute('users_inactive'); + if ($inactive_users_in_bean && is_array($inactive_users_in_bean)) { + if ($users) $users .= ','; + $users .= join(',', $inactive_users_in_bean); + } + if ($users) $options['users'] = $users; + $options['period'] = $bean->getAttribute('period'); $options['period_start'] = $bean->getAttribute('start_date'); $options['period_end'] = $bean->getAttribute('end_date'); @@ -1126,6 +1185,7 @@ class ttReportHelper { $options['show_custom_field_1'] = $bean->getAttribute('chcf_1'); $options['show_work_units'] = $bean->getAttribute('chunits'); $options['show_timesheet'] = $bean->getAttribute('chtimesheet'); + $options['show_files'] = $bean->getAttribute('chfiles'); $options['show_totals_only'] = $bean->getAttribute('chtotalsonly'); $options['group_by1'] = $bean->getAttribute('group_by1'); $options['group_by2'] = $bean->getAttribute('group_by2'); @@ -1138,13 +1198,19 @@ class ttReportHelper { global $user; // Check users. - $users_in_bean = $bean->getAttribute('users'); - if (is_array($users_in_bean)) { + $active_users_in_bean = $bean->getAttribute('users_active'); + $inactive_users_in_bean = $bean->getAttribute('users_inactive'); + if (is_array($active_users_in_bean) || is_array($inactive_users_in_bean)) { $users_in_group = ttGroupHelper::getUsers(); foreach ($users_in_group as $user_in_group) { $valid_ids[] = $user_in_group['id']; } - foreach ($users_in_bean as $user_in_bean) { + foreach ($active_users_in_bean as $user_in_bean) { + if (!in_array($user_in_bean, $valid_ids)) { + return false; + } + } + foreach ($inactive_users_in_bean as $user_in_bean) { if (!in_array($user_in_bean, $valid_ids)) { return false; } @@ -1605,11 +1671,11 @@ class ttReportHelper { if ($user->isPluginEnabled('ts') && $options['timesheet']) { $timesheet_option = $options['timesheet']; if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.submit_status = 1 and ts.approve_status is null)"; else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 1)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 1)"; else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approval_status = 0)"; + $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 0)"; } $join .= $inner_joins; return $join; @@ -1658,18 +1724,6 @@ class ttReportHelper { if (ttReportHelper::groupingBy('project', $options)) { $join .= ' left join tt_projects p on (ei.project_id = p.id)'; } - // Prepare inner joins. - $inner_joins = null; - if ($user->isPluginEnabled('ts') && $options['timesheet']) { - $timesheet_option = $options['timesheet']; - if ($timesheet_option == TIMESHEET_PENDING) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.submit_status = 1 and ts.approval_status is null)"; - else if ($timesheet_option == TIMESHEET_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 1)"; - else if ($timesheet_option == TIMESHEET_NOT_APPROVED) - $inner_joins .= " inner join tt_timesheets ts on (ei.timesheet_id = ts.id and ts.approval_status = 0)"; - } - $join .= $inner_joins; return $join; }