Add reverse_compute on Tax
issue4444 review6801002
This commit is contained in:
1 parent
d4165ad05a
commit
94b7a8676a
3 files changed
+79
-3
No files matched your search
@@ -1,3 +1,4 @@
|
||||
* Add reverse_compute on Tax
|
||||
* Add fix_party script
|
||||
* Allow to display only the balance in the General Ledger
|
||||
* Add TaxableMixin
|
||||
|
||||
@@ -788,11 +788,47 @@ class Tax(ModelSQL, ModelView):
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def sort_taxes(cls, taxes):
|
||||
def _reverse_rate_amount(cls, taxes, date):
|
||||
rate = None
|
||||
amount = 0
|
||||
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 == 'percentage':
|
||||
if rate is None:
|
||||
rate = tax.rate
|
||||
else:
|
||||
rate *= tax.rate
|
||||
elif tax.type == 'fixed':
|
||||
amount += tax.amount
|
||||
|
||||
if tax.childs:
|
||||
child_rate, child_amount = cls._reverse_rate_amount(
|
||||
tax.childs, date)
|
||||
if rate is None:
|
||||
rate = child_rate
|
||||
else:
|
||||
rate *= child_rate
|
||||
amount += child_amount
|
||||
return rate, amount
|
||||
|
||||
@classmethod
|
||||
def _reverse_unit_compute(cls, price_unit, taxes, date):
|
||||
rate, amount = cls._reverse_rate_amount(taxes, date)
|
||||
price_unit -= amount
|
||||
if rate is not None:
|
||||
price_unit = price_unit / (1 + rate)
|
||||
return price_unit
|
||||
|
||||
@classmethod
|
||||
def sort_taxes(cls, taxes, reverse=False):
|
||||
'''
|
||||
Return a list of taxes sorted
|
||||
'''
|
||||
return sorted(taxes, key=lambda t: (t.sequence, t.id))
|
||||
return sorted(taxes, key=lambda t: (t.sequence, t.id), reverse=reverse)
|
||||
|
||||
@classmethod
|
||||
def compute(cls, taxes, price_unit, quantity, date=None):
|
||||
@@ -815,6 +851,18 @@ class Tax(ModelSQL, ModelView):
|
||||
row['amount'] *= quantity
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def reverse_compute(cls, price_unit, taxes, date=None):
|
||||
'''
|
||||
Reverse compute the price_unit for taxes at the date.
|
||||
'''
|
||||
pool = Pool()
|
||||
Date = pool.get('ir.date')
|
||||
if date is None:
|
||||
date = Date.today()
|
||||
taxes = cls.sort_taxes(taxes, reverse=True)
|
||||
return cls._reverse_unit_compute(price_unit, taxes, date)
|
||||
|
||||
def update_tax(self, template2tax_code, template2account,
|
||||
template2tax=None):
|
||||
'''
|
||||
|
||||
+28
-1
@@ -329,7 +329,7 @@ class AccountTestCase(unittest.TestCase):
|
||||
transaction.cursor.rollback()
|
||||
|
||||
def test0040tax_compute(self):
|
||||
'Test tax compute'
|
||||
'Test tax compute/reverse_compute'
|
||||
with Transaction().start(DB_NAME, USER, context=CONTEXT):
|
||||
today = datetime.date.today()
|
||||
|
||||
@@ -372,6 +372,10 @@ class AccountTestCase(unittest.TestCase):
|
||||
'tax': child2,
|
||||
}])
|
||||
|
||||
self.assertEqual(
|
||||
self.tax.reverse_compute(Decimal('130'), [tax]),
|
||||
Decimal('100'))
|
||||
|
||||
child1.end_date = today + relativedelta(days=5)
|
||||
child1.save()
|
||||
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2, today),
|
||||
@@ -385,6 +389,10 @@ class AccountTestCase(unittest.TestCase):
|
||||
'tax': child2,
|
||||
}])
|
||||
|
||||
self.assertEqual(
|
||||
self.tax.reverse_compute(Decimal('130'), [tax], today),
|
||||
Decimal('100'))
|
||||
|
||||
child1.start_date = today + relativedelta(days=1)
|
||||
child1.save()
|
||||
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2, today),
|
||||
@@ -393,6 +401,9 @@ class AccountTestCase(unittest.TestCase):
|
||||
'amount': Decimal('20'),
|
||||
'tax': child2,
|
||||
}])
|
||||
self.assertEqual(
|
||||
self.tax.reverse_compute(Decimal('110'), [tax], today),
|
||||
Decimal('100'))
|
||||
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2,
|
||||
today + relativedelta(days=1)), [{
|
||||
'base': Decimal('200'),
|
||||
@@ -403,6 +414,10 @@ class AccountTestCase(unittest.TestCase):
|
||||
'amount': Decimal('20'),
|
||||
'tax': child2,
|
||||
}])
|
||||
self.assertEqual(
|
||||
self.tax.reverse_compute(
|
||||
Decimal('130'), [tax], today + relativedelta(days=1)),
|
||||
Decimal('100'))
|
||||
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2,
|
||||
today + relativedelta(days=5)), [{
|
||||
'base': Decimal('200'),
|
||||
@@ -413,12 +428,20 @@ class AccountTestCase(unittest.TestCase):
|
||||
'amount': Decimal('20'),
|
||||
'tax': child2,
|
||||
}])
|
||||
self.assertEqual(
|
||||
self.tax.reverse_compute(Decimal('130'), [tax],
|
||||
today + relativedelta(days=5)),
|
||||
Decimal('100'))
|
||||
self.assertEqual(self.tax.compute([tax], Decimal('100'), 2,
|
||||
today + relativedelta(days=6)), [{
|
||||
'base': Decimal('200'),
|
||||
'amount': Decimal('20'),
|
||||
'tax': child2,
|
||||
}])
|
||||
self.assertEqual(
|
||||
self.tax.reverse_compute(Decimal('110'), [tax],
|
||||
today + relativedelta(days=6)),
|
||||
Decimal('100'))
|
||||
|
||||
child1.end_date = None
|
||||
child1.save()
|
||||
@@ -432,6 +455,10 @@ class AccountTestCase(unittest.TestCase):
|
||||
'amount': Decimal('20'),
|
||||
'tax': child2,
|
||||
}])
|
||||
self.assertEqual(
|
||||
self.tax.reverse_compute(Decimal('130'), [tax],
|
||||
today + relativedelta(days=6)),
|
||||
Decimal('100'))
|
||||
|
||||
|
||||
def suite():
|
||||
|
||||
Reference in new issue
Block a user