diff --git a/sale.py b/sale.py index 6e453267c6..472ea7ae0e 100644 --- a/sale.py +++ b/sale.py @@ -426,63 +426,89 @@ class Sale(Workflow, ModelSQL, ModelView): pool = Pool() Tax = pool.get('account.tax') Invoice = pool.get('account.invoice') + Configuration = pool.get('account.configuration') - res = { + config = Configuration(1) + + changes = { 'untaxed_amount': Decimal('0.0'), 'tax_amount': Decimal('0.0'), 'total_amount': Decimal('0.0'), } if self.lines: + context = self.get_tax_context() taxes = {} + + def round_taxes(): + if self.currency: + for key, value in taxes.iteritems(): + taxes[key] = self.currency.round(value) + for line in self.lines: if getattr(line, 'type', 'line') != 'line': continue - res['untaxed_amount'] += (getattr(line, 'amount', None) + changes['untaxed_amount'] += (getattr(line, 'amount', None) or Decimal(0)) - tax_list = () - with Transaction().set_context(self.get_tax_context()): + + with Transaction().set_context(context): tax_list = Tax.compute(getattr(line, 'taxes', []), getattr(line, 'unit_price', None) or Decimal('0.0'), getattr(line, 'quantity', None) or 0.0) for tax in tax_list: key, val = Invoice._compute_tax(tax, 'out_invoice') - if not key in taxes: + if key not in taxes: taxes[key] = val['amount'] else: taxes[key] += val['amount'] - if self.currency: - for key in taxes: - res['tax_amount'] += self.currency.round(taxes[key]) + if config.tax_rounding == 'line': + round_taxes() + if config.tax_rounding == 'document': + round_taxes() + changes['tax_amount'] = sum(taxes.itervalues(), Decimal('0.0')) if self.currency: - res['untaxed_amount'] = self.currency.round(res['untaxed_amount']) - res['tax_amount'] = self.currency.round(res['tax_amount']) - res['total_amount'] = res['untaxed_amount'] + res['tax_amount'] + changes['untaxed_amount'] = self.currency.round( + changes['untaxed_amount']) + changes['tax_amount'] = self.currency.round(changes['tax_amount']) + changes['total_amount'] = (changes['untaxed_amount'] + + changes['tax_amount']) if self.currency: - res['total_amount'] = self.currency.round(res['total_amount']) - return res + changes['total_amount'] = self.currency.round( + changes['total_amount']) + return changes def get_tax_amount(self): pool = Pool() Tax = pool.get('account.tax') Invoice = pool.get('account.invoice') + Configuration = pool.get('account.configuration') + + config = Configuration(1) context = self.get_tax_context() taxes = {} + + def round_taxes(): + for key, value in taxes.iteritems(): + taxes[key] = self.currency.round(value) + for line in self.lines: if line.type != 'line': continue with Transaction().set_context(context): tax_list = Tax.compute(line.taxes, line.unit_price, line.quantity) - # Don't round on each line to handle rounding error for tax in tax_list: key, val = Invoice._compute_tax(tax, 'out_invoice') - if not key in taxes: + if key not in taxes: taxes[key] = val['amount'] else: taxes[key] += val['amount'] - return sum((self.currency.round(tax) for tax in taxes.values()), _ZERO) + if config.tax_rounding == 'line': + round_taxes() + if config.tax_rounding == 'document': + round_taxes() + return sum(taxes.itervalues(), _ZERO) @classmethod def get_amount(cls, sales, names):