X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;ds=sidebyside;f=SL%2FDATEV.pm;h=406f09d76be5cc9ae04b8227be49104e8530782d;hb=e28d95b4826728e7490d708b40b2514b2fe88a34;hp=bbdc9b53205aedfe021260dcc04aef24de39a857;hpb=631b4c042a087595af1ee3af1fee4dc4dc2470ea;p=kivitendo-erp.git diff --git a/SL/DATEV.pm b/SL/DATEV.pm index bbdc9b532..406f09d76 100644 --- a/SL/DATEV.pm +++ b/SL/DATEV.pm @@ -1,5 +1,5 @@ #===================================================================== -# Lx-Office ERP +# kivitendo ERP # Copyright (c) 2004 # # Author: Philip Reetz @@ -353,9 +353,9 @@ sub _get_transactions { my $query = qq|SELECT ac.acc_trans_id, ac.transdate, ac.trans_id,ar.id, ac.amount, ac.taxkey, - ar.invnumber, ar.duedate, ar.amount as umsatz, + ar.invnumber, ar.duedate, ar.amount as umsatz, ar.deliverydate, ct.name, - c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id, c.link, + c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id, ac.chart_link AS link, ar.invoice FROM acc_trans ac LEFT JOIN ar ON (ac.trans_id = ar.id) @@ -368,9 +368,9 @@ sub _get_transactions { UNION ALL SELECT ac.acc_trans_id, ac.transdate, ac.trans_id,ap.id, ac.amount, ac.taxkey, - ap.invnumber, ap.duedate, ap.amount as umsatz, + ap.invnumber, ap.duedate, ap.amount as umsatz, ap.deliverydate, ct.name, - c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id, c.link, + c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id, ac.chart_link AS link, ap.invoice FROM acc_trans ac LEFT JOIN ap ON (ac.trans_id = ap.id) @@ -383,9 +383,9 @@ sub _get_transactions { UNION ALL SELECT ac.acc_trans_id, ac.transdate, ac.trans_id,gl.id, ac.amount, ac.taxkey, - gl.reference AS invnumber, gl.transdate AS duedate, ac.amount as umsatz, + gl.reference AS invnumber, gl.transdate AS duedate, ac.amount as umsatz, NULL as deliverydate, gl.description AS name, - c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id, c.link, + c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id, ac.chart_link AS link, FALSE AS invoice FROM acc_trans ac LEFT JOIN gl ON (ac.trans_id = gl.id) @@ -410,12 +410,25 @@ sub _get_transactions { my $count = $ref->{amount}; my $firstrun = 1; + + # if the amount of a booking in a group is smaller than 0.02, any tax + # amounts will likely be smaller than 1 cent, so go into subcent mode my $subcent = abs($count) < 0.02; + # records from acc_trans are ordered by trans_id and acc_trans_id + # first check for unbalanced ledger inside one trans_id + # there may be several groups inside a trans_id, e.g. the original booking and the payment + # each group individually should be exactly balanced and each group + # individually needs its own datev lines + + # keep fetching new acc_trans lines until the end of a balanced group is reached while (abs($count) > 0.01 || $firstrun || ($subcent && abs($count) > 0.005)) { my $ref2 = $sth->fetchrow_hashref("NAME_lc"); last unless ($ref2); + # check if trans_id of current acc_trans line is still the same as the + # trans_id of the first line in group + if ($ref2->{trans_id} != $trans->[0]->{trans_id}) { $self->add_error("Unbalanced ledger! old trans_id " . $trans->[0]->{trans_id} . " new trans_id " . $ref2->{trans_id} . " count $count"); return; @@ -452,7 +465,23 @@ sub _get_transactions { next; } + # determine at which array position the reference value (called absumsatz) is + # and which amount it has + for my $j (0 .. (scalar(@{$trans}) - 1)) { + + # Three cases: + # 1: gl transaction (Dialogbuchung), invoice is false, no double split booking allowed + + # 2: sales or vendor invoice (Verkaufs- und Einkaufsrechnung): invoice is + # true, instead of absumsatz use link AR/AP (there should only be one + # entry) + + # 3. AR/AP transaction (Kreditoren- und Debitorenbuchung): invoice is false, + # instead of absumsatz use link AR/AP (there should only be one, so jump + # out of search as soon as you find it ) + + # case 1 and 2 # for gl-bookings no split is allowed and there is no AR/AP account, so we always use the maximum value as a reference # for ap/ar bookings we can always search for AR/AP in link and use that if ( ( not $trans->[$j]->{'invoice'} and abs($trans->[$j]->{'amount'}) > abs($absumsatz) ) @@ -460,12 +489,26 @@ sub _get_transactions { $absumsatz = $trans->[$j]->{'amount'}; $notsplitindex = $j; } + + # case 3 + # Problem: we can't distinguish between AR and AP and normal invoices via boolean "invoice" + # for AR and AP transaction exit the loop as soon as an AR or AP account is found + # there must be only one AR or AP chart in the booking + if ( $trans->[$j]->{'link'} eq 'AR' or $trans->[$j]->{'link'} eq 'AP') { + $notsplitindex = $j; # position in booking with highest amount + $absumsatz = $trans->[$j]->{'amount'}; + last; + }; } my $ml = ($trans->[0]->{'umsatz'} > 0) ? 1 : -1; my $rounding_error = 0; my @taxed; + # go through each line and determine if it is a tax booking or not + # skip all tax lines and notsplitindex line + # push all other accounts (e.g. income or expense) with corresponding taxkey + for my $j (0 .. (scalar(@{$trans}) - 1)) { if ( ($j != $notsplitindex) && !$trans->[$j]->{is_tax} @@ -485,7 +528,8 @@ sub _get_transactions { push @{ $self->{DATEV} }, [ \%new_trans, $trans->[$j] ]; } elsif (($j != $notsplitindex) && !$trans->[$j]->{is_tax}) { - my %tax_info = $taxkeys->get_full_tax_info('transdate' => $trans->[$j]->{transdate}); + my %tax_info = $taxkeys->get_full_tax_info('transdate' => $trans->[$j]->{transdate}, + 'deliverydate' => $trans->[$j]->{deliverydate}); my %new_trans = (); map { $new_trans{$_} = $trans->[$notsplitindex]->{$_}; } keys %{ $trans->[$notsplitindex] }; @@ -994,7 +1038,7 @@ __END__ =head1 NAME -SL::DATEV - Lx-Office DATEV Export module +SL::DATEV - kivitendo DATEV Export module =head1 SYNOPSIS