Merge pull request #698 from grindtildeath/11.0-mig-account_asset_management

[11.0][MIG] account_asset_management : Migration to v11
This commit is contained in:
Pedro M. Baeza
2018-10-26 00:40:28 +02:00
committed by GitHub
113 changed files with 105866 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: https://www.gnu.org/licenses/agpl
:alt: License: AGPL-3
==========================
Financial asset management
==========================
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.
Configuration
=============
It is recommended to configure your Purchase Journal with "Group Invoice Lines" to avoid the
creation of separate assets per Supplier Invoice Line.
Usage
=====
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/92/10.0
Known issues
============
The module in NOT compatible with the standard account_asset module.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/account-financial-tools/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Credits
=======
Contributors
------------
- OpenERP SA
- Luc De Meyer (Noviat)
- Frédéric Clementi (camptocamp)
- Florian Dacosta (Akretion)
- Stéphane Bidoul (Acsone)
- Adrien Peiffer (Acsone)
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit http://odoo-community.org.

View File

@@ -0,0 +1,2 @@
from . import models
from . import wizard

View File

@@ -0,0 +1,30 @@
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Assets Management',
'version': '11.0.1.0.0',
'license': 'AGPL-3',
'depends': [
'account_fiscal_year',
],
'conflicts': ['account_asset'],
'author': "Noviat,Odoo Community Association (OCA)",
'website': 'https://github.com/OCA/account-financial-tools',
'category': 'Accounting & Finance',
'data': [
'security/account_asset_security.xml',
'security/ir.model.access.csv',
'wizard/account_asset_compute.xml',
'wizard/account_asset_remove.xml',
'views/account_account.xml',
'views/account_asset.xml',
'views/account_asset_profile.xml',
'views/res_config_settings.xml',
'views/account_invoice.xml',
'views/account_invoice_line.xml',
'views/account_move.xml',
'views/account_move_line.xml',
'views/menuitem.xml',
],
}

View File

@@ -0,0 +1,735 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_asset
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-06-07 19:36+0000\n"
"PO-Revision-Date: 2013-06-07 19:36+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_asset
#: view:account.asset.asset:0
msgid "Assets in draft and open states"
msgstr ""
#. module: account_asset
#: field:account.asset.category,method_end:0
#: field:account.asset.history,method_end:0
#: field:asset.modify,method_end:0
msgid "Ending date"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,value_residual:0
msgid "Residual Value"
msgstr ""
#. module: account_asset
#: field:account.asset.category,account_expense_depreciation_id:0
msgid "Depr. Expense Account"
msgstr ""
#. module: account_asset
#: view:asset.asset.report:0
msgid "Group By..."
msgstr ""
#. module: account_asset
#: field:asset.asset.report,gross_value:0
msgid "Gross Amount"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
#: field:account.asset.depreciation.line,asset_id:0
#: field:account.asset.history,asset_id:0
#: field:account.move.line,asset_id:0
#: view:asset.asset.report:0
#: field:asset.asset.report,asset_id:0
#: model:ir.model,name:account_asset.model_account_asset_asset
msgid "Asset"
msgstr ""
#. module: account_asset
#: help:account.asset.asset,prorata:0
#: help:account.asset.category,prorata:0
msgid "Indicates that the first depreciation entry for this asset have to be done from the purchase date instead of the first January"
msgstr ""
#. module: account_asset
#: selection:account.asset.asset,method:0
#: selection:account.asset.category,method:0
msgid "Linear"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,company_id:0
#: field:account.asset.category,company_id:0
#: view:asset.asset.report:0
#: field:asset.asset.report,company_id:0
msgid "Company"
msgstr ""
#. module: account_asset
#: view:asset.modify:0
msgid "Modify"
msgstr ""
#. module: account_asset
#: selection:account.asset.asset,state:0
#: view:asset.asset.report:0
#: selection:asset.asset.report,state:0
msgid "Running"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Set to Draft"
msgstr ""
#. module: account_asset
#: view:asset.asset.report:0
#: model:ir.actions.act_window,name:account_asset.action_asset_asset_report
#: model:ir.model,name:account_asset.model_asset_asset_report
#: model:ir.ui.menu,name:account_asset.menu_action_asset_asset_report
msgid "Assets Analysis"
msgstr ""
#. module: account_asset
#: field:asset.modify,name:0
msgid "Reason"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,method_progress_factor:0
#: field:account.asset.category,method_progress_factor:0
msgid "Degressive Factor"
msgstr ""
#. module: account_asset
#: model:ir.actions.act_window,name:account_asset.action_account_asset_asset_list_normal
#: model:ir.ui.menu,name:account_asset.menu_action_account_asset_asset_list_normal
msgid "Asset Categories"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
#: field:account.asset.asset,account_move_line_ids:0
#: field:account.move.line,entry_ids:0
#: model:ir.actions.act_window,name:account_asset.act_entries_open
msgid "Entries"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
#: field:account.asset.asset,depreciation_line_ids:0
msgid "Depreciation Lines"
msgstr ""
#. module: account_asset
#: help:account.asset.asset,salvage_value:0
msgid "It is the amount you plan to have that you cannot depreciate."
msgstr ""
#. module: account_asset
#: help:account.asset.asset,method_period:0
msgid "The amount of time between two depreciations, in months"
msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,depreciation_date:0
#: view:asset.asset.report:0
#: field:asset.asset.report,depreciation_date:0
msgid "Depreciation Date"
msgstr ""
#. module: account_asset
#: constraint:account.asset.asset:0
msgid "Error ! You cannot create recursive assets."
msgstr ""
#. module: account_asset
#: field:asset.asset.report,posted_value:0
msgid "Posted Amount"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
#: view:asset.asset.report:0
#: model:ir.actions.act_window,name:account_asset.action_account_asset_asset_form
#: model:ir.ui.menu,name:account_asset.menu_action_account_asset_asset_form
#: model:ir.ui.menu,name:account_asset.menu_finance_assets
#: model:ir.ui.menu,name:account_asset.menu_finance_config_assets
msgid "Assets"
msgstr ""
#. module: account_asset
#: field:account.asset.category,account_depreciation_id:0
msgid "Depreciation Account"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
#: view:account.asset.category:0
#: view:account.asset.history:0
#: view:asset.modify:0
#: field:asset.modify,note:0
msgid "Notes"
msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,move_id:0
msgid "Depreciation Entry"
msgstr ""
#. module: account_asset
#: code:addons/account_asset/account_asset.py:82
#, python-format
msgid "Error!"
msgstr ""
#. module: account_asset
#: view:asset.asset.report:0
#: field:asset.asset.report,nbr:0
msgid "# of Depreciation Lines"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,method_period:0
msgid "Number of Months in a Period"
msgstr ""
#. module: account_asset
#: view:asset.asset.report:0
msgid "Assets in draft state"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,method_end:0
#: selection:account.asset.asset,method_time:0
#: selection:account.asset.category,method_time:0
#: selection:account.asset.history,method_time:0
msgid "Ending Date"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,code:0
msgid "Reference"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Account Asset"
msgstr ""
#. module: account_asset
#: model:ir.actions.act_window,name:account_asset.action_asset_depreciation_confirmation_wizard
#: model:ir.ui.menu,name:account_asset.menu_asset_depreciation_confirmation_wizard
msgid "Compute Assets"
msgstr ""
#. module: account_asset
#: field:account.asset.category,method_period:0
#: field:account.asset.history,method_period:0
#: field:asset.modify,method_period:0
msgid "Period Length"
msgstr ""
#. module: account_asset
#: selection:account.asset.asset,state:0
#: view:asset.asset.report:0
#: selection:asset.asset.report,state:0
msgid "Draft"
msgstr ""
#. module: account_asset
#: view:asset.asset.report:0
msgid "Date of asset purchase"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Change Duration"
msgstr ""
#. module: account_asset
#: help:account.asset.asset,method_number:0
#: help:account.asset.category,method_number:0
#: help:account.asset.history,method_number:0
msgid "The number of depreciations needed to depreciate your asset"
msgstr ""
#. module: account_asset
#: view:account.asset.category:0
msgid "Analytic Information"
msgstr ""
#. module: account_asset
#: field:account.asset.category,account_analytic_id:0
msgid "Analytic account"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,method:0
#: field:account.asset.category,method:0
msgid "Computation Method"
msgstr ""
#. module: account_asset
#: constraint:account.asset.asset:0
msgid "Prorata temporis can be applied only for time method \"number of depreciations\"."
msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,remaining_value:0
msgid "Next Period Depreciation"
msgstr ""
#. module: account_asset
#: help:account.asset.history,method_period:0
msgid "Time in month between two depreciations"
msgstr ""
#. module: account_asset
#: view:asset.modify:0
#: model:ir.actions.act_window,name:account_asset.action_asset_modify
#: model:ir.model,name:account_asset.model_asset_modify
msgid "Modify Asset"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,salvage_value:0
msgid "Salvage Value"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,category_id:0
#: view:account.asset.category:0
#: field:account.invoice.line,asset_category_id:0
#: view:asset.asset.report:0
msgid "Asset Category"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Assets in closed state"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,parent_id:0
msgid "Parent Asset"
msgstr ""
#. module: account_asset
#: view:account.asset.history:0
#: model:ir.model,name:account_asset.model_account_asset_history
msgid "Asset history"
msgstr ""
#. module: account_asset
#: view:account.asset.category:0
msgid "Search Asset Category"
msgstr ""
#. module: account_asset
#: view:asset.modify:0
msgid "months"
msgstr ""
#. module: account_asset
#: model:ir.model,name:account_asset.model_account_invoice_line
msgid "Invoice Line"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Depreciation Board"
msgstr ""
#. module: account_asset
#: field:asset.asset.report,unposted_value:0
msgid "Unposted Amount"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,method_time:0
#: field:account.asset.category,method_time:0
#: field:account.asset.history,method_time:0
msgid "Time Method"
msgstr ""
#. module: account_asset
#: view:asset.depreciation.confirmation.wizard:0
#: view:asset.modify:0
msgid "or"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,note:0
#: field:account.asset.category,note:0
#: field:account.asset.history,note:0
msgid "Note"
msgstr ""
#. module: account_asset
#: help:account.asset.history,method_time:0
msgid "The method to use to compute the dates and number of depreciation lines.\n"
"Number of Depreciations: Fix the number of depreciation lines and the time between 2 depreciations.\n"
"Ending Date: Choose the time between 2 depreciations and the date the depreciations won't go beyond."
msgstr ""
#. module: account_asset
#: help:account.asset.asset,method_time:0
#: help:account.asset.category,method_time:0
msgid "Choose the method to use to compute the dates and number of depreciation lines.\n"
" * Number of Depreciations: Fix the number of depreciation lines and the time between 2 depreciations.\n"
" * Ending Date: Choose the time between 2 depreciations and the date the depreciations won't go beyond."
msgstr ""
#. module: account_asset
#: view:asset.asset.report:0
msgid "Assets in running state"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Closed"
msgstr ""
#. module: account_asset
#: help:account.asset.asset,state:0
msgid "When an asset is created, the status is 'Draft'.\n"
"If the asset is confirmed, the status goes in 'Running' and the depreciation lines can be posted in the accounting.\n"
"You can manually close an asset when the depreciation is over. If the last line of depreciation is posted, the asset automatically goes in that status."
msgstr ""
#. module: account_asset
#: field:account.asset.asset,state:0
#: field:asset.asset.report,state:0
msgid "Status"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,partner_id:0
#: field:asset.asset.report,partner_id:0
msgid "Partner"
msgstr ""
#. module: account_asset
#: view:asset.asset.report:0
msgid "Posted depreciation lines"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,child_ids:0
msgid "Children Assets"
msgstr ""
#. module: account_asset
#: view:asset.asset.report:0
msgid "Date of depreciation"
msgstr ""
#. module: account_asset
#: field:account.asset.history,user_id:0
msgid "User"
msgstr ""
#. module: account_asset
#: field:account.asset.category,account_asset_id:0
msgid "Asset Account"
msgstr ""
#. module: account_asset
#: view:asset.asset.report:0
msgid "Extended Filters..."
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
#: view:asset.depreciation.confirmation.wizard:0
msgid "Compute"
msgstr ""
#. module: account_asset
#: view:account.asset.history:0
msgid "Asset History"
msgstr ""
#. module: account_asset
#: model:ir.model,name:account_asset.model_asset_depreciation_confirmation_wizard
msgid "asset.depreciation.confirmation.wizard"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,active:0
msgid "Active"
msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,parent_state:0
msgid "State of Asset"
msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,name:0
msgid "Depreciation Name"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
#: field:account.asset.asset,history_ids:0
msgid "History"
msgstr ""
#. module: account_asset
#: view:asset.depreciation.confirmation.wizard:0
msgid "Compute Asset"
msgstr ""
#. module: account_asset
#: field:asset.depreciation.confirmation.wizard,period_id:0
msgid "Period"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "General"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,prorata:0
#: field:account.asset.category,prorata:0
msgid "Prorata Temporis"
msgstr ""
#. module: account_asset
#: model:ir.model,name:account_asset.model_account_invoice
msgid "Invoice"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Set to Close"
msgstr ""
#. module: account_asset
#: view:asset.depreciation.confirmation.wizard:0
#: view:asset.modify:0
msgid "Cancel"
msgstr ""
#. module: account_asset
#: selection:account.asset.asset,state:0
#: selection:asset.asset.report,state:0
msgid "Close"
msgstr ""
#. module: account_asset
#: model:ir.model,name:account_asset.model_account_move_line
msgid "Journal Items"
msgstr ""
#. module: account_asset
#: view:asset.modify:0
msgid "Asset Durations to Modify"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,purchase_date:0
#: view:asset.asset.report:0
#: field:asset.asset.report,purchase_date:0
msgid "Purchase Date"
msgstr ""
#. module: account_asset
#: selection:account.asset.asset,method:0
#: selection:account.asset.category,method:0
msgid "Degressive"
msgstr ""
#. module: account_asset
#: help:asset.depreciation.confirmation.wizard,period_id:0
msgid "Choose the period for which you want to automatically post the depreciation lines of running assets"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Current"
msgstr ""
#. module: account_asset
#: code:addons/account_asset/account_asset.py:82
#, python-format
msgid "You cannot delete an asset that contains posted depreciation lines."
msgstr ""
#. module: account_asset
#: view:account.asset.category:0
msgid "Depreciation Method"
msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,amount:0
msgid "Current Depreciation"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,name:0
msgid "Asset Name"
msgstr ""
#. module: account_asset
#: field:account.asset.category,open_asset:0
msgid "Skip Draft State"
msgstr ""
#. module: account_asset
#: view:account.asset.category:0
msgid "Depreciation Dates"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,currency_id:0
msgid "Currency"
msgstr ""
#. module: account_asset
#: field:account.asset.category,journal_id:0
msgid "Journal"
msgstr ""
#. module: account_asset
#: field:account.asset.history,name:0
msgid "History name"
msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,depreciated_value:0
msgid "Amount Already Depreciated"
msgstr ""
#. module: account_asset
#: help:account.asset.asset,method:0
#: help:account.asset.category,method:0
msgid "Choose the method to use to compute the amount of depreciation lines.\n"
" * Linear: Calculated on basis of: Gross Value / Number of Depreciations\n"
" * Degressive: Calculated on basis of: Residual Value * Degressive Factor"
msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,move_check:0
#: view:asset.asset.report:0
#: field:asset.asset.report,move_check:0
msgid "Posted"
msgstr ""
#. module: account_asset
#: model:ir.actions.act_window,help:account_asset.action_asset_asset_report
msgid "<p>\n"
" From this report, you can have an overview on all depreciation. The\n"
" tool search can also be used to personalise your Assets reports and\n"
" so, match this analysis to your needs;\n"
" </p>\n"
" "
msgstr ""
#. module: account_asset
#: field:account.asset.asset,purchase_value:0
msgid "Gross Value"
msgstr ""
#. module: account_asset
#: field:account.asset.category,name:0
msgid "Name"
msgstr ""
#. module: account_asset
#: help:account.asset.category,open_asset:0
msgid "Check this if you want to automatically confirm the assets of this category when created by invoices."
msgstr ""
#. module: account_asset
#: field:asset.asset.report,name:0
msgid "Year"
msgstr ""
#. module: account_asset
#: model:ir.model,name:account_asset.model_account_asset_depreciation_line
msgid "Asset depreciation line"
msgstr ""
#. module: account_asset
#: view:account.asset.category:0
#: field:asset.asset.report,asset_category_id:0
#: model:ir.model,name:account_asset.model_account_asset_category
msgid "Asset category"
msgstr ""
#. module: account_asset
#: view:asset.asset.report:0
#: field:asset.asset.report,depreciation_value:0
msgid "Amount of Depreciation Lines"
msgstr ""
#. module: account_asset
#: code:addons/account_asset/wizard/wizard_asset_compute.py:50
#, python-format
msgid "Created Asset Moves"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Add an internal note here..."
msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,sequence:0
msgid "Sequence"
msgstr ""
#. module: account_asset
#: help:account.asset.category,method_period:0
msgid "State here the time between 2 depreciations, in months"
msgstr ""
#. module: account_asset
#: field:account.asset.history,date:0
msgid "Date"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,method_number:0
#: selection:account.asset.asset,method_time:0
#: field:account.asset.category,method_number:0
#: selection:account.asset.category,method_time:0
#: field:account.asset.history,method_number:0
#: selection:account.asset.history,method_time:0
#: field:asset.modify,method_number:0
msgid "Number of Depreciations"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Create Move"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Confirm Asset"
msgstr ""
#. module: account_asset
#: model:ir.actions.act_window,name:account_asset.action_account_asset_asset_tree
#: model:ir.ui.menu,name:account_asset.menu_action_account_asset_asset_tree
msgid "Asset Hierarchy"
msgstr ""

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,526 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_asset
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 5.0.6\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-11-24 12:54:56+0000\n"
"PO-Revision-Date: 2009-11-24 12:54:56+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_asset
#: model:ir.actions.act_window,name:account_asset.action_account_asset_asset_list_normal
#: model:ir.ui.menu,name:account_asset.menu_action_account_asset_asset_list_normal
msgid "Open Assets"
msgstr ""
#. module: account_asset
#: field:account.asset.property,method_end:0
#: field:account.asset.property.history,method_end:0
msgid "Ending date"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Depreciation board"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
#: field:account.asset.asset,name:0
#: field:account.asset.board,asset_id:0
#: field:account.asset.property,asset_id:0
#: field:account.invoice.line,asset_id:0
#: field:account.move.line,asset_id:0
#: model:ir.actions.act_window,name:account_asset.action_account_asset_asset_form
#: model:ir.model,name:account_asset.model_account_asset_asset
#: model:ir.ui.menu,name:account_asset.menu_action_account_asset_asset_form
msgid "Asset"
msgstr ""
#. module: account_asset
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
msgstr ""
#. module: account_asset
#: selection:account.asset.property,method:0
msgid "Linear"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Change duration"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,child_ids:0
msgid "Child assets"
msgstr ""
#. module: account_asset
#: field:account.asset.board,value_asset:0
msgid "Asset Value"
msgstr ""
#. module: account_asset
#: wizard_field:account.asset.modify,init,name:0
msgid "Reason"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
#: field:account.asset.asset,entry_ids:0
#: wizard_field:account.asset.compute,asset_compute,move_ids:0
msgid "Entries"
msgstr ""
#. module: account_asset
#: wizard_view:account.asset.compute,asset_compute:0
msgid "Generated entries"
msgstr ""
#. module: account_asset
#: wizard_field:account.asset.modify,init,method_delay:0
#: field:account.asset.property,method_delay:0
#: field:account.asset.property.history,method_delay:0
msgid "Number of interval"
msgstr ""
#. module: account_asset
#: wizard_button:account.asset.compute,asset_compute,asset_open:0
msgid "Open entries"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
#: model:ir.actions.act_window,name:account_asset.action_account_asset_asset_list
#: model:ir.ui.menu,name:account_asset.menu_action_account_asset_asset_list
#: model:ir.ui.menu,name:account_asset.menu_finance_Assets
#: model:ir.ui.menu,name:account_asset.menu_finance_config_Assets
msgid "Assets"
msgstr ""
#. module: account_asset
#: selection:account.asset.property,method:0
msgid "Progressive"
msgstr ""
#. module: account_asset
#: model:ir.actions.act_window,name:account_asset.action_account_asset_asset_list_draft
#: model:ir.ui.menu,name:account_asset.menu_action_account_asset_asset_list_draft
msgid "Draft Assets"
msgstr ""
#. module: account_asset
#: wizard_view:account.asset.modify,init:0
#: wizard_field:account.asset.modify,init,note:0
#: view:account.asset.property.history:0
msgid "Notes"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Change history"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Depreciation entries"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Methods"
msgstr ""
#. module: account_asset
#: wizard_view:account.asset.modify,init:0
msgid "Asset properties to modify"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,partner_id:0
msgid "Partner"
msgstr ""
#. module: account_asset
#: wizard_field:account.asset.modify,init,method_period:0
#: field:account.asset.property,method_period:0
#: field:account.asset.property.history,method_period:0
msgid "Period per interval"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Depreciation duration"
msgstr ""
#. module: account_asset
#: field:account.asset.property,account_analytic_id:0
msgid "Analytic account"
msgstr ""
#. module: account_asset
#: field:account.asset.property,state:0
msgid "State"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Depreciation methods"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Other information"
msgstr ""
#. module: account_asset
#: field:account.asset.board,value_asset_cumul:0
msgid "Cumul. value"
msgstr ""
#. module: account_asset
#: view:account.asset.property:0
msgid "Assets methods"
msgstr ""
#. module: account_asset
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
msgstr ""
#. module: account_asset
#: model:ir.model,name:account_asset.model_account_asset_property
msgid "Asset property"
msgstr ""
#. module: account_asset
#: wizard_view:account.asset.compute,asset_compute:0
#: wizard_view:account.asset.compute,init:0
#: wizard_button:account.asset.compute,init,asset_compute:0
#: model:ir.actions.wizard,name:account_asset.wizard_asset_compute
#: model:ir.ui.menu,name:account_asset.menu_wizard_asset_compute
msgid "Compute assets"
msgstr ""
#. module: account_asset
#: wizard_view:account.asset.modify,init:0
#: wizard_button:account.asset.modify,init,asset_modify:0
#: model:ir.actions.wizard,name:account_asset.wizard_asset_modify
msgid "Modify asset"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Confirm asset"
msgstr ""
#. module: account_asset
#: view:account.asset.property.history:0
#: model:ir.model,name:account_asset.model_account_asset_property_history
msgid "Asset history"
msgstr ""
#. module: account_asset
#: field:account.asset.property,date:0
msgid "Date created"
msgstr ""
#. module: account_asset
#: model:ir.module.module,description:account_asset.module_meta_information
msgid "Financial and accounting asset management.\n"
" Allows to define\n"
" * Asset category. \n"
" * Assets.\n"
" *Asset usage period and property.\n"
" "
msgstr ""
#. module: account_asset
#: field:account.asset.board,value_gross:0
#: field:account.asset.property,value_total:0
msgid "Gross value"
msgstr ""
#. module: account_asset
#: selection:account.asset.property,method_time:0
msgid "Ending period"
msgstr ""
#. module: account_asset
#: field:account.asset.board,name:0
msgid "Asset name"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Accounts information"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,note:0
#: field:account.asset.category,note:0
#: field:account.asset.property.history,note:0
msgid "Note"
msgstr ""
#. module: account_asset
#: selection:account.asset.asset,state:0
#: selection:account.asset.property,state:0
msgid "Draft"
msgstr ""
#. module: account_asset
#: field:account.asset.property,type:0
msgid "Depr. method type"
msgstr ""
#. module: account_asset
#: field:account.asset.property,account_asset_id:0
msgid "Asset account"
msgstr ""
#. module: account_asset
#: field:account.asset.property.history,asset_property_id:0
msgid "Method"
msgstr ""
#. module: account_asset
#: selection:account.asset.asset,state:0
msgid "Normal"
msgstr ""
#. module: account_asset
#: field:account.asset.property,method_progress_factor:0
msgid "Progressif factor"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,localisation:0
msgid "Localisation"
msgstr ""
#. module: account_asset
#: field:account.asset.property,method:0
msgid "Computation method"
msgstr ""
#. module: account_asset
#: field:account.asset.property,method_time:0
msgid "Time method"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,active:0
msgid "Active"
msgstr ""
#. module: account_asset
#: field:account.asset.property.history,user_id:0
msgid "User"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,property_ids:0
msgid "Asset method name"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,date:0
#: field:account.asset.property.history,date:0
msgid "Date"
msgstr ""
#. module: account_asset
#: field:account.asset.board,value_net:0
msgid "Net value"
msgstr ""
#. module: account_asset
#: wizard_view:account.asset.close,init:0
#: model:ir.actions.wizard,name:account_asset.wizard_asset_close
msgid "Close asset"
msgstr ""
#. module: account_asset
#: field:account.asset.property,history_ids:0
msgid "History"
msgstr ""
#. module: account_asset
#: field:account.asset.property,account_actif_id:0
msgid "Depreciation account"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,period_id:0
#: wizard_field:account.asset.compute,init,period_id:0
msgid "Period"
msgstr ""
#. module: account_asset
#: model:ir.actions.act_window,name:account_asset.action_account_asset_category_form
#: model:ir.ui.menu,name:account_asset.menu_action_account_asset_category_form
msgid "Asset Category"
msgstr ""
#. module: account_asset
#: wizard_button:account.asset.close,init,end:0
#: wizard_button:account.asset.compute,init,end:0
#: wizard_button:account.asset.modify,init,end:0
msgid "Cancel"
msgstr ""
#. module: account_asset
#: selection:account.asset.asset,state:0
#: wizard_button:account.asset.compute,asset_compute,end:0
#: selection:account.asset.property,state:0
msgid "Close"
msgstr ""
#. module: account_asset
#: selection:account.asset.property,state:0
msgid "Open"
msgstr ""
#. module: account_asset
#: constraint:ir.model:0
msgid "The Object name must start with x_ and not contain any special character !"
msgstr ""
#. module: account_asset
#: model:ir.module.module,shortdesc:account_asset.module_meta_information
msgid "Asset management"
msgstr ""
#. module: account_asset
#: view:account.asset.board:0
#: field:account.asset.property,board_ids:0
#: model:ir.model,name:account_asset.model_account_asset_board
msgid "Asset board"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,state:0
msgid "Global state"
msgstr ""
#. module: account_asset
#: selection:account.asset.property,method_time:0
msgid "Delay"
msgstr ""
#. module: account_asset
#: wizard_view:account.asset.close,init:0
msgid "General information"
msgstr ""
#. module: account_asset
#: field:account.asset.property,journal_analytic_id:0
msgid "Analytic journal"
msgstr ""
#. module: account_asset
#: field:account.asset.property,name:0
msgid "Method name"
msgstr ""
#. module: account_asset
#: field:account.asset.property,journal_id:0
msgid "Journal"
msgstr ""
#. module: account_asset
#: field:account.asset.property.history,name:0
msgid "History name"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Close method"
msgstr ""
#. module: account_asset
#: field:account.asset.property,entry_asset_ids:0
msgid "Asset Entries"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,category_id:0
#: view:account.asset.category:0
#: field:account.asset.category,name:0
#: model:ir.model,name:account_asset.model_account_asset_category
msgid "Asset category"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "Depreciation"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,code:0
#: field:account.asset.category,code:0
msgid "Asset code"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,value_total:0
msgid "Total value"
msgstr ""
#. module: account_asset
#: selection:account.asset.asset,state:0
msgid "View"
msgstr ""
#. module: account_asset
#: view:account.asset.asset:0
msgid "General info"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,sequence:0
msgid "Sequence"
msgstr ""
#. module: account_asset
#: field:account.asset.property,value_residual:0
msgid "Residual value"
msgstr ""
#. module: account_asset
#: wizard_button:account.asset.close,init,asset_close:0
msgid "End of asset"
msgstr ""
#. module: account_asset
#: selection:account.asset.property,type:0
msgid "Direct"
msgstr ""
#. module: account_asset
#: selection:account.asset.property,type:0
msgid "Indirect"
msgstr ""
#. module: account_asset
#: field:account.asset.asset,parent_id:0
msgid "Parent asset"
msgstr ""
#. module: account_asset
#: model:ir.actions.act_window,name:account_asset.action_account_asset_asset_tree
#: model:ir.ui.menu,name:account_asset.menu_action_account_asset_asset_tree
msgid "Asset Hierarchy"
msgstr ""

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
from . import account_account
from . import account_asset
from . import account_asset_profile
from . import account_asset_line
from . import account_asset_recompute_trigger
from . import account_invoice
from . import account_move
from . import date_range
from . import res_config_settings

View File

@@ -0,0 +1,25 @@
# Copyright 2009-2017 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class AccountAccount(models.Model):
_inherit = 'account.account'
asset_profile_id = fields.Many2one(
comodel_name='account.asset.profile',
string='Asset Profile',
help="Default Asset Profile when creating invoice lines "
"with this account.")
@api.multi
@api.constrains('asset_profile_id')
def _check_asset_profile(self):
for account in self:
if account.asset_profile_id and \
account.asset_profile_id.account_asset_id != account:
raise ValidationError(_(
"The Asset Account defined in the Asset Profile "
"must be equal to the account."))

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,274 @@
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import datetime
from odoo import api, fields, models, _
import odoo.addons.decimal_precision as dp
from odoo.exceptions import UserError
class AccountAssetLine(models.Model):
_name = 'account.asset.line'
_description = 'Asset depreciation table line'
_order = 'type, line_date'
name = fields.Char(string='Depreciation Name', size=64, readonly=True)
asset_id = fields.Many2one(
comodel_name='account.asset', string='Asset',
required=True, ondelete='cascade')
previous_id = fields.Many2one(
comodel_name='account.asset.line',
string='Previous Depreciation Line',
readonly=True)
parent_state = fields.Selection(
related='asset_id.state',
string='State of Asset',
readonly=True,
)
depreciation_base = fields.Float(
related='asset_id.depreciation_base',
string='Depreciation Base',
readonly=True,
)
amount = fields.Float(
string='Amount', digits=dp.get_precision('Account'),
required=True)
remaining_value = fields.Float(
compute='_compute_values',
digits=dp.get_precision('Account'),
string='Next Period Depreciation',
store=True)
depreciated_value = fields.Float(
compute='_compute_values',
digits=dp.get_precision('Account'),
string='Amount Already Depreciated',
store=True)
line_date = fields.Date(string='Date', required=True)
move_id = fields.Many2one(
comodel_name='account.move',
string='Depreciation Entry', readonly=True)
move_check = fields.Boolean(
compute='_compute_move_check',
string='Posted',
store=True)
type = fields.Selection(
selection=[
('create', 'Depreciation Base'),
('depreciate', 'Depreciation'),
('remove', 'Asset Removal')],
readonly=True, default='depreciate')
init_entry = fields.Boolean(
string='Initial Balance Entry',
help="Set this flag for entries of previous fiscal years "
"for which Odoo has not generated accounting entries.")
@api.depends('amount', 'previous_id', 'type')
@api.multi
def _compute_values(self):
dlines = self
if self.env.context.get('no_compute_asset_line_ids'):
# skip compute for lines in unlink
exclude_ids = self.env.context['no_compute_asset_line_ids']
dlines = self.filtered(lambda l: l.id not in exclude_ids)
dlines = dlines.filtered(lambda l: l.type == 'depreciate')
dlines = dlines.sorted(key=lambda l: l.line_date)
for i, dl in enumerate(dlines):
if i == 0:
depreciation_base = dl.depreciation_base
depreciated_value = dl.previous_id \
and (depreciation_base - dl.previous_id.remaining_value) \
or 0.0
remaining_value = \
depreciation_base - depreciated_value - dl.amount
else:
depreciated_value += dl.previous_id.amount
remaining_value -= dl.amount
dl.depreciated_value = depreciated_value
dl.remaining_value = remaining_value
@api.depends('move_id')
@api.multi
def _compute_move_check(self):
for line in self:
line.move_check = bool(line.move_id)
@api.onchange('amount')
def _onchange_amount(self):
if self.type == 'depreciate':
self.remaining_value = self.depreciation_base - \
self.depreciated_value - self.amount
@api.multi
def write(self, vals):
for dl in self:
if vals.get('line_date'):
if isinstance(vals['line_date'], datetime.date):
vals['line_date'] = fields.Date.to_string(
vals['line_date'])
line_date = vals.get('line_date') or dl.line_date
asset_lines = dl.asset_id.depreciation_line_ids
if list(vals.keys()) == ['move_id'] and not vals['move_id']:
# allow to remove an accounting entry via the
# 'Delete Move' button on the depreciation lines.
if not self.env.context.get('unlink_from_asset'):
raise UserError(_(
"You are not allowed to remove an accounting entry "
"linked to an asset."
"\nYou should remove such entries from the asset."))
elif list(vals.keys()) == ['asset_id']:
continue
elif dl.move_id and not self.env.context.get(
'allow_asset_line_update'):
raise UserError(_(
"You cannot change a depreciation line "
"with an associated accounting entry."))
elif vals.get('init_entry'):
check = asset_lines.filtered(
lambda l: l.move_check and l.type == 'depreciate' and
l.line_date <= line_date)
if check:
raise UserError(_(
"You cannot set the 'Initial Balance Entry' flag "
"on a depreciation line "
"with prior posted entries."))
elif vals.get('line_date'):
if dl.type == 'create':
check = asset_lines.filtered(
lambda l: l.type != 'create' and
(l.init_entry or l.move_check) and
l.line_date < vals['line_date'])
if check:
raise UserError(
_("You cannot set the Asset Start Date "
"after already posted entries."))
else:
check = asset_lines.filtered(
lambda l: (l.init_entry or l.move_check) and
l.line_date > vals['line_date'] and l != dl)
if check:
raise UserError(_(
"You cannot set the date on a depreciation line "
"prior to already posted entries."))
return super().write(vals)
@api.multi
def unlink(self):
for dl in self:
if dl.type == 'create' and dl.amount:
raise UserError(_(
"You cannot remove an asset line "
"of type 'Depreciation Base'."))
elif dl.move_id:
raise UserError(_(
"You cannot delete a depreciation line with "
"an associated accounting entry."))
previous = dl.previous_id
next_line = dl.asset_id.depreciation_line_ids.filtered(
lambda l: l.previous_id == dl and l not in self)
if next_line:
next_line.previous_id = previous
return super(AccountAssetLine, self.with_context(
no_compute_asset_line_ids=self.ids)).unlink()
def _setup_move_data(self, depreciation_date):
asset = self.asset_id
move_data = {
'name': asset.name,
'date': depreciation_date,
'ref': self.name,
'journal_id': asset.profile_id.journal_id.id,
}
return move_data
def _setup_move_line_data(self, depreciation_date, account, ml_type, move):
asset = self.asset_id
amount = self.amount
analytic_id = False
if ml_type == 'depreciation':
debit = amount < 0 and -amount or 0.0
credit = amount > 0 and amount or 0.0
elif ml_type == 'expense':
debit = amount > 0 and amount or 0.0
credit = amount < 0 and -amount or 0.0
analytic_id = asset.account_analytic_id.id
move_line_data = {
'name': asset.name,
'ref': self.name,
'move_id': move.id,
'account_id': account.id,
'credit': credit,
'debit': debit,
'journal_id': asset.profile_id.journal_id.id,
'partner_id': asset.partner_id.id,
'analytic_account_id': analytic_id,
'date': depreciation_date,
'asset_id': asset.id,
}
return move_line_data
@api.multi
def create_move(self):
created_move_ids = []
asset_ids = set()
ctx = dict(self.env.context,
allow_asset=True, check_move_validity=False)
for line in self:
asset = line.asset_id
depreciation_date = line.line_date
am_vals = line._setup_move_data(depreciation_date)
move = self.env['account.move'].with_context(ctx).create(am_vals)
depr_acc = asset.profile_id.account_depreciation_id
exp_acc = asset.profile_id.account_expense_depreciation_id
aml_d_vals = line._setup_move_line_data(
depreciation_date, depr_acc, 'depreciation', move)
self.env['account.move.line'].with_context(ctx).create(aml_d_vals)
aml_e_vals = line._setup_move_line_data(
depreciation_date, exp_acc, 'expense', move)
self.env['account.move.line'].with_context(ctx).create(aml_e_vals)
move.post()
line.with_context(allow_asset_line_update=True).write({
'move_id': move.id
})
created_move_ids.append(move.id)
asset_ids.add(asset.id)
# we re-evaluate the assets to determine if we can close them
for asset in self.env['account.asset'].browse(list(asset_ids)):
if asset.company_currency_id.is_zero(asset.value_residual):
asset.state = 'close'
return created_move_ids
@api.multi
def open_move(self):
self.ensure_one()
return {
'name': _("Journal Entry"),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.move',
'view_id': False,
'type': 'ir.actions.act_window',
'context': self.env.context,
'domain': [('id', '=', self.move_id.id)],
}
@api.multi
def unlink_move(self):
for line in self:
move = line.move_id
if move.state == 'posted':
move.button_cancel()
move.with_context(unlink_from_asset=True).unlink()
# trigger store function
line.with_context(unlink_from_asset=True).write(
{'move_id': False})
if line.parent_state == 'close':
line.asset_id.write({'state': 'open'})
elif line.parent_state == 'removed' and line.type == 'remove':
line.asset_id.write({
'state': 'close',
'date_remove': False,
})
line.unlink()
return True

View File

@@ -0,0 +1,180 @@
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class AccountAssetProfile(models.Model):
_name = 'account.asset.profile'
_description = 'Asset profile'
_order = 'name'
name = fields.Char(string='Name', size=64, required=True, index=True)
note = fields.Text()
account_analytic_id = fields.Many2one(
comodel_name='account.analytic.account',
string='Analytic account')
account_asset_id = fields.Many2one(
comodel_name='account.account',
domain=[('deprecated', '=', False)],
string='Asset Account', required=True)
account_depreciation_id = fields.Many2one(
comodel_name='account.account',
domain=[('deprecated', '=', False)],
string='Depreciation Account', required=True)
account_expense_depreciation_id = fields.Many2one(
comodel_name='account.account',
domain=[('deprecated', '=', False)],
string='Depr. Expense Account', required=True)
account_plus_value_id = fields.Many2one(
comodel_name='account.account',
domain=[('deprecated', '=', False)],
string='Plus-Value Account')
account_min_value_id = fields.Many2one(
comodel_name='account.account',
domain=[('deprecated', '=', False)],
string='Min-Value Account')
account_residual_value_id = fields.Many2one(
comodel_name='account.account',
domain=[('deprecated', '=', False)],
string='Residual Value Account')
journal_id = fields.Many2one(
comodel_name='account.journal',
domain=[('type', '=', 'general')],
string='Journal', required=True)
company_id = fields.Many2one(
comodel_name='res.company',
string='Company', required=True,
default=lambda self: self._default_company_id())
parent_id = fields.Many2one(
comodel_name='account.asset',
string='Parent Asset',
domain=[('type', '=', 'view')])
method = fields.Selection(
selection=lambda self: self._selection_method(),
string='Computation Method',
required=True,
help="Choose the method to use to compute the depreciation lines.\n"
" * Linear: Calculated on basis of: "
"Depreciation Base / Number of Depreciations. "
"Depreciation Base = Purchase Value - Salvage Value.\n"
" * Linear-Limit: Linear up to Salvage Value. "
"Depreciation Base = Purchase Value.\n"
" * Degressive: Calculated on basis of: "
"Residual Value * Degressive Factor.\n"
" * Degressive-Linear (only for Time Method = Year): "
"Degressive becomes linear when the annual linear "
"depreciation exceeds the annual degressive depreciation.\n"
" * Degressive-Limit: Degressive up to Salvage Value. "
"The Depreciation Base is equal to the asset value.",
default='linear')
method_number = fields.Integer(
string='Number of Years',
help="The number of years needed to depreciate your asset",
default=5)
method_period = fields.Selection(
selection=lambda self: self._selection_method_period(),
string='Period Length', required=True,
default='year',
help="Period length for the depreciation accounting entries")
method_progress_factor = fields.Float(
string='Degressive Factor', default=0.3)
method_time = fields.Selection(
selection=lambda self: self._selection_method_time(),
string='Time Method', required=True,
default='year',
help="Choose the method to use to compute the dates and "
"number of depreciation lines.\n"
" * Number of Years: Specify the number of years "
"for the depreciation.\n")
prorata = fields.Boolean(
string='Prorata Temporis',
help="Indicates that the first depreciation entry for this asset "
"has to be done from the depreciation start date instead of "
"the first day of the fiscal year.")
open_asset = fields.Boolean(
string='Skip Draft State',
help="Check this if you want to automatically confirm the assets "
"of this profile when created by invoices.")
asset_product_item = fields.Boolean(
string='Create an asset by product item',
help="By default during the validation of an invoice, an asset "
"is created by invoice line as long as an accounting entry is "
"created by invoice line. "
"With this setting, an accounting entry will be created by "
"product item. So, there will be an asset by product item.")
active = fields.Boolean(default=True)
@api.model
def _default_company_id(self):
return self.env['res.company']._company_default_get('account.asset')
@api.model
def _selection_method(self):
return[
('linear', _('Linear')),
('linear-limit', _('Linear up to Salvage Value')),
('degressive', _('Degressive')),
('degr-linear', _('Degressive-Linear')),
('degr-limit', _('Degressive up to Salvage Value')),
]
@api.model
def _selection_method_period(self):
return [
('month', _('Month')),
('quarter', _('Quarter')),
('year', _('Year')),
]
@api.model
def _selection_method_time(self):
"""
Install the 'account_asset_management_method_number_end' to enable the
'Number' and 'End' Time Methods.
"""
return [
('year', _('Number of Years')),
]
@api.multi
@api.constrains('method')
def _check_method(self):
for profile in self:
if profile.method == 'degr-linear' and \
profile.method_time != 'year':
raise UserError(
_("Degressive-Linear is only supported for Time Method = "
"Year."))
@api.onchange('method_time')
def _onchange_method_time(self):
if self.method_time != 'year':
self.prorata = True
@api.model
def create(self, vals):
if vals.get('method_time') != 'year' and not vals.get('prorata'):
vals['prorata'] = True
profile = super().create(vals)
acc_id = vals.get('account_asset_id')
if acc_id:
account = self.env['account.account'].browse(acc_id)
if not account.asset_profile_id:
account.write({'asset_profile_id': profile.id})
return profile
@api.multi
def write(self, vals):
if vals.get('method_time'):
if vals['method_time'] != 'year' and not vals.get('prorata'):
vals['prorata'] = True
res = super().write(vals)
# TODO last profile in self is defined as default on the related
# account. must be improved.
account = self.env['account.account'].browse(
vals.get('account_asset_id'))
if self and account and not account.asset_profile_id:
account.write({'asset_profile_id': self[-1].id})
return res

View File

@@ -0,0 +1,25 @@
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class AccountAssetRecomputeTrigger(models.Model):
_name = 'account.asset.recompute.trigger'
_description = "Asset table recompute triggers"
reason = fields.Char(
string='Reason', required=True)
company_id = fields.Many2one(
'res.company', string='Company', required=True)
date_trigger = fields.Datetime(
'Trigger Date',
readonly=True,
help="Date of the event triggering the need to "
"recompute the Asset Tables.")
date_completed = fields.Datetime(
'Completion Date', readonly=True)
state = fields.Selection(
selection=[('open', 'Open'), ('done', 'Done')],
string='State', default='open',
readonly=True)

View File

@@ -0,0 +1,144 @@
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import copy
from odoo import api, fields, models
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
@api.multi
def finalize_invoice_move_lines(self, move_lines):
move_lines = super().finalize_invoice_move_lines(move_lines)
new_lines = []
for line_tuple in move_lines:
line = line_tuple[2]
dp = self.env['decimal.precision']
if line.get('asset_profile_id') and \
line.get('quantity', 0.0) > 1.0:
profile = self.env['account.asset.profile'].browse(
[line.get('asset_profile_id')])
if profile.asset_product_item:
origin_line = copy.deepcopy(line)
line_qty = line.get('quantity')
line['quantity'] = round(line['quantity'] / line_qty,
dp.precision_get('Account'))
line['debit'] = round(line['debit'] / line_qty,
dp.precision_get('Account'))
line['credit'] = round(line['credit'] / line_qty,
dp.precision_get('Account'))
for analytic_line_tuple in line['analytic_line_ids']:
analytic_line = analytic_line_tuple[2]
analytic_line['amount'] = round(
analytic_line['amount'] / line_qty,
dp.precision_get('Account'))
analytic_line['unit_amount'] = round(
analytic_line['unit_amount'] / line_qty, 2)
line_to_create = line_qty
while line_to_create > 1:
line_to_create -= 1
new_line = copy.deepcopy(line_tuple)
new_lines.append(new_line)
# Compute rounding difference and apply it on the first
# line
line['quantity'] += round(
origin_line['quantity'] - line['quantity'] * line_qty,
2)
line['debit'] += round(
origin_line['debit'] - line['debit'] * line_qty,
dp.precision_get('Account'))
line['credit'] += round(
origin_line['credit'] - line['credit'] * line_qty,
dp.precision_get('Account'))
i = 0
for analytic_line_tuple in line['analytic_line_ids']:
analytic_line = analytic_line_tuple[2]
origin_analytic_line = \
origin_line['analytic_line_ids'][i][2]
analytic_line['amount'] += round(
origin_analytic_line['amount'] - analytic_line[
'amount'] * line_qty,
dp.precision_get('Account'))
analytic_line['unit_amount'] += round(
origin_analytic_line['unit_amount'] -
analytic_line[
'unit_amount'] * line_qty,
dp.precision_get('Account'))
i += 1
move_lines.extend(new_lines)
return move_lines
@api.multi
def action_move_create(self):
res = super().action_move_create()
for inv in self:
assets = inv.move_id.line_ids.mapped('asset_id')
for asset in assets:
asset.code = inv.move_name
asset_line_name = asset._get_depreciation_entry_name(0)
asset.depreciation_line_ids[0].with_context(
{'allow_asset_line_update': True}
).name = asset_line_name
return res
@api.multi
def action_cancel(self):
assets = self.env['account.asset']
for inv in self:
move = inv.move_id
assets |= move.line_ids.mapped('asset_id')
super().action_cancel()
if assets:
assets.unlink()
return True
@api.model
def line_get_convert(self, line, part):
res = super().line_get_convert(line, part)
if line.get('asset_profile_id'):
# skip empty debit/credit
if res.get('debit') or res.get('credit'):
res['asset_profile_id'] = line['asset_profile_id']
return res
@api.model
def inv_line_characteristic_hashcode(self, invoice_line):
res = super().inv_line_characteristic_hashcode(
invoice_line)
res += '-%s' % invoice_line.get('asset_profile_id', 'False')
return res
@api.model
def invoice_line_move_line_get(self):
res = super().invoice_line_move_line_get()
invoice_line_obj = self.env['account.invoice.line']
for vals in res:
if vals.get('invl_id'):
invline = invoice_line_obj.browse(vals['invl_id'])
if invline.asset_profile_id:
vals['asset_profile_id'] = invline.asset_profile_id.id
return res
class AccountInvoiceLine(models.Model):
_inherit = 'account.invoice.line'
asset_profile_id = fields.Many2one(
comodel_name='account.asset.profile',
string='Asset Profile')
asset_id = fields.Many2one(
comodel_name='account.asset',
string='Asset',
domain=[('type', '=', 'normal'),
('state', 'in', ['open', 'close'])],
help="Complete this field when selling an asset "
"in order to facilitate the creation of the "
"asset removal accounting entries via the "
"asset 'Removal' button")
@api.onchange('account_id')
def _onchange_account_id(self):
self.asset_profile_id = self.account_id.asset_profile_id.id
return super()._onchange_account_id()

View File

@@ -0,0 +1,165 @@
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from odoo import api, fields, models, _
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
# List of move's fields that can't be modified if move is linked
# with a depreciation line
FIELDS_AFFECTS_ASSET_MOVE = set(['journal_id', 'date'])
# List of move line's fields that can't be modified if move is linked
# with a depreciation line
FIELDS_AFFECTS_ASSET_MOVE_LINE = \
set(['credit', 'debit', 'account_id', 'journal_id', 'date',
'asset_profile_id', 'asset_id'])
class AccountMove(models.Model):
_inherit = 'account.move'
@api.multi
def unlink(self):
# for move in self:
deprs = self.env['account.asset.line'].search(
[('move_id', 'in', self.ids),
('type', 'in', ['depreciate', 'remove'])])
if deprs and not self.env.context.get('unlink_from_asset'):
raise UserError(
_("You are not allowed to remove an accounting entry "
"linked to an asset."
"\nYou should remove such entries from the asset."))
# trigger store function
deprs.write({'move_id': False})
return super().unlink()
@api.multi
def write(self, vals):
if set(vals).intersection(FIELDS_AFFECTS_ASSET_MOVE):
deprs = self.env['account.asset.line'].search(
[('move_id', 'in', self.ids), ('type', '=', 'depreciate')])
if deprs:
raise UserError(
_("You cannot change an accounting entry "
"linked to an asset depreciation line."))
return super().write(vals)
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
asset_profile_id = fields.Many2one(
comodel_name='account.asset.profile',
string='Asset Profile')
asset_id = fields.Many2one(
comodel_name='account.asset',
string='Asset', ondelete='restrict')
@api.onchange('account_id')
def _onchange_account_id(self):
self.asset_profile_id = self.account_id.asset_profile_id
@api.model
def create(self, vals):
if vals.get('asset_id') and not self.env.context.get('allow_asset'):
raise UserError(
_("You are not allowed to link "
"an accounting entry to an asset."
"\nYou should generate such entries from the asset."))
if vals.get('asset_profile_id'):
# create asset
asset_obj = self.env['account.asset']
move = self.env['account.move'].browse(vals['move_id'])
depreciation_base = vals['debit'] or -vals['credit']
temp_vals = {
'name': vals['name'],
'profile_id': vals['asset_profile_id'],
'purchase_value': depreciation_base,
'partner_id': vals['partner_id'],
'date_start': move.date,
}
if self.env.context.get('company_id'):
temp_vals['company_id'] = self.env.context['company_id']
temp_asset = asset_obj.new(temp_vals)
temp_asset._onchange_profile_id()
asset_vals = temp_asset._convert_to_write(temp_asset._cache)
self._get_asset_analytic_values(vals, asset_vals)
asset = asset_obj.with_context(
create_asset_from_move_line=True,
move_id=vals['move_id']).create(asset_vals)
vals['asset_id'] = asset.id
return super().create(vals)
@api.multi
def _prepare_asset_create(self, vals):
self.ensure_one()
debit = 'debit' in vals and vals.get('debit', 0.0) or self.debit
credit = 'credit' in vals and \
vals.get('credit', 0.0) or self.credit
depreciation_base = debit - credit
partner_id = 'partner' in vals and \
vals.get('partner', False) or self.partner_id.id
date_start = 'date' in vals and \
vals.get('date', False) or self.date
return {
'name': vals.get('name') or self.name,
'profile_id': vals['asset_profile_id'],
'purchase_value': depreciation_base,
'partner_id': partner_id,
'date_start': date_start,
'company_id': vals.get('company_id') or self.company_id.id,
}
@api.multi
def write(self, vals):
if (
self.mapped('asset_id') and
set(vals).intersection(FIELDS_AFFECTS_ASSET_MOVE_LINE) and
not (
self.env.context.get('allow_asset_removal') and
list(vals.keys()) == ['asset_id'])
):
raise UserError(
_("You cannot change an accounting item "
"linked to an asset depreciation line."))
if vals.get('asset_id'):
raise UserError(
_("You are not allowed to link "
"an accounting entry to an asset."
"\nYou should generate such entries from the asset."))
if vals.get('asset_profile_id'):
if len(self) == 1:
raise AssertionError(_(
'This option should only be used for a single id at a '
'time.'))
asset_obj = self.env['account.asset']
for aml in self:
if vals['asset_profile_id'] == aml.asset_profile_id.id:
continue
# create asset
asset_vals = aml._prepare_asset_create(vals)
self._play_onchange_profile_id(asset_vals)
self._get_asset_analytic_values(vals, asset_vals)
asset = asset_obj.with_context(
create_asset_from_move_line=True,
move_id=aml.move_id.id).create(asset_vals)
vals['asset_id'] = asset.id
return super().write(vals)
@api.model
def _get_asset_analytic_values(self, vals, asset_vals):
asset_vals['account_analytic_id'] = vals.get(
'analytic_account_id', False)
@api.model
def _play_onchange_profile_id(self, vals):
asset_obj = self.env['account.asset']
asset_temp = asset_obj.new(vals)
asset_temp._onchange_profile_id()
for field in asset_temp._fields:
if field not in vals and asset_temp[field]:
vals[field] = asset_temp._fields[field].\
convert_to_write(asset_temp[field], asset_temp)

View File

@@ -0,0 +1,50 @@
# Copyright 2009-2017 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import time
from odoo import api, models
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
class DateRange(models.Model):
_inherit = 'date.range'
@api.model
def create(self, vals):
# TODO:
# change logic to avoid table recompute overhead
# when a regular (duration = 1 year) new FY is created
fy_types = self.env['date.range.type'].search(
[('fiscal_year', '=', True)])
if vals.get('type_id') in fy_types._ids:
recompute_vals = {
'reason': 'creation of fiscalyear %s' % vals.get('code'),
'company_id':
vals.get('company_id') or
self.env.user.company_id.id,
'date_trigger': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'state': 'open',
}
self.env['account.asset.recompute.trigger'].sudo().create(
recompute_vals)
return super().create(vals)
@api.multi
def write(self, vals):
fy_types = self.env['date.range.type'].search(
[('fiscal_year', '=', True)])
if vals.get('type_id') in fy_types.ids:
if vals.get('date_start') or vals.get('date_end'):
for fy in self:
recompute_vals = {
'reason':
'duration change of fiscalyear %s' % fy.name,
'company_id': fy.company_id.id,
'date_trigger':
time.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'state': 'open',
}
self.env['account.asset.recompute.trigger'].sudo().\
create(recompute_vals)
return super().write(vals)

View File

@@ -0,0 +1,16 @@
# Copyright (c) 2014 ACSONE SA/NV (http://acsone.eu).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class Config(models.TransientModel):
_inherit = 'res.config.settings'
module_account_asset_management = fields.Boolean(
string='Assets management (OCA)',
help="""This allows you to manage the assets owned by a company
or a person. It keeps track of the depreciation occurred
on those assets, and creates account move for those
depreciation lines.
This installs the module account_asset_management.""")

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="account_asset_profile_multi_company_rule" model="ir.rule">
<field name="name">Account Asset Profile multi-company</field>
<field ref="model_account_asset_profile" name="model_id"/>
<field eval="True" name="global"/>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
</record>
<record id="account_asset_multi_company_rule" model="ir.rule">
<field name="name">Account Asset multi-company</field>
<field ref="model_account_asset" name="model_id"/>
<field eval="True" name="global"/>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,13 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_asset_profile_invoice,account.asset.profile,model_account_asset_profile,account.group_account_invoice,1,0,0,0
access_account_asset_profile_user,account.asset.profile,model_account_asset_profile,account.group_account_user,1,0,0,0
access_account_asset_profile_manager,account.asset.profile,model_account_asset_profile,account.group_account_manager,1,1,1,1
access_account_asset_invoice,account.asset,model_account_asset,account.group_account_invoice,1,1,1,1
access_account_asset_user,account.asset,model_account_asset,account.group_account_user,1,1,1,1
access_account_asset_manager,account.asset,model_account_asset,account.group_account_manager,1,1,1,1
access_account_asset_line_invoice,account.asset.line,model_account_asset_line,account.group_account_invoice,1,1,1,1
access_account_asset_line_user,account.asset.line,model_account_asset_line,account.group_account_user,1,1,1,1
access_account_asset_line_manager,account.asset.line,model_account_asset_line,account.group_account_manager,1,1,1,1
access_account_asset_recompute_trigger_user,account.asset.recompute.trigger,model_account_asset_recompute_trigger,account.group_account_user,1,1,1,1
access_account_asset_recompute_trigger_manager,account.asset.recompute.trigger,model_account_asset_recompute_trigger,account.group_account_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_asset_profile_invoice account.asset.profile model_account_asset_profile account.group_account_invoice 1 0 0 0
3 access_account_asset_profile_user account.asset.profile model_account_asset_profile account.group_account_user 1 0 0 0
4 access_account_asset_profile_manager account.asset.profile model_account_asset_profile account.group_account_manager 1 1 1 1
5 access_account_asset_invoice account.asset model_account_asset account.group_account_invoice 1 1 1 1
6 access_account_asset_user account.asset model_account_asset account.group_account_user 1 1 1 1
7 access_account_asset_manager account.asset model_account_asset account.group_account_manager 1 1 1 1
8 access_account_asset_line_invoice account.asset.line model_account_asset_line account.group_account_invoice 1 1 1 1
9 access_account_asset_line_user account.asset.line model_account_asset_line account.group_account_user 1 1 1 1
10 access_account_asset_line_manager account.asset.line model_account_asset_line account.group_account_manager 1 1 1 1
11 access_account_asset_recompute_trigger_user account.asset.recompute.trigger model_account_asset_recompute_trigger account.group_account_user 1 1 1 1
12 access_account_asset_recompute_trigger_manager account.asset.recompute.trigger model_account_asset_recompute_trigger account.group_account_manager 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1 @@
from . import test_account_asset_management

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="date_range_fy" model="date.range">
<field name="type_id" ref="account_fiscal_year.fiscalyear" />
<field name="name">FY_assets</field>
<field name="date_start" eval="time.strftime('%Y-01-01')"/>
<field name="date_end" eval="time.strftime('%Y-12-31')"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="date_range_fy_previous" model="date.range">
<field name="type_id" ref="account_fiscal_year.fiscalyear" />
<field name="name">FY_assets previous</field>
<field name="date_start" eval="(datetime.now() - relativedelta(years=1, month=1, day=1)).strftime('%Y-%m-%d')"/>
<field name="date_end" eval="(datetime.now() - relativedelta(years=1, month=12, day=31)).strftime('%Y-%m-%d')"/>
<field name="company_id" ref="base.main_company"/>
</record>
<!-- Type View Assets -->
<record id="account_asset_view_fa" model="account.asset">
<field name="type">view</field>
<field name="state">open</field>
<field name="name">Financial Assets</field>
<field name="purchase_value" eval="0.0"/>
</record>
<record id="account_asset_view_ict" model="account.asset">
<field name="type">view</field>
<field name="state">open</field>
<field name="name">ICT</field>
<field name="parent_id" ref="account_asset_view_fa"/>
<field name="purchase_value" eval="0.0"/>
</record>
<record id="account_asset_view_vehicle" model="account.asset">
<field name="type">view</field>
<field name="state">open</field>
<field name="name">Vehicles</field>
<field name="parent_id" ref="account_asset_view_fa"/>
<field name="purchase_value" eval="0.0"/>
</record>
<!-- Asset profiles -->
<record id="account_asset_profile_ict_3Y" model="account.asset.profile">
<field name="parent_id" ref="account_asset_view_ict"/>
<field name="account_expense_depreciation_id" ref="account.a_expense"/>
<field name="account_asset_id" ref="account.xfa"/>
<field name="account_depreciation_id" ref="account.xfa"/>
<field name="journal_id" ref="account.expenses_journal"/>
<field name="name">Hardware - 3 Years</field>
<field name="method_time">year</field>
<field name="method_number" eval="3"/>
<field name="method_period">year</field>
</record>
<record id="account_asset_profile_car_5Y" model="account.asset.profile">
<field name="parent_id" ref="account_asset_view_vehicle"/>
<field name="account_expense_depreciation_id" ref="account.a_expense"/>
<field name="account_asset_id" ref="account.xfa"/>
<field name="account_depreciation_id" ref="account.xfa"/>
<field name="journal_id" ref="account.expenses_journal"/>
<field name="name">Cars - 5 Years</field>
<field name="method_time">year</field>
<field name="method_number" eval="5"/>
<field name="method_period">year</field>
</record>
<!-- Assets -->
<record id="account_asset_asset_ict0" model="account.asset">
<field name="parent_id" ref="account_asset_view_ict"/>
<field name="state">draft</field>
<field name="method_time">year</field>
<field name="method_number" eval="3"/>
<field name="method_period">year</field>
<field name="date_start" eval="time.strftime('%Y-01-01')"/>
<field name="name">Laptop</field>
<field name="code">PI00101</field>
<field name="purchase_value" eval="1500.0"/>
<field name="profile_id" ref="account_asset_profile_ict_3Y"/>
</record>
<record id="account_asset_asset_vehicle0" model="account.asset">
<field name="parent_id" ref="account_asset_view_vehicle"/>
<field name="state">draft</field>
<field name="method_time">year</field>
<field name="method_number" eval="5"/>
<field name="method_period">year</field>
<field name="date_start" eval="time.strftime('%Y-01-01')"/>
<field name="name">CEO's Car</field>
<field name="purchase_value" eval="12000.0"/>
<field name="salvage_value" eval="2000.0"/>
<field name="profile_id" ref="account_asset_profile_car_5Y"/>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,469 @@
# Copyright (c) 2014 ACSONE SA/NV (acsone.eu).
# Copyright 2009-2018 Noviat
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import calendar
from datetime import date, datetime
import time
from odoo.tests.common import SavepointCase
from odoo import tools
from odoo.modules.module import get_resource_path
class TestAssetManagement(SavepointCase):
@classmethod
def _load(cls, module, *args):
tools.convert_file(cls.cr, module,
get_resource_path(module, *args),
{}, 'init', False, 'test',
cls.registry._assertion_report)
@classmethod
def setUpClass(cls):
super().setUpClass()
cls._load('account', 'test', 'account_minimal_test.xml')
cls._load('account_asset_management', 'tests',
'account_asset_test_data.xml')
# ENVIRONEMENTS
cls.asset_model = cls.env['account.asset']
cls.dl_model = cls.env['account.asset.line']
cls.remove_model = cls.env['account.asset.remove']
cls.account_invoice = cls.env['account.invoice']
cls.account_move_line = cls.env['account.move.line']
cls.account_account = cls.env['account.account']
cls.account_journal = cls.env['account.journal']
cls.account_invoice_line = cls.env['account.invoice.line']
# INSTANCES
# Instance: company
cls.company = cls.env.ref('base.main_company')
# Instance: account type (receivable)
cls.type_recv = cls.env.ref('account.data_account_type_receivable')
# Instance: account type (payable)
cls.type_payable = cls.env.ref('account.data_account_type_payable')
# Instance: account (receivable)
cls.account_recv = cls.account_account.create({
'name': 'test_account_receivable',
'code': '123',
'user_type_id': cls.type_recv.id,
'company_id': cls.company.id,
'reconcile': True})
# Instance: account (payable)
cls.account_payable = cls.account_account.create({
'name': 'test_account_payable',
'code': '321',
'user_type_id': cls.type_payable.id,
'company_id': cls.company.id,
'reconcile': True})
# Instance: partner
cls.partner = cls.env.ref('base.res_partner_2')
# Instance: journal
cls.journal = cls.account_journal.search(
[('type', '=', 'purchase')])[0]
# Instance: product
cls.product = cls.env.ref('product.product_product_4')
# Instance: invoice line
cls.invoice_line = cls.account_invoice_line.create({
'name': 'test',
'account_id': cls.account_payable.id,
'price_unit': 2000.00,
'quantity': 1,
'product_id': cls.product.id})
# Instance: invoice
cls.invoice = cls.account_invoice.create({
'partner_id': cls.partner.id,
'account_id': cls.account_recv.id,
'journal_id': cls.journal.id,
'invoice_line_ids': [(4, cls.invoice_line.id)]})
def test_01_nonprorata_basic(self):
"""Basic tests of depreciation board computations and postings."""
#
# first load demo assets and do some sanity checks
#
ict0 = self.browse_ref('account_asset_management.'
'account_asset_asset_ict0')
self.assertEqual(ict0.state, 'draft')
self.assertEqual(ict0.purchase_value, 1500)
self.assertEqual(ict0.salvage_value, 0)
self.assertEqual(ict0.depreciation_base, 1500)
self.assertEqual(len(ict0.depreciation_line_ids), 1)
vehicle0 = self.browse_ref('account_asset_management.'
'account_asset_asset_vehicle0')
self.assertEqual(vehicle0.state, 'draft')
self.assertEqual(vehicle0.purchase_value, 12000)
self.assertEqual(vehicle0.salvage_value, 2000)
self.assertEqual(vehicle0.depreciation_base, 10000)
self.assertEqual(len(vehicle0.depreciation_line_ids), 1)
#
# I compute the depreciation boards
#
ict0.compute_depreciation_board()
ict0.refresh()
self.assertEqual(len(ict0.depreciation_line_ids), 4)
self.assertEqual(ict0.depreciation_line_ids[1].amount, 500)
vehicle0.compute_depreciation_board()
vehicle0.refresh()
self.assertEqual(len(vehicle0.depreciation_line_ids), 6)
self.assertEqual(vehicle0.depreciation_line_ids[1].amount, 2000)
#
# I post the first depreciation line
#
ict0.validate()
ict0.depreciation_line_ids[1].create_move()
ict0.refresh()
self.assertEqual(ict0.state, 'open')
self.assertEqual(ict0.value_depreciated, 500)
self.assertEqual(ict0.value_residual, 1000)
vehicle0.validate()
vehicle0.depreciation_line_ids[1].create_move()
vehicle0.refresh()
self.assertEqual(vehicle0.state, 'open')
self.assertEqual(vehicle0.value_depreciated, 2000)
self.assertEqual(vehicle0.value_residual, 8000)
def test_02_prorata_basic(self):
"""Prorata temporis depreciation basic test."""
asset = self.asset_model.create({
'name': 'test asset',
'profile_id': self.ref('account_asset_management.'
'account_asset_profile_car_5Y'),
'purchase_value': 3333,
'salvage_value': 0,
'date_start': time.strftime('%Y-07-07'),
'method_time': 'year',
'method_number': 5,
'method_period': 'month',
'prorata': True,
})
asset.compute_depreciation_board()
asset.refresh()
if calendar.isleap(date.today().year):
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
46.44, places=2)
else:
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
47.33, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
55.55, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[3].amount,
55.55, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[4].amount,
55.55, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[5].amount,
55.55, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[6].amount,
55.55, places=2)
if calendar.isleap(date.today().year):
self.assertAlmostEqual(asset.depreciation_line_ids[-1].amount,
9.11, places=2)
else:
self.assertAlmostEqual(asset.depreciation_line_ids[-1].amount,
8.22, places=2)
def test_03_proprata_init_prev_year(self):
"""Prorata temporis depreciation with init value in prev year."""
# I create an asset in current year
asset = self.asset_model.create({
'name': 'test asset',
'profile_id': self.ref('account_asset_management.'
'account_asset_profile_car_5Y'),
'purchase_value': 3333,
'salvage_value': 0,
'date_start': '%d-07-07' % (datetime.now().year - 1,),
'method_time': 'year',
'method_number': 5,
'method_period': 'month',
'prorata': True,
})
# I create a initial depreciation line in previous year
self.dl_model.create({
'asset_id': asset.id,
'amount': 325.08,
'line_date': '%d-12-31' % (datetime.now().year - 1,),
'type': 'depreciate',
'init_entry': True,
})
self.assertEqual(len(asset.depreciation_line_ids), 2)
asset.compute_depreciation_board()
asset.refresh()
# I check the depreciated value is the initial value
self.assertAlmostEqual(asset.value_depreciated, 325.08,
places=2)
# I check computed values in the depreciation board
self.assertAlmostEqual(asset.depreciation_line_ids[3].amount, 55.55,
places=2)
if calendar.isleap(date.today().year - 1):
# for leap years the first year depreciation amount of 325.08
# is too high and hence a correction is applied to the next
# entry of the table
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
54.66, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[3].amount,
55.55, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[-1].amount,
9.11, places=2)
else:
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
55.55, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[-1].amount,
8.22, places=2)
def test_04_prorata_init_cur_year(self):
"""Prorata temporis depreciation with init value in curent year."""
asset = self.asset_model.create({
'name': 'test asset',
'profile_id': self.ref('account_asset_management.'
'account_asset_profile_car_5Y'),
'purchase_value': 3333,
'salvage_value': 0,
'date_start': time.strftime('%Y-07-07'),
'method_time': 'year',
'method_number': 5,
'method_period': 'month',
'prorata': True,
})
self.dl_model.create({
'asset_id': asset.id,
'amount': 279.44,
'line_date': time.strftime('%Y-11-30'),
'type': 'depreciate',
'init_entry': True,
})
self.assertEqual(len(asset.depreciation_line_ids), 2)
asset.compute_depreciation_board()
asset.refresh()
# I check the depreciated value is the initial value
self.assertAlmostEqual(asset.value_depreciated, 279.44,
places=2)
# I check computed values in the depreciation board
if calendar.isleap(date.today().year):
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
44.75, places=2)
else:
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
45.64, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[3].amount,
55.55, places=2)
if calendar.isleap(date.today().year):
self.assertAlmostEqual(asset.depreciation_line_ids[-1].amount,
9.11, places=2)
else:
self.assertAlmostEqual(asset.depreciation_line_ids[-1].amount,
8.22, places=2)
def test_05_degressive_linear(self):
"""Degressive-Linear with annual and quarterly depreciation."""
# annual depreciation
asset = self.asset_model.create({
'name': 'test asset',
'profile_id': self.ref('account_asset_management.'
'account_asset_profile_car_5Y'),
'purchase_value': 1000,
'salvage_value': 0,
'date_start': time.strftime('%Y-07-07'),
'method_time': 'year',
'method': 'degr-linear',
'method_progress_factor': 0.40,
'method_number': 5,
'method_period': 'year',
'prorata': False,
})
asset.compute_depreciation_board()
asset.refresh()
# check values in the depreciation board
self.assertEqual(len(asset.depreciation_line_ids), 5)
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
400.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
240.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[3].amount,
200.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[4].amount,
160.00, places=2)
# quarterly depreciation
asset = self.asset_model.create({
'name': 'test asset',
'profile_id': self.ref('account_asset_management.'
'account_asset_profile_car_5Y'),
'purchase_value': 1000,
'salvage_value': 0,
'date_start': time.strftime('%Y-07-07'),
'method_time': 'year',
'method': 'degr-linear',
'method_progress_factor': 0.40,
'method_number': 5,
'method_period': 'quarter',
'prorata': False,
})
asset.compute_depreciation_board()
asset.refresh()
# check values in the depreciation board
self.assertEqual(len(asset.depreciation_line_ids), 15)
# lines prior to asset start period are grouped in the first entry
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
300.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[3].amount,
60.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[7].amount,
50.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[13].amount,
40.00, places=2)
def test_06_degressive_limit(self):
"""Degressive with annual depreciation."""
asset = self.asset_model.create({
'name': 'test asset',
'profile_id': self.ref('account_asset_management.'
'account_asset_profile_car_5Y'),
'purchase_value': 1000,
'salvage_value': 100,
'date_start': time.strftime('%Y-07-07'),
'method_time': 'year',
'method': 'degr-limit',
'method_progress_factor': 0.40,
'method_number': 5,
'method_period': 'year',
'prorata': False,
})
asset.compute_depreciation_board()
asset.refresh()
# check values in the depreciation board
self.assertEqual(len(asset.depreciation_line_ids), 6)
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
400.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
240.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[3].amount,
144.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[4].amount,
86.40, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[5].amount,
29.60, places=2)
def test_07_linear_limit(self):
"""Degressive with annual depreciation."""
asset = self.asset_model.create({
'name': 'test asset',
'profile_id': self.ref('account_asset_management.'
'account_asset_profile_car_5Y'),
'purchase_value': 1000,
'salvage_value': 100,
'date_start': time.strftime('%Y-07-07'),
'method_time': 'year',
'method': 'linear-limit',
'method_number': 5,
'method_period': 'year',
'prorata': False,
})
asset.compute_depreciation_board()
asset.refresh()
# check values in the depreciation board
self.assertEqual(len(asset.depreciation_line_ids), 6)
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
200.00, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[-1].amount,
100.00, places=2)
def test_08_asset_removal(self):
"""Asset removal"""
asset = self.asset_model.create({
'name': 'test asset removal',
'profile_id': self.ref('account_asset_management.'
'account_asset_profile_car_5Y'),
'purchase_value': 5000,
'salvage_value': 0,
'date_start': time.strftime('%Y-01-01'),
'method_time': 'year',
'method_number': 5,
'method_period': 'quarter',
'prorata': False,
})
asset.compute_depreciation_board()
asset.validate()
wiz_ctx = {
'active_id': asset.id,
'early_removal': True,
}
wiz = self.remove_model.with_context(wiz_ctx).create({
'date_remove': time.strftime('%Y-01-31'),
'sale_value': 0.0,
'posting_regime': 'gain_loss_on_sale',
'account_plus_value_id': self.ref('account.a_sale'),
'account_min_value_id': self.ref('account.a_expense'),
})
wiz.remove()
asset.refresh()
self.assertEqual(len(asset.depreciation_line_ids), 3)
self.assertAlmostEqual(asset.depreciation_line_ids[1].amount,
81.46, places=2)
self.assertAlmostEqual(asset.depreciation_line_ids[2].amount,
4918.54, places=2)
def test_09_asset_from_invoice(self):
all_asset = self.env['account.asset'].search([])
invoice = self.invoice
asset_profile = self.env.ref(
'account_asset_management.account_asset_profile_car_5Y')
asset_profile.asset_product_item = False
self.assertTrue(len(invoice.invoice_line_ids) > 0)
line = invoice.invoice_line_ids[0]
self.assertTrue(line.price_unit > 0.0)
line.quantity = 2
line.asset_profile_id = asset_profile
invoice.action_invoice_open()
# I get all asset after invoice validation
current_asset = self.env['account.asset'].search([])
# I get the new asset
new_asset = current_asset - all_asset
# I check that a new asset is created
self.assertEqual(len(new_asset), 1)
# I check that the new asset has the correct purchase value
self.assertAlmostEqual(new_asset.purchase_value,
-line.price_unit * line.quantity,
places=2)
def test_10_asset_from_invoice_product_item(self):
all_asset = self.env['account.asset'].search([])
invoice = self.invoice
asset_profile = self.env.ref(
'account_asset_management.account_asset_profile_car_5Y')
asset_profile.asset_product_item = True
self.assertTrue(len(invoice.invoice_line_ids) > 0)
line = invoice.invoice_line_ids[0]
self.assertTrue(line.price_unit > 0.0)
line.quantity = 2
line.asset_profile_id = asset_profile
invoice.action_invoice_open()
# I get all asset after invoice validation
current_asset = self.env['account.asset'].search([])
# I get the new asset
new_asset = current_asset - all_asset
# I check that a new asset is created
self.assertEqual(len(new_asset), line.quantity)
for asset in new_asset:
# I check that the new asset has the correct purchase value
self.assertAlmostEqual(
asset.purchase_value, -line.price_unit, places=2)

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_form" model="ir.ui.view">
<field name="name">account.account.form</field>
<field name="model">account.account</field>
<field name="inherit_id" ref="account.view_account_form"/>
<field name="arch" type="xml">
<field name="user_type_id" position="before">
<field name="asset_profile_id"/>
</field>
</field>
</record>
</odoo>

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