Neuer Bericht "Verkaufsbericht" unter Verkauf->Berichte
[kivitendo-erp.git] / SL / RP.pm
1 #=====================================================================
2 # LX-Office ERP
3 # Copyright (C) 2004
4 # Based on SQL-Ledger Version 2.1.9
5 # Web http://www.lx-office.org
6 #
7 #=====================================================================
8 # SQL-Ledger Accounting
9 # Copyright (C) 1998-2002
10 #
11 #  Author: Dieter Simader
12 #   Email: dsimader@sql-ledger.org
13 #     Web: http://www.sql-ledger.org
14 #
15 #  Contributors: Benjamin Lee <benjaminlee@consultant.com>
16 #
17 # This program is free software; you can redistribute it and/or modify
18 # it under the terms of the GNU General Public License as published by
19 # the Free Software Foundation; either version 2 of the License, or
20 # (at your option) any later version.
21 #
22 # This program is distributed in the hope that it will be useful,
23 # but WITHOUT ANY WARRANTY; without even the implied warranty of
24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 # GNU General Public License for more details.
26 # You should have received a copy of the GNU General Public License
27 # along with this program; if not, write to the Free Software
28 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #======================================================================
30 #
31 # backend code for reports
32 #
33 #======================================================================
34
35 package RP;
36
37 use SL::DBUtils;
38 use Data::Dumper;
39 use List::Util qw(sum);
40
41 # use warnings;
42 use strict;
43
44 # new implementation of balance sheet
45 # readme!
46 #
47 # stuff missing from the original implementation:
48 # - bold stuff
49 # - subdescription
50 # - proper testing for heading charts
51 # - transmission from $form to TMPL realm is not as clear as i'd like
52 sub balance_sheet {
53   $main::lxdebug->enter_sub();
54
55   my $myconfig = \%main::myconfig;
56   my $form     = $main::form;
57   my $dbh      = $form->get_standard_dbh($myconfig);
58
59   my $last_period = 0;
60   my @categories  = qw(A C L Q);
61
62   # if there are any dates construct a where
63   if ($form->{asofdate}) {
64     $form->{period} = $form->{this_period} = conv_dateq($form->{asofdate});
65   }
66
67   get_accounts($dbh, $last_period, "", $form->{asofdate}, $form, \@categories);
68
69   # if there are any compare dates
70   if ($form->{compareasofdate}) {
71     $last_period = 1;
72     get_accounts($dbh, $last_period, "", $form->{compareasofdate}, $form, \@categories);
73     $form->{last_period} = conv_dateq($form->{compareasofdate});
74   }
75
76   # now we got $form->{A}{accno}{ }    assets
77   # and $form->{L}{accno}{ }           liabilities
78   # and $form->{Q}{accno}{ }           equity
79   # build asset accounts
80
81   my %account = ('A' => { 'ml'     => -1 },
82                  'L' => { 'ml'     =>  1 },
83                  'Q' => { 'ml'     =>  1 });
84
85   my $TMPL_DATA = {};
86
87   foreach my $category (grep { !/C/ } @categories) {
88
89     $TMPL_DATA->{$category} = [];
90     my $ml  = $account{$category}{ml};
91
92     foreach my $key (sort keys %{ $form->{$category} }) {
93
94       my $row = { %{ $form->{$category}{$key} } };
95
96       # if charttype "heading" - calculate this entry, start a new batch of charts belonging to this heading and skip the rest bo the loop
97       # header charts are not real charts. start a sub aggregation with them, but don't calculate anything with them
98       if ($row->{charttype} eq "H") {
99         if ($account{$category}{subtotal} && $form->{l_subtotal}) {
100           $row->{subdescription} = $account{$category}{subdescription};
101           $row->{this}           = $account{$category}{subthis} * $ml;                   # format: $dec, $dash
102           $row->{last}           = $account{$category}{sublast} * $ml if $last_period;   # format: $dec, $dash
103         }
104
105         $row->{subheader} = 1;
106         $account{$category}{subthis}        = $row->{this};
107         $account{$category}{sublast}        = $row->{last};
108         $account{$category}{subdescription} = $row->{description};
109         $account{$category}{subtotal} = 1;
110
111         $row->{this} = 0;
112         $row->{last} = 0;
113
114         next unless $form->{l_heading};
115       }
116
117       for my $period (qw(this last)) {
118         next if ($period eq 'last' && !$last_period);
119         # only add assets
120         $row->{$period}                    *= $ml;
121         $form->{total}{$category}{$period} += $row->{$period};      #      if ($row->{charttype} eq 'A') {   # why??
122       }
123
124       push @{ $TMPL_DATA->{$category} }, $row;
125     } # foreach
126
127     # resolve heading/subtotal
128     if ($account{$category}{subtotal} && $form->{l_subtotal}) {
129       $TMPL_DATA->{$category}[-1]{subdescription} = $account{$category}{subdescription};
130       $TMPL_DATA->{$category}[-1]{this}           = $account{$category}{subthis} * $ml;                   # format: $dec, $dash
131       $TMPL_DATA->{$category}[-1]{last}           = $account{$category}{sublast} * $ml if $last_period;   # format: $dec, $dash
132     }
133
134     $TMPL_DATA->{total}{$category}{this} = sum map { $_->{this} } @{ $TMPL_DATA->{$category} };
135     $TMPL_DATA->{total}{$category}{last} = sum map { $_->{last} } @{ $TMPL_DATA->{$category} };
136   }
137
138   for my $period (qw(this last)) {
139     next if ($period eq 'last' && !$last_period);
140
141     $form->{E}{$period}             = $form->{total}{A}{$period} - $form->{total}{L}{$period} - $form->{total}{Q}{$period};
142     $form->{total}{Q}{$period}     += $form->{E}{$period};
143     $TMPL_DATA->{total}{Q}{$period} = $form->{total}{Q}{$period};
144     $TMPL_DATA->{total}{$period}    = $form->{total}{L}{$period} + $form->{total}{Q}{$period};
145   }
146
147   push @{ $TMPL_DATA->{Q} }, $form->{E};
148
149   $main::lxdebug->leave_sub();
150
151   return $TMPL_DATA;
152 }
153
154 sub get_accounts {
155   $main::lxdebug->enter_sub();
156
157   my ($dbh, $last_period, $fromdate, $todate, $form, $categories) = @_;
158
159   my ($null, $department_id) = split /--/, $form->{department};
160
161   my $query;
162   my $dpt_where = '';
163   my $dpt_join  = '';
164   my $project   = '';
165   my $where     = "1 = 1";
166   my $glwhere   = "";
167   my $subwhere  = "";
168   my $item;
169   my $sth;
170   my $dec = $form->{decimalplaces};
171
172   my $category = qq| AND (| . join(" OR ", map({ "(c.category = " . $dbh->quote($_) . ")" } @{$categories})) . qq|) |;
173
174   # get headings
175   $query =
176     qq|SELECT c.accno, c.description, c.category
177        FROM chart c
178        WHERE (c.charttype = 'H')
179          $category
180        ORDER by c.accno|;
181
182   $sth = prepare_execute_query($form, $dbh, $query);
183
184   my @headingaccounts = ();
185   while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
186     $form->{ $ref->{category} }{ $ref->{accno} }{description} =
187       "$ref->{description}";
188     $form->{ $ref->{category} }{ $ref->{accno} }{charttype} = "H";
189     $form->{ $ref->{category} }{ $ref->{accno} }{accno}     = $ref->{accno};
190
191     push @headingaccounts, $ref->{accno};
192   }
193
194   $sth->finish;
195
196   if ($fromdate) {
197     $fromdate = conv_dateq($fromdate);
198     if ($form->{method} eq 'cash') {
199       $subwhere .= " AND (transdate >= $fromdate)";
200       $glwhere = " AND (ac.transdate >= $fromdate)";
201     } else {
202       $where .= " AND (ac.transdate >= $fromdate)";
203     }
204   }
205
206   if ($todate) {
207     $todate = conv_dateq($todate);
208     $where    .= " AND (ac.transdate <= $todate)";
209     $subwhere .= " AND (transdate <= $todate)";
210   }
211
212   if ($department_id) {
213     $dpt_join = qq| JOIN department t ON (a.department_id = t.id) |;
214     $dpt_where = qq| AND (t.id = | . conv_i($department_id, 'NULL') . qq|)|;
215   }
216
217   if ($form->{project_id}) {
218     # Diese Bedingung wird derzeit niemals wahr sein, da man in Bericht->Bilanz keine
219     # Projekte auswählen kann
220     $project = qq| AND (ac.project_id = | . conv_i($form->{project_id}, 'NULL') . qq|) |;
221   }
222
223   if ($form->{method} eq 'cash') {
224     $query =
225       qq|SELECT c.accno, sum(ac.amount) AS amount, c.description, c.category
226          FROM acc_trans ac
227          JOIN chart c ON (c.id = ac.chart_id)
228          JOIN ar a ON (a.id = ac.trans_id)
229          $dpt_join
230          WHERE $where
231            $dpt_where
232            $category
233            AND ac.trans_id IN
234              (
235                SELECT trans_id
236                FROM acc_trans a
237                JOIN chart c ON (a.chart_id = c.id)
238                WHERE (link LIKE '%AR_paid%')
239                $subwhere
240              )
241            $project
242          GROUP BY c.accno, c.description, c.category
243
244          UNION ALL
245
246          SELECT c.accno, sum(ac.amount) AS amount, c.description, c.category
247          FROM acc_trans ac
248          JOIN chart c ON (c.id = ac.chart_id)
249          JOIN ap a ON (a.id = ac.trans_id)
250          $dpt_join
251          WHERE $where
252            $dpt_where
253            $category
254            AND ac.trans_id IN
255              (
256                SELECT trans_id
257                FROM acc_trans a
258                JOIN chart c ON (a.chart_id = c.id)
259                WHERE (link LIKE '%AP_paid%')
260                $subwhere
261              )
262            $project
263          GROUP BY c.accno, c.description, c.category
264
265          UNION ALL
266
267          SELECT c.accno, sum(ac.amount) AS amount, c.description, c.category
268          FROM acc_trans ac
269          JOIN chart c ON (c.id = ac.chart_id)
270          JOIN gl a ON (a.id = ac.trans_id)
271          $dpt_join
272          WHERE $where
273            $glwhere
274            $dpt_where
275            $category
276              AND NOT ((c.link = 'AR') OR (c.link = 'AP'))
277            $project
278          GROUP BY c.accno, c.description, c.category |;
279
280     if ($form->{project_id}) {
281       # s.o. keine Projektauswahl in Bilanz
282       $query .=
283         qq|
284          UNION ALL
285
286          SELECT c.accno AS accno, SUM(ac.sellprice * ac.qty) AS amount, c.description AS description, c.category
287          FROM invoice ac
288          JOIN ar a ON (a.id = ac.trans_id)
289          JOIN parts p ON (ac.parts_id = p.id)
290          JOIN chart c on (p.income_accno_id = c.id)
291          $dpt_join
292          -- use transdate from subwhere
293          WHERE (c.category = 'I')
294            $subwhere
295            $dpt_where
296            AND ac.trans_id IN
297              (
298                SELECT trans_id
299                FROM acc_trans a
300                JOIN chart c ON (a.chart_id = c.id)
301                WHERE (link LIKE '%AR_paid%')
302                $subwhere
303              )
304            $project
305          GROUP BY c.accno, c.description, c.category
306
307          UNION ALL
308
309          SELECT c.accno AS accno, SUM(ac.sellprice) AS amount, c.description AS description, c.category
310          FROM invoice ac
311          JOIN ap a ON (a.id = ac.trans_id)
312          JOIN parts p ON (ac.parts_id = p.id)
313          JOIN chart c on (p.expense_accno_id = c.id)
314          $dpt_join
315          WHERE (c.category = 'E')
316            $subwhere
317            $dpt_where
318            AND ac.trans_id IN
319              (
320                SELECT trans_id
321                FROM acc_trans a
322                JOIN chart c ON (a.chart_id = c.id)
323                WHERE link LIKE '%AP_paid%'
324                $subwhere
325              )
326            $project
327          GROUP BY c.accno, c.description, c.category |;
328     }
329
330   } else {                      # if ($form->{method} eq 'cash')
331     # ich sehe keinen sinn das nochmal explizit ohne conv_i aufzurufen
332     # bitte prüfen und löschen jan 15.11.2009
333   #  if ($department_id) {
334   #    $dpt_join = qq| JOIN dpt_trans t ON (t.trans_id = ac.trans_id) |;
335   #    $dpt_where = qq| AND t.department_id = $department_id |;
336   #  }
337
338     $query = qq|
339       SELECT c.accno, sum(ac.amount) AS amount, c.description, c.category
340       FROM acc_trans ac
341       JOIN chart c ON (c.id = ac.chart_id)
342       $dpt_join
343       WHERE $where
344         $dpt_where
345         $category
346         $project
347       GROUP BY c.accno, c.description, c.category |;
348
349     if ($form->{project_id}) {
350       # s.o. keine Projektauswahl in Bilanz
351       $query .= qq|
352       UNION ALL
353
354       SELECT c.accno AS accno, SUM(ac.sellprice * ac.qty) AS amount, c.description AS description, c.category
355       FROM invoice ac
356       JOIN ar a ON (a.id = ac.trans_id)
357       JOIN parts p ON (ac.parts_id = p.id)
358       JOIN chart c on (p.income_accno_id = c.id)
359       $dpt_join
360       -- use transdate from subwhere
361       WHERE (c.category = 'I')
362         $subwhere
363         $dpt_where
364         $project
365       GROUP BY c.accno, c.description, c.category
366
367       UNION ALL
368
369       SELECT c.accno AS accno, SUM(ac.sellprice * ac.qty) * -1 AS amount, c.description AS description, c.category
370       FROM invoice ac
371       JOIN ap a ON (a.id = ac.trans_id)
372       JOIN parts p ON (ac.parts_id = p.id)
373       JOIN chart c on (p.expense_accno_id = c.id)
374       $dpt_join
375       WHERE (c.category = 'E')
376         $subwhere
377         $dpt_where
378         $project
379       GROUP BY c.accno, c.description, c.category |;
380     }
381   }
382
383   my @accno;
384   my $accno;
385   my $ref;
386
387   $sth = prepare_execute_query($form, $dbh, $query);
388
389   while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
390
391     if ($ref->{category} eq 'C') {
392       $ref->{category} = 'A';
393     }
394
395     # get last heading account
396     @accno = grep { $_ le "$ref->{accno}" } @headingaccounts;
397     $accno = pop @accno;
398     if ($accno) {
399       if ($last_period) {
400         $form->{ $ref->{category} }{$accno}{last} += $ref->{amount};
401       } else {
402         $form->{ $ref->{category} }{$accno}{this} += $ref->{amount};
403       }
404     }
405
406     $form->{ $ref->{category} }{ $ref->{accno} }{accno}       = $ref->{accno};
407     $form->{ $ref->{category} }{ $ref->{accno} }{description} = $ref->{description};
408     $form->{ $ref->{category} }{ $ref->{accno} }{charttype} = "A";
409
410     if ($last_period) {
411       $form->{ $ref->{category} }{ $ref->{accno} }{last} += $ref->{amount};
412     } else {
413       $form->{ $ref->{category} }{ $ref->{accno} }{this} += $ref->{amount};
414     }
415   }
416   $sth->finish;
417
418   # remove accounts with zero balance
419   foreach $category (@{$categories}) {
420     foreach $accno (keys %{ $form->{$category} }) {
421       $form->{$category}{$accno}{last} = $form->round_amount($form->{$category}{$accno}{last}, $dec);
422       $form->{$category}{$accno}{this} = $form->round_amount($form->{$category}{$accno}{this}, $dec);
423
424       delete $form->{$category}{$accno}
425         if (   $form->{$category}{$accno}{this} == 0
426             && $form->{$category}{$accno}{last} == 0);
427     }
428   }
429
430   $main::lxdebug->leave_sub();
431 }
432
433 sub get_accounts_g {
434   $main::lxdebug->enter_sub();
435
436   my ($dbh, $last_period, $fromdate, $todate, $form, $category) = @_;
437
438   my ($null, $department_id) = split /--/, $form->{department};
439
440   my $query;
441   my $dpt_where;
442   my $dpt_join;
443   my $project;
444   my $where    = "1 = 1";
445   my $glwhere  = "";
446   my $prwhere  = "";
447   my $subwhere = "";
448   my $inwhere = "";
449   my $item;
450
451   if ($fromdate) {
452     $fromdate = conv_dateq($fromdate);
453     if ($form->{method} eq 'cash') {
454       $subwhere .= " AND (transdate    >= $fromdate)";
455       $glwhere   = " AND (ac.transdate >= $fromdate)";
456       $prwhere   = " AND (a.transdate  >= $fromdate)";
457       $inwhere   = " AND (acc.transdate >= $fromdate)";
458     } else {
459       $where    .= " AND (ac.transdate >= $fromdate)";
460     }
461   }
462
463   if ($todate) {
464     $todate = conv_dateq($todate);
465     $subwhere   .= " AND (transdate    <= $todate)";
466     $where      .= " AND (ac.transdate <= $todate)";
467     $prwhere    .= " AND (a.transdate  <= $todate)";
468     $inwhere    .= " AND (acc.transdate <= $todate)";
469   }
470
471   if ($department_id) {
472     $dpt_join = qq| JOIN department t ON (a.department_id = t.id) |;
473     $dpt_where = qq| AND (t.id = | . conv_i($department_id, 'NULL') . qq|) |;
474   }
475
476   if ($form->{project_id}) {
477     $project = qq| AND (ac.project_id = | . conv_i($form->{project_id}) . qq|) |;
478   }
479
480 #
481 # GUV patch by Ronny Rentner (Bug 1190)
482 #
483 # GUV IST-Versteuerung
484 #
485 # Alle tatsaechlichen _Zahlungseingaenge_
486 # im Zeitraum erfassen
487 # (Teilzahlungen werden prozentual auf verschiedene Steuern aufgeteilt)
488 #
489 #
490
491   if ($form->{method} eq 'cash') {
492     $query =
493       qq|
494        SELECT SUM( ac.amount *
495                     (SELECT SUM(acc.amount) * -1
496                      FROM acc_trans acc
497                      INNER JOIN chart c ON (acc.chart_id = c.id AND c.link LIKE '%AR_paid%')
498                      WHERE 1=1 $inwhere AND acc.trans_id = ac.trans_id)
499                   / (SELECT amount FROM ar WHERE id = ac.trans_id)
500                 ) AS amount, c.pos_eur
501        FROM acc_trans ac
502        LEFT JOIN chart c ON (c.id  = ac.chart_id)
503        LEFT JOIN ar      ON (ar.id = ac.trans_id)
504        LEFT JOIN taxkeys tk ON (tk.id = (
505                                   SELECT id FROM taxkeys
506                                   WHERE chart_id = ac.chart_id
507                                   AND startdate <= COALESCE(ar.deliverydate,ar.transdate)
508                                   ORDER BY startdate DESC LIMIT 1
509                                   )
510                                 )
511       WHERE ac.trans_id IN (SELECT DISTINCT trans_id FROM acc_trans WHERE 1=1 $subwhere)
512
513       GROUP BY c.pos_eur
514
515 /*
516        SELECT SUM(ac.amount * chart_category_to_sgn(c.category)) AS amount, c.$category
517          FROM acc_trans ac
518          JOIN chart c ON (c.id = ac.chart_id)
519          JOIN ar a ON (a.id = ac.trans_id)
520          $dpt_join
521          WHERE $where $dpt_where
522            AND ac.trans_id IN ( SELECT trans_id FROM acc_trans a JOIN chart c ON (a.chart_id = c.id) WHERE (link LIKE '%AR_paid%') $subwhere)
523            $project
524          GROUP BY c.$category
525 */
526          UNION
527
528          SELECT SUM(ac.amount * chart_category_to_sgn(c.category)) AS amount, c.$category
529          FROM acc_trans ac
530          JOIN chart c ON (c.id = ac.chart_id)
531          JOIN ap a ON (a.id = ac.trans_id)
532          $dpt_join
533          WHERE $where $dpt_where
534            AND ac.trans_id IN ( SELECT trans_id FROM acc_trans a JOIN chart c ON (a.chart_id = c.id) WHERE (link LIKE '%AP_paid%') $subwhere)
535            $project
536          GROUP BY c.$category
537
538          UNION
539
540          SELECT SUM(ac.amount * chart_category_to_sgn(c.category)) AS amount, c.$category
541          FROM acc_trans ac
542          JOIN chart c ON (c.id = ac.chart_id)
543          JOIN gl a ON (a.id = ac.trans_id)
544          $dpt_join
545          WHERE $where $dpt_where $glwhere
546            AND NOT ((c.link = 'AR') OR (c.link = 'AP'))
547            $project
548          GROUP BY c.$category
549         |;
550
551     if ($form->{project_id}) {
552       $query .= qq|
553          UNION
554
555          SELECT SUM(ac.sellprice * ac.qty * chart_category_to_sgn(c.category)) AS amount, c.$category
556          FROM invoice ac
557          JOIN ar a ON (a.id = ac.trans_id)
558          JOIN parts p ON (ac.parts_id = p.id)
559          JOIN chart c on (p.income_accno_id = c.id)
560          $dpt_join
561          WHERE (c.category = 'I') $prwhere $dpt_where
562            AND ac.trans_id IN ( SELECT trans_id FROM acc_trans a JOIN chart c ON (a.chart_id = c.id) WHERE (link LIKE '%AR_paid%') $subwhere)
563            $project
564          GROUP BY c.$category
565
566          UNION
567
568          SELECT SUM(ac.sellprice * chart_category_to_sgn(c.category)) AS amount, c.$category
569          FROM invoice ac
570          JOIN ap a ON (a.id = ac.trans_id)
571          JOIN parts p ON (ac.parts_id = p.id)
572          JOIN chart c on (p.expense_accno_id = c.id)
573          $dpt_join
574          WHERE (c.category = 'E') $prwhere $dpt_where
575            AND ac.trans_id IN ( SELECT trans_id FROM acc_trans a JOIN chart c ON (a.chart_id = c.id) WHERE (link LIKE '%AP_paid%') $subwhere)
576          $project
577          GROUP BY c.$category
578          |;
579     }
580
581   } else {                      # if ($form->{method} eq 'cash')
582     # s.o. jan 15.11.2009
583 #    if ($department_id) {
584 #      ($dpt_join, $dpt_where) = sql_department($department_id);
585 #    }
586
587     $query = qq|
588         SELECT sum(ac.amount * chart_category_to_sgn(c.category)) AS amount, c.$category
589         FROM acc_trans ac
590         JOIN chart c ON (c.id = ac.chart_id)
591         $dpt_join
592         WHERE $where
593           $dpt_where
594           $project
595         GROUP BY c.$category |;
596
597     if ($form->{project_id}) {
598       $query .= qq|
599         UNION
600
601         SELECT SUM(ac.sellprice * ac.qty * chart_category_to_sgn(c.category)) AS amount, c.$category
602         FROM invoice ac
603         JOIN ar a ON (a.id = ac.trans_id)
604         JOIN parts p ON (ac.parts_id = p.id)
605         JOIN chart c on (p.income_accno_id = c.id)
606         $dpt_join
607         WHERE (c.category = 'I')
608           $prwhere
609           $dpt_where
610           $project
611         GROUP BY c.$category
612
613         UNION
614
615         SELECT SUM(ac.sellprice * ac.qty * chart_category_to_sgn(c.category)) AS amount, c.$category
616         FROM invoice ac
617         JOIN ap a ON (a.id = ac.trans_id)
618         JOIN parts p ON (ac.parts_id = p.id)
619         JOIN chart c on (p.expense_accno_id = c.id)
620         $dpt_join
621         WHERE (c.category = 'E')
622           $prwhere
623           $dpt_where
624           $project
625         GROUP BY c.$category |;
626     }
627   }
628
629   my @accno;
630   my $accno;
631   my $ref;
632
633   foreach my $ref (selectall_hashref_query($form, $dbh, $query)) {
634     if ($category eq "pos_bwa") {
635       if ($last_period) {
636         $form->{ $ref->{$category} }{kumm} += $ref->{amount};
637       } else {
638         $form->{ $ref->{$category} }{jetzt} += $ref->{amount};
639       }
640     } else {
641       $form->{ $ref->{$category} } += $ref->{amount};
642     }
643   }
644
645   $main::lxdebug->leave_sub();
646 }
647
648 sub trial_balance {
649   $main::lxdebug->enter_sub();
650
651   my ($self, $myconfig, $form, %options) = @_;
652
653   my $dbh = $form->dbconnect($myconfig);
654
655   my ($query, $sth, $ref);
656   my %balance = ();
657   my %trb     = ();
658   my ($null, $department_id) = split /--/, $form->{department};
659   my @headingaccounts = ();
660   my $dpt_where;
661   my $dpt_join;
662   my $project;
663
664   my $where    = "1 = 1";
665   my $invwhere = $where;
666
667   if ($department_id) {
668     $dpt_join = qq| JOIN dpt_trans t ON (ac.trans_id = t.trans_id) |;
669     $dpt_where = qq| AND (t.department_id = | . conv_i($department_id, 'NULL') . qq|) |;
670   }
671
672   # project_id only applies to getting transactions
673   # it has nothing to do with a trial balance
674   # but we use the same function to collect information
675
676   if ($form->{project_id}) {
677     $project = qq| AND (ac.project_id = | . conv_i($form->{project_id}, 'NULL') . qq|) |;
678   }
679
680   my $acc_cash_where = "";
681 #  my $ar_cash_where = "";
682 #  my $ap_cash_where = "";
683
684
685   if ($form->{method} eq "cash") {
686     $acc_cash_where =
687       qq| AND (ac.trans_id IN (
688             SELECT id
689             FROM ar
690             WHERE datepaid >= '$form->{fromdate}'
691               AND datepaid <= '$form->{todate}'
692
693             UNION
694
695             SELECT id
696             FROM ap
697             WHERE datepaid >= '$form->{fromdate}'
698               AND datepaid <= '$form->{todate}'
699
700             UNION
701
702             SELECT id
703             FROM gl
704             WHERE transdate >= '$form->{fromdate}'
705               AND transdate <= '$form->{todate}'
706           )) |;
707 #    $ar_ap_cash_where = qq| AND (a.datepaid>='$form->{fromdate}' AND a.datepaid<='$form->{todate}') |;
708   }
709
710   if ($options{beginning_balances}) {
711     foreach my $prefix (qw(from to)) {
712       next if ($form->{"${prefix}date"});
713
714       my $min_max = $prefix eq 'from' ? 'min' : 'max';
715       $query      = qq|SELECT ${min_max}(transdate)
716                        FROM acc_trans ac
717                        $dpt_join
718                        WHERE (1 = 1)
719                          $dpt_where
720                          $project|;
721       ($form->{"${prefix}date"}) = selectfirst_array_query($form, $dbh, $query);
722     }
723
724     # get beginning balances
725     $query =
726       qq|SELECT c.accno, c.category, SUM(ac.amount) AS amount, c.description
727           FROM acc_trans ac
728           LEFT JOIN chart c ON (ac.chart_id = c.id)
729           $dpt_join
730           WHERE ((select date_trunc('year', ac.transdate::date)) = (select date_trunc('year', ?::date))) AND ac.ob_transaction
731             $dpt_where
732             $project
733           GROUP BY c.accno, c.category, c.description |;
734
735     $sth = prepare_execute_query($form, $dbh, $query, $form->{fromdate});
736
737     while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
738
739       if ($ref->{amount} != 0 || $form->{all_accounts}) {
740         $trb{ $ref->{accno} }{description} = $ref->{description};
741         $trb{ $ref->{accno} }{charttype}   = 'A';
742         $trb{ $ref->{accno} }{beginning_balance} = $ref->{amount};
743
744         if ($ref->{amount} > 0) {
745           $trb{ $ref->{accno} }{haben_eb}   = $ref->{amount};
746         } else {
747           $trb{ $ref->{accno} }{soll_eb}   = $ref->{amount} * -1;
748         }
749         $trb{ $ref->{accno} }{category}    = $ref->{category};
750       }
751
752     }
753     $sth->finish;
754   }
755
756   # get headings
757   $query =
758     qq|SELECT c.accno, c.description, c.category
759        FROM chart c
760        WHERE c.charttype = 'H'
761        ORDER by c.accno|;
762
763   $sth = prepare_execute_query($form, $dbh, $query);
764
765   while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
766     $trb{ $ref->{accno} }{description} = $ref->{description};
767     $trb{ $ref->{accno} }{charttype}   = 'H';
768     $trb{ $ref->{accno} }{category}    = $ref->{category};
769
770     push @headingaccounts, $ref->{accno};
771   }
772
773   $sth->finish;
774
775   $where = " 1 = 1 ";
776   my $saldowhere    = " 1 = 1 ";
777   my $sumwhere      = " 1 = 1 ";
778   my $subwhere      = '';
779   my $sumsubwhere   = '';
780   my $saldosubwhere = '';
781   my $glsaldowhere  = '';
782   my $glsubwhere    = '';
783   my $glwhere       = '';
784   my $glsumwhere    = '';
785   my $tofrom;
786   my ($fromdate, $todate);
787
788   if ($form->{fromdate} || $form->{todate}) {
789     if ($form->{fromdate}) {
790       $fromdate = conv_dateq($form->{fromdate});
791       $tofrom        .= " AND (ac.transdate >= $fromdate)";
792       $subwhere      .= " AND (ac.transdate >= $fromdate)";
793       $sumsubwhere   .= " AND (ac.transdate >= (select date_trunc('year', date $fromdate))) ";
794       $saldosubwhere .= " AND (ac,transdate>=(select date_trunc('year', date $fromdate)))  ";
795       $invwhere      .= " AND (a.transdate >= $fromdate)";
796       $glsaldowhere  .= " AND ac.transdate>=(select date_trunc('year', date $fromdate)) ";
797       $glwhere        = " AND (ac.transdate >= $fromdate)";
798       $glsumwhere     = " AND (ac.transdate >= (select date_trunc('year', date $fromdate))) ";
799     }
800     if ($form->{todate}) {
801       $todate = conv_dateq($form->{todate});
802       $tofrom        .= " AND (ac.transdate <= $todate)";
803       $invwhere      .= " AND (a.transdate <= $todate)";
804       $saldosubwhere .= " AND (ac.transdate <= $todate)";
805       $sumsubwhere   .= " AND (ac.transdate <= $todate)";
806       $subwhere      .= " AND (ac.transdate <= $todate)";
807       $glwhere       .= " AND (ac.transdate <= $todate)";
808       $glsumwhere    .= " AND (ac.transdate <= $todate) ";
809       $glsaldowhere  .= " AND (ac.transdate <= $todate) ";
810    }
811   }
812
813   if ($form->{method} eq "cash") {
814     $where .=
815       qq| AND(ac.trans_id IN (SELECT id FROM ar WHERE datepaid>= $fromdate AND datepaid<= $todate UNION SELECT id FROM ap WHERE datepaid>= $fromdate AND datepaid<= $todate UNION SELECT id FROM gl WHERE transdate>= $fromdate AND transdate<= $todate)) AND (NOT ac.ob_transaction OR ac.ob_transaction IS NULL) AND (NOT ac.cb_transaction OR ac.cb_transaction IS NULL) |;
816     $saldowhere .= qq| AND(ac.trans_id IN (SELECT id FROM ar WHERE datepaid>= $fromdate AND datepaid<= $todate UNION SELECT id FROM ap WHERE datepaid>= $fromdate AND datepaid<= $todate UNION SELECT id FROM gl WHERE transdate>= $fromdate AND transdate<= $todate))  AND (NOT ac.cb_transaction OR ac.cb_transaction IS NULL) |;
817
818     $sumwhere .= qq| AND(ac.trans_id IN (SELECT id FROM ar WHERE datepaid>= $fromdate AND datepaid<= $todate UNION SELECT id FROM ap WHERE datepaid>= $fromdate AND datepaid<= $todate UNION SELECT id FROM gl WHERE transdate>= $fromdate AND transdate<= $todate)) AND (NOT ac.ob_transaction OR ac.ob_transaction IS NULL) AND (NOT ac.cb_transaction OR ac.cb_transaction IS NULL) |;
819   } else {
820     $where .= $tofrom . " AND (NOT ac.ob_transaction OR ac.ob_transaction IS NULL) AND (NOT ac.cb_transaction OR ac.cb_transaction IS NULL)";
821     $saldowhere .= $glsaldowhere . " AND (NOT ac.cb_transaction OR ac.cb_transaction IS NULL)";
822     $sumwhere .= $glsumwhere . " AND (NOT ac.ob_transaction OR ac.ob_transaction IS NULL) AND (NOT ac.cb_transaction OR ac.cb_transaction IS NULL)";
823   }
824
825   $query = qq|
826        SELECT c.accno, c.description, c.category, SUM(ac.amount) AS amount
827        FROM acc_trans ac
828        JOIN chart c ON (c.id = ac.chart_id)
829        $dpt_join
830        WHERE $where
831          $dpt_where
832          $project
833        GROUP BY c.accno, c.description, c.category |;
834
835   if ($form->{project_id}) {
836     $query .= qq|
837       -- add project transactions from invoice
838
839       UNION ALL
840
841       SELECT c.accno, c.description, c.category, SUM(ac.sellprice * ac.qty) AS amount
842       FROM invoice ac
843       JOIN ar a ON (ac.trans_id = a.id)
844       JOIN parts p ON (ac.parts_id = p.id)
845       JOIN chart c ON (p.income_accno_id = c.id)
846       $dpt_join
847       WHERE $invwhere
848         $dpt_where
849         $project
850       GROUP BY c.accno, c.description, c.category
851
852       UNION ALL
853
854       SELECT c.accno, c.description, c.category, SUM(ac.sellprice * ac.qty) * -1 AS amount
855       FROM invoice ac
856       JOIN ap a ON (ac.trans_id = a.id)
857       JOIN parts p ON (ac.parts_id = p.id)
858       JOIN chart c ON (p.expense_accno_id = c.id)
859       $dpt_join
860       WHERE $invwhere
861         $dpt_where
862         $project
863       GROUP BY c.accno, c.description, c.category
864       |;
865     }
866
867   $query .= qq| ORDER BY accno|;
868
869   $sth = prepare_execute_query($form, $dbh, $query);
870
871   # calculate the debit and credit in the period
872   while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
873     $trb{ $ref->{accno} }{description} = $ref->{description};
874     $trb{ $ref->{accno} }{charttype}   = 'A';
875     $trb{ $ref->{accno} }{category}    = $ref->{category};
876     $trb{ $ref->{accno} }{amount} += $ref->{amount};
877   }
878   $sth->finish;
879
880   # prepare query for each account
881   my ($q_drcr, $drcr, $q_project_drcr, $project_drcr);
882
883   $q_drcr =
884     qq|SELECT
885          (SELECT SUM(ac.amount) * -1
886           FROM acc_trans ac
887           JOIN chart c ON (c.id = ac.chart_id)
888           $dpt_join
889           WHERE $where
890             $dpt_where
891             $project
892           AND (ac.amount < 0)
893           AND (c.accno = ?)) AS debit,
894
895          (SELECT SUM(ac.amount)
896           FROM acc_trans ac
897           JOIN chart c ON (c.id = ac.chart_id)
898           $dpt_join
899           WHERE $where
900             $dpt_where
901             $project
902           AND ac.amount > 0
903           AND c.accno = ?) AS credit,
904         (SELECT SUM(ac.amount)
905          FROM acc_trans ac
906          JOIN chart c ON (ac.chart_id = c.id)
907          $dpt_join
908          WHERE $saldowhere
909            $dpt_where
910            $project
911          AND c.accno = ? AND (NOT ac.ob_transaction OR ac.ob_transaction IS NULL)) AS saldo,
912
913         (SELECT SUM(ac.amount)
914          FROM acc_trans ac
915          JOIN chart c ON (ac.chart_id = c.id)
916          $dpt_join
917          WHERE $sumwhere
918            $dpt_where
919            $project
920          AND amount > 0
921          AND c.accno = ?) AS sum_credit,
922
923         (SELECT SUM(ac.amount)
924          FROM acc_trans ac
925          JOIN chart c ON (ac.chart_id = c.id)
926          $dpt_join
927          WHERE $sumwhere
928            $dpt_where
929            $project
930          AND amount < 0
931          AND c.accno = ?) AS sum_debit,
932
933         (SELECT max(ac.transdate) FROM acc_trans ac
934         JOIN chart c ON (ac.chart_id = c.id)
935         $dpt_join
936         WHERE $where
937           $dpt_where
938           $project
939         AND c.accno = ?) AS last_transaction
940
941
942  |;
943
944   $drcr = prepare_query($form, $dbh, $q_drcr);
945
946   if ($form->{project_id}) {
947     # prepare query for each account
948     $q_project_drcr =
949       qq|SELECT
950           (SELECT SUM(ac.sellprice * ac.qty) * -1
951            FROM invoice ac
952            JOIN parts p ON (ac.parts_id = p.id)
953            JOIN ap a ON (ac.trans_id = a.id)
954            JOIN chart c ON (p.expense_accno_id = c.id)
955            $dpt_join
956            WHERE $invwhere
957              $dpt_where
958              $project
959            AND c.accno = ?) AS debit,
960
961           (SELECT SUM(ac.sellprice * ac.qty)
962            FROM invoice ac
963            JOIN parts p ON (ac.parts_id = p.id)
964            JOIN ar a ON (ac.trans_id = a.id)
965            JOIN chart c ON (p.income_accno_id = c.id)
966            $dpt_join
967            WHERE $invwhere
968              $dpt_where
969              $project
970            AND c.accno = ?) AS credit,
971
972         (SELECT SUM(ac.amount)
973          FROM acc_trans ac
974          JOIN chart c ON (ac.chart_id = c.id)
975          $dpt_join
976          WHERE $saldowhere
977            $dpt_where
978            $project
979          AND c.accno = ? AND (NOT ac.ob_transaction OR ac.ob_transaction IS NULL)) AS saldo,
980
981         (SELECT SUM(ac.amount)
982          FROM acc_trans ac
983          JOIN chart c ON (ac.chart_id = c.id)
984          $dpt_join
985          WHERE $sumwhere
986            $dpt_where
987            $project
988          AND amount > 0
989          AND c.accno = ?) AS sum_credit,
990
991         (SELECT SUM(ac.amount)
992          FROM acc_trans ac
993          JOIN chart c ON (ac.chart_id = c.id)
994          $dpt_join
995          WHERE $sumwhere
996            $dpt_where
997            $project
998          AND amount < 0
999          AND c.accno = ?) AS sum_debit,
1000
1001
1002         (SELECT max(ac.transdate) FROM acc_trans ac
1003         JOIN chart c ON (ac.chart_id = c.id)
1004         $dpt_join
1005         WHERE $where
1006           $dpt_where
1007           $project
1008         AND c.accno = ?) AS last_transaction
1009  |;
1010
1011     $project_drcr = prepare_query($form, $dbh, $q_project_drcr);
1012   }
1013
1014
1015   my ($debit, $credit, $saldo, $soll_saldo, $haben_saldo,$soll_kummuliert, $haben_kummuliert, $last_transaction);
1016
1017   foreach my $accno (sort keys %trb) {
1018     $ref = {};
1019
1020     $ref->{accno} = $accno;
1021     map { $ref->{$_} = $trb{$accno}{$_} }
1022       qw(description category charttype amount soll_eb haben_eb beginning_balance);
1023
1024     $ref->{balance} = $form->round_amount($balance{ $ref->{accno} }, 2);
1025
1026     if ($trb{$accno}{charttype} eq 'A') {
1027
1028       # get DR/CR
1029       do_statement($form, $drcr, $q_drcr, $ref->{accno}, $ref->{accno}, $ref->{accno}, $ref->{accno}, $ref->{accno}, $ref->{accno});
1030
1031       ($debit, $credit, $saldo, $haben_saldo, $soll_saldo) = (0, 0, 0, 0, 0);
1032       my ($soll_kumuliert, $haben_kumuliert) = (0, 0);
1033       $last_transaction = "";
1034       while (($debit, $credit, $saldo, $haben_kumuliert, $soll_kumuliert, $last_transaction) = $drcr->fetchrow_array) {
1035         $ref->{debit}  += $debit;
1036         $ref->{credit} += $credit;
1037         if ($saldo >= 0) {
1038           $ref->{haben_saldo} += $saldo;
1039         } else {
1040           $ref->{soll_saldo} += $saldo * -1;
1041         }
1042         $ref->{last_transaction} = $last_transaction;
1043         $ref->{soll_kumuliert} = $soll_kumuliert * -1;
1044         $ref->{haben_kumuliert} = $haben_kumuliert;
1045       }
1046       $drcr->finish;
1047
1048       if ($form->{project_id}) {
1049
1050         # get DR/CR
1051         do_statement($form, $project_drcr, $q_project_drcr, $ref->{accno}, $ref->{accno}, $ref->{accno}, $ref->{accno}, $ref->{accno}, $ref->{accno});
1052
1053         ($debit, $credit) = (0, 0);
1054         while (($debit, $credit, $saldo, $haben_kumuliert, $soll_kumuliert, $last_transaction) = $project_drcr->fetchrow_array) {
1055           $ref->{debit}  += $debit;
1056           $ref->{credit} += $credit;
1057           if ($saldo >= 0) {
1058             $ref->{haben_saldo} += $saldo;
1059           } else {
1060             $ref->{soll_saldo} += $saldo * -1;
1061           }
1062           $ref->{soll_kumuliert} += $soll_kumuliert * -1;
1063           $ref->{haben_kumuliert} += $haben_kumuliert;
1064         }
1065         $project_drcr->finish;
1066       }
1067
1068       $ref->{debit}  = $form->round_amount($ref->{debit},  2);
1069       $ref->{credit} = $form->round_amount($ref->{credit}, 2);
1070
1071       if ($ref->{haben_saldo} != 0) {
1072         $ref->{haben_saldo}  = $ref->{haben_saldo} + $ref->{beginning_balance};
1073         if ($ref->{haben_saldo} < 0) {
1074           $ref->{soll_saldo} = $form->round_amount(($ref->{haben_saldo} *- 1), 2);
1075           $ref->{haben_saldo} = 0;
1076         }
1077       } else {
1078         $ref->{soll_saldo} = $ref->{soll_saldo} - $ref->{beginning_balance};
1079         if ($ref->{soll_saldo} < 0) {
1080           $ref->{haben_saldo} = $form->round_amount(($ref->{soll_saldo} * -1), 2);
1081           $ref->{soll_saldo} = 0;
1082         }
1083      }
1084       $ref->{haben_saldo} = $form->round_amount($ref->{haben_saldo}, 2);
1085       $ref->{soll_saldo} = $form->round_amount($ref->{soll_saldo}, 2);
1086       $ref->{haben_kumuliert}  = $form->round_amount($ref->{haben_kumuliert},  2);
1087       $ref->{soll_kumuliert} = $form->round_amount($ref->{soll_kumuliert}, 2);
1088     }
1089
1090     # add subtotal
1091     my @accno;
1092     @accno = grep { $_ le "$ref->{accno}" } @headingaccounts;
1093     $accno = pop @accno;
1094     if ($accno) {
1095       $trb{$accno}{debit}  += $ref->{debit};
1096       $trb{$accno}{credit} += $ref->{credit};
1097       $trb{$accno}{soll_saldo}  += $ref->{soll_saldo};
1098       $trb{$accno}{haben_saldo} += $ref->{haben_saldo};
1099       $trb{$accno}{soll_kumuliert}  += $ref->{soll_kumuliert};
1100       $trb{$accno}{haben_kumuliert} += $ref->{haben_kumuliert};
1101     }
1102
1103     push @{ $form->{TB} }, $ref;
1104
1105   }
1106
1107   $dbh->disconnect;
1108
1109   # debits and credits for headings
1110   foreach my $accno (@headingaccounts) {
1111     foreach $ref (@{ $form->{TB} }) {
1112       if ($accno eq $ref->{accno}) {
1113         $ref->{debit}           = $trb{$accno}{debit};
1114         $ref->{credit}          = $trb{$accno}{credit};
1115         $ref->{soll_saldo}      = $trb{$accno}{soll_saldo};
1116         $ref->{haben_saldo}     = $trb{$accno}{haben_saldo};
1117         $ref->{soll_kumuliert}  = $trb{$accno}{soll_kumuliert};
1118         $ref->{haben_kumuliert} = $trb{$accno}{haben_kumuliert};
1119       }
1120     }
1121   }
1122
1123   $main::lxdebug->leave_sub();
1124 }
1125
1126 sub get_storno {
1127   $main::lxdebug->enter_sub();
1128   my ($self, $dbh, $form) = @_;
1129   my $arap = $form->{arap} eq "ar" ? "ar" : "ap";
1130   my $query = qq|SELECT invnumber FROM $arap WHERE invnumber LIKE "Storno zu "|;
1131   my $sth =  $dbh->prepare($query);
1132   while(my $ref = $sth->fetchrow_hashref()) {
1133     $ref->{invnumer} =~ s/Storno zu //g;
1134     $form->{storno}{$ref->{invnumber}} = 1;
1135   }
1136   $main::lxdebug->leave_sub();
1137 }
1138
1139 sub aging {
1140   $main::lxdebug->enter_sub();
1141
1142   my ($self, $myconfig, $form) = @_;
1143
1144   # connect to database
1145   my $dbh     = $form->dbconnect($myconfig);
1146
1147   my ($invoice, $arap, $buysell, $ct, $ct_id, $ml);
1148
1149   if ($form->{ct} eq "customer") {
1150     $invoice = "is";
1151     $arap = "ar";
1152     $buysell = "buy";
1153     $ct = "customer";
1154     $ml = -1;
1155   } else {
1156     $invoice = "ir";
1157     $arap = "ap";
1158     $buysell = "sell";
1159     $ct = "vendor";
1160     $ml = 1;
1161   }
1162   $ct_id = "${ct}_id";
1163
1164   $form->{todate} = $form->current_date($myconfig) unless ($form->{todate});
1165   my $todate = conv_dateq($form->{todate});
1166   my $fromdate = conv_dateq($form->{fromdate});
1167
1168   my $fromwhere = ($form->{fromdate} ne "") ? " AND (transdate >= (date $fromdate)) " : "";
1169
1170   my $where = " 1 = 1 ";
1171   my ($name, $null);
1172
1173   if ($form->{$ct_id}) {
1174     $where .= qq| AND (ct.id = | . conv_i($form->{$ct_id}) . qq|)|;
1175   } elsif ($form->{ $form->{ct} }) {
1176     $where .= qq| AND (ct.name ILIKE | . $dbh->quote('%' . $form->{$ct} . '%') . qq|)|;
1177   }
1178
1179   my $dpt_join;
1180   if ($form->{department}) {
1181     my ($null, $department_id) = split /--/, $form->{department};
1182     $dpt_join = qq| JOIN department d ON (a.department_id = d.id) |;
1183     $where .= qq| AND (a.department_id = | . conv_i($department_id, 'NULL') . qq|)|;
1184   }
1185   my $review_of_aging_list;
1186   if ($form->{review_of_aging_list}) {
1187     if ($form->{review_of_aging_list} =~ m "-"){
1188       my @period = split(/-/, $form->{review_of_aging_list});
1189       $review_of_aging_list = " AND $period[0] < date_part('days', now() - duedate) 
1190                                 AND date_part('days', now() - duedate)  < $period[1]";
1191     } else {
1192       $form->{review_of_aging_list} =~ s/[^0-9]//g;
1193       $review_of_aging_list = " AND $form->{review_of_aging_list} < date_part('days', now() - duedate)"; 
1194     }
1195   }
1196
1197   my $q_details = qq|
1198
1199     SELECT ${ct}.id AS ctid, ${ct}.name,
1200       street, zipcode, city, country, contact, email,
1201       phone as customerphone, fax as customerfax, ${ct}number,
1202       "invnumber", "transdate",
1203       (amount - COALESCE((SELECT sum(amount)*$ml FROM acc_trans LEFT JOIN chart ON (acc_trans.chart_id=chart.id) WHERE link ilike '%paid%' AND acc_trans.trans_id=${arap}.id AND acc_trans.transdate <= (date $todate)),0)) as "open", "amount",
1204       "duedate", invoice, ${arap}.id,
1205       (SELECT $buysell
1206        FROM exchangerate
1207        WHERE (${arap}.curr = exchangerate.curr)
1208          AND (exchangerate.transdate = ${arap}.transdate)) AS exchangerate
1209     FROM ${arap}, ${ct}
1210     WHERE ((paid != amount) OR (datepaid > (date $todate) AND datepaid is not null))
1211       AND NOT COALESCE (${arap}.storno, 'f')
1212       AND (${arap}.${ct}_id = ${ct}.id)
1213       AND (${ct}.id = ?)
1214       AND (transdate <= (date $todate) $fromwhere )
1215       $review_of_aging_list
1216     ORDER BY ctid, transdate, invnumber |;
1217
1218   my $sth_details = prepare_query($form, $dbh, $q_details);
1219
1220   # select outstanding vendors or customers, depends on $ct
1221   my $query =
1222     qq|SELECT DISTINCT ct.id, ct.name
1223        FROM $ct ct, $arap a
1224        $dpt_join
1225        WHERE $where
1226          AND (a.${ct_id} = ct.id)
1227          AND ((a.paid != a.amount) OR ((a.datepaid > $todate) AND (datepaid is NOT NULL)))
1228          AND (a.transdate <= $todate $fromwhere)
1229        ORDER BY ct.name|;
1230
1231   my $sth = prepare_execute_query($form, $dbh, $query);
1232
1233   $form->{AG} = [];
1234   # for each company that has some stuff outstanding
1235   while (my ($id) = $sth->fetchrow_array) {
1236     do_statement($form, $sth_details, $q_details, $id);
1237
1238     while (my $ref = $sth_details->fetchrow_hashref("NAME_lc")) {
1239       $ref->{module} = ($ref->{invoice}) ? $invoice : $arap;
1240       $ref->{exchangerate} = 1 unless $ref->{exchangerate};
1241       push @{ $form->{AG} }, $ref;
1242     }
1243
1244     $sth_details->finish;
1245
1246   }
1247
1248   $sth->finish;
1249
1250   # disconnect
1251   $dbh->disconnect;
1252
1253   $main::lxdebug->leave_sub();
1254 }
1255
1256 sub get_customer {
1257   $main::lxdebug->enter_sub();
1258
1259   my ($self, $myconfig, $form) = @_;
1260
1261   # connect to database
1262   my $dbh = $form->dbconnect($myconfig);
1263
1264   my $ct = $form->{ct} eq "customer" ? "customer" : "vendor";
1265
1266   my $query =
1267     qq|SELECT ct.name, ct.email, ct.cc, ct.bcc
1268        FROM $ct ct
1269        WHERE ct.id = ?|;
1270   ($form->{ $form->{ct} }, $form->{email}, $form->{cc}, $form->{bcc}) =
1271     selectrow_query($form, $dbh, $query, $form->{"${ct}_id"});
1272   $dbh->disconnect;
1273
1274   $main::lxdebug->leave_sub();
1275 }
1276
1277 sub get_taxaccounts {
1278   $main::lxdebug->enter_sub();
1279
1280   my ($self, $myconfig, $form) = @_;
1281
1282   # connect to database
1283   my $dbh = $form->dbconnect($myconfig);
1284
1285   # get tax accounts
1286   my $query =
1287     qq|SELECT c.accno, c.description, t.rate
1288        FROM chart c, tax t
1289        WHERE (c.link LIKE '%CT_tax%') AND (c.id = t.chart_id)
1290        ORDER BY c.accno|;
1291   $form->{taxaccounts} = selectall_hashref_quert($form, $dbh, $query);
1292
1293   $dbh->disconnect;
1294
1295   $main::lxdebug->leave_sub();
1296 }
1297
1298 sub tax_report {
1299   $main::lxdebug->enter_sub();
1300
1301   my ($self, $myconfig, $form) = @_;
1302
1303   # connect to database
1304   my $dbh = $form->dbconnect($myconfig);
1305
1306   my ($null, $department_id) = split /--/, $form->{department};
1307
1308   # build WHERE
1309   my $where = "1 = 1";
1310
1311   if ($department_id) {
1312     $where .= qq| AND (a.department_id = | . conv_i($department_id, 'NULL') . qq|) |;
1313   }
1314
1315   my ($accno, $rate);
1316
1317   if ($form->{accno}) {
1318     $accno = $form->{accno};
1319     $rate  = $form->{"$form->{accno}_rate"};
1320     $accno = qq| AND (ch.accno = | . $dbh->quote($accno) . qq|)|;
1321   }
1322   $rate *= 1;
1323
1324   my ($table, $ARAP);
1325
1326   if ($form->{db} eq 'ar') {
1327     $table = "customer";
1328     $ARAP  = "AR";
1329   } else {
1330     $table = "vendor";
1331     $ARAP  = "AP";
1332   }
1333
1334   my $arap = lc($ARAP);
1335
1336   my $transdate = "a.transdate";
1337
1338   if ($form->{method} eq 'cash') {
1339     $transdate = "a.datepaid";
1340
1341     my $todate = conv_dateq($form->{todate} ? $form->{todate} : $form->current_date($myconfig));
1342
1343     $where .= qq|
1344       AND ac.trans_id IN
1345         (
1346           SELECT trans_id
1347           FROM acc_trans a
1348           JOIN chart c ON (a.chart_id = c.id)
1349           WHERE (link LIKE '%${ARAP}_paid%')
1350           AND (transdate <= $todate)
1351         )
1352       |;
1353   }
1354
1355   # if there are any dates construct a where
1356   $where .= " AND ($transdate >= " . conv_dateq($form->{fromdate}) . ") " if ($form->{fromdate});
1357   $where .= " AND ($transdate <= " . conv_dateq($form->{todate}) . ") " if ($form->{todate});
1358
1359   my $ml = ($form->{db} eq 'ar') ? 1 : -1;
1360
1361   my $sortorder = join ', ', $form->sort_columns(qw(transdate invnumber name));
1362   $sortorder = $form->{sort} if ($form->{sort} && grep({ $_ eq $form->{sort} } qw(id transdate invnumber name netamount tax)));
1363
1364   my $query = '';
1365   if ($form->{report} !~ /nontaxable/) {
1366     $query =
1367       qq|SELECT a.id, '0' AS invoice, $transdate AS transdate, a.invnumber, n.name, a.netamount,
1368           ac.amount * $ml AS tax
1369          FROM acc_trans ac
1370          JOIN ${arap} a ON (a.id = ac.trans_id)
1371          JOIN chart ch ON (ch.id = ac.chart_id)
1372          JOIN $table n ON (n.id = a.${table}_id)
1373          WHERE
1374            $where
1375            $accno
1376            AND (a.invoice = '0')
1377
1378          UNION
1379
1380          SELECT a.id, '1' AS invoice, $transdate AS transdate, a.invnumber, n.name, i.sellprice * i.qty AS netamount,
1381            i.sellprice * i.qty * $rate * $ml AS tax
1382          FROM acc_trans ac
1383          JOIN ${arap} a ON (a.id = ac.trans_id)
1384          JOIN chart ch ON (ch.id = ac.chart_id)
1385          JOIN $table n ON (n.id = a.${table}_id)
1386          JOIN ${table}tax t ON (t.${table}_id = n.id)
1387          JOIN invoice i ON (i.trans_id = a.id)
1388          JOIN partstax p ON (p.parts_id = i.parts_id)
1389          WHERE
1390            $where
1391            $accno
1392            AND (a.invoice = '1')
1393          ORDER BY $sortorder|;
1394   } else {
1395     # only gather up non-taxable transactions
1396     $query =
1397       qq|SELECT a.id, '0' AS invoice, $transdate AS transdate, a.invnumber, n.name, a.netamount
1398          FROM acc_trans ac
1399          JOIN ${arap} a ON (a.id = ac.trans_id)
1400          JOIN $table n ON (n.id = a.${table}_id)
1401          WHERE
1402            $where
1403            AND (a.invoice = '0')
1404            AND (a.netamount = a.amount)
1405
1406          UNION
1407
1408          SELECT a.id, '1' AS invoice, $transdate AS transdate, a.invnumber, n.name, i.sellprice * i.qty AS netamount
1409          FROM acc_trans ac
1410          JOIN ${arap} a ON (a.id = ac.trans_id)
1411          JOIN $table n ON (n.id = a.${table}_id)
1412          JOIN invoice i ON (i.trans_id = a.id)
1413          WHERE
1414            $where
1415            AND (a.invoice = '1')
1416            AND (
1417              a.${table}_id NOT IN (SELECT ${table}_id FROM ${table}tax t (${table}_id))
1418              OR
1419              i.parts_id NOT IN (SELECT parts_id FROM partstax p (parts_id))
1420            )
1421          GROUP BY a.id, a.invnumber, $transdate, n.name, i.sellprice, i.qty
1422          ORDER by $sortorder|;
1423   }
1424
1425   $form->{TR} = selectall_hashref_query($form, $dbh, $query);
1426
1427   $dbh->disconnect;
1428
1429   $main::lxdebug->leave_sub();
1430 }
1431
1432 sub paymentaccounts {
1433   $main::lxdebug->enter_sub();
1434
1435   my ($self, $myconfig, $form) = @_;
1436
1437   # connect to database, turn AutoCommit off
1438   my $dbh = $form->dbconnect_noauto($myconfig);
1439
1440   my $ARAP = $form->{db} eq "ar" ? "AR" : "AP";
1441
1442   # get A(R|P)_paid accounts
1443   my $query =
1444     qq|SELECT accno, description
1445        FROM chart
1446        WHERE link LIKE '%${ARAP}_paid%'|;
1447   $form->{PR} = selectall_hashref_query($form, $dbh, $query);
1448
1449   $dbh->disconnect;
1450
1451   $main::lxdebug->leave_sub();
1452 }
1453
1454 sub payments {
1455   $main::lxdebug->enter_sub();
1456
1457   my ($self, $myconfig, $form) = @_;
1458
1459   # connect to database, turn AutoCommit off
1460   my $dbh = $form->dbconnect_noauto($myconfig);
1461
1462   my $ml = 1;
1463   my $arap;
1464   my $table;
1465   if ($form->{db} eq 'ar') {
1466     $table = 'customer';
1467     $ml = -1;
1468     $arap = 'ar';
1469   } else {
1470     $table = 'vendor';
1471     $arap = 'ap';
1472   }
1473
1474   my ($query, $sth);
1475   my $dpt_join;
1476   my $where;
1477
1478   if ($form->{department_id}) {
1479     $dpt_join = qq| JOIN dpt_trans t ON (t.trans_id = ac.trans_id) |;
1480     $where = qq| AND (t.department_id = | . conv_i($form->{department_id}, 'NULL') . qq|) |;
1481   }
1482
1483   if ($form->{fromdate}) {
1484     $where .= " AND (ac.transdate >= " . $dbh->quote($form->{fromdate}) . ") ";
1485   }
1486   if ($form->{todate}) {
1487     $where .= " AND (ac.transdate <= " . $dbh->quote($form->{todate}) . ") ";
1488   }
1489   if (!$form->{fx_transaction}) {
1490     $where .= " AND ac.fx_transaction = '0'";
1491   }
1492
1493   my $invnumber;
1494   my $reference;
1495   if ($form->{reference}) {
1496     $reference = $dbh->quote('%' . $form->{reference} . '%');
1497     $invnumber = " AND (a.invnumber LIKE $reference)";
1498     $reference = " AND (g.reference LIKE $reference)";
1499   }
1500   if ($form->{source}) {
1501     $where .= " AND (ac.source ILIKE " . $dbh->quote('%' . $form->{source} . '%') . ") ";
1502   }
1503   if ($form->{memo}) {
1504     $where .= " AND (ac.memo ILIKE " . $dbh->quote('%' . $form->{memo} . '%') . ") ";
1505   }
1506
1507   my %sort_columns =  (
1508     'transdate'    => [ qw(transdate lower_invnumber lower_name) ],
1509     'invnumber'    => [ qw(lower_invnumber lower_name transdate) ],
1510     'name'         => [ qw(lower_name transdate)                 ],
1511     'source'       => [ qw(lower_source)                         ],
1512     'memo'         => [ qw(lower_memo)                           ],
1513     );
1514   my %lowered_columns =  (
1515     'invnumber'       => { 'gl' => 'g.reference',   'arap' => 'a.invnumber', },
1516     'memo'            => { 'gl' => 'ac.memo',       'arap' => 'ac.memo',     },
1517     'source'          => { 'gl' => 'ac.source',     'arap' => 'ac.source',   },
1518     'name'            => { 'gl' => 'g.description', 'arap' => 'c.name',      },
1519     );
1520
1521   my $sortdir   = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
1522   my $sortkey   = $sort_columns{$form->{sort}} ? $form->{sort} : 'transdate';
1523   my $sortorder = join ', ', map { "$_ $sortdir" } @{ $sort_columns{$sortkey} };
1524
1525
1526   my %columns_for_sorting = ( 'gl' => '', 'arap' => '', );
1527   foreach my $spec (@{ $sort_columns{$sortkey} }) {
1528     next if ($spec !~ m/^lower_(.*)$/);
1529
1530     my $column = $1;
1531     map { $columns_for_sorting{$_} .= sprintf(', lower(%s) AS lower_%s', $lowered_columns{$column}->{$_}, $column) } qw(gl arap);
1532   }
1533
1534   $query = qq|SELECT id, accno, description FROM chart WHERE accno = ?|;
1535   $sth = prepare_query($form, $dbh, $query);
1536
1537   my $q_details =
1538       qq|SELECT c.name, a.invnumber, a.ordnumber,
1539            ac.transdate, ac.amount * $ml AS paid, ac.source,
1540            a.invoice, a.id, ac.memo, '${arap}' AS module
1541            $columns_for_sorting{arap}
1542          FROM acc_trans ac
1543          JOIN $arap a ON (ac.trans_id = a.id)
1544          JOIN $table c ON (c.id = a.${table}_id)
1545          $dpt_join
1546          WHERE (ac.chart_id = ?)
1547            $where
1548            $invnumber
1549
1550          UNION
1551
1552          SELECT g.description, g.reference, NULL AS ordnumber,
1553            ac.transdate, ac.amount * $ml AS paid, ac.source,
1554            '0' as invoice, g.id, ac.memo, 'gl' AS module
1555            $columns_for_sorting{gl}
1556          FROM acc_trans ac
1557          JOIN gl g ON (g.id = ac.trans_id)
1558          $dpt_join
1559          WHERE (ac.chart_id = ?)
1560            $where
1561            $reference
1562            AND (ac.amount * $ml) > 0
1563
1564          ORDER BY $sortorder|;
1565   my $sth_details = prepare_query($form, $dbh, $q_details);
1566
1567   $form->{PR} = [];
1568
1569   # cycle through each id
1570   foreach my $accno (split(/ /, $form->{paymentaccounts})) {
1571     do_statement($form, $sth, $query, $accno);
1572     my $ref = $sth->fetchrow_hashref();
1573     push(@{ $form->{PR} }, $ref);
1574     $sth->finish();
1575
1576     $form->{ $ref->{id} } = [] unless ($form->{ $ref->{id} });
1577
1578     do_statement($form, $sth_details, $q_details, $ref->{id}, $ref->{id});
1579     while (my $pr = $sth_details->fetchrow_hashref()) {
1580       push(@{ $form->{ $ref->{id} } }, $pr);
1581     }
1582     $sth_details->finish();
1583   }
1584
1585   $dbh->disconnect;
1586
1587   $main::lxdebug->leave_sub();
1588 }
1589
1590 sub bwa {
1591   $main::lxdebug->enter_sub();
1592
1593   my ($self, $myconfig, $form) = @_;
1594
1595   # connect to database
1596   my $dbh = $form->dbconnect($myconfig);
1597
1598   my $last_period = 0;
1599   my $category;
1600   my @categories  =
1601     qw(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40);
1602
1603   $form->{decimalplaces} *= 1;
1604
1605   &get_accounts_g($dbh, $last_period, $form->{fromdate}, $form->{todate}, $form, "pos_bwa");
1606
1607   # if there are any compare dates
1608   my $year;
1609   if ($form->{fromdate} || $form->{todate}) {
1610     $last_period = 1;
1611     if ($form->{fromdate}) {
1612       $form->{fromdate} =~ /[0-9]*\.[0-9]*\.([0-9]*)/;
1613       $year = $1;
1614     } else {
1615       $form->{todate} =~ /[0-9]*\.[0-9]*\.([0-9]*)/;
1616       $year = $1;
1617     }
1618     my $kummfromdate = $form->{comparefromdate};
1619     my $kummtodate   = $form->{comparetodate};
1620     &get_accounts_g($dbh, $last_period, $kummfromdate, $kummtodate, $form, "pos_bwa");
1621   }
1622
1623   my @periods        = qw(jetzt kumm);
1624   my @gesamtleistung = qw(1 3);
1625   my @gesamtkosten   = qw (10 11 12 13 14 15 16 17 18 19 20);
1626   my @ergebnisse     =
1627     qw (rohertrag betriebrohertrag betriebsergebnis neutraleraufwand neutralerertrag ergebnisvorsteuern ergebnis gesamtleistung gesamtkosten);
1628
1629   foreach my $key (@periods) {
1630     $form->{ "$key" . "gesamtleistung" } = 0;
1631     $form->{ "$key" . "gesamtkosten" }   = 0;
1632
1633     foreach $category (@categories) {
1634
1635       if (defined($form->{$category}{$key})) {
1636         $form->{"$key$category"} =
1637           $form->format_amount($myconfig,
1638                                $form->round_amount($form->{$category}{$key}, 2
1639                                ),
1640                                $form->{decimalplaces},
1641                                '0');
1642       }
1643     }
1644     foreach my $item (@gesamtleistung) {
1645       $form->{ "$key" . "gesamtleistung" } += $form->{$item}{$key};
1646     }
1647     $form->{ "$key" . "gesamtleistung" } -= $form->{2}{$key};
1648
1649     foreach my $item (@gesamtkosten) {
1650       $form->{ "$key" . "gesamtkosten" } += $form->{$item}{$key};
1651     }
1652     $form->{ "$key" . "rohertrag" } =
1653       $form->{ "$key" . "gesamtleistung" } - $form->{4}{$key};
1654     $form->{ "$key" . "betriebrohertrag" } =
1655       $form->{ "$key" . "rohertrag" } + $form->{5}{$key};
1656     $form->{ "$key" . "betriebsergebnis" } =
1657       $form->{ "$key" . "betriebrohertrag" } -
1658       $form->{ "$key" . "gesamtkosten" };
1659     $form->{ "$key" . "neutraleraufwand" } =
1660       $form->{30}{$key} + $form->{31}{$key};
1661     $form->{ "$key" . "neutralertrag" } =
1662       $form->{32}{$key} + $form->{33}{$key} + $form->{34}{$key};
1663     $form->{ "$key" . "ergebnisvorsteuern" } =
1664       $form->{ "$key" . "betriebsergebnis" } -
1665       $form->{ "$key" . "neutraleraufwand" } +
1666       $form->{ "$key" . "neutralertrag" };
1667     $form->{ "$key" . "ergebnis" } =
1668       $form->{ "$key" . "ergebnisvorsteuern" } - $form->{35}{$key};
1669
1670     if ($form->{ "$key" . "gesamtleistung" } > 0) {
1671       foreach $category (@categories) {
1672         if (defined($form->{$category}{$key})) {
1673           $form->{ "$key" . "gl" . "$category" } =
1674             $form->format_amount(
1675                                $myconfig,
1676                                $form->round_amount(
1677                                  ($form->{$category}{$key} /
1678                                     $form->{ "$key" . "gesamtleistung" } * 100
1679                                  ),
1680                                  $form->{decimalplaces}
1681                                ),
1682                                $form->{decimalplaces},
1683                                '0');
1684         }
1685       }
1686       foreach my $item (@ergebnisse) {
1687         $form->{ "$key" . "gl" . "$item" } =
1688           $form->format_amount($myconfig,
1689                                $form->round_amount(
1690                                  ( $form->{ "$key" . "$item" } /
1691                                      $form->{ "$key" . "gesamtleistung" } * 100
1692                                  ),
1693                                  $form->{decimalplaces}
1694                                ),
1695                                $form->{decimalplaces},
1696                                '0');
1697       }
1698     }
1699
1700     if ($form->{ "$key" . "gesamtkosten" } > 0) {
1701       foreach $category (@categories) {
1702         if (defined($form->{$category}{$key})) {
1703           $form->{ "$key" . "gk" . "$category" } =
1704             $form->format_amount($myconfig,
1705                                  $form->round_amount(
1706                                    ($form->{$category}{$key} /
1707                                       $form->{ "$key" . "gesamtkosten" } * 100
1708                                    ),
1709                                    $form->{decimalplaces}
1710                                  ),
1711                                  $form->{decimalplaces},
1712                                  '0');
1713         }
1714       }
1715       foreach my $item (@ergebnisse) {
1716         $form->{ "$key" . "gk" . "$item" } =
1717           $form->format_amount($myconfig,
1718                                $form->round_amount(
1719                                    ($form->{ "$key" . "$item" } /
1720                                       $form->{ "$key" . "gesamtkosten" } * 100
1721                                    ),
1722                                    $form->{decimalplaces}
1723                                ),
1724                                $form->{decimalplaces},
1725                                '0');
1726       }
1727     }
1728
1729     if ($form->{10}{$key} > 0) {
1730       foreach $category (@categories) {
1731         if (defined($form->{$category}{$key})) {
1732           $form->{ "$key" . "pk" . "$category" } =
1733             $form->format_amount(
1734                         $myconfig,
1735                         $form->round_amount(
1736                           ($form->{$category}{$key} / $form->{10}{$key} * 100),
1737                           $form->{decimalplaces}
1738                         ),
1739                         $form->{decimalplaces},
1740                         '0');
1741         }
1742       }
1743       foreach my $item (@ergebnisse) {
1744         $form->{ "$key" . "pk" . "$item" } =
1745           $form->format_amount($myconfig,
1746                                $form->round_amount(
1747                                                 ($form->{ "$key" . "$item" } /
1748                                                    $form->{10}{$key} * 100
1749                                                 ),
1750                                                 $form->{decimalplaces}
1751                                ),
1752                                $form->{decimalplaces},
1753                                '0');
1754       }
1755     }
1756
1757     if ($form->{4}{$key} > 0) {
1758       foreach $category (@categories) {
1759         if (defined($form->{$category}{$key})) {
1760           $form->{ "$key" . "auf" . "$category" } =
1761             $form->format_amount(
1762                          $myconfig,
1763                          $form->round_amount(
1764                            ($form->{$category}{$key} / $form->{4}{$key} * 100),
1765                            $form->{decimalplaces}
1766                          ),
1767                          $form->{decimalplaces},
1768                          '0');
1769         }
1770       }
1771       foreach my $item (@ergebnisse) {
1772         $form->{ "$key" . "auf" . "$item" } =
1773           $form->format_amount($myconfig,
1774                                $form->round_amount(
1775                                                 ($form->{ "$key" . "$item" } /
1776                                                    $form->{4}{$key} * 100
1777                                                 ),
1778                                                 $form->{decimalplaces}
1779                                ),
1780                                $form->{decimalplaces},
1781                                '0');
1782       }
1783     }
1784
1785     foreach my $item (@ergebnisse) {
1786       $form->{ "$key" . "$item" } =
1787         $form->format_amount($myconfig,
1788                              $form->round_amount($form->{ "$key" . "$item" },
1789                                                  $form->{decimalplaces}
1790                              ),
1791                              $form->{decimalplaces},
1792                              '0');
1793     }
1794
1795   }
1796   $dbh->disconnect;
1797
1798   $main::lxdebug->leave_sub();
1799 }
1800
1801 sub ustva {
1802   $main::lxdebug->enter_sub();
1803
1804   my ($self, $myconfig, $form) = @_;
1805
1806   # connect to database
1807   my $dbh = $form->dbconnect($myconfig);
1808
1809   my $last_period     = 0;
1810   my @categories_cent = qw(51r 511 86r 861 97r 971 93r 931
1811     96 66 43 45 53 62 65 67);
1812   my @categories_euro = qw(48 51 86 91 97 93 94);
1813   $form->{decimalplaces} *= 1;
1814
1815   foreach my $item (@categories_cent) {
1816     $form->{"$item"} = 0;
1817   }
1818   foreach my $item (@categories_euro) {
1819     $form->{"$item"} = 0;
1820   }
1821
1822   &get_accounts_g($dbh, $last_period, $form->{fromdate}, $form->{todate}, $form, "pos_ustva");
1823
1824   #   foreach $item (@categories_cent) {
1825   #     if ($form->{$item}{"jetzt"} > 0) {
1826   #       $form->{$item} = $form->{$item}{"jetzt"};
1827   #       delete $form->{$item}{"jetzt"};
1828   #     }
1829   #   }
1830   #   foreach $item (@categories_euro) {
1831   #     if ($form->{$item}{"jetzt"} > 0) {
1832   #       $form->{$item} = $form->{$item}{"jetzt"};
1833   #       delete $form->{$item}{"jetzt"};
1834   #     }  foreach $item (@categories_cent) {
1835   #     if ($form->{$item}{"jetzt"} > 0) {
1836   #       $form->{$item} = $form->{$item}{"jetzt"};
1837   #       delete $form->{$item}{"jetzt"};
1838   #     }
1839   #   }
1840   #   foreach $item (@categories_euro) {
1841   #     if ($form->{$item}{"jetzt"} > 0) {
1842   #       $form->{$item} = $form->{$item}{"jetzt"};
1843   #       delete $form->{$item}{"jetzt"};
1844   #     }
1845   #   }
1846   #
1847   #    }
1848
1849   #
1850   # Berechnung der USTVA Formularfelder
1851   #
1852   $form->{"51r"} = $form->{"511"};
1853   $form->{"86r"} = $form->{"861"};
1854   $form->{"97r"} = $form->{"971"};
1855   $form->{"93r"} = $form->{"931"};
1856
1857   #$form->{"96"}  = $form->{"94"} * 0.16;
1858   $form->{"43"} =
1859     $form->{"51r"} + $form->{"86r"} + $form->{"97r"} + $form->{"93r"} +
1860     $form->{"96"};
1861   $form->{"45"} = $form->{"43"};
1862   $form->{"53"} = $form->{"43"};
1863   $form->{"62"} = $form->{"43"} - $form->{"66"};
1864   $form->{"65"} = $form->{"43"} - $form->{"66"};
1865   $form->{"67"} = $form->{"43"} - $form->{"66"};
1866
1867   foreach my $item (@categories_cent) {
1868     $form->{$item} =
1869       $form->format_amount($myconfig, $form->round_amount($form->{$item}, 2),
1870                            2, '0');
1871   }
1872
1873   foreach my $item (@categories_euro) {
1874     $form->{$item} =
1875       $form->format_amount($myconfig, $form->round_amount($form->{$item}, 0),
1876                            0, '0');
1877   }
1878
1879   $dbh->disconnect;
1880
1881   $main::lxdebug->leave_sub();
1882 }
1883
1884 sub income_statement {
1885   $main::lxdebug->enter_sub();
1886
1887   my ($self, $myconfig, $form) = @_;
1888
1889   # connect to database
1890   my $dbh = $form->dbconnect($myconfig);
1891
1892   my $last_period          = 0;
1893   my @categories_einnahmen = qw(1 2 3 4 5 6 7);
1894   my @categories_ausgaben  =
1895     qw(8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31);
1896
1897   my @ergebnisse = qw(sumeura sumeurb guvsumme);
1898
1899   $form->{decimalplaces} *= 1;
1900
1901
1902
1903   &get_accounts_g($dbh, $last_period, $form->{fromdate}, $form->{todate},
1904                   $form, "pos_eur");
1905
1906
1907   foreach my $item (@categories_einnahmen) {
1908     $form->{"eur${item}"} =
1909       $form->format_amount($myconfig, $form->round_amount($form->{$item}, 2),2);
1910     $form->{"sumeura"} += $form->{$item};
1911   }
1912   foreach my $item (@categories_ausgaben) {
1913     $form->{"eur${item}"} =
1914       $form->format_amount($myconfig, $form->round_amount($form->{$item}, 2),2);
1915     $form->{"sumeurb"} += $form->{$item};
1916   }
1917
1918   $form->{"guvsumme"} = $form->{"sumeura"} - $form->{"sumeurb"};
1919
1920   foreach my $item (@ergebnisse) {
1921     $form->{$item} =
1922       $form->format_amount($myconfig, $form->round_amount($form->{$item}, 2),2);
1923   }
1924   $main::lxdebug->leave_sub();
1925 }
1926 1;