Mahnungsbericht: zweite Sortierung (fast) immer nach Mahnungslauf …
[kivitendo-erp.git] / SL / DN.pm
index 976b6aa..f3969fc 100644 (file)
--- a/SL/DN.pm
+++ b/SL/DN.pm
@@ -40,6 +40,7 @@ use SL::DBUtils;
 use SL::DB::AuthUser;
 use SL::DB::Default;
 use SL::DB::Employee;
+use SL::File;
 use SL::GenericTranslations;
 use SL::IS;
 use SL::Mailer;
@@ -50,6 +51,7 @@ use SL::DB::Language;
 use SL::TransNumber;
 use SL::Util qw(trim);
 use SL::DB;
+use SL::Webdav;
 
 use File::Copy;
 
@@ -192,7 +194,8 @@ sub create_invoice_for_fees {
              AND (d_interest.dunning_id <> ?)
              AND NOT (d_interest.fee_interest_ar_id ISNULL)
          ), 0)
-         AS max_previous_interest
+         AS max_previous_interest,
+         d.id AS link_id
        FROM dunning d
        WHERE dunning_id = ?|;
   @values = ($dunning_id, $dunning_id, $dunning_id);
@@ -201,6 +204,8 @@ sub create_invoice_for_fees {
   my ($fee_remaining, $interest_remaining) = (0, 0);
   my ($fee_total, $interest_total) = (0, 0);
 
+  my @link_ids;
+
   while (my $ref = $sth->fetchrow_hashref()) {
     $fee_remaining      += $form->round_amount($ref->{fee}, 2);
     $fee_remaining      -= $form->round_amount($ref->{max_previous_fee}, 2);
@@ -208,6 +213,7 @@ sub create_invoice_for_fees {
     $interest_remaining += $form->round_amount($ref->{interest}, 2);
     $interest_remaining -= $form->round_amount($ref->{max_previous_interest}, 2);
     $interest_total     += $form->round_amount($ref->{interest}, 2);
+    push @link_ids, $ref->{link_id};
   }
 
   $sth->finish();
@@ -271,6 +277,15 @@ sub create_invoice_for_fees {
              $::myconfig{login});   # employee_id
   do_query($form, $dbh, $query, @values);
 
+  RecordLinks->create_links(
+    'dbh'        => $dbh,
+    'mode'       => 'ids',
+    'from_table' => 'dunning',
+    'from_ids'   => \@link_ids,
+    'to_table'   => 'ar',
+    'to_id'      => $ar_id,
+  );
+
   $query =
     qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, gldate, taxkey, tax_id, chart_link)
        VALUES (?, ?, ?, current_date, current_date, 0,
@@ -302,8 +317,18 @@ sub save_dunning {
   my ($self, $myconfig, $form, $rows) = @_;
   $main::lxdebug->enter_sub();
 
+  $form->{DUNNING_PDFS_STORAGE} = [];
+
   my $rc = SL::DB->client->with_transaction(\&_save_dunning, $self, $myconfig, $form, $rows);
 
+  # Save PDFs in filemanagement and webdav after transation succeeded,
+  # because otherwise files in the storage may exists if the transaction
+  # failed. Ignore all errros.
+  # Todo: Maybe catch errros and display them as warnings or non fatal errors in the status.
+  if (!$error && $form->{DUNNING_PDFS_STORAGE} && scalar @{ $form->{DUNNING_PDFS_STORAGE} }) {
+    _store_pdf_to_webdav_and_filemanagement($_->{dunning_id}, $_->{path}, $_->{name}) for @{ $form->{DUNNING_PDFS_STORAGE} };
+  }
+
   if (!$rc) {
     die SL::DB->client->error
   }
@@ -326,9 +351,9 @@ sub _save_dunning {
   my $h_update_ar = prepare_query($form, $dbh, $q_update_ar);
 
   my $q_insert_dunning =
-    qq|INSERT INTO dunning (dunning_id, dunning_config_id, dunning_level, trans_id,
-                            fee,        interest,          transdate,     duedate)
-       VALUES (?, ?,
+    qq|INSERT INTO dunning (id,  dunning_id, dunning_config_id, dunning_level, trans_id,
+                            fee, interest,   transdate,         duedate,       original_invoice_printed)
+       VALUES (?, ?, ?,
                (SELECT dunning_level FROM dunning_config WHERE id = ?),
                ?,
                (SELECT SUM(fee)
@@ -338,7 +363,8 @@ sub _save_dunning {
                  * (SELECT interest_rate FROM dunning_config WHERE id = ?)
                  / 360,
                current_date,
-               current_date + (SELECT payment_terms FROM dunning_config WHERE id = ?))|;
+               current_date + (SELECT payment_terms FROM dunning_config WHERE id = ?),
+               ?)|;
   my $h_insert_dunning = prepare_query($form, $dbh, $q_insert_dunning);
 
   my @invoice_ids;
@@ -366,13 +392,24 @@ sub _save_dunning {
     $send_email       |= $row->{email};
     $print_invoice    |= $row->{print_invoice};
 
+    my ($row_id)       = selectrow_query($form, $dbh, qq|SELECT nextval('id')|);
     my $next_config_id = conv_i($row->{next_dunning_config_id});
     my $invoice_id     = conv_i($row->{invoice_id});
 
-    @values = ($dunning_id,     $next_config_id, $next_config_id,
-               $invoice_id,     $next_config_id, $invoice_id,
-               $next_config_id, $next_config_id);
+    @values = ($row_id,         $dunning_id,     $next_config_id,
+               $next_config_id, $invoice_id,     $next_config_id,
+               $invoice_id,     $next_config_id, $next_config_id,
+               $print_invoice);
     do_statement($form, $h_insert_dunning, $q_insert_dunning, @values);
+
+    RecordLinks->create_links(
+      'dbh'        => $dbh,
+      'mode'       => 'ids',
+      'from_table' => 'ar',
+      'from_ids'   => $invoice_id,
+      'to_table'   => 'dunning',
+      'to_id'      => $row_id,
+    );
   }
   # die this transaction, because for this customer only credit notes are
   # selected ...
@@ -391,7 +428,7 @@ sub _save_dunning {
   $self->print_dunning($myconfig, $form, $dunning_id, $dbh);
 
   if ($print_invoice) {
-    $self->print_original_invoices($myconfig, $form, $_, $dbh) for @invoice_ids;
+    $self->print_original_invoice($myconfig, $form, $dunning_id, $_) for @invoice_ids;
   }
 
   if ($send_email) {
@@ -743,13 +780,13 @@ sub get_dunning {
   }
 
   my %sort_columns = (
-    'dunning_description' => [ qw(dn.dunning_description customername invnumber) ],
-    'customername'        => [ qw(customername invnumber) ],
+    'dunning_description' => [ qw(dn.dunning_description da.dunning_id customername invnumber) ],
+    'customername'        => [ qw(customername da.dunning_id invnumber) ],
     'invnumber'           => [ qw(a.invnumber) ],
     'transdate'           => [ qw(a.transdate a.invnumber) ],
     'duedate'             => [ qw(a.duedate a.invnumber) ],
-    'dunning_date'        => [ qw(dunning_date a.invnumber) ],
-    'dunning_duedate'     => [ qw(dunning_duedate a.invnumber) ],
+    'dunning_date'        => [ qw(dunning_date da.dunning_id a.invnumber) ],
+    'dunning_duedate'     => [ qw(dunning_duedate da.dunning_id a.invnumber) ],
     'salesman'            => [ qw(salesman) ],
     );
 
@@ -760,7 +797,7 @@ sub get_dunning {
   my $query =
     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.interest, dn.dunning_description, dn.dunning_level, da.transdate AS dunning_date,
          da.duedate AS dunning_duedate, da.dunning_id, da.dunning_config_id,
          e2.name AS salesman
        FROM ar a
@@ -971,9 +1008,12 @@ sub print_dunning {
 
   delete $form->{tmpfile};
 
-  push @{ $form->{DUNNING_PDFS} }, $filename;
-  push @{ $form->{DUNNING_PDFS_EMAIL} }, { 'path' => "${spool}/$filename",
-                                           'name'     => $form->get_formname_translation('dunning') . "_${dunning_id}.pdf" };
+  push @{ $form->{DUNNING_PDFS} }        , $filename;
+  push @{ $form->{DUNNING_PDFS_EMAIL} }  , { 'path'       => "${spool}/$filename",
+                                             'name'       => $form->get_formname_translation('dunning') . "_${dunning_id}.pdf" };
+  push @{ $form->{DUNNING_PDFS_STORAGE} }, { 'dunning_id' => $dunning_id,
+                                             'path'       => "${spool}/$filename",
+                                             'name'       => $form->get_formname_translation('dunning') . "_${dunning_id}.pdf" };
 
   my $employee_id = ($::instance_conf->get_dunning_creator eq 'invoice_employee') ?
                       $form->{employee_id}                                        :
@@ -988,6 +1028,8 @@ sub print_dunning {
   }
   $form->{attachment_filename} = $form->get_formname_translation($form->{attachment_type}) . "_${dunning_id}.pdf";
   $form->{attachment_id} = $form->{invoice_id};
+
+  # this generates the file in the spool directory
   $form->parse_template($myconfig);
 
   $main::lxdebug->leave_sub();
@@ -1079,16 +1121,20 @@ sub print_invoice_for_fees {
 
   map { delete $form->{$_} } grep /^[a-z_]+_\d+$/, keys %{ $form };
 
-  $form->{attachment_filename} = $form->get_formname_translation('dunning_invoice') . "_${dunning_id}.pdf";
+  my $attachment_filename      = $form->get_formname_translation('dunning_invoice') . "_${dunning_id}.pdf";
+  $form->{attachment_filename} = $attachment_filename;
   $form->{attachment_type}     = "dunning";
-  $form->{attachment_id}       = $form->{invoice_id};
+  $form->{attachment_id}       = $invoice_id;
   $form->parse_template($myconfig);
 
   restore_form($saved_form);
 
-  push @{ $form->{DUNNING_PDFS} }, $filename;
-  push @{ $form->{DUNNING_PDFS_EMAIL} }, { 'filename' => "${spool}/$filename",
-                                           'name'     => "dunning_invoice_${dunning_id}.pdf" };
+  push @{ $form->{DUNNING_PDFS} },         $filename;
+  push @{ $form->{DUNNING_PDFS_EMAIL} },   { 'path'       => "${spool}/$filename",
+                                             'name'       => $attachment_filename };
+  push @{ $form->{DUNNING_PDFS_STORAGE} }, { 'dunning_id' => $dunning_id,
+                                             'path'       => "${spool}/$filename",
+                                             'name'       => $attachment_filename };
 
   $main::lxdebug->leave_sub();
 }
@@ -1114,8 +1160,8 @@ sub set_customer_cvars {
 
 }
 
-sub print_original_invoices {
-  my ($self, $myconfig, $form, $invoice_id) = @_;
+sub print_original_invoice {
+  my ($self, $myconfig, $form, $dunning_id, $invoice_id) = @_;
   # get one invoice as object and print to pdf
   my $invoice = SL::DB::Invoice->new(id => $invoice_id)->load;
 
@@ -1128,6 +1174,9 @@ sub print_original_invoices {
   $print_form->{media}    = 'file';
   # no language override, should always be the object's language
   $invoice->flatten_to_form($print_form, format_amounts => 1);
+  for my $i (1 .. $print_form->{rowcount}) {
+    $print_form->{"sellprice_$i"} = $print_form->{"fxsellprice_$i"};
+  }
   $print_form->prepare_for_printing;
 
   my $filename = SL::Helper::CreatePDF->create_pdf(
@@ -1151,11 +1200,58 @@ sub print_original_invoices {
   my $saved_reicpient_locale = $form->{recipient_locale};
   $form->{recipient_locale}  = $invoice->language;
 
-  push @{ $form->{DUNNING_PDFS} }, $file_name;
-  push @{ $form->{DUNNING_PDFS_EMAIL} }, { 'path' => "${spool}/$file_name",
-                                           'name' => $form->get_formname_translation('invoice') . "_" . $invoice->invnumber . ".pdf" };
+  my $attachment_filename    = $form->get_formname_translation('invoice') . "_" . $invoice->invnumber . ".pdf";
+
+  push @{ $form->{DUNNING_PDFS} },         $file_name;
+  push @{ $form->{DUNNING_PDFS_EMAIL} },   { 'path'       => "${spool}/$file_name",
+                                             'name'       => $attachment_filename };
+  push @{ $form->{DUNNING_PDFS_STORAGE} }, { 'dunning_id' => $dunning_id,
+                                             'path'       => "${spool}/$file_name",
+                                             'name'       => $attachment_filename };
 
   $form->{recipient_locale}  = $saved_reicpient_locale;
 }
 
+sub _store_pdf_to_webdav_and_filemanagement {
+  my ($dunning_id, $path, $name) =@_;
+
+  my @errors;
+
+  if ($::instance_conf->get_doc_storage) {
+    eval {
+      SL::File->save(
+        object_id   => $dunning_id,
+        object_type => 'dunning',
+        mime_type   => 'application/pdf',
+        source      => 'created',
+        file_type   => 'document',
+        file_name   => $name,
+        file_path   => $path,
+      );
+      1;
+    } or do {
+      push @errors, $::locale->text('Storing PDF in storage backend failed: #1', $@);
+    };
+  }
+
+  if ($::instance_conf->get_webdav_documents) {
+    eval {
+      my $webdav = SL::Webdav->new(
+        type     => 'dunning',
+        number   => $dunning_id,
+      );
+      my $webdav_file = SL::Webdav::File->new(
+        webdav   => $webdav,
+        filename => $name,
+      );
+      $webdav_file->store(file => $path);
+    } or do {
+      push @errors, $::locale->text('Storing PDF to webdav folder failed: #1', $@);
+    };
+  }
+
+  return @errors;
+}
+
+
 1;