Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision d62a113d

Von Moritz Bunkus vor 11 Monaten hinzugefügt

SEPA: XML-Version beim Download auswählbar

Unterschiede anzeigen:

SL/SEPA/XML.pm
use Carp;
use Encode;
use List::Util qw(first sum);
use List::MoreUtils qw(any);
use List::Util qw(first sum);
use POSIX qw(strftime);
use XML::Writer;
use SL::Iconv;
use SL::SEPA::XML::Transaction;
use constant V3_0_0 => 3_000_000;
use constant V3_8_0 => 3_800_000;
sub get_supported_versions {
return (
versions => [
{ id => V3_0_0(), description => "v3.0.0" },
{ id => V3_8_0(), description => "v3.8.0" },
],
default => get_default_version(),
);
}
sub get_default_version {
my $today = DateTime->today_local;
my $cutoff_v3_8_0 = DateTime->new_local(year => 2025, month => 10, day => 1);
return V3_8_0() if $today >= $cutoff_v3_8_0;
return V3_0_0();
}
sub is_version_valid {
shift while @_ && ref($_[0]);
my $id = $_[0];
my %versions = get_supported_versions();
return any { $_->{id} == $id } @{ $versions{versions} };
}
sub new {
my $class = shift;
my $self = {};
......
$self->{transactions} = [];
$self->{src_charset} = 'UTF-8';
$self->{grouped} = 0;
$self->{version} = get_default_version();
map { $self->{$_} = $params{$_} if (exists $params{$_}) } qw(src_charset company creditor_id message_id grouped collection);
map { $self->{$_} = $params{$_} if (exists $params{$_}) } qw(src_charset company creditor_id message_id grouped collection version);
$self->{iconv} = SL::Iconv->new($self->{src_charset}, "UTF-8") || croak "Unsupported source charset $self->{src_charset}.";
my $missing_parameter = first { !$self->{$_} } qw(company message_id);
croak "Missing parameter: $missing_parameter" if ($missing_parameter);
croak "Missing parameter: creditor_id" if !$self->{creditor_id} && $self->{collection};
croak "Invalid parameter: version" if !is_version_valid($self->{version});
map { $self->{$_} = $self->_replace_special_chars($self->{iconv}->convert($self->{$_})) } qw(company message_id creditor_id);
}
......
return substr $string, 0, 35;
}
sub _emit_cdtr_scheme_id {
my ($self, $xml) = @_;
$xml->startTag('CdtrSchmeId');
$xml->startTag('Id');
$xml->startTag('PrvtId');
$xml->startTag('Othr');
$xml->dataElement('Id', encode('UTF-8', substr($self->{creditor_id}, 0, 35)));
$xml->startTag('SchmeNm');
$xml->dataElement('Prtry', 'SEPA');
$xml->endTag('SchmeNm');
$xml->endTag('Othr');
$xml->endTag('PrvtId');
$xml->endTag('Id');
$xml->endTag('CdtrSchmeId');
}
sub to_xml {
my $self = shift;
......
my $is_coll = $self->{collection};
my $cd_src = $is_coll ? 'Cdtr' : 'Dbtr';
my $cd_dst = $is_coll ? 'Dbtr' : 'Cdtr';
my $pain_id = $is_coll ? 'pain.008.001.08' : 'pain.001.001.09';
my $pain_elmt = $is_coll ? 'CstmrDrctDbtInitn' : 'CstmrCdtTrfInitn';
my @pii_base = (strftime('PII%Y%m%d%H%M%S', @now), rand(1000000000));
my $pain_id = $is_coll && ($self->{version} == V3_0_0()) ? 'pain.008.001.02'
: $is_coll && ($self->{version} == V3_8_0()) ? 'pain.008.001.08'
: !$is_coll && ($self->{version} == V3_0_0()) ? 'pain.001.001.03'
: !$is_coll && ($self->{version} == V3_8_0()) ? 'pain.001.001.09'
: die("programming error: version not handled for pain ID");
my $bic_elt = $self->{version} == V3_0_0() ? 'BIC'
: $self->{version} == V3_8_0() ? 'BICFI'
: die("programming error: version not handled for BIC element name");
my $grouped_transactions = $self->_group_transactions();
......
}
$xml->endTag('PmtTpInf');
if ($is_coll) {
$xml->dataElement('ReqdColltnDt', $master_transaction->get('execution_date'));
if ($self->{version} == V3_0_0()) {
$xml->dataElement($is_coll ? 'ReqdColltnDt' : 'ReqdExctnDt', $master_transaction->get('execution_date'));
} elsif ($self->{version} == V3_8_0()) {
if ($is_coll) {
$xml->dataElement('ReqdColltnDt', $master_transaction->get('execution_date'));
} else {
$xml->startTag('ReqdExctnDt');
$xml->dataElement('Dt', $master_transaction->get('execution_date'));
$xml->endTag('ReqdExctnDt');
}
} else {
$xml->startTag('ReqdExctnDt');
$xml->dataElement('Dt', $master_transaction->get('execution_date'));
$xml->endTag('ReqdExctnDt');
die("programming error: version not handled for ReqdColl/ExctnDt");
}
$xml->startTag($cd_src);
......
$xml->startTag($cd_src . 'Agt');
$xml->startTag('FinInstnId');
$xml->dataElement('BICFI', $master_transaction->get('src_bic', 20));
$xml->dataElement($bic_elt, $master_transaction->get('src_bic', 20));
$xml->endTag('FinInstnId');
$xml->endTag($cd_src . 'Agt');
$xml->dataElement('ChrgBr', 'SLEV');
if ($is_coll) {
$xml->startTag('CdtrSchmeId');
$xml->startTag('Id');
$xml->startTag('PrvtId');
$xml->startTag('Othr');
$xml->dataElement('Id', encode('UTF-8', substr($self->{creditor_id}, 0, 35)));
$xml->startTag('SchmeNm');
$xml->dataElement('Prtry', 'SEPA');
$xml->endTag('SchmeNm');
$xml->endTag('Othr');
$xml->endTag('PrvtId');
$xml->endTag('Id');
$xml->endTag('CdtrSchmeId');
if ($is_coll && ($self->{version} == V3_8_0())) {
$self->_emit_cdtr_scheme_id($xml);
}
foreach my $transaction (@{ $transaction_group->{transactions} }) {
......
$xml->dataElement('MndtId', $self->_restricted_identification_sepa2($transaction->get('mandator_id')));
$xml->dataElement('DtOfSgntr', $self->_restricted_identification_sepa2($transaction->get('date_of_signature')));
if ($self->{version} == V3_0_0()) {
$self->_emit_cdtr_scheme_id($xml);
}
$xml->endTag('MndtRltdInf');
$xml->endTag('DrctDbtTx');
......
$xml->startTag("${cd_dst}Agt");
$xml->startTag('FinInstnId');
$xml->dataElement('BICFI', $transaction->get('dst_bic', 20));
$xml->dataElement($bic_elt, $transaction->get('dst_bic', 20));
$xml->endTag('FinInstnId');
$xml->endTag("${cd_dst}Agt");

Auch abrufbar als: Unified diff