Merge branch 'master' of vc.linet-services.de:public/lx-office-erp
[kivitendo-erp.git] / SL / DN.pm
index bd4b509..b00a83b 100644 (file)
--- a/SL/DN.pm
+++ b/SL/DN.pm
@@ -36,11 +36,14 @@ package DN;
 
 use SL::Common;
 use SL::DBUtils;
+use SL::GenericTranslations;
 use SL::IS;
 use SL::Mailer;
 use SL::MoreCommon;
 use SL::Template;
 
+use strict;
+
 sub get_config {
   $main::lxdebug->enter_sub();
 
@@ -266,7 +269,7 @@ sub create_invoice_for_fees {
 sub save_dunning {
   $main::lxdebug->enter_sub();
 
-  my ($self, $myconfig, $form, $rows, $userspath, $spool) = @_;
+  my ($self, $myconfig, $form, $rows) = @_;
   # connect to database
   my $dbh = $form->dbconnect_noauto($myconfig);
 
@@ -286,7 +289,7 @@ sub save_dunning {
                (SELECT SUM(fee)
                 FROM dunning_config
                 WHERE dunning_level <= (SELECT dunning_level FROM dunning_config WHERE id = ?)),
-               (SELECT (amount - paid) * (current_date - transdate) FROM ar WHERE id = ?)
+               (SELECT (amount - paid) * (current_date - duedate) FROM ar WHERE id = ?)
                  * (SELECT interest_rate FROM dunning_config WHERE id = ?)
                  / 360,
                current_date,
@@ -361,7 +364,7 @@ sub send_email {
     return;
   }
 
-  my $template     = PlainTextTemplate->new(undef, $form, $myconfig);
+  my $template     = SL::Template::create(type => 'PlainText', form => $form, myconfig => $myconfig);
   my $mail         = Mailer->new();
   $mail->{from}    = $myconfig->{email};
   $mail->{to}      = $ref->{recipient};
@@ -457,7 +460,7 @@ sub get_invoices {
     push(@values, $form->{minamount});
   }
 
-  $query =
+  my $query =
     qq|SELECT id
        FROM dunning_config
        WHERE dunning_level = (SELECT MAX(dunning_level) FROM dunning_config)|;
@@ -467,6 +470,7 @@ sub get_invoices {
     qq|SELECT
          a.id, a.ordnumber, a.transdate, a.invnumber, a.amount,
          ct.name AS customername, a.customer_id, a.duedate,
+         a.amount - a.paid AS open_amount,
 
          cfg.dunning_description, cfg.dunning_level,
 
@@ -500,7 +504,12 @@ sub get_invoices {
               ORDER BY dunning_level ASC
               LIMIT 1)
              , ?))
-       LEFT JOIN dunning d ON ((d.trans_id = a.id) AND (cfg.dunning_level = d.dunning_level))
+       LEFT JOIN dunning d ON (d.id = (
+         SELECT MAX(d2.id)
+         FROM dunning d2
+         WHERE (d2.trans_id      = a.id)
+           AND (d2.dunning_level = cfg.dunning_level)
+       ))
 
        WHERE (a.paid < a.amount)
          AND (a.duedate < current_date)
@@ -512,7 +521,7 @@ sub get_invoices {
 
   $form->{DUNNINGS} = [];
 
-  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+  while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
     next if ($ref->{pastdue} < $ref->{terms});
 
     $ref->{interest} = $form->round_amount($ref->{interest}, 2);
@@ -537,7 +546,7 @@ sub get_dunning {
   # connect to database
   my $dbh = $form->dbconnect($myconfig);
 
-  $where = qq| WHERE (da.trans_id = a.id)|;
+  my $where = qq| WHERE (da.trans_id = a.id)|;
 
   my @values;
 
@@ -598,6 +607,11 @@ sub get_dunning {
     push(@values, $form->{dunningto});
   }
 
+  if ($form->{salesman_id}) {
+    $where .= qq| AND a.salesman_id = ?|;
+    push(@values, conv_i($form->{salesman_id}));
+  }
+
   my %sort_columns = (
     'dunning_description' => [ qw(dn.dunning_description customername invnumber) ],
     'customername'        => [ qw(customername invnumber) ],
@@ -606,6 +620,7 @@ sub get_dunning {
     'duedate'             => [ qw(a.duedate a.invnumber) ],
     'dunning_date'        => [ qw(dunning_date a.invnumber) ],
     'dunning_duedate'     => [ qw(dunning_duedate a.invnumber) ],
+    'salesman'            => [ qw(salesman) ],
     );
 
   my $sortdir   = !defined $form->{sortdir}    ? 'ASC'         : $form->{sortdir} ? 'ASC' : 'DESC';
@@ -616,9 +631,11 @@ sub get_dunning {
     qq|SELECT a.id, a.ordnumber, a.invoice, a.transdate, a.invnumber, a.amount,
          ct.name AS customername, ct.id AS customer_id, a.duedate, da.fee,
          da.interest, dn.dunning_description, da.transdate AS dunning_date,
-         da.duedate AS dunning_duedate, da.dunning_id, da.dunning_config_id
+         da.duedate AS dunning_duedate, da.dunning_id, da.dunning_config_id,
+         e2.name AS salesman
        FROM ar a
-       JOIN customer ct ON (a.customer_id = ct.id), dunning da
+       JOIN customer ct ON (a.customer_id = ct.id)
+       LEFT JOIN employee e2 ON (a.salesman_id = e2.id), dunning da
        LEFT JOIN dunning_config dn ON (da.dunning_config_id = dn.id)
        $where
        ORDER BY $sortorder|;
@@ -644,38 +661,37 @@ sub melt_pdfs {
 
   $copies        *= 1;
   $copies         = 1 unless $copies;
-  my $inputfiles  = join " ", map { "${main::spool}/$_ " x $copies } @{ $form->{DUNNING_PDFS} };
+  my $spool       = $::lx_office_conf{paths}->{spool};
+  my $inputfiles  = join " ", map { "$spool/$_ " x $copies } @{ $form->{DUNNING_PDFS} };
   my $dunning_id  = $form->{dunning_id};
 
   $dunning_id     =~ s|[^\d]||g;
 
-  my $in = IO::File->new("gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=- $inputfiles |");
+  my $in = IO::File->new($::lx_office_conf{applications}->{ghostscript} . " -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=- $inputfiles |");
   $form->error($main::locale->text('Could not spawn ghostscript.')) unless $in;
 
-  my $out;
-
   if ($form->{media} eq 'printer') {
     $form->get_printer_code($myconfig);
+    my $out;
     if ($form->{printer_command}) {
       $out = IO::File->new("| $form->{printer_command}");
     }
 
+    $::locale->with_raw_io($out, sub { $out->print($_) while <$in> });
+
     $form->error($main::locale->text('Could not spawn the printer command.')) unless $out;
 
   } else {
-    $out = IO::File->new('>-');
-    $out->print(qq|Content-Type: Application/PDF\n| .
-                qq|Content-Disposition: attachment; filename="dunning_${dunning_id}.pdf"\n\n|);
-  }
+    my $dunning_filename = $form->get_formname_translation('dunning');
+    print qq|Content-Type: Application/PDF\n| .
+          qq|Content-Disposition: attachment; filename="${dunning_filename}_${dunning_id}.pdf"\n\n|;
 
-  while (my $line = <$in>) {
-    $out->print($line);
+    $::locale->with_raw_io(\*STDOUT, sub { print while <$in> });
   }
 
   $in->close();
-  $out->close();
 
-  map { unlink("${main::spool}/$_") } @{ $form->{DUNNING_PDFS} };
+  map { unlink("$spool/$_") } @{ $form->{DUNNING_PDFS} };
 
   $main::lxdebug->leave_sub();
 }
@@ -712,7 +728,7 @@ sub print_dunning {
 
   my $sth = prepare_execute_query($form, $dbh, $query, $dunning_id);
   my $first = 1;
-  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+  while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
     if ($first) {
       $form->{TEMPLATE_ARRAYS} = {};
       map({ $form->{TEMPLATE_ARRAYS}->{"dn_$_"} = []; } keys(%{$ref}));
@@ -737,7 +753,7 @@ sub print_dunning {
        LEFT JOIN contacts co ON (ar.cp_id = co.cp_id)
        WHERE (d.dunning_id = ?)
        LIMIT 1|;
-  $ref = selectfirst_hashref_query($form, $dbh, $query, $dunning_id);
+  my $ref = selectfirst_hashref_query($form, $dbh, $query, $dunning_id);
   map { $form->{$_} = $ref->{$_} } keys %{ $ref };
 
   $query =
@@ -773,19 +789,21 @@ sub print_dunning {
   $form->{total_open_amount} = $form->format_amount($myconfig, $form->round_amount($ref->{total_open_amount}, 2), 2);
   $form->{total_amount}      = $form->format_amount($myconfig, $form->round_amount($ref->{fee} + $ref->{total_interest} + $ref->{total_open_amount}, 2), 2);
 
+  $self->set_customer_cvars($myconfig, $form);
   $self->set_template_options($myconfig, $form);
 
   my $filename          = "dunning_${dunning_id}_" . Common::unique_id() . ".pdf";
-  $form->{OUT}          = ">${main::spool}/$filename";
+  my $spool             = $::lx_office_conf{paths}->{spool};
+  $form->{OUT}          = "${spool}/$filename";
   $form->{keep_tmpfile} = 1;
 
   delete $form->{tmpfile};
 
   push @{ $form->{DUNNING_PDFS} }, $filename;
-  push @{ $form->{DUNNING_PDFS_EMAIL} }, { 'filename' => "${main::spool}/$filename",
+  push @{ $form->{DUNNING_PDFS_EMAIL} }, { 'filename' => "${spool}/$filename",
                                            'name'     => "dunning_${dunning_id}.pdf" };
 
-  $form->parse_template($myconfig, $main::userspath);
+  $form->parse_template($myconfig);
 
   $dbh->disconnect() unless $provided_dbh;
 
@@ -823,7 +841,7 @@ sub print_invoice_for_fees {
   $query =
     qq|SELECT
          ar.invnumber, ar.transdate AS invdate, ar.amount, ar.netamount,
-         ar.duedate,   ar.notes,     ar.notes AS invoicenotes,
+         ar.duedate,   ar.notes,     ar.notes AS invoicenotes, ar.customer_id,
 
          c.name,      c.department_1,   c.department_2, c.street, c.zipcode, c.city, c.country,
          c.contact,   c.customernumber, c.phone,        c.fax,    c.email,
@@ -832,7 +850,7 @@ sub print_invoice_for_fees {
        FROM ar
        LEFT JOIN customer c ON (ar.customer_id = c.id)
        WHERE ar.id = ?|;
-  $ref = selectfirst_hashref_query($form, $dbh, $query, $ar_id);
+  my $ref = selectfirst_hashref_query($form, $dbh, $query, $ar_id);
   map { $form->{$_} = $ref->{$_} } keys %{ $ref };
 
   $query = qq|SELECT * FROM employee WHERE login = ?|;
@@ -864,22 +882,24 @@ sub print_invoice_for_fees {
 
   map { $form->{$_} = $form->format_amount($myconfig, $form->{$_}, 2) } qw(fee interest invamount);
 
+  $self->set_customer_cvars($myconfig, $form);
   $self->set_template_options($myconfig, $form);
 
   my $filename = Common::unique_id() . "dunning_invoice_${dunning_id}.pdf";
 
-  $form->{OUT}          = ">$main::spool/$filename";
+  my $spool             = $::lx_office_conf{paths}->{spool};
+  $form->{OUT}          = "$spool/$filename";
   $form->{keep_tmpfile} = 1;
   delete $form->{tmpfile};
 
   map { delete $form->{$_} } grep /^[a-z_]+_\d+$/, keys %{ $form };
 
-  $form->parse_template($myconfig, $main::userspath);
+  $form->parse_template($myconfig);
 
   restore_form($saved_form);
 
   push @{ $form->{DUNNING_PDFS} }, $filename;
-  push @{ $form->{DUNNING_PDFS_EMAIL} }, { 'filename' => "${main::spool}/$filename",
+  push @{ $form->{DUNNING_PDFS_EMAIL} }, { 'filename' => "${spool}/$filename",
                                            'name'     => "dunning_invoice_${dunning_id}.pdf" };
 
   $dbh->disconnect() unless $provided_dbh;
@@ -887,4 +907,18 @@ sub print_invoice_for_fees {
   $main::lxdebug->leave_sub();
 }
 
+sub set_customer_cvars {
+  my ($self, $myconfig, $form) = @_;
+
+  my $custom_variables = CVar->get_custom_variables(dbh      => $form->get_standard_dbh,
+                                                    module   => 'CT',
+                                                    trans_id => $form->{customer_id});
+  map { $form->{"vc_cvar_$_->{name}"} = $_->{value} } @{ $custom_variables };
+
+  $form->{cp_greeting} = GenericTranslations->get(dbh              => $form->get_standard_dbh,
+                                                  translation_type => 'greetings::' . ($form->{cp_gender} eq 'f' ? 'female' : 'male'),
+                                                  language_id      => $form->{language_id},
+                                                  allow_fallback   => 1);
+}
+
 1;