diff --git a/product_account_multicompany_default/README.rst b/product_account_multicompany_default/README.rst index c4fb013bb94..5f2845d535d 100644 --- a/product_account_multicompany_default/README.rst +++ b/product_account_multicompany_default/README.rst @@ -2,13 +2,10 @@ Product Account Multi-Company Default ===================================== -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:b354b96693fd1f8a16818ecd1fe6bfb577ac8691a6a895be3477c55e81a02481 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png :target: https://odoo-community.org/page/development-status @@ -23,13 +20,13 @@ Product Account Multi-Company Default :target: https://translation.odoo-community.org/projects/multi-company-16-0/multi-company-16-0-product_account_multicompany_default :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/multi-company&target_branch=16.0 + :target: https://runboat.odoo-community.org/webui/builds.html?repo=OCA/multi-company&target_branch=16.0 :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| This module extends the functionality of products and accounting to allow you -to propagate multi-company product accounts from the current company to all +to propagate multi-company product template and product category accounts from the current company to all other companies where you have access rights. .. IMPORTANT:: @@ -77,7 +74,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 +If you spotted it first, help us smashing it by providing a detailed and welcomed `feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -94,6 +91,7 @@ Contributors ~~~~~~~~~~~~ * Jairo Llopis (`Moduon `__) +* Telmo Santos Maintainers ~~~~~~~~~~~ diff --git a/product_account_multicompany_default/__manifest__.py b/product_account_multicompany_default/__manifest__.py index 325d6a489db..0b188e02839 100644 --- a/product_account_multicompany_default/__manifest__.py +++ b/product_account_multicompany_default/__manifest__.py @@ -16,5 +16,6 @@ ], "data": [ "views/product_template_view.xml", + "views/product_category_view.xml", ], } diff --git a/product_account_multicompany_default/models/__init__.py b/product_account_multicompany_default/models/__init__.py index 9649db77a15..00d0ae9ceff 100644 --- a/product_account_multicompany_default/models/__init__.py +++ b/product_account_multicompany_default/models/__init__.py @@ -1 +1,2 @@ from . import product +from . import product_category diff --git a/product_account_multicompany_default/models/product_category.py b/product_account_multicompany_default/models/product_category.py new file mode 100644 index 00000000000..90a4202ed30 --- /dev/null +++ b/product_account_multicompany_default/models/product_category.py @@ -0,0 +1,115 @@ +# Copyright 2023 Moduon Team S.L. +# Copyright 2024 Camptocamp SA +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0) +import logging +from collections import defaultdict +from functools import reduce +from itertools import groupby +from operator import itemgetter, or_ + +from odoo import _, api, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +class ProductCategory(models.Model): + _inherit = "product.category" + + def _propagate_multicompany_account(self, field): + """Set the same account for all companies. + + Args: + field (str): + The field to propagate. E.g. "property_account_income_categ_id" + or "property_account_expense_categ_id". + """ + alien_companies = self.env.user.company_ids - self.env.company + if not alien_companies: + raise UserError( + _( + "There are no other companies to propagate to. " + "Make sure you have access to other companies." + ) + ) + # Gain access to all companies of current user + self = self.with_context( + allowed_company_ids=self.env.company.ids + alien_companies.ids + ) + # Map alien accounts by company and code + alien_accounts = self.env["account.account"].search( + [ + ("company_id", "in", alien_companies.ids), + ( + "code", + "in", + self[field].mapped("code"), + ), + ] + ) + accounts_map = defaultdict(dict) + for account in alien_accounts: + accounts_map[account.company_id.id][account.code] = account.id + # Group categories by account + for good_account, categories_grouper in groupby(self, itemgetter(field)): + categories = reduce(or_, categories_grouper) + # Propagate account to alien companies if possible + target_code = good_account.code + for alien_company in alien_companies: + try: + # False is a valid value, if you want to remove the account + target_account_id = ( + target_code and accounts_map[alien_company.id][target_code] + ) + except KeyError: + _logger.warning( + "Not propagating account to company because it does " + "not exist there: product_categories=%s, company=%s, account=%s", + categories, + alien_company, + target_code, + ) + continue + if ( + categories.with_company(alien_company)[field] + and categories.with_company(alien_company)[field].id + != target_account_id + ): + categories.with_company(alien_company)[field] = target_account_id + + def propagate_multicompany_account_income(self): + self._propagate_multicompany_account("property_account_income_categ_id") + + def propagate_multicompany_account_expense(self): + self._propagate_multicompany_account("property_account_expense_categ_id") + + def _propagate_property_fields(self): + income_categories = self.filtered("property_account_income_categ_id") + expense_categories = self.filtered("property_account_expense_categ_id") + # Skip if no account was selected + if not income_categories and not expense_categories: + return + # Skip if user has access to only one company + alien_user_companies = self.env.user.company_ids - self.env.company + if not alien_user_companies: + return + # Propagate account to other companies by default + income_categories.propagate_multicompany_account_income() + expense_categories.propagate_multicompany_account_expense() + + @api.model_create_multi + def create(self, vals_list): + """Propagate accounts to other companies always, on creation.""" + res = super().create(vals_list) + res._propagate_property_fields() + return res + + def write(self, vals): + """If forced, propagate property values on write to other companies.""" + res = super().write(vals) + # Allow opt-in for progagation on write using context + # Useful for data import to update records + + if self.env.context.get("force_property_propagation"): + self._propagate_property_fields() + return res diff --git a/product_account_multicompany_default/readme/CONTRIBUTORS.rst b/product_account_multicompany_default/readme/CONTRIBUTORS.rst index 0b01e64914c..6cd78bce56a 100644 --- a/product_account_multicompany_default/readme/CONTRIBUTORS.rst +++ b/product_account_multicompany_default/readme/CONTRIBUTORS.rst @@ -1 +1,2 @@ * Jairo Llopis (`Moduon `__) +* Telmo Santos diff --git a/product_account_multicompany_default/readme/DESCRIPTION.rst b/product_account_multicompany_default/readme/DESCRIPTION.rst index 203c755a281..4e9c7ce5cd9 100644 --- a/product_account_multicompany_default/readme/DESCRIPTION.rst +++ b/product_account_multicompany_default/readme/DESCRIPTION.rst @@ -1,3 +1,3 @@ This module extends the functionality of products and accounting to allow you -to propagate multi-company product accounts from the current company to all +to propagate multi-company product template and product category accounts from the current company to all other companies where you have access rights. diff --git a/product_account_multicompany_default/static/description/index.html b/product_account_multicompany_default/static/description/index.html index 6bb2c476e0d..0d30a11880e 100644 --- a/product_account_multicompany_default/static/description/index.html +++ b/product_account_multicompany_default/static/description/index.html @@ -1,20 +1,20 @@ - + - + Product Account Multi-Company Default