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