Revision 1223ef45
Von Moritz Bunkus vor mehr als 11 Jahren hinzugefügt
t/db_helper/price_tax_calculator.t | ||
---|---|---|
1 |
use Test::More; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use lib 't'; |
|
6 |
use utf8; |
|
7 |
|
|
8 |
use Carp; |
|
9 |
use Data::Dumper; |
|
10 |
use Support::TestSetup; |
|
11 |
use Test::Exception; |
|
12 |
|
|
13 |
use SL::DB::Buchungsgruppe; |
|
14 |
use SL::DB::Currency; |
|
15 |
use SL::DB::Customer; |
|
16 |
use SL::DB::Employee; |
|
17 |
use SL::DB::Invoice; |
|
18 |
use SL::DB::Part; |
|
19 |
use SL::DB::Unit; |
|
20 |
|
|
21 |
my ($customer, $currency_id, @parts, $buchungsgruppe, $buchungsgruppe7, $unit, $employee, $tax, $tax7); |
|
22 |
|
|
23 |
sub reset_state { |
|
24 |
my %params = @_; |
|
25 |
|
|
26 |
$params{$_} ||= {} for qw(buchungsgruppe unit customer part tax); |
|
27 |
|
|
28 |
SL::DB::Manager::Invoice->delete_all(all => 1); |
|
29 |
SL::DB::Manager::Part->delete_all(all => 1); |
|
30 |
SL::DB::Manager::Customer->delete_all(all => 1); |
|
31 |
|
|
32 |
$buchungsgruppe = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%', %{ $params{buchungsgruppe} }) || croak "No accounting group"; |
|
33 |
$buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%') || croak "No accounting group for 7\%"; |
|
34 |
$unit = SL::DB::Manager::Unit->find_by(name => 'kg', %{ $params{unit} }) || croak "No unit"; |
|
35 |
$employee = SL::DB::Manager::Employee->current || croak "No employee"; |
|
36 |
$tax = SL::DB::Manager::Tax->find_by(taxkey => 3, rate => 0.19, %{ $params{tax} }) || croak "No tax"; |
|
37 |
$tax7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07) || croak "No tax for 7\%"; |
|
38 |
|
|
39 |
$currency_id = $::instance_conf->get_currency_id; |
|
40 |
|
|
41 |
$customer = SL::DB::Customer->new( |
|
42 |
name => 'Test Customer', |
|
43 |
currency_id => $currency_id, |
|
44 |
%{ $params{customer} } |
|
45 |
)->save; |
|
46 |
|
|
47 |
@parts = (); |
|
48 |
push @parts, SL::DB::Part->new( |
|
49 |
partnumber => 'T4254', |
|
50 |
description => 'Fourty-two fifty-four', |
|
51 |
lastcost => 1.93, |
|
52 |
sellprice => 2.34, |
|
53 |
buchungsgruppen_id => $buchungsgruppe->id, |
|
54 |
unit => $unit->name, |
|
55 |
%{ $params{part1} } |
|
56 |
)->save; |
|
57 |
|
|
58 |
push @parts, SL::DB::Part->new( |
|
59 |
partnumber => 'T0815', |
|
60 |
description => 'Zero EIGHT fifteeN @ 7%', |
|
61 |
lastcost => 5.473, |
|
62 |
sellprice => 9.714, |
|
63 |
buchungsgruppen_id => $buchungsgruppe7->id, |
|
64 |
unit => $unit->name, |
|
65 |
%{ $params{part2} } |
|
66 |
)->save; |
|
67 |
} |
|
68 |
|
|
69 |
sub new_invoice { |
|
70 |
my %params = @_; |
|
71 |
|
|
72 |
return SL::DB::Invoice->new( |
|
73 |
customer_id => $customer->id, |
|
74 |
currency_id => $currency_id, |
|
75 |
employee_id => $employee->id, |
|
76 |
salesman_id => $employee->id, |
|
77 |
gldate => DateTime->today_local->to_kivitendo, |
|
78 |
taxzone_id => 0, |
|
79 |
transdate => DateTime->today_local->to_kivitendo, |
|
80 |
invoice => 1, |
|
81 |
type => 'invoice', |
|
82 |
%params, |
|
83 |
); |
|
84 |
} |
|
85 |
|
|
86 |
sub new_item { |
|
87 |
my (%params) = @_; |
|
88 |
|
|
89 |
my $part = delete($params{part}) || $parts[0]; |
|
90 |
|
|
91 |
return SL::DB::InvoiceItem->new( |
|
92 |
parts_id => $part->id, |
|
93 |
lastcost => $part->lastcost, |
|
94 |
sellprice => $part->sellprice, |
|
95 |
description => $part->description, |
|
96 |
unit => $part->unit, |
|
97 |
%params, |
|
98 |
); |
|
99 |
} |
|
100 |
|
|
101 |
sub test_default_invoice_one_item_19_tax_not_included() { |
|
102 |
reset_state(); |
|
103 |
|
|
104 |
my $item = new_item(qty => 2.5); |
|
105 |
my $invoice = new_invoice( |
|
106 |
taxincluded => 0, |
|
107 |
invoiceitems => [ $item ], |
|
108 |
); |
|
109 |
|
|
110 |
# sellprice 2.34 * qty 2.5 = 5.85 |
|
111 |
# 19%(5.85) = 1.1115; rounded = 1.11 |
|
112 |
# total rounded = 6.96 |
|
113 |
|
|
114 |
# lastcost 1.93 * qty 2.5 = 4.825; rounded 4.83 |
|
115 |
# line marge_total = 1.02 |
|
116 |
# line marge_percent = 17.4358974358974 |
|
117 |
|
|
118 |
my $title = 'default invoice, one item, 19% tax not included'; |
|
119 |
my %data = $invoice->calculate_prices_and_taxes; |
|
120 |
|
|
121 |
is($item->marge_total, 1.02, "${title}: item marge_total"); |
|
122 |
is($item->marge_percent, 17.4358974358974, "${title}: item marge_percent"); |
|
123 |
is($item->marge_price_factor, 1, "${title}: item marge_price_factor"); |
|
124 |
|
|
125 |
is($invoice->netamount, 5.85, "${title}: netamount"); |
|
126 |
is($invoice->amount, 6.96, "${title}: amount"); |
|
127 |
is($invoice->marge_total, 1.02, "${title}: marge_total"); |
|
128 |
is($invoice->marge_percent, 17.4358974358974, "${title}: marge_percent"); |
|
129 |
|
|
130 |
is_deeply(\%data, { |
|
131 |
allocated => {}, |
|
132 |
amounts => { |
|
133 |
$buchungsgruppe->income_accno_id_0 => { |
|
134 |
amount => 5.85, |
|
135 |
tax_id => $tax->id, |
|
136 |
taxkey => 3, |
|
137 |
}, |
|
138 |
}, |
|
139 |
amounts_cogs => {}, |
|
140 |
assembly_items => [ |
|
141 |
[], |
|
142 |
], |
|
143 |
exchangerate => 1, |
|
144 |
taxes => { |
|
145 |
$tax->chart_id => 1.11, |
|
146 |
}, |
|
147 |
}, "${title}: calculated data"); |
|
148 |
} |
|
149 |
|
|
150 |
sub test_default_invoice_two_items_19_7_tax_not_included() { |
|
151 |
reset_state(); |
|
152 |
|
|
153 |
my $item1 = new_item(qty => 2.5); |
|
154 |
my $item2 = new_item(qty => 1.2, part => $parts[1]); |
|
155 |
my $invoice = new_invoice( |
|
156 |
taxincluded => 0, |
|
157 |
invoiceitems => [ $item1, $item2 ], |
|
158 |
); |
|
159 |
|
|
160 |
# item 1: |
|
161 |
# sellprice 2.34 * qty 2.5 = 5.85 |
|
162 |
# 19%(5.85) = 1.1115; rounded = 1.11 |
|
163 |
# total rounded = 6.96 |
|
164 |
|
|
165 |
# lastcost 1.93 * qty 2.5 = 4.825; rounded 4.83 |
|
166 |
# line marge_total = 1.02 |
|
167 |
# line marge_percent = 17.4358974358974 |
|
168 |
|
|
169 |
# item 2: |
|
170 |
# sellprice 9.714 * qty 1.2 = 11.6568 rounded 11.66 |
|
171 |
# 7%(11.6568) = 0.815976; rounded = 0.82 |
|
172 |
# total rounded = 12.48 |
|
173 |
|
|
174 |
# lastcost 5.473 * qty 1.2 = 6.5676; rounded 6.57 |
|
175 |
# line marge_total = 5.09 |
|
176 |
# line marge_percent = 43.6535162950257 |
|
177 |
|
|
178 |
my $title = 'default invoice, two item, 19/7% tax not included'; |
|
179 |
my %data = $invoice->calculate_prices_and_taxes; |
|
180 |
|
|
181 |
is($item1->marge_total, 1.02, "${title}: item1 marge_total"); |
|
182 |
is($item1->marge_percent, 17.4358974358974, "${title}: item1 marge_percent"); |
|
183 |
is($item1->marge_price_factor, 1, "${title}: item1 marge_price_factor"); |
|
184 |
|
|
185 |
is($item2->marge_total, 5.09, "${title}: item2 marge_total"); |
|
186 |
is($item2->marge_percent, 43.6535162950257, "${title}: item2 marge_percent"); |
|
187 |
is($item2->marge_price_factor, 1, "${title}: item2 marge_price_factor"); |
|
188 |
|
|
189 |
is($invoice->netamount, 5.85 + 11.66, "${title}: netamount"); |
|
190 |
is($invoice->amount, 6.96 + 12.48, "${title}: amount"); |
|
191 |
is($invoice->marge_total, 1.02 + 5.09, "${title}: marge_total"); |
|
192 |
is($invoice->marge_percent, 34.8943460879497, "${title}: marge_percent"); |
|
193 |
|
|
194 |
is_deeply(\%data, { |
|
195 |
allocated => {}, |
|
196 |
amounts => { |
|
197 |
$buchungsgruppe->income_accno_id_0 => { |
|
198 |
amount => 5.85, |
|
199 |
tax_id => $tax->id, |
|
200 |
taxkey => 3, |
|
201 |
}, |
|
202 |
$buchungsgruppe7->income_accno_id_0 => { |
|
203 |
amount => 11.66, |
|
204 |
tax_id => $tax7->id, |
|
205 |
taxkey => 2, |
|
206 |
}, |
|
207 |
}, |
|
208 |
amounts_cogs => {}, |
|
209 |
assembly_items => [ |
|
210 |
[], [], |
|
211 |
], |
|
212 |
exchangerate => 1, |
|
213 |
taxes => { |
|
214 |
$tax->chart_id => 1.11, |
|
215 |
$tax7->chart_id => 0.82, |
|
216 |
}, |
|
217 |
}, "${title}: calculated data"); |
|
218 |
} |
|
219 |
|
|
220 |
Support::TestSetup::login(); |
|
221 |
|
|
222 |
test_default_invoice_one_item_19_tax_not_included(); |
|
223 |
test_default_invoice_two_items_19_7_tax_not_included(); |
|
224 |
|
|
225 |
done_testing(); |
Auch abrufbar als: Unified diff
Erste Tests zum PriceTaxCalculator