Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Added new functionality to allow LaTeX generation of invoices. #875

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Further code improvements
simonschaufi committed Dec 10, 2016
commit a3fd2ff59be69d47b4f8b04c654b56bc2d51248d
59 changes: 35 additions & 24 deletions libraries/Kimai/Invoice/Checksum.php
Original file line number Diff line number Diff line change
@@ -24,65 +24,76 @@
* @author Gustav Johansson
*/

/**
* @param $type
* @param $id
* @param $args
* @return string
*/
function checksum($type, $id, $args)
{
switch ($type) {
case 'OCR':
return OCR($id, $args);
break;
break;
}
}


/**
* @param $id
* @param bool $addLength
* @return int|string
*/
function OCR($id, $addLength = true)
{
/**
* Calculates the checksum with length number according to the swedish OCR
* system. I.e., 123456 will have a length number added to it (including the
* length number itself and a checksum digit. The return invoice id will be
* a valid OCR-number: 12345682 where the next to last digit is the total
* length and the last digit is the checksum.
*/
* Calculates the checksum with length number according to the swedish OCR
* system. I.e., 123456 will have a length number added to it (including the
* length number itself and a checksum digit. The return invoice id will be
* a valid OCR-number: 12345682 where the next to last digit is the total
* length and the last digit is the checksum.
*/
//Check length. Max is 25 including checksum and length no.
if ($addLength) {
$max = 23;
$max = 23;
} else {
$max = 24;
$max = 24;
}
if (strlen($id) > $max) {
return -1;
}

//Calculate the length number (only last digit)
$len = (strlen($id) + 2) % 10;
$len = (strlen($id) + 2) % 10;
if ($addLength) {
$invoice = $id.$len;
$invoice = $id . $len;
} else {
$invoice = $id;
$invoice = $id;
}

//Calculate checksum
$inReverse = array_reverse(str_split($invoice));
$sum = 0;
$even = true;
$inReverse = array_reverse(str_split($invoice));
$sum = 0;
$even = true;
foreach ($inReverse as $num) {
if ($even) {
$even = false;
$tmp = $num * 2;
$even = false;
$tmp = $num * 2;
if ($tmp > 9) {
$tmp = $tmp - 9;
$tmp = $tmp - 9;
}
$sum = $sum + $tmp;
$sum = $sum + $tmp;
} else {
$even = true;
$sum = $sum + $num;
$even = true;
$sum = $sum + $num;
}
}
$check = 10 - ($sum % 10);
$check = 10 - ($sum % 10);
//Make sure we use 0 and not 10
if ($check == 10) {
$check = 0;
}
$checksum = $invoice.$check;
$checksum = $invoice . $check;

return $checksum;
}
121 changes: 64 additions & 57 deletions libraries/Kimai/Invoice/LaTeXRenderer.php
Original file line number Diff line number Diff line change
@@ -33,95 +33,103 @@ class Kimai_Invoice_LaTeXRenderer extends Kimai_Invoice_AbstractRenderer
*/
public function render()
{
//Setup
Kimai_Logger::logfile("Rendering LaTeX invoice!");
$vault = $this->getTemporaryDirectory();
$dateFormat = "%B %e, %Y";
$templateDir = $this->getTemplateDir().$this->getTemplateFile();
global $kga;

Kimai_Logger::logfile('Rendering LaTeX invoice!');
$tempDir = $this->getTemporaryDirectory();
$dateFormat = '%B %e, %Y';
$templateDir = $this->getTemplateDir() . $this->getTemplateFile();

//Load the ini file
$ini_file = $templateDir."/invoice.ini";
$ini_array = parse_ini_file($ini_file, true);
$iniFile = $templateDir . '/invoice.ini';
$iniArray = parse_ini_file($iniFile, true);

// fetch variables from model to get values
$customer = $this->getModel()->getCustomer();
$projects = $this->getModel()->getProjects();
$entries = $this->getModel()->getEntries();
$data = $this->getModel()->toArray();
//Get global settings
global $kga;

//Create invoiceId
$in = time();
$invoiceID = date("y", $in).$customer['customerID'].date("m", $in).date("d", $in);
include "Checksum.php";
$invoiceID = checksum('OCR', $invoiceID, true);
Kimai_Logger::logfile("invoiceID = $invoiceID");
$invoiceID = date('y', $in) . $customer['customerID'] . date('m', $in) . date('d', $in);
require_once 'Checksum.php';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be dropped as autoloading works out of the box if the class is correctly named.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

$invoiceID = checksum('OCR', $invoiceID, true);
Kimai_Logger::logfile('invoiceID: ' . $invoiceID);
$this->getModel()->setInvoiceId($invoiceID);
//Get data model

$data = $this->getModel()->toArray();
Kimai_Logger::logfile("tempdir = ".$vault);

//Write the header/footer data
$File = $vault."/info.tex";
$Handle = fopen($File, 'w');
fwrite($Handle, "\\def\\duedate{".strftime($dateFormat, $data['dueDate'])."}%\n");
fwrite($Handle, "\\def\\total{".$data['amount']."}%\n");
fwrite($Handle, "\\def\\invoiceID{".$data['invoiceId']."}%\n");
fwrite($Handle, "\\def\\currency{".$data['currencySign']."}%\n");
fwrite($Handle, "\\def\\companyName{".$customer['company']."}%\n");
fwrite($Handle, "\\def\\companyAddress{".$customer['street']."\\\\".$customer['zipcode']." ".$customer['city']."}%\n");
fwrite($Handle, "\\def\\companyPhone{".$customer['phone']."}%\n");
fwrite($Handle, "\\def\\companyEmail{".$customer['mail']."}%\n");
fwrite($Handle, "\\def\\comment{".$customer['comment']."}%\n");
fwrite($Handle, "\\def\\startDate{".strftime($dateFormat, $data['beginDate'])."}%\n");
fwrite($Handle, "\\def\\endDate{".strftime($dateFormat, $data['endDate'])."}%\n");
fwrite($Handle, "\\def\\vatRate{".$data['vatRate']."}%\n");
fwrite($Handle, "\\def\\vat{".$data['vat']."}%\n");
fwrite($Handle, "\\def\\gtotal{".$data['total']."}%\n");
fwrite($Handle, "\\endinput");
fclose($Handle);
$file = $tempDir . '/info.tex';
$handle = fopen($file, 'w');
$content = '';
$content .= "\\def\\duedate{" . strftime($dateFormat, $data['dueDate']) . "}%\n";
$content .= "\\def\\total{" . $data['amount'] . "}%\n";
$content .= "\\def\\invoiceID{" . $data['invoiceId'] . "}%\n";
$content .= "\\def\\currency{" . $data['currencySign'] . "}%\n";
$content .= "\\def\\companyName{" . $customer['company'] . "}%\n";
$content .= "\\def\\companyAddress{" . $customer['street'] . "\\\\" . $customer['zipcode'] . " " . $customer['city'] . "}%\n";
$content .= "\\def\\companyPhone{" . $customer['phone'] . "}%\n";
$content .= "\\def\\companyEmail{" . $customer['mail'] . "}%\n";
$content .= "\\def\\comment{" . $customer['comment'] . "}%\n";
$content .= "\\def\\startDate{" . strftime($dateFormat, $data['beginDate']) . "}%\n";
$content .= "\\def\\endDate{" . strftime($dateFormat, $data['endDate']) . "}%\n";
$content .= "\\def\\vatRate{" . $data['vatRate'] . "}%\n";
$content .= "\\def\\vat{" . $data['vat'] . "}%\n";
$content .= "\\def\\gtotal{" . $data['total'] . "}%\n";
$content .= "\\endinput";
fwrite($handle, $content);
fclose($handle);

//Write the table
$File = $vault."/data.tex";
$Handle = fopen($File, "w");
$file = $tempDir . '/data.tex';
$handle = fopen($file, 'w');
$content = '';
foreach ($entries as $row) {
$table_row = "\product";
foreach ($ini_array['table'] as $index) {
$table_row = $table_row."{".$row[$index]."}";
$table_row = "\\product";
foreach ($iniArray['table'] as $index) {
$table_row = $table_row . '{' . $row[$index] . '}';
}
$table_row = $table_row."%\n";
fwrite($Handle, $table_row);
$table_row = $table_row . "%\n";
$content .= $table_row;
}
fwrite($Handle, "\\endinput");
fclose($Handle);

$content .= "\\endinput";
fwrite($handle, $content);
fclose($handle);

//Copy all the neccessary files to the rendering directory
copy($templateDir."/invoice.tex", $vault."/".$data['invoiceId'].".tex");
foreach ($ini_array['files'] as $file) {
copy($templateDir."/".$file, $vault."/".$file);
copy($templateDir . '/invoice.tex', $tempDir . '/' . $data['invoiceId'] . '.tex');
foreach ($iniArray['files'] as $file) {
copy($templateDir . '/' . $file, $tempDir . '/' . $file);
}

//Run pdflatex, throw error if not!
$output = exec("cd ".$vault." && ".$kga['LaTeXExec']." ".$data['invoiceId'].".tex");
$output = exec('cd ' . $tempDir . ' && ' . $kga['LaTeXExec'] . ' ' . $data['invoiceId'] . '.tex');
if (strlen($output) == 0) {
Kimai_Logger::logfile("Could not execute pdflatex. Check your installation!");
Kimai_Logger::logfile('Could not execute pdflatex. Check your installation!');
return;
}
//Run pdflatex again, throw error if not!
$output = exec("cd ".$vault." && ".$kga['LaTeXExec']." ".$data['invoiceId'].".tex");
$output = exec('cd ' . $tempDir . ' && ' . $kga['LaTeXExec'] . ' ' . $data['invoiceId'] . '.tex');

//Return the rendered file
$this->sendResponse($vault."/".$data['invoiceId'].".pdf");
$this->sendResponse($tempDir . '/' . $data['invoiceId'] . '.pdf');
}

/**
* @return pdf
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does not return anything but just output the file

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to "@return null".

*/
public function sendResponse($data)
{
Kimai_Logger::logfile('File to send: ' . $data);
header('Content-Type: pdf');
header('Content-Disposition: attachment; filename="'.basename($data).'"');
header('Content-Length: '.filesize($data));
Kimai_Logger::logfile("File to send:".$data);
header('Content-Disposition: attachment; filename="' . basename($data) . '"');
header('Content-Length: ' . filesize($data));
ob_clean();
flush();
readfile($data);
exit;
}

/**
@@ -142,8 +150,7 @@ public function canRender()
if (!is_dir($this->getTemplateDir() . $this->getTemplateFile())) {
return false;
}
return (
is_file($this->getTemplateDir() . $this->getTemplateFile() . DIRECTORY_SEPARATOR . self::FILE_TEX)
);

return (is_file($this->getTemplateDir() . $this->getTemplateFile() . DIRECTORY_SEPARATOR . self::FILE_TEX));
}
}