Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 40d52f50

Von Moritz Bunkus vor fast 16 Jahren hinzugefügt

  • ID 40d52f5031f6e2344a0e1a8d420b5d22ccca5ea8
  • Vorgänger 15dbafbb
  • Nachfolger f4cf3038

DATEV-Schnittstelle: Auslagerung von KNE-Schreibfunktionen in eigenes Modul. Kosmetik. Einrückung. Coderefactoring für bessere Lesbarkeit.

Unterschiede anzeigen:

SL/DATEV.pm
27 27
package DATEV;
28 28

  
29 29
use SL::DBUtils;
30
use SL::DATEV::KNEFile;
30 31

  
31 32
use Data::Dumper;
32 33

  
......
500 501
  return $date;
501 502
}
502 503

  
503
sub formatumsatz {
504
  $main::lxdebug->enter_sub();
505

  
506
  my ($umsatz, $stellen) = @_;
507

  
508
  $umsatz =~ s/-//;
509
  ($vorkomma, $nachkomma) = split(/\./, $umsatz);
510
  $umsatz = "";
511
  if ($stellen > 0) {
512
    for ($i = $stellen; $i >= $stellen + 2 - length($vorkomma); $i--) {
513
      $umsatz .= "0";
514
    }
515
  }
516
  for ($i = 3; $i > length($nachkomma); $i--) {
517
    $nachkomma .= "0";
518
  }
519
  $umsatz = $vorkomma . substr($nachkomma, 0, 2);
504
sub trim_leading_zeroes {
505
  my $str = shift;
520 506

  
521
  $main::lxdebug->leave_sub();
507
  $str =~ s/^0+//g;
522 508

  
523
  return $umsatz;
509
  return $str;
524 510
}
525 511

  
526 512
sub make_ed_versionset {
......
595 581
  my $counter = 0;
596 582
  print qq|<br>2. Durchlauf:|;
597 583
  while (scalar(@{ $form->{DATEV} })) {
598
    my $blockcount      = 1;
599
    my $remaining_bytes = 256;
600
    my $total_bytes     = 256;
601
    my $umsatzsumme     = 0;
602
    my $buchungssatz    = "";
584
    my $umsatzsumme = 0;
603 585
    $filename++;
604 586
    my $ed_filename = $export_path . $filename;
605 587
    push(@filenames, $filename);
606
    open(ED, "> $ed_filename") or die "can't open outputfile: $!\n";
607 588
    $header = &make_kne_data_header($myconfig, $form, $fromto, $start_jahr);
608
    $remaining_bytes -= length($header);
589

  
590
    my $kne_file = SL::DATEV::KNEFile->new();
591
    $kne_file->add_block($header);
609 592

  
610 593
    while (scalar(@{ $form->{DATEV} }) > 0) {
611 594
      $transaction = shift @{ $form->{DATEV} };
......
615 598
        print("$counter ");
616 599
      }
617 600

  
618
      $umsatz         = 0;
619
      $gegenkonto     = "";
620
      $konto          = "";
621
      $belegfeld1     = "";
622
      $datum          = "";
623
      $waehrung       = "";
624
      $buchungstext   = "";
625
      $belegfeld2     = "";
626
      $datevautomatik = 0;
627
      $taxkey         = 0;
628
      $charttax       = 0;
629
      %umlaute = ('?' => 'ae',
630
                  '?' => 'oe',
631
                  '?' => 'ue',
632
                  '?' => 'Ae',
633
                  '?' => 'Oe',
634
                  '?' => 'Ue',
635
                  '?' => 'sz');
636

  
601
      my $umsatz         = 0;
602
      my $gegenkonto     = "";
603
      my $konto          = "";
604
      my $belegfeld1     = "";
605
      my $datum          = "";
606
      my $waehrung       = "";
607
      my $buchungstext   = "";
608
      my $belegfeld2     = "";
609
      my $datevautomatik = 0;
610
      my $taxkey         = 0;
611
      my $charttax       = 0;
612
      my %umlaute = ('?' => 'ae',
613
                     '?' => 'oe',
614
                     '?' => 'ue',
615
                     '?' => 'Ae',
616
                     '?' => 'Oe',
617
                     '?' => 'Ue',
618
                     '?' => 'sz');
637 619
      for (my $i = 0; $i < $trans_lines; $i++) {
638 620
        if ($trans_lines == 2) {
639 621
          if (abs($transaction->[$i]->{'amount'}) > abs($umsatz)) {
......
656 638
        if (   ($transaction->[$i]->{'id'} eq $transaction->[$i]->{'chart_id'})
657 639
            && ($trans_lines > 2)) {
658 640
          undef($transaction->[$i]);
659
            } elsif ($transaction->[$i]->{'amount'} > 0) {
641
        } elsif ($transaction->[$i]->{'amount'} > 0) {
660 642
          $haben = $i;
661
            } else {
643
        } else {
662 644
          $soll = $i;
663 645
        }
664 646
      }
665 647

  
666
      $umsatzsumme += abs($umsatz);
667

  
668 648
      # Umwandlung von Umlauten und Sonderzeichen in erlaubte Zeichen bei Textfeldern
669 649
      foreach $umlaut (keys(%umlaute)) {
670
        $transaction->[$haben]->{'invnumber'} =~
671
          s/${umlaut}/${umlaute{$umlaut}}/g;
672
        $transaction->[$haben]->{'name'} =~ s/${umlaut}/${umlaute{$umlaut}}/g;
650
        $transaction->[$haben]->{'invnumber'} =~ s/${umlaut}/${umlaute{$umlaut}}/g;
651
        $transaction->[$haben]->{'name'}      =~ s/${umlaut}/${umlaute{$umlaut}}/g;
673 652
      }
674 653

  
675 654
      $transaction->[$haben]->{'invnumber'} =~ s/[^0-9A-Za-z\$\%\&\*\+\-\/]//g;
676
      $transaction->[$haben]->{'name'} =~ s/[^0-9A-Za-z\$\%\&\*\+\-\ \/]//g;
655
      $transaction->[$haben]->{'name'}      =~ s/[^0-9A-Za-z\$\%\&\*\+\-\ \/]//g;
677 656

  
678
      $transaction->[$haben]->{'invnumber'} =
679
        substr($transaction->[$haben]->{'invnumber'}, 0, 12);
680
      $transaction->[$haben]->{'name'} =
681
        substr($transaction->[$haben]->{'name'}, 0, 30);
657
      $transaction->[$haben]->{'invnumber'} =  substr($transaction->[$haben]->{'invnumber'}, 0, 12);
658
      $transaction->[$haben]->{'name'}      =  substr($transaction->[$haben]->{'name'}, 0, 30);
682 659
      $transaction->[$haben]->{'invnumber'} =~ s/\ *$//;
683 660
      $transaction->[$haben]->{'name'}      =~ s/\ *$//;
684 661

  
685 662
      if ($trans_lines >= 2) {
686 663

  
687
        $gegenkonto = "a" . $transaction->[$haben]->{'accno'};
688
        $konto      = "e" . $transaction->[$soll]->{'accno'};
664
        $gegenkonto = "a" . trim_leading_zeroes($transaction->[$haben]->{'accno'});
665
        $konto      = "e" . trim_leading_zeroes($transaction->[$soll]->{'accno'});
689 666
        if ($transaction->[$haben]->{'invnumber'} ne "") {
690
          $belegfeld1 =
691
            "\xBD" . $transaction->[$haben]->{'invnumber'} . "\x1C";
667
          $belegfeld1 = "\xBD" . $transaction->[$haben]->{'invnumber'} . "\x1C";
692 668
        }
693 669
        $datum = "d";
694 670
        $datum .= &datetofour($transaction->[$haben]->{'transdate'}, 0);
......
697 673
          $buchungstext = "\x1E" . $transaction->[$haben]->{'name'} . "\x1C";
698 674
        }
699 675
        if ($transaction->[$haben]->{'duedate'} ne "") {
700
          $belegfeld2 = "\xBE"
701
            . &datetofour($transaction->[$haben]->{'duedate'}, 1) . "\x1C";
676
          $belegfeld2 = "\xBE" . &datetofour($transaction->[$haben]->{'duedate'}, 1) . "\x1C";
702 677
        }
703 678
      }
704 679

  
705
      if (($remaining_bytes - length("+" . &formatumsatz($umsatz, 0))) <= 6) {
706
        $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
707
        $buchungssatz .= "\x00" x $fuellzeichen;
708
        $blockcount++;
709
        $total_bytes = ($blockcount) * 256;
710
      }
711
      $umsatz = abs($umsatz);
712
      $vorzeichen = ($umsatz > 0) ? "+" : "-";
713
      $buchungssatz .= $vorzeichen . &formatumsatz($umsatz, 0);
714
      $remaining_bytes = $total_bytes - length($buchungssatz . $header);
715

  
716
      if ( ($taxkey || $datevautomatik)
717
        && (!$datevautomatik || ($datevautomatik && ($charttax ne $taxkey)))) {
718
        if (($remaining_bytes - length("\x6C" . "11")) <= 6) {
719
          $fuellzeichen =
720
            ($blockcount * 256 - length($buchungssatz . $header));
721
          $buchungssatz .= "\x00" x $fuellzeichen;
722
          $blockcount++;
723
          $total_bytes = ($blockcount) * 256;
724
        }
725
        if (!$datevautomatik) {
726
          $buchungssatz .= "\x6C" . $taxkey;
727
        } else {
728
          $buchungssatz .= "\x6C" . "4";
729
        }
730
        $remaining_bytes = $total_bytes - length($buchungssatz . $header);
731
      }
680
      $umsatz       = $kne_file->format_amount(abs($umsatz), 0);
681
      $umsatzsumme += $umsatz;
682
      $kne_file->add_block("+" . $umsatz);
732 683

  
733
      if (($remaining_bytes - length($gegenkonto)) <= 6) {
734
        $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
735
        $buchungssatz .= "\x00" x $fuellzeichen;
736
        $blockcount++;
737
        $total_bytes = ($blockcount) * 256;
738
      }
739
      $buchungssatz .= $gegenkonto;
740
      $remaining_bytes = $total_bytes - length($buchungssatz . $header);
741

  
742
      if (($remaining_bytes - length($belegfeld1)) <= 6) {
743
        $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
744
        $buchungssatz .= "\x00" x $fuellzeichen;
745
        $blockcount++;
746
        $total_bytes = ($blockcount) * 256;
747
      }
748
      $buchungssatz .= $belegfeld1;
749
      $remaining_bytes = $total_bytes - length($buchungssatz . $header);
750

  
751
      if (($remaining_bytes - length($belegfeld2)) <= 6) {
752
        $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
753
        $buchungssatz .= "\x00" x $fuellzeichen;
754
        $blockcount++;
755
        $total_bytes = ($blockcount) * 256;
756
      }
757
      $buchungssatz .= $belegfeld2;
758
      $remaining_bytes = $total_bytes - length($buchungssatz . $header);
759

  
760
      if (($remaining_bytes - length($datum)) <= 6) {
761
        $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
762
        $buchungssatz .= "\x00" x $fuellzeichen;
763
        $blockcount++;
764
        $total_bytes = ($blockcount) * 256;
684
      if (   ( $datevautomatik || $taxkey)
685
          && (!$datevautomatik || ($datevautomatik && ($charttax ne $taxkey)))) {
686
        $kne_file->add_block("\x6C" . (!$datevautomatik ? $taxkey : "4"));
765 687
      }
766
      $buchungssatz .= $datum;
767
      $remaining_bytes = $total_bytes - length($buchungssatz . $header);
768

  
769
      if (($remaining_bytes - length($konto)) <= 6) {
770
        $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
771
        $buchungssatz .= "\x00" x $fuellzeichen;
772
        $blockcount++;
773
        $total_bytes = ($blockcount) * 256;
774
      }
775
      $buchungssatz .= $konto;
776
      $remaining_bytes = $total_bytes - length($buchungssatz . $header);
777

  
778
      if (($remaining_bytes - length($buchungstext)) <= 6) {
779
        $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
780
        $buchungssatz .= "\x00" x $fuellzeichen;
781
        $blockcount++;
782
        $total_bytes = ($blockcount) * 256;
783
      }
784
      $buchungssatz .= $buchungstext;
785
      $remaining_bytes = $total_bytes - length($buchungssatz . $header);
786

  
787
      if (($remaining_bytes - (length($waehrung . "\x79"))) <= 6) {
788
        $fuellzeichen = ($blockcount * 256 - length($buchungssatz . $header));
789
        $buchungssatz .= "\x00" x $fuellzeichen;
790
        $blockcount++;
791
        $total_bytes = ($blockcount) * 256;
792
      }
793
      $buchungssatz .= $waehrung . "\x79";
794
      $remaining_bytes = $total_bytes - length($buchungssatz . $header);
795 688

  
689
      $kne_file->add_block($gegenkonto);
690
      $kne_file->add_block($belegfeld1);
691
      $kne_file->add_block($belegfeld2);
692
      $kne_file->add_block($datum);
693
      $kne_file->add_block($konto);
694
      $kne_file->add_block($buchungstext);
695
      $kne_file->add_block($waehrung . "\x79");
796 696
    }
797 697

  
798
    $mandantenendsumme =
799
      "x" . &formatumsatz($umsatzsumme, 14) . "\x79" . "\x7a";
800
    $fuellzeichen =
801
      256 - (length($header . $buchungssatz . $mandantenendsumme) % 256);
802
    $dateiende = "\x00" x $fuellzeichen;
803
    print(ED $header);
804
    print(ED $buchungssatz);
805
    print(ED $mandantenendsumme);
806
    print(ED $dateiende);
698
    my $mandantenendsumme = "x" . $kne_file->format_amount($umsatzsumme / 100.0, 14) . "\x79\x7a";
699

  
700
    $kne_file->add_block($mandantenendsumme);
701
    $kne_file->flush();
702

  
703
    open(ED, "> $ed_filename") or die "can't open outputfile: $!\n";
704
    print(ED $kne_file->get_data());
807 705
    close(ED);
808 706

  
809
    $ed_versionset[$fileno] =
810
      &make_ed_versionset($header, $filename, $blockcount, $fromto);
707
    $ed_versionset[$fileno] = &make_ed_versionset($header, $filename, $kne_file->get_block_count(), $fromto);
811 708
    $fileno++;
812 709
  }
813 710

  
......
864 761
  # connect to database
865 762
  my $dbh = $form->dbconnect($myconfig);
866 763

  
867
  $query =
868
    qq|SELECT c.accno, c.description FROM chart c WHERE c.accno >=|
869
    . $dbh->quote($form->{accnofrom}) . qq|
870
           AND c.accno <= |
871
    . $dbh->quote($form->{accnoto}) . qq| ORDER BY c.accno|;
764
  my (@where, @values) = ((), ());
765
  if ($form->{accnofrom}) {
766
    push @where, 'c.accno >= ?';
767
    push @values, $form->{accnofrom};
768
  }
769
  if ($form->{accnoto}) {
770
    push @where, 'c.accno <= ?';
771
    push @values, $form->{accnoto};
772
  }
773

  
774
  my $where_str = ' WHERE ' . join(' AND ', map { "($_)" } @where) if (scalar @where);
872 775

  
873
  $sth = $dbh->prepare($query);
874
  $sth->execute || $form->dberror($query);
776
  my $query     = qq|SELECT c.accno, c.description
777
                     FROM chart c
778
                     $where_str
779
                     ORDER BY c.accno|;
780

  
781
  my $sth = $dbh->prepare($query);
782
  $sth->execute(@values) || $form->dberror($query);
875 783

  
876 784
  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
877 785
    if (($remaining_bytes - length("t" . $ref->{'accno'})) <= 6) {
SL/DATEV/KNEFile.pm
1
package SL::DATEV::KNEFile;
2

  
3
sub new {
4
  my $type = shift;
5
  my $self = {};
6

  
7
  bless $self, $type;
8

  
9
  $self->_init(@_);
10

  
11
  return $self;
12
}
13

  
14
sub _init {
15
  my $self   = shift;
16
  my %params = @_;
17

  
18
  map { $self->{$_} = $params{$_} } keys %params;
19

  
20
  $self->{remaining_bytes} = 250;
21
  $self->{block_count}     =   0;
22
  $self->{data}            = '';
23
}
24

  
25
sub get_data {
26
  my $self = shift;
27

  
28
  return $self->{data} || '';
29
}
30

  
31
sub get_block_count {
32
  my $self = shift;
33

  
34
  return $self->{block_count};
35
}
36

  
37
sub add_block {
38
  my $self      = shift;
39
  my $block     = shift;
40

  
41
  my $block_len = length $block;
42

  
43

  
44
  $self->flush() if ($block_len > $self->{remaining_bytes});
45

  
46
  $self->{data}            .= $block;
47
  $self->{remaining_bytes} -= $block_len;
48

  
49
  return $self;
50
}
51

  
52
sub flush {
53
  my $self = shift;
54

  
55
  if (250 == $self->{remaining_bytes}) {
56
    return $self;
57
  }
58

  
59
  my $num_zeros             = 6 + $self->{remaining_bytes};
60
  $self->{data}            .= "\x00" x $num_zeros;
61

  
62
  $self->{remaining_bytes}  = 250;
63
  $self->{block_count}++;
64

  
65
  return $self;
66
}
67

  
68
sub format_amount {
69
  my $self   = shift;
70
  my $amount = shift;
71
  my $width  = shift;
72

  
73
  $amount =~ s/-//;
74
  my ($places, $decimal_places) = split m/\./, "$amount";
75

  
76
  $places          *= 1;
77
  $decimal_places ||= 0;
78

  
79
  if (0 < $width) {
80
    $width  -= 2;
81
    $places  = sprintf("\%0${stellen}d", $places);
82
  }
83

  
84
  $decimal_places .= '0' if (2 > length $decimal_places);
85
  $amount          = $places . substr($decimal_places, 0, 2);
86
  $amount         *= 1 if (!$width);
87

  
88
  return $amount;
89
}
90

  
91
1;

Auch abrufbar als: Unified diff