Mahnungen: PDF an Drucker schicken: Druckbefehl erst prüfen, dann verwenden
[kivitendo-erp.git] / SL / DN.pm
index aa82aa9..a4eb127 100644 (file)
--- a/SL/DN.pm
+++ b/SL/DN.pm
@@ -51,6 +51,7 @@ use SL::DB::Language;
 use SL::TransNumber;
 use SL::Util qw(trim);
 use SL::DB;
+use SL::Webdav;
 
 use File::Copy;
 
@@ -316,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
   }
@@ -341,7 +352,7 @@ sub _save_dunning {
 
   my $q_insert_dunning =
     qq|INSERT INTO dunning (id,  dunning_id, dunning_config_id, dunning_level, trans_id,
-                            fee, interest,   transdate,         duedate)
+                            fee, interest,   transdate,         duedate,       original_invoice_printed)
        VALUES (?, ?, ?,
                (SELECT dunning_level FROM dunning_config WHERE id = ?),
                ?,
@@ -352,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;
@@ -386,7 +398,8 @@ sub _save_dunning {
 
     @values = ($row_id,         $dunning_id,     $next_config_id,
                $next_config_id, $invoice_id,     $next_config_id,
-               $invoice_id,     $next_config_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(
@@ -415,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) {
@@ -724,6 +737,11 @@ sub get_dunning {
     push(@values, like($form->{$key}));
   }
 
+  if ($form->{dunning_id}) {
+    $where .= qq| AND da.dunning_id = ?|;
+    push(@values, conv_i($form->{dunning_id}));
+  }
+
   if ($form->{dunning_level}) {
     $where .= qq| AND a.dunning_config_id = ?|;
     push(@values, conv_i($form->{dunning_level}));
@@ -767,19 +785,20 @@ 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) ],
+    'dunning_id'          => [ qw(dunning_id a.invnumber) ],
     'salesman'            => [ qw(salesman) ],
     );
 
   my $sortdir   = !defined $form->{sortdir}    ? 'ASC'         : $form->{sortdir} ? 'ASC' : 'DESC';
   my $sortkey   = $sort_columns{$form->{sort}} ? $form->{sort} : 'customername';
-  my $sortorder = join ', ', map { "$_ $sortdir" } (@{ $sort_columns{$sortkey} }, 'da.dunning_id');
+  my $sortorder = join ', ', map { "$_ $sortdir" } @{ $sort_columns{$sortkey} };
 
   my $query =
     qq|SELECT a.id, a.ordnumber, a.invoice, a.transdate, a.invnumber, a.amount, a.language_id,
@@ -830,10 +849,10 @@ sub melt_pdfs {
       $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;
 
+    $::locale->with_raw_io($out, sub { $out->print($_) while <$in> });
+
   } else {
     my $dunning_filename = $form->get_formname_translation('dunning');
     print qq|Content-Type: Application/PDF\n| .
@@ -859,7 +878,7 @@ sub print_dunning {
 
   $dunning_id =~ s|[^\d]||g;
 
-  my ($language_tc, $output_numberformat, $output_dateformat, $output_longdates, @dunned_invoice_ids);
+  my ($language_tc, $output_numberformat, $output_dateformat, $output_longdates);
   if ($form->{"language_id"}) {
     ($language_tc, $output_numberformat, $output_dateformat, $output_longdates) =
       AM->get_language_details($myconfig, $form, $form->{language_id});
@@ -881,7 +900,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.employee_id,     ar.salesman_id,  ar.id AS dunned_invoice_id,
+         ar.employee_id,     ar.salesman_id,
          (SELECT cu.name FROM currencies cu WHERE cu.id = ar.currency_id) AS curr,
          (SELECT description from department WHERE id = ar.department_id) AS department,
          ar.amount - ar.paid AS open_amount,
@@ -903,7 +922,6 @@ sub print_dunning {
     map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2) } qw(amount netamount paid open_amount fee interest linetotal);
     map { $form->{$_} = $ref->{$_} } keys %$ref;
     map { push @{ $form->{TEMPLATE_ARRAYS}->{"dn_$_"} }, $ref->{$_} } keys %$ref;
-    push @dunned_invoice_ids, $ref->{dunned_invoice_id};
   }
   $sth->finish();
 
@@ -996,9 +1014,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}                                        :
@@ -1017,21 +1038,6 @@ sub print_dunning {
   # this generates the file in the spool directory
   $form->parse_template($myconfig);
 
-  # save dunning pdf in filemanagement for each invoice
-  if ($::instance_conf->get_doc_storage) {
-    foreach my $dunned_invoice_id (@dunned_invoice_ids) {
-      SL::File->save(
-        object_id   => $dunned_invoice_id,
-        object_type => $form->{attachment_type},
-        mime_type   => 'application/pdf',
-        source      => 'created',
-        file_type   => 'document',
-        file_name   => $form->{attachment_filename},
-        file_path   => "${spool}/$filename",
-      );
-    }
-  }
-
   $main::lxdebug->leave_sub();
 }
 
@@ -1129,26 +1135,12 @@ sub print_invoice_for_fees {
 
   restore_form($saved_form);
 
-  push @{ $form->{DUNNING_PDFS} }, $filename;
-  push @{ $form->{DUNNING_PDFS_EMAIL} }, { 'path' => "${spool}/$filename",
-                                           'name' => $attachment_filename };
-
-  # save dunning fee pdf in filemanagement for each dunned invoice
-  if ($::instance_conf->get_doc_storage) {
-    $query                 = qq|SELECT trans_id FROM dunning WHERE dunning_id = ?|;
-    my @dunned_invoice_ids = selectall_array_query($form, $dbh, $query, $dunning_id);
-    foreach my $dunned_invoice_id (@dunned_invoice_ids) {
-      SL::File->save(
-        object_id   => $dunned_invoice_id,
-        object_type => 'dunning',
-        mime_type   => 'application/pdf',
-        source      => 'created',
-        file_type   => 'document',
-        file_name   => $attachment_filename,
-        file_path   => "${spool}/$filename",
-      );
-    }
-  }
+  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();
 }
@@ -1174,8 +1166,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;
 
@@ -1216,25 +1208,56 @@ sub print_original_invoices {
 
   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} },         $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;
 
-  # save original invoice pdf in filemanagement for dunned invoice
   if ($::instance_conf->get_doc_storage) {
-    SL::File->save(
-      object_id   => $invoice_id,
-      object_type => 'dunning',
-      mime_type   => 'application/pdf',
-      source      => 'created',
-      file_type   => 'document',
-      file_name   => $attachment_filename,
-      file_path   => "${spool}/$file_name",
-    );
+    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;