diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ae928d9..52b3bfb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -97,7 +97,7 @@ repos: rev: v0.1.3 hooks: - id: ruff - args: [--fix, --exit-non-zero-on-fix] + args: [--fix, --exit-non-zero-on-fix, --unsafe-fixes] - id: ruff-format - repo: https://github.com/OCA/pylint-odoo rev: v8.0.19 diff --git a/fiscal_company_base/__init__.py b/fiscal_company_base/__init__.py index 1c20904..0650744 100644 --- a/fiscal_company_base/__init__.py +++ b/fiscal_company_base/__init__.py @@ -1,3 +1 @@ from . import models - -from .post_install import post_install_set_fiscal_company diff --git a/fiscal_company_base/__manifest__.py b/fiscal_company_base/__manifest__.py index 0186f5f..e4c9cdc 100644 --- a/fiscal_company_base/__manifest__.py +++ b/fiscal_company_base/__manifest__.py @@ -5,23 +5,20 @@ { "name": "CAE - Base", - "version": "12.0.1.2.3", + "version": "16.0.1.0.0", "category": "CAE", "summary": "Manage CAE (Cooperatives of Activities and Employment)", "author": "GRAP", "website": "https://github.com/grap/odoo-addons-cae", "license": "AGPL-3", - "post_init_hook": "post_install_set_fiscal_company", "depends": [ "base", - # GRAP - "technical_partner_access", + # Dependency added to have the possibility to create demo user, + # without "notification_type" error + "mail", ], "data": [ - "security/ir_module_category.xml", - "security/res_groups.xml", - "security/ir_rule.xml", - "security/ir.model.access.csv", + # "security/ir_rule.xml", "views/view_res_company.xml", ], "demo": [ diff --git a/fiscal_company_base/demo/res_groups.xml b/fiscal_company_base/demo/res_groups.xml index 4534f12..5584f29 100644 --- a/fiscal_company_base/demo/res_groups.xml +++ b/fiscal_company_base/demo/res_groups.xml @@ -6,47 +6,9 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/fiscal_company_base/demo/res_partner.xml b/fiscal_company_base/demo/res_partner.xml index 37b64c8..a70a3e5 100644 --- a/fiscal_company_base/demo/res_partner.xml +++ b/fiscal_company_base/demo/res_partner.xml @@ -10,8 +10,6 @@ Copyright (C) 2018-Today GRAP (http://www.grap.coop) CAE - Mother Partner - - diff --git a/fiscal_company_base/demo/res_partner_company.xml b/fiscal_company_base/demo/res_partner_company.xml index 31971df..db33478 100644 --- a/fiscal_company_base/demo/res_partner_company.xml +++ b/fiscal_company_base/demo/res_partner_company.xml @@ -8,21 +8,28 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop) - - + + + Group Company + + + + + + Group Company + + group + + + - - + Your Mother Company - + @@ -30,16 +37,13 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop) Your Mother Company fiscal_mother - - - - + Your Child Company 1 (Service) - + @@ -47,18 +51,13 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop) Your Child Company 1 (Service) - fiscal_child - - - - Your Child Company 2 (Production) - + @@ -66,12 +65,7 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop) Your Child Company 2 (Production) - fiscal_child - - - - diff --git a/fiscal_company_base/demo/res_partner_users.xml b/fiscal_company_base/demo/res_partner_users.xml index 8d2137a..0aee9ff 100644 --- a/fiscal_company_base/demo/res_partner_users.xml +++ b/fiscal_company_base/demo/res_partner_users.xml @@ -20,10 +20,6 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop) Accountant User accountant@cae.coop - - - - @@ -42,10 +38,6 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop) Worker User worker@cae.coop - - - - @@ -58,5 +50,4 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop) ]"/> - diff --git a/fiscal_company_base/fix_test.py b/fiscal_company_base/fix_test.py deleted file mode 100644 index ac405ed..0000000 --- a/fiscal_company_base/fix_test.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (C) 2018 - Today: GRAP (http://www.grap.coop) -# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - - -_FIELD_LIST = [ - ("res_partner", "notify_email"), - ("res_partner", "invoice_warn"), - ("res_partner", "sale_warn"), - ("res_partner", "picking_warn"), - ("res_partner", "purchase_warn"), -] - - -def fix_required_field(env, function): - """Tests are failing on a database with some modules installed like 'mail' - because the load of the registry in TransactionCase seems to be bad. - To be sure, run "print self.registry('res.partner')._defaults and see - that the mandatory field 'notify_email' doesn't appear. - So this is a monkey patch that drop and add not null constraint - to make the tests working. - arguments : function. - 'DROP' at the beginning of the test setUp(self) - 'SET' at the end of the test tearDown(self) - """ - for table_name, field_name in _FIELD_LIST: - env.cr.execute( - """ - SELECT A.ATTNAME - FROM PG_ATTRIBUTE A, PG_CLASS C - WHERE A.ATTRELID = C.OID - AND A.ATTNAME = '%s' - AND C.relname= '%s';""" - % (field_name, table_name) - ) - if env.cr.fetchone(): - env.cr.execute( - """ - ALTER TABLE %s - ALTER COLUMN %s - %s NOT NULL;""" - % (table_name, field_name, function) - ) diff --git a/fiscal_company_base/i18n/fr.po b/fiscal_company_base/i18n/fr.po index c43dac8..07fa0ef 100644 --- a/fiscal_company_base/i18n/fr.po +++ b/fiscal_company_base/i18n/fr.po @@ -4,11 +4,11 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" +"Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-28 13:47+0000\n" -"PO-Revision-Date: 2021-05-28 13:47+0000\n" -"Last-Translator: <>\n" +"POT-Creation-Date: 2024-08-04 10:22+0000\n" +"PO-Revision-Date: 2024-08-04 10:22+0000\n" +"Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -16,81 +16,19 @@ msgstr "" "Plural-Forms: \n" #. module: fiscal_company_base -#: selection:res.company,fiscal_type:0 +#: model:ir.model.fields.selection,name:fiscal_company_base.selection__res_company__fiscal_type__fiscal_mother msgid "CAE" msgstr "" -#. module: fiscal_company_base -#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company_code -msgid "Code" -msgstr "" - #. module: fiscal_company_base #: model:ir.model,name:fiscal_company_base.model_res_company msgid "Companies" msgstr "Sociétés" -#. module: fiscal_company_base -#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company_create_wizard_company_id -msgid "Company" -msgstr "Société" - -#. module: fiscal_company_base -#: model:ir.model,name:fiscal_company_base.model_res_company_create_wizard -msgid "Company Creation Wizard" -msgstr "Assistant de création de société" - -#. module: fiscal_company_base -#: model:ir.model,name:fiscal_company_base.model_ir_property -msgid "Company Property" -msgstr "Propriété de la société" - -#. module: fiscal_company_base -#: model:ir.module.category,name:fiscal_company_base.module_category_fiscal_company -msgid "Cooperatives of Activities and Employment" -msgstr "Coopératives d'Activités et d'Emplois" - -#. module: fiscal_company_base -#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company_create_wizard_create_uid -msgid "Created by" -msgstr "Créé par" - -#. module: fiscal_company_base -#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company_create_wizard_create_date -msgid "Created on" -msgstr "Créé le" - -#. module: fiscal_company_base -#: model:res.groups,name:fiscal_company_base.fiscal_company_disabled_feature -msgid "Disabled Features" -msgstr "Fonctionnalités désactivées" - -#. module: fiscal_company_base -#: model:ir.model.fields,field_description:fiscal_company_base.field_fiscal_mother_check_mixin__display_name -#: model:ir.model.fields,field_description:fiscal_company_base.field_include_fiscal_company_search_mixin__display_name -#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company_create_wizard_display_name -msgid "Display Name" -msgstr "Nom affiché" - #. module: fiscal_company_base #: model:ir.model.fields,field_description:fiscal_company_base.field_res_company__fiscal_company_id msgid "Fiscal Company" -msgstr "" - -#. module: fiscal_company_base -#: model:res.groups,name:fiscal_company_base.fiscal_company_manager -msgid "Fiscal Company Manager" -msgstr "Responsable CAE" - -#. module: fiscal_company_base -#: model:ir.model,name:fiscal_company_base.model_fiscal_mother_check_mixin -msgid "Fiscal Mother Check Mixin" -msgstr "" - -#. module: fiscal_company_base -#: model_terms:ir.ui.view,arch_db:fiscal_company_base.view_res_company_form -msgid "Fiscal Settings" -msgstr "Paramétrages fiscaux" +msgstr "Société Fiscale" #. module: fiscal_company_base #: model:ir.model.fields,field_description:fiscal_company_base.field_res_company__fiscal_type @@ -98,84 +36,102 @@ msgid "Fiscal Type" msgstr "Type fiscal" #. module: fiscal_company_base -#: selection:res.company,fiscal_type:0 +#: model:ir.model.fields.selection,name:fiscal_company_base.selection__res_company__fiscal_type__group msgid "Group" -msgstr "" - -#. module: fiscal_company_base -#: model:ir.model.fields,field_description:fiscal_company_base.field_fiscal_mother_check_mixin__id -#: model:ir.model.fields,field_description:fiscal_company_base.field_include_fiscal_company_search_mixin__id -#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company_create_wizard_id -msgid "ID" -msgstr "" - -#. module: fiscal_company_base -#: model:ir.model,name:fiscal_company_base.model_include_fiscal_company_search_mixin -msgid "Include Fiscal Company Search Mixin" -msgstr "" +msgstr "Groupe" #. module: fiscal_company_base -#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company__other_fiscal_child_ids -msgid "Integrated Companies" -msgstr "Activités integrées" - -#. module: fiscal_company_base -#: selection:res.company,fiscal_type:0 +#: model:ir.model.fields.selection,name:fiscal_company_base.selection__res_company__fiscal_type__fiscal_child msgid "Integrated Company" -msgstr "Activité integrée" - -#. module: fiscal_company_base -#: model:ir.model.fields,field_description:fiscal_company_base.field_fiscal_mother_check_mixin____last_update -#: model:ir.model.fields,field_description:fiscal_company_base.field_include_fiscal_company_search_mixin____last_update -#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company_create_wizard___last_update -msgid "Last Modified on" -msgstr "Dernière modification le" +msgstr "Activité intégrée" #. module: fiscal_company_base -#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company_create_wizard_write_uid -msgid "Last Updated by" -msgstr "Mis à jour par" +#: model:ir.model.fields.selection,name:fiscal_company_base.selection__res_company__fiscal_type__normal +msgid "Normal" +msgstr "" #. module: fiscal_company_base -#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company_create_wizard_write_date -msgid "Last Updated on" -msgstr "Mis à jour le" +#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company__fiscal_child_ids +msgid "Technical Integrated Companies" +msgstr "Sociétés fiscales filles (champ techniques)" #. module: fiscal_company_base -#: selection:res.company,fiscal_type:0 -msgid "Normal" -msgstr "Activité associée" +#. odoo-python +#: code:addons/fiscal_company_base/models/res_company.py:0 +#, python-format +msgid "" +"The company '%(company_name)s' (type %(fiscal_type_name)s) can only have a " +"parent company with a type 'Group'." +msgstr "" +"La société '%(company_name)s' (type %(fiscal_type_name)s) peut seulement avoir une " +"société parent de type 'Groupe'." #. module: fiscal_company_base -#: code:addons/fiscal_company_base/models/res_company.py:60 +#. odoo-python +#: code:addons/fiscal_company_base/models/res_company.py:0 #, python-format -msgid "Only CAE company can have Integrated Companies" -msgstr "Seul les CAE peuvent avoir des activités integrées" +msgid "" +"The company '%(company_name)s' (type 'Fiscal Child') can only have a parent " +"company with a type 'Fiscal Mother'." +msgstr "" +"La société '%(company_name)s' (type 'Activité Intégrée') peut seulement avoir une société parent " +"de type 'CAE'." #. module: fiscal_company_base -#: model:ir.model.fields,field_description:fiscal_company_base.field_res_company__fiscal_child_ids -msgid "Technical Integrated Companies" +#. odoo-python +#: code:addons/fiscal_company_base/models/res_company.py:0 +#, python-format +msgid "" +"The company '%(company_name)s' can not be '%(fiscal_type)s' because it " +"contains companies." msgstr "" +"La société '%(company_name)s' ne peut pas être de type '%(fiscal_type)s' car elle " +"contient des sociétés filles." #. module: fiscal_company_base -#: model:ir.model,name:fiscal_company_base.model_res_users -msgid "Users" -msgstr "Utilisateurs" +#. odoo-python +#: code:addons/fiscal_company_base/models/res_company.py:0 +#, python-format +msgid "" +"The company '%(company_name)s' can not be 'Fiscal Mother' because it " +"contains companies type of '%(error_types)s'" +msgstr "" +"La société '%(company_name)s' ne peut pas être de type 'CAE' car elle " +"contient des sociétés de type '%(error_types)s'" #. module: fiscal_company_base -#: code:addons/fiscal_company_base/models/fiscal_mother_check_mixin.py:25 +#. odoo-python +#: code:addons/fiscal_company_base/models/res_company.py:0 #, python-format -msgid "You can't affect the item %s (model '%s') to a fiscal mother company." -msgstr "Vous ne pouvez pas affecter cet élément %s (modèle '%s') a une société de type CAE." +msgid "" +"The company '%(company_name)s' can not be 'Group' because it contains " +"companies type of '%(error_types)s'" +msgstr "" +"La société '%(company_name)s' ne peut pas être de type 'Groupe' car elle contient " +"des sociétés de type '%(error_types)s'" #. module: fiscal_company_base -#: code:addons/fiscal_company_base/models/res_company.py:73 +#. odoo-python +#: code:addons/fiscal_company_base/models/fiscal_child_check_mixin.py:0 #, python-format -msgid "You can't select in the field fiscal company, an other company for a non integrated company." -msgstr "Sur le champ `société fiscale` Vous ne pouvez pas sélectionner une société fiscale différente pour une activite intégrée" +msgid "" +"You can't affect the item(s) %(item_names)s to a Fiscal Child company.\n" +"\n" +" (model '%(model_name)s')" +msgstr "" +"Vous ne pouvez pas affecter ces éléments %(item_names)s à une activité intégrée.\n" +"\n" +" (Modèle '%(model_name)s')" #. module: fiscal_company_base -#: code:addons/fiscal_company_base/models/res_company.py:83 +#. odoo-python +#: code:addons/fiscal_company_base/models/fiscal_mother_check_mixin.py:0 #, python-format -msgid "You should select in the field fiscal company, a CAE company for a Integrated Company." +msgid "" +"You can't affect the item(s) %(item_names)s to a Fiscal Mother company.\n" +"\n" +" (model '%(model_name)s')" msgstr "" +"Vous ne pouvez pas affecter ces éléments %(item_names)s à une CAE.\n" +"\n" +" (Modèle '%(model_name)s')" diff --git a/fiscal_company_base/models/__init__.py b/fiscal_company_base/models/__init__.py index 52f8f59..afd7acd 100644 --- a/fiscal_company_base/models/__init__.py +++ b/fiscal_company_base/models/__init__.py @@ -1,6 +1,4 @@ -from . import fiscal_child_check_mixin -from . import fiscal_mother_check_mixin -from . import include_fiscal_company_search_mixin +# from . import fiscal_child_check_mixin +# from . import fiscal_mother_check_mixin +# from . import include_fiscal_company_search_mixin from . import res_company -from . import res_users -from . import ir_property diff --git a/fiscal_company_base/models/fiscal_child_check_mixin.py b/fiscal_company_base/models/fiscal_child_check_mixin.py index 59da317..5252dd9 100644 --- a/fiscal_company_base/models/fiscal_child_check_mixin.py +++ b/fiscal_company_base/models/fiscal_child_check_mixin.py @@ -25,9 +25,10 @@ def _check_fiscal_child_company_id(self): if bad_items: raise ValidationError( _( - "You can't affect the item(s) %s to a Fiscal" + "You can't affect the item(s) %(item_names)s to a Fiscal" " Child company.\n\n" - " (model '%s')" + " (model '%(model_name)s')", + item_names=",".join([x.name for x in bad_items]), + model_name=self._name, ) - % (",".join([x.name for x in bad_items]), self._name) ) diff --git a/fiscal_company_base/models/fiscal_mother_check_mixin.py b/fiscal_company_base/models/fiscal_mother_check_mixin.py index 988d4a4..2d9371e 100644 --- a/fiscal_company_base/models/fiscal_mother_check_mixin.py +++ b/fiscal_company_base/models/fiscal_mother_check_mixin.py @@ -23,9 +23,10 @@ def _check_fiscal_child_company_id(self): if bad_items: raise ValidationError( _( - "You can't affect the item(s) %s to a Fiscal" + "You can't affect the item(s) %(item_names)s to a Fiscal" " Mother company.\n\n" - " (model '%s')" + " (model '%(model_name)s')", + item_names=",".join([x.name for x in bad_items]), + model_name=self._name, ) - % (",".join([x.name for x in bad_items]), self._name) ) diff --git a/fiscal_company_base/models/ir_property.py b/fiscal_company_base/models/ir_property.py deleted file mode 100644 index bc1dc6a..0000000 --- a/fiscal_company_base/models/ir_property.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (C) 2020-Today: GRAP (http://www.grap.coop) -# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import api, models - - -class IrProperty(models.Model): - _inherit = "ir.property" - - @api.model - def get(self, name, model, res_id=False): - if ( - "overload_force_company" in self.env.context - and "force_company" in self.env.context - ): - return super( - IrProperty, - self.with_context( - force_company=self.env.context.get("overload_force_company") - ), - ).get(name, model, res_id=res_id) - else: - return super().get(name, model, res_id=res_id) diff --git a/fiscal_company_base/models/res_company.py b/fiscal_company_base/models/res_company.py index 72bfae1..03195bb 100644 --- a/fiscal_company_base/models/res_company.py +++ b/fiscal_company_base/models/res_company.py @@ -3,7 +3,8 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import _, api, exceptions, fields, models +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError _RES_COMPANY_FISCAL_TYPE = [ ("group", "Group"), @@ -16,16 +17,17 @@ class ResCompany(models.Model): _inherit = "res.company" - # Columns Section fiscal_type = fields.Selection( selection=_RES_COMPANY_FISCAL_TYPE, - string="Fiscal Type", required=True, default="normal", ) fiscal_company_id = fields.Many2one( - comodel_name="res.company", string="Fiscal Company" + comodel_name="res.company", + string="Fiscal Company", + compute="_compute_fiscal_company_id", + store=True, ) fiscal_child_ids = fields.One2many( @@ -35,80 +37,82 @@ class ResCompany(models.Model): readonly=True, ) - other_fiscal_child_ids = fields.One2many( - comodel_name="res.company", - compute="_compute_other_fiscal_child_ids", - string="Integrated Companies", - ) - - @api.multi - def _compute_other_fiscal_child_ids(self): + @api.depends("fiscal_type", "parent_id") + def _compute_fiscal_company_id(self): for company in self: - companies = self.search( - [("id", "in", company.fiscal_child_ids.ids), ("id", "!=", company.id)] - ) - company.other_fiscal_child_ids = companies.ids + if company.fiscal_type in ["normal", "fiscal_mother"]: + company.fiscal_company_id = company + elif company.fiscal_type == "fiscal_child": + company.fiscal_company_id = company.parent_id + elif company.fiscal_type == "group": + company.fiscal_company_id = False # Constrains Section - @api.constrains("fiscal_child_ids", "fiscal_type") - def _check_non_fiscal_childs(self): - for company in self: - if company.fiscal_type != "fiscal_mother" and len( - company.other_fiscal_child_ids - ): - raise exceptions.ValidationError( - _("Only CAE company can have Integrated Companies") + @api.constrains("parent_id", "fiscal_type") + def _check_fiscal_type_with_parent_type(self): + for company in self.filtered( + lambda x: x.fiscal_type in ["group", "normal", "fiscal_mother"] + ): + if company.parent_id.fiscal_type not in ["group", False]: + raise ValidationError( + _( + "The company '%(company_name)s' (type %(fiscal_type_name)s)" + " can only have a parent company with a type 'Group'.", + company_name=company.name, + fiscal_type_name=company.fiscal_type, + ) ) - - @api.constrains("fiscal_company_id", "fiscal_type") - def _check_non_fiscal_child_company(self): - for company in self: - # skip special case of creation - if company.fiscal_company_id: - if ( - company.fiscal_type in ("normal", "fiscal_mother") - and company.id != company.fiscal_company_id.id - ): - raise exceptions.ValidationError( - _( - "You can't select in the field fiscal company, an" - " other company for a non integrated company." - ) + for company in self.filtered(lambda x: x.fiscal_type in ["fiscal_child"]): + if company.parent_id.fiscal_type != "fiscal_mother": + raise ValidationError( + _( + "The company '%(company_name)s' (type 'Fiscal Child')" + " can only have a parent company with a type 'Fiscal Mother'.", + company_name=company.name, ) - elif ( - company.fiscal_type == "fiscal_child" - and company.fiscal_company_id.fiscal_type != "fiscal_mother" - ): - raise exceptions.ValidationError( - _( - "You should select in the field fiscal company, a" - " CAE company for a Integrated Company." - ) + ) + + @api.constrains("child_ids", "fiscal_type") + def _check_fiscal_type_with_child_type(self): + for company in self.filtered( + lambda x: x.fiscal_type in ["normal", "fiscal_child"] + ): + if company.child_ids: + raise ValidationError( + _( + "The company '%(company_name)s' can not be '%(fiscal_type)s'" + " because it contains companies.", + company_name=company.name, + fiscal_type=company.fiscal_type, ) + ) - # Overload Section - @api.model - def create(self, vals): - company = super().create(vals) - if not vals.get("fiscal_company_id", False): - company.fiscal_company_id = company.id - if vals.get("fiscal_type", False) == "fiscal_child": - company._propagate_access_right() - return company + for company in self.filtered(lambda x: x.fiscal_type in ["fiscal_mother"]): + error_types = set(company.mapped("child_ids.fiscal_type")) - set( + {"fiscal_child"} + ) + + if error_types: + raise ValidationError( + _( + "The company '%(company_name)s' can not be 'Fiscal Mother'" + " because it contains companies type of '%(error_types)s'", + company_name=company.name, + error_types=error_types, + ) + ) - @api.multi - def write(self, vals): - res = super().write(vals) - if vals.get("fiscal_type", False) == "fiscal_child": - self._propagate_access_right() - return res + for company in self.filtered(lambda x: x.fiscal_type in ["group"]): + error_types = set(company.mapped("child_ids.fiscal_type")) - set( + {"normal", "group", "fiscal_mother"} + ) - # Private section - @api.multi - def _propagate_access_right(self): - """Give access to the given fiscal child companies to all the - users that have access to the fiscal mother company""" - for company in self: - user_ids = company.fiscal_company_id.user_ids.ids - new_user_ids = list(set(user_ids) - set(company.user_ids.ids)) - company.write({"user_ids": [(4, id) for id in list(set(new_user_ids))]}) + if error_types: + raise ValidationError( + _( + "The company '%(company_name)s' can not be 'Group'" + " because it contains companies type of '%(error_types)s'", + company_name=company.name, + error_types=error_types, + ) + ) diff --git a/fiscal_company_base/models/res_users.py b/fiscal_company_base/models/res_users.py deleted file mode 100644 index d992c6d..0000000 --- a/fiscal_company_base/models/res_users.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (C) 2013-Today: GRAP (http://www.grap.coop) -# @author: Julien WESTE -# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import api, models - - -class ResUsers(models.Model): - _inherit = "res.users" - - # Overload Section - @api.model - def create(self, vals): - user = super().create(vals) - if vals.get("company_ids", False): - user._propagate_access_right() - return user - - @api.multi - def write(self, vals): - res = super().write(vals) - if vals.get("company_ids", False): - self._propagate_access_right() - return res - - # Private function section - @api.multi - def _propagate_access_right(self): - """If a user has access to a fiscal_mother company, so he'll have - access to all the child_company""" - new_company_ids = [] - for user in self: - for mother_company in user.company_ids.filtered( - lambda x: x.fiscal_type == "fiscal_mother" - ): - all_ids = mother_company.fiscal_child_ids.ids - existing_ids = user.company_ids.ids - new_company_ids += list(set(all_ids) - set(existing_ids)) - super(ResUsers, user).write( - {"company_ids": [(4, id) for id in list(set(new_company_ids))]} - ) diff --git a/fiscal_company_base/post_install.py b/fiscal_company_base/post_install.py deleted file mode 100644 index ce9d5d0..0000000 --- a/fiscal_company_base/post_install.py +++ /dev/null @@ -1,16 +0,0 @@ -from odoo import SUPERUSER_ID, api - - -def post_install_set_fiscal_company(cr, registry): - """Initialize correctly fiscal_company_id for - existing companies (that are normal, by default) - """ - with api.Environment.manage(): - env = api.Environment(cr, SUPERUSER_ID, {}) - companies = ( - env["res.company"] - .with_context(active_test=False) - .search([("fiscal_type", "!=", "fiscal_child")]) - ) - for company in companies: - company.fiscal_company_id = company.id diff --git a/fiscal_company_base/readme/DESCRIPTION.rst b/fiscal_company_base/readme/DESCRIPTION.rst index 5fc4711..5066835 100644 --- a/fiscal_company_base/readme/DESCRIPTION.rst +++ b/fiscal_company_base/readme/DESCRIPTION.rst @@ -16,9 +16,10 @@ the parent company. **Companies feature** * Add a new field on company `fiscal_type`: - * `normal` : classical company + * `normal` : Classical company * `fiscal_mother`: CAE company, that can host many child companies * `fiscal_child`: child company, hosted by the CAE + * `group`: Group company, that can host many 'Normal' and CAE companies **Users Feature** diff --git a/fiscal_company_base/security/ir.model.access.csv b/fiscal_company_base/security/ir.model.access.csv deleted file mode 100644 index 70ed3f5..0000000 --- a/fiscal_company_base/security/ir.model.access.csv +++ /dev/null @@ -1,5 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -,,,,,,, -access_sequence_manager,Sequence CAE manager,base.model_ir_sequence,fiscal_company_base.fiscal_company_manager,1,1,1,1 -access_ui_view_manager,View CAE manager,base.model_ir_ui_view,fiscal_company_base.fiscal_company_manager,1,1,1,1 -access_property_manager,Property CAE manager,base.model_ir_property,fiscal_company_base.fiscal_company_manager,1,1,1,1 diff --git a/fiscal_company_base/security/ir_module_category.xml b/fiscal_company_base/security/ir_module_category.xml deleted file mode 100644 index d398b70..0000000 --- a/fiscal_company_base/security/ir_module_category.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - Cooperatives of Activities and Employment - - - diff --git a/fiscal_company_base/security/res_groups.xml b/fiscal_company_base/security/res_groups.xml deleted file mode 100644 index 79e40d9..0000000 --- a/fiscal_company_base/security/res_groups.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - Fiscal Company Manager - - - - - - Disabled Features - - - - diff --git a/fiscal_company_base/tests/__init__.py b/fiscal_company_base/tests/__init__.py index d9b96c4..893ced3 100644 --- a/fiscal_company_base/tests/__init__.py +++ b/fiscal_company_base/tests/__init__.py @@ -1 +1 @@ -from . import test_module +from . import test_fiscal_type_constrains diff --git a/fiscal_company_base/tests/test_fiscal_type_constrains.py b/fiscal_company_base/tests/test_fiscal_type_constrains.py new file mode 100644 index 0000000..9d28136 --- /dev/null +++ b/fiscal_company_base/tests/test_fiscal_type_constrains.py @@ -0,0 +1,300 @@ +# Copyright (C) 2013 - Today: GRAP (http://www.grap.coop) +# @author Julien WESTE +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo.exceptions import ValidationError +from odoo.tests import tagged +from odoo.tests.common import TransactionCase + + +@tagged("post_install", "-at_install") +class TestModule(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls.ResCompany = cls.env["res.company"] + cls.group_company = cls.env.ref("fiscal_company_base.company_group") + cls.mother_company = cls.env.ref("fiscal_company_base.company_fiscal_mother") + cls.child_company = cls.env.ref("fiscal_company_base.company_fiscal_child_1") + cls.normal_company = cls.env.ref("base.main_company") + + # Test Section + def test_01_res_company_check_contraint_child_company_normal(self): + """A 'normal' company can only have parent type == 'group' + (or no parent)""" + self.ResCompany.create( + { + "name": "new_company_01_A", + "fiscal_type": "normal", + } + ) + + self.ResCompany.create( + { + "name": "new_company_01_B", + "fiscal_type": "normal", + "parent_id": self.group_company.id, + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('normal')" + " and parent company ('normal')", + ): + self.ResCompany.create( + { + "name": "new_company_01_C", + "fiscal_type": "normal", + "parent_id": self.normal_company.id, + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('normal')" + " and parent company ('fiscal_mother')", + ): + self.ResCompany.create( + { + "name": "new_company_01_D", + "fiscal_type": "normal", + "parent_id": self.mother_company.id, + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('normal')" + " and parent company ('fiscal_child')", + ): + self.ResCompany.create( + { + "name": "new_company_01_E", + "fiscal_type": "normal", + "parent_id": self.child_company.id, + } + ) + + def test_02_res_company_check_contraint_child_company_group(self): + """A 'group' company can only have parent type == 'group' + (or no parent)""" + self.ResCompany.create( + { + "name": "new_company_02_A", + "fiscal_type": "group", + } + ) + + self.ResCompany.create( + { + "name": "new_company_02_B", + "fiscal_type": "group", + "parent_id": self.group_company.id, + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('group')" + " and parent company ('normal')", + ): + self.ResCompany.create( + { + "name": "new_company_02_C", + "fiscal_type": "group", + "parent_id": self.normal_company.id, + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('group')" + " and parent company ('fiscal_mother')", + ): + self.ResCompany.create( + { + "name": "new_company_02_D", + "fiscal_type": "group", + "parent_id": self.mother_company.id, + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('group')" + " and parent company ('fiscal_child')", + ): + self.ResCompany.create( + { + "name": "new_company_02_E", + "fiscal_type": "group", + "parent_id": self.child_company.id, + } + ) + + def test_03_res_company_check_contraint_child_company_fiscal_mother(self): + """A 'fiscal_mother' company can only have parent type == 'group' + (or no parent)""" + self.ResCompany.create( + { + "name": "new_company_03_A", + "fiscal_type": "fiscal_mother", + } + ) + + self.ResCompany.create( + { + "name": "new_company_03_B", + "fiscal_type": "fiscal_mother", + "parent_id": self.group_company.id, + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('fiscal_mother')" + " and parent company ('normal')", + ): + self.ResCompany.create( + { + "name": "new_company_03_C", + "fiscal_type": "fiscal_mother", + "parent_id": self.normal_company.id, + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('fiscal_mother')" + " and parent company ('fiscal_mother')", + ): + self.ResCompany.create( + { + "name": "new_company_03_D", + "fiscal_type": "fiscal_mother", + "parent_id": self.mother_company.id, + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('fiscal_mother')" + " and parent company ('fiscal_child')", + ): + self.ResCompany.create( + { + "name": "new_company_03_E", + "fiscal_type": "fiscal_mother", + "parent_id": self.child_company.id, + } + ) + + def test_04_res_company_check_contraint_child_company_fiscal_child(self): + """A 'fiscal_child' company can only have parent type == 'fiscal_mother'""" + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('fiscal_child')" + " without parent company", + ): + self.ResCompany.create( + { + "name": "new_company_04_A", + "fiscal_type": "fiscal_child", + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('fiscal_child')" + " and parent company ('group')", + ): + self.ResCompany.create( + { + "name": "new_company_04_B", + "fiscal_type": "fiscal_child", + "parent_id": self.group_company.id, + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('fiscal_child')" + " and parent company ('normal')", + ): + self.ResCompany.create( + { + "name": "new_company_04_C", + "fiscal_type": "fiscal_child", + "parent_id": self.normal_company.id, + } + ) + + self.ResCompany.create( + { + "name": "new_company_04_D", + "fiscal_type": "fiscal_child", + "parent_id": self.mother_company.id, + } + ) + + with self.assertRaises( + ValidationError, + msg="You can not create a child company ('fiscal_child')" + " and parent company ('fiscal_child')", + ): + self.ResCompany.create( + { + "name": "new_company_04_E", + "fiscal_type": "fiscal_child", + "parent_id": self.child_company.id, + } + ) + + def test_10_res_company_check_contraint_parent_company_set_normal(self): + with self.assertRaises( + ValidationError, + msg="You can not set as 'normal' company" + " a company that contains other companies.", + ): + self.group_company.fiscal_type = "normal" + + with self.assertRaises( + ValidationError, + msg="You can not set as 'normal' company" + " a company that contains other companies.", + ): + self.mother_company.fiscal_type = "normal" + + def test_11_res_company_check_contraint_parent_company_set_fiscal_mother(self): + with self.assertRaises( + ValidationError, + msg="You can not set as 'fiscal_mother' company" + " a company that doesn't contains only fiscal_child companies.", + ): + self.group_company.fiscal_type = "fiscal_mother" + + def test_12_res_company_check_contraint_parent_company_set_fiscal_child(self): + with self.assertRaises( + ValidationError, + msg="You can not set as 'fiscal_child' company" + " a company that contains other companies.", + ): + self.group_company.fiscal_type = "fiscal_child" + + with self.assertRaises( + ValidationError, + msg="You can not set as 'fiscal_child' company" + " a company that contains other companies.", + ): + self.mother_company.fiscal_type = "fiscal_child" + + def test_13_res_company_check_contraint_parent_company_set_group(self): + with self.assertRaises( + ValidationError, + msg="You can not set as 'group' company" + " a company that contains fiscal_child companies.", + ): + self.mother_company.fiscal_type = "group" diff --git a/fiscal_company_base/tests/test_module.py b/fiscal_company_base/tests/test_module.py deleted file mode 100644 index ba9e015..0000000 --- a/fiscal_company_base/tests/test_module.py +++ /dev/null @@ -1,149 +0,0 @@ -# Copyright (C) 2013 - Today: GRAP (http://www.grap.coop) -# @author Julien WESTE -# @author Sylvain LE GAL (https://twitter.com/legalsylvain) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo.exceptions import ValidationError -from odoo.tests.common import TransactionCase - -from ..fix_test import fix_required_field - - -class TestModule(TransactionCase): - """Tests for 'Base Fiscal Company' Module""" - - # Overload Section - def setUp(self): - super().setUp() - - self.ResUsers = self.env["res.users"] - self.ResCompany = self.env["res.company"] - self.mother_company = self.env.ref("fiscal_company_base.company_fiscal_mother") - self.base_company = self.env.ref("base.main_company") - self.user_accountant = self.env.ref("fiscal_company_base.user_accountant") - self.user_accountant.write({"company_id": self.mother_company.id}) - self.env.clear() - fix_required_field(self, "DROP") - - # def tearDown(self): - # self.cr.rollback() - # fix_required_field(self, 'SET') - # super().tearDown() - - # Test Section - def test_01_res_users_propagate_access_right_create(self): - """[Functional Test] A new user with access to mother company must - have access to child companies""" - new_user = self.ResUsers.sudo(user=self.user_accountant).create( - { - "name": "new_user", - "login": "new_user@odoo.com", - "company_id": self.mother_company.id, - "company_ids": [(4, self.mother_company.id)], - } - ) - self.assertEqual( - len(new_user.company_ids), - len(self.mother_company.fiscal_child_ids), - "Affect a mother company to a new user must give access right" - "to the childs companies", - ) - - def test_02_res_users_propagate_access_right_write(self): - """[Functional Test] Give access to a mother company must give acces - to the child companies""" - new_user = self.ResUsers.create( - { - "name": "new_user", - "login": "new_user@odoo.com", - "company_id": self.base_company.id, - "company_ids": [(4, self.base_company.id)], - } - ) - new_user.write({"company_ids": [(4, self.mother_company.id)]}) - self.assertEqual( - len(new_user.company_ids), - len(self.mother_company.fiscal_child_ids) + 1, - "Give access to a mother company must give access" "to the child companies", - ) - - def test_03_res_company_check_contraint_fail_01(self): - """[Contraint Test] Try to create a company with - 'fiscal_type != 'child' and and a mother company.""" - with self.assertRaises(ValidationError): - self.ResCompany.sudo(user=self.user_accountant).create( - { - "name": "new_company", - "fiscal_type": "normal", - "fiscal_company_id": self.mother_company.id, - } - ) - - def test_04_res_company_check_contraint_fail_02(self): - """[Contraint Test] Try to create a company with - 'fiscal_type != 'child' and and a mother company.""" - with self.assertRaises(ValidationError): - self.ResCompany.sudo(user=self.user_accountant).create( - { - "name": "new_company_1", - "fiscal_type": "fiscal_mother", - "fiscal_company_id": self.mother_company.id, - } - ) - with self.assertRaises(ValidationError): - self.ResCompany.sudo(user=self.user_accountant).create( - { - "name": "new_company_2", - "fiscal_type": "normal", - "fiscal_company_id": self.mother_company.id, - } - ) - - def test_05_res_company_check_contraint_fail_03(self): - """[Contraint Test] Try to create a company with - 'fiscal_type = 'child' without a mother company.""" - with self.assertRaises(ValidationError): - self.ResCompany.sudo(user=self.user_accountant).create( - { - "name": "new_company", - "fiscal_type": "fiscal_child", - "fiscal_company_id": False, - } - ) - - def test_06_res_company_create_child_propagate_success(self): - """[Contraint Test] Create a child company and check propagation.""" - new_company = self.ResCompany.sudo(user=self.user_accountant).create( - { - "name": "new_company", - "fiscal_type": "fiscal_child", - "fiscal_company_id": self.mother_company.id, - } - ) - new_access = self.user_accountant.company_ids.filtered( - lambda x: x.id == new_company.id - ).ids - self.assertEqual( - new_access, - [new_company.id], - "Existing user must have access to the new child company.", - ) - - def test_07_res_company_write_child_propagate_success(self): - """[Contraint Test] Create and write a child company and check - propagation.""" - new_company = self.ResCompany.sudo(user=self.user_accountant).create( - {"name": "new_company", "fiscal_type": "normal"} - ) - new_company.sudo(user=self.user_accountant).write( - {"fiscal_type": "fiscal_child", "fiscal_company_id": self.mother_company.id} - ) - - new_access = self.user_accountant.company_ids.filtered( - lambda x: x.id == new_company.id - ).ids - self.assertEqual( - new_access, - [new_company.id], - "Existing user must have access to the new child company.", - ) diff --git a/fiscal_company_base/views/view_res_company.xml b/fiscal_company_base/views/view_res_company.xml index bb121ab..a3d687c 100644 --- a/fiscal_company_base/views/view_res_company.xml +++ b/fiscal_company_base/views/view_res_company.xml @@ -41,20 +41,10 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop) res.company - - - - - - - - - + + + - -