229e43004c24b4e5671f244c4dd39e0a9e2ce9e1
[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   $form->{title} = $locale->text('Chart of Accounts');
78
79   CA->all_accounts(\%myconfig, \%$form);
80
81   my @columns     = qw(accno description debit credit);
82   my %column_defs = (
83     'accno'       => { 'text' => $locale->text('Account'), },
84     'description' => { 'text' => $locale->text('Description'), },
85     'debit'       => { 'text' => $locale->text('Debit'), },
86     'credit'      => { 'text' => $locale->text('Credit'), },
87   );
88
89   my $report = SL::ReportGenerator->new(\%myconfig, $form);
90
91   $report->set_options('output_format'         => 'HTML',
92                        'title'                 => $form->{title},
93                        'attachment_basename'   => $locale->text('chart_of_accounts') . strftime('_%Y%m%d', localtime time),
94                        'std_column_visibility' => 1,
95     );
96   $report->set_options_from_form();
97
98   $report->set_columns(%column_defs);
99   $report->set_column_order(@columns);
100
101   $report->set_export_options('chart_of_accounts');
102
103   $report->set_sort_indicator($form->{sort}, 1);
104
105   my %totals = ('debit' => 0, 'credit' => 0);
106
107   foreach my $ca (@{ $form->{CA} }) {
108     my $row = { };
109
110     foreach (qw(debit credit)) {
111       $totals{$_} += $ca->{$_} * 1;
112       $ca->{$_}    = $form->format_amount(\%myconfig, $ca->{$_}, 2) if ($ca->{$_});
113     }
114
115     map { $row->{$_} = { 'data' => $ca->{$_} } } @columns;
116
117     map { $row->{$_}->{align} = 'right'       } qw(debit credit);
118     map { $row->{$_}->{class} = 'listheading' } @columns if ($ca->{charttype} eq "H");
119
120     $row->{accno}->{link} = build_std_url('action=list', 'accno=' . E($ca->{accno}), 'description=' . E($ca->{description}));
121
122     $report->add_data($row);
123   }
124
125   my $row = { map { $_ => { 'class' => 'listtotal', 'align' => 'right' } } @columns };
126   map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals{$_}, 2) } qw(debit credit);
127
128   $report->add_separator();
129   $report->add_data($row);
130
131   $report->generate_with_headers();
132
133   $lxdebug->leave_sub();
134 }
135
136 sub list {
137   $lxdebug->enter_sub();
138
139   $form->{title} = $locale->text('List Transactions');
140   $form->{title} .= " - " . $locale->text('Account') . " $form->{accno}";
141
142   # get departments
143   $form->all_departments(\%myconfig);
144   if (@{ $form->{all_departments} }) {
145     $form->{selectdepartment} = "<option>\n";
146
147     map {
148       $form->{selectdepartment} .=
149         "<option>$_->{description}--$_->{id}\n"
150     } (@{ $form->{all_departments} });
151   }
152
153   $department = qq|
154         <tr>
155           <th align=right nowrap>| . $locale->text('Department') . qq|</th>
156           <td colspan=3><select name=department>$form->{selectdepartment}</select></td>
157         </tr>
158 | if $form->{selectdepartment};
159
160   $form->header;
161
162   $form->{description} =~ s/\"/&quot;/g;
163
164   print qq|
165 <body>
166
167 <form method=post action=$form->{script}>
168
169 <input type=hidden name=accno value=$form->{accno}>
170 <input type=hidden name=description value="$form->{description}">
171 <input type=hidden name=sort value=transdate>
172 <input type=hidden name=eur value=$eur>
173 <input type=hidden name=accounttype value=$form->{accounttype}>
174
175 <table border=0 width=100%>
176   <tr><th class=listtop>$form->{title}</th></tr>
177   <tr height="5"></tr
178   <tr valign=top>
179     <td>
180       <table>
181         $department
182         <tr>
183           <th align=right>| . $locale->text('From') . qq|</th>
184           <td><input name=fromdate size=11 title="$myconfig{dateformat}"></td>
185           <th align=right>| . $locale->text('To') . qq|</th>
186           <td><input name=todate size=11 title="$myconfig{dateformat}"></td>
187         </tr>
188         <tr>
189           <th align=right>| . $locale->text('Include in Report') . qq|</th>
190           <td colspan=3>
191           <input name=l_subtotal class=checkbox type=checkbox value=Y>&nbsp;|
192     . $locale->text('Subtotal') . qq|</td>
193         </tr>
194       </table>
195     </td>
196   </tr>
197   <tr><td><hr size=3 noshade></td></tr>
198 </table>
199
200 <input type=hidden name=login value=$form->{login}>
201 <input type=hidden name=password value=$form->{password}>
202
203 <br><input class=submit type=submit name=action value="|
204     . $locale->text('List Transactions') . qq|">
205 </form>
206
207 </body>
208 </html>
209 |;
210
211   $lxdebug->leave_sub();
212 }
213
214 sub list_transactions {
215   $lxdebug->enter_sub();
216
217   $form->{title} = $locale->text('Account') . " $form->{accno} - $form->{description}";
218
219   CA->all_transactions(\%myconfig, \%$form);
220
221   my @options;
222   if ($form->{department}) {
223     my ($department) = split /--/, $form->{department};
224     push @options, $locale->text('Department') . " : $department";
225   }
226   if ($form->{projectnumber}) {
227     push @options, $locale->text('Project Number') . " : $form->{projectnumber}<br>";
228   }
229
230   my $period;
231   if ($form->{fromdate} || $form->{todate}) {
232     my ($fromdate, $todate);
233
234     if ($form->{fromdate}) {
235       $fromdate = $locale->date(\%myconfig, $form->{fromdate}, 1);
236     }
237     if ($form->{todate}) {
238       $todate = $locale->date(\%myconfig, $form->{todate}, 1);
239     }
240
241     $period = "$fromdate - $todate";
242
243   } else {
244     $period = $locale->date(\%myconfig, $form->current_date(\%myconfig), 1);
245   }
246
247   push @options, $period;
248
249   my @columns     = qw(transdate reference description debit credit balance);
250   my %column_defs = (
251     'transdate'   => { 'text' => $locale->text('Date'), },
252     'reference'   => { 'text' => $locale->text('Reference'), },
253     'description' => { 'text' => $locale->text('Description'), },
254     'debit'       => { 'text' => $locale->text('Debit'), },
255     'credit'      => { 'text' => $locale->text('Credit'), },
256     'balance'     => { 'text' => $locale->text('Balance'), },
257   );
258   my %column_alignment = map { $_ => 'right' } qw(debit credit balance);
259
260   my @hidden_variables = qw(accno fromdate todate description accounttype l_heading l_subtotal department projectnumber project_id sort);
261
262   my $link = build_std_url('action=list_transactions', grep { $form->{$_} } @hidden_variables);
263   map { $column_defs{$_}->{link} = $link . "&sort=$_" } qw(transdate reference description);
264
265   $form->{callback} = $link . '&sort=' . E($form->{sort});
266
267   my $report = SL::ReportGenerator->new(\%myconfig, $form);
268
269   $report->set_options('top_info_text'         => join("\n", @options),
270                        'output_format'         => 'HTML',
271                        'title'                 => $form->{title},
272                        'attachment_basename'   => $locale->text('list_of_transactions') . strftime('_%Y%m%d', localtime time),
273                        'std_column_visibility' => 1,
274     );
275   $report->set_options_from_form();
276
277   $report->set_columns(%column_defs);
278   $report->set_column_order(@columns);
279
280   $report->set_export_options('list_transactions', @hidden_variables);
281
282   $report->set_sort_indicator($form->{sort}, 1);
283
284   $column_defs->{balance}->{visible} = $form->{accno} ? 1 : 0;
285
286   my $ml = ($form->{category} =~ /(A|E)/) ? -1 : 1;
287
288   if ($form->{accno} && $form->{balance}) {
289     my $row = {
290       'balance' => {
291         'data'  => $form->format_amount(\%myconfig, $form->{balance} * $ml, 2),
292         'align' => 'right',
293       },
294     };
295
296     $report->add_data($row);
297   }
298
299   my $idx       = 0;
300   my %totals    = ( 'debit' => 0, 'credit' => 0 );
301   my %subtotals = ( 'debit' => 0, 'credit' => 0 );
302   my ($previous_index, $row_set);
303
304   foreach my $ca (@{ $form->{CA} }) {
305     $form->{balance} += $ca->{amount};
306
307     foreach (qw(debit credit)) {
308       $subtotals{$_} += $ca->{$_};
309       $totals{$_}    += $ca->{$_};
310       $ca->{$_}       = $form->format_amount(\%myconfig, $ca->{$_}, 2) if ($ca->{$_} != 0);
311     }
312
313     $ca->{balance} = $form->format_amount(\%myconfig, $form->{balance} * $ml, 2);
314
315     my $row = { };
316
317     foreach (@columns) {
318       $row->{$_} = {
319         'data'  => $ca->{$_},
320         'align' => $column_alignment{$_},
321       };
322     }
323
324     if ($ca->{index} ne $previous_index) {
325       $report->add_data($row_set) if ($row_set);
326
327       $row_set         = [ ];
328       $previous_index  = $ca->{index};
329
330       $row->{reference}->{link} = build_std_url("script=$ca->{module}.pl", 'action=edit', 'id=' . E($ca->{id}), 'callback');
331
332     } else {
333       map { $row->{$_}->{data} = '' } qw(reference description);
334       $row->{transdate}->{data} = '' if ($form->{sort} eq 'transdate');
335     }
336
337     push @{ $row_set }, $row;
338
339     if (($form->{l_subtotal} eq 'Y')
340         && (($idx == scalar @{ $form->{CA} } - 1)
341             || ($ca->{$form->{sort}} ne $form->{CA}->[$idx + 1]->{$form->{sort}}))) {
342       $report->add_data(create_subtotal_row(\%subtotals, \@columns, \%column_alignment, 'listsubtotal'));
343     }
344
345     $idx++;
346   }
347
348   $report->add_data($row_set) if ($row_set);
349
350   $report->add_separator();
351
352   my $row = create_subtotal_row(\%totals, \@columns, \%column_alignment, 'listtotal');
353   $row->{balance}->{data} = $form->format_amount(\%myconfig, $form->{balance} * $ml, 2);
354   $report->add_data($row);
355
356   $report->generate_with_headers();
357
358   $lxdebug->leave_sub();
359 }
360
361 sub create_subtotal_row {
362   $lxdebug->enter_sub();
363
364   my ($totals, $columns, $column_alignment, $class) = @_;
365
366   my $row = { map { $_ => { 'data' => '', 'class' => $class, 'align' => $column_alignment->{$_}, } } @{ $columns } };
367
368   map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, 2) } qw(credit debit);
369
370   map { $totals->{$_} = 0 } qw(debit credit);
371
372   $lxdebug->leave_sub();
373
374   return $row;
375 }