Invoice PAIN & CSV can be uploaded

This commit is contained in:
2026-02-13 22:37:27 +01:00
parent cd526231ed
commit 4f4dff2edd
29 changed files with 1635 additions and 193 deletions

View File

@@ -0,0 +1,127 @@
<?php
namespace App\Providers;
use App\Models\Invoice;
use DOMDocument;
use Exception;
class PainFileProvider {
public string $senderIban;
public string $senderName;
public string $senderBic;
/* @var Invoice[] */
public array $invoices;
public function __construct(string $senderIban, string $senderName, string $senderBic, array $invoices) {
$this->senderIban = $senderIban;
$this->senderName = $senderName;
$this->senderBic = $senderBic;
$this->invoices = $invoices;
}
public function createPainFileContent() : string {
$doc = new DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;
$senderIban = str_replace(' ', '', $this->senderIban);
$senderBic = str_replace(' ', '', $this->senderBic);
// Root-Element
$document = $doc->createElement('Document');
$document->setAttribute('xmlns', 'urn:iso:std:iso:20022:tech:xsd:pain.001.001.03');
$document->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$doc->appendChild($document);
// CstmrCdtTrfInitn
$cstmr_cdt_trf_initn = $doc->createElement('CstmrCdtTrfInitn');
$document->appendChild($cstmr_cdt_trf_initn);
// GrpHdr
$grp_hdr = $doc->createElement('GrpHdr');
$cstmr_cdt_trf_initn->appendChild($grp_hdr);
$grp_hdr->appendChild($doc->createElement('MsgId', uniqid('MSG')));
$grp_hdr->appendChild($doc->createElement('CreDtTm', date('c')));
$grp_hdr->appendChild($doc->createElement('NbOfTxs', count($this->invoices)));
$totalAmount = array_sum(array_column($this->invoices, 'amount'));
$grp_hdr->appendChild($doc->createElement('CtrlSum', number_format($totalAmount, 2, '.', '')));
$initg_pty = $doc->createElement('InitgPty');
$initg_pty->appendChild($doc->createElement('Nm', $this->senderName));
$grp_hdr->appendChild($initg_pty);
// PmtInf
$pmt_inf = $doc->createElement('PmtInf');
$cstmr_cdt_trf_initn->appendChild($pmt_inf);
$pmt_inf->appendChild($doc->createElement('PmtInfId', uniqid('PMT')));
$pmt_inf->appendChild($doc->createElement('PmtMtd', 'TRF'));
$pmt_inf->appendChild($doc->createElement('BtchBookg', 'false'));
$pmt_inf->appendChild($doc->createElement('NbOfTxs', count($this->invoices)));
$pmt_inf->appendChild($doc->createElement('CtrlSum', number_format($totalAmount, 2, '.', '')));
$pmt_tp_inf = $doc->createElement('PmtTpInf');
$svc_lvl = $doc->createElement('SvcLvl');
$svc_lvl->appendChild($doc->createElement('Cd', 'SEPA'));
$pmt_tp_inf->appendChild($svc_lvl);
$pmt_inf->appendChild($pmt_tp_inf);
$pmt_inf->appendChild($doc->createElement('ReqdExctnDt', date('Y-m-d', mktime(0))));
$dbtr = $doc->createElement('Dbtr');
$dbtr->appendChild($doc->createElement('Nm', $this->senderName));
$pmt_inf->appendChild($dbtr);
$dbtr_acct = $doc->createElement('DbtrAcct');
$id = $doc->createElement('Id');
$id->appendChild($doc->createElement('IBAN', $senderIban));
$dbtr_acct->appendChild($id);
$pmt_inf->appendChild($dbtr_acct);
$dbtr_agt = $doc->createElement('DbtrAgt');
$id = $doc->createElement('FinInstnId');
$id->appendChild($doc->createElement('BIC', $senderBic));
$dbtr_agt->appendChild($id);
$pmt_inf->appendChild($dbtr_agt);
foreach ($this->invoices as $index => $invoice) {
$cdt_trf_tx_inf = $doc->createElement('CdtTrfTxInf');
$pmt_id = $doc->createElement('PmtId');
$pmt_id->appendChild($doc->createElement('EndToEndId', uniqid('ET')));
$cdt_trf_tx_inf->appendChild($pmt_id);
$amt = $doc->createElement('Amt');
$instd_amt = $doc->createElement('InstdAmt', number_format($invoice['amount'], 2, '.', ''));
$instd_amt->setAttribute('Ccy', 'EUR');
$amt->appendChild($instd_amt);
$cdt_trf_tx_inf->appendChild($amt);
$cdtr = $doc->createElement('Cdtr');
$cdtr->appendChild($doc->createElement('Nm', $invoice['contact_bank_owner']));
$cdt_trf_tx_inf->appendChild($cdtr);
$cdtr_acct = $doc->createElement('CdtrAcct');
$cdtr_id = $doc->createElement('Id');
$cdtr_id->appendChild($doc->createElement('IBAN', str_replace(' ', '', $invoice['contact_bank_iban'])));
$cdtr_acct->appendChild($cdtr_id);
$cdt_trf_tx_inf->appendChild($cdtr_acct);
$rmt_inf = $doc->createElement('RmtInf');
$rmt_inf->appendChild($doc->createElement('Ustrd', 'Auslagenerstattung Rechnungsnummer ' . $invoice['invoice_number']));
$cdt_trf_tx_inf->appendChild($rmt_inf);
$pmt_inf->appendChild($cdt_trf_tx_inf);
}
$xml_content = $doc->saveXML();
if (false === $xml_content) {
throw new Exception('Failed to generate XML content.');
}
return $xml_content;
}
}