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");
bin/mozilla/sepa.pl
'vc' => $vc);
$form->header();
print $form->parse_html_template('sepa/bank_transfer_created', { 'id' => $id, 'vc' => $vc });
my %sepa_versions = SL::SEPA::XML->get_supported_versions;
print $form->parse_html_template('sepa/bank_transfer_created', { 'id' => $id, 'vc' => $vc, sepa_versions => \%sepa_versions });
}
$main::lxdebug->leave_sub();
......
push @options, $form->{l_executed} ? $locale->text('executed') : $locale->text('not yet executed') if ($form->{l_executed} != $form->{l_not_executed});
push @options, $form->{l_closed} ? $locale->text('closed') : $locale->text('open') if ($form->{l_open} != $form->{l_closed});
my %sepa_versions = SL::SEPA::XML->get_supported_versions;
$report->set_options('top_info_text' => join("\n", @options),
'raw_top_info_text' => $form->parse_html_template('sepa/bank_transfer_list_top'),
'raw_top_info_text' => $form->parse_html_template('sepa/bank_transfer_list_top', { 'show_buttons' => $open_available, sepa_versions => \%sepa_versions, }),
'raw_bottom_info_text' => $form->parse_html_template('sepa/bank_transfer_list_bottom', { 'show_buttons' => $open_available, vc => $vc }),
'std_column_visibility' => 1,
'output_format' => 'HTML',
......
'message_id' => $message_id,
'grouped' => 1,
'collection' => $vc eq 'customer',
'version' => $form->{sepa_xml_version},
);
foreach my $item (@items) {
locale/de/all
'SEPA Transfer Amount' => 'Betrag in offenen SEPA Exporten',
'SEPA XML Docs for Exports ' => 'SEPA-XML-Dokumente Export-Nummer',
'SEPA XML download' => 'SEPA-XML-Download',
'SEPA XML version' => 'SEPA-XML-Version',
'SEPA creditor ID' => 'SEPA-Kreditoren-Identifikation',
'SEPA exports' => 'SEPA-Exporte',
'SEPA message ID' => 'SEPA-Nachrichten-ID',
......
'The PDF has been printed' => 'Das PDF-Dokument wurde gedruckt.',
'The Protocol for Host Name seems invalid (expected: http:// or https://)!' => 'Das Protokoll für den Server sieht falsch aus. Erwartet wird "http://" oder "https://".',
'The Proxy Name seems invalid' => 'Der Hostname des Proxys sieht falsch aus',
'The SEPA export has been created.' => 'Der SEPA-Export wurde erstellt',
'The SEPA export has been created.' => 'Der SEPA-Export wurde erstellt.',
'The SEPA strings have been saved.' => 'Die bei SEPA-Überweisungen verwendeten Begriffe wurden gespeichert.',
'The SQL query can be parameterized with variables named as follows: <%name%>.' => 'Die SQL-Abfrage kann mittels Variablen wie folgt parametrisiert werden: <%Variablenname%>.',
'The SQL query does not contain any parameter that need to be configured.' => 'Die SQL-Abfrage enthält keine Parameter, die angegeben werden müssten.',
locale/en/all
'SEPA Transfer Amount' => '',
'SEPA XML Docs for Exports ' => '',
'SEPA XML download' => '',
'SEPA XML version' => '',
'SEPA creditor ID' => '',
'SEPA exports' => '',
'SEPA message ID' => '',
templates/design40_webpages/sepa/bank_transfer_created.html
[% USE T8 %]
[% USE HTML %]
[%- USE T8 %]
[% USE HTML %][%- USE LxERP -%][%- USE L -%]
<h1>[% title %]</h1>
<p>[% 'The SEPA export has been created.' | $T8 %]</p>
<ul>
<li><a href="sepa.pl?action=bank_transfer_download_sepa_xml&id=[% HTML.url(id) %]&vc=[% HTML.url(vc) %]"> [% 'Download SEPA XML export file' | $T8 %] </a></li>
[%- IF INSTANCE_CONF.get_doc_storage %]
<li><a href="sepa.pl?action=bank_transfer_download_sepa_docs&id=[% HTML.url(id) %]&vc=[% HTML.url(vc) %]"> [% 'Download Documents for exported bookings' | $T8 %] </a></li>
[% END %]
<li><a href="sepa.pl?action=bank_transfer_list&l_open=1&l_not_executed=1&vc=[% HTML.url(vc) %]"> [% 'List open SEPA exports' | $T8 %] </a></li>
</ul>
<p>
[% 'The SEPA export has been created.' | $T8 %]
</p>
<h2>[% LxERP.t8('Download SEPA XML export file') %]</h2>
<form method="post" action="sepa.pl">
<p>
[% LxERP.t8("SEPA XML version") %]:
[% L.select_tag('sepa_xml_version', sepa_versions.versions, title_key='description', selected=sepa_versions.default) %]
</p>
<p>
[% L.hidden_tag('action', 'bank_transfer_download_sepa_xml') %]
[% L.hidden_tag('id', id) %]
[% L.hidden_tag('vc', vc) %]
[% L.submit_tag('dummy', LxERP.t8('Download')) %]
</p>
</form>
[%- IF INSTANCE_CONF.get_doc_storage %]
<h2>[% LxERP.t8('Download Documents for exported bookings') %]</h2>
<p>
<a href="sepa.pl?action=bank_transfer_download_sepa_docs&id=[% HTML.url(id) %]&vc=[% HTML.url(vc) %]"> [% 'Download Documents for exported bookings' | $T8 %]</a>
</p>
[% END %]
<h2>[% LxERP.t8('List open SEPA exports') %]</h2>
<p>
<a href="sepa.pl?action=bank_transfer_list&l_open=1&l_not_executed=1&vc=[% HTML.url(vc) %]">[% 'List open SEPA exports' | $T8 %]</a>
</p>
templates/design40_webpages/sepa/bank_transfer_list_top.html
[%- USE LxERP -%][%- USE L -%]
<form action="sepa.pl" method="post" id="form">
[% IF show_buttons %]
<p>
[% LxERP.t8("SEPA XML version") %]:
[% L.select_tag('sepa_xml_version', sepa_versions.versions, title_key='description', selected=sepa_versions.default) %]
</p>
[% END %]
templates/webpages/sepa/bank_transfer_created.html
[%- USE T8 %]
[% USE HTML %]
[% USE HTML %][%- USE LxERP -%][%- USE L -%]
<h1>[% title %]</h1>
<p>
<p>
[% 'The SEPA export has been created.' | $T8 %]
</p>
<p>
<ul>
<li>
<a href="sepa.pl?action=bank_transfer_download_sepa_xml&id=[% HTML.url(id) %]&vc=[% HTML.url(vc) %]">
[% 'Download SEPA XML export file' | $T8 %]
</a>
</li>
[%- IF INSTANCE_CONF.get_doc_storage %]
<li><a href="sepa.pl?action=bank_transfer_download_sepa_docs&id=[% HTML.url(id) %]&vc=[% HTML.url(vc) %]"> [% 'Download Documents for exported bookings' | $T8 %] </a></li>
[% END %]
<li>
<a href="sepa.pl?action=bank_transfer_list&l_open=1&l_not_executed=1&vc=[% HTML.url(vc) %]">
[% 'List open SEPA exports' | $T8 %]
</a>
</li>
</ul>
</p>
</p>
<h2>[% LxERP.t8('Download SEPA XML export file') %]</h2>
<form method="post" action="sepa.pl">
<p>
[% LxERP.t8("SEPA XML version") %]:
[% L.select_tag('sepa_xml_version', sepa_versions.versions, title_key='description', selected=sepa_versions.default) %]
</p>
<p>
[% L.hidden_tag('action', 'bank_transfer_download_sepa_xml') %]
[% L.hidden_tag('id', id) %]
[% L.hidden_tag('vc', vc) %]
[% L.submit_tag('dummy', LxERP.t8('Download')) %]
</p>
</form>
[%- IF INSTANCE_CONF.get_doc_storage %]
<h2>[% LxERP.t8('Download Documents for exported bookings') %]</h2>
<p>
<a href="sepa.pl?action=bank_transfer_download_sepa_docs&id=[% HTML.url(id) %]&vc=[% HTML.url(vc) %]"> [% 'Download Documents for exported bookings' | $T8 %]</a>
</p>
[% END %]
<h2>[% LxERP.t8('List open SEPA exports') %]</h2>
<p>
<a href="sepa.pl?action=bank_transfer_list&l_open=1&l_not_executed=1&vc=[% HTML.url(vc) %]">[% 'List open SEPA exports' | $T8 %]</a>
</p>
templates/webpages/sepa/bank_transfer_list_top.html
[%- USE LxERP -%][%- USE L -%]
<form action="sepa.pl" method="post" id="form">
[% IF show_buttons %]
<p>
[% LxERP.t8("SEPA XML version") %]:
[% L.select_tag('sepa_xml_version', sepa_versions.versions, title_key='description', selected=sepa_versions.default) %]
</p>
[% END %]

Auch abrufbar als: Unified diff