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