Testfälle für neue API von DATEV angepasst
[kivitendo-erp.git] / t / datev / datev_format_2018.t
1 use strict;
2 use Test::More;
3 use Test::Deep qw(cmp_deeply);
4
5 use lib 't';
6
7 use_ok 'Support::TestSetup';
8 use SL::DATEV qw(:CONSTANTS);
9 use SL::Dev::ALL qw(:ALL);
10 use List::Util qw(sum);
11 use SL::DB::Buchungsgruppe;
12 use SL::DB::Chart;
13 use DateTime;
14 use Data::Dumper;
15 use utf8;
16
17 Support::TestSetup::login();
18
19 my $dbh = SL::DB->client->dbh;
20
21 clear_up();
22 my $buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%') || die "No accounting group for 7\%";
23 my $date            = DateTime->new(year => 2017, month =>  7, day => 19);
24 my $department      = create_department(description => 'Kästchenweiße heiße Preise');
25 my $project         = create_project(projectnumber => 2017, description => '299');
26
27 my $part1 = new_part(partnumber => '19', description => 'Part 19%')->save;
28 my $part2 = new_part(
29   partnumber         => '7',
30   description        => 'Part 7%',
31   buchungsgruppen_id => $buchungsgruppe7->id,
32 )->save;
33
34 my $invoice = create_sales_invoice(
35   invnumber    => "ݗݘݰݶ",
36   itime        => $date,
37   gldate       => $date,
38   taxincluded  => 0,
39   transdate    => $date,
40   invoiceitems => [ create_invoice_item(part => $part1, qty =>  3, sellprice => 550),
41                     create_invoice_item(part => $part2, qty => 10, sellprice => 50),
42                   ],
43   department_id    => $department->id,
44   globalproject_id => $project->id,
45 );
46
47 # lets make a boom
48 # generate_datev_* doesnt care about encoding but
49 # csv_buchungsexport does! all arabic will be deleted
50 # and no string will be left as invnumber
51
52 my $datev1 = SL::DATEV->new(
53   dbh        => $dbh,
54   trans_id   => $invoice->id,
55 );
56
57 my $startdate = DateTime->new(year => 2017, month =>  1, day =>  1);
58 my $enddate   = DateTime->new(year => 2017, month =>  12, day => 31);
59 my $today     = DateTime->new(year => 2017, month =>  3, day => 17);
60
61
62 $datev1->from($startdate);
63 $datev1->to($enddate);
64
65 $datev1->generate_datev_data;
66 $datev1->generate_datev_lines;
67
68 # check conversion to csv
69 $datev1->from($startdate);
70 $datev1->to($enddate);
71 my ($datev_csv, $die_message);
72 eval {
73   $datev_csv = SL::DATEV::CSV->new(datev_lines  => $datev1->generate_datev_lines,
74                                    from         => $startdate,
75                                    to           => $enddate,
76                                    locked       => $datev1->locked,
77                                   );
78   my $lines_aref = $datev_csv->lines; # dies only if we assign (do stuff with the data)
79   1;
80 } or do {
81   $die_message = $@;
82 };
83 ok($die_message =~ m/Falscher Feldwert 'ݗݘݰݶ' für Feld 'belegfeld1' bei der Transaktion mit dem Umsatz von/, 'wrong_encoding');
84
85
86 $invoice->invnumber('ݗݘݰݶmuh');
87 $invoice->save();
88
89 my $datev3 = SL::DATEV->new(
90   dbh        => $dbh,
91   trans_id   => $invoice->id,
92 );
93
94 $datev3->from($startdate);
95 $datev3->to($enddate);
96 $datev3->generate_datev_data;
97 $datev3->generate_datev_lines;
98 my ($datev_csv2, $die_message2);
99 eval {
100   $datev_csv2 = SL::DATEV::CSV->new(datev_lines  => $datev3->generate_datev_lines,
101                                     from         => $startdate,
102                                     to           => $enddate,
103                                     locked       => $datev3->locked,
104                                    );
105 my $lines_aref = $datev_csv2->lines; # dies only if we assign (do stuff with the data)
106
107   1;
108 } or do {
109   $die_message2 = $@;
110 };
111
112 # redefine invnumber, we have mixed encodings, should still fail
113 ok($die_message2 =~ m/Falscher Feldwert 'ݗݘݰݶmuh' für Feld 'belegfeld1' bei der Transaktion mit dem Umsatz von/, 'mixed_wrong_encoding');
114
115 # create one haben buchung with GLTransaction today
116
117 my $expense_chart = SL::DB::Manager::Chart->find_by(accno => '4660'); # Reisekosten
118 my $cash_chart    = SL::DB::Manager::Chart->find_by(accno => '1000'); # Kasse
119 my $tax_chart     = SL::DB::Manager::Chart->find_by(accno => '1576'); # Vorsteuer
120 my $tax_9         = SL::DB::Manager::Tax->find_by(taxkey => 9, rate => 0.19) || die "No tax";
121
122 my @acc_trans;
123 push(@acc_trans, SL::DB::AccTransaction->new(
124                                       chart_id   => $expense_chart->id,
125                                       chart_link => $expense_chart->link,
126                                       amount     => -84.03,
127                                       transdate  => $today,
128                                       source     => '',
129                                       taxkey     => 9,
130                                       tax_id     => $tax_9->id,
131                                       project_id => $project->id,
132 ));
133 push(@acc_trans, SL::DB::AccTransaction->new(
134                                       chart_id   => $tax_chart->id,
135                                       chart_link => $tax_chart->link,
136                                       amount     => -15.97,
137                                       transdate  => $today,
138                                       source     => '',
139                                       taxkey     => 9,
140                                       tax_id     => $tax_9->id,
141                                       project_id => $project->id,
142 ));
143 push(@acc_trans, SL::DB::AccTransaction->new(
144                                       chart_id   => $cash_chart->id,
145                                       chart_link => $cash_chart->link,
146                                       amount     => 100,
147                                       transdate  => $today,
148                                       source     => '',
149                                       taxkey     => 0,
150                                       tax_id     => 0,
151 ));
152
153 my $gl_transaction = SL::DB::GLTransaction->new(
154   reference      => "Reise März 2018",
155   description    => "Reisekonsten März 2018 / Ma Schmidt",
156   transdate      => $today,
157   gldate         => $today,
158   employee_id    => SL::DB::Manager::Employee->current->id,
159   taxincluded    => 1,
160   type           => undef,
161   ob_transaction => 0,
162   cb_transaction => 0,
163   storno         => 0,
164   storno_id      => undef,
165   transactions   => \@acc_trans,
166 )->save;
167 my $datev2 = SL::DATEV->new(
168   dbh        => $dbh,
169   trans_id   => $gl_transaction->id,
170 );
171
172 $datev2->from($startdate);
173 $datev2->to($enddate);
174 $datev2->generate_datev_data;
175 $datev2->generate_datev_lines;
176
177 my $datev_csv3  = SL::DATEV::CSV->new(datev_lines  => $datev2->generate_datev_lines,
178                                       from         => $startdate,
179                                       to           => $enddate,
180                                       locked       => $datev2->locked,
181                                      );
182
183 my @data_csv = $datev_csv3->lines;
184 @data_csv    = sort { $a->[0] cmp $b->[0] } @{ $datev_csv3->lines };
185 cmp_deeply($data_csv[0], [ 100, 'H', 'EUR', '', '', '', '4660', '1000', 9, '1703', 'Reise März 2',
186                      '', '', '', '', '', '', '', '', '', '', '',
187                      '', '', '', '', '', '', '', '', '', '', '', '', '',
188                      '', '', '', '', '', '', '', '', '', '', '',
189                      '', '', '', '', '', '', '', '', '', '', '', '', '',
190                      '', '', '', '', '', '', '', '', '', '', '', '', '',
191                      '', '', '', '', '', '', '', '', '', '', '', '', '',
192                      '', '', '', '', '', '', '', '', '', '', '', '', '',
193                      '', '', '', '', '', '', '', '', '', '', '', '', '',
194                      '', '', '', '', '' ]
195        );
196
197 # TODO warnings are not yet tested
198 # currently most of the valid_checks are senseless because of
199 # the strict input_checks before. Maybe something like encoding mismatch of invnumber,
200 # can be altered to just a warning (not a mandantory field!)
201
202 done_testing();
203 clear_up();
204
205
206 sub clear_up {
207   SL::DB::Manager::AccTransaction->delete_all( all => 1);
208   SL::DB::Manager::GLTransaction->delete_all(  all => 1);
209   SL::DB::Manager::InvoiceItem->delete_all(    all => 1);
210   SL::DB::Manager::Invoice->delete_all(        all => 1);
211   SL::DB::Manager::Customer->delete_all(       all => 1);
212   SL::DB::Manager::Part->delete_all(           all => 1);
213   SL::DB::Manager::Project->delete_all(        all => 1);
214   SL::DB::Manager::Department->delete_all(     all => 1);
215   SL::DATEV->clean_temporary_directories;
216 };
217
218 1;