3 use Test::Deep qw(cmp_deeply cmp_bag);
8 use_ok 'Support::TestSetup';
9 use SL::DATEV qw(:CONSTANTS);
10 use SL::Dev::ALL qw(:ALL);
11 use List::Util qw(sum);
12 use SL::DB::Buchungsgruppe;
16 Support::TestSetup::login();
20 my $dbh = SL::DB->client->dbh;
22 my $buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%') || die "No accounting group for 7\%";
23 my $bank = SL::DB::Manager::Chart->find_by(description => 'Bank') || die 'Can\'t find chart "Bank"';
24 my $date = DateTime->new(year => 2017, month => 1, day => 1);
25 my $payment_date = DateTime->new(year => 2017, month => 1, day => 5);
26 my $gldate = DateTime->new(year => 2017, month => 2, day => 9); # simulate bookings for Jan being made in Feb
27 my $department = create_department(description => 'Kostenstelle DATEV-Schnittstelle 2018');
28 my $project = create_project(projectnumber => 2017, description => 'Crowd-Funding September 2017');
29 my $customer = new_customer(customernumber => '10001', name => 'Testcustomer')->save;
30 my $vendor = new_vendor(vendornumber => '70001', name => 'Testvendor')->save;
32 my $part1 = new_part(partnumber => '19', description => 'Part 19%')->save;
35 description => 'Part 7%',
36 buchungsgruppen_id => $buchungsgruppe7->id,
39 my $invoice = create_sales_invoice(
40 invnumber => "Þ sales ¥& invöice",
41 customer => $customer,
44 intnotes => 'booked in February',
47 invoiceitems => [ create_invoice_item(part => $part1, qty => 3, sellprice => 70),
48 create_invoice_item(part => $part2, qty => 10, sellprice => 50),
50 department_id => $department->id,
51 globalproject_id => $project->id,
53 $invoice->pay_invoice(chart_id => $bank->id,
54 amount => $invoice->open_amount,
55 transdate => $payment_date->to_kivitendo,
59 my $datev1 = SL::DATEV->new(
60 dbh => $invoice->db->dbh,
61 trans_id => $invoice->id,
64 $datev1->generate_datev_data;
66 my @data_datev = sort { $a->{umsatz} <=> $b->{umsatz} } @{ $datev1->generate_datev_lines() };
67 cmp_deeply \@data_datev, [
69 'belegfeld1' => "\x{de} sales \x{a5}& inv\x{f6}ice",
70 'buchungstext' => 'Testcustomer',
71 'datum' => '01.01.2017',
72 'gegenkonto' => '8400',
74 'kost1' => 'Kostenstelle DATEV-Schnittstelle 2018',
75 'kost2' => 'Crowd-Funding September 2017',
81 'belegfeld1' => "\x{de} sales \x{a5}& inv\x{f6}ice",
82 'buchungstext' => 'Testcustomer',
83 'datum' => '01.01.2017',
84 'gegenkonto' => '8300',
86 'kost1' => 'Kostenstelle DATEV-Schnittstelle 2018',
87 'kost2' => 'Crowd-Funding September 2017',
93 'belegfeld1' => "\x{de} sales \x{a5}& inv\x{f6}ice",
94 'buchungstext' => 'Testcustomer',
95 'buchungstext' => 'Testcustomer',
96 'datum' => '05.01.2017',
97 'gegenkonto' => '1400',
99 'kost1' => 'Kostenstelle DATEV-Schnittstelle 2018',
100 'kost2' => 'Crowd-Funding September 2017',
105 ], "trans_id datev check ok";
108 $datev1->generate_datev_data;
109 # TODO for cmp_deeply we need to sort the incoming data structure (see below)
110 cmp_bag $datev1->generate_datev_lines, [
112 'belegfeld1' => "\x{de} sales \x{a5}& inv\x{f6}ice",
113 'buchungstext' => 'Testcustomer',
114 'datum' => '01.01.2017',
115 'gegenkonto' => '8400',
116 'konto' => $customer->customernumber,
117 'kost1' => 'Kostenstelle DATEV-Schnittstelle 2018',
118 'kost2' => 'Crowd-Funding September 2017',
124 'belegfeld1' => "\x{de} sales \x{a5}& inv\x{f6}ice",
125 'buchungstext' => 'Testcustomer',
126 'datum' => '01.01.2017',
127 'gegenkonto' => '8300',
128 'konto' => $customer->customernumber,
129 'kost1' => 'Kostenstelle DATEV-Schnittstelle 2018',
130 'kost2' => 'Crowd-Funding September 2017',
136 'belegfeld1' => "\x{de} sales \x{a5}& inv\x{f6}ice",
137 'buchungstext' => 'Testcustomer',
138 'datum' => '05.01.2017',
139 'gegenkonto' => $customer->customernumber,
141 'kost1' => 'Kostenstelle DATEV-Schnittstelle 2018',
142 'kost2' => 'Crowd-Funding September 2017',
147 ], "trans_id datev check use_pk ok";
150 my $startdate = DateTime->new(year => 2017, month => 1, day => 1);
151 my $enddate = DateTime->new(year => 2017, month => 12, day => 31);
153 # check conversion to csv
154 $datev1->from($startdate);
155 $datev1->to($enddate);
156 # reset use_pk for csv_buchungsexport
158 $datev1->generate_datev_data;
161 my $datev_csv = SL::DATEV::CSV->new(datev_lines => $datev1->generate_datev_lines,
164 locked => $datev1->locked,
169 # we need sort, because pay_invoice is not acc_trans_id order safe
170 my @data_csv = sort { $a->[0] cmp $b->[0] } @{ $datev_csv->lines };
171 # warnings should be undef -> no array elements at all
172 is(scalar @{ $datev_csv->warnings }, 0);
175 cmp_deeply($data_csv[1], [ '535', 'S', 'EUR', '', '', '', '1400', '8300', '', '0101', "\x{de} sales \x{a5}& i",
176 '', '', 'Testcustomer', '', '', '', '', '', '', '', '',
177 '', '', '', '', '', '', '', '', '', '', '', '', '',
178 '', 'Kostenst', 'Crowd-Fu', '', '', '', '', '', '', '', '',
179 '', '', '', '', '', '', '', '', '', '', '', '', '',
180 '', '', '', '', '', '', '', '', '', '', '', '', '',
181 '', '', '', '', '', '', '', '', '', '', '', '', '',
182 '', '', '', '', '', '', '', '', '', '', '', '', '',
183 '', '', '', '', '', '', '', '', '', '', '', '', '',
184 '', '', '1', '', '', '', '', '', '' ]
187 cmp_deeply($data_csv[0], [ '249,9', 'S', 'EUR', '', '', '', '1400', '8400', '', '0101', "\x{de} sales \x{a5}& i",
188 '', '', 'Testcustomer', '', '', '', '', '', '', '', '',
189 '', '', '', '', '', '', '', '', '', '', '', '', '',
190 '', 'Kostenst', 'Crowd-Fu', '', '', '', '', '', '', '', '',
191 '', '', '', '', '', '', '', '', '', '', '', '', '',
192 '', '', '', '', '', '', '', '', '', '', '', '', '',
193 '', '', '', '', '', '', '', '', '', '', '', '', '',
194 '', '', '', '', '', '', '', '', '', '', '', '', '',
195 '', '', '', '', '', '', '', '', '', '', '', '', '',
196 '', '', '1', '', '', '', '', '', '' ]
198 cmp_deeply($data_csv[2], [ '784,9', 'S', 'EUR', '', '', '', '1200', '1400', '', '0501', "\x{de} sales \x{a5}& i",
199 '', '', 'Testcustomer', '', '', '', '', '', '', '', '',
200 '', '', '', '', '', '', '', '', '', '', '', '', '',
201 '', 'Kostenst', 'Crowd-Fu', '', '', '', '', '', '', '', '',
202 '', '', '', '', '', '', '', '', '', '', '', '', '',
203 '', '', '', '', '', '', '', '', '', '', '', '', '',
204 '', '', '', '', '', '', '', '', '', '', '', '', '',
205 '', '', '', '', '', '', '', '', '', '', '', '', '',
206 '', '', '', '', '', '', '', '', '', '', '', '', '',
207 '', '', '1', '', '', '', '', '', '' ]
209 my $march_9 = DateTime->new(year => 2017, month => 3, day => 9);
210 my $invoice2 = create_sales_invoice(
211 invnumber => "2 sales invoice",
212 customer => $customer,
215 intnotes => 'booked in March',
218 invoiceitems => [ create_invoice_item(part => $part1, qty => 6, sellprice => 70),
219 create_invoice_item(part => $part2, qty => 20, sellprice => 50),
223 my $credit_note = create_credit_note(
224 invnumber => 'Gutschrift 34',
225 customer => $customer,
228 intnotes => 'booked in February',
231 invoiceitems => [ create_invoice_item(part => $part1, qty => 3, sellprice => 70),
232 create_invoice_item(part => $part2, qty => 10, sellprice => 50),
236 my $datev = SL::DATEV->new(
241 $datev->generate_datev_data(from_to => $datev->fromto);
242 my $datev_lines = $datev->generate_datev_lines;
243 my $umsatzsumme = sum map { $_->{umsatz} } @{ $datev_lines };
244 cmp_ok($::form->round_amount($umsatzsumme,2), '==', 3924.5, "Sum of all bookings ok");
246 $datev->generate_datev_data(use_pk => 1, from_to => $datev->fromto);
247 $datev_lines = $datev->generate_datev_lines;
249 note('testing purchase invoice');
250 my $purchase_invoice = create_ap_transaction(
257 itime => $date, # make sure itime is 1.1., as gldatefrom tests for itime!
261 chart => SL::DB::Manager::Chart->find_by(accno => '3400'),
265 chart => SL::DB::Manager::Chart->find_by(accno => '3300'),
271 $datev1 = SL::DATEV->new(
272 dbh => $purchase_invoice->db->dbh,
273 trans_id => $purchase_invoice->id,
276 $datev1->generate_datev_data;
277 cmp_deeply $datev1->generate_datev_lines, [
279 'belegfeld1' => 'ap1',
280 'buchungstext' => 'Testvendor',
281 'datum' => '01.01.2017',
282 'gegenkonto' => '1600',
291 'belegfeld1' => 'ap1',
292 'buchungstext' => 'Testvendor',
293 'datum' => '01.01.2017',
294 'gegenkonto' => '1600',
302 ], "trans_id datev check purchase_invoice ok";
304 $datev1->generate_datev_data;
305 cmp_deeply $datev1->generate_datev_lines, [
307 'belegfeld1' => 'ap1',
308 'buchungstext' => 'Testvendor',
309 'datum' => '01.01.2017',
310 'gegenkonto' => $vendor->vendornumber,
319 'belegfeld1' => 'ap1',
320 'buchungstext' => 'Testvendor',
321 'datum' => '01.01.2017',
322 'gegenkonto' => $vendor->vendornumber,
330 ], "trans_id datev check purchase_invoice use_pk ok";
332 note('testing gldatefrom');
333 # test an order with transdate in january, but that was booked in march
334 # gldatefrom in DATEV.pm checks for itime, not gldate!!!
335 $datev = SL::DATEV->new(
338 to => DateTime->new(year => 2017, month => 01, day => 31),
341 $::form = Support::TestSetup->create_new_form;
342 $::form->{gldatefrom} = DateTime->new(year => 2017, month => 3, day => 1)->to_kivitendo;
344 $datev->generate_datev_data(from_to => $datev->fromto);
345 $datev_lines = $datev->generate_datev_lines;
346 $umsatzsumme = sum map { $_->{umsatz} } @{ $datev_lines };
347 cmp_ok($umsatzsumme, '==', 1569.8, "Sum of bookings made after March 1st (only invoice2) ok");
349 $::form->{gldatefrom} = DateTime->new(year => 2017, month => 5, day => 1)->to_kivitendo;
350 $datev->generate_datev_data(from_to => $datev->fromto);
351 cmp_deeply $datev->generate_datev_lines, [], "no bookings for January made after May 1st: ok";
357 SL::DB::Manager::AccTransaction->delete_all(all => 1);
358 SL::DB::Manager::InvoiceItem->delete_all( all => 1);
359 SL::DB::Manager::Invoice->delete_all( all => 1);
360 SL::DB::Manager::PurchaseInvoice->delete_all(all => 1);
361 SL::DB::Manager::Customer->delete_all( all => 1);
362 SL::DB::Manager::Part->delete_all( all => 1);
363 SL::DB::Manager::Project->delete_all( all => 1);
364 SL::DB::Manager::Department->delete_all( all => 1);
365 SL::DATEV->clean_temporary_directories;