7 |
7 |
use Config::Std;
|
8 |
8 |
use DateTime::Format::Strptime;
|
9 |
9 |
use English qw(-no_match_vars);
|
|
10 |
use List::MoreUtils qw(uniq);
|
10 |
11 |
|
11 |
12 |
use SL::DB::AuthUser;
|
12 |
13 |
use SL::DB::Default;
|
... | ... | |
14 |
15 |
use SL::DB::Invoice;
|
15 |
16 |
use SL::DB::PeriodicInvoice;
|
16 |
17 |
use SL::DB::PeriodicInvoicesConfig;
|
|
18 |
use SL::Helper::CreatePDF qw(create_pdf find_template);
|
17 |
19 |
use SL::Mailer;
|
|
20 |
use SL::Util qw(trim);
|
18 |
21 |
|
19 |
22 |
sub create_job {
|
20 |
23 |
$_[0]->create_standard_job('0 3 1 * *'); # first day of month at 3:00 am
|
... | ... | |
24 |
27 |
my $self = shift;
|
25 |
28 |
$self->{db_obj} = shift;
|
26 |
29 |
|
|
30 |
$self->{job_errors} = [];
|
|
31 |
|
27 |
32 |
my $configs = SL::DB::Manager::PeriodicInvoicesConfig->get_all(query => [ active => 1 ]);
|
28 |
33 |
|
29 |
34 |
foreach my $config (@{ $configs }) {
|
... | ... | |
31 |
36 |
_log_msg("Periodic invoice configuration ID " . $config->id . " extended through " . $new_end_date->strftime('%d.%m.%Y') . "\n") if $new_end_date;
|
32 |
37 |
}
|
33 |
38 |
|
34 |
|
my (@new_invoices, @invoices_to_print);
|
|
39 |
my (@new_invoices, @invoices_to_print, @invoices_to_email);
|
35 |
40 |
|
36 |
41 |
_log_msg("Number of configs: " . scalar(@{ $configs}));
|
37 |
42 |
|
... | ... | |
47 |
52 |
_log_msg("Dates: " . join(' ', map { $_->to_lxoffice } @dates));
|
48 |
53 |
|
49 |
54 |
foreach my $date (@dates) {
|
50 |
|
my $invoice = $self->_create_periodic_invoice($config, $date);
|
51 |
|
next unless $invoice;
|
|
55 |
my $data = $self->_create_periodic_invoice($config, $date);
|
|
56 |
next unless $data;
|
|
57 |
|
|
58 |
_log_msg("Invoice " . $data->{invoice}->invnumber . " posted for config ID " . $config->id . ", period start date " . $::locale->format_date(\%::myconfig, $date) . "\n");
|
52 |
59 |
|
53 |
|
_log_msg("Invoice " . $invoice->invnumber . " posted for config ID " . $config->id . ", period start date " . $::locale->format_date(\%::myconfig, $date) . "\n");
|
54 |
|
push @new_invoices, $invoice;
|
55 |
|
push @invoices_to_print, [ $invoice, $config ] if $config->print;
|
|
60 |
push @new_invoices, $data;
|
|
61 |
push @invoices_to_print, $data if $config->print;
|
|
62 |
push @invoices_to_email, $data if $config->send_email;
|
56 |
63 |
|
57 |
64 |
# last;
|
58 |
65 |
}
|
59 |
66 |
}
|
60 |
67 |
|
61 |
|
_print_invoice(@{ $_ }) for @invoices_to_print;
|
|
68 |
$self->_print_invoice($_) for @invoices_to_print;
|
|
69 |
$self->_email_invoice($_) for @invoices_to_email;
|
62 |
70 |
|
63 |
|
_send_email(\@new_invoices, [ map { $_->[0] } @invoices_to_print ]) if @new_invoices;
|
|
71 |
$self->_send_summary_email(
|
|
72 |
[ map { $_->{invoice} } @new_invoices ],
|
|
73 |
[ map { $_->{invoice} } @invoices_to_print ],
|
|
74 |
[ map { $_->{invoice} } @invoices_to_email ],
|
|
75 |
);
|
|
76 |
|
|
77 |
if (@{ $self->{job_errors} }) {
|
|
78 |
my $msg = @{ $self->{job_errors} };
|
|
79 |
_log_msg("Errors: $msg");
|
|
80 |
die $msg;
|
|
81 |
}
|
64 |
82 |
|
65 |
83 |
return 1;
|
66 |
84 |
}
|
... | ... | |
177 |
195 |
}
|
178 |
196 |
|
179 |
197 |
sub _create_periodic_invoice {
|
180 |
|
$main::lxdebug->enter_sub();
|
181 |
|
|
182 |
198 |
my $self = shift;
|
183 |
199 |
my $config = shift;
|
184 |
200 |
my $period_start_date = shift;
|
... | ... | |
242 |
258 |
$::lxdebug->message(LXDebug->WARN(), "_create_invoice failed: " . join("\n", (split(/\n/, $self->{db_obj}->db->error))[0..2]));
|
243 |
259 |
return undef;
|
244 |
260 |
}
|
245 |
|
$main::lxdebug->leave_sub();
|
246 |
|
return $invoice;
|
|
261 |
|
|
262 |
return {
|
|
263 |
config => $config,
|
|
264 |
period_start_date => $period_start_date,
|
|
265 |
invoice => $invoice,
|
|
266 |
time_period_vars => $time_period_vars,
|
|
267 |
};
|
247 |
268 |
}
|
248 |
269 |
|
249 |
270 |
sub _calculate_dates {
|
... | ... | |
251 |
272 |
return $config->calculate_invoice_dates(end_date => DateTime->today_local);
|
252 |
273 |
}
|
253 |
274 |
|
254 |
|
sub _send_email {
|
255 |
|
my ($posted_invoices, $printed_invoices) = @_;
|
|
275 |
sub _send_summary_email {
|
|
276 |
my ($self, $posted_invoices, $printed_invoices, $emailed_invoices) = @_;
|
256 |
277 |
|
257 |
278 |
my %config = %::lx_office_conf;
|
258 |
279 |
|
... | ... | |
274 |
295 |
my $email_template = $config{periodic_invoices}->{email_template};
|
275 |
296 |
my $filename = $email_template || ( (SL::DB::Default->get->templates || "templates/webpages") . "/oe/periodic_invoices_email.txt" );
|
276 |
297 |
my %params = ( POSTED_INVOICES => $posted_invoices,
|
277 |
|
PRINTED_INVOICES => $printed_invoices );
|
|
298 |
PRINTED_INVOICES => $printed_invoices,
|
|
299 |
EMAILED_INVOICES => $emailed_invoices );
|
278 |
300 |
|
279 |
301 |
my $output;
|
280 |
302 |
$template->process($filename, \%params, \$output);
|
... | ... | |
290 |
312 |
}
|
291 |
313 |
|
292 |
314 |
sub _print_invoice {
|
293 |
|
my ($invoice, $config) = @_;
|
|
315 |
my ($self, $data) = @_;
|
|
316 |
|
|
317 |
my $invoice = $data->{invoice};
|
|
318 |
my $config = $data->{config};
|
294 |
319 |
|
295 |
320 |
return unless $config->print && $config->printer_id && $config->printer->printer_command;
|
296 |
321 |
|
... | ... | |
319 |
344 |
eval {
|
320 |
345 |
$form->parse_template(\%::myconfig);
|
321 |
346 |
1;
|
322 |
|
} || die $EVAL_ERROR->getMessage;
|
|
347 |
} or do {
|
|
348 |
push @{ $self->{job_errors} }, $EVAL_ERROR->getMessage;
|
|
349 |
};
|
323 |
350 |
});
|
324 |
351 |
}
|
325 |
352 |
|
|
353 |
sub _email_invoice {
|
|
354 |
my ($self, $data) = @_;
|
|
355 |
|
|
356 |
$data->{config}->load;
|
|
357 |
|
|
358 |
return unless $data->{config}->send_email;
|
|
359 |
|
|
360 |
my @recipients =
|
|
361 |
uniq
|
|
362 |
map { lc }
|
|
363 |
grep { $_ }
|
|
364 |
map { trim($_) }
|
|
365 |
(split(m{,}, $data->{config}->email_recipient_address),
|
|
366 |
$data->{config}->email_recipient_contact ? ($data->{config}->email_recipient_contact->cp_email) : ());
|
|
367 |
|
|
368 |
return unless @recipients;
|
|
369 |
|
|
370 |
my %create_params = (
|
|
371 |
template => $self->find_template(name => 'invoice'),
|
|
372 |
variables => Form->new(''),
|
|
373 |
return => 'file_name',
|
|
374 |
variable_content_types => {
|
|
375 |
longdescription => 'html',
|
|
376 |
partnotes => 'html',
|
|
377 |
notes => 'html',
|
|
378 |
},
|
|
379 |
);
|
|
380 |
|
|
381 |
$data->{invoice}->flatten_to_form($create_params{variables}, format_amounts => 1);
|
|
382 |
$create_params{variables}->prepare_for_printing;
|
|
383 |
|
|
384 |
my $pdf_file_name;
|
|
385 |
|
|
386 |
eval {
|
|
387 |
$pdf_file_name = $self->create_pdf(%create_params);
|
|
388 |
|
|
389 |
for (qw(email_subject email_body)) {
|
|
390 |
_replace_vars(
|
|
391 |
object => $data->{config},
|
|
392 |
vars => $data->{time_period_vars},
|
|
393 |
attribute => $_,
|
|
394 |
attribute_format => 'text'
|
|
395 |
);
|
|
396 |
}
|
|
397 |
|
|
398 |
for my $recipient (@recipients) {
|
|
399 |
my $mail = Mailer->new;
|
|
400 |
$mail->{from} = $data->{config}->email_sender || $::lx_office_conf{periodic_invoices}->{email_from};
|
|
401 |
$mail->{to} = $recipient;
|
|
402 |
$mail->{subject} = $data->{config}->email_subject;
|
|
403 |
$mail->{message} = $data->{config}->email_body;
|
|
404 |
$mail->{attachments} = [{
|
|
405 |
filename => $pdf_file_name,
|
|
406 |
name => sprintf('%s %s.pdf', $::locale->text('Invoice'), $data->{invoice}->invnumber),
|
|
407 |
}];
|
|
408 |
|
|
409 |
my $error = $mail->send;
|
|
410 |
|
|
411 |
push @{ $self->{job_errors} }, $error if $error;
|
|
412 |
}
|
|
413 |
|
|
414 |
1;
|
|
415 |
|
|
416 |
} or do {
|
|
417 |
push @{ $self->{job_errors} }, $EVAL_ERROR;
|
|
418 |
};
|
|
419 |
|
|
420 |
unlink $pdf_file_name if $pdf_file_name;
|
|
421 |
}
|
|
422 |
|
326 |
423 |
1;
|
327 |
424 |
|
328 |
425 |
__END__
|
Wiederkerende Rechnungen: Implementation automatischer Versand via E-Mail