Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 652aebcf

Von Johannes Grassler vor etwa 1 Jahr hinzugefügt

  • ID 652aebcf4860d72bba8ec400765b679085b057f3
  • Vorgänger 06d29e36
  • Nachfolger ea01c174

XMLInvoice: Formaterkennung umgebaut

  • Formaterkennung nun in den Unterklassen von SL::XMLInvoice
  • Interface fuer Subklassen um check_signature() und supported() ergaenzt.
  • Lade Subklassen mit Module::Load

Unterschiede anzeigen:

SL/XMLInvoice.pm
3 3
use strict;
4 4
use warnings;
5 5

  
6
use Module::Load;
7

  
6 8
use SL::Locale::String qw(t8);
7 9
use XML::LibXML;
8 10

  
......
166 168
  die "Children of $self must implement a metadata() method returning the bill's metadata as a hash.";
167 169
}
168 170

  
171
=item check_signature($dom)
172

  
173
This static method takes a DOM object and returns 1 if this DOM object can be
174
parsed by the child class in question, 0 otherwise. C<SL::XMLInvoice> uses this
175
method to determine which child class to instantiate for a given document. All
176
child classes must implement this method.
177

  
178
=cut
179

  
180
sub check_signature {
181
  my $self = shift;
182
  die "Children of $self must implement a check_signature() method returning 1 for supported XML, 0 for unsupported XML.";
183
}
184

  
185
=item supported()
186

  
187
This static method returns an array of free-form strings describing XML invoice
188
types parseable by the child class. C<SL::XMLInvoice> uses this method to
189
output a list of supported XML invoice types if its constructor fails to find
190
to find an appropriate child class to parse the given document with. All child
191
classes must implement this method.
192

  
193
=cut
194

  
195
sub supported {
196
  my $self = shift;
197
  die "Children of $self must implement a supported() method returning a list of supported XML invoice types.";
198
}
199

  
200

  
169 201
=item items()
170 202

  
171 203
This method returns an array of hashes containing line item metadata, such as
......
181 213
  die "Children of $self must implement a item() method returning the bill's items as a hash.";
182 214
}
183 215

  
216

  
184 217
=item parse_xml()
185 218

  
186 219
This method is only implemented in child classes of C<SL::XMLInvoice> and is
......
206 239

  
207 240
=over 4
208 241

  
209
=item _document_nodenames()
242
=item _document_modules()
210 243

  
211
This method is implemented in C<SL::XMLInvoice> only and returns a hash mapping
212
XML document root node name to a child class implementing a parser for it. If
213
you add any child classes for new XML document types you need to add them to
214
this hash and add a use statement to make it available from C<SL::XMLInvoice>.
244
This method is implemented in C<SL::XMLInvoice> only and returns a list of
245
child classes, each implementing an XML invoice parser. If you add any child
246
classes for new XML document types you need to add them to this list to make it
247
available from C<SL::XMLInvoice>.
215 248

  
216 249
=cut
217 250

  
218
sub _document_nodenames {
219
  return {
220
    'rsm:CrossIndustryInvoice' => 'SL::XMLInvoice::CrossIndustryInvoice',
221
    'ubl:Invoice' => 'SL::XMLInvoice::UBL',
222
  };
251
sub _document_modules {
252
  return (
253
    'SL::XMLInvoice::CrossIndustryInvoice',
254
    'SL::XMLInvoice::UBL',
255
  );
223 256
}
224 257

  
225 258
=item _data_keys()
......
260 293
sub new {
261 294
  my ($self, $xml_data) = @_;
262 295
  my $type = undef;
296

  
263 297
  $self = {};
264 298

  
265 299
  bless $self;
......
274 308
  }
275 309

  
276 310
  # Determine parser class to use
277
  my $document_nodename = $self->{dom}->documentElement->nodeName;
278
  if ( ${$self->_document_nodenames}{$document_nodename} ) {
279
    $type = ${$self->_document_nodenames}{$document_nodename}
280
  }
311
  foreach my $module ( $self->_document_modules )
312
    {
313
    load $module;
314
    if ( $module->check_signature($self->{dom}) ) {
315
      $type = $module;
316
      last;
317
      }
318
    }
281 319

  
282 320
  unless ( $type ) {
283 321
    $self->{result} = RES_UNKNOWN_ROOT_NODE_TYPE;
284
    my $node_types = join(",", keys %{ $self->_document_nodenames });
285
    $self->{message} =  t8("Could not parse XML Invoice: unknown root node name (#1) (supported: (#2))",
286
                           $document_nodename,
287
                           $node_types,
322
    my @supported = ();
323

  
324
    foreach my $module ( $self->_document_modules ) {
325
      my @module_list = $module->supported();
326
      push @supported, @module_list;
327
    }
328

  
329
    my $supported_types = join(",\n", @supported);
330
    $self->{message} =  t8("Could not parse XML Invoice: unknown XML invoice type\nsupported: #1",
331
                           $supported_types,
288 332
                        );
289 333
    return $self;
290 334
  }
291 335

  
292
  eval {require $type}; # Load the parser class
293 336
  bless $self, $type;
294 337

  
295 338
  # Implementation sanity check for child classes: make sure they are aware of
SL/XMLInvoice/CrossIndustryInvoice.pm
9 9

  
10 10
=head1 NAME
11 11

  
12
SL::XMLInvoice::FakturX - XML parser for UN/CEFACT Cross Industry Invoice
12
SL::XMLInvoice::CrossIndustryInvoice - XML parser for UN/CEFACT Cross Industry Invoice
13 13

  
14 14
=head1 DESCRIPTION
15 15

  
......
54 54

  
55 55
=cut
56 56

  
57
sub supported {
58
  my @supported = ( "UN/CEFACT Cross Industry Invoice (urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100)" );
59
  return @supported;
60
}
61

  
62
sub check_signature {
63
  my ($self, $dom) = @_;
64

  
65
  my $rootnode = $dom->documentElement;
66

  
67
  foreach my $attr ( $rootnode->attributes ) {
68
    if ( $attr->getData =~ m/urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100/ ) {
69
      return 1;
70
      }
71
    }
72

  
73
  return 0;
74
}
75

  
57 76
# XML XPath expressions for global metadata
58 77
sub scalar_xpaths {
59 78
  return {
SL/XMLInvoice/UBL.pm
54 54

  
55 55
=cut
56 56

  
57
# XML XPath expression for
57
sub supported {
58
  my @supported = ( "Oasis Universal Business Language (UBL) invoice version 2 (urn:oasis:names:specification:ubl:schema:xsd:Invoice-2)" );
59
  return @supported;
60
}
61

  
62
sub check_signature {
63
  my ($self, $dom) = @_;
64

  
65
  my $rootnode = $dom->documentElement;
66

  
67
  foreach my $attr ( $rootnode->attributes ) {
68
    if ( $attr->getData =~ m/urn:oasis:names:specification:ubl:schema:xsd:Invoice-2/ ) {
69
      return 1;
70
      }
71
    }
72

  
73
  return 0;
74
}
75

  
76
# XML XPath expressions for scalar metadata
58 77
sub scalar_xpaths {
59 78
  return {
60 79
    currency => '//cbc:DocumentCurrencyCode',
......
72 91
  };
73 92
}
74 93

  
94
# XML XPath expressions for parsing bill items
75 95
sub item_xpaths {
76 96
  return {
77 97
    'currency' => './cbc:LineExtensionAmount[attribute::currencyID]',
locale/de/all
847 847
  'Could not load this vendor'  => 'Konnte diesen Lieferanten nicht laden',
848 848
  'Could not open ZUGFeRD file for reading: #1' => 'Die ZUGFeRD Datei konnte nicht zum Lesen geöffnet werden: #1',
849 849
  'Could not parse PDF embedded attachment #1: #2' => 'Konnte PDF-Anhang #1 nicht verarbeiten: #2',
850
  'Could not parse XML Invoice: unknown root node name (#1) (supported: (#2))' => 'Konnte XML-Rechnung nicht verabeiten: unbekanntes Wurzelelement (unterstützt: #2)',
850
  'Could not parse XML Invoice: unknown XML invoice type\nsupported: #1' => 'Konnte XML-Rechnung nicht verarbeiten: unbekanntes XML-Format.\nUnterstützt: #1',
851 851
  'Could not print dunning.'    => 'Die Mahnungen konnten nicht gedruckt werden.',
852 852
  'Could not reconcile chosen elements!' => 'Die gewählten Elemente konnten nicht ausgeglichen werden!',
853 853
  'Could not spawn ghostscript.' => 'Die Anwendung "ghostscript" konnte nicht gestartet werden.',

Auch abrufbar als: Unified diff