Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 631b4c04

Von Sven Schöling vor mehr als 12 Jahren hinzugefügt

  • ID 631b4c042a087595af1ee3af1fee4dc4dc2470ea
  • Vorgänger 71180454
  • Nachfolger 7e7a1369

DATEV Export modular gekapselt.

Unterschiede anzeigen:

SL/DATEV.pm
24 24
# Datev export module
25 25
#======================================================================
26 26

  
27
package DATEV;
27
package SL::DATEV;
28 28

  
29 29
use utf8;
30 30
use strict;
......
34 34
use SL::Taxkeys;
35 35

  
36 36
use Data::Dumper;
37
use DateTime;
38
use Exporter qw(import);
37 39
use File::Path;
38
use List::Util qw(max);
40
use List::Util qw(max sum);
39 41
use Time::HiRes qw(gettimeofday);
40 42

  
43
{
44
  my $i = 0;
45
  use constant {
46
    DATEV_ET_BUCHUNGEN => $i++,
47
    DATEV_ET_STAMM     => $i++,
48

  
49
    DATEV_FORMAT_KNE   => $i++,
50
    DATEV_FORMAT_OBE   => $i++,
51
  };
52
}
53

  
54
my @export_constants = qw(DATEV_ET_BUCHUNGEN DATEV_ET_STAMM DATEV_FORMAT_KNE DATEV_FORMAT_OBE);
55
our @EXPORT_OK = (@export_constants);
56
our %EXPORT_TAGS = (CONSTANTS => [ @export_constants ]);
57

  
58

  
59
sub new {
60
  my $class = shift;
61
  my %data  = @_;
62

  
63
  my $obj = bless {}, $class;
64

  
65
  $obj->$_($data{$_}) for keys %data;
66

  
67
  $obj;
68
}
69

  
70
sub exporttype {
71
  my $self = shift;
72
  $self->{exporttype} = $_[0] if @_;
73
  return $self->{exporttype};
74
}
75

  
76
sub has_exporttype {
77
  defined $_[0]->{exporttype};
78
}
79

  
80
sub format {
81
  my $self = shift;
82
  $self->{format} = $_[0] if @_;
83
  return $self->{format};
84
}
85

  
86
sub has_format {
87
  defined $_[0]->{format};
88
}
89

  
41 90
sub _get_export_path {
42 91
  $main::lxdebug->enter_sub();
43 92

  
44 93
  my ($a, $b) = gettimeofday();
45
  my $path    = get_path_for_download_token("${a}-${b}-${$}");
94
  my $path    = _get_path_for_download_token("${a}-${b}-${$}");
46 95

  
47 96
  mkpath($path) unless (-d $path);
48 97

  
......
51 100
  return $path;
52 101
}
53 102

  
54
sub get_path_for_download_token {
103
sub _get_path_for_download_token {
55 104
  $main::lxdebug->enter_sub();
56 105

  
57
  my $token = shift;
106
  my $token = shift || '';
58 107
  my $path;
59 108

  
60 109
  if ($token =~ m|^(\d+)-(\d+)-(\d+)$|) {
61
    $path = $::lx_office_conf{paths}->{userspath} . "/datev-export-${1}-${2}-${3}";
110
    $path = $::lx_office_conf{paths}->{userspath} . "/datev-export-${1}-${2}-${3}/";
62 111
  }
63 112

  
64 113
  $main::lxdebug->leave_sub();
......
66 115
  return $path;
67 116
}
68 117

  
69
sub get_download_token_for_path {
118
sub _get_download_token_for_path {
70 119
  $main::lxdebug->enter_sub();
71 120

  
72 121
  my $path = shift;
......
81 130
  return $token;
82 131
}
83 132

  
133
sub download_token {
134
  my $self = shift;
135
  $self->{download_token} = $_[0] if @_;
136
  return $self->{download_token} ||= _get_download_token_for_path($self->export_path);
137
}
138

  
139
sub export_path {
140
  my ($self) = @_;
141

  
142
  return  $self->{export_path} ||= _get_path_for_download_token($self->{download_token}) || _get_export_path();
143
}
144

  
145
sub add_filenames {
146
  my $self = shift;
147
  push @{ $self->{filenames} ||= [] }, @_;
148
}
149

  
150
sub filenames {
151
  return @{ $_[0]{filenames} || [] };
152
}
153

  
154
sub add_error {
155
  my $self = shift;
156
  push @{ $self->{errors} ||= [] }, @_;
157
}
158

  
159
sub errors {
160
  return @{ $_[0]{errors} || [] };
161
}
162

  
163
sub add_net_gross_differences {
164
  my $self = shift;
165
  push @{ $self->{net_gross_differences} ||= [] }, @_;
166
}
167

  
168
sub net_gross_differences {
169
  return @{ $_[0]{net_gross_differences} || [] };
170
}
171

  
172
sub sum_net_gross_differences {
173
  return sum $_[0]->net_gross_differences;
174
}
175

  
176
sub from {
177
 my $self = shift;
178

  
179
 if (@_) {
180
   $self->{from} = $_[0];
181
 }
182

  
183
 return $self->{from};
184
}
185

  
186
sub to {
187
 my $self = shift;
188

  
189
 if (@_) {
190
   $self->{to} = $_[0];
191
 }
192

  
193
 return $self->{to};
194
}
195

  
196
sub accnofrom {
197
 my $self = shift;
198

  
199
 if (@_) {
200
   $self->{accnofrom} = $_[0];
201
 }
202

  
203
 return $self->{accnofrom};
204
}
205

  
206
sub accnoto {
207
 my $self = shift;
208

  
209
 if (@_) {
210
   $self->{accnoto} = $_[0];
211
 }
212

  
213
 return $self->{accnoto};
214
}
215

  
216

  
217
sub dbh {
218
  my $self = shift;
219

  
220
  if (@_) {
221
    $self->{dbh} = $_[0];
222
    $self->{provided_dbh} = 1;
223
  }
224

  
225
  $self->{dbh} ||= $::form->get_standard_dbh;
226
}
227

  
228
sub provided_dbh {
229
  $_[0]{provided_dbh};
230
}
231

  
84 232
sub clean_temporary_directories {
85
  $main::lxdebug->enter_sub();
233
  $::lxdebug->enter_sub;
86 234

  
87 235
  foreach my $path (glob($::lx_office_conf{paths}->{userspath} . "/datev-export-*")) {
88
    next unless (-d $path);
236
    next unless -d $path;
89 237

  
90 238
    my $mtime = (stat($path))[9];
91 239
    next if ((time() - $mtime) < 8 * 60 * 60);
......
93 241
    rmtree $path;
94 242
  }
95 243

  
96
  $main::lxdebug->leave_sub();
244
  $::lxdebug->leave_sub;
97 245
}
98 246

  
99 247
sub _fill {
......
120 268
}
121 269

  
122 270
sub get_datev_stamm {
123
  $main::lxdebug->enter_sub();
124

  
125
  my ($self, $myconfig, $form) = @_;
271
  return $_[0]{stamm} ||= selectfirst_hashref_query($::form, $_[0]->dbh, 'SELECT * FROM datev');
272
}
126 273

  
127
  # connect to database
128
  my $dbh = $form->dbconnect($myconfig);
274
sub save_datev_stamm {
275
  my ($self, $data) = @_;
129 276

  
130
  my $query = qq|SELECT * FROM datev|;
131
  my $sth   = $dbh->prepare($query);
132
  $sth->execute || $form->dberror($query);
277
  do_query($::form, $self->dbh, 'DELETE FROM datev');
133 278

  
134
  my $ref = $sth->fetchrow_hashref("NAME_lc");
279
  my @columns = qw(beraternr beratername dfvkz mandantennr datentraegernr abrechnungsnr);
135 280

  
136
  map { $form->{$_} = $ref->{$_} } keys %$ref;
281
  my $query = "INSERT INTO datev (" . join(', ', @columns) . ") VALUES (" . join(', ', ('?') x @columns) . ")";
282
  do_query($::form, $self->dbh, $query, map { $data->{$_} } @columns);
137 283

  
138
  $sth->finish;
139
  $dbh->disconnect;
140
  $main::lxdebug->leave_sub();
284
  $self->dbh->commit unless $self->provided_dbh;
141 285
}
142 286

  
143
sub save_datev_stamm {
144
  $main::lxdebug->enter_sub();
287
sub export {
288
  my ($self) = @_;
289
  my $result;
145 290

  
146
  my ($self, $myconfig, $form) = @_;
147

  
148
  # connect to database
149
  my $dbh = $form->dbconnect_noauto($myconfig);
150

  
151
  my $query = qq|DELETE FROM datev|;
152
  $dbh->do($query) || $form->dberror($query);
153

  
154
  $query = qq|INSERT INTO datev
155
              (beraternr, beratername, dfvkz, mandantennr, datentraegernr, abrechnungsnr) VALUES
156
              (|
157
    . $dbh->quote($form->{beraternr}) . qq|,|
158
    . $dbh->quote($form->{beratername}) . qq|,|
159
    . $dbh->quote($form->{dfvkz}) . qq|,
160
              |
161
    . $dbh->quote($form->{mandantennr}) . qq|,|
162
    . $dbh->quote($form->{datentraegernr}) . qq|,|
163
    . $dbh->quote($form->{abrechnungsnr}) . qq|)|;
164
  my $sth = $dbh->prepare($query);
165
  $sth->execute || $form->dberror($query);
166
  $sth->finish;
291
  die 'no format set!' unless $self->has_format;
167 292

  
168
  $dbh->commit;
169
  $dbh->disconnect;
170
  $main::lxdebug->leave_sub();
293
  if ($self->format == DATEV_FORMAT_KNE) {
294
    $result = $self->kne_export;
295
  } elsif ($self->format == DATEV_FORMAT_OBE) {
296
    $result = $self->obe_export;
297
  } else {
298
    die 'unrecognized export format';
299
  }
300

  
301
  return $result;
171 302
}
172 303

  
173 304
sub kne_export {
174
  $main::lxdebug->enter_sub();
175

  
176
  my ($self, $myconfig, $form) = @_;
305
  my ($self) = @_;
177 306
  my $result;
178 307

  
179
  if ($form->{exporttype} == 0) {
180
    $result = kne_buchungsexport($myconfig, $form);
308
  die 'no exporttype set!' unless $self->has_exporttype;
309

  
310
  if ($self->exporttype == DATEV_ET_BUCHUNGEN) {
311
    $result = $self->kne_buchungsexport;
312
  } elsif ($self->exporttype == DATEV_ET_STAMM) {
313
    $result = $self->kne_stammdatenexport;
181 314
  } else {
182
    $result = kne_stammdatenexport($myconfig, $form);
315
    die 'unrecognized exporttype';
183 316
  }
184 317

  
185
  $main::lxdebug->leave_sub();
186

  
187 318
  return $result;
188 319
}
189 320

  
190 321
sub obe_export {
191
  $main::lxdebug->enter_sub();
192

  
193
  my ($self, $myconfig, $form) = @_;
194

  
195
  # connect to database
196
  my $dbh = $form->dbconnect_noauto($myconfig);
197
  $dbh->commit;
198
  $dbh->disconnect;
199
  $main::lxdebug->leave_sub();
322
  die 'not yet implemented';
200 323
}
201 324

  
202
sub get_dates {
203
  $main::lxdebug->enter_sub();
204

  
205
  my ($zeitraum, $monat, $quartal, $transdatefrom, $transdateto) = @_;
206
  my ($fromto, $jahr, $leap);
207

  
208
  my $form = $main::form;
209

  
210
  $fromto = "transdate >= ";
211

  
212
  my @a = localtime;
213
  $a[5] += 1900;
214
  $jahr = $a[5];
215
  if ($zeitraum eq "monat") {
216
  SWITCH: {
217
      $monat eq "1" && do {
218
        $form->{fromdate} = "1.1.$jahr";
219
        $form->{todate}   = "31.1.$jahr";
220
        last SWITCH;
221
      };
222
      $monat eq "2" && do {
223
        $form->{fromdate} = "1.2.$jahr";
224

  
225
        #this works from 1901 to 2099, 1900 and 2100 fail.
226
        $leap = ($jahr % 4 == 0) ? "29" : "28";
227
        $form->{todate} = "$leap.2.$jahr";
228
        last SWITCH;
229
      };
230
      $monat eq "3" && do {
231
        $form->{fromdate} = "1.3.$jahr";
232
        $form->{todate}   = "31.3.$jahr";
233
        last SWITCH;
234
      };
235
      $monat eq "4" && do {
236
        $form->{fromdate} = "1.4.$jahr";
237
        $form->{todate}   = "30.4.$jahr";
238
        last SWITCH;
239
      };
240
      $monat eq "5" && do {
241
        $form->{fromdate} = "1.5.$jahr";
242
        $form->{todate}   = "31.5.$jahr";
243
        last SWITCH;
244
      };
245
      $monat eq "6" && do {
246
        $form->{fromdate} = "1.6.$jahr";
247
        $form->{todate}   = "30.6.$jahr";
248
        last SWITCH;
249
      };
250
      $monat eq "7" && do {
251
        $form->{fromdate} = "1.7.$jahr";
252
        $form->{todate}   = "31.7.$jahr";
253
        last SWITCH;
254
      };
255
      $monat eq "8" && do {
256
        $form->{fromdate} = "1.8.$jahr";
257
        $form->{todate}   = "31.8.$jahr";
258
        last SWITCH;
259
      };
260
      $monat eq "9" && do {
261
        $form->{fromdate} = "1.9.$jahr";
262
        $form->{todate}   = "30.9.$jahr";
263
        last SWITCH;
264
      };
265
      $monat eq "10" && do {
266
        $form->{fromdate} = "1.10.$jahr";
267
        $form->{todate}   = "31.10.$jahr";
268
        last SWITCH;
269
      };
270
      $monat eq "11" && do {
271
        $form->{fromdate} = "1.11.$jahr";
272
        $form->{todate}   = "30.11.$jahr";
273
        last SWITCH;
274
      };
275
      $monat eq "12" && do {
276
        $form->{fromdate} = "1.12.$jahr";
277
        $form->{todate}   = "31.12.$jahr";
278
        last SWITCH;
279
      };
280
    }
281
    $fromto .=
282
      "'" . $form->{fromdate} . "' and transdate <= '" . $form->{todate} . "'";
283
  }
284

  
285
  elsif ($zeitraum eq "quartal") {
286
    if ($quartal == 1) {
287
      $fromto .=
288
        "'01.01." . $jahr . "' and transdate <= '31.03." . $jahr . "'";
289
    } elsif ($quartal == 2) {
290
      $fromto .=
291
        "'01.04." . $jahr . "' and transdate <= '30.06." . $jahr . "'";
292
    } elsif ($quartal == 3) {
293
      $fromto .=
294
        "'01.07." . $jahr . "' and transdate <= '30.09." . $jahr . "'";
295
    } elsif ($quartal == 4) {
296
      $fromto .=
297
        "'01.10." . $jahr . "' and transdate <= '31.12." . $jahr . "'";
298
    }
299
  }
300

  
301
  elsif ($zeitraum eq "zeit") {
302
    $fromto            .= "'" . $transdatefrom . "' and transdate <= '" . $transdateto . "'";
303
    my ($yy, $mm, $dd)  = $main::locale->parse_date(\%main::myconfig, $transdatefrom);
304
    $jahr               = $yy;
305
  }
325
sub fromto {
326
  my ($self) = @_;
306 327

  
307
  $main::lxdebug->leave_sub();
328
  return unless $self->from && $self->to;
308 329

  
309
  return ($fromto, $jahr);
330
  return "transdate >= '" . $self->from->to_lxoffice . "' and transdate <= '" . $self->to->to_lxoffice . "'";
310 331
}
311 332

  
312 333
sub _sign {
313
  my $value = shift;
314

  
315
  return $value < 0 ? -1
316
    :    $value > 0 ?  1
317
    :                  0;
334
  $_[0] <=> 0;
318 335
}
319 336

  
320 337
sub _get_transactions {
321 338
  $main::lxdebug->enter_sub();
322

  
339
  my $self     = shift;
323 340
  my $fromto   =  shift;
341
  my $progress_callback = shift || sub {};
324 342

  
325
  my $myconfig =  \%main::myconfig;
326 343
  my $form     =  $main::form;
327 344

  
328
  my $dbh      =  $form->get_standard_dbh($myconfig);
329

  
330 345
  my ($notsplitindex);
331
  my @errors   = ();
332

  
333
  $form->{net_gross_differences}     = [];
334
  $form->{sum_net_gross_differences} = 0;
335 346

  
336 347
  $fromto      =~ s/transdate/ac\.transdate/g;
337 348

  
338 349
  my $taxkeys  = Taxkeys->new();
339 350
  my $filter   = '';            # Useful for debugging purposes
340 351

  
341
  my %all_taxchart_ids = selectall_as_map($form, $dbh, qq|SELECT DISTINCT chart_id, TRUE AS is_set FROM tax|, 'chart_id', 'is_set');
352
  my %all_taxchart_ids = selectall_as_map($form, $self->dbh, qq|SELECT DISTINCT chart_id, TRUE AS is_set FROM tax|, 'chart_id', 'is_set');
342 353

  
343 354
  my $query    =
344 355
    qq|SELECT ac.acc_trans_id, ac.transdate, ac.trans_id,ar.id, ac.amount, ac.taxkey,
......
385 396

  
386 397
       ORDER BY trans_id, acc_trans_id|;
387 398

  
388
  my $sth = prepare_execute_query($form, $dbh, $query);
389
  $form->{DATEV} = [];
399
  my $sth = prepare_execute_query($form, $self->dbh, $query);
400
  $self->{DATEV} = [];
390 401

  
391 402
  my $counter = 0;
392 403
  while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
393 404
    $counter++;
394 405
    if (($counter % 500) == 0) {
395
      print("$counter ");
406
      $progress_callback->($counter);
396 407
    }
397 408

  
398 409
    my $trans    = [ $ref ];
......
406 417
      last unless ($ref2);
407 418

  
408 419
      if ($ref2->{trans_id} != $trans->[0]->{trans_id}) {
409
        $form->error("Unbalanced ledger! old trans_id " . $trans->[0]->{trans_id} . " new trans_id " . $ref2->{trans_id} . " count $count");
410
        ::end_of_request();
420
        $self->add_error("Unbalanced ledger! old trans_id " . $trans->[0]->{trans_id} . " new trans_id " . $ref2->{trans_id} . " count $count");
421
        return;
411 422
      }
412 423

  
413 424
      push @{ $trans }, $ref2;
......
437 448
    my %taxid_taxkeys = ();
438 449
    my $absumsatz     = 0;
439 450
    if (scalar(@{$trans}) <= 2) {
440
      push @{ $form->{DATEV} }, $trans;
451
      push @{ $self->{DATEV} }, $trans;
441 452
      next;
442 453
    }
443 454

  
......
471 482
        $new_trans{'umsatz'}      = abs($trans->[$j]->{'amount'}) * $ml;
472 483
        $trans->[$j]->{'umsatz'}  = abs($trans->[$j]->{'amount'}) * $ml;
473 484

  
474
        push @{ $form->{DATEV} }, [ \%new_trans, $trans->[$j] ];
485
        push @{ $self->{DATEV} }, [ \%new_trans, $trans->[$j] ];
475 486

  
476 487
      } elsif (($j != $notsplitindex) && !$trans->[$j]->{is_tax}) {
477 488
        my %tax_info = $taxkeys->get_full_tax_info('transdate' => $trans->[$j]->{transdate});
......
500 511
          $absumsatz               -= $rounded;
501 512
        }
502 513

  
503
        push @{ $form->{DATEV} }, [ \%new_trans, $trans->[$j] ];
504
        push @taxed, $form->{DATEV}->[-1];
514
        push @{ $self->{DATEV} }, [ \%new_trans, $trans->[$j] ];
515
        push @taxed, $self->{DATEV}->[-1];
505 516
      }
506 517
    }
507 518

  
......
545 556

  
546 557
    $absumsatz = $form->round_amount($absumsatz, 2);
547 558
    if (abs($absumsatz) >= (0.01 * (1 + scalar @taxed))) {
548
      push @errors, "Datev-Export fehlgeschlagen! Bei Transaktion $trans->[0]->{trans_id} ($absumsatz)\n";
559
      $self->add_error("Datev-Export fehlgeschlagen! Bei Transaktion $trans->[0]->{trans_id} ($absumsatz)");
549 560

  
550 561
    } elsif (abs($absumsatz) >= 0.01) {
551
      push @{ $form->{net_gross_differences} }, $absumsatz;
552
      $form->{sum_net_gross_differences} += $absumsatz;
562
      $self->add_net_gross_differences($absumsatz);
553 563
    }
554 564
  }
555 565

  
556 566
  $sth->finish();
557 567

  
558
  $form->error(join("<br>\n", @errors)) if (@errors);
559

  
560
  $main::lxdebug->leave_sub();
568
  $::lxdebug->leave_sub;
561 569
}
562 570

  
563 571
sub make_kne_data_header {
564 572
  $main::lxdebug->enter_sub();
565 573

  
566
  my ($myconfig, $form, $fromto, $start_jahr) = @_;
574
  my ($self, $form) = @_;
567 575
  my ($primanota);
568 576

  
569
  my $jahr = $start_jahr;
570
  if (!$jahr) {
571
    my @a = localtime;
572
    $jahr = $a[5];
573
  }
577
  my $stamm = $self->get_datev_stamm;
578

  
579
  my $jahr = $self->from ? $self->from->year : DateTime->today->year;
574 580

  
575 581
  #Header
576 582
  my $header  = "\x1D\x181";
577
  $header    .= _fill($form->{datentraegernr}, 3, ' ', 'left');
578
  $header    .= ($fromto) ? "11" : "13"; # Anwendungsnummer
579
  $header    .= _fill($form->{dfvkz}, 2, '0');
580
  $header    .= _fill($form->{beraternr}, 7, '0');
581
  $header    .= _fill($form->{mandantennr}, 5, '0');
582
  $header    .= _fill($form->{abrechnungsnr} . $jahr, 6, '0');
583

  
584
  $fromto         =~ s/transdate|>=|and|\'|<=//g;
585
  my ($from, $to) =  split /   /, $fromto;
586
  $from           =~ s/ //g;
587
  $to             =~ s/ //g;
588

  
589
  if ($from ne "") {
590
    my ($fday, $fmonth, $fyear) = split(/\./, $from);
591
    if (length($fmonth) < 2) {
592
      $fmonth = "0" . $fmonth;
593
    }
594
    if (length($fday) < 2) {
595
      $fday = "0" . $fday;
596
    }
597
    $from = $fday . $fmonth . substr($fyear, -2, 2);
598
  } else {
599
    $from = "";
600
  }
583
  $header    .= _fill($stamm->{datentraegernr}, 3, ' ', 'left');
584
  $header    .= ($self->fromto) ? "11" : "13"; # Anwendungsnummer
585
  $header    .= _fill($stamm->{dfvkz}, 2, '0');
586
  $header    .= _fill($stamm->{beraternr}, 7, '0');
587
  $header    .= _fill($stamm->{mandantennr}, 5, '0');
588
  $header    .= _fill($stamm->{abrechnungsnr} . $jahr, 6, '0');
601 589

  
602
  $header .= $from;
590
  $header .= $self->from ? $self->from->strftime('%d%m%y') : '';
591
  $header .= $self->to   ? $self->to->strftime('%d%m%y')   : '';
603 592

  
604
  if ($to ne "") {
605
    my ($tday, $tmonth, $tyear) = split(/\./, $to);
606
    if (length($tmonth) < 2) {
607
      $tmonth = "0" . $tmonth;
608
    }
609
    if (length($tday) < 2) {
610
      $tday = "0" . $tday;
611
    }
612
    $to = $tday . $tmonth . substr($tyear, -2, 2);
613
  } else {
614
    $to = "";
615
  }
616
  $header .= $to;
617

  
618
  if ($fromto ne "") {
593
  if ($self->fromto) {
619 594
    $primanota = "001";
620 595
    $header .= $primanota;
621 596
  }
622 597

  
623
  $header .= _fill($form->{passwort}, 4, '0');
598
  $header .= _fill($stamm->{passwort}, 4, '0');
624 599
  $header .= " " x 16;       # Anwendungsinfo
625 600
  $header .= " " x 16;       # Inputinfo
626 601
  $header .= "\x79";
627 602

  
628 603
  #Versionssatz
629
  my $versionssatz  = $form->{exporttype} == 0 ? "\xB5" . "1," : "\xB6" . "1,";
604
  my $versionssatz  = $self->exporttype == DATEV_ET_BUCHUNGEN ? "\xB5" . "1," : "\xB6" . "1,";
630 605

  
631
  my $dbh           = $form->get_standard_dbh($myconfig);
632 606
  my $query         = qq|SELECT accno FROM chart LIMIT 1|;
633
  my $ref           = selectfirst_hashref_query($form, $dbh, $query);
607
  my $ref           = selectfirst_hashref_query($form, $self->dbh, $query);
634 608

  
635 609
  $versionssatz    .= length $ref->{accno};
636 610
  $versionssatz    .= ",";
......
683 657
sub make_ed_versionset {
684 658
  $main::lxdebug->enter_sub();
685 659

  
686
  my ($header, $filename, $blockcount, $fromto) = @_;
660
  my ($self, $header, $filename, $blockcount) = @_;
687 661

  
688 662
  my $versionset  = "V" . substr($filename, 2, 5);
689 663
  $versionset    .= substr($header, 6, 22);
690 664

  
691
  if ($fromto ne "") {
665
  if ($self->fromto) {
692 666
    $versionset .= "0000" . substr($header, 28, 19);
693 667
  } else {
694 668
    my $datum = " " x 16;
......
709 683
sub make_ev_header {
710 684
  $main::lxdebug->enter_sub();
711 685

  
712
  my ($form, $fileno) = @_;
686
  my ($self, $form, $fileno) = @_;
687

  
688
  my $stamm = $self->get_datev_stamm;
713 689

  
714
  my $ev_header  = _fill($form->{datentraegernr}, 3, ' ', 'left');
690
  my $ev_header  = _fill($stamm->{datentraegernr}, 3, ' ', 'left');
715 691
  $ev_header    .= "   ";
716
  $ev_header    .= _fill($form->{beraternr}, 7, ' ', 'left');
717
  $ev_header    .= _fill($form->{beratername}, 9, ' ', 'left');
692
  $ev_header    .= _fill($stamm->{beraternr}, 7, ' ', 'left');
693
  $ev_header    .= _fill($stamm->{beratername}, 9, ' ', 'left');
718 694
  $ev_header    .= " ";
719 695
  $ev_header    .= (_fill($fileno, 5, '0')) x 2;
720 696
  $ev_header    .= " " x 95;
......
727 703
sub kne_buchungsexport {
728 704
  $main::lxdebug->enter_sub();
729 705

  
730
  my ($myconfig, $form) = @_;
706
  my ($self) = @_;
707

  
708
  my $form = $::form;
731 709

  
732 710
  my @filenames;
733 711

  
734
  my $export_path = _get_export_path() . "/";
735 712
  my $filename    = "ED00000";
736 713
  my $evfile      = "EV01";
737 714
  my @ed_versionset;
738 715
  my $fileno = 0;
739 716

  
740
  $form->header;
741
  print qq|
742
  <html>
743
  <body>Export in Bearbeitung<br>
744
  Buchungss&auml;tze verarbeitet:
745
|;
746

  
747
  my ($fromto, $start_jahr) =
748
    &get_dates($form->{zeitraum}, $form->{monat},
749
               $form->{quartal},  $form->{transdatefrom},
750
               $form->{transdateto});
751
  _get_transactions($fromto);
717
  my $fromto = $self->fromto;
718

  
719
  $self->_get_transactions($fromto);
720

  
721
  return if $self->errors;
722

  
752 723
  my $counter = 0;
753
  print qq|<br>2. Durchlauf:|;
754
  while (scalar(@{ $form->{DATEV} })) {
724

  
725
  while (scalar(@{ $self->{DATEV} || [] })) {
755 726
    my $umsatzsumme = 0;
756 727
    $filename++;
757
    my $ed_filename = $export_path . $filename;
728
    my $ed_filename = $self->export_path . $filename;
758 729
    push(@filenames, $filename);
759
    my $header = &make_kne_data_header($myconfig, $form, $fromto, $start_jahr);
730
    my $header = $self->make_kne_data_header($form);
760 731

  
761 732
    my $kne_file = SL::DATEV::KNEFile->new();
762 733
    $kne_file->add_block($header);
763 734

  
764
    while (scalar(@{ $form->{DATEV} }) > 0) {
765
      my $transaction = shift @{ $form->{DATEV} };
735
    while (scalar(@{ $self->{DATEV} }) > 0) {
736
      my $transaction = shift @{ $self->{DATEV} };
766 737
      my $trans_lines = scalar(@{$transaction});
767 738
      $counter++;
768
      if (($counter % 500) == 0) {
769
        print("$counter ");
770
      }
771 739

  
772 740
      my $umsatz         = 0;
773 741
      my $gegenkonto     = "";
......
885 853
    print(ED $kne_file->get_data());
886 854
    close(ED);
887 855

  
888
    $ed_versionset[$fileno] = &make_ed_versionset($header, $filename, $kne_file->get_block_count(), $fromto);
856
    $ed_versionset[$fileno] = $self->make_ed_versionset($header, $filename, $kne_file->get_block_count());
889 857
    $fileno++;
890 858
  }
891 859

  
892 860
  #Make EV Verwaltungsdatei
893
  my $ev_header = &make_ev_header($form, $fileno);
894
  my $ev_filename = $export_path . $evfile;
861
  my $ev_header = $self->make_ev_header($form, $fileno);
862
  my $ev_filename = $self->export_path . $evfile;
895 863
  push(@filenames, $evfile);
896 864
  open(EV, ">", $ev_filename) or die "can't open outputfile: EV01\n";
897 865
  print(EV $ev_header);
......
900 868
    print(EV $ed_versionset[$file]);
901 869
  }
902 870
  close(EV);
903
  print qq|<br>Done. <br>
904
|;
905 871
  ###
872

  
873
  $self->add_filenames(@filenames);
874

  
906 875
  $main::lxdebug->leave_sub();
907 876

  
908
  return { 'download_token' => get_download_token_for_path($export_path), 'filenames' => \@filenames };
877
  return { 'download_token' => $self->download_token, 'filenames' => \@filenames };
909 878
}
910 879

  
911 880
sub kne_stammdatenexport {
912 881
  $main::lxdebug->enter_sub();
913 882

  
914
  my ($myconfig, $form) = @_;
915
  $form->{abrechnungsnr} = "99";
883
  my ($self) = @_;
884
  my $form = $::form;
916 885

  
917
  $form->header;
918
  print qq|
919
  <html>
920
  <body>Export in Bearbeitung<br>
921
|;
886
  $self->get_datev_stamm->{abrechnungsnr} = "99";
922 887

  
923 888
  my @filenames;
924 889

  
925
  my $export_path = _get_export_path() . "/";
926 890
  my $filename    = "ED00000";
927 891
  my $evfile      = "EV01";
928 892
  my @ed_versionset;
......
933 897
  my $total_bytes     = 256;
934 898
  my $buchungssatz    = "";
935 899
  $filename++;
936
  my $ed_filename = $export_path . $filename;
900
  my $ed_filename = $self->export_path . $filename;
937 901
  push(@filenames, $filename);
938 902
  open(ED, ">", $ed_filename) or die "can't open outputfile: $!\n";
939
  my $header = &make_kne_data_header($myconfig, $form, "");
903
  my $header = $self->make_kne_data_header($form);
940 904
  $remaining_bytes -= length($header);
941 905

  
942 906
  my $fuellzeichen;
943
  our $fromto;
944

  
945
  # connect to database
946
  my $dbh = $form->dbconnect($myconfig);
947 907

  
948 908
  my (@where, @values) = ((), ());
949
  if ($form->{accnofrom}) {
909
  if ($self->accnofrom) {
950 910
    push @where, 'c.accno >= ?';
951
    push @values, $form->{accnofrom};
911
    push @values, $self->accnofrom;
952 912
  }
953
  if ($form->{accnoto}) {
913
  if ($self->accnoto) {
954 914
    push @where, 'c.accno <= ?';
955
    push @values, $form->{accnoto};
915
    push @values, $self->accnoto;
956 916
  }
957 917

  
958 918
  my $where_str = @where ? ' WHERE ' . join(' AND ', map { "($_)" } @where) : '';
......
962 922
                     $where_str
963 923
                     ORDER BY c.accno|;
964 924

  
965
  my $sth = $dbh->prepare($query);
925
  my $sth = $self->dbh->prepare($query);
966 926
  $sth->execute(@values) || $form->dberror($query);
967 927

  
968 928
  while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
......
1002 962

  
1003 963
  #Make EV Verwaltungsdatei
1004 964
  $ed_versionset[0] =
1005
    &make_ed_versionset($header, $filename, $blockcount, $fromto);
965
    $self->make_ed_versionset($header, $filename, $blockcount);
1006 966

  
1007
  my $ev_header = &make_ev_header($form, $fileno);
1008
  my $ev_filename = $export_path . $evfile;
967
  my $ev_header = $self->make_ev_header($form, $fileno);
968
  my $ev_filename = $self->export_path . $evfile;
1009 969
  push(@filenames, $evfile);
1010 970
  open(EV, ">", $ev_filename) or die "can't open outputfile: EV01\n";
1011 971
  print(EV $ev_header);
......
1015 975
  }
1016 976
  close(EV);
1017 977

  
1018
  $dbh->disconnect;
1019
  ###
1020

  
1021
  print qq|<br>Done. <br>
1022
|;
978
  $self->add_filenames(@filenames);
1023 979

  
1024 980
  $main::lxdebug->leave_sub();
1025 981

  
1026
  return { 'download_token' => get_download_token_for_path($export_path), 'filenames' => \@filenames };
982
  return { 'download_token' => $self->download_token, 'filenames' => \@filenames };
983
}
984

  
985
sub DESTROY {
986
  clean_temporary_directories();
1027 987
}
1028 988

  
1029 989
1;
990

  
991
__END__
992

  
993
=encoding utf-8
994

  
995
=head1 NAME
996

  
997
SL::DATEV - Lx-Office DATEV Export module
998

  
999
=head1 SYNOPSIS
1000

  
1001
  use SL::DATEV qw(:CONSTANTS);
1002

  
1003
  my $datev = SL::DATEV->new(
1004
    exporttype => DATEV_ET_BUCHUNGEN,
1005
    format     => DATEV_FORMAT_KNE,
1006
    from       => $startdate,
1007
    to         => $enddate,
1008
  );
1009

  
1010
  my $datev = SL::DATEV->new(
1011
    exporttype => DATEV_ET_STAMM,
1012
    format     => DATEV_FORMAT_KNE,
1013
    accnofrom  => $start_account_number,
1014
    accnoto    => $end_account_number,
1015
  );
1016

  
1017
  # get or set datev stamm
1018
  my $hashref = $datev->get_datev_stamm;
1019
  $datev->save_datev_stamm($hashref);
1020

  
1021
  # manually clean up temporary directories
1022
  $datev->clean_temporary_directories;
1023

  
1024
  # export
1025
  $datev->export;
1026

  
1027
  if ($datev->errors) {
1028
    die join "\n", $datev->error;
1029
  }
1030

  
1031
  # get relevant data for saving the export:
1032
  my $dl_token = $datev->download_token;
1033
  my $path     = $datev->export_path;
1034
  my @files    = $datev->filenames;
1035

  
1036
  # retrieving an export at a later time
1037
  my $datev = SL::DATEV->new(
1038
    download_token => $dl_token_from_user,
1039
  );
1040

  
1041
  my $path     = $datev->export_path;
1042
  my @files    = glob("$path/*");
1043

  
1044
=head1 DESCRIPTION
1045

  
1046
This module implements the DATEV export standard. For usage see above.
1047

  
1048
=head1 FUNCTIONS
1049

  
1050
=over 4
1051

  
1052
=item new PARAMS
1053

  
1054
Generic constructor. See section attributes for information about hat to pass.
1055

  
1056
=item get_datev_stamm
1057

  
1058
Loads DATEV Stammdaten and returns as hashref.
1059

  
1060
=item save_datev_stamm HASHREF
1061

  
1062
Saves DATEV Stammdaten from provided hashref.
1063

  
1064
=item exporttype
1065

  
1066
See L<CONSTANTS> for possible values
1067

  
1068
=item has_exporttype
1069

  
1070
Returns true if an exporttype has been set. Without exporttype most report functions won't work.
1071

  
1072
=item format
1073

  
1074
Specifies the designated format of the export. Currently only KNE export is implemented.
1075

  
1076
See L<CONSTANTS> for possible values
1077

  
1078
=item has_format
1079

  
1080
Returns true if a format has been set. Without format most report functions won't work.
1081

  
1082
=item download_token
1083

  
1084
Returns a download token for this DATEV object.
1085

  
1086
Note: If either a download_token or export_path were set at the creation these are infered, otherwise randomly generated.
1087

  
1088
=item export_path
1089

  
1090
Returns an export_path for this DATEV object.
1091

  
1092
Note: If either a download_token or export_path were set at the creation these are infered, otherwise randomly generated.
1093

  
1094
=item filenames
1095

  
1096
Returns a list of filenames generated by this DATEV object. This only works if th files were generated during it's lifetime, not if the object was created from a download_token.
1097

  
1098
=item net_gross_differences
1099

  
1100
If there were any net gross differences during calculation they will be collected here.
1101

  
1102
=item sum_net_gross_differences
1103

  
1104
Sum of all differences.
1105

  
1106
=item clean_temporary_directories
1107

  
1108
Forces a garbage collection on previous exports which will delete all exports that are older than 8 hours. It will be automatically called on destruction of the object, but is advised to be called manually before delivering results of an export to the user.
1109

  
1110
=item errors
1111

  
1112
Returns a list of errors that occured. If no errors occured, the export was a success.
1113

  
1114
=item export
1115

  
1116
Exports data. You have to have set L<exporttype> and L<format> or an error will
1117
occur. OBE exports are currently not implemented.
1118

  
1119
=back
1120

  
1121
=head1 ATTRIBUTES
1122

  
1123
This is a list of attributes set in either the C<new> or a method of the same name.
1124

  
1125
=over 4
1126

  
1127
=item dbh
1128

  
1129
Set a database handle to use in the process. This allows for an export to be
1130
done on a transaction in progress without committing first.
1131

  
1132
=item exporttype
1133

  
1134
See L<CONSTANTS> for possible values. This MUST be set before export is called.
1135

  
1136
=item format
1137

  
1138
See L<CONSTANTS> for possible values. This MUST be set before export is called.
1139

  
1140
=item download_token
1141

  
1142
Can be set on creation to retrieve a prior export for download.
1143

  
1144
=item from
1145

  
1146
=item to
1147

  
1148
Set boundary dates for the export. Currently thse MUST be set for the export to work.
1149

  
1150
=item accnofrom
1151

  
1152
=item accnoto
1153

  
1154
Set boundary account numbers for the export. Only useful for a stammdaten export.
1155

  
1156
=back
1157

  
1158
=head1 CONSTANTS
1159

  
1160
=head2 Supplied to L<exporttype>
1161

  
1162
=over 4
1163

  
1164
=item DATEV_ET_BUCHUNGEN
1165

  
1166
=item DATEV_ET_STAMM
1167

  
1168
=back
1169

  
1170
=head2 Supplied to L<format>.
1171

  
1172
=over 4
1173

  
1174
=item DATEV_FORMAT_KNE
1175

  
1176
=item DATEV_FORMAT_OBE
1177

  
1178
=back
1179

  
1180
=head1 ERROR HANDLING
1181

  
1182
This module will die in the following cases:
1183

  
1184
=over 4
1185

  
1186
=item *
1187

  
1188
No or unrecognized exporttype or format was provided for an export
1189

  
1190
=item *
1191

  
1192
OBE rxport was called, which is not yet implemented.
1193

  
1194
=item *
1195

  
1196
general I/O errors
1197

  
1198
=back
1199

  
1200
Errors that occur during th actual export will be collected in L<errors>. The following types can occur at the moment:
1201

  
1202
=over 4
1203

  
1204
=item *
1205

  
1206
C<Unbalanced Ledger!>. Exactly that, your ledger is unbalanced. Should never occur.
1207

  
1208
=item *
1209

  
1210
C<Datev-Export fehlgeschlagen! Bei Transaktion %d (%f).>  This error occurs if a
1211
transaction could not be reliably sorted out, or had rounding errors over the acceptable threshold.
1212

  
1213
=back
1214

  
1215
=head1 BUGS AND CAVEATS
1216

  
1217
=over 4
1218

  
1219
=item *
1220

  
1221
Handling of Vollvorlauf is currently not fully implemented. You must provide both from and to to get a working export.
1222

  
1223
=item *
1224

  
1225
OBE export is currently not implemented.
1226

  
1227
=back
1228

  
1229
=head1 TODO
1230

  
1231
- handling of export_path and download token is a bit dodgy, clean that up.
1232

  
1233
=head1 SEE ALSO
1234

  
1235
L<SL::DATEV::KNEFile>
1236

  
1237
=head1 AUTHORS
1238

  
1239
Philip Reetz E<lt>p.reetz@linet-services.deE<gt>,
1240

  
1241
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>,
1242

  
1243
Jan Büren E<lt>jan@lx-office-hosting.deE<gt>,
1244

  
1245
Geoffrey Richardson E<lt>information@lx-office-hosting.deE<gt>,
1246

  
1247
Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>,
1248

  
1249
Stephan Köhler
1250

  
1251
=cut
bin/mozilla/datev.pl
29 29
use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
30 30

  
31 31
use SL::Common;
32
use SL::DATEV;
32
use SL::DATEV qw(:CONSTANTS);
33 33

  
34 34
use strict;
35 35

  
......
45 45
  $::lxdebug->enter_sub;
46 46
  $::auth->assert('datev_export');
47 47

  
48
  DATEV->get_datev_stamm(\%::myconfig, $::form);
48
  my $stamm = SL::DATEV->new->get_datev_stamm;
49

  
49 50
  $::form->header;
50
  print $::form->parse_html_template('datev/export');
51
  print $::form->parse_html_template('datev/export', $stamm);
51 52

  
52 53
  $::lxdebug->leave_sub;
53 54
}
......
85 86
}
86 87

  
87 88
sub export3 {
88
  $main::lxdebug->enter_sub();
89

  
90
  my $form     = $main::form;
91
  my %myconfig = %main::myconfig;
92
  my $locale   = $main::locale;
93

  
94
  $main::auth->assert('datev_export');
95

  
96
  DATEV::clean_temporary_directories();
97

  
98
  DATEV->save_datev_stamm(\%myconfig, \%$form);
89
  $::lxdebug->enter_sub;
90
  $::auth->assert('datev_export');
99 91

  
100
  my $link = "datev.pl?action=download&download_token=";
92
  my %data = (
93
    exporttype => $::form->{exporttype} ? DATEV_ET_STAMM : DATEV_ET_BUCHUNGEN,
94
    format     => $::form->{kne}        ? DATEV_FORMAT_KNE : DATEV_FORMAT_OBE,
95
  );
96

  
97
  if ($::form->{exporttype} == DATEV_ET_STAMM) {
98
    $data{accnofrom}  = $::form->{accnofrom},
99
    $data{accnoto}    = $::form->{accnoto},
100
  } elsif ($::form->{exporttype} == DATEV_ET_BUCHUNGEN) {
101
    @data{qw(from to)} = _get_dates(
102
      $::form->{zeitraum}, $::form->{monat}, $::form->{quartal},
103
      $::form->{transdatefrom}, $::form->{transdateto},
104
    );
105
  } else {
106
    die 'invalid exporttype';
107
  }
101 108

  
102
  if ($form->{kne}) {
103
    my $result = DATEV->kne_export(\%myconfig, \%$form);
104
    if ($result && @{ $result->{filenames} }) {
105
      $link .= Q($result->{download_token});
109
  my $datev = SL::DATEV->new(%data);
106 110

  
107
      print(qq|<br><b>| . $locale->text('KNE-Export erfolgreich!') . qq|</b><br><br><a href="$link">Download</a>|);
111
  $datev->clean_temporary_directories;
112
  $datev->save_datev_stamm($::form);
108 113

  
109
      print $form->parse_html_template('datev/net_gross_difference') if @{ $form->{net_gross_differences} };
114
  $datev->export;
110 115

  
111
    } else {
112
      $form->error("KNE-Export schlug fehl.");
113
    }
116
  if (!$datev->errors) {
117
    $::form->header;
118
    print $::form->parse_html_template('datev/export3', { datev => $datev });
114 119
  } else {
115
    # OBE-Export nicht implementiert.
116

  
117
    # my @filenames = DATEV->obe_export(\%myconfig, \%$form);
118
    # if (@filenames) {
119
    #   print(qq|<br><b>| . $locale->text('OBE-Export erfolgreich!') . qq|</b><br>|);
120
    #   $link .= "&filenames=" . $form->escape(join(":", @filenames));
121
    #   print(qq|<br><a href="$link">Download</a>|);
122
    # } else {
123
    #   $form->error("OBE-Export schlug fehl.");
124
    # }
120
    $::form->error("Export schlug fehl.\n" . join "\n", $datev->errors);
125 121
  }
126 122

  
127
  print("</body></html>");
128

  
129
  $main::lxdebug->leave_sub();
123
  $::lxdebug->leave_sub;
130 124
}
131 125

  
132 126
sub download {
......
135 129
  my $form     = $main::form;
136 130
  my $locale   = $main::locale;
137 131

  
138
  $main::auth->assert('datev_export');
132
  $::auth->assert('datev_export');
139 133

  
140 134
  my $tmp_name = Common->tmpname();
141 135
  my $zip_name = strftime("kivitendo-datev-export-%Y%m%d.zip", localtime(time()));
142 136

  
143 137
  my $cwd = getcwd();
144 138

  
145
  my $path = DATEV::get_path_for_download_token($form->{download_token});
139
  my $datev = SL::DATEV->new(download_token => $form->{download_token});
140

  
141
  my $path = $datev->export_path;
146 142
  if (!$path) {
147 143
    $form->error($locale->text("Your download does not exist anymore. Please re-run the DATEV export assistant."));
148 144
  }
......
153 149

  
154 150
  if (!@filenames) {
155 151
    chdir($cwd);
156
    DATEV::clean_temporary_directories();
157 152
    $form->error($locale->text("Your download does not exist anymore. Please re-run the DATEV export assistant."));
158 153
  }
159 154

  
......
175 170

  
176 171
  unlink($tmp_name);
177 172

  
178
  DATEV::clean_temporary_directories();
179

  
180 173
  $main::lxdebug->leave_sub();
181 174
}
175

  
176
sub _get_dates {
177
  $::lxdebug->enter_sub;
178

  
179
  my ($mode, $month, $quarter, $transdatefrom, $transdateto) = @_;
180
  my ($fromdate, $todate);
181

  
182
  if ($mode eq "monat") {
183
    $fromdate = DateTime->new(day => 1, month => $month, year => DateTime->today->year);
184
    $todate   = $fromdate->clone->add(months => 1)->add(days => -1);
185
  } elsif ($mode eq "quartal") {
186
    die 'quarter out of of bounds' if $quarter < 1 || $quarter > 4;
187
    $fromdate = DateTime->new(day => 1, month => (3 * $quarter - 2), year => DateTime->today->year);
188
    $todate   = $fromdate->clone->add(months => 3)->add(days => -1);
189
  } elsif ($mode eq "zeit") {
190
    $fromdate = DateTime->from_lxoffice($transdatefrom);
191
    $todate   = DateTime->from_lxoffice($transdateto);
192
    die 'need from and to time' unless $fromdate && $todate;
193
  } else {
194
    die 'undefined interval mode';
195
  }
196

  
197
  $::lxdebug->leave_sub;
198

  
199
  return ($fromdate, $todate);
200
}
t/datev/interface.t
1
use strict;
2
use Test::More;
3
use Test::Deep ();
4

  
5
use lib 't';
6

  
7
use_ok 'Support::TestSetup';
8
use SL::DATEV qw(:CONSTANTS);
9
use DateTime;
10

  
11
Support::TestSetup::login();
12

  
13
# first, test all the accessors
14
my $d = new_ok('SL::DATEV' => [], 'new without params');
15

  
16
# export_type
17
ok(!$d->has_exporttype, 'no exporttype');
18
is($d->exporttype(DATEV_ET_BUCHUNGEN), DATEV_ET_BUCHUNGEN, 'set exporttype');
19
is($d->exporttype, DATEV_ET_BUCHUNGEN, 'get exporttype');
20
ok($d->has_exporttype, 'now exporttype');
21

  
22
# export_path/download_token
23
ok(!$d->has_format, 'no format');
24
is($d->format(DATEV_FORMAT_KNE), DATEV_FORMAT_KNE, 'set format');
25
is($d->format, DATEV_FORMAT_KNE, 'get format');
26
ok($d->has_format, 'now format');
27

  
28
# check if autogenerated download token work work
29
ok($d->export_path, 'auto generated export path');
30
ok($d->download_token, 'auto generated download token');
31

  
32
my $export_path = $d->export_path;
33
my $download_token = $d->download_token;
34

  
35
# see if that's roundtrip safe
36
$d = new_ok('SL::DATEV' => [ download_token => $download_token ], 'new with dl token');
37

  
38
is($d->download_token, $download_token, 'previously set download token');
39
is($d->export_path, $export_path, 'export path from download token');
40

  
41

  
42
# array attributes
43
Test::Deep::cmp_deeply([$d->filenames], [], 'init filenames');
44
is($d->add_filenames(qw(a b c)), 3, 'add filenames');
45
Test::Deep::cmp_deeply([$d->filenames], [qw(a b c)], 'get filenames');
46

  
47
Test::Deep::cmp_deeply([$d->errors], [], 'init errors');
48
is($d->add_error(qw(a b c)), 3, 'add error');
49
Test::Deep::cmp_deeply([$d->errors], [qw(a b c)], 'get errors');
50

  
51
Test::Deep::cmp_deeply([$d->net_gross_differences], [], 'init net_gross_differences');
52
is($d->add_net_gross_differences(qw(1 2 3)), 3, 'add net_gross_differences');
53
Test::Deep::cmp_deeply([$d->net_gross_differences], [qw(1 2 3)], 'get net_gross_differences');
54
is($d->sum_net_gross_differences, 6, 'sum net_gross_differences');
55

  
56

  
57
#get/set attributes
58

  
59
is($d->from, undef, 'init from');
60
is($d->from(DateTime->today), DateTime->today, 'set from');
61
is($d->from, DateTime->today, 'get from');
62

  
63
is($d->to, undef, 'init to');
64
is($d->to(DateTime->today), DateTime->today, 'set to');
65
is($d->to, DateTime->today, 'get to');
66

  
67
is($d->accnofrom, undef, 'init accnofrom');
68
is($d->accnofrom('3400'), '3400', 'set accnofrom');
69
is($d->accnofrom, '3400', 'get accnofrom');
70

  
71
is($d->accnoto, undef, 'init accnoto');
72
is($d->accnoto('3400'), '3400', 'set accnoto');
73
is($d->accnoto, '3400', 'get accnoto');
74

  
75
# dbh handling
76
is($d->dbh, $::form->get_standard_dbh, 'init dbh');
77
ok(!$d->provided_dbh, 'no dbh provided');
78

  
79
my $other_dbh = $::form->get_standard_dbh->clone;
80

  
81
$d = new_ok('SL::DATEV' => [ dbh => $other_dbh ], 'new with dbh');
82
isnt($d->dbh, $::form->get_standard_dbh, 'now a different dbh');
83
ok($d->provided_dbh, 'now got some provided dbh');
84

  
85

  
86
$d = new_ok('SL::DATEV' => [], 'another clean one');
87
is($d->fromto, undef, 'if no from or to -> fromto undef');
88

  
89
# TODO:error handling. test that stuff dies if it has to
90

  
91
done_testing();
92

  
93

  
94
1;
templates/webpages/datev/export3.html
1
[%- USE T8 %]
2
[%- USE HTML %]
3
<html>
4
<body>
5
  Export in Bearbeitung<br>
6

  
7
  <br>
8
  Done.
9
  <br>
10

  
11
  <br><b>[% 'KNE-Export erfolgreich!' | $T8 %]</b>
12
  <br>
13
  <br>
14
  <a href="datev.pl?action=download&download_token=[% datev.download_token | html %]">Download</a>
15

  
16
[% IF datev.net_gross_differences.size %]
17
[% INCLUDE 'datev/net_gross_difference'
18
  net_gross_differences     = datev.net_gross_differences,
19
  sum_net_gross_differences = datev.sum_net_gross_differences
20
%]
21
[% END %]
22

  
23
</body>
24
</html>

Auch abrufbar als: Unified diff