X-Git-Url: http://wagnertech.de/gitweb/gitweb.cgi/mfinanz.git/blobdiff_plain/e5f53eb5c67c19d6a356fcde22ca46169cdca5dc..27e9e34d3e7535217351bbb2c787110fb23f6607:/SL/DB/Helper/ZUGFeRD.pm diff --git a/SL/DB/Helper/ZUGFeRD.pm b/SL/DB/Helper/ZUGFeRD.pm index 5cee13a3e..826cef1a9 100644 --- a/SL/DB/Helper/ZUGFeRD.pm +++ b/SL/DB/Helper/ZUGFeRD.pm @@ -15,7 +15,7 @@ use SL::Helper::UNECERecommendation20; use Carp; use Encode qw(encode); -use List::MoreUtils qw(pairwise); +use List::MoreUtils qw(any pairwise); use List::Util qw(first sum); use Template; use XML::Writer; @@ -50,7 +50,10 @@ sub _type_code { # 381 (Credit note) # 389 (Credit note, self billed invoice) - return $type eq 'credit_note' ? 381 : 380; + return $type eq 'credit_note' ? 381 + : $type eq 'invoice_storno' ? 457 + : $type eq 'credit_note_storno' ? 458 + : 380; } sub _unit_code { @@ -298,9 +301,12 @@ sub _exchanged_document_context { # $params{xml}->startTag("rsm:ExchangedDocumentContext"); - $params{xml}->startTag("ram:TestIndicator"); - $params{xml}->dataElement("udt:Indicator", "true"); # TODO: change to 'false' - $params{xml}->endTag; + + if ($::instance_conf->get_create_zugferd_invoices == 2) { + $params{xml}->startTag("ram:TestIndicator"); + $params{xml}->dataElement("udt:Indicator", "true"); + $params{xml}->endTag; + } $params{xml}->startTag("ram:GuidelineSpecifiedDocumentContextParameter"); $params{xml}->dataElement("ram:ID", "urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended"); @@ -362,6 +368,20 @@ sub _exchanged_document { # } +sub _specified_tax_registration { + my ($ustid_nr, %params) = @_; + + return unless $ustid_nr; + + $ustid_nr = "DE$ustid_nr" unless $ustid_nr =~ m{^[A-Z]{2}}; + + # + $params{xml}->startTag("ram:SpecifiedTaxRegistration"); + $params{xml}->dataElement("ram:ID", _u8($ustid_nr), "schemeID" => "VA"); + $params{xml}->endTag; + # +} + sub _seller_trade_party { my ($self, %params) = @_; @@ -408,15 +428,7 @@ sub _seller_trade_party { # } - my $ustid_nr = $::instance_conf->get_co_ustid; - if ($ustid_nr) { - $ustid_nr = "DE$ustid_nr" unless $ustid_nr =~ m{^[A-Z]{2}}; - # - $params{xml}->startTag("ram:SpecifiedTaxRegistration"); - $params{xml}->dataElement("ram:ID", _u8($ustid_nr), "schemeID" => "VA"); - $params{xml}->endTag; - # - } + _specified_tax_registration($::instance_conf->get_co_ustid, %params); $params{xml}->endTag; # @@ -431,6 +443,7 @@ sub _buyer_trade_party { $params{xml}->dataElement("ram:Name", _u8($self->customer->name)); _customer_postal_trade_address(%params, customer => $self->customer); + _specified_tax_registration($self->customer->ustid, %params); $params{xml}->endTag; # @@ -515,9 +528,42 @@ sub _supply_chain_trade_transaction { # } +sub _validate_data { + my ($self) = @_; + + my $prefix = $::locale->text('The ZUGFeRD invoice data cannot be generated because the data validation failed.') . ' '; + + if (!$::instance_conf->get_co_ustid) { + SL::X::ZUGFeRDValidation->throw(message => $prefix . $::locale->text('The VAT registration number is missing in the client configuration.')); + } + + if (!$::instance_conf->get_company || any { my $get = "get_address_$_"; !$::instance_conf->$get } qw(street1 zipcode city)) { + SL::X::ZUGFeRDValidation->throw(message => $prefix . $::locale->text('The company\'s address information is incomplete in the client configuration.')); + } + + if ($::instance_conf->get_address_country && !SL::Helper::ISO3166::map_name_to_alpha_2_code($::instance_conf->get_address_country)) { + SL::X::ZUGFeRDValidation->throw(message => $prefix . $::locale->text('The country from the company\'s address in the client configuration cannot be mapped to an ISO 3166-1 alpha 2 code.')); + } + + if ($self->customer->country && !SL::Helper::ISO3166::map_name_to_alpha_2_code($self->customer->country)) { + SL::X::ZUGFeRDValidation->throw(message => $prefix . $::locale->text('The country from the customer\'s address cannot be mapped to an ISO 3166-1 alpha 2 code.')); + } + + if (!SL::Helper::ISO4217::map_currency_name_to_code($self->currency->name)) { + SL::X::ZUGFeRDValidation->throw(message => $prefix . $::locale->text('The currency "#1" cannot be mapped to an ISO 4217 currency code.', $self->currency->name)); + } + + my $failed_unit = first { !SL::Helper::UNECERecommendation20::map_name_to_code($_) } map { $_->unit } @{ $self->items }; + if ($failed_unit) { + SL::X::ZUGFeRDValidation->throw(message => $prefix . $::locale->text('One of the units used (#1) cannot be mapped to a known unit code from the UN/ECE Recommendation 20 list.', $failed_unit)); + } +} + sub create_zugferd_data { my ($self) = @_; + _validate_data($self); + my %ptc_data = $self->calculate_prices_and_taxes; my $output = ''; my $xml = XML::Writer->new(