Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 324726ac

Von Jan Büren vor fast 6 Jahren hinzugefügt

  • ID 324726acd30b8992854a2d59fec2a50265613eef
  • Vorgänger a9903fd7
  • Nachfolger f40cd4e1

Fixt #348 DatevExport kommt mit bestimmten Zeichen im Buchungstext nicht klar

In der Mandantenkonfiguration befindet sich jetzt eine Einstellung,
welche die Kodierung des DATEV-Exports steuert. DATEV erwartet CP1252.
kivitendo kann diese Kodierung so vom kivitendo Nutzer einfordern, alternativ nicht
vorhandenen Zeichen versuchen zu ersetzen oder die DATEV-Erwartung ignorieren
und UTF-8 liefern. Voreingestellt ist CP1252 mit Ersetzungen

Unterschiede anzeigen:

SL/DATEV.pm
35 35
use SL::DATEV::CSV;
36 36
use SL::DB;
37 37
use SL::HTML::Util ();
38
use SL::Iconv;
38 39
use SL::Locale::String qw(t8);
39 40

  
40 41
use Data::Dumper;
......
393 394
                eol          => "\r\n",
394 395
              }) or die "Cannot use CSV: ".Text::CSV_XS->error_diag();
395 396

  
396
    my $csv_file = IO::File->new($self->export_path . '/' . $filename, '>:encoding(cp1252)') or die "Can't open: $!";
397
    # get encoding from defaults - use cp1252 if DATEV strict export is used
398
    my $enc = ($::instance_conf->get_datev_export_format eq 'cp1252') ? 'cp1252' : 'utf-8';
399
    my $csv_file = IO::File->new($self->export_path . '/' . $filename, ">:encoding($enc)") or die "Can't open: $!";
400

  
397 401
    $csv->print($csv_file, $_) for @{ $datev_csv->header };
398 402
    $csv->print($csv_file, $_) for @{ $datev_csv->lines  };
399 403
    $csv_file->close;
400 404
    $self->{warnings} = $datev_csv->warnings;
401 405

  
406
    # convert utf-8 to cp1252//translit if set
407
    if ($::instance_conf->get_datev_export_format eq 'cp1252-translit') {
408

  
409
      my $filename_translit = "EXTF_DATEV_kivitendo_translit" . $self->from->ymd() . '-' . $self->to->ymd() . ".csv";
410
      open my $fh_in,  '<:encoding(UTF-8)',  $self->export_path . '/' . $filename or die "could not open $filename for reading: $!";
411
      open my $fh_out, '>', $self->export_path . '/' . $filename_translit         or die "could not open $filename_translit for writing: $!";
412

  
413
      my $converter = SL::Iconv->new("utf-8", "cp1252//translit");
414

  
415
      print $fh_out $converter->convert($_) while <$fh_in>;
416
      close $fh_in;
417
      close $fh_out;
418

  
419
      unlink $self->export_path . '/' . $filename or warn "Could not unlink $filename: $!";
420
      $filename = $filename_translit;
421
    }
422

  
402 423
    return { download_token => $self->download_token, filenames => $filename };
403 424

  
404 425
  } elsif ($self->exporttype == DATEV_ET_STAMM) {
SL/DATEV/CSV.pm
103 103
                              max_length      => 12,
104 104
                              type            => 'Text',
105 105
                              default         => '',
106
                              input_check     => sub { my ($text) = @_; check_encoding($text); },
106
                              input_check     => sub { return 1 unless $::instance_conf->get_datev_export_format eq 'cp1252';
107
                                                       my ($text) = @_; check_encoding($text); },
108
                              valid_check     => sub { return 1 if     $::instance_conf->get_datev_export_format eq 'cp1252';
109
                                                       my ($text) = @_; check_encoding($text); },
107 110
                              formatter       => sub { my ($input) = @_; return substr($input, 0, 12) },
108 111
                            },
109 112
                            {
......
127 130
                              max_length      => 60,
128 131
                              type            => 'Text',
129 132
                              default         => '',
130
                              input_check     => sub { my ($text) = @_; return 1 unless $text; check_encoding($text);  },
131
                              formatter       => sub { my ($input) = @_; return substr($input, 0, 60) },
133
                              input_check     => sub { return 1 unless $::instance_conf->get_datev_export_format eq 'cp1252';
134
                                                       my ($text) = @_; check_encoding($text); },
135
                              valid_check     => sub { return 1 if     $::instance_conf->get_datev_export_format eq 'cp1252';
136
                                                       my ($text) = @_; check_encoding($text); },
132 137
                            },  # pos 14
133 138
                            {
134 139
                              kivi_datev_name => 'not yet implemented',
SL/DB/MetaSetup/Default.pm
45 45
  datev_check_on_gl_transaction             => { type => 'boolean', default => 'true' },
46 46
  datev_check_on_purchase_invoice           => { type => 'boolean', default => 'true' },
47 47
  datev_check_on_sales_invoice              => { type => 'boolean', default => 'true' },
48
  datev_export_format                       => { type => 'enum', check_in => [ 'cp1252', 'cp1252-translit', 'utf-8' ], db_type => 'datev_export_format_enum', default => 'cp1252-translit' },
48 49
  disabled_price_sources                    => { type => 'array' },
49 50
  doc_delete_printfiles                     => { type => 'boolean', default => 'false' },
50 51
  doc_files                                 => { type => 'boolean', default => 'false' },
locale/de/all
844 844
  'DATEV - Export Assistent'    => 'DATEV-Exportassistent',
845 845
  'DATEV Angaben'               => 'DATEV-Angaben',
846 846
  'DATEV Export'                => 'DATEV-Export',
847
  'DATEV check configuration'   => 'Einstellungen für DATEV-Prüfung',
848 847
  'DATEV check returned errors:' => 'Die DATEV Prüfung dieser Buchung ergab Fehler:',
848
  'DATEV configuration'         => 'Einstellungen für DATEV',
849
  'DATEV expects the encoding to be Western Europe conform (LATIN-1, cp1252). By setting this to "Strict and halt" the DATEV export halts with a error if there is a single character in "Posting Text" which is not LATIN-1 encodeable. By setting this to "Strict but replace" kivitendo will replace the character with a similar one and the export will simply warn about those fields. By setting this to relaxed (UTF-8) the DATEV export encoding will be in kivitendo (UTF-8) encoded and the external import program has to handle this (this may work for DATEV deriviates or future versions of DATEV). Background details: For example turkish characters (Ç) are not valid cp1252 charactes and armenian characters like "Գեղարդ" are probably not replaceable in cp1252' => 'DATEV erwartet westeuropäische Zeichenkodierung (LATIN-1, cp1252). Die Einstellung "Strikt und Abbruch" erlaubt keine nicht kodiebaren Zeichen im DATEV-Export und bricht diesen mit einer Fehlermeldung ab. Die Einstellung "Strikt mit Ersetzungen" versucht ähnliche Zeichen (bspw. c statt ć) zu verwenden und gibt zusätzlich eine Warnung beim DATEV-Expport aus. Die Einstellung "Lax (UTF-8)" ignoriert diese Anforderung und übergibt die Daten im kivitendo-konformen UTF-8 Format. Letzteres kann für zukünftige DATEV-Version oder DATEV-kompatible Alternativen interessant sein. Hintergrund-Info: Beispielsweise sind schon türkische Zeichen (Ç) nicht mehr im westeuropäischen Zeichensätze enthalten und armenische Zeiche wie "Գեղարդ" könnnen sicherlich überhaupt nicht mit Zeichen in cp1252 ersetzt werden.',
849 850
  'DATEX - Export Assistent'    => 'DATEV-Exportassistent',
850 851
  'DELETED'                     => 'Gelöscht',
851 852
  'DFV-Kennzeichen'             => 'DFV-Kennzeichen',
......
882 883
  'Date missing!'               => 'Datum fehlt!',
883 884
  'Date the payment is due in full' => 'Das Datum, bis die Rechnung in voller Höhe bezahlt werden muss',
884 885
  'Date the payment is due with discount' => 'Das Datum, bis die Rechnung unter Abzug von Skonto bezahlt werden kann',
886
  'Datev export encoding'       => 'DATEV-Export Kodierung',
885 887
  'Datevautomatik'              => 'Datev-Automatik',
886 888
  'Datum von'                   => 'Datum von',
887 889
  'Deactivate by default'       => 'Deaktiviert als Voreinstellung',
......
2530 2532
  'Reference / Invoice Number'  => 'Referenz / Rechnungsnummer',
2531 2533
  'Reference day'               => 'Referenztag',
2532 2534
  'Reference missing!'          => 'Referenz fehlt!',
2535
  'Relaxed (UTF-8)'             => 'Lax (UTF-8)',
2533 2536
  'Release From Stock'          => 'Lagerausgang',
2534 2537
  'Remaining'                   => 'Rest',
2535 2538
  'Remaining Amount'            => 'abzurechnender Betrag',
......
2991 2994
  'Storno (one letter abbreviation)' => 'S',
2992 2995
  'Storno Invoice'              => 'Stornorechnung',
2993 2996
  'Street'                      => 'Straße',
2997
  'Strict and halt'             => 'Strikt und Abbruch',
2998
  'Strict but replace'          => 'Strikt mit Ersetzungen',
2994 2999
  'Style the picture with the following CSS code' => 'Bildeigenschaft mit folgendem CSS-Style versehen',
2995 3000
  'Stylesheet'                  => 'Stilvorlage',
2996 3001
  'Sub function blocks'         => 'Unterfunktionsblöcke',
sql/Pg-upgrade2/datev_export_format.sql
1
-- @tag: datev_export_format
2
-- @description: Setzt die ausgehende Formatierung des DATEV-Exports
3
-- @depends: release_3_5_1
4

  
5
CREATE TYPE datev_export_format_enum AS ENUM ('cp1252', 'cp1252-translit', 'utf-8');
6

  
7
ALTER TABLE defaults ADD COLUMN datev_export_format datev_export_format_enum default 'cp1252-translit';
8

  
templates/webpages/client_config/_datev_check_configuration.html
29 29
   <td>[% L.yes_no_tag('defaults.datev_check_on_gl_transaction', SELF.defaults.datev_check_on_gl_transaction) %]</td>
30 30
   <td>[% LxERP.t8('Perform check when a gl transaction is posted?') %]</td>
31 31
  </tr>
32
  <tr>
33
   <td align="right">[% LxERP.t8('Datev export encoding') %]</td>
34
   <td>[% L.select_tag('defaults.datev_export_format', [ [ 'cp1252', LxERP.t8('Strict and halt') ],[ 'cp1252-translit', LxERP.t8('Strict but replace') ],[ 'utf-8', LxERP.t8('Relaxed (UTF-8)') ]  ], default=SELF.defaults.datev_export_format) %]
35
   <td>[% LxERP.t8('DATEV expects the encoding to be Western Europe conform (LATIN-1, cp1252). By setting this to "Strict and halt" the DATEV export halts with a error if there is a single character in "Posting Text" which is not LATIN-1 encodeable. By setting this to "Strict but replace" kivitendo will replace the character with a similar one and the export will simply warn about those fields. By setting this to relaxed (UTF-8) the DATEV export encoding will be in kivitendo (UTF-8) encoded and the external import program has to handle this (this may work for DATEV deriviates or future versions of DATEV). Background details: For example turkish characters (Ç) are not valid cp1252 charactes and armenian characters like "Գեղարդ" are probably not replaceable in cp1252') %]</td>
36
  </tr>
32 37
 </table>
33 38
</div>
templates/webpages/client_config/form.html
84 84
   <li><a href="#default_accounts">[% LxERP.t8('Default Accounts') %]</a></li>
85 85
   <li><a href="#posting_configuration">[% LxERP.t8('Posting Configuration') %]</a></li>
86 86
   [% IF FORM.feature_datev %]
87
     <li><a href="#datev_check_configuration">[% LxERP.t8('DATEV check configuration') %]</a></li>
87
     <li><a href="#datev_check_configuration">[% LxERP.t8('DATEV configuration') %]</a></li>
88 88
   [% END %]
89 89
   <li><a href="#orders_deleteable">[% LxERP.t8('Orders / Delivery Orders deleteable') %]</a></li>
90 90
[%- IF INSTANCE_CONF.get_doc_storage %]

Auch abrufbar als: Unified diff