Revision 4af55f64
Von Jan Büren vor mehr als 1 Jahr hinzugefügt
SL/Controller/BankTransaction.pm | ||
---|---|---|
585 | 585 |
} |
586 | 586 |
my (@warnings); |
587 | 587 |
|
588 |
my $transit_items_account = SL::DB::Manager::Chart->find_by(id => SL::DB::Default->get->transit_items_chart_id); |
|
589 |
|
|
588 | 590 |
my $worker = sub { |
589 | 591 |
my $bt_id = $data{bank_transaction_id}; |
590 | 592 |
my $sign = $bank_transaction->amount < 0 ? -1 : 1; |
591 | 593 |
my $payment_received = $bank_transaction->amount > 0; |
592 | 594 |
my $payment_sent = $bank_transaction->amount < 0; |
595 |
my ($has_negative_record, $has_positive_record); |
|
593 | 596 |
|
594 | 597 |
|
595 | 598 |
foreach my $invoice_id (@{ $params{invoice_ids} }) { |
... | ... | |
601 | 604 |
message => $::locale->text("The ID #1 is not a valid database ID.", $invoice_id), |
602 | 605 |
}; |
603 | 606 |
} |
607 |
$has_positive_record = 1 if $invoice->amount > 0; # invoice |
|
608 |
$has_negative_record = 1 if $invoice->amount < 0; # credit_note |
|
604 | 609 |
push @{ $data{invoices} }, $invoice; |
605 | 610 |
} |
606 | 611 |
|
612 |
if (ref $transit_items_account eq 'SL::DB::Chart' && $has_positive_record |
|
613 |
&& scalar @{ $data{invoices} } == 2 && $has_negative_record) { |
|
614 |
|
|
615 |
$self->_check_and_book_credit_note( |
|
616 |
invoices => $data{invoices}, |
|
617 |
chart_id => $transit_items_account->id, |
|
618 |
bt_id => $bt_id, |
|
619 |
transdate => $bank_transaction->valutadate, |
|
620 |
transit_chart => $transit_items_account ); |
|
621 |
|
|
622 |
} |
|
607 | 623 |
if ( $payment_received |
608 | 624 |
&& any { ( $_->is_sales && ($_->amount < 0)) |
609 | 625 |
|| (!$_->is_sales && ($_->amount > 0)) |
... | ... | |
1009 | 1025 |
); |
1010 | 1026 |
} |
1011 | 1027 |
|
1028 |
sub _check_and_book_credit_note { |
|
1029 |
my $self = shift; |
|
1030 |
my %params = @_; |
|
1031 |
Common::check_params(\%params, qw(chart_id transdate bt_id invoices transit_chart)); |
|
1032 |
|
|
1033 |
croak "No invoice " unless (ref $params{invoices}->[0] eq 'SL::DB::PurchaseInvoice') |
|
1034 |
|| (ref $params{invoices}->[0] eq 'SL::DB::Invoice' ); |
|
1035 |
croak "Not a valid date" unless ref $params{transdate} eq 'DateTime'; |
|
1036 |
croak "Not a valid chart" unless ref $params{transit_chart} eq 'SL::DB::Chart'; |
|
1037 |
croak "Need exactly two records" unless scalar @{ $params{invoices} } == 2; |
|
1038 |
|
|
1039 |
|
|
1040 |
my ($has_one_credit_note, $has_one_invoice, $amount, $credit_note_index, $credit_note_no, $invoice_no); |
|
1041 |
my $index = 0; |
|
1042 |
foreach my $invoice (@{ $params{invoices} }) { |
|
1043 |
if ( ( $invoice->is_sales && $invoice->type eq 'credit_note') |
|
1044 |
|| (!$invoice->is_sales && $invoice->invoice_type eq 'purchase_credit_note')) { |
|
1045 |
# credit_notes | purchase_credit_note |
|
1046 |
# -1397.11000 | AR | 504.74000 | AP |
|
1047 |
# 1397.11000 | AR_paid | -504.74000 | AP_paid |
|
1048 |
|
|
1049 |
my $mult = $invoice->is_sales ? -1 : 1; # multiplier for getting the right sign for credit_notes |
|
1050 |
$amount = ($invoice->amount - $invoice->paid) * $mult; |
|
1051 |
# (-200 - (-10)) * $mult = AR_paid (positive) |AP_paid (negative) |
|
1052 |
|
|
1053 |
$has_one_credit_note += 1; |
|
1054 |
$credit_note_index = $index; |
|
1055 |
$credit_note_no = $invoice->invnumber; |
|
1056 |
} else { |
|
1057 |
$has_one_invoice += 1; |
|
1058 |
$invoice_no = $invoice->invnumber; |
|
1059 |
} |
|
1060 |
$index++; |
|
1061 |
} |
|
1062 |
die "Invalid state" unless ($has_one_credit_note == 1 && $has_one_invoice == 1); |
|
1063 |
|
|
1064 |
foreach my $invoice (@{ $params{invoices} }) { |
|
1065 |
my $is_credit_note = $invoice->invoice_type =~ m/credit_note/ ? 1 : undef; |
|
1066 |
my $sign = $invoice->invoice_type =~ m/credit_note/ ? 1 : -1; # correct sign for bookings |
|
1067 |
my $paid_sign = $invoice->invoice_type =~ m/credit_note/ ? -1 : 1; # paid is always negative for credit_note |
|
1068 |
|
|
1069 |
my $new_acc_trans = SL::DB::AccTransaction->new(trans_id => $invoice->id, |
|
1070 |
chart_id => $params{transit_chart}->id, |
|
1071 |
chart_link => $params{transit_chart}->link, |
|
1072 |
amount => $amount * $sign, |
|
1073 |
transdate => $params{transdate}, |
|
1074 |
source => $is_credit_note ? $invoice_no : $credit_note_no, |
|
1075 |
memo => t8('Automatically assigned with bank transaction'), |
|
1076 |
taxkey => 0, |
|
1077 |
tax_id => SL::DB::Manager::Tax->find_by(taxkey => 0)->id); |
|
1078 |
|
|
1079 |
my $arap_booking= SL::DB::AccTransaction->new(trans_id => $invoice->id, |
|
1080 |
chart_id => $invoice->reference_account->id, |
|
1081 |
chart_link => $invoice->reference_account->link, |
|
1082 |
amount => $amount * $sign * -1, |
|
1083 |
transdate => $params{transdate}, |
|
1084 |
source => '', |
|
1085 |
taxkey => 0, |
|
1086 |
tax_id => SL::DB::Manager::Tax->find_by(taxkey => 0)->id); |
|
1087 |
$new_acc_trans->save; |
|
1088 |
$arap_booking->save; |
|
1089 |
$invoice->update_attributes(paid => $invoice->paid + (abs($amount) * $paid_sign), datepaid => $params{transdate}); |
|
1090 |
|
|
1091 |
# link both acc_trans transactions |
|
1092 |
my $id_type = $invoice->is_sales ? 'ar' : 'ap'; |
|
1093 |
my %props_acc = ( |
|
1094 |
acc_trans_id => $new_acc_trans->acc_trans_id, |
|
1095 |
bank_transaction_id => $params{bt_id}, |
|
1096 |
$id_type => $invoice->id, |
|
1097 |
); |
|
1098 |
SL::DB::BankTransactionAccTrans->new(%props_acc)->save; |
|
1099 |
%props_acc = ( |
|
1100 |
acc_trans_id => $arap_booking->acc_trans_id, |
|
1101 |
bank_transaction_id => $params{bt_id}, |
|
1102 |
$id_type => $invoice->id, |
|
1103 |
); |
|
1104 |
SL::DB::BankTransactionAccTrans->new(%props_acc)->save; |
|
1105 |
# done |
|
1106 |
|
|
1107 |
# Record a record link from the bank transaction to the credit note |
|
1108 |
if ($invoice->invoice_type =~ m/credit_note/) { |
|
1109 |
my %props = ( |
|
1110 |
from_table => 'bank_transactions', |
|
1111 |
from_id => $params{bt_id}, |
|
1112 |
to_table => $id_type, |
|
1113 |
to_id => $invoice->id, |
|
1114 |
); |
|
1115 |
SL::DB::RecordLink->new(%props)->save; |
|
1116 |
} |
|
1117 |
} |
|
1118 |
# throw away the credit note |
|
1119 |
splice @{ $params{invoices} }, $credit_note_index, 1; |
|
1120 |
# and return nothing. hook is completely done |
|
1121 |
} |
|
1122 |
|
|
1012 | 1123 |
sub init_problems { [] } |
1013 | 1124 |
|
1014 | 1125 |
sub init_models { |
... | ... | |
1206 | 1317 |
gl transaction or to the notes field of an ap transaction. |
1207 | 1318 |
You have to write your own custom code. |
1208 | 1319 |
|
1320 |
=item C<_check_and_book_credit_note> |
|
1321 |
|
|
1322 |
This method takes a array of invoices with two entries one one valid credit note |
|
1323 |
and books the amount of the credit note against the invoice via the default |
|
1324 |
transfer items account (i.e. SKR04 1370) and adds a source and memo entry for the |
|
1325 |
payment booking. |
|
1326 |
Logical and visual linking of the payment booking and credit note record to the bank |
|
1327 |
transaction will also be done (necessary cond. for unlinking a bank transaction). |
|
1328 |
If the methods success the credit note will be deleted from |
|
1329 |
the original caller's array and he can further process the data without pondering |
|
1330 |
about the removed credit note data. |
|
1331 |
|
|
1209 | 1332 |
=back |
1210 | 1333 |
|
1211 | 1334 |
=head1 AUTHOR |
Auch abrufbar als: Unified diff
Kontoauszug verbuchen: Gutschriften über durchlaufende Posten verbuchen
Benötigt eine Rechnung und eine Gutschrift.
Bevor die Rechnung über pay_invoice bezahlt wird, wird die Gutschrift
gegen die Rechnung ausgeglichen und für die weitere Verarbeitung gelöscht.
Logisch sind die Buchungen dann mit der Bank Transaktion verknüpft und
somit wieder löschbar. S.a. POD