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