From df63a062256a3edf572f3e5abe71e29933a966b2 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Thu, 1 Jun 2023 12:34:18 +0200 Subject: [PATCH 1/5] [FIX] eater: Add restraints on parent and child eaters Signed-off-by: Carmen Bianca BAKKER --- eater/models/partner.py | 48 +++++++++++++++++++++++- eater/tests/__init__.py | 1 + eater/tests/test_partner.py | 75 +++++++++++++++++++++++++++++++++++++ eater/views/partner.xml | 12 ++++-- 4 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 eater/tests/__init__.py create mode 100644 eater/tests/test_partner.py diff --git a/eater/models/partner.py b/eater/models/partner.py index fcbabf999..2bb3a82cf 100644 --- a/eater/models/partner.py +++ b/eater/models/partner.py @@ -18,9 +18,53 @@ class Partner(models.Model): domain=[("customer", "=", True), ("eater", "=", "eater")], ) parent_eater_id = fields.Many2one( - "res.partner", string="Parent Worker", readonly=True + "res.partner", + string="Parent Worker", + readonly=True, + domain=[("customer", "=", True), ("eater", "=", "worker_eater")], ) + @api.constrains("eater", "parent_eater_id") + def _check_parent_is_worker(self): + """The parent of an eater must be a worker_eater, and worker_eaters + cannot have parents. + """ + for partner in self: + parent = partner.parent_eater_id + if partner.eater == "eater" and parent: + if parent.eater != "worker_eater": + raise ValidationError( + _( + "{0} cannot be the parent of {1} because the parent" + " must be a worker." + ).format(parent.name, partner.name) + ) + if partner.eater == "worker_eater" and parent: + raise ValidationError( + _( + "%s cannot have a parent worker because they are" + " themselves a worker." + ) + % partner.name + ) + + @api.constrains("customer", "parent_eater_id", "child_eater_ids") + def _check_eater_is_customer(self): + """An eater (or worker_eater) with a parent (or a child) must be a customer.""" + for partner in self: + if ( + partner.parent_eater_id or partner.child_eater_ids + ) and not partner.customer: + raise ValidationError( + _("%s must be a customer to be an eater or a parent worker.") + % partner.name + ) + if partner.parent_eater_id and not partner.parent_eater_id.customer: + raise ValidationError( + _("%s must be a customer to be a parent worker.") + % partner.parent_eater_id.name + ) + @api.multi def write(self, values): for partner in self: @@ -42,7 +86,7 @@ def write(self, values): for command in values["child_eater_ids"]: if command[0] == 2: command[0] = 3 - return super(Partner, self).write(values) + return super().write(values) @api.multi def _new_eater(self, surname, name, email): diff --git a/eater/tests/__init__.py b/eater/tests/__init__.py new file mode 100644 index 000000000..20117cf82 --- /dev/null +++ b/eater/tests/__init__.py @@ -0,0 +1 @@ +from . import test_partner diff --git a/eater/tests/test_partner.py b/eater/tests/test_partner.py new file mode 100644 index 000000000..3ca9086b9 --- /dev/null +++ b/eater/tests/test_partner.py @@ -0,0 +1,75 @@ +from odoo.exceptions import ValidationError +from odoo.tests.common import SavepointCase + + +class TestPartner(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.worker_1 = cls.env["res.partner"].create( + { + "name": "Worker 1", + "eater": "worker_eater", + "customer": True, + } + ) + cls.worker_2 = cls.env["res.partner"].create( + { + "name": "Worker 2", + "eater": "worker_eater", + "customer": True, + } + ) + cls.eater_1 = cls.env["res.partner"].create( + { + "name": "Eater 1", + "eater": "eater", + "customer": True, + } + ) + cls.eater_2 = cls.env["res.partner"].create( + { + "name": "Eater 2", + "eater": "eater", + "customer": True, + } + ) + + def test_eater_not_parent_of_worker_eater(self): + with self.assertRaises(ValidationError): + self.worker_1.parent_eater_id = self.eater_1 + + def test_worker_eater_not_child_of_eater(self): + with self.assertRaises(ValidationError): + self.eater_1.child_eater_ids = self.worker_1 + + def test_eater_not_parent_of_eater(self): + with self.assertRaises(ValidationError): + self.eater_1.parent_eater_id = self.eater_2 + + def test_worker_eater_no_parent(self): + with self.assertRaises(ValidationError): + self.worker_2.parent_eater_id = self.worker_1 + + def test_no_parent_of_self(self): + with self.assertRaises(ValidationError): + self.worker_2.parent_eater_id = self.worker_2 + + def test_worker_eater_parent_of_eater(self): + self.eater_1.parent_eater_id = self.worker_1 + + def test_worker_eater_not_customer(self): + self.eater_1.parent_eater_id = self.worker_1 + with self.assertRaises(ValidationError): + self.worker_1.customer = False + + def test_worker_eater_not_customer_2(self): + # same, but reversed + self.worker_1.customer = False + with self.assertRaises(ValidationError): + self.eater_1.parent_eater_id = self.worker_1 + + def test_eater_not_customer(self): + self.eater_1.parent_eater_id = self.worker_1 + with self.assertRaises(ValidationError): + self.eater_1.customer = False diff --git a/eater/views/partner.xml b/eater/views/partner.xml index 4b1ec924b..262dc4e7e 100644 --- a/eater/views/partner.xml +++ b/eater/views/partner.xml @@ -8,10 +8,7 @@ - + + @@ -28,6 +31,7 @@ name="%(new_eater_wizard_action)d" type="action" class="btn btn-primary" + attrs="{'invisible': [('eater', '=', 'eater')]}" /> From f07df072417e7a3ee02e9b109e531c2ba389edd3 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Thu, 1 Jun 2023 16:40:40 +0200 Subject: [PATCH 2/5] [FIX] eater: Migration script Signed-off-by: Carmen Bianca BAKKER --- eater/__manifest__.py | 2 +- eater/migrations/12.0.2.0.0/pre-migration.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 eater/migrations/12.0.2.0.0/pre-migration.py diff --git a/eater/__manifest__.py b/eater/__manifest__.py index 3546ef588..9618bfe14 100644 --- a/eater/__manifest__.py +++ b/eater/__manifest__.py @@ -11,7 +11,7 @@ "author": "BEES coop - Cellule IT, Coop IT Easy SC", "website": "https://github.com/beescoop/Obeesdoo", "category": "Sales", - "version": "12.0.1.0.0", + "version": "12.0.2.0.0", "depends": ["base", "partner_firstname"], "data": [ "wizard/new_eater_wizard_views.xml", diff --git a/eater/migrations/12.0.2.0.0/pre-migration.py b/eater/migrations/12.0.2.0.0/pre-migration.py new file mode 100644 index 000000000..1b7235286 --- /dev/null +++ b/eater/migrations/12.0.2.0.0/pre-migration.py @@ -0,0 +1,17 @@ +# SPDX-FileCopyrightText: 2023 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + # This is an impossible scenario. It causes an endless loop bug that I'm not + # able to debug exactly, but it's easier to just get rid of this scenario. + sql = """ + UPDATE res_partner + SET parent_eater_id = null + WHERE eater = 'worker_eater' + """ + openupgrade.logged_query(env.cr, sql) From 0dfa7305c67733f033db0e4bc6ddf19e758f5f63 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Thu, 1 Jun 2023 17:14:52 +0200 Subject: [PATCH 3/5] [FIX] cooperator_eater: Repair tests Signed-off-by: Carmen Bianca BAKKER --- cooperator_eater/tests/test_eaters.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cooperator_eater/tests/test_eaters.py b/cooperator_eater/tests/test_eaters.py index 93498adbe..664b687a4 100644 --- a/cooperator_eater/tests/test_eaters.py +++ b/cooperator_eater/tests/test_eaters.py @@ -33,6 +33,10 @@ def setUpClass(cls): {"name": "Eater 4", "customer": True, "eater": "eater"} ) + cls.cooperator_x.eater = "worker_eater" + cls.cooperator_y.eater = "worker_eater" + cls.cooperator_z.eater = "worker_eater" + cls.worker_share = ptemplate_obj.create( { "name": "Worker Share", From e35a029b326911c575aa87cffc0ded78ca47ecfd Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Thu, 29 Jun 2023 11:55:28 +0200 Subject: [PATCH 4/5] [IMP] eater: Set customer=True for child and parent eaters This was not correctly restrained previously, so let's fix this. Signed-off-by: Carmen Bianca BAKKER --- eater/migrations/12.0.3.0.0/post-migration.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 eater/migrations/12.0.3.0.0/post-migration.py diff --git a/eater/migrations/12.0.3.0.0/post-migration.py b/eater/migrations/12.0.3.0.0/post-migration.py new file mode 100644 index 000000000..0bf617423 --- /dev/null +++ b/eater/migrations/12.0.3.0.0/post-migration.py @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2023 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + # Parent and child eaters should be customers. + sql = """ + UPDATE res_partner + SET customer = true + WHERE parent_eater_id IS NOT NULL OR id IN ( + SELECT parent_eater_id + FROM res_partner + WHERE parent_eater_id IS NOT NULL + ) + """ + openupgrade.logged_query(env.cr, sql) From ef91d91c4a7c73b8bdc1dc674783f5304b82ff91 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Wed, 6 Sep 2023 11:41:21 +0200 Subject: [PATCH 5/5] [REF] eater: Undo changes to customer In 13.0, the customer field disappears. To ease the migration, let's just get rid of the customer requirement already. It didn't add much, and deleting code is good dopamine. Signed-off-by: Carmen Bianca BAKKER --- eater/migrations/12.0.3.0.0/post-migration.py | 20 ------------------ eater/models/partner.py | 21 ++----------------- eater/tests/test_partner.py | 20 ------------------ eater/views/partner.xml | 2 +- 4 files changed, 3 insertions(+), 60 deletions(-) delete mode 100644 eater/migrations/12.0.3.0.0/post-migration.py diff --git a/eater/migrations/12.0.3.0.0/post-migration.py b/eater/migrations/12.0.3.0.0/post-migration.py deleted file mode 100644 index 0bf617423..000000000 --- a/eater/migrations/12.0.3.0.0/post-migration.py +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Coop IT Easy SC -# -# SPDX-License-Identifier: AGPL-3.0-or-later - -from openupgradelib import openupgrade - - -@openupgrade.migrate() -def migrate(env, version): - # Parent and child eaters should be customers. - sql = """ - UPDATE res_partner - SET customer = true - WHERE parent_eater_id IS NOT NULL OR id IN ( - SELECT parent_eater_id - FROM res_partner - WHERE parent_eater_id IS NOT NULL - ) - """ - openupgrade.logged_query(env.cr, sql) diff --git a/eater/models/partner.py b/eater/models/partner.py index 2bb3a82cf..efb66c3c0 100644 --- a/eater/models/partner.py +++ b/eater/models/partner.py @@ -15,13 +15,13 @@ class Partner(models.Model): child_eater_ids = fields.One2many( "res.partner", "parent_eater_id", - domain=[("customer", "=", True), ("eater", "=", "eater")], + domain=[("eater", "=", "eater")], ) parent_eater_id = fields.Many2one( "res.partner", string="Parent Worker", readonly=True, - domain=[("customer", "=", True), ("eater", "=", "worker_eater")], + domain=[("eater", "=", "worker_eater")], ) @api.constrains("eater", "parent_eater_id") @@ -48,23 +48,6 @@ def _check_parent_is_worker(self): % partner.name ) - @api.constrains("customer", "parent_eater_id", "child_eater_ids") - def _check_eater_is_customer(self): - """An eater (or worker_eater) with a parent (or a child) must be a customer.""" - for partner in self: - if ( - partner.parent_eater_id or partner.child_eater_ids - ) and not partner.customer: - raise ValidationError( - _("%s must be a customer to be an eater or a parent worker.") - % partner.name - ) - if partner.parent_eater_id and not partner.parent_eater_id.customer: - raise ValidationError( - _("%s must be a customer to be a parent worker.") - % partner.parent_eater_id.name - ) - @api.multi def write(self, values): for partner in self: diff --git a/eater/tests/test_partner.py b/eater/tests/test_partner.py index 3ca9086b9..398b982fa 100644 --- a/eater/tests/test_partner.py +++ b/eater/tests/test_partner.py @@ -10,28 +10,24 @@ def setUpClass(cls): { "name": "Worker 1", "eater": "worker_eater", - "customer": True, } ) cls.worker_2 = cls.env["res.partner"].create( { "name": "Worker 2", "eater": "worker_eater", - "customer": True, } ) cls.eater_1 = cls.env["res.partner"].create( { "name": "Eater 1", "eater": "eater", - "customer": True, } ) cls.eater_2 = cls.env["res.partner"].create( { "name": "Eater 2", "eater": "eater", - "customer": True, } ) @@ -57,19 +53,3 @@ def test_no_parent_of_self(self): def test_worker_eater_parent_of_eater(self): self.eater_1.parent_eater_id = self.worker_1 - - def test_worker_eater_not_customer(self): - self.eater_1.parent_eater_id = self.worker_1 - with self.assertRaises(ValidationError): - self.worker_1.customer = False - - def test_worker_eater_not_customer_2(self): - # same, but reversed - self.worker_1.customer = False - with self.assertRaises(ValidationError): - self.eater_1.parent_eater_id = self.worker_1 - - def test_eater_not_customer(self): - self.eater_1.parent_eater_id = self.worker_1 - with self.assertRaises(ValidationError): - self.eater_1.customer = False diff --git a/eater/views/partner.xml b/eater/views/partner.xml index 262dc4e7e..7d5506a5b 100644 --- a/eater/views/partner.xml +++ b/eater/views/partner.xml @@ -8,7 +8,7 @@ - +