[MIG] account_asset_management: Migration to 11.0
This commit is contained in:
parent
49d1c36679
commit
a7cdfdd14d
@ -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.
|
||||
|
@ -1,3 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import models
|
||||
from . import wizard
|
||||
|
@ -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,
|
||||
}
|
||||
|
1175
account_asset_management/i18n/account_asset_management.pot
Normal file
1175
account_asset_management/i18n/account_asset_management.pot
Normal file
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
@ -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)
|
@ -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
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2009-2017 Noviat
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
|
@ -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)' \
|
||||
|
@ -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)],
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2009-2018 Noviat
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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)',
|
2
account_asset_management/readme/CONFIGURE.rst
Normal file
2
account_asset_management/readme/CONFIGURE.rst
Normal 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.
|
7
account_asset_management/readme/CONTRIBUTORS.rst
Normal file
7
account_asset_management/readme/CONTRIBUTORS.rst
Normal 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>
|
13
account_asset_management/readme/DESCRIPTION.rst
Normal file
13
account_asset_management/readme/DESCRIPTION.rst
Normal 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.
|
1
account_asset_management/readme/USAGE.rst
Normal file
1
account_asset_management/readme/USAGE.rst
Normal file
@ -0,0 +1 @@
|
||||
The module in NOT compatible with the standard account_asset module.
|
444
account_asset_management/static/description/index.html
Normal file
444
account_asset_management/static/description/index.html
Normal 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 depreciation’s 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 <<a class="reference external" href="mailto:akim.juillerat@camptocamp.com">akim.juillerat@camptocamp.com</a>></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>
|
@ -1,2 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import test_account_asset_management
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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">
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user