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