Die ausgewiesenen Mahngebühren gelten pro Rechnung, nicht pro erzeugter Mahnung,...
[kivitendo-erp.git] / SL / DN.pm
1 #======================================================================
2 # LX-Office ERP
3 # Copyright (C) 2006
4 # Based on SQL-Ledger Version 2.1.9
5 # Web http://www.lx-office.org
6 #
7 #=====================================================================
8 # SQL-Ledger Accounting
9 # Copyright (C) 1998-2002
10 #
11 #  Author: Dieter Simader
12 #   Email: dsimader@sql-ledger.org
13 #     Web: http://www.sql-ledger.org
14 #
15 #  Contributors:
16 #
17 # This program is free software; you can redistribute it and/or modify
18 # it under the terms of the GNU General Public License as published by
19 # the Free Software Foundation; either version 2 of the License, or
20 # (at your option) any later version.
21 #
22 # This program is distributed in the hope that it will be useful,
23 # but WITHOUT ANY WARRANTY; without even the implied warranty of
24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 # GNU General Public License for more details.
26 # You should have received a copy of the GNU General Public License
27 # along with this program; if not, write to the Free Software
28 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #======================================================================
30 #
31 # Dunning process module
32 #
33 #======================================================================
34
35 package DN;
36
37 use SL::Template;
38 use SL::IS;
39 use SL::Common;
40 use SL::DBUtils;
41 use Data::Dumper;
42
43 sub get_config {
44   $main::lxdebug->enter_sub();
45
46   my ($self, $myconfig, $form) = @_;
47
48   # connect to database
49   my $dbh = $form->dbconnect($myconfig);
50
51   my $query =
52     qq|SELECT * | .
53     qq|FROM dunning_config | .
54     qq|ORDER BY dunning_level|;
55   $form->{DUNNING} = selectall_hashref_query($form, $dbh, $query);
56
57   foreach my $ref (@{ $form->{DUNNING} }) {
58     $ref->{fee} = $form->format_amount($myconfig, $ref->{fee}, 2);
59     $ref->{interest_rate} = $form->format_amount($myconfig, ($ref->{interest_rate} * 100));
60   }
61
62   $dbh->disconnect();
63
64   $main::lxdebug->leave_sub();
65 }
66
67 sub save_config {
68   $main::lxdebug->enter_sub();
69
70   my ($self, $myconfig, $form) = @_;
71
72   # connect to database
73   my $dbh = $form->dbconnect_noauto($myconfig);
74
75   my ($query, @values);
76
77   for my $i (1 .. $form->{rowcount}) {
78     $form->{"fee_$i"} = $form->parse_amount($myconfig, $form->{"fee_$i"}) * 1;
79     $form->{"interest_rate_$i"} = $form->parse_amount($myconfig, $form->{"interest_rate_$i"}) / 100;
80
81     if (($form->{"dunning_level_$i"} ne "") &&
82         ($form->{"dunning_description_$i"} ne "")) {
83       @values = (conv_i($form->{"dunning_level_$i"}), $form->{"dunning_description_$i"},
84                  $form->{"email_subject_$i"}, $form->{"email_body_$i"},
85                  $form->{"template_$i"}, $form->{"fee_$i"}, $form->{"interest_rate_$i"},
86                  $form->{"active_$i"} ? 't' : 'f', $form->{"auto_$i"} ? 't' : 'f', $form->{"email_$i"} ? 't' : 'f',
87                  $form->{"email_attachment_$i"} ? 't' : 'f', conv_i($form->{"payment_terms_$i"}), conv_i($form->{"terms_$i"}));
88       if ($form->{"id_$i"}) {
89         $query =
90           qq|UPDATE dunning_config SET
91                dunning_level = ?, dunning_description = ?,
92                email_subject = ?, email_body = ?,
93                template = ?, fee = ?, interest_rate = ?,
94                active = ?, auto = ?, email = ?,
95                email_attachment = ?, payment_terms = ?, terms = ?
96              WHERE id = ?|;
97         push(@values, conv_i($form->{"id_$i"}));
98       } else {
99         $query =
100           qq|INSERT INTO dunning_config
101                (dunning_level, dunning_description, email_subject, email_body,
102                 template, fee, interest_rate, active, auto, email,
103                 email_attachment, payment_terms, terms)
104              VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|;
105       }
106       do_query($form, $dbh, $query, @values);
107     }
108
109     if (($form->{"dunning_description_$i"} eq "") && ($form->{"id_$i"})) {
110       $query = qq|DELETE FROM dunning_config WHERE id = ?|;
111       do_query($form, $dbh, $query, $form->{"id_$i"});
112     }
113   }
114
115   $dbh->commit;
116   $dbh->disconnect;
117
118   $main::lxdebug->leave_sub();
119 }
120
121 sub save_dunning {
122   $main::lxdebug->enter_sub();
123
124   my ($self, $myconfig, $form, $rows, $userspath, $spool, $sendmail) = @_;
125   # connect to database
126   my $dbh = $form->dbconnect_noauto($myconfig);
127
128   my ($query, @values);
129
130   my ($dunning_id) = selectrow_query($form, $dbh, qq|SELECT nextval('id')|);
131
132   my $q_update_ar = qq|UPDATE ar SET dunning_config_id = ? WHERE id = ?|;
133   my $h_update_ar = prepare_query($form, $dbh, $q_update_ar);
134
135   my $q_insert_dunning =
136     qq|INSERT INTO dunning (dunning_id, dunning_config_id, dunning_level,
137                             trans_id, fee, interest, transdate, duedate)
138        VALUES (?, ?,
139                (SELECT dunning_level FROM dunning_config WHERE id = ?),
140                ?,
141                (SELECT SUM(fee)
142                 FROM dunning_config
143                 WHERE dunning_level <= (SELECT dunning_level FROM dunning_config WHERE id = ?)),
144                (SELECT (amount - paid) * (current_date - transdate) FROM ar WHERE id = ?)
145                  * (SELECT interest_rate FROM dunning_config WHERE id = ?)
146                  / 360,
147                current_date,
148                current_date + (SELECT payment_terms FROM dunning_config WHERE id = ?))|;
149   my $h_insert_dunning = prepare_query($form, $dbh, $q_insert_dunning);
150
151   my @invoice_ids;
152   my ($next_dunning_config_id, $customer_id);
153   my $send_email = 0;
154
155   foreach my $row (@{ $rows }) {
156     push @invoice_ids, $row->{invoice_id};
157     $next_dunning_config_id = $row->{next_dunning_config_id};
158     $customer_id            = $row->{customer_id};
159
160     @values = ($row->{next_dunning_config_id}, $row->{invoice_id});
161     do_statement($form, $h_update_ar, $q_update_ar, @values);
162
163     $send_email |= $row->{email};
164
165     my $next_config_id = conv_i($row->{next_dunning_config_id});
166     my $invoice_id     = conv_i($row->{invoice_id});
167
168     @values = ($dunning_id,     $next_config_id, $next_config_id,
169                $invoice_id,     $next_config_id, $invoice_id,
170                $next_config_id, $next_config_id);
171     do_statement($form, $h_insert_dunning, $q_insert_dunning, @values);
172   }
173
174   $h_update_ar->finish();
175   $h_insert_dunning->finish();
176
177   my $query =
178     qq|SELECT
179          ar.invnumber, ar.ordnumber, ar.amount, ar.netamount,
180          ar.transdate, ar.duedate, ar.paid, ar.amount - ar.paid AS open_amount,
181          da.fee, da.interest, da.transdate AS dunning_date, da.duedate AS dunning_duedate
182        FROM ar
183        LEFT JOIN dunning_config cfg ON (cfg.id = ar.dunning_config_id)
184        LEFT JOIN dunning da ON (ar.id = da.trans_id AND cfg.dunning_level = da.dunning_level)
185        WHERE ar.id IN (|
186        . join(", ", map { "?" } @invoice_ids) . qq|)|;
187
188   my $sth = prepare_execute_query($form, $dbh, $query, @invoice_ids);
189   my $first = 1;
190   while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
191     if ($first) {
192       map({ $form->{"dn_$_"} = []; } keys(%{$ref}));
193       $first = 0;
194     }
195
196     $ref->{interest_rate} = $form->format_amount($myconfig, $ref->{interest_rate} * 100);
197     map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2) } qw(amount netamount paid open_amount fee interest);
198     map { push(@{ $form->{"dn_$_"} }, $ref->{$_})} keys %$ref;
199     map { $form->{$_} = $ref->{$_} } keys %{ $ref };
200   }
201   $sth->finish;
202
203   $query =
204     qq|SELECT id AS customer_id, name, street, zipcode, city, country, department_1, department_2, email
205        FROM customer
206        WHERE id = ?|;
207   $ref = selectfirst_hashref_query($form, $dbh, $query, $customer_id);
208   map { $form->{$_} = $ref->{$_} } keys %{ $ref };
209
210   $query =
211     qq|SELECT
212          cfg.interest_rate, cfg.template AS formname,
213          cfg.email_subject, cfg.email_body, cfg.email_attachment,
214          (SELECT SUM(fee)
215           FROM dunning
216           WHERE dunning_id = ?)
217          AS fee,
218          (SELECT SUM(interest)
219           FROM dunning
220           WHERE dunning_id = ?)
221          AS total_interest,
222          (SELECT SUM(amount) - SUM(paid)
223           FROM ar
224           WHERE id IN (| . join(", ", map { "?" } @invoice_ids) . qq|))
225          AS total_open_amount
226        FROM dunning_config cfg
227        WHERE id = ?|;
228   $ref = selectfirst_hashref_query($form, $dbh, $query, $dunning_id, $dunning_id, @invoice_ids, $next_dunning_config_id);
229   map { $form->{$_} = $ref->{$_} } keys %{ $ref };
230
231   $form->{interest_rate}     = $form->format_amount($myconfig, $ref->{interest_rate} * 100);
232   $form->{fee}               = $form->format_amount($myconfig, $ref->{fee}, 2);
233   $form->{total_interest}    = $form->format_amount($myconfig, $form->round_amount($ref->{total_interest}, 2), 2);
234   $form->{total_open_amount} = $form->format_amount($myconfig, $form->round_amount($ref->{total_open_amount}, 2), 2);
235   $form->{total_amount}      = $form->format_amount($myconfig, $form->round_amount($ref->{fee} + $ref->{total_interest} + $ref->{total_open_amount}, 2), 2);
236
237   $form->{templates}    = "$myconfig->{templates}";
238   $form->{language}     = $form->get_template_language(\%myconfig);
239   $form->{printer_code} = $form->get_printer_code(\%myconfig);
240
241   if ($form->{language} ne "") {
242     $form->{language} = "_" . $form->{language};
243   }
244
245   if ($form->{printer_code} ne "") {
246     $form->{printer_code} = "_" . $form->{printer_code};
247   }
248
249   $form->{IN} = "$form->{formname}$form->{language}$form->{printer_code}.html";
250   if ($form->{format} eq 'postscript') {
251     $form->{postscript} = 1;
252     $form->{IN} =~ s/html$/tex/;
253   } elsif ($form->{"format"} =~ /pdf/) {
254     $form->{pdf} = 1;
255     if ($form->{"format"} =~ /opendocument/) {
256       $form->{IN} =~ s/html$/odt/;
257     } else {
258       $form->{IN} =~ s/html$/tex/;
259     }
260   } elsif ($form->{"format"} =~ /opendocument/) {
261     $form->{"opendocument"} = 1;
262     $form->{"IN"} =~ s/html$/odt/;
263   }
264
265   if ($send_email && ($form->{email} ne "")) {
266     $form->{media} = 'email';
267   }
268
269   $form->{keep_tmpfile} = 0;
270   if ($form->{media} eq 'email') {
271     $form->{subject} = qq|$form->{label} $form->{"${inv}number"}|
272       unless $form->{subject};
273     if (!$form->{email_attachment}) {
274       $form->{do_not_attach} = 1;
275     } else {
276       $form->{do_not_attach} = 0;
277     }
278     $form->{subject} = parse_strings($myconfig, $form, $userspath, $form->{email_subject});
279     $form->{message} = parse_strings($myconfig, $form, $userspath, $form->{email_body});
280
281     $form->{OUT} = "$sendmail";
282
283   } else {
284
285     my $filename = Common::unique_id() . $form->{login} . ".pdf";
286     $form->{OUT} = ">$spool/$filename";
287     push(@{ $form->{DUNNING_PDFS} }, $filename);
288     $form->{keep_tmpfile} = 1;
289   }
290
291   delete($form->{tmpfile});
292   $form->parse_template($myconfig, $userspath);
293
294   $dbh->commit;
295   $dbh->disconnect;
296
297   $main::lxdebug->leave_sub();
298 }
299
300 sub get_invoices {
301
302   $main::lxdebug->enter_sub();
303
304   my ($self, $myconfig, $form) = @_;
305
306   # connect to database
307   my $dbh = $form->dbconnect($myconfig);
308
309   my $where;
310   my @values;
311
312   $form->{customer_id} = $1 if ($form->{customer} =~ /--(\d+)$/);
313
314   if ($form->{customer_id}) {
315     $where .= qq| AND (a.customer_id = ?)|;
316     push(@values, $form->{customer_id});
317
318   } elsif ($form->{customer}) {
319     $where .= qq| AND (ct.name ILIKE ?)|;
320     push(@values, '%' . $form->{customer} . '%');
321   }
322
323   my %columns = (
324     "ordnumber" => "a.ordnumber",
325     "invnumber" => "a.invnumber",
326     "notes"     => "a.notes",
327     );
328   foreach my $key (keys(%columns)) {
329     next unless ($form->{$key});
330     $where .= qq| AND $columns{$key} ILIKE ?|;
331     push(@values, '%' . $form->{$key} . '%');
332   }
333
334   if ($form->{dunning_level}) {
335     $where .= qq| AND nextcfg.id = ?|;
336     push(@values, conv_i($form->{dunning_level}));
337   }
338
339   $form->{minamount} = $form->parse_amount($myconfig,$form->{minamount});
340   if ($form->{minamount}) {
341     $where .= qq| AND ((a.amount - a.paid) > ?) |;
342     push(@values, $form->{minamount});
343   }
344
345   $query =
346     qq|SELECT
347          a.id, a.ordnumber, a.transdate, a.invnumber, a.amount,
348          ct.name AS customername, a.customer_id, a.duedate,
349
350          cfg.dunning_description, cfg.dunning_level,
351
352          d.transdate AS dunning_date, d.duedate AS dunning_duedate,
353          d.fee, d.interest,
354
355          a.duedate + cfg.terms - current_date AS nextlevel,
356          current_date - COALESCE(d.duedate, a.duedate) AS pastdue,
357          current_date + cfg.payment_terms AS next_duedate,
358
359          nextcfg.dunning_description AS next_dunning_description,
360          nextcfg.id AS next_dunning_config_id,
361          nextcfg.terms, nextcfg.active, nextcfg.email
362
363        FROM ar a
364
365        LEFT JOIN customer ct ON (a.customer_id = ct.id)
366        LEFT JOIN dunning_config cfg ON (a.dunning_config_id = cfg.id)
367        LEFT JOIN dunning_config nextcfg ON
368          (nextcfg.id =
369            (SELECT id
370             FROM dunning_config
371             WHERE dunning_level >
372               COALESCE((SELECT dunning_level
373                         FROM dunning_config
374                         WHERE id = a.dunning_config_id
375                         ORDER BY dunning_level DESC
376                         LIMIT 1),
377                        0)
378             LIMIT 1))
379        LEFT JOIN dunning d ON ((d.trans_id = a.id) AND (cfg.dunning_level = d.dunning_level))
380
381        WHERE (a.paid < a.amount)
382          AND (a.duedate < current_date)
383
384        $where
385
386        ORDER BY a.id, transdate, duedate, name|;
387   my $sth = prepare_execute_query($form, $dbh, $query, @values);
388
389   $form->{DUNNINGS} = [];
390
391   while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
392     next if !$ref->{terms} || ($ref->{pastdue} < $ref->{terms});
393
394     $ref->{interest} = $form->round_amount($ref->{interest}, 2);
395     push(@{ $form->{DUNNINGS} }, $ref);
396   }
397
398   $sth->finish;
399
400   $query = qq|SELECT id, dunning_description FROM dunning_config ORDER BY dunning_level|;
401   $form->{DUNNING_CONFIG} = selectall_hashref_query($form, $dbh, $query);
402
403   $dbh->disconnect;
404   $main::lxdebug->leave_sub();
405 }
406
407 sub get_dunning {
408
409   $main::lxdebug->enter_sub();
410
411   my ($self, $myconfig, $form) = @_;
412
413   # connect to database
414   my $dbh = $form->dbconnect($myconfig);
415
416   $where = qq| WHERE (da.trans_id = a.id)|;
417
418   my @values;
419
420   if ($form->{customer_id}) {
421     $where .= qq| AND (a.customer_id = ?)|;
422     push(@values, $form->{customer_id});
423
424   } elsif ($form->{customer}) {
425     $where .= qq| AND (ct.name ILIKE ?)|;
426     push(@values, '%' . $form->{customer} . '%');
427   }
428
429   my %columns = (
430     "ordnumber" => "a.ordnumber",
431     "invnumber" => "a.invnumber",
432     "notes" => "a.notes",
433     );
434   foreach my $key (keys(%columns)) {
435     next unless ($form->{$key});
436     $where .= qq| AND $columns{$key} ILIKE ?|;
437     push(@values, '%' . $form->{$key} . '%');
438   }
439
440   if ($form->{dunning_level}) {
441     $where .= qq| AND a.dunning_config_id = ?|;
442     push(@values, conv_i($form->{dunning_level}));
443   }
444
445   if ($form->{department_id}) {
446     $where .= qq| AND a.department_id = ?|;
447     push @values, conv_i($form->{department_id});
448   }
449
450   $form->{minamount} = $form->parse_amount($myconfig, $form->{minamount});
451   if ($form->{minamount}) {
452     $where .= qq| AND ((a.amount - a.paid) > ?) |;
453     push(@values, $form->{minamount});
454   }
455
456   if (!$form->{showold}) {
457     $where .= qq| AND (a.amount > a.paid) AND (da.dunning_config_id = a.dunning_config_id) |;
458   }
459
460   if ($form->{transdatefrom}) {
461     $where .= qq| AND a.transdate >= ?|;
462     push(@values, $form->{transdatefrom});
463   }
464   if ($form->{transdateto}) {
465     $where .= qq| AND a.transdate <= ?|;
466     push(@values, $form->{transdateto});
467   }
468   if ($form->{dunningfrom}) {
469     $where .= qq| AND da.transdate >= ?|;
470     push(@values, $form->{dunningfrom});
471   }
472   if ($form->{dunningto}) {
473     $where .= qq| AND da.transdate >= ?|;
474     push(@values, $form->{dunningto});
475   }
476
477   $query =
478     qq|SELECT a.id, a.ordnumber, a.invoice, a.transdate, a.invnumber, a.amount,
479          ct.name AS customername, ct.id AS customer_id, a.duedate, da.fee,
480          da.interest, dn.dunning_description, da.transdate AS dunning_date,
481          da.duedate AS dunning_duedate, da.dunning_id, da.dunning_config_id
482        FROM ar a
483        JOIN customer ct ON (a.customer_id = ct.id), dunning da
484        LEFT JOIN dunning_config dn ON (da.dunning_config_id = dn.id)
485        $where
486        ORDER BY name, a.id|;
487
488   $form->{DUNNINGS} = selectall_hashref_query($form, $dbh, $query, @values);
489
490   foreach my $ref (@{ $form->{DUNNINGS} }) {
491     map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2)} qw(amount fee interest);
492   }
493
494   $dbh->disconnect;
495   $main::lxdebug->leave_sub();
496 }
497
498 sub parse_strings {
499
500   $main::lxdebug->enter_sub();
501
502   my ($myconfig, $form, $userspath, $string) = @_;
503
504   local (*IN, *OUT);
505
506   my $format = $form->{format};
507   $form->{format} = "html";
508
509   $tmpstring = "parse_string.html";
510   $tmpfile = "$myconfig->{templates}/$tmpstring";
511   open(OUT, ">", $tmpfile) or $form->error("$tmpfile : $!");
512
513   print(OUT $string);
514   close(OUT);
515
516   my $in = $form->{IN};
517   $form->{IN} = $tmpstring;
518   $template = HTMLTemplate->new($tmpstring, $form, $myconfig, $userspath);
519
520   my $fileid = time;
521   $form->{tmpfile} = "$userspath/${fileid}.$tmpstring";
522
523   open(OUT, ">", $form->{tmpfile}) or $form->error("$form->{OUT} : $!");
524   if (!$template->parse(*OUT)) {
525     $form->cleanup();
526     $form->error("$form->{IN} : " . $template->get_error());
527   }
528
529   close(OUT);
530   my $result = "";
531   open(IN, "<", $form->{tmpfile}) or $form->error($form->cleanup . "$form->{tmpfile} : $!");
532
533   while (<IN>) {
534     $result .= $_;
535   }
536
537   close(IN);
538 #   unlink($tmpfile);
539 #   unlink($form->{tmpfile});
540   $form->{IN} = $in;
541   $form->{format} = $format;
542
543   $main::lxdebug->leave_sub();
544   return $result;
545 }
546
547 sub melt_pdfs {
548
549   $main::lxdebug->enter_sub();
550
551   my ($self, $myconfig, $form, $userspath) = @_;
552
553   local (*IN, *OUT);
554
555   # Don't allow access outside of $userspath.
556   map { $_ =~ s|.*/||; } @{ $form->{DUNNING_PDFS} };
557
558   my $inputfiles = join " ", map { "$userspath/$_" } @{ $form->{DUNNING_PDFS} };
559   my $outputfile = "$userspath/dunning.pdf";
560
561   system("gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=$outputfile $inputfiles");
562
563   map { unlink("$userspath/$_") } @{ $form->{DUNNING_PDFS} };
564
565   my $numbytes = (-s $outputfile);
566   open(IN, $outputfile) || $form->error($self->cleanup() . "$outputfile : $!");
567
568   $form->{copies} = 1 unless $form->{media} eq 'printer';
569
570   chdir($self->{cwd});
571
572   for my $i (1 .. $form->{copies}) {
573     # launch application
574     print qq|Content-Type: Application/PDF
575 Content-Disposition: attachment; filename="$outputfile"
576 Content-Length: $numbytes
577
578 |;
579
580     open(OUT, ">-") or $form->error($form->cleanup . "$!: STDOUT");
581
582     while (<IN>) {
583       print OUT $_;
584     }
585
586     close(OUT);
587
588     seek(IN, 0, 0);
589   }
590
591   close(IN);
592   unlink($outputfile);
593
594   $main::lxdebug->leave_sub();
595 }
596
597 sub print_dunning {
598   $main::lxdebug->enter_sub();
599
600   my ($self, $myconfig, $form, $dunning_id, $userspath, $spool, $sendmail) = @_;
601   # connect to database
602   my $dbh = $form->dbconnect_noauto($myconfig);
603
604   my $query =
605     qq|SELECT invnumber, ordnumber, customer_id, amount, netamount,
606          ar.transdate, ar.duedate, paid, amount - paid AS open_amount,
607          template AS formname, email_subject, email_body, email_attachment,
608          da.fee, da.interest, da.transdate AS dunning_date, da.duedate AS dunning_duedate
609        FROM dunning da
610        LEFT JOIN dunning_config ON (dunning_config.id = da.dunning_config_id)
611        LEFT JOIN ar ON (ar.id = da.trans_id)
612        WHERE (da.dunning_id = ?)|;
613
614   my $sth = prepare_execute_query($form, $dbh, $query, $dunning_id);
615   my $first = 1;
616   while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
617     if ($first) {
618       map({ $form->{"dn_$_"} = []; } keys(%{$ref}));
619       $first = 0;
620     }
621     map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2) } qw(amount netamount paid open_amount fee interest);
622     map { $form->{$_} = $ref->{$_} } keys %$ref;
623     map { push @{ $form->{"dn_$_"} }, $ref->{$_}} keys %$ref;
624   }
625   $sth->finish;
626
627   $query =
628     qq|SELECT id AS customer_id, name, street, zipcode, city, country, department_1, department_2, email
629        FROM customer
630        WHERE id =
631          (SELECT customer_id
632           FROM dunning d
633           LEFT JOIN ar ON (d.trans_id = ar.id)
634           WHERE d.id = ?)|;
635   $ref = selectfirst_hashref_query($form, $dbh, $query, $dunning_id);
636   map { $form->{$_} = $ref->{$_} } keys %{ $ref };
637
638   $query =
639     qq|SELECT
640          cfg.interest_rate, cfg.template AS formname,
641          cfg.email_subject, cfg.email_body, cfg.email_attachment,
642          d.transdate AS dunning_date,
643          (SELECT SUM(fee)
644           FROM dunning
645           WHERE dunning_id = ?)
646          AS fee,
647          (SELECT SUM(interest)
648           FROM dunning
649           WHERE dunning_id = ?)
650          AS total_interest,
651          (SELECT SUM(amount) - SUM(paid)
652           FROM ar
653           WHERE id IN
654             (SELECT trans_id
655              FROM dunning
656              WHERE dunning_id = ?))
657          AS total_open_amount
658        FROM dunning d
659        LEFT JOIN dunning_config cfg ON (d.dunning_config_id = cfg.id)
660        WHERE d.dunning_id = ?
661        LIMIT 1|;
662   $ref = selectfirst_hashref_query($form, $dbh, $query, $dunning_id, $dunning_id, $dunning_id, $dunning_id);
663   map { $form->{$_} = $ref->{$_} } keys %{ $ref };
664
665   $form->{interest_rate}     = $form->format_amount($myconfig, $ref->{interest_rate} * 100);
666   $form->{fee}               = $form->format_amount($myconfig, $ref->{fee}, 2);
667   $form->{total_interest}    = $form->format_amount($myconfig, $form->round_amount($ref->{total_interest}, 2), 2);
668   $form->{total_open_amount} = $form->format_amount($myconfig, $form->round_amount($ref->{total_open_amount}, 2), 2);
669   $form->{total_amount}      = $form->format_amount($myconfig, $form->round_amount($ref->{fee} + $ref->{total_interest} + $ref->{total_open_amount}, 2), 2);
670
671
672   $form->{templates} = "$myconfig->{templates}";
673
674   $form->{language} = $form->get_template_language(\%myconfig);
675   $form->{printer_code} = $form->get_printer_code(\%myconfig);
676
677   if ($form->{language} ne "") {
678     $form->{language} = "_" . $form->{language};
679   }
680
681   if ($form->{printer_code} ne "") {
682     $form->{printer_code} = "_" . $form->{printer_code};
683   }
684
685   $form->{IN} = "$form->{formname}$form->{language}$form->{printer_code}.html";
686   if ($form->{format} eq 'postscript') {
687     $form->{postscript} = 1;
688     $form->{IN} =~ s/html$/tex/;
689   } elsif ($form->{"format"} =~ /pdf/) {
690     $form->{pdf} = 1;
691     if ($form->{"format"} =~ /opendocument/) {
692       $form->{IN} =~ s/html$/odt/;
693     } else {
694       $form->{IN} =~ s/html$/tex/;
695     }
696   } elsif ($form->{"format"} =~ /opendocument/) {
697     $form->{"opendocument"} = 1;
698     $form->{"IN"} =~ s/html$/odt/;
699   }
700
701   if ($form->{"send_email"} && ($form->{email} ne "")) {
702     $form->{media} = 'email';
703   }
704
705   $form->{keep_tmpfile} = 0;
706   if ($form->{media} eq 'email') {
707     $form->{subject} = qq|$form->{label} $form->{"${inv}number"}|
708       unless $form->{subject};
709     if (!$form->{email_attachment}) {
710       $form->{do_not_attach} = 1;
711     } else {
712       $form->{do_not_attach} = 0;
713     }
714     $form->{subject} = parse_strings($myconfig, $form, $userspath, $form->{email_subject});
715     $form->{message} = parse_strings($myconfig, $form, $userspath, $form->{email_body});
716
717     $form->{OUT} = "$sendmail";
718
719   } else {
720
721     my $filename = Common::unique_id() . $form->{login} . ".pdf";
722
723     push(@{ $form->{DUNNING_PDFS} }, $filename);
724     $form->{keep_tmpfile} = 1;
725   }
726
727   $form->parse_template($myconfig, $userspath);
728
729   $dbh->commit;
730   $dbh->disconnect;
731
732   $main::lxdebug->leave_sub();
733 }
734
735 1;