Use fixed year of 365 days

issue8743
review254471002
This commit is contained in:
Cédric Krier
2019-11-16 14:49:18 +01:00
parent db83ccf3bf
commit 3523c26bbe
4 changed files with 72 additions and 8 deletions
+2
View File
@@ -1,3 +1,5 @@
* Use fixed year of 365 days
Version 5.4.0 - 2019-11-04
* Bug fixes (see mercurial logs for details)
* Add depreciated amount
+35 -6
View File
@@ -30,6 +30,26 @@ def date2datetime(date):
return datetime.datetime.combine(date, datetime.time())
February = 2
def normalized_delta(start, end):
"Returns timedelta using fixed 365 days per year"
assert start <= end
delta = end - start
correction = 0
if start.year == end.year:
if calendar.isleap(start.year) and start.month <= 2 and end.month > 2:
correction -= 1
else:
if calendar.isleap(start.year) and start.month <= February:
correction -= 1
if calendar.isleap(end.year) and end.month > February:
correction -= 1
correction -= calendar.leapdays(start.year + 1, end.year)
return delta + datetime.timedelta(days=correction)
class Asset(Workflow, ModelSQL, ModelView):
'Asset'
__name__ = 'account.asset'
@@ -396,21 +416,30 @@ class Asset(Workflow, ModelSQL, ModelView):
start_date = max([self.start_date
- relativedelta.relativedelta(days=1)]
+ [l.date for l in self.lines])
first_delta = dates[0] - start_date
first_delta = normalized_delta(start_date, dates[0])
if len(dates) > 1:
last_delta = dates[-1] - dates[-2]
last_delta = normalized_delta(dates[-2], dates[-1])
else:
last_delta = first_delta
if self.frequency == 'monthly':
_, first_ndays = calendar.monthrange(
dates[0].year, dates[0].month)
if (calendar.isleap(dates[0].year)
and dates[0].month == February):
first_ndays -= 1
_, last_ndays = calendar.monthrange(
dates[-1].year, dates[-1].month)
if (calendar.isleap(dates[-1].year)
and dates[-1].month == February):
last_ndays -= 1
elif self.frequency == 'yearly':
first_ndays = 365 + calendar.isleap(dates[0].year)
last_ndays = 365 + calendar.isleap(dates[-1].year)
first_ratio = Decimal(first_delta.days) / Decimal(first_ndays)
last_ratio = Decimal(last_delta.days) / Decimal(last_ndays)
first_ndays = last_ndays = 365
first_ratio = (
Decimal(min(first_delta.days, first_ndays))
/ Decimal(first_ndays))
last_ratio = (
Decimal(min(last_delta.days, last_ndays))
/ Decimal(last_ndays))
depreciation = amount / (
len(dates) - 2 + first_ratio + last_ratio)
if date == dates[0]:
+6 -2
View File
@@ -13,10 +13,14 @@ An Asset defines how an asset is depreciated. It is mainly defined by:
- Value, Depreciated Amount and Residual Value.
- Start and End Date.
- Depreciation Method:
- Linear
- Frequency:
- Monthly
- Yearly
- Yearly (using fixed year of 365 days)
- Lines.
The asset can be in one of this states:
@@ -31,7 +35,7 @@ The asset can be in one of this states:
* Closed
The value of the asset has been completly depreciated.
The value of the asset has been completely depreciated.
A wizard "Create Assets Moves" allows to post all accounting move up to a date.
+29
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 as dt
import unittest
import doctest
import trytond.tests.test_tryton
@@ -7,12 +8,40 @@ from trytond.tests.test_tryton import ModuleTestCase
from trytond.tests.test_tryton import doctest_teardown
from trytond.tests.test_tryton import doctest_checker
from trytond.modules.account_asset.asset import normalized_delta
class AccountAssetTestCase(ModuleTestCase):
'Test AccountAsset module'
module = 'account_asset'
extras = ['purchase']
def test_normalized_delta(self):
"Test normalized detal"
for start, end, delta in [
(dt.date(2019, 1, 1), dt.date(2019, 12, 31),
dt.timedelta(days=364)),
(dt.date(2019, 1, 1), dt.date(2020, 1, 1),
dt.timedelta(days=365)),
(dt.date(2019, 1, 1), dt.date(2019, 3, 1),
dt.timedelta(days=31 + 28)),
(dt.date(2024, 1, 1), dt.date(2024, 2, 1),
dt.timedelta(days=31)),
(dt.date(2024, 1, 1), dt.date(2024, 3, 1),
dt.timedelta(days=31 + 28)),
(dt.date(2024, 3, 1), dt.date(2024, 4, 1),
dt.timedelta(days=31)),
(dt.date(2024, 1, 1), dt.date(2025, 1, 1),
dt.timedelta(days=365)),
(dt.date(2023, 1, 1), dt.date(2025, 1, 1),
dt.timedelta(days=365 * 2)),
(dt.date(2000, 1, 1), dt.date(2020, 1, 1),
dt.timedelta(days=365 * 20)),
]:
self.assertEqual(
normalized_delta(start, end), delta,
msg='%s - %s' % (start, end))
def suite():
suite = trytond.tests.test_tryton.suite()