Dateimanagement: Download-Aktion: Version richtig interpretieren
[kivitendo-erp.git] / SL / DN.pm
index dd4d61a..460d231 100644 (file)
--- a/SL/DN.pm
+++ b/SL/DN.pm
@@ -111,7 +111,8 @@ sub _save_config {
                  $form->{"template_$i"}, $form->{"fee_$i"}, $form->{"interest_rate_$i"},
                  $form->{"active_$i"} ? 't' : 'f', $form->{"auto_$i"} ? 't' : 'f', $form->{"email_$i"} ? 't' : 'f',
                  $form->{"email_attachment_$i"} ? 't' : 'f', conv_i($form->{"payment_terms_$i"}), conv_i($form->{"terms_$i"}),
-                 $form->{"create_invoices_for_fees_$i"} ? 't' : 'f');
+                 $form->{"create_invoices_for_fees_$i"} ? 't' : 'f',
+                 $form->{"print_original_invoice_$i"} ? 't' : 'f');
       if ($form->{"id_$i"}) {
         $query =
           qq|UPDATE dunning_config SET
@@ -120,7 +121,8 @@ sub _save_config {
                template = ?, fee = ?, interest_rate = ?,
                active = ?, auto = ?, email = ?,
                email_attachment = ?, payment_terms = ?, terms = ?,
-               create_invoices_for_fees = ?
+               create_invoices_for_fees = ?,
+               print_original_invoice = ?
              WHERE id = ?|;
         push(@values, conv_i($form->{"id_$i"}));
       } else {
@@ -128,8 +130,9 @@ sub _save_config {
           qq|INSERT INTO dunning_config
                (dunning_level, dunning_description, email_subject, email_body,
                 template, fee, interest_rate, active, auto, email,
-                email_attachment, payment_terms, terms, create_invoices_for_fees)
-             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|;
+                email_attachment, payment_terms, terms, create_invoices_for_fees,
+                print_original_invoice)
+             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|;
       }
       do_query($form, $dbh, $query, @values);
     }
@@ -189,7 +192,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);
@@ -198,6 +202,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);
@@ -205,6 +211,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();
@@ -268,6 +275,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,
@@ -323,9 +339,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)
+       VALUES (?, ?, ?,
                (SELECT dunning_level FROM dunning_config WHERE id = ?),
                ?,
                (SELECT SUM(fee)
@@ -343,6 +359,16 @@ sub _save_dunning {
   my ($send_email, $print_invoice) = (0, 0);
 
   foreach my $row (@{ $rows }) {
+    if ($row->{credit_note}) {
+      my $i = $row->{row};
+      %{ $form->{LIST_CREDIT_NOTES}{$row->{customer_id}}{$row->{invoice_id}} } = (
+        open_amount => $form->{"open_amount_$i"},
+        amount      => $form->{"amount_$i"},
+        invnumber   => $form->{"invnumber_$i"},
+        invdate     => $form->{"invdate_$i"},
+      );
+      next;
+    }
     push @invoice_ids, $row->{invoice_id};
     $next_dunning_config_id = $row->{next_dunning_config_id};
     $customer_id            = $row->{customer_id};
@@ -353,14 +379,27 @@ 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);
     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 ...
+  return unless $customer_id;
 
   $h_update_ar->finish();
   $h_insert_dunning->finish();
@@ -577,6 +616,7 @@ sub get_invoices {
   if (!$form->{l_include_direct_debit}) {
     $where .= qq| AND NOT COALESCE(a.direct_debit, FALSE) |;
   }
+  my $paid = ($form->{l_include_credit_notes}) ? "WHERE (a.paid <> a.amount)" : "WHERE (a.paid < a.amount)";
 
   $query =
     qq|SELECT
@@ -597,7 +637,7 @@ sub get_invoices {
 
          nextcfg.dunning_description AS next_dunning_description,
          nextcfg.id AS next_dunning_config_id,
-         nextcfg.terms, nextcfg.active, nextcfg.email
+         nextcfg.terms, nextcfg.active, nextcfg.email, nextcfg.print_original_invoice
 
        FROM ar a
 
@@ -625,9 +665,8 @@ sub get_invoices {
          WHERE (d2.trans_id      = a.id)
            AND (d2.dunning_level = cfg.dunning_level)
        ))
-
-       WHERE (a.paid < a.amount)
-         AND (a.duedate < current_date)
+        $paid
+        AND (a.duedate < current_date)
 
        $where
 
@@ -638,7 +677,7 @@ sub get_invoices {
 
   while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
     next if ($ref->{pastdue} < $ref->{terms});
-
+    $ref->{credit_note} = 1 if ($ref->{amount} < 0 && $form->{l_include_credit_notes});
     $ref->{interest} = $form->round_amount($ref->{interest}, 2);
     push(@{ $form->{DUNNINGS} }, $ref);
   }
@@ -739,12 +778,12 @@ sub get_dunning {
 
   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} };
+  my $sortorder = join ', ', map { "$_ $sortdir" } (@{ $sort_columns{$sortkey} }, 'da.dunning_id');
 
   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
@@ -866,6 +905,14 @@ sub print_dunning {
   }
   $sth->finish();
 
+  # if we have some credit notes to add, do a safety check on the first customer id
+  # and add one entry for each credit note
+  if ($form->{LIST_CREDIT_NOTES} && $form->{LIST_CREDIT_NOTES}->{$form->{TEMPLATE_ARRAYS}->{"dn_customer_id"}[0]}) {
+    my $first_customer_id = $form->{TEMPLATE_ARRAYS}->{"dn_customer_id"}[0];
+    while ( my ($cred_id, $value) = each(%{ $form->{LIST_CREDIT_NOTES}->{$first_customer_id} } ) ) {
+      map { push @{ $form->{TEMPLATE_ARRAYS}->{"dn_$_"} }, $value->{$_} } keys %{ $value };
+    }
+  }
   $query =
     qq|SELECT
          c.id AS customer_id, c.name,         c.street,       c.zipcode,   c.city,
@@ -915,8 +962,16 @@ sub print_dunning {
   $form->{interest_rate}     = $form->format_amount($myconfig, $ref->{interest_rate} * 100);
   $form->{fee}               = $form->format_amount($myconfig, $ref->{fee}, 2);
   $form->{total_interest}    = $form->format_amount($myconfig, $form->round_amount($ref->{total_interest}, 2), 2);
-  $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);
+  my $total_open_amount      = $ref->{total_open_amount};
+  if ($form->{l_include_credit_notes}) {
+    # a bit stupid, but redo calc because of credit notes
+    $total_open_amount      = 0;
+    foreach my $amount (@{ $form->{TEMPLATE_ARRAYS}->{dn_open_amount} }) {
+      $total_open_amount += $form->parse_amount($myconfig, $amount, 2);
+    }
+  }
+  $form->{total_open_amount} = $form->format_amount($myconfig, $form->round_amount($total_open_amount, 2), 2);
+  $form->{total_amount}      = $form->format_amount($myconfig, $form->round_amount($ref->{fee} + $ref->{total_interest} + $total_open_amount, 2), 2);
 
   $::form->format_dates($output_dateformat, $output_longdates,
     qw(dn_dunning_date dn_dunning_duedate dn_transdate dn_duedate
@@ -1096,12 +1151,20 @@ 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(
-                   template  => 'invoice.tex',
-                   variables => $print_form,
-                   return    => 'file_name',
+                   template               => 'invoice.tex',
+                   variables              => $print_form,
+                   return                 => 'file_name',
+                   variable_content_types => {
+                     longdescription => 'html',
+                     partnotes       => 'html',
+                     notes           => 'html',
+                   },
   );
 
   my $spool       = $::lx_office_conf{paths}->{spool};