Mahnprozess um Filter nach (Kunden) Land erweitert
[kivitendo-erp.git] / SL / DN.pm
index 5cf42b5..94e5b77 100644 (file)
--- a/SL/DN.pm
+++ b/SL/DN.pm
@@ -36,10 +36,13 @@ package DN;
 
 use SL::Common;
 use SL::DBUtils;
+use SL::GenericTranslations;
 use SL::IS;
 use SL::Mailer;
 use SL::MoreCommon;
 use SL::Template;
+use SL::DB::Printer;
+use SL::DB::Language;
 
 use strict;
 
@@ -268,7 +271,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);
 
@@ -288,7 +291,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,
@@ -363,7 +366,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};
@@ -402,15 +405,54 @@ sub set_template_options {
     $form->{printer_code} = "_" . $form->{printer_code};
   }
 
-  $form->{IN}  = "$form->{formname}$form->{language}$form->{printer_code}.html";
-  $form->{pdf} = 1;
+  my $extension = 'html';
+  if ($form->{format} eq 'postscript') {
+    $form->{postscript}   = 1;
+    $extension            = 'tex';
 
-  if ($form->{"format"} =~ /opendocument/) {
-    $form->{IN} =~ s/html$/odt/;
-  } else {
-    $form->{IN} =~ s/html$/tex/;
+  } elsif ($form->{"format"} =~ /pdf/) {
+    $form->{pdf}          = 1;
+    $extension            = $form->{'format'} =~ m/opendocument/i ? 'odt' : 'tex';
+
+  } elsif ($form->{"format"} =~ /opendocument/) {
+    $form->{opendocument} = 1;
+    $extension            = 'odt';
+  } elsif ($form->{"format"} =~ /excel/) {
+    $form->{excel} = 1;
+    $extension            = 'xls';
+  }
+
+
+  # search for the template
+  my @template_files;
+  push @template_files, "$form->{formname}_email$form->{language}$form->{printer_code}.$extension" if $form->{media} eq 'email';
+  push @template_files, "$form->{formname}$form->{language}$form->{printer_code}.$extension";
+  push @template_files, "$form->{formname}.$extension";
+  push @template_files, "default.$extension";
+
+  $form->{IN} = undef;
+  for my $filename (@template_files) {
+    if (-f "$form->{templates}/$filename") {
+      $form->{IN} = $filename;
+      last;
+    }
+  }
+
+  if (!defined $form->{IN}) {
+    $::form->error($::locale->text('Cannot find matching template for this print request. Please contact your template maintainer. I tried these: #1.', join ', ', map { "'$_'"} @template_files));
   }
 
+  # prepare meta information for template introspection
+  $form->{template_meta} = {
+    formname  => $form->{formname},
+    language  => SL::DB::Manager::Language->find_by_or_create(id => $form->{language_id}),
+    format    => $form->{format},
+    media     => $form->{media},
+    extension => $extension,
+    printer   => SL::DB::Manager::Printer->find_by_or_create(id => $form->{printer_id}),
+    today     => DateTime->today,
+  };
+
   $main::lxdebug->leave_sub();
 }
 
@@ -441,6 +483,7 @@ sub get_invoices {
     "ordnumber" => "a.ordnumber",
     "invnumber" => "a.invnumber",
     "notes"     => "a.notes",
+    "country"   => "ct.country",
     );
   foreach my $key (keys(%columns)) {
     next unless ($form->{$key});
@@ -467,7 +510,7 @@ sub get_invoices {
 
   $query =
     qq|SELECT
-         a.id, a.ordnumber, a.transdate, a.invnumber, a.amount,
+         a.id, a.ordnumber, a.transdate, a.invnumber, a.amount, a.language_id,
          ct.name AS customername, a.customer_id, a.duedate,
          a.amount - a.paid AS open_amount,
 
@@ -503,7 +546,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)
@@ -622,7 +670,7 @@ sub get_dunning {
   my $sortorder = join ', ', map { "$_ $sortdir" } @{ $sort_columns{$sortkey} };
 
   my $query =
-    qq|SELECT a.id, a.ordnumber, a.invoice, a.transdate, a.invnumber, a.amount,
+    qq|SELECT a.id, a.ordnumber, a.invoice, a.transdate, a.invnumber, a.amount, a.language_id,
          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,
@@ -655,39 +703,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 {
     my $dunning_filename = $form->get_formname_translation('dunning');
-    $out = IO::File->new('>-');
-    $out->print(qq|Content-Type: Application/PDF\n| .
-                qq|Content-Disposition: attachment; filename="${dunning_filename}_${dunning_id}.pdf"\n\n|);
-  }
+    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();
 }
@@ -714,6 +760,7 @@ sub print_dunning {
          ar.transdate,       ar.duedate,      ar.customer_id,
          ar.invnumber,       ar.ordnumber,    ar.cp_id,
          ar.amount,          ar.netamount,    ar.paid,
+         ar.curr,
          ar.amount - ar.paid AS open_amount,
          ar.amount - ar.paid + da.fee + da.interest AS linetotal
 
@@ -742,11 +789,13 @@ sub print_dunning {
          c.country,           c.department_1, c.department_2, c.email,     c.customernumber,
          c.greeting,          c.contact,      c.phone,        c.fax,       c.homepage,
          c.email,             c.taxincluded,  c.business_id,  c.taxnumber, c.iban,
+         c,ustid,             e.name as salesman_name,
          co.*
        FROM dunning d
        LEFT JOIN ar          ON (d.trans_id = ar.id)
        LEFT JOIN customer c  ON (ar.customer_id = c.id)
        LEFT JOIN contacts co ON (ar.cp_id = co.cp_id)
+       LEFT JOIN employee e  ON (ar.salesman_id = e.id)
        WHERE (d.dunning_id = ?)
        LIMIT 1|;
   my $ref = selectfirst_hashref_query($form, $dbh, $query, $dunning_id);
@@ -785,19 +834,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;
 
@@ -835,7 +886,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,
@@ -876,22 +927,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;
@@ -899,4 +952,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;