1 #=====================================================================
6 # Email: p.reetz@linet-services.de
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #======================================================================
25 #======================================================================
30 use SL::DATEV::KNEFile;
34 use Time::HiRes qw(gettimeofday);
36 sub _get_export_path {
37 $main::lxdebug->enter_sub();
39 my ($a, $b) = gettimeofday();
40 my $path = get_path_for_download_token("${a}-${b}-${$}");
42 mkpath($path) unless (-d $path);
44 $main::lxdebug->leave_sub();
49 sub get_path_for_download_token {
50 $main::lxdebug->enter_sub();
55 if ($token =~ m|^(\d+)-(\d+)-(\d+)$|) {
56 $path = "${main::userspath}/datev-export-${1}-${2}-${3}";
59 $main::lxdebug->leave_sub();
64 sub get_download_token_for_path {
65 $main::lxdebug->enter_sub();
70 if ($path =~ m|.*datev-export-(\d+)-(\d+)-(\d+)/?$|) {
71 $token = "${1}-${2}-${3}";
74 $main::lxdebug->leave_sub();
79 sub clean_temporary_directories {
80 $main::lxdebug->enter_sub();
82 foreach my $path (glob "${main::userspath}/datev-export-*") {
83 next unless (-d $path);
85 my $mtime = (stat($path))[9];
86 next if ((time() - $mtime) < 8 * 60 * 60);
91 $main::lxdebug->leave_sub();
95 $main::lxdebug->enter_sub();
98 my $field_len = shift;
99 my $fill_char = shift;
100 my $alignment = shift || 'right';
102 my $text_len = length $text;
104 if ($field_len < $text_len) {
105 $text = substr $text, 0, $field_len;
107 } elsif ($field_len > $text_len) {
108 my $filler = ($fill_char) x ($field_len - $text_len);
109 $text = $alignment eq 'right' ? $filler . $text : $text . $filler;
112 $main::lxdebug->leave_sub();
117 sub get_datev_stamm {
118 $main::lxdebug->enter_sub();
120 my ($self, $myconfig, $form) = @_;
122 # connect to database
123 my $dbh = $form->dbconnect($myconfig);
125 $query = qq|SELECT * FROM datev|;
126 $sth = $dbh->prepare($query);
127 $sth->execute || $form->dberror($query);
129 my $ref = $sth->fetchrow_hashref(NAME_lc);
131 map { $form->{$_} = $ref->{$_} } keys %$ref;
135 $main::lxdebug->leave_sub();
138 sub save_datev_stamm {
139 $main::lxdebug->enter_sub();
141 my ($self, $myconfig, $form) = @_;
143 # connect to database
144 my $dbh = $form->dbconnect_noauto($myconfig);
146 $query = qq|DELETE FROM datev|;
147 $dbh->do($query) || $form->dberror($query);
149 $query = qq|INSERT INTO datev
150 (beraternr, beratername, dfvkz, mandantennr, datentraegernr, abrechnungsnr) VALUES
152 . $dbh->quote($form->{beraternr}) . qq|,|
153 . $dbh->quote($form->{beratername}) . qq|,|
154 . $dbh->quote($form->{dfvkz}) . qq|,
156 . $dbh->quote($form->{mandantennr}) . qq|,|
157 . $dbh->quote($form->{datentraegernr}) . qq|,|
158 . $dbh->quote($form->{abrechnungsnr}) . qq|)|;
159 $sth = $dbh->prepare($query);
160 $sth->execute || $form->dberror($query);
165 $main::lxdebug->leave_sub();
169 $main::lxdebug->enter_sub();
171 my ($self, $myconfig, $form) = @_;
174 if ($form->{exporttype} == 0) {
175 $result = kne_buchungsexport($myconfig, $form);
177 $result = kne_stammdatenexport($myconfig, $form);
180 $main::lxdebug->leave_sub();
186 $main::lxdebug->enter_sub();
188 my ($self, $myconfig, $form) = @_;
190 # connect to database
191 my $dbh = $form->dbconnect_noauto($myconfig);
194 $main::lxdebug->leave_sub();
198 $main::lxdebug->enter_sub();
200 my ($zeitraum, $monat, $quartal, $transdatefrom, $transdateto) = @_;
202 $fromto = "transdate >= ";
207 if ($zeitraum eq "monat") {
209 $monat eq "1" && do {
210 $form->{fromdate} = "1.1.$jahr";
211 $form->{todate} = "31.1.$jahr";
214 $monat eq "2" && do {
215 $form->{fromdate} = "1.2.$jahr";
217 #this works from 1901 to 2099, 1900 and 2100 fail.
218 $leap = ($jahr % 4 == 0) ? "29" : "28";
219 $form->{todate} = "$leap.2.$jahr";
222 $monat eq "3" && do {
223 $form->{fromdate} = "1.3.$jahr";
224 $form->{todate} = "31.3.$jahr";
227 $monat eq "4" && do {
228 $form->{fromdate} = "1.4.$jahr";
229 $form->{todate} = "30.4.$jahr";
232 $monat eq "5" && do {
233 $form->{fromdate} = "1.5.$jahr";
234 $form->{todate} = "31.5.$jahr";
237 $monat eq "6" && do {
238 $form->{fromdate} = "1.6.$jahr";
239 $form->{todate} = "30.6.$jahr";
242 $monat eq "7" && do {
243 $form->{fromdate} = "1.7.$jahr";
244 $form->{todate} = "31.7.$jahr";
247 $monat eq "8" && do {
248 $form->{fromdate} = "1.8.$jahr";
249 $form->{todate} = "31.8.$jahr";
252 $monat eq "9" && do {
253 $form->{fromdate} = "1.9.$jahr";
254 $form->{todate} = "30.9.$jahr";
257 $monat eq "10" && do {
258 $form->{fromdate} = "1.10.$jahr";
259 $form->{todate} = "31.10.$jahr";
262 $monat eq "11" && do {
263 $form->{fromdate} = "1.11.$jahr";
264 $form->{todate} = "30.11.$jahr";
267 $monat eq "12" && do {
268 $form->{fromdate} = "1.12.$jahr";
269 $form->{todate} = "31.12.$jahr";
274 "'" . $form->{fromdate} . "' and transdate <= '" . $form->{todate} . "'";
277 elsif ($zeitraum eq "quartal") {
280 "'01.01." . $jahr . "' and transdate <= '31.03." . $jahr . "'";
281 } elsif ($quartal == 2) {
283 "'01.04." . $jahr . "' and transdate <= '30.06." . $jahr . "'";
284 } elsif ($quartal == 3) {
286 "'01.07." . $jahr . "' and transdate <= '30.09." . $jahr . "'";
287 } elsif ($quartal == 4) {
289 "'01.10." . $jahr . "' and transdate <= '31.12." . $jahr . "'";
293 elsif ($zeitraum eq "zeit") {
294 $fromto .= "'" . $transdatefrom . "' and transdate <= '" . $transdateto . "'";
295 my ($yy, $mm, $dd) = $main::locale->parse_date(\%main::myconfig, $transdatefrom);
299 $main::lxdebug->leave_sub();
301 return ($fromto, $jahr);
304 sub _get_transactions {
305 $main::lxdebug->enter_sub();
309 my $myconfig = \%main::myconfig;
310 my $form = $main::form;
312 my $dbh = $form->get_standard_dbh($myconfig);
316 $fromto =~ s/transdate/ac\.transdate/g;
318 my %taxes = selectall_as_map($form, $dbh, qq|SELECT id, rate FROM tax|, 'id', 'rate');
321 qq|SELECT ac.oid, ac.transdate, ac.trans_id,ar.id, ac.amount, ac.taxkey,
322 ar.invnumber, ar.duedate, ar.amount as umsatz,
324 c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id,
325 t.chart_id, t.rate, t.id AS taxid, t.taxkey AS taxtaxkey
326 FROM acc_trans ac,ar ar, customer ct, chart c
327 LEFT JOIN tax t ON (t.chart_id = c.id)
329 AND (ac.trans_id = ar.id)
330 AND (ac.trans_id = ar.id)
331 AND (ar.customer_id = ct.id)
332 AND (ac.chart_id = c.id)
336 SELECT ac.oid, ac.transdate, ac.trans_id,ap.id, ac.amount, ac.taxkey,
337 ap.invnumber, ap.duedate, ap.amount as umsatz,
339 c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id,
340 t.chart_id, t.rate, t.id AS taxid, t.taxkey AS taxtaxkey
341 FROM acc_trans ac, ap ap, vendor ct, chart c
342 LEFT JOIN tax t ON (t.chart_id = c.id)
344 AND (ac.trans_id = ap.id)
345 AND (ap.vendor_id = ct.id)
346 AND (ac.chart_id = c.id)
350 SELECT ac.oid, ac.transdate, ac.trans_id,gl.id, ac.amount, ac.taxkey,
351 gl.reference AS invnumber, gl.transdate AS duedate, ac.amount as umsatz,
352 gl.description AS name,
353 c.accno, c.taxkey_id as charttax, c.datevautomatik, c.id,
354 t.chart_id, t.rate, t.id AS taxid, t.taxkey AS taxtaxkey
355 FROM acc_trans ac, gl gl, chart c
356 LEFT JOIN tax t ON (t.chart_id = c.id)
358 AND (ac.trans_id = gl.id)
359 AND (ac.chart_id = c.id)
361 ORDER BY trans_id, oid|;
363 my $sth = prepare_execute_query($form, $dbh, $query);
367 while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
369 if (($counter % 500) == 0) {
373 my $trans = [ $ref ];
375 my $count = $ref->{amount};
378 while (abs($count) > 0.01 || $firstrun) {
379 my $ref2 = $sth->fetchrow_hashref(NAME_lc);
382 push @{ $trans }, $ref2;
384 $count += $ref2->{amount};
388 my %taxid_taxkeys = ();
390 if (scalar(@{$trans}) <= 2) {
391 push @{ $form->{DATEV} }, $trans;
395 for my $j (0 .. (scalar(@{$trans}) - 1)) {
396 if (abs($trans->[$j]->{'amount'}) > abs($absumsatz)) {
397 $absumsatz = $trans->[$j]->{'amount'};
400 if (($trans->[$j]->{'taxtaxkey'}) && ($trans->[$j]->{'taxid'})) {
401 $taxid_taxkeys{$trans->[$j]->{'taxtaxkey'}} = $trans->[$j]->{'taxid'};
405 my $ml = ($trans->[0]->{'umsatz'} > 0) ? 1 : -1;
406 for my $j (0 .. (scalar(@{$trans}) - 1)) {
407 if ( ($j != $notsplitindex)
408 && ($trans->[$j]->{'chart_id'} eq "")
409 && ( $trans->[$j]->{'taxkey'} eq ""
410 || $trans->[$j]->{'taxkey'} eq "0"
411 || $trans->[$j]->{'taxkey'} eq "1"
412 || $trans->[$j]->{'taxkey'} eq "10"
413 || $trans->[$j]->{'taxkey'} eq "11")) {
415 map { $new_trans{$_} = $trans->[$notsplitindex]->{$_}; } keys %{ $trans->[$notsplitindex] };
417 $absumsatz += $trans->[$j]->{'amount'};
418 $new_trans{'amount'} = $trans->[$j]->{'amount'} * (-1);
419 $new_trans{'umsatz'} = abs($trans->[$j]->{'amount'}) * $ml;
420 $trans->[$j]->{'umsatz'} = abs($trans->[$j]->{'amount'}) * $ml;
422 push @splits, [ \%new_trans, $trans->[$j] ];
423 push @{ $form->{DATEV} }, $splits[-1];
425 } elsif (($j != $notsplitindex) && ($trans->[$j]->{'chart_id'} eq "")) {
426 $absumsatz += ($trans->[$j]->{'amount'} * (1 + $taxes{ $taxid_taxkeys{$trans->[$j]->{'taxkey'}} }));
429 map { $new_trans{$_} = $trans->[$notsplitindex]->{$_}; } keys %{ $trans->[$notsplitindex] };
431 my $tax_rate = 1 + $taxes{ $taxid_taxkeys{$trans->[$j]->{'taxkey'}} };
432 $new_trans{'amount'} = $form->round_amount(($trans->[$j]->{'amount'} * $tax_rate * -1), 2);
433 $new_trans{'umsatz'} = abs($form->round_amount(($trans->[$j]->{'amount'} * $tax_rate), 2)) * $ml;
434 $trans->[$j]->{'umsatz'} = abs($form->round_amount(($trans->[$j]->{'amount'} * $tax_rate), 2)) * $ml;
436 push @splits, [ \%new_trans, $trans->[$j] ];
437 push @{ $form->{DATEV} }, $splits[-1];
441 if (abs($absumsatz) > 0.01) {
442 push @errors, "Datev-Export fehlgeschlagen! Bei Transaktion $trans->[0]->{trans_id} ($absumsatz)\n";
448 $form->error(join("<br>\n", @errors)) if (@errors);
450 $main::lxdebug->leave_sub();
453 sub make_kne_data_header {
454 $main::lxdebug->enter_sub();
456 my ($myconfig, $form, $fromto, $start_jahr) = @_;
458 my $jahr = $start_jahr;
465 my $header = "\x1D\x181";
466 $header .= _fill($form->{datentraegernr}, 3, '0');
467 $header .= ($fromto) ? "11" : "13"; # Anwendungsnummer
468 $header .= _fill($form->{dfvkz}, 2, '0');
469 $header .= _fill($form->{beraternr}, 7, '0');
470 $header .= _fill($form->{mandantennr}, 5, '0');
471 $header .= _fill($form->{abrechnungsnr} . $jahr, 6, '0');
473 $fromto =~ s/transdate|>=|and|\'|<=//g;
474 my ($from, $to) = split / /, $fromto;
479 my ($fday, $fmonth, $fyear) = split(/\./, $from);
480 if (length($fmonth) < 2) {
481 $fmonth = "0" . $fmonth;
483 if (length($fday) < 2) {
486 $from = $fday . $fmonth . substr($fyear, -2, 2);
494 my ($tday, $tmonth, $tyear) = split(/\./, $to);
495 if (length($tmonth) < 2) {
496 $tmonth = "0" . $tmonth;
498 if (length($tday) < 2) {
501 $to = $tday . $tmonth . substr($tyear, -2, 2);
509 $header .= $primanota;
512 $header .= _fill($form->{passwort}, 4, '0');
513 $header .= " " x 16; # Anwendungsinfo
514 $header .= " " x 16; # Inputinfo
518 my $versionssatz = $form->{exporttype} == 0 ? "\xB5" . "1," : "\xB6" . "1,";
520 my $dbh = $form->get_standard_dbh($myconfig);
521 my $query = qq|SELECT accno FROM chart LIMIT 1|;
522 my $ref = selectfirst_hashref_query($form, $dbh, $query);
524 $versionssatz .= length $ref->{accno};
525 $versionssatz .= ",";
526 $versionssatz .= length $ref->{accno};
527 $versionssatz .= ",SELF" . "\x1C\x79";
529 $header .= $versionssatz;
531 $main::lxdebug->leave_sub();
537 $main::lxdebug->enter_sub();
539 my ($date, $six) = @_;
541 ($day, $month, $year) = split(/\./, $date);
544 $day = substr($day, 1, 1);
546 if (length($month) < 2) {
547 $month = "0" . $month;
549 if (length($year) > 2) {
550 $year = substr($year, -2, 2);
554 $date = $day . $month . $year;
556 $date = $day . $month;
559 $main::lxdebug->leave_sub();
564 sub trim_leading_zeroes {
572 sub make_ed_versionset {
573 $main::lxdebug->enter_sub();
575 my ($header, $filename, $blockcount, $fromto) = @_;
577 my $versionset = "V" . substr($filename, 2, 5);
578 $versionset .= substr($header, 6, 22);
581 $versionset .= "0000" . substr($header, 28, 19);
584 $versionset .= $datum . "001" . substr($header, 28, 4);
587 $versionset .= _fill($blockcount, 5, '0');
588 $versionset .= "001";
590 $versionset .= substr($header, -12, 10) . " ";
591 $versionset .= " " x 53;
593 $main::lxdebug->leave_sub();
599 $main::lxdebug->enter_sub();
601 my ($form, $fileno) = @_;
603 my $ev_header = _fill($form->{datentraegernr}, 3, ' ', 'left');
605 $ev_header .= _fill($form->{beraternr}, 7, ' ', 'left');
606 $ev_header .= _fill($form->{beratername}, 9, ' ', 'left');
608 $ev_header .= (_fill($fileno, 5, '0')) x 2;
609 $ev_header .= " " x 95;
611 $main::lxdebug->leave_sub();
616 sub kne_buchungsexport {
617 $main::lxdebug->enter_sub();
619 my ($myconfig, $form) = @_;
623 my $export_path = _get_export_path() . "/";
624 my $filename = "ED00000";
632 <body>Export in Bearbeitung<br>
633 Buchungssätze verarbeitet:
636 ($fromto, $start_jahr) =
637 &get_dates($form->{zeitraum}, $form->{monat},
638 $form->{quartal}, $form->{transdatefrom},
639 $form->{transdateto});
640 _get_transactions($fromto);
642 print qq|<br>2. Durchlauf:|;
643 while (scalar(@{ $form->{DATEV} })) {
646 my $ed_filename = $export_path . $filename;
647 push(@filenames, $filename);
648 $header = &make_kne_data_header($myconfig, $form, $fromto, $start_jahr);
650 my $kne_file = SL::DATEV::KNEFile->new();
651 $kne_file->add_block($header);
653 while (scalar(@{ $form->{DATEV} }) > 0) {
654 $transaction = shift @{ $form->{DATEV} };
655 $trans_lines = scalar(@{$transaction});
657 if (($counter % 500) == 0) {
667 my $buchungstext = "";
669 my $datevautomatik = 0;
672 my %umlaute = ('ä' => 'ae',
679 for (my $i = 0; $i < $trans_lines; $i++) {
680 if ($trans_lines == 2) {
681 if (abs($transaction->[$i]->{'amount'}) > abs($umsatz)) {
682 $umsatz = $transaction->[$i]->{'amount'};
685 if (abs($transaction->[$i]->{'umsatz'}) > abs($umsatz)) {
686 $umsatz = $transaction->[$i]->{'umsatz'};
689 if ($transaction->[$i]->{'datevautomatik'}) {
692 if ($transaction->[$i]->{'taxkey'}) {
693 $taxkey = $transaction->[$i]->{'taxkey'};
695 if ($transaction->[$i]->{'charttax'}) {
696 $charttax = $transaction->[$i]->{'charttax'};
698 if ( ($transaction->[$i]->{'id'} eq $transaction->[$i]->{'chart_id'})
699 && ($trans_lines > 2)) {
700 undef($transaction->[$i]);
701 } elsif ($transaction->[$i]->{'amount'} > 0) {
708 # Umwandlung von Umlauten und Sonderzeichen in erlaubte Zeichen bei Textfeldern
709 foreach $umlaut (keys(%umlaute)) {
710 $transaction->[$haben]->{'invnumber'} =~ s/${umlaut}/${umlaute{$umlaut}}/g;
711 $transaction->[$haben]->{'name'} =~ s/${umlaut}/${umlaute{$umlaut}}/g;
714 $transaction->[$haben]->{'invnumber'} =~ s/[^0-9A-Za-z\$\%\&\*\+\-\/]//g;
715 $transaction->[$haben]->{'name'} =~ s/[^0-9A-Za-z\$\%\&\*\+\-\ \/]//g;
717 $transaction->[$haben]->{'invnumber'} = substr($transaction->[$haben]->{'invnumber'}, 0, 12);
718 $transaction->[$haben]->{'name'} = substr($transaction->[$haben]->{'name'}, 0, 30);
719 $transaction->[$haben]->{'invnumber'} =~ s/\ *$//;
720 $transaction->[$haben]->{'name'} =~ s/\ *$//;
722 if ($trans_lines >= 2) {
724 $gegenkonto = "a" . trim_leading_zeroes($transaction->[$haben]->{'accno'});
725 $konto = "e" . trim_leading_zeroes($transaction->[$soll]->{'accno'});
726 if ($transaction->[$haben]->{'invnumber'} ne "") {
727 $belegfeld1 = "\xBD" . $transaction->[$haben]->{'invnumber'} . "\x1C";
730 $datum .= &datetofour($transaction->[$haben]->{'transdate'}, 0);
731 $waehrung = "\xB3" . "EUR" . "\x1C";
732 if ($transaction->[$haben]->{'name'} ne "") {
733 $buchungstext = "\x1E" . $transaction->[$haben]->{'name'} . "\x1C";
735 if ($transaction->[$haben]->{'duedate'} ne "") {
736 $belegfeld2 = "\xBE" . &datetofour($transaction->[$haben]->{'duedate'}, 1) . "\x1C";
740 $umsatz = $kne_file->format_amount(abs($umsatz), 0);
741 $umsatzsumme += $umsatz;
742 $kne_file->add_block("+" . $umsatz);
744 if ( ( $datevautomatik || $taxkey)
745 && (!$datevautomatik || ($datevautomatik && ($charttax ne $taxkey)))) {
746 $kne_file->add_block("\x6C" . (!$datevautomatik ? $taxkey : "4"));
749 $kne_file->add_block($gegenkonto);
750 $kne_file->add_block($belegfeld1);
751 $kne_file->add_block($belegfeld2);
752 $kne_file->add_block($datum);
753 $kne_file->add_block($konto);
754 $kne_file->add_block($buchungstext);
755 $kne_file->add_block($waehrung . "\x79");
758 my $mandantenendsumme = "x" . $kne_file->format_amount($umsatzsumme / 100.0, 14) . "\x79\x7a";
760 $kne_file->add_block($mandantenendsumme);
763 open(ED, "> $ed_filename") or die "can't open outputfile: $!\n";
764 print(ED $kne_file->get_data());
767 $ed_versionset[$fileno] = &make_ed_versionset($header, $filename, $kne_file->get_block_count(), $fromto);
771 #Make EV Verwaltungsdatei
772 $ev_header = &make_ev_header($form, $fileno);
773 $ev_filename = $export_path . $evfile;
774 push(@filenames, $evfile);
775 open(EV, "> $ev_filename") or die "can't open outputfile: EV01\n";
776 print(EV $ev_header);
778 foreach $file (@ed_versionset) {
779 print(EV $ed_versionset[$file]);
782 print qq|<br>Done. <br>
785 $main::lxdebug->leave_sub();
787 return { 'download_token' => get_download_token_for_path($export_path), 'filenames' => \@filenames };
790 sub kne_stammdatenexport {
791 $main::lxdebug->enter_sub();
793 my ($myconfig, $form) = @_;
794 $form->{abrechnungsnr} = "99";
799 <body>Export in Bearbeitung<br>
804 my $export_path = _get_export_path() . "/";
805 my $filename = "ED00000";
811 my $remaining_bytes = 256;
812 my $total_bytes = 256;
813 my $buchungssatz = "";
815 my $ed_filename = $export_path . $filename;
816 push(@filenames, $filename);
817 open(ED, "> $ed_filename") or die "can't open outputfile: $!\n";
818 $header = &make_kne_data_header($myconfig, $form, "");
819 $remaining_bytes -= length($header);
821 # connect to database
822 my $dbh = $form->dbconnect($myconfig);
824 my (@where, @values) = ((), ());
825 if ($form->{accnofrom}) {
826 push @where, 'c.accno >= ?';
827 push @values, $form->{accnofrom};
829 if ($form->{accnoto}) {
830 push @where, 'c.accno <= ?';
831 push @values, $form->{accnoto};
834 my $where_str = ' WHERE ' . join(' AND ', map { "($_)" } @where) if (scalar @where);
836 my $query = qq|SELECT c.accno, c.description
841 my $sth = $dbh->prepare($query);
842 $sth->execute(@values) || $form->dberror($query);
844 while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
845 if (($remaining_bytes - length("t" . $ref->{'accno'})) <= 6) {
846 $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
847 $buchungssatz .= "\x00" x $fuellzeichen;
849 $total_bytes = ($blockcount) * 256;
851 $buchungssatz .= "t" . $ref->{'accno'};
852 $remaining_bytes = $total_bytes - length($buchungssatz . $header);
853 $ref->{'description'} =~ s/[^0-9A-Za-z\$\%\&\*\+\-\/]//g;
854 $ref->{'description'} = substr($ref->{'description'}, 0, 40);
855 $ref->{'description'} =~ s/\ *$//;
858 ($remaining_bytes - length("\x1E" . $ref->{'description'} . "\x1C\x79")
861 $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
862 $buchungssatz .= "\x00" x $fuellzeichen;
864 $total_bytes = ($blockcount) * 256;
866 $buchungssatz .= "\x1E" . $ref->{'description'} . "\x1C\x79";
867 $remaining_bytes = $total_bytes - length($buchungssatz . $header);
872 print(ED $buchungssatz);
873 $fuellzeichen = 256 - (length($header . $buchungssatz . "z") % 256);
874 $dateiende = "\x00" x $fuellzeichen;
876 print(ED $dateiende);
879 #Make EV Verwaltungsdatei
881 &make_ed_versionset($header, $filename, $blockcount, $fromto);
883 $ev_header = &make_ev_header($form, $fileno);
884 $ev_filename = $export_path . $evfile;
885 push(@filenames, $evfile);
886 open(EV, "> $ev_filename") or die "can't open outputfile: EV01\n";
887 print(EV $ev_header);
889 foreach $file (@ed_versionset) {
890 print(EV $ed_versionset[$file]);
897 print qq|<br>Done. <br>
900 $main::lxdebug->leave_sub();
902 return { 'download_token' => get_download_token_for_path($export_path), 'filenames' => \@filenames };