Revision 817e6304
Von Tamino Steinert vor etwa 1 Jahr hinzugefügt
SL/Controller/EmailJournal.pm | ||
---|---|---|
|
||
use parent qw(SL::Controller::Base);
|
||
|
||
use SL::ZUGFeRD;
|
||
use SL::Controller::ZUGFeRD;
|
||
use SL::Controller::Helper::GetModels;
|
||
use SL::DB::Employee;
|
||
use SL::DB::EmailJournal;
|
||
... | ... | |
);
|
||
}
|
||
|
||
sub action_zugferd_import_with_attachment {
|
||
my ($self) = @_;
|
||
|
||
my $email_journal_id = $::form->{email_journal_id};
|
||
my $attachment_id = $::form->{attachment_id};
|
||
|
||
die "no 'email_journal_id' was given" unless $email_journal_id;
|
||
die "no 'attachment_id' was given" unless $attachment_id;
|
||
|
||
my $attachment = SL::DB::EmailJournalAttachment->new(id => $attachment_id)->load();
|
||
|
||
my $content = $attachment->content; # scalar ref
|
||
|
||
die t8("can only parse a pdf or xml file") unless $content =~ m/^%PDF|<\?xml/;
|
||
|
||
my %res;
|
||
if ( $content =~ m/^%PDF/ ) {
|
||
%res = %{SL::ZUGFeRD->extract_from_pdf($content)};
|
||
} else {
|
||
%res = %{SL::ZUGFeRD->extract_from_xml($content)};
|
||
}
|
||
|
||
unless ($res{'result'} == SL::ZUGFeRD::RES_OK()) {
|
||
die(t8("Could not extract Factur-X/ZUGFeRD data, data and error message:") . " $res{'message'}");
|
||
}
|
||
|
||
my $form_defaults = SL::Controller::ZUGFeRD->build_ap_transaction_form_defaults(\%res);
|
||
$form_defaults->{email_journal_id} = $email_journal_id;
|
||
$form_defaults->{email_attachment_id} = $attachment_id;
|
||
$form_defaults->{callback} = $::form->{back_to};
|
||
|
||
flash_later('info',
|
||
t8("The ZUGFeRD/Factur-X invoice '#1' has been loaded.", $attachment->name));
|
||
$self->redirect_to(
|
||
controller => 'ap.pl',
|
||
action => 'load_zugferd',
|
||
form_defaults => $form_defaults,
|
||
);
|
||
}
|
||
|
||
sub action_update_attachment_preview {
|
||
my ($self) = @_;
|
||
$::auth->assert('email_journal');
|
||
... | ... | |
id => $attachment_id,
|
||
)->load if $attachment_id;
|
||
|
||
$self->js->hide('#zugferd_import_div');
|
||
if ($attachment && $attachment->content =~ m/^%PDF|<\?xml/) {
|
||
my $content = $attachment->content;
|
||
my %res;
|
||
if ( $content =~ m/^%PDF/ ) {
|
||
%res = %{SL::ZUGFeRD->extract_from_pdf($content)};
|
||
} else {
|
||
%res = %{SL::ZUGFeRD->extract_from_xml($content)};
|
||
}
|
||
if ($res{'result'} == SL::ZUGFeRD::RES_OK()) {
|
||
$self->js->show('#zugferd_import_div');
|
||
}
|
||
}
|
||
|
||
$self->js
|
||
->replaceWith('#attachment_preview',
|
||
SL::Presenter::EmailJournal::attachment_preview(
|
SL/Controller/ZUGFeRD.pm | ||
---|---|---|
my $file = $::form->{file};
|
||
my $file_name = $::form->{file_name};
|
||
|
||
my %res; # result data structure returned by SL::ZUGFeRD->extract_from_{pdf,xml}()
|
||
my $parser; # SL::XMLInvoice object created by SL::ZUGFeRD->extract_from_{pdf,xml}()
|
||
my $vendor; # SL::DB::Vendor object
|
||
my %res; # result data structure returned by SL::ZUGFeRD->extract_from_{pdf,xml}()
|
||
|
||
die t8("missing file for action import") unless $file;
|
||
die t8("can only parse a pdf or xml file") unless $file =~ m/^%PDF|<\?xml/;
|
||
... | ... | |
die(t8("Could not extract Factur-X/ZUGFeRD data, data and error message:") . " $res{'message'}");
|
||
}
|
||
|
||
$parser = $res{'invoice_xml'};
|
||
my $form_defaults = $self->build_ap_transaction_form_defaults(\%res);
|
||
|
||
# save the zugferd file to session file for reuse in ap.pl
|
||
my $session_file = SL::SessionFile->new($file_name, mode => 'w');
|
||
$session_file->fh->print($file);
|
||
$session_file->fh->close;
|
||
$form_defaults->{zugferd_session_file} = $file_name;
|
||
|
||
$form_defaults->{callback} = $self->url_for(action => 'upload_zugferd');
|
||
|
||
$self->redirect_to(
|
||
controller => 'ap.pl',
|
||
action => 'load_zugferd',
|
||
form_defaults => $form_defaults,
|
||
);
|
||
}
|
||
|
||
sub build_ap_transaction_form_defaults {
|
||
my ($self, $data) = @_;
|
||
|
||
my $parser = $data->{'invoice_xml'};
|
||
|
||
my %metadata = %{$parser->metadata};
|
||
my @items = @{$parser->items};
|
||
... | ... | |
die t8("Cannot process this invoice: neither VAT ID nor tax ID present.");
|
||
}
|
||
|
||
$vendor = find_vendor($metadata{'ustid'}, $metadata{'taxnumber'});
|
||
my $vendor = find_vendor($metadata{'ustid'}, $metadata{'taxnumber'});
|
||
|
||
die t8("Vendor with VAT ID (#1) and/or tax ID (#2) not found. Please check if the vendor " .
|
||
"#3 exists and whether it has the correct tax ID/VAT ID." ,
|
||
... | ... | |
|
||
# Check IBAN specified on bill matches the one we've got in
|
||
# the database for this vendor.
|
||
if ($iban) {
|
||
$intnotes .= "\nIBAN: ";
|
||
$intnotes .= $iban ne $vendor->iban ?
|
||
t8("Record IBAN #1 doesn't match vendor IBAN #2", $iban, $vendor->iban)
|
||
: $iban
|
||
}
|
||
|
||
# save the zugferd file to session file for reuse in ap.pl
|
||
my $session_file = SL::SessionFile->new($file_name, mode => 'w');
|
||
$session_file->fh->print($file);
|
||
$session_file->fh->close;
|
||
if ($iban) {
|
||
$intnotes .= "\nIBAN: ";
|
||
$intnotes .= $iban ne $vendor->iban ?
|
||
t8("Record IBAN #1 doesn't match vendor IBAN #2", $iban, $vendor->iban)
|
||
: $iban
|
||
}
|
||
|
||
# Use invoice creation date as due date if there's no due date
|
||
$metadata{'duedate'} = $metadata{'transdate'} unless defined $metadata{'duedate'};
|
||
... | ... | |
}
|
||
$item_form{rowcount} = $row;
|
||
|
||
$self->redirect_to(
|
||
controller => 'ap.pl',
|
||
action => 'load_zugferd',
|
||
form_defaults => {
|
||
zugferd_session_file => $file_name,
|
||
callback => $self->url_for(action => 'upload_zugferd'),
|
||
vendor_id => $vendor->id,
|
||
vendor => $vendor->name,
|
||
invnumber => $invnumber,
|
||
transdate => $metadata{'transdate'},
|
||
duedate => $metadata{'duedate'},
|
||
no_payment_bookings => 0,
|
||
intnotes => $intnotes,
|
||
taxincluded => 0,
|
||
direct_debit => $metadata{'direct_debit'},
|
||
currency => $currency->name,
|
||
AP_chart_id => $ap_chart_id,
|
||
paid_1_suggestion => $::form->format_amount(\%::myconfig, $metadata{'total'}, 2),
|
||
%item_form,
|
||
},
|
||
);
|
||
|
||
return {
|
||
vendor_id => $vendor->id,
|
||
vendor => $vendor->name,
|
||
invnumber => $invnumber,
|
||
transdate => $metadata{'transdate'},
|
||
duedate => $metadata{'duedate'},
|
||
no_payment_bookings => 0,
|
||
intnotes => $intnotes,
|
||
taxincluded => 0,
|
||
direct_debit => $metadata{'direct_debit'},
|
||
currency => $currency->name,
|
||
AP_chart_id => $ap_chart_id,
|
||
paid_1_suggestion => $::form->format_amount(\%::myconfig, $metadata{'total'}, 2),
|
||
%item_form,
|
||
},
|
||
}
|
||
|
||
sub check_auth {
|
bin/mozilla/ap.pl | ||
---|---|---|
$::auth->assert('ap_transactions');
|
||
|
||
my $file_name = $::form->{form_defaults}->{zugferd_session_file};
|
||
flash('info', $::locale->text(
|
||
"The ZUGFeRD/Factur-X invoice '#1' has been loaded.", $file_name));
|
||
if ($file_name) {
|
||
flash('info', $::locale->text(
|
||
"The ZUGFeRD/Factur-X invoice '#1' has been loaded.", $file_name));
|
||
}
|
||
|
||
my $template_ap = SL::DB::Manager::RecordTemplate->get_first(where => [vendor_id => $::form->{form_defaults}->{vendor_id}]);
|
||
if ($template_ap) {
|
js/kivi.EmailJournal.js | ||
---|---|---|
$.post("controller.pl", data, kivi.eval_json_result);
|
||
}
|
||
|
||
ns.zugferd_import_with_attachment = function() {
|
||
let data = $('#record_action_form').serializeArray();
|
||
data.push({ name: 'action', value: 'EmailJournal/zugferd_import_with_attachment' });
|
||
$.post("controller.pl", data, kivi.eval_json_result);
|
||
}
|
||
|
||
ns.toggle_obsolete = function(email_journal_id) {
|
||
let data = $('#record_action_form').serializeArray();
|
||
data.push({ name: 'action', value: 'EmailJournal/toggle_obsolete' });
|
templates/design40_webpages/email_journal/show.html | ||
---|---|---|
) %]
|
||
</div>
|
||
[% END %]
|
||
|
||
<div id="zugferd_import_div" style="display:none">
|
||
<!-- get shown if the attachment is valid zugferd -->
|
||
[% L.button_tag('kivi.EmailJournal.zugferd_import_with_attachment();',
|
||
LxERP.t8('Factur-X/ZUGFeRD import'),
|
||
style="margin-top:5px"
|
||
)
|
||
%]
|
||
</div>
|
||
|
||
</div></div> <!-- action_div -->
|
||
|
||
<div id="record_selection_div">
|
templates/webpages/email_journal/show.html | ||
---|---|---|
[% END %]
|
||
</div>
|
||
</div>
|
||
|
||
<div id="zugferd_import_div" style="display:none">
|
||
<!-- get shown if the attachment is valid zugferd -->
|
||
[% L.button_tag('kivi.EmailJournal.zugferd_import_with_attachment();',
|
||
LxERP.t8('Factur-X/ZUGFeRD import'),
|
||
style="margin-top:5px"
|
||
)
|
||
%]
|
||
</div>
|
||
|
||
</tr> <tr>
|
||
<td>
|
||
<div id="record_selection_div">
|
Auch abrufbar als: Unified diff
EmailJournal: Anhang als ZUGFeRD importieren