Add start/end date to tax

issue3600
review2771002
This commit is contained in:
Cédric Krier
2014-01-31 22:30:34 +01:00
parent 8959193ca6
commit cedde4101f
5 changed files with 136 additions and 6 deletions
+1
View File
@@ -1,3 +1,4 @@
* Add start/end date to tax
* Use account of write-off journal as default
* Add write-off journal type
* Add description on write-off move
+20 -6
View File
@@ -1,5 +1,6 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
import datetime
from decimal import Decimal
from sql.aggregate import Sum
@@ -347,6 +348,8 @@ class TaxTemplate(ModelSQL, ModelView):
description = fields.Char('Description', required=True, translate=True)
group = fields.Many2One('account.tax.group', 'Group')
sequence = fields.Integer('Sequence')
start_date = fields.Date('Starting Date')
end_date = fields.Date('Ending Date')
amount = fields.Numeric('Amount', digits=(16, 8),
states={
'required': Eval('type') == 'fixed',
@@ -449,7 +452,8 @@ class TaxTemplate(ModelSQL, ModelView):
res = {}
for field in ('name', 'description', 'sequence', 'amount',
'rate', 'type', 'invoice_base_sign', 'invoice_tax_sign',
'credit_note_base_sign', 'credit_note_tax_sign'):
'credit_note_base_sign', 'credit_note_tax_sign',
'start_date', 'end_date'):
if not tax or getattr(tax, field) != getattr(self, field):
res[field] = getattr(self, field)
for field in ('group',):
@@ -571,6 +575,8 @@ class Tax(ModelSQL, ModelView):
}, depends=['parent'])
active = fields.Boolean('Active')
sequence = fields.Integer('Sequence', help='Use to order the taxes')
start_date = fields.Date('Starting Date')
end_date = fields.Date('Ending Date')
currency_digits = fields.Function(fields.Integer('Currency Digits'),
'on_change_with_currency_digits')
amount = fields.Numeric('Amount', digits=(16, Eval('currency_digits', 2)),
@@ -749,13 +755,17 @@ class Tax(ModelSQL, ModelView):
}
@classmethod
def _unit_compute(cls, taxes, price_unit):
def _unit_compute(cls, taxes, price_unit, date):
res = []
for tax in taxes:
start_date = tax.start_date or datetime.date.min
end_date = tax.end_date or datetime.date.max
if not (start_date <= date <= end_date):
continue
if tax.type != 'none':
res.append(tax._process_tax(price_unit))
if len(tax.childs):
res.extend(cls._unit_compute(tax.childs, price_unit))
res.extend(cls._unit_compute(tax.childs, price_unit, date))
return res
@classmethod
@@ -766,16 +776,20 @@ class Tax(ModelSQL, ModelView):
return sorted(taxes, key=lambda t: (t.sequence, t.id))
@classmethod
def compute(cls, taxes, price_unit, quantity):
def compute(cls, taxes, price_unit, quantity, date=None):
'''
Compute taxes for price_unit and quantity.
Compute taxes for price_unit and quantity at the date.
Return list of dict for each taxes and their childs with:
base
amount
tax
'''
pool = Pool()
Date = pool.get('ir.date')
if date is None:
date = Date.today()
taxes = cls.sort_taxes(taxes)
res = cls._unit_compute(taxes, price_unit)
res = cls._unit_compute(taxes, price_unit, date)
quantity = Decimal(str(quantity or 0.0))
for row in res:
row['base'] *= quantity
+107
View File
@@ -4,6 +4,7 @@ import unittest
import doctest
import datetime
from decimal import Decimal
from dateutil.relativedelta import relativedelta
import trytond.tests.test_tryton
from trytond.tests.test_tryton import test_view, test_depends, doctest_dropdb
from trytond.tests.test_tryton import POOL, DB_NAME, USER, CONTEXT
@@ -31,6 +32,7 @@ class AccountTestCase(unittest.TestCase):
self.period = POOL.get('account.period')
self.balance_non_deferral = POOL.get(
'account.fiscalyear.balance_non_deferral', type='wizard')
self.tax = POOL.get('account.tax')
def test0005views(self):
'Test views'
@@ -316,6 +318,111 @@ class AccountTestCase(unittest.TestCase):
transaction.cursor.rollback()
def test0040tax_compute(self):
'Test tax compute'
with Transaction().start(DB_NAME, USER, context=CONTEXT):
today = datetime.date.today()
tax_account, = self.account.search([
('name', '=', 'Main Tax'),
])
tax = self.tax()
tax.name = tax.description = 'Test'
tax.type = 'none'
tax.invoice_account = tax_account
tax.credit_note_account = tax_account
child1 = self.tax()
child1.name = child1.description = 'Child 1'
child1.type = 'percentage'
child1.rate = Decimal('0.2')
child1.invoice_account = tax_account
child1.credit_note_account = tax_account
child1.save()
child2 = self.tax()
child2.name = child2.description = 'Child 1'
child2.type = 'fixed'
child2.amount = Decimal('10')
child2.invoice_account = tax_account
child2.credit_note_account = tax_account
child2.save()
tax.childs = [child1, child2]
tax.save()
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2),
[{
'base': Decimal('200'),
'amount': Decimal('40.0'),
'tax': child1,
}, {
'base': Decimal('200'),
'amount': Decimal('20'),
'tax': child2,
}])
child1.end_date = today + relativedelta(days=5)
child1.save()
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2, today),
[{
'base': Decimal('200'),
'amount': Decimal('40.0'),
'tax': child1,
}, {
'base': Decimal('200'),
'amount': Decimal('20'),
'tax': child2,
}])
child1.start_date = today + relativedelta(days=1)
child1.save()
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2, today),
[{
'base': Decimal('200'),
'amount': Decimal('20'),
'tax': child2,
}])
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2,
today + relativedelta(days=1)), [{
'base': Decimal('200'),
'amount': Decimal('40.0'),
'tax': child1,
}, {
'base': Decimal('200'),
'amount': Decimal('20'),
'tax': child2,
}])
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2,
today + relativedelta(days=5)), [{
'base': Decimal('200'),
'amount': Decimal('40.0'),
'tax': child1,
}, {
'base': Decimal('200'),
'amount': Decimal('20'),
'tax': child2,
}])
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2,
today + relativedelta(days=6)), [{
'base': Decimal('200'),
'amount': Decimal('20'),
'tax': child2,
}])
child1.end_date = None
child1.save()
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2,
today + relativedelta(days=6)), [{
'base': Decimal('200'),
'amount': Decimal('40.0'),
'tax': child1,
}, {
'base': Decimal('200'),
'amount': Decimal('20'),
'tax': child2,
}])
def suite():
suite = trytond.tests.test_tryton.suite()
+4
View File
@@ -14,6 +14,10 @@ this repository contains the full copyright notices and license terms. -->
<field name="group"/>
<label name="sequence"/>
<field name="sequence"/>
<label name="start_date"/>
<field name="start_date"/>
<label name="end_date"/>
<field name="end_date"/>
<label name="type"/>
<field name="type"/>
<group col="1" id="label_amount_rate">
+4
View File
@@ -14,6 +14,10 @@ this repository contains the full copyright notices and license terms. -->
<field name="group"/>
<label name="sequence"/>
<field name="sequence"/>
<label name="start_date"/>
<field name="start_date"/>
<label name="end_date"/>
<field name="end_date"/>
<label name="type"/>
<field name="type"/>
<group col="1" id="label_amount_rate">