Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision e3338e4a

Von Tamino Steinert vor 11 Monaten hinzugefügt

  • ID e3338e4ac8e8ad5342aad71ef8e3e31c3cffbb1a
  • Vorgänger ef2af60b
  • Nachfolger 9cf32c2d

EmailJournal: Anhang als ZUGFeRD importieren

Unterschiede anzeigen:

SL/Controller/EmailJournal.pm
4 4

  
5 5
use parent qw(SL::Controller::Base);
6 6

  
7
use SL::ZUGFeRD;
8
use SL::Controller::ZUGFeRD;
7 9
use SL::Controller::Helper::GetModels;
8 10
use SL::DB::Employee;
9 11
use SL::DB::EmailJournal;
......
380 382
  );
381 383
}
382 384

  
385
sub action_zugferd_import_with_attachment {
386
  my ($self) = @_;
387

  
388
  my $email_journal_id   = $::form->{email_journal_id};
389
  my $attachment_id      = $::form->{attachment_id};
390

  
391
  die "no 'email_journal_id' was given" unless $email_journal_id;
392
  die "no 'attachment_id' was given"    unless $attachment_id;
393

  
394
  my $attachment = SL::DB::EmailJournalAttachment->new(id => $attachment_id)->load();
395

  
396
  my $content = $attachment->content; # scalar ref
397

  
398
  die t8("can only parse a pdf or xml file") unless $content =~ m/^%PDF|<\?xml/;
399

  
400
  my %res;
401
  if ( $content =~ m/^%PDF/ ) {
402
    %res = %{SL::ZUGFeRD->extract_from_pdf($content)};
403
  } else {
404
    %res = %{SL::ZUGFeRD->extract_from_xml($content)};
405
  }
406

  
407
  unless ($res{'result'} == SL::ZUGFeRD::RES_OK()) {
408
    die(t8("Could not extract Factur-X/ZUGFeRD data, data and error message:") . " $res{'message'}");
409
  }
410

  
411
  my $form_defaults = SL::Controller::ZUGFeRD->build_ap_transaction_form_defaults(\%res);
412
  $form_defaults->{email_journal_id}    = $email_journal_id;
413
  $form_defaults->{email_attachment_id} = $attachment_id;
414
  $form_defaults->{callback}            = $::form->{back_to};
415

  
416
  flash_later('info',
417
    t8("The ZUGFeRD/Factur-X invoice '#1' has been loaded.", $attachment->name));
418
  $self->redirect_to(
419
    controller    => 'ap.pl',
420
    action        => 'load_zugferd',
421
    form_defaults => $form_defaults,
422
  );
423
}
424

  
383 425
sub action_update_attachment_preview {
384 426
  my ($self) = @_;
385 427
  $::auth->assert('email_journal');
......
390 432
    id => $attachment_id,
391 433
  )->load if $attachment_id;
392 434

  
435
  $self->js->hide('#zugferd_import_div');
436
  if ($attachment && $attachment->content =~ m/^%PDF|<\?xml/) {
437
    my $content = $attachment->content;
438
    my %res;
439
    if ( $content =~ m/^%PDF/ ) {
440
      %res = %{SL::ZUGFeRD->extract_from_pdf($content)};
441
    } else {
442
      %res = %{SL::ZUGFeRD->extract_from_xml($content)};
443
    }
444
    if ($res{'result'} == SL::ZUGFeRD::RES_OK()) {
445
      $self->js->show('#zugferd_import_div');
446
    }
447
  }
448

  
393 449
  $self->js
394 450
    ->replaceWith('#attachment_preview',
395 451
      SL::Presenter::EmailJournal::attachment_preview(
SL/Controller/ZUGFeRD.pm
127 127
  my $file = $::form->{file};
128 128
  my $file_name = $::form->{file_name};
129 129

  
130
  my %res;          # result data structure returned by SL::ZUGFeRD->extract_from_{pdf,xml}()
131
  my $parser;       # SL::XMLInvoice object created by SL::ZUGFeRD->extract_from_{pdf,xml}()
132
  my $vendor;       # SL::DB::Vendor object
130
  my %res; # result data structure returned by SL::ZUGFeRD->extract_from_{pdf,xml}()
133 131

  
134 132
  die t8("missing file for action import")   unless $file;
135 133
  die t8("can only parse a pdf or xml file") unless $file =~ m/^%PDF|<\?xml/;
......
145 143
    die(t8("Could not extract Factur-X/ZUGFeRD data, data and error message:") . " $res{'message'}");
146 144
  }
147 145

  
148
  $parser = $res{'invoice_xml'};
146
  my $form_defaults = $self->build_ap_transaction_form_defaults(\%res);
147

  
148
  # save the zugferd file to session file for reuse in ap.pl
149
  my $session_file = SL::SessionFile->new($file_name, mode => 'w');
150
  $session_file->fh->print($file);
151
  $session_file->fh->close;
152
  $form_defaults->{zugferd_session_file} = $file_name;
153

  
154
  $form_defaults->{callback} = $self->url_for(action => 'upload_zugferd');
155

  
156
  $self->redirect_to(
157
    controller    => 'ap.pl',
158
    action        => 'load_zugferd',
159
    form_defaults => $form_defaults,
160
  );
161
}
162

  
163
sub build_ap_transaction_form_defaults {
164
  my ($self, $data) = @_;
165

  
166
  my $parser = $data->{'invoice_xml'};
149 167

  
150 168
  my %metadata = %{$parser->metadata};
151 169
  my @items = @{$parser->items};
......
158 176
    die t8("Cannot process this invoice: neither VAT ID nor tax ID present.");
159 177
  }
160 178

  
161
  $vendor = find_vendor($metadata{'ustid'}, $metadata{'taxnumber'});
179
  my $vendor = find_vendor($metadata{'ustid'}, $metadata{'taxnumber'});
162 180

  
163 181
  die t8("Vendor with VAT ID (#1) and/or tax ID (#2) not found. Please check if the vendor " .
164 182
          "#3 exists and whether it has the correct tax ID/VAT ID." ,
......
170 188

  
171 189
  # Check IBAN specified on bill matches the one we've got in
172 190
  # the database for this vendor.
173
 if ($iban) {
174
   $intnotes .= "\nIBAN: ";
175
   $intnotes .= $iban ne $vendor->iban ?
176
         t8("Record IBAN #1 doesn't match vendor IBAN #2", $iban, $vendor->iban)
177
       : $iban
178
 }
179

  
180
  # save the zugferd file to session file for reuse in ap.pl
181
  my $session_file = SL::SessionFile->new($file_name, mode => 'w');
182
  $session_file->fh->print($file);
183
  $session_file->fh->close;
191
  if ($iban) {
192
    $intnotes .= "\nIBAN: ";
193
    $intnotes .= $iban ne $vendor->iban ?
194
          t8("Record IBAN #1 doesn't match vendor IBAN #2", $iban, $vendor->iban)
195
        : $iban
196
  }
184 197

  
185 198
  # Use invoice creation date as due date if there's no due date
186 199
  $metadata{'duedate'} = $metadata{'transdate'} unless defined $metadata{'duedate'};
......
254 267
  }
255 268
  $item_form{rowcount} = $row;
256 269

  
257
  $self->redirect_to(
258
    controller           => 'ap.pl',
259
    action               => 'load_zugferd',
260
    form_defaults => {
261
      zugferd_session_file => $file_name,
262
      callback             => $self->url_for(action => 'upload_zugferd'),
263
      vendor_id            => $vendor->id,
264
      vendor               => $vendor->name,
265
      invnumber            => $invnumber,
266
      transdate            => $metadata{'transdate'},
267
      duedate              => $metadata{'duedate'},
268
      no_payment_bookings  => 0,
269
      intnotes             => $intnotes,
270
      taxincluded          => 0,
271
      direct_debit         => $metadata{'direct_debit'},
272
      currency             => $currency->name,
273
      AP_chart_id          => $ap_chart_id,
274
      paid_1_suggestion    => $::form->format_amount(\%::myconfig, $metadata{'total'}, 2),
275
      %item_form,
276
    },
277
  );
278

  
270
  return {
271
    vendor_id            => $vendor->id,
272
    vendor               => $vendor->name,
273
    invnumber            => $invnumber,
274
    transdate            => $metadata{'transdate'},
275
    duedate              => $metadata{'duedate'},
276
    no_payment_bookings  => 0,
277
    intnotes             => $intnotes,
278
    taxincluded          => 0,
279
    direct_debit         => $metadata{'direct_debit'},
280
    currency             => $currency->name,
281
    AP_chart_id          => $ap_chart_id,
282
    paid_1_suggestion    => $::form->format_amount(\%::myconfig, $metadata{'total'}, 2),
283
    %item_form,
284
  },
279 285
}
280 286

  
281 287
sub check_auth {
bin/mozilla/ap.pl
115 115
  $::auth->assert('ap_transactions');
116 116

  
117 117
  my $file_name = $::form->{form_defaults}->{zugferd_session_file};
118
  flash('info', $::locale->text(
119
      "The ZUGFeRD/Factur-X invoice '#1' has been loaded.", $file_name));
118
  if ($file_name) {
119
    flash('info', $::locale->text(
120
        "The ZUGFeRD/Factur-X invoice '#1' has been loaded.", $file_name));
121
  }
120 122

  
121 123
  my $template_ap = SL::DB::Manager::RecordTemplate->get_first(where => [vendor_id => $::form->{form_defaults}->{vendor_id}]);
122 124
  if ($template_ap) {
js/kivi.EmailJournal.js
56 56
    $.post("controller.pl", data, kivi.eval_json_result);
57 57
  }
58 58

  
59
  ns.zugferd_import_with_attachment = function() {
60
    let data = $('#record_action_form').serializeArray();
61
    data.push({ name: 'action', value: 'EmailJournal/zugferd_import_with_attachment' });
62
    $.post("controller.pl", data, kivi.eval_json_result);
63
  }
64

  
59 65
  ns.toggle_obsolete = function(email_journal_id) {
60 66
    let data = $('#record_action_form').serializeArray();
61 67
    data.push({ name: 'action', value: 'EmailJournal/toggle_obsolete' });
templates/design40_webpages/email_journal/show.html
172 172
         ) %]
173 173
      </div>
174 174
      [% END %]
175

  
176
      <div id="zugferd_import_div" style="display:none">
177
        <!-- get shown if the attachment is valid zugferd -->
178
        [% L.button_tag('kivi.EmailJournal.zugferd_import_with_attachment();',
179
          LxERP.t8('Factur-X/ZUGFeRD import'),
180
          style="margin-top:5px"
181
          )
182
        %]
183
      </div>
184

  
175 185
    </div></div> <!-- action_div -->
176 186

  
177 187
    <div id="record_selection_div">
templates/webpages/email_journal/show.html
164 164
      [% END %]
165 165
      </div>
166 166
    </div>
167

  
168
    <div id="zugferd_import_div" style="display:none">
169
      <!-- get shown if the attachment is valid zugferd -->
170
      [% L.button_tag('kivi.EmailJournal.zugferd_import_with_attachment();',
171
        LxERP.t8('Factur-X/ZUGFeRD import'),
172
        style="margin-top:5px"
173
        )
174
      %]
175
    </div>
176

  
167 177
  </tr> <tr>
168 178
    <td>
169 179
    <div id="record_selection_div">

Auch abrufbar als: Unified diff