Add asset depreciation report

issue4184
review14501002
This commit is contained in:
Nicolas Évrard committed 2015-02-03 17:20:11 +01:00
1 parent 78fa67cbeb
commit cd4cbe7b7a
9 files changed
+249 -3

No files matched your search

+2
View File
@@ -1,3 +1,5 @@
* Add asset depreciation report
Version 3.4.0 - 2014-10-20
* Bug fixes (see mercurial logs for details)
+2
View File
@@ -5,6 +5,8 @@ Prerequisites
-------------
* Python 2.7 or later (http://www.python.org/)
* python-dateutil (http://labix.org/python-dateutil)
* cached-property (https://github.com/pydanny/cached-property)
* trytond (http://www.tryton.org/)
* trytond_account (http://www.tryton.org/)
* trytond_account_product (http://www.tryton.org/)
+5
View File
@@ -16,6 +16,7 @@ def register():
CreateMovesStart,
UpdateAssetStart,
UpdateAssetShowDepreciation,
PrintDepreciationTableStart,
Category,
Template,
InvoiceLine,
@@ -26,4 +27,8 @@ def register():
Pool.register(
CreateMoves,
UpdateAsset,
PrintDepreciationTable,
module='account_asset', type_='wizard')
Pool.register(
AssetDepreciationTable,
module='account_asset', type_='report')
+203 -2
View File
@@ -5,17 +5,23 @@ import calendar
from decimal import Decimal
from dateutil import relativedelta
from dateutil import rrule
from itertools import groupby
from cached_property import cached_property
from trytond.model import Workflow, ModelSQL, ModelView, fields
from trytond.pyson import Eval, Bool, If
from trytond.pool import Pool
from trytond.transaction import Transaction
from trytond.wizard import Wizard, StateView, StateTransition, Button
from trytond.wizard import (Wizard, StateView, StateTransition, StateAction,
Button)
from trytond.tools import grouped_slice
from trytond.modules.company import CompanyReport
__all__ = ['Asset', 'AssetLine', 'AssetUpdateMove',
'CreateMovesStart', 'CreateMoves',
'UpdateAssetStart', 'UpdateAssetShowDepreciation', 'UpdateAsset']
'UpdateAssetStart', 'UpdateAssetShowDepreciation', 'UpdateAsset',
'AssetDepreciationTable',
'PrintDepreciationTableStart', 'PrintDepreciationTable']
def date2datetime(date):
@@ -811,3 +817,198 @@ class UpdateAsset(Wizard):
})
Asset.create_lines([asset])
return 'end'
class AssetDepreciationTable(CompanyReport):
'Asset Depreciation Table'
__name__ = 'account.asset.depreciation_table'
@classmethod
def get_context(cls, records, data):
context = super(AssetDepreciationTable, cls).get_context(records, data)
AssetDepreciation = cls.get_asset_depreciation()
AssetDepreciation.start_date = data['start_date']
AssetDepreciation.end_date = data['end_date']
Grouper = cls.get_grouper()
grouped_assets = groupby(sorted(records, key=cls.group_assets),
cls.group_assets)
context['grouped_depreciations'] = grouped_depreciations = []
for g_key, assets in grouped_assets:
depreciations = [AssetDepreciation(a) for a in assets]
grouped_depreciations.append(Grouper(g_key, depreciations))
return context
@staticmethod
def group_assets(asset):
return asset.product
@classmethod
def get_grouper(cls):
class Grouper(object):
def __init__(self, key, depreciations):
self.product = key
self.depreciations = depreciations
for attr_name in self.grouped_attributes():
setattr(self, attr_name,
cached_property(self.adder(attr_name)))
def adder(self, attr_name):
def _sum(self):
return sum(getattr(d, attr_name)
for d in self.depreciations if getattr(d, attr_name))
return _sum
@staticmethod
def grouped_attributes():
return {
'start_fixed_value',
'value_increase',
'value_decrease',
'end_fixed_value',
'start_value',
'amortization_increase',
'amortization_decrease',
'end_value',
'actual_value',
'closing_value',
}
return Grouper
@classmethod
def get_asset_depreciation(cls):
class AssetDepreciation(object):
def __init__(self, asset):
self.asset = asset
@cached_property
def asset_lines(self):
return filter(
lambda l: self.start_date < l.date <= self.end_date,
self.asset.lines)
@cached_property
def update_lines(self):
filter_ = lambda l: (l.account.kind == 'other'
and self.start_date < l.move.date <= self.end_date)
return filter(filter_,
(l for m in self.asset.update_moves for l in m.lines))
@cached_property
def start_fixed_value(self):
if self.start_date < self.asset.start_date:
return 0
value = self.asset_lines[0].acquired_value
date = self.asset_lines[0].date
for line in self.update_lines:
if line.move.date < date:
value += line.debit - line.credit
return value
@cached_property
def value_increase(self):
value = sum(l.debit - l.credit for l in self.update_lines
if l.debit > l.credit)
if self.start_date < self.asset.start_date:
value += self.asset_lines[0].acquired_value
return value
@cached_property
def value_decrease(self):
return sum(l.credit - l.debit for l in self.update_lines
if l.credit > l.debit)
@cached_property
def end_fixed_value(self):
value = self.asset_lines[-1].acquired_value
date = self.asset_lines[-1].date
for line in self.update_lines:
if line.move.date > date:
value += line.debit - line.credit
return value
@cached_property
def start_value(self):
return (self.asset_lines[0].actual_value
+ self.asset_lines[0].depreciation)
@cached_property
def amortization_increase(self):
return sum(l.depreciation for l in self.asset_lines
if l.depreciation > 0)
@cached_property
def amortization_decrease(self):
return sum(l.depreciation for l in self.asset_lines
if l.depreciation < 0)
@cached_property
def end_value(self):
return self.asset_lines[-1].actual_value
@cached_property
def actual_value(self):
value = self.end_value
date = self.asset_lines[-1].date
value += sum(l.debit - l.credit for l in self.update_lines
if l.move.date > date)
return value
@cached_property
def closing_value(self):
if not self.asset.move:
return None
revenue_lines = [l for l in self.asset.move.lines
if l.account == self.asset.product.account_revenue_used]
return sum(l.debit - l.credit for l in revenue_lines)
return AssetDepreciation
class PrintDepreciationTableStart(ModelView):
'Asset Depreciation Table Start'
__name__ = 'account.asset.print_depreciation_table.start'
start_date = fields.Date('Start Date', required=True,
domain=[('start_date', '<', Eval('end_date'))],
depends=['end_date'])
end_date = fields.Date('End Date', required=True,
domain=[('end_date', '>', Eval('start_date'))],
depends=['start_date'])
@staticmethod
def default_start_date():
return datetime.date.today() - relativedelta.relativedelta(years=1)
@staticmethod
def default_end_date():
return datetime.date.today()
class PrintDepreciationTable(Wizard):
'Asset Depreciation Table'
__name__ = 'account.asset.print_depreciation_table'
start = StateView('account.asset.print_depreciation_table.start',
'account_asset.print_depreciation_table_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-print', default=True),
])
print_ = StateAction('account_asset.report_depreciation_table')
def do_print_(self, action):
pool = Pool()
Asset = pool.get('account.asset')
assets = Asset.search([
('start_date', '<', self.start.end_date),
('end_date', '>', self.start.start_date),
('state', '=', 'running'),
])
return action, {
'ids': [a.id for a in assets],
'start_date': self.start.start_date,
'end_date': self.start.end_date,
}
+21
View File
@@ -185,6 +185,27 @@
</record>
<menuitem name="Create Assets Moves" parent="menu_asset" sequence="10"
action="wizard_create_moves" id="menu_create_moves"/>
<record model="ir.action.report" id="report_depreciation_table">
<field name="name">Depreciation Table</field>
<field name="model">account.asset</field>
<field name="report_name">account.asset.depreciation_table</field>
<field name="report">account_asset/asset_table.odt</field>
</record>
<record model="ir.ui.view"
id="print_depreciation_table_start_view_form">
<field name="model">account.asset.print_depreciation_table.start</field>
<field name="type">form</field>
<field name="name">print_depreciation_table_start</field>
</record>
<record model="ir.action.wizard" id="wizard_print_depreciation_table">
<field name="name">Print Depreciation Table</field>
<field name="wiz_name">account.asset.print_depreciation_table</field>
</record>
<menuitem name="Print Depreciation Table" icon="tryton-print"
parent="account.menu_reporting"
action="wizard_print_depreciation_table"
id="menu_create_depreciation_table"/>
</data>
<data noupdate="1">
<record model="account.journal" id="journal_asset">
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -41,7 +41,7 @@ if minor_version % 2:
'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
name[8:], name, version))
requires = []
requires = ['cached-property', 'python-dateutil']
for dep in info.get('depends', []):
if not re.match(r'(ir|res|webdav)(\W|$)', dep):
requires.append(get_require_version('trytond_%s' % dep))
+6
View File
@@ -258,3 +258,9 @@ Sale the asset::
Decimal('339.28')
>>> depreciation_account.credit
Decimal('239.28')
Generate the asset report::
>>> print_depreciation_table = Wizard(
... 'account.asset.print_depreciation_table')
>>> print_depreciation_table.execute('print_')
+9
View File
@@ -0,0 +1,9 @@
<?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="Choose Dates">
<label name="start_date"/>
<field name="start_date"/>
<label name="end_date"/>
<field name="end_date"/>
</form>