From 690ae9b4db92291b70cdd4f6044d07a256f424dd Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Thu, 25 Jul 2024 09:25:50 -0500 Subject: [PATCH 01/18] [ADD] account_analytic_distribution_manual: New module to easily autocomplete analytic accounts on any model that has a field for analytic accounts. --- .../README.rst | 96 ++++ .../__init__.py | 3 + .../__manifest__.py | 26 + .../account_analytic_distribution_manual.pot | 139 ++++++ .../i18n/es.po | 149 ++++++ .../models/__init__.py | 1 + .../account_analytic_distribution_manual.py | 28 ++ .../readme/CONFIGURE.rst | 6 + .../readme/CONTRIBUTORS.rst | 3 + .../readme/DESCRIPTION.rst | 1 + .../readme/USAGE.rst | 4 + .../security/analytic_security.xml | 8 + .../security/ir.model.access.csv | 3 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 447 ++++++++++++++++++ .../analytic_distribution.esm.js | 84 ++++ .../analytic_distribution.xml | 23 + ...ccount_analytic_distribution_manual.esm.js | 86 ++++ .../tests/__init__.py | 3 + .../tests/common.py | 44 ++ .../test_analytic_distribution_manual.py | 26 + .../test_analytic_distribution_manual_tour.py | 44 ++ ...unt_analytic_distribution_manual_views.xml | 92 ++++ 23 files changed, 1316 insertions(+) create mode 100644 account_analytic_distribution_manual/README.rst create mode 100644 account_analytic_distribution_manual/__init__.py create mode 100644 account_analytic_distribution_manual/__manifest__.py create mode 100644 account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot create mode 100644 account_analytic_distribution_manual/i18n/es.po create mode 100644 account_analytic_distribution_manual/models/__init__.py create mode 100644 account_analytic_distribution_manual/models/account_analytic_distribution_manual.py create mode 100644 account_analytic_distribution_manual/readme/CONFIGURE.rst create mode 100644 account_analytic_distribution_manual/readme/CONTRIBUTORS.rst create mode 100644 account_analytic_distribution_manual/readme/DESCRIPTION.rst create mode 100644 account_analytic_distribution_manual/readme/USAGE.rst create mode 100644 account_analytic_distribution_manual/security/analytic_security.xml create mode 100644 account_analytic_distribution_manual/security/ir.model.access.csv create mode 100644 account_analytic_distribution_manual/static/description/icon.png create mode 100644 account_analytic_distribution_manual/static/description/index.html create mode 100644 account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js create mode 100644 account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml create mode 100644 account_analytic_distribution_manual/static/src/tests/tours/account_analytic_distribution_manual.esm.js create mode 100644 account_analytic_distribution_manual/tests/__init__.py create mode 100644 account_analytic_distribution_manual/tests/common.py create mode 100644 account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py create mode 100644 account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py create mode 100644 account_analytic_distribution_manual/views/account_analytic_distribution_manual_views.xml diff --git a/account_analytic_distribution_manual/README.rst b/account_analytic_distribution_manual/README.rst new file mode 100644 index 0000000000..4e6810863f --- /dev/null +++ b/account_analytic_distribution_manual/README.rst @@ -0,0 +1,96 @@ +==================================== +Account analytic distribution manual +==================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:d88bb48f8d7e08fefe783447ae9850712f06c9c6642170e3a47e00551a22e29d + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--analytic-lightgray.png?logo=github + :target: https://github.com/OCA/account-analytic/tree/16.0/account_analytic_distribution_manual + :alt: OCA/account-analytic +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/account-analytic-16-0/account-analytic-16-0-account_analytic_distribution_manual + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-analytic&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +#. Go to Invoicing > Configuration > Analytic Accounting > Manual Analytic Distributions +#. Create or edit the necessary records. + +Note: to test this module please ensure than the `account_analytic_tag_distribution` module is uninstalled, +This module hides the `analytic_distribution` field, +`see here `_ + +Usage +===== + +#. Go to Invoicing > Customer > Invoices +#. Open or create a invoice +#. On the invoice line, select the analytic account. A new field labeled "Manual Distribution" should appear at the top. +#. Select a record from the list, and it will be added to the distribution and the invoice lines. + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* Tecnativa (https://www.tecnativa.com): + + * Carlos Lopez + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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-analytic `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_analytic_distribution_manual/__init__.py b/account_analytic_distribution_manual/__init__.py new file mode 100644 index 0000000000..0335f4df25 --- /dev/null +++ b/account_analytic_distribution_manual/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2024 Tecnativa - Carlos Lopez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import models diff --git a/account_analytic_distribution_manual/__manifest__.py b/account_analytic_distribution_manual/__manifest__.py new file mode 100644 index 0000000000..43f6013065 --- /dev/null +++ b/account_analytic_distribution_manual/__manifest__.py @@ -0,0 +1,26 @@ +# Copyright 2024 Tecnativa - Carlos Lopez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Account analytic distribution manual", + "summary": "Account analytic distribution manual", + "version": "16.0.1.0.1", + "license": "AGPL-3", + "website": "https://github.com/OCA/account-analytic", + "author": "Tecnativa, Odoo Community Association (OCA)", + "depends": ["account"], + "data": [ + "security/analytic_security.xml", + "security/ir.model.access.csv", + "views/account_analytic_distribution_manual_views.xml", + ], + "assets": { + "web.assets_backend": [ + "account_analytic_distribution_manual/static/src/components/**/*", + ], + "web.assets_tests": [ + "account_analytic_distribution_manual/static/src/tests/tours/**/*", + ], + }, + "installable": True, +} diff --git a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot new file mode 100644 index 0000000000..4a6b2e667f --- /dev/null +++ b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot @@ -0,0 +1,139 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_analytic_distribution_manual +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_analytic_distribution_manual +#. odoo-python +#: code:addons/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py:0 +#, python-format +msgid "%s (Copy)" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_analytic_distribution_manual +msgid "Account analytic distribution manual" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__active +msgid "Active" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model_terms:ir.actions.act_window,help:account_analytic_distribution_manual.action_account_analytic_distribution_manual +msgid "Add a new Manual Analytic Distributions" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution +msgid "Analytic" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_precision +msgid "Analytic Precision" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_search +msgid "Archived" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__company_id +msgid "Company" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__create_uid +msgid "Created by" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__create_date +msgid "Created on" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__display_name +msgid "Display Name" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__id +msgid "ID" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual____last_update +msgid "Last Modified on" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__write_date +msgid "Last Updated on" +msgstr "" + +#. module: account_analytic_distribution_manual +#. odoo-javascript +#: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js:0 +#, python-format +msgid "Loading..." +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.actions.act_window,name:account_analytic_distribution_manual.action_account_analytic_distribution_manual +#: model:ir.ui.menu,name:account_analytic_distribution_manual.account_analytic_distribution_manual_menu +msgid "Manual Analytic Distributions" +msgstr "" + +#. module: account_analytic_distribution_manual +#. odoo-javascript +#: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml:0 +#, python-format +msgid "Manual distribution" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__name +msgid "Name" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form +msgid "Name..." +msgstr "" + +#. module: account_analytic_distribution_manual +#. odoo-javascript +#: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js:0 +#, python-format +msgid "No Analytic Distribution Manual found" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.constraint,message:account_analytic_distribution_manual.constraint_account_analytic_distribution_manual_unique_name_by_company +msgid "The name must be unique per Company!" +msgstr "" diff --git a/account_analytic_distribution_manual/i18n/es.po b/account_analytic_distribution_manual/i18n/es.po new file mode 100644 index 0000000000..c91e14b0ac --- /dev/null +++ b/account_analytic_distribution_manual/i18n/es.po @@ -0,0 +1,149 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_analytic_distribution_manual +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-07-29 06:51-0500\n" +"PO-Revision-Date: 2024-07-29 06:55-0500\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.0.1\n" + +#. module: account_analytic_distribution_manual +#. odoo-python +#: code:addons/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py:0 +#, python-format +msgid "%s (Copy)" +msgstr "%s (Copia)" + +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_analytic_distribution_manual +msgid "Account analytic distribution manual" +msgstr "Distribución Analítica Manual" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__active +msgid "Active" +msgstr "Activo" + +#. module: account_analytic_distribution_manual +#: model_terms:ir.actions.act_window,help:account_analytic_distribution_manual.action_account_analytic_distribution_manual +msgid "Add a new Manual Analytic Distributions" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution +msgid "Analytic" +msgstr "Analítico" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "Buscar Distribución Analítica" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_precision +msgid "Analytic Precision" +msgstr "Precisión Analítica" + +#. module: account_analytic_distribution_manual +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_search +msgid "Archived" +msgstr "Archivado" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__company_id +msgid "Company" +msgstr "Compañia" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__id +msgid "ID" +msgstr "" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual____last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: account_analytic_distribution_manual +#. odoo-javascript +#: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js:0 +#, python-format +msgid "Loading..." +msgstr "Cargando..." + +#. module: account_analytic_distribution_manual +#: model:ir.actions.act_window,name:account_analytic_distribution_manual.action_account_analytic_distribution_manual +#: model:ir.ui.menu,name:account_analytic_distribution_manual.account_analytic_distribution_manual_menu +msgid "Manual Analytic Distributions" +msgstr "" + +#. module: account_analytic_distribution_manual +#. odoo-javascript +#: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml:0 +#, python-format +msgid "Manual distribution" +msgstr "Distribución Manual" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__name +msgid "Name" +msgstr "Nombre" + +#. module: account_analytic_distribution_manual +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form +msgid "Name..." +msgstr "Nombre..." + +#. module: account_analytic_distribution_manual +#. odoo-javascript +#: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js:0 +#, python-format +msgid "No Analytic Distribution Manual found" +msgstr "Distribuciones Manuales no encontradas" + +#. module: account_analytic_distribution_manual +#: model:ir.model.constraint,message:account_analytic_distribution_manual.constraint_account_analytic_distribution_manual_unique_name_by_company +msgid "The name must be unique per Company!" +msgstr "El nombre debe ser único por compañía!" + +#~ msgid "Add a new Manual analytic distributions" +#~ msgstr "Agregar nueva Distribución Analítica Manual" + +#~ msgid "Manual analytic distributions" +#~ msgstr "Distribuciones analíticas manuales" diff --git a/account_analytic_distribution_manual/models/__init__.py b/account_analytic_distribution_manual/models/__init__.py new file mode 100644 index 0000000000..5748b25dfa --- /dev/null +++ b/account_analytic_distribution_manual/models/__init__.py @@ -0,0 +1 @@ +from . import account_analytic_distribution_manual diff --git a/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py b/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py new file mode 100644 index 0000000000..19a6a23e09 --- /dev/null +++ b/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py @@ -0,0 +1,28 @@ +from odoo import _, api, fields, models + + +class AccountAnalyticDistributionManual(models.Model): + _name = "account.analytic.distribution.manual" + _inherit = "analytic.mixin" + _description = "Account analytic distribution manual" + + name = fields.Char(required=True) + active = fields.Boolean(default=True) + company_id = fields.Many2one( + "res.company", required=True, default=lambda self: self.env.company + ) + + _sql_constraints = [ + ( + "unique_name_by_company", + "unique(name, company_id)", + "The name must be unique per Company!", + ), + ] + + @api.returns("self", lambda value: value.id) + def copy(self, default=None): + default = dict(default or {}) + if "name" not in default: + default["name"] = _("%s (Copy)") % self.name + return super().copy(default=default) diff --git a/account_analytic_distribution_manual/readme/CONFIGURE.rst b/account_analytic_distribution_manual/readme/CONFIGURE.rst new file mode 100644 index 0000000000..bc14e98caf --- /dev/null +++ b/account_analytic_distribution_manual/readme/CONFIGURE.rst @@ -0,0 +1,6 @@ +#. Go to Invoicing > Configuration > Analytic Accounting > Manual Analytic Distributions +#. Create or edit the necessary records. + +Note: to test this module please ensure than the `account_analytic_tag_distribution` module is uninstalled, +This module hides the `analytic_distribution` field, +`see here `_ diff --git a/account_analytic_distribution_manual/readme/CONTRIBUTORS.rst b/account_analytic_distribution_manual/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..7227f68b5a --- /dev/null +++ b/account_analytic_distribution_manual/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* Tecnativa (https://www.tecnativa.com): + + * Carlos Lopez \ No newline at end of file diff --git a/account_analytic_distribution_manual/readme/DESCRIPTION.rst b/account_analytic_distribution_manual/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..d5dd0605c2 --- /dev/null +++ b/account_analytic_distribution_manual/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts. diff --git a/account_analytic_distribution_manual/readme/USAGE.rst b/account_analytic_distribution_manual/readme/USAGE.rst new file mode 100644 index 0000000000..306cd0b876 --- /dev/null +++ b/account_analytic_distribution_manual/readme/USAGE.rst @@ -0,0 +1,4 @@ +#. Go to Invoicing > Customer > Invoices +#. Open or create a invoice +#. On the invoice line, select the analytic account. A new field labeled "Manual Distribution" should appear at the top. +#. Select a record from the list, and it will be added to the distribution and the invoice lines. \ No newline at end of file diff --git a/account_analytic_distribution_manual/security/analytic_security.xml b/account_analytic_distribution_manual/security/analytic_security.xml new file mode 100644 index 0000000000..bc04e102f8 --- /dev/null +++ b/account_analytic_distribution_manual/security/analytic_security.xml @@ -0,0 +1,8 @@ + + + + Analytic Manual Distribution multi company rule + + [('company_id', 'in', company_ids)] + + diff --git a/account_analytic_distribution_manual/security/ir.model.access.csv b/account_analytic_distribution_manual/security/ir.model.access.csv new file mode 100644 index 0000000000..23009595b2 --- /dev/null +++ b/account_analytic_distribution_manual/security/ir.model.access.csv @@ -0,0 +1,3 @@ +"id","name","model_id/id","group_id/id","perm_read","perm_write","perm_create","perm_unlink" +"access_account_analytic_distribution_manual_group_user","account_analytic_distribution_manual_group_user","model_account_analytic_distribution_manual","base.group_user",1,0,0,0 +"access_account_analytic_distribution_manual_group_analytic_accounting","access_account_analytic_distribution_manual_group_analytic_accounting","model_account_analytic_distribution_manual","analytic.group_analytic_accounting",1,1,1,1 diff --git a/account_analytic_distribution_manual/static/description/icon.png b/account_analytic_distribution_manual/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/account_analytic_distribution_manual/static/description/index.html b/account_analytic_distribution_manual/static/description/index.html new file mode 100644 index 0000000000..dd39613427 --- /dev/null +++ b/account_analytic_distribution_manual/static/description/index.html @@ -0,0 +1,447 @@ + + + + + +Account analytic distribution manual + + + +
+

Account analytic distribution manual

+ + +

Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

+

This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts.

+

Table of contents

+ +
+

Configuration

+
    +
  1. Go to Invoicing > Configuration > Analytic Accounting > Manual Analytic Distributions
  2. +
  3. Create or edit the necessary records.
  4. +
+

Note: to test this module please ensure than the account_analytic_tag_distribution module is uninstalled, +This module hides the analytic_distribution field, +see here

+
+
+

Usage

+
    +
  1. Go to Invoicing > Customer > Invoices
  2. +
  3. Open or create a invoice
  4. +
  5. On the invoice line, select the analytic account. A new field labeled “Manual Distribution” should appear at the top.
  6. +
  7. Select a record from the list, and it will be added to the distribution and the invoice lines.
  8. +
+
+
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+ +
+
+

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-analytic project on GitHub.

+

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

+
+
+
+ + diff --git a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js new file mode 100644 index 0000000000..7d4962810f --- /dev/null +++ b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js @@ -0,0 +1,84 @@ +/** @odoo-module **/ + +import {AnalyticDistribution} from "@analytic/components/analytic_distribution/analytic_distribution"; +import {patch} from "@web/core/utils/patch"; + +patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { + // Autocomplete + sourcesAnalyticDistributionManual() { + return [ + { + placeholder: this.env._t("Loading..."), + options: (searchTerm) => + this.loadOptionsSourceDistributionManual(searchTerm), + }, + ]; + }, + async loadOptionsSourceDistributionManual(searchTerm) { + const searchLimit = 6; + const records = await this.fetchAnalyticDistributionManual( + [...this.searchAnalyticDistributionManualDomain(searchTerm)], + searchLimit + 1 + ); + const options = records.map((result) => ({ + value: result.id, + label: result.display_name, + analytic_distribution: result.analytic_distribution, + })); + if (!options.length) { + options.push({ + label: this.env._t("No Analytic Distribution Manual found"), + classList: "o_m2o_no_result", + unselectable: true, + }); + } + return options; + }, + async fetchAnalyticDistributionManual(domain, limit = null) { + const args = { + domain: domain, + fields: ["id", "display_name", "analytic_distribution"], + context: [], + }; + if (limit) { + args.limit = limit; + } + return await this.orm.call( + "account.analytic.distribution.manual", + "search_read", + [], + args + ); + }, + searchAnalyticDistributionManualDomain(searchTerm) { + const domain = [["name", "ilike", searchTerm]]; + if (this.props.record.data.company_id) { + domain.push(["company_id", "=", this.props.record.data.company_id[0]]); + } + return domain; + }, + async onSelectDistributionManual(option) { + const selected_option = Object.getPrototypeOf(option); + const account_ids = Object.keys(selected_option.analytic_distribution).map( + (id) => parseInt(id, 10) + ); + const analytic_accounts = await this.fetchAnalyticAccounts([ + ["id", "in", account_ids], + ]); + // Clear all distribution + for (const group_id in this.list) { + this.list[group_id].distribution = []; + } + for (const account of analytic_accounts) { + // Add new tags + const planId = account.root_plan_id[0]; + const tag = this.newTag(planId); + tag.analytic_account_id = account.id; + tag.analytic_account_name = account.display_name; + tag.percentage = selected_option.analytic_distribution[account.id]; + this.list[planId].distribution.push(tag); + } + + this.autoFill(); + }, +}); diff --git a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml new file mode 100644 index 0000000000..a50ee390bc --- /dev/null +++ b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml @@ -0,0 +1,23 @@ + + + + +
+ Manual distribution + +
+
+
+
diff --git a/account_analytic_distribution_manual/static/src/tests/tours/account_analytic_distribution_manual.esm.js b/account_analytic_distribution_manual/static/src/tests/tours/account_analytic_distribution_manual.esm.js new file mode 100644 index 0000000000..e617f689c8 --- /dev/null +++ b/account_analytic_distribution_manual/static/src/tests/tours/account_analytic_distribution_manual.esm.js @@ -0,0 +1,86 @@ +/** @odoo-module */ + +import tour from "web_tour.tour"; + +tour.register( + "account_analytic_distribution_manual", + { + test: true, + url: "/web", + }, + [ + tour.stepUtils.showAppsMenuItem(), + { + id: "account_menu_click", + content: "Go to Invoicing", + trigger: '.o_app[data-menu-xmlid="account.menu_finance"]', + }, + { + content: "Go to Customers", + trigger: 'span:contains("Customers")', + }, + { + content: "Go to Invoices", + trigger: 'a:contains("Invoices")', + }, + { + extra_trigger: '.breadcrumb:contains("Invoices")', + content: "Create new invoice", + trigger: ".o_list_button_add", + }, + { + content: "Add Customer", + trigger: + 'div.o_field_widget.o_field_res_partner_many2one[name="partner_id"] div input', + run: "text partner_a", + }, + { + content: "Valid Customer", + trigger: '.ui-menu-item a:contains("partner_a")', + }, + { + content: "Add items", + trigger: + 'div[name="invoice_line_ids"] .o_field_x2many_list_row_add a:contains("Add a line")', + }, + { + content: "Select product_a", + trigger: + 'div[name="invoice_line_ids"] .o_selected_row .o_list_many2one[name="product_id"] input', + }, + { + content: "Type product_a", + trigger: + 'div[name="invoice_line_ids"] .o_selected_row .o_list_many2one[name="product_id"] input', + run: "text product_a", + }, + { + content: "Valid product_a", + trigger: '.ui-menu-item-wrapper:contains("product_a")', + }, + { + content: "Select analytic_distribution", + trigger: + 'div[name="invoice_line_ids"] .o_selected_row div.o_field_analytic_distribution[name="analytic_distribution"]', + }, + { + content: "Type Manual Distribution 1", + trigger: + 'div[name="invoice_line_ids"] .o_selected_row .analytic_distribution_popup input[id="analytic_manual_distribution"]', + run: "text Manual Distribution 1", + }, + { + content: "Valid Manual Distribution 1", + trigger: + 'div[name="invoice_line_ids"] .o_selected_row .analytic_distribution_popup li a:contains("Manual Distribution 1")', + }, + { + content: "Apply selected Option", + trigger: + 'div[name="invoice_line_ids"] .o_selected_row .analytic_distribution_popup input[id="analytic_manual_distribution"]', + run: "click", + }, + // Save account.move + ...tour.stepUtils.saveForm(), + ] +); diff --git a/account_analytic_distribution_manual/tests/__init__.py b/account_analytic_distribution_manual/tests/__init__.py new file mode 100644 index 0000000000..add5eb092d --- /dev/null +++ b/account_analytic_distribution_manual/tests/__init__.py @@ -0,0 +1,3 @@ +from . import common +from . import test_analytic_distribution_manual +from . import test_analytic_distribution_manual_tour diff --git a/account_analytic_distribution_manual/tests/common.py b/account_analytic_distribution_manual/tests/common.py new file mode 100644 index 0000000000..8728e3a7b4 --- /dev/null +++ b/account_analytic_distribution_manual/tests/common.py @@ -0,0 +1,44 @@ +# Copyright 2024 Tecnativa - Carlos Lopez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo.addons.base.tests.common import BaseCommon + + +class DistributionManualCommon(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + AnalyticAccount = cls.env["account.analytic.account"] + AnalyticPlan = cls.env["account.analytic.plan"] + cls.ManualDistribution = cls.env["account.analytic.distribution.manual"] + cls.plan_a = AnalyticPlan.create({"name": "Plan A"}) + cls.analytic_account_a1 = AnalyticAccount.create( + { + "name": "analytic_account_a1", + "plan_id": cls.plan_a.id, + } + ) + cls.analytic_account_a2 = AnalyticAccount.create( + { + "name": "analytic_account_a2", + "plan_id": cls.plan_a.id, + } + ) + cls.distribution_1 = cls.ManualDistribution.create( + { + "name": "Manual Distribution 1", + "analytic_distribution": { + cls.analytic_account_a1.id: 40, + cls.analytic_account_a2.id: 60, + }, + } + ) + cls.product_a = cls.env["product.product"].create( + { + "name": "product_a", + "lst_price": 100.0, + "standard_price": 80.0, + "taxes_id": False, + } + ) + cls.partner_a = cls.env["res.partner"].create({"name": "partner_a"}) diff --git a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py new file mode 100644 index 0000000000..b50c10041c --- /dev/null +++ b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py @@ -0,0 +1,26 @@ +# Copyright 2024 Tecnativa - Carlos Lopez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from psycopg2.errors import UniqueViolation + +from odoo.tests import tagged +from odoo.tools import mute_logger + +from odoo.addons.account_analytic_distribution_manual.tests.common import ( + DistributionManualCommon, +) + + +@tagged("post_install", "-at_install") +class TestAnalyticDistributionManual(DistributionManualCommon): + @mute_logger("odoo.sql_db") + def test_copy_manual_distribution(self): + distribution = self.distribution_1.copy() + self.assertEqual(distribution.name, "Manual Distribution 1 (Copy)") + distribution2 = self.distribution_1.copy({"name": "New name"}) + self.assertEqual(distribution2.name, "New name") + with self.assertRaises(UniqueViolation): + self.ManualDistribution.create( + { + "name": "Manual Distribution 1", + } + ) diff --git a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py new file mode 100644 index 0000000000..c30e4e705c --- /dev/null +++ b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py @@ -0,0 +1,44 @@ +# Copyright 2024 Tecnativa - Carlos Lopez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo.tests import RecordCapturer, new_test_user, tagged +from odoo.tests.common import HttpCase, users + +from odoo.addons.account_analytic_distribution_manual.tests.common import ( + DistributionManualCommon, +) + + +@tagged("post_install", "-at_install") +class TestAnalyticDistributionManual(DistributionManualCommon, HttpCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + new_test_user( + cls.env, + login="analytic-manual-distribution-user", + groups="analytic.group_analytic_accounting,account.group_account_invoice", + ) + + @users("analytic-manual-distribution-user") + def test_manual_distribution_tour(self): + with RecordCapturer( + self.env["account.move"], [("move_type", "=", "out_invoice")] + ) as capt: + self.start_tour( + "/web", + "account_analytic_distribution_manual", + login="analytic-manual-distribution-user", + ) + invoice = capt.records + invoice.action_post() + self.assertEqual(invoice.partner_id, self.partner_a) + self.assertEqual(len(invoice.invoice_line_ids.analytic_line_ids), 2) + analytic_line1 = invoice.invoice_line_ids.analytic_line_ids.filtered( + lambda x: x.account_id == self.analytic_account_a1 + ) + self.assertEqual(analytic_line1.amount, 40) + analytic_line2 = invoice.invoice_line_ids.analytic_line_ids.filtered( + lambda x: x.account_id == self.analytic_account_a2 + ) + self.assertEqual(analytic_line2.amount, 60) diff --git a/account_analytic_distribution_manual/views/account_analytic_distribution_manual_views.xml b/account_analytic_distribution_manual/views/account_analytic_distribution_manual_views.xml new file mode 100644 index 0000000000..990ecb0212 --- /dev/null +++ b/account_analytic_distribution_manual/views/account_analytic_distribution_manual_views.xml @@ -0,0 +1,92 @@ + + + + + view.account.analytic.distribution.manual.tree + account.analytic.distribution.manual + + + + + + + + + + + view.account.analytic.distribution.manual.form + account.analytic.distribution.manual + +
+ + +
+
+ + + + + +
+
+
+
+ + + view.account.analytic.distribution.manual.search + account.analytic.distribution.manual + + + + + + + + + + Manual Analytic Distributions + ir.actions.act_window + account.analytic.distribution.manual + tree,form + [] + {} + +

+ Add a new Manual Analytic Distributions +

+
+
+ + +
From 6e41782293c6919444a25ff604ea27e36f14d606 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 31 Jul 2024 11:27:50 +0000 Subject: [PATCH 02/18] Added translation using Weblate (Italian) --- .../i18n/it.po | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 account_analytic_distribution_manual/i18n/it.po diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po new file mode 100644 index 0000000000..d36bd00a88 --- /dev/null +++ b/account_analytic_distribution_manual/i18n/it.po @@ -0,0 +1,142 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_analytic_distribution_manual +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-07-31 15:58+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.6.2\n" + +#. module: account_analytic_distribution_manual +#. odoo-python +#: code:addons/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py:0 +#, python-format +msgid "%s (Copy)" +msgstr "%s (copia)" + +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_analytic_distribution_manual +msgid "Account analytic distribution manual" +msgstr "Distribuzione analitica conto manuale" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__active +msgid "Active" +msgstr "Attiva" + +#. module: account_analytic_distribution_manual +#: model_terms:ir.actions.act_window,help:account_analytic_distribution_manual.action_account_analytic_distribution_manual +msgid "Add a new Manual Analytic Distributions" +msgstr "Aggiungere una nuova distribuzione analitica manuale" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution +msgid "Analytic" +msgstr "Analitico" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "Ricerca distribuzione analitica" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_precision +msgid "Analytic Precision" +msgstr "Precisione analitica" + +#. module: account_analytic_distribution_manual +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_search +msgid "Archived" +msgstr "In archivio" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__company_id +msgid "Company" +msgstr "Azienda" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__id +msgid "ID" +msgstr "ID" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual____last_update +msgid "Last Modified on" +msgstr "Ultima modifica il" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: account_analytic_distribution_manual +#. odoo-javascript +#: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js:0 +#, python-format +msgid "Loading..." +msgstr "Caricamento ..." + +#. module: account_analytic_distribution_manual +#: model:ir.actions.act_window,name:account_analytic_distribution_manual.action_account_analytic_distribution_manual +#: model:ir.ui.menu,name:account_analytic_distribution_manual.account_analytic_distribution_manual_menu +msgid "Manual Analytic Distributions" +msgstr "Distribuzione analitica manuale" + +#. module: account_analytic_distribution_manual +#. odoo-javascript +#: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml:0 +#, python-format +msgid "Manual distribution" +msgstr "Distribuzione manuale" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__name +msgid "Name" +msgstr "Nome" + +#. module: account_analytic_distribution_manual +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form +msgid "Name..." +msgstr "Nome..." + +#. module: account_analytic_distribution_manual +#. odoo-javascript +#: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js:0 +#, python-format +msgid "No Analytic Distribution Manual found" +msgstr "Nessuna distribuzione analitica manuale trovata" + +#. module: account_analytic_distribution_manual +#: model:ir.model.constraint,message:account_analytic_distribution_manual.constraint_account_analytic_distribution_manual_unique_name_by_company +msgid "The name must be unique per Company!" +msgstr "Il nome deve essere univoco per azienda!" From 406a5156ac73b3322c0d22826fa8a4228574b551 Mon Sep 17 00:00:00 2001 From: carolinafernandez-tecnativa Date: Fri, 2 Aug 2024 12:37:26 +0000 Subject: [PATCH 03/18] Translated using Weblate (Spanish) Currently translated at 95.6% (22 of 23 strings) Translation: account-analytic-16.0/account-analytic-16.0-account_analytic_distribution_manual Translate-URL: https://translation.odoo-community.org/projects/account-analytic-16-0/account-analytic-16-0-account_analytic_distribution_manual/es/ --- account_analytic_distribution_manual/i18n/es.po | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/account_analytic_distribution_manual/i18n/es.po b/account_analytic_distribution_manual/i18n/es.po index c91e14b0ac..355d64f67f 100644 --- a/account_analytic_distribution_manual/i18n/es.po +++ b/account_analytic_distribution_manual/i18n/es.po @@ -7,15 +7,16 @@ msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-29 06:51-0500\n" -"PO-Revision-Date: 2024-07-29 06:55-0500\n" -"Last-Translator: \n" +"PO-Revision-Date: 2024-08-02 14:08+0000\n" +"Last-Translator: carolinafernandez-tecnativa \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.0.1\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.6.2\n" #. module: account_analytic_distribution_manual #. odoo-python @@ -37,7 +38,7 @@ msgstr "Activo" #. module: account_analytic_distribution_manual #: model_terms:ir.actions.act_window,help:account_analytic_distribution_manual.action_account_analytic_distribution_manual msgid "Add a new Manual Analytic Distributions" -msgstr "" +msgstr "Agregar nueva Distribución Analítica Manual" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution @@ -111,7 +112,7 @@ msgstr "Cargando..." #: model:ir.actions.act_window,name:account_analytic_distribution_manual.action_account_analytic_distribution_manual #: model:ir.ui.menu,name:account_analytic_distribution_manual.account_analytic_distribution_manual_menu msgid "Manual Analytic Distributions" -msgstr "" +msgstr "Distribuciones analíticas manuales" #. module: account_analytic_distribution_manual #. odoo-javascript From 958cf0b3b7862f7c6bf677fedd4bebd44c0554c2 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Wed, 7 Aug 2024 06:30:18 -0500 Subject: [PATCH 04/18] [IMP] account_analytic_distribution_manual: Enhanced control of analytics account from manual distribution - Show the current distribution selected at the top of the tags - When unselecting a distribution, all related analytic accounts are also unselected --- .../README.rst | 8 +- .../models/__init__.py | 2 + .../account_analytic_distribution_manual.py | 2 + .../models/analytic_mixin.py | 10 ++ .../models/base.py | 86 +++++++++++++ .../readme/CONFIGURE.rst | 3 - .../readme/ROADMAP.rst | 1 + .../static/description/index.html | 28 +++-- .../analytic_distribution.esm.js | 117 +++++++++++++++++- .../analytic_distribution.xml | 7 +- ...ccount_analytic_distribution_manual.esm.js | 18 +++ .../test_analytic_distribution_manual_tour.py | 1 - 12 files changed, 255 insertions(+), 28 deletions(-) create mode 100644 account_analytic_distribution_manual/models/analytic_mixin.py create mode 100644 account_analytic_distribution_manual/models/base.py create mode 100644 account_analytic_distribution_manual/readme/ROADMAP.rst diff --git a/account_analytic_distribution_manual/README.rst b/account_analytic_distribution_manual/README.rst index 4e6810863f..3a2884b58e 100644 --- a/account_analytic_distribution_manual/README.rst +++ b/account_analytic_distribution_manual/README.rst @@ -41,9 +41,6 @@ Configuration #. Go to Invoicing > Configuration > Analytic Accounting > Manual Analytic Distributions #. Create or edit the necessary records. -Note: to test this module please ensure than the `account_analytic_tag_distribution` module is uninstalled, -This module hides the `analytic_distribution` field, -`see here `_ Usage ===== @@ -53,6 +50,11 @@ Usage #. On the invoice line, select the analytic account. A new field labeled "Manual Distribution" should appear at the top. #. Select a record from the list, and it will be added to the distribution and the invoice lines. +Known issues / Roadmap +====================== + +Compatibility with `Analytic Distribution Models` to use Manual Distribution as Default values + Bug Tracker =========== diff --git a/account_analytic_distribution_manual/models/__init__.py b/account_analytic_distribution_manual/models/__init__.py index 5748b25dfa..1b1cb07792 100644 --- a/account_analytic_distribution_manual/models/__init__.py +++ b/account_analytic_distribution_manual/models/__init__.py @@ -1 +1,3 @@ from . import account_analytic_distribution_manual +from . import analytic_mixin +from . import base diff --git a/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py b/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py index 19a6a23e09..2d10a941cb 100644 --- a/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py +++ b/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py @@ -1,3 +1,5 @@ +# Copyright 2024 Tecnativa - Carlos Lopez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import _, api, fields, models diff --git a/account_analytic_distribution_manual/models/analytic_mixin.py b/account_analytic_distribution_manual/models/analytic_mixin.py new file mode 100644 index 0000000000..a2f361114a --- /dev/null +++ b/account_analytic_distribution_manual/models/analytic_mixin.py @@ -0,0 +1,10 @@ +# Copyright 2024 Tecnativa - Carlos Lopez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class AnalyticMixin(models.AbstractModel): + _inherit = "analytic.mixin" + + # it will not be a many2one field + manual_distribution_id = fields.Integer(string="Manual Distribution ID") diff --git a/account_analytic_distribution_manual/models/base.py b/account_analytic_distribution_manual/models/base.py new file mode 100644 index 0000000000..0c12ea3840 --- /dev/null +++ b/account_analytic_distribution_manual/models/base.py @@ -0,0 +1,86 @@ +# Copyright 2024 Tecnativa - Carlos Lopez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import json + +from lxml import etree + +from odoo import api, models +from odoo.tools.misc import frozendict + + +class AnalyticMixin(models.AbstractModel): + _inherit = "base" + + @api.model + def get_view(self, view_id=None, view_type="form", **options): + """ + The purpose of inheriting this method is to + add a specific field, 'manual_distribution_id', + to the tree/form views if the model has this field defined. + + Additionally, if a one2many field exists + and the related model has the 'manual_distribution_id' field, + the method will add the 'manual_distribution_id' field to the sub-view. + + Finally, the method returns the modified view. + + Note: This method should be inherited in the base model, + not in the analytic.mixin model, + to ensure it executes correctly for models + that do not inherit from the mixin but have one2many fields. + For example, when rendering account.move, + it does not inherit from analytic.mixin, + but it has one2many fields that inherit from analytic.mixin. + """ + + def add_field(node, view_type, res_model): + attribute = "column_invisible" if view_type == "tree" else "invisible" + modifiers = json.dumps({attribute: True}) + field_options = { + "name": manual_distribution_field_name, + "modifiers": modifiers, + } + field_element = etree.SubElement(node, "field", field_options) + new_arch, new_models = View.postprocess_and_fields(field_element, res_model) + _merge_view_fields(all_models, new_models) + return field_element + + def model_has_field(model): + return manual_distribution_field_name in self.env[model]._fields + + def _merge_view_fields(all_models, new_models): + """Merge new_models into all_models. Both are {modelname(str) ➔ fields(tuple)}.""" + for model, view_fields in new_models.items(): + if model in all_models: + all_models[model] = tuple(set(all_models[model]) | set(view_fields)) + else: + all_models[model] = tuple(view_fields) + + result = super().get_view(view_id=view_id, view_type=view_type, **options) + if view_type in ["tree", "form"]: + View = self.env["ir.ui.view"] + manual_distribution_field_name = "manual_distribution_id" + all_models = result["models"].copy() # {modelname(str) ➔ fields(tuple)} + arch = etree.fromstring(result["arch"]) + if model_has_field(result.get("model")): + root_node = arch.xpath(f"/{view_type}") + for node in root_node: + add_field(node, view_type, result.get("model")) + # check fields one2many + for (res_model, field_list) in result["models"].items(): + for field_name in field_list: + if field_name not in self.env[res_model]._fields: + continue + field_def = self.env[res_model]._fields[field_name] + if field_def.type != "one2many": + continue + if not model_has_field(field_def.comodel_name): + continue + for sub_view_type in ["tree", "form"]: + xpath_expr = f"//field[@name='{field_name}']/{sub_view_type}" + sub_node = arch.xpath(xpath_expr) + for child_node in sub_node: + add_field(child_node, sub_view_type, field_def.comodel_name) + result["arch"] = etree.tostring(arch, encoding="unicode") + result["models"] = frozendict(all_models) + return result diff --git a/account_analytic_distribution_manual/readme/CONFIGURE.rst b/account_analytic_distribution_manual/readme/CONFIGURE.rst index bc14e98caf..e1c510c265 100644 --- a/account_analytic_distribution_manual/readme/CONFIGURE.rst +++ b/account_analytic_distribution_manual/readme/CONFIGURE.rst @@ -1,6 +1,3 @@ #. Go to Invoicing > Configuration > Analytic Accounting > Manual Analytic Distributions #. Create or edit the necessary records. -Note: to test this module please ensure than the `account_analytic_tag_distribution` module is uninstalled, -This module hides the `analytic_distribution` field, -`see here `_ diff --git a/account_analytic_distribution_manual/readme/ROADMAP.rst b/account_analytic_distribution_manual/readme/ROADMAP.rst new file mode 100644 index 0000000000..bbaa6cd7df --- /dev/null +++ b/account_analytic_distribution_manual/readme/ROADMAP.rst @@ -0,0 +1 @@ +Compatibility with `Analytic Distribution Models` to use Manual Distribution as Default values diff --git a/account_analytic_distribution_manual/static/description/index.html b/account_analytic_distribution_manual/static/description/index.html index dd39613427..3bedc800de 100644 --- a/account_analytic_distribution_manual/static/description/index.html +++ b/account_analytic_distribution_manual/static/description/index.html @@ -376,11 +376,12 @@

Account analytic distribution manual

  • Configuration
  • Usage
  • -
  • Bug Tracker
  • -
  • Credits @@ -391,9 +392,6 @@

    Configuration

  • Go to Invoicing > Configuration > Analytic Accounting > Manual Analytic Distributions
  • Create or edit the necessary records.
  • -

    Note: to test this module please ensure than the account_analytic_tag_distribution module is uninstalled, -This module hides the analytic_distribution field, -see here

    Usage

    @@ -404,8 +402,12 @@

    Usage

  • Select a record from the list, and it will be added to the distribution and the invoice lines.
  • +
    +

    Known issues / Roadmap

    +

    Compatibility with Analytic Distribution Models to use Manual Distribution as Default values

    +
    -

    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 to smash it by providing a detailed and welcomed @@ -413,15 +415,15 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Tecnativa
    -

    Contributors

    +

    Contributors

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association diff --git a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js index 7d4962810f..72661bf716 100644 --- a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js +++ b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js @@ -2,8 +2,101 @@ import {AnalyticDistribution} from "@analytic/components/analytic_distribution/analytic_distribution"; import {patch} from "@web/core/utils/patch"; +const {useState} = owl; patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { + setup() { + this._super(); + this.manual_distribution_by_id = {}; + this.state_manual_distribution = useState({ + id: this.props.record.data.manual_distribution_id || 0, + label: "", + analytic_distribution: [], + }); + }, + async willStart() { + await this._super(); + if (this.state_manual_distribution.id) { + this.refreshManualDistribution(this.state_manual_distribution.id); + } + }, + async willUpdate(nextProps) { + await this._super(nextProps); + const record_id = this.props.record.data.id || 0; + const current_manual_distribution_id = this.state_manual_distribution.id; + const new_manual_distribution_id = + nextProps.record.data.manual_distribution_id || 0; + const manual_distribution_Changed = + current_manual_distribution_id !== new_manual_distribution_id; + // When record is created, and manual_distribution_id is cleared + // but user discard changes, we need to refresh the manual distribution + const force_refresh_discart = new_manual_distribution_id === 0 && record_id > 0; + if ( + manual_distribution_Changed && + (new_manual_distribution_id > 0 || force_refresh_discart) + ) { + await this.refreshManualDistribution(new_manual_distribution_id); + } + }, + async save() { + await this._super(); + await this.props.record.update({ + manual_distribution_id: this.state_manual_distribution.id, + }); + }, + async refreshManualDistribution(manual_distribution_id) { + if (manual_distribution_id === 0) { + this.deleteManualTag(); + return; + } + const current_record = this.manual_distribution_by_id[manual_distribution_id]; + if (current_record) { + this.state_manual_distribution.id = current_record.id; + this.state_manual_distribution.label = current_record.display_name; + this.state_manual_distribution.analytic_distribution = + current_record.analytic_distribution; + return; + } + const records = await this.fetchAnalyticDistributionManual([ + ["id", "=", manual_distribution_id], + ]); + if (records.length) { + const record = records[0]; + this.state_manual_distribution.id = record.id; + this.state_manual_distribution.label = record.display_name; + this.state_manual_distribution.analytic_distribution = + record.analytic_distribution; + } else { + this.deleteManualTag(); + } + }, + get tags() { + let res = this._super(); + if (this.state_manual_distribution.id) { + // Remove the delete button from tags + // it will be added only to the manual distribution tag + /* eslint-disable-next-line no-unused-vars */ + res = res.map(({onDelete, ...rest}) => rest); + res.unshift({ + id: this.nextId++, + text: this.state_manual_distribution.label, + onDelete: this.editingRecord ? () => this.deleteManualTag() : undefined, + }); + } + return res; + }, + deleteManualTag() { + this.state_manual_distribution = { + id: 0, + label: "", + analytic_distribution: [], + }; + // Clear all distribution + for (const group_id in this.list) { + this.list[group_id].distribution = []; + } + this.autoFill(); + }, // Autocomplete sourcesAnalyticDistributionManual() { return [ @@ -20,11 +113,15 @@ patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { [...this.searchAnalyticDistributionManualDomain(searchTerm)], searchLimit + 1 ); - const options = records.map((result) => ({ - value: result.id, - label: result.display_name, - analytic_distribution: result.analytic_distribution, - })); + const options = []; + for (const record of records) { + options.push({ + value: record.id, + label: record.display_name, + analytic_distribution: record.analytic_distribution, + }); + this.manual_distribution_by_id[record.id] = record; + } if (!options.length) { options.push({ label: this.env._t("No Analytic Distribution Manual found"), @@ -57,8 +154,18 @@ patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { } return domain; }, + onChangeAutoCompleteDistributionManual(inputValue) { + if (inputValue === "") { + this.deleteManualTag(); + } + }, async onSelectDistributionManual(option) { const selected_option = Object.getPrototypeOf(option); + this.state_manual_distribution = { + id: selected_option.value, + label: selected_option.label, + analytic_distribution: selected_option.analytic_distribution, + }; const account_ids = Object.keys(selected_option.analytic_distribution).map( (id) => parseInt(id, 10) ); diff --git a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml index a50ee390bc..ed720811ea 100644 --- a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml +++ b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml @@ -1,21 +1,22 @@ - - +
    Manual distribution
    diff --git a/account_analytic_distribution_manual/static/src/tests/tours/account_analytic_distribution_manual.esm.js b/account_analytic_distribution_manual/static/src/tests/tours/account_analytic_distribution_manual.esm.js index e617f689c8..890fb7c2de 100644 --- a/account_analytic_distribution_manual/static/src/tests/tours/account_analytic_distribution_manual.esm.js +++ b/account_analytic_distribution_manual/static/src/tests/tours/account_analytic_distribution_manual.esm.js @@ -80,6 +80,24 @@ tour.register( 'div[name="invoice_line_ids"] .o_selected_row .analytic_distribution_popup input[id="analytic_manual_distribution"]', run: "click", }, + // Compatibility with analytic_distribution_widget_remove_save + // this module remove buttons + // so to close popup click on any form area + { + content: "Close Popup", + trigger: "div.o_form_sheet_bg", + run: "click", + }, + { + content: "Check Tag Manual is on the top", + trigger: + 'div[name="invoice_line_ids"] .o_selected_row div.o_field_analytic_distribution[name="analytic_distribution"] div.o_field_tags div.o_tag_badge_text:contains("Manual Distribution 1")', + }, + { + content: "Confirm Invoice", + trigger: 'button[name="action_post"]', + run: "click", + }, // Save account.move ...tour.stepUtils.saveForm(), ] diff --git a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py index c30e4e705c..f33c306687 100644 --- a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py +++ b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py @@ -31,7 +31,6 @@ def test_manual_distribution_tour(self): login="analytic-manual-distribution-user", ) invoice = capt.records - invoice.action_post() self.assertEqual(invoice.partner_id, self.partner_a) self.assertEqual(len(invoice.invoice_line_ids.analytic_line_ids), 2) analytic_line1 = invoice.invoice_line_ids.analytic_line_ids.filtered( From 0081e2dd47b3d0a9e532aa4ab022a58d4ebd3199 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Wed, 7 Aug 2024 09:21:15 -0500 Subject: [PATCH 05/18] [IMP] account_analytic_distribution_manual: post_init_hook to convert old data to new models(if table exists) --- .../README.rst | 2 +- .../__init__.py | 1 + .../__manifest__.py | 3 +- account_analytic_distribution_manual/hooks.py | 56 +++++++++++++++++++ .../account_analytic_distribution_manual.pot | 26 +++++++++ .../i18n/es.po | 26 +++++++++ .../i18n/it.po | 26 +++++++++ .../static/description/index.html | 2 +- 8 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 account_analytic_distribution_manual/hooks.py diff --git a/account_analytic_distribution_manual/README.rst b/account_analytic_distribution_manual/README.rst index 3a2884b58e..a33d549e99 100644 --- a/account_analytic_distribution_manual/README.rst +++ b/account_analytic_distribution_manual/README.rst @@ -7,7 +7,7 @@ Account analytic distribution manual !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:d88bb48f8d7e08fefe783447ae9850712f06c9c6642170e3a47e00551a22e29d + !! source digest: sha256:c02584753627ec6ded32e79e2d3885b73af7f6275eec5402f2d0bc7f8612d61f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/account_analytic_distribution_manual/__init__.py b/account_analytic_distribution_manual/__init__.py index 0335f4df25..ef36cf2928 100644 --- a/account_analytic_distribution_manual/__init__.py +++ b/account_analytic_distribution_manual/__init__.py @@ -1,3 +1,4 @@ # Copyright 2024 Tecnativa - Carlos Lopez # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from . import models +from .hooks import post_init_hook diff --git a/account_analytic_distribution_manual/__manifest__.py b/account_analytic_distribution_manual/__manifest__.py index 43f6013065..f9776f8caa 100644 --- a/account_analytic_distribution_manual/__manifest__.py +++ b/account_analytic_distribution_manual/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Account analytic distribution manual", "summary": "Account analytic distribution manual", - "version": "16.0.1.0.1", + "version": "16.0.2.0.0", "license": "AGPL-3", "website": "https://github.com/OCA/account-analytic", "author": "Tecnativa, Odoo Community Association (OCA)", @@ -23,4 +23,5 @@ ], }, "installable": True, + "post_init_hook": "post_init_hook", } diff --git a/account_analytic_distribution_manual/hooks.py b/account_analytic_distribution_manual/hooks.py new file mode 100644 index 0000000000..394850d68f --- /dev/null +++ b/account_analytic_distribution_manual/hooks.py @@ -0,0 +1,56 @@ +# Copyright 2024 Tecnativa - Carlos Lopez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import SUPERUSER_ID, api, tools + + +def post_init_hook(cr, registry): + if tools.table_exists(cr, "account_analytic_tag"): + env = api.Environment(cr, SUPERUSER_ID, {}) + sql = """ + WITH counted_tags AS ( + SELECT + tag.id, + tag.name, + tag.active, + tag.company_id, + ROW_NUMBER() OVER (PARTITION BY tag.name ORDER BY tag.id) AS row_count + FROM account_analytic_tag tag + WHERE tag.active_analytic_distribution = true + ) + SELECT + CASE + WHEN row_count = 1 THEN tag.name + ELSE CONCAT(tag.name, ' (', tag.id, ')') + END AS name, + tag.id, + tag.active, + tag.company_id, + distribution.account_id, + distribution.percentage + FROM + counted_tags tag + INNER JOIN + account_analytic_distribution distribution ON tag.id = distribution.tag_id; + + """ + env.cr.execute(sql) + distribution_by_tag = {} + distribution_manual_vals = [] + for data in env.cr.dictfetchall(): + tag_key = (data["name"], data["active"], data["company_id"]) + distribution_by_tag.setdefault(tag_key, []).append(data) + for tag_key, distributions in distribution_by_tag.items(): + tag_name, tag_active, company_id = tag_key + distribution_manual_val = { + "name": tag_name, + "active": tag_active, + "company_id": company_id or env.company.id, + "analytic_distribution": { + distribution["account_id"]: distribution["percentage"] + for distribution in distributions + }, + } + distribution_manual_vals.append(distribution_manual_val) + if distribution_manual_vals: + env["account.analytic.distribution.manual"].create(distribution_manual_vals) diff --git a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot index 4a6b2e667f..7e88804749 100644 --- a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot +++ b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot @@ -45,6 +45,11 @@ msgstr "" msgid "Analytic Distribution Search" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_analytic_mixin +msgid "Analytic Mixin" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_precision msgid "Analytic Precision" @@ -56,6 +61,11 @@ msgstr "" msgid "Archived" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_base +msgid "Base" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__company_id msgid "Company" @@ -109,6 +119,22 @@ msgstr "" msgid "Manual Analytic Distributions" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_model__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_reconcile_model_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_analytic_mixin__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense_split__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_purchase_order_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_sale_order_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__manual_distribution_id +msgid "Manual Distribution ID" +msgstr "" + #. module: account_analytic_distribution_manual #. odoo-javascript #: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml:0 diff --git a/account_analytic_distribution_manual/i18n/es.po b/account_analytic_distribution_manual/i18n/es.po index 355d64f67f..3ea37f1b2b 100644 --- a/account_analytic_distribution_manual/i18n/es.po +++ b/account_analytic_distribution_manual/i18n/es.po @@ -50,6 +50,11 @@ msgstr "Analítico" msgid "Analytic Distribution Search" msgstr "Buscar Distribución Analítica" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_analytic_mixin +msgid "Analytic Mixin" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_precision msgid "Analytic Precision" @@ -61,6 +66,11 @@ msgstr "Precisión Analítica" msgid "Archived" msgstr "Archivado" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_base +msgid "Base" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__company_id msgid "Company" @@ -114,6 +124,22 @@ msgstr "Cargando..." msgid "Manual Analytic Distributions" msgstr "Distribuciones analíticas manuales" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_model__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_reconcile_model_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_analytic_mixin__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense_split__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_purchase_order_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_sale_order_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__manual_distribution_id +msgid "Manual Distribution ID" +msgstr "" + #. module: account_analytic_distribution_manual #. odoo-javascript #: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml:0 diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po index d36bd00a88..483012db72 100644 --- a/account_analytic_distribution_manual/i18n/it.po +++ b/account_analytic_distribution_manual/i18n/it.po @@ -48,6 +48,11 @@ msgstr "Analitico" msgid "Analytic Distribution Search" msgstr "Ricerca distribuzione analitica" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_analytic_mixin +msgid "Analytic Mixin" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_precision msgid "Analytic Precision" @@ -59,6 +64,11 @@ msgstr "Precisione analitica" msgid "Archived" msgstr "In archivio" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_base +msgid "Base" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__company_id msgid "Company" @@ -112,6 +122,22 @@ msgstr "Caricamento ..." msgid "Manual Analytic Distributions" msgstr "Distribuzione analitica manuale" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_model__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_reconcile_model_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_analytic_mixin__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense_split__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_purchase_order_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_sale_order_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__manual_distribution_id +msgid "Manual Distribution ID" +msgstr "" + #. module: account_analytic_distribution_manual #. odoo-javascript #: code:addons/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml:0 diff --git a/account_analytic_distribution_manual/static/description/index.html b/account_analytic_distribution_manual/static/description/index.html index 3bedc800de..8160046cf9 100644 --- a/account_analytic_distribution_manual/static/description/index.html +++ b/account_analytic_distribution_manual/static/description/index.html @@ -367,7 +367,7 @@

    Account analytic distribution manual

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:d88bb48f8d7e08fefe783447ae9850712f06c9c6642170e3a47e00551a22e29d +!! source digest: sha256:c02584753627ec6ded32e79e2d3885b73af7f6275eec5402f2d0bc7f8612d61f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

    This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts.

    From d9876b6758ab99baa6f2f18cb7ca18b988636089 Mon Sep 17 00:00:00 2001 From: mymage Date: Mon, 12 Aug 2024 07:18:08 +0000 Subject: [PATCH 06/18] Translated using Weblate (Italian) Currently translated at 100.0% (26 of 26 strings) Translation: account-analytic-16.0/account-analytic-16.0-account_analytic_distribution_manual Translate-URL: https://translation.odoo-community.org/projects/account-analytic-16-0/account-analytic-16-0-account_analytic_distribution_manual/it/ --- account_analytic_distribution_manual/i18n/it.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po index 483012db72..65a64b4921 100644 --- a/account_analytic_distribution_manual/i18n/it.po +++ b/account_analytic_distribution_manual/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-07-31 15:58+0000\n" +"PO-Revision-Date: 2024-08-12 09:58+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -51,7 +51,7 @@ msgstr "Ricerca distribuzione analitica" #. module: account_analytic_distribution_manual #: model:ir.model,name:account_analytic_distribution_manual.model_analytic_mixin msgid "Analytic Mixin" -msgstr "" +msgstr "Mixin analitica" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_precision @@ -67,7 +67,7 @@ msgstr "In archivio" #. module: account_analytic_distribution_manual #: model:ir.model,name:account_analytic_distribution_manual.model_base msgid "Base" -msgstr "" +msgstr "Imponibile" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__company_id @@ -136,7 +136,7 @@ msgstr "Distribuzione analitica manuale" #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__manual_distribution_id msgid "Manual Distribution ID" -msgstr "" +msgstr "ID distribuzione manuale" #. module: account_analytic_distribution_manual #. odoo-javascript From 83659dd5eb92c2782dcbc22f54dedf764cfdb9d2 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Wed, 14 Aug 2024 09:20:07 -0500 Subject: [PATCH 07/18] [IMP] account_analytic_distribution_manual: change field type from integer to many2one - If the user needs to group by this field, it was impossible when it was an integer. - Added a script to populate the new field in models related to account_analytic_tags. Note: When multiple tags are present, only the last record is populated. --- .../README.rst | 2 +- .../__manifest__.py | 2 +- account_analytic_distribution_manual/hooks.py | 140 +++++++++++++++++- .../account_analytic_distribution_manual.pot | 2 +- .../i18n/es.po | 2 +- .../i18n/it.po | 7 +- .../models/analytic_mixin.py | 3 +- .../static/description/index.html | 2 +- .../analytic_distribution.esm.js | 14 +- 9 files changed, 155 insertions(+), 19 deletions(-) diff --git a/account_analytic_distribution_manual/README.rst b/account_analytic_distribution_manual/README.rst index a33d549e99..23414453ac 100644 --- a/account_analytic_distribution_manual/README.rst +++ b/account_analytic_distribution_manual/README.rst @@ -7,7 +7,7 @@ Account analytic distribution manual !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:c02584753627ec6ded32e79e2d3885b73af7f6275eec5402f2d0bc7f8612d61f + !! source digest: sha256:60d66a0454fbbebc52afb8eec20e990b153432894213e15e969858c38991abd2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/account_analytic_distribution_manual/__manifest__.py b/account_analytic_distribution_manual/__manifest__.py index f9776f8caa..eb36e4f2e0 100644 --- a/account_analytic_distribution_manual/__manifest__.py +++ b/account_analytic_distribution_manual/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Account analytic distribution manual", "summary": "Account analytic distribution manual", - "version": "16.0.2.0.0", + "version": "16.0.2.0.1", "license": "AGPL-3", "website": "https://github.com/OCA/account-analytic", "author": "Tecnativa, Odoo Community Association (OCA)", diff --git a/account_analytic_distribution_manual/hooks.py b/account_analytic_distribution_manual/hooks.py index 394850d68f..e7b8184cba 100644 --- a/account_analytic_distribution_manual/hooks.py +++ b/account_analytic_distribution_manual/hooks.py @@ -3,10 +3,112 @@ from odoo import SUPERUSER_ID, api, tools +# metadata for all models related to account_analytic_tag(m2m) +# add more models if needed +RELATION_M2M_INFO = { + "account_analytic_tag_account_asset_profile_rel": { + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + "table2": "account_asset_profile", + "column2": "account_asset_profile_id", + }, + "account_analytic_tag_hr_expense_rel": { + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + "table2": "hr_expense", + "column2": "hr_expense_id", + }, + "account_reconcile_model_second_analytic_tag_rel": { + "table2": "account_reconcile_model", + "column2": "account_reconcile_model_id", + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + }, + "hr_timesheet_switch_line_tag_rel": { + "table2": "hr_timesheet_switch", + "column2": "line_id", + "table1": "account_analytic_tag", + "column1": "tag_id", + }, + "account_analytic_tag_sale_order_line_rel": { + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + "table2": "sale_order_line", + "column2": "sale_order_line_id", + }, + "account_reconcile_model_analytic_tag_rel": { + "table2": "account_reconcile_model_line", + "column2": "account_reconcile_model_line_id", + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + }, + "account_analytic_tag_mis_report_instance_rel": { + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + "table2": "mis_report_instance", + "column2": "mis_report_instance_id", + }, + "account_analytic_tag_account_move_line_rel": { + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + "table2": "account_move_line", + "column2": "account_move_line_id", + }, + "account_analytic_tag_mis_report_instance_period_rel": { + "table2": "mis_report_instance_period", + "column2": "mis_report_instance_period_id", + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + }, + "account_analytic_tag_general_ledger_report_wizard_rel": { + "table2": "general_ledger_report_wizard", + "column2": "general_ledger_report_wizard_id", + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + }, + "account_analytic_default_account_analytic_tag_rel": { + "table2": "account_analytic_default", + "column2": "account_analytic_default_id", + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + }, + "account_analytic_tag_purchase_order_line_rel": { + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + "table2": "purchase_order_line", + "column2": "purchase_order_line_id", + }, + "account_analytic_tag_account_asset_rel": { + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + "table2": "account_asset", + "column2": "account_asset_id", + }, + "account_analytic_tag_project_task_stock_rel": { + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + "table2": "project_task", + "column2": "project_task_id", + }, + "account_analytic_tag_project_task_rel": { + "table1": "account_analytic_tag", + "column1": "account_analytic_tag_id", + "table2": "project_task", + "column2": "project_task_id", + }, + "account_analytic_line_tag_rel": { + "table2": "account_analytic_line", + "column2": "line_id", + "table1": "account_analytic_tag", + "column1": "tag_id", + }, +} + def post_init_hook(cr, registry): if tools.table_exists(cr, "account_analytic_tag"): env = api.Environment(cr, SUPERUSER_ID, {}) + DistributionManual = env["account.analytic.distribution.manual"] sql = """ WITH counted_tags AS ( SELECT @@ -36,12 +138,13 @@ def post_init_hook(cr, registry): """ env.cr.execute(sql) distribution_by_tag = {} - distribution_manual_vals = [] for data in env.cr.dictfetchall(): - tag_key = (data["name"], data["active"], data["company_id"]) + tag_key = (data["id"], data["name"], data["active"], data["company_id"]) distribution_by_tag.setdefault(tag_key, []).append(data) + distribution_map = {} + all_tag_ids = [] for tag_key, distributions in distribution_by_tag.items(): - tag_name, tag_active, company_id = tag_key + tag_id, tag_name, tag_active, company_id = tag_key distribution_manual_val = { "name": tag_name, "active": tag_active, @@ -51,6 +154,31 @@ def post_init_hook(cr, registry): for distribution in distributions }, } - distribution_manual_vals.append(distribution_manual_val) - if distribution_manual_vals: - env["account.analytic.distribution.manual"].create(distribution_manual_vals) + new_distribution = DistributionManual.create(distribution_manual_val) + distribution_map[tag_id] = new_distribution + all_tag_ids.append(tag_id) + # Update references in all models related to account_analytic_tag(m2m) + for table_m2m, info in RELATION_M2M_INFO.items(): + column1 = info["column1"] + table2 = info["table2"] + column2 = info["column2"] + res_model_name = table2.replace("_", ".") + if ( + res_model_name in env + and "manual_distribution_id" in env[res_model_name]._fields + ): + sql = f""" + SELECT {column1}, {column2} + FROM {table_m2m} + WHERE {column1} IN %s + """ + env.cr.execute(sql, (tuple(all_tag_ids),)) + for tag_id, res_id in env.cr.fetchall(): + env.cr.execute( + f""" + UPDATE {table2} + SET manual_distribution_id = %s + WHERE id = %s + """, + (distribution_map[tag_id].id, res_id), + ) diff --git a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot index 7e88804749..86cd4b94e8 100644 --- a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot +++ b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot @@ -132,7 +132,7 @@ msgstr "" #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__manual_distribution_id -msgid "Manual Distribution ID" +msgid "Manual Distribution" msgstr "" #. module: account_analytic_distribution_manual diff --git a/account_analytic_distribution_manual/i18n/es.po b/account_analytic_distribution_manual/i18n/es.po index 3ea37f1b2b..684fbc3c98 100644 --- a/account_analytic_distribution_manual/i18n/es.po +++ b/account_analytic_distribution_manual/i18n/es.po @@ -137,7 +137,7 @@ msgstr "Distribuciones analíticas manuales" #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__manual_distribution_id -msgid "Manual Distribution ID" +msgid "Manual Distribution" msgstr "" #. module: account_analytic_distribution_manual diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po index 65a64b4921..b1c5145765 100644 --- a/account_analytic_distribution_manual/i18n/it.po +++ b/account_analytic_distribution_manual/i18n/it.po @@ -135,8 +135,8 @@ msgstr "Distribuzione analitica manuale" #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__manual_distribution_id -msgid "Manual Distribution ID" -msgstr "ID distribuzione manuale" +msgid "Manual Distribution" +msgstr "" #. module: account_analytic_distribution_manual #. odoo-javascript @@ -166,3 +166,6 @@ msgstr "Nessuna distribuzione analitica manuale trovata" #: model:ir.model.constraint,message:account_analytic_distribution_manual.constraint_account_analytic_distribution_manual_unique_name_by_company msgid "The name must be unique per Company!" msgstr "Il nome deve essere univoco per azienda!" + +#~ msgid "Manual Distribution ID" +#~ msgstr "ID distribuzione manuale" diff --git a/account_analytic_distribution_manual/models/analytic_mixin.py b/account_analytic_distribution_manual/models/analytic_mixin.py index a2f361114a..b14d3f653b 100644 --- a/account_analytic_distribution_manual/models/analytic_mixin.py +++ b/account_analytic_distribution_manual/models/analytic_mixin.py @@ -6,5 +6,4 @@ class AnalyticMixin(models.AbstractModel): _inherit = "analytic.mixin" - # it will not be a many2one field - manual_distribution_id = fields.Integer(string="Manual Distribution ID") + manual_distribution_id = fields.Many2one("account.analytic.distribution.manual") diff --git a/account_analytic_distribution_manual/static/description/index.html b/account_analytic_distribution_manual/static/description/index.html index 8160046cf9..a9d36cac7a 100644 --- a/account_analytic_distribution_manual/static/description/index.html +++ b/account_analytic_distribution_manual/static/description/index.html @@ -367,7 +367,7 @@

    Account analytic distribution manual

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:c02584753627ec6ded32e79e2d3885b73af7f6275eec5402f2d0bc7f8612d61f +!! source digest: sha256:60d66a0454fbbebc52afb8eec20e990b153432894213e15e969858c38991abd2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

    This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts.

    diff --git a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js index 72661bf716..571585958b 100644 --- a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js +++ b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js @@ -9,7 +9,9 @@ patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { this._super(); this.manual_distribution_by_id = {}; this.state_manual_distribution = useState({ - id: this.props.record.data.manual_distribution_id || 0, + id: this.props.record.data.manual_distribution_id + ? this.props.record.data.manual_distribution_id[0] + : 0, label: "", analytic_distribution: [], }); @@ -24,8 +26,9 @@ patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { await this._super(nextProps); const record_id = this.props.record.data.id || 0; const current_manual_distribution_id = this.state_manual_distribution.id; - const new_manual_distribution_id = - nextProps.record.data.manual_distribution_id || 0; + const new_manual_distribution_id = nextProps.record.data.manual_distribution_id + ? this.props.record.data.manual_distribution_id[0] + : 0; const manual_distribution_Changed = current_manual_distribution_id !== new_manual_distribution_id; // When record is created, and manual_distribution_id is cleared @@ -41,7 +44,10 @@ patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { async save() { await this._super(); await this.props.record.update({ - manual_distribution_id: this.state_manual_distribution.id, + manual_distribution_id: [ + this.state_manual_distribution.id, + this.state_manual_distribution.label, + ], }); }, async refreshManualDistribution(manual_distribution_id) { From b461d1fdb8c7a10c34063c5b3ac599e288c61727 Mon Sep 17 00:00:00 2001 From: mymage Date: Fri, 16 Aug 2024 07:21:03 +0000 Subject: [PATCH 08/18] Translated using Weblate (Italian) Currently translated at 100.0% (26 of 26 strings) Translation: account-analytic-16.0/account-analytic-16.0-account_analytic_distribution_manual Translate-URL: https://translation.odoo-community.org/projects/account-analytic-16-0/account-analytic-16-0-account_analytic_distribution_manual/it/ --- account_analytic_distribution_manual/i18n/it.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po index b1c5145765..77a9c2a476 100644 --- a/account_analytic_distribution_manual/i18n/it.po +++ b/account_analytic_distribution_manual/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-08-12 09:58+0000\n" +"PO-Revision-Date: 2024-08-16 09:58+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -136,7 +136,7 @@ msgstr "Distribuzione analitica manuale" #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__manual_distribution_id msgid "Manual Distribution" -msgstr "" +msgstr "Distribuzione manuale" #. module: account_analytic_distribution_manual #. odoo-javascript From f401c2caa11461266155b2215aaba00ab656640d Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Tue, 27 Aug 2024 05:59:35 -0500 Subject: [PATCH 09/18] [IMP] account_analytic_distribution_manual: add field manual_distribution_id into account.invoice.report --- account_analytic_distribution_manual/README.rst | 2 +- account_analytic_distribution_manual/__init__.py | 1 + .../__manifest__.py | 2 +- .../i18n/account_analytic_distribution_manual.pot | 6 ++++++ account_analytic_distribution_manual/i18n/es.po | 6 ++++++ account_analytic_distribution_manual/i18n/it.po | 6 ++++++ .../reports/__init__.py | 1 + .../reports/invoice_report.py | 14 ++++++++++++++ .../static/description/index.html | 2 +- 9 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 account_analytic_distribution_manual/reports/__init__.py create mode 100644 account_analytic_distribution_manual/reports/invoice_report.py diff --git a/account_analytic_distribution_manual/README.rst b/account_analytic_distribution_manual/README.rst index 23414453ac..726d8b3e5c 100644 --- a/account_analytic_distribution_manual/README.rst +++ b/account_analytic_distribution_manual/README.rst @@ -7,7 +7,7 @@ Account analytic distribution manual !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:60d66a0454fbbebc52afb8eec20e990b153432894213e15e969858c38991abd2 + !! source digest: sha256:653ab616c32f188e47837795b0b299865043f6c53899f0a1b92d6087177f94c5 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/account_analytic_distribution_manual/__init__.py b/account_analytic_distribution_manual/__init__.py index ef36cf2928..f58c885722 100644 --- a/account_analytic_distribution_manual/__init__.py +++ b/account_analytic_distribution_manual/__init__.py @@ -1,4 +1,5 @@ # Copyright 2024 Tecnativa - Carlos Lopez # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from . import models +from . import reports from .hooks import post_init_hook diff --git a/account_analytic_distribution_manual/__manifest__.py b/account_analytic_distribution_manual/__manifest__.py index eb36e4f2e0..28b8d1e543 100644 --- a/account_analytic_distribution_manual/__manifest__.py +++ b/account_analytic_distribution_manual/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Account analytic distribution manual", "summary": "Account analytic distribution manual", - "version": "16.0.2.0.1", + "version": "16.0.2.1.0", "license": "AGPL-3", "website": "https://github.com/OCA/account-analytic", "author": "Tecnativa, Odoo Community Association (OCA)", diff --git a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot index 86cd4b94e8..4be5e9f8db 100644 --- a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot +++ b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot @@ -91,6 +91,11 @@ msgstr "" msgid "ID" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual____last_update msgid "Last Modified on" @@ -122,6 +127,7 @@ msgstr "" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_model__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_invoice_report__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_line__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_reconcile_model_line__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_analytic_mixin__manual_distribution_id diff --git a/account_analytic_distribution_manual/i18n/es.po b/account_analytic_distribution_manual/i18n/es.po index 684fbc3c98..13c3976369 100644 --- a/account_analytic_distribution_manual/i18n/es.po +++ b/account_analytic_distribution_manual/i18n/es.po @@ -96,6 +96,11 @@ msgstr "Nombre mostrado" msgid "ID" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual____last_update msgid "Last Modified on" @@ -127,6 +132,7 @@ msgstr "Distribuciones analíticas manuales" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_model__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_invoice_report__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_line__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_reconcile_model_line__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_analytic_mixin__manual_distribution_id diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po index 77a9c2a476..8e910f46e5 100644 --- a/account_analytic_distribution_manual/i18n/it.po +++ b/account_analytic_distribution_manual/i18n/it.po @@ -94,6 +94,11 @@ msgstr "Nome visualizzato" msgid "ID" msgstr "ID" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual____last_update msgid "Last Modified on" @@ -125,6 +130,7 @@ msgstr "Distribuzione analitica manuale" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_model__manual_distribution_id +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_invoice_report__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_line__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_reconcile_model_line__manual_distribution_id #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_analytic_mixin__manual_distribution_id diff --git a/account_analytic_distribution_manual/reports/__init__.py b/account_analytic_distribution_manual/reports/__init__.py new file mode 100644 index 0000000000..dc823f037b --- /dev/null +++ b/account_analytic_distribution_manual/reports/__init__.py @@ -0,0 +1 @@ +from . import invoice_report diff --git a/account_analytic_distribution_manual/reports/invoice_report.py b/account_analytic_distribution_manual/reports/invoice_report.py new file mode 100644 index 0000000000..c58835e95e --- /dev/null +++ b/account_analytic_distribution_manual/reports/invoice_report.py @@ -0,0 +1,14 @@ +# Copyright 2024 Tecnativa - Carlos Lopez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class AccountInvoiceReport(models.Model): + _inherit = "account.invoice.report" + + manual_distribution_id = fields.Many2one( + "account.analytic.distribution.manual", readonly=True + ) + + def _select(self): + return super()._select() + ", line.manual_distribution_id" diff --git a/account_analytic_distribution_manual/static/description/index.html b/account_analytic_distribution_manual/static/description/index.html index a9d36cac7a..f47e9359b9 100644 --- a/account_analytic_distribution_manual/static/description/index.html +++ b/account_analytic_distribution_manual/static/description/index.html @@ -367,7 +367,7 @@

    Account analytic distribution manual

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:60d66a0454fbbebc52afb8eec20e990b153432894213e15e969858c38991abd2 +!! source digest: sha256:653ab616c32f188e47837795b0b299865043f6c53899f0a1b92d6087177f94c5 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

    This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts.

    From 22601f6b0f2b3da9283062d406b997b164381f01 Mon Sep 17 00:00:00 2001 From: mymage Date: Thu, 29 Aug 2024 10:13:28 +0000 Subject: [PATCH 10/18] Translated using Weblate (Italian) Currently translated at 100.0% (27 of 27 strings) Translation: account-analytic-16.0/account-analytic-16.0-account_analytic_distribution_manual Translate-URL: https://translation.odoo-community.org/projects/account-analytic-16-0/account-analytic-16-0-account_analytic_distribution_manual/it/ --- account_analytic_distribution_manual/i18n/it.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po index 8e910f46e5..824a23327f 100644 --- a/account_analytic_distribution_manual/i18n/it.po +++ b/account_analytic_distribution_manual/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-08-16 09:58+0000\n" +"PO-Revision-Date: 2024-08-29 13:06+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -97,7 +97,7 @@ msgstr "ID" #. module: account_analytic_distribution_manual #: model:ir.model,name:account_analytic_distribution_manual.model_account_invoice_report msgid "Invoices Statistics" -msgstr "" +msgstr "Statistiche fatture" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual____last_update From 3387bc7ba67cc198f7cf6f6cab5f2150007d74a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Wed, 28 Aug 2024 13:22:49 +0200 Subject: [PATCH 11/18] [IMP] account_analytic_distribution_manual: Add extra json field for export/import of analytical distributions TT50235 --- .../README.rst | 2 +- .../__manifest__.py | 2 +- .../account_analytic_distribution_manual.pot | 13 ++++++ .../i18n/es.po | 13 ++++++ .../i18n/it.po | 13 ++++++ .../account_analytic_distribution_manual.py | 38 +++++++++++++++++ .../static/description/index.html | 2 +- .../tests/__init__.py | 1 - .../test_analytic_distribution_manual.py | 42 +++++++++++++++++++ 9 files changed, 122 insertions(+), 4 deletions(-) diff --git a/account_analytic_distribution_manual/README.rst b/account_analytic_distribution_manual/README.rst index 726d8b3e5c..4711e0050f 100644 --- a/account_analytic_distribution_manual/README.rst +++ b/account_analytic_distribution_manual/README.rst @@ -7,7 +7,7 @@ Account analytic distribution manual !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:653ab616c32f188e47837795b0b299865043f6c53899f0a1b92d6087177f94c5 + !! source digest: sha256:aecf27efa35344e48b3446192d23b39eacd077c07e737f067b2eb4a46179f2b3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/account_analytic_distribution_manual/__manifest__.py b/account_analytic_distribution_manual/__manifest__.py index 28b8d1e543..aeb4970554 100644 --- a/account_analytic_distribution_manual/__manifest__.py +++ b/account_analytic_distribution_manual/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Account analytic distribution manual", "summary": "Account analytic distribution manual", - "version": "16.0.2.1.0", + "version": "16.0.2.2.0", "license": "AGPL-3", "website": "https://github.com/OCA/account-analytic", "author": "Tecnativa, Odoo Community Association (OCA)", diff --git a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot index 4be5e9f8db..b305d29178 100644 --- a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot +++ b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot @@ -55,6 +55,11 @@ msgstr "" msgid "Analytic Precision" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +msgid "Analytic distribution (importable)" +msgstr "" + #. module: account_analytic_distribution_manual #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_search @@ -81,6 +86,14 @@ msgstr "" msgid "Created on" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +msgid "" +"Defining this field, it will set the analytical distribution in JSON format," +" but using the analytic accounts names as keys of the dictionary, so it " +"eases the human input." +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__display_name msgid "Display Name" diff --git a/account_analytic_distribution_manual/i18n/es.po b/account_analytic_distribution_manual/i18n/es.po index 13c3976369..5892273b81 100644 --- a/account_analytic_distribution_manual/i18n/es.po +++ b/account_analytic_distribution_manual/i18n/es.po @@ -60,6 +60,11 @@ msgstr "" msgid "Analytic Precision" msgstr "Precisión Analítica" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +msgid "Analytic distribution (importable)" +msgstr "" + #. module: account_analytic_distribution_manual #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_search @@ -86,6 +91,14 @@ msgstr "Creado por" msgid "Created on" msgstr "Creado el" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +msgid "" +"Defining this field, it will set the analytical distribution in JSON format, " +"but using the analytic accounts names as keys of the dictionary, so it eases " +"the human input." +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__display_name msgid "Display Name" diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po index 824a23327f..aa4efe28e9 100644 --- a/account_analytic_distribution_manual/i18n/it.po +++ b/account_analytic_distribution_manual/i18n/it.po @@ -58,6 +58,11 @@ msgstr "Mixin analitica" msgid "Analytic Precision" msgstr "Precisione analitica" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +msgid "Analytic distribution (importable)" +msgstr "" + #. module: account_analytic_distribution_manual #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_search @@ -84,6 +89,14 @@ msgstr "Creato da" msgid "Created on" msgstr "Creato il" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +msgid "" +"Defining this field, it will set the analytical distribution in JSON format, " +"but using the analytic accounts names as keys of the dictionary, so it eases " +"the human input." +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__display_name msgid "Display Name" diff --git a/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py b/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py index 2d10a941cb..8d0502e873 100644 --- a/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py +++ b/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py @@ -1,4 +1,5 @@ # Copyright 2024 Tecnativa - Carlos Lopez +# Copyright 2024 Tecnativa - Víctor Martínez # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import _, api, fields, models @@ -10,6 +11,15 @@ class AccountAnalyticDistributionManual(models.Model): name = fields.Char(required=True) active = fields.Boolean(default=True) + analytic_distribution_import = fields.Json( + compute="_compute_analytic_distribution_import", + inverse="_inverse_analytic_distribution_import", + readonly=False, + string="Analytic distribution (importable)", + help="Defining this field, it will set the analytical distribution in JSON " + "format, but using the analytic accounts names as keys of the dictionary, so it " + "eases the human input.", + ) company_id = fields.Many2one( "res.company", required=True, default=lambda self: self.env.company ) @@ -22,6 +32,34 @@ class AccountAnalyticDistributionManual(models.Model): ), ] + @api.depends("analytic_distribution") + def _compute_analytic_distribution_import(self): + aa_model = self.env["account.analytic.account"] + for item in self: + data = {} + distribution = item.analytic_distribution + for key in list(distribution.keys()): + aa_record = aa_model.browse(int(key)) + data[aa_record.name] = distribution[key] + item.analytic_distribution_import = data + + def _inverse_analytic_distribution_import(self): + """Convert the json to the appropriate value of analytic_distribution.""" + aa_model = self.env["account.analytic.account"] + for item in self: + base_domain = [("company_id", "in", item.company_id.ids + [False])] + data = {} + new_distribution = item.analytic_distribution_import + for key in list(new_distribution.keys()): + domain = base_domain + [("name", "=", key)] + aa_record = aa_model.search( + domain, + limit=1, + ) + if aa_record: + data[aa_record.id] = new_distribution[key] + item.analytic_distribution = data + @api.returns("self", lambda value: value.id) def copy(self, default=None): default = dict(default or {}) diff --git a/account_analytic_distribution_manual/static/description/index.html b/account_analytic_distribution_manual/static/description/index.html index f47e9359b9..a1a3ec7a12 100644 --- a/account_analytic_distribution_manual/static/description/index.html +++ b/account_analytic_distribution_manual/static/description/index.html @@ -367,7 +367,7 @@

    Account analytic distribution manual

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:653ab616c32f188e47837795b0b299865043f6c53899f0a1b92d6087177f94c5 +!! source digest: sha256:aecf27efa35344e48b3446192d23b39eacd077c07e737f067b2eb4a46179f2b3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

    This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts.

    diff --git a/account_analytic_distribution_manual/tests/__init__.py b/account_analytic_distribution_manual/tests/__init__.py index add5eb092d..14e81a6de9 100644 --- a/account_analytic_distribution_manual/tests/__init__.py +++ b/account_analytic_distribution_manual/tests/__init__.py @@ -1,3 +1,2 @@ -from . import common from . import test_analytic_distribution_manual from . import test_analytic_distribution_manual_tour diff --git a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py index b50c10041c..ba062b1d6b 100644 --- a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py +++ b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py @@ -1,4 +1,5 @@ # Copyright 2024 Tecnativa - Carlos Lopez +# Copyright 2024 Tecnativa - Víctor Martínez # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) from psycopg2.errors import UniqueViolation @@ -24,3 +25,44 @@ def test_copy_manual_distribution(self): "name": "Manual Distribution 1", } ) + + def test_manual_distribution_analytic_distribution_text(self): + self.analytic_account_a1.name = "test-1" + aa_1 = self.analytic_account_a1 + self.analytic_account_a2.name = "test-2" + aa_2 = self.analytic_account_a2 + self.assertEqual( + self.distribution_1.analytic_distribution_import, + {"test-1": 40.0, "test-2": 60.0}, + ) + # Set analytic_distribution_import field + self.distribution_1.analytic_distribution_import = { + "test-1": 20.0, + "test-2": 80.0, + } + self.assertEqual( + self.distribution_1.analytic_distribution, + {str(aa_1.id): 20.0, str(aa_2.id): 80.0}, + ) + # Remove aa_2 + self.distribution_1.analytic_distribution_import = {"test-1": 40.0} + self.assertEqual( + self.distribution_1.analytic_distribution, {str(aa_1.id): 40.0} + ) + # Create aa_2 again + self.distribution_1.analytic_distribution_import = { + "test-1": 40.0, + "test-2": 60.0, + } + self.assertEqual( + self.distribution_1.analytic_distribution, + {str(aa_1.id): 40.0, str(aa_2.id): 60.0}, + ) + # Update with an "incorrect name" + self.distribution_1.analytic_distribution_import = { + "test-1": 40.0, + "test-3": 60.0, + } + self.assertEqual( + self.distribution_1.analytic_distribution, {str(aa_1.id): 40.0} + ) From 6b67d3844ac318fdf64c55c903dda464c95468cb Mon Sep 17 00:00:00 2001 From: mymage Date: Fri, 6 Sep 2024 12:16:50 +0000 Subject: [PATCH 12/18] Translated using Weblate (Italian) Currently translated at 100.0% (29 of 29 strings) Translation: account-analytic-16.0/account-analytic-16.0-account_analytic_distribution_manual Translate-URL: https://translation.odoo-community.org/projects/account-analytic-16-0/account-analytic-16-0-account_analytic_distribution_manual/it/ --- account_analytic_distribution_manual/i18n/it.po | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po index aa4efe28e9..f2bdcee555 100644 --- a/account_analytic_distribution_manual/i18n/it.po +++ b/account_analytic_distribution_manual/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-08-29 13:06+0000\n" +"PO-Revision-Date: 2024-09-06 15:06+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -61,7 +61,7 @@ msgstr "Precisione analitica" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import msgid "Analytic distribution (importable)" -msgstr "" +msgstr "Distribuzione analitica (importabile)" #. module: account_analytic_distribution_manual #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form @@ -96,6 +96,9 @@ msgid "" "but using the analytic accounts names as keys of the dictionary, so it eases " "the human input." msgstr "" +"Definendo questo campo, verrà impostata la distribuzione analitica in " +"formato JSON, ma utilizzando i nomi degli account analitici come chiavi del " +"dizionario, in modo da semplificare l'inserimento umano." #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__display_name From aff037aff673b4f70b73dbe13ffe664ad15fbb4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Mon, 9 Sep 2024 09:23:44 +0200 Subject: [PATCH 13/18] [IMP] account_analytic_distribution_manual: Add manual_distribution_id field to analytic items TT50751 --- .../README.rst | 2 +- .../__manifest__.py | 3 ++- account_analytic_distribution_manual/hooks.py | 11 ++++++++++ .../account_analytic_distribution_manual.pot | 15 +++++++++++++ .../i18n/es.po | 15 +++++++++++++ .../i18n/it.po | 15 +++++++++++++ .../migrations/16.0.2.3.0/post-migration.py | 19 ++++++++++++++++ .../models/__init__.py | 2 ++ .../models/account_analytic_line.py | 12 ++++++++++ .../models/account_move_line.py | 14 ++++++++++++ .../static/description/index.html | 2 +- .../test_analytic_distribution_manual.py | 20 ++++++++++++++++- .../views/account_analytic_line_views.xml | 22 +++++++++++++++++++ 13 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 account_analytic_distribution_manual/migrations/16.0.2.3.0/post-migration.py create mode 100644 account_analytic_distribution_manual/models/account_analytic_line.py create mode 100644 account_analytic_distribution_manual/models/account_move_line.py create mode 100644 account_analytic_distribution_manual/views/account_analytic_line_views.xml diff --git a/account_analytic_distribution_manual/README.rst b/account_analytic_distribution_manual/README.rst index 4711e0050f..0bff121565 100644 --- a/account_analytic_distribution_manual/README.rst +++ b/account_analytic_distribution_manual/README.rst @@ -7,7 +7,7 @@ Account analytic distribution manual !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:aecf27efa35344e48b3446192d23b39eacd077c07e737f067b2eb4a46179f2b3 + !! source digest: sha256:a5311932734b13be15d7ea90c7d10b5330e734b8b582126f30f01558f9d571c6 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/account_analytic_distribution_manual/__manifest__.py b/account_analytic_distribution_manual/__manifest__.py index aeb4970554..b7fc4285d4 100644 --- a/account_analytic_distribution_manual/__manifest__.py +++ b/account_analytic_distribution_manual/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Account analytic distribution manual", "summary": "Account analytic distribution manual", - "version": "16.0.2.2.0", + "version": "16.0.2.3.0", "license": "AGPL-3", "website": "https://github.com/OCA/account-analytic", "author": "Tecnativa, Odoo Community Association (OCA)", @@ -13,6 +13,7 @@ "security/analytic_security.xml", "security/ir.model.access.csv", "views/account_analytic_distribution_manual_views.xml", + "views/account_analytic_line_views.xml", ], "assets": { "web.assets_backend": [ diff --git a/account_analytic_distribution_manual/hooks.py b/account_analytic_distribution_manual/hooks.py index e7b8184cba..ac4596f6b6 100644 --- a/account_analytic_distribution_manual/hooks.py +++ b/account_analytic_distribution_manual/hooks.py @@ -182,3 +182,14 @@ def post_init_hook(cr, registry): """, (distribution_map[tag_id].id, res_id), ) + # Define the value of manual_distribution_id in the line items + env.cr.execute( + """ + UPDATE account_analytic_line AS aal + SET manual_distribution_id = aml.manual_distribution_id + FROM account_move_line AS aml + WHERE aal.move_line_id = aml.id + AND aml.manual_distribution_id IS NOT NULL + AND aal.manual_distribution_id IS NULL + """, + ) diff --git a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot index b305d29178..35356fcf20 100644 --- a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot +++ b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot @@ -45,6 +45,11 @@ msgstr "" msgid "Analytic Distribution Search" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_analytic_line +msgid "Analytic Line" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model,name:account_analytic_distribution_manual.model_analytic_mixin msgid "Analytic Mixin" @@ -60,6 +65,11 @@ msgstr "" msgid "Analytic distribution (importable)" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_line__manual_distribution_id +msgid "Analytic distribution manual" +msgstr "" + #. module: account_analytic_distribution_manual #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_search @@ -109,6 +119,11 @@ msgstr "" msgid "Invoices Statistics" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_move_line +msgid "Journal Item" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual____last_update msgid "Last Modified on" diff --git a/account_analytic_distribution_manual/i18n/es.po b/account_analytic_distribution_manual/i18n/es.po index 5892273b81..de436b7dcc 100644 --- a/account_analytic_distribution_manual/i18n/es.po +++ b/account_analytic_distribution_manual/i18n/es.po @@ -50,6 +50,11 @@ msgstr "Analítico" msgid "Analytic Distribution Search" msgstr "Buscar Distribución Analítica" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_analytic_line +msgid "Analytic Line" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model,name:account_analytic_distribution_manual.model_analytic_mixin msgid "Analytic Mixin" @@ -65,6 +70,11 @@ msgstr "Precisión Analítica" msgid "Analytic distribution (importable)" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_line__manual_distribution_id +msgid "Analytic distribution manual" +msgstr "" + #. module: account_analytic_distribution_manual #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_search @@ -114,6 +124,11 @@ msgstr "" msgid "Invoices Statistics" msgstr "" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_move_line +msgid "Journal Item" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual____last_update msgid "Last Modified on" diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po index f2bdcee555..853e181505 100644 --- a/account_analytic_distribution_manual/i18n/it.po +++ b/account_analytic_distribution_manual/i18n/it.po @@ -48,6 +48,11 @@ msgstr "Analitico" msgid "Analytic Distribution Search" msgstr "Ricerca distribuzione analitica" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_analytic_line +msgid "Analytic Line" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model,name:account_analytic_distribution_manual.model_analytic_mixin msgid "Analytic Mixin" @@ -63,6 +68,11 @@ msgstr "Precisione analitica" msgid "Analytic distribution (importable)" msgstr "Distribuzione analitica (importabile)" +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_line__manual_distribution_id +msgid "Analytic distribution manual" +msgstr "" + #. module: account_analytic_distribution_manual #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_search @@ -115,6 +125,11 @@ msgstr "ID" msgid "Invoices Statistics" msgstr "Statistiche fatture" +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_move_line +msgid "Journal Item" +msgstr "" + #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual____last_update msgid "Last Modified on" diff --git a/account_analytic_distribution_manual/migrations/16.0.2.3.0/post-migration.py b/account_analytic_distribution_manual/migrations/16.0.2.3.0/post-migration.py new file mode 100644 index 0000000000..c564a8b3d7 --- /dev/null +++ b/account_analytic_distribution_manual/migrations/16.0.2.3.0/post-migration.py @@ -0,0 +1,19 @@ +# Copyright 2024 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.logged_query( + env.cr, + """ + UPDATE account_analytic_line AS aal + SET manual_distribution_id = aml.manual_distribution_id + FROM account_move_line AS aml + WHERE aal.move_line_id = aml.id + AND aml.manual_distribution_id IS NOT NULL + AND aal.manual_distribution_id IS NULL + """, + ) diff --git a/account_analytic_distribution_manual/models/__init__.py b/account_analytic_distribution_manual/models/__init__.py index 1b1cb07792..acc328512d 100644 --- a/account_analytic_distribution_manual/models/__init__.py +++ b/account_analytic_distribution_manual/models/__init__.py @@ -1,3 +1,5 @@ from . import account_analytic_distribution_manual +from . import account_analytic_line +from . import account_move_line from . import analytic_mixin from . import base diff --git a/account_analytic_distribution_manual/models/account_analytic_line.py b/account_analytic_distribution_manual/models/account_analytic_line.py new file mode 100644 index 0000000000..d42ed82304 --- /dev/null +++ b/account_analytic_distribution_manual/models/account_analytic_line.py @@ -0,0 +1,12 @@ +# Copyright 2024 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class AccountAnalyticLine(models.Model): + _inherit = "account.analytic.line" + + manual_distribution_id = fields.Many2one( + comodel_name="account.analytic.distribution.manual", + string="Analytic distribution manual", + ) diff --git a/account_analytic_distribution_manual/models/account_move_line.py b/account_analytic_distribution_manual/models/account_move_line.py new file mode 100644 index 0000000000..d287baa4e7 --- /dev/null +++ b/account_analytic_distribution_manual/models/account_move_line.py @@ -0,0 +1,14 @@ +# Copyright 2024 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import models + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + def _prepare_analytic_lines(self): + vals = super()._prepare_analytic_lines() + if self.manual_distribution_id: + for val in vals: + val.update({"manual_distribution_id": self.manual_distribution_id.id}) + return vals diff --git a/account_analytic_distribution_manual/static/description/index.html b/account_analytic_distribution_manual/static/description/index.html index a1a3ec7a12..788db856e2 100644 --- a/account_analytic_distribution_manual/static/description/index.html +++ b/account_analytic_distribution_manual/static/description/index.html @@ -367,7 +367,7 @@

    Account analytic distribution manual

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:aecf27efa35344e48b3446192d23b39eacd077c07e737f067b2eb4a46179f2b3 +!! source digest: sha256:a5311932734b13be15d7ea90c7d10b5330e734b8b582126f30f01558f9d571c6 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

    This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts.

    diff --git a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py index ba062b1d6b..137e77ee75 100644 --- a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py +++ b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) from psycopg2.errors import UniqueViolation -from odoo.tests import tagged +from odoo.tests import Form, tagged from odoo.tools import mute_logger from odoo.addons.account_analytic_distribution_manual.tests.common import ( @@ -26,6 +26,24 @@ def test_copy_manual_distribution(self): } ) + def test_manual_distribution_analytic_distribution_process(self): + invoice_form = Form( + self.env["account.move"].with_context(default_move_type="out_invoice") + ) + invoice_form.partner_id = self.partner_a + with invoice_form.invoice_line_ids.new() as line_form: + line_form.product_id = self.product_a + line_form.manual_distribution_id = self.distribution_1 + invoice = invoice_form.save() + invoice_line = invoice.invoice_line_ids + invoice_line.analytic_distribution = self.distribution_1.analytic_distribution + invoice.action_post() + self.assertTrue(len(invoice_line.analytic_line_ids), 2) + self.assertEqual( + invoice_line.analytic_line_ids.mapped("manual_distribution_id"), + self.distribution_1, + ) + def test_manual_distribution_analytic_distribution_text(self): self.analytic_account_a1.name = "test-1" aa_1 = self.analytic_account_a1 diff --git a/account_analytic_distribution_manual/views/account_analytic_line_views.xml b/account_analytic_distribution_manual/views/account_analytic_line_views.xml new file mode 100644 index 0000000000..7dad33c2df --- /dev/null +++ b/account_analytic_distribution_manual/views/account_analytic_line_views.xml @@ -0,0 +1,22 @@ + + + account.analytic.line.tree + account.analytic.line + + + + + + + + + account.analytic.line.form + account.analytic.line + + + + + + + + From 01fe9766b29b8f060db67fb9077faef30a97704f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Tue, 10 Sep 2024 07:39:19 +0000 Subject: [PATCH 14/18] Translated using Weblate (Spanish) Currently translated at 75.0% (24 of 32 strings) Translation: account-analytic-16.0/account-analytic-16.0-account_analytic_distribution_manual Translate-URL: https://translation.odoo-community.org/projects/account-analytic-16-0/account-analytic-16-0-account_analytic_distribution_manual/es/ --- account_analytic_distribution_manual/i18n/es.po | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/account_analytic_distribution_manual/i18n/es.po b/account_analytic_distribution_manual/i18n/es.po index de436b7dcc..777644858e 100644 --- a/account_analytic_distribution_manual/i18n/es.po +++ b/account_analytic_distribution_manual/i18n/es.po @@ -7,9 +7,8 @@ msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-29 06:51-0500\n" -"PO-Revision-Date: 2024-08-02 14:08+0000\n" -"Last-Translator: carolinafernandez-tecnativa \n" +"PO-Revision-Date: 2024-09-10 10:06+0000\n" +"Last-Translator: Víctor Martínez \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" @@ -73,7 +72,7 @@ msgstr "" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_line__manual_distribution_id msgid "Analytic distribution manual" -msgstr "" +msgstr "Distribución Analítica Manual" #. module: account_analytic_distribution_manual #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form @@ -117,7 +116,7 @@ msgstr "Nombre mostrado" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__id msgid "ID" -msgstr "" +msgstr "ID" #. module: account_analytic_distribution_manual #: model:ir.model,name:account_analytic_distribution_manual.model_account_invoice_report From 2b1bd2b95bafa79da3d5523def6f2b3c662e553b Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 11 Sep 2024 06:56:24 +0000 Subject: [PATCH 15/18] Translated using Weblate (Italian) Currently translated at 100.0% (32 of 32 strings) Translation: account-analytic-16.0/account-analytic-16.0-account_analytic_distribution_manual Translate-URL: https://translation.odoo-community.org/projects/account-analytic-16-0/account-analytic-16-0-account_analytic_distribution_manual/it/ --- account_analytic_distribution_manual/i18n/it.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po index 853e181505..964f9e4cdc 100644 --- a/account_analytic_distribution_manual/i18n/it.po +++ b/account_analytic_distribution_manual/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-09-06 15:06+0000\n" +"PO-Revision-Date: 2024-09-11 09:06+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -51,7 +51,7 @@ msgstr "Ricerca distribuzione analitica" #. module: account_analytic_distribution_manual #: model:ir.model,name:account_analytic_distribution_manual.model_account_analytic_line msgid "Analytic Line" -msgstr "" +msgstr "Riga analitica" #. module: account_analytic_distribution_manual #: model:ir.model,name:account_analytic_distribution_manual.model_analytic_mixin @@ -71,7 +71,7 @@ msgstr "Distribuzione analitica (importabile)" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_line__manual_distribution_id msgid "Analytic distribution manual" -msgstr "" +msgstr "Distribuzione analitica manuale" #. module: account_analytic_distribution_manual #: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form @@ -128,7 +128,7 @@ msgstr "Statistiche fatture" #. module: account_analytic_distribution_manual #: model:ir.model,name:account_analytic_distribution_manual.model_account_move_line msgid "Journal Item" -msgstr "" +msgstr "Movimento contabile" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual____last_update From 67414c67fc0e4ca511d45fe55554ad75493e08d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Mon, 23 Sep 2024 13:50:33 +0200 Subject: [PATCH 16/18] [IMP] account_analytic_distribution_manual: Add extra json field for export/import to analytic.mixin Move the functionality to the analytic.mixin model so that it can also be used in account.move.line records TT50944 --- .../README.rst | 2 +- .../__manifest__.py | 2 +- .../account_analytic_distribution_manual.pot | 22 ++++++++++ .../i18n/es.po | 22 ++++++++++ .../i18n/it.po | 22 ++++++++++ .../account_analytic_distribution_manual.py | 37 ---------------- .../models/analytic_mixin.py | 43 ++++++++++++++++++- .../static/description/index.html | 2 +- .../test_analytic_distribution_manual.py | 34 ++++++++++++++- 9 files changed, 144 insertions(+), 42 deletions(-) diff --git a/account_analytic_distribution_manual/README.rst b/account_analytic_distribution_manual/README.rst index 0bff121565..91f9bf703d 100644 --- a/account_analytic_distribution_manual/README.rst +++ b/account_analytic_distribution_manual/README.rst @@ -7,7 +7,7 @@ Account analytic distribution manual !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:a5311932734b13be15d7ea90c7d10b5330e734b8b582126f30f01558f9d571c6 + !! source digest: sha256:2e94cdbcdd48a9f51651a3e52c44e93e4e43fbe151a46aa14b15cd0d98e0d9bf !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/account_analytic_distribution_manual/__manifest__.py b/account_analytic_distribution_manual/__manifest__.py index b7fc4285d4..7f6a1daa62 100644 --- a/account_analytic_distribution_manual/__manifest__.py +++ b/account_analytic_distribution_manual/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Account analytic distribution manual", "summary": "Account analytic distribution manual", - "version": "16.0.2.3.0", + "version": "16.0.2.4.0", "license": "AGPL-3", "website": "https://github.com/OCA/account-analytic", "author": "Tecnativa, Odoo Community Association (OCA)", diff --git a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot index 35356fcf20..0445a05641 100644 --- a/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot +++ b/account_analytic_distribution_manual/i18n/account_analytic_distribution_manual.pot @@ -62,6 +62,17 @@ msgstr "" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_model__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_reconcile_model_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_analytic_mixin__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense_split__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_purchase_order_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_sale_order_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__analytic_distribution_import msgid "Analytic distribution (importable)" msgstr "" @@ -98,6 +109,17 @@ msgstr "" #. module: account_analytic_distribution_manual #: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_analytic_distribution_model__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_move_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_reconcile_model_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_analytic_mixin__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_hr_expense__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_hr_expense_split__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_purchase_order_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_sale_order_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_move__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_move_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_scrap__analytic_distribution_import msgid "" "Defining this field, it will set the analytical distribution in JSON format," " but using the analytic accounts names as keys of the dictionary, so it " diff --git a/account_analytic_distribution_manual/i18n/es.po b/account_analytic_distribution_manual/i18n/es.po index 777644858e..7e04362799 100644 --- a/account_analytic_distribution_manual/i18n/es.po +++ b/account_analytic_distribution_manual/i18n/es.po @@ -66,6 +66,17 @@ msgstr "Precisión Analítica" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_model__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_reconcile_model_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_analytic_mixin__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense_split__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_purchase_order_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_sale_order_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__analytic_distribution_import msgid "Analytic distribution (importable)" msgstr "" @@ -102,6 +113,17 @@ msgstr "Creado el" #. module: account_analytic_distribution_manual #: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_analytic_distribution_model__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_move_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_reconcile_model_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_analytic_mixin__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_hr_expense__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_hr_expense_split__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_purchase_order_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_sale_order_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_move__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_move_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_scrap__analytic_distribution_import msgid "" "Defining this field, it will set the analytical distribution in JSON format, " "but using the analytic accounts names as keys of the dictionary, so it eases " diff --git a/account_analytic_distribution_manual/i18n/it.po b/account_analytic_distribution_manual/i18n/it.po index 964f9e4cdc..c0c4f968b5 100644 --- a/account_analytic_distribution_manual/i18n/it.po +++ b/account_analytic_distribution_manual/i18n/it.po @@ -65,6 +65,17 @@ msgstr "Precisione analitica" #. module: account_analytic_distribution_manual #: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_model__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_reconcile_model_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_analytic_mixin__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_hr_expense_split__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_purchase_order_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_sale_order_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__analytic_distribution_import msgid "Analytic distribution (importable)" msgstr "Distribuzione analitica (importabile)" @@ -101,6 +112,17 @@ msgstr "Creato il" #. module: account_analytic_distribution_manual #: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_analytic_distribution_model__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_move_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_reconcile_model_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_analytic_mixin__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_hr_expense__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_hr_expense_split__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_purchase_order_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_sale_order_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_move__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_move_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_scrap__analytic_distribution_import msgid "" "Defining this field, it will set the analytical distribution in JSON format, " "but using the analytic accounts names as keys of the dictionary, so it eases " diff --git a/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py b/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py index 8d0502e873..f11f284941 100644 --- a/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py +++ b/account_analytic_distribution_manual/models/account_analytic_distribution_manual.py @@ -11,15 +11,6 @@ class AccountAnalyticDistributionManual(models.Model): name = fields.Char(required=True) active = fields.Boolean(default=True) - analytic_distribution_import = fields.Json( - compute="_compute_analytic_distribution_import", - inverse="_inverse_analytic_distribution_import", - readonly=False, - string="Analytic distribution (importable)", - help="Defining this field, it will set the analytical distribution in JSON " - "format, but using the analytic accounts names as keys of the dictionary, so it " - "eases the human input.", - ) company_id = fields.Many2one( "res.company", required=True, default=lambda self: self.env.company ) @@ -32,34 +23,6 @@ class AccountAnalyticDistributionManual(models.Model): ), ] - @api.depends("analytic_distribution") - def _compute_analytic_distribution_import(self): - aa_model = self.env["account.analytic.account"] - for item in self: - data = {} - distribution = item.analytic_distribution - for key in list(distribution.keys()): - aa_record = aa_model.browse(int(key)) - data[aa_record.name] = distribution[key] - item.analytic_distribution_import = data - - def _inverse_analytic_distribution_import(self): - """Convert the json to the appropriate value of analytic_distribution.""" - aa_model = self.env["account.analytic.account"] - for item in self: - base_domain = [("company_id", "in", item.company_id.ids + [False])] - data = {} - new_distribution = item.analytic_distribution_import - for key in list(new_distribution.keys()): - domain = base_domain + [("name", "=", key)] - aa_record = aa_model.search( - domain, - limit=1, - ) - if aa_record: - data[aa_record.id] = new_distribution[key] - item.analytic_distribution = data - @api.returns("self", lambda value: value.id) def copy(self, default=None): default = dict(default or {}) diff --git a/account_analytic_distribution_manual/models/analytic_mixin.py b/account_analytic_distribution_manual/models/analytic_mixin.py index b14d3f653b..de7ce15392 100644 --- a/account_analytic_distribution_manual/models/analytic_mixin.py +++ b/account_analytic_distribution_manual/models/analytic_mixin.py @@ -1,9 +1,50 @@ # Copyright 2024 Tecnativa - Carlos Lopez +# Copyright 2024 Tecnativa - Víctor Martínez # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import fields, models +from odoo import api, fields, models class AnalyticMixin(models.AbstractModel): _inherit = "analytic.mixin" manual_distribution_id = fields.Many2one("account.analytic.distribution.manual") + analytic_distribution_import = fields.Json( + compute="_compute_analytic_distribution_import", + inverse="_inverse_analytic_distribution_import", + readonly=False, + string="Analytic distribution (importable)", + help="Defining this field, it will set the analytical distribution in JSON " + "format, but using the analytic accounts names as keys of the dictionary, so it " + "eases the human input.", + ) + + @api.depends("analytic_distribution") + def _compute_analytic_distribution_import(self): + aa_model = self.env["account.analytic.account"] + for item in self: + data = {} + distribution = item.analytic_distribution or {} + for key in list(distribution.keys()): + aa_record = aa_model.browse(int(key)) + data[aa_record.name] = distribution[key] + item.analytic_distribution_import = data + + def _inverse_analytic_distribution_import(self): + """Convert the json to the appropriate value of analytic_distribution.""" + aa_model = self.env["account.analytic.account"] + for item in self: + company = ( + item.company_id if "company_id" in item._fields else self.env.company + ) + base_domain = [("company_id", "in", company.ids + [False])] + data = {} + new_distribution = item.analytic_distribution_import or {} + for key in list(new_distribution.keys()): + domain = base_domain + [("name", "=", key)] + aa_record = aa_model.search( + domain, + limit=1, + ) + if aa_record: + data[aa_record.id] = new_distribution[key] + item.analytic_distribution = data diff --git a/account_analytic_distribution_manual/static/description/index.html b/account_analytic_distribution_manual/static/description/index.html index 788db856e2..d1fe14bf4a 100644 --- a/account_analytic_distribution_manual/static/description/index.html +++ b/account_analytic_distribution_manual/static/description/index.html @@ -367,7 +367,7 @@

    Account analytic distribution manual

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:a5311932734b13be15d7ea90c7d10b5330e734b8b582126f30f01558f9d571c6 +!! source digest: sha256:2e94cdbcdd48a9f51651a3e52c44e93e4e43fbe151a46aa14b15cd0d98e0d9bf !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

    This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts.

    diff --git a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py index 137e77ee75..d222685855 100644 --- a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py +++ b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py @@ -26,7 +26,7 @@ def test_copy_manual_distribution(self): } ) - def test_manual_distribution_analytic_distribution_process(self): + def test_manual_distribution_analytic_distribution_process_01(self): invoice_form = Form( self.env["account.move"].with_context(default_move_type="out_invoice") ) @@ -44,6 +44,38 @@ def test_manual_distribution_analytic_distribution_process(self): self.distribution_1, ) + def test_manual_distribution_analytic_distribution_process_02(self): + invoice_form = Form( + self.env["account.move"].with_context(default_move_type="out_invoice") + ) + invoice_form.partner_id = self.partner_a + with invoice_form.invoice_line_ids.new() as line_form: + line_form.product_id = self.product_a + invoice = invoice_form.save() + invoice_line = invoice.invoice_line_ids + invoice_line.manual_distribution_id = self.distribution_1 + self.analytic_account_a1.name = "test-1" + aa_1 = self.analytic_account_a1 + self.analytic_account_a2.name = "test-2" + aa_2 = self.analytic_account_a2 + invoice_line.analytic_distribution_import = { + "test-1": 20.0, + "test-2": 80.0, + } + self.assertEqual( + invoice_line.analytic_distribution, + {str(aa_1.id): 20.0, str(aa_2.id): 80.0}, + ) + invoice.action_post() + self.assertTrue(len(invoice_line.analytic_line_ids), 2) + self.assertEqual( + invoice_line.analytic_line_ids.mapped("manual_distribution_id"), + self.distribution_1, + ) + accounts = invoice_line.analytic_line_ids.mapped("account_id") + self.assertIn(aa_1, accounts) + self.assertIn(aa_2, accounts) + def test_manual_distribution_analytic_distribution_text(self): self.analytic_account_a1.name = "test-1" aa_1 = self.analytic_account_a1 From ade53217aec9909f081ad02e8fc8ba6eefddabda Mon Sep 17 00:00:00 2001 From: bobrador Date: Wed, 9 Oct 2024 15:16:42 +0200 Subject: [PATCH 17/18] [IMP] account_analytic_distribution_manual: pre-commit auto fixes --- .../README.rst | 42 ++++++++++--------- account_analytic_distribution_manual/hooks.py | 3 +- .../models/analytic_mixin.py | 4 +- .../models/base.py | 5 ++- .../pyproject.toml | 3 ++ .../readme/CONFIGURE.md | 3 ++ .../readme/CONFIGURE.rst | 3 -- .../readme/CONTRIBUTORS.md | 2 + .../readme/CONTRIBUTORS.rst | 3 -- .../{DESCRIPTION.rst => DESCRIPTION.md} | 3 +- .../readme/ROADMAP.md | 2 + .../readme/ROADMAP.rst | 1 - .../readme/USAGE.md | 6 +++ .../readme/USAGE.rst | 4 -- .../static/description/index.html | 21 ++++++---- 15 files changed, 61 insertions(+), 44 deletions(-) create mode 100644 account_analytic_distribution_manual/pyproject.toml create mode 100644 account_analytic_distribution_manual/readme/CONFIGURE.md delete mode 100644 account_analytic_distribution_manual/readme/CONFIGURE.rst create mode 100644 account_analytic_distribution_manual/readme/CONTRIBUTORS.md delete mode 100644 account_analytic_distribution_manual/readme/CONTRIBUTORS.rst rename account_analytic_distribution_manual/readme/{DESCRIPTION.rst => DESCRIPTION.md} (50%) create mode 100644 account_analytic_distribution_manual/readme/ROADMAP.md delete mode 100644 account_analytic_distribution_manual/readme/ROADMAP.rst create mode 100644 account_analytic_distribution_manual/readme/USAGE.md delete mode 100644 account_analytic_distribution_manual/readme/USAGE.rst diff --git a/account_analytic_distribution_manual/README.rst b/account_analytic_distribution_manual/README.rst index 91f9bf703d..97d42c443a 100644 --- a/account_analytic_distribution_manual/README.rst +++ b/account_analytic_distribution_manual/README.rst @@ -17,18 +17,19 @@ Account analytic distribution manual :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--analytic-lightgray.png?logo=github - :target: https://github.com/OCA/account-analytic/tree/16.0/account_analytic_distribution_manual + :target: https://github.com/OCA/account-analytic/tree/17.0/account_analytic_distribution_manual :alt: OCA/account-analytic .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/account-analytic-16-0/account-analytic-16-0-account_analytic_distribution_manual + :target: https://translation.odoo-community.org/projects/account-analytic-17-0/account-analytic-17-0-account_analytic_distribution_manual :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/account-analytic&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-analytic&target_branch=17.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| -This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts. +This module provides an easy way to quickly autocomplete analytic +accounts on any model that has a field for analytic accounts. **Table of contents** @@ -38,22 +39,25 @@ This module provides an easy way to quickly autocomplete analytic accounts on an Configuration ============= -#. Go to Invoicing > Configuration > Analytic Accounting > Manual Analytic Distributions -#. Create or edit the necessary records. - +1. Go to Invoicing > Configuration > Analytic Accounting > Manual + Analytic Distributions +2. Create or edit the necessary records. Usage ===== -#. Go to Invoicing > Customer > Invoices -#. Open or create a invoice -#. On the invoice line, select the analytic account. A new field labeled "Manual Distribution" should appear at the top. -#. Select a record from the list, and it will be added to the distribution and the invoice lines. +1. Go to Invoicing > Customer > Invoices +2. Open or create a invoice +3. On the invoice line, select the analytic account. A new field labeled + "Manual Distribution" should appear at the top. +4. Select a record from the list, and it will be added to the + distribution and the invoice lines. Known issues / Roadmap ====================== -Compatibility with `Analytic Distribution Models` to use Manual Distribution as Default values +Compatibility with Analytic Distribution Models to use Manual +Distribution as Default values Bug Tracker =========== @@ -61,7 +65,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 to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -69,19 +73,19 @@ Credits ======= Authors -~~~~~~~ +------- * Tecnativa Contributors -~~~~~~~~~~~~ +------------ -* Tecnativa (https://www.tecnativa.com): +- Tecnativa (https://www.tecnativa.com): - * Carlos Lopez + - Carlos Lopez Maintainers -~~~~~~~~~~~ +----------- This module is maintained by the OCA. @@ -93,6 +97,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-analytic `_ project on GitHub. +This module is part of the `OCA/account-analytic `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_analytic_distribution_manual/hooks.py b/account_analytic_distribution_manual/hooks.py index ac4596f6b6..2b355c8d9d 100644 --- a/account_analytic_distribution_manual/hooks.py +++ b/account_analytic_distribution_manual/hooks.py @@ -133,7 +133,8 @@ def post_init_hook(cr, registry): FROM counted_tags tag INNER JOIN - account_analytic_distribution distribution ON tag.id = distribution.tag_id; + account_analytic_distribution distribution + ON tag.id = distribution.tag_id; """ env.cr.execute(sql) diff --git a/account_analytic_distribution_manual/models/analytic_mixin.py b/account_analytic_distribution_manual/models/analytic_mixin.py index de7ce15392..607ba16a12 100644 --- a/account_analytic_distribution_manual/models/analytic_mixin.py +++ b/account_analytic_distribution_manual/models/analytic_mixin.py @@ -14,8 +14,8 @@ class AnalyticMixin(models.AbstractModel): readonly=False, string="Analytic distribution (importable)", help="Defining this field, it will set the analytical distribution in JSON " - "format, but using the analytic accounts names as keys of the dictionary, so it " - "eases the human input.", + "format, but using the analytic accounts names as keys of the dictionary, so " + "it eases the human input.", ) @api.depends("analytic_distribution") diff --git a/account_analytic_distribution_manual/models/base.py b/account_analytic_distribution_manual/models/base.py index 0c12ea3840..f03a5396da 100644 --- a/account_analytic_distribution_manual/models/base.py +++ b/account_analytic_distribution_manual/models/base.py @@ -49,7 +49,8 @@ def model_has_field(model): return manual_distribution_field_name in self.env[model]._fields def _merge_view_fields(all_models, new_models): - """Merge new_models into all_models. Both are {modelname(str) ➔ fields(tuple)}.""" + """Merge new_models into all_models. + Both are {modelname(str) ➔ fields(tuple)}.""" for model, view_fields in new_models.items(): if model in all_models: all_models[model] = tuple(set(all_models[model]) | set(view_fields)) @@ -67,7 +68,7 @@ def _merge_view_fields(all_models, new_models): for node in root_node: add_field(node, view_type, result.get("model")) # check fields one2many - for (res_model, field_list) in result["models"].items(): + for res_model, field_list in result["models"].items(): for field_name in field_list: if field_name not in self.env[res_model]._fields: continue diff --git a/account_analytic_distribution_manual/pyproject.toml b/account_analytic_distribution_manual/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/account_analytic_distribution_manual/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/account_analytic_distribution_manual/readme/CONFIGURE.md b/account_analytic_distribution_manual/readme/CONFIGURE.md new file mode 100644 index 0000000000..703da17aab --- /dev/null +++ b/account_analytic_distribution_manual/readme/CONFIGURE.md @@ -0,0 +1,3 @@ +1. Go to Invoicing \> Configuration \> Analytic Accounting \> Manual + Analytic Distributions +2. Create or edit the necessary records. diff --git a/account_analytic_distribution_manual/readme/CONFIGURE.rst b/account_analytic_distribution_manual/readme/CONFIGURE.rst deleted file mode 100644 index e1c510c265..0000000000 --- a/account_analytic_distribution_manual/readme/CONFIGURE.rst +++ /dev/null @@ -1,3 +0,0 @@ -#. Go to Invoicing > Configuration > Analytic Accounting > Manual Analytic Distributions -#. Create or edit the necessary records. - diff --git a/account_analytic_distribution_manual/readme/CONTRIBUTORS.md b/account_analytic_distribution_manual/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..cdd4ae91a8 --- /dev/null +++ b/account_analytic_distribution_manual/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- Tecnativa (): + - Carlos Lopez diff --git a/account_analytic_distribution_manual/readme/CONTRIBUTORS.rst b/account_analytic_distribution_manual/readme/CONTRIBUTORS.rst deleted file mode 100644 index 7227f68b5a..0000000000 --- a/account_analytic_distribution_manual/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,3 +0,0 @@ -* Tecnativa (https://www.tecnativa.com): - - * Carlos Lopez \ No newline at end of file diff --git a/account_analytic_distribution_manual/readme/DESCRIPTION.rst b/account_analytic_distribution_manual/readme/DESCRIPTION.md similarity index 50% rename from account_analytic_distribution_manual/readme/DESCRIPTION.rst rename to account_analytic_distribution_manual/readme/DESCRIPTION.md index d5dd0605c2..63ed554f7c 100644 --- a/account_analytic_distribution_manual/readme/DESCRIPTION.rst +++ b/account_analytic_distribution_manual/readme/DESCRIPTION.md @@ -1 +1,2 @@ -This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts. +This module provides an easy way to quickly autocomplete analytic +accounts on any model that has a field for analytic accounts. diff --git a/account_analytic_distribution_manual/readme/ROADMAP.md b/account_analytic_distribution_manual/readme/ROADMAP.md new file mode 100644 index 0000000000..9cc9d2085e --- /dev/null +++ b/account_analytic_distribution_manual/readme/ROADMAP.md @@ -0,0 +1,2 @@ +Compatibility with Analytic Distribution Models to use Manual +Distribution as Default values diff --git a/account_analytic_distribution_manual/readme/ROADMAP.rst b/account_analytic_distribution_manual/readme/ROADMAP.rst deleted file mode 100644 index bbaa6cd7df..0000000000 --- a/account_analytic_distribution_manual/readme/ROADMAP.rst +++ /dev/null @@ -1 +0,0 @@ -Compatibility with `Analytic Distribution Models` to use Manual Distribution as Default values diff --git a/account_analytic_distribution_manual/readme/USAGE.md b/account_analytic_distribution_manual/readme/USAGE.md new file mode 100644 index 0000000000..f55405cdfc --- /dev/null +++ b/account_analytic_distribution_manual/readme/USAGE.md @@ -0,0 +1,6 @@ +1. Go to Invoicing \> Customer \> Invoices +2. Open or create a invoice +3. On the invoice line, select the analytic account. A new field + labeled "Manual Distribution" should appear at the top. +4. Select a record from the list, and it will be added to the + distribution and the invoice lines. diff --git a/account_analytic_distribution_manual/readme/USAGE.rst b/account_analytic_distribution_manual/readme/USAGE.rst deleted file mode 100644 index 306cd0b876..0000000000 --- a/account_analytic_distribution_manual/readme/USAGE.rst +++ /dev/null @@ -1,4 +0,0 @@ -#. Go to Invoicing > Customer > Invoices -#. Open or create a invoice -#. On the invoice line, select the analytic account. A new field labeled "Manual Distribution" should appear at the top. -#. Select a record from the list, and it will be added to the distribution and the invoice lines. \ No newline at end of file diff --git a/account_analytic_distribution_manual/static/description/index.html b/account_analytic_distribution_manual/static/description/index.html index d1fe14bf4a..fdf96eb14d 100644 --- a/account_analytic_distribution_manual/static/description/index.html +++ b/account_analytic_distribution_manual/static/description/index.html @@ -369,8 +369,9 @@

    Account analytic distribution manual

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:2e94cdbcdd48a9f51651a3e52c44e93e4e43fbe151a46aa14b15cd0d98e0d9bf !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

    Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

    -

    This module provides an easy way to quickly autocomplete analytic accounts on any model that has a field for analytic accounts.

    +

    Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

    +

    This module provides an easy way to quickly autocomplete analytic +accounts on any model that has a field for analytic accounts.

    Table of contents

      @@ -389,7 +390,8 @@

      Account analytic distribution manual

      Configuration

        -
      1. Go to Invoicing > Configuration > Analytic Accounting > Manual Analytic Distributions
      2. +
      3. Go to Invoicing > Configuration > Analytic Accounting > Manual +Analytic Distributions
      4. Create or edit the necessary records.
      @@ -398,20 +400,23 @@

      Usage

      1. Go to Invoicing > Customer > Invoices
      2. Open or create a invoice
      3. -
      4. On the invoice line, select the analytic account. A new field labeled “Manual Distribution” should appear at the top.
      5. -
      6. Select a record from the list, and it will be added to the distribution and the invoice lines.
      7. +
      8. On the invoice line, select the analytic account. A new field labeled +“Manual Distribution” should appear at the top.
      9. +
      10. Select a record from the list, and it will be added to the +distribution and the invoice lines.

    Known issues / Roadmap

    -

    Compatibility with Analytic Distribution Models to use Manual Distribution as Default values

    +

    Compatibility with Analytic Distribution Models to use Manual +Distribution as Default values

    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 to smash it by providing a detailed and welcomed -feedback.

    +feedback.

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

    @@ -440,7 +445,7 @@

    Maintainers

    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-analytic project on GitHub.

    +

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

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

    From 60f773d5965c043dfdf06161d60b234c475e3cf8 Mon Sep 17 00:00:00 2001 From: bobrador Date: Thu, 10 Oct 2024 14:03:42 +0200 Subject: [PATCH 18/18] [MIG] account_analytic_distribution_manual: Migration to 17.0 --- .../README.rst | 4 + .../__init__.py | 1 - .../__manifest__.py | 3 +- account_analytic_distribution_manual/hooks.py | 196 ------------------ .../i18n/ca.po | 196 ++++++++++++++++++ .../migrations/16.0.2.3.0/post-migration.py | 19 -- .../models/base.py | 6 +- .../readme/CONTRIBUTORS.md | 2 + .../reports/invoice_report.py | 4 +- .../static/description/index.html | 4 + .../analytic_distribution.esm.js | 150 +++++++++----- .../analytic_distribution.xml | 3 +- ...ccount_analytic_distribution_manual.esm.js | 43 ++-- .../test_analytic_distribution_manual.py | 14 +- .../test_analytic_distribution_manual_tour.py | 10 +- ...unt_analytic_distribution_manual_views.xml | 2 +- .../views/account_analytic_line_views.xml | 4 +- 17 files changed, 353 insertions(+), 308 deletions(-) delete mode 100644 account_analytic_distribution_manual/hooks.py create mode 100644 account_analytic_distribution_manual/i18n/ca.po delete mode 100644 account_analytic_distribution_manual/migrations/16.0.2.3.0/post-migration.py diff --git a/account_analytic_distribution_manual/README.rst b/account_analytic_distribution_manual/README.rst index 97d42c443a..823882e898 100644 --- a/account_analytic_distribution_manual/README.rst +++ b/account_analytic_distribution_manual/README.rst @@ -84,6 +84,10 @@ Contributors - Carlos Lopez +- APSL - Nagarro + + - Bernat Obrador + Maintainers ----------- diff --git a/account_analytic_distribution_manual/__init__.py b/account_analytic_distribution_manual/__init__.py index f58c885722..8b60a0b20b 100644 --- a/account_analytic_distribution_manual/__init__.py +++ b/account_analytic_distribution_manual/__init__.py @@ -2,4 +2,3 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from . import models from . import reports -from .hooks import post_init_hook diff --git a/account_analytic_distribution_manual/__manifest__.py b/account_analytic_distribution_manual/__manifest__.py index 7f6a1daa62..02ab1cc8f9 100644 --- a/account_analytic_distribution_manual/__manifest__.py +++ b/account_analytic_distribution_manual/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Account analytic distribution manual", "summary": "Account analytic distribution manual", - "version": "16.0.2.4.0", + "version": "17.0.1.0.0", "license": "AGPL-3", "website": "https://github.com/OCA/account-analytic", "author": "Tecnativa, Odoo Community Association (OCA)", @@ -24,5 +24,4 @@ ], }, "installable": True, - "post_init_hook": "post_init_hook", } diff --git a/account_analytic_distribution_manual/hooks.py b/account_analytic_distribution_manual/hooks.py deleted file mode 100644 index 2b355c8d9d..0000000000 --- a/account_analytic_distribution_manual/hooks.py +++ /dev/null @@ -1,196 +0,0 @@ -# Copyright 2024 Tecnativa - Carlos Lopez -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from odoo import SUPERUSER_ID, api, tools - -# metadata for all models related to account_analytic_tag(m2m) -# add more models if needed -RELATION_M2M_INFO = { - "account_analytic_tag_account_asset_profile_rel": { - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - "table2": "account_asset_profile", - "column2": "account_asset_profile_id", - }, - "account_analytic_tag_hr_expense_rel": { - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - "table2": "hr_expense", - "column2": "hr_expense_id", - }, - "account_reconcile_model_second_analytic_tag_rel": { - "table2": "account_reconcile_model", - "column2": "account_reconcile_model_id", - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - }, - "hr_timesheet_switch_line_tag_rel": { - "table2": "hr_timesheet_switch", - "column2": "line_id", - "table1": "account_analytic_tag", - "column1": "tag_id", - }, - "account_analytic_tag_sale_order_line_rel": { - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - "table2": "sale_order_line", - "column2": "sale_order_line_id", - }, - "account_reconcile_model_analytic_tag_rel": { - "table2": "account_reconcile_model_line", - "column2": "account_reconcile_model_line_id", - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - }, - "account_analytic_tag_mis_report_instance_rel": { - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - "table2": "mis_report_instance", - "column2": "mis_report_instance_id", - }, - "account_analytic_tag_account_move_line_rel": { - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - "table2": "account_move_line", - "column2": "account_move_line_id", - }, - "account_analytic_tag_mis_report_instance_period_rel": { - "table2": "mis_report_instance_period", - "column2": "mis_report_instance_period_id", - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - }, - "account_analytic_tag_general_ledger_report_wizard_rel": { - "table2": "general_ledger_report_wizard", - "column2": "general_ledger_report_wizard_id", - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - }, - "account_analytic_default_account_analytic_tag_rel": { - "table2": "account_analytic_default", - "column2": "account_analytic_default_id", - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - }, - "account_analytic_tag_purchase_order_line_rel": { - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - "table2": "purchase_order_line", - "column2": "purchase_order_line_id", - }, - "account_analytic_tag_account_asset_rel": { - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - "table2": "account_asset", - "column2": "account_asset_id", - }, - "account_analytic_tag_project_task_stock_rel": { - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - "table2": "project_task", - "column2": "project_task_id", - }, - "account_analytic_tag_project_task_rel": { - "table1": "account_analytic_tag", - "column1": "account_analytic_tag_id", - "table2": "project_task", - "column2": "project_task_id", - }, - "account_analytic_line_tag_rel": { - "table2": "account_analytic_line", - "column2": "line_id", - "table1": "account_analytic_tag", - "column1": "tag_id", - }, -} - - -def post_init_hook(cr, registry): - if tools.table_exists(cr, "account_analytic_tag"): - env = api.Environment(cr, SUPERUSER_ID, {}) - DistributionManual = env["account.analytic.distribution.manual"] - sql = """ - WITH counted_tags AS ( - SELECT - tag.id, - tag.name, - tag.active, - tag.company_id, - ROW_NUMBER() OVER (PARTITION BY tag.name ORDER BY tag.id) AS row_count - FROM account_analytic_tag tag - WHERE tag.active_analytic_distribution = true - ) - SELECT - CASE - WHEN row_count = 1 THEN tag.name - ELSE CONCAT(tag.name, ' (', tag.id, ')') - END AS name, - tag.id, - tag.active, - tag.company_id, - distribution.account_id, - distribution.percentage - FROM - counted_tags tag - INNER JOIN - account_analytic_distribution distribution - ON tag.id = distribution.tag_id; - - """ - env.cr.execute(sql) - distribution_by_tag = {} - for data in env.cr.dictfetchall(): - tag_key = (data["id"], data["name"], data["active"], data["company_id"]) - distribution_by_tag.setdefault(tag_key, []).append(data) - distribution_map = {} - all_tag_ids = [] - for tag_key, distributions in distribution_by_tag.items(): - tag_id, tag_name, tag_active, company_id = tag_key - distribution_manual_val = { - "name": tag_name, - "active": tag_active, - "company_id": company_id or env.company.id, - "analytic_distribution": { - distribution["account_id"]: distribution["percentage"] - for distribution in distributions - }, - } - new_distribution = DistributionManual.create(distribution_manual_val) - distribution_map[tag_id] = new_distribution - all_tag_ids.append(tag_id) - # Update references in all models related to account_analytic_tag(m2m) - for table_m2m, info in RELATION_M2M_INFO.items(): - column1 = info["column1"] - table2 = info["table2"] - column2 = info["column2"] - res_model_name = table2.replace("_", ".") - if ( - res_model_name in env - and "manual_distribution_id" in env[res_model_name]._fields - ): - sql = f""" - SELECT {column1}, {column2} - FROM {table_m2m} - WHERE {column1} IN %s - """ - env.cr.execute(sql, (tuple(all_tag_ids),)) - for tag_id, res_id in env.cr.fetchall(): - env.cr.execute( - f""" - UPDATE {table2} - SET manual_distribution_id = %s - WHERE id = %s - """, - (distribution_map[tag_id].id, res_id), - ) - # Define the value of manual_distribution_id in the line items - env.cr.execute( - """ - UPDATE account_analytic_line AS aal - SET manual_distribution_id = aml.manual_distribution_id - FROM account_move_line AS aml - WHERE aal.move_line_id = aml.id - AND aml.manual_distribution_id IS NOT NULL - AND aal.manual_distribution_id IS NULL - """, - ) diff --git a/account_analytic_distribution_manual/i18n/ca.po b/account_analytic_distribution_manual/i18n/ca.po new file mode 100644 index 0000000000..6347c0867b --- /dev/null +++ b/account_analytic_distribution_manual/i18n/ca.po @@ -0,0 +1,196 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_analytic_distribution_manual +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-10-15 12:54+0000\n" +"PO-Revision-Date: 2024-10-15 12:54+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_analytic_distribution_manual +msgid "Account analytic distribution manual" +msgstr "Distribució Analítica Manual" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__active +msgid "Active" +msgstr "Actiu" + +#. module: account_analytic_distribution_manual +#: model_terms:ir.actions.act_window,help:account_analytic_distribution_manual.action_account_analytic_distribution_manual +msgid "Add a new Manual Analytic Distributions" +msgstr "Afegir una nova Distribució Analítica Manual" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution +msgid "Analytic Distribution" +msgstr "Distribució Analítica" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "Cerca de Distribució Analítica" + +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_account_analytic_line +msgid "Analytic Line" +msgstr "Línia Analítica" + +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_analytic_mixin +msgid "Analytic Mixin" +msgstr "Combinació Analítica" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_precision +msgid "Analytic Precision" +msgstr "Precisión Analítica" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_model__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_asset__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_asset_profile__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_template_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_move_template_line_run__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_reconcile_model_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_spread__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_spread_template__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_spread_template_auto__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_analytic_mixin__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_mrp_bom__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_mrp_production__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_mrp_workcenter__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_purchase_order_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_sale_order_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_move_line__analytic_distribution_import +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_stock_scrap__analytic_distribution_import +msgid "Analytic distribution (importable)" +msgstr "Distribució analítica (importable)" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_line__manual_distribution_id +msgid "Analytic distribution manual" +msgstr "Distribució analítica manual" + +#. module: account_analytic_distribution_manual +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_form +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual.view_account_analytic_distribution_manual_search +msgid "Archived" +msgstr "Arxivat" + +#. module: account_analytic_distribution_manual +#: model:ir.model,name:account_analytic_distribution_manual.model_base +msgid "Base" +msgstr "Base" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__company_id +msgid "Company" +msgstr "Companyia" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__create_uid +msgid "Created by" +msgstr "Creat per" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__create_date +msgid "Created on" +msgstr "Creat el" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_analytic_distribution_model__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_asset__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_asset_profile__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_move_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_move_template_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_move_template_line_run__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_reconcile_model_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_spread__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_spread_template__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_account_spread_template_auto__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_analytic_mixin__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_mrp_bom__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_mrp_production__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_mrp_workcenter__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_purchase_order_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_sale_order_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_move__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_move_line__analytic_distribution_import +#: model:ir.model.fields,help:account_analytic_distribution_manual.field_stock_scrap__analytic_distribution_import +msgid "" +"Defining this field, it will set the analytical distribution in JSON format," +" but using the analytic accounts names as keys of the dictionary, so it " +"eases the human input." +msgstr "" +"Definint aquest camp, es definirà la distribució analítica en format JSON," +" utilitzant els noms dels comptes analítics com a claus del diccionari, així " +"facilitant l'entrada per part de l'usuari." + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__id +msgid "ID" +msgstr "ID" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__name +msgid "Name" +msgstr "Nom" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__type" +msgid "Type" +msgstr "Tipus" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__sequence" +msgid "Sequence" +msgstr "Seqüència" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__display_name +msgid "Display Name" +msgstr "Nom a mostrar" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__price" +msgid "Price" +msgstr "Preu" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__total_amount" +msgid "Total Amount" +msgstr "Import Total" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__analytic_account_id" +msgid "Analytic Account" +msgstr "Compte Analític" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__amount" +msgid "Amount" +msgstr "Import" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__write_uid" +msgid "Last Updated by" +msgstr "Última actualització per" + +#. module: account_analytic_distribution_manual +#: model:ir.model.fields,field_description:account_analytic_distribution_manual.field_account_analytic_distribution_manual__write_date" +msgid "Last Updated on" +msgstr "Última actualització el" diff --git a/account_analytic_distribution_manual/migrations/16.0.2.3.0/post-migration.py b/account_analytic_distribution_manual/migrations/16.0.2.3.0/post-migration.py deleted file mode 100644 index c564a8b3d7..0000000000 --- a/account_analytic_distribution_manual/migrations/16.0.2.3.0/post-migration.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2024 Tecnativa - Víctor Martínez -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from openupgradelib import openupgrade - - -@openupgrade.migrate() -def migrate(env, version): - openupgrade.logged_query( - env.cr, - """ - UPDATE account_analytic_line AS aal - SET manual_distribution_id = aml.manual_distribution_id - FROM account_move_line AS aml - WHERE aal.move_line_id = aml.id - AND aml.manual_distribution_id IS NOT NULL - AND aal.manual_distribution_id IS NULL - """, - ) diff --git a/account_analytic_distribution_manual/models/base.py b/account_analytic_distribution_manual/models/base.py index f03a5396da..a391aa52fa 100644 --- a/account_analytic_distribution_manual/models/base.py +++ b/account_analytic_distribution_manual/models/base.py @@ -1,6 +1,5 @@ # Copyright 2024 Tecnativa - Carlos Lopez # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -import json from lxml import etree @@ -35,12 +34,13 @@ def get_view(self, view_id=None, view_type="form", **options): def add_field(node, view_type, res_model): attribute = "column_invisible" if view_type == "tree" else "invisible" - modifiers = json.dumps({attribute: True}) field_options = { "name": manual_distribution_field_name, - "modifiers": modifiers, } field_element = etree.SubElement(node, "field", field_options) + # Now, attributes need to be set directly on the 'field_element'. + # If they are passed through 'field_options', it won't work correctly. + field_element.set(attribute, "1") new_arch, new_models = View.postprocess_and_fields(field_element, res_model) _merge_view_fields(all_models, new_models) return field_element diff --git a/account_analytic_distribution_manual/readme/CONTRIBUTORS.md b/account_analytic_distribution_manual/readme/CONTRIBUTORS.md index cdd4ae91a8..2e48dbfee8 100644 --- a/account_analytic_distribution_manual/readme/CONTRIBUTORS.md +++ b/account_analytic_distribution_manual/readme/CONTRIBUTORS.md @@ -1,2 +1,4 @@ - Tecnativa (): - Carlos Lopez +- APSL - Nagarro \<\> + - Bernat Obrador diff --git a/account_analytic_distribution_manual/reports/invoice_report.py b/account_analytic_distribution_manual/reports/invoice_report.py index c58835e95e..fdfc8840ac 100644 --- a/account_analytic_distribution_manual/reports/invoice_report.py +++ b/account_analytic_distribution_manual/reports/invoice_report.py @@ -6,9 +6,7 @@ class AccountInvoiceReport(models.Model): _inherit = "account.invoice.report" - manual_distribution_id = fields.Many2one( - "account.analytic.distribution.manual", readonly=True - ) + manual_distribution_id = fields.Many2one("account.analytic.distribution.manual") def _select(self): return super()._select() + ", line.manual_distribution_id" diff --git a/account_analytic_distribution_manual/static/description/index.html b/account_analytic_distribution_manual/static/description/index.html index fdf96eb14d..a46d0786d9 100644 --- a/account_analytic_distribution_manual/static/description/index.html +++ b/account_analytic_distribution_manual/static/description/index.html @@ -434,6 +434,10 @@

    Contributors

  • Carlos Lopez
+
  • APSL - Nagarro <https://apsl.tech>
      +
    • Bernat Obrador
    • +
    +
  • diff --git a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js index 571585958b..911b967385 100644 --- a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js +++ b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.esm.js @@ -1,13 +1,16 @@ /** @odoo-module **/ import {AnalyticDistribution} from "@analytic/components/analytic_distribution/analytic_distribution"; +import {AutoComplete} from "@web/core/autocomplete/autocomplete"; +import {_t} from "@web/core/l10n/translation"; import {patch} from "@web/core/utils/patch"; const {useState} = owl; -patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { +patch(AnalyticDistribution.prototype, { setup() { - this._super(); + super.setup(...arguments); this.manual_distribution_by_id = {}; + this.accountsDetails = {}; this.state_manual_distribution = useState({ id: this.props.record.data.manual_distribution_id ? this.props.record.data.manual_distribution_id[0] @@ -17,13 +20,14 @@ patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { }); }, async willStart() { - await this._super(); + await super.willStart(...arguments); if (this.state_manual_distribution.id) { this.refreshManualDistribution(this.state_manual_distribution.id); } + this.accountsDetails = await this.fetchAccountDetails(); }, async willUpdate(nextProps) { - await this._super(nextProps); + await super.willUpdate(nextProps); const record_id = this.props.record.data.id || 0; const current_manual_distribution_id = this.state_manual_distribution.id; const new_manual_distribution_id = nextProps.record.data.manual_distribution_id @@ -42,13 +46,12 @@ patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { } }, async save() { - await this._super(); - await this.props.record.update({ - manual_distribution_id: [ - this.state_manual_distribution.id, - this.state_manual_distribution.label, - ], - }); + await super.save(); + if (this.state_manual_distribution.id) { + await this.props.record.update({ + manual_distribution_id: [this.state_manual_distribution.id], + }); + } }, async refreshManualDistribution(manual_distribution_id) { if (manual_distribution_id === 0) { @@ -76,38 +79,40 @@ patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { this.deleteManualTag(); } }, - get tags() { - let res = this._super(); + + planSummaryTags() { + let tags = super.planSummaryTags(...arguments); if (this.state_manual_distribution.id) { // Remove the delete button from tags // it will be added only to the manual distribution tag /* eslint-disable-next-line no-unused-vars */ - res = res.map(({onDelete, ...rest}) => rest); - res.unshift({ + tags = tags.map(({onDelete, ...rest}) => rest); + tags.unshift({ id: this.nextId++, text: this.state_manual_distribution.label, onDelete: this.editingRecord ? () => this.deleteManualTag() : undefined, }); } - return res; + + return tags; }, + deleteManualTag() { - this.state_manual_distribution = { - id: 0, - label: "", - analytic_distribution: [], - }; + this.state_manual_distribution.id = 0; + this.state_manual_distribution.label = ""; + this.state_manual_distribution.analytic_distribution = []; // Clear all distribution - for (const group_id in this.list) { - this.list[group_id].distribution = []; - } - this.autoFill(); + this.state.formattedData = []; + this.props.record.update({ + [this.props.name]: this.dataToJson(), + manual_distribution_id: null, + }); }, // Autocomplete sourcesAnalyticDistributionManual() { return [ { - placeholder: this.env._t("Loading..."), + placeholder: _t("Loading..."), options: (searchTerm) => this.loadOptionsSourceDistributionManual(searchTerm), }, @@ -130,7 +135,7 @@ patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { } if (!options.length) { options.push({ - label: this.env._t("No Analytic Distribution Manual found"), + label: _t("No Analytic Distribution Manual found"), classList: "o_m2o_no_result", unselectable: true, }); @@ -160,38 +165,81 @@ patch(AnalyticDistribution.prototype, "account_analytic_distribution_manual", { } return domain; }, + async fetchAccountDetails() { + const domain = []; + if (this.props.record.data.company_id) { + domain.push(["company_id", "=", this.props.record.data.company_id[0]]); + } + const records = await this.orm.call( + "account.analytic.account", + "search_read", + [], + { + domain: domain, + fields: ["id", "name", "color", "root_plan_id"], + } + ); + const accountsDetails = {}; + + for (const record of records) { + accountsDetails[record.id] = { + id: record.id, + display_name: record.name, + color: record.color, + root_plan_id: record.root_plan_id, + }; + } + return accountsDetails; + }, onChangeAutoCompleteDistributionManual(inputValue) { if (inputValue === "") { this.deleteManualTag(); } }, + async processSelectedOption(selected_option) { + const formattedLines = []; + for (const idsString in selected_option.analytic_distribution) { + const percentage = selected_option.analytic_distribution[idsString]; + + // Parse the IDs of selected_options, converting the key (e.g., "1,3") into an array of IDs [1, 3]. + const idsArray = idsString.split(",").map((id) => parseInt(id, 10)); + const lineToAdd = { + id: this.nextId++, + analyticAccounts: this.plansToArray(), + percentage: percentage / 100, + }; + + for (let i = 0; i < idsArray.length; i++) { + const accountId = idsArray[i]; + const accountData = this.accountsDetails[accountId]; + if (accountData) { + lineToAdd.analyticAccounts.push({ + accountId: accountData.id, + accountDisplayName: accountData.display_name, + planColor: accountData.color, + accountRootPlanId: accountData.root_plan_id[0], + planId: accountData.root_plan_id[0], + planName: accountData.root_plan_id[1], + }); + } + } + formattedLines.push(lineToAdd); + } + this.state.formattedData.push(...formattedLines); + await this.save(); + }, async onSelectDistributionManual(option) { const selected_option = Object.getPrototypeOf(option); - this.state_manual_distribution = { - id: selected_option.value, - label: selected_option.label, - analytic_distribution: selected_option.analytic_distribution, - }; - const account_ids = Object.keys(selected_option.analytic_distribution).map( - (id) => parseInt(id, 10) - ); - const analytic_accounts = await this.fetchAnalyticAccounts([ - ["id", "in", account_ids], - ]); + + this.state_manual_distribution.id = selected_option.value; + this.state_manual_distribution.label = selected_option.label; + this.state_manual_distribution.analytic_distribution = + selected_option.analytic_distribution; // Clear all distribution - for (const group_id in this.list) { - this.list[group_id].distribution = []; - } - for (const account of analytic_accounts) { - // Add new tags - const planId = account.root_plan_id[0]; - const tag = this.newTag(planId); - tag.analytic_account_id = account.id; - tag.analytic_account_name = account.display_name; - tag.percentage = selected_option.analytic_distribution[account.id]; - this.list[planId].distribution.push(tag); - } + this.state.formattedData = []; - this.autoFill(); + await this.processSelectedOption(selected_option); }, }); + +AnalyticDistribution.components = {...AnalyticDistribution.components, AutoComplete}; diff --git a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml index ed720811ea..df8f19e01f 100644 --- a/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml +++ b/account_analytic_distribution_manual/static/src/components/analytic_distribution/analytic_distribution.xml @@ -4,9 +4,8 @@ id="analytic_distribution_inherit" t-inherit="analytic.AnalyticDistributionPopup" t-inherit-mode="extension" - owl="1" > - +
    Manual distribution [ + ...stepUtils.goToAppSteps("account.menu_finance", ""), { content: "Go to Customers", trigger: 'span:contains("Customers")', @@ -24,9 +17,8 @@ tour.register( trigger: 'a:contains("Invoices")', }, { - extra_trigger: '.breadcrumb:contains("Invoices")', content: "Create new invoice", - trigger: ".o_list_button_add", + trigger: "button.o_list_button_add", }, { content: "Add Customer", @@ -61,8 +53,9 @@ tour.register( { content: "Select analytic_distribution", trigger: - 'div[name="invoice_line_ids"] .o_selected_row div.o_field_analytic_distribution[name="analytic_distribution"]', + 'div[name="invoice_line_ids"] .o_selected_row .o_analytic_distribution_cell', }, + { content: "Type Manual Distribution 1", trigger: @@ -74,11 +67,17 @@ tour.register( trigger: 'div[name="invoice_line_ids"] .o_selected_row .analytic_distribution_popup li a:contains("Manual Distribution 1")', }, + // The tour steps execute faster than the time it takes for JavaScript + // to set the distribution. This can cause the distribution step to + // not be fully completed before moving to the next step. + // To address this, we introduce a 1-second delay (1000 milliseconds) + // to give enough time for the distribution process to complete + // before closing the popup. { - content: "Apply selected Option", + content: "Wait 1 second before closing popup", trigger: 'div[name="invoice_line_ids"] .o_selected_row .analytic_distribution_popup input[id="analytic_manual_distribution"]', - run: "click", + run: () => new Promise((resolve) => setTimeout(resolve, 1000)), }, // Compatibility with analytic_distribution_widget_remove_save // this module remove buttons @@ -99,6 +98,6 @@ tour.register( run: "click", }, // Save account.move - ...tour.stepUtils.saveForm(), - ] -); + ...stepUtils.saveForm(), + ], +}); diff --git a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py index d222685855..d8387c3775 100644 --- a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py +++ b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual.py @@ -72,9 +72,17 @@ def test_manual_distribution_analytic_distribution_process_02(self): invoice_line.analytic_line_ids.mapped("manual_distribution_id"), self.distribution_1, ) - accounts = invoice_line.analytic_line_ids.mapped("account_id") - self.assertIn(aa_1, accounts) - self.assertIn(aa_2, accounts) + # In this case, the analytic account ID is stored in + # the field x_plan{self.plan_a.id}_id, + # not in the account_id field. The account_id field + # only contains the ID of the analytic + # account from the first plan (Projects), + # or the plan with ID = 1. + account_by_plan = invoice_line.analytic_line_ids.mapped( + f"x_plan{self.plan_a.id}_id" + ) + self.assertIn(aa_1, account_by_plan) + self.assertIn(aa_2, account_by_plan) def test_manual_distribution_analytic_distribution_text(self): self.analytic_account_a1.name = "test-1" diff --git a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py index f33c306687..d71c72a9b0 100644 --- a/account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py +++ b/account_analytic_distribution_manual/tests/test_analytic_distribution_manual_tour.py @@ -9,7 +9,7 @@ ) -@tagged("post_install", "-at_install") +@tagged("post_install", "-at_install", "mi_tag") class TestAnalyticDistributionManual(DistributionManualCommon, HttpCase): @classmethod def setUpClass(cls): @@ -33,11 +33,15 @@ def test_manual_distribution_tour(self): invoice = capt.records self.assertEqual(invoice.partner_id, self.partner_a) self.assertEqual(len(invoice.invoice_line_ids.analytic_line_ids), 2) + + account_id_field = self.plan_a._column_name() + analytic_line1 = invoice.invoice_line_ids.analytic_line_ids.filtered( - lambda x: x.account_id == self.analytic_account_a1 + lambda x: getattr(x, account_id_field) == self.analytic_account_a1 ) self.assertEqual(analytic_line1.amount, 40) + analytic_line2 = invoice.invoice_line_ids.analytic_line_ids.filtered( - lambda x: x.account_id == self.analytic_account_a2 + lambda x: getattr(x, account_id_field) == self.analytic_account_a2 ) self.assertEqual(analytic_line2.amount, 60) diff --git a/account_analytic_distribution_manual/views/account_analytic_distribution_manual_views.xml b/account_analytic_distribution_manual/views/account_analytic_distribution_manual_views.xml index 990ecb0212..66203a9585 100644 --- a/account_analytic_distribution_manual/views/account_analytic_distribution_manual_views.xml +++ b/account_analytic_distribution_manual/views/account_analytic_distribution_manual_views.xml @@ -27,7 +27,7 @@ name="web_ribbon" title="Archived" bg_color="bg-danger" - attrs="{'invisible': [('active', '=', True)]}" + invisible="active" />