|  | package SL::DB::Helper::Payment;
 | 
  
    |  | 
 | 
  
    |  | use strict;
 | 
  
    |  | 
 | 
  
    |  | use parent qw(Exporter);
 | 
  
    |  | our @EXPORT = qw(pay_invoice);
 | 
  
    |  | our @EXPORT_OK = qw(skonto_date amount_less_skonto within_skonto_period percent_skonto reference_account open_amount skonto_amount valid_skonto_amount validate_payment_type get_payment_select_options_for_bank_transaction forex _skonto_charts_and_tax_correction get_exchangerate_for_bank_transaction get_exchangerate _add_bank_fx_fees);
 | 
  
    |  | our %EXPORT_TAGS = (
 | 
  
    |  |   "ALL" => [@EXPORT, @EXPORT_OK],
 | 
  
    |  | );
 | 
  
    |  | 
 | 
  
    |  | require SL::DB::Chart;
 | 
  
    |  | 
 | 
  
    |  | use Carp;
 | 
  
    |  | use Data::Dumper;
 | 
  
    |  | use DateTime;
 | 
  
    |  | use List::Util qw(sum);
 | 
  
    |  | use Params::Validate qw(:all);
 | 
  
    |  | 
 | 
  
    |  | use SL::DATEV qw(:CONSTANTS);
 | 
  
    |  | use SL::DB::Exchangerate;
 | 
  
    |  | use SL::DB::Currency;
 | 
  
    |  | use SL::HTML::Util;
 | 
  
    |  | use SL::Locale::String qw(t8);
 | 
  
    |  | 
 | 
  
    |  | #
 | 
  
    |  | # Public functions not exported by default
 | 
  
    |  | #
 | 
  
    |  | 
 | 
  
    |  | sub pay_invoice {
 | 
  
    |  |   my ($self, %params) = @_;
 | 
  
    |  |   # todo named params
 | 
  
    |  |   require SL::DB::Tax;
 | 
  
    |  | 
 | 
  
    |  |   my $is_sales = ref($self) eq 'SL::DB::Invoice';
 | 
  
    |  |   my $mult = $is_sales ? 1 : -1;  # multiplier for getting the right sign depending on ar/ap
 | 
  
    |  |   my @new_acc_ids;
 | 
  
    |  |   my $paid_amount = 0; # the amount that will be later added to $self->paid, should be in default currency
 | 
  
    |  | 
 | 
  
    |  |   # default values if not set
 | 
  
    |  |   $params{payment_type} = 'without_skonto' unless $params{payment_type};
 | 
  
    |  |   validate_payment_type($params{payment_type});
 | 
  
    |  | 
 | 
  
    |  |   # check for required parameters and optional params depending on payment_type
 | 
  
    |  |   Common::check_params(\%params, qw(chart_id transdate amount));
 | 
  
    |  |   Common::check_params(\%params, qw(bt_id)) unless $params{payment_type} eq 'without_skonto';
 | 
  
    |  | 
 | 
  
    |  |   # three valid cases, test logical params in depth, before proceeding ...
 | 
  
    |  |   if ( $params{'payment_type'} eq 'without_skonto' && abs($params{'amount'}) < 0) {
 | 
  
    |  |     croak "invalid amount for payment_type 'without_skonto': $params{'amount'}\n";
 | 
  
    |  |   } elsif ($params{'payment_type'} eq 'free_skonto') {
 | 
  
    |  |     # we dont like too much automagic for this payment type.
 | 
  
    |  |     # we force caller input for amount and skonto amount
 | 
  
    |  |     Common::check_params(\%params, qw(skonto_amount));
 | 
  
    |  |     # secondly we dont want to handle credit notes and purchase credit notes
 | 
  
    |  |     croak("Cannot use 'free skonto' for credit or debit notes") if ($params{amount} < 0 || $params{skonto_amount} <= 0);
 | 
  
    |  |     # both amount have to be rounded
 | 
  
    |  |     $params{skonto_amount} = _round($params{skonto_amount});
 | 
  
    |  |     $params{amount}        = _round($params{amount});
 | 
  
    |  |     # lastly skonto_amount has to be smaller or equal than the open invoice amount
 | 
  
    |  |     if ($params{skonto_amount} > _round($self->open_amount)) {
 | 
  
    |  |       croak("Skonto amount:" . $params{skonto_amount} . " |