Revision a0392369
Von Bernd Bleßmann vor fast 4 Jahren hinzugefügt
SL/DN.pm | ||
---|---|---|
54 | 54 |
use SL::Webdav; |
55 | 55 |
|
56 | 56 |
use File::Copy; |
57 |
use File::Slurp qw(read_file); |
|
57 | 58 |
|
58 | 59 |
use strict; |
59 | 60 |
|
... | ... | |
319 | 320 |
|
320 | 321 |
$form->{DUNNING_PDFS_STORAGE} = []; |
321 | 322 |
|
322 |
my $rc = SL::DB->client->with_transaction(\&_save_dunning, $self, $myconfig, $form, $rows); |
|
323 |
# Catch any error, either exception or a call to form->error |
|
324 |
# and return it to the calling function. |
|
325 |
my ($error, $rc); |
|
326 |
eval { |
|
327 |
local $form->{__ERROR_HANDLER} = sub { die @_ }; |
|
328 |
$rc = SL::DB->client->with_transaction(\&_save_dunning, $self, $myconfig, $form, $rows); |
|
329 |
1; |
|
330 |
} or do { |
|
331 |
$error = $@; |
|
332 |
}; |
|
323 | 333 |
|
324 | 334 |
# Save PDFs in filemanagement and webdav after transation succeeded, |
325 | 335 |
# because otherwise files in the storage may exists if the transaction |
... | ... | |
329 | 339 |
_store_pdf_to_webdav_and_filemanagement($_->{dunning_id}, $_->{path}, $_->{name}) for @{ $form->{DUNNING_PDFS_STORAGE} }; |
330 | 340 |
} |
331 | 341 |
|
332 |
if (!$rc) {
|
|
333 |
die SL::DB->client->error
|
|
334 |
} |
|
342 |
$error = 'unknown errror' if !$error && !$rc;
|
|
343 |
$rc->{error} = $error if $error;
|
|
344 |
|
|
335 | 345 |
$::lxdebug->leave_sub; |
336 | 346 |
|
337 | 347 |
return $rc; |
... | ... | |
413 | 423 |
} |
414 | 424 |
# die this transaction, because for this customer only credit notes are |
415 | 425 |
# selected ... |
416 |
return unless $customer_id;
|
|
426 |
die "only credit notes are selected for this customer\n" unless $customer_id;
|
|
417 | 427 |
|
418 | 428 |
$h_update_ar->finish(); |
419 | 429 |
$h_insert_dunning->finish(); |
... | ... | |
435 | 445 |
$self->send_email($myconfig, $form, $dunning_id, $dbh); |
436 | 446 |
} |
437 | 447 |
|
438 |
return 1;
|
|
448 |
return ({dunning_id => $dunning_id, print_original_invoice => $print_invoice, send_email => $send_email});
|
|
439 | 449 |
} |
440 | 450 |
|
441 | 451 |
sub send_email { |
... | ... | |
826 | 836 |
|
827 | 837 |
$main::lxdebug->enter_sub(); |
828 | 838 |
|
829 |
my ($self, $myconfig, $form, $copies) = @_; |
|
839 |
my ($self, $myconfig, $form, $copies, %params) = @_;
|
|
830 | 840 |
|
831 | 841 |
# Don't allow access outside of $spool. |
832 | 842 |
map { $_ =~ s|.*/||; } @{ $form->{DUNNING_PDFS} }; |
... | ... | |
842 | 852 |
my $in = IO::File->new($::lx_office_conf{applications}->{ghostscript} . " -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=- $inputfiles |"); |
843 | 853 |
$form->error($main::locale->text('Could not spawn ghostscript.')) unless $in; |
844 | 854 |
|
845 |
if ($form->{media} eq 'printer') { |
|
846 |
$form->get_printer_code($myconfig); |
|
847 |
my $out; |
|
848 |
if ($form->{printer_command}) { |
|
849 |
$out = IO::File->new("| $form->{printer_command}"); |
|
850 |
} |
|
855 |
my $dunning_filename = $form->get_formname_translation('dunning'); |
|
856 |
my $attachment_filename = "${dunning_filename}_${dunning_id}.pdf"; |
|
857 |
my $content; |
|
858 |
if ($params{return_content}) { |
|
859 |
$content = read_file($in); |
|
851 | 860 |
|
852 |
$form->error($main::locale->text('Could not spawn the printer command.')) unless $out; |
|
861 |
} else { |
|
862 |
if ($form->{media} eq 'printer') { |
|
863 |
$form->get_printer_code($myconfig); |
|
864 |
my $out; |
|
865 |
if ($form->{printer_command}) { |
|
866 |
$out = IO::File->new("| $form->{printer_command}"); |
|
867 |
} |
|
853 | 868 |
|
854 |
$::locale->with_raw_io($out, sub { $out->print($_) while <$in> });
|
|
869 |
$form->error($main::locale->text('Could not spawn the printer command.')) unless $out;
|
|
855 | 870 |
|
856 |
} else { |
|
857 |
my $dunning_filename = $form->get_formname_translation('dunning'); |
|
858 |
print qq|Content-Type: Application/PDF\n| . |
|
859 |
qq|Content-Disposition: attachment; filename="${dunning_filename}_${dunning_id}.pdf"\n\n|; |
|
871 |
$::locale->with_raw_io($out, sub { $out->print($_) while <$in> }); |
|
872 |
|
|
873 |
} else { |
|
874 |
print qq|Content-Type: Application/PDF\n| . |
|
875 |
qq|Content-Disposition: attachment; filename=$attachment_filename\n\n|; |
|
860 | 876 |
|
861 |
$::locale->with_raw_io(\*STDOUT, sub { print while <$in> }); |
|
877 |
$::locale->with_raw_io(\*STDOUT, sub { print while <$in> }); |
|
878 |
} |
|
862 | 879 |
} |
863 | 880 |
|
864 | 881 |
$in->close(); |
... | ... | |
866 | 883 |
map { unlink("$spool/$_") } @{ $form->{DUNNING_PDFS} }; |
867 | 884 |
|
868 | 885 |
$main::lxdebug->leave_sub(); |
886 |
return ($attachment_filename, $content) if $params{return_content}; |
|
869 | 887 |
} |
870 | 888 |
|
871 | 889 |
sub print_dunning { |
... | ... | |
1014 | 1032 |
|
1015 | 1033 |
delete $form->{tmpfile}; |
1016 | 1034 |
|
1017 |
push @{ $form->{DUNNING_PDFS} } , $filename; |
|
1018 |
push @{ $form->{DUNNING_PDFS_EMAIL} } , { 'path' => "${spool}/$filename", |
|
1019 |
'name' => $form->get_formname_translation('dunning') . "_${dunning_id}.pdf" }; |
|
1020 |
push @{ $form->{DUNNING_PDFS_STORAGE} }, { 'dunning_id' => $dunning_id, |
|
1021 |
'path' => "${spool}/$filename", |
|
1022 |
'name' => $form->get_formname_translation('dunning') . "_${dunning_id}.pdf" }; |
|
1023 |
|
|
1024 | 1035 |
my $employee_id = ($::instance_conf->get_dunning_creator eq 'invoice_employee') ? |
1025 | 1036 |
$form->{employee_id} : |
1026 | 1037 |
SL::DB::Manager::Employee->current->id; |
... | ... | |
1038 | 1049 |
# this generates the file in the spool directory |
1039 | 1050 |
$form->parse_template($myconfig); |
1040 | 1051 |
|
1052 |
push @{ $form->{DUNNING_PDFS} } , $filename; |
|
1053 |
push @{ $form->{DUNNING_PDFS_EMAIL} } , { 'path' => "${spool}/$filename", |
|
1054 |
'name' => $form->get_formname_translation('dunning') . "_${dunning_id}.pdf" }; |
|
1055 |
push @{ $form->{DUNNING_PDFS_STORAGE} }, { 'dunning_id' => $dunning_id, |
|
1056 |
'path' => "${spool}/$filename", |
|
1057 |
'name' => $form->get_formname_translation('dunning') . "_${dunning_id}.pdf" }; |
|
1058 |
|
|
1041 | 1059 |
$main::lxdebug->leave_sub(); |
1042 | 1060 |
} |
1043 | 1061 |
|
bin/mozilla/dn.pl | ||
---|---|---|
34 | 34 |
|
35 | 35 |
use POSIX qw(strftime); |
36 | 36 |
|
37 |
use List::Util qw(notall); |
|
37 | 38 |
use List::MoreUtils qw(none); |
38 | 39 |
|
39 | 40 |
use SL::IS; |
... | ... | |
210 | 211 |
|
211 | 212 |
my $active=1; |
212 | 213 |
my @rows = (); |
214 |
my @status; |
|
213 | 215 |
undef($form->{DUNNING_PDFS}); |
214 | 216 |
|
215 | 217 |
my $saved_language_id = $form->{language_id}; |
... | ... | |
242 | 244 |
if (!$form->{force_lang}) { |
243 | 245 |
$form->{language_id} = @{$level}[0]->{language_id}; |
244 | 246 |
} |
245 |
DN->save_dunning(\%myconfig, $form, $level); |
|
247 |
my $rc = DN->save_dunning(\%myconfig, $form, $level); |
|
248 |
$rc->{error} =~ s{\n}{<br />}g if $rc->{error}; |
|
249 |
push @status, { invnumbers => [map { $form->{'invnumber_' . $_->{row}} } @$level], |
|
250 |
map { ( $_ => $rc->{$_} ) } qw(error dunning_id print_original_invoice send_email), }; |
|
246 | 251 |
} |
247 | 252 |
} |
248 | 253 |
|
... | ... | |
260 | 265 |
if (!$form->{force_lang}) { |
261 | 266 |
$form->{language_id} = @{$level}[0]->{language_id}; |
262 | 267 |
} |
263 |
DN->save_dunning(\%myconfig, $form, $level); |
|
268 |
my $rc = DN->save_dunning(\%myconfig, $form, $level); |
|
269 |
$rc->{error} =~ s{\n}{<br />}g if $rc->{error}; |
|
270 |
push @status, { invnumbers => [map { $form->{'invnumber_' . $_->{row}} } @$level], |
|
271 |
map { ( $_ => $rc->{$_} ) } qw(error dunning_id print_original_invoice send_email), }; |
|
264 | 272 |
} |
265 | 273 |
} |
266 | 274 |
|
267 | 275 |
$form->{language_id} = $saved_language_id; |
268 | 276 |
|
269 |
if (scalar @{ $form->{DUNNING_PDFS} }) { |
|
277 |
my $pdf_filename; |
|
278 |
my $pdf_content; |
|
279 |
if ($form->{DUNNING_PDFS} && scalar @{ $form->{DUNNING_PDFS} }) { |
|
270 | 280 |
$form->{dunning_id} = strftime("%Y%m%d", localtime time) if scalar @{ $form->{DUNNING_PDFS}} > 1; |
271 |
DN->melt_pdfs(\%myconfig, $form, $form->{copies}); |
|
281 |
($pdf_filename, $pdf_content) = DN->melt_pdfs(\%myconfig, $form, $form->{copies}, return_content => $form->{media} ne 'printer'); |
|
282 |
|
|
283 |
flash('info', t8('Dunning Process started for selected invoices!')); |
|
284 |
if ($form->{media} eq 'printer') { |
|
285 |
flash('info', t8('The PDF has been printed')); |
|
286 |
} else { |
|
287 |
flash('info', t8('The PDF has been created')); |
|
288 |
} |
|
272 | 289 |
} |
273 | 290 |
|
274 | 291 |
# saving the history |
... | ... | |
279 | 296 |
} |
280 | 297 |
# /saving the history |
281 | 298 |
|
282 |
if ($form->{media} eq 'printer') { |
|
283 |
delete $form->{callback}; |
|
284 |
$form->redirect($locale->text('Dunning Process started for selected invoices!')); |
|
285 |
} |
|
299 |
setup_dn_status_action_bar(); |
|
300 |
$form->{"title"} = $locale->text("Dunning status"); |
|
301 |
$form->header(); |
|
302 |
print $form->parse_html_template('dunning/status', { |
|
303 |
pdf_filename => $pdf_filename, |
|
304 |
pdf_content => $pdf_content, |
|
305 |
status => \@status, }); |
|
286 | 306 |
|
287 | 307 |
$main::lxdebug->leave_sub(); |
288 | 308 |
} |
... | ... | |
692 | 712 |
} |
693 | 713 |
} |
694 | 714 |
|
715 |
sub setup_dn_status_action_bar { |
|
716 |
for my $bar ($::request->layout->get('actionbar')) { |
|
717 |
$bar->add( |
|
718 |
action => [ |
|
719 |
t8('Back'), |
|
720 |
link => $::form->{callback}, |
|
721 |
accesskey => 'enter', |
|
722 |
], |
|
723 |
); |
|
724 |
} |
|
725 |
|
|
726 |
} |
|
727 |
|
|
695 | 728 |
# end of main |
templates/webpages/dunning/status.html | ||
---|---|---|
1 |
[% USE HTML %] |
|
2 |
[% USE LxERP -%] |
|
3 |
[% USE P -%] |
|
4 |
[% USE T8 -%] |
|
5 |
[% USE Base64 -%] |
|
6 |
|
|
7 |
<h1>[% title | html %]</h1> |
|
8 |
|
|
9 |
[%- INCLUDE 'common/flash.html' -%] |
|
10 |
|
|
11 |
<table> |
|
12 |
<thead class="listheading"> |
|
13 |
<tr> |
|
14 |
<th>[% 'Dunning number' | $T8 %]</th> |
|
15 |
<th width="250px">[% 'Invoice Number' | $T8 %]</th> |
|
16 |
<th>[% 'Include original Invoices?' | $T8 %]</th> |
|
17 |
<th>[% 'eMail?' | $T8 %]</th> |
|
18 |
<th>[% 'Status' | $T8 %]</th> |
|
19 |
</tr> |
|
20 |
</thead> |
|
21 |
<tbody> |
|
22 |
[% FOREACH s = status -%] |
|
23 |
<tr class=[%- IF s.error %]"listrow_error"[% ELSE %]"listrow"[% END %]> |
|
24 |
<td>[% IF !s.error %][% P.link_tag('dn.pl?action=show_dunning&showold=1&dunning_id=' _ s.dunning_id, s.dunning_id) %][% END %]</td> |
|
25 |
<td>[% s.invnumbers.join(", ") %]</td> |
|
26 |
<td>[% s.print_original_invoice ? LxERP.t8('Yes') : LxERP.t8('No') %]</td> |
|
27 |
<td>[% s.send_email ? LxERP.t8('Yes') : LxERP.t8('No') %]</td> |
|
28 |
<td>[% s.error ? s.error : LxERP.t8('Ok') %]</td> |
|
29 |
</tr> |
|
30 |
[%- END %] |
|
31 |
</tbody> |
|
32 |
</table> |
|
33 |
|
|
34 |
[%- IF pdf_filename && pdf_content -%] |
|
35 |
<script type="text/javascript"> |
|
36 |
<!-- |
|
37 |
$(function() {kivi.save_file('[% pdf_content.encode_base64 %]', 'application/pdf', 0, '[% pdf_filename %]');}); |
|
38 |
--> |
|
39 |
</script> |
|
40 |
[%- END %] |
Auch abrufbar als: Unified diff
Mahnungen: Status-Bericht nach Mahnlauf mit evtl. Fehlermeldungen.
Das Erzeugen der Mahnungen erfolgt je nach ausgewählten Rechnungen in mehreren
Schritten (Zusammenfassen je Kunde und Mahnlevel oder auch einzeln für jede
Rechnung).
Hierbei können in einem Schritt durchaus Mahnungen für einen Kunden oder einen
Mahnlevel erfolgreich erzeugt und per Mail verschickt werden. In einem
folgenden Schritt kann aber ein Fehler auftreten, der dann zum Abbruch und
einer Fehlermeldung führt.
Dabei gab es bisher keinen Hinweis, ob einzelne Schritte erfolgreich waren und
Mahnungen erzeugt wurden.
Dieser commit sammelt die Ergebnisse der einzelnen Schritte und zeigt am Ende
aller Schritte einen Status-Bericht an.