Der letzte Einkauspreis wurde nicht geladen und daher auch keine MArgenberechnung
[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 my $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 $query;
755   my $where    = "";
756   my $glwhere  = "";
757   my $subwhere = "";
758   my $ARwhere  = "";
759   my $APwhere  = '';
760   my $arwhere  = "";
761   my $item;
762
763     my $gltaxkey_where = "(tk.pos_ustva>=59 AND tk.pos_ustva<=66)";
764
765   if ($fromdate) {
766     if ($form->{method} eq 'cash') {
767       $subwhere .= " AND transdate >= '$fromdate'";
768       $glwhere = " AND ac.transdate >= '$fromdate'";
769       $ARwhere .= " AND acc.transdate >= '$fromdate'"; 
770     }
771     $APwhere .= " AND AP.transdate >= '$fromdate'";
772     $where .= " AND ac.transdate >= '$fromdate'";
773   }
774
775   if ($todate) {
776     $where    .= " AND ac.transdate <= '$todate'";
777     $ARwhere  .= " AND acc.transdate <= '$todate'";
778   }
779
780   ############################################
781   # Method eq 'cash' = IST Versteuerung
782   ############################################
783   # Betrifft nur die eingenommene Umsatzsteuer
784   #
785   ############################################
786
787   if ($form->{method} eq 'cash') {  
788
789     $query = qq|
790        SELECT
791          -- USTVA IST-Versteuerung
792          -- 
793          -- Alle tatsaechlichen _Zahlungseingaenge_ 
794          -- im Voranmeldezeitraum erfassen 
795          -- (Teilzahlungen werden prozentual auf verschiedene Steuern aufgeteilt)
796          SUM( ac.amount * 
797             -- Bezahlt / Rechnungssumme
798            ( 
799              SELECT SUM(acc.amount)
800              FROM acc_trans acc
801              INNER JOIN chart c ON (acc.chart_id   =   c.id 
802                                     AND c.link   like  '%AR_paid%')
803              WHERE
804               1=1 
805               $ARwhere
806               AND acc.trans_id = ac.trans_id
807               )
808            / 
809            ( 
810             SELECT amount FROM ar WHERE id = ac.trans_id  
811            )
812          ) AS amount,
813          tk.pos_ustva
814        FROM acc_trans ac
815        LEFT JOIN chart c ON (c.id  = ac.chart_id)
816        LEFT JOIN ar      ON (ar.id = ac.trans_id)
817        LEFT JOIN taxkeys tk ON (
818          tk.id = (
819            SELECT id FROM taxkeys 
820            WHERE chart_id   = ac.chart_id 
821              -- AND taxkey_id  = ac.taxkey 
822              AND startdate <= COALESCE(ar.deliverydate,ar.transdate)
823            ORDER BY startdate DESC LIMIT 1
824          )
825        )
826        WHERE 
827        1=1 
828        -- Here no where, please. All Transactions ever should be
829        -- testet if they are paied in the USTVA report period.
830        GROUP BY tk.pos_ustva
831     |;
832    
833   } elsif ($form->{method} eq 'accrual') {
834     #########################################
835     # Method eq 'accrual' = Soll Versteuerung
836     #########################################
837
838     $query = qq|
839        -- Alle Einnahmen AR und pos_ustva erfassen
840        SELECT
841          - sum(ac.amount) AS amount, 
842          tk.pos_ustva
843        FROM acc_trans ac 
844        JOIN chart c ON (c.id = ac.chart_id) 
845        JOIN ar ON (ar.id = ac.trans_id)
846        JOIN taxkeys tk ON (
847          tk.id = (
848            SELECT id FROM taxkeys 
849            WHERE chart_id   = ac.chart_id 
850              AND startdate <= COALESCE(ar.deliverydate,ar.transdate)
851            ORDER BY startdate DESC LIMIT 1
852          )
853        )
854        $dpt_join
855        WHERE 1 = 1
856        $where
857        GROUP BY tk.pos_ustva
858   |;
859    
860   } else {
861   
862     $self->error("Unknown tax method: $form->{method}")
863
864   }
865   
866   #########################################
867   # Ausgaben und Gl Buchungen sind gleich
868   # für Ist- und Soll-Versteuerung
869   #########################################
870   $query .= qq| 
871      UNION -- alle Ausgaben AP erfassen
872
873        SELECT
874          sum(ac.amount) AS amount, 
875          tk.pos_ustva
876        FROM acc_trans ac
877        JOIN ap ON (ap.id = ac.trans_id )
878        JOIN chart c ON (c.id = ac.chart_id)
879        LEFT JOIN taxkeys tk ON (
880            tk.id = (
881              SELECT id FROM taxkeys 
882              WHERE 1=1
883                AND chart_id=ac.chart_id 
884                --AND taxkey_id = ac.taxkey 
885                AND startdate <= COALESCE(AP.transdate)
886              ORDER BY startdate DESC LIMIT 1
887            )
888        )
889        WHERE
890        1=1
891        $where
892        GROUP BY tk.pos_ustva
893
894      UNION -- Einnahmen direkter gl Buchungen erfassen
895
896        SELECT sum
897          ( - ac.amount) AS amount, 
898          tk.pos_ustva
899        FROM acc_trans ac
900        JOIN chart c ON (c.id = ac.chart_id)
901        JOIN gl a ON (a.id = ac.trans_id)
902        LEFT JOIN taxkeys tk ON (
903          tk.id = (
904            SELECT id FROM taxkeys 
905            WHERE chart_id=ac.chart_id 
906              AND NOT $gltaxkey_where  
907              AND startdate <= COALESCE(ac.transdate)
908            ORDER BY startdate DESC LIMIT 1
909          )
910        )
911
912        $dpt_join
913        WHERE 1 = 1
914        $where
915        GROUP BY tk.pos_ustva
916
917
918      UNION -- Ausgaben direkter gl Buchungen erfassen
919
920        SELECT sum
921          (ac.amount) AS amount, 
922          tk.pos_ustva
923        FROM acc_trans ac
924        JOIN chart c ON (c.id = ac.chart_id)
925        JOIN gl a ON (a.id = ac.trans_id)
926        LEFT JOIN taxkeys tk ON (
927          tk.id = (
928            SELECT id FROM taxkeys 
929            WHERE chart_id=ac.chart_id 
930              AND $gltaxkey_where 
931              AND startdate <= COALESCE(ac.transdate)
932            ORDER BY startdate DESC LIMIT 1
933          )
934        )
935
936        $dpt_join
937        WHERE 1 = 1
938        $where
939        GROUP BY tk.pos_ustva
940
941   |;
942
943   my @accno;
944   my $accno;
945   my $ref;
946
947   # Show all $query in Debuglevel LXDebug::QUERY
948   $callingdetails = (caller (0))[3];
949   $main::lxdebug->message(LXDebug::QUERY, "$callingdetails \$query=\n $query");
950               
951   my $sth = $dbh->prepare($query);
952   
953   $sth->execute || $form->dberror($query);
954
955   while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
956     # Bug 365 solved?!
957     $ref->{amount} *= -1;
958     $form->{ $ref->{$category} } += $ref->{amount};
959   }
960
961   $sth->finish;
962
963   $main::lxdebug->leave_sub();
964
965 }
966
967 sub get_config {
968   $main::lxdebug->enter_sub();
969
970   my ($self, $userspath, $filename) = @_;
971
972   $form->error("Missing Parameter: @_") if !$userspath || !$filename;
973
974   my $form = $main::form;
975
976   $filename = "$form->{login}_$filename";
977   $filename =~ s|.*/||;
978   $filename = "$userspath/$filename";
979   open my $FACONF, "<", $filename or sub {# Annon Sub
980     # catch open error
981     # create file if file does not exist
982     open my $FANEW, ">", $filename  or $form->error("CREATE: $filename : $!");
983     close $FANEW                    or $form->error("CLOSE: $filename : $!");
984     
985     #try again open file
986     open my $FACONF, "<", $filename or $form->error("OPEN: $filename : $!");
987   };
988
989   while (<$FACONF>) {
990     last if (/^\[/);
991     next if (/^(\#|\s)/);
992
993     # remove comments
994     s/\s#.*//g;
995
996     # remove any trailing whitespace
997     s/^\s*(.*?)\s*$/$1/;
998     my ($key, $value) = split(/=/, $_, 2);
999
1000     $form->{$key} = "$value";
1001
1002   }
1003
1004   close $FACONF;
1005
1006   $main::lxdebug->leave_sub();
1007 }
1008
1009
1010 1;