Merge branch 'fronkdev' into 'master'

PreorderBilling: Added optional pdf format for invoice detail file

See merge request fronk/thetool!1852
This commit is contained in:
Frank Schubert
2025-10-21 16:27:46 +00:00
5 changed files with 355 additions and 48 deletions

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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");