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