Kosmetik
[kivitendo-erp.git] / SL / DATEV.pm
1 #=====================================================================
2 # Lx-Office ERP
3 # Copyright (c) 2004
4 #
5 #  Author: Philip Reetz
6 #   Email: p.reetz@linet-services.de
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 #
24 # Datev export module
25 #======================================================================
26
27 package DATEV;
28
29 use SL::DBUtils;
30
31 use Data::Dumper;
32
33 sub get_datev_stamm {
34   $main::lxdebug->enter_sub();
35
36   my ($self, $myconfig, $form) = @_;
37
38   # connect to database
39   my $dbh = $form->dbconnect($myconfig);
40
41   $query = qq|SELECT * FROM datev|;
42   $sth   = $dbh->prepare($query);
43   $sth->execute || $form->dberror($query);
44
45   my $ref = $sth->fetchrow_hashref(NAME_lc);
46
47   map { $form->{$_} = $ref->{$_} } keys %$ref;
48
49   $sth->finish;
50   $dbh->disconnect;
51   $main::lxdebug->leave_sub();
52 }
53
54 sub save_datev_stamm {
55   $main::lxdebug->enter_sub();
56
57   my ($self, $myconfig, $form) = @_;
58
59   # connect to database
60   my $dbh = $form->dbconnect_noauto($myconfig);
61
62   $query = qq|DELETE FROM datev|;
63   $dbh->do($query) || $form->dberror($query);
64
65   $query = qq|INSERT INTO datev
66               (beraternr, beratername, dfvkz, mandantennr, datentraegernr, abrechnungsnr) VALUES
67               (|
68     . $dbh->quote($form->{beraternr}) . qq|,|
69     . $dbh->quote($form->{beratername}) . qq|,|
70     . $dbh->quote($form->{dfvkz}) . qq|,
71               |
72     . $dbh->quote($form->{mandantennr}) . qq|,|
73     . $dbh->quote($form->{datentraegernr}) . qq|,|
74     . $dbh->quote($form->{abrechnungsnr}) . qq|)|;
75   $sth = $dbh->prepare($query);
76   $sth->execute || $form->dberror($query);
77   $sth->finish;
78
79   $dbh->commit;
80   $dbh->disconnect;
81   $main::lxdebug->leave_sub();
82 }
83
84 sub kne_export {
85   $main::lxdebug->enter_sub();
86
87   my ($self, $myconfig, $form) = @_;
88   my @rc;
89
90   if ($form->{exporttype} == 0) {
91     @rc = &kne_buchungsexport($myconfig, $form);
92   } else {
93     @rc = &kne_stammdatenexport($myconfig, $form);
94   }
95
96   $main::lxdebug->leave_sub();
97
98   return @rc;
99 }
100
101 sub obe_export {
102   $main::lxdebug->enter_sub();
103
104   my ($self, $myconfig, $form) = @_;
105
106   # connect to database
107   my $dbh = $form->dbconnect_noauto($myconfig);
108   $dbh->commit;
109   $dbh->disconnect;
110   $main::lxdebug->leave_sub();
111 }
112
113 sub get_dates {
114   $main::lxdebug->enter_sub();
115
116   my ($zeitraum, $monat, $quartal, $transdatefrom, $transdateto) = @_;
117
118   $fromto = "transdate >= ";
119
120   my @a = localtime;
121   $a[5] += 1900;
122   $jahr = $a[5];
123   if ($zeitraum eq "monat") {
124   SWITCH: {
125       $monat eq "1" && do {
126         $form->{fromdate} = "1.1.$jahr";
127         $form->{todate}   = "31.1.$jahr";
128         last SWITCH;
129       };
130       $monat eq "2" && do {
131         $form->{fromdate} = "1.2.$jahr";
132
133         #this works from 1901 to 2099, 1900 and 2100 fail.
134         $leap = ($jahr % 4 == 0) ? "29" : "28";
135         $form->{todate} = "$leap.2.$jahr";
136         last SWITCH;
137       };
138       $monat eq "3" && do {
139         $form->{fromdate} = "1.3.$jahr";
140         $form->{todate}   = "31.3.$jahr";
141         last SWITCH;
142       };
143       $monat eq "4" && do {
144         $form->{fromdate} = "1.4.$jahr";
145         $form->{todate}   = "30.4.$jahr";
146         last SWITCH;
147       };
148       $monat eq "5" && do {
149         $form->{fromdate} = "1.5.$jahr";
150         $form->{todate}   = "31.5.$jahr";
151         last SWITCH;
152       };
153       $monat eq "6" && do {
154         $form->{fromdate} = "1.6.$jahr";
155         $form->{todate}   = "30.6.$jahr";
156         last SWITCH;
157       };
158       $monat eq "7" && do {
159         $form->{fromdate} = "1.7.$jahr";
160         $form->{todate}   = "31.7.$jahr";
161         last SWITCH;
162       };
163       $monat eq "8" && do {
164         $form->{fromdate} = "1.8.$jahr";
165         $form->{todate}   = "31.8.$jahr";
166         last SWITCH;
167       };
168       $monat eq "9" && do {
169         $form->{fromdate} = "1.9.$jahr";
170         $form->{todate}   = "30.9.$jahr";
171         last SWITCH;
172       };
173       $monat eq "10" && do {
174         $form->{fromdate} = "1.10.$jahr";
175         $form->{todate}   = "31.10.$jahr";
176         last SWITCH;
177       };
178       $monat eq "11" && do {
179         $form->{fromdate} = "1.11.$jahr";
180         $form->{todate}   = "30.11.$jahr";
181         last SWITCH;
182       };
183       $monat eq "12" && do {
184         $form->{fromdate} = "1.12.$jahr";
185         $form->{todate}   = "31.12.$jahr";
186         last SWITCH;
187       };
188     }
189     $fromto .=
190       "'" . $form->{fromdate} . "' and transdate <= '" . $form->{todate} . "'";
191   }
192
193   elsif ($zeitraum eq "quartal") {
194     if ($quartal == 1) {
195       $fromto .=
196         "'01.01." . $jahr . "' and transdate <= '31.03." . $jahr . "'";
197     } elsif ($quartal == 2) {
198       $fromto .=
199         "'01.04." . $jahr . "' and transdate <= '30.06." . $jahr . "'";
200     } elsif ($quartal == 3) {
201       $fromto .=
202         "'01.07." . $jahr . "' and transdate <= '30.09." . $jahr . "'";
203     } elsif ($quartal == 4) {
204       $fromto .=
205         "'01.10." . $jahr . "' and transdate <= '31.12." . $jahr . "'";
206     }
207   }
208
209   elsif ($zeitraum eq "zeit") {
210     $fromto .=
211       "'" . $transdatefrom . "' and transdate <= '" . $transdateto . "'";
212   }
213
214   $main::lxdebug->leave_sub();
215
216   return $fromto;
217 }
218
219 sub get_transactions {
220   $main::lxdebug->enter_sub();
221
222   my $dbh = $form->get_standard_dbh($myconfig);
223
224   $fromto =~ s/transdate/ac\.transdate/g;
225
226   my %taxes = selectall_as_map($form, $dbh, qq|SELECT id, rate FROM tax|, 'id', 'rate');
227
228   my $query =
229     qq|SELECT ac.oid, ac.transdate, ac.trans_id,ar.id, ac.amount, ac.taxkey,
230          ar.invnumber, ar.duedate, ar.amount as umsatz,
231          ct.name,
232          c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id,
233          t.chart_id, t.rate, t.id AS taxid, t.taxkey AS taxtaxkey
234        FROM acc_trans ac,ar ar, customer ct, chart c
235        LEFT JOIN tax t ON (t.chart_id = c.id)
236        WHERE $fromto
237          AND (ac.trans_id = ar.id)
238          AND (ac.trans_id = ar.id)
239          AND (ar.customer_id = ct.id)
240          AND (ac.chart_id = c.id)
241
242        UNION ALL
243
244        SELECT ac.oid, ac.transdate, ac.trans_id,ap.id, ac.amount, ac.taxkey,
245          ap.invnumber, ap.duedate, ap.amount as umsatz,
246          ct.name,
247          c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id,
248          t.chart_id, t.rate, t.id AS taxid, t.taxkey AS taxtaxkey
249        FROM acc_trans ac, ap ap, vendor ct, chart c
250        LEFT JOIN tax t ON (t.chart_id = c.id)
251        WHERE $fromto
252          AND (ac.trans_id = ap.id)
253          AND (ap.vendor_id = ct.id)
254          AND (ac.chart_id = c.id)
255
256        UNION ALL
257
258        SELECT ac.oid, ac.transdate, ac.trans_id,gl.id, ac.amount, ac.taxkey,
259          gl.reference AS invnumber, gl.transdate AS duedate, ac.amount as umsatz,
260          gl.description AS name,
261          c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id,
262          t.chart_id, t.rate, t.id AS taxid, t.taxkey AS taxtaxkey
263        FROM acc_trans ac, gl gl, chart c
264        LEFT JOIN tax t ON (t.chart_id = c.id)
265        WHERE $fromto
266          AND (ac.trans_id = gl.id)
267          AND (ac.chart_id = c.id)
268
269        ORDER BY trans_id, oid|;
270
271   my $sth = prepare_execute_query($form, $dbh, $query);
272
273   $i = 0;
274   $g = 0;
275   my $counter = 0;
276   my @splits;
277   while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
278     $count    = 0;
279     $firstrun = 1;
280     $counter++;
281     if (($counter % 500) == 0) {
282       print("$counter ");
283     }
284
285     $count += $ref->{amount};
286     push @{$i}, $ref;
287     while (abs($count) > 0.01 || $firstrun) {
288       $ref2 = $sth->fetchrow_hashref(NAME_lc);
289       last unless ($ref2);
290       $count += $ref2->{amount};
291       push @{$i}, $ref2;
292       $firstrun = 0;
293     }
294     my %taxid_taxkeys = ();
295     $absumsatz = 0;
296     if (scalar(@{$i}) > 2) {
297       for my $j (0 .. (scalar(@{$i}) - 1)) {
298         if (abs($i->[$j]->{'amount'}) > abs($absumsatz)) {
299           $absumsatz     = $i->[$j]->{'amount'};
300           $notsplitindex = $j;
301         }
302         if (($i->[$j]->{'taxtaxkey'}) && ($i->[$j]->{'taxid'})) {
303           $taxid_taxkeys{$i->[$j]->{'taxtaxkey'}}     = $i->[$j]->{'taxid'};
304         }
305       }
306       $ml = ($i->[0]->{'umsatz'} > 0) ? 1 : -1;
307       for my $j (0 .. (scalar(@{$i}) - 1)) {
308         if (   ($j != $notsplitindex)
309             && ($i->[$j]->{'chart_id'}  eq "")
310             && (   $i->[$j]->{'taxkey'} eq ""
311                 || $i->[$j]->{'taxkey'} eq "0"
312                 || $i->[$j]->{'taxkey'} eq "1"
313                 || $i->[$j]->{'taxkey'} eq "10"
314                 || $i->[$j]->{'taxkey'} eq "11")) {
315           my %blubb = {};
316           map({ $blubb{$_} = $i->[$notsplitindex]->{$_}; } keys(%{ $i->[$notsplitindex] }));
317
318           $absumsatz           += $i->[$j]->{'amount'};
319           $blubb{'amount'}      = $i->[$j]->{'amount'} * (-1);
320           $blubb{'umsatz'}      = abs($i->[$j]->{'amount'}) * $ml;
321           $i->[$j]->{'umsatz'}  = abs($i->[$j]->{'amount'}) * $ml;
322
323           push @{ $splits[$g] }, \%blubb;    #$i->[$notsplitindex];
324           push @{ $splits[$g] }, $i->[$j];
325           push @{ $form->{DATEV} }, \@{ $splits[$g] };
326
327           $g++;
328
329         } elsif (($j != $notsplitindex) && ($i->[$j]->{'chart_id'} eq "")) {
330           $absumsatz += ($i->[$j]->{'amount'} * (1 + $taxes{ $taxid_taxkeys{$i->[$j]->{'taxkey'}} }));
331
332           my %blubb   = {};
333           map({ $blubb{$_} = $i->[$notsplitindex]->{$_}; } keys(%{ $i->[$notsplitindex] }));
334
335           $test                = 1 + $taxes{  $taxid_taxkeys{$i->[$j]->{'taxkey'}} };
336           $blubb{'amount'}     = $form->round_amount(($i->[$j]->{'amount'} * $test * -1), 2);
337           $blubb{'umsatz'}     = abs($form->round_amount(($i->[$j]->{'amount'} * $test), 2)) * $ml;
338           $i->[$j]->{'umsatz'} = abs($form->round_amount(($i->[$j]->{'amount'} * $test), 2)) * $ml;
339
340           push @{ $splits[$g] }, \%blubb;
341           push @{ $splits[$g] }, $i->[$j];
342           push @{ $form->{DATEV} }, \@{ $splits[$g] };
343           $g++;
344
345         } else {
346           next;
347         }
348       }
349       if (abs($absumsatz) > 0.01) {
350         $form->error("Datev-Export fehlgeschlagen! Bei Transaktion $i->[0]->{trans_id} $absumsatz\n");
351       }
352     } else {
353       push @{ $form->{DATEV} }, \@{$i};
354     }
355     $i++;
356   }
357   $sth->finish;
358   $dbh->disconnect;
359
360   $main::lxdebug->leave_sub();
361 }
362
363 sub make_kne_data_header {
364   $main::lxdebug->enter_sub();
365
366   my ($myconfig, $form, $fromto) = @_;
367
368   # connect to database
369   my $dbh = $form->dbconnect($myconfig);
370
371   my @a = localtime;
372   $jahr = $a[5];
373
374   #Header
375   $anwendungsnr = ($fromto) ? "\x31\x31" : "\x31\x33";
376   while (length($form->{datentraegernr}) < 3) {
377     $form->{datentraegernr} = "\x30" . $form->{datentraegernr};
378   }
379
380   $header = "\x1D\x18\x31" . $form->{datentraegernr} . $anwendungsnr;
381
382   $dfvkz = $form->{dfvkz};
383   while (length($dfvkz) < 2) {
384     $dfvkz = "\x30" . $dfvkz;
385   }
386   $header .= $dfvkz;
387
388   $beraternr = $form->{beraternr};
389   while (length($beraternr) < 7) {
390     $beraternr = "\x30" . $beraternr;
391   }
392   $header .= $beraternr;
393
394   $mandantennr = $form->{mandantennr};
395   while (length($mandantennr) < 5) {
396     $mandantennr = "\x30" . $mandantennr;
397   }
398   $header .= $mandantennr;
399
400   $abrechnungsnr = $form->{abrechnungsnr} . $jahr;
401   while (length($abrechnungsnr) < 6) {
402     $abrechnungsnr = "\x30" . $abrechnungsnr;
403   }
404   $header .= $abrechnungsnr;
405
406   $fromto =~ s/transdate|>=|and|\'|<=//g;
407   my ($from, $to) = split /   /, $fromto;
408   $from =~ s/ //g;
409   $to   =~ s/ //g;
410
411   if ($from ne "") {
412     my ($fday, $fmonth, $fyear) = split(/\./, $from);
413     if (length($fmonth) < 2) {
414       $fmonth = "0" . $fmonth;
415     }
416     if (length($fday) < 2) {
417       $fday = "0" . $fday;
418     }
419     $from = $fday . $fmonth . substr($fyear, -2, 2);
420   } else {
421     $from = "";
422   }
423
424   $header .= $from;
425
426   if ($to ne "") {
427     my ($tday, $tmonth, $tyear) = split(/\./, $to);
428     if (length($tmonth) < 2) {
429       $tmonth = "0" . $tmonth;
430     }
431     if (length($tday) < 2) {
432       $tday = "0" . $tday;
433     }
434     $to = $tday . $tmonth . substr($tyear, -2, 2);
435   } else {
436     $to = "";
437   }
438   $header .= $to;
439   if ($fromto ne "") {
440     $primanota = "\x30\x30\x31";
441     $header .= $primanota;
442   }
443
444   $passwort = $form->{passwort};
445   while (length($passwort) < 4) {
446     $passwort = "\x30" . $passwort;
447   }
448   $header .= $passwort;
449
450   $anwendungsinfo = "\x20" x 16;
451   $header .= $anwendungsinfo;
452   $inputinfo = "\x20" x 16;
453   $header .= $inputinfo;
454
455   $header .= "\x79";
456
457   #Versionssatz
458   if ($form->{exporttype} == 0) {
459     $versionssatz = "\xB5" . "1,";
460   } else {
461     $versionssatz = "\xB6" . "1,";
462   }
463
464   $query = qq| select accno from chart limit 1|;
465   $sth   = $dbh->prepare($query);
466   $sth->execute || $form->dberror($query);
467   my $ref = $sth->fetchrow_hashref(NAME_lc);
468
469   $accnolength = $ref->{accno};
470   $sth->finish;
471
472   $versionssatz .= length($accnolength);
473   $versionssatz .= ",";
474   $versionssatz .= length($accnolength);
475   $versionssatz .= ",SELF" . "\x1C\x79";
476
477   $dbh->disconnect;
478
479   $header .= $versionssatz;
480
481   $main::lxdebug->leave_sub();
482
483   return $header;
484 }
485
486 sub datetofour {
487   $main::lxdebug->enter_sub();
488
489   my ($date, $six) = @_;
490
491   ($day, $month, $year) = split(/\./, $date);
492
493   if ($day =~ /^0/) {
494     $day = substr($day, 1, 1);
495   }
496   if (length($month) < 2) {
497     $month = "0" . $month;
498   }
499   if (length($year) > 2) {
500     $year = substr($year, -2, 2);
501   }
502
503   if ($six) {
504     $date = $day . $month . $year;
505   } else {
506     $date = $day . $month;
507   }
508
509   $main::lxdebug->leave_sub();
510
511   return $date;
512 }
513
514 sub formatumsatz {
515   $main::lxdebug->enter_sub();
516
517   my ($umsatz, $stellen) = @_;
518
519   $umsatz =~ s/-//;
520   ($vorkomma, $nachkomma) = split(/\./, $umsatz);
521   $umsatz = "";
522   if ($stellen > 0) {
523     for ($i = $stellen; $i >= $stellen + 2 - length($vorkomma); $i--) {
524       $umsatz .= "0";
525     }
526   }
527   for ($i = 3; $i > length($nachkomma); $i--) {
528     $nachkomma .= "0";
529   }
530   $umsatz = $vorkomma . substr($nachkomma, 0, 2);
531
532   $main::lxdebug->leave_sub();
533
534   return $umsatz;
535 }
536
537 sub make_ed_versionset {
538   $main::lxdebug->enter_sub();
539
540   my ($header, $filename, $blockcount, $fromto) = @_;
541
542   $versionset = "V" . substr($filename, 2, 5);
543   $versionset .= substr($header, 6, 22);
544   if ($fromto ne "") {
545     $versionset .= "0000" . substr($header, 28, 19);
546   } else {
547     $datum = "\x20" x 16;
548     $versionset .= $datum . "001" . substr($header, 28, 4);
549   }
550   while (length($blockcount) < 5) {
551     $blockcount = "0" . $blockcount;
552   }
553   $versionset .= $blockcount;
554   $versionset .= "001";
555   $versionset .= "\x20\x31";
556   $versionset .= substr($header, -12, 10) . "    ";
557   $versionset .= "\x20" x 53;
558
559   $main::lxdebug->leave_sub();
560
561   return $versionset;
562 }
563
564 sub make_ev_header {
565   $main::lxdebug->enter_sub();
566
567   my ($form, $fileno) = @_;
568   $datentraegernr = $form->{datentraegernr};
569   $beraternummer  = $form->{beraternr};
570   $beratername    = $form->{beratername};
571   $anzahl_dateien = $fileno;
572
573   while (length($datentraegernr) < 3) {
574     $datentraegernr .= " ";
575   }
576
577   while (length($beraternummer) < 7) {
578     $beraternummer .= " ";
579   }
580
581   while (length($beratername) < 9) {
582     $beratername .= " ";
583   }
584
585   while (length($anzahl_dateien) < 5) {
586     $anzahl_dateien = "0" . $anzahl_dateien;
587   }
588
589   $ev_header =
590     $datentraegernr . "\x20\x20\x20" . $beraternummer . $beratername . "\x20";
591   $ev_header .= $anzahl_dateien . $anzahl_dateien;
592   $ev_header .= "\x20" x 95;
593
594   $main::lxdebug->leave_sub();
595
596   return $ev_header;
597 }
598
599 sub kne_buchungsexport {
600   $main::lxdebug->enter_sub();
601
602   my ($myconfig, $form) = @_;
603
604   my @filenames;
605
606   my $export_path = $main::userspath . "/";
607   my $filename    = "ED00000";
608   my $evfile      = "EV01";
609   my @ed_versionsets;
610   my $fileno = 0;
611
612   $form->header;
613   print qq|
614   <html>
615   <body>Export in Bearbeitung<br>
616   Buchungss&auml;tze verarbeitet:
617 |;
618
619   $fromto =
620     &get_dates($form->{zeitraum}, $form->{monat},
621                $form->{quartal},  $form->{transdatefrom},
622                $form->{transdateto});
623   &get_transactions($myconfig, $form, $fromto);
624   my $counter = 0;
625   print qq|<br>2. Durchlauf:|;
626   while (scalar(@{ $form->{DATEV} })) {
627     my $blockcount      = 1;
628     my $remaining_bytes = 256;
629     my $total_bytes     = 256;
630     my $umsatzsumme     = 0;
631     my $buchungssatz    = "";
632     $filename++;
633     my $ed_filename = $export_path . $filename;
634     push(@filenames, $filename);
635     open(ED, "> $ed_filename") or die "can't open outputfile: $!\n";
636     $header = &make_kne_data_header($myconfig, $form, $fromto);
637     $remaining_bytes -= length($header);
638
639     while (scalar(@{ $form->{DATEV} }) > 0) {
640       $transaction = shift @{ $form->{DATEV} };
641       $trans_lines = scalar(@{$transaction});
642       $counter++;
643       if (($counter % 500) == 0) {
644         print("$counter ");
645       }
646
647       $umsatz         = 0;
648       $gegenkonto     = "";
649       $konto          = "";
650       $belegfeld1     = "";
651       $datum          = "";
652       $waehrung       = "";
653       $buchungstext   = "";
654       $belegfeld2     = "";
655       $datevautomatik = 0;
656       $taxkey         = 0;
657       $charttax       = 0;
658       %umlaute = ('ä' => 'ae',
659                   'ö' => 'oe',
660                   'ü' => 'ue',
661                   'Ä' => 'Ae',
662                   'Ö' => 'Oe',
663                   'Ãœ' => 'Ue',
664                   'ß' => 'sz');
665
666       for (my $i = 0; $i < $trans_lines; $i++) {
667         if ($trans_lines == 2) {
668           if (abs($transaction->[$i]->{'amount'}) > abs($umsatz)) {
669             $umsatz = $transaction->[$i]->{'amount'};
670           }
671         } else {
672           if (abs($transaction->[$i]->{'umsatz'}) > abs($umsatz)) {
673             $umsatz = $transaction->[$i]->{'umsatz'};
674           }
675         }
676         if ($transaction->[$i]->{'datevautomatik'}) {
677           $datevautomatik = 1;
678         }
679         if ($transaction->[$i]->{'taxkey'}) {
680           $taxkey = $transaction->[$i]->{'taxkey'};
681         }
682         if ($transaction->[$i]->{'charttax'}) {
683           $charttax = $transaction->[$i]->{'charttax'};
684         }
685         if (   ($transaction->[$i]->{'id'} eq $transaction->[$i]->{'chart_id'})
686             && ($trans_lines > 2)) {
687           undef($transaction->[$i]);
688             } elsif ($transaction->[$i]->{'amount'} > 0) {
689           $haben = $i;
690             } else {
691           $soll = $i;
692         }
693       }
694
695       $umsatzsumme += abs($umsatz);
696
697       # Umwandlung von Umlauten und Sonderzeichen in erlaubte Zeichen bei Textfeldern
698       foreach $umlaut (keys(%umlaute)) {
699         $transaction->[$haben]->{'invnumber'} =~
700           s/${umlaut}/${umlaute{$umlaut}}/g;
701         $transaction->[$haben]->{'name'} =~ s/${umlaut}/${umlaute{$umlaut}}/g;
702       }
703
704       $transaction->[$haben]->{'invnumber'} =~ s/[^0-9A-Za-z\$\%\&\*\+\-\/]//g;
705       $transaction->[$haben]->{'name'} =~ s/[^0-9A-Za-z\$\%\&\*\+\-\ \/]//g;
706
707       $transaction->[$haben]->{'invnumber'} =
708         substr($transaction->[$haben]->{'invnumber'}, 0, 12);
709       $transaction->[$haben]->{'name'} =
710         substr($transaction->[$haben]->{'name'}, 0, 30);
711       $transaction->[$haben]->{'invnumber'} =~ s/\ *$//;
712       $transaction->[$haben]->{'name'}      =~ s/\ *$//;
713
714       if ($trans_lines >= 2) {
715
716         $gegenkonto = "a" . $transaction->[$haben]->{'accno'};
717         $konto      = "e" . $transaction->[$soll]->{'accno'};
718         if ($transaction->[$haben]->{'invnumber'} ne "") {
719           $belegfeld1 =
720             "\xBD" . $transaction->[$haben]->{'invnumber'} . "\x1C";
721         }
722         $datum = "d";
723         $datum .= &datetofour($transaction->[$haben]->{'transdate'}, 0);
724         $waehrung = "\xB3" . "EUR" . "\x1C";
725         if ($transaction->[$haben]->{'name'} ne "") {
726           $buchungstext = "\x1E" . $transaction->[$haben]->{'name'} . "\x1C";
727         }
728         if ($transaction->[$haben]->{'duedate'} ne "") {
729           $belegfeld2 = "\xBE"
730             . &datetofour($transaction->[$haben]->{'duedate'}, 1) . "\x1C";
731         }
732       }
733
734       if (($remaining_bytes - length("+" . &formatumsatz($umsatz, 0))) <= 6) {
735         $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
736         $buchungssatz .= "\x00" x $fuellzeichen;
737         $blockcount++;
738         $total_bytes = ($blockcount) * 256;
739       }
740       $umsatz = abs($umsatz);
741       $vorzeichen = ($umsatz > 0) ? "+" : "-";
742       $buchungssatz .= $vorzeichen . &formatumsatz($umsatz, 0);
743       $remaining_bytes = $total_bytes - length($buchungssatz . $header);
744
745       if ( ($taxkey || $datevautomatik)
746         && (!$datevautomatik || ($datevautomatik && ($charttax ne $taxkey)))) {
747         if (($remaining_bytes - length("\x6C" . "11")) <= 6) {
748           $fuellzeichen =
749             ($blockcount * 256 - length($buchungssatz . $header));
750           $buchungssatz .= "\x00" x $fuellzeichen;
751           $blockcount++;
752           $total_bytes = ($blockcount) * 256;
753         }
754         if (!$datevautomatik) {
755           $buchungssatz .= "\x6C" . $taxkey;
756         } else {
757           $buchungssatz .= "\x6C" . "4";
758         }
759         $remaining_bytes = $total_bytes - length($buchungssatz . $header);
760       }
761
762       if (($remaining_bytes - length($gegenkonto)) <= 6) {
763         $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
764         $buchungssatz .= "\x00" x $fuellzeichen;
765         $blockcount++;
766         $total_bytes = ($blockcount) * 256;
767       }
768       $buchungssatz .= $gegenkonto;
769       $remaining_bytes = $total_bytes - length($buchungssatz . $header);
770
771       if (($remaining_bytes - length($belegfeld1)) <= 6) {
772         $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
773         $buchungssatz .= "\x00" x $fuellzeichen;
774         $blockcount++;
775         $total_bytes = ($blockcount) * 256;
776       }
777       $buchungssatz .= $belegfeld1;
778       $remaining_bytes = $total_bytes - length($buchungssatz . $header);
779
780       if (($remaining_bytes - length($belegfeld2)) <= 6) {
781         $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
782         $buchungssatz .= "\x00" x $fuellzeichen;
783         $blockcount++;
784         $total_bytes = ($blockcount) * 256;
785       }
786       $buchungssatz .= $belegfeld2;
787       $remaining_bytes = $total_bytes - length($buchungssatz . $header);
788
789       if (($remaining_bytes - length($datum)) <= 6) {
790         $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
791         $buchungssatz .= "\x00" x $fuellzeichen;
792         $blockcount++;
793         $total_bytes = ($blockcount) * 256;
794       }
795       $buchungssatz .= $datum;
796       $remaining_bytes = $total_bytes - length($buchungssatz . $header);
797
798       if (($remaining_bytes - length($konto)) <= 6) {
799         $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
800         $buchungssatz .= "\x00" x $fuellzeichen;
801         $blockcount++;
802         $total_bytes = ($blockcount) * 256;
803       }
804       $buchungssatz .= $konto;
805       $remaining_bytes = $total_bytes - length($buchungssatz . $header);
806
807       if (($remaining_bytes - length($buchungstext)) <= 6) {
808         $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
809         $buchungssatz .= "\x00" x $fuellzeichen;
810         $blockcount++;
811         $total_bytes = ($blockcount) * 256;
812       }
813       $buchungssatz .= $buchungstext;
814       $remaining_bytes = $total_bytes - length($buchungssatz . $header);
815
816       if (($remaining_bytes - (length($waehrung . "\x79"))) <= 6) {
817         $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
818         $buchungssatz .= "\x00" x $fuellzeichen;
819         $blockcount++;
820         $total_bytes = ($blockcount) * 256;
821       }
822       $buchungssatz .= $waehrung . "\x79";
823       $remaining_bytes = $total_bytes - length($buchungssatz . $header);
824
825     }
826
827     $mandantenendsumme =
828       "x" . &formatumsatz($umsatzsumme, 14) . "\x79" . "\x7a";
829     $fuellzeichen =
830       256 - (length($header . $buchungssatz . $mandantenendsumme) % 256);
831     $dateiende = "\x00" x $fuellzeichen;
832     print(ED $header);
833     print(ED $buchungssatz);
834     print(ED $mandantenendsumme);
835     print(ED $dateiende);
836     close(ED);
837
838     $ed_versionset[$fileno] =
839       &make_ed_versionset($header, $filename, $blockcount, $fromto);
840     $fileno++;
841   }
842
843   #Make EV Verwaltungsdatei
844   $ev_header = &make_ev_header($form, $fileno);
845   $ev_filename = $export_path . $evfile;
846   push(@filenames, $evfile);
847   open(EV, "> $ev_filename") or die "can't open outputfile: EV01\n";
848   print(EV $ev_header);
849
850   foreach $file (@ed_versionset) {
851     print(EV $ed_versionset[$file]);
852   }
853   close(EV);
854   print qq|<br>Done. <br>
855 |;
856   ###
857   $main::lxdebug->leave_sub();
858
859   return @filenames;
860 }
861
862 sub kne_stammdatenexport {
863   $main::lxdebug->enter_sub();
864
865   my ($myconfig, $form) = @_;
866   $form->{abrechnungsnr} = "99";
867
868   $form->header;
869   print qq|
870   <html>
871   <body>Export in Bearbeitung<br>
872 |;
873
874   my @filenames;
875
876   my $export_path = $main::userspath . "/";
877   my $filename    = "ED00000";
878   my $evfile      = "EV01";
879   my @ed_versionsets;
880   my $fileno          = 1;
881   my $i               = 0;
882   my $blockcount      = 1;
883   my $remaining_bytes = 256;
884   my $total_bytes     = 256;
885   my $buchungssatz    = "";
886   $filename++;
887   my $ed_filename = $export_path . $filename;
888   push(@filenames, $filename);
889   open(ED, "> $ed_filename") or die "can't open outputfile: $!\n";
890   $header = &make_kne_data_header($myconfig, $form, "");
891   $remaining_bytes -= length($header);
892
893   # connect to database
894   my $dbh = $form->dbconnect($myconfig);
895
896   $query =
897     qq|SELECT c.accno, c.description FROM chart c WHERE c.accno >=|
898     . $dbh->quote($form->{accnofrom}) . qq|
899            AND c.accno <= |
900     . $dbh->quote($form->{accnoto}) . qq| ORDER BY c.accno|;
901
902   $sth = $dbh->prepare($query);
903   $sth->execute || $form->dberror($query);
904
905   while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
906     if (($remaining_bytes - length("t" . $ref->{'accno'})) <= 6) {
907       $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
908       $buchungssatz .= "\x00" x $fuellzeichen;
909       $blockcount++;
910       $total_bytes = ($blockcount) * 256;
911     }
912     $buchungssatz .= "t" . $ref->{'accno'};
913     $remaining_bytes = $total_bytes - length($buchungssatz . $header);
914     $ref->{'description'} =~ s/[^0-9A-Za-z\$\%\&\*\+\-\/]//g;
915     $ref->{'description'} = substr($ref->{'description'}, 0, 40);
916     $ref->{'description'} =~ s/\ *$//;
917
918     if (
919         ($remaining_bytes - length("\x1E" . $ref->{'description'} . "\x1C\x79")
920         ) <= 6
921       ) {
922       $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
923       $buchungssatz .= "\x00" x $fuellzeichen;
924       $blockcount++;
925       $total_bytes = ($blockcount) * 256;
926     }
927     $buchungssatz .= "\x1E" . $ref->{'description'} . "\x1C\x79";
928     $remaining_bytes = $total_bytes - length($buchungssatz . $header);
929   }
930
931   $sth->finish;
932   print(ED $header);
933   print(ED $buchungssatz);
934   $fuellzeichen = 256 - (length($header . $buchungssatz . "z") % 256);
935   $dateiende = "\x00" x $fuellzeichen;
936   print(ED "z");
937   print(ED $dateiende);
938   close(ED);
939
940   #Make EV Verwaltungsdatei
941   $ed_versionset[0] =
942     &make_ed_versionset($header, $filename, $blockcount, $fromto);
943
944   $ev_header = &make_ev_header($form, $fileno);
945   $ev_filename = $export_path . $evfile;
946   push(@filenames, $evfile);
947   open(EV, "> $ev_filename") or die "can't open outputfile: EV01\n";
948   print(EV $ev_header);
949
950   foreach $file (@ed_versionset) {
951     print(EV $ed_versionset[$file]);
952   }
953   close(EV);
954
955   $dbh->disconnect;
956   ###
957
958   print qq|<br>Done. <br>
959 |;
960
961   $main::lxdebug->leave_sub();
962
963   return @filenames;
964 }
965
966 1;