Fehler #82 » 0001-PTC-rundet-nicht-mehr-Rabatt-vor-Mengenmultiplikatio.patch
SL/DB/Helper/PriceTaxCalculator.pm | ||
---|---|---|
87 | 87 |
$item->fxsellprice($item->sellprice) if $data->{is_invoice}; |
88 | 88 | |
89 | 89 |
my $num_dec = max 2, _num_decimal_places($item->sellprice); |
90 |
my $discount = _round($item->sellprice * ($item->discount || 0), $num_dec); |
|
91 |
my $sellprice = _round($item->sellprice - $discount, $num_dec); |
|
90 |
# my $discount = _round($item->sellprice * ($item->discount || 0), $num_dec); |
|
91 |
# my $sellprice; # = _round($item->sellprice - $discount, $num_dec); |
|
92 |
my $sellprice = $item->sellprice; # don't include rounded discount into sellprice |
|
93 |
# any time the sellprice is multiplied with qty discount has to be considered as part of the multiplication |
|
92 | 94 | |
93 | 95 |
$item->price_factor( ! $item->price_factor_obj ? 1 : ($item->price_factor_obj->factor || 1)); |
94 | 96 |
$item->marge_price_factor(! $part->price_factor ? 1 : ($part->price_factor->factor || 1)); |
95 |
my $linetotal = _round($sellprice * $item->qty / $item->price_factor, 2) * $data->{exchangerate}; |
|
97 |
my $linetotal = _round($sellprice * (1-$item->discount) * $item->qty / $item->price_factor, 2) * $data->{exchangerate};
|
|
96 | 98 |
$linetotal = _round($linetotal, 2); |
97 | 99 | |
98 |
$data->{invoicediff} += $sellprice * $item->qty * $data->{exchangerate} / $item->price_factor - $linetotal if $self->taxincluded; |
|
100 |
$data->{invoicediff} += $sellprice * (1-$item->discount) * $item->qty * $data->{exchangerate} / $item->price_factor - $linetotal if $self->taxincluded;
|
|
99 | 101 | |
100 | 102 |
my $linetotal_cost = 0; |
101 | 103 | |
... | ... | |
133 | 135 |
die "tax_amount != 0 but no chart_id for taxkey " . $taxkey->id . " tax " . $taxkey->tax->id; |
134 | 136 |
} |
135 | 137 | |
136 |
$self->netamount($self->netamount + $sellprice * $item->qty / $item->price_factor); |
|
138 |
$self->netamount($self->netamount + $sellprice * (1-$item->discount) * $item->qty / $item->price_factor);
|
|
137 | 139 | |
138 | 140 |
my $chart = $part->get_chart(type => $data->{is_sales} ? 'income' : 'expense', taxzone => $self->taxzone_id); |
139 | 141 |
$data->{amounts}->{ $chart->id } ||= { taxkey => $taxkey->taxkey_id, tax_id => $taxkey->tax_id, amount => 0 }; |
... | ... | |
233 | 235 | |
234 | 236 |
next unless $qty; |
235 | 237 | |
236 |
my $linetotal = _round(($entry->sellprice * $qty) / $base_factor, 2); |
|
238 |
my $linetotal = _round(($entry->sellprice * (1-$entry->discount) * $qty) / $base_factor, 2);
|
|
237 | 239 | |
238 | 240 |
$data->{amounts_cogs}->{ $expense_income_chart->id } -= $linetotal; |
239 | 241 |
$data->{amounts_cogs}->{ $inventory_chart->id } += $linetotal; |
t/db_helper/price_tax_calculator.t | ||
---|---|---|
413 | 413 |
my $title = 'default invoice, one item, sellprice, rounding, discount'; |
414 | 414 |
my %data = $invoice->calculate_prices_and_taxes; |
415 | 415 | |
416 |
is($invoice->netamount, 3.48, "${title}: netamount");
|
|
416 |
is($invoice->netamount, 3.49, "${title}: netamount");
|
|
417 | 417 | |
418 |
is($invoice->amount, 4.14, "${title}: amount");
|
|
418 |
is($invoice->amount, 4.15, "${title}: amount");
|
|
419 | 419 | |
420 |
is($invoice->marge_total, 3.48, "${title}: marge_total");
|
|
420 |
is($invoice->marge_total, 3.49, "${title}: marge_total");
|
|
421 | 421 |
is($invoice->marge_percent, 100, "${title}: marge_percent"); |
422 | 422 | |
423 | 423 |
is_deeply(\%data, { |
424 | 424 |
allocated => {}, |
425 | 425 |
amounts => { |
426 | 426 |
$buchungsgruppe->income_accno_id($taxzone) => { |
427 |
amount => 3.48,
|
|
427 |
amount => 3.49,
|
|
428 | 428 |
tax_id => $tax->id, |
429 | 429 |
taxkey => 3, |
430 | 430 |
}, |
... | ... | |
438 | 438 |
$tax->chart_id => 0.66, |
439 | 439 |
}, |
440 | 440 |
items => [ |
441 |
{ linetotal => 3.48,
|
|
441 |
{ linetotal => 3.49,
|
|
442 | 442 |
linetotal_cost => 0, |
443 | 443 |
sellprice => 0.58, |
444 |
tax_amount => 0.6612, |
|
444 |
tax_amount => 0.6631, |
|
445 |
taxkey_id => $taxkeys{$item->parts_id}->id, |
|
446 |
}, |
|
447 |
], |
|
448 |
}, "${title}: calculated data"); |
|
449 |
} |
|
450 | ||
451 |
sub test_default_invoice_one_item_19_tax_not_included_rounding_discount_huge_qty() { |
|
452 |
reset_state(); |
|
453 | ||
454 |
my $item = new_item(qty => 100000, part => $parts[2], discount => 0.03, sellprice => 0.10); |
|
455 |
my $invoice = new_invoice( |
|
456 |
taxincluded => 0, |
|
457 |
invoiceitems => [ $item ], |
|
458 |
); |
|
459 | ||
460 |
my %taxkeys = map { ($_->id => $_->get_taxkey(date => DateTime->today_local, is_sales => 1, taxzone => $invoice->taxzone_id)) } uniq map { $_->part } ($item); |
|
461 | ||
462 |
# PTC and ar form calculate linetotal differently: |
|
463 |
# 6 parts for 0.60 with 3% discount |
|
464 |
# |
|
465 |
# ar form: |
|
466 |
# linetotal = sellprice 0.60 * qty 6 * discount (1 - 0.03) = 3.492 rounded 3.49 |
|
467 |
# total = 3.49 + 0.66 = 4.15 |
|
468 |
# |
|
469 |
# PTC: |
|
470 |
# discount = sellprice 0.60 * discount (0.03) = 0.018; rounded 0.02 |
|
471 |
# sellprice = sellprice 0.60 - discount 0.02 = 0.58 |
|
472 |
# linetotal = sellprice 0.58 * qty 6 = 3.48 |
|
473 |
# 19%(3.48) = 0.6612; rounded = 0.66 |
|
474 |
# total rounded = 3.48 + 0.66 = 4.14 |
|
475 | ||
476 |
my $title = 'default invoice, one item, sellprice, rounding, discount'; |
|
477 |
my %data = $invoice->calculate_prices_and_taxes; |
|
478 | ||
479 |
is($invoice->netamount, 9700, "${title}: netamount"); |
|
480 | ||
481 |
is($invoice->amount, 11543, "${title}: amount"); |
|
482 | ||
483 |
is($invoice->marge_total, 9700, "${title}: marge_total"); |
|
484 |
is($invoice->marge_percent, 100, "${title}: marge_percent"); |
|
485 | ||
486 |
is_deeply(\%data, { |
|
487 |
allocated => {}, |
|
488 |
amounts => { |
|
489 |
$buchungsgruppe->income_accno_id($taxzone) => { |
|
490 |
amount => 9700, |
|
491 |
tax_id => $tax->id, |
|
492 |
taxkey => 3, |
|
493 |
}, |
|
494 |
}, |
|
495 |
amounts_cogs => {}, |
|
496 |
assembly_items => [ |
|
497 |
[], |
|
498 |
], |
|
499 |
exchangerate => 1, |
|
500 |
taxes => { |
|
501 |
$tax->chart_id => 1843, |
|
502 |
}, |
|
503 |
items => [ |
|
504 |
{ linetotal => 9700, |
|
505 |
linetotal_cost => 0, |
|
506 |
sellprice => 0.1, |
|
507 |
tax_amount => 1843, |
|
445 | 508 |
taxkey_id => $taxkeys{$item->parts_id}->id, |
446 | 509 |
}, |
447 | 510 |
], |
... | ... | |
454 | 517 |
test_default_invoice_two_items_19_7_tax_not_included(); |
455 | 518 |
test_default_invoice_three_items_sellprice_rounding_discount(); |
456 | 519 |
test_default_invoice_one_item_19_tax_not_included_rounding_discount(); |
520 |
test_default_invoice_one_item_19_tax_not_included_rounding_discount_huge_qty(); |
|
457 | 521 | |
458 | 522 |
clear_up(); |
459 | 523 |
done_testing(); |
460 |
- |