[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
|
Assets Management
|
||||||
:alt: License: AGPL-3
|
=================
|
||||||
|
|
||||||
==========================
|
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
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
|
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
|
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 module contains a large number of functional enhancements compared to
|
||||||
the standard account_asset module from Odoo.
|
the standard account_asset module from Odoo.
|
||||||
|
|
||||||
|
**Table of contents**
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
=============
|
=============
|
||||||
|
|
||||||
@ -29,46 +53,50 @@ creation of separate assets per Supplier Invoice Line.
|
|||||||
Usage
|
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.
|
The module in NOT compatible with the standard account_asset module.
|
||||||
|
|
||||||
Bug Tracker
|
Bug Tracker
|
||||||
===========
|
===========
|
||||||
|
|
||||||
Bugs are tracked on `GitHub Issues
|
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-tools/issues>`_.
|
||||||
<https://github.com/OCA/account-financial-tools/issues>`_. In case of trouble, please
|
In case of trouble, please check there if your issue has already been reported.
|
||||||
check there if your issue has already been reported. If you spotted it first,
|
If you spotted it first, help us smashing it by providing a detailed and welcomed
|
||||||
help us smash it by providing detailed and welcomed feedback.
|
`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
|
Credits
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
Authors
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
* Noviat
|
||||||
|
|
||||||
Contributors
|
Contributors
|
||||||
------------
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
- OpenERP SA
|
- OpenERP SA
|
||||||
- Luc De Meyer (Noviat)
|
- Luc De Meyer (Noviat)
|
||||||
- Frédéric Clementi (camptocamp)
|
- Frédéric Clementi (camptocamp)
|
||||||
- Florian Dacosta (Akretion)
|
- Florian Dacosta (Akretion)
|
||||||
- Stéphane Bidoul (Acsone)
|
- Stéphane Bidoul (Acsone)
|
||||||
- Adrien Peiffer (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
|
.. image:: https://odoo-community.org/logo.png
|
||||||
:alt: Odoo Community Association
|
:alt: Odoo Community Association
|
||||||
:target: https://odoo-community.org
|
:target: https://odoo-community.org
|
||||||
|
|
||||||
This module is maintained by the OCA.
|
|
||||||
|
|
||||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||||
mission is to support the collaborative development of Odoo features and
|
mission is to support the collaborative development of Odoo features and
|
||||||
promote its widespread use.
|
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 models
|
||||||
from . import wizard
|
from . import wizard
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2009-2018 Noviat
|
# Copyright 2009-2018 Noviat
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
{
|
{
|
||||||
'name': 'Assets Management',
|
'name': 'Assets Management',
|
||||||
'version': '10.0.3.1.0',
|
'version': '11.0.1.0.0',
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
'depends': [
|
'depends': [
|
||||||
'account_fiscal_year',
|
'account_fiscal_year',
|
||||||
],
|
],
|
||||||
'conflicts': ['account_asset'],
|
'conflicts': ['account_asset'],
|
||||||
'author': "Noviat,Odoo Community Association (OCA)",
|
'author': "Noviat,Odoo Community Association (OCA)",
|
||||||
'website': 'http://www.noviat.com',
|
'website': 'https://github.com/OCA/account-financial-tools',
|
||||||
'category': 'Accounting & Finance',
|
'category': 'Accounting & Finance',
|
||||||
'sequence': 32,
|
|
||||||
'data': [
|
'data': [
|
||||||
'security/account_asset_security.xml',
|
'security/account_asset_security.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
@ -22,14 +20,11 @@
|
|||||||
'views/account_account.xml',
|
'views/account_account.xml',
|
||||||
'views/account_asset.xml',
|
'views/account_asset.xml',
|
||||||
'views/account_asset_profile.xml',
|
'views/account_asset_profile.xml',
|
||||||
'views/account_config_settings.xml',
|
'views/res_config_settings.xml',
|
||||||
'views/account_invoice.xml',
|
'views/account_invoice.xml',
|
||||||
'views/account_invoice_line.xml',
|
'views/account_invoice_line.xml',
|
||||||
'views/account_move.xml',
|
'views/account_move.xml',
|
||||||
'views/account_move_line.xml',
|
'views/account_move_line.xml',
|
||||||
'views/menuitem.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_account
|
||||||
from . import account_asset
|
from . import account_asset
|
||||||
from . import account_asset_profile
|
from . import account_asset_profile
|
||||||
@ -7,4 +6,4 @@ from . import account_asset_recompute_trigger
|
|||||||
from . import account_invoice
|
from . import account_invoice
|
||||||
from . import account_move
|
from . import account_move
|
||||||
from . import date_range
|
from . import date_range
|
||||||
from . import res_config
|
from . import res_config_settings
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2009-2017 Noviat
|
# Copyright 2009-2017 Noviat
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2009-2018 Noviat
|
# Copyright 2009-2018 Noviat
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# 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
|
import odoo.addons.decimal_precision as dp
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError
|
||||||
from odoo.osv import expression
|
from odoo.osv import expression
|
||||||
|
from functools import reduce
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -83,7 +83,9 @@ class AccountAsset(models.Model):
|
|||||||
string='Parent Asset', readonly=True,
|
string='Parent Asset', readonly=True,
|
||||||
states={'draft': [('readonly', False)]},
|
states={'draft': [('readonly', False)]},
|
||||||
domain=[('type', '=', 'view')],
|
domain=[('type', '=', 'view')],
|
||||||
ondelete='restrict')
|
ondelete='restrict',
|
||||||
|
index=True,
|
||||||
|
)
|
||||||
parent_left = fields.Integer(index=True)
|
parent_left = fields.Integer(index=True)
|
||||||
parent_right = fields.Integer(index=True)
|
parent_right = fields.Integer(index=True)
|
||||||
child_ids = fields.One2many(
|
child_ids = fields.One2many(
|
||||||
@ -104,7 +106,7 @@ class AccountAsset(models.Model):
|
|||||||
('open', 'Running'),
|
('open', 'Running'),
|
||||||
('close', 'Close'),
|
('close', 'Close'),
|
||||||
('removed', 'Removed'),
|
('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"
|
help="When an asset is created, the status is 'Draft'.\n"
|
||||||
"If the asset is confirmed, the status goes in 'Running' "
|
"If the asset is confirmed, the status goes in 'Running' "
|
||||||
"and the depreciation lines can be posted "
|
"and the depreciation lines can be posted "
|
||||||
@ -206,7 +208,7 @@ class AccountAsset(models.Model):
|
|||||||
for line in asset.depreciation_line_ids:
|
for line in asset.depreciation_line_ids:
|
||||||
if line.move_id:
|
if line.move_id:
|
||||||
asset.move_line_check = True
|
asset.move_line_check = True
|
||||||
continue
|
break
|
||||||
|
|
||||||
@api.depends('purchase_value', 'salvage_value', 'type', 'method')
|
@api.depends('purchase_value', 'salvage_value', 'type', 'method')
|
||||||
@api.multi
|
@api.multi
|
||||||
@ -234,17 +236,20 @@ class AccountAsset(models.Model):
|
|||||||
lambda l: l.type in ('depreciate', 'remove') and
|
lambda l: l.type in ('depreciate', 'remove') and
|
||||||
(l.init_entry or l.move_check))
|
(l.init_entry or l.move_check))
|
||||||
value_depreciated = sum([l.amount for l in lines])
|
value_depreciated = sum([l.amount for l in lines])
|
||||||
asset.value_residual = \
|
residual = asset.depreciation_base - value_depreciated
|
||||||
asset.depreciation_base - value_depreciated
|
depreciated = value_depreciated
|
||||||
asset.value_depreciated = value_depreciated
|
|
||||||
else:
|
else:
|
||||||
asset.value_residual = 0.0
|
residual = 0.0
|
||||||
asset.value_depreciated = 0.0
|
depreciated = 0.0
|
||||||
|
asset.update({
|
||||||
|
'value_residual': residual,
|
||||||
|
'value_depreciated': depreciated
|
||||||
|
})
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
@api.constrains('parent_id')
|
@api.constrains('parent_id')
|
||||||
def _check_recursion(self, parent=None):
|
def _check_recursion(self, parent=None):
|
||||||
res = super(AccountAsset, self)._check_recursion(parent=parent)
|
res = super()._check_recursion(parent=parent)
|
||||||
if not res:
|
if not res:
|
||||||
raise UserError(
|
raise UserError(
|
||||||
_("Error ! You can not create recursive assets."))
|
_("Error ! You can not create recursive assets."))
|
||||||
@ -279,9 +284,10 @@ class AccountAsset(models.Model):
|
|||||||
dl_create_line = self.depreciation_line_ids.filtered(
|
dl_create_line = self.depreciation_line_ids.filtered(
|
||||||
lambda r: r.type == 'create')
|
lambda r: r.type == 'create')
|
||||||
if dl_create_line:
|
if dl_create_line:
|
||||||
dl_create_line.write({
|
dl_create_line.update({
|
||||||
'amount': self.depreciation_base,
|
'amount': self.depreciation_base,
|
||||||
'line_date': self.date_start})
|
'line_date': self.date_start
|
||||||
|
})
|
||||||
|
|
||||||
@api.onchange('profile_id')
|
@api.onchange('profile_id')
|
||||||
def _onchange_profile_id(self):
|
def _onchange_profile_id(self):
|
||||||
@ -290,16 +296,18 @@ class AccountAsset(models.Model):
|
|||||||
raise UserError(
|
raise UserError(
|
||||||
_("You cannot change the profile of an asset "
|
_("You cannot change the profile of an asset "
|
||||||
"with accounting entries."))
|
"with accounting entries."))
|
||||||
if self.profile_id:
|
|
||||||
profile = self.profile_id
|
profile = self.profile_id
|
||||||
self.parent_id = profile.parent_id
|
if profile:
|
||||||
self.method = profile.method
|
self.update({
|
||||||
self.method_number = profile.method_number
|
'parent_id': profile.parent_id,
|
||||||
self.method_time = profile.method_time
|
'method': profile.method,
|
||||||
self.method_period = profile.method_period
|
'method_number': profile.method_number,
|
||||||
self.method_progress_factor = profile.method_progress_factor
|
'method_time': profile.method_time,
|
||||||
self.prorata = profile.prorata
|
'method_period': profile.method_period,
|
||||||
self.account_analytic_id = profile.account_analytic_id
|
'method_progress_factor': profile.method_progress_factor,
|
||||||
|
'prorata': profile.prorata,
|
||||||
|
'account_analytic_id': profile.account_analytic_id,
|
||||||
|
})
|
||||||
|
|
||||||
@api.onchange('method_time')
|
@api.onchange('method_time')
|
||||||
def _onchange_method_time(self):
|
def _onchange_method_time(self):
|
||||||
@ -309,10 +317,12 @@ class AccountAsset(models.Model):
|
|||||||
@api.onchange('type')
|
@api.onchange('type')
|
||||||
def _onchange_type(self):
|
def _onchange_type(self):
|
||||||
if self.type == 'view':
|
if self.type == 'view':
|
||||||
self.date_start = False
|
self.update({
|
||||||
self.profile_id = False
|
'date_start': False,
|
||||||
self.purchase_value = False
|
'profile_id': False,
|
||||||
self.salvage_value = False
|
'purchase_value': False,
|
||||||
|
'salvage_value': False,
|
||||||
|
})
|
||||||
if self.depreciation_line_ids:
|
if self.depreciation_line_ids:
|
||||||
self.depreciation_line_ids.unlink()
|
self.depreciation_line_ids.unlink()
|
||||||
|
|
||||||
@ -322,8 +332,8 @@ class AccountAsset(models.Model):
|
|||||||
vals['prorata'] = True
|
vals['prorata'] = True
|
||||||
if vals.get('type') == 'view':
|
if vals.get('type') == 'view':
|
||||||
vals['date_start'] = False
|
vals['date_start'] = False
|
||||||
asset = super(AccountAsset, self).create(vals)
|
asset = super().create(vals)
|
||||||
if self._context.get('create_asset_from_move_line'):
|
if self.env.context.get('create_asset_from_move_line'):
|
||||||
# Trigger compute of depreciation_base
|
# Trigger compute of depreciation_base
|
||||||
asset.salvage_value = 0.0
|
asset.salvage_value = 0.0
|
||||||
if asset.type == 'normal':
|
if asset.type == 'normal':
|
||||||
@ -335,20 +345,19 @@ class AccountAsset(models.Model):
|
|||||||
if vals.get('method_time'):
|
if vals.get('method_time'):
|
||||||
if vals['method_time'] != 'year' and not vals.get('prorata'):
|
if vals['method_time'] != 'year' and not vals.get('prorata'):
|
||||||
vals['prorata'] = True
|
vals['prorata'] = True
|
||||||
super(AccountAsset, self).write(vals)
|
res = super().write(vals)
|
||||||
for asset in self:
|
for asset in self:
|
||||||
asset_type = vals.get('type') or asset.type
|
asset_type = vals.get('type') or asset.type
|
||||||
if asset_type == 'view' or \
|
if asset_type == 'view' or \
|
||||||
self._context.get('asset_validate_from_write'):
|
self.env.context.get('asset_validate_from_write'):
|
||||||
continue
|
continue
|
||||||
asset._create_first_asset_line()
|
asset._create_first_asset_line()
|
||||||
if asset.profile_id.open_asset and \
|
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()
|
asset.compute_depreciation_board()
|
||||||
# extra context to avoid recursion
|
# extra context to avoid recursion
|
||||||
ctx = dict(self._context, asset_validate_from_write=True)
|
asset.with_context(asset_validate_from_write=True).validate()
|
||||||
asset.with_context(ctx).validate()
|
return res
|
||||||
return True
|
|
||||||
|
|
||||||
def _create_first_asset_line(self):
|
def _create_first_asset_line(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
@ -364,8 +373,8 @@ class AccountAsset(models.Model):
|
|||||||
'type': 'create',
|
'type': 'create',
|
||||||
}
|
}
|
||||||
asset_line = asset_line_obj.create(asset_line_vals)
|
asset_line = asset_line_obj.create(asset_line_vals)
|
||||||
if self._context.get('create_asset_from_move_line'):
|
if self.env.context.get('create_asset_from_move_line'):
|
||||||
asset_line.move_id = self._context['move_id']
|
asset_line.move_id = self.env.context['move_id']
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def unlink(self):
|
def unlink(self):
|
||||||
@ -379,11 +388,11 @@ class AccountAsset(models.Model):
|
|||||||
_("You cannot delete an asset that contains "
|
_("You cannot delete an asset that contains "
|
||||||
"posted depreciation lines."))
|
"posted depreciation lines."))
|
||||||
# update accounting entries linked to lines of type 'create'
|
# update accounting entries linked to lines of type 'create'
|
||||||
ctx = dict(self._context, allow_asset_removal=True,
|
amls = self.with_context(
|
||||||
from_parent_object=True)
|
allow_asset_removal=True, from_parent_object=True
|
||||||
amls = self.with_context(ctx).mapped('account_move_line_ids')
|
).mapped('account_move_line_ids')
|
||||||
amls.write({'asset_id': False})
|
amls.write({'asset_id': False})
|
||||||
return super(AccountAsset, self).unlink()
|
return super().unlink()
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def name_search(self, name, args=None, operator='ilike', limit=100):
|
def name_search(self, name, args=None, operator='ilike', limit=100):
|
||||||
@ -422,7 +431,7 @@ class AccountAsset(models.Model):
|
|||||||
@api.multi
|
@api.multi
|
||||||
def remove(self):
|
def remove(self):
|
||||||
self.ensure_one()
|
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
|
early_removal = False
|
||||||
if self.method in ['linear-limit', 'degr-limit']:
|
if self.method in ['linear-limit', 'degr-limit']:
|
||||||
@ -441,7 +450,6 @@ class AccountAsset(models.Model):
|
|||||||
'target': 'new',
|
'target': 'new',
|
||||||
'type': 'ir.actions.act_window',
|
'type': 'ir.actions.act_window',
|
||||||
'context': ctx,
|
'context': ctx,
|
||||||
'nodestroy': True,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
@ -461,13 +469,17 @@ class AccountAsset(models.Model):
|
|||||||
'res_model': 'account.move',
|
'res_model': 'account.move',
|
||||||
'view_id': False,
|
'view_id': False,
|
||||||
'type': 'ir.actions.act_window',
|
'type': 'ir.actions.act_window',
|
||||||
'context': self._context,
|
'context': self.env.context,
|
||||||
'nodestroy': True,
|
|
||||||
'domain': [('id', 'in', am_ids)],
|
'domain': [('id', 'in', am_ids)],
|
||||||
}
|
}
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def compute_depreciation_board(self):
|
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']
|
line_obj = self.env['account.asset.line']
|
||||||
digits = self.env['decimal.precision'].precision_get('Account')
|
digits = self.env['decimal.precision'].precision_get('Account')
|
||||||
|
|
||||||
@ -498,8 +510,8 @@ class AccountAsset(models.Model):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# group lines prior to depreciation start period
|
# group lines prior to depreciation start period
|
||||||
depreciation_start_date = datetime.strptime(
|
depreciation_start_date = fields.Datetime.from_string(
|
||||||
asset.date_start, '%Y-%m-%d')
|
asset.date_start)
|
||||||
lines = table[0]['lines']
|
lines = table[0]['lines']
|
||||||
lines1 = []
|
lines1 = []
|
||||||
lines2 = []
|
lines2 = []
|
||||||
@ -512,9 +524,6 @@ class AccountAsset(models.Model):
|
|||||||
else:
|
else:
|
||||||
lines2.append(line)
|
lines2.append(line)
|
||||||
if lines1:
|
if lines1:
|
||||||
def group_lines(x, y):
|
|
||||||
y.update({'amount': x['amount'] + y['amount']})
|
|
||||||
return y
|
|
||||||
lines1 = [reduce(group_lines, lines1)]
|
lines1 = [reduce(group_lines, lines1)]
|
||||||
lines1[0]['depreciated_value'] = 0.0
|
lines1[0]['depreciated_value'] = 0.0
|
||||||
table[0]['lines'] = lines1 + lines2
|
table[0]['lines'] = lines1 + lines2
|
||||||
@ -523,8 +532,8 @@ class AccountAsset(models.Model):
|
|||||||
# recompute in case of deviation
|
# recompute in case of deviation
|
||||||
depreciated_value_posted = depreciated_value = 0.0
|
depreciated_value_posted = depreciated_value = 0.0
|
||||||
if posted_lines:
|
if posted_lines:
|
||||||
last_depreciation_date = datetime.strptime(
|
last_depreciation_date = fields.Datetime.from_string(
|
||||||
last_line.line_date, '%Y-%m-%d')
|
last_line.line_date)
|
||||||
last_date_in_table = table[-1]['lines'][-1]['date']
|
last_date_in_table = table[-1]['lines'][-1]['date']
|
||||||
if last_date_in_table <= last_depreciation_date:
|
if last_date_in_table <= last_depreciation_date:
|
||||||
raise UserError(
|
raise UserError(
|
||||||
@ -616,8 +625,8 @@ class AccountAsset(models.Model):
|
|||||||
- years: duration in calendar years, considering also leap years
|
- years: duration in calendar years, considering also leap years
|
||||||
"""
|
"""
|
||||||
fy = self.env['date.range'].browse(fy_id)
|
fy = self.env['date.range'].browse(fy_id)
|
||||||
fy_date_start = datetime.strptime(fy.date_start, '%Y-%m-%d')
|
fy_date_start = fields.Datetime.from_string(fy.date_start)
|
||||||
fy_date_stop = datetime.strptime(fy.date_end, '%Y-%m-%d')
|
fy_date_stop = fields.Datetime.from_string(fy.date_end)
|
||||||
days = (fy_date_stop - fy_date_start).days + 1
|
days = (fy_date_stop - fy_date_start).days + 1
|
||||||
months = (fy_date_stop.year - fy_date_start.year) * 12 \
|
months = (fy_date_stop.year - fy_date_start.year) * 12 \
|
||||||
+ (fy_date_stop.month - fy_date_start.month) + 1
|
+ (fy_date_stop.month - fy_date_start.month) + 1
|
||||||
@ -639,7 +648,7 @@ class AccountAsset(models.Model):
|
|||||||
factor = float(duration) / cy_days
|
factor = float(duration) / cy_days
|
||||||
elif i == cnt - 1: # last year
|
elif i == cnt - 1: # last year
|
||||||
duration = (
|
duration = (
|
||||||
fy_date_stop - datetime(year, 01, 01)).days + 1
|
fy_date_stop - datetime(year, 1, 1)).days + 1
|
||||||
factor += float(duration) / cy_days
|
factor += float(duration) / cy_days
|
||||||
else:
|
else:
|
||||||
factor += 1.0
|
factor += 1.0
|
||||||
@ -655,8 +664,8 @@ class AccountAsset(models.Model):
|
|||||||
fy_id = entry['fy_id']
|
fy_id = entry['fy_id']
|
||||||
if self.prorata:
|
if self.prorata:
|
||||||
if firstyear:
|
if firstyear:
|
||||||
depreciation_date_start = datetime.strptime(
|
depreciation_date_start = fields.Datetime.from_string(
|
||||||
self.date_start, '%Y-%m-%d')
|
self.date_start)
|
||||||
fy_date_stop = entry['date_stop']
|
fy_date_stop = entry['date_stop']
|
||||||
first_fy_asset_days = \
|
first_fy_asset_days = \
|
||||||
(fy_date_stop - depreciation_date_start).days + 1
|
(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 the fiscal year starts in the middle of a month.
|
||||||
"""
|
"""
|
||||||
if self.prorata:
|
if self.prorata:
|
||||||
depreciation_start_date = datetime.strptime(
|
depreciation_start_date = fields.Datetime.from_string(
|
||||||
self.date_start, '%Y-%m-%d')
|
self.date_start)
|
||||||
else:
|
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(
|
depreciation_start_date = datetime(
|
||||||
fy_date_start.year, fy_date_start.month, 1)
|
fy_date_start.year, fy_date_start.month, 1)
|
||||||
return depreciation_start_date
|
return depreciation_start_date
|
||||||
@ -717,8 +726,8 @@ class AccountAsset(models.Model):
|
|||||||
depreciation_stop_date = depreciation_start_date + \
|
depreciation_stop_date = depreciation_start_date + \
|
||||||
relativedelta(years=self.method_number, days=-1)
|
relativedelta(years=self.method_number, days=-1)
|
||||||
elif self.method_time == 'end':
|
elif self.method_time == 'end':
|
||||||
depreciation_stop_date = datetime.strptime(
|
depreciation_stop_date = fields.Datetime.from_string(
|
||||||
self.method_end, '%Y-%m-%d')
|
self.method_end)
|
||||||
return depreciation_stop_date
|
return depreciation_stop_date
|
||||||
|
|
||||||
def _get_first_period_amount(self, table, entry, depreciation_start_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')
|
amount = entry.get('period_amount')
|
||||||
if self.prorata and self.method_time == 'year':
|
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
|
full_periods = len(dates) - 1
|
||||||
amount = entry['fy_amount'] - amount * full_periods
|
amount = entry['fy_amount'] - amount * full_periods
|
||||||
return amount
|
return amount
|
||||||
@ -812,7 +821,7 @@ class AccountAsset(models.Model):
|
|||||||
depreciation_stop_date, line_dates):
|
depreciation_stop_date, line_dates):
|
||||||
|
|
||||||
digits = self.env['decimal.precision'].precision_get('Account')
|
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
|
i_max = len(table) - 1
|
||||||
remaining_value = self.depreciation_base
|
remaining_value = self.depreciation_base
|
||||||
depreciated_value = 0.0
|
depreciated_value = 0.0
|
||||||
@ -902,7 +911,7 @@ class AccountAsset(models.Model):
|
|||||||
asset_date_start = datetime.strptime(self.date_start, '%Y-%m-%d')
|
asset_date_start = datetime.strptime(self.date_start, '%Y-%m-%d')
|
||||||
fy = company.find_daterange_fy(asset_date_start)
|
fy = company.find_daterange_fy(asset_date_start)
|
||||||
fiscalyear_lock_date = company.fiscalyear_lock_date
|
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
|
init_flag = True
|
||||||
if fy:
|
if fy:
|
||||||
fy_id = fy.id
|
fy_id = fy.id
|
||||||
@ -957,14 +966,20 @@ class AccountAsset(models.Model):
|
|||||||
fy_date_start = fy_date_stop + relativedelta(days=1)
|
fy_date_start = fy_date_stop + relativedelta(days=1)
|
||||||
fy = company.find_daterange_fy(fy_date_start)
|
fy = company.find_daterange_fy(fy_date_start)
|
||||||
if fy:
|
if fy:
|
||||||
if fiscalyear_lock_date >= fy.date_end:
|
if (
|
||||||
|
fiscalyear_lock_date and
|
||||||
|
fiscalyear_lock_date >= fy.date_end
|
||||||
|
):
|
||||||
init_flag = True
|
init_flag = True
|
||||||
else:
|
else:
|
||||||
init_flag = False
|
init_flag = False
|
||||||
fy_date_stop = datetime.strptime(fy.date_end, '%Y-%m-%d')
|
fy_date_stop = datetime.strptime(fy.date_end, '%Y-%m-%d')
|
||||||
else:
|
else:
|
||||||
fy_date_stop = fy_date_stop + relativedelta(years=1)
|
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
|
init_flag = True
|
||||||
else:
|
else:
|
||||||
init_flag = False
|
init_flag = False
|
||||||
@ -1035,7 +1050,7 @@ class AccountAsset(models.Model):
|
|||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def _compute_entries(self, date_end, check_triggers=False):
|
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
|
# generate periodical accounting entries
|
||||||
result = []
|
result = []
|
||||||
error_log = ''
|
error_log = ''
|
||||||
@ -1057,9 +1072,9 @@ class AccountAsset(models.Model):
|
|||||||
order='line_date')
|
order='line_date')
|
||||||
for depreciation in depreciations:
|
for depreciation in depreciations:
|
||||||
try:
|
try:
|
||||||
with self._cr.savepoint():
|
with self.env.cr.savepoint():
|
||||||
result += depreciation.create_move()
|
result += depreciation.create_move()
|
||||||
except:
|
except Exception:
|
||||||
e = exc_info()[0]
|
e = exc_info()[0]
|
||||||
tb = ''.join(format_exception(*exc_info()))
|
tb = ''.join(format_exception(*exc_info()))
|
||||||
asset_ref = depreciation.asset_id.code and '%s (ref: %s)' \
|
asset_ref = depreciation.asset_id.code and '%s (ref: %s)' \
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2009-2018 Noviat
|
# Copyright 2009-2018 Noviat
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
@ -23,16 +22,15 @@ class AccountAssetLine(models.Model):
|
|||||||
string='Previous Depreciation Line',
|
string='Previous Depreciation Line',
|
||||||
readonly=True)
|
readonly=True)
|
||||||
parent_state = fields.Selection(
|
parent_state = fields.Selection(
|
||||||
selection=[
|
|
||||||
('draft', 'Draft'),
|
|
||||||
('open', 'Running'),
|
|
||||||
('close', 'Close'),
|
|
||||||
('removed', 'Removed')],
|
|
||||||
related='asset_id.state',
|
related='asset_id.state',
|
||||||
string='State of Asset')
|
string='State of Asset',
|
||||||
|
readonly=True,
|
||||||
|
)
|
||||||
depreciation_base = fields.Float(
|
depreciation_base = fields.Float(
|
||||||
related='asset_id.depreciation_base',
|
related='asset_id.depreciation_base',
|
||||||
string='Depreciation Base')
|
string='Depreciation Base',
|
||||||
|
readonly=True,
|
||||||
|
)
|
||||||
amount = fields.Float(
|
amount = fields.Float(
|
||||||
string='Amount', digits=dp.get_precision('Account'),
|
string='Amount', digits=dp.get_precision('Account'),
|
||||||
required=True)
|
required=True)
|
||||||
@ -63,17 +61,17 @@ class AccountAssetLine(models.Model):
|
|||||||
init_entry = fields.Boolean(
|
init_entry = fields.Boolean(
|
||||||
string='Initial Balance Entry',
|
string='Initial Balance Entry',
|
||||||
help="Set this flag for entries of previous fiscal years "
|
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.depends('amount', 'previous_id', 'type')
|
||||||
@api.multi
|
@api.multi
|
||||||
def _compute_values(self):
|
def _compute_values(self):
|
||||||
dlines = 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
|
# skip compute for lines in unlink
|
||||||
exclude_ids = self._context['no_compute_asset_line_ids']
|
exclude_ids = self.env.context['no_compute_asset_line_ids']
|
||||||
dlines = dlines.filtered(lambda l: l.id not in exclude_ids)
|
dlines = self.filtered(lambda l: l.id not in exclude_ids)
|
||||||
dlines = self.filtered(lambda l: l.type == 'depreciate')
|
dlines = dlines.filtered(lambda l: l.type == 'depreciate')
|
||||||
dlines = dlines.sorted(key=lambda l: l.line_date)
|
dlines = dlines.sorted(key=lambda l: l.line_date)
|
||||||
|
|
||||||
for i, dl in enumerate(dlines):
|
for i, dl in enumerate(dlines):
|
||||||
@ -107,20 +105,21 @@ class AccountAssetLine(models.Model):
|
|||||||
for dl in self:
|
for dl in self:
|
||||||
if vals.get('line_date'):
|
if vals.get('line_date'):
|
||||||
if isinstance(vals['line_date'], datetime.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
|
line_date = vals.get('line_date') or dl.line_date
|
||||||
asset_lines = dl.asset_id.depreciation_line_ids
|
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
|
# allow to remove an accounting entry via the
|
||||||
# 'Delete Move' button on the depreciation lines.
|
# '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(_(
|
raise UserError(_(
|
||||||
"You are not allowed to remove an accounting entry "
|
"You are not allowed to remove an accounting entry "
|
||||||
"linked to an asset."
|
"linked to an asset."
|
||||||
"\nYou should remove such entries from the asset."))
|
"\nYou should remove such entries from the asset."))
|
||||||
elif vals.keys() == ['asset_id']:
|
elif list(vals.keys()) == ['asset_id']:
|
||||||
continue
|
continue
|
||||||
elif dl.move_id and not self._context.get(
|
elif dl.move_id and not self.env.context.get(
|
||||||
'allow_asset_line_update'):
|
'allow_asset_line_update'):
|
||||||
raise UserError(_(
|
raise UserError(_(
|
||||||
"You cannot change a depreciation line "
|
"You cannot change a depreciation line "
|
||||||
@ -152,7 +151,7 @@ class AccountAssetLine(models.Model):
|
|||||||
raise UserError(_(
|
raise UserError(_(
|
||||||
"You cannot set the date on a depreciation line "
|
"You cannot set the date on a depreciation line "
|
||||||
"prior to already posted entries."))
|
"prior to already posted entries."))
|
||||||
return super(AccountAssetLine, self).write(vals)
|
return super().write(vals)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def unlink(self):
|
def unlink(self):
|
||||||
@ -166,13 +165,12 @@ class AccountAssetLine(models.Model):
|
|||||||
"You cannot delete a depreciation line with "
|
"You cannot delete a depreciation line with "
|
||||||
"an associated accounting entry."))
|
"an associated accounting entry."))
|
||||||
previous = dl.previous_id
|
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)
|
lambda l: l.previous_id == dl and l not in self)
|
||||||
if next:
|
if next_line:
|
||||||
next.previous_id = previous
|
next_line.previous_id = previous
|
||||||
ctx = dict(self._context, no_compute_asset_line_ids=self.ids)
|
return super(AccountAssetLine, self.with_context(
|
||||||
return super(
|
no_compute_asset_line_ids=self.ids)).unlink()
|
||||||
AccountAssetLine, self.with_context(ctx)).unlink()
|
|
||||||
|
|
||||||
def _setup_move_data(self, depreciation_date):
|
def _setup_move_data(self, depreciation_date):
|
||||||
asset = self.asset_id
|
asset = self.asset_id
|
||||||
@ -184,14 +182,14 @@ class AccountAssetLine(models.Model):
|
|||||||
}
|
}
|
||||||
return move_data
|
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
|
asset = self.asset_id
|
||||||
amount = self.amount
|
amount = self.amount
|
||||||
analytic_id = False
|
analytic_id = False
|
||||||
if type == 'depreciation':
|
if ml_type == 'depreciation':
|
||||||
debit = amount < 0 and -amount or 0.0
|
debit = amount < 0 and -amount or 0.0
|
||||||
credit = 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
|
debit = amount > 0 and amount or 0.0
|
||||||
credit = amount < 0 and -amount or 0.0
|
credit = amount < 0 and -amount or 0.0
|
||||||
analytic_id = asset.account_analytic_id.id
|
analytic_id = asset.account_analytic_id.id
|
||||||
@ -213,8 +211,9 @@ class AccountAssetLine(models.Model):
|
|||||||
@api.multi
|
@api.multi
|
||||||
def create_move(self):
|
def create_move(self):
|
||||||
created_move_ids = []
|
created_move_ids = []
|
||||||
asset_ids = []
|
asset_ids = set()
|
||||||
ctx = dict(self._context, allow_asset=True, check_move_validity=False)
|
ctx = dict(self.env.context,
|
||||||
|
allow_asset=True, check_move_validity=False)
|
||||||
for line in self:
|
for line in self:
|
||||||
asset = line.asset_id
|
asset = line.asset_id
|
||||||
depreciation_date = line.line_date
|
depreciation_date = line.line_date
|
||||||
@ -229,14 +228,14 @@ class AccountAssetLine(models.Model):
|
|||||||
depreciation_date, exp_acc, 'expense', move)
|
depreciation_date, exp_acc, 'expense', move)
|
||||||
self.env['account.move.line'].with_context(ctx).create(aml_e_vals)
|
self.env['account.move.line'].with_context(ctx).create(aml_e_vals)
|
||||||
move.post()
|
move.post()
|
||||||
write_ctx = dict(self._context, allow_asset_line_update=True)
|
line.with_context(allow_asset_line_update=True).write({
|
||||||
line.with_context(write_ctx).write({'move_id': move.id})
|
'move_id': move.id
|
||||||
|
})
|
||||||
created_move_ids.append(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
|
# we re-evaluate the assets to determine if we can close them
|
||||||
for asset in self.env['account.asset'].browse(
|
for asset in self.env['account.asset'].browse(list(asset_ids)):
|
||||||
list(set(asset_ids))):
|
if asset.company_currency_id.is_zero(asset.value_residual):
|
||||||
if asset.company_id.currency_id.is_zero(asset.value_residual):
|
|
||||||
asset.state = 'close'
|
asset.state = 'close'
|
||||||
return created_move_ids
|
return created_move_ids
|
||||||
|
|
||||||
@ -250,8 +249,7 @@ class AccountAssetLine(models.Model):
|
|||||||
'res_model': 'account.move',
|
'res_model': 'account.move',
|
||||||
'view_id': False,
|
'view_id': False,
|
||||||
'type': 'ir.actions.act_window',
|
'type': 'ir.actions.act_window',
|
||||||
'context': self._context,
|
'context': self.env.context,
|
||||||
'nodestroy': True,
|
|
||||||
'domain': [('id', '=', self.move_id.id)],
|
'domain': [('id', '=', self.move_id.id)],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2009-2018 Noviat
|
# Copyright 2009-2018 Noviat
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
@ -11,7 +10,7 @@ class AccountAssetProfile(models.Model):
|
|||||||
_description = 'Asset profile'
|
_description = 'Asset profile'
|
||||||
_order = 'name'
|
_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()
|
note = fields.Text()
|
||||||
account_analytic_id = fields.Many2one(
|
account_analytic_id = fields.Many2one(
|
||||||
comodel_name='account.analytic.account',
|
comodel_name='account.analytic.account',
|
||||||
@ -158,7 +157,7 @@ class AccountAssetProfile(models.Model):
|
|||||||
def create(self, vals):
|
def create(self, vals):
|
||||||
if vals.get('method_time') != 'year' and not vals.get('prorata'):
|
if vals.get('method_time') != 'year' and not vals.get('prorata'):
|
||||||
vals['prorata'] = True
|
vals['prorata'] = True
|
||||||
profile = super(AccountAssetProfile, self).create(vals)
|
profile = super().create(vals)
|
||||||
acc_id = vals.get('account_asset_id')
|
acc_id = vals.get('account_asset_id')
|
||||||
if acc_id:
|
if acc_id:
|
||||||
account = self.env['account.account'].browse(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.get('method_time'):
|
||||||
if vals['method_time'] != 'year' and not vals.get('prorata'):
|
if vals['method_time'] != 'year' and not vals.get('prorata'):
|
||||||
vals['prorata'] = True
|
vals['prorata'] = True
|
||||||
super(AccountAssetProfile, self).write(vals)
|
res = super().write(vals)
|
||||||
for profile in self:
|
# TODO last profile in self is defined as default on the related
|
||||||
acc_id = vals.get('account_asset_id')
|
# account. must be improved.
|
||||||
if acc_id:
|
account = self.env['account.account'].browse(
|
||||||
account = self.env['account.account'].browse(acc_id)
|
vals.get('account_asset_id'))
|
||||||
if not account.asset_profile_id:
|
if self and account and not account.asset_profile_id:
|
||||||
account.write({'asset_profile_id': profile.id})
|
account.write({'asset_profile_id': self[-1].id})
|
||||||
return True
|
return res
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2009-2018 Noviat
|
# Copyright 2009-2018 Noviat
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2009-2018 Noviat
|
# Copyright 2009-2018 Noviat
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
@ -12,8 +11,7 @@ class AccountInvoice(models.Model):
|
|||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def finalize_invoice_move_lines(self, move_lines):
|
def finalize_invoice_move_lines(self, move_lines):
|
||||||
move_lines = super(AccountInvoice, self) \
|
move_lines = super().finalize_invoice_move_lines(move_lines)
|
||||||
.finalize_invoice_move_lines(move_lines)
|
|
||||||
new_lines = []
|
new_lines = []
|
||||||
for line_tuple in move_lines:
|
for line_tuple in move_lines:
|
||||||
line = line_tuple[2]
|
line = line_tuple[2]
|
||||||
@ -74,11 +72,9 @@ class AccountInvoice(models.Model):
|
|||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def action_move_create(self):
|
def action_move_create(self):
|
||||||
res = super(AccountInvoice, self).action_move_create()
|
res = super().action_move_create()
|
||||||
for inv in self:
|
for inv in self:
|
||||||
move = inv.move_id
|
assets = inv.move_id.line_ids.mapped('asset_id')
|
||||||
assets = [aml.asset_id for aml in
|
|
||||||
filter(lambda x: x.asset_id, move.line_ids)]
|
|
||||||
for asset in assets:
|
for asset in assets:
|
||||||
asset.code = inv.move_name
|
asset.code = inv.move_name
|
||||||
asset_line_name = asset._get_depreciation_entry_name(0)
|
asset_line_name = asset._get_depreciation_entry_name(0)
|
||||||
@ -92,15 +88,15 @@ class AccountInvoice(models.Model):
|
|||||||
assets = self.env['account.asset']
|
assets = self.env['account.asset']
|
||||||
for inv in self:
|
for inv in self:
|
||||||
move = inv.move_id
|
move = inv.move_id
|
||||||
assets = move.line_ids.mapped('asset_id')
|
assets |= move.line_ids.mapped('asset_id')
|
||||||
super(AccountInvoice, self).action_cancel()
|
super().action_cancel()
|
||||||
if assets:
|
if assets:
|
||||||
assets.unlink()
|
assets.unlink()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def line_get_convert(self, line, part):
|
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'):
|
if line.get('asset_profile_id'):
|
||||||
# skip empty debit/credit
|
# skip empty debit/credit
|
||||||
if res.get('debit') or res.get('credit'):
|
if res.get('debit') or res.get('credit'):
|
||||||
@ -109,16 +105,17 @@ class AccountInvoice(models.Model):
|
|||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def inv_line_characteristic_hashcode(self, invoice_line):
|
def inv_line_characteristic_hashcode(self, invoice_line):
|
||||||
res = super(AccountInvoice, self).inv_line_characteristic_hashcode(
|
res = super().inv_line_characteristic_hashcode(
|
||||||
invoice_line)
|
invoice_line)
|
||||||
res += '-%s' % invoice_line.get('asset_profile_id', 'False')
|
res += '-%s' % invoice_line.get('asset_profile_id', 'False')
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def invoice_line_move_line_get(self):
|
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']
|
invoice_line_obj = self.env['account.invoice.line']
|
||||||
for vals in res:
|
for vals in res:
|
||||||
|
if vals.get('invl_id'):
|
||||||
invline = invoice_line_obj.browse(vals['invl_id'])
|
invline = invoice_line_obj.browse(vals['invl_id'])
|
||||||
if invline.asset_profile_id:
|
if invline.asset_profile_id:
|
||||||
vals['asset_profile_id'] = invline.asset_profile_id.id
|
vals['asset_profile_id'] = invline.asset_profile_id.id
|
||||||
@ -144,4 +141,4 @@ class AccountInvoiceLine(models.Model):
|
|||||||
@api.onchange('account_id')
|
@api.onchange('account_id')
|
||||||
def _onchange_account_id(self):
|
def _onchange_account_id(self):
|
||||||
self.asset_profile_id = self.account_id.asset_profile_id.id
|
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
|
# Copyright 2009-2018 Noviat
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
@ -23,31 +22,30 @@ class AccountMove(models.Model):
|
|||||||
_inherit = 'account.move'
|
_inherit = 'account.move'
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def unlink(self, **kwargs):
|
def unlink(self):
|
||||||
for move in self:
|
# for move in self:
|
||||||
deprs = self.env['account.asset.line'].search(
|
deprs = self.env['account.asset.line'].search(
|
||||||
[('move_id', '=', move.id),
|
[('move_id', 'in', self.ids),
|
||||||
('type', 'in', ['depreciate', 'remove'])])
|
('type', 'in', ['depreciate', 'remove'])])
|
||||||
if deprs and not self._context.get('unlink_from_asset'):
|
if deprs and not self.env.context.get('unlink_from_asset'):
|
||||||
raise UserError(
|
raise UserError(
|
||||||
_("You are not allowed to remove an accounting entry "
|
_("You are not allowed to remove an accounting entry "
|
||||||
"linked to an asset."
|
"linked to an asset."
|
||||||
"\nYou should remove such entries from the asset."))
|
"\nYou should remove such entries from the asset."))
|
||||||
# trigger store function
|
# trigger store function
|
||||||
deprs.write({'move_id': False})
|
deprs.write({'move_id': False})
|
||||||
return super(AccountMove, self).unlink(**kwargs)
|
return super().unlink()
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def write(self, vals):
|
def write(self, vals):
|
||||||
if set(vals).intersection(FIELDS_AFFECTS_ASSET_MOVE):
|
if set(vals).intersection(FIELDS_AFFECTS_ASSET_MOVE):
|
||||||
for move in self:
|
|
||||||
deprs = self.env['account.asset.line'].search(
|
deprs = self.env['account.asset.line'].search(
|
||||||
[('move_id', '=', move.id), ('type', '=', 'depreciate')])
|
[('move_id', 'in', self.ids), ('type', '=', 'depreciate')])
|
||||||
if deprs:
|
if deprs:
|
||||||
raise UserError(
|
raise UserError(
|
||||||
_("You cannot change an accounting entry "
|
_("You cannot change an accounting entry "
|
||||||
"linked to an asset depreciation line."))
|
"linked to an asset depreciation line."))
|
||||||
return super(AccountMove, self).write(vals)
|
return super().write(vals)
|
||||||
|
|
||||||
|
|
||||||
class AccountMoveLine(models.Model):
|
class AccountMoveLine(models.Model):
|
||||||
@ -65,8 +63,8 @@ class AccountMoveLine(models.Model):
|
|||||||
self.asset_profile_id = self.account_id.asset_profile_id
|
self.asset_profile_id = self.account_id.asset_profile_id
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def create(self, vals, **kwargs):
|
def create(self, vals):
|
||||||
if vals.get('asset_id') and not self._context.get('allow_asset'):
|
if vals.get('asset_id') and not self.env.context.get('allow_asset'):
|
||||||
raise UserError(
|
raise UserError(
|
||||||
_("You are not allowed to link "
|
_("You are not allowed to link "
|
||||||
"an accounting entry to an asset."
|
"an accounting entry to an asset."
|
||||||
@ -83,26 +81,47 @@ class AccountMoveLine(models.Model):
|
|||||||
'partner_id': vals['partner_id'],
|
'partner_id': vals['partner_id'],
|
||||||
'date_start': move.date,
|
'date_start': move.date,
|
||||||
}
|
}
|
||||||
if self._context.get('company_id'):
|
if self.env.context.get('company_id'):
|
||||||
temp_vals['company_id'] = self._context['company_id']
|
temp_vals['company_id'] = self.env.context['company_id']
|
||||||
temp_asset = asset_obj.new(temp_vals)
|
temp_asset = asset_obj.new(temp_vals)
|
||||||
temp_asset._onchange_profile_id()
|
temp_asset._onchange_profile_id()
|
||||||
asset_vals = temp_asset._convert_to_write(temp_asset._cache)
|
asset_vals = temp_asset._convert_to_write(temp_asset._cache)
|
||||||
self._get_asset_analytic_values(vals, asset_vals)
|
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(
|
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
|
vals['asset_id'] = asset.id
|
||||||
return super(AccountMoveLine, self).create(vals, **kwargs)
|
return super().create(vals)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def write(self, vals, **kwargs):
|
def _prepare_asset_create(self, vals):
|
||||||
for aml in self:
|
self.ensure_one()
|
||||||
if aml.asset_id:
|
debit = 'debit' in vals and vals.get('debit', 0.0) or self.debit
|
||||||
if set(vals).intersection(FIELDS_AFFECTS_ASSET_MOVE_LINE):
|
credit = 'credit' in vals and \
|
||||||
if not (self.env.context.get('allow_asset_removal') and
|
vals.get('credit', 0.0) or self.credit
|
||||||
vals.keys() == ['asset_id']):
|
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(
|
raise UserError(
|
||||||
_("You cannot change an accounting item "
|
_("You cannot change an accounting item "
|
||||||
"linked to an asset depreciation line."))
|
"linked to an asset depreciation line."))
|
||||||
@ -112,41 +131,28 @@ class AccountMoveLine(models.Model):
|
|||||||
"an accounting entry to an asset."
|
"an accounting entry to an asset."
|
||||||
"\nYou should generate such entries from the asset."))
|
"\nYou should generate such entries from the asset."))
|
||||||
if vals.get('asset_profile_id'):
|
if vals.get('asset_profile_id'):
|
||||||
assert len(self.ids) == 1, \
|
if len(self) == 1:
|
||||||
'This option should only be used for a single id at a time.'
|
raise AssertionError(_(
|
||||||
|
'This option should only be used for a single id at a '
|
||||||
|
'time.'))
|
||||||
asset_obj = self.env['account.asset']
|
asset_obj = self.env['account.asset']
|
||||||
for aml in self:
|
for aml in self:
|
||||||
if vals['asset_profile_id'] == aml.asset_profile_id.id:
|
if vals['asset_profile_id'] == aml.asset_profile_id.id:
|
||||||
continue
|
continue
|
||||||
# create asset
|
# create asset
|
||||||
debit = 'debit' in vals and vals.get('debit', 0.0) or aml.debit
|
asset_vals = aml._prepare_asset_create(vals)
|
||||||
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,
|
|
||||||
}
|
|
||||||
self._play_onchange_profile_id(asset_vals)
|
self._play_onchange_profile_id(asset_vals)
|
||||||
self._get_asset_analytic_values(vals, asset_vals)
|
self._get_asset_analytic_values(vals, asset_vals)
|
||||||
ctx = dict(self._context, create_asset_from_move_line=True,
|
asset = asset_obj.with_context(
|
||||||
move_id=aml.move_id.id)
|
create_asset_from_move_line=True,
|
||||||
asset = asset_obj.with_context(ctx).create(asset_vals)
|
move_id=aml.move_id.id).create(asset_vals)
|
||||||
vals['asset_id'] = asset.id
|
vals['asset_id'] = asset.id
|
||||||
return super(AccountMoveLine, self).write(vals, **kwargs)
|
return super().write(vals)
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _get_asset_analytic_values(self, vals, asset_vals):
|
def _get_asset_analytic_values(self, vals, asset_vals):
|
||||||
asset_vals['account_analytic_id'] = \
|
asset_vals['account_analytic_id'] = vals.get(
|
||||||
vals.get('analytic_account_id', False)
|
'analytic_account_id', False)
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _play_onchange_profile_id(self, vals):
|
def _play_onchange_profile_id(self, vals):
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright 2009-2017 Noviat
|
# Copyright 2009-2017 Noviat
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# 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(
|
self.env['account.asset.recompute.trigger'].sudo().create(
|
||||||
recompute_vals)
|
recompute_vals)
|
||||||
return super(DateRange, self).create(vals)
|
return super().create(vals)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def write(self, vals):
|
def write(self, vals):
|
||||||
@ -48,4 +47,4 @@ class DateRange(models.Model):
|
|||||||
}
|
}
|
||||||
self.env['account.asset.recompute.trigger'].sudo().\
|
self.env['account.asset.recompute.trigger'].sudo().\
|
||||||
create(recompute_vals)
|
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).
|
# Copyright (c) 2014 ACSONE SA/NV (http://acsone.eu).
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# 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):
|
class Config(models.TransientModel):
|
||||||
_inherit = 'account.config.settings'
|
_inherit = 'res.config.settings'
|
||||||
|
|
||||||
module_account_asset_management = fields.Boolean(
|
module_account_asset_management = fields.Boolean(
|
||||||
string='Assets management (OCA)',
|
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
|
from . import test_account_asset_management
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" ?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<data noupdate="1">
|
<data noupdate="1">
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2014 ACSONE SA/NV (acsone.eu).
|
# Copyright (c) 2014 ACSONE SA/NV (acsone.eu).
|
||||||
# Copyright 2009-2018 Noviat
|
# Copyright 2009-2018 Noviat
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
@ -7,87 +6,89 @@ import calendar
|
|||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import odoo.tests.common as common
|
from odoo.tests.common import SavepointCase
|
||||||
from odoo import tools
|
from odoo import tools
|
||||||
from odoo.modules.module import get_resource_path
|
from odoo.modules.module import get_resource_path
|
||||||
|
|
||||||
|
|
||||||
class TestAssetManagement(common.TransactionCase):
|
class TestAssetManagement(SavepointCase):
|
||||||
|
|
||||||
def _load(self, module, *args):
|
@classmethod
|
||||||
tools.convert_file(self.cr, module,
|
def _load(cls, module, *args):
|
||||||
|
tools.convert_file(cls.cr, module,
|
||||||
get_resource_path(module, *args),
|
get_resource_path(module, *args),
|
||||||
{}, 'init', False, 'test',
|
{}, 'init', False, 'test',
|
||||||
self.registry._assertion_report)
|
cls.registry._assertion_report)
|
||||||
|
|
||||||
def setUp(self):
|
@classmethod
|
||||||
super(TestAssetManagement, self).setUp()
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
|
||||||
self._load('account', 'test', 'account_minimal_test.xml')
|
cls._load('account', 'test', 'account_minimal_test.xml')
|
||||||
self._load('account_asset_management', 'tests',
|
cls._load('account_asset_management', 'tests',
|
||||||
'account_asset_test_data.xml')
|
'account_asset_test_data.xml')
|
||||||
|
|
||||||
# ENVIRONEMENTS
|
# ENVIRONEMENTS
|
||||||
self.asset_model = self.env['account.asset']
|
cls.asset_model = cls.env['account.asset']
|
||||||
self.dl_model = self.env['account.asset.line']
|
cls.dl_model = cls.env['account.asset.line']
|
||||||
self.remove_model = self.env['account.asset.remove']
|
cls.remove_model = cls.env['account.asset.remove']
|
||||||
self.account_invoice = self.env['account.invoice']
|
cls.account_invoice = cls.env['account.invoice']
|
||||||
self.account_move_line = self.env['account.move.line']
|
cls.account_move_line = cls.env['account.move.line']
|
||||||
self.account_account = self.env['account.account']
|
cls.account_account = cls.env['account.account']
|
||||||
self.account_journal = self.env['account.journal']
|
cls.account_journal = cls.env['account.journal']
|
||||||
self.account_invoice_line = self.env['account.invoice.line']
|
cls.account_invoice_line = cls.env['account.invoice.line']
|
||||||
|
|
||||||
# INSTANCES
|
# INSTANCES
|
||||||
|
|
||||||
# Instance: company
|
# Instance: company
|
||||||
self.company = self.env.ref('base.main_company')
|
cls.company = cls.env.ref('base.main_company')
|
||||||
|
|
||||||
# Instance: account type (receivable)
|
# 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)
|
# 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)
|
# Instance: account (receivable)
|
||||||
self.account_recv = self.account_account.create({
|
cls.account_recv = cls.account_account.create({
|
||||||
'name': 'test_account_receivable',
|
'name': 'test_account_receivable',
|
||||||
'code': '123',
|
'code': '123',
|
||||||
'user_type_id': self.type_recv.id,
|
'user_type_id': cls.type_recv.id,
|
||||||
'company_id': self.company.id,
|
'company_id': cls.company.id,
|
||||||
'reconcile': True})
|
'reconcile': True})
|
||||||
|
|
||||||
# Instance: account (payable)
|
# Instance: account (payable)
|
||||||
self.account_payable = self.account_account.create({
|
cls.account_payable = cls.account_account.create({
|
||||||
'name': 'test_account_payable',
|
'name': 'test_account_payable',
|
||||||
'code': '321',
|
'code': '321',
|
||||||
'user_type_id': self.type_payable.id,
|
'user_type_id': cls.type_payable.id,
|
||||||
'company_id': self.company.id,
|
'company_id': cls.company.id,
|
||||||
'reconcile': True})
|
'reconcile': True})
|
||||||
|
|
||||||
# Instance: partner
|
# Instance: partner
|
||||||
self.partner = self.env.ref('base.res_partner_2')
|
cls.partner = cls.env.ref('base.res_partner_2')
|
||||||
|
|
||||||
# Instance: journal
|
# Instance: journal
|
||||||
self.journal = self.account_journal.search(
|
cls.journal = cls.account_journal.search(
|
||||||
[('type', '=', 'purchase')])[0]
|
[('type', '=', 'purchase')])[0]
|
||||||
|
|
||||||
# Instance: product
|
# Instance: product
|
||||||
self.product = self.env.ref('product.product_product_4')
|
cls.product = cls.env.ref('product.product_product_4')
|
||||||
|
|
||||||
# Instance: invoice line
|
# Instance: invoice line
|
||||||
self.invoice_line = self.account_invoice_line.create({
|
cls.invoice_line = cls.account_invoice_line.create({
|
||||||
'name': 'test',
|
'name': 'test',
|
||||||
'account_id': self.account_payable.id,
|
'account_id': cls.account_payable.id,
|
||||||
'price_unit': 2000.00,
|
'price_unit': 2000.00,
|
||||||
'quantity': 1,
|
'quantity': 1,
|
||||||
'product_id': self.product.id})
|
'product_id': cls.product.id})
|
||||||
|
|
||||||
# Instance: invoice
|
# Instance: invoice
|
||||||
self.invoice = self.account_invoice.create({
|
cls.invoice = cls.account_invoice.create({
|
||||||
'partner_id': self.partner.id,
|
'partner_id': cls.partner.id,
|
||||||
'account_id': self.account_recv.id,
|
'account_id': cls.account_recv.id,
|
||||||
'journal_id': self.journal.id,
|
'journal_id': cls.journal.id,
|
||||||
'invoice_line_ids': [(4, self.invoice_line.id)]})
|
'invoice_line_ids': [(4, cls.invoice_line.id)]})
|
||||||
|
|
||||||
def test_01_nonprorata_basic(self):
|
def test_01_nonprorata_basic(self):
|
||||||
"""Basic tests of depreciation board computations and postings."""
|
"""Basic tests of depreciation board computations and postings."""
|
||||||
@ -96,30 +97,30 @@ class TestAssetManagement(common.TransactionCase):
|
|||||||
#
|
#
|
||||||
ict0 = self.browse_ref('account_asset_management.'
|
ict0 = self.browse_ref('account_asset_management.'
|
||||||
'account_asset_asset_ict0')
|
'account_asset_asset_ict0')
|
||||||
self.assertEquals(ict0.state, 'draft')
|
self.assertEqual(ict0.state, 'draft')
|
||||||
self.assertEquals(ict0.purchase_value, 1500)
|
self.assertEqual(ict0.purchase_value, 1500)
|
||||||
self.assertEquals(ict0.salvage_value, 0)
|
self.assertEqual(ict0.salvage_value, 0)
|
||||||
self.assertEquals(ict0.depreciation_base, 1500)
|
self.assertEqual(ict0.depreciation_base, 1500)
|
||||||
self.assertEquals(len(ict0.depreciation_line_ids), 1)
|
self.assertEqual(len(ict0.depreciation_line_ids), 1)
|
||||||
vehicle0 = self.browse_ref('account_asset_management.'
|
vehicle0 = self.browse_ref('account_asset_management.'
|
||||||
'account_asset_asset_vehicle0')
|
'account_asset_asset_vehicle0')
|
||||||
self.assertEquals(vehicle0.state, 'draft')
|
self.assertEqual(vehicle0.state, 'draft')
|
||||||
self.assertEquals(vehicle0.purchase_value, 12000)
|
self.assertEqual(vehicle0.purchase_value, 12000)
|
||||||
self.assertEquals(vehicle0.salvage_value, 2000)
|
self.assertEqual(vehicle0.salvage_value, 2000)
|
||||||
self.assertEquals(vehicle0.depreciation_base, 10000)
|
self.assertEqual(vehicle0.depreciation_base, 10000)
|
||||||
self.assertEquals(len(vehicle0.depreciation_line_ids), 1)
|
self.assertEqual(len(vehicle0.depreciation_line_ids), 1)
|
||||||
|
|
||||||
#
|
#
|
||||||
# I compute the depreciation boards
|
# I compute the depreciation boards
|
||||||
#
|
#
|
||||||
ict0.compute_depreciation_board()
|
ict0.compute_depreciation_board()
|
||||||
ict0.refresh()
|
ict0.refresh()
|
||||||
self.assertEquals(len(ict0.depreciation_line_ids), 4)
|
self.assertEqual(len(ict0.depreciation_line_ids), 4)
|
||||||
self.assertEquals(ict0.depreciation_line_ids[1].amount, 500)
|
self.assertEqual(ict0.depreciation_line_ids[1].amount, 500)
|
||||||
vehicle0.compute_depreciation_board()
|
vehicle0.compute_depreciation_board()
|
||||||
vehicle0.refresh()
|
vehicle0.refresh()
|
||||||
self.assertEquals(len(vehicle0.depreciation_line_ids), 6)
|
self.assertEqual(len(vehicle0.depreciation_line_ids), 6)
|
||||||
self.assertEquals(vehicle0.depreciation_line_ids[1].amount, 2000)
|
self.assertEqual(vehicle0.depreciation_line_ids[1].amount, 2000)
|
||||||
|
|
||||||
#
|
#
|
||||||
# I post the first depreciation line
|
# I post the first depreciation line
|
||||||
@ -127,15 +128,15 @@ class TestAssetManagement(common.TransactionCase):
|
|||||||
ict0.validate()
|
ict0.validate()
|
||||||
ict0.depreciation_line_ids[1].create_move()
|
ict0.depreciation_line_ids[1].create_move()
|
||||||
ict0.refresh()
|
ict0.refresh()
|
||||||
self.assertEquals(ict0.state, 'open')
|
self.assertEqual(ict0.state, 'open')
|
||||||
self.assertEquals(ict0.value_depreciated, 500)
|
self.assertEqual(ict0.value_depreciated, 500)
|
||||||
self.assertEquals(ict0.value_residual, 1000)
|
self.assertEqual(ict0.value_residual, 1000)
|
||||||
vehicle0.validate()
|
vehicle0.validate()
|
||||||
vehicle0.depreciation_line_ids[1].create_move()
|
vehicle0.depreciation_line_ids[1].create_move()
|
||||||
vehicle0.refresh()
|
vehicle0.refresh()
|
||||||
self.assertEquals(vehicle0.state, 'open')
|
self.assertEqual(vehicle0.state, 'open')
|
||||||
self.assertEquals(vehicle0.value_depreciated, 2000)
|
self.assertEqual(vehicle0.value_depreciated, 2000)
|
||||||
self.assertEquals(vehicle0.value_residual, 8000)
|
self.assertEqual(vehicle0.value_residual, 8000)
|
||||||
|
|
||||||
def test_02_prorata_basic(self):
|
def test_02_prorata_basic(self):
|
||||||
"""Prorata temporis depreciation basic test."""
|
"""Prorata temporis depreciation basic test."""
|
||||||
@ -199,7 +200,7 @@ class TestAssetManagement(common.TransactionCase):
|
|||||||
'type': 'depreciate',
|
'type': 'depreciate',
|
||||||
'init_entry': True,
|
'init_entry': True,
|
||||||
})
|
})
|
||||||
self.assertEquals(len(asset.depreciation_line_ids), 2)
|
self.assertEqual(len(asset.depreciation_line_ids), 2)
|
||||||
asset.compute_depreciation_board()
|
asset.compute_depreciation_board()
|
||||||
asset.refresh()
|
asset.refresh()
|
||||||
# I check the depreciated value is the initial value
|
# I check the depreciated value is the initial value
|
||||||
@ -245,7 +246,7 @@ class TestAssetManagement(common.TransactionCase):
|
|||||||
'type': 'depreciate',
|
'type': 'depreciate',
|
||||||
'init_entry': True,
|
'init_entry': True,
|
||||||
})
|
})
|
||||||
self.assertEquals(len(asset.depreciation_line_ids), 2)
|
self.assertEqual(len(asset.depreciation_line_ids), 2)
|
||||||
asset.compute_depreciation_board()
|
asset.compute_depreciation_board()
|
||||||
asset.refresh()
|
asset.refresh()
|
||||||
# I check the depreciated value is the initial value
|
# I check the depreciated value is the initial value
|
||||||
@ -289,7 +290,7 @@ class TestAssetManagement(common.TransactionCase):
|
|||||||
asset.refresh()
|
asset.refresh()
|
||||||
|
|
||||||
# check values in the depreciation board
|
# 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,
|
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
|
||||||
400.00, places=2)
|
400.00, places=2)
|
||||||
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
|
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
|
||||||
@ -318,7 +319,7 @@ class TestAssetManagement(common.TransactionCase):
|
|||||||
asset.refresh()
|
asset.refresh()
|
||||||
|
|
||||||
# check values in the depreciation board
|
# 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
|
# lines prior to asset start period are grouped in the first entry
|
||||||
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
|
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
|
||||||
300.00, places=2)
|
300.00, places=2)
|
||||||
@ -349,7 +350,7 @@ class TestAssetManagement(common.TransactionCase):
|
|||||||
asset.refresh()
|
asset.refresh()
|
||||||
|
|
||||||
# check values in the depreciation board
|
# 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,
|
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
|
||||||
400.00, places=2)
|
400.00, places=2)
|
||||||
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
|
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
|
||||||
@ -380,7 +381,7 @@ class TestAssetManagement(common.TransactionCase):
|
|||||||
asset.refresh()
|
asset.refresh()
|
||||||
|
|
||||||
# check values in the depreciation board
|
# 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,
|
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
|
||||||
200.00, places=2)
|
200.00, places=2)
|
||||||
self.assertAlmostEqual(asset.depreciation_line_ids[-1].amount,
|
self.assertAlmostEqual(asset.depreciation_line_ids[-1].amount,
|
||||||
@ -415,7 +416,7 @@ class TestAssetManagement(common.TransactionCase):
|
|||||||
})
|
})
|
||||||
wiz.remove()
|
wiz.remove()
|
||||||
asset.refresh()
|
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,
|
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
|
||||||
81.46, places=2)
|
81.46, places=2)
|
||||||
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
|
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<odoo>
|
<odoo>
|
||||||
|
|
||||||
<record id="view_account_form" model="ir.ui.view">
|
<record id="view_account_form" model="ir.ui.view">
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<odoo>
|
<odoo>
|
||||||
|
|
||||||
<record model="ir.ui.view" id="account_asset_view_form">
|
<record model="ir.ui.view" id="account_asset_view_form">
|
||||||
@ -17,8 +18,8 @@
|
|||||||
attrs="{'invisible': [('type', '=', 'view')]}"/>
|
attrs="{'invisible': [('type', '=', 'view')]}"/>
|
||||||
</header>
|
</header>
|
||||||
<sheet>
|
<sheet>
|
||||||
<div class="oe_button_box oe_right">
|
<div class="oe_button_box">
|
||||||
<button name="open_entries" string="Journal Entries" type="object" class="oe_inline"
|
<button name="open_entries" string="Journal Entries" type="object" class="oe_stat_button" icon="fa-bars"
|
||||||
attrs="{'invisible': [('type', '=', 'view')]}"/>
|
attrs="{'invisible': [('type', '=', 'view')]}"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_title">
|
<div class="oe_title">
|
||||||
@ -77,20 +78,20 @@
|
|||||||
<group>
|
<group>
|
||||||
<separator string="Depreciation Method" colspan="2"/>
|
<separator string="Depreciation Method" colspan="2"/>
|
||||||
<field name="method"/>
|
<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'])]}"/>
|
attrs="{'invisible': [('method', 'in', ['linear', 'linear-limit'])], 'required': [('method', 'in', ['degressive', 'degr-linear', 'degr-limit'])]}"/>
|
||||||
<field name="prorata" attrs="{'readonly': [('method_time', '!=', 'year')]}"/>
|
<field name="prorata" attrs="{'readonly': [('method_time', '!=', 'year')]}"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
<page string="Depreciation Board">
|
<page string="Depreciation Board">
|
||||||
<header>
|
<div>
|
||||||
<button type="object" name="compute_depreciation_board"
|
<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'])]}"/>
|
attrs="{'invisible': [('state', 'in', ['close', 'removed'])]}"/>
|
||||||
</header>
|
</div>
|
||||||
<field name="depreciation_line_ids" mode="tree" options="{'reload_on_button': true}">
|
<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="type"/>
|
||||||
<field name="line_date"/>
|
<field name="line_date"/>
|
||||||
<field name="depreciated_value" readonly="1"/>
|
<field name="depreciated_value" readonly="1"/>
|
||||||
@ -172,7 +173,7 @@
|
|||||||
<field name="name">account.asset.tree</field>
|
<field name="name">account.asset.tree</field>
|
||||||
<field name="model">account.asset</field>
|
<field name="model">account.asset</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree string="Assets" colors="blue:(type == 'view')">
|
<tree string="Assets" decoration-info="type == 'view'">
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="type" invisible="1"/>
|
<field name="type" invisible="1"/>
|
||||||
<field name="code"/>
|
<field name="code"/>
|
||||||
@ -194,9 +195,9 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search string="Account Asset">
|
<search string="Account Asset">
|
||||||
<filter string="Draft" name="draft" domain="[('state', '=', 'draft')]" help="Draft Assets"/>
|
<filter string="Draft" name="draft" domain="[('state', '=', 'draft')]" help="Draft Assets"/>
|
||||||
<filter string="Running" domain="[('state', '=', 'open')]" help="Assets in Running State"/>
|
<filter string="Running" name="running" domain="[('state', '=', 'open')]" help="Assets in Running State"/>
|
||||||
<filter string="Close" domain="[('state', '=', 'close')]" help="Assets in Close State"/>
|
<filter string="Close" name="close" domain="[('state', '=', 'close')]" help="Assets in Close State"/>
|
||||||
<filter string="Removed" domain="[('state', '=', 'removed')]" help="Assets which have been removed"/>
|
<filter string="Removed" name="removed" domain="[('state', '=', 'removed')]" help="Assets which have been removed"/>
|
||||||
<separator orientation="vertical"/>
|
<separator orientation="vertical"/>
|
||||||
<field name="name" string="Asset"/>
|
<field name="name" string="Asset"/>
|
||||||
<field name="code"/>
|
<field name="code"/>
|
||||||
@ -219,37 +220,6 @@
|
|||||||
<field name="search_view_id" ref="account_asset_view_search"/>
|
<field name="search_view_id" ref="account_asset_view_search"/>
|
||||||
</record>
|
</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"
|
<act_window id="act_entries_open"
|
||||||
name="Journal Items"
|
name="Journal Items"
|
||||||
src_model="account.asset"
|
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