Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 08ed7551

Von Jan Büren vor 8 Monaten hinzugefügt

  • ID 08ed755185207c4af74f366cd783cd5c1fdec694
  • Vorgänger 46d48c74
  • Nachfolger dd69eacf

DATEV-Export um Beleg-Export erweitert

Die Option steht bei aktivierten DMS und dem Backend-Typ 'Dateisystem'
zu Verfügung.

Unterschiede anzeigen:

SL/DATEV.pm
38 38
use SL::Locale::String qw(t8);
39 39
use SL::VATIDNr;
40 40

  
41
use Archive::Zip;
41 42
use Data::Dumper;
42 43
use DateTime;
43 44
use Exporter qw(import);
......
48 49
use List::UtilsBy qw(partition_by sort_by);
49 50
use Text::CSV_XS;
50 51
use Time::HiRes qw(gettimeofday);
52
use XML::LibXML;
51 53

  
52 54
{
53 55
  my $i = 0;
......
348 350
    $csv_file->close;
349 351
    $self->{warnings} = $datev_csv->warnings;
350 352

  
353
    $self->_create_xml_and_documents if $self->{documents} && scalar @{ $self->{guids} };
354

  
351 355
    # convert utf-8 to cp1252//translit if set
352 356
    if ($::instance_conf->get_datev_export_format eq 'cp1252-translit') {
353 357

  
......
402 406
 }
403 407
 return $self->{imported};
404 408
}
409
sub documents {
410
 my $self = shift;
411

  
412
 if (@_) {
413
   $self->{documents} = $_[0];
414
 }
415
 return $self->{documents};
416
}
417
sub _create_xml_and_documents {
418
  my $self = shift;
419

  
420
  die "No guids" unless scalar @{ $self->{guids} };
421

  
422
  my $today = DateTime->now_local;
423
  my $doc   = XML::LibXML::Document->new('1.0', 'utf-8');
424

  
425
  my $root  = $doc->createElement('archive');
426
  #<archive xmlns="http://xml.datev.de/bedi/tps/document/v05.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xml.datev.de/bedi/tps/document/v05.0 Document_v050.xsd" version="5.0" generatingSystem="DATEV-Musterdaten">
427

  
428
  $root->setAttribute('xmlns'              => 'http://xml.datev.de/bedi/tps/document/v05.0');
429
  $root->setAttribute('xmlns:xsi'          => 'http://www.w3.org/2001/XMLSchema-instance');
430
  $root->setAttribute('xsi:schemaLocation' => 'http://xml.datev.de/bedi/tps/document/v05.0 Document_v050.xsd');
431
  $root->setAttribute('version'            => '5.0');
432
  $root->setAttribute('generatingSystem'   => 'kivitendo');
433

  
434
  # header with timestamp
435
  my $header_tag = $doc->createElement('header');
436
  $root->appendChild($header_tag);
437
  my $date_tag = $doc->createElement('date');
438
  $date_tag->appendTextNode($today);
439
  $header_tag->appendChild($date_tag);
440

  
441

  
442
  # content
443
  my $content_node = $doc->createElement('content');
444
  $root->appendChild($content_node);
445
  # we have n document childs
446
  foreach my $guid (@{ $self->{guids} }) {
447
    # 1. get filename and file location
448
    my $file_version = SL::DB::Manager::FileVersion->find_by(guid => $guid);
449
    die "Invalid guid $guid" unless ref $file_version eq 'SL::DB::FileVersion';
450
    # file_name has to be unique add guid if needed
451
    my $filename_for_zip = (exists $self->{files}{$file_version->file_name})
452
                           ? $file_version->file_name . '__' . $guid
453
                           : $file_version->file_name;
454
    $self->{files}{$filename_for_zip} = $file_version->get_system_location;
455
    # create xml metadata for files
456
    my $document_node = $doc->createElement('document');
457
    # set attr
458
    $document_node->setAttribute('guid'      => $guid);
459
    $document_node->setAttribute('processID' => '1');
460
    $document_node->setAttribute('type'      => '1');
461
    $content_node->appendChild($document_node);
462
    my $extension_node = $doc->createElement('extension');
463
    $extension_node->setAttribute('xsi:type' => 'File');
464
    $extension_node->setAttribute('name'     => $filename_for_zip);
465
    $document_node->appendChild($extension_node);
466
  }
467
  $doc->setDocumentElement($root);
468

  
469
  # create Archive::Zip in Export Path
470
  my $zip = Archive::Zip->new();
471
  # add metadata document
472
  $zip->addString($doc->toString(), 'document.xml');
473
  # add real files
474
  foreach my $filename (keys %{ $self->{files} }) {
475
    $zip->addFile($self->{files}{$filename}, $filename);
476
  }
477
  die "Cannot write Belege-XML.zip" unless ($zip->writeToFileNamed($self->export_path . 'Belege-XML.zip')
478
                                            == Archive::Zip::AZ_OK());
479
}
405 480

  
406 481
sub generate_datev_data {
407 482
  $main::lxdebug->enter_sub();
......
820 895
    my $taxkey         = 0;
821 896
    my $charttax       = 0;
822 897
    my $ustid          ="";
898
    my $document_guid  ="";
823 899
    my ($haben, $soll);
824 900
    for (my $i = 0; $i < $trans_lines; $i++) {
825 901
      if ($trans_lines == 2) {
......
907 983
    }
908 984
    # set lock for each transaction
909 985
    $datev_data{locked} = $self->locked;
910

  
986
    # add guids if datev export with documents is requested
987
    if ($self->documents) {
988
      # add exactly one document link for the latest created/uploaded document
989
      my $latest_document = SL::DB::Manager::File->get_first(query =>
990
                                [
991
                                  object_id => $transaction->[$haben]->{trans_id},
992
                                  file_type => 'document'
993
                                ],
994
                                  sort_by   => 'itime DESC');
995
      if (ref $latest_document eq 'SL::DB::File') {
996
        # if we have a booking document add guid from the latest version
997
        $datev_data{document_guid} = $latest_document->file_version->[-1]->guid;
998
        push @{ $self->{guids} }, $datev_data{document_guid};
999
      }
1000
    }
911 1001
    push(@datev_lines, \%datev_data) if $datev_data{umsatz};
912 1002
  }
913 1003

  
......
956 1046
  return 1;
957 1047
}
958 1048

  
1049
sub check_document_export {
1050
  my ($self) = @_;
1051

  
1052
  # no dms enabled and works only for type Filesystem
1053
  return 0 unless $::instance_conf->get_doc_storage
1054
               && $::instance_conf->get_doc_storage_for_documents eq 'Filesystem';
1055

  
1056
  return 1;
1057

  
1058
  # TODO maybe needed
1059
  # not all last month ar ap gl booking have an entry -> rent ?
1060
  my $query = <<"SQL";
1061
  select distinct trans_id,object_id from acc_trans
1062
  left join files on files.object_id=trans_id
1063
  where date_trunc('month', transdate) = date_trunc('month', current_date - interval '1 month')
1064
  and object_id is null
1065
  LIMIT 1
1066
SQL
1067
  my ($booking_has_no_document)  = selectrow_query($::form, SL::DB->client->dbh, $query);
1068
  return defined $booking_has_no_document ? 0 : 1;
1069

  
1070
}
959 1071
sub DESTROY {
960 1072
  clean_temporary_directories();
961 1073
}
SL/DATEV/CSV.pm
153 153
                              kivi_datev_name => 'not yet implemented',
154 154
                            },
155 155
                            {
156
                              kivi_datev_name => 'not yet implemented',
156
                              kivi_datev_name => 'document_guid',
157 157
                              csv_header_name => t8('Link to invoice'),
158 158
                              max_length      => 210, # DMS Application shortcut and GUID
159 159
                                                      # Example: "BEDI"
160 160
                                                      # "8DB85C02-4CC3-FF3E-06D7-7F87EEECCF3A".
161
                              type            => 'Text',
162
                              default         => '',
163
                              input_check     => sub { my ($check) = @_; return 1 unless $check; return ($check =~ m/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/) },
164
                              formatter       => sub { my ($input) = @_; return '' unless $input; return 'BEDI "' . $input . '"' },
165

  
161 166
                            }, # pos 20
162 167
                            {
163 168
                              kivi_datev_name => 'not yet implemented',
bin/mozilla/datev.pl
74 74
  setup_datev_export2_action_bar();
75 75

  
76 76
  $::form->header;
77
  $::form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all_sorted;
78
  $::form->{show_pk_option}  = SL::DATEV->new->check_vcnumbers_are_valid_pk_numbers;
77
  $::form->{ALL_DEPARTMENTS}        = SL::DB::Manager::Department->get_all_sorted;
78
  $::form->{show_pk_option}         = SL::DATEV->new->check_vcnumbers_are_valid_pk_numbers;
79
  $::form->{show_documents_option}  = SL::DATEV->new->check_document_export;
79 80

  
80 81
  # check if we have mismatching number length domains
81 82
  SL::DATEV->new->check_valid_length_of_accounts;
......
98 99
    $::form->{zeitraum}, $::form->{monat}, $::form->{quartal},
99 100
    $::form->{transdatefrom}, $::form->{transdateto},
100 101
  );
101
  $data{use_pk} = $::form->{use_pk};
102
  $data{locked} = $::form->{locked};
103
  $data{imported} = $::form->{imported};
102
  $data{use_pk}    = $::form->{use_pk};
103
  $data{locked}    = $::form->{locked};
104
  $data{imported}  = $::form->{imported};
105
  $data{documents} = $::form->{documents};
104 106

  
105 107
  my $datev = SL::DATEV->new(%data);
106 108

  
templates/webpages/datev/export_bewegungsdaten.html
113 113
           <td align=left></td>
114 114
           <td colspan="3">[% L.yes_no_tag('imported', 0) %]</td>
115 115
        </tr>
116
         <tr>
117
           <td align=left>[% 'Export Documents' | $T8 %]</td>
118
           <td align=left></td>
119
          [% IF show_documents_option %]
120
           <td colspan="3">[% L.yes_no_tag('documents', 0, disabled => 0) %]</td>
121
          [% ELSE %]
122
           <td>[% L.yes_no_tag('documents', 0, disabled => 1) %] </td>
123
           <td colspan="2"><font color="gray">[% 'Hint: DMS Feature has to be activated' | $T8 %]</font></td>
124
          [% END %]
125
        </tr>
126

  
116 127
        </table>
117 128
     </td>
118 129
   </tr>

Auch abrufbar als: Unified diff