Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision b17ed7c1

Von Jan Büren vor mehr als 2 Jahren hinzugefügt

  • ID b17ed7c107ac1f91bb7072e34354bed12c33ac0f
  • Vorgänger 29360784
  • Nachfolger 293fb807

Payment-Helper: skonto_charts entfernt

Unterschiede anzeigen:

SL/DB/Helper/Payment.pm
4 4

  
5 5
use parent qw(Exporter);
6 6
our @EXPORT = qw(pay_invoice);
7
our @EXPORT_OK = qw(skonto_date skonto_charts amount_less_skonto within_skonto_period percent_skonto reference_account reference_amount open_amount open_percent remaining_skonto_days skonto_amount check_skonto_configuration valid_skonto_amount get_payment_suggestions validate_payment_type open_sepa_transfer_amount get_payment_select_options_for_bank_transaction exchangerate forex _skonto_charts_and_tax_correction);
7
our @EXPORT_OK = qw(skonto_date amount_less_skonto within_skonto_period percent_skonto reference_account reference_amount open_amount open_percent remaining_skonto_days skonto_amount check_skonto_configuration valid_skonto_amount get_payment_suggestions validate_payment_type open_sepa_transfer_amount get_payment_select_options_for_bank_transaction exchangerate forex _skonto_charts_and_tax_correction);
8 8
our %EXPORT_TAGS = (
9 9
  "ALL" => [@EXPORT, @EXPORT_OK],
10 10
);
......
711 711
  return @skonto_charts;
712 712
}
713 713

  
714
sub skonto_charts {
715
  my $self = shift;
716

  
717
  # TODO: use param for amount, may also want to calculate skonto_amounts by
718
  # passing percentage in the future
719

  
720
  my $amount = shift || $self->skonto_amount;
721

  
722
  croak "no amount passed to skonto_charts" unless abs(_round($amount)) >= 0.01;
723

  
724
  # TODO: check whether there are negative values in invoice / acc_trans ... credited items
725

  
726
  # don't check whether skonto applies, because user may want to override this
727
  # return undef unless $self->percent_skonto;
728

  
729
  my $is_sales = ref($self) eq 'SL::DB::Invoice';
730

  
731
  my $mult = $is_sales ? 1 : -1;  # multiplier for getting the right sign
732

  
733
  my @skonto_charts;  # resulting array with all income/expense accounts that have to be corrected
734

  
735
  # calculate effective skonto (percentage) in difference_as_skonto mode
736
  # only works if there are no negative acc_trans values
737
  my $effective_skonto_rate = $amount ? $amount / $self->amount : 0;
738

  
739
  # checks:
740
  my $total_skonto_amount  = 0;
741
  my $total_rounding_error = 0;
742

  
743
  my $reference_ARAP_amount = 0;
744

  
745
  # my $transactions = $self->transactions;
746
  foreach my $transaction (@{ $self->transactions }) {
747
    # find all transactions with an AR_amount or AP_amount link
748
    $transaction->{chartlinks} = { map { $_ => 1 } split(m/:/, $transaction->{chart_link}) };
749
    # second condition is that we can determine an automatic Skonto account for each AR_amount entry
750

  
751
    if ( ( $is_sales && $transaction->{chartlinks}->{AR_amount} ) or ( !$is_sales && $transaction->{chartlinks}->{AP_amount}) ) {
752
        # $reference_ARAP_amount += $transaction->{amount} * $mult;
753

  
754
        # quick hack that works around problem of non-unique tax keys in SKR04
755
        # ? use tax_id in acc_trans
756
        my $tax = SL::DB::Manager::Tax->get_first( where => [id => $transaction->{tax_id}]);
757
        croak "no tax for taxkey " . $transaction->{taxkey} unless ref $tax;
758

  
759
        if ( $is_sales ) {
760
          die t8('no skonto_chart configured for taxkey #1 : #2 : #3', $transaction->{taxkey} , $tax->taxdescription , $tax->rate*100) unless ref $tax->skonto_sales_chart;
761
        } else {
762
          die t8('no skonto_chart configured for taxkey #1 : #2 : #3', $transaction->{taxkey} , $tax->taxdescription , $tax->rate*100) unless ref $tax->skonto_purchase_chart;
763
        };
764

  
765
        my $skonto_amount_unrounded;
766

  
767
        my $skonto_percent_abs = $self->amount ? abs($transaction->amount * (1 + $tax->rate) * 100 / $self->amount) : 0;
768

  
769
        my $transaction_amount = abs($transaction->{amount} * (1 + $tax->rate));
770
        my $transaction_skonto_percent = abs($transaction_amount/$self->amount); # abs($transaction->{amount} * (1 + $tax->rate));
771

  
772

  
773
        $skonto_amount_unrounded   = abs($amount * $transaction_skonto_percent);
774
        my $skonto_amount_rounded  = _round($skonto_amount_unrounded);
775
        my $rounding_error         = $skonto_amount_unrounded - $skonto_amount_rounded;
776
        my $rounded_rounding_error = _round($rounding_error);
777

  
778
        $total_rounding_error += $rounding_error;
779
        $total_skonto_amount  += $skonto_amount_rounded;
780

  
781
        my $rec = {
782
          # skonto_percent_abs: relative part of amount + tax to the total invoice amount
783
          'skonto_percent_abs'     => $skonto_percent_abs,
784
          'chart_id'               => $is_sales ? $tax->skonto_sales_chart->id : $tax->skonto_purchase_chart->id,
785
          'skonto_amount'          => $skonto_amount_rounded,
786
          # 'rounding_error'         => $rounding_error,
787
          # 'rounded_rounding_error' => $rounded_rounding_error,
788
        };
789

  
790
        push @skonto_charts, $rec;
791
      }
792
  }
793

  
794
  # if the rounded sum of all rounding_errors reaches 0.01 this sum is
795
  # subtracted from the largest skonto_amount
796
  my $rounded_total_rounding_error = abs(_round($total_rounding_error));
797

  
798
  if ( $rounded_total_rounding_error > 0 ) {
799
    my $highest_amount_pos = 0;
800
    my $highest_amount = 0;
801
    my $i = -1;
802
    foreach my $ref ( @skonto_charts ) {
803
      $i++;
804
      if ( $ref->{skonto_amount} > $highest_amount ) {
805
        $highest_amount     = $ref->{skonto_amount};
806
        $highest_amount_pos = $i;
807
      };
808
    };
809
    $skonto_charts[$i]->{skonto_amount} -= $rounded_total_rounding_error;
810
  };
811

  
812
  return @skonto_charts;
813
};
814

  
815

  
816 714
sub within_skonto_period {
817 715
  my $self = shift;
818 716
  my $dateref = shift || DateTime->now->truncate( to => 'day' );

Auch abrufbar als: Unified diff