Mahnungen: Mit Rechnung verknüpfen
authorFelix Eichler <felix.eichler@opendynamic.de>
Wed, 19 Sep 2018 10:02:40 +0000 (12:02 +0200)
committerJan Büren <jan@kivitendo.de>
Fri, 12 Feb 2021 06:59:43 +0000 (07:59 +0100)
Erstellte Mahnungen werden mit den gemahnten Rechnungen verknüpft und
unter "Verknüpfte Belege" gelistet.
Außerdem werden Rechnungen über Mahnkosten wiederum zu den zugehörigen
Mahnungen verknüpft.

impl. #7440

SL/Controller/RecordLinks.pm
SL/DB/Dunning.pm
SL/DB/Helper/LinkedRecords.pm
SL/DN.pm
SL/Presenter/ALL.pm
SL/Presenter/Dunning.pm [new file with mode: 0644]
SL/Presenter/Record.pm

index 152fe95..eec3ce2 100644 (file)
@@ -52,6 +52,7 @@ my @link_type_specifics = (
   { title => t8('Email'),                   type => 'email_journal',           model => 'EmailJournal',    number => 'id', description => 'subject', description_title => t8('Subject'), },
   { title => t8('AR Transaction'),          type => 'ar_transaction',          model => 'Invoice',         number => 'invnumber', },
   { title => t8('AP Transaction'),          type => 'ap_transaction',          model => 'PurchaseInvoice', number => 'invnumber', },
+  { title => t8('Dunning'),                 type => 'dunning',                 model => 'Dunning',         number => 'dunning_id', },
 );
 
 my @link_types = map { +{ %link_type_defaults, %{ $_ } } } @link_type_specifics;
index 9be274b..c61bf0f 100644 (file)
@@ -6,10 +6,16 @@ package SL::DB::Dunning;
 use strict;
 
 use SL::DB::MetaSetup::Dunning;
+use SL::DB::Helper::LinkedRecords;
 
 __PACKAGE__->meta->initialize;
 
 # Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
 __PACKAGE__->meta->make_manager_class;
 
+
+sub date {
+  goto &transdate;
+}
+
 1;
index 8b719aa..adc3dac 100644 (file)
@@ -314,6 +314,7 @@ sub sort_linked_records {
                   'SL::DB::Letter'          => sub { $_[0]->letternumber },
                   'SL::DB::ShopOrder'       => sub { $_[0]->shop_ordernumber },
                   'SL::DB::EmailJournal'    => sub { $_[0]->id },
+                  'SL::DB::Dunning'         => sub { $_[0]->dunning_id },
                   UNKNOWN                   => '9999999999999999',
                 );
   my $number_xtor = sub {
@@ -345,6 +346,7 @@ sub sort_linked_records {
               'SL::DB::Letter'          => 200,
               'SL::DB::ShopOrder'       => 250,
               'SL::DB::EmailJournal'    => 300,
+              'SL::DB::Dunning'         => 350,
               UNKNOWN                   => 999,
             );
   my $score_xtor = sub {
index 46ab23a..143998f 100644 (file)
--- a/SL/DN.pm
+++ b/SL/DN.pm
@@ -192,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);
@@ -201,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);
@@ -208,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();
@@ -271,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,
@@ -326,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)
@@ -366,13 +379,23 @@ 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 ...
index 73511b5..aa404de 100644 (file)
@@ -5,6 +5,7 @@ use strict;
 use SL::Presenter::Chart;
 use SL::Presenter::CustomerVendor;
 use SL::Presenter::DeliveryOrder;
+use SL::Presenter::Dunning;
 use SL::Presenter::EscapedText;
 use SL::Presenter::Invoice;
 use SL::Presenter::GL;
@@ -26,6 +27,7 @@ our %presenters = (
   chart                       => 'SL::Presenter::Chart',
   customer_vendor             => 'SL::Presenter::CustomerVendor',
   delivery_order              => 'SL::Presenter::DeliveryOrder',
+  dunning                     => 'SL::Presenter::Dunning',
   escaped_text                => 'SL::Presenter::EscapedText',
   invoice                     => 'SL::Presenter::Invoice',
   gl                          => 'SL::Presenter::GL',
diff --git a/SL/Presenter/Dunning.pm b/SL/Presenter/Dunning.pm
new file mode 100644 (file)
index 0000000..4c8b70c
--- /dev/null
@@ -0,0 +1,30 @@
+package SL::Presenter::Dunning;
+
+use strict;
+
+use SL::Presenter::EscapedText qw(escape is_escaped);
+
+use Exporter qw(import);
+our @EXPORT_OK = qw(dunning);
+
+use Carp;
+
+sub dunning {
+  my ($dunning, $type, %params) = @_;
+
+  $params{display} ||= 'inline';
+
+  croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
+
+  my $invoice = SL::DB::Manager::Invoice->find_by( id => $dunning->trans_id );
+
+  my $text = join '', (
+    $params{no_link} ? '' : '<a href="dn.pl?action=print_dunning&amp;format=pdf&amp;media=screen&amp;dunning_id=' . $dunning->dunning_id . '&amp;language_id=' . $invoice->language_id . '">',
+    escape($dunning->dunning_config->dunning_description),
+    $params{no_link} ? '' : '</a>',
+  );
+
+  is_escaped($text);
+}
+
+1;
index 5890f42..db68fa6 100644 (file)
@@ -67,6 +67,8 @@ sub grouped_record_list {
   $output .= _letter_list(                 $groups{letters},                  %params) if $groups{letters};
   $output .= _email_journal_list(          $groups{email_journals},           %params) if $groups{email_journals};
 
+  $output .= _dunning_list(                $groups{dunnings},                 %params) if $groups{dunnings};
+
   $output  = SL::Presenter->get->render('presenter/record/grouped_record_list', %params, output => $output);
 
   return $output;
@@ -195,6 +197,7 @@ sub _group_records {
     bank_transactions        => sub { (ref($_[0]) eq 'SL::DB::BankTransaction') &&  $_[0]->id                           },
     letters                  => sub { (ref($_[0]) eq 'SL::DB::Letter')          &&  $_[0]->id                           },
     email_journals           => sub { (ref($_[0]) eq 'SL::DB::EmailJournal')    &&  $_[0]->id                           },
+    dunnings                 => sub { (ref($_[0]) eq 'SL::DB::Dunning')                                                 },
   );
 
   my %groups;
@@ -573,7 +576,23 @@ sub _email_journal_list {
     %params,
   );
 }
+sub _dunning_list {
+  my ($list, %params) = @_;
 
+  return record_list(
+    $list,
+    title   => $::locale->text('Dunnings'),
+    type    => 'dunning',
+    columns => [
+      [ $::locale->text('Dunning Level'),   sub { $_[0]->presenter->dunning(display => 'table-cell') } ],
+      [ $::locale->text('Dunning Date'),    'transdate'                                                ],
+      [ $::locale->text('Dunning Duedate'), 'duedate'                                                  ],
+      [ $::locale->text('Total Fees'),      'fee'                                                      ],
+      [ $::locale->text('Interest'),        'interest'                                                 ],
+    ],
+    %params,
+  );
+}
 
 1;