+sub _check_and_book_credit_note {
+ my $self = shift;
+ my %params = @_;
+ Common::check_params(\%params, qw(chart_id transdate bt_id invoices transit_chart));
+
+ croak "No invoice " unless (ref $params{invoices}->[0] eq 'SL::DB::PurchaseInvoice')
+ || (ref $params{invoices}->[0] eq 'SL::DB::Invoice' );
+ croak "Not a valid date" unless ref $params{transdate} eq 'DateTime';
+ croak "Not a valid chart" unless ref $params{transit_chart} eq 'SL::DB::Chart';
+ croak "Need exactly two records" unless scalar @{ $params{invoices} } == 2;
+
+
+ my ($has_one_credit_note, $has_one_invoice, $amount, $credit_note_index, $credit_note_no, $invoice_no);
+ my $index = 0;
+ foreach my $invoice (@{ $params{invoices} }) {
+ if ( ( $invoice->is_sales && $invoice->type eq 'credit_note')
+ || (!$invoice->is_sales && $invoice->invoice_type eq 'purchase_credit_note')) {
+ # credit_notes | purchase_credit_note
+ # -1397.11000 | AR | 504.74000 | AP
+ # 1397.11000 | AR_paid | -504.74000 | AP_paid
+
+ my $mult = $invoice->is_sales ? -1 : 1; # multiplier for getting the right sign for credit_notes
+ $amount = ($invoice->amount - $invoice->paid) * $mult;
+ # (-200 - (-10)) * $mult = AR_paid (positive) |AP_paid (negative)
+
+ $has_one_credit_note += 1;
+ $credit_note_index = $index;
+ $credit_note_no = $invoice->invnumber;
+ } else {
+ $has_one_invoice += 1;
+ $invoice_no = $invoice->invnumber;
+ }
+ $index++;
+ }
+ die "Invalid state" unless ($has_one_credit_note == 1 && $has_one_invoice == 1);
+
+ foreach my $invoice (@{ $params{invoices} }) {
+ my $is_credit_note = $invoice->is_credit_note ? 1 : undef;
+ my $sign = $invoice->is_credit_note ? 1 : -1; # correct sign for bookings
+ my $paid_sign = $invoice->is_credit_note ? -1 : 1; # paid is always negative for credit_note
+
+ my $new_acc_trans = SL::DB::AccTransaction->new(trans_id => $invoice->id,
+ chart_id => $params{transit_chart}->id,
+ chart_link => $params{transit_chart}->link,
+ amount => $amount * $sign,
+ transdate => $params{transdate},
+ source => $is_credit_note ? $invoice_no : $credit_note_no,
+ memo => t8('Automatically assigned with bank transaction'),
+ taxkey => 0,
+ tax_id => SL::DB::Manager::Tax->find_by(taxkey => 0)->id);
+
+ my $arap_booking= SL::DB::AccTransaction->new(trans_id => $invoice->id,
+ chart_id => $invoice->reference_account->id,
+ chart_link => $invoice->reference_account->link,
+ amount => $amount * $sign * -1,
+ transdate => $params{transdate},
+ source => '',
+ taxkey => 0,
+ tax_id => SL::DB::Manager::Tax->find_by(taxkey => 0)->id);
+ $new_acc_trans->save;
+ $arap_booking->save;
+ $invoice->update_attributes(paid => $invoice->paid + (abs($amount) * $paid_sign), datepaid => $params{transdate});
+
+ # link both acc_trans transactions
+ my $id_type = $invoice->is_sales ? 'ar' : 'ap';
+ my %props_acc = (
+ acc_trans_id => $new_acc_trans->acc_trans_id,
+ bank_transaction_id => $params{bt_id},
+ $id_type => $invoice->id,
+ );
+ SL::DB::BankTransactionAccTrans->new(%props_acc)->save;
+ %props_acc = (
+ acc_trans_id => $arap_booking->acc_trans_id,
+ bank_transaction_id => $params{bt_id},
+ $id_type => $invoice->id,
+ );
+ SL::DB::BankTransactionAccTrans->new(%props_acc)->save;
+ # done
+
+ # Record a record link from the bank transaction to the credit note
+ if ($invoice->invoice_type =~ m/credit_note/) {
+ my %props = (
+ from_table => 'bank_transactions',
+ from_id => $params{bt_id},
+ to_table => $id_type,
+ to_id => $invoice->id,
+ );
+ SL::DB::RecordLink->new(%props)->save;
+ }
+ }
+ # throw away the credit note
+ splice @{ $params{invoices} }, $credit_note_index, 1;
+ # and return nothing. hook is completely done
+}
+