Kontoauszug verbuchen: Neuen Skonto-Typ
authorJan Büren <jan@kivitendo.de>
Tue, 12 Mar 2019 10:20:29 +0000 (11:20 +0100)
committerJan Büren <jan@kivitendo.de>
Tue, 12 Mar 2019 10:20:29 +0000 (11:20 +0100)
Eingabe eines freien Skonto-Betrags in der Maske aktiv.
Ferner Anzeigen des Skonto-Betrags bei with_skonto_pt, damit
der Anwender besser visuell unterstützt wird.

SL/Controller/BankTransaction.pm
SL/DB/Helper/Payment.pm
js/kivi.BankTransaction.js
templates/webpages/bank_transactions/_payment_suggestion.html

index 60a558e..638da64 100644 (file)
@@ -627,12 +627,25 @@ sub save_single_bank_transaction {
         };
       }
 
-      my $payment_type;
+      my ($payment_type, $free_skonto_amount);
       if ( defined $::form->{invoice_skontos}->{"$bt_id"} ) {
         $payment_type = shift(@{ $::form->{invoice_skontos}->{"$bt_id"} });
       } else {
         $payment_type = 'without_skonto';
-      };
+      }
+
+      if ($payment_type eq 'free_skonto') {
+        # parse user input > 0
+        if ($::form->parse_amount(\%::myconfig, $::form->{"free_skonto_amount"}->{"$bt_id"}{$invoice->id}) > 0) {
+          $free_skonto_amount = $::form->parse_amount(\%::myconfig, $::form->{"free_skonto_amount"}->{"$bt_id"}{$invoice->id});
+        } else {
+          return {
+            %data,
+            result  => 'error',
+            message => $::locale->text("Free skonto amount has to be a positive number."),
+          };
+        }
+      }
     # pay invoice
     # TODO rewrite this: really booked amount should be a return value of Payment.pm
     # also this controller shouldnt care about how to calc skonto. we simply delegate the
@@ -648,6 +661,7 @@ sub save_single_bank_transaction {
 
     # get the right direction for the payment bookings (all amounts < 0 are stornos, credit notes or negative ap)
     $amount_for_payment *= -1 if $invoice->amount < 0;
+    $free_skonto_amount *= -1 if ($free_skonto_amount && $invoice->amount < 0);
     # get the right direction for the bank transaction
     $amount_for_booking *= $sign;
 
@@ -655,12 +669,13 @@ sub save_single_bank_transaction {
 
     # ... and then pay the invoice
     my @acc_ids = $invoice->pay_invoice(chart_id => $bank_transaction->local_bank_account->chart_id,
-                          trans_id     => $invoice->id,
-                          amount       => $amount_for_payment,
-                          payment_type => $payment_type,
-                          source       => $source,
-                          memo         => $memo,
-                          transdate    => $bank_transaction->valutadate->to_kivitendo);
+                          trans_id      => $invoice->id,
+                          amount        => $amount_for_payment,
+                          payment_type  => $payment_type,
+                          source        => $source,
+                          memo          => $memo,
+                          skonto_amount => $free_skonto_amount,
+                          transdate     => $bank_transaction->valutadate->to_kivitendo);
     # ... and record the origin via BankTransactionAccTrans
     if (scalar(@acc_ids) < 2) {
       return {
index dced3d7..55f9029 100644 (file)
@@ -461,6 +461,8 @@ sub percent_skonto {
 
 sub amount_less_skonto {
   # amount that has to be paid if skonto applies, always return positive rounded values
+  # no, rare case, but credit_notes and negative ap have negative amounts
+  # and therefore this comment may be misguiding
   # the result is rounded so we can directly compare it with the user input
   my $self = shift;
 
@@ -650,24 +652,26 @@ sub get_payment_select_options_for_bank_transaction {
 
 
   # CAVEAT template code expects with_skonto_pt at position 1 for visual help
+  # due to skonto_charts, we cannot offer skonto for credit notes and neg ap
+  my $skontoable = $self->amount > 0 ? 1 : 0;
   my @options;
   if(!$self->skonto_date) {
     push(@options, { payment_type => 'without_skonto', display => t8('without skonto'), selected => 1 });
     # wrong call to presenter or not implemented? disabled option is ignored
     # push(@options, { payment_type => 'with_skonto_pt', display => t8('with skonto acc. to pt'), disabled => 1 });
-    push(@options, { payment_type => 'free_skonto', display => t8('free skonto') });
+    push(@options, { payment_type => 'free_skonto', display => t8('free skonto') }) if $skontoable;
     return @options;
   }
   # valid skonto date, check if skonto is preferred
   my $bt = SL::DB::BankTransaction->new(id => $bt_id)->load;
   if ($self->skonto_date && $self->within_skonto_period($bt->transdate)) {
     push(@options, { payment_type => 'without_skonto', display => t8('without skonto') });
-    push(@options, { payment_type => 'with_skonto_pt', display => t8('with skonto acc. to pt'), selected => 1 });
+    push(@options, { payment_type => 'with_skonto_pt', display => t8('with skonto acc. to pt'), selected => 1 }) if $skontoable;
   } else {
     push(@options, { payment_type => 'without_skonto', display => t8('without skonto') , selected => 1 });
-    push(@options, { payment_type => 'with_skonto_pt', display => t8('with skonto acc. to pt')});
+    push(@options, { payment_type => 'with_skonto_pt', display => t8('with skonto acc. to pt')}) if $skontoable;
   }
-  push(@options, { payment_type => 'free_skonto', display => t8('free skonto') });
+  push(@options, { payment_type => 'free_skonto', display => t8('free skonto') }) if $skontoable;
   return @options;
 }
 
@@ -783,8 +787,9 @@ This function deals with all the acc_trans entries and also updates paid and dat
 The params C<transdate> and C<chart_id> are mandantory.
 If the default payment ('without_skonto') is used the param amount is also
 mandantory.
-If the payment type ('free_skonto') is used the number param skonto_amount
-is as well mandantory and has to be lower than the currently open invoice amount.
+If the payment type ('free_skonto') is used the number params skonto_amount and amount
+are as well mandantory and need to be positive. Furthermore the skonto amount has
+to be lower than the payment or open invoice amount.
 
 Transdate can either be a date object or a date string.
 Chart_id is the id of the payment booking chart.
@@ -1131,6 +1136,12 @@ Returns 1 if record uses a different currency, 0 if the default currency is used
 when looking at open amount, maybe consider that there may already be queued
 amounts in SEPA Export
 
+=item * C<skonto_charts>
+
+Cannot handle negative skonto amounts, will always calculate the skonto amount
+for credit notes or negative ap transactions with a positive sign.
+
+
 =back
 
 =head1 AUTHOR
index 0c13463..a0a0f0f 100644 (file)
@@ -140,4 +140,20 @@ namespace('kivi.BankTransaction', function(ns) {
       }
     });
   };
+  ns.update_skonto = function(caller, bt_id, prop_id, formatted_amount_with_skonto_pt) {
+    if (caller.value === 'free_skonto') {
+      $('#free_skonto_amount_' + bt_id + '_' + prop_id).val("");
+      $('#free_skonto_amount_' + bt_id + '_' + prop_id).prop('disabled', false);
+      $('#free_skonto_amount_' + bt_id + '_' + prop_id).focus();
+    }
+    if (caller.value === 'without_skonto') {
+      $('#free_skonto_amount_' + bt_id + '_' + prop_id).val(kivi.format_amount(0,2));
+      $('#free_skonto_amount_' + bt_id + '_' + prop_id).prop('disabled', true);
+    }
+    if (caller.value === 'with_skonto_pt') {
+      $('#free_skonto_amount_' + bt_id + '_' + prop_id).val(formatted_amount_with_skonto_pt);
+      $('#free_skonto_amount_' + bt_id + '_' + prop_id).prop('disabled', true);
+    }
+  };
+
 });
index 20a437a..8f2e736 100644 (file)
@@ -2,8 +2,11 @@
 <span id="[% HTML.escape(bt_id) %].[% HTML.escape(invoice.id) %]" data-invoice-amount="[% HTML.escape(invoice.open_amount * 1) %]">
  [% P.hidden_tag("invoice_ids." _ bt_id _ "[]", invoice.id) %]
  [% SELECT_OPTIONS = invoice.get_payment_select_options_for_bank_transaction(bt_id) %]
+ [% formatted_skonto_amount_selected = SELECT_OPTIONS.1.selected ? LxERP.format_amount(invoice.skonto_amount, 2) : LxERP.format_amount(0, 2) %]
+ [% formatted_skonto_amount          = LxERP.format_amount(invoice.skonto_amount, 2) %]
  [% LxERP.t8("Invno.") %]: [% HTML.escape(invoice.invnumber) %]</br>
  [% LxERP.t8("Open amount") %]: [% LxERP.format_amount(invoice.open_amount, 2) %]</br>
- [% P.select_tag("invoice_skontos." _ bt_id _ "[]", SELECT_OPTIONS, value_key="payment_type", title_key="display") %]
+ [% P.select_tag("invoice_skontos." _ bt_id _ "[]", SELECT_OPTIONS, value_key="payment_type", title_key="display", onChange="kivi.BankTransaction.update_skonto(this, " _ bt_id _ ", " _ invoice.id _ ", '$formatted_skonto_amount')"  ) %]</br>
+ [% LxERP.t8("Skonto amount") %]: [% P.input_tag("free_skonto_amount." _ bt_id _ "." _ invoice.id _ "", "$formatted_skonto_amount_selected", default=0, style=style, disabled=1, size=4, class='numeric') %]
  [% P.link_tag("#", "x", onclick="kivi.BankTransaction.delete_invoice(" _ bt_id _ "," _ invoice.id _ ")") %]
 </span>