From 52be38027cde45b36b7c8beedfd0066c4c5f2e92 Mon Sep 17 00:00:00 2001 From: les-adhoc Date: Mon, 19 Oct 2026 17:52:20 -0300 Subject: [PATCH 1/5] [MIG] portal_partner_state: Migration to 20.0 --- portal_partner_state/__manifest__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/portal_partner_state/__manifest__.py b/portal_partner_state/__manifest__.py index 8341bebcd..f8e63a662 100644 --- a/portal_partner_state/__manifest__.py +++ b/portal_partner_state/__manifest__.py @@ -19,7 +19,7 @@ ############################################################################## { "name": "Portal Partner State", - "version": "19.0.1.0.0", + "version": "20.0.1.0.0", "category": "Tools", "complexity": "easy", "author": "ADHOC SA", @@ -32,6 +32,6 @@ "data": [ "security/ir.model.access.csv", ], - "installable": False, + "installable": True, "auto_install": True, } From 10945d7c6a13879a575539b20b909a45e1bc0daa Mon Sep 17 00:00:00 2001 From: les-adhoc Date: Mon, 19 Oct 2026 17:52:38 -0300 Subject: [PATCH 2/5] [MIG] portal_partner_state: upgrade_code 19.4-00-ir-access --- portal_partner_state/__manifest__.py | 2 +- portal_partner_state/security/ir.access.csv | 3 +++ portal_partner_state/security/ir.model.access.csv | 3 --- 3 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 portal_partner_state/security/ir.access.csv delete mode 100644 portal_partner_state/security/ir.model.access.csv diff --git a/portal_partner_state/__manifest__.py b/portal_partner_state/__manifest__.py index f8e63a662..2e624813f 100644 --- a/portal_partner_state/__manifest__.py +++ b/portal_partner_state/__manifest__.py @@ -30,7 +30,7 @@ "portal", ], "data": [ - "security/ir.model.access.csv", + 'security/ir.access.csv', ], "installable": True, "auto_install": True, diff --git a/portal_partner_state/security/ir.access.csv b/portal_partner_state/security/ir.access.csv new file mode 100644 index 000000000..408410ab6 --- /dev/null +++ b/portal_partner_state/security/ir.access.csv @@ -0,0 +1,3 @@ +id,name,model_id,group_id/id,operation,domain +access_res_partner_state_field_portal,partner_state_field_portal,res.partner.state_field,base.group_portal,r, +access_ir_model_fields_portal,ir_model_fields,ir.model.fields,base.group_portal,r, diff --git a/portal_partner_state/security/ir.model.access.csv b/portal_partner_state/security/ir.model.access.csv deleted file mode 100644 index 24109d25d..000000000 --- a/portal_partner_state/security/ir.model.access.csv +++ /dev/null @@ -1,3 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_res_partner_state_field_portal,partner_state_field_portal,partner_state.model_res_partner_state_field,base.group_portal,1,0,0,0 -access_ir_model_fields_portal,ir_model_fields,base.model_ir_model_fields,base.group_portal,1,0,0,0 From d1b89f6df3dfadba134c07e7a9731b98b5825921 Mon Sep 17 00:00:00 2001 From: les-adhoc Date: Mon, 19 Oct 2026 18:21:04 -0300 Subject: [PATCH 3/5] [I18N] portal_partner_state: add tests, sync README and translations --- portal_partner_state/README.rst | 9 +- portal_partner_state/__manifest__.py | 2 +- portal_partner_state/i18n/es.po | 86 +++++++++++++++ .../i18n/portal_partner_state.pot | 102 ++++++++++++++++++ portal_partner_state/tests/__init__.py | 5 + .../tests/test_portal_partner_state.py | 25 +++++ 6 files changed, 225 insertions(+), 4 deletions(-) create mode 100644 portal_partner_state/i18n/portal_partner_state.pot create mode 100644 portal_partner_state/tests/__init__.py create mode 100644 portal_partner_state/tests/test_portal_partner_state.py diff --git a/portal_partner_state/README.rst b/portal_partner_state/README.rst index 9a2f6e22e..a0e1f0ec0 100644 --- a/portal_partner_state/README.rst +++ b/portal_partner_state/README.rst @@ -16,14 +16,17 @@ Portal with Partner State This module integrate partner state using portal. -#. Add a model access rule in order to able portal users to see the portal. +#. Add a model access rule in order to able portal users to see the portal: + portal users can read the Partner State Fields configuration and the + fields it points to, but can not modify it. Installation ============ To install this module, you need to: -#. Just install this module. +#. Just install this module. It is installed automatically when both + "Partner State" and "Portal" are installed. Configuration ============= @@ -48,7 +51,7 @@ Bug Tracker =========== Bugs are tracked on `GitHub Issues -`_. In case of trouble, please +`_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. diff --git a/portal_partner_state/__manifest__.py b/portal_partner_state/__manifest__.py index 2e624813f..299ebc783 100644 --- a/portal_partner_state/__manifest__.py +++ b/portal_partner_state/__manifest__.py @@ -30,7 +30,7 @@ "portal", ], "data": [ - 'security/ir.access.csv', + "security/ir.access.csv", ], "installable": True, "auto_install": True, diff --git a/portal_partner_state/i18n/es.po b/portal_partner_state/i18n/es.po index db80dcabf..9a3f6a439 100644 --- a/portal_partner_state/i18n/es.po +++ b/portal_partner_state/i18n/es.po @@ -4,3 +4,89 @@ msgstr "" "Language-Team: Spanish (https://app.transifex.com/adhoc/teams/46451/es/)\n" "Language: es\n" "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" + +#. module: portal_partner_state +#: model:ir.module.module,description:base.module_portal_partner_state +msgid "" +".. |company| replace:: ADHOC SA\n" +"\n" +".. |company_logo| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-logo.png\n" +" :alt: ADHOC SA\n" +" :target: https://www.adhoc.com.ar\n" +"\n" +".. |icon| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-icon.png\n" +"\n" +".. image:: https://img.shields.io/badge/license-AGPL--3-blue.png\n" +" :target: https://www.gnu.org/licenses/agpl\n" +" :alt: License: AGPL-3\n" +"\n" +"=========================\n" +"Portal with Partner State\n" +"=========================\n" +"\n" +"This module integrate partner state using portal.\n" +"\n" +"#. Add a model access rule in order to able portal users to see the portal:\n" +" portal users can read the Partner State Fields configuration and the\n" +" fields it points to, but can not modify it.\n" +"\n" +"Installation\n" +"============\n" +"\n" +"To install this module, you need to:\n" +"\n" +"#. Just install this module. It is installed automatically when both\n" +" \"Partner State\" and \"Portal\" are installed.\n" +"\n" +"Configuration\n" +"=============\n" +"\n" +"To configure this module, you need to:\n" +"\n" +"#. Just install this module.\n" +"\n" +"Usage\n" +"=====\n" +"\n" +"To use this module, you need to:\n" +"\n" +"#. Log in with a user with the portal group.\n" +"#. Check if you can see the portal.\n" +"\n" +".. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas\n" +" :alt: Try me on Runbot\n" +" :target: http://runbot.adhoc.com.ar/\n" +"\n" +"Bug Tracker\n" +"===========\n" +"\n" +"Bugs are tracked on `GitHub Issues\n" +"`_. In case of trouble, please\n" +"check there if your issue has already been reported. If you spotted it first,\n" +"help us smashing it by providing a detailed and welcomed feedback.\n" +"\n" +"Credits\n" +"=======\n" +"\n" +"Images\n" +"------\n" +"\n" +"* |company| |icon|\n" +"\n" +"Contributors\n" +"------------\n" +"\n" +"Maintainer\n" +"----------\n" +"\n" +"|company_logo|\n" +"\n" +"This module is maintained by the |company|.\n" +"\n" +"To contribute to this module, please visit https://www.adhoc.com.ar.\n" +msgstr "" + +#. module: portal_partner_state +#: model:ir.module.module,shortdesc:base.module_portal_partner_state +msgid "Portal Partner State" +msgstr "" diff --git a/portal_partner_state/i18n/portal_partner_state.pot b/portal_partner_state/i18n/portal_partner_state.pot new file mode 100644 index 000000000..85e747b7e --- /dev/null +++ b/portal_partner_state/i18n/portal_partner_state.pot @@ -0,0 +1,102 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * portal_partner_state +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 20.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-10-19 21:13+0000\n" +"PO-Revision-Date: 2026-10-19 21:13+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: portal_partner_state +#: model:ir.module.module,description:base.module_portal_partner_state +msgid "" +".. |company| replace:: ADHOC SA\n" +"\n" +".. |company_logo| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-logo.png\n" +" :alt: ADHOC SA\n" +" :target: https://www.adhoc.com.ar\n" +"\n" +".. |icon| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-icon.png\n" +"\n" +".. image:: https://img.shields.io/badge/license-AGPL--3-blue.png\n" +" :target: https://www.gnu.org/licenses/agpl\n" +" :alt: License: AGPL-3\n" +"\n" +"=========================\n" +"Portal with Partner State\n" +"=========================\n" +"\n" +"This module integrate partner state using portal.\n" +"\n" +"#. Add a model access rule in order to able portal users to see the portal:\n" +" portal users can read the Partner State Fields configuration and the\n" +" fields it points to, but can not modify it.\n" +"\n" +"Installation\n" +"============\n" +"\n" +"To install this module, you need to:\n" +"\n" +"#. Just install this module. It is installed automatically when both\n" +" \"Partner State\" and \"Portal\" are installed.\n" +"\n" +"Configuration\n" +"=============\n" +"\n" +"To configure this module, you need to:\n" +"\n" +"#. Just install this module.\n" +"\n" +"Usage\n" +"=====\n" +"\n" +"To use this module, you need to:\n" +"\n" +"#. Log in with a user with the portal group.\n" +"#. Check if you can see the portal.\n" +"\n" +".. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas\n" +" :alt: Try me on Runbot\n" +" :target: http://runbot.adhoc.com.ar/\n" +"\n" +"Bug Tracker\n" +"===========\n" +"\n" +"Bugs are tracked on `GitHub Issues\n" +"`_. In case of trouble, please\n" +"check there if your issue has already been reported. If you spotted it first,\n" +"help us smashing it by providing a detailed and welcomed feedback.\n" +"\n" +"Credits\n" +"=======\n" +"\n" +"Images\n" +"------\n" +"\n" +"* |company| |icon|\n" +"\n" +"Contributors\n" +"------------\n" +"\n" +"Maintainer\n" +"----------\n" +"\n" +"|company_logo|\n" +"\n" +"This module is maintained by the |company|.\n" +"\n" +"To contribute to this module, please visit https://www.adhoc.com.ar.\n" +msgstr "" + +#. module: portal_partner_state +#: model:ir.module.module,shortdesc:base.module_portal_partner_state +msgid "Portal Partner State" +msgstr "" diff --git a/portal_partner_state/tests/__init__.py b/portal_partner_state/tests/__init__.py new file mode 100644 index 000000000..67ccb525f --- /dev/null +++ b/portal_partner_state/tests/__init__.py @@ -0,0 +1,5 @@ +############################################################################## +# For copyright and license notices, see __manifest__.py file in module root +# directory +############################################################################## +from . import test_portal_partner_state diff --git a/portal_partner_state/tests/test_portal_partner_state.py b/portal_partner_state/tests/test_portal_partner_state.py new file mode 100644 index 000000000..b52c8e4c3 --- /dev/null +++ b/portal_partner_state/tests/test_portal_partner_state.py @@ -0,0 +1,25 @@ +############################################################################## +# For copyright and license notices, see __manifest__.py file in module root +# directory +############################################################################## +from odoo.exceptions import AccessError +from odoo.tests import TransactionCase, new_test_user, tagged + + +@tagged("post_install", "-at_install") +class TestPortalPartnerState(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.portal_user = new_test_user(cls.env, login="portal_partner_state", groups="base.group_portal") + field = cls.env["ir.model.fields"]._get("res.partner", "name") + cls.state_field = cls.env["res.partner.state_field"].create({"field_id": field.id}) + + def test_portal_reads_state_fields(self): + records = self.env["res.partner.state_field"].with_user(self.portal_user).search([]) + self.assertIn(self.state_field, records) + self.assertEqual(records.field_id.mapped("name"), records.sudo().field_id.mapped("name")) + + def test_portal_cannot_write_state_fields(self): + with self.assertRaises(AccessError): + self.state_field.with_user(self.portal_user).write({"approval": False}) From cbaef09c7332b9ab81be6a12f4617dde9e099041 Mon Sep 17 00:00:00 2001 From: les-adhoc Date: Mon, 19 Oct 2026 18:37:28 -0300 Subject: [PATCH 4/5] [FIX] portal_partner_state: limit portal read on ir.model.fields to partner fields The portal only needs the res.partner fields that partner_state reads when the portal layout tracks the partner. Reading the whole table also exposed fields like the AI prompts of ai_fields. Adds a test that opens /my as a portal user, which fails with a 403 without the bridge, and one that checks the portal sees only res.partner fields. --- portal_partner_state/security/ir.access.csv | 2 +- .../tests/test_portal_partner_state.py | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/portal_partner_state/security/ir.access.csv b/portal_partner_state/security/ir.access.csv index 408410ab6..842574b68 100644 --- a/portal_partner_state/security/ir.access.csv +++ b/portal_partner_state/security/ir.access.csv @@ -1,3 +1,3 @@ id,name,model_id,group_id/id,operation,domain access_res_partner_state_field_portal,partner_state_field_portal,res.partner.state_field,base.group_portal,r, -access_ir_model_fields_portal,ir_model_fields,ir.model.fields,base.group_portal,r, +access_ir_model_fields_portal,ir_model_fields,ir.model.fields,base.group_portal,r,"[('model', '=', 'res.partner')]" diff --git a/portal_partner_state/tests/test_portal_partner_state.py b/portal_partner_state/tests/test_portal_partner_state.py index b52c8e4c3..4aa04e7dc 100644 --- a/portal_partner_state/tests/test_portal_partner_state.py +++ b/portal_partner_state/tests/test_portal_partner_state.py @@ -3,7 +3,7 @@ # directory ############################################################################## from odoo.exceptions import AccessError -from odoo.tests import TransactionCase, new_test_user, tagged +from odoo.tests import HttpCase, TransactionCase, new_test_user, tagged @tagged("post_install", "-at_install") @@ -23,3 +23,18 @@ def test_portal_reads_state_fields(self): def test_portal_cannot_write_state_fields(self): with self.assertRaises(AccessError): self.state_field.with_user(self.portal_user).write({"approval": False}) + + def test_portal_reads_only_partner_fields(self): + fields = self.env["ir.model.fields"].with_user(self.portal_user).search([]) + self.assertTrue(fields) + self.assertEqual(set(fields.mapped("model")), {"res.partner"}) + + +@tagged("post_install", "-at_install") +class TestPortalPartnerStateHttp(HttpCase): + def test_portal_home(self): + new_test_user(self.env, login="portal_partner_state", groups="base.group_portal") + self.authenticate("portal_partner_state", "portal_partner_state") + response = self.url_open("/my") + self.assertEqual(response.status_code, 200) + self.assertTrue(response.url.endswith("/my"), "the portal user was redirected to the login") From 83f82d322a9ef83df85342fc27fd687d1c8093e7 Mon Sep 17 00:00:00 2001 From: les-adhoc Date: Mon, 2 Nov 2026 14:26:09 -0300 Subject: [PATCH 5/5] [I18N] portal_partner_state: translate module name --- portal_partner_state/i18n/es.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portal_partner_state/i18n/es.po b/portal_partner_state/i18n/es.po index 9a3f6a439..df8028be5 100644 --- a/portal_partner_state/i18n/es.po +++ b/portal_partner_state/i18n/es.po @@ -89,4 +89,4 @@ msgstr "" #. module: portal_partner_state #: model:ir.module.module,shortdesc:base.module_portal_partner_state msgid "Portal Partner State" -msgstr "" +msgstr "Estado de Empresas en el portal"