2
0

[MIG] account_asset_management: Migration to 11.0

This commit is contained in:
Akim Juillerat 2018-10-01 11:57:07 +02:00 committed by Rodrigo
parent 49d1c36679
commit a7cdfdd14d
113 changed files with 40986 additions and 43415 deletions

View File

@ -1,10 +1,29 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: https://www.gnu.org/licenses/agpl
:alt: License: AGPL-3
=================
Assets Management
=================
==========================
Financial asset management
==========================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github
:target: https://github.com/OCA/account-financial-tools/tree/11.0/account_asset_management
:alt: OCA/account-financial-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/account-financial-tools-11-0/account-financial-tools-11-0-account_asset_management
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/92/11.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
This Module manages the assets owned by a company. It will keep
track of depreciation's occurred on those assets. And it allows to create
@ -20,6 +39,11 @@ Excel based reporting is available via the 'account_asset_management_xls' module
The module contains a large number of functional enhancements compared to
the standard account_asset module from Odoo.
**Table of contents**
.. contents::
:local:
Configuration
=============
@ -29,46 +53,50 @@ creation of separate assets per Supplier Invoice Line.
Usage
=====
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/92/10.0
Known issues
============
The module in NOT compatible with the standard account_asset module.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/account-financial-tools/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-tools/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_asset_management%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Noviat
Contributors
------------
~~~~~~~~~~~~
- OpenERP SA
- Luc De Meyer (Noviat)
- Frédéric Clementi (camptocamp)
- Florian Dacosta (Akretion)
- Stéphane Bidoul (Acsone)
- Adrien Peiffer (Acsone)
- Akim Juillerat <akim.juillerat@camptocamp.com>
Maintainer
----------
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit http://odoo-community.org.
This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/11.0/account_asset_management>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@ -1,3 +1,2 @@
# -*- coding: utf-8 -*-
from . import models
from . import wizard

View File

@ -1,19 +1,17 @@
# -*- coding: utf-8 -*-
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Assets Management',
'version': '10.0.3.1.0',
'version': '11.0.1.0.0',
'license': 'AGPL-3',
'depends': [
'account_fiscal_year',
],
'conflicts': ['account_asset'],
'author': "Noviat,Odoo Community Association (OCA)",
'website': 'http://www.noviat.com',
'website': 'https://github.com/OCA/account-financial-tools',
'category': 'Accounting & Finance',
'sequence': 32,
'data': [
'security/account_asset_security.xml',
'security/ir.model.access.csv',
@ -22,14 +20,11 @@
'views/account_account.xml',
'views/account_asset.xml',
'views/account_asset_profile.xml',
'views/account_config_settings.xml',
'views/res_config_settings.xml',
'views/account_invoice.xml',
'views/account_invoice_line.xml',
'views/account_move.xml',
'views/account_move_line.xml',
'views/menuitem.xml',
],
'auto_install': False,
'installable': True,
'application': True,
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,148 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2009-2017 Noviat
# Copyright OpenUpgrade contributors (https://github.com/oca/openupgradelib)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
_logger = logging.getLogger(__name__)
_logger.setLevel(logging.DEBUG)
column_renames = {
'account_account': [
('asset_category_id', 'asset_profile_id', 'Asset Profile'),
],
'account_asset': [
('asset_value', 'depreciation_base', 'Depreciation Base'),
('category_id', 'profile_id', 'Asset Profile'),
],
'account_invoice_line': [
('asset_category_id', 'asset_profile_id', 'Asset Profile'),
],
'account_move_line': [
('asset_category_id', 'asset_profile_id', 'Asset Profile'),
],
}
table_renames = [
('account_asset_asset', 'account_asset'),
('account_asset_category', 'account_asset_profile'),
('account_asset_depreciation_line', 'account_asset_line')]
model_renames = [
('account.asset.asset', 'account.asset'),
('account.asset.category', 'account.asset.profile'),
('account.asset.depreciation.line', 'account.asset.line')]
view_refs = [
'account_asset_management.view_account_asset_form',
'account_asset_management.view_invoice_asset_category',
'account_asset_management.view_account_invoice_asset_form',
'account_asset_management.view_account_move_line_form_inherit',
'account_asset_management.view_account_move_asset_form'
]
def is_module_installed(cr, module):
""" Check if `module` is installed.
:return: True / False
"""
cr.execute(
"SELECT id FROM ir_module_module "
"WHERE name=%s and state IN ('installed', 'to upgrade')", (module,))
return bool(cr.fetchone())
def table_exists(cr, table):
""" Check whether a certain table or view exists """
cr.execute('SELECT 1 FROM pg_class WHERE relname = %s', (table,))
return cr.fetchone()
def rename_columns(cr, column_spec):
for table in column_spec.keys():
for (old, new, comment) in column_spec[table]:
cr.execute(
"SELECT column_name "
"FROM information_schema.columns "
"WHERE table_name=%s "
"AND column_name=%s",
(table, new))
res = cr.fetchone()
if not res:
_logger.info("table %s, column %s: renaming to %s",
table, old, new)
cr.execute(
'ALTER TABLE "%s" RENAME "%s" TO "%s"'
% (table, old, new,))
cr.execute('DROP INDEX IF EXISTS "%s_%s_index"' % (table, old))
if comment:
cr.execute(
"COMMENT ON COLUMN %s.%s IS '%s'"
% (table, new, comment))
def rename_tables(cr, table_spec):
to_rename = [x[0] for x in table_spec]
for old, new in list(table_spec):
if (table_exists(cr, old + '_id_seq') and
old + '_id_seq' not in to_rename):
table_spec.append((old + '_id_seq', new + '_id_seq'))
for (old, new) in table_spec:
_logger.info("table %s: renaming to %s",
old, new)
if table_exists(cr, old) and not table_exists(cr, new):
cr.execute('ALTER TABLE "%s" RENAME TO "%s"' % (old, new))
def rename_models(cr, model_spec):
for (old, new) in model_spec:
_logger.info("model %s: renaming to %s",
old, new)
cr.execute('UPDATE ir_model SET model = %s '
'WHERE model = %s', (new, old,))
cr.execute('UPDATE ir_model_fields SET relation = %s '
'WHERE relation = %s', (new, old,))
cr.execute('UPDATE ir_model_data SET model = %s '
'WHERE model = %s', (new, old,))
cr.execute('UPDATE ir_attachment SET res_model = %s '
'WHERE res_model = %s', (new, old,))
cr.execute('UPDATE ir_model_fields SET model = %s '
'WHERE model = %s', (new, old,))
cr.execute('UPDATE ir_translation set '
"name=%s || substr(name, strpos(name, ',')) "
'where name like %s',
(new, old + ',%'),)
if is_module_installed(cr, 'mail'):
# fortunately, the data model didn't change up to now
cr.execute(
'UPDATE mail_message SET model=%s where model=%s', (new, old),
)
if table_exists(cr, 'mail_followers'):
cr.execute(
'UPDATE mail_followers SET res_model=%s '
'WHERE res_model=%s',
(new, old),
)
def remove_views(cr, view_refs):
model = 'ir.ui.view'
for view_ref in view_refs:
module, name = view_ref.split('.')
cr.execute(
'SELECT res_id FROM ir_model_data '
'WHERE module = %s AND name = %s AND model = %s',
(module, name, model)
)
res = cr.fetchone()
if res:
cr.execute(
'DELETE FROM ir_ui_view WHERE id = %s', (res[0],))
def migrate(cr, version):
remove_views(cr, view_refs)
rename_tables(cr, table_renames)
rename_models(cr, model_renames)
rename_columns(cr, column_renames)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from . import account_account
from . import account_asset
from . import account_asset_profile
@ -7,4 +6,4 @@ from . import account_asset_recompute_trigger
from . import account_invoice
from . import account_move
from . import date_range
from . import res_config
from . import res_config_settings

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2009-2017 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -13,6 +12,7 @@ from odoo import api, fields, models, _
import odoo.addons.decimal_precision as dp
from odoo.exceptions import UserError
from odoo.osv import expression
from functools import reduce
_logger = logging.getLogger(__name__)
@ -83,7 +83,9 @@ class AccountAsset(models.Model):
string='Parent Asset', readonly=True,
states={'draft': [('readonly', False)]},
domain=[('type', '=', 'view')],
ondelete='restrict')
ondelete='restrict',
index=True,
)
parent_left = fields.Integer(index=True)
parent_right = fields.Integer(index=True)
child_ids = fields.One2many(
@ -104,7 +106,7 @@ class AccountAsset(models.Model):
('open', 'Running'),
('close', 'Close'),
('removed', 'Removed'),
], string='Status', required=True, default='draft', copy='draft',
], string='Status', required=True, default='draft', copy=False,
help="When an asset is created, the status is 'Draft'.\n"
"If the asset is confirmed, the status goes in 'Running' "
"and the depreciation lines can be posted "
@ -206,7 +208,7 @@ class AccountAsset(models.Model):
for line in asset.depreciation_line_ids:
if line.move_id:
asset.move_line_check = True
continue
break
@api.depends('purchase_value', 'salvage_value', 'type', 'method')
@api.multi
@ -234,17 +236,20 @@ class AccountAsset(models.Model):
lambda l: l.type in ('depreciate', 'remove') and
(l.init_entry or l.move_check))
value_depreciated = sum([l.amount for l in lines])
asset.value_residual = \
asset.depreciation_base - value_depreciated
asset.value_depreciated = value_depreciated
residual = asset.depreciation_base - value_depreciated
depreciated = value_depreciated
else:
asset.value_residual = 0.0
asset.value_depreciated = 0.0
residual = 0.0
depreciated = 0.0
asset.update({
'value_residual': residual,
'value_depreciated': depreciated
})
@api.multi
@api.constrains('parent_id')
def _check_recursion(self, parent=None):
res = super(AccountAsset, self)._check_recursion(parent=parent)
res = super()._check_recursion(parent=parent)
if not res:
raise UserError(
_("Error ! You can not create recursive assets."))
@ -279,9 +284,10 @@ class AccountAsset(models.Model):
dl_create_line = self.depreciation_line_ids.filtered(
lambda r: r.type == 'create')
if dl_create_line:
dl_create_line.write({
dl_create_line.update({
'amount': self.depreciation_base,
'line_date': self.date_start})
'line_date': self.date_start
})
@api.onchange('profile_id')
def _onchange_profile_id(self):
@ -290,16 +296,18 @@ class AccountAsset(models.Model):
raise UserError(
_("You cannot change the profile of an asset "
"with accounting entries."))
if self.profile_id:
profile = self.profile_id
self.parent_id = profile.parent_id
self.method = profile.method
self.method_number = profile.method_number
self.method_time = profile.method_time
self.method_period = profile.method_period
self.method_progress_factor = profile.method_progress_factor
self.prorata = profile.prorata
self.account_analytic_id = profile.account_analytic_id
profile = self.profile_id
if profile:
self.update({
'parent_id': profile.parent_id,
'method': profile.method,
'method_number': profile.method_number,
'method_time': profile.method_time,
'method_period': profile.method_period,
'method_progress_factor': profile.method_progress_factor,
'prorata': profile.prorata,
'account_analytic_id': profile.account_analytic_id,
})
@api.onchange('method_time')
def _onchange_method_time(self):
@ -309,10 +317,12 @@ class AccountAsset(models.Model):
@api.onchange('type')
def _onchange_type(self):
if self.type == 'view':
self.date_start = False
self.profile_id = False
self.purchase_value = False
self.salvage_value = False
self.update({
'date_start': False,
'profile_id': False,
'purchase_value': False,
'salvage_value': False,
})
if self.depreciation_line_ids:
self.depreciation_line_ids.unlink()
@ -322,8 +332,8 @@ class AccountAsset(models.Model):
vals['prorata'] = True
if vals.get('type') == 'view':
vals['date_start'] = False
asset = super(AccountAsset, self).create(vals)
if self._context.get('create_asset_from_move_line'):
asset = super().create(vals)
if self.env.context.get('create_asset_from_move_line'):
# Trigger compute of depreciation_base
asset.salvage_value = 0.0
if asset.type == 'normal':
@ -335,20 +345,19 @@ class AccountAsset(models.Model):
if vals.get('method_time'):
if vals['method_time'] != 'year' and not vals.get('prorata'):
vals['prorata'] = True
super(AccountAsset, self).write(vals)
res = super().write(vals)
for asset in self:
asset_type = vals.get('type') or asset.type
if asset_type == 'view' or \
self._context.get('asset_validate_from_write'):
self.env.context.get('asset_validate_from_write'):
continue
asset._create_first_asset_line()
if asset.profile_id.open_asset and \
self._context.get('create_asset_from_move_line'):
self.env.context.get('create_asset_from_move_line'):
asset.compute_depreciation_board()
# extra context to avoid recursion
ctx = dict(self._context, asset_validate_from_write=True)
asset.with_context(ctx).validate()
return True
asset.with_context(asset_validate_from_write=True).validate()
return res
def _create_first_asset_line(self):
self.ensure_one()
@ -364,8 +373,8 @@ class AccountAsset(models.Model):
'type': 'create',
}
asset_line = asset_line_obj.create(asset_line_vals)
if self._context.get('create_asset_from_move_line'):
asset_line.move_id = self._context['move_id']
if self.env.context.get('create_asset_from_move_line'):
asset_line.move_id = self.env.context['move_id']
@api.multi
def unlink(self):
@ -379,11 +388,11 @@ class AccountAsset(models.Model):
_("You cannot delete an asset that contains "
"posted depreciation lines."))
# update accounting entries linked to lines of type 'create'
ctx = dict(self._context, allow_asset_removal=True,
from_parent_object=True)
amls = self.with_context(ctx).mapped('account_move_line_ids')
amls = self.with_context(
allow_asset_removal=True, from_parent_object=True
).mapped('account_move_line_ids')
amls.write({'asset_id': False})
return super(AccountAsset, self).unlink()
return super().unlink()
@api.model
def name_search(self, name, args=None, operator='ilike', limit=100):
@ -422,7 +431,7 @@ class AccountAsset(models.Model):
@api.multi
def remove(self):
self.ensure_one()
ctx = dict(self._context, active_ids=self.ids, active_id=self.id)
ctx = dict(self.env.context, active_ids=self.ids, active_id=self.id)
early_removal = False
if self.method in ['linear-limit', 'degr-limit']:
@ -441,7 +450,6 @@ class AccountAsset(models.Model):
'target': 'new',
'type': 'ir.actions.act_window',
'context': ctx,
'nodestroy': True,
}
@api.multi
@ -461,13 +469,17 @@ class AccountAsset(models.Model):
'res_model': 'account.move',
'view_id': False,
'type': 'ir.actions.act_window',
'context': self._context,
'nodestroy': True,
'context': self.env.context,
'domain': [('id', 'in', am_ids)],
}
@api.multi
def compute_depreciation_board(self):
def group_lines(x, y):
y.update({'amount': x['amount'] + y['amount']})
return y
line_obj = self.env['account.asset.line']
digits = self.env['decimal.precision'].precision_get('Account')
@ -498,8 +510,8 @@ class AccountAsset(models.Model):
continue
# group lines prior to depreciation start period
depreciation_start_date = datetime.strptime(
asset.date_start, '%Y-%m-%d')
depreciation_start_date = fields.Datetime.from_string(
asset.date_start)
lines = table[0]['lines']
lines1 = []
lines2 = []
@ -512,9 +524,6 @@ class AccountAsset(models.Model):
else:
lines2.append(line)
if lines1:
def group_lines(x, y):
y.update({'amount': x['amount'] + y['amount']})
return y
lines1 = [reduce(group_lines, lines1)]
lines1[0]['depreciated_value'] = 0.0
table[0]['lines'] = lines1 + lines2
@ -523,8 +532,8 @@ class AccountAsset(models.Model):
# recompute in case of deviation
depreciated_value_posted = depreciated_value = 0.0
if posted_lines:
last_depreciation_date = datetime.strptime(
last_line.line_date, '%Y-%m-%d')
last_depreciation_date = fields.Datetime.from_string(
last_line.line_date)
last_date_in_table = table[-1]['lines'][-1]['date']
if last_date_in_table <= last_depreciation_date:
raise UserError(
@ -616,8 +625,8 @@ class AccountAsset(models.Model):
- years: duration in calendar years, considering also leap years
"""
fy = self.env['date.range'].browse(fy_id)
fy_date_start = datetime.strptime(fy.date_start, '%Y-%m-%d')
fy_date_stop = datetime.strptime(fy.date_end, '%Y-%m-%d')
fy_date_start = fields.Datetime.from_string(fy.date_start)
fy_date_stop = fields.Datetime.from_string(fy.date_end)
days = (fy_date_stop - fy_date_start).days + 1
months = (fy_date_stop.year - fy_date_start.year) * 12 \
+ (fy_date_stop.month - fy_date_start.month) + 1
@ -639,7 +648,7 @@ class AccountAsset(models.Model):
factor = float(duration) / cy_days
elif i == cnt - 1: # last year
duration = (
fy_date_stop - datetime(year, 01, 01)).days + 1
fy_date_stop - datetime(year, 1, 1)).days + 1
factor += float(duration) / cy_days
else:
factor += 1.0
@ -655,8 +664,8 @@ class AccountAsset(models.Model):
fy_id = entry['fy_id']
if self.prorata:
if firstyear:
depreciation_date_start = datetime.strptime(
self.date_start, '%Y-%m-%d')
depreciation_date_start = fields.Datetime.from_string(
self.date_start)
fy_date_stop = entry['date_stop']
first_fy_asset_days = \
(fy_date_stop - depreciation_date_start).days + 1
@ -689,10 +698,10 @@ class AccountAsset(models.Model):
if the fiscal year starts in the middle of a month.
"""
if self.prorata:
depreciation_start_date = datetime.strptime(
self.date_start, '%Y-%m-%d')
depreciation_start_date = fields.Datetime.from_string(
self.date_start)
else:
fy_date_start = datetime.strptime(fy.date_start, '%Y-%m-%d')
fy_date_start = fields.Datetime.from_string(fy.date_start)
depreciation_start_date = datetime(
fy_date_start.year, fy_date_start.month, 1)
return depreciation_start_date
@ -717,8 +726,8 @@ class AccountAsset(models.Model):
depreciation_stop_date = depreciation_start_date + \
relativedelta(years=self.method_number, days=-1)
elif self.method_time == 'end':
depreciation_stop_date = datetime.strptime(
self.method_end, '%Y-%m-%d')
depreciation_stop_date = fields.Datetime.from_string(
self.method_end)
return depreciation_stop_date
def _get_first_period_amount(self, table, entry, depreciation_start_date,
@ -729,7 +738,7 @@ class AccountAsset(models.Model):
"""
amount = entry.get('period_amount')
if self.prorata and self.method_time == 'year':
dates = filter(lambda x: x <= entry['date_stop'], line_dates)
dates = [x for x in line_dates if x <= entry['date_stop']]
full_periods = len(dates) - 1
amount = entry['fy_amount'] - amount * full_periods
return amount
@ -812,7 +821,7 @@ class AccountAsset(models.Model):
depreciation_stop_date, line_dates):
digits = self.env['decimal.precision'].precision_get('Account')
asset_sign = self.depreciation_base >= 0 and 1 or -1
asset_sign = 1 if self.depreciation_base >= 0 else -1
i_max = len(table) - 1
remaining_value = self.depreciation_base
depreciated_value = 0.0
@ -902,7 +911,7 @@ class AccountAsset(models.Model):
asset_date_start = datetime.strptime(self.date_start, '%Y-%m-%d')
fy = company.find_daterange_fy(asset_date_start)
fiscalyear_lock_date = company.fiscalyear_lock_date
if fiscalyear_lock_date >= self.date_start:
if fiscalyear_lock_date and fiscalyear_lock_date >= self.date_start:
init_flag = True
if fy:
fy_id = fy.id
@ -957,14 +966,20 @@ class AccountAsset(models.Model):
fy_date_start = fy_date_stop + relativedelta(days=1)
fy = company.find_daterange_fy(fy_date_start)
if fy:
if fiscalyear_lock_date >= fy.date_end:
if (
fiscalyear_lock_date and
fiscalyear_lock_date >= fy.date_end
):
init_flag = True
else:
init_flag = False
fy_date_stop = datetime.strptime(fy.date_end, '%Y-%m-%d')
else:
fy_date_stop = fy_date_stop + relativedelta(years=1)
if fiscalyear_lock_date >= fy_date_stop.strftime('%Y-%m-%d'):
if (
fiscalyear_lock_date and
fiscalyear_lock_date >= fy_date_stop.strftime('%Y-%m-%d')
):
init_flag = True
else:
init_flag = False
@ -1035,7 +1050,7 @@ class AccountAsset(models.Model):
@api.multi
def _compute_entries(self, date_end, check_triggers=False):
# To DO : add ir_cron job calling this method to
# TODO : add ir_cron job calling this method to
# generate periodical accounting entries
result = []
error_log = ''
@ -1057,9 +1072,9 @@ class AccountAsset(models.Model):
order='line_date')
for depreciation in depreciations:
try:
with self._cr.savepoint():
with self.env.cr.savepoint():
result += depreciation.create_move()
except:
except Exception:
e = exc_info()[0]
tb = ''.join(format_exception(*exc_info()))
asset_ref = depreciation.asset_id.code and '%s (ref: %s)' \

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -23,16 +22,15 @@ class AccountAssetLine(models.Model):
string='Previous Depreciation Line',
readonly=True)
parent_state = fields.Selection(
selection=[
('draft', 'Draft'),
('open', 'Running'),
('close', 'Close'),
('removed', 'Removed')],
related='asset_id.state',
string='State of Asset')
string='State of Asset',
readonly=True,
)
depreciation_base = fields.Float(
related='asset_id.depreciation_base',
string='Depreciation Base')
string='Depreciation Base',
readonly=True,
)
amount = fields.Float(
string='Amount', digits=dp.get_precision('Account'),
required=True)
@ -63,17 +61,17 @@ class AccountAssetLine(models.Model):
init_entry = fields.Boolean(
string='Initial Balance Entry',
help="Set this flag for entries of previous fiscal years "
"for which OpenERP has not generated accounting entries.")
"for which Odoo has not generated accounting entries.")
@api.depends('amount', 'previous_id', 'type')
@api.multi
def _compute_values(self):
dlines = self
if self._context.get('no_compute_asset_line_ids'):
if self.env.context.get('no_compute_asset_line_ids'):
# skip compute for lines in unlink
exclude_ids = self._context['no_compute_asset_line_ids']
dlines = dlines.filtered(lambda l: l.id not in exclude_ids)
dlines = self.filtered(lambda l: l.type == 'depreciate')
exclude_ids = self.env.context['no_compute_asset_line_ids']
dlines = self.filtered(lambda l: l.id not in exclude_ids)
dlines = dlines.filtered(lambda l: l.type == 'depreciate')
dlines = dlines.sorted(key=lambda l: l.line_date)
for i, dl in enumerate(dlines):
@ -107,20 +105,21 @@ class AccountAssetLine(models.Model):
for dl in self:
if vals.get('line_date'):
if isinstance(vals['line_date'], datetime.date):
vals['line_date'] = vals['line_date'].strftime('%Y-%m-%d')
vals['line_date'] = fields.Date.to_string(
vals['line_date'])
line_date = vals.get('line_date') or dl.line_date
asset_lines = dl.asset_id.depreciation_line_ids
if vals.keys() == ['move_id'] and not vals['move_id']:
if list(vals.keys()) == ['move_id'] and not vals['move_id']:
# allow to remove an accounting entry via the
# 'Delete Move' button on the depreciation lines.
if not self._context.get('unlink_from_asset'):
if not self.env.context.get('unlink_from_asset'):
raise UserError(_(
"You are not allowed to remove an accounting entry "
"linked to an asset."
"\nYou should remove such entries from the asset."))
elif vals.keys() == ['asset_id']:
elif list(vals.keys()) == ['asset_id']:
continue
elif dl.move_id and not self._context.get(
elif dl.move_id and not self.env.context.get(
'allow_asset_line_update'):
raise UserError(_(
"You cannot change a depreciation line "
@ -152,7 +151,7 @@ class AccountAssetLine(models.Model):
raise UserError(_(
"You cannot set the date on a depreciation line "
"prior to already posted entries."))
return super(AccountAssetLine, self).write(vals)
return super().write(vals)
@api.multi
def unlink(self):
@ -166,13 +165,12 @@ class AccountAssetLine(models.Model):
"You cannot delete a depreciation line with "
"an associated accounting entry."))
previous = dl.previous_id
next = dl.asset_id.depreciation_line_ids.filtered(
next_line = dl.asset_id.depreciation_line_ids.filtered(
lambda l: l.previous_id == dl and l not in self)
if next:
next.previous_id = previous
ctx = dict(self._context, no_compute_asset_line_ids=self.ids)
return super(
AccountAssetLine, self.with_context(ctx)).unlink()
if next_line:
next_line.previous_id = previous
return super(AccountAssetLine, self.with_context(
no_compute_asset_line_ids=self.ids)).unlink()
def _setup_move_data(self, depreciation_date):
asset = self.asset_id
@ -184,14 +182,14 @@ class AccountAssetLine(models.Model):
}
return move_data
def _setup_move_line_data(self, depreciation_date, account, type, move):
def _setup_move_line_data(self, depreciation_date, account, ml_type, move):
asset = self.asset_id
amount = self.amount
analytic_id = False
if type == 'depreciation':
if ml_type == 'depreciation':
debit = amount < 0 and -amount or 0.0
credit = amount > 0 and amount or 0.0
elif type == 'expense':
elif ml_type == 'expense':
debit = amount > 0 and amount or 0.0
credit = amount < 0 and -amount or 0.0
analytic_id = asset.account_analytic_id.id
@ -213,8 +211,9 @@ class AccountAssetLine(models.Model):
@api.multi
def create_move(self):
created_move_ids = []
asset_ids = []
ctx = dict(self._context, allow_asset=True, check_move_validity=False)
asset_ids = set()
ctx = dict(self.env.context,
allow_asset=True, check_move_validity=False)
for line in self:
asset = line.asset_id
depreciation_date = line.line_date
@ -229,14 +228,14 @@ class AccountAssetLine(models.Model):
depreciation_date, exp_acc, 'expense', move)
self.env['account.move.line'].with_context(ctx).create(aml_e_vals)
move.post()
write_ctx = dict(self._context, allow_asset_line_update=True)
line.with_context(write_ctx).write({'move_id': move.id})
line.with_context(allow_asset_line_update=True).write({
'move_id': move.id
})
created_move_ids.append(move.id)
asset_ids.append(asset.id)
asset_ids.add(asset.id)
# we re-evaluate the assets to determine if we can close them
for asset in self.env['account.asset'].browse(
list(set(asset_ids))):
if asset.company_id.currency_id.is_zero(asset.value_residual):
for asset in self.env['account.asset'].browse(list(asset_ids)):
if asset.company_currency_id.is_zero(asset.value_residual):
asset.state = 'close'
return created_move_ids
@ -250,8 +249,7 @@ class AccountAssetLine(models.Model):
'res_model': 'account.move',
'view_id': False,
'type': 'ir.actions.act_window',
'context': self._context,
'nodestroy': True,
'context': self.env.context,
'domain': [('id', '=', self.move_id.id)],
}

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -11,7 +10,7 @@ class AccountAssetProfile(models.Model):
_description = 'Asset profile'
_order = 'name'
name = fields.Char(string='Name', size=64, required=True, index=1)
name = fields.Char(string='Name', size=64, required=True, index=True)
note = fields.Text()
account_analytic_id = fields.Many2one(
comodel_name='account.analytic.account',
@ -158,7 +157,7 @@ class AccountAssetProfile(models.Model):
def create(self, vals):
if vals.get('method_time') != 'year' and not vals.get('prorata'):
vals['prorata'] = True
profile = super(AccountAssetProfile, self).create(vals)
profile = super().create(vals)
acc_id = vals.get('account_asset_id')
if acc_id:
account = self.env['account.account'].browse(acc_id)
@ -171,11 +170,11 @@ class AccountAssetProfile(models.Model):
if vals.get('method_time'):
if vals['method_time'] != 'year' and not vals.get('prorata'):
vals['prorata'] = True
super(AccountAssetProfile, self).write(vals)
for profile in self:
acc_id = vals.get('account_asset_id')
if acc_id:
account = self.env['account.account'].browse(acc_id)
if not account.asset_profile_id:
account.write({'asset_profile_id': profile.id})
return True
res = super().write(vals)
# TODO last profile in self is defined as default on the related
# account. must be improved.
account = self.env['account.account'].browse(
vals.get('account_asset_id'))
if self and account and not account.asset_profile_id:
account.write({'asset_profile_id': self[-1].id})
return res

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -12,8 +11,7 @@ class AccountInvoice(models.Model):
@api.multi
def finalize_invoice_move_lines(self, move_lines):
move_lines = super(AccountInvoice, self) \
.finalize_invoice_move_lines(move_lines)
move_lines = super().finalize_invoice_move_lines(move_lines)
new_lines = []
for line_tuple in move_lines:
line = line_tuple[2]
@ -74,11 +72,9 @@ class AccountInvoice(models.Model):
@api.multi
def action_move_create(self):
res = super(AccountInvoice, self).action_move_create()
res = super().action_move_create()
for inv in self:
move = inv.move_id
assets = [aml.asset_id for aml in
filter(lambda x: x.asset_id, move.line_ids)]
assets = inv.move_id.line_ids.mapped('asset_id')
for asset in assets:
asset.code = inv.move_name
asset_line_name = asset._get_depreciation_entry_name(0)
@ -92,15 +88,15 @@ class AccountInvoice(models.Model):
assets = self.env['account.asset']
for inv in self:
move = inv.move_id
assets = move.line_ids.mapped('asset_id')
super(AccountInvoice, self).action_cancel()
assets |= move.line_ids.mapped('asset_id')
super().action_cancel()
if assets:
assets.unlink()
return True
@api.model
def line_get_convert(self, line, part):
res = super(AccountInvoice, self).line_get_convert(line, part)
res = super().line_get_convert(line, part)
if line.get('asset_profile_id'):
# skip empty debit/credit
if res.get('debit') or res.get('credit'):
@ -109,19 +105,20 @@ class AccountInvoice(models.Model):
@api.model
def inv_line_characteristic_hashcode(self, invoice_line):
res = super(AccountInvoice, self).inv_line_characteristic_hashcode(
res = super().inv_line_characteristic_hashcode(
invoice_line)
res += '-%s' % invoice_line.get('asset_profile_id', 'False')
return res
@api.model
def invoice_line_move_line_get(self):
res = super(AccountInvoice, self).invoice_line_move_line_get()
res = super().invoice_line_move_line_get()
invoice_line_obj = self.env['account.invoice.line']
for vals in res:
invline = invoice_line_obj.browse(vals['invl_id'])
if invline.asset_profile_id:
vals['asset_profile_id'] = invline.asset_profile_id.id
if vals.get('invl_id'):
invline = invoice_line_obj.browse(vals['invl_id'])
if invline.asset_profile_id:
vals['asset_profile_id'] = invline.asset_profile_id.id
return res
@ -144,4 +141,4 @@ class AccountInvoiceLine(models.Model):
@api.onchange('account_id')
def _onchange_account_id(self):
self.asset_profile_id = self.account_id.asset_profile_id.id
return super(AccountInvoiceLine, self)._onchange_account_id()
return super()._onchange_account_id()

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -23,31 +22,30 @@ class AccountMove(models.Model):
_inherit = 'account.move'
@api.multi
def unlink(self, **kwargs):
for move in self:
deprs = self.env['account.asset.line'].search(
[('move_id', '=', move.id),
('type', 'in', ['depreciate', 'remove'])])
if deprs and not self._context.get('unlink_from_asset'):
raise UserError(
_("You are not allowed to remove an accounting entry "
"linked to an asset."
"\nYou should remove such entries from the asset."))
# trigger store function
deprs.write({'move_id': False})
return super(AccountMove, self).unlink(**kwargs)
def unlink(self):
# for move in self:
deprs = self.env['account.asset.line'].search(
[('move_id', 'in', self.ids),
('type', 'in', ['depreciate', 'remove'])])
if deprs and not self.env.context.get('unlink_from_asset'):
raise UserError(
_("You are not allowed to remove an accounting entry "
"linked to an asset."
"\nYou should remove such entries from the asset."))
# trigger store function
deprs.write({'move_id': False})
return super().unlink()
@api.multi
def write(self, vals):
if set(vals).intersection(FIELDS_AFFECTS_ASSET_MOVE):
for move in self:
deprs = self.env['account.asset.line'].search(
[('move_id', '=', move.id), ('type', '=', 'depreciate')])
if deprs:
raise UserError(
_("You cannot change an accounting entry "
"linked to an asset depreciation line."))
return super(AccountMove, self).write(vals)
deprs = self.env['account.asset.line'].search(
[('move_id', 'in', self.ids), ('type', '=', 'depreciate')])
if deprs:
raise UserError(
_("You cannot change an accounting entry "
"linked to an asset depreciation line."))
return super().write(vals)
class AccountMoveLine(models.Model):
@ -65,8 +63,8 @@ class AccountMoveLine(models.Model):
self.asset_profile_id = self.account_id.asset_profile_id
@api.model
def create(self, vals, **kwargs):
if vals.get('asset_id') and not self._context.get('allow_asset'):
def create(self, vals):
if vals.get('asset_id') and not self.env.context.get('allow_asset'):
raise UserError(
_("You are not allowed to link "
"an accounting entry to an asset."
@ -83,70 +81,78 @@ class AccountMoveLine(models.Model):
'partner_id': vals['partner_id'],
'date_start': move.date,
}
if self._context.get('company_id'):
temp_vals['company_id'] = self._context['company_id']
if self.env.context.get('company_id'):
temp_vals['company_id'] = self.env.context['company_id']
temp_asset = asset_obj.new(temp_vals)
temp_asset._onchange_profile_id()
asset_vals = temp_asset._convert_to_write(temp_asset._cache)
self._get_asset_analytic_values(vals, asset_vals)
ctx = dict(self._context, create_asset_from_move_line=True,
move_id=vals['move_id'])
asset = asset_obj.with_context(
ctx).create(asset_vals)
create_asset_from_move_line=True,
move_id=vals['move_id']).create(asset_vals)
vals['asset_id'] = asset.id
return super(AccountMoveLine, self).create(vals, **kwargs)
return super().create(vals)
@api.multi
def write(self, vals, **kwargs):
for aml in self:
if aml.asset_id:
if set(vals).intersection(FIELDS_AFFECTS_ASSET_MOVE_LINE):
if not (self.env.context.get('allow_asset_removal') and
vals.keys() == ['asset_id']):
raise UserError(
_("You cannot change an accounting item "
"linked to an asset depreciation line."))
def _prepare_asset_create(self, vals):
self.ensure_one()
debit = 'debit' in vals and vals.get('debit', 0.0) or self.debit
credit = 'credit' in vals and \
vals.get('credit', 0.0) or self.credit
depreciation_base = debit - credit
partner_id = 'partner' in vals and \
vals.get('partner', False) or self.partner_id.id
date_start = 'date' in vals and \
vals.get('date', False) or self.date
return {
'name': vals.get('name') or self.name,
'profile_id': vals['asset_profile_id'],
'purchase_value': depreciation_base,
'partner_id': partner_id,
'date_start': date_start,
'company_id': vals.get('company_id') or self.company_id.id,
}
@api.multi
def write(self, vals):
if (
self.mapped('asset_id') and
set(vals).intersection(FIELDS_AFFECTS_ASSET_MOVE_LINE) and
not (
self.env.context.get('allow_asset_removal') and
list(vals.keys()) == ['asset_id'])
):
raise UserError(
_("You cannot change an accounting item "
"linked to an asset depreciation line."))
if vals.get('asset_id'):
raise UserError(
_("You are not allowed to link "
"an accounting entry to an asset."
"\nYou should generate such entries from the asset."))
if vals.get('asset_profile_id'):
assert len(self.ids) == 1, \
'This option should only be used for a single id at a time.'
if len(self) == 1:
raise AssertionError(_(
'This option should only be used for a single id at a '
'time.'))
asset_obj = self.env['account.asset']
for aml in self:
if vals['asset_profile_id'] == aml.asset_profile_id.id:
continue
# create asset
debit = 'debit' in vals and vals.get('debit', 0.0) or aml.debit
credit = 'credit' in vals and \
vals.get('credit', 0.0) or aml.credit
depreciation_base = debit - credit
partner_id = 'partner' in vals and \
vals.get('partner', False) or aml.partner_id.id
date_start = 'date' in vals and \
vals.get('date', False) or aml.date
asset_vals = {
'name': vals.get('name') or aml.name,
'profile_id': vals['asset_profile_id'],
'purchase_value': depreciation_base,
'partner_id': partner_id,
'date_start': date_start,
'company_id': vals.get('company_id') or aml.company_id.id,
}
asset_vals = aml._prepare_asset_create(vals)
self._play_onchange_profile_id(asset_vals)
self._get_asset_analytic_values(vals, asset_vals)
ctx = dict(self._context, create_asset_from_move_line=True,
move_id=aml.move_id.id)
asset = asset_obj.with_context(ctx).create(asset_vals)
asset = asset_obj.with_context(
create_asset_from_move_line=True,
move_id=aml.move_id.id).create(asset_vals)
vals['asset_id'] = asset.id
return super(AccountMoveLine, self).write(vals, **kwargs)
return super().write(vals)
@api.model
def _get_asset_analytic_values(self, vals, asset_vals):
asset_vals['account_analytic_id'] = \
vals.get('analytic_account_id', False)
asset_vals['account_analytic_id'] = vals.get(
'analytic_account_id', False)
@api.model
def _play_onchange_profile_id(self, vals):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2009-2017 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -29,7 +28,7 @@ class DateRange(models.Model):
}
self.env['account.asset.recompute.trigger'].sudo().create(
recompute_vals)
return super(DateRange, self).create(vals)
return super().create(vals)
@api.multi
def write(self, vals):
@ -48,4 +47,4 @@ class DateRange(models.Model):
}
self.env['account.asset.recompute.trigger'].sudo().\
create(recompute_vals)
return super(DateRange, self).write(vals)
return super().write(vals)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2014 ACSONE SA/NV (http://acsone.eu).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -6,7 +5,7 @@ from odoo import fields, models
class Config(models.TransientModel):
_inherit = 'account.config.settings'
_inherit = 'res.config.settings'
module_account_asset_management = fields.Boolean(
string='Assets management (OCA)',

View File

@ -0,0 +1,2 @@
It is recommended to configure your Purchase Journal with "Group Invoice Lines" to avoid the
creation of separate assets per Supplier Invoice Line.

View File

@ -0,0 +1,7 @@
- OpenERP SA
- Luc De Meyer (Noviat)
- Frédéric Clementi (camptocamp)
- Florian Dacosta (Akretion)
- Stéphane Bidoul (Acsone)
- Adrien Peiffer (Acsone)
- Akim Juillerat <akim.juillerat@camptocamp.com>

View File

@ -0,0 +1,13 @@
This Module manages the assets owned by a company. It will keep
track of depreciation's occurred on those assets. And it allows to create
accounting entries from the depreciation lines.
The full asset life-cycle is managed (from asset creation to asset removal).
Assets can be created manually as well as automatically
(via the creation of an accounting entry on the asset account).
Excel based reporting is available via the 'account_asset_management_xls' module.
The module contains a large number of functional enhancements compared to
the standard account_asset module from Odoo.

View File

@ -0,0 +1 @@
The module in NOT compatible with the standard account_asset module.

View File

@ -0,0 +1,444 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>Assets Management</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="assets-management">
<h1 class="title">Assets Management</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/11.0/account_asset_management"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/account-financial-tools-11-0/account-financial-tools-11-0-account_asset_management"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/92/11.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This Module manages the assets owned by a company. It will keep
track of depreciations occurred on those assets. And it allows to create
accounting entries from the depreciation lines.</p>
<p>The full asset life-cycle is managed (from asset creation to asset removal).</p>
<p>Assets can be created manually as well as automatically
(via the creation of an accounting entry on the asset account).</p>
<p>Excel based reporting is available via the account_asset_management_xls module.</p>
<p>The module contains a large number of functional enhancements compared to
the standard account_asset module from Odoo.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="id1">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="id2">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id7">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#id1">Configuration</a></h1>
<p>It is recommended to configure your Purchase Journal with “Group Invoice Lines” to avoid the
creation of separate assets per Supplier Invoice Line.</p>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id2">Usage</a></h1>
<p>The module in NOT compatible with the standard account_asset module.</p>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_asset_management%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id4">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id5">Authors</a></h2>
<ul class="simple">
<li>Noviat</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id6">Contributors</a></h2>
<ul class="simple">
<li>OpenERP SA</li>
<li>Luc De Meyer (Noviat)</li>
<li>Frédéric Clementi (camptocamp)</li>
<li>Florian Dacosta (Akretion)</li>
<li>Stéphane Bidoul (Acsone)</li>
<li>Adrien Peiffer (Acsone)</li>
<li>Akim Juillerat &lt;<a class="reference external" href="mailto:akim.juillerat&#64;camptocamp.com">akim.juillerat&#64;camptocamp.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id7">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/11.0/account_asset_management">OCA/account-financial-tools</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,2 +1 @@
# -*- coding: utf-8 -*-
from . import test_account_asset_management

View File

@ -1,4 +1,4 @@
<?xml version="1.0" ?>
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2014 ACSONE SA/NV (acsone.eu).
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@ -7,87 +6,89 @@ import calendar
from datetime import date, datetime
import time
import odoo.tests.common as common
from odoo.tests.common import SavepointCase
from odoo import tools
from odoo.modules.module import get_resource_path
class TestAssetManagement(common.TransactionCase):
class TestAssetManagement(SavepointCase):
def _load(self, module, *args):
tools.convert_file(self.cr, module,
@classmethod
def _load(cls, module, *args):
tools.convert_file(cls.cr, module,
get_resource_path(module, *args),
{}, 'init', False, 'test',
self.registry._assertion_report)
cls.registry._assertion_report)
def setUp(self):
super(TestAssetManagement, self).setUp()
@classmethod
def setUpClass(cls):
super().setUpClass()
self._load('account', 'test', 'account_minimal_test.xml')
self._load('account_asset_management', 'tests',
'account_asset_test_data.xml')
cls._load('account', 'test', 'account_minimal_test.xml')
cls._load('account_asset_management', 'tests',
'account_asset_test_data.xml')
# ENVIRONEMENTS
self.asset_model = self.env['account.asset']
self.dl_model = self.env['account.asset.line']
self.remove_model = self.env['account.asset.remove']
self.account_invoice = self.env['account.invoice']
self.account_move_line = self.env['account.move.line']
self.account_account = self.env['account.account']
self.account_journal = self.env['account.journal']
self.account_invoice_line = self.env['account.invoice.line']
cls.asset_model = cls.env['account.asset']
cls.dl_model = cls.env['account.asset.line']
cls.remove_model = cls.env['account.asset.remove']
cls.account_invoice = cls.env['account.invoice']
cls.account_move_line = cls.env['account.move.line']
cls.account_account = cls.env['account.account']
cls.account_journal = cls.env['account.journal']
cls.account_invoice_line = cls.env['account.invoice.line']
# INSTANCES
# Instance: company
self.company = self.env.ref('base.main_company')
cls.company = cls.env.ref('base.main_company')
# Instance: account type (receivable)
self.type_recv = self.env.ref('account.data_account_type_receivable')
cls.type_recv = cls.env.ref('account.data_account_type_receivable')
# Instance: account type (payable)
self.type_payable = self.env.ref('account.data_account_type_payable')
cls.type_payable = cls.env.ref('account.data_account_type_payable')
# Instance: account (receivable)
self.account_recv = self.account_account.create({
cls.account_recv = cls.account_account.create({
'name': 'test_account_receivable',
'code': '123',
'user_type_id': self.type_recv.id,
'company_id': self.company.id,
'user_type_id': cls.type_recv.id,
'company_id': cls.company.id,
'reconcile': True})
# Instance: account (payable)
self.account_payable = self.account_account.create({
cls.account_payable = cls.account_account.create({
'name': 'test_account_payable',
'code': '321',
'user_type_id': self.type_payable.id,
'company_id': self.company.id,
'user_type_id': cls.type_payable.id,
'company_id': cls.company.id,
'reconcile': True})
# Instance: partner
self.partner = self.env.ref('base.res_partner_2')
cls.partner = cls.env.ref('base.res_partner_2')
# Instance: journal
self.journal = self.account_journal.search(
cls.journal = cls.account_journal.search(
[('type', '=', 'purchase')])[0]
# Instance: product
self.product = self.env.ref('product.product_product_4')
cls.product = cls.env.ref('product.product_product_4')
# Instance: invoice line
self.invoice_line = self.account_invoice_line.create({
cls.invoice_line = cls.account_invoice_line.create({
'name': 'test',
'account_id': self.account_payable.id,
'account_id': cls.account_payable.id,
'price_unit': 2000.00,
'quantity': 1,
'product_id': self.product.id})
'product_id': cls.product.id})
# Instance: invoice
self.invoice = self.account_invoice.create({
'partner_id': self.partner.id,
'account_id': self.account_recv.id,
'journal_id': self.journal.id,
'invoice_line_ids': [(4, self.invoice_line.id)]})
cls.invoice = cls.account_invoice.create({
'partner_id': cls.partner.id,
'account_id': cls.account_recv.id,
'journal_id': cls.journal.id,
'invoice_line_ids': [(4, cls.invoice_line.id)]})
def test_01_nonprorata_basic(self):
"""Basic tests of depreciation board computations and postings."""
@ -96,30 +97,30 @@ class TestAssetManagement(common.TransactionCase):
#
ict0 = self.browse_ref('account_asset_management.'
'account_asset_asset_ict0')
self.assertEquals(ict0.state, 'draft')
self.assertEquals(ict0.purchase_value, 1500)
self.assertEquals(ict0.salvage_value, 0)
self.assertEquals(ict0.depreciation_base, 1500)
self.assertEquals(len(ict0.depreciation_line_ids), 1)
self.assertEqual(ict0.state, 'draft')
self.assertEqual(ict0.purchase_value, 1500)
self.assertEqual(ict0.salvage_value, 0)
self.assertEqual(ict0.depreciation_base, 1500)
self.assertEqual(len(ict0.depreciation_line_ids), 1)
vehicle0 = self.browse_ref('account_asset_management.'
'account_asset_asset_vehicle0')
self.assertEquals(vehicle0.state, 'draft')
self.assertEquals(vehicle0.purchase_value, 12000)
self.assertEquals(vehicle0.salvage_value, 2000)
self.assertEquals(vehicle0.depreciation_base, 10000)
self.assertEquals(len(vehicle0.depreciation_line_ids), 1)
self.assertEqual(vehicle0.state, 'draft')
self.assertEqual(vehicle0.purchase_value, 12000)
self.assertEqual(vehicle0.salvage_value, 2000)
self.assertEqual(vehicle0.depreciation_base, 10000)
self.assertEqual(len(vehicle0.depreciation_line_ids), 1)
#
# I compute the depreciation boards
#
ict0.compute_depreciation_board()
ict0.refresh()
self.assertEquals(len(ict0.depreciation_line_ids), 4)
self.assertEquals(ict0.depreciation_line_ids[1].amount, 500)
self.assertEqual(len(ict0.depreciation_line_ids), 4)
self.assertEqual(ict0.depreciation_line_ids[1].amount, 500)
vehicle0.compute_depreciation_board()
vehicle0.refresh()
self.assertEquals(len(vehicle0.depreciation_line_ids), 6)
self.assertEquals(vehicle0.depreciation_line_ids[1].amount, 2000)
self.assertEqual(len(vehicle0.depreciation_line_ids), 6)
self.assertEqual(vehicle0.depreciation_line_ids[1].amount, 2000)
#
# I post the first depreciation line
@ -127,15 +128,15 @@ class TestAssetManagement(common.TransactionCase):
ict0.validate()
ict0.depreciation_line_ids[1].create_move()
ict0.refresh()
self.assertEquals(ict0.state, 'open')
self.assertEquals(ict0.value_depreciated, 500)
self.assertEquals(ict0.value_residual, 1000)
self.assertEqual(ict0.state, 'open')
self.assertEqual(ict0.value_depreciated, 500)
self.assertEqual(ict0.value_residual, 1000)
vehicle0.validate()
vehicle0.depreciation_line_ids[1].create_move()
vehicle0.refresh()
self.assertEquals(vehicle0.state, 'open')
self.assertEquals(vehicle0.value_depreciated, 2000)
self.assertEquals(vehicle0.value_residual, 8000)
self.assertEqual(vehicle0.state, 'open')
self.assertEqual(vehicle0.value_depreciated, 2000)
self.assertEqual(vehicle0.value_residual, 8000)
def test_02_prorata_basic(self):
"""Prorata temporis depreciation basic test."""
@ -199,7 +200,7 @@ class TestAssetManagement(common.TransactionCase):
'type': 'depreciate',
'init_entry': True,
})
self.assertEquals(len(asset.depreciation_line_ids), 2)
self.assertEqual(len(asset.depreciation_line_ids), 2)
asset.compute_depreciation_board()
asset.refresh()
# I check the depreciated value is the initial value
@ -245,7 +246,7 @@ class TestAssetManagement(common.TransactionCase):
'type': 'depreciate',
'init_entry': True,
})
self.assertEquals(len(asset.depreciation_line_ids), 2)
self.assertEqual(len(asset.depreciation_line_ids), 2)
asset.compute_depreciation_board()
asset.refresh()
# I check the depreciated value is the initial value
@ -289,7 +290,7 @@ class TestAssetManagement(common.TransactionCase):
asset.refresh()
# check values in the depreciation board
self.assertEquals(len(asset.depreciation_line_ids), 5)
self.assertEqual(len(asset.depreciation_line_ids), 5)
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
400.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
@ -318,7 +319,7 @@ class TestAssetManagement(common.TransactionCase):
asset.refresh()
# check values in the depreciation board
self.assertEquals(len(asset.depreciation_line_ids), 15)
self.assertEqual(len(asset.depreciation_line_ids), 15)
# lines prior to asset start period are grouped in the first entry
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
300.00, places=2)
@ -349,7 +350,7 @@ class TestAssetManagement(common.TransactionCase):
asset.refresh()
# check values in the depreciation board
self.assertEquals(len(asset.depreciation_line_ids), 6)
self.assertEqual(len(asset.depreciation_line_ids), 6)
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
400.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
@ -380,7 +381,7 @@ class TestAssetManagement(common.TransactionCase):
asset.refresh()
# check values in the depreciation board
self.assertEquals(len(asset.depreciation_line_ids), 6)
self.assertEqual(len(asset.depreciation_line_ids), 6)
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
200.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[-1].amount,
@ -415,7 +416,7 @@ class TestAssetManagement(common.TransactionCase):
})
wiz.remove()
asset.refresh()
self.assertEquals(len(asset.depreciation_line_ids), 3)
self.assertEqual(len(asset.depreciation_line_ids), 3)
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
81.46, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,

View File

@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_form" model="ir.ui.view">

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="account_asset_view_form">
@ -17,8 +18,8 @@
attrs="{'invisible': [('type', '=', 'view')]}"/>
</header>
<sheet>
<div class="oe_button_box oe_right">
<button name="open_entries" string="Journal Entries" type="object" class="oe_inline"
<div class="oe_button_box">
<button name="open_entries" string="Journal Entries" type="object" class="oe_stat_button" icon="fa-bars"
attrs="{'invisible': [('type', '=', 'view')]}"/>
</div>
<div class="oe_title">
@ -77,20 +78,20 @@
<group>
<separator string="Depreciation Method" colspan="2"/>
<field name="method"/>
<field name="method_progress_factor" digits="(14, 4)"
<field name="method_progress_factor"
attrs="{'invisible': [('method', 'in', ['linear', 'linear-limit'])], 'required': [('method', 'in', ['degressive', 'degr-linear', 'degr-limit'])]}"/>
<field name="prorata" attrs="{'readonly': [('method_time', '!=', 'year')]}"/>
</group>
</group>
</page>
<page string="Depreciation Board">
<header>
<div>
<button type="object" name="compute_depreciation_board"
string="Compute" icon="fa-gears" colspan="2"
string=" Compute" icon="fa-gears"
attrs="{'invisible': [('state', 'in', ['close', 'removed'])]}"/>
</header>
</div>
<field name="depreciation_line_ids" mode="tree" options="{'reload_on_button': true}">
<tree string="Asset Lines" colors="blue:(move_check == False) and (init_entry == False)" create="false">
<tree string="Asset Lines" decoration-info="(move_check == False) and (init_entry == False)" create="false">
<field name="type"/>
<field name="line_date"/>
<field name="depreciated_value" readonly="1"/>
@ -172,7 +173,7 @@
<field name="name">account.asset.tree</field>
<field name="model">account.asset</field>
<field name="arch" type="xml">
<tree string="Assets" colors="blue:(type == 'view')">
<tree string="Assets" decoration-info="type == 'view'">
<field name="name"/>
<field name="type" invisible="1"/>
<field name="code"/>
@ -194,9 +195,9 @@
<field name="arch" type="xml">
<search string="Account Asset">
<filter string="Draft" name="draft" domain="[('state', '=', 'draft')]" help="Draft Assets"/>
<filter string="Running" domain="[('state', '=', 'open')]" help="Assets in Running State"/>
<filter string="Close" domain="[('state', '=', 'close')]" help="Assets in Close State"/>
<filter string="Removed" domain="[('state', '=', 'removed')]" help="Assets which have been removed"/>
<filter string="Running" name="running" domain="[('state', '=', 'open')]" help="Assets in Running State"/>
<filter string="Close" name="close" domain="[('state', '=', 'close')]" help="Assets in Close State"/>
<filter string="Removed" name="removed" domain="[('state', '=', 'removed')]" help="Assets which have been removed"/>
<separator orientation="vertical"/>
<field name="name" string="Asset"/>
<field name="code"/>
@ -219,37 +220,6 @@
<field name="search_view_id" ref="account_asset_view_search"/>
</record>
<record model="ir.ui.view" id="account_asset_view_tree_hierarchy">
<field name="name">account.asset.hierarchy</field>
<field name="model">account.asset</field>
<field name="field_parent">child_ids</field>
<field name="arch" type="xml">
<tree string="Assets" colors="blue:(type == 'view')">
<field name="name"/>
<field name="type" invisible="1"/>
<field name="code"/>
<!--
<field name="depreciation_base" attrs="{'invisible': [('type', '=', 'view')]}"/>
<field name="value_depreciated" attrs="{'invisible': [('type', '=', 'view')]}"/>
<field name="value_residual" attrs="{'invisible': [('type', '=', 'view')]}"/>
<field name="date_start"/>
<field name="date_remove"/>
<field name="profile_id"/>
<field name="state" attrs="{'invisible': [('type', '=', 'view')]}"/>
<field name="company_id" groups="base.group_multi_company"/>
-->
</tree>
</field>
</record>
<record id="account_asset_action_hierarchy" model="ir.actions.act_window">
<field name="name">Asset Hierarchy</field>
<field name="res_model">account.asset</field>
<field name="view_type">tree</field>
<field name="domain">[('parent_id','=',False)]</field>
<field name="view_id" ref="account_asset_view_tree_hierarchy"/>
</record>
<act_window id="act_entries_open"
name="Journal Items"
src_model="account.asset"

Some files were not shown because too many files have changed in this diff Show More