-
+
+
@@ -64,6 +117,7 @@ $pagination_entity_name = "Rechnungen";
@@ -90,7 +144,12 @@ $pagination_entity_name = "Rechnungen";
total + $invoice->total_setup; ?>
total_gross + $invoice->total_setup_gross; ?>
- | $invoice->id])?>"> =$invoice->invoice_number?> |
+
+ $invoice->id])?>"> =$invoice->invoice_number?>
+ pdf): ?>
+
+
+ |
=date("d.m.Y", $invoice->invoice_date)?> |
=$invoice->customer_number?> |
@@ -126,5 +185,23 @@ $pagination_entity_name = "Rechnungen";
+
\ No newline at end of file
diff --git a/application/Invoice/Invoice.php b/application/Invoice/Invoice.php
index 1bc9fade9..b1293e021 100644
--- a/application/Invoice/Invoice.php
+++ b/application/Invoice/Invoice.php
@@ -1,8 +1,103 @@
id) {
+ $invoice_number = $this->invoice_number;
+ $invoice_date = $this->invoice_date;
+ } else {
+ $invoice_number = "PROFORMA";
+ $invoice_date = 1;
+ }
+
+ $filename = "";
+ $positions = $this->getProperty("positions");
+
+ $vat = [];
+ foreach ($positions as $p) {
+ if (!array_key_exists($p->vatrate, $vat)) {
+ $vat[$p->vatrate] = 0;
+ }
+ $vat[$p->vatrate] += $p->price_gross - ($p->price * $p->amount);
+ }
+
+ $pdf_vars = [
+ "invoice" => $this,
+ "vat" => $vat,
+ "bank_iban" => TT_INVOICE_BANK_IBAN,
+ "bank_bic" => TT_INVOICE_BANK_BIC,
+ "bank_bank"=> TT_INVOICE_BANK_BANK,
+ "bank_owner" => TT_INVOICE_BANK_OWNER
+ ];
+
+ // Replace placeholders in header
+ $headerHtml = file_get_contents(BASEDIR . "/Layout/default/Invoice/PDF_HEADER.html");
+ $headerHtml = str_replace("{{ basedir }}", BASEDIR, $headerHtml);
+ $headerHtml = str_replace("{{ addressLine_1 }}", $this->company ? $this->company : "", $headerHtml);
+ $headerHtml = str_replace("{{ addressLine_2 }}", $this->firstname . " " . $this->lastname, $headerHtml);
+ $headerHtml = str_replace("{{ addressLine_3 }}", nl2br($this->street), $headerHtml);
+ $headerHtml = str_replace("{{ addressLine_4 }}", $this->zip . " " . $this->city, $headerHtml);
+ $headerHtml = str_replace("{{ addressLine_5 }}", $this->country != "Österreich" ? $this->country : "", $headerHtml);
+ $headerHtml = str_replace("{{ customerNumber }}", $this->customer_number, $headerHtml);
+ $headerHtml = str_replace("{{ billingAccount }}", $this->fibu_account_number, $headerHtml);
+ $headerHtml = str_replace("{{ invoiceNumber }}", $invoice_number, $headerHtml);
+ $headerHtml = str_replace("{{ invoiceDate }}", date("d.m.Y", $invoice_date), $headerHtml);
+ $headerHtml = str_replace("{{ vatHtml }}", $this->uid ? " |
| Ihre UID: | " . $this->uid . " |
" : "", $headerHtml);
+ $headerHtml = str_replace("{{ qrCodeSrc }}", $this->getSepaQRCode($invoice_number, round($this->total_gross, 2)), $headerHtml);
+
+ $headerFile = BASEDIR . "/var/temp/invoice_header-" . date("U") . "-" . rand(1000, 9999) . ".html";
+ file_put_contents($headerFile, $headerHtml);
+
+
+ // Replace placeholders in header
+ $footerHtml = file_get_contents(BASEDIR . "/Layout/default/Invoice/PDF_FOOTER.html");
+ $footerHtml = str_replace("{{ bank_iban }}", TT_INVOICE_BANK_IBAN_FORMATTED, $footerHtml);
+ $footerHtml = str_replace("{{ bank_bic }}", TT_INVOICE_BANK_BIC, $footerHtml);
+ $footerHtml = str_replace("{{ bank_bank }}", TT_INVOICE_BANK_BANK, $footerHtml);
+ $footerHtml = str_replace("{{ bank_owner }}", TT_INVOICE_BANK_OWNER, $footerHtml);
+
+
+ $footerFile = BASEDIR . "/var/temp/invoice_footer-" . date("U") . "-" . rand(1000, 9999) . ".html";
+ file_put_contents($footerFile, $footerHtml);
+
+
+ $pdf = new PdfForm("Invoice/PDF_MAIN", $pdf_vars);
+ $wkhtmltopdfArgs = "--header-html $headerFile --footer-html $footerFile";
+ $filename = $pdf->render($wkhtmltopdfArgs);
+
+ return $filename;
+
+ }
+
+ public function getSepaQRCode($paymentReference, $amount) {
+ $xinonIBAN = TT_INVOICE_BANK_IBAN;
+ $xinonBIC = TT_INVOICE_BANK_BIC;
+ $xinonOwner = TT_INVOICE_BANK_OWNER;
+
+ $epc = "BCD
+001
+1
+SCT
+$xinonBIC
+$xinonOwner
+$xinonIBAN
+EUR$amount
+XINO
+$paymentReference
+
+XINON GmbH";
+
+ return (new QRCode)->render($epc);
+ }
public function getProperty($name) {
if($this->$name == null) {
@@ -24,6 +119,17 @@ class Invoice extends mfBaseModel {
return $this->voicenumbers;
}
+ if($name == "pdf") {
+ $ifile = InvoiceFileModel::getFirst(["invoice_id" => $this->id]);
+ if(!$ifile) return null;
+
+ $file = $ifile->file;
+ if(!$file) return null;
+
+ $this->pdf = $file;
+ return $this->pdf;
+ }
+
if($name == "creator") {
$this->creator = mfValuecache::singleton()->get("Worker-id-".$this->create_by);
if($this->creator === null) {
diff --git a/application/Invoice/InvoiceController.php b/application/Invoice/InvoiceController.php
index bdc2dd3b4..9597dc64a 100644
--- a/application/Invoice/InvoiceController.php
+++ b/application/Invoice/InvoiceController.php
@@ -1,10 +1,5 @@
redirect("Invoice");
}
+ $filename = $invoice->createPdf();
+ header('Content-Type: application/octet-stream');
+ header('Content-disposition: attachment; filename="'.$filename.'"');
+ header('Content-Transfer-Encoding: binary');
+ header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+ header('Content-Type: ' . mime_content_type($filename));
+ header("Content-Length: " . filesize($filename));
- $vat = [];
+ readfile($filename);
+ exit;
+
+ /*$vat = [];
foreach ($invoice->positions as $p) {
if (!array_key_exists($p->vatrate, $vat)) {
$vat[$p->vatrate] = 0;
@@ -148,30 +153,11 @@ class InvoiceController extends mfBaseController {
$pdf = new PdfForm("Invoice/PDF_MAIN", $pdf_vars);
$wkhtmltopdfArgs = "--header-html $headerFile --footer-html $footerFile";
- $pdf->download($invoice->invoice_number . ".pdf", $wkhtmltopdfArgs);
+ $pdf->download($invoice->invoice_number . ".pdf", $wkhtmltopdfArgs);*/
}
- public function getBankQRCode($paymentReference, $amount) {
- $xinonIBAN = TT_INVOICE_BANK_IBAN;
- $xinonBIC = TT_INVOICE_BANK_BIC;
- $xinonOwner = TT_INVOICE_BANK_OWNER;
- $epc = "BCD
-001
-1
-SCT
-$xinonBIC
-$xinonOwner
-$xinonIBAN
-EUR$amount
-XINO
-$paymentReference
-
-XINON GmbH";
-
- return (new QRCode)->render($epc);
- }
protected function runInvoicingAction() {
$i = 0;
@@ -665,7 +651,117 @@ XINON GmbH";
exit;
}
+ public function createPDFsAction() {
+ $invoice_path = MFUPLOAD_FILE_SAVE_PATH."/".TT_INVOICE_SAVE_SUBFOLDER."/";
+ foreach(InvoiceModel::getAll() as $invoice) {
+ if(InvoiceFileModel::getFirst(["invoice_id" => $invoice->id])) {
+ continue;
+ }
+ // create PDF
+ $tmp_filename = $invoice->createPdf();
+ if(!$tmp_filename) {
+ $this->layout()->setFlash("Error creating PDF file", "error");
+ $this->redirect("Invoice");
+ }
+
+ $new_filename = $invoice->invoice_number.".pdf";
+
+ // move pdf to correct folder
+ if(!rename($tmp_filename, $invoice_path.$new_filename)) {
+ $this->layout()->setFlash("Error moving created PDF file", "error");
+ $this->redirect("Invoice");
+ }
+
+ // create File
+ $file = FileModel::create([
+ "name" => $invoice->invoice_number,
+ "filename" => $new_filename,
+ "subfolder" => TT_INVOICE_SAVE_SUBFOLDER,
+ "store_filename" => $new_filename,
+ "orig_filename" => $new_filename,
+ ]);
+
+ if(!$file->save()) {
+ $this->layout()->setFlash("Error saving PDF file", "error");
+ $this->redirect("Invoice");
+ }
+
+ // create InvoiceFile
+ $ifile = InvoiceFileModel::create([
+ "invoice_id" => $invoice->id,
+ "file_id" => $file->id,
+ "name" => $new_filename,
+ "description" => ""
+ ]);
+
+ if(!$ifile->save()) {
+ $this->layout()->setFlash("Error saving PDF Invoice file", "error");
+ $this->redirect("Invoice");
+ }
+
+ }
+ }
+
public function printInvoicesAction() {
- //$start = $r->
+ $start = $this->request->delivery_start_date;
+ $end = $this->request->delivery_end_date;
+
+ try {
+ $start_date = DateTime::createFromFormat("d.m.Y", $start, new DateTimeZone("Europe/Vienna"));
+ $start_date->setTime(0,0,0);
+
+ $end_date = DateTime::createFromFormat("d.m.Y", $end, new DateTimeZone("Europe/Vienna"));
+ $end_date->setTime(23,59,59);
+ } catch(Exception $e) {
+ $this->layout()->setFlash("Von- oder Bisdatum ungültig", "error");
+ $this->redirect("Invoice");
+ }
+
+ if(!InvoiceModel::count(["billing_delivery" => "paper", "invoice_date>=" => $start_date->getTimestamp(), "invoice_date<=" => $end_date->getTimestamp()])) {
+ $this->layout()->setFlash("Keine Rechnungen im angegebenen Zeitraum gefunden", "error");
+ $this->redirect("Invoice");
+ }
+
+ $pdf_files = [];
+
+ foreach(InvoiceModel::search(["billing_delivery" => "paper", "invoice_date>=" => $start_date->getTimestamp(), "invoice_date<=" => $end_date->getTimestamp()]) as $invoice) {
+ $filename = $invoice->createPdf();
+ if(!$filename) {
+ $this->layout()->setFlash("Fehler beim PDF erstellen (".$invoice->invoice_number.")", "error");
+ $this->redirect("Invoice");
+ }
+
+ $pdf_files[] = $filename;
+ }
+
+ if(!count($pdf_files)) {
+ $this->layout()->setFlash("Fehler beim PDF erstellen: Keine PDFs zum zusammenführen", "error");
+ $this->redirect("Invoice");
+ }
+
+ $output_path = MFUPLOAD_FILE_SAVE_PATH."/".TT_INVOICE_SAVE_SUBFOLDER;
+ $output_filename = "invoices-print-".date("Y-m-d-H-i-s").".pdf";
+ $output_filepath = "$output_path/$output_filename";
+
+ foreach($pdf_files as $file) {
+ $pdf_unite_cmd = PDFUNITE_BIN_PATH." '$file' '$output_filepath'";
+ shell_exec($pdf_unite_cmd);
+ }
+
+ if(!file_exists($output_filepath)) {
+ $this->layout()->setFlash("Fehler beim PDFs zusammenführen: Ausgabedatei nicht gefunden", "error");
+ $this->redirect("Invoice");
+ }
+
+ header('Content-Type: application/octet-stream');
+ header('Content-disposition: attachment; filename="'.$output_filename.'"');
+ header('Content-Transfer-Encoding: binary');
+ header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+ header('Content-Type: ' . mime_content_type($output_filepath));
+ header("Content-Length: " . filesize($output_filepath));
+
+ readfile($output_filepath);
+ exit;
+
}
}
\ No newline at end of file
diff --git a/application/Invoice/InvoiceModel.php b/application/Invoice/InvoiceModel.php
index 1aa805a93..ade544387 100644
--- a/application/Invoice/InvoiceModel.php
+++ b/application/Invoice/InvoiceModel.php
@@ -33,6 +33,7 @@ class InvoiceModel {
public $total;
public $total_gross;
public $bmd_export_date;
+ public $date_delivered;
public $total_vat;
public $create_by;
public $edit_by;
@@ -173,7 +174,7 @@ class InvoiceModel {
$sql = "SELECT COUNT(*) as cnt FROM Invoice
WHERE $where";
- //mfLoghandler::singleton()->debug($sql);
+ mfLoghandler::singleton()->debug($sql);
$res = $db->query($sql);
if($db->num_rows($res)) {
@@ -220,7 +221,7 @@ class InvoiceModel {
private static function getSqlFilter($filter) {
$where = "1=1 ";
-
+ //var_dump($filter);exit;
$db = FronkDB::singleton();
//var_dump($filter);exit;
@@ -253,6 +254,31 @@ class InvoiceModel {
}
}
+ if(array_key_exists("invoice_date>", $filter)) {
+ $invoice_date = $db->escape($filter['invoice_date>']);
+ if($invoice_date) {
+ $where .= " AND Invoice.invoice_date > '$invoice_date'";
+ }
+ }
+ if(array_key_exists("invoice_date>=", $filter)) {
+ $invoice_date = $db->escape($filter['invoice_date>=']);
+ if($invoice_date) {
+ $where .= " AND Invoice.invoice_date >= '$invoice_date'";
+ }
+ }
+ if(array_key_exists("invoice_date<", $filter)) {
+ $invoice_date = $db->escape($filter['invoice_date<']);
+ if($invoice_date) {
+ $where .= " AND Invoice.invoice_date < '$invoice_date'";
+ }
+ }
+ if(array_key_exists("invoice_date<=", $filter)) {
+ $invoice_date = $db->escape($filter['invoice_date<=']);
+ if($invoice_date) {
+ $where .= " AND Invoice.invoice_date <= '$invoice_date'";
+ }
+ }
+
if(array_key_exists("bmd_export_date", $filter)) {
$bmd_export_date = $filter['bmd_export_date'];
if(is_numeric($bmd_export_date)) {
@@ -264,6 +290,17 @@ class InvoiceModel {
}
}
+ if(array_key_exists("date_delivered", $filter)) {
+ $date_delivered = $filter['date_delivered'];
+ if(is_numeric($date_delivered)) {
+ $where .= " AND Invoice.date_delivered=$date_delivered";
+ } elseif($date_delivered === null || $date_delivered === false) {
+ $where .= " AND Invoice.date_delivered IS NULL";
+ } elseif($date_delivered === true) {
+ $where .= " AND Invoice.date_delivered > 0";
+ }
+ }
+
if(array_key_exists("billingaddress_id", $filter)) {
$Invoiceaddress_id = $filter['billingaddress_id'];
if(is_numeric($Invoiceaddress_id)) {
@@ -353,7 +390,6 @@ class InvoiceModel {
$where .= " AND Invoice.Invoice_period = $Invoice_period";
}
}
-
//var_dump($filter, $where);exit;
return $where;
}
diff --git a/application/InvoiceFile/InvoiceFile.php b/application/InvoiceFile/InvoiceFile.php
new file mode 100644
index 000000000..5d2398cad
--- /dev/null
+++ b/application/InvoiceFile/InvoiceFile.php
@@ -0,0 +1,39 @@
+$name == null) {
+
+ if(!$this->id) {
+ return null;
+ }
+
+ if($name == "creator") {
+ $this->creator = new User($this->create_by);
+ return $this->creator;
+ }
+
+ if($name == "editor") {
+ $this->editor = new User($this->edit_by);
+ return $this->editor;
+ }
+
+ $classname = ucfirst($name);
+ $idfield = $name."_id";
+ $this->$name = new $classname($this->$idfield);
+
+ if($this->$name->id) {
+ return $this->$name;
+ } else {
+ return null;
+ }
+ }
+
+ return $this->$name;
+ }
+
+}
\ No newline at end of file
diff --git a/application/InvoiceFile/InvoiceFileController.php b/application/InvoiceFile/InvoiceFileController.php
new file mode 100644
index 000000000..3053fa0e3
--- /dev/null
+++ b/application/InvoiceFile/InvoiceFileController.php
@@ -0,0 +1,37 @@
+needlogin=true;
+ $me = new User();
+ $me->loadMe();
+ $this->me = $me;
+ $this->layout()->set("me",$me);
+
+ if(!$me->is(["Admin","salespartner"])) {
+ $this->redirect("Dashboard");
+ }
+ }
+
+ protected function editAction() {
+ // internal redirect to File::editAction
+ }
+
+ protected function deleteAction() {
+ $id = $this->request->id;
+
+ $orderfile = new InvoiceFile($id);
+ if(!$orderfile->id || $orderfile->id != $id) {
+ $this->layout()->setFlash("Dokument nicht gefunden.", "error");
+ $this->redirect("Order");
+ }
+
+ $order_id = $orderfile->order_id;
+
+ $orderfile->file->delete();
+ $orderfile->delete();
+ $this->redirect("Order", "edit", ["id" => $order_id]);
+ }
+ */
+}
\ No newline at end of file
diff --git a/application/InvoiceFile/InvoiceFileModel.php b/application/InvoiceFile/InvoiceFileModel.php
new file mode 100644
index 000000000..c1f74c5c7
--- /dev/null
+++ b/application/InvoiceFile/InvoiceFileModel.php
@@ -0,0 +1,134 @@
+ $value) {
+ if(property_exists(get_called_class(), $field)) {
+ $model ->$field = $value;
+ }
+ }
+
+ $me = new User();
+ $me->loadMe();
+
+ if($model->create_by === null) {
+ $model->create_by = $me->id;
+ }
+ if($model->edit_by === null) {
+ $model->edit_by = $me->id;
+ }
+
+ return $model;
+ }
+
+ public static function getAll() {
+ $items = [];
+
+ $db = FronkDB::singleton();
+
+ $res = $db->select("InvoiceFile", "*", "1=1 ORDER BY name");
+ if($db->num_rows($res)) {
+ while($data = $db->fetch_object($res)) {
+ $items[] = new InvoiceFile($data);
+ }
+ }
+ return $items;
+
+ }
+
+ public static function getFirst($filter = []) {
+ $db = FronkDB::singleton();
+
+ $where = self::getSqlFilter($filter);
+ $res = $db->select("InvoiceFile", "*", "$where ORDER BY name");
+ if($db->num_rows($res)) {
+ $data = $db->fetch_object($res);
+ $item = new InvoiceFile($data);
+ if($item->id) {
+ return $item;
+ } else {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ public static function search($filter) {
+ $items = [];
+ $db = FronkDB::singleton();
+
+ $where = self::getSqlFilter($filter);
+
+ $sql = "SELECT InvoiceFile.* FROM InvoiceFile
+ LEFT JOIN File ON (InvoiceFile.file_id = File.id)
+ WHERE $where
+ ORDER BY invoice_id, name";
+
+ $res = $db->query($sql);
+
+ if($db->num_rows($res)) {
+ while($data = $db->fetch_object($res)) {
+ $items[] = new InvoiceFile($data);
+ }
+ }
+ return $items;
+ }
+
+ private static function getSqlFilter($filter) {
+ $where = "1=1 ";
+
+
+ if(array_key_exists("file_id", $filter)) {
+ $file_id = $filter['file_id'];
+ if(is_numeric($file_id)) {
+ $where .= " AND file_id=$file_id";
+ }
+ }
+
+ if(array_key_exists("invoice_id", $filter)) {
+ $invoice_id = $filter['invoice_id'];
+ if(is_numeric($invoice_id)) {
+ $where .= " AND invoice_id=$invoice_id";
+ }
+ }
+
+ //var_dump($filter);exit;
+ if(array_key_exists("name", $filter)) {
+ $name = FronkDB::singleton()->escape($filter['name']);
+ if($name) {
+ $where .= " AND name='$name'";
+ }
+ }
+
+ if(array_key_exists("filename", $filter)) {
+ $filename = FronkDB::singleton()->escape($filter['filename']);
+ if($filename) {
+ $where .= " AND File.filename='$filename'";
+ }
+ }
+
+ if(array_key_exists("subfolder", $filter)) {
+ $subfolder = FronkDB::singleton()->escape($filter['subfolder']);
+ if($subfolder) {
+ $where .= " AND File.subfolder='$subfolder'";
+ }
+ }
+
+ //var_dump($filter, $where);exit;
+ return $where;
+ }
+
+}
\ No newline at end of file
diff --git a/application/IvtCustomer/IvtCustomerModel.php b/application/IvtCustomer/IvtCustomerModel.php
index 3ccf5aea5..46e91717a 100644
--- a/application/IvtCustomer/IvtCustomerModel.php
+++ b/application/IvtCustomer/IvtCustomerModel.php
@@ -20,7 +20,7 @@ class IvtCustomerModel {
return $items;
}
- public static function getFirst() {
+ public static function getFirst($filter = []) {
$db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME);
$where = self::getSqlFilter($filter);
diff --git a/db/migrations/20240709193526_invoice_add_date_delivered.php b/db/migrations/20240709193526_invoice_add_date_delivered.php
new file mode 100644
index 000000000..8bc474436
--- /dev/null
+++ b/db/migrations/20240709193526_invoice_add_date_delivered.php
@@ -0,0 +1,31 @@
+getEnvironment() == "thetool") {
+ $table = $this->table("Invoice");
+ $table->addColumn("date_delivered", "integer", ["null" => true, "default" => null, "after" => "bmd_export_date"]);
+ $table->update();
+ }
+
+ if($this->getEnvironment() == "addressdb") {
+
+ }
+ }
+
+ public function down(): void
+ {
+ if($this->getEnvironment() == "thetool") {
+ $this->table("Invoice")->removeColumn("date_delivered")->save();
+ }
+
+ if($this->getEnvironment() == "addressdb") {
+
+ }
+ }
+}
diff --git a/db/migrations/20240709214432_create_invoice_file.php b/db/migrations/20240709214432_create_invoice_file.php
new file mode 100644
index 000000000..c4bc3b31a
--- /dev/null
+++ b/db/migrations/20240709214432_create_invoice_file.php
@@ -0,0 +1,41 @@
+getEnvironment() == "thetool") {
+ $table = $this->table("InvoiceFile");
+ $table->addColumn("invoice_id", "integer", ["null" => false]);
+ $table->addColumn("file_id", "integer", ["null" => false]);
+ $table->addColumn("name", "string", ["null" => false, "limit" => 1024]);
+ $table->addColumn("description", "string", ["null" => true, "default" => null, "limit" => 1024]);
+
+ $table->addColumn("create_by", "integer", ["null" => false]);
+ $table->addColumn("edit_by", "integer", ["null" => false]);
+ $table->addColumn("create", "integer", ["null" => false]);
+ $table->addColumn("edit", "integer", ["null" => false]);
+
+ $table->create();
+
+ }
+
+ if($this->getEnvironment() == "addressdb") {
+
+ }
+ }
+
+ public function down(): void
+ {
+ if($this->getEnvironment() == "thetool") {
+ $this->table("InvoiceFile")->drop()->save();
+ }
+
+ if($this->getEnvironment() == "addressdb") {
+
+ }
+ }
+}
diff --git a/scripts/fibu-check/test-bmd-export-sepa-data.php b/scripts/fibu-check/test-bmd-export-sepa-data.php
new file mode 100644
index 000000000..4fd735a99
--- /dev/null
+++ b/scripts/fibu-check/test-bmd-export-sepa-data.php
@@ -0,0 +1,79 @@
+#!/usr/bin/php
+id) {
+ die("Kunde $customer_number nicht im ivt gefunden\n");
+ }
+
+
+ $ivt_iban = strtoupper(str_replace(" ","", $ivt_customer->IBAN));
+ $ivt_bic = strtoupper(str_replace(" ","", $ivt_customer->BIC));
+
+ if($ivt_iban != $iban) {
+ echo "$customer_number | iban: $iban <> $ivt_iban\n";
+ }
+ if($ivt_bic != $bic) {
+ echo "$customer_number | bic: $bic <> $ivt_bic\n";
+ }
+
+ $i++;
+}
+
+echo "\n$i Zeilen verarbeitet\n";
\ No newline at end of file
diff --git a/scripts/fibu-check/test-bmd-sepafile-sepa-data.php b/scripts/fibu-check/test-bmd-sepafile-sepa-data.php
new file mode 100644
index 000000000..b7b00cd5a
--- /dev/null
+++ b/scripts/fibu-check/test-bmd-sepafile-sepa-data.php
@@ -0,0 +1,117 @@
+#!/usr/bin/php
+@i', $line, $m)) {
+ $in_tx = false;
+ $rechnum = false;
+ $iban = false;
+ $bic = false;
+ $i++;
+ continue;
+ }
+
+ $m = [];
+ if(preg_match('@
@i', $line, $m)) {
+ $in_tx = true;
+ continue;
+ }
+
+ if($in_tx) {
+ $m = [];
+ if(preg_match('@([a-z0-9-]+)@i', $line, $m)) {
+ $rechnum = $m[1];
+ }
+
+ if(preg_match('@([a-z0-9-]+)@i', $line, $m)) {
+ $bic = $m[1];
+ }
+
+ if(preg_match('@([a-z0-9-]+)@i', $line, $m)) {
+ $iban = $m[1];
+ }
+
+ if($rechnum && $bic && $iban) {
+
+ if(!array_key_exists($rechnum, $data)) {
+ $data[$rechnum] = [
+ "iban" => $iban,
+ "bic" => $bic
+ ];
+ }
+ }
+
+ }
+}
+
+echo "$i input datensätze\n";
+exit;
+
+$i = 0;
+foreach($data as $r => $d) {
+ //echo "$r ".$d["iban"]." ".$d["bic"]."\n";
+
+ $m = [];
+ if(!preg_match('/(RN2024-.+)/', $r, $m)) {
+ die("error");
+ }
+
+ $rechnum = $m[1];
+ $sepa_iban = strtoupper(str_replace(" ","", $d["iban"]));
+ $sepa_bic = strtoupper(str_replace(" ","", $d["bic"]));
+
+ $invoice = InvoiceModel::getFirst(["invoice_number" => $rechnum]);
+ if(!$invoice) {
+ die("$rechnum not found\n");
+ }
+
+ $address = new Address($invoice->billingaddress_id);
+ if(!$address) {
+ die("not billingaddress\n");
+ }
+ $tiban = strtoupper(str_replace(" ","", $address->bank_account_iban));
+ $tbic = strtoupper(str_replace(" ","", $address->bank_account_bic));
+
+ if($sepa_iban != $tiban) {
+ echo "$rechnum | tool iban: $tiban <> $sepa_iban\n";
+ }
+ if($sepa_bic != $tbic) {
+ echo "$rechnum | tool bic: $tbic <> $sepa_bic\n";
+ }
+
+ $i++;
+}
+echo "$i sepa daten verglichen\n";
\ No newline at end of file