diff --git a/website_membership_signup_required/controllers/website_sale.py b/website_membership_signup_required/controllers/website_sale.py index 6a9a109..16d0194 100644 --- a/website_membership_signup_required/controllers/website_sale.py +++ b/website_membership_signup_required/controllers/website_sale.py @@ -95,4 +95,31 @@ class WebsiteSaleMembershipSignup(WebsiteSale): product_custom_attribute_values=product_custom_attribute_values, no_variant_attribute_value_ids=no_variant_attribute_value_ids, **kwargs - ) \ No newline at end of file + ) + + def _get_mandatory_address_fields(self, country_sudo): + # EMES: the phone field is not mandatory at checkout, for any flow + # (membership or regular). The core's default set in + # `website_sale/controllers/main.py:_get_mandatory_address_fields` + # includes 'phone' alongside name/street/city/country_id. Removing it + # here cascades to both billing and delivery mandatory fields (both + # delegates to this method) and propagates to the frontend: the + # hidden `required_fields` input sent to the address form no longer + # lists 'phone', so `address.js` neither marks the input as + # `:required` nor shows the red asterisk, and the server-side + # `_check_billing_address` / `_check_delivery_address` no longer + # reject empty phones. + fields = super()._get_mandatory_address_fields(country_sudo) + fields.discard("phone") + return fields + + def _get_mandatory_fields(self): + # Portal's `_get_mandatory_fields` (in + # `portal/controllers/portal.py`) returns + # `["name", "phone", "email", "street", "city", "country_id"]`, + # and `website_sale`'s `_get_mandatory_billing_address_fields` + # UNIONS that set with the one from `_get_mandatory_address_fields`. + # So even after we drop 'phone' from the address set above, the + # portal set re-adds it for billing. We need to drop it here too. + fields = list(super()._get_mandatory_fields()) + return [f for f in fields if f != "phone"] \ No newline at end of file diff --git a/website_membership_signup_required/tests/test_membership_signup.py b/website_membership_signup_required/tests/test_membership_signup.py index e956206..bd4e277 100644 --- a/website_membership_signup_required/tests/test_membership_signup.py +++ b/website_membership_signup_required/tests/test_membership_signup.py @@ -7,6 +7,9 @@ from odoo.fields import Date from odoo.addons.website_membership_signup_required.controllers.main import ( AuthSignupHomeMembership as AuthSignupHome, ) +from odoo.addons.website_membership_signup_required.controllers.website_sale import ( + WebsiteSaleMembershipSignup, +) from odoo.addons.website.tools import MockRequest from odoo.tests import TransactionCase, tagged @@ -119,7 +122,14 @@ class TestMembershipSignup(TransactionCase): values = controller._prepare_signup_values(qcontext) self.assertEqual(values.get("firstname"), "John") self.assertEqual(values.get("lastname"), "Doe") - self.assertNotIn("name", values) + # partner_firstname: `name` is composed (lastname + firstname, or + # firstname + lastname depending on _get_names_order) and added by + # our override so that the core signup check (no name or partner) + # passes. partner_firstname's `res.partner.create` will later drop + # this composed `name` and recompute it from the split fields. + self.assertIn("name", values) + self.assertIn("John", values["name"]) + self.assertIn("Doe", values["name"]) # -- RF-08 ------------------------------------------------------------- @@ -135,4 +145,56 @@ class TestMembershipSignup(TransactionCase): self.assertEqual(order.order_line.product_id, self.membership_product) # Confirming the SO drives membership creation (core `membership`). order.action_confirm() - self.assertEqual(order.state, "sale") \ No newline at end of file + self.assertEqual(order.state, "sale") + + # -- Phone not mandatory at checkout (EMES) ---------------------------- + + def test_09_phone_not_mandatory_address_fields(self): + """`phone` must not be part of the mandatory checkout fields, for + any address (billing or delivery) and any flow on the EMES website. + The core default (`website_sale/controllers/main.py: + _get_mandatory_address_fields`) includes 'phone'; our override drops + it. The frontend `address.js` then no longer marks the input + `:required` nor shows the asterisk, and the server-side + `_check_billing_address` / `_check_delivery_address` no longer + reject empty phones. + """ + country = self.env.ref("base.es") + ctrl = WebsiteSaleMembershipSignup() + fields = ctrl._get_mandatory_address_fields(country) + self.assertNotIn("phone", fields) + # Default mandatory fields still present. + self.assertIn("name", fields) + self.assertIn("street", fields) + self.assertIn("city", fields) + self.assertIn("country_id", fields) + + def test_10_phone_not_in_portal_mandatory_fields(self): + """`phone` must also be dropped from the portal-side mandatory + field list (`portal/controllers/portal.py:_get_mandatory_fields` + returns `["name", "phone", "email", "street", "city", + "country_id"]`). `website_sale`'s + `_get_mandatory_billing_address_fields` UNIONS that set with the + address set from `_get_mandatory_address_fields`, so even with the + address override alone, 'phone' would come back via the portal + path for billing. Hence this second override. + """ + ctrl = WebsiteSaleMembershipSignup() + fields = ctrl._get_mandatory_fields() + self.assertNotIn("phone", fields) + # Other portal mandatory fields still present. + self.assertIn("name", fields) + self.assertIn("email", fields) + self.assertIn("country_id", fields) + + def test_11_phone_not_in_mandatory_billing_address_fields(self): + """End-to-end check of the billing set: the union of + `_get_mandatory_address_fields` + `_get_mandatory_fields` (which is + what `_get_mandatory_billing_address_fields` returns) must NOT + contain 'phone'. + """ + country = self.env.ref("base.es") + ctrl = WebsiteSaleMembershipSignup() + billing_fields = ctrl._get_mandatory_billing_address_fields(country) + self.assertNotIn("phone", billing_fields) + self.assertIn("email", billing_fields) \ No newline at end of file