3 use Test::Deep qw(cmp_deeply);
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;
17 Support::TestSetup::login();
19 my $dbh = SL::DB->client->dbh;
23 my $d = SL::DB::Default->get;
24 $d->update_attributes(datev_export_format => 'cp1252');
26 my $ustid = 'DE123456788';
27 my $buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%') || die "No accounting group for 7\%";
28 my $date = DateTime->new(year => 2017, month => 7, day => 19);
29 my $department = create_department(description => 'Kästchenweiße heiße Preise');
30 my $project = create_project(projectnumber => 2017, description => '299');
31 my $bank = SL::DB::Manager::Chart->find_by(description => 'Bank') || die 'Can\'t find chart "Bank"';
32 my $customer = new_customer(name => 'Test customer', ustid => $ustid)->save();
33 my $part1 = new_part(partnumber => '19', description => 'Part 19%')->save;
36 description => 'Part 7%',
37 buchungsgruppen_id => $buchungsgruppe7->id,
40 my $invoice = create_sales_invoice(
46 invoiceitems => [ create_invoice_item(part => $part1, qty => 3, sellprice => 550),
47 create_invoice_item(part => $part2, qty => 10, sellprice => 50),
49 department_id => $department->id,
50 globalproject_id => $project->id,
51 customer_id => $customer->id,
55 # generate_datev_* doesn't care about encoding but
56 # csv_buchungsexport does! all arabic will be deleted
57 # and no string will be left as invnumber
59 my $datev1 = SL::DATEV->new(
61 trans_id => $invoice->id,
64 my $startdate = DateTime->new(year => 2017, month => 1, day => 1);
65 my $enddate = DateTime->new(year => 2017, month => 12, day => 31);
66 my $today = DateTime->new(year => 2017, month => 3, day => 17);
68 $datev1->from($startdate);
69 $datev1->to($enddate);
71 $datev1->generate_datev_data;
72 $datev1->generate_datev_lines;
74 # check conversion to csv
75 $datev1->from($startdate);
76 $datev1->to($enddate);
77 my ($datev_csv, $die_message);
79 $datev_csv = SL::DATEV::CSV->new(datev_lines => $datev1->generate_datev_lines,
82 locked => $datev1->locked,
84 my $lines_aref = $datev_csv->lines; # dies only if we assign (do stuff with the data)
89 ok($die_message =~ m/Falscher Feldwert 'ݗݘݰݶ' für Feld 'belegfeld1' bei der Transaktion mit dem Umsatz von/, 'wrong_encoding');
92 $invoice->invnumber('ݗݘݰݶmuh');
95 my $datev3 = SL::DATEV->new(
97 trans_id => $invoice->id,
100 $datev3->from($startdate);
101 $datev3->to($enddate);
102 $datev3->generate_datev_data;
103 $datev3->generate_datev_lines;
104 my ($datev_csv2, $die_message2);
106 $datev_csv2 = SL::DATEV::CSV->new(datev_lines => $datev3->generate_datev_lines,
109 locked => $datev3->locked,
111 my $lines_aref = $datev_csv2->lines; # dies only if we assign (do stuff with the data)
118 # redefine invnumber, we have mixed encodings, should still fail
119 ok($die_message2 =~ m/Falscher Feldwert 'ݗݘݰݶmuh' für Feld 'belegfeld1' bei der Transaktion mit dem Umsatz von/, 'mixed_wrong_encoding');
121 # check with good number
122 $invoice->invnumber('meine muh');
125 $invoice->pay_invoice(chart_id => $bank->id,
126 amount => $invoice->open_amount,
127 transdate => $invoice->transdate->clone->add(days => 10),
132 my $datev4 = SL::DATEV->new(
134 trans_id => $invoice->id,
137 $datev4->from($startdate);
138 $datev4->to($enddate);
139 $datev4->generate_datev_data;
140 $datev4->generate_datev_lines;
142 my ($datev_csv4, $die_message3, $lines_aref);
144 $datev_csv4 = SL::DATEV::CSV->new(datev_lines => $datev4->generate_datev_lines,
147 locked => $datev4->locked,
149 $lines_aref = $datev_csv4->lines; # dies only if we assign (do stuff with the data)
155 ok(!($die_message3), 'no die message');
156 ok(scalar @{ $datev_csv4->warnings } == 0, 'no warnings');
159 note('testing invoice without deliverydate');
160 my @sorted = sort { $a->[0] cmp $b->[0] } @{ $lines_aref }; # sort by string-comparison of amount
161 cmp_deeply $sorted[0],
162 [ '1963,5', 'S', 'EUR', '', '', '',
163 '1400', '8400', '', '1907', 'meine muh',
164 '', '', 'Test customer', '', '', '', '', '', '',
165 '', '', '', '', '', '', '', '', '',
166 '', '', '', '', '', '', '', "K\x{e4}stchen",
167 '299', '', $ustid, '', '', '',
168 '', '', '', '', '', '', '', '', '',
169 '', '', '', '', '', '', '', '', '',
170 '', '', '', '', '', '', '', '', '',
171 '', '', '', '', '', '', '', '', '',
172 '', '', '', '', '', '', '', '', '',
173 '', '', '', '', '', '', '', '', '',
174 '', '', '', '', '', '', '', '', '',
175 '', '', '', '', '', '', '', '1', '',
178 'invoice without deliverydate 19% tax export ok';
179 cmp_deeply $sorted[2],
180 [ '535', 'S', 'EUR', '', '', '',
181 '1400', '8300', '', '1907','meine muh',
182 '', '', 'Test customer', '', '', '', '', '', '',
183 '', '', '', '', '', '', '', '', '',
184 '', '', '', '', '', '', '', "K\x{e4}stchen",
185 '299', '', $ustid, '', '', '',
186 '', '', '', '', '', '', '', '', '',
187 '', '', '', '', '', '', '', '', '',
188 '', '', '', '', '', '', '', '', '',
189 '', '', '', '', '', '', '', '', '',
190 '', '', '', '', '', '', '', '', '',
191 '', '', '', '', '', '', '', '', '',
192 '', '', '', '', '', '', '', '', '',
193 '', '', '', '', '', '', '', '1', '',
196 'invoice without deliverydate 16% tax export ok';
197 cmp_deeply $sorted[1],
198 [ '2498,5', 'S', 'EUR', '', '', '',
199 '1200', '1400', '', '2907','meine muh',
200 '', '', 'Test customer', '', '', '', '', '', '',
201 '', '', '', '', '', '', '', '', '',
202 '', '', '', '', '', '', '', "K\x{e4}stchen",
203 '299', '', $ustid, '', '', '',
204 '', '', '', '', '', '', '', '', '',
205 '', '', '', '', '', '', '', '', '',
206 '', '', '', '', '', '', '', '', '',
207 '', '', '', '', '', '', '', '', '',
208 '', '', '', '', '', '', '', '', '',
209 '', '', '', '', '', '', '', '', '',
210 '', '', '', '', '', '', '', '', '',
211 '', '', '', '', '', '', '', '1', '',
214 'invoice without deliverydate payment export ok';
216 # create one haben buchung with GLTransaction today
218 my $expense_chart = SL::DB::Manager::Chart->find_by(accno => '4660'); # Reisekosten
219 my $cash_chart = SL::DB::Manager::Chart->find_by(accno => '1000'); # Kasse
221 note('testing gl transaction without deliverydate');
222 my $gl_transaction = create_gl_transaction(
223 reference => "Reise März 2018",
224 description => "Reisekosten März 2018 / Ma Schmidt",
230 chart => $expense_chart,
232 debit => 100, # net 84.03
235 chart => $cash_chart,
242 my $datev2 = SL::DATEV->new(
244 trans_id => $gl_transaction->id,
247 $datev2->from($startdate);
248 $datev2->to($enddate);
249 $datev2->generate_datev_data;
251 my $datev_csv3 = SL::DATEV::CSV->new(datev_lines => $datev2->generate_datev_lines,
254 locked => $datev2->locked,
257 my @data_csv = sort { $a->[0] cmp $b->[0] } @{ $datev_csv3->lines };
258 cmp_deeply($data_csv[0],
259 [ '100', 'S', 'EUR', '', '', '', '4660', '1000', 9, '1703', 'Reise März 2',
260 '', '', 'Reisekosten März 2018 / Ma Schmidt', '', '', '', '', '', '', '', '',
261 '', '', '', '', '', '', '', '', '', '', '', '', '',
262 '', '', '', '', '', '', '', '', '', '', '',
263 '', '', '', '', '', '', '', '', '', '', '', '', '',
264 '', '', '', '', '', '', '', '', '', '', '', '', '',
265 '', '', '', '', '', '', '', '', '', '', '', '', '',
266 '', '', '', '', '', '', '', '', '', '', '', '', '',
267 '', '', '', '', '', '', '', '', '', '', '', '', '',
268 '', '', '1', '', '', '', '', '', '',
270 'gl datev export without delivery date ok');
273 note('testing same invoice, but with deliverydate');
274 # 8400 and 8300 should have deliverydate in datev, payment should not
275 $invoice->deliverydate(DateTime->new(year => 2017, month => 7, day => 18));
278 $datev1 = SL::DATEV->new(
280 trans_id => $invoice->id,
283 $datev1->from($startdate);
284 $datev1->to($enddate);
285 $datev1->generate_datev_data;
286 $datev1->generate_datev_lines;
288 $datev_csv = SL::DATEV::CSV->new(datev_lines => $datev1->generate_datev_lines,
291 locked => $datev1->locked,
293 @sorted = sort { $a->[0] cmp $b->[0] } @{ $datev_csv->lines };
294 cmp_deeply $sorted[0],
295 [ '1963,5', 'S', 'EUR', '', '', '',
296 '1400', '8400', '', '1907', 'meine muh',
297 '', '', 'Test customer', '', '', '', '', '', '',
298 '', '', '', '', '', '', '', '', '',
299 '', '', '', '', '', '', '', "K\x{e4}stchen",
300 '299', '', $ustid, '', '', '',
301 '', '', '', '', '', '', '', '', '',
302 '', '', '', '', '', '', '', '', '',
303 '', '', '', '', '', '', '', '', '',
304 '', '', '', '', '', '', '', '', '',
305 '', '', '', '', '', '', '', '', '',
306 '', '', '', '', '', '', '', '', '',
307 '', '', '', '', '', '', '', '', '',
308 '', '', '', '', '', '', '', '1', '18072017',
311 'invoice with deliverydate 19% tax export ok';
313 cmp_deeply $sorted[2],
314 [ '535', 'S', 'EUR', '', '', '',
315 '1400', '8300', '', '1907','meine muh',
316 '', '', 'Test customer', '', '', '', '', '', '',
317 '', '', '', '', '', '', '', '', '',
318 '', '', '', '', '', '', '', "K\x{e4}stchen",
319 '299', '', $ustid, '', '', '',
320 '', '', '', '', '', '', '', '', '',
321 '', '', '', '', '', '', '', '', '',
322 '', '', '', '', '', '', '', '', '',
323 '', '', '', '', '', '', '', '', '',
324 '', '', '', '', '', '', '', '', '',
325 '', '', '', '', '', '', '', '', '',
326 '', '', '', '', '', '', '', '', '',
327 '', '', '', '', '', '', '', '1', '18072017',
330 'invoice with deliverydate 16% tax export ok';
332 cmp_deeply $sorted[1],
333 [ '2498,5', 'S', 'EUR', '', '', '',
334 '1200', '1400', '', '2907','meine muh',
335 '', '', 'Test customer', '', '', '', '', '', '',
336 '', '', '', '', '', '', '', '', '',
337 '', '', '', '', '', '', '', "K\x{e4}stchen",
338 '299', '', $ustid, '', '', '',
339 '', '', '', '', '', '', '', '', '',
340 '', '', '', '', '', '', '', '', '',
341 '', '', '', '', '', '', '', '', '',
342 '', '', '', '', '', '', '', '', '',
343 '', '', '', '', '', '', '', '', '',
344 '', '', '', '', '', '', '', '', '',
345 '', '', '', '', '', '', '', '', '',
346 '', '', '', '', '', '', '', '1', '',
349 'invoice with deliverydate payment export ok';
351 note('testing same gl transaction with deliverydate');
352 $gl_transaction->deliverydate(DateTime->new(year => 2017, month => 7, day => 18));
353 $gl_transaction->save;
355 $datev1 = SL::DATEV->new(
357 trans_id => $gl_transaction->id,
360 $datev1->from($startdate);
361 $datev1->to($enddate);
362 $datev1->generate_datev_data;
364 $datev_csv = SL::DATEV::CSV->new(datev_lines => $datev1->generate_datev_lines,
367 locked => $datev1->locked,
370 @sorted = sort { $a->[0] cmp $b->[0] } @{ $datev_csv->lines };
371 cmp_deeply($sorted[0],
372 [ '100', 'S', 'EUR', '', '', '', '4660', '1000', 9, '1703', 'Reise März 2',
373 '', '', 'Reisekosten März 2018 / Ma Schmidt', '', '', '', '', '', '', '', '',
374 '', '', '', '', '', '', '', '', '', '', '', '', '',
375 '', '', '', '', '', '', '', '', '', '', '',
376 '', '', '', '', '', '', '', '', '', '', '', '', '',
377 '', '', '', '', '', '', '', '', '', '', '', '', '',
378 '', '', '', '', '', '', '', '', '', '', '', '', '',
379 '', '', '', '', '', '', '', '', '', '', '', '', '',
380 '', '', '', '', '', '', '', '', '', '', '', '', '',
381 '', '', '1', '18072017', '', '', '', '', '',
383 'testing gl transaction with delivery date datev export ok');
385 # TODO warnings are not yet tested
386 # currently most of the valid_checks are senseless because of
387 # the strict input_checks before. Maybe something like encoding mismatch of invnumber,
388 # can be altered to just a warning (not a mandantory field!)
395 SL::DB::Manager::AccTransaction->delete_all( all => 1);
396 SL::DB::Manager::GLTransaction->delete_all( all => 1);
397 SL::DB::Manager::InvoiceItem->delete_all( all => 1);
398 SL::DB::Manager::Invoice->delete_all( all => 1);
399 SL::DB::Manager::Customer->delete_all( all => 1);
400 SL::DB::Manager::Part->delete_all( all => 1);
401 SL::DB::Manager::Project->delete_all( all => 1);
402 SL::DB::Manager::Department->delete_all( all => 1);
403 SL::DATEV->clean_temporary_directories;