From 02dfd0184e8c23773a8db991499eb5a66322a345 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Tue, 6 Jun 2023 17:00:07 +0200 Subject: [PATCH 01/19] [IMP] cooperator: Scaffolding for multi-company e-mail templates In this commit, the confirmation e-mail template (chosen at random) is configured on the res.company model instead of fetched via its XMLID. In a future commit, all the other cooperator-related e-mail templates will be configured in the same way, using the common scaffolding from this commit. The commit introduces a bug/regression, which is that the confirmation e-mail won't actually be sent. This is a result of the new scaffolding. Before, this happened: 1. cooperator is marked installed. 2. The mail template data file gets sourced, creating the confirmation template's record. 3. The subscription request demo data file gets sourced, creating a subscription.request record. 4. While creating the record, an e-mail using the confirmation template gets sent. In the new logic, this happens: 1. cooperator is marked installed. 2. The mail template data file gets sourced, creating the confirmation template's record, but NOT setting it on company 1. 3. The subscription request demo data file gets sourced, creating a subscription.request record. 4. While creating the record, Odoo tries to send a mail of the template company_id.cooperator_confirmation_mail_template, but the field is empty. 5. Error, obviously, but we've commented out the erroneous code, so let's proceed. 6. As a post-init hook, a copy of the confirmation template gets set on all companies' cooperator_confirmation_mail_template field. We'll need to re-jig the logic to circumvent the error. A problem for future me. Or you, if you're reading this in the distant future. Hello. Signed-off-by: Carmen Bianca BAKKER --- cooperator/__init__.py | 8 ++ cooperator/__manifest__.py | 1 + cooperator/models/company.py | 65 ++++++++++++++++ cooperator/models/subscription_request.py | 8 +- cooperator/tests/__init__.py | 1 + cooperator/tests/test_mail_templates.py | 95 +++++++++++++++++++++++ cooperator/views/res_company_view.xml | 4 + 7 files changed, 179 insertions(+), 3 deletions(-) create mode 100644 cooperator/tests/test_mail_templates.py diff --git a/cooperator/__init__.py b/cooperator/__init__.py index 7660e7bf6..bc21b805d 100644 --- a/cooperator/__init__.py +++ b/cooperator/__init__.py @@ -1,3 +1,11 @@ from . import models from . import report from . import wizard + +from odoo import api, SUPERUSER_ID + + +def _assign_default_mail_template_ids(cr, registry): + env = api.Environment(cr, SUPERUSER_ID, {}) + companies = env["res.company"].search([]) + companies._setup_default_cooperator_mail_templates() diff --git a/cooperator/__manifest__.py b/cooperator/__manifest__.py index 7b4fb039b..647cba1e9 100644 --- a/cooperator/__manifest__.py +++ b/cooperator/__manifest__.py @@ -54,4 +54,5 @@ "demo/users.xml", ], "application": True, + "post_init_hook": "_assign_default_mail_template_ids", } diff --git a/cooperator/models/company.py b/cooperator/models/company.py index 653561b2c..84b66901c 100644 --- a/cooperator/models/company.py +++ b/cooperator/models/company.py @@ -103,6 +103,11 @@ def _compute_base_logo(self): send_certificate_email = fields.Boolean( string="Send certificate email", default=True ) + cooperator_confirmation_mail_template = fields.Many2one( + comodel_name="mail.template", + string="Share confirmation email template", + domain="[('model', '=', 'subscription.request')]", + ) send_confirmation_email = fields.Boolean( string="Send confirmation email", default=True ) @@ -138,3 +143,63 @@ def onchange_financial_risk_approval_required(self): def onchange_generic_rules_approval_required(self): if self.generic_rules_approval_required: self.display_generic_rules_approval = True + + @api.model + def create(self, vals): + result = super().create(vals) + # The ignore_list is populated such that, if the user defines a template + # they want to use during company creation, that choice doesn't get + # overridden. The boolean check exists because, when creating a company + # from the UI, all empty fields are defined with no value. + result._setup_default_cooperator_mail_templates( + ignore_list=[key for key, val in vals.items() if val] + ) + return result + + @api.model + def _get_cooperator_mail_template_fields(self): + return { + "cooperator_confirmation_mail_template": "cooperator.email_template_confirmation", + } + + def _get_default_cooperator_mail_template(self, xmlid, copy=True): + """Get the mail template from its xmlid and either return it or return + a copy of it. + """ + self.ensure_one() + try: + template = self.env.ref(xmlid) + except ValueError: + return False + if copy: + result = template.copy() + # Set name to 'Company - Template' instead of 'Template (copy)'. + result.name = "{} - {}".format(self.name, template.name) + return result + else: + return template + + def _assign_default_cooperator_mail_template( + self, field, xmlid, copy=True, override=False + ): + for company in self: + if override or not getattr(company, field): + company.write( + { + field: company._get_default_cooperator_mail_template( + xmlid, copy=copy + ).id + } + ) + + def _setup_default_cooperator_mail_templates( + self, copy=True, override=False, ignore_list=None + ): + if ignore_list is None: + ignore_list = [] + for field, xmlid in self._get_cooperator_mail_template_fields().items(): + if field in ignore_list: + continue + self._assign_default_cooperator_mail_template( + field, xmlid, copy=copy, override=override + ) diff --git a/cooperator/models/subscription_request.py b/cooperator/models/subscription_request.py index 1d2486553..d30dcc630 100644 --- a/cooperator/models/subscription_request.py +++ b/cooperator/models/subscription_request.py @@ -53,10 +53,11 @@ def get_required_field(self): def get_mail_template_notif(self, is_company=False): if is_company: + # TODO: Fix this, obviously mail_template = "cooperator.email_template_confirmation_company" + return self.env.ref(mail_template, False) else: - mail_template = "cooperator.email_template_confirmation" - return self.env.ref(mail_template, False) + return self.company_id.cooperator_confirmation_mail_template @api.constrains("share_product_id", "is_company") def _check_share_available_to_user(self): @@ -121,7 +122,8 @@ def create(self, vals): partner.cooperator = True subscription_request = super().create(vals) - subscription_request._send_confirmation_mail() + # FIXME: This should NOT be in the create method. + # subscription_request._send_confirmation_mail() return subscription_request @api.model diff --git a/cooperator/tests/__init__.py b/cooperator/tests/__init__.py index 586162b33..14203466e 100644 --- a/cooperator/tests/__init__.py +++ b/cooperator/tests/__init__.py @@ -1 +1,2 @@ from . import test_cooperator +from . import test_mail_templates diff --git a/cooperator/tests/test_mail_templates.py b/cooperator/tests/test_mail_templates.py new file mode 100644 index 000000000..f0f1247d7 --- /dev/null +++ b/cooperator/tests/test_mail_templates.py @@ -0,0 +1,95 @@ +# SPDX-FileCopyrightText: 2023 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +from odoo.tests.common import SavepointCase + + +class TestMailTemplates(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.default_template = cls.env.ref("cooperator.email_template_confirmation") + + def test_new_company_gets_copy_of_template(self): + """When creating a company, they should correctly get a copy of the mail + template. + """ + company = self.env["res.company"].create({"name": "Test Company"}) + new_template = company.cooperator_confirmation_mail_template + self.assertIn(company.name, new_template.name) + + def test_existing_company_gets_copy_of_template(self): + """When running the default method on an existing company, they should + correctly get a copy of the mail template. This mirrors the posthook. + """ + company = self.env["res.company"].create({"name": "Test Company"}) + company.cooperator_confirmation_mail_template = False + + company._assign_default_cooperator_mail_template( + "cooperator_confirmation_mail_template", + "cooperator.email_template_confirmation", + ) + new_template = company.cooperator_confirmation_mail_template + self.assertIn(company.name, new_template.name) + + def test_assign_default_mail_template_no_copy(self): + """When providing copy=False, the global template is used.""" + company = self.env["res.company"].create({"name": "Test Company"}) + company.cooperator_confirmation_mail_template = False + + company._assign_default_cooperator_mail_template( + "cooperator_confirmation_mail_template", + "cooperator.email_template_confirmation", + copy=False, + ) + new_template = company.cooperator_confirmation_mail_template + self.assertEqual(new_template, self.default_template) + + def test_assign_no_override(self): + """When instructing not to override, don't.""" + company = self.env["res.company"].create({"name": "Test Company"}) + template = company.cooperator_confirmation_mail_template + + company._assign_default_cooperator_mail_template( + "cooperator_confirmation_mail_template", + "cooperator.email_template_confirmation", + override=False, + ) + new_template = company.cooperator_confirmation_mail_template + self.assertEqual(template, new_template) + + def test_assign_override(self): + """When instructing to override, do.""" + company = self.env["res.company"].create({"name": "Test Company"}) + template = company.cooperator_confirmation_mail_template + + company._assign_default_cooperator_mail_template( + "cooperator_confirmation_mail_template", + "cooperator.email_template_confirmation", + override=True, + ) + new_template = company.cooperator_confirmation_mail_template + self.assertNotEqual(template, new_template) + + def test_create_company_dont_override_vals(self): + """When defining a field in the create method, don't override it.""" + company = self.env["res.company"].create( + { + "name": "Test Company", + "cooperator_confirmation_mail_template": self.default_template.id, + } + ) + self.assertEqual( + company.cooperator_confirmation_mail_template, self.default_template + ) + + def test_create_company_override_falsy_val(self): + """When 'defining' a field in the create method as falsy, do override it.""" + company = self.env["res.company"].create( + { + "name": "Test Company", + "cooperator_confirmation_mail_template": False, + } + ) + self.assertTrue(company.cooperator_confirmation_mail_template) diff --git a/cooperator/views/res_company_view.xml b/cooperator/views/res_company_view.xml index d74baefeb..89c1ea102 100644 --- a/cooperator/views/res_company_view.xml +++ b/cooperator/views/res_company_view.xml @@ -39,6 +39,10 @@ + From 1fa62087fe1dd3b3d15b0456f32f877907aa4c79 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Tue, 6 Jun 2023 17:17:25 +0200 Subject: [PATCH 02/19] [IMP] cooperator: Set cooperator_capital_release_mail_template on company Signed-off-by: Carmen Bianca BAKKER --- cooperator/models/account_move.py | 2 +- cooperator/models/company.py | 8 ++++++++ cooperator/views/res_company_view.xml | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cooperator/models/account_move.py b/cooperator/models/account_move.py index 406247447..08b15f013 100644 --- a/cooperator/models/account_move.py +++ b/cooperator/models/account_move.py @@ -205,7 +205,7 @@ def action_invoice_paid(self): return True def _get_capital_release_mail_template(self): - return self.env.ref("cooperator.email_template_release_capital", False) + return self.company_id.cooperator_capital_release_mail_template def send_capital_release_request_mail(self): if self.company_id.send_capital_release_email: diff --git a/cooperator/models/company.py b/cooperator/models/company.py index 84b66901c..39b99cd1c 100644 --- a/cooperator/models/company.py +++ b/cooperator/models/company.py @@ -111,6 +111,11 @@ def _compute_base_logo(self): send_confirmation_email = fields.Boolean( string="Send confirmation email", default=True ) + cooperator_capital_release_mail_template = fields.Many2one( + comodel_name="mail.template", + string="Capital release email template", + domain="[('model', '=', 'account.move')]", + ) send_capital_release_email = fields.Boolean( string="Send Capital Release email", default=True ) @@ -160,6 +165,9 @@ def create(self, vals): def _get_cooperator_mail_template_fields(self): return { "cooperator_confirmation_mail_template": "cooperator.email_template_confirmation", + "cooperator_capital_release_mail_template": ( + "cooperator.email_template_release_capital" + ), } def _get_default_cooperator_mail_template(self, xmlid, copy=True): diff --git a/cooperator/views/res_company_view.xml b/cooperator/views/res_company_view.xml index 89c1ea102..1ed6a2061 100644 --- a/cooperator/views/res_company_view.xml +++ b/cooperator/views/res_company_view.xml @@ -44,6 +44,10 @@ attrs="{'invisible': [('send_confirmation_email', '=', False)]}" /> + From 35f27cfae9069cac89b39a1d4ee1257d8d5c67f8 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Tue, 6 Jun 2023 17:24:51 +0200 Subject: [PATCH 03/19] [IMP] cooperator: Set cooperator_waiting_list_mail_template on company Signed-off-by: Carmen Bianca BAKKER --- cooperator/models/company.py | 6 ++++++ cooperator/models/subscription_request.py | 4 ++-- cooperator/views/res_company_view.xml | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cooperator/models/company.py b/cooperator/models/company.py index 39b99cd1c..62c1644c5 100644 --- a/cooperator/models/company.py +++ b/cooperator/models/company.py @@ -119,6 +119,11 @@ def _compute_base_logo(self): send_capital_release_email = fields.Boolean( string="Send Capital Release email", default=True ) + cooperator_waiting_list_mail_template = fields.Many2one( + comodel_name="mail.template", + string="Waiting list email template", + domain="[('model', '=', 'subscription.request')]", + ) send_waiting_list_email = fields.Boolean( string="Send Waiting List email", default=True ) @@ -168,6 +173,7 @@ def _get_cooperator_mail_template_fields(self): "cooperator_capital_release_mail_template": ( "cooperator.email_template_release_capital" ), + "cooperator_waiting_list_mail_template": "cooperator.email_template_waiting_list", } def _get_default_cooperator_mail_template(self, xmlid, copy=True): diff --git a/cooperator/models/subscription_request.py b/cooperator/models/subscription_request.py index d30dcc630..8e9c45c51 100644 --- a/cooperator/models/subscription_request.py +++ b/cooperator/models/subscription_request.py @@ -781,8 +781,8 @@ def cancel_subscription_request(self): def _send_waiting_list_mail(self): if self.company_id.send_waiting_list_email: - waiting_list_mail_template = self.env.ref( - "cooperator.email_template_waiting_list", False + waiting_list_mail_template = ( + self.company_id.cooperator_waiting_list_mail_template ) waiting_list_mail_template.send_mail(self.id, True) diff --git a/cooperator/views/res_company_view.xml b/cooperator/views/res_company_view.xml index 1ed6a2061..4bfcfa64d 100644 --- a/cooperator/views/res_company_view.xml +++ b/cooperator/views/res_company_view.xml @@ -49,6 +49,8 @@ attrs="{'invisible': [('send_capital_release_email', '=', False)]}" /> + + From 043d64398bee34149183a5624a406a96342cac9f Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Tue, 6 Jun 2023 17:31:37 +0200 Subject: [PATCH 04/19] [IMP] cooperator: Set cooperator_confirmation_company_mail_template on company Signed-off-by: Carmen Bianca BAKKER --- cooperator/models/company.py | 8 ++++++++ cooperator/models/subscription_request.py | 4 +--- cooperator/views/res_company_view.xml | 4 ++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/cooperator/models/company.py b/cooperator/models/company.py index 62c1644c5..5b69265a7 100644 --- a/cooperator/models/company.py +++ b/cooperator/models/company.py @@ -108,6 +108,11 @@ def _compute_base_logo(self): string="Share confirmation email template", domain="[('model', '=', 'subscription.request')]", ) + cooperator_confirmation_company_mail_template = fields.Many2one( + comodel_name="mail.template", + string="Company share confirmation email template", + domain="[('model', '=', 'subscription.request')]", + ) send_confirmation_email = fields.Boolean( string="Send confirmation email", default=True ) @@ -170,6 +175,9 @@ def create(self, vals): def _get_cooperator_mail_template_fields(self): return { "cooperator_confirmation_mail_template": "cooperator.email_template_confirmation", + "cooperator_confirmation_company_mail_template": ( + "cooperator.email_template_confirmation_company" + ), "cooperator_capital_release_mail_template": ( "cooperator.email_template_release_capital" ), diff --git a/cooperator/models/subscription_request.py b/cooperator/models/subscription_request.py index 8e9c45c51..419ccc772 100644 --- a/cooperator/models/subscription_request.py +++ b/cooperator/models/subscription_request.py @@ -53,9 +53,7 @@ def get_required_field(self): def get_mail_template_notif(self, is_company=False): if is_company: - # TODO: Fix this, obviously - mail_template = "cooperator.email_template_confirmation_company" - return self.env.ref(mail_template, False) + return self.company_id.cooperator_confirmation_company_mail_template else: return self.company_id.cooperator_confirmation_mail_template diff --git a/cooperator/views/res_company_view.xml b/cooperator/views/res_company_view.xml index 4bfcfa64d..074a909f0 100644 --- a/cooperator/views/res_company_view.xml +++ b/cooperator/views/res_company_view.xml @@ -43,6 +43,10 @@ name="cooperator_confirmation_mail_template" attrs="{'invisible': [('send_confirmation_email', '=', False)]}" /> + Date: Wed, 7 Jun 2023 09:27:01 +0200 Subject: [PATCH 05/19] [IMP] cooperator: Set cooperator_certificate_mail_template on company Signed-off-by: Carmen Bianca BAKKER --- cooperator/models/account_move.py | 5 ++--- cooperator/models/company.py | 6 ++++++ cooperator/views/res_company_view.xml | 4 ++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cooperator/models/account_move.py b/cooperator/models/account_move.py index 08b15f013..b2d1cde1d 100644 --- a/cooperator/models/account_move.py +++ b/cooperator/models/account_move.py @@ -61,10 +61,9 @@ def create_user(self, partner): def get_mail_template_certificate(self): if self.partner_id.member: - mail_template = "cooperator.email_template_certificat_increase" + return self.env.ref("cooperator.email_template_certificat_increase") else: - mail_template = "cooperator.email_template_certificat" - return self.env.ref(mail_template) + return self.company_id.cooperator_certificate_mail_template def get_sequence_register(self): return self.env.ref("cooperator.sequence_subscription", False) diff --git a/cooperator/models/company.py b/cooperator/models/company.py index 5b69265a7..d750e0940 100644 --- a/cooperator/models/company.py +++ b/cooperator/models/company.py @@ -100,6 +100,11 @@ def _compute_base_logo(self): translate=True, help="Text to display aside the checkbox to approve the generic rules.", ) + cooperator_certificate_mail_template = fields.Many2one( + comodel_name="mail.template", + string="Certificate email template", + domain="[('model', '=', 'res.partner')]", + ) send_certificate_email = fields.Boolean( string="Send certificate email", default=True ) @@ -182,6 +187,7 @@ def _get_cooperator_mail_template_fields(self): "cooperator.email_template_release_capital" ), "cooperator_waiting_list_mail_template": "cooperator.email_template_waiting_list", + "cooperator_certificate_mail_template": "cooperator.email_template_certificat", } def _get_default_cooperator_mail_template(self, xmlid, copy=True): diff --git a/cooperator/views/res_company_view.xml b/cooperator/views/res_company_view.xml index 074a909f0..129eebf46 100644 --- a/cooperator/views/res_company_view.xml +++ b/cooperator/views/res_company_view.xml @@ -53,6 +53,10 @@ attrs="{'invisible': [('send_capital_release_email', '=', False)]}" /> + From 579b74445e1e808f0ac730b7dd76600ecc514742 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Wed, 7 Jun 2023 09:34:24 +0200 Subject: [PATCH 06/19] [IMP] cooperator: Set cooperator_certifice_increase_mail_template on company Signed-off-by: Carmen Bianca BAKKER --- cooperator/models/account_move.py | 2 +- cooperator/models/company.py | 8 ++++++++ cooperator/views/res_company_view.xml | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cooperator/models/account_move.py b/cooperator/models/account_move.py index b2d1cde1d..83ca4cd59 100644 --- a/cooperator/models/account_move.py +++ b/cooperator/models/account_move.py @@ -61,7 +61,7 @@ def create_user(self, partner): def get_mail_template_certificate(self): if self.partner_id.member: - return self.env.ref("cooperator.email_template_certificat_increase") + return self.company_id.cooperator_certificate_increase_mail_template else: return self.company_id.cooperator_certificate_mail_template diff --git a/cooperator/models/company.py b/cooperator/models/company.py index d750e0940..5c0c61108 100644 --- a/cooperator/models/company.py +++ b/cooperator/models/company.py @@ -105,6 +105,11 @@ def _compute_base_logo(self): string="Certificate email template", domain="[('model', '=', 'res.partner')]", ) + cooperator_certificate_increase_mail_template = fields.Many2one( + comodel_name="mail.template", + string="Certificate increase email template", + domain="[('model', '=', 'res.partner')]", + ) send_certificate_email = fields.Boolean( string="Send certificate email", default=True ) @@ -188,6 +193,9 @@ def _get_cooperator_mail_template_fields(self): ), "cooperator_waiting_list_mail_template": "cooperator.email_template_waiting_list", "cooperator_certificate_mail_template": "cooperator.email_template_certificat", + "cooperator_certificate_increase_mail_template": ( + "cooperator.email_template_certificat_increase" + ), } def _get_default_cooperator_mail_template(self, xmlid, copy=True): diff --git a/cooperator/views/res_company_view.xml b/cooperator/views/res_company_view.xml index 129eebf46..141410f1e 100644 --- a/cooperator/views/res_company_view.xml +++ b/cooperator/views/res_company_view.xml @@ -57,6 +57,10 @@ name="cooperator_certificate_mail_template" attrs="{'invisible': [('send_certificate_email', '=', False)]}" /> + From 0c81316204515b809818b0670f854ae4b23f072e Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Wed, 7 Jun 2023 09:49:27 +0200 Subject: [PATCH 07/19] [IMP] cooperator: Set cooperator_share_transfer_mail_template on company Signed-off-by: Carmen Bianca BAKKER --- cooperator/models/company.py | 8 ++++++++ cooperator/models/operation_request.py | 2 +- cooperator/views/res_company_view.xml | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cooperator/models/company.py b/cooperator/models/company.py index 5c0c61108..c1eebf094 100644 --- a/cooperator/models/company.py +++ b/cooperator/models/company.py @@ -142,6 +142,11 @@ def _compute_base_logo(self): send_waiting_list_email = fields.Boolean( string="Send Waiting List email", default=True ) + cooperator_share_transfer_mail_template = fields.Many2one( + comodel_name="mail.template", + string="Share transfer email template", + domain="[('model', '=', 'res.partner')]", + ) send_share_transfer_email = fields.Boolean( string="Send Share Transfer Email", default=True ) @@ -196,6 +201,9 @@ def _get_cooperator_mail_template_fields(self): "cooperator_certificate_increase_mail_template": ( "cooperator.email_template_certificat_increase" ), + "cooperator_share_transfer_mail_template": ( + "cooperator.email_template_share_transfer" + ), } def _get_default_cooperator_mail_template(self, xmlid, copy=True): diff --git a/cooperator/models/operation_request.py b/cooperator/models/operation_request.py index 65e0a7145..a1413a33e 100644 --- a/cooperator/models/operation_request.py +++ b/cooperator/models/operation_request.py @@ -276,7 +276,7 @@ def validate(self): ) def _get_share_transfer_mail_template(self): - return self.env.ref("cooperator.email_template_share_transfer", False) + return self.company_id.cooperator_share_transfer_mail_template def _get_share_update_mail_template(self): return self.env.ref("cooperator.email_template_share_update", False) diff --git a/cooperator/views/res_company_view.xml b/cooperator/views/res_company_view.xml index 141410f1e..f9d5f36a7 100644 --- a/cooperator/views/res_company_view.xml +++ b/cooperator/views/res_company_view.xml @@ -63,6 +63,7 @@ /> + From 97bc40b42b0210f2502162d3ec3a26d3316854c5 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Wed, 7 Jun 2023 10:02:50 +0200 Subject: [PATCH 08/19] [IMP] cooperator: Set cooperator_share_update_mail_template on company Signed-off-by: Carmen Bianca BAKKER --- cooperator/models/company.py | 6 ++++++ cooperator/models/operation_request.py | 2 +- cooperator/views/res_company_view.xml | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cooperator/models/company.py b/cooperator/models/company.py index c1eebf094..6fe4a6de0 100644 --- a/cooperator/models/company.py +++ b/cooperator/models/company.py @@ -150,6 +150,11 @@ def _compute_base_logo(self): send_share_transfer_email = fields.Boolean( string="Send Share Transfer Email", default=True ) + cooperator_share_update_mail_template = fields.Many2one( + comodel_name="mail.template", + string="Share transfer email template", + domain="[('model', '=', 'res.partner')]", + ) send_share_update_email = fields.Boolean( string="Send Share Update Email", default=True ) @@ -204,6 +209,7 @@ def _get_cooperator_mail_template_fields(self): "cooperator_share_transfer_mail_template": ( "cooperator.email_template_share_transfer" ), + "cooperator_share_update_mail_template": "cooperator.email_template_share_update", } def _get_default_cooperator_mail_template(self, xmlid, copy=True): diff --git a/cooperator/models/operation_request.py b/cooperator/models/operation_request.py index a1413a33e..d860b47c3 100644 --- a/cooperator/models/operation_request.py +++ b/cooperator/models/operation_request.py @@ -279,7 +279,7 @@ def _get_share_transfer_mail_template(self): return self.company_id.cooperator_share_transfer_mail_template def _get_share_update_mail_template(self): - return self.env.ref("cooperator.email_template_share_update", False) + return self.company_id.cooperator_share_update_mail_template def _send_share_transfer_mail( self, sub_register_line diff --git a/cooperator/views/res_company_view.xml b/cooperator/views/res_company_view.xml index f9d5f36a7..f9bb9db00 100644 --- a/cooperator/views/res_company_view.xml +++ b/cooperator/views/res_company_view.xml @@ -64,6 +64,7 @@ + From 3a7279ee10325992f65c19eaf85ec1fcd8180599 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Wed, 7 Jun 2023 10:47:01 +0200 Subject: [PATCH 09/19] [IMP] cooperator: Migration script to populate company fields Signed-off-by: Carmen Bianca BAKKER --- cooperator/__manifest__.py | 2 +- .../migrations/14.0.1.7.0/post-migration.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 cooperator/migrations/14.0.1.7.0/post-migration.py diff --git a/cooperator/__manifest__.py b/cooperator/__manifest__.py index 647cba1e9..e56709f5c 100644 --- a/cooperator/__manifest__.py +++ b/cooperator/__manifest__.py @@ -7,7 +7,7 @@ { "name": "Cooperators", "summary": "Manage your cooperators", - "version": "14.0.1.6.0", + "version": "14.0.1.7.0", "depends": [ "base", "web", diff --git a/cooperator/migrations/14.0.1.7.0/post-migration.py b/cooperator/migrations/14.0.1.7.0/post-migration.py new file mode 100644 index 000000000..220a83864 --- /dev/null +++ b/cooperator/migrations/14.0.1.7.0/post-migration.py @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2023 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +import logging + +from odoo import SUPERUSER_ID, api + +_logger = logging.getLogger(__name__) + + +def migrate(cr, version): + env = api.Environment(cr, SUPERUSER_ID, {}) + companies = env["res.company"].search([]) + companies._setup_default_cooperator_mail_templates() From bf5aa278d397f08ac700466e37784497c66beee4 Mon Sep 17 00:00:00 2001 From: Carmen Bianca BAKKER Date: Wed, 7 Jun 2023 15:24:33 +0200 Subject: [PATCH 10/19] [REF] cooperator: Send confirmation e-mail as a separate step from subscription request creation This was rather bad design to start with, and caused a bug during the installation of this module (at which stage the mail templates were not yet correctly set on the companies). An additional state 'confirmed' is created. The use case is to immediately click on it after all the values are correct. Signed-off-by: Carmen Bianca BAKKER --- cooperator/models/subscription_request.py | 34 +++++++++++++------ cooperator/tests/cooperator_test_mixin.py | 2 ++ .../views/subscription_request_view.xml | 20 +++++++++-- .../wizard/validate_subscription_request.py | 2 +- cooperator_website/controllers/main.py | 2 ++ 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/cooperator/models/subscription_request.py b/cooperator/models/subscription_request.py index 419ccc772..5db74fcd4 100644 --- a/cooperator/models/subscription_request.py +++ b/cooperator/models/subscription_request.py @@ -108,7 +108,7 @@ def create(self, vals): if partner: pending_requests_domain = [ ("partner_id", "=", partner.id), - ("state", "in", ("draft", "waiting", "done")), + ("state", "in", ("draft", "confirmed", "waiting", "done")), ] # we don't use partner.coop_candidate because we want to also # handle draft and waiting requests. @@ -120,8 +120,6 @@ def create(self, vals): partner.cooperator = True subscription_request = super().create(vals) - # FIXME: This should NOT be in the create method. - # subscription_request._send_confirmation_mail() return subscription_request @api.model @@ -224,6 +222,7 @@ def _compute_subscription_amount(self): state = fields.Selection( [ ("draft", "Draft"), + ("confirmed", "Confirmed"), ("block", "Blocked"), # todo reword to blocked ("done", "Done"), ("waiting", "Waiting"), @@ -680,10 +679,12 @@ def _get_partner_domain(self): def validate_subscription_request(self): # todo rename to validate (careful with iwp dependencies) self.ensure_one() - if self.state not in ("draft", "waiting"): + if self.state not in ("confirmed", "waiting"): raise ValidationError( - _("The request must be in draft or on waiting list to be validated") + _("The request must be confirmed or on waiting list to be validated") ) + if not self.is_valid_iban: + raise ValidationError(_("Cannot validate request with invalid IBAN.")) partner_obj = self.env["res.partner"] @@ -759,10 +760,21 @@ def validate_subscription_request(self): return invoice + def confirm_subscription_request(self): + self.ensure_one() + if self.state not in ["draft"]: + raise ValidationError(_("Only draft requests can be confirmed.")) + if not self.is_valid_iban: + raise ValidationError(_("Cannot confirm request with invalid IBAN.")) + self._send_confirmation_mail() + self.write({"state": "confirmed"}) + def block_subscription_request(self): self.ensure_one() - if self.state != "draft": - raise ValidationError(_("Only draft requests can be blocked.")) + if self.state not in ["draft", "confirmed"]: + raise ValidationError( + _("Only draft and confirmed requests can be blocked.") + ) self.write({"state": "block"}) def unblock_subscription_request(self): @@ -773,8 +785,8 @@ def unblock_subscription_request(self): def cancel_subscription_request(self): self.ensure_one() - if self.state not in ("draft", "waiting", "done", "block"): - raise ValidationError(_("You cannot cancel a request in this " "state.")) + if self.state not in ("draft", "confirmed", "waiting", "done", "block"): + raise ValidationError(_("You cannot cancel a request in this state.")) self.write({"state": "cancelled"}) def _send_waiting_list_mail(self): @@ -786,9 +798,9 @@ def _send_waiting_list_mail(self): def put_on_waiting_list(self): self.ensure_one() - if self.state != "draft": + if self.state not in ["draft", "confirmed"]: raise ValidationError( - _("Only draft request can be put on the waiting list.") + _("Only draft and confirmed request can be put on the waiting list.") ) self._send_waiting_list_mail() self.write({"state": "waiting"}) diff --git a/cooperator/tests/cooperator_test_mixin.py b/cooperator/tests/cooperator_test_mixin.py index a38e1dac6..100d4afe1 100644 --- a/cooperator/tests/cooperator_test_mixin.py +++ b/cooperator/tests/cooperator_test_mixin.py @@ -91,6 +91,7 @@ def set_up_cooperator_test_data(cls): "skip_iban_control": True, } ) + cls.subscription_request_1.confirm_subscription_request() cls.bank_journal = cls.env["account.journal"].create( {"name": "Bank", "type": "bank", "code": "BNK67"} ) @@ -161,6 +162,7 @@ def get_dummy_subscription_requests_vals(self): "birthdate": "1980-01-01", "iban": "BE60096123456870", "source": "manual", + "state": "confirmed", } def get_dummy_company_subscription_requests_vals(self): diff --git a/cooperator/views/subscription_request_view.xml b/cooperator/views/subscription_request_view.xml index 6222270d0..0abfce34c 100644 --- a/cooperator/views/subscription_request_view.xml +++ b/cooperator/views/subscription_request_view.xml @@ -24,12 +24,19 @@ +