Kontenuebersicht und Kontenblatt angepasst, so dass auch bei EUR korrekte Werte angez...
[kivitendo-erp.git] / bin / mozilla / ca.pl
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) 2001
10 #
11 #  Author: Dieter Simader
12 #   Email: dsimader@sql-ledger.org
13 #     Web: http://www.sql-ledger.org
14 #
15 #
16 # This program is free software; you can redistribute it and/or modify
17 # it under the terms of the GNU General Public License as published by
18 # the Free Software Foundation; either version 2 of the License, or
19 # (at your option) any later version.
20 #
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 # GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #======================================================================
29 #
30 # module for Chart of Accounts, Income Statement and Balance Sheet
31 # search and edit transactions posted by the GL, AR and AP
32 #
33 #======================================================================
34
35 use POSIX qw(strftime);
36
37 use SL::CA;
38 use SL::ReportGenerator;
39
40 require "bin/mozilla/reportgenerator.pl";
41
42 1;
43
44 # end of main
45
46 # this is for our long dates
47 # $locale->text('January')
48 # $locale->text('February')
49 # $locale->text('March')
50 # $locale->text('April')
51 # $locale->text('May ')
52 # $locale->text('June')
53 # $locale->text('July')
54 # $locale->text('August')
55 # $locale->text('September')
56 # $locale->text('October')
57 # $locale->text('November')
58 # $locale->text('December')
59
60 # this is for our short month
61 # $locale->text('Jan')
62 # $locale->text('Feb')
63 # $locale->text('Mar')
64 # $locale->text('Apr')
65 # $locale->text('May')
66 # $locale->text('Jun')
67 # $locale->text('Jul')
68 # $locale->text('Aug')
69 # $locale->text('Sep')
70 # $locale->text('Oct')
71 # $locale->text('Nov')
72 # $locale->text('Dec')
73
74 sub chart_of_accounts {
75   $lxdebug->enter_sub();
76
77   $auth->assert('report');
78
79   $form->{title} = $locale->text('Chart of Accounts');
80
81   if ($eur) {
82     $form->{method} = "cash";
83   }
84
85   CA->all_accounts(\%myconfig, \%$form);
86
87   my @columns     = qw(accno description debit credit);
88   my %column_defs = (
89     'accno'       => { 'text' => $locale->text('Account'), },
90     'description' => { 'text' => $locale->text('Description'), },
91     'debit'       => { 'text' => $locale->text('Debit'), },
92     'credit'      => { 'text' => $locale->text('Credit'), },
93   );
94
95   my $report = SL::ReportGenerator->new(\%myconfig, $form);
96
97   $report->set_options('output_format'         => 'HTML',
98                        'title'                 => $form->{title},
99                        'attachment_basename'   => $locale->text('chart_of_accounts') . strftime('_%Y%m%d', localtime time),
100                        'std_column_visibility' => 1,
101     );
102   $report->set_options_from_form();
103
104   $report->set_columns(%column_defs);
105   $report->set_column_order(@columns);
106
107   $report->set_export_options('chart_of_accounts');
108
109   $report->set_sort_indicator($form->{sort}, 1);
110
111   my %totals = ('debit' => 0, 'credit' => 0);
112
113   foreach my $ca (@{ $form->{CA} }) {
114     next unless defined $ca->{amount};
115     my $row = { };
116
117     foreach (qw(debit credit)) {
118       $totals{$_} += $ca->{$_} * 1;
119       $ca->{$_}    = $form->format_amount(\%myconfig, $ca->{$_}, 2) if ($ca->{$_});
120     }
121
122     map { $row->{$_} = { 'data' => $ca->{$_} } } @columns;
123
124     map { $row->{$_}->{align} = 'right'       } qw(debit credit);
125     map { $row->{$_}->{class} = 'listheading' } @columns if ($ca->{charttype} eq "H");
126
127     $row->{accno}->{link} = build_std_url('action=list', 'accno=' . E($ca->{accno}), 'description=' . E($ca->{description}));
128
129     $report->add_data($row);
130   }
131
132   my $row = { map { $_ => { 'class' => 'listtotal', 'align' => 'right' } } @columns };
133   map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals{$_}, 2) } qw(debit credit);
134
135   $report->add_separator();
136   $report->add_data($row);
137
138   $report->generate_with_headers();
139
140   $lxdebug->leave_sub();
141 }
142
143 sub list {
144   $lxdebug->enter_sub();
145
146   $auth->assert('report');
147
148   $form->{title} = $locale->text('List Transactions');
149   $form->{title} .= " - " . $locale->text('Account') . " $form->{accno}";
150   $year = (localtime)[5] + 1900;
151
152   # get departments
153   $form->all_departments(\%myconfig);
154   if (@{ $form->{all_departments} }) {
155     $form->{selectdepartment} = "<option>\n";
156
157     map {
158       $form->{selectdepartment} .=
159         "<option>$_->{description}--$_->{id}\n"
160     } (@{ $form->{all_departments} });
161   }
162
163   $department = qq|
164         <tr>
165           <th align=right nowrap>| . $locale->text('Department') . qq|</th>
166           <td colspan=3><select name=department>$form->{selectdepartment}</select></td>
167         </tr>
168 | if $form->{selectdepartment};
169   $accrual = ($eur) ? ""        : "checked";
170   $cash    = ($eur) ? "checked" : "";
171
172   $name_1    = "fromdate";
173   $id_1      = "fromdate";
174   $value_1   = "$form->{fromdate}";
175   $trigger_1 = "trigger1";
176   $name_2    = "todate";
177   $id_2      = "todate";
178   $value_2   = "";
179   $trigger_2 = "trigger2";
180
181
182   # with JavaScript Calendar
183   if ($form->{jsscript}) {
184     if ($name_1 eq "") {
185
186       $button1 = qq|
187          <input name=$name_2 id=$id_2 size=11 title="$myconfig{dateformat}" onBlur=\"check_right_date_format(this)\">|;
188       $button1_2 = qq|
189         <input type=button name=$name_2 id="$trigger_2" value=|
190         . $locale->text('button') . qq|>|;
191
192       #write Trigger
193       $jsscript =
194         Form->write_trigger(\%myconfig, "1", "$name_2", "BR", "$trigger_2");
195     } else {
196       $button1 = qq|
197          <input name=$name_1 id=$id_1 size=11 title="$myconfig{dateformat}" onBlur=\"check_right_date_format(this)\" value="$value_1">|;
198       $button1_2 = qq|
199         <input type=button name=$name_1 id="$trigger_1" value=|
200         . $locale->text('button') . qq|>|;
201       $button2 = qq|
202          <input name=$name_2 id=$id_2 size=11 title="$myconfig{dateformat}" onBlur=\"check_right_date_format(this)\">|;
203       $button2_2 = qq|
204          <input type=button name=$name_2 id="$trigger_2" value=|
205         . $locale->text('button') . qq|>
206        |;
207
208       #write Trigger
209       $jsscript =
210         Form->write_trigger(\%myconfig, "2", "$name_1", "BR", "$trigger_1",
211                             "$name_2", "BL", "$trigger_2");
212     }
213   } else {
214
215     # without JavaScript Calendar
216     if ($name_1 eq "") {
217       $button1 =
218         qq|<input name=$name_2 id=$id_2 size=11 title="$myconfig{dateformat}" onBlur=\"check_right_date_format(this)\">|;
219     } else {
220       $button1 =
221         qq|<input name=$name_1 id=$id_1 size=11 title="$myconfig{dateformat}" value="$value_1" onBlur=\"check_right_date_format(this)\">|;
222       $button2 =
223         qq|<input name=$name_2 id=$id_2 size=11 title="$myconfig{dateformat}" onBlur=\"check_right_date_format(this)\">|;
224     }
225   }
226   $form->{javascript} .= qq|<script type="text/javascript" src="js/common.js"></script>|;
227   $form->header;
228   $onload = qq|focus()|;
229   $onload .= qq|;setupDateFormat('|. $myconfig{dateformat} .qq|', '|. $locale->text("Falsches Datumsformat!") .qq|')|;
230   $onload .= qq|;setupPoints('|. $myconfig{numberformat} .qq|', '|. $locale->text("wrongformat") .qq|')|;
231
232
233   $form->header;
234
235   $form->{description} =~ s/\"/&quot;/g;
236
237   print qq|
238 <body onLoad="$onload">
239
240 <form method=post action=$form->{script}>
241
242 <input type=hidden name=accno value=$form->{accno}>
243 <input type=hidden name=description value="$form->{description}">
244 <input type=hidden name=sort value=transdate>
245 <input type=hidden name=eur value=$eur>
246 <input type=hidden name=accounttype value=$form->{accounttype}>
247
248 <table border=0 width=100%>
249   <tr>
250     <th class=listtop>$form->{title}</th>
251   </tr>
252
253 </table>
254 <table>
255         <tr>
256           <th align=left><input name=reporttype class=radio type=radio value="custom" checked> |
257       . $locale->text('Customized Report') . qq|</th>
258         </tr>
259         <tr>
260           <th colspan=1>| . $locale->text('Year') . qq|</th>
261           <td><input name=year size=11 title="|
262       . $locale->text('YYYY') . qq|" value="$year"></td>
263         </tr>
264 |;
265
266     print qq|
267         <tr>
268                 <td align=right>
269 <b> | . $locale->text('Yearly') . qq|</b> </td>
270                 <th align=left>| . $locale->text('Quarterly') . qq|</th>
271                 <th align=left colspan=3>| . $locale->text('Monthly') . qq|</th>
272         </tr>
273         <tr>
274                 <td align=right>&nbsp; <input name=duetyp class=radio type=radio value="13"
275 $checked></td>
276                 <td><input name=duetyp class=radio type=radio value="A" $checked >&nbsp;1. |
277       . $locale->text('Quarter') . qq|</td>
278 |;
279     $checked = "checked";
280     print qq|
281                 <td><input name=duetyp class=radio type=radio value="1" $checked >&nbsp;|
282       . $locale->text('January') . qq|</td>
283 |;
284     $checked = "";
285     print qq|
286                 <td><input name=duetyp class=radio type=radio value="5" $checked >&nbsp;|
287       . $locale->text('May') . qq|</td>
288                 <td><input name=duetyp class=radio type=radio value="9" $checked >&nbsp;|
289       . $locale->text('September') . qq|</td>
290
291         </tr>
292         <tr>
293                 <td align= right>&nbsp;</td>
294                 <td><input name=duetyp class=radio type=radio value="B" $checked>&nbsp;2. |
295       . $locale->text('Quarter') . qq|</td>
296                 <td><input name=duetyp class=radio type=radio value="2" $checked >&nbsp;|
297       . $locale->text('February') . qq|</td>
298                 <td><input name=duetyp class=radio type=radio value="6" $checked >&nbsp;|
299       . $locale->text('June') . qq|</td>
300                 <td><input name=duetyp class=radio type=radio value="10" $checked >&nbsp;|
301       . $locale->text('October') . qq|</td>
302         </tr>
303         <tr>
304                 <td> &nbsp;</td>
305                 <td><input name=duetyp class=radio type=radio value="C" $checked>&nbsp;3. |
306       . $locale->text('Quarter') . qq|</td>
307                 <td><input name=duetyp class=radio type=radio value="3" $checked >&nbsp;|
308       . $locale->text('March') . qq|</td>
309                 <td><input name=duetyp class=radio type=radio value="7" $checked >&nbsp;|
310       . $locale->text('July') . qq|</td>
311                 <td><input name=duetyp class=radio type=radio value="11" $checked >&nbsp;|
312       . $locale->text('November') . qq|</td>
313
314         </tr>
315         <tr>
316                 <td> &nbsp;</td>
317                 <td><input name=duetyp class=radio type=radio value="D" $checked>&nbsp;4. |
318       . $locale->text('Quarter') . qq|&nbsp;</td>
319                 <td><input name=duetyp class=radio type=radio value="4" $checked >&nbsp;|
320       . $locale->text('April') . qq|</td>
321                 <td><input name=duetyp class=radio type=radio value="8" $checked >&nbsp;|
322       . $locale->text('August') . qq|</td>
323                 <td><input name=duetyp class=radio type=radio value="12" $checked >&nbsp;|
324       . $locale->text('December') . qq|</td>
325
326         </tr>
327         <tr>
328                 <td colspan=5><hr size=3 noshade></td>
329         </tr>
330         <tr>
331           <th align=left><input name=reporttype class=radio type=radio value="free" $checked> |
332       . $locale->text('Free report period') . qq|</th>
333           <td align=left colspan=4>| . $locale->text('From') . qq|&nbsp;
334               $button1
335               $button1_2&nbsp;
336               | . $locale->text('Bis') . qq|&nbsp;
337               $button2
338               $button2_2
339           </td>
340         </tr>
341         <tr>
342                 <td colspan=5><hr size=3 noshade></td>
343         </tr>
344         <tr>
345           <th align=leftt>| . $locale->text('Method') . qq|</th>
346           <td colspan=3><input name=method class=radio type=radio value=accrual $accrual>|
347       . $locale->text('Accrual') . qq|
348           &nbsp;<input name=method class=radio type=radio value=cash $cash>|
349       . $locale->text('EUR') . qq|</td>
350         </tr>
351         <tr>
352          <th align=right colspan=4>|
353       . $locale->text('Decimalplaces')
354       . qq|</th>
355              <td><input name=decimalplaces size=3 value="2"></td>
356          </tr>
357          <tr>
358             <td><input name="subtotal" class=checkbox type=checkbox value=1> | . $locale->text('Subtotal') . qq|</td>
359          </tr>
360
361 $jsscript
362   <tr><td colspan=5 ><hr size=3 noshade></td></tr>
363 </table>
364
365 <br><input class=submit type=submit name=action value="|
366     . $locale->text('List Transactions') . qq|">
367 </form>
368
369 </body>
370 </html>
371 |;
372
373   $lxdebug->leave_sub();
374 }
375
376 sub format_debit_credit {
377   $lxdebug->enter_sub();
378
379   my $dc = shift;
380
381   my $formatted_dc  = $form->format_amount(\%myconfig, abs($dc), 2) . ' ';
382   $formatted_dc    .= ($dc > 0) ? $locale->text('Credit (one letter abbreviation)') : $locale->text('Debit (one letter abbreviation)');
383
384   $lxdebug->leave_sub();
385
386   return $formatted_dc;
387 }
388
389
390 sub list_transactions {
391   $lxdebug->enter_sub();
392
393   $auth->assert('report');
394
395   $form->{title} = $locale->text('Account') . " $form->{accno} - $form->{description}";
396
397   if ($form->{reporttype} eq "custom") {
398
399     #forgotten the year --> thisyear
400     if ($form->{year} !~ m/^\d\d\d\d$/) {
401       $locale->date(\%myconfig, $form->current_date(\%myconfig), 0) =~
402         /(\d\d\d\d)/;
403       $form->{year} = $1;
404     }
405
406     #yearly report
407     if ($form->{duetyp} eq "13") {
408       $form->{fromdate} = "1.1.$form->{year}";
409       $form->{todate}   = "31.12.$form->{year}";
410     }
411
412     #Quater reports
413     if ($form->{duetyp} eq "A") {
414       $form->{fromdate} = "1.1.$form->{year}";
415       $form->{todate}   = "31.3.$form->{year}";
416     }
417     if ($form->{duetyp} eq "B") {
418       $form->{fromdate} = "1.4.$form->{year}";
419       $form->{todate}   = "30.6.$form->{year}";
420     }
421     if ($form->{duetyp} eq "C") {
422       $form->{fromdate} = "1.7.$form->{year}";
423       $form->{todate}   = "30.9.$form->{year}";
424     }
425     if ($form->{duetyp} eq "D") {
426       $form->{fromdate} = "1.10.$form->{year}";
427       $form->{todate}   = "31.12.$form->{year}";
428     }
429
430     #Monthly reports
431   SWITCH: {
432       $form->{duetyp} eq "1" && do {
433         $form->{fromdate} = "1.1.$form->{year}";
434         $form->{todate}   = "31.1.$form->{year}";
435         last SWITCH;
436       };
437       $form->{duetyp} eq "2" && do {
438         $form->{fromdate} = "1.2.$form->{year}";
439
440         #this works from 1901 to 2099, 1900 and 2100 fail.
441         $leap = ($form->{year} % 4 == 0) ? "29" : "28";
442         $form->{todate} = "$leap.2.$form->{year}";
443         last SWITCH;
444       };
445       $form->{duetyp} eq "3" && do {
446         $form->{fromdate} = "1.3.$form->{year}";
447         $form->{todate}   = "31.3.$form->{year}";
448         last SWITCH;
449       };
450       $form->{duetyp} eq "4" && do {
451         $form->{fromdate} = "1.4.$form->{year}";
452         $form->{todate}   = "30.4.$form->{year}";
453         last SWITCH;
454       };
455       $form->{duetyp} eq "5" && do {
456         $form->{fromdate} = "1.5.$form->{year}";
457         $form->{todate}   = "31.5.$form->{year}";
458         last SWITCH;
459       };
460       $form->{duetyp} eq "6" && do {
461         $form->{fromdate} = "1.6.$form->{year}";
462         $form->{todate}   = "30.6.$form->{year}";
463         last SWITCH;
464       };
465       $form->{duetyp} eq "7" && do {
466         $form->{fromdate} = "1.7.$form->{year}";
467         $form->{todate}   = "31.7.$form->{year}";
468         last SWITCH;
469       };
470       $form->{duetyp} eq "8" && do {
471         $form->{fromdate} = "1.8.$form->{year}";
472         $form->{todate}   = "31.8.$form->{year}";
473         last SWITCH;
474       };
475       $form->{duetyp} eq "9" && do {
476         $form->{fromdate} = "1.9.$form->{year}";
477         $form->{todate}   = "30.9.$form->{year}";
478         last SWITCH;
479       };
480       $form->{duetyp} eq "10" && do {
481         $form->{fromdate} = "1.10.$form->{year}";
482         $form->{todate}   = "31.10.$form->{year}";
483         last SWITCH;
484       };
485       $form->{duetyp} eq "11" && do {
486         $form->{fromdate} = "1.11.$form->{year}";
487         $form->{todate}   = "30.11.$form->{year}";
488         last SWITCH;
489       };
490       $form->{duetyp} eq "12" && do {
491         $form->{fromdate} = "1.12.$form->{year}";
492         $form->{todate}   = "31.12.$form->{year}";
493         last SWITCH;
494       };
495     }
496   }
497
498   CA->all_transactions(\%myconfig, \%$form);
499
500   $form->{saldo_old} += $form->{beginning_balance};
501   $form->{saldo_new} += $form->{beginning_balance};
502   my $saldo_old = format_debit_credit($form->{saldo_old});
503   my $eb_string = format_debit_credit($form->{beginning_balance});
504   $form->{balance} = $form->{saldo_old};
505
506   my @options;
507   if ($form->{department}) {
508     my ($department) = split /--/, $form->{department};
509     push @options, $locale->text('Department') . " : $department";
510   }
511   if ($form->{projectnumber}) {
512     push @options, $locale->text('Project Number') . " : $form->{projectnumber}<br>";
513   }
514
515   my $period;
516   if ($form->{fromdate} || $form->{todate}) {
517     my ($fromdate, $todate);
518
519     if ($form->{fromdate}) {
520       $fromdate = $locale->date(\%myconfig, $form->{fromdate}, 1);
521     }
522     if ($form->{todate}) {
523       $todate = $locale->date(\%myconfig, $form->{todate}, 1);
524     }
525
526     $period = "$fromdate - $todate";
527
528   } else {
529     $period = $locale->date(\%myconfig, $form->current_date(\%myconfig), 1);
530   }
531
532   push @options, $period;
533
534   $form->{print_date} = $locale->text('Create Date') . " " . $locale->date(\%myconfig, $form->current_date(\%myconfig), 0);
535   push (@options, $form->{print_date});
536
537   $form->{company} = $locale->text('Company') . " " . $myconfig{company};
538   push (@options, $form->{company});
539
540   my @columns     = qw(transdate reference description gegenkonto debit credit ustkonto ustrate balance);
541   my %column_defs = (
542     'transdate'   => { 'text' => $locale->text('Date'), },
543     'reference'   => { 'text' => $locale->text('Reference'), },
544     'description' => { 'text' => $locale->text('Description'), },
545     'debit'       => { 'text' => $locale->text('Debit'), },
546     'credit'      => { 'text' => $locale->text('Credit'), },
547     'gegenkonto'     => { 'text' => $locale->text('Gegenkonto'), },
548     'ustkonto'     => { 'text' => $locale->text('USt-Konto'), },
549     'balance'          => { 'text' => $locale->text('Balance'), },
550     'ustrate'     => { 'text' => $locale->text('Satz %'), },
551  );
552
553   my @hidden_variables = qw(accno fromdate todate description accounttype l_heading subtotal department projectnumber project_id sort);
554
555   my $link = build_std_url('action=list_transactions', grep { $form->{$_} } @hidden_variables);
556
557   $form->{callback} = $link . '&sort=' . E($form->{sort});
558
559   my %column_alignment = map { $_ => 'right' } qw(debit credit);
560
561   @custom_headers = ();
562  # Zeile 1:
563  push @custom_headers, [
564    { 'text' => 'Letzte Buchung', },
565    { 'text' => 'EB-Wert', },
566    { 'text' => 'Saldo alt', 'colspan' => 2, },
567    { 'text' => 'Jahresverkehrszahlen alt', 'colspan' => 2, },
568    { 'text' => '', 'colspan' => 2, },
569  ];
570  push @custom_headers, [
571    { 'text' => $form->{last_transaction}, },
572    { 'text' => $eb_string, },
573    { 'text' => $saldo_old, 'colspan' => 2, },
574    { 'text' => $form->format_amount(\%myconfig, abs($form->{old_balance_debit}), 2) . " S", },
575    { 'text' => $form->format_amount(\%myconfig, $form->{old_balance_credit}, 2) . " H", },
576    { 'text' => '', 'colspan' => 2, },
577  ];
578  # Zeile 2:
579  push @custom_headers, [
580    { 'text' => $locale->text('Date'), 'link' => $link . "&sort=transdate", },
581    { 'text' => $locale->text('Reference'), 'link' => $link . "&sort=reference",  },
582    { 'text' => $locale->text('Description'), 'link' => $link . "&sort=description",  },
583    { 'text' => $locale->text('Gegenkonto'), },
584    { 'text' => $locale->text('Debit'), },
585    { 'text' => $locale->text('Credit'), },
586    { 'text' => $locale->text('USt-Konto'), },
587    { 'text' => $locale->text('Satz %'), },
588    { 'text' => $locale->text('Balance'), },
589  ];
590
591
592
593
594
595   my $report = SL::ReportGenerator->new(\%myconfig, $form);
596   $report->set_custom_headers(@custom_headers);
597
598   $report->set_options('top_info_text'         => join("\n", @options),
599                        'output_format'         => 'HTML',
600                        'title'                 => $form->{title},
601                        'attachment_basename'   => $locale->text('list_of_transactions') . strftime('_%Y%m%d', localtime time),
602                        'std_column_visibility' => 1,
603     );
604   $report->set_options_from_form();
605
606   $report->set_columns(%column_defs);
607   $report->set_column_order(@columns);
608
609   $report->set_export_options('list_transactions', @hidden_variables);
610
611   $report->set_sort_indicator($form->{sort}, 1);
612
613   $column_defs->{balance}->{visible} = 1;
614
615   my $ml = ($form->{category} =~ /(A|E)/) ? -1 : 1;
616
617
618   my $idx       = 0;
619   my %totals    = ( 'debit' => 0, 'credit' => 0 );
620   my %subtotals = ( 'debit' => 0, 'credit' => 0 );
621   my ($previous_index, $row_set);
622
623   foreach my $ca (@{ $form->{CA} }) {
624
625     foreach (qw(debit credit)) {
626       $subtotals{$_} += $ca->{$_};
627       $totals{$_}    += $ca->{$_};
628       if ($_ =~ /debit.*/) {
629         $ml = -1;
630       } else {
631         $ml = 1;
632       }
633       $form->{balance}= $form->{balance} + $ca->{$_} * $ml;
634       $ca->{$_}       = $form->format_amount(\%myconfig, $ca->{$_}, 2) if ($ca->{$_} != 0);
635     }
636
637     my $do_subtotal = 0;
638     if (($form->{subtotal})
639         && (($idx == scalar @{ $form->{CA} } - 1)
640             || ($ca->{$form->{sort}} ne $form->{CA}->[$idx + 1]->{$form->{sort}}))) {
641       $do_subtotal = 1;
642     }
643
644     my $row = { };
645
646     $ca->{ustrate} = $form->format_amount(\%myconfig, $ca->{ustrate} * 100, 2) if ($ca->{ustrate} != 0);
647
648     if ($ca->{memo} ne "") {
649       $ca->{description} .= " \n " . $ca->{memo};
650     }
651
652
653
654     foreach my $gegenkonto (@{ $ca->{GEGENKONTO} }) {
655       if ($ca->{gegenkonto} eq "") {
656         $ca->{gegenkonto} = $gegenkonto->{accno};
657       } else {
658         $ca->{gegenkonto} .= ", " . $gegenkonto->{accno};
659       }
660     }
661
662     foreach (@columns) {
663       $row->{$_} = {
664         'data'  => $ca->{$_},
665         'align' => $column_alignment{$_},
666       };
667     }
668
669     $row->{balance}->{data}        = $form->format_amount(\%myconfig, $form->{balance}, 2, 'DRCR');
670
671     if ($ca->{index} ne $previous_index) {
672 #       $report->add_data($row_set) if ($row_set);
673
674 #       $row_set         = [ ];
675       $previous_index  = $ca->{index};
676
677       $row->{reference}->{link} = build_std_url("script=$ca->{module}.pl", 'action=edit', 'id=' . E($ca->{id}), 'callback');
678
679     } elsif ($ca->{index} eq $previous_index) {
680       map { $row->{$_}->{data} = '' } qw(reference description);
681       $row->{transdate}->{data} = '' if ($form->{sort} eq 'transdate');
682     }
683
684     my $row_set = [];
685
686     push @{ $row_set }, $row;
687
688     push @{ $row_set }, create_subtotal_row(\%subtotals, \@columns, \%column_alignment, 'listsubtotal') if ($do_subtotal);
689
690
691     $idx++;
692     $report->add_data($row_set);
693
694   }
695
696   $report->add_data($row_set) if ($row_set);
697
698   $report->add_separator();
699
700   my $row = create_subtotal_row(\%totals, \@columns, \%column_alignment, 'listtotal');
701
702
703   $row->{balance}->{data}        = $form->format_amount(\%myconfig, $form->{balance}, 2, 'DRCR');
704
705   $report->add_data($row);
706
707
708   $report->add_separator();
709   my $row = {
710      'transdate' => {
711        'data'    => "",
712        'class' => 'listtotal',
713      },
714      'reference' => {
715        'data'    => $locale->text('EB-Wert'),
716        'class' => 'listtotal',
717      },
718      'description'      => {
719        'data'    => $locale->text('Saldo neu'),
720        'colspan' => 2,
721        'class' => 'listtotal',
722      },
723      'debit'      => {
724        'data'    => $locale->text('Jahresverkehrszahlen neu'),
725        'colspan' => 2,
726        'align' => 'left',
727        'class' => 'listtotal',
728     },
729      'ustkonto'      => {
730        'data'    => '',
731        'colspan' => 2,
732        'align' => 'left',
733        'class' => 'listtotal',
734     },
735   };
736
737   $report->add_data($row);
738   my $saldo_new = format_debit_credit($form->{saldo_new});
739   my $row = {
740      'transdate' => {
741        'data'    => "",
742        'class' => 'listtotal',
743      },
744      'reference' => {
745        'data'    => $eb_string,
746        'class' => 'listtotal',
747      },
748      'description'      => {
749        'data'    => $saldo_new,
750        'colspan' => 2,
751        'class' => 'listtotal',
752      },
753      'debit'      => {
754        'data'    => $form->format_amount(\%myconfig, abs($form->{current_balance_debit}) , 2) . " S",
755        'class' => 'listtotal',
756      },
757       'credit'      => {
758        'data'    => $form->format_amount(\%myconfig, $form->{current_balance_credit}, 2) . " H",
759        'class' => 'listtotal',
760      },
761       'ustkonto'      => {
762        'data'    => "",
763        'colspan' => 2,
764        'class' => 'listtotal',
765      },
766   };
767
768   $report->add_data($row);
769
770   $report->generate_with_headers();
771
772   $lxdebug->leave_sub();
773 }
774
775 sub create_subtotal_row {
776   $lxdebug->enter_sub();
777
778   my ($totals, $columns, $column_alignment, $class) = @_;
779
780   my $row = { map { $_ => { 'data' => '', 'class' => $class, 'align' => $column_alignment->{$_}, } } @{ $columns } };
781
782   map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, 2) } qw(credit debit);
783
784   map { $totals->{$_} = 0 } qw(debit credit);
785
786   $lxdebug->leave_sub();
787
788   return $row;
789 }