From f3bf06cf633ac4dcca993f06b4e03225be58930a Mon Sep 17 00:00:00 2001 From: NoeBerdoz Date: Tue, 28 Apr 2026 13:32:15 +0200 Subject: [PATCH 1/2] [REF] T3150: Refactor UTM handling using native Odoo's utm.mixin --- my_compassion/__manifest__.py | 1 + my_compassion/controllers/my2_sponsorships.py | 71 +++---------------- my_compassion/models/contracts.py | 10 ++- 3 files changed, 20 insertions(+), 62 deletions(-) diff --git a/my_compassion/__manifest__.py b/my_compassion/__manifest__.py index 5a976c5a..d82f14b9 100644 --- a/my_compassion/__manifest__.py +++ b/my_compassion/__manifest__.py @@ -114,6 +114,7 @@ "auth_signup_verify_email", # OCA/server-auth "queue_job", "theme_compassion_2025", + "utm", ], "demo": [], "installable": True, diff --git a/my_compassion/controllers/my2_sponsorships.py b/my_compassion/controllers/my2_sponsorships.py index 007122be..8d483245 100644 --- a/my_compassion/controllers/my2_sponsorships.py +++ b/my_compassion/controllers/my2_sponsorships.py @@ -201,75 +201,28 @@ def _get_filtered_domain(cls, post): class MyCompassionNewSponsorshipController(http.Controller): - @staticmethod - def _extract_utm_information() -> dict: - """ - Extracts utm medium, source and campaign information - from the session and returns it. - Return: - a dictionary containing utm information or empty dict - IMPORTANT: - the utms need to be created first, otherwise they - will be ignored! - """ - utm_mapping = { - "wizard_utm_medium": ("utm.medium", "medium_id"), - "wizard_utm_source": ("utm.source", "source_id"), - "wizard_utm_campaign": ("utm.campaign", "campaign_id"), - } - session_vals = {k: request.session.get(k) for k in utm_mapping} - if any(session_vals.values()): - utm_vals = {} - for k, val in session_vals.items(): - if val: - model, f_id = utm_mapping[k] - rec = ( - request.env[model] - .sudo() - .search([("name", "=ilike", val)], limit=1) - ) - # only assign if campaign already exists - if rec: - utm_vals[f_id] = rec.id - # clean up the session variables - for k in utm_mapping: - request.session.pop(k, None) - return utm_vals - return {} - @http.route( - "/my2/new-sponsorship/", + '/my2/new-sponsorship/', type="http", auth="public", website=True, ) - def wizard_start(self, child_id, sponsorship_type="standard", **kwargs): + def wizard_start(self, child, sponsorship_type="standard", **kwargs): """ Renders the new sponsorship wizard initial page. + + UTM tracking from query params is handled by Odoo's utm.mixin model. + return: An HTTP response containing a rendered template with the initial wizard page. """ - child = request.env["compassion.child"].sudo().browse(child_id) - - if not child.exists(): - raise NotFound("Child not found in database") - - # capture and store utm information - utm_medium = kwargs.get("utm_medium") - utm_source = kwargs.get("utm_source") - utm_campaign = kwargs.get("utm_campaign") - - if utm_medium: - request.session["wizard_utm_medium"] = utm_medium - if utm_source: - request.session["wizard_utm_source"] = utm_source - if utm_campaign: - request.session["wizard_utm_campaign"] = utm_campaign - # Make sure child is available and reserve it for 5 minutes - if child.state not in child._available_states(): + child = child.sudo() + if not child.exists() or child.state not in child._available_states(): raise NotFound() + + # Reserve child for 5 minutes reservation_uuid = self._get_reservation_uuid() - if not child.sudo().reserve_for_web_sponsorship(reservation_uuid): + if not child.reserve_for_web_sponsorship(reservation_uuid): raise Gone() # Create new wizard @@ -348,10 +301,6 @@ def sponsorship_wizard_submit(self, **post): raise Gone() sponsorship = wizard.finish_sponsorship() - utm_values = self._extract_utm_information() - if utm_values: - sponsorship.sudo().write(utm_values) - # Redirect to thank-you page return request.redirect( f"/my2/new-sponsorship/thank-you?sponsorship_id={sponsorship.id}" diff --git a/my_compassion/models/contracts.py b/my_compassion/models/contracts.py index 4e32f8eb..51160dad 100644 --- a/my_compassion/models/contracts.py +++ b/my_compassion/models/contracts.py @@ -2,7 +2,15 @@ class RecurringContract(models.Model): - _inherit = "recurring.contract" + """ + Extends the recurring.contract model for MyCompassion features. + + Inheriting "utm.mixin" makes sure that the model integrates Odoo's utm features. + This allows Odoo to automatically intercept UTM cookies. + """ + + _name = "recurring.contract" + _inherit = ["recurring.contract", "utm.mixin"] can_show_on_my_compassion = fields.Boolean( string="Can be shown on My Compassion", From 62324d31b9fa61f31af4565046a3fe4fda9b0f88 Mon Sep 17 00:00:00 2001 From: NoeBerdoz Date: Tue, 28 Apr 2026 14:25:24 +0200 Subject: [PATCH 2/2] [FIX] T3150: Add generic query parameters handling on login redirection --- my_compassion/controllers/my2_sponsorships.py | 8 ++++++++ .../templates/pages/my2_new_sponsorship_wizard.xml | 7 +------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/my_compassion/controllers/my2_sponsorships.py b/my_compassion/controllers/my2_sponsorships.py index 8d483245..f506bb02 100644 --- a/my_compassion/controllers/my2_sponsorships.py +++ b/my_compassion/controllers/my2_sponsorships.py @@ -8,6 +8,7 @@ ############################################################################## import random import uuid +from urllib.parse import urlencode from dateutil.relativedelta import relativedelta from werkzeug.exceptions import BadRequest, Gone, NotFound @@ -354,6 +355,12 @@ def _render_form_content(wizard): ) currency_name = request.env.user.company_id.currency_id.name + # Send the user back to the exact URL they came from after login, + # preserving every query param (UTM, sponsorship_type, anything else). + login_url_redirect = ( + f"/web/login?{urlencode({'redirect': request.httprequest.full_path})}" + ) + # Render step template first inner_step_html = request.env["ir.qweb"]._render( wizard.current_step.template, @@ -365,6 +372,7 @@ def _render_form_content(wizard): "spoken_languages": spoken_languages, "lead_sources": lead_sources, "currency_name": currency_name, + "login_url_redirect": login_url_redirect, }, ) diff --git a/my_compassion/templates/pages/my2_new_sponsorship_wizard.xml b/my_compassion/templates/pages/my2_new_sponsorship_wizard.xml index 7de8179a..7abe7c40 100644 --- a/my_compassion/templates/pages/my2_new_sponsorship_wizard.xml +++ b/my_compassion/templates/pages/my2_new_sponsorship_wizard.xml @@ -68,12 +68,7 @@ Page: My Compassion 2 New Sponsorship Wizard Page