52c665e0ece46c5b8b6928521bd316a525ae38c9
[kivitendo-erp.git] / t / datev / invoices.t
1 use strict;
2 use Test::More;
3 use Test::Deep qw(cmp_bag);
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
15 Support::TestSetup::login();
16
17 clear_up();
18
19 my $dbh = SL::DB->client->dbh;
20
21 my $buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%') || die "No accounting group for 7\%";
22 my $bank            = SL::DB::Manager::Chart->find_by(description => 'Bank')                 || die 'Can\'t find chart "Bank"';
23 my $date            = DateTime->new(year => 2017, month =>  1, day => 1);
24 my $payment_date    = DateTime->new(year => 2017, month =>  1, day => 5);
25 my $gldate          = DateTime->new(year => 2017, month =>  2, day => 9); # simulate bookings for Jan being made in Feb
26 my $department      = create_department(description => 'Kostenstelle DATEV-Schnittstelle 2018');
27 my $project         = create_project(projectnumber => 2017, description => 'Crowd-Funding September 2017');
28
29 my $part1 = new_part(partnumber => '19', description => 'Part 19%')->save;
30 my $part2 = new_part(
31   partnumber         => '7',
32   description        => 'Part 7%',
33   buchungsgruppen_id => $buchungsgruppe7->id,
34 )->save;
35
36 my $invoice = create_sales_invoice(
37   invnumber    => "Þ sales ¥& invöice",
38   itime        => $gldate,
39   gldate       => $gldate,
40   intnotes     => 'booked in February',
41   taxincluded  => 0,
42   transdate    => $date,
43   invoiceitems => [ create_invoice_item(part => $part1, qty =>  3, sellprice => 70),
44                     create_invoice_item(part => $part2, qty => 10, sellprice => 50),
45                   ],
46   department_id    => $department->id,
47   globalproject_id => $project->id,
48 );
49 $invoice->pay_invoice(chart_id      => $bank->id,
50                       amount        => $invoice->open_amount,
51                       transdate     => $payment_date->to_kivitendo,
52                       memo          => 'foobar',
53                       source        => 'barfoo',
54                      );
55 my $datev1 = SL::DATEV->new(
56   dbh        => $invoice->db->dbh,
57   trans_id   => $invoice->id,
58 );
59 $datev1->generate_datev_data;
60 cmp_bag $datev1->generate_datev_lines, [
61                                          {
62                                            'belegfeld1'   => "\x{de} sales \x{a5}& inv\x{f6}ice",
63                                            'buchungstext' => 'Testcustomer',
64                                            'datum'        => '01.01.2017',
65                                            'gegenkonto'   => '8400',
66                                            'konto'        => '1400',
67                                            'kost1'        => 'Kostenstelle DATEV-Schnittstelle 2018',
68                                            'kost2'        => 'Crowd-Funding September 2017',
69                                            'umsatz'       => '249.9',
70                                            'waehrung'     => 'EUR',
71                                            'soll_haben_kennzeichen' => 'S',
72                                          },
73                                          {
74                                            'belegfeld1'   => "\x{de} sales \x{a5}& inv\x{f6}ice",
75                                            'buchungstext' => 'Testcustomer',
76                                            'datum'        => '01.01.2017',
77                                            'gegenkonto'   => '8300',
78                                            'konto'        => '1400',
79                                            'kost1'        => 'Kostenstelle DATEV-Schnittstelle 2018',
80                                            'kost2'        => 'Crowd-Funding September 2017',
81                                            'umsatz'       => 535,
82                                            'waehrung'     => 'EUR',
83                                            'soll_haben_kennzeichen' => 'S',
84                                          },
85                                          {
86                                            'belegfeld1'   => "\x{de} sales \x{a5}& inv\x{f6}ice",
87                                            'buchungstext' => 'Testcustomer',
88                                            'datum'        => '05.01.2017',
89                                            'gegenkonto'   => '1400',
90                                            'konto'        => '1200',
91                                            'kost1'        => 'Kostenstelle DATEV-Schnittstelle 2018',
92                                            'kost2'        => 'Crowd-Funding September 2017',
93                                            'umsatz'       => '784.9',
94                                            'waehrung'     => 'EUR',
95                                            'soll_haben_kennzeichen' => 'S',
96                                          },
97                                        ], "trans_id datev check ok";
98
99 my $startdate = DateTime->new(year => 2017, month =>  1, day =>  1);
100 my $enddate   = DateTime->new(year => 2017, month => 12, day => 31);
101
102 # check conversion to csv
103 $datev1->from($startdate);
104 $datev1->to($enddate);
105
106 # splice away the header, because sort won't do
107 # we need sort, because pay_invoice is not acc_trans_id order safe
108 my @data_csv = splice @{ $datev1->csv_buchungsexport() }, 2, 5;
109 @data_csv    = sort { $a->[0] <=> $b->[0] } @data_csv;
110
111 my $cp1252_belegfeld1   = SL::Iconv::convert("UTF-8", "CP1252", 'Þ sales ¥& i');
112 my $cp1252_buchungstext = SL::Iconv::convert("UTF-8", "CP1252", 'Þ sales ¥& invöice');
113
114 cmp_bag($data_csv[1], [ 535, 'S', 'EUR', undef, undef, undef, '1400', '8300', undef, '0101', $cp1252_belegfeld1,
115                      undef, undef, $cp1252_buchungstext, undef, undef, undef, undef, undef, undef, undef, undef,
116                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
117                      undef, 'Crowd-Fu', 'Kostenst', undef, undef, undef, undef, undef, undef, undef, undef,
118                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
119                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
120                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
121                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
122                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
123                      undef, undef, undef, undef, undef ]
124        );
125
126 cmp_bag($data_csv[0], [ '249,9', 'S', 'EUR', undef, undef, undef, '1400', '8400', undef, '0101', $cp1252_belegfeld1,
127                      undef, undef, $cp1252_buchungstext, undef, undef, undef, undef, undef, undef, undef, undef,
128                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
129                      undef, 'Crowd-Fu', 'Kostenst', undef, undef, undef, undef, undef, undef, undef, undef,
130                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
131                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
132                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
133                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
134                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
135                      undef, undef, undef, undef, undef ]
136        );
137 cmp_bag($data_csv[2], [ '784,9', 'S', 'EUR', undef, undef, undef, '1200', '1400', undef, '0501', $cp1252_belegfeld1,
138                      undef, undef, $cp1252_buchungstext, undef, undef, undef, undef, undef, undef, undef, undef,
139                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
140                      undef, 'Crowd-Fu', 'Kostenst', undef, undef, undef, undef, undef, undef, undef, undef,
141                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
142                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
143                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
144                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
145                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
146                      undef, undef, undef, undef, undef ]
147         );
148 my $march_9 = DateTime->new(year => 2017, month =>  3, day => 9);
149 my $invoice2 = create_sales_invoice(
150   invnumber    => "2 sales invoice",
151   itime        => $march_9,
152   gldate       => $march_9,
153   intnotes     => 'booked in March',
154   taxincluded  => 0,
155   transdate    => $date,
156   invoiceitems => [ create_invoice_item(part => $part1, qty =>  6, sellprice => 70),
157                     create_invoice_item(part => $part2, qty => 20, sellprice => 50),
158                   ]
159 );
160
161 my $credit_note = create_credit_note(
162   invnumber    => 'Gutschrift 34',
163   itime        => $gldate,
164   gldate       => $gldate,
165   intnotes     => 'booked in February',
166   taxincluded  => 0,
167   transdate    => $date,
168   invoiceitems => [ create_invoice_item(part => $part1, qty =>  3, sellprice => 70),
169                     create_invoice_item(part => $part2, qty => 10, sellprice => 50),
170                   ]
171 );
172
173 my $datev = SL::DATEV->new(
174   dbh        => $dbh,
175   from       => $startdate,
176   to         => $enddate,
177 );
178 $datev->generate_datev_data(from_to => $datev->fromto);
179 my $datev_lines = $datev->generate_datev_lines;
180 my $umsatzsumme = sum map { $_->{umsatz} } @{ $datev_lines };
181 cmp_ok($::form->round_amount($umsatzsumme,2), '==', 3924.5, "Sum of all bookings ok");
182
183 note('testing gldatefrom');
184 $datev = SL::DATEV->new(
185   dbh        => $dbh,
186   from       => $startdate,
187   to         => DateTime->new(year => 2017, month => 01, day => 31),
188 );
189
190 $::form               = Support::TestSetup->create_new_form;
191 $::form->{gldatefrom} = DateTime->new(year => 2017, month => 3, day => 1)->to_kivitendo;
192
193 $datev->generate_datev_data(from_to => $datev->fromto);
194 $datev_lines = $datev->generate_datev_lines;
195 $umsatzsumme = sum map { $_->{umsatz} } @{ $datev_lines };
196 cmp_ok($umsatzsumme, '==', 1569.8, "Sum of bookings made after March 1st (only invoice2) ok");
197
198 $::form->{gldatefrom} = DateTime->new(year => 2017, month => 5, day => 1)->to_kivitendo;
199 $datev->generate_datev_data(from_to => $datev->fromto);
200 cmp_bag $datev->generate_datev_lines, [], "no bookings for January made after May 1st: ok";
201
202 done_testing();
203 clear_up();
204
205 sub clear_up {
206   SL::DB::Manager::AccTransaction->delete_all(all => 1);
207   SL::DB::Manager::InvoiceItem->delete_all(   all => 1);
208   SL::DB::Manager::Invoice->delete_all(       all => 1);
209   SL::DB::Manager::Customer->delete_all(      all => 1);
210   SL::DB::Manager::Part->delete_all(          all => 1);
211   SL::DB::Manager::Project->delete_all(       all => 1);
212   SL::DB::Manager::Department->delete_all(    all => 1);
213   SL::DATEV->clean_temporary_directories;
214 };
215
216 1;