Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision ba929776

Von Johannes Grassler vor etwa 1 Jahr hinzugefügt

  • ID ba929776d1fc83b3a749b6f95ebff7cdc492b66b
  • Vorgänger c1775b18
  • Nachfolger d2291970

ZUGFeRD: Importiere via SessionFile

Benutze das SessionFile aus

834abeb456898df96e69deaad4a7c27915ad6a57

um die strukturierten Daten der ZUGFeRD/Faktur-X-Rechnung in
das Formular fuer die Kreditorenbuchung zu uebertragen. Diese
Loesung ist deutlich eleganter als die bisherige, die fuer
jeden Import ein RecordTemplate erzeugte und es nach dem
Import in der Datenbank beliess.

Unterschiede anzeigen:

bin/mozilla/ap.pl
56 56
use SL::DB::ValidityToken;
57 57
use SL::Presenter::ItemsList;
58 58
use SL::Webdav;
59
use SL::ZUGFeRD;
59 60
use SL::Locale::String qw(t8);
60 61

  
61 62
require "bin/mozilla/common.pl";
......
109 110
  $::form->show_generic_error($::locale->text("You do not have the permissions to access this function.")) if !       $cache->{_may_view_or_edit_this_invoice};
110 111
}
111 112

  
113
sub load_zugferd {
114
  $::auth->assert('ap_transactions');
115

  
116
  my $data;    # buffer for holding file contents
117

  
118
  my $form_defaults = $::form->{form_defaults};
119
  my $file = SL::SessionFile->new($form_defaults->{zugferd_session_file}, mode => '<');
120
  my $file_name = $file->file_name;
121

  
122
  $::form->{$_} = $form_defaults->{$_} for keys %{ $form_defaults // {} };
123

  
124
  # Defaults
125
  $::form->{title}            = "Add";
126
  $::form->{paidaccounts}     = 1;
127

  
128
  $file->open('<');
129
  if ( ! defined($file->fh->read($data, -s $file->fh)) ) {
130
      SL::Helper::Flash::flash_later('error',
131
        t8('Could not open ZUGFeRD file for reading: #1', $!));
132
  } else {
133

  
134
      my %res;          # result data structure returned by SL::ZUGFeRD->extract_from_{pdf,xml}()
135
      my $parser;       # SL::XMLInvoice object created by SL::ZUGFeRD->extract_from_{pdf,xml}()
136
      my $template_ap;  # SL::DB::RecordTemplate object
137
      my $vendor;       # SL::DB::Vendor object
138
      my %metadata;     # structured data extracted from XML payload
139
      my @items;        # list of invoice items
140
      my $default_ap_amount_chart;
141

  
142
      if ( $data =~ m/^%PDF/ ) {
143
        %res = %{SL::ZUGFeRD->extract_from_pdf($data)};
144
      } else {
145
        %res = %{SL::ZUGFeRD->extract_from_xml($data)};
146
      }
147

  
148

  
149
      $parser = $res{'invoice_xml'};
150
      %metadata = %{$parser->metadata};
151
      @items = @{$parser->items};
152

  
153
      $default_ap_amount_chart = SL::DB::Manager::Chart->find_by(charttype => 'A');
154

  
155
      my $row = 0;
156
      foreach my $i (@items) {
157
        $row++;
158

  
159
        my %item = %{$i};
160

  
161
        my $net_total = $::form->format_amount(\%::myconfig, $item{'subtotal'}, 2);
162
        my $desc = $item{'description'};
163
        my $tax_rate = $item{'tax_rate'} / 100; # XML data is usually in percent
164

  
165
        my $taxes = SL::DB::Manager::Tax->get_all(
166
          where   => [
167
            chart_categories => { like => '%' . $default_ap_amount_chart->category . '%' },
168
            rate => $tax_rate,
169
          ],
170
        );
171

  
172
        # If we really can't find any tax definition (a simple rounding error may
173
        # be sufficient for that to happen), grab the first tax fitting the default
174
        # AP amount chart, just like the AP form would do it for manual entry.
175
        if ( scalar @{$taxes} == 0 ) {
176
          $taxes = SL::DB::Manager::Tax->get_all(
177
            where   => [ chart_categories => { like => '%' . $default_ap_amount_chart->category . '%' } ],
178
          );
179
        }
180

  
181
        my $tax = ${$taxes}[0];
182

  
183
        if (!$tax) {
184
          $row--;
185
          next;
186
        }
187

  
188
        $::form->{"AP_amount_chart_id_${row}"}          = $default_ap_amount_chart->id; # FIXME: add heuristic for picking a better one
189
        $::form->{"previous_AP_amount_chart_id_${row}"} = $default_ap_amount_chart->id; # FIXME: add heuristic for picking a better one
190
        $::form->{"amount_${row}"}                      = $net_total;
191
        $::form->{"taxchart_${row}"}                    = $tax->id . '--' . $tax->rate;
192
      }
193

  
194
      flash('info', $::locale->text("The ZUGFeRD/Factur-X invoice '#1' has been loaded.", $file_name));
195

  
196
      $::form->{form_validity_token} = SL::DB::ValidityToken->create(scope => SL::DB::ValidityToken::SCOPE_PURCHASE_INVOICE_POST())->token;
197
      $::form->{rowcount}         = $row;
198

  
199
      update(
200
        keep_rows_without_amount => 1,
201
        dont_add_new_row         => 1,
202
      );
203
    }
204
}
205

  
112 206
sub load_record_template {
113 207
  $::auth->assert('ap_transactions');
114 208

  

Auch abrufbar als: Unified diff