Solved Bug 365: Falsche UStVA bei negativem Vorsteuer-Betrag
[kivitendo-erp.git] / SL / USTVA.pm
1 #=====================================================================
2 # Lx-Office ERP
3 # Copyright (c) 2004 by Udo Spallek, Aachen
4 #
5 #  Author: Udo Spallek
6 #   Email: udono@gmx.net
7 #     Web: http://www.lx-office.org
8 #
9 #
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the Free Software
21 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #======================================================================
23 # Utilities for ustva
24 #=====================================================================
25
26 package USTVA;
27
28 sub create_steuernummer {
29   $main::lxdebug->enter_sub();
30
31   $part           = $form->{part};
32   $patterncount   = $form->{patterncount};
33   $delimiter      = $form->{delimiter};
34   $elster_pattern = $form->{elster_pattern};
35
36   # rebuild steuernummer and elstersteuernummer
37   # es gibt eine gespeicherte steuernummer $form->{steuernummer}
38   # und die parts und delimiter
39
40   my $h = 0;
41   my $i = 0;
42
43   $steuernummer_new       = $part;
44   $elstersteuernummer_new = $elster_FFFF;
45   $elstersteuernummer_new .= '0';
46
47   for ($h = 1; $h < $patterncount; $h++) {
48     $steuernummer_new .= qq|$delimiter|;
49     for ($i = 1; $i <= length($elster_pattern); $i++) {
50       $steuernummer_new       .= $form->{"part_$h\_$i"};
51       $elstersteuernummer_new .= $form->{"part_$h\_$i"};
52     }
53   }
54   if ($form->{steuernummer} ne $steuernummer_new) {
55     $form->{steuernummer}       = $steuernummer_new;
56     $form->{elstersteuernummer} = $elstersteuernummer_new;
57     $form->{steuernummer_new}   = $steuernummer_new;
58   }
59   $main::lxdebug->leave_sub();
60   return ($steuernummer_new, $elstersteuernummer_new);
61 }
62
63 sub steuernummer_input {
64   $main::lxdebug->enter_sub();
65
66   ($elsterland, $elsterFFFF, $steuernummer) = @_;
67
68   $elster_land  = $elsterland;
69   $elster_FFFF  = $elsterFFFF;
70   $steuernummer = '0000000000' if ($steuernummer eq '');
71
72   # $steuernummer formatieren (nur Zahlen) -> $stnr
73   $stnr = $steuernummer;
74   $stnr =~ s/\D+//g;
75
76   #Pattern description Elstersteuernummer
77   my %elster_STNRformat = (
78                         'Mecklenburg Vorpommern' => 'FFF/BBB/UUUUP',    # '/' 3
79                         'Hessen'                 => '0FF BBB UUUUP',    # ' ' 3
80                         'Nordrhein Westfalen'    => 'FFF/BBBB/UUUP',    # '/' 3
81                         'Schleswig Holstein'     => 'FF BBB UUUUP',     # ' ' 2
82                         'Berlin'                 => 'FF/BBB/UUUUP',     # '/' 3
83                         'Thüringen'              => 'FFF/BBB/UUUUP',    # '/' 3
84                         'Sachsen'                => 'FFF/BBB/UUUUP',    # '/' 3
85                         'Hamburg'                => 'FF/BBB/UUUUP',     # '/' 3
86                         'Baden Würtemberg'       => 'FF/BBB/UUUUP',     # '/' 2
87                         'Sachsen Anhalt'         => 'FFF/BBB/UUUUP',    # '/' 3
88                         'Saarland'               => 'FFF/BBB/UUUUP',    # '/' 3
89                         'Bremen'                 => 'FF BBB UUUUP',     # ' ' 3
90                         'Bayern'                 => 'FFF/BBB/UUUUP',    # '/' 3
91                         'Rheinland Pfalz'        => 'FF/BBB/UUUU/P',    # '/' 4
92                         'Niedersachsen'          => 'FF/BBB/UUUUP',     # '/' 3
93                         'Brandenburg'            => 'FFF/BBB/UUUUP',    # '/' 3
94   );
95
96   #split the pattern
97   $elster_pattern = $elster_STNRformat{$elster_land};
98   my @elster_pattern = split(' ', $elster_pattern);
99   my $delimiter      = '&nbsp;';
100   my $patterncount   = @elster_pattern;
101   if ($patterncount < 2) {
102     @elster_pattern = ();
103     @elster_pattern = split('/', $elster_pattern);
104     $delimiter      = '/';
105     $patterncount   = @elster_pattern;
106   }
107
108   # no we have an array of patternparts and a delimiter
109   # create the first automated and fixed part and delimiter
110
111   print qq|<b><font size="+1">|;
112   $part = '';
113 SWITCH: {
114     $elster_pattern[0] eq 'FFF' && do {
115       $part = substr($elster_FFFF, 1, 4);
116       print qq|$part|;
117       last SWITCH;
118     };
119     $elster_pattern[0] eq '0FF' && do {
120       $part = '0' . substr($elster_FFFF, 2, 4);
121       print qq|$part|;
122       last SWITCH;
123     };
124     $elster_pattern[0] eq 'FF' && do {
125       $part = substr($elster_FFFF, 2, 4);
126       print qq|$part|;
127       last SWITCH;
128     };
129     1 == 1 && do {
130       print qq|Fehler!|;
131       last SWITCH;
132     };
133   }
134
135   #now the rest of the Steuernummer ...
136   print qq|</b></font>|;
137   print qq|\n
138            <input type=hidden name="elster_pattern" value="$elster_pattern">
139            <input type=hidden name="patterncount" value="$patterncount">
140            <input type=hidden name="patternlength" value="$patterncount">
141            <input type=hidden name="delimiter" value="$delimiter">
142            <input type=hidden name="part" value="$part">
143   |;
144   my $h = 0;
145   my $i = 0;
146   my $j = 0;
147   $k = 0;
148
149   for ($h = 1; $h < $patterncount; $h++) {
150     print qq|&nbsp;$delimiter&nbsp;\n|;
151     for ($i = 1; $i <= length($elster_pattern[$h]); $i++) {
152       print qq|<select name="part_$h\_$i">\n|;
153
154       for ($j = 0; $j <= 9; $j++) {
155         print qq|      <option value="$j"|;
156         if ($steuernummer ne '') {
157           if ($j eq substr($stnr, length($part) + $k, 1)) {
158             print qq| selected|;
159           }
160         }
161         print qq|>$j</option>\n|;
162       }
163       $k++;
164       print qq|</select>\n|;
165     }
166   }
167   $main::lxdebug->leave_sub();
168 }
169
170 sub fa_auswahl {
171   $main::lxdebug->enter_sub();
172
173   use SL::Form;
174
175   # Referenz wird übergeben, hash of hash wird nicht
176   # in neues  Hash kopiert, sondern direkt über die Referenz verändert
177   # Prototyp für diese Konstruktion
178
179   my ($land, $elsterFFFF, $elster_init) =
180     @_;    #Referenz auf Hash von Hash übergeben
181   my $terminal = '';
182   my $FFFF     = $elsterFFFF;
183   my $ffff     = '';
184   my $checked  = '';
185   $checked = 'checked' if ($elsterFFFF eq '' and $land eq '');
186
187   #if ($ENV{HTTP_USER_AGENT} =~ /(mozilla|opera|w3m)/i){
188   #$terminal='mozilla';
189   #} elsif ($ENV{HTTP_USER_AGENT} =~ /(links|lynx)/i){
190   #$terminal = 'lynx';
191   #}
192
193   #if ( $terminal eq 'mozilla' or $terminal eq 'js' ) {
194   print qq|
195         <br>
196         <script language="Javascript">
197         function update_auswahl()
198         {
199                 var elsterBLAuswahl = document.verzeichnis.elsterland_new;
200                 var elsterFAAuswahl = document.verzeichnis.elsterFFFF_new;
201
202                 elsterFAAuswahl.options.length = 0; // dropdown aufräumen
203                 |;
204
205   foreach $elster_land (sort keys %$elster_init) {
206     print qq|
207                if (elsterBLAuswahl.options[elsterBLAuswahl.selectedIndex].
208                value == "$elster_land")
209                {
210                |;
211     my $j              = 0;
212     my %elster_land_fa = ();
213     $FFFF = '';
214     for $FFFF (keys %{ $elster_init->{$elster_land} }) {
215       $elster_land_fa{$FFFF} = $elster_init->{$elster_land}->{$FFFF}->[0];
216     }
217     foreach $ffff (sort { $elster_land_fa{$a} cmp $elster_land_fa{$b} }
218                    keys(%elster_land_fa)
219       ) {
220       print qq|
221                    elsterFAAuswahl.options[$j] = new Option("$elster_land_fa{$ffff} ($ffff)","$ffff");|;
222       $j++;
223     }
224     print qq|
225                }|;
226   }
227   print qq|
228         }
229         </script>
230
231         <table width="100%">
232           <tr>
233             <td>
234                Bundesland
235             </td>
236             <td>
237               <select size="1" name="elsterland_new" onchange="update_auswahl()">|;
238   if ($land eq '') {
239     print qq|<option value="Auswahl" $checked>hier auswählen...</option>\n|;
240   }
241   foreach $elster_land (sort keys %$elster_init) {
242     print qq|
243                   <option value="$elster_land"|;
244     if ($elster_land eq $land and $checked eq '') {
245       print qq| selected|;
246     }
247     print qq|>$elster_land</option>
248              |;
249   }
250   print qq|
251             </td>
252           </tr>
253           |;
254
255   my $elster_land = '';
256   $elster_land = ($land ne '') ? $land : '';
257   %elster_land_fa = ();
258   for $FFFF (keys %{ $elster_init->{$elster_land} }) {
259     $elster_land_fa{$FFFF} = $elster_init->{$elster_land}->{$FFFF}->[0];
260   }
261
262   print qq|
263            <tr>
264               <td>Finanzamt
265               </td>
266               <td>
267                  <select size="1" name="elsterFFFF_new">|;
268   if ($elsterFFFF eq '') {
269     print qq|<option value="Auswahl" $checked>hier auswählen...</option>|;
270   } else {
271     foreach $ffff (sort { $elster_land_fa{$a} cmp $elster_land_fa{$b} }
272                    keys(%elster_land_fa)
273       ) {
274
275       print qq|
276                         <option value="$ffff"|;
277       if ($ffff eq $elsterFFFF and $checked eq '') {
278         print qq| selected|;
279       }
280       print qq|>$elster_land_fa{$ffff} ($ffff)</option>|;
281     }
282   }
283   print qq|
284                  </td>
285               </tr>
286             </table>
287             </select>|;
288
289   $main::lxdebug->leave_sub();
290 }
291
292 sub info {
293   $main::lxdebug->enter_sub();
294
295   my $msg = $_[0];
296
297   if ($ENV{HTTP_USER_AGENT}) {
298     $msg =~ s/\n/<br>/g;
299
300     print qq|<body><h2 class=info>Hinweis</h2>
301
302     <p><b>$msg</b>
303     <br>
304     <br>
305     <hr>
306     <input type=button value="zurück" onClick="history.go(-1)">
307     </body>
308     |;
309
310     exit;
311
312   } else {
313
314     if ($form->{error_function}) {
315       &{ $form->{error_function} }($msg);
316     } else {
317       die "Hinweis: $msg\n";
318     }
319   }
320
321   $main::lxdebug->leave_sub();
322 }
323
324 sub stichtag {
325   $main::lxdebug->enter_sub();
326
327   # noch nicht fertig
328   # soll mal eine Erinnerungsfunktion für USTVA Abgaben werden, die automatisch
329   # den Termin der nächsten USTVA anzeigt.
330   #
331   #
332   my ($today, $FA_dauerfrist, $FA_voranmeld) = @_;
333
334   #$today zerlegen:
335
336   #$today =today * 1;
337   $today =~ /(\d\d\d\d)(\d\d)(\d\d)/;
338   $year     = $1;
339   $month    = $2;
340   $day      = $3;
341   $yy       = $year;
342   $mm       = $month;
343   $yymmdd   = "$year$month$day" * 1;
344   $mmdd     = "$month$day" * 1;
345   $stichtag = '';
346
347   #$tage_bis = '1234';
348   #$ical = '...vcal format';
349
350   #if ($FA_voranmeld eq 'month'){
351
352   %liste = ("0110" => 'December',
353             "0210" => 'January',
354             "0310" => 'February',
355             "0410" => 'March',
356             "0510" => 'April',
357             "0610" => 'May',
358             "0710" => 'June',
359             "0810" => 'July',
360             "0910" => 'August',
361             "1010" => 'September',
362             "1110" => 'October',
363             "1210" => 'November');
364
365   #$mm += $dauerfrist
366   #$month *= 1;
367   $month += 1 if ($day > 10);
368   $month    = sprintf("%02d", $month);
369   $stichtag = $year . $month . "10";
370   $ust_va   = $month . "10";
371
372   foreach $date (%liste) {
373     $ust_va = $liste{$date} if ($date eq $stichtag);
374   }
375
376   #} elsif ($FA_voranmeld eq 'quarter'){
377   #1;
378
379   #}
380
381   #@stichtag = ('10.04.2004', '10.05.2004');
382
383   #@liste = ['0110', '0210', '0310', '0410', '0510', '0610', '0710', '0810', '0910',
384   #          '1010', '1110', '1210', ];
385   #
386   #foreach $key (@liste){
387   #  #if ($ddmm < ('0110' * 1));
388   #  if ($ddmm ){}
389   #  $stichtag = $liste[$key - 1] if ($ddmm > $key);
390   #
391   #}
392   #
393   #$stichtag =~ /([\d]\d)(\d\d)$/
394   #$stichtag = "$1.$2.$yy"
395   #$stichtag=$1;
396   $main::lxdebug->leave_sub();
397   return ($stichtag, $description, $tage_bis, $ical);
398 }
399
400 sub query_finanzamt {
401   $main::lxdebug->enter_sub();
402
403   my ($myconfig, $form) = @_;
404   my $dbh = $form->dbconnect($myconfig) or $self->error(DBI->errstr);
405
406   #Test, if table finanzamt exist
407   my $table    = 'finanzamt';
408   my $filename = "sql/$table.sql";
409
410   my $tst = $dbh->prepare("SELECT * FROM $table");
411   $tst->execute;
412   if ($DBI::err) {
413
414     #There is no table, read the table from sql/finanzamt.sql
415     print qq|<p>Bitte warten, Tabelle $table wird einmalig in Datenbank:
416     $myconfig->{dbname} als Benutzer: $myconfig->{dbuser} hinzugefügt...</p>|;
417     process_query($form, $dbh, $filename) || $self->error(DBI->errstr);
418
419     #execute second last call
420     my $dbh = $form->dbconnect($myconfig) or $self->error(DBI->errstr);
421     $dbh->disconnect();
422   }
423   $tst->finish();
424
425   #$dbh->disconnect();
426
427   my @vars = (
428     'FA_Land_Nr',             #  0
429     'FA_BUFA_Nr',             #  1
430                               #'FA_Verteiler',                          #  2
431     'FA_Name',                #  3
432     'FA_Strasse',             #  4
433     'FA_PLZ',                 #  5
434     'FA_Ort',                 #  6
435     'FA_Telefon',             #  7
436     'FA_Fax',                 #  8
437     'FA_PLZ_Grosskunden',     #  9
438     'FA_PLZ_Postfach',        # 10
439     'FA_Postfach',            # 11
440     'FA_BLZ_1',               # 12
441     'FA_Kontonummer_1',       # 13
442     'FA_Bankbezeichnung_1',   # 14
443                               #'FA_BankIBAN_1',                         # 15
444                               #'FA_BankBIC_1',                          # 16
445                               #'FA_BankInhaber_BUFA_Nr_1',                      # 17
446     'FA_BLZ_2',               # 18
447     'FA_Kontonummer_2',       # 19
448     'FA_Bankbezeichnung_2',   # 20
449                               #'FA_BankIBAN_2',                         # 21
450                               #'FA_BankBIC_2',                          # 22
451                               #'FA_BankInhaber_BUFA_Nr_2',                      # 23
452     'FA_Oeffnungszeiten',     # 24
453     'FA_Email',               # 25
454     'FA_Internet'             # 26
455                               #'FA_zustaendige_Hauptstelle_BUFA_Nr',            # 27
456                               #'FA_zustaendige_vorgesetzte_Finanzbehoerde'      # 28
457   );
458
459   my $field = join(', ', @vars);
460
461   my $query = "SELECT $field FROM finanzamt ORDER BY FA_Land_nr";
462   my $sth = $dbh->prepare($query) or $self->error($dbh->errstr);
463   $sth->execute || $form->dberror($query);
464   my $array_ref = $sth->fetchall_arrayref();
465   my $land      = '';
466   foreach my $row (@$array_ref) {
467     my $FA_finanzamt = $row;
468     $land = 'Schleswig Holstein'     if (@$FA_finanzamt[0] eq '1');
469     $land = 'Hamburg'                if (@$FA_finanzamt[0] eq '2');
470     $land = 'Niedersachsen'          if (@$FA_finanzamt[0] eq '3');
471     $land = 'Bremen'                 if (@$FA_finanzamt[0] eq '4');
472     $land = 'Nordrhein Westfalen'    if (@$FA_finanzamt[0] eq '5');
473     $land = 'Hessen'                 if (@$FA_finanzamt[0] eq '6');
474     $land = 'Rheinland Pfalz'        if (@$FA_finanzamt[0] eq '7');
475     $land = 'Baden Würtemberg'       if (@$FA_finanzamt[0] eq '8');
476     $land = 'Bayern'                 if (@$FA_finanzamt[0] eq '9');
477     $land = 'Saarland'               if (@$FA_finanzamt[0] eq '10');
478     $land = 'Berlin'                 if (@$FA_finanzamt[0] eq '11');
479     $land = 'Brandenburg'            if (@$FA_finanzamt[0] eq '12');
480     $land = 'Mecklenburg Vorpommern' if (@$FA_finanzamt[0] eq '13');
481     $land = 'Sachsen'                if (@$FA_finanzamt[0] eq '14');
482     $land = 'Sachsen Anhalt'         if (@$FA_finanzamt[0] eq '15');
483     $land = 'Thüringen'              if (@$FA_finanzamt[0] eq '16');
484
485     my $ffff = @$FA_finanzamt[1];
486
487     my $rec = {};
488     $rec->{$land} = $ffff;
489
490     shift @$row;
491     shift @$row;
492
493     $finanzamt{$land}{$ffff} = [@$FA_finanzamt];
494   }
495
496   $sth->finish();
497   $dbh->disconnect();
498
499   $main::lxdebug->leave_sub();
500
501   return \%finanzamt;
502 }
503
504 sub process_query {
505   $main::lxdebug->enter_sub();
506
507   # Copyright D. Simander -> SL::Form under Gnu GPL.
508   my ($form, $dbh, $filename) = @_;
509
510   #  return unless (-f $filename);
511
512   open(FH, "$filename") or $form->error("$filename : $!\n");
513   my $query = "";
514   my $sth;
515   my @quote_chars;
516
517   while (<FH>) {
518
519     # Remove DOS and Unix style line endings.
520     s/[\r\n]//g;
521
522     # don't add comments or empty lines
523     next if /^(--.*|\s+)$/;
524
525     for (my $i = 0; $i < length($_); $i++) {
526       my $char = substr($_, $i, 1);
527
528       # Are we inside a string?
529       if (@quote_chars) {
530         if ($char eq $quote_chars[-1]) {
531           pop(@quote_chars);
532         }
533         $query .= $char;
534
535       } else {
536         if (($char eq "'") || ($char eq "\"")) {
537           push(@quote_chars, $char);
538
539         } elsif ($char eq ";") {
540
541           # Query is complete. Send it.
542
543           $sth = $dbh->prepare($query);
544           $sth->execute || $form->dberror($query);
545           $sth->finish;
546
547           $char  = "";
548           $query = "";
549         }
550
551         $query .= $char;
552       }
553     }
554   }
555
556   close FH;
557
558   $main::lxdebug->leave_sub();
559 }
560
561 sub ustva {
562   $main::lxdebug->enter_sub();
563
564   my ($self, $myconfig, $form) = @_;
565
566   # connect to database
567   my $dbh = $form->dbconnect($myconfig);
568
569   my $last_period     = 0;
570   my $category        = "pos_ustva";
571   my @categories_cent = qw(511 861 36 80 971 931 98 96 53 74
572     85 65 66 61 62 67 63 64 59 69 39 83
573     Z43 Z45 Z53 Z62 Z65 Z67);
574
575   my @categories_euro = qw(41 44 49 43 48 51 86 35 77 76 91 97 93
576     95 94 42 60 45 52 73 84);
577
578   $form->{decimalplaces} *= 1;
579
580   foreach $item (@categories_cent) {
581     $form->{"$item"} = 0;
582   }
583   foreach $item (@categories_euro) {
584     $form->{"$item"} = 0;
585   }
586
587   &get_accounts_ustva($dbh, $last_period, $form->{fromdate}, $form->{todate},
588                       $form, $category);
589
590   #
591   # Berechnung der USTVA Formularfelder
592   #
593   $form->{"51r"} = $form->{"511"};
594   $form->{"86r"} = $form->{"861"};
595   $form->{"97r"} = $form->{"971"};
596   $form->{"93r"} = $form->{"931"};
597   $form->{"Z43"} =
598     $form->{"511"} + $form->{"861"} + $form->{"36"} + $form->{"80"} +
599     $form->{"971"} + $form->{"931"} + $form->{"96"} + $form->{"98"};
600   $form->{"Z45"} = $form->{"Z43"};
601   $form->{"Z53"} = $form->{"Z43"};
602   $form->{"Z62"} =
603     $form->{"Z43"} - $form->{"66"} - $form->{"61"} - $form->{"62"} -
604     $form->{"63"} - $form->{"64"} - $form->{"59"};
605   $form->{"Z65"} = $form->{"Z62"} - $form->{"69"};
606   $form->{"83"}  = $form->{"Z65"} - $form->{"39"};
607
608   foreach $item (@categories_cent) {
609     $form->{$item} =
610       $form->format_amount($myconfig, $form->round_amount($form->{$item}, 2),
611                            2, '0');
612   }
613
614   foreach $item (@categories_euro) {
615     $form->{$item} =
616       $form->format_amount($myconfig, $form->round_amount($form->{$item}, 0),
617                            0, '0');
618   }
619
620   $dbh->disconnect;
621
622   $main::lxdebug->leave_sub();
623 }
624
625 sub get_accounts_ustva {
626   $main::lxdebug->enter_sub();
627
628   my ($dbh, $last_period, $fromdate, $todate, $form, $category) = @_;
629
630   my ($null, $department_id) = split /--/, $form->{department};
631
632   my $query;
633   my $dpt_where;
634   my $dpt_join;
635   my $project;
636   my $where    = "1 = 1";
637   my $glwhere  = "";
638   my $subwhere = "";
639   my $ARwhere  = "";
640   my $arwhere  = "";
641   my $item;
642
643   if ($fromdate) {
644     if ($form->{method} eq 'cash') {
645       $subwhere .= " AND transdate >= '$fromdate'";
646       $glwhere = " AND ac.transdate >= '$fromdate'";
647       $ARwhere .= " AND acc.transdate >= '$fromdate'";
648     }
649     $where .= " AND ac.transdate >= '$fromdate'";
650   }
651
652   if ($todate) {
653     $where    .= " AND ac.transdate <= '$todate'";
654     $ARwhere  .= " AND acc.transdate <= '$todate'";
655     $subwhere .= " AND transdate <= '$todate'";
656   }
657
658   if ($department_id) {
659     $dpt_join = qq|
660                JOIN department t ON (a.department_id = t.id)
661                   |;
662     $dpt_where = qq|
663                AND t.id = $department_id
664                    |;
665   }
666
667   if ($form->{project_id}) {
668     $project = qq|
669                  AND ac.project_id = $form->{project_id}
670                  |;
671   }
672
673   if ($form->{method} eq 'cash') {
674
675     $query = qq|
676
677  SELECT
678    SUM( ac.amount *
679       -- Bezahlt / Rechnungssumme
680      ( 
681        SELECT SUM(acc.amount)
682        FROM acc_trans acc
683        INNER JOIN chart c ON (acc.chart_id = c.id AND c.link like '%AR_paid%')
684        WHERE
685         1=1 
686         $ARwhere
687         AND acc.trans_id = ac.trans_id
688         )
689      / 
690      ( 
691       select amount from ar where id = ac.trans_id  
692      )
693    ) AS amount,
694    c.pos_ustva
695    FROM acc_trans ac
696    JOIN chart c ON (c.id = ac.chart_id)
697    --JOIN ar ON (ar.id = ac.trans_id)
698    where 
699      1=1 
700      -- Here no where, please. All Transactions ever should be
701      -- testet if they are paied in the USTVA report period.
702    GROUP BY c.pos_ustva
703         UNION
704
705                  SELECT sum(ac.amount) AS amount,
706                  c.$category
707                  FROM acc_trans ac
708                  JOIN chart c ON (c.id = ac.chart_id)
709                  JOIN ap a ON (a.id = ac.trans_id)
710                  $dpt_join
711                  WHERE $where
712                  $dpt_where
713                  AND ac.trans_id IN
714                    (
715                      SELECT trans_id
716                      FROM acc_trans
717                      JOIN chart ON (chart_id = id)
718                      WHERE link LIKE '%AP_amount%'
719                      $subwhere
720                    )
721
722                  $project
723                  GROUP BY c.$category
724
725         UNION
726
727                  SELECT sum(ac.amount) AS amount,
728                  c.$category
729                  FROM acc_trans ac
730                  JOIN chart c ON (c.id = ac.chart_id)
731                  JOIN gl a ON (a.id = ac.trans_id)
732                  $dpt_join
733                  WHERE $where
734                  $glwhere
735                  $dpt_from
736                  AND NOT (c.link = 'AR' OR c.link = 'AP')
737                  $project
738                  GROUP BY c.$category
739
740                  |;
741
742     if ($form->{project_id}) {
743
744       $query .= qq|
745
746          UNION
747
748                  SELECT SUM(ac.sellprice * ac.qty) AS amount,
749                  c.$category
750                  FROM invoice ac
751                  JOIN ar a ON (a.id = ac.trans_id)
752                  JOIN parts p ON (ac.parts_id = p.id)
753                  JOIN chart c on (p.income_accno_id = c.id)
754                  $dpt_join
755         -- use transdate from subwhere
756                  WHERE 1 = 1 $subwhere
757                  AND c.category = 'I'
758                  $dpt_where
759                  AND ac.trans_id IN
760                    (
761                      SELECT trans_id
762                      FROM acc_trans
763                      JOIN chart ON (chart_id = id)
764                      WHERE link LIKE '%AR_paid%'
765                      $subwhere
766                    )
767
768                  $project
769                  GROUP BY c.$category
770
771          UNION
772
773                  SELECT SUM(ac.sellprice) AS amount,
774                  c.$category
775                  FROM invoice ac
776                  JOIN ap a ON (a.id = ac.trans_id)
777                  JOIN parts p ON (ac.parts_id = p.id)
778                  JOIN chart c on (p.expense_accno_id = c.id)
779                  $dpt_join
780                  WHERE 1 = 1 $subwhere
781                  AND c.category = 'E'
782                  $dpt_where
783                  AND ac.trans_id IN
784                    (
785                      SELECT trans_id
786                      FROM acc_trans
787                      JOIN chart ON (chart_id = id)
788                      WHERE link LIKE '%AP_paid%'
789                      $subwhere
790                    )
791
792                  $project
793                  GROUP BY c.$category
794                  |;
795     }
796
797   } else {
798
799     if ($department_id) {
800       $dpt_join = qq|
801               JOIN dpt_trans t ON (t.trans_id = ac.trans_id)
802               |;
803       $dpt_where = qq|
804                AND t.department_id = $department_id
805               |;
806     }
807
808     $query = qq|
809
810                  SELECT sum(ac.amount) AS amount,
811                  c.$category
812                  FROM acc_trans ac
813                  JOIN chart c ON (c.id = ac.chart_id)
814                  $dpt_join
815                  WHERE $where
816                  $dpt_where
817                  $project
818                  GROUP BY c.$category
819                  |;
820
821     if ($form->{project_id}) {
822
823       $query .= qq|
824
825         UNION
826
827                  SELECT SUM(ac.sellprice * ac.qty) AS amount,
828                  c.$category
829                  FROM invoice ac
830                  JOIN ar a ON (a.id = ac.trans_id)
831                  JOIN parts p ON (ac.parts_id = p.id)
832                  JOIN chart c on (p.income_accno_id = c.id)
833                  $dpt_join
834         -- use transdate from subwhere
835                  WHERE 1 = 1 $subwhere
836                  AND c.category = 'I'
837                  $dpt_where
838                  $project
839                  GROUP BY c.$category
840
841         UNION
842
843                  SELECT SUM(ac.sellprice * ac.qty) * -1 AS amount,
844                  c.$category
845                  FROM invoice ac
846                  JOIN ap a ON (a.id = ac.trans_id)
847                  JOIN parts p ON (ac.parts_id = p.id)
848                  JOIN chart c on (p.expense_accno_id = c.id)
849                  $dpt_join
850                  WHERE 1 = 1 $subwhere
851                  AND c.category = 'E'
852                  $dpt_where
853                  $project
854                  GROUP BY c.$category
855                  |;
856
857     }
858   }
859
860   my @accno;
861   my $accno;
862   my $ref;
863
864   # Show all $query in Debuglevel LXDebug::QUERY
865   $callingdetails = (caller (0))[3];
866   $main::lxdebug->message(LXDebug::QUERY, "$callingdetails \$query=\n $query");
867               
868   my $sth = $dbh->prepare($query);
869   $sth->execute || $form->dberror($query);
870
871   while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
872 # Bug 365 solved?!
873 #    if ($ref->{amount} < 0) {
874       $ref->{amount} *= -1;
875 #    }
876     if ($category eq "pos_bwa") {
877       if ($last_period) {
878         $form->{ $ref->{$category} }{kumm} += $ref->{amount};
879       } else {
880         $form->{ $ref->{$category} }{jetzt} += $ref->{amount};
881       }
882     } else {
883       $form->{ $ref->{$category} } += $ref->{amount};
884     }
885   }
886   $sth->finish;
887
888   $main::lxdebug->leave_sub();
889 }
890
891 1;