diff --git a/ChangeLog b/ChangeLog index 1dcdfc40a1..da015996df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,14 @@ or as "seventeen thousand five hundred". Note that numbers STILL default to decimal-radix instead of asking the user to choose. + * src/business/business-core/gncEntry.[ch]: + * src/business/business-ledger/gncEntryLedger.c: + Properly round invoice entries and totals. Fixes #300042. + Perform internal computations to LCD, but then export rounded values. + Now, using the test case in Bug #300042 I get the same values + in the invoice window, in the printable invoice report, and + in the CoA Registers. + 2006-07-16 Andreas Köhler * src/gnome-utils/gnc-main-window.c: Do not move windows on diff --git a/src/business/business-core/gncEntry.c b/src/business/business-core/gncEntry.c index a26da73d21..f7d1ba7cd5 100644 --- a/src/business/business-core/gncEntry.c +++ b/src/business/business-core/gncEntry.c @@ -839,13 +839,15 @@ GncOrder * gncEntryGetOrder (GncEntry *entry) * the amount the merchant gets; the taxes are the amount the gov't * gets, and the customer pays the sum or value + taxes. * + * The SCU is the denominator to convert the value. + * * The discount return value is just for entertainment -- you may way * to let a consumer know how much they saved. */ void gncEntryComputeValue (gnc_numeric qty, gnc_numeric price, GncTaxTable *tax_table, gboolean tax_included, gnc_numeric discount, GncAmountType discount_type, - GncDiscountHow discount_how, + GncDiscountHow discount_how, int SCU, gnc_numeric *value, gnc_numeric *discount_value, GList **tax_value) { @@ -975,11 +977,15 @@ void gncEntryComputeValue (gnc_numeric qty, gnc_numeric price, * need to compute taxes (based on 'pretax') if the caller wants it. */ - if (discount_value != NULL) + if (discount_value != NULL) { + if (SCU) discount = gnc_numeric_convert(discount, SCU, GNC_RND_ROUND); *discount_value = discount; + } - if (value != NULL) + if (value != NULL) { + if (SCU) result = gnc_numeric_convert(result, SCU, GNC_RND_ROUND); *value = result; + } /* Now... Compute the list of tax values (if the caller wants it) */ @@ -995,12 +1001,14 @@ void gncEntryComputeValue (gnc_numeric qty, gnc_numeric price, switch (gncTaxTableEntryGetType (entry)) { case GNC_AMT_TYPE_VALUE: + if (SCU) amount = gnc_numeric_convert(amount, SCU, GNC_RND_ROUND); taxes = gncAccountValueAdd (taxes, acc, amount); break; case GNC_AMT_TYPE_PERCENT: amount = gnc_numeric_div (amount, percent, GNC_DENOM_AUTO, GNC_DENOM_LCD); tax = gnc_numeric_mul (pretax, amount, GNC_DENOM_AUTO, GNC_DENOM_LCD); + if (SCU) tax = gnc_numeric_convert(tax, SCU, GNC_RND_ROUND); taxes = gncAccountValueAdd (taxes, acc, tax); break; default: @@ -1066,12 +1074,16 @@ gncEntryRecomputeValues (GncEntry *entry) entry->b_tax_values = NULL; } + /* Determine the commodity denominator */ + denom = get_entry_commodity_denom (entry); + /* Compute the invoice values */ gncEntryComputeValue (entry->quantity, entry->i_price, (entry->i_taxable ? entry->i_tax_table : NULL), entry->i_taxincluded, entry->i_discount, entry->i_disc_type, entry->i_disc_how, + denom, &(entry->i_value), &(entry->i_disc_value), &(entry->i_tax_values)); @@ -1080,9 +1092,9 @@ gncEntryRecomputeValues (GncEntry *entry) (entry->b_taxable ? entry->b_tax_table : NULL), entry->b_taxincluded, gnc_numeric_zero(), GNC_AMT_TYPE_VALUE, GNC_DISC_PRETAX, + denom, &(entry->b_value), NULL, &(entry->b_tax_values)); - denom = get_entry_commodity_denom (entry); entry->i_value_rounded = gnc_numeric_convert (entry->i_value, denom, GNC_RND_ROUND); entry->i_disc_value_rounded = gnc_numeric_convert (entry->i_disc_value, denom, diff --git a/src/business/business-core/gncEntry.h b/src/business/business-core/gncEntry.h index 865322d691..349522422e 100644 --- a/src/business/business-core/gncEntry.h +++ b/src/business/business-core/gncEntry.h @@ -174,7 +174,9 @@ GList * gncEntryReturnTaxValues (GncEntry *entry, gboolean is_inv); /** Compute the Entry value, tax-value, and discount_value, based on * the quantity, price, discount, tax-table, and types. The value is * the amount the merchant gets, the taxes are what the gov't gets, - * and the discount is how much the customer saved. + * and the discount is how much the customer saved. The SCU is the + * target denominator of the value and tax -- it should be the + * account or commodity SCU of the target. * * The tax_values list is the property of the entry and will be * destroyed automatically, so use it quickly. Note that all return @@ -187,7 +189,7 @@ void gncEntryGetValue (GncEntry *entry, gboolean is_inv, gnc_numeric *value, void gncEntryComputeValue (gnc_numeric qty, gnc_numeric price, GncTaxTable *tax_table, gboolean tax_included, gnc_numeric discount, GncAmountType discount_type, - GncDiscountHow discount_how, + GncDiscountHow discount_how, int SCU, /* return values */ gnc_numeric *value, gnc_numeric *discount_value, GList **tax_values); diff --git a/src/business/business-ledger/gncEntryLedger.c b/src/business/business-ledger/gncEntryLedger.c index fba53c82ac..41763af9c9 100644 --- a/src/business/business-ledger/gncEntryLedger.c +++ b/src/business/business-ledger/gncEntryLedger.c @@ -672,16 +672,12 @@ gnc_entry_ledger_compute_value (GncEntryLedger *ledger, gncEntryComputeValue (qty, price, (taxable ? table : NULL), taxincluded, discount, disc_type, disc_how, + 100, /* XXX -- compute a real denominator */ value, NULL, &taxes); - /* Now convert the values to the proper denomination */ - if (value) - *value = gnc_numeric_convert (*value, 100 /* XXX */, GNC_RND_ROUND); - - if (tax_value) { + /* return the tax value */ + if (tax_value) *tax_value = gncAccountValueTotal (taxes); - *tax_value = gnc_numeric_convert (*tax_value, 100 /* XXX */, GNC_RND_ROUND); - } } gboolean