Revision ee33349b
Von Bernd Bleßmann vor mehr als 1 Jahr hinzugefügt
t/controllers/csvimport/aptransactions.t | ||
---|---|---|
1 |
use Test::More; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use lib 't'; |
|
6 |
|
|
7 |
use Carp; |
|
8 |
use Support::TestSetup; |
|
9 |
use Test::Exception; |
|
10 |
|
|
11 |
use SL::Dev::ALL qw(:ALL); |
|
12 |
|
|
13 |
use SL::Controller::CsvImport; |
|
14 |
|
|
15 |
use_ok 'SL::Controller::CsvImport::APTransaction'; |
|
16 |
|
|
17 |
use SL::DB::AccTransaction; |
|
18 |
use SL::DB::Buchungsgruppe; |
|
19 |
use SL::DB::Chart; |
|
20 |
use SL::DB::Currency; |
|
21 |
use SL::DB::Employee; |
|
22 |
use SL::DB::Invoice; |
|
23 |
use SL::DB::TaxZone; |
|
24 |
use SL::DB::Vendor; |
|
25 |
|
|
26 |
my ($vendor, $currency_id, $employee, $taxzone, $project, $department); |
|
27 |
my ($transdate, $transdate_string); |
|
28 |
|
|
29 |
sub clear_up { |
|
30 |
SL::DB::Manager::AccTransaction->delete_all (all => 1); |
|
31 |
SL::DB::Manager::PurchaseInvoice->delete_all(all => 1); |
|
32 |
SL::DB::Manager::Vendor->delete_all (all => 1); |
|
33 |
SL::DB::Manager::Project->delete_all (all => 1); |
|
34 |
SL::DB::Manager::Department->delete_all (all => 1); |
|
35 |
}; |
|
36 |
|
|
37 |
sub reset_state { |
|
38 |
# Create test data |
|
39 |
my %params = @_; |
|
40 |
|
|
41 |
$transdate = DateTime->today_local; |
|
42 |
$transdate->set_year(2019) if $transdate->year == 2020; # hardcode for 2019 in 2020, because of tax rate change in Germany |
|
43 |
$transdate_string = $transdate->to_kivitendo; |
|
44 |
|
|
45 |
$params{$_} ||= {} for qw(buchungsgruppe vendor tax); |
|
46 |
|
|
47 |
clear_up(); |
|
48 |
$employee = SL::DB::Manager::Employee->current || croak "No employee"; |
|
49 |
$taxzone = SL::DB::Manager::TaxZone->find_by( description => 'Inland') || croak "No taxzone"; |
|
50 |
$currency_id = $::instance_conf->get_currency_id; |
|
51 |
|
|
52 |
$vendor = new_vendor( |
|
53 |
currency_id => $currency_id, |
|
54 |
taxzone_id => $taxzone->id, |
|
55 |
%{ $params{vendor} }, |
|
56 |
)->save; |
|
57 |
|
|
58 |
$project = SL::DB::Project->new( |
|
59 |
projectnumber => 'P1', |
|
60 |
description => 'Project X', |
|
61 |
project_type => SL::DB::Manager::ProjectType->find_by(description => 'Standard'), |
|
62 |
project_status => SL::DB::Manager::ProjectStatus->find_by(name => 'running'), |
|
63 |
)->save; |
|
64 |
|
|
65 |
$department = SL::DB::Department->new( |
|
66 |
description => 'Department 1', |
|
67 |
)->save; |
|
68 |
} |
|
69 |
|
|
70 |
Support::TestSetup::login(); |
|
71 |
|
|
72 |
reset_state(vendor => {vendornumber => 2}); |
|
73 |
|
|
74 |
##### |
|
75 |
sub test_import { |
|
76 |
my $file = shift; |
|
77 |
|
|
78 |
my $controller = SL::Controller::CsvImport->new( |
|
79 |
type => 'ap_transactions' |
|
80 |
); |
|
81 |
$controller->load_default_profile; |
|
82 |
$controller->profile->set( |
|
83 |
charset => 'utf-8', |
|
84 |
sep_char => ',', |
|
85 |
quote_char => '"', |
|
86 |
numberformat => $::myconfig{numberformat}, |
|
87 |
); |
|
88 |
|
|
89 |
my $csv_aptransactions_import = SL::Controller::CsvImport::APTransaction->new( |
|
90 |
settings => {'ap_column' => 'Rechnung', |
|
91 |
'transaction_column' => 'AccTransaction', |
|
92 |
'max_amount_diff' => 0.02 |
|
93 |
}, |
|
94 |
controller => $controller, |
|
95 |
file => $file, |
|
96 |
); |
|
97 |
|
|
98 |
$csv_aptransactions_import->run(test => 0); |
|
99 |
|
|
100 |
# don't try and save objects that have errors |
|
101 |
$csv_aptransactions_import->save_objects unless scalar @{$csv_aptransactions_import->controller->data->[0]->{errors}}; |
|
102 |
|
|
103 |
return $csv_aptransactions_import->controller->data; |
|
104 |
} |
|
105 |
|
|
106 |
##### manually create an ap transaction from scratch, testing the methods |
|
107 |
$::myconfig{numberformat} = '1000.00'; |
|
108 |
$::myconfig{dateformat} = 'dd.mm.yyyy'; |
|
109 |
my $old_locale = $::locale; |
|
110 |
# set locale to en so we can match errors |
|
111 |
$::locale = Locale->new('en'); |
|
112 |
|
|
113 |
my $amount = 10; |
|
114 |
|
|
115 |
my $ap = SL::DB::PurchaseInvoice->new( |
|
116 |
invoice => 0, |
|
117 |
invnumber => 'manual invoice', |
|
118 |
taxzone_id => $taxzone->id, |
|
119 |
currency_id => $currency_id, |
|
120 |
taxincluded => 'f', |
|
121 |
vendor_id => $vendor->id, |
|
122 |
transdate => $transdate, |
|
123 |
employee_id => SL::DB::Manager::Employee->current->id, |
|
124 |
transactions => [], |
|
125 |
); |
|
126 |
|
|
127 |
my $tax9 = SL::DB::Manager::Tax->find_by(rate => 0.19, taxkey => 9) || die "can't find tax with taxkey 9"; |
|
128 |
my $income_chart = SL::DB::Manager::Chart->find_by(accno => '3400') || die "can't find expense chart"; |
|
129 |
|
|
130 |
$ap->add_ap_amount_row( |
|
131 |
amount => $amount, |
|
132 |
chart => $income_chart, |
|
133 |
tax_id => $tax9->id, |
|
134 |
); |
|
135 |
|
|
136 |
$ap->recalculate_amounts; # set amount and netamount from transactions |
|
137 |
is $ap->amount, '10', 'amount of manual invoice is 10'; |
|
138 |
is $ap->netamount, '8.4', 'netamount of manual invoice is 10'; |
|
139 |
|
|
140 |
$ap->create_ap_row( chart => SL::DB::Manager::Chart->find_by(accno => '1600', link => 'AP') ); |
|
141 |
my $result = $ap->validate_acc_trans(); |
|
142 |
is $result, 1, 'manual $ap validates'; |
|
143 |
|
|
144 |
$ap->save; |
|
145 |
is ${ $ap->transactions }[0]->chart->accno, '3400', 'assigned expense chart after save ok'; |
|
146 |
is ${ $ap->transactions }[2]->chart->accno, '1600', 'assigned payable chart after save ok'; |
|
147 |
is scalar @{$ap->transactions}, 3, 'manual invoice has 3 acc_trans entries'; |
|
148 |
|
|
149 |
$ap->pay_invoice( chart_id => SL::DB::Manager::Chart->find_by(accno => '1200')->id, # bank |
|
150 |
amount => $ap->open_amount, |
|
151 |
transdate => $transdate, |
|
152 |
payment_type => 'without_skonto', # default if not specified |
|
153 |
); |
|
154 |
$result = $ap->validate_acc_trans(); |
|
155 |
is $result, 1, 'manual invoice validates after payment'; |
|
156 |
|
|
157 |
##### |
|
158 |
reset_state(vendor => {vendornumber => 2}); |
|
159 |
|
|
160 |
my ($entries, $entry, $file); |
|
161 |
my $saved_invoices = 0; |
|
162 |
|
|
163 |
# starting test of csv imports |
|
164 |
# to debug errors in certain tests, run after test_import: |
|
165 |
# $::lxdebug->dump(0, "entry 0 errors: ", $entry->{errors}->[0]); |
|
166 |
##### basic test |
|
167 |
$file = \<<"EOL"; |
|
168 |
datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate |
|
169 |
datatype,accno,amount,taxkey |
|
170 |
"Rechnung",2,1,"invoice 1",f,1600,"$transdate_string" |
|
171 |
"AccTransaction",3400,159.48,9 |
|
172 |
EOL |
|
173 |
$entries = test_import($file); |
|
174 |
is $entries->[0]->{errors}->[0], undef, 'basic test: no errors in ap row'; |
|
175 |
is $entries->[1]->{errors}->[0], undef, 'basic test: no errors in acc_trans row'; |
|
176 |
|
|
177 |
$entry = $entries->[0]; |
|
178 |
is $entry->{object}->validate_acc_trans, 1, 'basic test: acc_trans validates'; |
|
179 |
is $entry->{object}->invnumber, 'invoice 1', 'basic test: invnumber ok'; |
|
180 |
is $entry->{object}->vendor_id, $vendor->id, 'basic test: vendor_id ok'; |
|
181 |
is scalar @{$entry->{object}->transactions}, 3, 'basic test: invoice 1 has 3 acc_trans entries'; |
|
182 |
is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), -159.48, 'basic test: invoice 1 ap amount is -159.48'; |
|
183 |
is $entry->{object}->direct_debit, '0', 'basic test: no direct debit'; |
|
184 |
is $entry->{object}->taxincluded, '0', 'basic test: taxincluded is false'; |
|
185 |
is $entry->{object}->amount, '189.78', 'basic test: ap amount tax not included is 189.78'; |
|
186 |
is $entry->{object}->netamount, '159.48', 'basic test: ap netamount tax not included is 159.48'; |
|
187 |
|
|
188 |
$saved_invoices++; |
|
189 |
|
|
190 |
##### test for duplicate invnumber |
|
191 |
# $file = \<<"EOL"; |
|
192 |
# datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate |
|
193 |
# datatype,accno,amount,taxkey |
|
194 |
# "Rechnung",2,1,"invoice 1",f,1600,"$transdate_string" |
|
195 |
# "AccTransaction",3400,159.48,3 |
|
196 |
# EOL |
|
197 |
# $entries = test_import($file); |
|
198 |
# $entry = $entries->[0]; |
|
199 |
# $entry->{object}->validate_acc_trans; |
|
200 |
# is $entry->{errors}->[0], 'Error: invnumber already exists', 'detects verify_amount differences'; |
|
201 |
|
|
202 |
##### test for no invnumber given |
|
203 |
# $file = \<<"EOL"; |
|
204 |
# datatype,vendornumber,currency_id,taxincluded,apchart,transdate |
|
205 |
# datatype,accno,amount,taxkey |
|
206 |
# "Rechnung",2,1,f,1600,"$transdate_string" |
|
207 |
# "AccTransaction",3400,159.48,3 |
|
208 |
# EOL |
|
209 |
# $entries = test_import($file); |
|
210 |
# $entry = $entries->[0]; |
|
211 |
# $entry->{object}->validate_acc_trans; |
|
212 |
# is $entry->{object}->invnumber =~ /^\d+$/, 1, 'invnumber assigned automatically'; |
|
213 |
|
|
214 |
##### basic test without amounts in Rechnung, only specified in AccTransaction |
|
215 |
$file = \<<"EOL"; |
|
216 |
datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate |
|
217 |
datatype,accno,amount,taxkey |
|
218 |
"Rechnung",2,1,"invoice 1 no amounts",f,1600,"$transdate_string" |
|
219 |
"AccTransaction",3400,159.48,9 |
|
220 |
EOL |
|
221 |
$entries = test_import($file); |
|
222 |
is $entries->[0]->{errors}->[0], undef, 'basic test no amounts: no errors in ap row'; |
|
223 |
is $entries->[1]->{errors}->[0], undef, 'basic test no amounts: no errors in acc_trans row'; |
|
224 |
|
|
225 |
$entry = $entries->[0]; |
|
226 |
is $entry->{object}->validate_acc_trans, 1, 'basic test no amounts: acc_trans validates'; |
|
227 |
is $entry->{object}->invnumber, 'invoice 1 no amounts', 'basic test no amounts: invnumber ok'; |
|
228 |
is $entry->{object}->vendor_id, $vendor->id, 'basic test no amounts: vendor_id ok'; |
|
229 |
is scalar @{$entry->{object}->transactions}, 3, 'basic test no amounts: invoice 1 has 3 acc_trans entries'; |
|
230 |
is $::form->round_amount($entry->{object}->amount, 2), '189.78', 'basic test no amounts: not taxincluded ap amount'; |
|
231 |
is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), '-159.48', 'basic test no amounts: not taxincluded acc_trans netamount'; |
|
232 |
is $::form->round_amount($entry->{object}->netamount, 2), 159.48, 'basic test no amounts: invoice 1 ap netamount is 159.48'; |
|
233 |
|
|
234 |
$saved_invoices++; |
|
235 |
|
|
236 |
##### basic test: credit_note |
|
237 |
$file = \<<"EOL"; |
|
238 |
datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate |
|
239 |
datatype,accno,amount,taxkey |
|
240 |
"Rechnung",2,1,"credit note",f,1600,"$transdate_string" |
|
241 |
"AccTransaction",3400,-159.48,9 |
|
242 |
EOL |
|
243 |
$entries = test_import($file); |
|
244 |
is $entries->[0]->{errors}->[0], undef, 'basic test: credit_note: no errors in ap row'; |
|
245 |
is $entries->[1]->{errors}->[0], undef, 'basic test: credit_note: no errors in acc_trans row'; |
|
246 |
|
|
247 |
$entry = $entries->[0]; |
|
248 |
is $entry->{object}->validate_acc_trans, 1, 'basic test: credit_note: acc_trans validates'; |
|
249 |
is $entry->{object}->invnumber, 'credit note', 'basic test: credit_note: invnumber ok'; |
|
250 |
is scalar @{$entry->{object}->transactions}, 3, 'basic test: credit_note: credit note has 3 acc_trans entries'; |
|
251 |
is $::form->round_amount($entry->{object}->amount, 2), '-189.78', 'basic test: credit_note: taxincluded ap amount'; |
|
252 |
is $::form->round_amount($entry->{object}->netamount, 2), '-159.48', 'basic test: credit_note: taxincluded ap net amount'; |
|
253 |
is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), 159.48, 'credit note ap amount is 159.48'; |
|
254 |
|
|
255 |
$saved_invoices++; |
|
256 |
|
|
257 |
#### verify_amount differs: max_amount_diff = 0.02, 189.80 is ok, 189.81 is not |
|
258 |
$file = \<<"EOL"; |
|
259 |
datatype,vendornumber,verify_amount,verify_netamount,currency_id,invnumber,taxincluded,apchart,transdate |
|
260 |
datatype,accno,amount,taxkey |
|
261 |
"Rechnung",2,189.81,159.48,1,"invoice amounts differing",f,1600,"$transdate_string" |
|
262 |
"AccTransaction",3400,159.48,9 |
|
263 |
EOL |
|
264 |
$entries = test_import($file); |
|
265 |
|
|
266 |
$entry = $entries->[0]; |
|
267 |
is $entry->{errors}->[0], 'Amounts differ too much', 'detects verify_amount differences'; |
|
268 |
|
|
269 |
##### direct debit |
|
270 |
$file = \<<"EOL"; |
|
271 |
datatype,vendornumber,currency_id,invnumber,taxincluded,direct_debit,apchart,transdate |
|
272 |
datatype,accno,amount,taxkey |
|
273 |
"Rechnung",2,1,"invoice with direct debit",f,t,1600,"$transdate_string" |
|
274 |
"AccTransaction",3400,159.48,9 |
|
275 |
EOL |
|
276 |
|
|
277 |
$entries = test_import($file); |
|
278 |
is $entries->[0]->{errors}->[0], undef, 'direct debit: no errors in ap row'; |
|
279 |
is $entries->[1]->{errors}->[0], undef, 'direct debit: no errors in acc_trans row'; |
|
280 |
|
|
281 |
$entry = $entries->[0]; |
|
282 |
is $entry->{object}->validate_acc_trans, 1, 'direct debit: acc_trans validates'; |
|
283 |
is $entry->{object}->direct_debit, '1', 'direct debit'; |
|
284 |
|
|
285 |
$saved_invoices++; |
|
286 |
|
|
287 |
#### tax included |
|
288 |
$file = \<<"EOL"; |
|
289 |
datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate |
|
290 |
datatype,accno,amount,taxkey |
|
291 |
"Rechnung",2,1,"invoice 1 tax included no amounts",t,1600,"$transdate_string" |
|
292 |
"AccTransaction",3400,189.78,9 |
|
293 |
EOL |
|
294 |
|
|
295 |
$entries = test_import($file); |
|
296 |
$entry = $entries->[0]; |
|
297 |
|
|
298 |
is $entry->{errors}->[0], undef, 'tax included: no errors in ap row'; |
|
299 |
is $entry->{errors}->[1], undef, 'tax included: no errors in acc_trans row'; |
|
300 |
|
|
301 |
is $entry->{object}->validate_acc_trans, 1, 'tax included: acc_trans validates'; |
|
302 |
|
|
303 |
is $entry->{object}->taxincluded, '1', 'tax included: taxincluded is true'; |
|
304 |
is $::form->round_amount($entry->{object}->amount, 2), '189.78', 'tax included: ap amount'; |
|
305 |
is $::form->round_amount($entry->{object}->netamount, 2), '159.48', 'tax included: ap net amount'; |
|
306 |
is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), '-159.48', 'tax included: acc_trans netamount'; |
|
307 |
|
|
308 |
$saved_invoices++; |
|
309 |
|
|
310 |
#### multiple tax included |
|
311 |
$file = \<<"EOL"; |
|
312 |
datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate |
|
313 |
datatype,accno,amount,taxkey |
|
314 |
"Rechnung",2,1,"invoice multiple tax included",t,1600,"$transdate_string" |
|
315 |
"AccTransaction",3400,94.89,9 |
|
316 |
"AccTransaction",3400,94.89,9 |
|
317 |
EOL |
|
318 |
|
|
319 |
$entries = test_import($file); |
|
320 |
is $entries->[0]->{errors}->[0], undef, 'multiple tax included: no errors in ap row'; |
|
321 |
is $entries->[1]->{errors}->[0], undef, 'multiple tax included: no errors in 1. acc_trans row'; |
|
322 |
is $entries->[2]->{errors}->[0], undef, 'multiple tax included: no errors in 2. acc_trans row'; |
|
323 |
|
|
324 |
$entry = $entries->[0]; |
|
325 |
is $entry->{object}->validate_acc_trans, 1, 'multiple tax included: acc_trans validates'; |
|
326 |
|
|
327 |
is $::form->round_amount($entry->{object}->amount, 2), '189.78', 'multiple tax included: ap amount'; |
|
328 |
is $::form->round_amount($entry->{object}->netamount, 2), '159.48', 'multiple tax included: ap netamount'; |
|
329 |
is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), '-79.74', 'multiple tax included: amount'; |
|
330 |
is $::form->round_amount($entry->{object}->transactions->[1]->amount, 2), '-15.15', 'multiple tax included: tax'; |
|
331 |
|
|
332 |
$saved_invoices++; |
|
333 |
|
|
334 |
# different payable chart |
|
335 |
$file = \<<EOL; |
|
336 |
datatype,vendornumber,currency_id,invnumber,taxincluded,apchart |
|
337 |
datatype,accno,amount,taxkey |
|
338 |
"Rechnung",2,1,"invoice mit apchart 1605",f,1605 |
|
339 |
"AccTransaction",3400,159.48,9 |
|
340 |
EOL |
|
341 |
|
|
342 |
$entries = test_import($file); |
|
343 |
is $entries->[0]->{errors}->[0], undef, 'different payable chart: no errors in ap row'; |
|
344 |
is $entries->[1]->{errors}->[0], undef, 'different payable chart: no errors in acc_trans row'; |
|
345 |
|
|
346 |
$entry = $entries->[0]; |
|
347 |
is $entry->{object}->validate_acc_trans, 1, 'different payable chart: acc_trans validates'; |
|
348 |
is $entry->{object}->transactions->[2]->chart->accno, '1605', 'different payable chart: apchart set to 1605'; |
|
349 |
|
|
350 |
$saved_invoices++; |
|
351 |
|
|
352 |
# missing vendor |
|
353 |
$file = \<<EOL; |
|
354 |
datatype,currency_id,invnumber,taxincluded,apchart |
|
355 |
datatype,accno,amount,taxkey |
|
356 |
"Rechnung",1,"invoice missing vendor",f,1600 |
|
357 |
"AccTransaction",3400,159.48,9 |
|
358 |
EOL |
|
359 |
|
|
360 |
$entries = test_import($file); |
|
361 |
$entry = $entries->[0]; |
|
362 |
is $entry->{errors}->[0], 'Error: Vendor missing', 'detects missing vendor'; |
|
363 |
|
|
364 |
##### vendor by name |
|
365 |
$file = \<<EOL; |
|
366 |
datatype,vendor,currency_id,invnumber,taxincluded,apchart |
|
367 |
datatype,accno,amount,taxkey |
|
368 |
"Rechnung","Testlieferant",1,"invoice vendor name",f,1600 |
|
369 |
"AccTransaction",3400,159.48,9 |
|
370 |
EOL |
|
371 |
|
|
372 |
$entries = test_import($file); |
|
373 |
is $entries->[0]->{errors}->[0], undef, 'vendor by name: no errors in ap row'; |
|
374 |
is $entries->[1]->{errors}->[0], undef, 'vendor by name: no errors in acc_trans row'; |
|
375 |
|
|
376 |
$entry = $entries->[0]; |
|
377 |
is $entry->{object}->validate_acc_trans, 1, 'vendor by name: acc_trans validates'; |
|
378 |
is $entry->{object}->vendor->name, "Testlieferant", 'detects vendor by name'; |
|
379 |
|
|
380 |
$saved_invoices++; |
|
381 |
|
|
382 |
##### detect missing chart |
|
383 |
$file = \<<EOL; |
|
384 |
datatype,currency_id,invnumber,vendor,apchart |
|
385 |
datatype,amount,taxkey |
|
386 |
"Rechnung",1,"invoice missing chart","Testlieferant",1600 |
|
387 |
"AccTransaction",4,9 |
|
388 |
EOL |
|
389 |
|
|
390 |
$entries = test_import($file); |
|
391 |
|
|
392 |
$entry = $entries->[1]; |
|
393 |
is $entry->{errors}->[0], 'Error: chart missing', 'detects missing chart (chart_id or accno)'; |
|
394 |
|
|
395 |
##### detect illegal chart by accno |
|
396 |
$file = \<<EOL; |
|
397 |
datatype,currency_id,invnumber,vendor,apchart |
|
398 |
datatype,accno,amount,taxkey |
|
399 |
"Rechnung",1,"invoice illegal chart accno","Testlieferant",1600 |
|
400 |
"AccTransaction",9999,4,9 |
|
401 |
EOL |
|
402 |
|
|
403 |
$entries = test_import($file); |
|
404 |
|
|
405 |
$entry = $entries->[1]; |
|
406 |
is $entry->{errors}->[0], 'Error: invalid chart (accno)', 'detects invalid chart (chart_id or accno)'; |
|
407 |
|
|
408 |
# ##### detect illegal apchart |
|
409 |
$file = \<<EOL; |
|
410 |
datatype,currency_id,invnumber,vendor,taxincluded,apchart |
|
411 |
datatype,accno,amount,taxkey |
|
412 |
"Rechnung",1,"invoice illegal apchart","Testlieferant",f,11600 |
|
413 |
"AccTransaction",3400,159.48,9 |
|
414 |
EOL |
|
415 |
|
|
416 |
$entries = test_import($file); |
|
417 |
|
|
418 |
$entry = $entries->[0]; |
|
419 |
is $entry->{errors}->[0], "Error: can't find ap chart with accno 11600", 'detects illegal payable chart (apchart)'; |
|
420 |
|
|
421 |
##### detect chart by id |
|
422 |
$file = \<<EOL; |
|
423 |
datatype,currency_id,invnumber,vendor,taxincluded,apchart |
|
424 |
datatype,amount,chart_id,taxkey |
|
425 |
"Rechnung",1,"invoice chart_id","Testlieferant",f,1600 |
|
426 |
"AccTransaction",159.48,37,9 |
|
427 |
EOL |
|
428 |
|
|
429 |
$entries = test_import($file); |
|
430 |
is $entries->[0]->{errors}->[0], undef, 'detect chart by id: no errors in ap row'; |
|
431 |
is $entries->[1]->{errors}->[0], undef, 'detect chart by id: no errors in acc_trans row'; |
|
432 |
|
|
433 |
$entry = $entries->[0]; |
|
434 |
is $entry->{object}->validate_acc_trans, 1, 'detect chart by id: acc_trans validates'; |
|
435 |
|
|
436 |
$entry = $entries->[1]; # acc_trans entry is at entry array pos 1 |
|
437 |
is $entry->{object}->chart->id, "37", 'detects chart by id'; |
|
438 |
|
|
439 |
$saved_invoices++; |
|
440 |
|
|
441 |
##### detect chart by accno |
|
442 |
$file = \<<EOL; |
|
443 |
datatype,currency_id,invnumber,vendor,taxincluded,apchart |
|
444 |
datatype,amount,accno,taxkey |
|
445 |
"Rechnung",1,"invoice by chart accno","Testlieferant",f,1600 |
|
446 |
"AccTransaction",159.48,3400,9 |
|
447 |
EOL |
|
448 |
|
|
449 |
$entries = test_import($file); |
|
450 |
is $entries->[0]->{errors}->[0], undef, 'detect chart by accno: no errors in ap row'; |
|
451 |
is $entries->[1]->{errors}->[0], undef, 'detect chart by accno: no errors in acc_trans row'; |
|
452 |
|
|
453 |
$entry = $entries->[0]; |
|
454 |
is $entry->{object}->validate_acc_trans, 1, 'detect chart by accno: acc_trans validates'; |
|
455 |
|
|
456 |
$entry = $entries->[1]; |
|
457 |
is $entry->{object}->chart->accno, "3400", 'detects chart by accno'; |
|
458 |
|
|
459 |
$saved_invoices++; |
|
460 |
|
|
461 |
##### detect chart isn't an ap_chart |
|
462 |
$file = \<<EOL; |
|
463 |
datatype,currency_id,invnumber,vendor,taxincluded,apchart |
|
464 |
datatype,amount,accno,taxkey |
|
465 |
"Rechnung",1,"invoice by chart accno","Testlieferant",f,1600 |
|
466 |
"AccTransaction",159.48,1600,9 |
|
467 |
EOL |
|
468 |
|
|
469 |
$entries = test_import($file); |
|
470 |
|
|
471 |
$entry = $entries->[1]; |
|
472 |
is $entry->{errors}->[0], 'Error: chart isn\'t an ap_amount chart', 'detects valid chart that is not an ap_amount chart'; |
|
473 |
|
|
474 |
# missing taxkey |
|
475 |
$file = \<<EOL; |
|
476 |
datatype,currency_id,invnumber,vendor,apchart |
|
477 |
datatype,amount,accno |
|
478 |
"Rechnung",1,"invoice missing taxkey chart accno","Testlieferant",1600 |
|
479 |
"AccTransaction",159.48,3400 |
|
480 |
EOL |
|
481 |
|
|
482 |
$entries = test_import($file); |
|
483 |
|
|
484 |
$entry = $entries->[1]; |
|
485 |
is $entry->{errors}->[0], 'Error: taxkey missing', 'detects missing taxkey (DATEV Steuerschlüssel)'; |
|
486 |
|
|
487 |
# illegal taxkey |
|
488 |
$file = \<<EOL; |
|
489 |
datatype,currency_id,invnumber,vendor,apchart |
|
490 |
datatype,amount,accno,taxkey |
|
491 |
"Rechnung",1,"invoice illegal taxkey","Testlieferant",1600 |
|
492 |
"AccTransaction",4,3400,123 |
|
493 |
EOL |
|
494 |
|
|
495 |
$entries = test_import($file); |
|
496 |
|
|
497 |
$entry = $entries->[1]; |
|
498 |
is $entry->{errors}->[0], 'Error: invalid taxkey', 'detects invalid taxkey (DATEV Steuerschlüssel)'; |
|
499 |
|
|
500 |
# taxkey |
|
501 |
$file = \<<EOL; |
|
502 |
datatype,vendornumber,currency_id,invnumber,apchart,taxincluded |
|
503 |
datatype,accno,amount,taxkey |
|
504 |
"Rechnung",2,1,"invoice by taxkey",1600,1 |
|
505 |
"AccTransaction",3400,4,9 |
|
506 |
EOL |
|
507 |
|
|
508 |
$entries = test_import($file); |
|
509 |
is $entries->[0]->{errors}->[0], undef, 'taxkey: no errors in ap row'; |
|
510 |
is $entries->[1]->{errors}->[0], undef, 'taxkey: no errors in acc_trans row'; |
|
511 |
|
|
512 |
$entry = $entries->[1]; |
|
513 |
is $entry->{object}->taxkey, 9, 'detects taxkey'; |
|
514 |
|
|
515 |
$saved_invoices++; |
|
516 |
|
|
517 |
# acc_trans project |
|
518 |
$file = \<<EOL; |
|
519 |
datatype,vendornumber,currency_id,invnumber,apchart,taxincluded |
|
520 |
datatype,accno,amount,taxkey,projectnumber |
|
521 |
"Rechnung",2,1,"invoice with acc_trans project",1600,f |
|
522 |
"AccTransaction",3400,159.48,9,P1 |
|
523 |
EOL |
|
524 |
|
|
525 |
$entries = test_import($file); |
|
526 |
is $entries->[0]->{errors}->[0], undef, 'acc_trans project: no errors in ap row'; |
|
527 |
is $entries->[1]->{errors}->[0], undef, 'acc_trans project: no errors in acc_trans row'; |
|
528 |
|
|
529 |
$entry = $entries->[1]; |
|
530 |
is $entry->{object}->project->projectnumber, 'P1', 'detects acc_trans project'; |
|
531 |
|
|
532 |
$saved_invoices++; |
|
533 |
|
|
534 |
##### various tests |
|
535 |
$file = \<<EOL; |
|
536 |
datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate,duedate,globalprojectnumber,department |
|
537 |
datatype,accno,amount,taxkey,projectnumber |
|
538 |
"Rechnung",2,1,"invoice various",t,1600,21.04.2016,30.04.2016,P1,Department 1 |
|
539 |
"AccTransaction",3400,119,9,P1 |
|
540 |
"AccTransaction",3300,107,8,P1 |
|
541 |
"AccTransaction",3559,100,0,P1 |
|
542 |
EOL |
|
543 |
|
|
544 |
$entries = test_import($file); |
|
545 |
is $entries->[0]->{errors}->[0], undef, 'various tests: errors in ap row'; |
|
546 |
is $entries->[1]->{errors}->[0], undef, 'various tests: no errors in 1. acc_trans row'; |
|
547 |
is $entries->[2]->{errors}->[0], undef, 'various tests: no errors in 2. acc_trans row'; |
|
548 |
is $entries->[3]->{errors}->[0], undef, 'various tests: no errors in 3. acc_trans row'; |
|
549 |
|
|
550 |
$entry = $entries->[0]; |
|
551 |
is $entry->{object}->validate_acc_trans, 1, 'various tests: acc_trans validates'; |
|
552 |
|
|
553 |
is $entry->{object}->duedate->to_kivitendo, '30.04.2016', 'various tests: duedate'; |
|
554 |
is $entry->{object}->transdate->to_kivitendo, '21.04.2016', 'various tests: transdate'; |
|
555 |
is $entry->{object}->globalproject->description, 'Project X', 'various tests: project'; |
|
556 |
is $entry->{object}->department->description, 'Department 1', 'various tests: department'; |
|
557 |
# 3300 is third entry after 3400 and tax for 3400 |
|
558 |
is $::form->round_amount($entry->{object}->transactions->[2]->amount), '-100', '3300 net amount: -100'; |
|
559 |
is $entry->{object}->transactions->[2]->taxkey, '8', '3300 has taxkey 8'; |
|
560 |
is $entry->{object}->transactions->[2]->project_id, $project->id, 'AccTrans project'; |
|
561 |
|
|
562 |
$saved_invoices++; |
|
563 |
|
|
564 |
##### ap amount test |
|
565 |
$file = \<<EOL; |
|
566 |
datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate,duedate,globalprojectnumber,department |
|
567 |
datatype,accno,amount,taxkey,projectnumber |
|
568 |
"Rechnung",2,1,"invoice various 1",t,1600,21.04.2016,30.04.2016,P1,Department 1 |
|
569 |
"AccTransaction",3400,119,9,P1 |
|
570 |
"AccTransaction",3300,107,8,P1 |
|
571 |
"AccTransaction",3559,100,0,P1 |
|
572 |
"Rechnung",2,1,"invoice various 2",t,1600,21.04.2016,30.04.2016,P1,Department 1 |
|
573 |
"AccTransaction",3400,119,9,P1 |
|
574 |
"AccTransaction",3400,107,8,P1 |
|
575 |
"AccTransaction",3559,100,0,P1 |
|
576 |
EOL |
|
577 |
|
|
578 |
$entries = test_import($file); |
|
579 |
is $entries->[0]->{errors}->[0], undef, 'ap amount test: no errors in 1. ap row'; |
|
580 |
is $entries->[1]->{errors}->[0], undef, 'ap amount test: no errors in 1. acc_trans row (ap row 1)'; |
|
581 |
is $entries->[2]->{errors}->[0], undef, 'ap amount test: no errors in 2. acc_trans row (ap row 1)'; |
|
582 |
is $entries->[3]->{errors}->[0], undef, 'ap amount test: no errors in 3. acc_trans row (ap row 1)'; |
|
583 |
is $entries->[4]->{errors}->[0], undef, 'ap amount test: no errors in 2. ap row'; |
|
584 |
is $entries->[5]->{errors}->[0], undef, 'ap amount test: no errors in 1. acc_trans row (ap row 2)'; |
|
585 |
is $entries->[6]->{errors}->[0], undef, 'ap amount test: no errors in 2. acc_trans row (ap row 2)'; |
|
586 |
is $entries->[7]->{errors}->[0], undef, 'ap amount test: no errors in 3. acc_trans row (ap row 2)'; |
|
587 |
|
|
588 |
$entry = $entries->[0]; |
|
589 |
is $entry->{object}->validate_acc_trans, 1, 'ap amount test: acc_trans validates'; |
|
590 |
is $entry->{object}->duedate->to_kivitendo, '30.04.2016', 'duedate'; |
|
591 |
is $entry->{info_data}->{amount}, '326', "First invoice amount displayed in info data"; |
|
592 |
$entry = $entries->[4]; |
|
593 |
is $entry->{info_data}->{amount}, '326', "Second invoice amount displayed in info data"; |
|
594 |
|
|
595 |
$saved_invoices++; |
|
596 |
$saved_invoices++; |
|
597 |
|
|
598 |
# multiple entries, taxincluded = f |
|
599 |
$file = \<<EOL; |
|
600 |
datatype,vendornumber,currency_id,invnumber,taxincluded,apchart |
|
601 |
datatype,accno,amount,taxkey |
|
602 |
"Rechnung",2,1,"invoice 4 acc_trans",f,1600 |
|
603 |
"AccTransaction",3400,39.87,9 |
|
604 |
"AccTransaction",3400,39.87,9 |
|
605 |
"AccTransaction",3400,39.87,9 |
|
606 |
"AccTransaction",3400,39.87,9 |
|
607 |
"Rechnung",2,1,"invoice 4 acc_trans 2",f,1600 |
|
608 |
"AccTransaction",3400,39.87,9 |
|
609 |
"AccTransaction",3400,39.87,9 |
|
610 |
"AccTransaction",3400,39.87,9 |
|
611 |
"AccTransaction",3400,39.87,9 |
|
612 |
"Rechnung",2,1,"invoice 4 acc_trans 3",f,1600 |
|
613 |
"AccTransaction",3400,39.87,9 |
|
614 |
"AccTransaction",3400,39.87,9 |
|
615 |
"AccTransaction",3400,39.87,9 |
|
616 |
"AccTransaction",3400,39.87,9 |
|
617 |
"Rechnung",2,1,"invoice 4 acc_trans 4",f,1605 |
|
618 |
"AccTransaction",3400,39.87,9 |
|
619 |
"AccTransaction",3400,39.87,9 |
|
620 |
"AccTransaction",3400,39.87,9 |
|
621 |
"AccTransaction",3400,39.87,9 |
|
622 |
EOL |
|
623 |
|
|
624 |
$entries = test_import($file); |
|
625 |
|
|
626 |
my $i = 0; |
|
627 |
foreach my $entry ( @$entries ) { |
|
628 |
next unless $entry->{object}->isa('SL::DB::PurchaseInvoice'); |
|
629 |
$i++; |
|
630 |
is scalar @{$entry->{object}->transactions}, 9, "multiple entries: invoice $i: 'acc_trans' has 9 acc_trans entries"; |
|
631 |
$entry->{object}->validate_acc_trans; |
|
632 |
is $entry->{object}->validate_acc_trans, 1, "multiple entries: invoice $i: 'acc_trans validates'"; |
|
633 |
} |
|
634 |
|
|
635 |
$saved_invoices++; |
|
636 |
$saved_invoices++; |
|
637 |
$saved_invoices++; |
|
638 |
$saved_invoices++; |
|
639 |
|
|
640 |
##### missing acc_trans |
|
641 |
$file = \<<EOL; |
|
642 |
datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate,duedate,globalprojectnumber,department |
|
643 |
datatype,accno,amount,taxkey,projectnumber |
|
644 |
"Rechnung",2,1,"invoice acc_trans missing",t,1600,21.04.2016,30.04.2016,P1,Department 1 |
|
645 |
"Rechnung",2,1,"invoice various a",t,1600,21.04.2016,30.04.2016,P1,Department 1 |
|
646 |
"AccTransaction",3400,119,9,P1 |
|
647 |
"AccTransaction",3300,107,8,P1 |
|
648 |
EOL |
|
649 |
|
|
650 |
$entries = test_import($file); |
|
651 |
|
|
652 |
$entry = $entries->[0]; |
|
653 |
is $entry->{errors}->[0], "Error: ap transaction doesn't validate", 'detects invalid ap, maybe acc_trans entry missing'; |
|
654 |
|
|
655 |
##### taxkey differs from active_taxkey |
|
656 |
$file = \<<EOL; |
|
657 |
datatype,vendornumber,currency_id,invnumber,taxincluded,apchart |
|
658 |
datatype,accno,amount,taxkey |
|
659 |
"Rechnung",2,1,"invoice 1 tax included no amounts",t,1600 |
|
660 |
"AccTransaction",3400,189.78,8 |
|
661 |
EOL |
|
662 |
|
|
663 |
$entries = test_import($file); |
|
664 |
is $entries->[0]->{errors}->[0], undef, 'taxkey differs from active_taxkey: no errors in ap row'; |
|
665 |
is $entries->[1]->{errors}->[0], undef, 'taxkey differs from active_taxkey: no errors in acc_trans row'; |
|
666 |
|
|
667 |
$entry = $entries->[0]; |
|
668 |
is $entry->{object}->transactions->[1]->taxkey, '8', 'taxkey differs from active_taxkey'; |
|
669 |
|
|
670 |
$saved_invoices++; |
|
671 |
|
|
672 |
##### |
|
673 |
my $number_of_imported_invoices = SL::DB::Manager::PurchaseInvoice->get_all_count; |
|
674 |
is $number_of_imported_invoices, $saved_invoices, 'All invoices saved'; |
|
675 |
|
|
676 |
##### |
|
677 |
clear_up(); # remove all data at end of tests |
|
678 |
|
|
679 |
# end of tests |
|
680 |
done_testing; |
|
681 |
|
|
682 |
1; |
|
683 |
|
|
684 |
##### |
|
685 |
# vim: ft=perl |
|
686 |
# set emacs to perl mode |
|
687 |
# Local Variables: |
|
688 |
# mode: perl |
|
689 |
# End: |
Auch abrufbar als: Unified diff
Unit-Test: CSV-Import Kreditorenbuchungen
Kopie und Anpassung vom Test des Debitorenbuchungsimports