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