Add Tax rounding configuration

issue4106
review11401002
This commit is contained in:
Cédric Krier committed 2014-09-17 22:19:37 +02:00
1 parent 561151b719
commit ffbc7a3432
8 files changed
+167 -21

No files matched your search

+2
View File
@@ -1,3 +1,5 @@
* Add Tax rounding configuration
Version 3.2.0 - 2014-04-21
* Bug fixes (see mercurial logs for details)
* Use account of write-off journal as default
+2
View File
@@ -27,6 +27,8 @@ def register():
Period,
Move,
Reconciliation,
Configuration,
ConfigurationTaxRounding,
module='account_invoice', type_='model')
Pool.register(
PrintInvoice,
+54 -2
View File
@@ -1,12 +1,64 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from trytond.model import fields
from trytond.model import ModelSQL, ModelView, MatchMixin, fields
from trytond.pyson import Eval
from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
__all__ = ['FiscalYear', 'Period', 'Move', 'Reconciliation']
__all__ = ['Configuration', 'ConfigurationTaxRounding',
'FiscalYear', 'Period', 'Move', 'Reconciliation']
__metaclass__ = PoolMeta
tax_roundings = [
('document', 'Per Document'),
('line', 'Per Line'),
]
class Configuration:
__name__ = 'account.configuration'
tax_rounding = fields.Function(fields.Selection(tax_roundings,
'Tax Rounding'), 'on_change_with_tax_rounding')
tax_roundings = fields.One2Many('account.configuration.tax_rounding',
'configuration', 'Tax Roundings')
@fields.depends('tax_roundings')
def on_change_with_tax_rounding(self, name=None, pattern=None):
context = Transaction().context
if pattern is None:
pattern = {}
pattern = pattern.copy()
pattern['company'] = context.get('company')
for line in self.tax_roundings:
if line.match(pattern):
return line.method
return 'document'
class ConfigurationTaxRounding(ModelSQL, ModelView, MatchMixin):
'Account Configuration Tax Rounding'
__name__ = 'account.configuration.tax_rounding'
configuration = fields.Many2One('account.configuration', 'Configuration',
required=True, ondelete='CASCADE')
sequence = fields.Integer('Sequence')
company = fields.Many2One('company.company', 'Company')
method = fields.Selection(tax_roundings, 'Method', required=True)
@classmethod
def __setup__(cls):
super(ConfigurationTaxRounding, cls).__setup__()
cls._order.insert(0, ('sequence', 'ASC'))
@staticmethod
def order_sequence(tables):
table, _ = tables[None]
return [table.sequence == None, table.sequence]
@staticmethod
def default_method():
return 'document'
class FiscalYear:
__name__ = 'account.fiscalyear'
+36
View File
@@ -3,6 +3,42 @@
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.ui.view" id="configuration_view_form">
<field name="model">account.configuration</field>
<field name="inherit" ref="account.configuration_view_form"/>
<field name="name">configuration_form</field>
</record>
<record model="ir.ui.view" id="configuration_tax_rounding_view_form">
<field name="model">account.configuration.tax_rounding</field>
<field name="type">form</field>
<field name="name">configuration_tax_rounding_form</field>
</record>
<record model="ir.ui.view" id="configuration_tax_rounding_view_list">
<field name="model">account.configuration.tax_rounding</field>
<field name="type">tree</field>
<field name="name">configuration_tax_rounding_list</field>
</record>
<record model="ir.model.access" id="access_configuration_tax_rounding">
<field name="model"
search="[('model', '=', 'account.configuration.tax_rounding')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access"
id="access_configuration_tax_rounding_account_admin">
<field name="model"
search="[('model', '=', 'account.configuration.tax_rounding')]"/>
<field name="group" ref="account.group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="fiscalyear_view_form">
<field name="model">account.fiscalyear</field>
<field name="inherit" ref="account.fiscalyear_view_form"/>
+40 -19
View File
@@ -436,6 +436,10 @@ class Invoice(Workflow, ModelSQL, ModelView):
InvoiceTax = pool.get('account.invoice.tax')
Account = pool.get('account.account')
TaxCode = pool.get('account.tax.code')
Configuration = pool.get('account.configuration')
config = Configuration(1)
res = {
'untaxed_amount': Decimal('0.0'),
'tax_amount': Decimal('0.0'),
@@ -443,6 +447,13 @@ class Invoice(Workflow, ModelSQL, ModelView):
'taxes': {},
}
computed_taxes = {}
def round_taxes():
if self.currency:
for value in computed_taxes.itervalues():
for field in ('base', 'amount'):
value[field] = self.currency.round(value[field])
if self.lines:
context = self.get_tax_context()
for line in self.lines:
@@ -457,16 +468,16 @@ class Invoice(Workflow, ModelSQL, ModelView):
for tax in taxes:
key, val = self._compute_tax(tax,
self.type or 'out_invoice')
if not key in computed_taxes:
if key not in computed_taxes:
computed_taxes[key] = val
else:
computed_taxes[key]['base'] += val['base']
computed_taxes[key]['amount'] += val['amount']
if self.currency:
for key in computed_taxes:
for field in ('base', 'amount'):
computed_taxes[key][field] = self.currency.round(
computed_taxes[key][field])
if config.tax_rounding == 'line':
round_taxes()
if config.tax_rounding == 'document':
round_taxes()
tax_keys = []
for tax in (self.taxes or []):
if tax.manual:
@@ -808,31 +819,41 @@ class Invoice(Workflow, ModelSQL, ModelView):
return key, val
def _compute_taxes(self):
Tax = Pool().get('account.tax')
pool = Pool()
Tax = pool.get('account.tax')
Configuration = pool.get('account.configuration')
config = Configuration(1)
context = self.get_tax_context()
res = {}
taxes = {}
def round_taxes():
for value in taxes.itervalues():
for field in ('base', 'amount'):
value[field] = self.currency.round(value[field])
for line in self.lines:
# Don't round on each line to handle rounding error
if line.type != 'line':
continue
with Transaction().set_context(**context):
taxes = Tax.compute(line.taxes, line.unit_price,
tax_list = Tax.compute(line.taxes, line.unit_price,
line.quantity,
date=self.accounting_date or self.invoice_date)
for tax in taxes:
for tax in tax_list:
key, val = self._compute_tax(tax, self.type)
val['invoice'] = self.id
if not key in res:
res[key] = val
if key not in taxes:
taxes[key] = val
else:
res[key]['base'] += val['base']
res[key]['amount'] += val['amount']
for key in res:
for field in ('base', 'amount'):
res[key][field] = self.currency.round(res[key][field])
return res
taxes[key]['base'] += val['base']
taxes[key]['amount'] += val['amount']
if config.tax_rounding == 'line':
round_taxes()
if config.tax_rounding == 'document':
round_taxes()
return taxes
@classmethod
def update_taxes(cls, invoices, exception=False):
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/form/field[@name='default_account_payable']" position="after">
<group id="tax_roundings" col="2" colspan="4">
<field name="tax_roundings" colspan="2"/>
<label name="tax_rounding"/>
<field name="tax_rounding"/>
</group>
</xpath>
</data>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<form string="Account Configuration Tax Rounding" cursor="company">
<label name="configuration"/>
<field name="configuration"/>
<label name="sequence"/>
<field name="sequence"/>
<label name="company"/>
<field name="company"/>
<label name="method"/>
<field name="method"/>
</form>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree string="Account Configuration Tax Roundings" sequence="sequence">
<field name="configuration"/>
<field name="company"/>
<field name="method" expand="1"/>
</tree>