Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 665741c4

Von Jan Büren vor fast 6 Jahren hinzugefügt

  • ID 665741c4bc6d05d6092a76383c1a444a3507921e
  • Vorgänger 07181f33
  • Nachfolger c301c2b3

BankTransaction: save_single_bank_transaction API-Änderung

S.a. POD und devel-Liste
Testfälle angepasst

Unterschiede anzeigen:

SL/Controller/BankTransaction.pm
558 558

  
559 559
  my $bank_transaction = $data{bank_transaction};
560 560

  
561
  # see pod
562
  if (@{ $bank_transaction->linked_invoices } || $bank_transaction->invoice_amount != 0) {
563
        return {
564
          %data,
565
          result  => 'error',
566
          message => $::locale->text("Bank transaction with id #1 has already been linked to one or more record and/or some amount is already assigned.", $bank_transaction->id),
567
        };
568
      }
569 561
  my (@warnings);
570 562

  
571 563
  my $worker = sub {
572 564
    my $bt_id                 = $data{bank_transaction_id};
573 565
    my $sign                  = $bank_transaction->amount < 0 ? -1 : 1;
574 566
    my $amount_of_transaction = $sign * $bank_transaction->amount;
567
    my $assigned_amount       = $sign * $bank_transaction->invoice_amount;
568
    my $not_assigned_amount   = $amount_of_transaction - $assigned_amount;
575 569
    my $payment_received      = $bank_transaction->amount > 0;
576 570
    my $payment_sent          = $bank_transaction->amount < 0;
577 571

  
572
    croak("No amount left to assign") if ($not_assigned_amount <= 0);
578 573

  
579 574
    foreach my $invoice_id (@{ $params{invoice_ids} }) {
580 575
      my $invoice = SL::DB::Manager::Invoice->find_by(id => $invoice_id) || SL::DB::Manager::PurchaseInvoice->find_by(id => $invoice_id);
......
634 629
      } else {
635 630
        $payment_type = 'without_skonto';
636 631
      };
637

  
638

  
639
      # pay invoice or go to the next bank transaction if the amount is not sufficiently high
640
      if ($invoice->open_amount <= $amount_of_transaction && $n_invoices < $max_invoices) {
641
        my $open_amount = ($payment_type eq 'with_skonto_pt'?$invoice->amount_less_skonto:$invoice->open_amount);
642
        # first calculate new bank transaction amount ...
643
        if ($invoice->is_sales) {
644
          $amount_of_transaction -= $sign * $open_amount;
645
          $bank_transaction->invoice_amount($bank_transaction->invoice_amount + $open_amount);
646
        } else {
647
          $amount_of_transaction += $sign * $open_amount;
648
          $bank_transaction->invoice_amount($bank_transaction->invoice_amount - $open_amount);
649
        }
650
        # ... and then pay the invoice
651
        my @acc_ids = $invoice->pay_invoice(chart_id => $bank_transaction->local_bank_account->chart_id,
652
                              trans_id     => $invoice->id,
653
                              amount       => $open_amount,
654
                              payment_type => $payment_type,
655
                              source       => $source,
656
                              memo         => $memo,
657
                              transdate    => $bank_transaction->transdate->to_kivitendo);
658
        # ... and record the origin via BankTransactionAccTrans
659
        if (scalar(@acc_ids) != 2) {
660
          return {
661
            %data,
662
            result  => 'error',
663
            message => $::locale->text("Unable to book transactions for bank purpose #1", $bank_transaction->purpose),
664
          };
665
        }
666
        foreach my $acc_trans_id (@acc_ids) {
667
            my $id_type = $invoice->is_sales ? 'ar' : 'ap';
668
            my  %props_acc = (
669
              acc_trans_id        => $acc_trans_id,
670
              bank_transaction_id => $bank_transaction->id,
671
              $id_type            => $invoice->id,
672
            );
673
            SL::DB::BankTransactionAccTrans->new(%props_acc)->save;
674
        }
675

  
676

  
677
      } else {
678
      # use the whole amount of the bank transaction for the invoice, overpay the invoice if necessary
679

  
680
        # $invoice->open_amount     is negative for credit_notes
681
        # $bank_transaction->amount is negative for outgoing transactions
682
        # so $amount_of_transaction is negative but needs positive
683
        # $invoice->open_amount may be negative for ap_transaction but may be positiv for negative ap_transaction
684
        # if $invoice->open_amount is negative $bank_transaction->amount is positve
685
        # if $invoice->open_amount is positive $bank_transaction->amount is negative
686
        # but amount of transaction is for both positive
687

  
688
        $amount_of_transaction *= -1 if ($invoice->amount < 0);
689

  
690
        # if we have a skonto case - the last invoice needs skonto
691
        $amount_of_transaction = $invoice->amount_less_skonto if ($payment_type eq 'with_skonto_pt');
692

  
693

  
694
        my $overpaid_amount = $amount_of_transaction - $invoice->open_amount;
695
        $invoice->pay_invoice(chart_id     => $bank_transaction->local_bank_account->chart_id,
696
                              trans_id     => $invoice->id,
697
                              amount       => $amount_of_transaction,
698
                              payment_type => $payment_type,
699
                              source       => $source,
700
                              memo         => $memo,
701
                              transdate    => $bank_transaction->transdate->to_kivitendo);
702
        $bank_transaction->invoice_amount($bank_transaction->amount);
703
        $amount_of_transaction = 0;
704

  
705
        if ($overpaid_amount >= 0.01) {
706
          push @warnings, {
707
            %data,
708
            result  => 'warning',
709
            message => $::locale->text('Invoice #1 was overpaid by #2.', $invoice->invnumber, $::form->format_amount(\%::myconfig, $overpaid_amount, 2)),
710
          };
711
        }
712
      }
632
    # pay invoice
633
    # TODO rewrite this: really booked amount should be a return value of Payment.pm
634
    # also this controller shouldnt care about how to calc skonto. we simply delegate the
635
    # payment_type to the helper and get the corresponding bank_transaction values back
636

  
637
    my $open_amount = ($payment_type eq 'with_skonto_pt' ? $invoice->amount_less_skonto : $invoice->open_amount);
638
    my $amount_for_booking = abs(($open_amount < $not_assigned_amount) ? $open_amount : $not_assigned_amount);
639
    $amount_for_booking *= $sign;
640
    $bank_transaction->invoice_amount($bank_transaction->invoice_amount + $amount_for_booking);
641

  
642
    # ... and then pay the invoice
643
    my @acc_ids = $invoice->pay_invoice(chart_id => $bank_transaction->local_bank_account->chart_id,
644
                          trans_id     => $invoice->id,
645
                          amount       => ($open_amount < $not_assigned_amount) ? $open_amount : $not_assigned_amount,
646
                          payment_type => $payment_type,
647
                          source       => $source,
648
                          memo         => $memo,
649
                          transdate    => $bank_transaction->transdate->to_kivitendo);
650
    # ... and record the origin via BankTransactionAccTrans
651
    if (scalar(@acc_ids) != 2) {
652
      return {
653
        %data,
654
        result  => 'error',
655
        message => $::locale->text("Unable to book transactions for bank purpose #1", $bank_transaction->purpose),
656
      };
657
    }
658
    foreach my $acc_trans_id (@acc_ids) {
659
        my $id_type = $invoice->is_sales ? 'ar' : 'ap';
660
        my  %props_acc = (
661
          acc_trans_id        => $acc_trans_id,
662
          bank_transaction_id => $bank_transaction->id,
663
          $id_type            => $invoice->id,
664
        );
665
        SL::DB::BankTransactionAccTrans->new(%props_acc)->save;
666
    }
713 667
      # Record a record link from the bank transaction to the invoice
714 668
      my %props = (
715 669
        from_table => 'bank_transactions',
......
965 919
C<invoice_ids>, an array ref of database IDs to purchase or sales
966 920
invoice objects).
967 921

  
922
This method handles already partly assigned bank transactions.
923

  
968 924
This method cannot handle already partly assigned bank transactions, i.e.
969 925
a bank transaction that has a invoice_amount <> 0 but not the fully
970 926
transaction amount (invoice_amount == amount).
971 927

  
972 928
If the amount of the bank transaction is higher than the sum of
973
the assigned invoices (1 .. n) the last invoice will be overpayed.
929
the assigned invoices (1 .. n) the bank transaction will only be
930
partly assigned.
974 931

  
975 932
The whole function is wrapped in a database transaction. If an
976 933
exception occurs the bank transaction is not posted at all. The same

Auch abrufbar als: Unified diff