DATEV Format 2018 Backend, Musterdateien und Tests
[kivitendo-erp.git] / t / datev / datev_format_2018.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 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 eval {
72   $datev1->csv_buchungsexport();
73   1;  };
74 like($@, qr/^Not a valid value: '' for 'belegfeld1' with .*/, "wrong encoding");
75
76 # redefine invnumber, but still broken
77 $invoice->invnumber('ݗݘݰݶmuh');
78 $invoice->save();
79 $datev1->generate_datev_data;
80 $datev1->generate_datev_lines;
81 eval {
82   $datev1->csv_buchungsexport();
83   1;  };
84 like($@, qr/^Not a valid value: '' for 'belegfeld1' with amount/, "mixed encoding");
85
86
87 # create one haben buchung with GLTransaction today
88
89 my $expense_chart = SL::DB::Manager::Chart->find_by(accno => '4660'); # Reisekosten
90 my $cash_chart    = SL::DB::Manager::Chart->find_by(accno => '1000'); # Kasse
91 my $tax_chart     = SL::DB::Manager::Chart->find_by(accno => '1576'); # Vorsteuer
92 my $tax_9         = SL::DB::Manager::Tax->find_by(taxkey => 9, rate => 0.19) || die "No tax";
93
94 my @acc_trans;
95 push(@acc_trans, SL::DB::AccTransaction->new(
96                                       chart_id   => $expense_chart->id,
97                                       chart_link => $expense_chart->link,
98                                       amount     => -84.03,
99                                       transdate  => $today,
100                                       source     => '',
101                                       taxkey     => 9,
102                                       tax_id     => $tax_9->id,
103                                       project_id => $project->id,
104 ));
105 push(@acc_trans, SL::DB::AccTransaction->new(
106                                       chart_id   => $tax_chart->id,
107                                       chart_link => $tax_chart->link,
108                                       amount     => -15.97,
109                                       transdate  => $today,
110                                       source     => '',
111                                       taxkey     => 9,
112                                       tax_id     => $tax_9->id,
113                                       project_id => $project->id,
114 ));
115 push(@acc_trans, SL::DB::AccTransaction->new(
116                                       chart_id   => $cash_chart->id,
117                                       chart_link => $cash_chart->link,
118                                       amount     => 100,
119                                       transdate  => $today,
120                                       source     => '',
121                                       taxkey     => 0,
122                                       tax_id     => 0,
123 ));
124
125 my $gl_transaction = SL::DB::GLTransaction->new(
126   reference      => "Reisekosten März 2018",
127   description    => "Reisekonsten März 2018 / Ma Schmidt",
128   transdate      => $today,
129   gldate         => $today,
130   employee_id    => SL::DB::Manager::Employee->current->id,
131   taxincluded    => 1,
132   type           => undef,
133   ob_transaction => 0,
134   cb_transaction => 0,
135   storno         => 0,
136   storno_id      => undef,
137   transactions   => \@acc_trans,
138 )->save;
139 my $datev2 = SL::DATEV->new(
140   dbh        => $dbh,
141   trans_id   => $gl_transaction->id,
142 );
143
144 $datev2->from($startdate);
145 $datev2->to($enddate);
146 $datev2->generate_datev_data;
147 $datev2->generate_datev_lines;
148
149 my @data_csv = splice @{ $datev2->csv_buchungsexport() }, 2, 5;
150 @data_csv    = sort { $a->[0] <=> $b->[0] } @data_csv;
151
152
153 my $cp1252_posting_text   = SL::Iconv::convert("UTF-8", "CP1252", 'Reisekosten März 2018');
154 cmp_bag($data_csv[0], [ 100, 'H', 'EUR', undef, undef, undef, '4660', '1000', 9, '1703', 'Reisekosten ',
155                      undef, undef, $cp1252_posting_text, undef, undef, undef, undef, undef, undef, undef, undef,
156                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
157                      undef, undef, '', undef, undef, undef, undef, undef, undef, undef, undef,
158                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
159                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
160                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
161                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
162                      undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
163                      undef, undef, undef, undef, undef ]
164        );
165
166 done_testing();
167 clear_up();
168
169
170 sub clear_up {
171   SL::DB::Manager::AccTransaction->delete_all( all => 1);
172   SL::DB::Manager::InvoiceItem->delete_all(    all => 1);
173   SL::DB::Manager::Invoice->delete_all(        all => 1);
174   SL::DB::Manager::Customer->delete_all(       all => 1);
175   SL::DB::Manager::Part->delete_all(           all => 1);
176   SL::DB::Manager::Project->delete_all(        all => 1);
177   SL::DB::Manager::Department->delete_all(     all => 1);
178   SL::DATEV->clean_temporary_directories;
179 };
180
181 1;