Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision eada6c17

Von Johannes Grassler vor mehr als 1 Jahr hinzugefügt

  • ID eada6c176efe6d4d4bd24420fe73f2ad7fd675f7
  • Vorgänger 08649f7d
  • Nachfolger 46477289

Einrueckungen und weitere Stilprobleme repariert

Unterschiede anzeigen:

SL/Controller/ZUGFeRD.pm
if ( ! ($metadata{'ustid'} or $metadata{'taxnumber'}) ) {
die t8("Cannot process this invoice: neither VAT ID nor tax ID present.");
}
}
$vendor = find_vendor($metadata{'ustid'}, $metadata{'taxnumber'});
......
my $tax_rate = $item{'tax_rate'} / 100; # XML data is usually in percent
my $taxes = SL::DB::Manager::Tax->get_all(
where => [ chart_categories => { like => '%' . $default_ap_amount_chart->category . '%' },
rate => $tax_rate,
],
where => [
chart_categories => { like => '%' . $default_ap_amount_chart->category . '%' },
rate => $tax_rate,
],
);
# If we really can't find any tax definition (a simple rounding error may
......
my $tax = ${$taxes}[0];
my $item_obj = SL::DB::RecordTemplateItem
->new(amount1 => $net_total,
record_template_id => $template_ap->id,
chart_id => $default_ap_amount_chart->id,
tax_id => $tax->id,
);
my $item_obj = SL::DB::RecordTemplateItem->new(
amount1 => $net_total,
record_template_id => $template_ap->id,
chart_id => $default_ap_amount_chart->id,
tax_id => $tax->id,
);
$item_obj->save;
}
SL/XMLInvoice.pm
package SL::XMLInvoice;
use strict;
use warnings;
use XML::LibXML;
use SL::XMLInvoice::UBL;
use SL::XMLInvoice::CrossIndustryInvoice;
use constant RES_OK => 0;
use constant RES_XML_PARSING_FAILED => 1;
use constant RES_UNKNOWN_ROOT_NODE_TYPE => 2;
=head1 NAME
SL::XMLInvoice - Top level factory class for XML Invoice parsers.
......
=cut
use strict;
use warnings;
use XML::LibXML;
=head1 ATTRIBUTES
=over 4
......
=cut
use constant RES_OK => 0;
use constant RES_XML_PARSING_FAILED => 1;
use constant RES_UNKNOWN_ROOT_NODE_TYPE => 2;
=head1 METHODS
=head2 Data structure definition methods (only in C<SL::XMLInvoice>)
......
sub metadata {
my $self = shift;
die "Children of $self must implement a metadata() method returning the bill's metadata as a hash.";
}
}
=item items()
......
sub items {
my $self = shift;
die "Children of $self must implement a item() method returning the bill's items as a hash.";
}
}
=item parse_xml()
......
sub parse_xml {
my $self = shift;
die "Children of $self must implement a parse_xml() method.";
}
}
=head2 Internal methods
......
=cut
use SL::XMLInvoice::UBL;
use SL::XMLInvoice::CrossIndustryInvoice;
sub _document_nodenames {
return {
'rsm:CrossIndustryInvoice' => 'SL::XMLInvoice::CrossIndustryInvoice',
......
sub _data_keys {
my $self = shift;
die "Children of $self must implement a _data_keys() method returning the keys an invoice item hash will contain.";
}
}
=item _item_keys()
......
sub _item_keys {
my $self = shift;
die "Children of $self must implement a _item_keys() method returning the keys an invoice item hash will contain.";
}
}
sub new
{
sub new {
my ($self, $xml_data) = @_;
my $type = undef;
$self = {};
......
$self->{message} = $::locale->text("Parsing the XML data failed: $xml_data");
$self->{result} = RES_XML_PARSING_FAILED;
return $self;
}
}
# Determine parser class to use
my $document_nodename = $self->{dom}->documentElement->nodeName;
if ( ${$self->_document_nodenames}{$document_nodename} ) {
$type = ${$self->_document_nodenames}{$document_nodename}
}
}
unless ( $type ) {
$self->{result} = RES_UNKNOWN_ROOT_NODE_TYPE;
......
$node_types,
$document_nodename);
return $self;
}
}
bless $self, $type;
# Implementation sanity check for child classes: make sure they are aware of
# the keys the hash returned by their metadata() method must contain.
my @missing_data_keys = ();
foreach my $data_key ( @{$self->data_keys} )
{
unless ( ${$self->_data_keys}{$data_key}) { push @missing_data_keys, $data_key; }
}
my @missing_data_keys = grep { !${$self->_data_keys}{$data_key} } @{ $self->data_keys };
if ( scalar(@missing_data_keys) > 0 ) {
die "Incomplete implementation: the following metadata keys appear to be missing from $type: " . join(", ", @missing_data_keys);
}
......
# Implementation sanity check for child classes: make sure they are aware of
# the keys the hashes returned by their items() method must contain.
my @missing_item_keys = ();
foreach my $item_key ( @{$self->item_keys} )
{
foreach my $item_key ( @{$self->item_keys} ) {
unless ( ${$self->_item_keys}{$item_key}) { push @missing_item_keys, $item_key; }
}
}
if ( scalar(@missing_item_keys) > 0 ) {
die "Incomplete implementation: the following item keys appear to be missing from $type: " . join(", ", @missing_item_keys);
}
......
$self->{result} = RES_OK;
return $self;
}
}
1;
SL/XMLInvoice/CrossIndustryInvoice.pm
package SL::XMLInvoice::CrossIndustryInvoice;
use strict;
use warnings;
use parent qw(SL::XMLInvoice);
use constant ITEMS_XPATH => '//ram:IncludedSupplyChainTradeLineItem';
=head1 NAME
SL::XMLInvoice::FakturX - XML parser for UN/CEFACT Cross Industry Invoice
......
=cut
use strict;
use constant ITEMS_XPATH => '//ram:IncludedSupplyChainTradeLineItem';
# XML XPath expressions for global metadata
sub scalar_xpaths {
return {
......
push @items, \%line_item;
}
}
1;
SL/XMLInvoice/UBL.pm
package SL::XMLInvoice::UBL;
use strict;
use warnings;
use parent qw(SL::XMLInvoice);
use constant ITEMS_XPATH => '//cac:InvoiceLine';
=head1 NAME
SL::XMLInvoice::UBL - XML parser for Universal Business Language invoices
......
=cut
use strict;
use parent qw(SL::XMLInvoice);
use constant ITEMS_XPATH => '//cac:InvoiceLine';
# XML XPath expression for
sub scalar_xpaths {
return {
......
# have to guess whether it's a tax ID or VAT ID (not using
# SL::VATIDNr->validate here to keep this code portable):
if ( ${$self->{_metadata}}{'ustid'} =~ qr"/" )
{
if ( ${$self->{_metadata}}{'ustid'} =~ qr"/" ) {
# Unset this since the 'taxid' key has been retrieved with the same xpath
# expression.
${$self->{_metadata}}{'ustid'} = undef;
} else {
} else {
# Unset this since the 'ustid' key has been retrieved with the same xpath
# expression.
${$self->{_metadata}}{'taxnumber'} = undef;
}
}
my @items;
$self->{_items} = \@items;
SL/ZUGFeRD.pm
use constant PROFILE_FACTURX_EXTENDED => 0;
use constant PROFILE_XRECHNUNG => 1;
use constant RES_OK => 0;
use constant RES_ERR_FILE_OPEN => -1;
use constant RES_ERR_NO_ATTACHMENT => -2;
use constant RES_OK => 0;
use constant RES_ERR_FILE_OPEN => -1;
use constant RES_ERR_NO_ATTACHMENT => -2;
our @customer_settings = (
[ 0, t8('Do not create Factur-X/ZUGFeRD invoices') ],
......
if ( $parser->{status} == SL::XMLInvoice::RES_OK ){
return $parser;
} else {
push @res, t8("Could not parse PDF embedded attachment #1: #2",
$k,
$parser->{result});
push @res, t8(
"Could not parse PDF embedded attachment #1: #2",
$k,
$parser->{result}
);
}
}
}
......
# this point - if there were no attachments at all, we would have bailed out
# a lot earlier.
%res_fail = ( result => RES_ERR_FILE_OPEN(),
message => join("; ", @res),
%res_fail = (
result => RES_ERR_FILE_OPEN(),
message => join("; ", @res),
);
return \%res_fail;

Auch abrufbar als: Unified diff