1 #=====================================================================
3 # Copyright (c) 2004 by Udo Spallek, Aachen
7 # Web: http://www.lx-office.org
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.
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., 51 Franklin Street, Fifth Floor, Boston,
23 #======================================================================
25 #=====================================================================
31 use List::Util qw(first);
36 use SL::DB::Finanzamt;
37 use SL::Locale::String qw(t8);
42 my @tax_office_information = (
43 { 'id' => 8, 'name' => 'Baden-Württemberg', 'taxbird_nr' => '1', 'elster_format' => 'FFBBB/UUUUP', },
44 { 'id' => 9, 'name' => 'Bayern', 'taxbird_nr' => '2', 'elster_format' => 'FFF/BBB/UUUUP', },
45 { 'id' => 11, 'name' => 'Berlin', 'taxbird_nr' => '3', 'elster_format' => 'FF/BBB/UUUUP', },
46 { 'id' => 12, 'name' => 'Brandenburg', 'taxbird_nr' => '4', 'elster_format' => 'FFF/BBB/UUUUP', },
47 { 'id' => 4, 'name' => 'Bremen', 'taxbird_nr' => '5', 'elster_format' => 'FF BBB UUUUP', },
48 { 'id' => 2, 'name' => 'Hamburg', 'taxbird_nr' => '6', 'elster_format' => 'FF/BBB/UUUUP', },
49 { 'id' => 6, 'name' => 'Hessen', 'taxbird_nr' => '7', 'elster_format' => '0FF BBB UUUUP', },
50 { 'id' => 13, 'name' => 'Mecklenburg-Vorpommern', 'taxbird_nr' => '8', 'elster_format' => 'FFF/BBB/UUUUP', },
51 { 'id' => 3, 'name' => 'Niedersachsen', 'taxbird_nr' => '9', 'elster_format' => 'FF/BBB/UUUUP', },
52 { 'id' => 5, 'name' => 'Nordrhein-Westfalen', 'taxbird_nr' => '10', 'elster_format' => 'FFF/BBBB/UUUP', },
53 { 'id' => 7, 'name' => 'Rheinland-Pfalz', 'taxbird_nr' => '11', 'elster_format' => 'FF/BBB/UUUUP', },
54 { 'id' => 10, 'name' => 'Saarland', 'taxbird_nr' => '12', 'elster_format' => 'FFF/BBB/UUUUP', },
55 { 'id' => 14, 'name' => 'Sachsen', 'taxbird_nr' => '13', 'elster_format' => 'FFF/BBB/UUUUP', },
56 { 'id' => 15, 'name' => 'Sachsen-Anhalt', 'taxbird_nr' => '14', 'elster_format' => 'FFF/BBB/UUUUP', },
57 { 'id' => 1, 'name' => 'Schleswig-Holstein', 'taxbird_nr' => '15', 'elster_format' => 'FF BBB UUUUP', },
58 { 'id' => 16, 'name' => 'Thüringen', 'taxbird_nr' => '16', 'elster_format' => 'FFF/BBB/UUUUP', },
61 my @fiamt_config = qw(taxnumber fa_bufa_nr fa_dauerfrist fa_steuerberater_city fa_steuerberater_name
62 fa_steuerberater_street fa_steuerberater_tel fa_voranmeld);
64 my @fiamt_finanzamt = qw(
65 fa_land_nr fa_bufa_nr fa_name fa_strasse
66 fa_plz fa_ort fa_telefon fa_fax
67 fa_plz_grosskunden fa_plz_postfach fa_postfach
68 fa_blz_1 fa_kontonummer_1 fa_bankbezeichnung_1
69 fa_blz_2 fa_kontonummer_2 fa_bankbezeichnung_2 fa_oeffnungszeiten
70 fa_email fa_internet);
88 $self->{tax_office_information} = [];
90 foreach (@tax_office_information) {
92 $entry->{name} = $::locale->{iconv_utf8}->convert($entry->{name});
93 push @{ $self->{tax_office_information} }, $entry;
99 my ( $self, $form ) = @_;
101 my $coa = $::instance_conf->get_coa;
103 $form->{"COA_$coa"} = '1';
104 $form->{COA_Germany} = '1' if ($coa =~ m/^germany/i);
110 sub report_variables {
111 # Get all positions for taxreport out of the database
112 # Needs Databaseupdate Pg-upgrade2/USTVA_abstraction.pl
117 my $myconfig = $arg_ref->{myconfig};
118 my $form = $arg_ref->{form};
119 my $type = $arg_ref->{type}; # 'paied' || 'received' || ''
120 my $attribute = $arg_ref->{attribute}; #
121 my $dec_places = (defined $arg_ref->{dec_places}) ? $arg_ref->{dec_places}:undef;
123 my $where_type = $type ? "AND tax.report_headings.type = '$type'" : '';
124 my $where_dcp = defined $dec_places ? "AND tax.report_variables.dec_places = '$dec_places'" : '';
128 FROM tax.report_variables
129 LEFT JOIN tax.report_headings
130 ON (tax.report_variables.heading_id = tax.report_headings.id)
138 SL::DB->client->with_transaction(sub {
139 my $dbh = SL::DB->client->dbh;
140 my $sth = $dbh->prepare($query);
142 $sth->execute() || $form->dberror($query);
144 while ( my $row_ref = $sth->fetchrow_arrayref() ) {
145 push @positions, @$row_ref; # Copy the array contents
150 }) or do { die SL::DB->client->error };
156 sub steuernummer_input {
157 $main::lxdebug->enter_sub();
159 my ($self, $elsterland, $elsterFFFF, $steuernummer) = @_;
160 our ($elster_FFFF, $elster_land);
162 my $steuernummer_input = '';
164 $elster_land = $elsterland;
165 $elster_FFFF = $elsterFFFF;
166 $steuernummer = '0000000000' if ($steuernummer eq '');
168 # $steuernummer formatieren (nur Zahlen) -> $stnr
169 my $stnr = $steuernummer;
172 #Pattern description Elstersteuernummer
175 my $tax_office = first { $_->{id} eq $elster_land } @{ $self->{tax_office_information} };
176 my $elster_pattern = $tax_office->{elster_format};
177 # $::lxdebug->message(LXDebug->DEBUG2, "stnr=".$stnr." elster_FFFF=".$elster_FFFF.
178 # " pattern=".$elster_pattern." land=".$elster_land);
179 my @elster_pattern = split(' ', $elster_pattern);
180 my $delimiter1 = ' ';
181 my $delimiter2 = ' ';
182 my $patterncount = @elster_pattern;
183 if ($patterncount < 2) {
184 @elster_pattern = ();
185 @elster_pattern = split('/', $elster_pattern);
188 $patterncount = @elster_pattern;
189 if ($patterncount < 2) {
190 @elster_pattern = ();
191 @elster_pattern = split(' ', $elster_pattern);
194 $patterncount = @elster_pattern;
198 # no we have an array of patternparts and a delimiter
199 # create the first automated and fixed part and delimiter
201 $steuernummer_input .= qq|<b><font size="+1">|;
203 # $::lxdebug->message(LXDebug->DEBUG2, "pattern0=".$elster_pattern[0]);
205 $elster_pattern[0] eq 'FFF' && do {
206 $part = substr($elster_FFFF, 1, 4);
207 $steuernummer_input .= qq|$part|;
210 $elster_pattern[0] eq '0FF' && do {
211 $part = '0' . substr($elster_FFFF, 2, 4);
212 $steuernummer_input .= qq|$part|;
215 $elster_pattern[0] eq 'FFBBB' && do {
216 $part = substr($elster_FFFF, 2, 4);
217 $steuernummer_input .= qq|$part|;
221 @elster_pattern = ('FF','BBB','UUUUP');
224 $elster_pattern[0] eq 'FF' && do {
225 $part = substr($elster_FFFF, 2, 4);
226 $steuernummer_input .= qq|$part|;
230 $steuernummer_input .= qq|Fehler!|;
235 #now the rest of the Steuernummer ...
236 $steuernummer_input .= qq|</font></b>|;
237 $steuernummer_input .= qq|\n
238 <input type=hidden name="elster_pattern" value="$elster_pattern">
239 <input type=hidden name="patterncount" value="$patterncount">
240 <input type=hidden name="patternlength" value="$patterncount">
241 <input type=hidden name="delimiter1" value="$delimiter1">
242 <input type=hidden name="delimiter2" value="$delimiter2">
243 <input type=hidden name="part" value="$part">
248 for (my $h = 1; $h < $patterncount; $h++) {
249 my $delimiter = ( $h==1?$delimiter1:$delimiter2);
250 $steuernummer_input .= qq| $delimiter \n|;
251 # $::lxdebug->message(LXDebug->DEBUG2, "pattern[$h]=".$elster_pattern[$h]);
252 for (my $i = 1; $i <= length($elster_pattern[$h]); $i++) {
253 $steuernummer_input .= qq|<select name="part_$h\_$i">\n|;
255 for (my $j = 0; $j <= 9; $j++) {
256 $steuernummer_input .= qq| <option value="$j"|;
257 if ($steuernummer ne '') {
258 if ($j eq substr($stnr, length($part) + $k, 1)) {
259 $steuernummer_input .= qq| selected|;
262 $steuernummer_input .= qq|>$j</option>\n|;
265 $steuernummer_input .= qq|</select>\n|;
269 $main::lxdebug->leave_sub();
271 return $steuernummer_input;
275 $main::lxdebug->enter_sub();
277 # Referenz wird übergeben, hash of hash wird nicht
278 # in neues Hash kopiert, sondern direkt über die Referenz verändert
279 # Prototyp für diese Konstruktion
281 my ($self, $land, $elsterFFFF, $elster_init) = @_;
283 # $::lxdebug->message(LXDebug->DEBUG2,"land=".$land." amt=".$elsterFFFF);
285 my $FFFF = $elsterFFFF;
288 $checked = 'checked' if ($elsterFFFF eq '' and $land eq '');
290 my %elster_land_name = ();
293 <script language="Javascript">
294 function update_auswahl()
296 var elsterBLAuswahl = document.verzeichnis.fa_land_nr_new;
297 var elsterFAAuswahl = document.verzeichnis.fa_bufa_nr_new;
299 elsterFAAuswahl.options.length = 0; // dropdown aufräumen
302 foreach my $elster_land (sort keys %$elster_init) {
304 if (elsterBLAuswahl.options[elsterBLAuswahl.selectedIndex].value == "$elster_land")
308 %elster_land_fa = ();
310 for $FFFF (keys %{ $elster_init->{$elster_land} }) {
311 if ( $FFFF eq 'name' ) {
312 $elster_land_name{$elster_land} = $elster_init->{$elster_land}{$FFFF};
313 delete $elster_init->{$elster_land}{$FFFF};
315 $elster_land_fa{$FFFF} = $elster_init->{$elster_land}{$FFFF}->fa_name;
318 foreach $ffff (sort { $elster_land_fa{$a} cmp $elster_land_fa{$b} }
319 keys(%elster_land_fa)
322 elsterFAAuswahl.options[$j] = new Option("$elster_land_fa{$ffff} ($ffff)","$ffff");|;
338 <select size="1" name="fa_land_nr_new" onchange="update_auswahl()">|;
340 $fa_auswahl .= qq|<option value="Auswahl" $checked>| . $main::locale->text('Select federal state...') . qq|</option>\n|;
342 foreach my $elster_land (sort keys %$elster_init) {
344 <option value="$elster_land"|;
345 # $::lxdebug->message(LXDebug->DEBUG2,"land=".$land." elster_land=".$elster_land." lname=".$elster_land_name{$elster_land});
346 if ($elster_land eq $land and $checked eq '') {
347 $fa_auswahl .= qq| selected|;
349 $fa_auswahl .= qq|>$elster_land_name{$elster_land}</option>
358 my $elster_land = '';
359 $elster_land = ($land ne '') ? $land : '';
360 %elster_land_fa = ();
361 for $FFFF (keys %{ $elster_init->{$elster_land} }) {
362 $elster_land_fa{$FFFF} = $elster_init->{$elster_land}{$FFFF}->fa_name;
370 <select size="1" name="fa_bufa_nr_new">|;
371 if ($elsterFFFF eq '') {
372 $fa_auswahl .= qq|<option value="Auswahl" $checked>| . $main::locale->text('Select tax office...') . qq|</option>|;
374 foreach $ffff (sort { $elster_land_fa{$a} cmp $elster_land_fa{$b} }
375 keys(%elster_land_fa)
379 <option value="$ffff"|;
380 if ($ffff eq $elsterFFFF and $checked eq '') {
381 $fa_auswahl .= qq| selected|;
383 $fa_auswahl .= qq|>$elster_land_fa{$ffff} ($ffff)</option>|;
392 $main::lxdebug->leave_sub();
398 $main::lxdebug->enter_sub();
402 if ($ENV{HTTP_USER_AGENT}) {
405 print qq|<body><h2 class=info>Hinweis</h2>
411 <input type=button value="| . $main::locale->text('Back') . qq|" onClick="history.go(-1)">
415 $::dispatcher->end_request;
419 die "Hinweis: $msg\n";
422 $main::lxdebug->leave_sub();
425 sub query_finanzamt {
426 $main::lxdebug->enter_sub();
428 my ($self, $myconfig, $form) = @_;
430 my $dbh = SL::DB->client->dbh;
432 #Test, if table finanzamt exist
433 my $table = 'finanzamt';
434 my $filename = "sql/$table.sql";
436 my $tst = $dbh->prepare("SELECT * FROM $table");
437 $tst->execute || do {
438 #There is no table, read the table from sql/finanzamt.sql
439 print qq|<p>Bitte warten, Tabelle $table wird einmalig in Datenbank:
440 $myconfig->{dbname} als Benutzer: $myconfig->{dbuser} hinzugefügt...</p>|;
441 SL::DB->client->with_transaction(sub {
442 process_query($form, $dbh, $filename) || $self->error(DBI->errstr);
444 }) or do { die SL::DB->client->error };
449 my $fiamt = SL::DB::Finanzamt->_get_manager_class->get_all(sort => 'fa_land_nr');
452 foreach my $row (@$fiamt) {
453 my $tax_office = first { $_->{id} == $row->fa_land_nr } @{ $self->{tax_office_information} };
454 $land = $tax_office->{id};
455 $finanzamt{$land}{$row->fa_bufa_nr} = $row;
456 $finanzamt{$land}{'name'} ||= $tax_office->{name};
458 $main::lxdebug->leave_sub();
464 $main::lxdebug->enter_sub();
466 my ($form, $dbh, $filename) = @_;
468 open my $FH, "<", "$filename" or $form->error("$filename : $!\n");
475 # Remove DOS and Unix style line endings.
478 # don't add comments or empty lines
479 next if /^(--.*|\s+)$/;
481 for (my $i = 0; $i < length($_); $i++) {
482 my $char = substr($_, $i, 1);
484 # Are we inside a string?
486 if ($char eq $quote_chars[-1]) {
492 if (($char eq "'") || ($char eq "\"")) {
493 push(@quote_chars, $char);
495 } elsif ($char eq ";") {
497 # Query is complete. Send it.
499 $sth = $dbh->prepare($query);
500 $sth->execute || $form->dberror($query);
514 $main::lxdebug->leave_sub();
518 $main::lxdebug->enter_sub();
520 my ($self, $myconfig, $form) = @_;
522 my $dbh = SL::DB->client->dbh;
525 my $category = "pos_ustva";
527 $form->{coa} = $::instance_conf->get_coa;
529 unless ($form->{coa} eq 'Germany-DATEV-SKR03EU' or $form->{coa} eq 'Germany-DATEV-SKR04EU') {
530 croak t8("Advance turnover tax return only valid for SKR03 or SKR04");
532 my @category_cent = USTVA->report_variables({
533 myconfig => $myconfig,
536 attribute => 'position',
539 push @category_cent, ("pos_ustva_811b_kivi", "pos_ustva_861b_kivi");
540 if ( $form->{coa} eq 'Germany-DATEV-SKR03EU' or $form->{coa} eq 'Germany-DATEV-SKR04EU') {
541 push @category_cent, qw(Z43 Z45 Z53 Z54 Z62 Z65 Z67);
543 my @category_euro = USTVA->report_variables({
544 myconfig => $myconfig,
547 attribute => 'position',
550 push @category_euro, ("pos_ustva_81b_kivi", "pos_ustva_86b_kivi");
551 @{$form->{category_cent}} = @category_cent;
552 @{$form->{category_euro}} = @category_euro;
553 $form->{decimalplaces} *= 1;
555 foreach my $item (@category_cent) {
556 $form->{"$item"} = 0;
558 foreach my $item (@category_euro) {
559 $form->{"$item"} = 0;
562 # Controlvariable for templates
563 my $coa_name = $form->{coa};
564 $form->{"$coa_name"} = '1';
566 &get_accounts_ustva($dbh, $last_period, $form->{fromdate}, $form->{todate},
569 ###########################################
571 # Nationspecific Modfications
573 ###########################################
577 if ( $form->{coa} eq 'Germany-DATEV-SKR03EU' or $form->{coa} eq 'Germany-DATEV-SKR04EU') {
580 # Umordnen der Kennziffern
581 if ( $form->{year} < 2007) {
582 $form->{35} += $form->{81};
583 $form->{36} += $form->{811};
584 $form->{95} += $form->{89};
585 $form->{98} += $form->{891};
586 map { delete $form->{$_} } qw(81 811 89 891);
588 $form->{35} += $form->{51};
589 $form->{36} += $form->{511};
590 $form->{95} += $form->{97};
591 $form->{98} += $form->{971};
592 map { delete $form->{$_} } qw(51 511 97 971);
598 # Fixme: Wird auch noch für Oesterreich gebraucht,
599 # weil kein eigenes Ausgabeformular
600 # sollte aber aus der allgemeinen Steuerberechnung verschwinden
602 # Berechnung der USTVA Formularfelder laut Bogen 207
605 $form->{"51r"} = $form->{"511"};
606 $form->{"86r"} = $form->{"861"};
607 $form->{"97r"} = $form->{"971"};
608 $form->{"93r"} = $form->{"931"};
610 $form->{"Z43"} = $form->{"511"} + $form->{"811"} + $form->{"861"}
611 + $form->{"36"} + $form->{"80"} + $form->{"971"}
612 + $form->{"891"} + $form->{"931"} + $form->{"96"}
615 $form->{"Z45"} = $form->{"Z43"};
617 $form->{"Z53"} = $form->{"Z45"} + $form->{"47"} + $form->{"53"} + $form->{"74"}
618 + $form->{"85"} + $form->{"65"};
620 $form->{"Z62"} = $form->{"Z53"} - $form->{"66"} - $form->{"61"}
621 - $form->{"62"} - $form->{"67"} - $form->{"63"}
622 - $form->{"64"} - $form->{"59"};
624 $form->{"Z65"} = $form->{"Z62"} - $form->{"69"};
625 $form->{"83"} = $form->{"Z65"} - $form->{"39"};
627 $main::lxdebug->leave_sub();
630 sub get_accounts_ustva {
631 $main::lxdebug->enter_sub();
633 my ($dbh, $last_period, $fromdate, $todate, $form, $category) = @_;
645 my $gltaxkey_where = "((tk.pos_ustva = 46) OR (tk.pos_ustva>=59 AND tk.pos_ustva<=67) or (tk.pos_ustva>=89 AND tk.pos_ustva<=93))";
648 if ($form->{accounting_method} eq 'cash') {
649 $subwhere .= " AND transdate >= '$fromdate'";
650 $glwhere = " AND ac.transdate >= '$fromdate'";
651 $ARwhere .= " AND acc.transdate >= '$fromdate'";
653 $APwhere .= " AND AP.transdate >= '$fromdate'";
654 $where .= " AND ac.transdate >= '$fromdate'";
658 $where .= " AND ac.transdate <= '$todate'";
659 $ARwhere .= " AND acc.transdate <= '$todate'";
662 my $acc_trans_where = '1=1';
663 if ($fromdate || $todate) {
664 $acc_trans_where = "ac.trans_id IN (SELECT DISTINCT trans_id FROM acc_trans WHERE ";
667 $acc_trans_where .= "transdate >= '$fromdate'";
670 $acc_trans_where .= " AND " if ($fromdate);
671 $acc_trans_where .= "transdate <= '$todate'";
674 $acc_trans_where .= ")";
677 ############################################
678 # Method eq 'cash' = IST Versteuerung
679 ############################################
680 # Betrifft nur die eingenommene Umsatzsteuer
682 ############################################
684 if ($form->{accounting_method} eq 'cash') {
688 -- USTVA IST-Versteuerung
690 -- Alle tatsaechlichen _Zahlungseingaenge_
691 -- im Voranmeldezeitraum erfassen
692 -- (Teilzahlungen werden prozentual auf verschiedene Steuern aufgeteilt)
694 -- Bezahlt / Rechnungssumme
696 SELECT SUM(acc.amount)
698 INNER JOIN chart c ON (acc.chart_id = c.id
699 AND c.link like '%AR_paid%')
703 AND acc.trans_id = ac.trans_id
706 SELECT amount FROM ar WHERE id = ac.trans_id
709 tk.pos_ustva, t.rate, c.accno
711 LEFT JOIN chart c ON (c.id = ac.chart_id)
712 LEFT JOIN ar ON (ar.id = ac.trans_id)
713 LEFT JOIN tax t ON (t.id = ac.tax_id)
714 LEFT JOIN taxkeys tk ON (
716 SELECT id FROM taxkeys
717 WHERE chart_id = ac.chart_id
718 -- AND taxkey_id = ac.taxkey
719 AND startdate <= COALESCE(ar.deliverydate,ar.transdate)
720 ORDER BY startdate DESC LIMIT 1
725 GROUP BY tk.pos_ustva, t.rate, c.accno
728 } elsif ($form->{accounting_method} eq 'accrual') {
729 #########################################
730 # Method eq 'accrual' = Soll Versteuerung
731 #########################################
734 -- Alle Einnahmen AR und pos_ustva erfassen
736 - sum(ac.amount) AS amount,
737 tk.pos_ustva, t.rate, c.accno
739 JOIN chart c ON (c.id = ac.chart_id)
740 JOIN ar ON (ar.id = ac.trans_id)
741 JOIN tax t ON (t.id = ac.tax_id)
744 SELECT id FROM taxkeys
745 WHERE chart_id = ac.chart_id
746 AND startdate <= COALESCE(ar.deliverydate,ar.transdate)
747 ORDER BY startdate DESC LIMIT 1
753 GROUP BY tk.pos_ustva, t.rate, c.accno
758 $form->error("Unknown tax method: $form->{accounting_method}")
762 #########################################
763 # Ausgaben und Gl Buchungen sind gleich
764 # für Ist- und Soll-Versteuerung
765 #########################################
767 UNION -- alle Ausgaben AP erfassen
770 sum(ac.amount) AS amount,
771 tk.pos_ustva, t.rate, c.accno
773 JOIN ap ON (ap.id = ac.trans_id )
774 JOIN chart c ON (c.id = ac.chart_id)
775 JOIN tax t ON (t.id = ac.tax_id)
776 LEFT JOIN taxkeys tk ON (
778 SELECT id FROM taxkeys
780 AND chart_id=ac.chart_id
781 --AND taxkey_id = ac.taxkey
782 AND startdate <= COALESCE(AP.transdate)
783 ORDER BY startdate DESC LIMIT 1
789 GROUP BY tk.pos_ustva, t.rate, c.accno
791 UNION -- Einnahmen direkter gl Buchungen erfassen
794 ( - ac.amount) AS amount,
795 tk.pos_ustva, t.rate, c.accno
797 JOIN chart c ON (c.id = ac.chart_id)
798 JOIN gl a ON (a.id = ac.trans_id)
799 JOIN tax t ON (t.id = ac.tax_id)
800 LEFT JOIN taxkeys tk ON (
802 SELECT id FROM taxkeys
803 WHERE chart_id=ac.chart_id
804 AND NOT $gltaxkey_where
805 AND startdate <= COALESCE(ac.transdate)
806 ORDER BY startdate DESC LIMIT 1
813 GROUP BY tk.pos_ustva, t.rate, c.accno
816 UNION -- Ausgaben direkter gl Buchungen erfassen
819 (ac.amount) AS amount,
820 tk.pos_ustva, t.rate, c.accno
822 JOIN chart c ON (c.id = ac.chart_id)
823 JOIN gl a ON (a.id = ac.trans_id)
824 JOIN tax t ON (t.id = ac.tax_id)
825 LEFT JOIN taxkeys tk ON (
827 SELECT id FROM taxkeys
828 WHERE chart_id=ac.chart_id
830 AND startdate <= COALESCE(ac.transdate)
831 ORDER BY startdate DESC LIMIT 1
838 GROUP BY tk.pos_ustva, t.rate, c.accno
842 # Show all $query in Debuglevel LXDebug::QUERY
843 my $callingdetails = (caller (0))[3];
844 $main::lxdebug->message(LXDebug->QUERY(), "$callingdetails \$query=\n $query");
846 my $sth = $dbh->prepare($query);
848 $sth->execute || $form->dberror($query);
849 # ugly, but we need to use static accnos
850 my ($accno_five, $accno_sixteen, $corr);
852 if ($form->{coa} eq 'Germany-DATEV-SKR03EU') {
854 $accno_sixteen = 1775;
855 } elsif (($form->{coa} eq 'Germany-DATEV-SKR04EU')) {
856 $accno_five = 3803; # SKR04
857 $accno_sixteen = 3805; # SKR04
858 } else {die "wrong call"; }
860 while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
861 next unless $ref->{$category};
863 $ref->{amount} *= -1;
865 if ($ref->{pos_ustva} eq '35') {
866 if ($ref->{rate} == 0.16) {
867 $form->{"pos_ustva_81b_kivi"} += $ref->{amount};
868 } elsif ($ref->{rate} == 0.05) {
869 $form->{"pos_ustva_86b_kivi"} += $ref->{amount};
870 } elsif ($ref->{rate} == 0.19) {
871 # pos_ustva says 16, but rate says 19
872 # (pos_ustva should be tax dependent and not taxkeys dependent)
873 # correction hotfix for this case:
874 # bookings exists with 19% ->
875 # move 19% bookings to the 19% position
876 # Dont rely on dates of taxkeys
878 $form->{"81"} += $ref->{amount};
879 } elsif ($ref->{rate} == 0.07) {
880 # pos_ustva says 5, but rate says 7
882 # Dont rely on dates of taxkeys
884 $form->{"86"} += $ref->{amount};
885 } else {die ("No valid tax rate for pos 35" . Dumper($ref)); }
887 # USTVA Pos 36 (Steuerkonten)
888 if ($ref->{pos_ustva} eq '36') {
889 if ($ref->{accno} =~ /^$accno_sixteen/) {
890 $form->{"pos_ustva_811b_kivi"} += $ref->{amount};
891 } elsif ($ref->{accno} =~ /^$accno_five/) {
892 $form->{"pos_ustva_861b_kivi"} += $ref->{amount};
893 } else { die ("No valid accno for pos 36" . Dumper($ref)); }
895 $form->{ $ref->{$category} } += $ref->{amount} unless $corr;
900 $main::lxdebug->leave_sub();
905 $main::lxdebug->enter_sub();
907 my ($self, $form) = @_;
909 # init some form vars
910 my @anmeldungszeitraum =
911 qw('0401' '0402' '0403'
915 '0441' '0442' '0443' '0444');
917 foreach my $item (@anmeldungszeitraum) {
921 #forgotten the year --> thisyear
922 if ($form->{year} !~ m/^\d\d\d\d$/) {
923 $form->{year} = substr(
925 $form->current_date(\%::myconfig), \%::myconfig
928 $::lxdebug->message(LXDebug->DEBUG1,
929 qq|Actual year from Database: $form->{year}\n|);
933 # using dates in ISO-8601 format: yyyymmmdd for Postgres...
937 if ($form->{period} eq "13") {
938 $form->{fromdate} = "$form->{year}0101";
939 $form->{todate} = "$form->{year}1231";
943 if ($form->{period} eq "41") {
944 $form->{fromdate} = "$form->{year}0101";
945 $form->{todate} = "$form->{year}0331";
946 $form->{'0441'} = "X";
948 if ($form->{period} eq "42") {
949 $form->{fromdate} = "$form->{year}0401";
950 $form->{todate} = "$form->{year}0630";
951 $form->{'0442'} = "X";
953 if ($form->{period} eq "43") {
954 $form->{fromdate} = "$form->{year}0701";
955 $form->{todate} = "$form->{year}0930";
956 $form->{'0443'} = "X";
958 if ($form->{period} eq "44") {
959 $form->{fromdate} = "$form->{year}1001";
960 $form->{todate} = "$form->{year}1231";
961 $form->{'0444'} = "X";
966 $form->{period} eq "01" && do {
967 $form->{fromdate} = "$form->{year}0101";
968 $form->{todate} = "$form->{year}0131";
969 $form->{'0401'} = "X";
972 $form->{period} eq "02" && do {
973 $form->{fromdate} = "$form->{year}0201";
975 #this works from 1901 to 2099, 1900 and 2100 fail.
976 my $leap = ($form->{year} % 4 == 0) ? "29" : "28";
977 $form->{todate} = "$form->{year}02$leap";
978 $form->{"0402"} = "X";
981 $form->{period} eq "03" && do {
982 $form->{fromdate} = "$form->{year}0301";
983 $form->{todate} = "$form->{year}0331";
984 $form->{"0403"} = "X";
987 $form->{period} eq "04" && do {
988 $form->{fromdate} = "$form->{year}0401";
989 $form->{todate} = "$form->{year}0430";
990 $form->{"0404"} = "X";
993 $form->{period} eq "05" && do {
994 $form->{fromdate} = "$form->{year}0501";
995 $form->{todate} = "$form->{year}0531";
996 $form->{"0405"} = "X";
999 $form->{period} eq "06" && do {
1000 $form->{fromdate} = "$form->{year}0601";
1001 $form->{todate} = "$form->{year}0630";
1002 $form->{"0406"} = "X";
1005 $form->{period} eq "07" && do {
1006 $form->{fromdate} = "$form->{year}0701";
1007 $form->{todate} = "$form->{year}0731";
1008 $form->{"0407"} = "X";
1011 $form->{period} eq "08" && do {
1012 $form->{fromdate} = "$form->{year}0801";
1013 $form->{todate} = "$form->{year}0831";
1014 $form->{"0408"} = "X";
1017 $form->{period} eq "09" && do {
1018 $form->{fromdate} = "$form->{year}0901";
1019 $form->{todate} = "$form->{year}0930";
1020 $form->{"0409"} = "X";
1023 $form->{period} eq "10" && do {
1024 $form->{fromdate} = "$form->{year}1001";
1025 $form->{todate} = "$form->{year}1031";
1026 $form->{"0410"} = "X";
1029 $form->{period} eq "11" && do {
1030 $form->{fromdate} = "$form->{year}1101";
1031 $form->{todate} = "$form->{year}1130";
1032 $form->{"0411"} = "X";
1035 $form->{period} eq "12" && do {
1036 $form->{fromdate} = "$form->{year}1201";
1037 $form->{todate} = "$form->{year}1231";
1038 $form->{"0412"} = "X";
1043 # Kontrollvariablen für die Templates
1044 $form->{"year$_"} = ($form->{year} >= $_ ) ? "1":"0" for 2007..2107;
1046 $main::lxdebug->leave_sub();
1049 sub get_fiamt_vars {
1050 return @fiamt_finanzamt;
1054 $main::lxdebug->enter_sub();
1058 'steuernummer' => 'taxnumber',
1059 'elsterFFFF' => 'fa_bufa_nr',
1060 'FA_dauerfrist' => 'fa_dauerfrist',
1061 'FA_steuerberater_city' => 'fa_steuerberater_city',
1062 'FA_steuerberater_name' => 'fa_steuerberater_name',
1063 'FA_steuerberater_street' => 'fa_steuerberater_street',
1064 'FA_steuerberater_tel' => 'fa_steuerberater_tel',
1065 'FA_voranmeld' => 'fa_voranmeld',
1068 my $filename = $::lx_office_conf{paths}{userspath}."/finanzamt.ini";
1070 return unless (open( $FACONF, "<", $filename));
1074 next if (/^(\#|\s)/);
1079 # remove any trailing whitespace
1080 s/^\s*(.*?)\s*$/$1/;
1081 my ($key, $value) = split(/=/, $_, 2);
1083 $main::lxdebug->message(LXDebug->DEBUG2(), "oldkey: ".$key." val=".$value." newkey=".
1084 $oldkeys{$key}." oval=".$::form->{$oldkeys{$key}});
1085 if ( $oldkeys{$key} && $::form->{$oldkeys{$key}} eq '' ) {
1086 $::form->{$oldkeys{$key}} = $::locale->{iconv_utf8}->convert($value);
1087 $main::lxdebug->message(LXDebug->DEBUG2(), "set ".$oldkeys{$key}."=".$::form->{$oldkeys{$key}});
1091 $main::lxdebug->leave_sub();
1096 $main::lxdebug->enter_sub();
1097 my $defaults = SL::DB::Default->get;
1098 my @rd_config = @fiamt_config;
1099 push @rd_config ,qw(accounting_method coa company address co_ustid duns);
1100 $::form->{$_} = $defaults->$_ for @rd_config;
1102 if ( $::form->{taxnumber} eq '' || $::form->{fa_bufa_nr} eq '') {
1103 #alte finanzamt.ini lesen, ggf abspeichern
1104 if ( get_oldconfig() ) {
1110 my $coa = $::form->{coa};
1111 $::form->{"COA_$coa"} = '1';
1112 $::form->{COA_Germany} = '1' if ($coa =~ m/^germany/i);
1113 $main::lxdebug->leave_sub();
1117 $main::lxdebug->enter_sub();
1118 if ( $::form->{fa_bufa_nr} && $::form->{fa_bufa_nr} ne '' ) {
1119 my $fiamt = SL::DB::Finanzamt->_get_manager_class->get_first(
1120 query => [ fa_bufa_nr => $::form->{fa_bufa_nr} ]);
1121 $::form->{$_} = $fiamt->$_ for @fiamt_finanzamt;
1123 $main::lxdebug->leave_sub();
1127 $main::lxdebug->enter_sub();
1128 my $defaults = SL::DB::Default->get;
1129 $defaults->$_($::form->{$_}) for @fiamt_config;
1131 if ( $defaults->fa_bufa_nr ) {
1132 my $fiamt = SL::DB::Finanzamt->_get_manager_class->get_first(
1133 query => [ fa_bufa_nr => $defaults->fa_bufa_nr ]);
1134 $fiamt->$_($::form->{$_}) for @fiamt_finanzamt;
1137 $main::lxdebug->leave_sub();