diff --git a/.isort.cfg b/.isort.cfg index 303829993..6d359cb17 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -9,4 +9,4 @@ line_length=88 known_odoo=odoo known_odoo_addons=odoo.addons sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER -known_third_party=dateutil,openupgradelib,psycopg2,setuptools +known_third_party=dateutil,setuptools diff --git a/account_asset_management/README.rst b/account_asset_management/README.rst index 47dd21eb6..ec9a823b1 100644 --- a/account_asset_management/README.rst +++ b/account_asset_management/README.rst @@ -14,13 +14,13 @@ Assets Management :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/12.0/account_asset_management + :target: https://github.com/OCA/account-financial-tools/tree/13.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-12-0/account-financial-tools-12-0-account_asset_management + :target: https://translation.odoo-community.org/projects/account-financial-tools-13-0/account-financial-tools-13-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/12.0 + :target: https://runbot.odoo-community.org/runbot/92/13.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -44,12 +44,6 @@ the standard account_asset module from Odoo. .. contents:: :local: -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 ===== @@ -58,6 +52,23 @@ The module in NOT compatible with the standard account_asset module. Changelog ========= +13.0.1.0.0 (2019-10-21) +~~~~~~~~~~~~~~~~~~~~~~~ + +* Python code and views were adapted to be compatible with v13. +* When assets are created through accounting journal items, + they are created when the journal items is posted. +* When a Bill Invoice is created or modified, at the time it is saved, + for each line that has an Asset profile and Quantity 'N' + greater than 1, it will be replaced by 'N' lines identical to it but + with quantity 1. This was done to maintain the same behavior as in + the previous version, in which for each asset created there is a + Journal Item. In addition, this solution does not change the data + model which does not cause migration scripts. +* The configuration option was removed so the only function of that is to + allow the module to be uninstalled by unchecking that configuration option. +* Tests were adapted. + 12.0.2.1.0 (2019-10-21) ~~~~~~~~~~~~~~~~~~~~~~~ @@ -75,7 +86,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -90,17 +101,21 @@ Authors Contributors ~~~~~~~~~~~~ -- OpenERP SA -- Luc De Meyer (Noviat) -- Frédéric Clementi (camptocamp) -- Florian Dacosta (Akretion) -- Stéphane Bidoul (Acsone) -- Adrien Peiffer (Acsone) -- Akim Juillerat -- Henrik Norlin (Apps2GROW) -- Maxence Groine -- Kitti Upariphutthiphong -- Saran Lim. +* OpenERP SA +* Luc De Meyer (Noviat) +* Frédéric Clementi (camptocamp) +* Florian Dacosta (Akretion) +* Stéphane Bidoul (Acsone) +* Adrien Peiffer (Acsone) +* Akim Juillerat +* Henrik Norlin (Apps2GROW) +* Maxence Groine +* Kitti Upariphutthiphong +* Saran Lim. +* `Tecnativa `_: + + * Ernesto Tejeda + * Pedro M. Baeza Maintainers ~~~~~~~~~~~ @@ -115,6 +130,6 @@ 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. -This module is part of the `OCA/account-financial-tools `_ project on GitHub. +This module is part of the `OCA/account-financial-tools `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_asset_management/__manifest__.py b/account_asset_management/__manifest__.py index ace4d3099..32da6ad2c 100644 --- a/account_asset_management/__manifest__.py +++ b/account_asset_management/__manifest__.py @@ -4,11 +4,12 @@ { "name": "Assets Management", - "version": "12.0.2.1.3", + "version": "13.0.1.0.0", "license": "AGPL-3", "depends": ["account"], "excludes": ["account_asset"], - "author": "Noviat,Odoo Community Association (OCA)", + "external_dependencies": {"python": ["python-dateutil"]}, + "author": "Noviat, Odoo Community Association (OCA)", "website": "https://github.com/OCA/account-financial-tools", "category": "Accounting & Finance", "data": [ @@ -20,9 +21,6 @@ "views/account_asset.xml", "views/account_asset_group.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", diff --git a/account_asset_management/migrations/12.0.1.0.0/openupgrade_analysis.txt b/account_asset_management/migrations/12.0.1.0.0/openupgrade_analysis.txt deleted file mode 100644 index d667a9f14..000000000 --- a/account_asset_management/migrations/12.0.1.0.0/openupgrade_analysis.txt +++ /dev/null @@ -1,157 +0,0 @@ -Done after the analysis: -NEW model account.asset.group -NEW field account.asset group_id -NEW field account.asset.profile group_id -account.asset date_start required -account.asset profile_id required - ----Fields in module 'account_asset_management'--- -account_asset / account.asset.asset / category_id (many2one) : DEL relation: account.asset.category, required -account_asset / account.asset.asset / currency_id (many2one) : DEL relation: res.currency, required, req_default: function -account_asset / account.asset.asset / date (date) : DEL required, req_default: function -account_asset / account.asset.asset / depreciation_line_ids (one2many): relation is now 'account.asset.line' ('account.asset.depreciation.line') [nothing to do] -account_asset / account.asset.asset / invoice_id (many2one) : DEL relation: account.invoice -account_asset / account.asset.asset / message_follower_ids (one2many): DEL relation: mail.followers -account_asset / account.asset.asset / message_ids (one2many) : DEL relation: mail.message -account_asset / account.asset.asset / message_last_post (datetime) : DEL -account_asset / account.asset.asset / method (selection) : selection_keys is now 'function' ('['degressive', 'linear']') -account_asset / account.asset.asset / method_period (integer) : selection_keys is now 'function' ('False') -account_asset / account.asset.asset / method_period (integer) : type is now 'selection' ('integer') -account_asset / account.asset.asset / method_time (selection) : selection_keys is now 'function' ('['end', 'number']') -account_asset / account.asset.asset / state (selection) : selection_keys is now '['close', 'draft', 'open', 'removed']' ('['close', 'draft', 'open']') -account_asset / account.asset.asset / type (selection) : DEL required -account_asset / account.asset.asset / value (float) : DEL required -account_asset / account.asset.asset / value_residual (float) : is now stored -account_asset / account.asset.asset / website_message_ids (one2many): DEL relation: mail.message -account_asset / account.asset.category / account_depreciation_expense_id (many2one): DEL relation: account.account, required -account_asset / account.asset.category / group_entries (boolean) : DEL -account_asset / account.asset.category / method (selection) : selection_keys is now 'function' ('['degressive', 'linear']') -account_asset / account.asset.category / method_end (date) : DEL -account_asset / account.asset.category / method_period (integer) : selection_keys is now 'function' ('False') -account_asset / account.asset.category / method_period (integer) : type is now 'selection' ('integer') -account_asset / account.asset.category / method_time (selection) : selection_keys is now 'function' ('['end', 'number']') -account_asset / account.asset.category / type (selection) : DEL required, selection_keys: ['purchase', 'sale'], req_default: function -account_asset / account.asset.depreciation.line / asset_id (many2one) : relation is now 'account.asset' ('account.asset.asset') [nothing to do] -account_asset / account.asset.depreciation.line / depreciated_value (float) : now a function -account_asset / account.asset.depreciation.line / depreciation_date (date) : DEL -account_asset / account.asset.depreciation.line / move_posted_check (boolean) : DEL -account_asset / account.asset.depreciation.line / remaining_value (float) : now a function -account_asset / account.asset.depreciation.line / sequence (integer) : DEL required -account_asset / account.invoice.line / asset_category_id (many2one) : DEL relation: account.asset.category -account_asset / account.invoice.line / asset_end_date (date) : DEL -account_asset / account.invoice.line / asset_mrr (float) : DEL -account_asset / account.invoice.line / asset_start_date (date) : DEL -account_asset / account.move / asset_depreciation_ids (one2many): DEL relation: account.asset.depreciation.line -account_asset / product.template / asset_category_id (many2one) : DEL relation: account.asset.category -account_asset / product.template / deferred_revenue_category_id (many2one): DEL relation: account.asset.category -account_asset_management / account.account / asset_profile_id (many2one) : NEW relation: account.asset.profile -account_asset_management / account.asset / account_analytic_id (many2one): NEW relation: account.analytic.account -account_asset_management / account.asset / account_move_line_ids (one2many): NEW relation: account.move.line -account_asset_management / account.asset / company_currency_id (many2one): NEW relation: res.currency, isrelated: related, stored -account_asset_management / account.asset / date_remove (date) : NEW -account_asset_management / account.asset / date_start (date) : NEW -account_asset_management / account.asset / depreciation_base (float) : NEW isfunction: function, stored -account_asset_management / account.asset / profile_id (many2one) : NEW relation: account.asset.profile -account_asset_management / account.asset / purchase_value (float) : NEW required -account_asset_management / account.asset / value_depreciated (float) : NEW isfunction: function, stored -account_asset_management / account.asset.line / init_entry (boolean) : NEW -account_asset_management / account.asset.line / line_date (date) : NEW required -account_asset_management / account.asset.line / previous_id (many2one) : NEW relation: account.asset.line -account_asset_management / account.asset.line / type (selection) : NEW selection_keys: ['create', 'depreciate', 'remove'], hasdefault -account_asset_management / account.asset.profile / account_expense_depreciation_id (many2one): NEW relation: account.account, required -account_asset_management / account.asset.profile / account_min_value_id (many2one): NEW relation: account.account -account_asset_management / account.asset.profile / account_plus_value_id (many2one): NEW relation: account.account -account_asset_management / account.asset.profile / account_residual_value_id (many2one): NEW relation: account.account -account_asset_management / account.asset.profile / asset_product_item (boolean) : NEW -account_asset_management / account.asset.profile / note (text) : NEW -account_asset_management / account.asset.recompute.trigger / company_id (many2one) : NEW relation: res.company, required -account_asset_management / account.asset.recompute.trigger / date_completed (datetime) : NEW -account_asset_management / account.asset.recompute.trigger / date_trigger (datetime) : NEW -account_asset_management / account.asset.recompute.trigger / reason (char) : NEW required -account_asset_management / account.asset.recompute.trigger / state (selection) : NEW selection_keys: ['done', 'open'], hasdefault -account_asset_management / account.invoice.line / asset_id (many2one) : NEW relation: account.asset -account_asset_management / account.invoice.line / asset_profile_id (many2one) : NEW relation: account.asset.profile -account_asset_management / account.move.line / asset_id (many2one) : NEW relation: account.asset -account_asset_management / account.move.line / asset_profile_id (many2one) : NEW relation: account.asset.profile ----XML records in module 'account_asset_management'--- -NEW ir.actions.act_window: account_asset_management.account_asset_action -NEW ir.actions.act_window: account_asset_management.account_asset_compute_action -NEW ir.actions.act_window: account_asset_management.account_asset_profile_action -NEW ir.actions.act_window: account_asset_management.act_entries_open -DEL ir.actions.act_window: account_asset.action_account_asset_asset_form -DEL ir.actions.act_window: account_asset.action_account_asset_asset_list_normal_purchase -DEL ir.actions.act_window: account_asset.action_asset_asset_report -DEL ir.actions.act_window: account_asset.action_asset_depreciation_confirmation_wizard -DEL ir.actions.act_window: account_asset.action_asset_modify -DEL ir.cron: account_asset.account_asset_cron -NEW ir.model.access: account_asset_management.access_account_asset_invoice -NEW ir.model.access: account_asset_management.access_account_asset_line_invoice -NEW ir.model.access: account_asset_management.access_account_asset_line_manager -NEW ir.model.access: account_asset_management.access_account_asset_line_user -NEW ir.model.access: account_asset_management.access_account_asset_manager -NEW ir.model.access: account_asset_management.access_account_asset_profile_invoice -NEW ir.model.access: account_asset_management.access_account_asset_profile_manager -NEW ir.model.access: account_asset_management.access_account_asset_profile_user -NEW ir.model.access: account_asset_management.access_account_asset_recompute_trigger_manager -NEW ir.model.access: account_asset_management.access_account_asset_recompute_trigger_user -NEW ir.model.access: account_asset_management.access_account_asset_user -DEL ir.model.access: account_asset.access_account_asset_asset -DEL ir.model.access: account_asset.access_account_asset_asset_invoicing_payment -DEL ir.model.access: account_asset.access_account_asset_asset_manager -DEL ir.model.access: account_asset.access_account_asset_category -DEL ir.model.access: account_asset.access_account_asset_category_invoicing_payment -DEL ir.model.access: account_asset.access_account_asset_category_manager -DEL ir.model.access: account_asset.access_account_asset_depreciation_line -DEL ir.model.access: account_asset.access_account_asset_depreciation_line_invoicing_payment -DEL ir.model.access: account_asset.access_account_asset_depreciation_line_manager -DEL ir.model.access: account_asset.access_asset_asset_report -DEL ir.model.access: account_asset.access_asset_asset_report_manager -NEW ir.rule: account_asset_management.account_asset_multi_company_rule (noupdate) -NEW ir.rule: account_asset_management.account_asset_profile_multi_company_rule (noupdate) -DEL ir.rule: account_asset.account_asset_asset_multi_company_rule (noupdate) -DEL ir.rule: account_asset.account_asset_category_multi_company_rule (noupdate) -NEW ir.ui.menu: account_asset_management.account_asset_compute_menu -NEW ir.ui.menu: account_asset_management.account_asset_menu -NEW ir.ui.menu: account_asset_management.account_asset_profile_menu -NEW ir.ui.menu: account_asset_management.menu_finance_assets -NEW ir.ui.menu: account_asset_management.menu_finance_config_assets -DEL ir.ui.menu: account_asset.menu_action_account_asset_asset_form -DEL ir.ui.menu: account_asset.menu_action_account_asset_asset_list_normal_purchase -DEL ir.ui.menu: account_asset.menu_action_asset_asset_report -DEL ir.ui.menu: account_asset.menu_asset_depreciation_confirmation_wizard -DEL ir.ui.menu: account_asset.menu_finance_config_assets -NEW ir.ui.view: account_asset_management.account_asset_compute_view_form -NEW ir.ui.view: account_asset_management.account_asset_compute_view_form_result -NEW ir.ui.view: account_asset_management.account_asset_profile_view_form -NEW ir.ui.view: account_asset_management.account_asset_profile_view_search -NEW ir.ui.view: account_asset_management.account_asset_profile_view_tree -NEW ir.ui.view: account_asset_management.account_asset_remove_view_form -NEW ir.ui.view: account_asset_management.account_asset_view_form -NEW ir.ui.view: account_asset_management.account_asset_view_search -NEW ir.ui.view: account_asset_management.account_asset_view_tree -NEW ir.ui.view: account_asset_management.invoice_form -NEW ir.ui.view: account_asset_management.invoice_supplier_form -NEW ir.ui.view: account_asset_management.res_config_settings_view_form -NEW ir.ui.view: account_asset_management.view_account_form -NEW ir.ui.view: account_asset_management.view_account_move_line_filter -NEW ir.ui.view: account_asset_management.view_invoice_line_form -NEW ir.ui.view: account_asset_management.view_move_form -NEW ir.ui.view: account_asset_management.view_move_line_form -DEL ir.ui.view: account_asset.action_account_asset_report_graph -DEL ir.ui.view: account_asset.action_account_asset_report_pivot -DEL ir.ui.view: account_asset.asset_modify_form -DEL ir.ui.view: account_asset.assets_backend -DEL ir.ui.view: account_asset.qunit_suite -DEL ir.ui.view: account_asset.res_config_settings_view_form -DEL ir.ui.view: account_asset.view_account_asset_asset_category_kanban -DEL ir.ui.view: account_asset.view_account_asset_asset_form -DEL ir.ui.view: account_asset.view_account_asset_asset_kanban -DEL ir.ui.view: account_asset.view_account_asset_asset_purchase_tree -DEL ir.ui.view: account_asset.view_account_asset_category_form -DEL ir.ui.view: account_asset.view_account_asset_category_search -DEL ir.ui.view: account_asset.view_account_asset_category_tree -DEL ir.ui.view: account_asset.view_account_asset_search -DEL ir.ui.view: account_asset.view_asset_asset_report_search -DEL ir.ui.view: account_asset.view_asset_depreciation_confirmation_wizard -DEL ir.ui.view: account_asset.view_invoice_asset_category -DEL ir.ui.view: account_asset.view_product_template_form_inherit diff --git a/account_asset_management/migrations/12.0.1.0.0/openupgrade_analysis_work.txt b/account_asset_management/migrations/12.0.1.0.0/openupgrade_analysis_work.txt deleted file mode 100644 index 1f6b39c46..000000000 --- a/account_asset_management/migrations/12.0.1.0.0/openupgrade_analysis_work.txt +++ /dev/null @@ -1,201 +0,0 @@ -Done after the analysis: -NEW model account.asset.group -NEW field account.asset group_id -NEW field account.asset.profile group_id -account.asset date_start required -account.asset profile_id required -# TODO: account.asset of type 'view' (archived): set date_start & profile_id - ----Fields in module 'account_asset_management'--- -account_asset / account.asset.asset / category_id (many2one) : DEL relation: account.asset.category, required -# renamed to profile_id -account_asset / account.asset.asset / currency_id (many2one) : DEL relation: res.currency, required, req_default: function -# renamed to company_currency_id -account_asset / account.asset.asset / date (date) : DEL required, req_default: function -# renamed to date_start -account_asset / account.asset.asset / depreciation_line_ids (one2many): relation is now 'account.asset.line' ('account.asset.depreciation.line') [nothing to do] -account_asset / account.asset.asset / invoice_id (many2one) : DEL relation: account.invoice -# DEL -account_asset / account.asset.asset / message_follower_ids (one2many): DEL relation: mail.followers -# DEL -account_asset / account.asset.asset / message_ids (one2many) : DEL relation: mail.message -# DEL -account_asset / account.asset.asset / message_last_post (datetime) : DEL -# DEL -account_asset / account.asset.asset / method (selection) : selection_keys is now 'function' ('['degressive', 'linear']') -# TODO: LOG WARNING IF METHOD IS NOT linear OR degressive -account_asset / account.asset.asset / method_period (integer) : selection_keys is now 'function' ('False') -account_asset / account.asset.asset / method_period (integer) : type is now 'selection' ('integer') -# renamed method_number to method_number_11 (11.0: Number of depreciations, 12.0: Number of years) -# renamed method_period to method_period_11 (11.0: Number of months in a period, 12.0: Period Length: year/quarter/month) -# TODO: LOG WARNING IF method_period_11 is other than (1, 3, 12) -account_asset / account.asset.asset / method_time (selection) : selection_keys is now 'function' ('['end', 'number']') -account_asset / account.asset.asset / state (selection) : selection_keys is now '['close', 'draft', 'open', 'removed']' ('['close', 'draft', 'open']') -account_asset / account.asset.asset / type (selection) : DEL required -# DEL -account_asset / account.asset.asset / value (float) : DEL required -# renamed to purchase_value -account_asset / account.asset.asset / value_residual (float) : is now stored -account_asset / account.asset.asset / website_message_ids (one2many): DEL relation: mail.message -# DEL -account_asset / account.asset.category / account_depreciation_expense_id (many2one): DEL relation: account.account, required -# renamed to account_expense_depreciation_id -account_asset / account.asset.category / group_entries (boolean) : DEL -# DEL -account_asset / account.asset.category / method (selection) : selection_keys is now 'function' ('['degressive', 'linear']') -# TODO: LOG WARNING IF METHOD IS NOT linear OR degressive -account_asset / account.asset.category / method_end (date) : DEL -# DEL -account_asset / account.asset.category / method_period (integer) : selection_keys is now 'function' ('False') -account_asset / account.asset.category / method_period (integer) : type is now 'selection' ('integer') -# renamed method_number to method_number_11 (11.0: Number of depreciations, 12.0: Number of years) -# renamed method_period to method_period_11 (11.0: Number of months in a period, 12.0: Period Length: year/quarter/month) -# TODO: LOG WARNING IF method_period_11 is other than (1, 3, 12) -account_asset / account.asset.category / method_time (selection) : selection_keys is now 'function' ('['end', 'number']') -account_asset / account.asset.category / type (selection) : DEL required, selection_keys: ['purchase', 'sale'], req_default: function -# DEL -account_asset / account.asset.depreciation.line / asset_id (many2one) : relation is now 'account.asset' ('account.asset.asset') [nothing to do] -account_asset / account.asset.depreciation.line / depreciated_value (float) : now a function -account_asset / account.asset.depreciation.line / depreciation_date (date) : DEL -# renamed to line_date -account_asset / account.asset.depreciation.line / move_posted_check (boolean) : DEL -# DEL -account_asset / account.asset.depreciation.line / remaining_value (float) : now a function -account_asset / account.asset.depreciation.line / sequence (integer) : DEL required -# DEL -account_asset / account.invoice.line / asset_category_id (many2one) : DEL relation: account.asset.category -# renamed to asset_profile_id -account_asset / account.invoice.line / asset_end_date (date) : DEL -# DEL -account_asset / account.invoice.line / asset_mrr (float) : DEL -# DEL -account_asset / account.invoice.line / asset_start_date (date) : DEL -# DEL -account_asset / account.move / asset_depreciation_ids (one2many): DEL relation: account.asset.depreciation.line -# DEL -account_asset / product.template / asset_category_id (many2one) : DEL relation: account.asset.category -# DEL -account_asset / product.template / deferred_revenue_category_id (many2one): DEL relation: account.asset.category -# DEL -account_asset_management / account.account / asset_profile_id (many2one) : NEW relation: account.asset.profile -account_asset_management / account.asset / account_analytic_id (many2one): NEW relation: account.analytic.account -# get from profile_id.account_analytic_id -account_asset_management / account.asset / account_move_line_ids (one2many): NEW relation: account.move.line -account_asset_management / account.asset / child_ids (one2many) : NEW relation: account.asset -account_asset_management / account.asset / company_currency_id (many2one): NEW relation: res.currency, isrelated: related, stored -# renamed from currency_id -account_asset_management / account.asset / date_remove (date) : NEW -account_asset_management / account.asset / date_start (date) : NEW -# renamed from date -account_asset_management / account.asset / depreciation_base (float) : NEW isfunction: function, stored -account_asset_management / account.asset / profile_id (many2one) : NEW relation: account.asset.profile -# renamed from category_id -account_asset_management / account.asset / purchase_value (float) : NEW required -# renamed from value -account_asset_management / account.asset / value_depreciated (float) : NEW isfunction: function, stored -account_asset_management / account.asset.line / init_entry (boolean) : NEW -account_asset_management / account.asset.line / line_date (date) : NEW required -# renamed from depreciation_date -account_asset_management / account.asset.line / previous_id (many2one) : NEW relation: account.asset.line -account_asset_management / account.asset.line / type (selection) : NEW selection_keys: ['create', 'depreciate', 'remove'], hasdefault -account_asset_management / account.asset.profile / account_expense_depreciation_id (many2one): NEW relation: account.account, required -# renamed from account_depreciation_expense_id -account_asset_management / account.asset.profile / account_min_value_id (many2one): NEW relation: account.account -account_asset_management / account.asset.profile / account_plus_value_id (many2one): NEW relation: account.account -account_asset_management / account.asset.profile / account_residual_value_id (many2one): NEW relation: account.account -account_asset_management / account.asset.profile / asset_product_item (boolean) : NEW -account_asset_management / account.asset.profile / note (text) : NEW -account_asset_management / account.asset.recompute.trigger / company_id (many2one) : NEW relation: res.company, required -account_asset_management / account.asset.recompute.trigger / date_completed (datetime) : NEW -account_asset_management / account.asset.recompute.trigger / date_trigger (datetime) : NEW -account_asset_management / account.asset.recompute.trigger / reason (char) : NEW required -account_asset_management / account.asset.recompute.trigger / state (selection) : NEW selection_keys: ['done', 'open'], hasdefault -account_asset_management / account.invoice.line / asset_id (many2one) : NEW relation: account.asset -account_asset_management / account.invoice.line / asset_profile_id (many2one) : NEW relation: account.asset.profile -# renamed from asset_category_id -account_asset_management / account.move.line / asset_id (many2one) : NEW relation: account.asset -# get from account.asset.line (asset_id, move_id) -account_asset_management / account.move.line / asset_profile_id (many2one) : NEW relation: account.asset.profile -# get from account.asset.line (asset_id, move_id, profile_id) ----XML records in module 'account_asset_management'--- -NEW ir.actions.act_window: account_asset_management.account_asset_action -NEW ir.actions.act_window: account_asset_management.account_asset_compute_action -NEW ir.actions.act_window: account_asset_management.account_asset_profile_action -NEW ir.actions.act_window: account_asset_management.act_entries_open -DEL ir.actions.act_window: account_asset.action_account_asset_asset_form -DEL ir.actions.act_window: account_asset.action_account_asset_asset_list_normal_purchase -DEL ir.actions.act_window: account_asset.action_asset_asset_report -DEL ir.actions.act_window: account_asset.action_asset_depreciation_confirmation_wizard -DEL ir.actions.act_window: account_asset.action_asset_modify -DEL ir.cron: account_asset.account_asset_cron -NEW ir.model.access: account_asset_management.access_account_asset_invoice -NEW ir.model.access: account_asset_management.access_account_asset_line_invoice -NEW ir.model.access: account_asset_management.access_account_asset_line_manager -NEW ir.model.access: account_asset_management.access_account_asset_line_user -NEW ir.model.access: account_asset_management.access_account_asset_manager -NEW ir.model.access: account_asset_management.access_account_asset_profile_invoice -NEW ir.model.access: account_asset_management.access_account_asset_profile_manager -NEW ir.model.access: account_asset_management.access_account_asset_profile_user -NEW ir.model.access: account_asset_management.access_account_asset_recompute_trigger_manager -NEW ir.model.access: account_asset_management.access_account_asset_recompute_trigger_user -NEW ir.model.access: account_asset_management.access_account_asset_user -DEL ir.model.access: account_asset.access_account_asset_asset -DEL ir.model.access: account_asset.access_account_asset_asset_invoicing_payment -DEL ir.model.access: account_asset.access_account_asset_asset_manager -DEL ir.model.access: account_asset.access_account_asset_category -DEL ir.model.access: account_asset.access_account_asset_category_invoicing_payment -DEL ir.model.access: account_asset.access_account_asset_category_manager -DEL ir.model.access: account_asset.access_account_asset_depreciation_line -DEL ir.model.access: account_asset.access_account_asset_depreciation_line_invoicing_payment -DEL ir.model.access: account_asset.access_account_asset_depreciation_line_manager -DEL ir.model.access: account_asset.access_asset_asset_report -DEL ir.model.access: account_asset.access_asset_asset_report_manager -NEW ir.rule: account_asset_management.account_asset_multi_company_rule (noupdate) -NEW ir.rule: account_asset_management.account_asset_profile_multi_company_rule (noupdate) -DEL ir.rule: account_asset.account_asset_asset_multi_company_rule (noupdate) -DEL ir.rule: account_asset.account_asset_category_multi_company_rule (noupdate) -NEW ir.ui.menu: account_asset_management.account_asset_compute_menu -NEW ir.ui.menu: account_asset_management.account_asset_menu -NEW ir.ui.menu: account_asset_management.account_asset_profile_menu -NEW ir.ui.menu: account_asset_management.menu_finance_assets -NEW ir.ui.menu: account_asset_management.menu_finance_config_assets -DEL ir.ui.menu: account_asset.menu_action_account_asset_asset_form -DEL ir.ui.menu: account_asset.menu_action_account_asset_asset_list_normal_purchase -DEL ir.ui.menu: account_asset.menu_action_asset_asset_report -DEL ir.ui.menu: account_asset.menu_asset_depreciation_confirmation_wizard -DEL ir.ui.menu: account_asset.menu_finance_config_assets -NEW ir.ui.view: account_asset_management.account_asset_compute_view_form -NEW ir.ui.view: account_asset_management.account_asset_compute_view_form_result -NEW ir.ui.view: account_asset_management.account_asset_profile_view_form -NEW ir.ui.view: account_asset_management.account_asset_profile_view_search -NEW ir.ui.view: account_asset_management.account_asset_profile_view_tree -NEW ir.ui.view: account_asset_management.account_asset_remove_view_form -NEW ir.ui.view: account_asset_management.account_asset_view_form -NEW ir.ui.view: account_asset_management.account_asset_view_search -NEW ir.ui.view: account_asset_management.account_asset_view_tree -NEW ir.ui.view: account_asset_management.invoice_form -NEW ir.ui.view: account_asset_management.invoice_supplier_form -NEW ir.ui.view: account_asset_management.res_config_settings_view_form -NEW ir.ui.view: account_asset_management.view_account_form -NEW ir.ui.view: account_asset_management.view_account_move_line_filter -NEW ir.ui.view: account_asset_management.view_invoice_line_form -NEW ir.ui.view: account_asset_management.view_move_form -NEW ir.ui.view: account_asset_management.view_move_line_form -DEL ir.ui.view: account_asset.action_account_asset_report_graph -DEL ir.ui.view: account_asset.action_account_asset_report_pivot -DEL ir.ui.view: account_asset.asset_modify_form -DEL ir.ui.view: account_asset.assets_backend -DEL ir.ui.view: account_asset.qunit_suite -DEL ir.ui.view: account_asset.res_config_settings_view_form -DEL ir.ui.view: account_asset.view_account_asset_asset_category_kanban -DEL ir.ui.view: account_asset.view_account_asset_asset_form -DEL ir.ui.view: account_asset.view_account_asset_asset_kanban -DEL ir.ui.view: account_asset.view_account_asset_asset_purchase_tree -DEL ir.ui.view: account_asset.view_account_asset_category_form -DEL ir.ui.view: account_asset.view_account_asset_category_search -DEL ir.ui.view: account_asset.view_account_asset_category_tree -DEL ir.ui.view: account_asset.view_account_asset_search -DEL ir.ui.view: account_asset.view_asset_asset_report_search -DEL ir.ui.view: account_asset.view_asset_depreciation_confirmation_wizard -DEL ir.ui.view: account_asset.view_invoice_asset_category -DEL ir.ui.view: account_asset.view_product_template_form_inherit diff --git a/account_asset_management/migrations/12.0.1.0.0/post-migration.py b/account_asset_management/migrations/12.0.1.0.0/post-migration.py deleted file mode 100644 index 07d2f0f1e..000000000 --- a/account_asset_management/migrations/12.0.1.0.0/post-migration.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright 2019 Apps2GROW - Henrik Norlin -# Copyright 2019 Tecnativa - Pedro M. Baeza -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openupgradelib import openupgrade -from psycopg2 import sql - -from odoo.tools import float_is_zero - - -def adjust_asset_values(env): - """Avoid method_time != 'year' when possible + adjust other values - in assets and asset profiles. - """ - # Copy analytic account value - openupgrade.logged_query( - env.cr, - """ - UPDATE account_asset aa - SET account_analytic_id = aap.account_analytic_id - FROm account_asset_profile aap - WHERE aa.profile_id = aap.id""", - ) - # Adjust method_time, method_number and method_period - number = sql.Identifier(openupgrade.get_legacy_name("method_number")) - period = sql.Identifier(openupgrade.get_legacy_name("method_period")) - for table in ["account_asset_profile", "account_asset"]: - table = sql.Identifier(table) - openupgrade.logged_query( - env.cr, - sql.SQL( - """ - UPDATE {table} - SET method_time = 'year', - method_number = ({number} * {period}) / 12 - WHERE MOD({number} * {period}, 12) = 0 - """ - ).format(number=number, period=period, table=table), - ) - openupgrade.logged_query( - env.cr, - sql.SQL( - """ - UPDATE {table} - SET method_period = (CASE - WHEN {period} = 1 THEN 'month' - WHEN {period} = 3 THEN 'quarter' - WHEN {period} = 12 THEN 'year' - END) - WHERE {period} IN (1, 3, 12) - """ - ).format(period=period, table=table), - ) - - -def adjust_aml_values(env): - openupgrade.logged_query( - env.cr, - """ - UPDATE account_move_line aml - SET asset_id = aa.id, - asset_profile_id = aa.profile_id - FROM account_asset aa, - account_asset_line aal - WHERE aal.move_id = aml.move_id - AND aa.id = aal.asset_id""", - ) - - -def handle_account_asset_disposal_migration(env): - """Take care of potentially installed `account_asset_disposal` module. - - In this phase we set the last asset line to the type remove on the - corresponding assets. - """ - column_name = openupgrade.get_legacy_name("disposal_move_id") - if not openupgrade.column_exists(env.cr, "account_asset", column_name): - return - env.cr.execute( - sql.SQL("SELECT id FROM account_asset WHERE {col} IS NOT NULL").format( - col=sql.Identifier(column_name) - ) - ) - assets = ( - env["account.asset"] - .with_context(allow_asset_line_update=True) - .browse(x[0] for x in env.cr.fetchall()) - ) - assets.mapped("depreciation_line_ids").filtered( - lambda x: float_is_zero( - x.remaining_value, - precision_rounding=x.asset_id.company_currency_id.rounding, - ) - ).write({"type": "remove"}) - - -@openupgrade.migrate() -def migrate(env, version): - copied_column = openupgrade.get_legacy_name("method_time") - if not openupgrade.column_exists(env.cr, "account_asset", copied_column): - # We avoid this migration if `account_asset` was not installed in v11 - return - adjust_asset_values(env) - adjust_aml_values(env) - handle_account_asset_disposal_migration(env) diff --git a/account_asset_management/migrations/12.0.1.0.0/pre-migration.py b/account_asset_management/migrations/12.0.1.0.0/pre-migration.py deleted file mode 100644 index e2255401a..000000000 --- a/account_asset_management/migrations/12.0.1.0.0/pre-migration.py +++ /dev/null @@ -1,109 +0,0 @@ -# Copyright 2019 Apps2GROW - Henrik Norlin -# Copyright 2019 Tecnativa - Pedro M. Baeza -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openupgradelib import openupgrade - -_model_renames = [ - ("account.asset.category", "account.asset.profile"), - ("account.asset.depreciation.line", "account.asset.line"), - ("account.asset.asset", "account.asset"), -] - -_table_renames = [ - (old.replace(".", "_"), new.replace(".", "_")) for (old, new) in _model_renames -] - -_column_copies = { - "account_asset": [("method_number", None, None), ("method_time", None, None)], - "account_asset_profile": [ - ("method_number", None, None), - ("method_time", None, None), - ], -} - -_column_renames = { - "account_asset": [("method_period", None)], - "account_asset_profile": [("method_period", None)], -} - -_field_renames = [ - ("account.asset", "account_asset", "category_id", "profile_id"), - ("account.asset", "account_asset", "currency_id", "company_currency_id"), - ("account.asset", "account_asset", "date", "date_start"), - ("account.asset", "account_asset", "value", "purchase_value"), - ("account.asset.line", "account_asset_line", "depreciation_date", "line_date"), - ( - "account.asset.profile", - "account_asset_profile", - "account_depreciation_expense_id", - "account_expense_depreciation_id", - ), - ( - "account.invoice.line", - "account_invoice_line", - "asset_category_id", - "asset_profile_id", - ), -] - - -def handle_account_asset_disposal_migration(env): - """Take care of potentially installed `account_asset_disposal` module. - - In this phase we rename stuff for adapting to the new data structure. - """ - cr = env.cr - if not openupgrade.column_exists(cr, "account_asset", "disposal_move_id"): - return - openupgrade.copy_columns(cr, {"account_asset": [("state", None, None)]}) - openupgrade.rename_columns(cr, {"account_asset": [("disposal_move_id", None)]}) - openupgrade.map_values( - cr, - openupgrade.get_legacy_name("state"), - "state", - [("disposed", "removed")], - table="account_asset", - ) - openupgrade.rename_fields( - env, - [ - ("account.asset", "account_asset", "disposal_date", "date_remove"), - ( - "account.asset.profile", - "account_asset_profile", - "account_loss_id", - "account_residual_value_id", - ), - ], - ) - - -@openupgrade.migrate() -def migrate(env, version): - cr = env.cr - if openupgrade.table_exists(cr, "account_asset_asset"): - # `account_asset` module was installed in v11 - if openupgrade.table_exists(cr, "account_asset"): - # `account_asset_management` module also installed in v11 - # TODO: Merge in existing tables assets if both module installed - pass - else: - openupgrade.rename_models(cr, _model_renames) - openupgrade.rename_tables(cr, _table_renames) - openupgrade.copy_columns(cr, _column_copies) - openupgrade.rename_columns(cr, _column_renames) - openupgrade.rename_fields(env, _field_renames) - handle_account_asset_disposal_migration(env) - if openupgrade.column_exists(cr, "account_asset", "analytic_account_id"): - # account_asset_analytic module in OCA/account_analytic - openupgrade.rename_fields( - env, - [ - ( - "account.asset", - "account_asset", - "analytic_account_id", - "account_analytic_id", - ) - ], - ) diff --git a/account_asset_management/migrations/12.0.2.0.0/post-migration.py b/account_asset_management/migrations/12.0.2.0.0/post-migration.py deleted file mode 100644 index bb759106c..000000000 --- a/account_asset_management/migrations/12.0.2.0.0/post-migration.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright 2019 Apps2GROW - Henrik Norlin -# Copyright 2019 Tecnativa - Pedro M. Baeza -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openupgradelib import openupgrade -from psycopg2 import sql - - -def create_asset_groups(cr): - # Add a supporting column for indicating the source asset view - origin_column = sql.Identifier(openupgrade.get_legacy_name("view_asset_id")) - openupgrade.logged_query( - cr, sql.SQL("ALTER TABLE account_asset_group ADD {} int4").format(origin_column) - ) - # Now fill new table recursively attending parents - parent_column = sql.Identifier(openupgrade.get_legacy_name("parent_id")) - parent_group_ids = ("NULL",) - query_sql = sql.SQL( - """ - INSERT INTO account_asset_group ( - name, code, company_id, parent_id, create_uid, - create_date, write_date, write_uid, {origin_column} - ) - SELECT va.name, va.code, va.company_id, aag2.id, va.create_uid, - va.create_date, va.write_date, va.write_uid, va.id - FROM {table} va - LEFT JOIN account_asset_group aag2 - ON aag2.{origin_column} = va.{parent_column} - WHERE {parent_column} {rest_sql} - RETURNING id - """ - ) - isnull = sql.SQL("IS NULL") - inids = sql.SQL("IN %(ids)s") - while parent_group_ids: - query = query_sql.format( - origin_column=origin_column, - table=sql.Identifier(openupgrade.get_legacy_name("account_asset_view")), - parent_column=parent_column, - rest_sql=isnull if parent_group_ids == ("NULL",) else inids, - ) - openupgrade.logged_query(cr, query, {"ids": parent_group_ids}) - parent_group_ids = tuple(x[0] for x in cr.fetchall()) - - -def update_asset_group_links(cr): - parent_column = sql.Identifier(openupgrade.get_legacy_name("parent_id")) - origin_column = sql.Identifier(openupgrade.get_legacy_name("view_asset_id")) - openupgrade.logged_query( - cr, - sql.SQL( - """ - INSERT INTO account_asset_profile_group_rel - (profile_id, group_id) - SELECT aap.id, aag.id - FROM account_asset_profile aap - JOIN account_asset_group aag - ON aag.{origin_column} = aap.{parent_column}""" - ).format(parent_column=parent_column, origin_column=origin_column), - ) - openupgrade.logged_query( - cr, - sql.SQL( - """ - INSERT INTO account_asset_group_rel - (asset_id, group_id) - SELECT aa.id, aag.id - FROM account_asset aa - JOIN account_asset_group aag - ON aag.{origin_column} = aa.{parent_column}""" - ).format(parent_column=parent_column, origin_column=origin_column), - ) - - -@openupgrade.migrate() -def migrate(env, version): - column = openupgrade.get_legacy_name("parent_id") - if openupgrade.column_exists(env.cr, "account_asset", column): - # if migrating directly from v11 `account_asset` module, there are no - # view assets nor parents - create_asset_groups(env.cr) - update_asset_group_links(env.cr) diff --git a/account_asset_management/migrations/12.0.2.0.0/pre-migration.py b/account_asset_management/migrations/12.0.2.0.0/pre-migration.py deleted file mode 100644 index a56908df7..000000000 --- a/account_asset_management/migrations/12.0.2.0.0/pre-migration.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2019 Tecnativa - Pedro M. Baeza -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openupgradelib import openupgrade -from psycopg2 import sql - -_column_renames = { - "account_asset_profile": [("parent_id", None)], - "account_asset": [("parent_id", None)], -} - - -def move_view_assets(cr): - """Copy view assets to other table for preserving them, but outside of the - main table, so remove them from there. - """ - temp_table = sql.Identifier(openupgrade.get_legacy_name("account_asset_view")) - openupgrade.logged_query( - cr, - sql.SQL( - """ - CREATE TABLE {} AS ( - SELECT * FROM account_asset - WHERE type='view' - )""" - ).format(temp_table), - ) - openupgrade.logged_query(cr, "DELETE FROM account_asset WHERE type='view'") - - -@openupgrade.migrate() -def migrate(env, version): - if openupgrade.column_exists(env.cr, "account_asset", "parent_id"): - # if migrating directly from v11 `account_asset` module, there are no - # view assets nor parents - openupgrade.rename_columns(env.cr, _column_renames) - openupgrade.logged_query( - env.cr, - """ - ALTER TABLE account_asset - DROP CONSTRAINT account_asset_parent_id_fkey""", - ) - openupgrade.logged_query( - env.cr, - """ - ALTER TABLE account_asset_profile - DROP CONSTRAINT account_asset_profile_parent_id_fkey""", - ) - move_view_assets(env.cr) diff --git a/account_asset_management/models/__init__.py b/account_asset_management/models/__init__.py index d7cde7086..b64596fd1 100644 --- a/account_asset_management/models/__init__.py +++ b/account_asset_management/models/__init__.py @@ -5,6 +5,4 @@ from . import account_asset_profile from . import account_asset_line from . import account_asset_recompute_trigger from . import account_fiscal_year -from . import account_invoice from . import account_move -from . import res_config_settings diff --git a/account_asset_management/models/account_account.py b/account_asset_management/models/account_account.py index 53610f6fb..6e1b0f360 100644 --- a/account_asset_management/models/account_account.py +++ b/account_asset_management/models/account_account.py @@ -14,7 +14,6 @@ class AccountAccount(models.Model): 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: diff --git a/account_asset_management/models/account_asset.py b/account_asset_management/models/account_asset.py index 5e2f7ea38..d61bac18a 100644 --- a/account_asset_management/models/account_asset.py +++ b/account_asset_management/models/account_asset.py @@ -15,8 +15,6 @@ from odoo import _, api, fields, models from odoo.exceptions import UserError from odoo.osv import expression -import odoo.addons.decimal_precision as dp - _logger = logging.getLogger(__name__) @@ -43,7 +41,6 @@ class AccountAsset(models.Model): ) name = fields.Char( string="Asset Name", - size=64, required=True, readonly=True, states={"draft": [("readonly", False)]}, @@ -65,7 +62,7 @@ class AccountAsset(models.Model): ) salvage_value = fields.Float( string="Salvage Value", - digits=dp.get_precision("Account"), + digits="Account", readonly=True, states={"draft": [("readonly", False)]}, help="The estimated value that an asset will realize upon " @@ -74,7 +71,7 @@ class AccountAsset(models.Model): ) depreciation_base = fields.Float( compute="_compute_depreciation_base", - digits=dp.get_precision("Account"), + digits="Account", string="Depreciation Base", store=True, help="This amount represent the depreciation base " @@ -82,13 +79,13 @@ class AccountAsset(models.Model): ) value_residual = fields.Float( compute="_compute_depreciation", - digits=dp.get_precision("Account"), + digits="Account", string="Residual Value", store=True, ) value_depreciated = fields.Float( compute="_compute_depreciation", - digits=dp.get_precision("Account"), + digits="Account", string="Depreciated Value", store=True, ) @@ -261,18 +258,18 @@ class AccountAsset(models.Model): @api.model def _default_company_id(self): - return self.env["res.company"]._company_default_get("account.asset") + return self.env.company - @api.multi def _compute_move_line_check(self): for asset in self: + move_line_check = False for line in asset.depreciation_line_ids: if line.move_id: - asset.move_line_check = True + move_line_check = True break + asset.move_line_check = move_line_check @api.depends("purchase_value", "salvage_value", "method") - @api.multi def _compute_depreciation_base(self): for asset in self: if asset.method in ["linear-limit", "degr-limit"]: @@ -280,7 +277,6 @@ class AccountAsset(models.Model): else: asset.depreciation_base = asset.purchase_value - asset.salvage_value - @api.multi @api.depends( "depreciation_base", "depreciation_line_ids.type", @@ -300,7 +296,6 @@ class AccountAsset(models.Model): depreciated = value_depreciated asset.update({"value_residual": residual, "value_depreciated": depreciated}) - @api.multi @api.constrains("method", "method_time") def _check_method(self): for asset in self: @@ -309,7 +304,6 @@ class AccountAsset(models.Model): _("Degressive-Linear is only supported for Time Method = " "Year.") ) - @api.multi @api.constrains("date_start", "method_end", "method_time") def _check_dates(self): for asset in self: @@ -386,7 +380,6 @@ class AccountAsset(models.Model): asset._create_first_asset_line() return asset - @api.multi def write(self, vals): if vals.get("method_time"): if vals["method_time"] != "year" and not vals.get("prorata"): @@ -421,7 +414,6 @@ class AccountAsset(models.Model): if self.env.context.get("create_asset_from_move_line"): asset_line.move_id = self.env.context["move_id"] - @api.multi def unlink(self): for asset in self: if asset.state != "draft": @@ -453,7 +445,6 @@ class AccountAsset(models.Model): assets = self.search(domain + args, limit=limit) return assets.name_get() - @api.multi @api.depends("name", "code") def name_get(self): result = [] @@ -464,7 +455,6 @@ class AccountAsset(models.Model): result.append((asset.id, name)) return result - @api.multi def validate(self): for asset in self: if asset.company_currency_id.is_zero(asset.value_residual): @@ -473,7 +463,6 @@ class AccountAsset(models.Model): asset.state = "open" return True - @api.multi def remove(self): self.ensure_one() ctx = dict(self.env.context, active_ids=self.ids, active_id=self.id) @@ -489,7 +478,6 @@ class AccountAsset(models.Model): return { "name": _("Generate Asset Removal entries"), - "view_type": "form", "view_mode": "form", "res_model": "account.asset.remove", "target": "new", @@ -497,11 +485,9 @@ class AccountAsset(models.Model): "context": ctx, } - @api.multi def set_to_draft(self): return self.write({"state": "draft"}) - @api.multi def open_entries(self): self.ensure_one() amls = self.env["account.move.line"].search( @@ -510,7 +496,6 @@ class AccountAsset(models.Model): am_ids = [l.move_id.id for l in amls] return { "name": _("Journal Entries"), - "view_type": "form", "view_mode": "tree,form", "res_model": "account.move", "view_id": False, @@ -519,12 +504,74 @@ class AccountAsset(models.Model): "domain": [("id", "in", am_ids)], } - @api.multi - def compute_depreciation_board(self): + def _group_lines(self, table): + """group lines prior to depreciation start period.""" + def group_lines(x, y): y.update({"amount": x["amount"] + y["amount"]}) return y + depreciation_start_date = self.date_start + lines = table[0]["lines"] + lines1 = [] + lines2 = [] + flag = lines[0]["date"] < depreciation_start_date + for line in lines: + if flag: + lines1.append(line) + if line["date"] >= depreciation_start_date: + flag = False + else: + lines2.append(line) + if lines1: + lines1 = [reduce(group_lines, lines1)] + lines1[0]["depreciated_value"] = 0.0 + table[0]["lines"] = lines1 + lines2 + + def _compute_depreciation_line( + self, + depreciated_value_posted, + table_i_start, + line_i_start, + table, + last_line, + posted_lines, + ): + digits = self.env["decimal.precision"].precision_get("Account") + + seq = len(posted_lines) + depr_line = last_line + last_date = table[-1]["lines"][-1]["date"] + depreciated_value = depreciated_value_posted + for entry in table[table_i_start:]: + for line in entry["lines"][line_i_start:]: + seq += 1 + name = self._get_depreciation_entry_name(seq) + amount = line["amount"] + if line["date"] == last_date: + # ensure that the last entry of the table always + # depreciates the remaining value + amount = self.depreciation_base - depreciated_value + if self.method in ["linear-limit", "degr-limit"]: + amount -= self.salvage_value + if amount: + vals = { + "previous_id": depr_line.id, + "amount": round(amount, digits), + "asset_id": self.id, + "name": name, + "line_date": line["date"], + "line_days": line["days"], + "init_entry": entry["init"], + } + depreciated_value += round(amount, digits) + depr_line = self.env["account.asset.line"].create(vals) + else: + seq -= 1 + line_i_start = 0 + + def compute_depreciation_board(self): + line_obj = self.env["account.asset.line"] digits = self.env["decimal.precision"].precision_get("Account") @@ -557,23 +604,7 @@ class AccountAsset(models.Model): if not table: continue - # group lines prior to depreciation start period - depreciation_start_date = asset.date_start - lines = table[0]["lines"] - lines1 = [] - lines2 = [] - flag = lines[0]["date"] < depreciation_start_date - for line in lines: - if flag: - lines1.append(line) - if line["date"] >= depreciation_start_date: - flag = False - else: - lines2.append(line) - if lines1: - lines1 = [reduce(group_lines, lines1)] - lines1[0]["depreciated_value"] = 0.0 - table[0]["lines"] = lines1 + lines2 + asset._group_lines(table) # check table with posted entries and # recompute in case of deviation @@ -589,7 +620,7 @@ class AccountAsset(models.Model): ) ) - for table_i, entry in enumerate(table): + for _table_i, entry in enumerate(table): residual_amount_table = entry["lines"][-1]["remaining_value"] if ( entry["date_start"] @@ -597,21 +628,22 @@ class AccountAsset(models.Model): <= entry["date_stop"] ): break + if entry["date_stop"] == last_depreciation_date: - table_i += 1 - line_i = 0 + _table_i += 1 + _line_i = 0 else: - entry = table[table_i] + entry = table[_table_i] date_min = entry["date_start"] - for line_i, line in enumerate(entry["lines"]): + for _line_i, line in enumerate(entry["lines"]): residual_amount_table = line["remaining_value"] if date_min <= last_depreciation_date <= line["date"]: break date_min = line["date"] if line["date"] == last_depreciation_date: - line_i += 1 - table_i_start = table_i - line_i_start = line_i + _line_i += 1 + table_i_start = _table_i + line_i_start = _line_i # check if residual value corresponds with table # and adjust table when needed @@ -630,40 +662,14 @@ class AccountAsset(models.Model): table_i_start = 0 line_i_start = 0 - seq = len(posted_lines) - depr_line = last_line - last_date = table[-1]["lines"][-1]["date"] - depreciated_value = depreciated_value_posted - for entry in table[table_i_start:]: - for line in entry["lines"][line_i_start:]: - seq += 1 - name = asset._get_depreciation_entry_name(seq) - if line["date"] == last_date: - # ensure that the last entry of the table always - # depreciates the remaining value - if asset.method in ["linear-limit", "degr-limit"]: - depr_max = asset.depreciation_base - asset.salvage_value - else: - depr_max = asset.depreciation_base - amount = depr_max - depreciated_value - else: - amount = line["amount"] - if amount: - vals = { - "previous_id": depr_line.id, - "amount": round(amount, digits), - "asset_id": asset.id, - "name": name, - "line_date": line["date"], - "line_days": line["days"], - "init_entry": entry["init"], - } - depreciated_value += round(amount, digits) - depr_line = line_obj.create(vals) - else: - seq -= 1 - line_i_start = 0 - + asset._compute_depreciation_line( + depreciated_value_posted, + table_i_start, + line_i_start, + table, + last_line, + posted_lines, + ) return True def _get_fy_duration(self, fy, option="days"): @@ -1031,7 +1037,7 @@ class AccountAsset(models.Model): entry["lines"] = lines line_dates = line_dates[li:] - for i, entry in enumerate(table): + for entry in table: if not entry["fy_amount"]: entry["fy_amount"] = sum([l["amount"] for l in entry["lines"]]) @@ -1097,7 +1103,6 @@ class AccountAsset(models.Model): """ use this method to customise the name of the accounting entry """ return (self.code or str(self.id)) + "/" + str(seq) - @api.multi def _compute_entries(self, date_end, check_triggers=False): # TODO : add ir_cron job calling this method to # generate periodical accounting entries @@ -1106,11 +1111,11 @@ class AccountAsset(models.Model): if check_triggers: recompute_obj = self.env["account.asset.recompute.trigger"] recomputes = recompute_obj.sudo().search([("state", "=", "open")]) - if check_triggers and recomputes: - trigger_companies = recomputes.mapped("company_id") - for asset in self: - if asset.company_id.id in trigger_companies.ids: - asset.compute_depreciation_board() + if recomputes: + trigger_companies = recomputes.mapped("company_id") + for asset in self: + if asset.company_id.id in trigger_companies.ids: + asset.compute_depreciation_board() depreciations = self.env["account.asset.line"].search( [ diff --git a/account_asset_management/models/account_asset_group.py b/account_asset_management/models/account_asset_group.py index d8319e039..c7d1598a2 100644 --- a/account_asset_management/models/account_asset_group.py +++ b/account_asset_management/models/account_asset_group.py @@ -28,4 +28,4 @@ class AccountAssetGroup(models.Model): @api.model def _default_company_id(self): - return self.env["res.company"]._company_default_get("account.asset") + return self.env.company diff --git a/account_asset_management/models/account_asset_line.py b/account_asset_management/models/account_asset_line.py index 1794fc16c..f7c296c0e 100644 --- a/account_asset_management/models/account_asset_line.py +++ b/account_asset_management/models/account_asset_line.py @@ -4,8 +4,6 @@ from odoo import _, api, fields, models from odoo.exceptions import UserError -import odoo.addons.decimal_precision as dp - class AccountAssetLine(models.Model): _name = "account.asset.line" @@ -27,18 +25,16 @@ class AccountAssetLine(models.Model): 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 - ) + amount = fields.Float(string="Amount", digits="Account", required=True) remaining_value = fields.Float( compute="_compute_values", - digits=dp.get_precision("Account"), + digits="Account", string="Next Period Depreciation", store=True, ) depreciated_value = fields.Float( compute="_compute_values", - digits=dp.get_precision("Account"), + digits="Account", string="Amount Already Depreciated", store=True, ) @@ -66,7 +62,6 @@ class AccountAssetLine(models.Model): ) @api.depends("amount", "previous_id", "type") - @api.multi def _compute_values(self): dlines = self if self.env.context.get("no_compute_asset_line_ids"): @@ -96,7 +91,6 @@ class AccountAssetLine(models.Model): 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) @@ -108,7 +102,6 @@ class AccountAssetLine(models.Model): self.depreciation_base - self.depreciated_value - self.amount ) - @api.multi def write(self, vals): for dl in self: line_date = vals.get("line_date") or dl.line_date @@ -163,9 +156,9 @@ class AccountAssetLine(models.Model): ) else: check = asset_lines.filtered( - lambda l: l != dl - and (l.init_entry or l.move_check) - and l.line_date > fields.Date.to_date(vals["line_date"]) + lambda al: al != dl + and (al.init_entry or al.move_check) + and al.line_date > fields.Date.to_date(vals["line_date"]) ) if check: raise UserError( @@ -176,7 +169,6 @@ class AccountAssetLine(models.Model): ) return super().write(vals) - @api.multi def unlink(self): for dl in self: if dl.type == "create" and dl.amount: @@ -203,9 +195,8 @@ class AccountAssetLine(models.Model): def _setup_move_data(self, depreciation_date): asset = self.asset_id move_data = { - "name": asset.name, "date": depreciation_date, - "ref": self.name, + "ref": "{} - {}".format(asset.name, self.name), "journal_id": asset.profile_id.journal_id.id, } return move_data @@ -236,7 +227,6 @@ class AccountAssetLine(models.Model): } return move_line_data - @api.multi def create_move(self): created_move_ids = [] asset_ids = set() @@ -266,12 +256,10 @@ class AccountAssetLine(models.Model): 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, @@ -280,13 +268,10 @@ class AccountAssetLine(models.Model): "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() + move.with_context(force_delete=True, unlink_from_asset=True).unlink() # trigger store function line.with_context(unlink_from_asset=True).write({"move_id": False}) if line.parent_state == "close": diff --git a/account_asset_management/models/account_asset_profile.py b/account_asset_management/models/account_asset_profile.py index a751ffcc9..a1b4c7f53 100644 --- a/account_asset_management/models/account_asset_profile.py +++ b/account_asset_management/models/account_asset_profile.py @@ -149,7 +149,7 @@ class AccountAssetProfile(models.Model): @api.model def _default_company_id(self): - return self.env["res.company"]._company_default_get("account.asset") + return self.env.company @api.model def _selection_method(self): @@ -173,7 +173,6 @@ class AccountAssetProfile(models.Model): """ return [("year", _("Number of Years or end date"))] - @api.multi @api.constrains("method") def _check_method(self): for profile in self: @@ -199,7 +198,6 @@ class AccountAssetProfile(models.Model): 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"): diff --git a/account_asset_management/models/account_asset_recompute_trigger.py b/account_asset_management/models/account_asset_recompute_trigger.py index 6403b276f..4d7c7789f 100644 --- a/account_asset_management/models/account_asset_recompute_trigger.py +++ b/account_asset_management/models/account_asset_recompute_trigger.py @@ -13,7 +13,7 @@ class AccountAssetRecomputeTrigger(models.Model): date_trigger = fields.Datetime( "Trigger Date", readonly=True, - help="Date of the event triggering the need to " "recompute the Asset Tables.", + help="Date of the event triggering the need to recompute the Asset Tables.", ) date_completed = fields.Datetime("Completion Date", readonly=True) state = fields.Selection( diff --git a/account_asset_management/models/account_fiscal_year.py b/account_asset_management/models/account_fiscal_year.py index 36ca404fc..21dade86a 100644 --- a/account_asset_management/models/account_fiscal_year.py +++ b/account_asset_management/models/account_fiscal_year.py @@ -30,7 +30,6 @@ class AccountFiscalYear(models.Model): self.env["account.asset.recompute.trigger"].sudo().create(recompute_vals) return super().create(vals) - @api.multi def write(self, vals): if vals.get("date_from") or vals.get("date_to"): for fy in self: diff --git a/account_asset_management/models/account_invoice.py b/account_asset_management/models/account_invoice.py deleted file mode 100644 index 2c1266ecd..000000000 --- a/account_asset_management/models/account_invoice.py +++ /dev/null @@ -1,150 +0,0 @@ -# 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=[("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() diff --git a/account_asset_management/models/account_move.py b/account_asset_management/models/account_move.py index e1c50d2bc..299172400 100644 --- a/account_asset_management/models/account_move.py +++ b/account_asset_management/models/account_move.py @@ -14,20 +14,19 @@ FIELDS_AFFECTS_ASSET_MOVE = {"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 = { - "credit", - "debit", - "account_id", - "journal_id", - "date", - "asset_profile_id", - "asset_id", + "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( @@ -45,7 +44,6 @@ class AccountMove(models.Model): 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( @@ -60,6 +58,45 @@ class AccountMove(models.Model): ) return super().write(vals) + def post(self): + for move in self: + for aml in move.line_ids.filtered("asset_profile_id"): + depreciation_base = aml.debit or -aml.credit + vals = { + "name": aml.name, + "code": move.name, + "profile_id": aml.asset_profile_id.id, + "purchase_value": depreciation_base, + "partner_id": aml.partner_id.id, + "date_start": move.date, + "account_analytic_id": aml.analytic_account_id.id, + } + if self.env.context.get("company_id"): + vals["company_id"] = self.env.context["company_id"] + asset = ( + self.env["account.asset"] + .with_context(create_asset_from_move_line=True, move_id=move.id) + .create(vals) + ) + aml.with_context(allow_asset=True).asset_id = asset.id + super().post() + + def button_draft(self): + invoices = self.filtered(lambda r: not r.is_sale_document()) + if invoices: + invoices.line_ids.asset_id.unlink() + super().button_draft() + + def _reverse_move_vals(self, default_values, cancel=True): + move_vals = super()._reverse_move_vals(default_values, cancel) + if move_vals["type"] not in ("out_invoice", "out_refund"): + for line_command in move_vals.get("line_ids", []): + line_vals = line_command[2] # (0, 0, {...}) + asset = self.env["account.asset"].browse(line_vals["asset_id"]) + asset.unlink() + line_vals.update(asset_profile_id=False, asset_id=False) + return move_vals + class AccountMoveLine(models.Model): _inherit = "account.move.line" @@ -74,61 +111,26 @@ class AccountMoveLine(models.Model): @api.onchange("account_id") def _onchange_account_id(self): self.asset_profile_id = self.account_id.asset_profile_id + super()._onchange_account_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.model_create_multi + def create(self, vals_list): + for vals in vals_list: + move = self.env["account.move"].browse(vals.get("move_id")) + if not move.is_sale_document(): + 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." + ) + ) + records = super().create(vals_list) + for record in records: + record._expand_asset_line() + return records - @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 set(vals).intersection(FIELDS_AFFECTS_ASSET_MOVE_LINE) and not ( self.env.context.get("allow_asset_removal") @@ -136,8 +138,8 @@ class AccountMoveLine(models.Model): ): # Check if at least one asset is linked to a move linked_asset = False - for move in self: - linked_asset = move.asset_id + for move_line in self.filtered(lambda r: not r.move_id.is_sale_document()): + linked_asset = move_line.asset_id if linked_asset: raise UserError( _( @@ -145,7 +147,12 @@ class AccountMoveLine(models.Model): "linked to an asset depreciation line." ) ) - if vals.get("asset_id"): + + if ( + self.filtered(lambda r: not r.move_id.is_sale_document()) + and vals.get("asset_id") + and not self.env.context.get("allow_asset") + ): raise UserError( _( "You are not allowed to link " @@ -153,36 +160,22 @@ class AccountMoveLine(models.Model): "\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) + super().write(vals) + if "quantity" in vals or "asset_profile_id" in vals: + for record in self: + record._expand_asset_line() + return True - @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 - ) + def _expand_asset_line(self): + self.ensure_one() + if self.asset_profile_id and self.quantity > 1.0: + profile = self.asset_profile_id + if profile.asset_product_item: + aml = self.with_context(check_move_validity=False) + qty = self.quantity + name = self.name + aml.write({"quantity": 1, "name": "{} {}".format(name, 1)}) + aml._onchange_price_subtotal() + for i in range(1, int(qty)): + aml.copy({"name": "{} {}".format(name, i + 1)}) + aml.move_id._onchange_invoice_line_ids() diff --git a/account_asset_management/models/res_config_settings.py b/account_asset_management/models/res_config_settings.py deleted file mode 100644 index 55b0942c9..000000000 --- a/account_asset_management/models/res_config_settings.py +++ /dev/null @@ -1,17 +0,0 @@ -# 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.""", - ) diff --git a/account_asset_management/readme/CONFIGURE.rst b/account_asset_management/readme/CONFIGURE.rst deleted file mode 100644 index 2bdc6c95d..000000000 --- a/account_asset_management/readme/CONFIGURE.rst +++ /dev/null @@ -1,2 +0,0 @@ -It is recommended to configure your Purchase Journal with "Group Invoice Lines" to avoid the -creation of separate assets per Supplier Invoice Line. diff --git a/account_asset_management/readme/CONTRIBUTORS.rst b/account_asset_management/readme/CONTRIBUTORS.rst index 6afc965f8..4504972bc 100644 --- a/account_asset_management/readme/CONTRIBUTORS.rst +++ b/account_asset_management/readme/CONTRIBUTORS.rst @@ -1,11 +1,15 @@ -- OpenERP SA -- Luc De Meyer (Noviat) -- Frédéric Clementi (camptocamp) -- Florian Dacosta (Akretion) -- Stéphane Bidoul (Acsone) -- Adrien Peiffer (Acsone) -- Akim Juillerat -- Henrik Norlin (Apps2GROW) -- Maxence Groine -- Kitti Upariphutthiphong -- Saran Lim. +* OpenERP SA +* Luc De Meyer (Noviat) +* Frédéric Clementi (camptocamp) +* Florian Dacosta (Akretion) +* Stéphane Bidoul (Acsone) +* Adrien Peiffer (Acsone) +* Akim Juillerat +* Henrik Norlin (Apps2GROW) +* Maxence Groine +* Kitti Upariphutthiphong +* Saran Lim. +* `Tecnativa `_: + + * Ernesto Tejeda + * Pedro M. Baeza diff --git a/account_asset_management/readme/HISTORY.rst b/account_asset_management/readme/HISTORY.rst index d68c9d780..85492f514 100644 --- a/account_asset_management/readme/HISTORY.rst +++ b/account_asset_management/readme/HISTORY.rst @@ -1,3 +1,20 @@ +13.0.1.0.0 (2019-10-21) +~~~~~~~~~~~~~~~~~~~~~~~ + +* Python code and views were adapted to be compatible with v13. +* When assets are created through accounting journal items, + they are created when the journal items is posted. +* When a Bill Invoice is created or modified, at the time it is saved, + for each line that has an Asset profile and Quantity 'N' + greater than 1, it will be replaced by 'N' lines identical to it but + with quantity 1. This was done to maintain the same behavior as in + the previous version, in which for each asset created there is a + Journal Item. In addition, this solution does not change the data + model which does not cause migration scripts. +* The configuration option was removed so the only function of that is to + allow the module to be uninstalled by unchecking that configuration option. +* Tests were adapted. + 12.0.2.1.0 (2019-10-21) ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/account_asset_management/static/description/index.html b/account_asset_management/static/description/index.html index 45a03a50e..8873df453 100644 --- a/account_asset_management/static/description/index.html +++ b/account_asset_management/static/description/index.html @@ -367,7 +367,7 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runbot

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.

@@ -380,27 +380,22 @@ the standard account_asset module from Odoo.

Table of contents

-
-

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

The module in NOT compatible with the standard account_asset module.

@@ -408,13 +403,31 @@ creation of separate assets per Supplier Invoice Line.

Changelog

-

12.0.2.1.0 (2019-10-21)

+

13.0.1.0.0 (2019-10-21)

+
    +
  • Python code and views were adapted to be compatible with v13.
  • +
  • When assets are created through accounting journal items, +they are created when the journal items is posted.
  • +
  • When a Bill Invoice is created or modified, at the time it is saved, +for each line that has an Asset profile and Quantity ‘N’ +greater than 1, it will be replaced by ‘N’ lines identical to it but +with quantity 1. This was done to maintain the same behavior as in +the previous version, in which for each asset created there is a +Journal Item. In addition, this solution does not change the data +model which does not cause migration scripts.
  • +
  • The configuration option was removed so the only function of that is to +allow the module to be uninstalled by unchecking that configuration option.
  • +
  • Tests were adapted.
  • +
+
+
+

12.0.2.1.0 (2019-10-21)

  • [IMP] Add option to calculate depreciation table by days
-
-

12.0.1.0.0 (2019-01-13)

+
+

12.0.1.0.0 (2019-01-13)

  • [BREAKING] account.asset: parent_path has replaced parent_left & parent_right (TODO: migration script)
  • [BREAKING] account.asset.recompute.trigger: depends on date_range.py (TODO: re-implement in account_fiscal_year.py)
  • @@ -422,23 +435,23 @@ creation of separate assets per Supplier Invoice Line.

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Noviat
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association

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.

-

This module is part of the OCA/account-financial-tools project on GitHub.

+

This module is part of the OCA/account-financial-tools project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/account_asset_management/tests/test_account_asset_management.py b/account_asset_management/tests/test_account_asset_management.py index f54587243..984d858fe 100644 --- a/account_asset_management/tests/test_account_asset_management.py +++ b/account_asset_management/tests/test_account_asset_management.py @@ -8,7 +8,7 @@ from datetime import date, datetime from odoo import tools from odoo.modules.module import get_resource_path -from odoo.tests.common import SavepointCase +from odoo.tests.common import Form, SavepointCase class TestAssetManagement(SavepointCase): @@ -36,45 +36,17 @@ class TestAssetManagement(SavepointCase): 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_invoice = cls.env["account.move"] 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"] + cls.account_invoice_line = cls.env["account.move.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") @@ -84,57 +56,38 @@ class TestAssetManagement(SavepointCase): # 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, - } + move_form = Form( + cls.env["account.move"].with_context( + default_type="in_invoice", check_move_validity=False + ) ) + move_form.partner_id = cls.partner + move_form.journal_id = cls.journal + with move_form.invoice_line_ids.new() as line_form: + line_form.name = "test" + line_form.product_id = cls.product + line_form.price_unit = 2000.00 + line_form.quantity = 1 + cls.invoice = move_form.save() - # 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)], - } - ) - - cls.invoice_line_2 = cls.account_invoice_line.create( - { - "name": "test 2", - "account_id": cls.account_payable.id, - "price_unit": 10000.00, - "quantity": 1, - "product_id": cls.product.id, - } - ) - cls.invoice_line_3 = cls.account_invoice_line.create( - { - "name": "test 3", - "account_id": cls.account_payable.id, - "price_unit": 20000.00, - "quantity": 1, - "product_id": cls.product.id, - } - ) - - cls.invoice_2 = 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_2.id), - (4, cls.invoice_line_3.id), - ], - } + move_form = Form( + cls.env["account.move"].with_context( + default_type="in_invoice", check_move_validity=False + ) ) + move_form.partner_id = cls.partner + move_form.journal_id = cls.journal + with move_form.invoice_line_ids.new() as line_form: + line_form.name = "test 2" + line_form.product_id = cls.product + line_form.price_unit = 10000.00 + line_form.quantity = 1 + with move_form.invoice_line_ids.new() as line_form: + line_form.name = "test 3" + line_form.product_id = cls.product + line_form.price_unit = 20000.00 + line_form.quantity = 1 + cls.invoice_2 = move_form.save() def test_01_nonprorata_basic(self): """Basic tests of depreciation board computations and postings.""" @@ -494,7 +447,7 @@ class TestAssetManagement(SavepointCase): self.assertTrue(line.price_unit > 0.0) line.quantity = 2 line.asset_profile_id = asset_profile - invoice.action_invoice_open() + invoice.post() # I get all asset after invoice validation current_asset = self.env["account.asset"].search([]) # I get the new asset @@ -503,7 +456,7 @@ class TestAssetManagement(SavepointCase): 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 + new_asset.purchase_value, line.price_unit * line.quantity, places=2 ) def test_10_asset_from_invoice_product_item(self): @@ -518,20 +471,23 @@ class TestAssetManagement(SavepointCase): self.assertTrue(line.price_unit > 0.0) line.quantity = 2 line.asset_profile_id = asset_profile - invoice.action_invoice_open() + self.assertEqual(len(invoice.invoice_line_ids), 2) + invoice.post() # 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) + self.assertEqual(len(new_asset), 2) 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) + self.assertAlmostEqual(asset.purchase_value, line.price_unit, places=2) def test_11_assets_from_invoice(self): all_assets = self.env["account.asset"].search([]) - invoice = self.invoice_2 + ctx = dict(self.invoice_2._context) + del ctx["default_type"] + invoice = self.invoice_2.with_context(ctx) asset_profile = self.env.ref( "account_asset_management.account_asset_profile_car_5Y" ) @@ -543,7 +499,7 @@ class TestAssetManagement(SavepointCase): invoice.invoice_line_ids.write( {"quantity": 1, "asset_profile_id": asset_profile.id} ) - invoice.action_invoice_open() + invoice.post() # Retrieve all assets after invoice validation current_assets = self.env["account.asset"].search([]) # What are the new assets? @@ -644,7 +600,7 @@ class TestAssetManagement(SavepointCase): ) asset.compute_depreciation_board() asset.refresh() - for i in range(1, 11): + for _i in range(1, 11): self.assertAlmostEqual( asset.depreciation_line_ids[1].amount, 166.67, places=2 ) diff --git a/account_asset_management/views/account_asset.xml b/account_asset_management/views/account_asset.xml index 182470eb2..fb1418490 100644 --- a/account_asset_management/views/account_asset.xml +++ b/account_asset_management/views/account_asset.xml @@ -82,7 +82,7 @@
@@ -209,15 +209,15 @@ Assets account.asset - form + name="Journal Items" + binding_model="account.asset" + binding_views="form" + res_model="account.move.line" + domain="['|',('asset_id','in',context.get('active_ids')),('asset_id','=','active_id')]"/> diff --git a/account_asset_management/views/account_asset_group.xml b/account_asset_management/views/account_asset_group.xml index 27cb1e29f..531609d8a 100644 --- a/account_asset_management/views/account_asset_group.xml +++ b/account_asset_management/views/account_asset_group.xml @@ -47,7 +47,6 @@ Asset Groups account.asset.group - form tree,form diff --git a/account_asset_management/views/account_asset_profile.xml b/account_asset_management/views/account_asset_profile.xml index 2f684a17d..a262d7cac 100644 --- a/account_asset_management/views/account_asset_profile.xml +++ b/account_asset_management/views/account_asset_profile.xml @@ -75,7 +75,6 @@ Asset Profiles account.asset.profile - form tree,form diff --git a/account_asset_management/views/account_invoice.xml b/account_asset_management/views/account_invoice.xml deleted file mode 100644 index 6f1431ca6..000000000 --- a/account_asset_management/views/account_invoice.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - account.invoice.supplier.form - account.invoice - - - - - - - - - - account.invoice.customer.form - account.invoice - - - - - - - - - diff --git a/account_asset_management/views/account_invoice_line.xml b/account_asset_management/views/account_invoice_line.xml deleted file mode 100644 index d44dea417..000000000 --- a/account_asset_management/views/account_invoice_line.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - account.invoice.form.add.asset_profile - account.invoice.line - - - - - - - - - - diff --git a/account_asset_management/views/account_move.xml b/account_asset_management/views/account_move.xml index ac12384b4..b5659d9a4 100644 --- a/account_asset_management/views/account_move.xml +++ b/account_asset_management/views/account_move.xml @@ -2,13 +2,20 @@ - account.move.form + account.move.form.account.asset.management account.move + + + + - + diff --git a/account_asset_management/views/res_config_settings.xml b/account_asset_management/views/res_config_settings.xml deleted file mode 100644 index a8cc8014a..000000000 --- a/account_asset_management/views/res_config_settings.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - res.config.settings.view.form.inherit.account - - res.config.settings - - - - - - - - - {'invisible': [('module_account_asset_management', '=', False)]} - - - - - diff --git a/account_asset_management/wizard/account_asset_compute.py b/account_asset_management/wizard/account_asset_compute.py index ba22c8e02..df51489de 100644 --- a/account_asset_management/wizard/account_asset_compute.py +++ b/account_asset_management/wizard/account_asset_compute.py @@ -1,7 +1,7 @@ # Copyright 2009-2018 Noviat # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, fields, models +from odoo import _, fields, models class AccountAssetCompute(models.TransientModel): @@ -17,7 +17,6 @@ class AccountAssetCompute(models.TransientModel): ) note = fields.Text() - @api.multi def asset_compute(self): assets = self.env["account.asset"].search([("state", "=", "open")]) created_move_ids, error_log = assets._compute_entries( @@ -26,12 +25,13 @@ class AccountAssetCompute(models.TransientModel): if error_log: module = __name__.split("addons.")[1].split(".")[0] - result_view = self.env.ref("{}.{}_view_form_result".format(module, self._table)) + result_view = self.env.ref( + "{}.{}_view_form_result".format(module, self._table) + ) self.note = _("Compute Assets errors") + ":\n" + error_log return { "name": _("Compute Assets result"), "res_id": self.id, - "view_type": "form", "view_mode": "form", "res_model": "account.asset.compute", "view_id": result_view.id, @@ -42,7 +42,6 @@ class AccountAssetCompute(models.TransientModel): return { "name": _("Created Asset Moves"), - "view_type": "form", "view_mode": "tree,form", "res_model": "account.move", "view_id": False, @@ -50,13 +49,11 @@ class AccountAssetCompute(models.TransientModel): "type": "ir.actions.act_window", } - @api.multi def view_asset_moves(self): self.ensure_one() domain = [("id", "in", self.env.context.get("asset_move_ids", []))] return { "name": _("Created Asset Moves"), - "view_type": "form", "view_mode": "tree,form", "res_model": "account.move", "view_id": False, diff --git a/account_asset_management/wizard/account_asset_compute.xml b/account_asset_management/wizard/account_asset_compute.xml index a3a7bb090..9bbd2722e 100644 --- a/account_asset_management/wizard/account_asset_compute.xml +++ b/account_asset_management/wizard/account_asset_compute.xml @@ -36,7 +36,6 @@ Compute Assets account.asset.compute - form tree,form new diff --git a/account_asset_management/wizard/account_asset_remove.py b/account_asset_management/wizard/account_asset_remove.py index 2bf32a656..6e9aa5187 100644 --- a/account_asset_management/wizard/account_asset_remove.py +++ b/account_asset_management/wizard/account_asset_remove.py @@ -80,14 +80,20 @@ class AccountAssetRemove(models.TransientModel): asset_id = self.env.context.get("active_id") sale_value = 0.0 account_sale_id = False - inv_lines = self.env["account.invoice.line"].search( - [("asset_id", "=", asset_id)] + inv_lines = self.env["account.move.line"].search( + [ + ("asset_id", "=", asset_id), + ("move_id.type", "in", ("out_invoice", "out_refund")), + ] ) for line in inv_lines: - inv = line.invoice_id - comp_curr = inv.company_id.currency_id + inv = line.move_id + comp_curr = inv.company_currency_id inv_curr = inv.currency_id - if line.invoice_id.state in ["open", "paid"]: + if ( + line.move_id.invoice_payment_state == "paid" + or line.parent_state == "draft" + ): account_sale_id = line.account_id.id amount = line.price_subtotal if inv_curr != comp_curr: @@ -133,7 +139,6 @@ class AccountAssetRemove(models.TransientModel): def _residual_value_regime_countries(self): return ["FR"] - @api.multi def remove(self): self.ensure_one() asset_line_obj = self.env["account.asset.line"] @@ -201,7 +206,6 @@ class AccountAssetRemove(models.TransientModel): return { "name": _("Asset '%s' Removal Journal Entry") % asset_ref, - "view_type": "form", "view_mode": "tree,form", "res_model": "account.move", "view_id": False,