Add UTM parameters to shortened URL

Closes #12772
This commit is contained in:
Cédric Krier committed 2023-11-24 19:28:23 +01:00
1 parent f9a638e951
commit 2cf37b3763
8 files changed
+104 -5

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Add UTM parameters to shortened URL
Version 7.0.0 - 2023-10-30
--------------------------
+7 -3
View File
@@ -13,10 +13,11 @@ try:
except ImportError:
OpportunityAbstract = None
from . import marketing, sale, sale_opportunity_reporting, sale_reporting
from .marketing import MarketingCampaignMixin, Parameter
from . import marketing, sale, sale_opportunity_reporting, sale_reporting, web
from .marketing import MarketingCampaignMixin, MarketingCampaignUTM, Parameter
__all__ = ['register', 'Parameter', 'MarketingCampaignMixin']
__all__ = [
'register', 'Parameter', 'MarketingCampaignMixin', 'MarketingCampaignUTM']
def register():
@@ -41,6 +42,9 @@ def register():
Pool.register(
sale.POSSale,
module='marketing_campaign', type_='model', depends=['sale_point'])
Pool.register(
web.ShortenedURL,
module='marketing_campaign', type_='model', depends=['web_shortener'])
if SaleAbstract:
Pool.register_mixin(
sale_reporting.AbstractMarketingCampaign, SaleAbstract,
@@ -31,4 +31,10 @@ Campaign
Yield the field names of the :class:`Parameter` fields.
.. class:: MarketingCampaignUTM
The *MarketingCampaignUTM* is a mixin_ that helps to add UTM_ parameters to
URL.
.. _mixin: https://en.wikipedia.org/wiki/Mixin
.. _UTM: https://en.wikipedia.org/wiki/UTM_parameters
+34
View File
@@ -1,6 +1,8 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from urllib.parse import parse_qsl, urlencode, urlparse, urlunparse
from sql.functions import Lower
from sql.operators import Equal
@@ -78,6 +80,38 @@ class Source(Parameter):
__name__ = 'marketing.source'
class MarketingCampaignUTM:
__slots__ = ()
@property
def utm_campaign(self):
if campaign := getattr(self, 'marketing_campaign', None):
return campaign.name
@property
def utm_medium(self):
if medium := getattr(self, 'marketing_medium', None):
return medium.name
@property
def utm_source(self):
if source := getattr(self, 'marketing_source', None):
return source.name
def add_utm_parameters(self, url):
params = {}
for name in ['utm_campaign', 'utm_medium', 'utm_source']:
if value := getattr(self, name):
params[name] = value
if params:
url_parts = list(urlparse(url))
query = dict(parse_qsl(url_parts[4]))
query.update(params)
url_parts[4] = urlencode(query)
url = urlunparse(url_parts)
return url
class MarketingCampaignMixin(Model):
marketing_campaign = fields.Many2One(
+1
View File
@@ -55,6 +55,7 @@ tests_require = [
get_require_version('trytond_sale'),
get_require_version('trytond_sale_opportunity'),
get_require_version('trytond_sale_point'),
get_require_version('trytond_web_shortener'),
]
setup(name=name,
@@ -1,12 +1,47 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.tests.test_tryton import ModuleTestCase
from unittest.mock import patch
from trytond.model import ModelStorage
from trytond.modules.marketing_campaign import MarketingCampaignUTM
from trytond.pool import Pool
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
class MarketingCampaignTestCase(ModuleTestCase):
"Test Marketing Campaign module"
module = 'marketing_campaign'
extras = ['sale', 'sale_opportunity', 'sale_point']
extras = ['sale', 'sale_opportunity', 'sale_point', 'web_shortener']
@with_transaction()
def test_shortened_url_add_utm(self):
"Test add UTM to shortened URL"
pool = Pool()
ShortenedURL = pool.get('web.shortened_url')
URLAccess = pool.get('web.shortened_url.access')
Campaign = pool.get('marketing.campaign')
with patch.object(URLAccess, 'save'):
class Record(MarketingCampaignUTM, ModelStorage):
__slots__ = ('marketing_campaign',)
id = 1
Record.__setup__()
Record.__post_setup__()
campaign = Campaign(name='campaign')
campaign.save()
record = Record()
record.marketing_campaign = campaign
shortened_url = ShortenedURL(
redirect_url='http://example.com/',
record=record,
method=None)
self.assertEqual(
shortened_url.access(),
'http://example.com/?utm_campaign=campaign')
del ModuleTestCase
+1
View File
@@ -7,6 +7,7 @@ extras_depend:
sale
sale_opportunity
sale_point
web_shortener
xml:
marketing.xml
sale.xml
+17
View File
@@ -0,0 +1,17 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.pool import PoolMeta
from .marketing import MarketingCampaignUTM
class ShortenedURL(metaclass=PoolMeta):
__name__ = 'web.shortened_url'
def access(self, **values):
url = super().access(**values)
if isinstance(self.record, MarketingCampaignUTM):
url = self.record.add_utm_parameters(url)
return url