Revision dd75973a
Von Kivitendo Admin vor mehr als 6 Jahren hinzugefügt
SL/DB/Helper/PriceTaxCalculator.pm | ||
---|---|---|
$item->fxsellprice($item->sellprice) if $data->{is_invoice};
|
||
|
||
my $num_dec = max 2, _num_decimal_places($item->sellprice);
|
||
my $discount = _round($item->sellprice * ($item->discount || 0), $num_dec);
|
||
my $sellprice = _round($item->sellprice - $discount, $num_dec);
|
||
# my $discount = _round($item->sellprice * ($item->discount || 0), $num_dec);
|
||
# my $sellprice; # = _round($item->sellprice - $discount, $num_dec);
|
||
my $sellprice = $item->sellprice; # don't include rounded discount into sellprice
|
||
# any time the sellprice is multiplied with qty discount has to be considered as part of the multiplication
|
||
|
||
$item->price_factor( ! $item->price_factor_obj ? 1 : ($item->price_factor_obj->factor || 1));
|
||
$item->marge_price_factor(! $part->price_factor ? 1 : ($part->price_factor->factor || 1));
|
||
my $linetotal = _round($sellprice * $item->qty / $item->price_factor, 2) * $data->{exchangerate};
|
||
my $linetotal = _round($sellprice * (1-$item->discount) * $item->qty / $item->price_factor, 2) * $data->{exchangerate};
|
||
$linetotal = _round($linetotal, 2);
|
||
|
||
$data->{invoicediff} += $sellprice * $item->qty * $data->{exchangerate} / $item->price_factor - $linetotal if $self->taxincluded;
|
||
$data->{invoicediff} += $sellprice * (1-$item->discount) * $item->qty * $data->{exchangerate} / $item->price_factor - $linetotal if $self->taxincluded;
|
||
|
||
my $linetotal_cost = 0;
|
||
|
||
... | ... | |
die "tax_amount != 0 but no chart_id for taxkey " . $taxkey->id . " tax " . $taxkey->tax->id;
|
||
}
|
||
|
||
$self->netamount($self->netamount + $sellprice * $item->qty / $item->price_factor);
|
||
$self->netamount($self->netamount + $sellprice * (1-$item->discount) * $item->qty / $item->price_factor);
|
||
|
||
my $chart = $part->get_chart(type => $data->{is_sales} ? 'income' : 'expense', taxzone => $self->taxzone_id);
|
||
$data->{amounts}->{ $chart->id } ||= { taxkey => $taxkey->taxkey_id, tax_id => $taxkey->tax_id, amount => 0 };
|
||
... | ... | |
|
||
next unless $qty;
|
||
|
||
my $linetotal = _round(($entry->sellprice * $qty) / $base_factor, 2);
|
||
my $linetotal = _round(($entry->sellprice * (1-$entry->discount) * $qty) / $base_factor, 2);
|
||
|
||
$data->{amounts_cogs}->{ $expense_income_chart->id } -= $linetotal;
|
||
$data->{amounts_cogs}->{ $inventory_chart->id } += $linetotal;
|
t/db_helper/price_tax_calculator.t | ||
---|---|---|
my $title = 'default invoice, one item, sellprice, rounding, discount';
|
||
my %data = $invoice->calculate_prices_and_taxes;
|
||
|
||
is($invoice->netamount, 3.48, "${title}: netamount");
|
||
is($invoice->netamount, 3.49, "${title}: netamount");
|
||
|
||
is($invoice->amount, 4.14, "${title}: amount");
|
||
is($invoice->amount, 4.15, "${title}: amount");
|
||
|
||
is($invoice->marge_total, 3.48, "${title}: marge_total");
|
||
is($invoice->marge_total, 3.49, "${title}: marge_total");
|
||
is($invoice->marge_percent, 100, "${title}: marge_percent");
|
||
|
||
is_deeply(\%data, {
|
||
allocated => {},
|
||
amounts => {
|
||
$buchungsgruppe->income_accno_id($taxzone) => {
|
||
amount => 3.48,
|
||
amount => 3.49,
|
||
tax_id => $tax->id,
|
||
taxkey => 3,
|
||
},
|
||
... | ... | |
$tax->chart_id => 0.66,
|
||
},
|
||
items => [
|
||
{ linetotal => 3.48,
|
||
{ linetotal => 3.49,
|
||
linetotal_cost => 0,
|
||
sellprice => 0.58,
|
||
tax_amount => 0.6612,
|
||
tax_amount => 0.6631,
|
||
taxkey_id => $taxkeys{$item->parts_id}->id,
|
||
},
|
||
],
|
||
}, "${title}: calculated data");
|
||
}
|
||
|
||
sub test_default_invoice_one_item_19_tax_not_included_rounding_discount_huge_qty() {
|
||
reset_state();
|
||
|
||
my $item = new_item(qty => 100000, part => $parts[2], discount => 0.03, sellprice => 0.10);
|
||
my $invoice = new_invoice(
|
||
taxincluded => 0,
|
||
invoiceitems => [ $item ],
|
||
);
|
||
|
||
my %taxkeys = map { ($_->id => $_->get_taxkey(date => DateTime->today_local, is_sales => 1, taxzone => $invoice->taxzone_id)) } uniq map { $_->part } ($item);
|
||
|
||
# PTC and ar form calculate linetotal differently:
|
||
# 6 parts for 0.60 with 3% discount
|
||
#
|
||
# ar form:
|
||
# linetotal = sellprice 0.60 * qty 6 * discount (1 - 0.03) = 3.492 rounded 3.49
|
||
# total = 3.49 + 0.66 = 4.15
|
||
#
|
||
# PTC:
|
||
# discount = sellprice 0.60 * discount (0.03) = 0.018; rounded 0.02
|
||
# sellprice = sellprice 0.60 - discount 0.02 = 0.58
|
||
# linetotal = sellprice 0.58 * qty 6 = 3.48
|
||
# 19%(3.48) = 0.6612; rounded = 0.66
|
||
# total rounded = 3.48 + 0.66 = 4.14
|
||
|
||
my $title = 'default invoice, one item, sellprice, rounding, discount';
|
||
my %data = $invoice->calculate_prices_and_taxes;
|
||
|
||
is($invoice->netamount, 9700, "${title}: netamount");
|
||
|
||
is($invoice->amount, 11543, "${title}: amount");
|
||
|
||
is($invoice->marge_total, 9700, "${title}: marge_total");
|
||
is($invoice->marge_percent, 100, "${title}: marge_percent");
|
||
|
||
is_deeply(\%data, {
|
||
allocated => {},
|
||
amounts => {
|
||
$buchungsgruppe->income_accno_id($taxzone) => {
|
||
amount => 9700,
|
||
tax_id => $tax->id,
|
||
taxkey => 3,
|
||
},
|
||
},
|
||
amounts_cogs => {},
|
||
assembly_items => [
|
||
[],
|
||
],
|
||
exchangerate => 1,
|
||
taxes => {
|
||
$tax->chart_id => 1843,
|
||
},
|
||
items => [
|
||
{ linetotal => 9700,
|
||
linetotal_cost => 0,
|
||
sellprice => 0.1,
|
||
tax_amount => 1843,
|
||
taxkey_id => $taxkeys{$item->parts_id}->id,
|
||
},
|
||
],
|
||
... | ... | |
test_default_invoice_two_items_19_7_tax_not_included();
|
||
test_default_invoice_three_items_sellprice_rounding_discount();
|
||
test_default_invoice_one_item_19_tax_not_included_rounding_discount();
|
||
test_default_invoice_one_item_19_tax_not_included_rounding_discount_huge_qty();
|
||
|
||
clear_up();
|
||
done_testing();
|
Auch abrufbar als: Unified diff
PTC rundet nicht mehr Rabatt vor Mengenmultiplikation
siehe Ticket #82
Neuer Test für 100000 Artikel zu 0,10€ bei 3% Rabatt
Einen weiteren Test angepasst an die neuen Zahlen.