Revision 0bdaae6a
Von Johannes Grassler vor mehr als 1 Jahr hinzugefügt
SL/XMLInvoice.pm | ||
---|---|---|
use strict;
|
||
use warnings;
|
||
|
||
use Module::Load;
|
||
|
||
use SL::Locale::String qw(t8);
|
||
use XML::LibXML;
|
||
|
||
... | ... | |
die "Children of $self must implement a metadata() method returning the bill's metadata as a hash.";
|
||
}
|
||
|
||
=item check_signature($dom)
|
||
|
||
This static method takes a DOM object and returns 1 if this DOM object can be
|
||
parsed by the child class in question, 0 otherwise. C<SL::XMLInvoice> uses this
|
||
method to determine which child class to instantiate for a given document. All
|
||
child classes must implement this method.
|
||
|
||
=cut
|
||
|
||
sub check_signature {
|
||
my $self = shift;
|
||
die "Children of $self must implement a check_signature() method returning 1 for supported XML, 0 for unsupported XML.";
|
||
}
|
||
|
||
=item supported()
|
||
|
||
This static method returns an array of free-form strings describing XML invoice
|
||
types parseable by the child class. C<SL::XMLInvoice> uses this method to
|
||
output a list of supported XML invoice types if its constructor fails to find
|
||
to find an appropriate child class to parse the given document with. All child
|
||
classes must implement this method.
|
||
|
||
=cut
|
||
|
||
sub supported {
|
||
my $self = shift;
|
||
die "Children of $self must implement a supported() method returning a list of supported XML invoice types.";
|
||
}
|
||
|
||
|
||
=item items()
|
||
|
||
This method returns an array of hashes containing line item metadata, such as
|
||
... | ... | |
die "Children of $self must implement a item() method returning the bill's items as a hash.";
|
||
}
|
||
|
||
|
||
=item parse_xml()
|
||
|
||
This method is only implemented in child classes of C<SL::XMLInvoice> and is
|
||
... | ... | |
|
||
=over 4
|
||
|
||
=item _document_nodenames()
|
||
=item _document_modules()
|
||
|
||
This method is implemented in C<SL::XMLInvoice> only and returns a hash mapping
|
||
XML document root node name to a child class implementing a parser for it. If
|
||
you add any child classes for new XML document types you need to add them to
|
||
this hash and add a use statement to make it available from C<SL::XMLInvoice>.
|
||
This method is implemented in C<SL::XMLInvoice> only and returns a list of
|
||
child classes, each implementing an XML invoice parser. If you add any child
|
||
classes for new XML document types you need to add them to this list to make it
|
||
available from C<SL::XMLInvoice>.
|
||
|
||
=cut
|
||
|
||
sub _document_nodenames {
|
||
return {
|
||
'rsm:CrossIndustryInvoice' => 'SL::XMLInvoice::CrossIndustryInvoice',
|
||
'ubl:Invoice' => 'SL::XMLInvoice::UBL',
|
||
};
|
||
sub _document_modules {
|
||
return (
|
||
'SL::XMLInvoice::CrossIndustryInvoice',
|
||
'SL::XMLInvoice::UBL',
|
||
);
|
||
}
|
||
|
||
=item _data_keys()
|
||
... | ... | |
sub new {
|
||
my ($self, $xml_data) = @_;
|
||
my $type = undef;
|
||
|
||
$self = {};
|
||
|
||
bless $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}
|
||
}
|
||
foreach my $module ( $self->_document_modules )
|
||
{
|
||
load $module;
|
||
if ( $module->check_signature($self->{dom}) ) {
|
||
$type = $module;
|
||
last;
|
||
}
|
||
}
|
||
|
||
unless ( $type ) {
|
||
$self->{result} = RES_UNKNOWN_ROOT_NODE_TYPE;
|
||
my $node_types = join(",", keys %{ $self->_document_nodenames });
|
||
$self->{message} = t8("Could not parse XML Invoice: unknown root node name (#1) (supported: (#2))",
|
||
$document_nodename,
|
||
$node_types,
|
||
my @supported = ();
|
||
|
||
foreach my $module ( $self->_document_modules ) {
|
||
my @module_list = $module->supported();
|
||
push @supported, @module_list;
|
||
}
|
||
|
||
my $supported_types = join(",\n", @supported);
|
||
$self->{message} = t8("Could not parse XML Invoice: unknown XML invoice type\nsupported: #1",
|
||
$supported_types,
|
||
);
|
||
return $self;
|
||
}
|
||
|
||
eval {require $type}; # Load the parser class
|
||
bless $self, $type;
|
||
|
||
# Implementation sanity check for child classes: make sure they are aware of
|
SL/XMLInvoice/CrossIndustryInvoice.pm | ||
---|---|---|
|
||
=head1 NAME
|
||
|
||
SL::XMLInvoice::FakturX - XML parser for UN/CEFACT Cross Industry Invoice
|
||
SL::XMLInvoice::CrossIndustryInvoice - XML parser for UN/CEFACT Cross Industry Invoice
|
||
|
||
=head1 DESCRIPTION
|
||
|
||
... | ... | |
|
||
=cut
|
||
|
||
sub supported {
|
||
my @supported = ( "UN/CEFACT Cross Industry Invoice (urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100)" );
|
||
return @supported;
|
||
}
|
||
|
||
sub check_signature {
|
||
my ($self, $dom) = @_;
|
||
|
||
my $rootnode = $dom->documentElement;
|
||
|
||
foreach my $attr ( $rootnode->attributes ) {
|
||
if ( $attr->getData =~ m/urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100/ ) {
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
# XML XPath expressions for global metadata
|
||
sub scalar_xpaths {
|
||
return {
|
SL/XMLInvoice/UBL.pm | ||
---|---|---|
|
||
=cut
|
||
|
||
# XML XPath expression for
|
||
sub supported {
|
||
my @supported = ( "Oasis Universal Business Language (UBL) invoice version 2 (urn:oasis:names:specification:ubl:schema:xsd:Invoice-2)" );
|
||
return @supported;
|
||
}
|
||
|
||
sub check_signature {
|
||
my ($self, $dom) = @_;
|
||
|
||
my $rootnode = $dom->documentElement;
|
||
|
||
foreach my $attr ( $rootnode->attributes ) {
|
||
if ( $attr->getData =~ m/urn:oasis:names:specification:ubl:schema:xsd:Invoice-2/ ) {
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
# XML XPath expressions for scalar metadata
|
||
sub scalar_xpaths {
|
||
return {
|
||
currency => '//cbc:DocumentCurrencyCode',
|
||
... | ... | |
};
|
||
}
|
||
|
||
# XML XPath expressions for parsing bill items
|
||
sub item_xpaths {
|
||
return {
|
||
'currency' => './cbc:LineExtensionAmount[attribute::currencyID]',
|
locale/de/all | ||
---|---|---|
'Could not load this draft' => 'Dieser Entwurf konnte nicht geladen werden',
|
||
'Could not load this vendor' => 'Konnte diesen Lieferanten nicht laden',
|
||
'Could not parse PDF embedded attachment #1: #2' => 'Konnte PDF-Anhang #1 nicht verarbeiten: #2',
|
||
'Could not parse XML Invoice: unknown root node name (#1) (supported: (#2))' => 'Konnte XML-Rechnung nicht verabeiten: unbekanntes Wurzelelement (unterstützt: #2)',
|
||
'Could not parse XML Invoice: unknown XML invoice type\nsupported: #1' => 'Konnte XML-Rechnung nicht verarbeiten: unbekanntes XML-Format.\nUnterstützt: #1',
|
||
'Could not print dunning.' => 'Die Mahnungen konnten nicht gedruckt werden.',
|
||
'Could not reconcile chosen elements!' => 'Die gewählten Elemente konnten nicht ausgeglichen werden!',
|
||
'Could not spawn ghostscript.' => 'Die Anwendung "ghostscript" konnte nicht gestartet werden.',
|
Auch abrufbar als: Unified diff
XMLInvoice: Formaterkennung umgebaut