isPluginEnabled('cf')) { require_once('plugins/CustomFields.class.php'); $custom_fields = new CustomFields(); } // Report settings are stored in session bean before we get here. $bean = new ActionForm('reportBean', new Form('reportForm'), $request); $config = new ttConfigHelper($user->getConfig()); $show_note_column = $bean->getAttribute('chnote') && !$config->getDefinedValue('report_note_on_separate_row'); $show_note_row = $bean->getAttribute('chnote') && $config->getDefinedValue('report_note_on_separate_row'); // There are 2 variations of report: totals only, or normal. Totals only means that the report // is grouped by either date, user, client, project, task or cf_1 and user only needs to see subtotals by group. $totals_only = ($bean->getAttribute('chtotalsonly') == '1'); // Obtain items for report. $options = ttReportHelper::getReportOptions($bean); $grouping = ttReportHelper::grouping($options); if (!$totals_only) $items = ttReportHelper::getItems($options); // Individual entries. if ($totals_only || $grouping) $subtotals = ttReportHelper::getSubtotals($options); // Subtotals for groups of items. $totals = ttReportHelper::getTotals($options); // Totals for the entire report. // Assign variables that are used to print subtotals. if ($items && $grouping) { $print_subtotals = true; $first_pass = true; $prev_grouped_by = ''; $cur_grouped_by = ''; } // Build a string to use as filename for the files being downloaded. $filename = strtolower($i18n->get('title.report')).'_'.$bean->mValues['start_date'].'_'.$bean->mValues['end_date']; // Start preparing HTML to build PDF from. $styleHeader = 'style="background-color:#a6ccf7;"'; $styleSubtotal = 'style="background-color:#e0e0e0;"'; $styleCentered = 'style="text-align:center;"'; $styleRightAligned = 'style="text-align:right;"'; $title = $i18n->get('title.report').": ".$totals['start_date']." - ".$totals['end_date']; $html = '

'.$title.'

'; $html .= ''; if ($totals_only) { // We are building a "totals only" report with only subtotals and total. $group_by_header = ttReportHelper::makeGroupByHeader($options); $colspan = 1; // Column span for an empty row. // Table header. $html .= ''; $html .= ""; $html .= ''; if ($bean->getAttribute('chduration')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chunits')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chcost')) { $colspan++; $html .= "'; } $html .= ''; $html .= ''; // Print subtotals. foreach ($subtotals as $subtotal) { $html .= ''; $html .= ''; if ($bean->getAttribute('chduration')) $html .= "'; if ($bean->getAttribute('chunits')) $html .= "'; if ($bean->getAttribute('chcost')) { $html .= "'; } $html .= ''; } // Print totals. $html .= ''; $html .= ""; $html .= ''; if ($bean->getAttribute('chduration')) $html .= "'; if ($bean->getAttribute('chunits')) $html .= "'; if ($bean->getAttribute('chcost')) { $html .= "'; } $html .= ''; $html .= '
'.htmlspecialchars($group_by_header).'".$i18n->get('label.duration').'".$i18n->get('label.work_units_short').'".$i18n->get('label.cost').'
'.htmlspecialchars($subtotal['name']).'".$subtotal['time'].'".$subtotal['units'].'"; if ($user->can('manage_invoices') || $user->isClient()) $html .= $subtotal['cost']; else $html .= $subtotal['expenses']; $html .= '
 
'.$i18n->get('label.total').'".$totals['time'].'".$totals['units'].'"; $html .= htmlspecialchars($user->currency).' '; if ($user->can('manage_invoices') || $user->isClient()) $html .= $totals['cost']; else $html .= $totals['expenses']; $html .= '
'; } else { // We are building a normal report with items, optionally grouped with subtotals, and total. $colspan = 1; // Column span for an empty row. // Table header. $html .= ''; $html .= ""; $html .= ''.$i18n->get('label.date').''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { $colspan++; $html .= ''.$i18n->get('label.user').''; } if ($bean->getAttribute('chclient')) { $colspan++; $html .= ''.$i18n->get('label.client').''; } if ($bean->getAttribute('chproject')) { $colspan++; $html .= ''.$i18n->get('label.project').''; } if ($bean->getAttribute('chtask')) { $colspan++; $html .= ''.$i18n->get('label.task').''; } if ($bean->getAttribute('chcf_1')) { $colspan++; $html .= ''.htmlspecialchars($custom_fields->fields[0]['label']).''; } if ($bean->getAttribute('chstart')) { $colspan++; $html .= "".$i18n->get('label.start').''; } if ($bean->getAttribute('chfinish')) { $colspan++; $html .= "".$i18n->get('label.finish').''; } if ($bean->getAttribute('chduration')) { $colspan++; $html .= "".$i18n->get('label.duration').''; } if ($bean->getAttribute('chunits')) { $colspan++; $html .= "".$i18n->get('label.work_units_short').''; } if ($show_note_column) { $colspan++; $html .= ''.$i18n->get('label.note').''; } if ($bean->getAttribute('chcost')) { $colspan++; $html .= "".$i18n->get('label.cost').''; } if ($bean->getAttribute('chapproved')) { $colspan++; $html .= "".$i18n->get('label.approved').''; } if ($bean->getAttribute('chpaid')) { $colspan++; $html .= "".$i18n->get('label.paid').''; } if ($bean->getAttribute('chip')) { $colspan++; $html .= "".$i18n->get('label.ip').''; } if ($bean->getAttribute('chinvoice')) { $colspan++; $html .= ''.$i18n->get('label.invoice').''; } if ($bean->getAttribute('chtimesheet')) { $colspan++; $html .= ''.$i18n->get('label.timesheet').''; } $html .= ''; $html .= ''; foreach ($items as $item) { // Print a subtotal for a block of grouped values. $cur_date = $item['date']; if ($print_subtotals) { $cur_grouped_by = $item['grouped_by']; if ($cur_grouped_by != $prev_grouped_by && !$first_pass) { $html .= ''; $html .= ''.$i18n->get('label.subtotal').''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { $html .= ''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['user']); $html .= ''; } if ($bean->getAttribute('chclient')) { $html .= ''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['client']); $html .= ''; } if ($bean->getAttribute('chproject')) { $html .= ''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['project']); $html .= ''; } if ($bean->getAttribute('chtask')) { $html .= ''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['task']); $html .= ''; } if ($bean->getAttribute('chcf_1')) { $html .= ''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['cf_1']); $html .= ''; } if ($bean->getAttribute('chstart')) $html .= ''; if ($bean->getAttribute('chfinish')) $html .= ''; if ($bean->getAttribute('chduration')) $html .= "".$subtotals[$prev_grouped_by]['time'].''; if ($bean->getAttribute('chunits')) $html .= "".$subtotals[$prev_grouped_by]['units'].''; if ($show_note_column) $html .= ''; if ($bean->getAttribute('chcost')) { $html .= ""; if ($user->can('manage_invoices') || $user->isClient()) $html .= $subtotals[$prev_grouped_by]['cost']; else $html .= $subtotals[$prev_grouped_by]['expenses']; $html .= ''; } if ($bean->getAttribute('chapproved')) $html .= ''; if ($bean->getAttribute('chpaid')) $html .= ''; if ($bean->getAttribute('chip')) $html .= ''; if ($bean->getAttribute('chinvoice')) $html .= ''; if ($bean->getAttribute('chtimesheet')) $html .= ''; $html .= ''; $html .= ' '; // TODO: page breaks on PDF reports is a rarely used feature. // Currently without configuration capability. // Consider adding an option to user profile instead. if (isTrue('PDF_REPORT_PAGE_BREAKS')) { import('ttUserConfig'); $uc = new ttUserConfig(); $use_breaks = $uc->getValue(SYSC_PDF_REPORT_PAGE_BREAKS); if ($use_breaks) $html .= '
'; } } $first_pass = false; } // Print a regular row. $html .= ''; $html .= ''.$item['date'].''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $html .= ''.htmlspecialchars($item['user']).''; if ($bean->getAttribute('chclient')) $html .= ''.htmlspecialchars($item['client']).''; if ($bean->getAttribute('chproject')) $html .= ''.htmlspecialchars($item['project']).''; if ($bean->getAttribute('chtask')) $html .= ''.htmlspecialchars($item['task']).''; if ($bean->getAttribute('chcf_1')) $html .= ''.htmlspecialchars($item['cf_1']).''; if ($bean->getAttribute('chstart')) $html .= "".$item['start'].''; if ($bean->getAttribute('chfinish')) $html .= "".$item['finish'].''; if ($bean->getAttribute('chduration')) $html .= "".$item['duration'].''; if ($bean->getAttribute('chunits')) $html .= "".$item['units'].''; if ($show_note_column) $html .= ''.htmlspecialchars($item['note']).''; if ($bean->getAttribute('chcost')) { $html .= ""; if ($user->can('manage_invoices') || $user->isClient()) $html .= $item['cost']; else $html .= $item['expense']; $html .= ''; } if ($bean->getAttribute('chapproved')) { $html .= ''; $html .= $item['approved'] == 1 ? $i18n->get('label.yes') : $i18n->get('label.no'); $html .= ''; } if ($bean->getAttribute('chpaid')) { $html .= ''; $html .= $item['paid'] == 1 ? $i18n->get('label.yes') : $i18n->get('label.no'); $html .= ''; } if ($bean->getAttribute('chip')) { $html .= ''; $html .= $item['modified'] ? $item['modified_ip'].' '.$item['modified'] : $item['created_ip'].' '.$item['created']; $html .= ''; } if ($bean->getAttribute('chinvoice')) $html .= ''.htmlspecialchars($item['invoice']).''; if ($bean->getAttribute('chtimesheet')) $html .= ''.htmlspecialchars($item['timesheet_name']).''; $html .= ''; if ($show_note_row && $item['note']) { $html .= ''; $html .= "".$i18n->get('label.note').''; $noteSpan = $colspan-1; $html .= ''.htmlspecialchars($item['note']).''; $html .= ''; } $prev_date = $item['date']; if ($print_subtotals) $prev_grouped_by = $item['grouped_by']; } // Print a terminating subtotal. if ($print_subtotals) { $html .= ''; $html .= ''.$i18n->get('label.subtotal').''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { $html .= ''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['user']); $html .= ''; } if ($bean->getAttribute('chclient')) { $html .= ''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['client']); $html .= ''; } if ($bean->getAttribute('chproject')) { $html .= ''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['project']); $html .= ''; } if ($bean->getAttribute('chtask')) { $html .= ''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['task']); $html .= ''; } if ($bean->getAttribute('chcf_1')) { $html .= ''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['cf_1']); $html .= ''; } if ($bean->getAttribute('chstart')) $html .= ''; if ($bean->getAttribute('chfinish')) $html .= ''; if ($bean->getAttribute('chduration')) $html .= "".$subtotals[$prev_grouped_by]['time'].''; if ($bean->getAttribute('chunits')) $html .= "".$subtotals[$prev_grouped_by]['units'].''; if ($show_note_column) $html .= ''; if ($bean->getAttribute('chcost')) { $html .= ""; if ($user->can('manage_invoices') || $user->isClient()) $html .= $subtotals[$prev_grouped_by]['cost']; else $html .= $subtotals[$prev_grouped_by]['expenses']; $html .= ''; } if ($bean->getAttribute('chapproved')) $html .= ''; if ($bean->getAttribute('chpaid')) $html .= ''; if ($bean->getAttribute('chip')) $html .= ''; if ($bean->getAttribute('chinvoice')) $html .= ''; if ($bean->getAttribute('chtimesheet')) $html .= ''; $html .= ''; } // Print totals. $html .= ' '; $html .= ''; $html .= ''.$i18n->get('label.total').''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $html .= ''; if ($bean->getAttribute('chclient')) $html .= ''; if ($bean->getAttribute('chproject')) $html .= ''; if ($bean->getAttribute('chtask')) $html .= ''; if ($bean->getAttribute('chcf_1')) $html .= ''; if ($bean->getAttribute('chstart')) $html .= ''; if ($bean->getAttribute('chfinish')) $html .= ''; if ($bean->getAttribute('chduration')) $html .= "".$totals['time'].''; if ($bean->getAttribute('chunits')) $html .= "".$totals['units'].''; if ($show_note_column) $html .= ''; if ($bean->getAttribute('chcost')) { $html .= "".htmlspecialchars($user->currency).' '; if ($user->can('manage_invoices') || $user->isClient()) $html .= $totals['cost']; else $html .= $totals['expenses']; $html .= ''; } if ($bean->getAttribute('chapproved')) $html .= ''; if ($bean->getAttribute('chpaid')) $html .= ''; if ($bean->getAttribute('chip')) $html .= ''; if ($bean->getAttribute('chinvoice')) $html .= ''; if ($bean->getAttribute('chtimesheet')) $html .= ''; $html .= ''; $html .= ''; } // Output footer. if (!defined('REPORT_FOOTER') || !(REPORT_FOOTER == false)) // By default we print it unless explicitely defined as false. $html .= '

'.$i18n->get('form.mail.footer').'

'; // By this time we have html ready. // Determine title for report. $title = $i18n->get('title.report').": ".$totals['start_date']." - ".$totals['end_date']; header('Pragma: public'); // This is needed for IE8 to download files over https. header('Content-Type: text/html; charset=utf-8'); header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); header('Cache-Control: no-store, no-cache, must-revalidate'); header('Cache-Control: post-check=0, pre-check=0', false); header('Cache-Control: private', false); header('Content-Type: application/pdf'); header('Content-Disposition: attachment; filename="'.$filename.'.pdf"'); // Beginning of TCPDF code here. // Extend TCPDF class so that we can use custom header and footer. class ttPDF extends TCPDF { public $image_file = 'images/tt_logo.png'; // Image file for the logo in header. public $page_word = 'Page'; // Localized "Page" word in footer, ex: Page 1/2. // SetImageFile - sets image file name. public function SetImageFile($imgFile) { $this->image_file = $imgFile; } // SetPageWord - sets page word for footer. public function SetPageWord($pageWord) { $this->page_word = $pageWord; } // Page header. public function Header() { // Print logo, which is the only element of our custom header. $this->Image($this->image_file, 10, 10, '', '', '', '', 'T', false, 300, 'C', false, false, 0, false, false, false); } // Page footer. public function Footer() { // Position at 15 mm from bottom. $this->SetY(-15); // Set font. $this->SetFont('freeserif', 'I', 8); // Print localized page number. $this->Cell(0, 10, $this->page_word.' '.$this->getAliasNumPage().'/'.$this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M'); } } // Create new PDF document. $pdf = new ttPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); // If custom logo file exists - set it. if (file_exists('images/'.$user->group_id.'.png')) $pdf->SetImageFile('images/'.$user->group_id.'.png'); // Set page word for the footer. $pdf->SetPageWord($i18n->get('label.page')); // Set document information. $pdf->SetCreator(PDF_CREATOR); $pdf->SetAuthor('Anuko Time Tracker'); $pdf->SetTitle('Anuko Time Tracker Report'); $pdf->SetSubject('Anuko Time Tracker Report'); $pdf->SetKeywords('Anuko, time, tracker, report'); // Set margins. $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); $pdf->SetHeaderMargin(PDF_MARGIN_HEADER); $pdf->SetFooterMargin(PDF_MARGIN_FOOTER); // Set auto page breaks. $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM); // Set image scale factor. $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); // Add a page. $pdf->AddPage(); // Set font (freeserif seems to work for all languages). $pdf->SetFont('freeserif', '', 10); // helvetica here does not work for Russian. // Write HTML. $pdf->writeHTML($html, true, false, false, false, ''); // Close and output PDF document. // $pdf->Output('timesheet.pdf', 'I'); // This will display inline in browser. $pdf->Output($filename.'.pdf', 'D'); // D is for downloads. // End of of TCPDF code.