PreorderBilling: Added optional pdf format for invoice detail file
This commit is contained in:
@@ -185,8 +185,11 @@ $pagination_entity_name = "Rechnungen";
|
||||
<i class="fas fa-fw fa-mail" title="per Email versendet am <?=date("d.m.Y H:i", $invoice->date_delivered)?>"></i>
|
||||
<?php endif; ?>
|
||||
<?php if($invoice->csv): ?>
|
||||
<a class="ml-2" href="<?=self::getUrl("PreorderBillingInvoice", "downloadCsv", ["id" => $invoice->id])?>">
|
||||
<i class="fas fa-fw fa-file-csv" title="CSV-Datei herunterladen"></i>
|
||||
<a class="ml-2" href="<?=self::getUrl("PreorderBillingInvoice", "downloadDetailCsv", ["id" => $invoice->id])?>">
|
||||
<i class="far fa-fw fa-file-csv" title="Rechnungsgetails als CSV-Datei herunterladen"></i>
|
||||
</a>
|
||||
<a class="ml-1" href="<?=self::getUrl("PreorderBillingInvoice", "downloadDetailPdf", ["id" => $invoice->id])?>">
|
||||
<i class="far fa-fw fa-file-pdf text-danger" title="Rechnungsgetails als PDF-Datei herunterladen"></i>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
|
||||
134
Layout/default/PreorderBillingInvoice/detail.pdf.php
Normal file
134
Layout/default/PreorderBillingInvoice/detail.pdf.php
Normal file
@@ -0,0 +1,134 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Invoice Detail</title>
|
||||
<meta charset="utf-8" />
|
||||
<style>
|
||||
body {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding-top: 0;
|
||||
font-family: "DejaVu Sans Mono", monospace;
|
||||
font-size: 9px;
|
||||
}
|
||||
.separator {
|
||||
margin-top: 48px;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
#topSpacer {
|
||||
margin-bottom: 32px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
border: 1px solid #aaa;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.data-table tbody td,
|
||||
.data-table tbody th {
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
border: 1px solid #d9d9d9;
|
||||
}
|
||||
|
||||
.data-table tbody tr.even td {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.data-table tbody tr {
|
||||
border-top: 1px dashed #aaa;
|
||||
border-bottom: 1px dashed #aaa;
|
||||
page-break-inside: avoid !important;
|
||||
}
|
||||
|
||||
.data-table tbody tr.top {
|
||||
page-break-after: avoid !important;
|
||||
}
|
||||
.data-table tbody tr.bottom {
|
||||
page-break-before: avoid !important;
|
||||
}
|
||||
|
||||
.data-table tbody tr.top td,
|
||||
.data-table tbody tr.top th {
|
||||
border-top: 1px dashed #aaa;
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
}
|
||||
|
||||
.data-table tbody tr.bottom td {
|
||||
border-bottom: 1px dashed #aaa;
|
||||
border-top: 1px solid #d7d7d7;
|
||||
}
|
||||
|
||||
.data-table tbody tr.bottom th {
|
||||
border-bottom: 1px solid #aaa;
|
||||
border-top: 1px solid #d9d9d9;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.border-right {
|
||||
border-right: 1px dotted #ddd;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Detailblatt zu Rechnung <?=$rechnum?></h1>
|
||||
|
||||
<div>Netzbetreiber: <strong><?=$netzbetreiber?></strong></div>
|
||||
|
||||
<table class="data-table">
|
||||
<tr class="top">
|
||||
<th class="align-left">Rechnungsnummer</th>
|
||||
<th class="align-left">Bestelldatum</th>
|
||||
<th class="align-left" colspan="6">Netzgebiet</th>
|
||||
</tr>
|
||||
<tr class="bottom">
|
||||
<th class="align-left">Rechnungsdatum</th>
|
||||
<th class="align-left">Extref</th>
|
||||
<th class="align-left">OAID</th>
|
||||
<th class="align-left">Periode Von</th>
|
||||
<th class="align-left">Periode Bis</th>
|
||||
<th class="align-right">Artikelnummer</th>
|
||||
<th class="align-left">Produkt</th>
|
||||
<th class="align-right">Preis Netto</th>
|
||||
</tr>
|
||||
<?php $i=0; foreach($positions as $position): ?>
|
||||
<tr class="top <?=$i%2==0 ? "even" : "odd"?>">
|
||||
<td class="align-left"><?=$position["rechnum"]?></td>
|
||||
<td class="align-left"><?=$position["bestdatum"]?></td>
|
||||
<td class="align-left" colspan="6"><?=$position["netzgebiet"]?></td>
|
||||
</tr>
|
||||
<tr class="bottom <?=$i%2==0 ? "even" : "odd"?>">
|
||||
<td class="align-left"><?=$position["rechdatum"]?></td>
|
||||
<td class="align-left"><?=$position["extref"]?></td>
|
||||
<td class="align-left"><?=$position["oaid"]?></td>
|
||||
<td class="align-left"><?=$position["von"]?></td>
|
||||
<td class="align-left"><?=$position["bis"]?></td>
|
||||
<td class="align-right"><?=$position["artnum"]?></td>
|
||||
<td class="align-left"><?=$position["produkt"]?></td>
|
||||
<td class="align-right"><?=$position["netto"]?></td>
|
||||
</tr>
|
||||
<?php $i++; endforeach; ?>
|
||||
</table>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -90,7 +90,7 @@ class File extends mfBaseModel {
|
||||
$path .= "/$filename";
|
||||
|
||||
if(!file_exists($path)) {
|
||||
throw new Exception("File not found", 4041);
|
||||
throw new Exception("File not found $path ", 4041);
|
||||
}
|
||||
|
||||
return $path;
|
||||
|
||||
@@ -6,9 +6,11 @@ use chillerlan\QRCode\Output\QROutputInterface;
|
||||
|
||||
class PreorderBillingInvoice extends mfBaseModel {
|
||||
protected $forcestr = ["company", "zip", "email", "phone"];
|
||||
private $netowner;
|
||||
private $positions;
|
||||
private $pdf;
|
||||
private $csv;
|
||||
private $detailpdf;
|
||||
|
||||
private $emailLog;
|
||||
private $creator;
|
||||
@@ -169,8 +171,7 @@ RML Infrastruktur GmbH";
|
||||
// get pdf file
|
||||
$ifile = PreorderBillingInvoiceFile::createFromInvoice($this);
|
||||
if(!$ifile) {
|
||||
$this->layout()->setFlash("Fehler beim PDF erstellen");
|
||||
$this->redirect("PreorderBillingInvoice");
|
||||
return false;
|
||||
}
|
||||
$pdf = $ifile->file;
|
||||
|
||||
@@ -184,17 +185,31 @@ RML Infrastruktur GmbH";
|
||||
return false;
|
||||
}
|
||||
|
||||
// get csv file
|
||||
$csv_filename = false;
|
||||
$csv = $this->getProperty("csv");
|
||||
if($csv) {
|
||||
try {
|
||||
$csv_filename = $csv->getFullPath();
|
||||
} catch (\Exception $e) {
|
||||
$this->log->error("CSV-File for Invoice " . $this->id . " not found");
|
||||
// get detail file
|
||||
$detail_file = null;
|
||||
$netowner = $this->getProperty("netowner");
|
||||
if(!$netowner || !array_key_exists($netowner->id, TT_PREORDER_BILLING)) {
|
||||
return false;
|
||||
}
|
||||
$netowner_config = TT_PREORDER_BILLING[$netowner->id];
|
||||
|
||||
if(array_key_exists($this->owner_id, $netowner_config["netoperators"])) {
|
||||
$anb_config = $netowner_config["netoperators"][$this->owner_id];
|
||||
$detail_format = $anb_config["invoice-detail-file-format"];
|
||||
if($detail_format == "csv") {
|
||||
$detail_file = $this->getProperty("csv");
|
||||
|
||||
}
|
||||
if($detail_format == "pdf") {
|
||||
$detail_file = $this->getProperty("detailpdf");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// get csv file
|
||||
|
||||
|
||||
|
||||
$tpl = new Layout();
|
||||
$tpl->setTemplate("Emailtemplates/preorder-invoice/rml/invoice-email.html");
|
||||
if($this->owner_id) {
|
||||
@@ -238,8 +253,8 @@ RML Infrastruktur GmbH";
|
||||
$email->setTo($to);
|
||||
$email->setHeader("X-".MFAPPNAME."-Iid", $this->id);
|
||||
$email->addAttachment($pdf_filename, null, $pdf->filename, "application/pdf");
|
||||
if($csv_filename) {
|
||||
$email->addAttachment($csv_filename, null, $csv->filename, "text/csv");
|
||||
if($detail_file) {
|
||||
$email->addAttachment($detail_file->getFullPath(), null, $detail_file->filename, $detail_file->mimetype);
|
||||
}
|
||||
$email->send();
|
||||
$this->log->info(__METHOD__.": Sending Preorder Invoice ".$this->invoice_number." to $to");
|
||||
@@ -248,9 +263,152 @@ RML Infrastruktur GmbH";
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getPdfFromDetailCsv() {
|
||||
$netowner = $this->getProperty("netowner");
|
||||
if(!$netowner || !array_key_exists($netowner->id, TT_PREORDER_BILLING)) {
|
||||
return false;
|
||||
}
|
||||
$netowner_config = TT_PREORDER_BILLING[$netowner->id];
|
||||
|
||||
$csv_file = $this->getProperty("csv");
|
||||
$input = fopen($csv_file->getFullPath(), "r");
|
||||
if(!$input) return false;
|
||||
|
||||
$bom = "\xef\xbb\xbf";
|
||||
if(fgets($input, 4) !== $bom) {
|
||||
// BOM not found - rewind pointer to start of file.
|
||||
rewind($input);
|
||||
}
|
||||
|
||||
$headers = [];
|
||||
$positions = [];
|
||||
|
||||
$c = 0;
|
||||
$i = 0;
|
||||
while($csv = fgetcsv($input, 0, ";")) {
|
||||
$i++;
|
||||
|
||||
if($i == 1) {
|
||||
foreach($csv as $key => $name) {
|
||||
$headers[$name] = $key;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!trim($csv[1])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$data["netzbetreiber"] = trim($csv[$headers["Netzbetreiber"]]);
|
||||
$data["rechnum"] = trim($csv[$headers["Rechungsnummer"]]);
|
||||
$data["rechdatum"] = (new DateTime(trim($csv[$headers["Rechnungsdatum"]])))->format("d.m.Y");
|
||||
$data["netzgebiet"] = trim($csv[$headers["Netzgebiet"]]);
|
||||
$data["oaid"] = trim($csv[$headers["OAID"]]);
|
||||
$data["extref"] = trim($csv[$headers["Extref"]]);
|
||||
$data["bestdatum"] = (new DateTime(trim($csv[$headers["Bestelldatum"]])))->format("d.m.Y");
|
||||
$data["von"] = trim($csv[$headers["Periode von"]]);
|
||||
$data["bis"] = trim($csv[$headers["Periode bis"]]);
|
||||
$data["artnum"] = trim($csv[$headers["Artikelnummer"]]);
|
||||
$data["produkt"] = trim($csv[$headers["Produkt"]]);
|
||||
$data["anzahl"] = trim($csv[$headers["Anzahl"]]);
|
||||
$data["netto"] = trim($csv[$headers["Preis Netto"]]);
|
||||
|
||||
$positions[] = $data;
|
||||
}
|
||||
|
||||
if(!count($positions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$invoice_number = $this->invoice_number;
|
||||
|
||||
$variables = [
|
||||
"positions" => $positions,
|
||||
"netzbetreiber" => $this->getProperty("owner")->getCompanyOrName(),
|
||||
"rechnum" => $invoice_number,
|
||||
];
|
||||
|
||||
$pdf = new PdfForm("PreorderBillingInvoice/detail.pdf", $variables);
|
||||
$path = $pdf->render("-O landscape");
|
||||
if(!$path) return false;
|
||||
|
||||
|
||||
$filename = "$invoice_number-detail.pdf";
|
||||
$subfolder = $netowner_config["subfolder"];
|
||||
|
||||
$new_filepath = MFUPLOAD_FILE_SAVE_PATH."/$subfolder/$filename";
|
||||
if(!rename($path, $new_filepath)) {
|
||||
unlink($path);
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = FileModel::create([
|
||||
"name" => $filename,
|
||||
"filename" => $filename,
|
||||
"store_filename" => $filename,
|
||||
"orig_filename" => $filename,
|
||||
"subfolder" => $subfolder,
|
||||
"mimetype" => "application/pdf",
|
||||
]);
|
||||
if(!$file->save()) {
|
||||
unlink($new_filepath);
|
||||
return false;
|
||||
}
|
||||
|
||||
$invoice_file = PreorderBillingInvoiceFile::create([
|
||||
"invoice_id" => $this->id,
|
||||
"file_id" => $file->id,
|
||||
"name" => $filename,
|
||||
]);
|
||||
if(!$invoice_file->save()) {
|
||||
$file->delete();
|
||||
//unlink($new_filepath);
|
||||
return false;
|
||||
}
|
||||
|
||||
return $invoice_file;
|
||||
|
||||
//$pdf->download();
|
||||
|
||||
/*
|
||||
$file = FileModel::create([
|
||||
"" => "",
|
||||
]);*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function getProperty($name) {
|
||||
if($this->$name == null) {
|
||||
|
||||
if($name == "netowner") {
|
||||
$netowner = new Address($this->netowner_id);
|
||||
if(!$netowner->id) {
|
||||
return false;
|
||||
}
|
||||
$this->netowner = $netowner;
|
||||
return $this->netowner;
|
||||
}
|
||||
|
||||
if($name == "owner") {
|
||||
$owner = new Address($this->owner_id);
|
||||
if(!$owner->id) {
|
||||
return false;
|
||||
}
|
||||
$this->owner = $owner;
|
||||
return $this->owner;
|
||||
}
|
||||
|
||||
if($name == "billingaddress") {
|
||||
$billingaddress = new Address($this->billingaddress_id);
|
||||
if(!$billingaddress->id) {
|
||||
return false;
|
||||
}
|
||||
$this->billingaddress = $billingaddress;
|
||||
return $this->billingaddress;
|
||||
}
|
||||
|
||||
if($name == "positions") {
|
||||
$positions = PreorderBillingInvoiceposition::search(["invoice_id" => $this->id]);
|
||||
$this->positions = $positions;
|
||||
@@ -279,6 +437,19 @@ RML Infrastruktur GmbH";
|
||||
return $this->csv;
|
||||
}
|
||||
|
||||
if($name == "detailpdf") {
|
||||
// same as csv but in pdf format
|
||||
$ifile = PreorderBillingInvoiceFile::getFirst(["invoice_id" => $this->id, "name" => "%-detail.pdf"]);
|
||||
if(!$ifile || !$ifile->file || !$ifile->file->id) {
|
||||
$ifile = $this->getPdfFromDetailCsv();
|
||||
}
|
||||
|
||||
if(!$ifile || !$ifile->file || !$ifile->file->id) return null;
|
||||
|
||||
$this->detailpdf = $ifile->file;
|
||||
return $this->detailpdf;
|
||||
}
|
||||
|
||||
if($name == "emailLog") {
|
||||
$emaillog = EmailLog::getFirst(["object_type" => "PreorderBillingInvoice", "object_id" => $this->id]);
|
||||
if($emaillog) {
|
||||
|
||||
@@ -181,7 +181,38 @@ class PreorderBillingInvoiceController extends mfBaseController {
|
||||
exit;
|
||||
}
|
||||
|
||||
protected function downloadCsv() {
|
||||
protected function downloadDetailPdf() {
|
||||
$id = $this->request->id;
|
||||
if (!is_numeric($id) || !$id) {
|
||||
$this->layout()->setFlash("Rechnung nicht gefunden", "error");
|
||||
$this->redirect("Invoice");
|
||||
}
|
||||
|
||||
$invoice = new PreorderBillingInvoice($id);
|
||||
if (!$invoice->id) {
|
||||
$this->layout()->setFlash("Rechnung nicht gefunden", "error");
|
||||
$this->redirect("Invoice");
|
||||
}
|
||||
|
||||
|
||||
$csv = $invoice->detailpdf;
|
||||
if(!$csv) {
|
||||
$this->layout()->setFlash("Fehler beim PDF Generieren", "error");
|
||||
}
|
||||
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-disposition: attachment; filename="'.$csv->filename.'"');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header("Content-Length: " . filesize($csv->getFullPath()));
|
||||
if($csv->mimetype) {
|
||||
header('Content-Type: '.$csv->mimetype);
|
||||
}
|
||||
readfile($csv->getFullPath());
|
||||
exit;
|
||||
}
|
||||
|
||||
protected function downloadDetailCsv() {
|
||||
$id = $this->request->id;
|
||||
if (!is_numeric($id) || !$id) {
|
||||
$this->layout()->setFlash("Rechnung nicht gefunden", "error");
|
||||
@@ -704,38 +735,6 @@ class PreorderBillingInvoiceController extends mfBaseController {
|
||||
return ["sent" => $sent, "defer" => $defer];
|
||||
}
|
||||
|
||||
/*$pdf = $invoice->pdf;
|
||||
$pdf = false;
|
||||
|
||||
if(!$pdf || !$pdf->name) {
|
||||
$ifile = PreorderBillingInvoiceFile::createFromInvoice($invoice);
|
||||
if(!$ifile) {
|
||||
$this->layout()->setFlash("Fehler beim PDF erstellen");
|
||||
$this->redirect("PreorderBillingInvoice");
|
||||
}
|
||||
$pdf = $ifile->file;
|
||||
}
|
||||
|
||||
$pdf_file = false;
|
||||
try {
|
||||
$pdf_file = $pdf->getFullPath();
|
||||
} catch (Exception $e) {
|
||||
$this->log->error(__METHOD__.": File for Invoice ".$invoice->id." not found");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!file_exists($pdf_file)) {
|
||||
$this->log->error(__METHOD__.": Datei ".$pdf->filename." nicht gefunden");
|
||||
continue;
|
||||
}
|
||||
|
||||
if($invoice->total == 0) {
|
||||
$this->log->info(__METHOD__.": Skipping ".$invoice->invoice_number." because total is zero");
|
||||
$invoice->date_delivered = date("U");
|
||||
$invoice->save();
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
if(!$invoice->sendByEmail()) {
|
||||
$this->log->warning(__METHOD__.": Error sending ".$invoice->invoice_number." to ".$invoice->email);
|
||||
$invoice->date_delivered = date("U");
|
||||
|
||||
Reference in New Issue
Block a user