.
*/
include('../../libraries/tcpdf/tcpdf.php');
class MYPDF extends TCPDF {
var $w = array();
var $print_time;
var $date_format;
var $time_format;
var $columns;
var $moneySum;
var $timeSum;
/**
* Format a unix timestamp as a date string.
* @param int $number unix timestamp
* @return string formatted string
*/
public function date($number) {
return strftime($this->date_format,$number);
}
/**
* Format a unix timestamp as a time string.
* @param int $number unix timestamp
* @return string formatted string
*/
public function time($number) {
if ($number == -1)
return "-------";
else
return strftime($this->time_format,$number);
}
/**
* Format the duration.
* @param int $number duration.
* @return duration nicely formatted
*/
public function timespan($number) {
global $kga;
if ($number == -1)
return "-------";
else
return str_replace(".",$kga['conf']['decimalSeparator'],sprintf("%01.2f",$number))." ".$kga['lang']['xp_ext']['duration_unit'];
}
/**
* Format an amount of money.
* @param int $number amount of money
* @return string formatted string
*/
public function money($number) {
return formatCurrency($number,false);
}
/**
* Create the array which hold the column widths. They depends on the maximum with
* the time column and the money column need.
* @param int $max_time_width maximum width the time column needs.
* @param int $max_time_width maximum width the time column needs.
* @return array containing the widths of the columns
*/
public function columnWidths($max_time_width,$max_money_width) {
return array($max_time_width,
$this->getPageWidth()-$this->pagedim[$this->page]['lm']-$this->pagedim[$this->page]['rm']-$max_time_width-$max_money_width,
$max_money_width);
}
/**
* Split the string in lines and check if a line would overflow and cause more lines.
* @param string $string Text to check.
* @param int $line_width
* @return int Number of lines the text will need.
*/
public function getHtmlStringLines($string,$line_width) {
$htmlLines = explode("
",$string);
$lineCount = count($htmlLines);
foreach ($htmlLines as $line) {
$lineCount += ceil($this->GetStringWidth($line)/$line_width);
}
return $lineCount;
}
/**
* Print a footer on every page.
*/
public function Footer() {
global $kga,$knd_data, $pct_data;
// Position at 1.5 cm from bottom
$this->SetY(-15);
// customer data
/*$this->SetFont('helvetica', '', 8); // Set font
$this->Cell(80, 10, $knd_data['knd_name'].' ('.$pct_data['pct_name'].')', 0, 0, 'L');*/
// Page number
$this->SetFont('helvetica', 'I', 8); // Set font
$this->Cell(30, 10, $kga['lang']['xp_ext']['page'].' '.$this->getAliasNumPage().'/'.$this->getAliasNbPages(), 0, 0, 'C');
//Datum
$this->SetFont('helvetica', '', 8); // Set font
$this->Cell(0, 10, date('d.m.Y H:i:s', $this->print_time), 0, 0, 'R');
}
/**
* Put a new entry into the PDF document. Decide if it's a time entry or
* expense entry and call the appropriate functions.
* @param array $columns array containing all fields which should be printed
* (Columns is misleading, but they were columns in the browser.)
* @param array $data the data of this entry
* @param array $widths the widths of the columns
*/
public function printRows($data,$widths) {
$this->moneySum = 0;
$this->timeSum = 0;
foreach($data as $row) {
if ($row['type'] == "exp") {
$this->printExpenseRow($widths,$row);
$this->moneySum+=$row['wage'];
}
else {
$this->printTimeRow($widths,$row);
$this->moneySum+=$row['wage'];
$this->timeSum +=$row['dec_zef_time']==-1?0:$row['dec_zef_time'];
}
}
}
/**
* Put a new expense entry into the PDF document.
* @param array $columns array containing all fields which should be printed
* (Columns is misleading, but they were columns in the browser.)
* @param array $w the widths of the columns
* @param array $row the data of this entry
*/
function printExpenseRow($w,$row) {
global $kga;
$date_string = '';
if (isset($this->columns['date']))
$date_string = $this->date($row['time_in']);
if (isset($this->columns['from']))
$date_string .= ' '.$this->time($row['time_in']);
$event_string = (isset($this->columns['action']) && !empty($row['evt_name'])) ? $kga['lang']['xp_ext']['expense'].': '.$row['evt_name'].'' : '';
$user_string = (isset($this->columns['user']) && !empty($row['username'])) ? $kga['lang']['xp_ext']['by'].': '.$row['username'].'' : '';
$comment_string = (isset($this->columns['comment']) && !empty($row['comment'])) ? $kga['lang']['comment'].': '.nl2br($row['comment']).'' : '';
$wage_string = ''.$this->money($row['wage']).'';
$event_fills_row = empty($user_string) || ($this->GetStringWidth($event_string)+$this->GetStringWidth($user_string) > $w[1]);
// Find out how many rows we use for this entry.
$field_rows = 2;
if (!empty($event_string) && !empty($user_string) && $event_fills_row)
$field_rows++;
if (empty($event_string) && empty($user_string))
$field_rows--;
if (empty($comment_string))
$field_rows--;
$probable_comment_lines = $this->GetHtmlStringLines($comment_string,$w[1]);
// check if page break is nessessary
if ($this->getPageHeight()-$this->pagedim[$this->page]['bm']-($this->getY()+($field_rows+$probable_comment_lines+4)*6) < 0) {
if (isset($this->columns['wage']) && isset($this->columns['dec_time'])) {
$this->ln();
$this->WriteHtmlCell($w[0]+$w[1]+$w[2], 6, $this->getX(),$this->getY(),$this->timespan($this->timeSum),'',0,0,true,'R');
$this->ln();
$this->WriteHtmlCell($w[0]+$w[1], 6, $this->getX(),$this->getY(),$kga['lang']['xp_ext']['subtotal'].':', '',0,0,true,'R');
$this->WriteHtmlCell($w[2], 6, $this->getX(),$this->getY(),$this->money($this->moneySum),'',0,0,true,'R');
} else if(isset($this->columns['wage'])) {
$this->ln();
$this->WriteHtmlCell($w[0]+$w[1], 6, $this->getX(),$this->getY(),$kga['lang']['xp_ext']['subtotal'].':', '',0,0,true,'R');
$this->WriteHtmlCell($w[2], 6, $this->getX(),$this->getY(),$this->money($this->moneySum),'',0,0,true,'R');
} else if(isset($this->columns['dec_time'])) {
$this->ln();
$this->WriteHtmlCell($w[0]+$w[1], 6, $this->getX(),$this->getY(),$kga['lang']['xp_ext']['subtotal'].':', '',0,0,true,'R');
$this->WriteHtmlCell($w[2], 6, $this->getX(),$this->getY(),$this->timespan($this->timeSum),'',0,0,true,'R');
}
$this->AddPage();
}
$this->ln();
$this->Cell($w[0], 6, $date_string, '', 0, 'R');
for ($i=0;$i<3;$i++) {
$handled_row = false;
switch ($i) {
case 0: // row with event or event and user
if ($event_fills_row && !empty($event_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$event_string, 'L');
$handled_row = true;
}
else if (!empty($event_string) && !empty($user_string)) {
$this->WriteHtmlCell($w[1]/2, 6, $this->getX(),$this->getY(),$event_string, 'L');
$this->WriteHtmlCell($w[1]/2, 6, $this->getX(),$this->getY(),$user_string, '');
$handled_row = true;
}
else if (!empty($user_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$user_string, 'L');
$handled_row = true;
}
break;
case 1: // row with user
if ($event_fills_row && !empty($user_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$user_string, 'L');
$handled_row = true;
}
break;
case 2: // row with comment
if (!empty($comment_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$comment_string, 'L');
$handled_row = true;
}
break;
}
if ($handled_row) {
$field_rows--;
if ($field_rows == 0) { // if this is the last row
$this->ln($this->getLastH());
$this->Cell($w[0], 6, '');
$this->Cell($w[1], 6, '','T');
if (isset($this->columns['wage'])) {
$this->WriteHtmlCell($w[2], 6, $this->getX(),$this->getY()-$this->getLastH(),$wage_string, '',0,0,true,'R');
}
$this->ln();
//$this->ln();
break; // leave for loop
}
else {
$this->ln();
$this->Cell($w[0],6,'');
}
}
}
}
/**
* Put a new time entry into the PDF document.
* @param array $columns array containing all fields which should be printed
* (Columns is misleading, but they were columns in the browser.)
* @param array $w the widths of the columns
* @param array $row the data of this entry
*/
function printTimeRow($w,$row) {
global $kga;
$from_date_string = '';
if (isset($this->columns['date']))
$from_date_string = $this->date($row['time_in']);
if (isset($this->columns['from']))
$from_date_string .= ' '.$this->time($row['time_in']);
$to_date_string = '';
if (isset($this->columns['to'])) {
if (isset($this->columns['date']))
$to_date_string = $this->date($row['time_out']);
$to_date_string .= ' '.$this->time($row['time_out']);
}
if (isset($this->columns['action']) && !empty($row['evt_name']))
$event_string = $kga['lang']['evt'].': '.$row['evt_name'].'';
else
$event_string = '';
if (isset($this->columns['user']) && !empty($row['username']))
$user_string = $kga['lang']['xp_ext']['done_by'].': '.$row['username'].'';
else
$user_string = '';
if (isset($this->columns['location']) && !empty($row['location']))
$location_string = $kga['lang']['zlocation'].': '.$row['location'].'';
else
$location_string = '';
if (isset($this->columns['trackingnr']) && !empty($row['trackingnr']))
$trackingnr_string = $kga['lang']['trackingnr'].': '.$row['trackingnr'].'';
else
$trackingnr_string = '';
if (isset($this->columns['comment']) && !empty($row['comment']))
$comment_string = $kga['lang']['comment'].': '.nl2br($row['comment']).'';
else
$comment_string = '';
if (isset($this->columns['time']) && !empty($row['zef_duration']))
$time_string = $kga['lang']['xp_ext']['duration'].': '.$row['zef_duration'].' '.$kga['lang']['xp_ext']['duration_unit'].'';
else
$time_string = '';
if (isset($this->columns['rate']) && !empty($row['zef_rate']))
$rate_string = $kga['lang']['rate'].': '.$row['zef_rate'].'';
else
$rate_string = '';
if (isset($this->columns['wage']) && !empty($row['wage']))
$wage_string = ''.$this->money($row['wage']).'';
else
$wage_string = '';
$event_fills_row = empty($user_string) || ($this->GetStringWidth($event_string)+$this->GetStringWidth($user_string) > $w[1]);
$field_rows = 4; // number of rows in block of values
if (!empty($event_string) && !empty($user_string) && $event_fills_row)
$field_rows++;
if (empty($event_string) && empty($user_string))
$field_rows--;
if (empty($location_string) && empty($trackingnr_string))
$field_rows--;
if (empty($comment_string))
$field_rows--;
if (empty($time_string) && empty($rate_string))
$field_rows--;
$probable_comment_lines = $this->getHtmlStringLines($comment_string,$w[1]);
// check if page break is nessessary
if ($this->getPageHeight()-$this->pagedim[$this->page]['bm']-($this->getY()+($field_rows+$probable_comment_lines+4)*6) < 0) {
if (isset($this->columns['wage']) && isset($this->columns['dec_time'])) {
$this->ln();
$this->WriteHtmlCell($w[0]+$w[1]+$w[2], 6, $this->getX(),$this->getY(),$this->timespan($this->timeSum),'',0,0,true,'R');
$this->ln();
$this->WriteHtmlCell($w[0]+$w[1], 6, $this->getX(),$this->getY(),$kga['lang']['xp_ext']['subtotal'].':', '',0,0,true,'R');
$this->WriteHtmlCell($w[2], 6, $this->getX(),$this->getY(),$this->money($this->moneySum),'',0,0,true,'R');
} else if(isset($this->columns['wage'])) {
$this->ln();
$this->WriteHtmlCell($w[0]+$w[1], 6, $this->getX(),$this->getY(),$kga['lang']['xp_ext']['subtotal'].':', '',0,0,true,'R');
$this->WriteHtmlCell($w[2], 6, $this->getX(),$this->getY(),$this->money($this->moneySum),'',0,0,true,'R');
} else if(isset($this->columns['dec_time'])) {
$this->ln();
$this->WriteHtmlCell($w[0]+$w[1], 6, $this->getX(),$this->getY(),$kga['lang']['xp_ext']['subtotal'].':', '',0,0,true,'R');
$this->WriteHtmlCell($w[2], 6, $this->getX(),$this->getY(),$this->timespan($this->timeSum),'',0,0,true,'R');
}
$this->AddPage();
}
$this->ln();
$this->Cell($w[0], 6, $from_date_string, '', 0, 'R');
for ($i=0;$i<5;$i++) {
$handled_row = false;
switch ($i) {
case 0: // row with event or event and user
if ($event_fills_row && !empty($event_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$event_string, 'L');
$handled_row = true;
}
else if (!empty($event_string) && !empty($user_string)) {
$this->WriteHtmlCell($w[1]/2, 6, $this->getX(),$this->getY(),$event_string, 'L');
$this->WriteHtmlCell($w[1]/2, 6, $this->getX(),$this->getY(),$user_string, '');
$handled_row = true;
}
else if (!empty($user_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$user_string, 'L');
$handled_row = true;
}
break;
case 1: // row with user
if ($event_fills_row && !empty($user_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$user_string, 'L');
$handled_row = true;
}
break;
case 2: // row with location and/or tracking number
if (!empty($location_string) && empty($trackingnr_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$location_string, 'L');
$handled_row = true;
}
else if (empty($location_string) && !empty($trackingnr_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$trackingnr_string, 'L');
$handled_row = true;
}
else if (!empty($location_string) && !empty($trackingnr_string)) {
$this->WriteHtmlCell($w[1]/2, 6, $this->getX(),$this->getY(),$location_string, 'L');
$this->WriteHtmlCell($w[1]/2, 6, $this->getX(),$this->getY(),$trackingnr_string, '');
$handled_row = true;
}
break;
case 3: // row with comment
if (!empty($comment_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$comment_string, 'L');
$handled_row = true;
}
break;
case 4: // row with time and/or rate
if (!empty($time_string) && empty($rate_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$time_string, 'L');
$handled_row = true;
}
else if (empty($time_string) && !empty($rate_string)) {
$this->WriteHtmlCell($w[1], 6, $this->getX(),$this->getY(),$rate_string, 'L');
$handled_row = true;
}
else if (!empty($time_string) && !empty($rate_string)) {
$this->WriteHtmlCell($w[1]/2, 6, $this->getX(),$this->getY(),$time_string, 'L');
$this->WriteHtmlCell($w[1]/2, 6, $this->getX(),$this->getY(),$rate_string, '');
$handled_row = true;
}
break;
}
if ($handled_row) {
$field_rows--;
if ($field_rows == 0) { // if this is the last row
$this->ln($this->getLastH());
$this->Cell($w[0], 6, '');
$this->Cell($w[1], 6, '','T');
$this->WriteHtmlCell($w[2], 6, $this->getX(),$this->getY()-$this->getLastH(),$wage_string, '',0,0,true,'R');
$this->ln();
//$this->ln();
break; // leave for loop
}
else {
$this->ln();
$this->Cell($w[0],6,'');
}
}
}
}
/**
* Print a header of the summarization table.
* @param array $w widths of the columns
* @param array $headers name of the column headers
*/
public function printHeader($w,$header) {
// Colors, line width and bold font
$this->SetFillColor(240, 240, 240);
$this->SetTextColor(0);
$this->SetDrawColor(0,0,0);
$this->SetLineWidth(0.3);
$this->SetFont('', 'B');
for($i = 0; $i < count($header); $i++) {
if ($w[$i] <= 0) continue;
$this->Cell($w[$i], 7, $header[$i], 1, 0, 'C', 1);
}
$this->Ln();
}
/**
* Print the summarization table.
* @param array $headers name of the column headers
* @param array $data summarized data to print
*/
public function ColoredTable_result($header,$data) {
global $kga;
$w = array($this->getPageWidth()-$this->pagedim[$this->page]['lm']-$this->pagedim[$this->page]['rm'],0,0);
if (isset($this->columns['wage'])) {
$w[2] = 30;
$w[0] -= 30;
}
if (isset($this->columns['dec_time'])) {
$w[1] = 30;
$w[0] -= 30;
}
// Header
$this->printHeader($w,$header);
// Color and font restoration
$this->SetFillColor(224, 235, 255);
$this->SetTextColor(0);
$this->SetFont('');
// Data
$fill = 0;
$sum = 0;
$sum_time = 0;
foreach($data as $row) {
// check if page break is nessessary
if ($this->getPageHeight()-$this->pagedim[$this->page]['bm']-($this->getY()+20) < 0) {
$this->Cell(array_sum($w), 0, '', 'T');
$this->Ln();
$this->Cell($w[0], 6, $kga['lang']['xp_ext']['subtotal'].':', '', 0, 'R', false);
if (isset($this->columns['dec_time']))
$this->Cell($w[1], 6, $this->timespan($sum_time), isset($this->columns['wage'])?'R':'', 0, 'R', true);
if (isset($this->columns['wage']))
$this->Cell($w[2], 6, $this->money($sum), 'L', 0, 'R', true);
$this->Ln();
$this->AddPage();
$this->printHeader($w,$header);
// Color and font restoration
$this->SetFillColor(224, 235, 255);
$this->SetTextColor(0);
$this->SetFont('');
}
$this->Cell($w[0], 6, $row['name'], 'LR', 0, 'L', $fill);
if (isset($this->columns['dec_time']))
$this->Cell($w[1], 6, $this->timespan($row['time']), 'LR', 0, 'R', $fill);
if (isset($this->columns['wage']))
$this->Cell($w[2], 6, $this->money($row['wage']), 'LR', 0, 'R', $fill);
$this->Ln();
$fill=!$fill;
$sum+=$row['wage'];
$sum_time += $row['time']==-1?0:$row['time'];
}
$this->Cell(array_sum($w), 0, '', 'T');
$this->Ln();
$this->Cell($w[0], 6, $kga['lang']['xp_ext']['finalamount'].':', '', 0, 'R', false);
$this->SetFont('', 'B');
if (isset($this->columns['dec_time']))
$this->Cell($w[1], 6, $this->timespan($sum_time), isset($this->columns['wage'])?'R':'', 0, 'R', false);
if (isset($this->columns['wage']))
$this->Cell($w[2], 6, $this->money($sum), 'L', 0, 'R', false);
$this->SetFont('');
}
}
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->columns = $columns;
$pdf->date_format = $dateformat;
$pdf->time_format = $timeformat;
$pdf->print_time = time();
$pdf->SetDisplayMode('default', 'continuous'); //PDF-Seitenanzeige fortlaufend
// determine page title
switch ($filter_type) {
case 0:
$pdf_title = $kga['lang']['xp_ext']['pdf_headline_only_times'];
break;
case 1:
$pdf_title = $kga['lang']['xp_ext']['pdf_headline_only_expenses'];
break;
case -1:
default:
$pdf_title = $kga['lang']['xp_ext']['pdf_headline'];
}
// determine filter values
switch ($filter_cleared) {
case 0:
$pdf_filter[] = $kga['lang']['xp_ext']['cleared_open'];
break;
case 1:
$pdf_filter[] = $kga['lang']['xp_ext']['cleared_cleared'];
break;
}
switch ($filter_refundable) {
case 0:
$pdf_filter[] = $kga['lang']['xp_ext']['refundable_refundable'];
break;
case 1:
$pdf_filter[] = $kga['lang']['xp_ext']['refundable_not_refundable'];
break;
}
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetTitle($pdf_title);
$pdf->setPrintHeader(false);
$pdf->AddPage();
$pdf->setFont('helvetica');
if (isset($_REQUEST['create_bookmarks']))
$pdf->Bookmark($pdf_title, 0, 0);
//$pdf->ImageEps('kimai-logo.ai', 0, 10, 60, 0, "http://www.kimai.org", true, 'T', 'R'); // include company logo
$pdf->WriteHtml('