Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision a607a2d0

Von Bernd Bleßmann vor mehr als 10 Jahren hinzugefügt

  • ID a607a2d0854ef2b2e85bff4ab9657166236129c0
  • Vorgänger 68e4c3a2
  • Nachfolger 81b492ac

Rundungsfehler bei periodischen Rechnungen mit Einzelpreisen ...

... mit einer Nachkommastelle und Rabatt behoben.

siehe auch commit a22b8118e0bd68acac8a2d7b02a2d4f9fd0eaff1

Zudem einen Test dazu angelegt. Allerdings weicht die Art, wie der
PriceTaxCalculator und die Beleg-Masken rechnen, von einander ab.
Da müsste nochmal geprüft werden, was die richtige Art ist
(erst Rabatt abziehen und dann runden,
oder gerundeten Rabatt abziehen und wieder runden).
Auch beim Errechnen des Amounts gibt es unterschiede
(netamount * (1+Steuersatz),
oder aufsummieren).

Unterschiede anzeigen:

SL/DB/Helper/PriceTaxCalculator.pm
6 6
our @EXPORT = qw(calculate_prices_and_taxes);
7 7

  
8 8
use Carp;
9
use List::Util qw(sum min);
9
use List::Util qw(sum min max);
10 10

  
11 11
sub calculate_prices_and_taxes {
12 12
  my ($self, %params) = @_;
......
83 83
  $item->base_qty($item_unit->convert_to($item->qty, $part_unit));
84 84
  $item->fxsellprice($item->sellprice) if $data->{is_invoice};
85 85

  
86
  my $num_dec   = _num_decimal_places($item->sellprice) || 2;
87
  #  ^ we need at least 2 decimal places                   ^
88
  # my test case 43.00 € with 0 decimal places and 0.5 discount ->
89
  # : sellprice before:43.00000
90
  # : num dec   before:0
91
  # : discount / sellprice ratio:  22  /  21
92
  # : discount = 43 * 0.5 _round(21.5, 0) = 22
93
  # TODO write a test case
86
  my $num_dec   = max 2, _num_decimal_places($item->sellprice);
94 87
  my $discount  = _round($item->sellprice * ($item->discount || 0), $num_dec);
95 88
  my $sellprice = _round($item->sellprice - $discount,              $num_dec);
96 89

  
t/db_helper/price_tax_calculator.t
217 217
  }, "${title}: calculated data");
218 218
}
219 219

  
220
sub test_default_invoice_three_items_sellprice_rounding_discount() {
221
  reset_state();
222

  
223
  my $item1   = new_item(qty => 1, sellprice => 5.55, discount => .05);
224
  my $item2   = new_item(qty => 1, sellprice => 5.50, discount => .05);
225
  my $item3   = new_item(qty => 1, sellprice => 5.00, discount => .05);
226
  my $invoice = new_invoice(
227
    taxincluded  => 0,
228
    invoiceitems => [ $item1, $item2, $item3 ],
229
  );
230

  
231
  # this is how price_tax_calculator is implemented. It differs from
232
  # the way sales_order / invoice - forms are calculating:
233
  # linetotal = sellprice 5.55 * qty 1 * (1 - 0.05) = 5.2725; rounded 5.27
234
  # linetotal = sellprice 5.50 * qty 1 * (1 - 0.05) = 5.225 rounded 5.23
235
  # linetotal = sellprice 5.00 * qty 1 * (1 - 0.05) = 4.75; rounded 4.75
236
  # ...
237

  
238
  # item 1:
239
  # discount = sellprice 5.55 * discount (0.05) = 0.2775; rounded 0.28
240
  # sellprice = sellprice 5.55 - discount 0.28 = 5.27; rounded 5.27
241
  # linetotal = sellprice 5.27 * qty 1 = 5.27; rounded 5.27
242
  # 19%(5.27) = 1.0013; rounded = 1.00
243
  # total rounded = 6.27
244

  
245
  # lastcost 1.93 * qty 1 = 1.93; rounded 1.93
246
  # line marge_total = 3.34
247
  # line marge_percent = 63.3776091081594
248

  
249
  # item 2:
250
  # discount = sellprice 5.50 * discount 0.05 = 0.275; rounded 0.28
251
  # sellprice = sellprice 5.50 - discount 0.28 = 5.22; rounded 5.22
252
  # linetotal = sellprice 5.22 * qty 1 = 5.22; rounded 5.22
253
  # 19%(5.22) = 0.9918; rounded = 0.99
254
  # total rounded = 6.21
255

  
256
  # lastcost 1.93 * qty 1 = 1.93; rounded 1.93
257
  # line marge_total = 5.22 - 1.93 = 3.29
258
  # line marge_percent = 3.29/5.22 = 0.630268199233716
259

  
260
  # item 3:
261
  # discount = sellprice 5.00 * discount 0.25 = 0.25; rounded 0.25
262
  # sellprice = sellprice 5.00 - discount 0.25 = 4.75; rounded 4.75
263
  # linetotal = sellprice 4.75 * qty 1 = 4.75; rounded 4.75
264
  # 19%(4.75) = 0.9025; rounded = 0.90
265
  # total rounded = 5.65
266

  
267
  # lastcost 1.93 * qty 1 = 1.93; rounded 1.93
268
  # line marge_total = 2.82
269
  # line marge_percent = 59.3684210526316
270

  
271
  my $title = 'default invoice, three items, sellprice, rounding, discount';
272
  my %data  = $invoice->calculate_prices_and_taxes;
273

  
274
  is($item1->marge_total,        3.34,               "${title}: item1 marge_total");
275
  is($item1->marge_percent,      63.3776091081594,   "${title}: item1 marge_percent");
276
  is($item1->marge_price_factor, 1,                  "${title}: item1 marge_price_factor");
277

  
278
  is($item2->marge_total,        3.29,               "${title}: item2 marge_total");
279
  is($item2->marge_percent,      63.0268199233716,  "${title}: item2 marge_percent");
280
  is($item2->marge_price_factor, 1,                  "${title}: item2 marge_price_factor");
281

  
282
  is($item3->marge_total,        2.82,               "${title}: item3 marge_total");
283
  is($item3->marge_percent,      59.3684210526316,   "${title}: item3 marge_percent");
284
  is($item3->marge_price_factor, 1,                  "${title}: item3 marge_price_factor");
285

  
286
  is($invoice->netamount,        5.27 + 5.22 + 4.75, "${title}: netamount");
287

  
288
  # 6.27 + 6.21 + 5.65 = 18.13
289
  # 1.19*(5.27 + 5.22 + 4.75) = 18.1356; rounded 18.14
290
  #is($invoice->amount,           6.27 + 6.21 + 5.65, "${title}: amount");
291
  is($invoice->amount,           18.14,              "${title}: amount");
292

  
293
  is($invoice->marge_total,      3.34 + 3.29 + 2.82, "${title}: marge_total");
294
  is($invoice->marge_percent,    62.007874015748,    "${title}: marge_percent");
295

  
296
  is_deeply(\%data, {
297
    allocated                             => {},
298
    amounts                               => {
299
      $buchungsgruppe->income_accno_id_0  => {
300
        amount                            => 15.24,
301
        tax_id                            => $tax->id,
302
        taxkey                            => 3,
303
      },
304
    },
305
    amounts_cogs                          => {},
306
    assembly_items                        => [
307
      [], [], [],
308
    ],
309
    exchangerate                          => 1,
310
    taxes                                 => {
311
      $tax->chart_id                      => 2.9,
312
    },
313
  }, "${title}: calculated data");
314
}
315

  
220 316
Support::TestSetup::login();
221 317

  
222 318
test_default_invoice_one_item_19_tax_not_included();
223 319
test_default_invoice_two_items_19_7_tax_not_included();
320
test_default_invoice_three_items_sellprice_rounding_discount();
224 321

  
225 322
done_testing();

Auch abrufbar als: Unified diff