diff --git a/frappe/email/doctype/newsletter/newsletter.json b/frappe/email/doctype/newsletter/newsletter.json index 6b000e89a3..9774e9abad 100644 --- a/frappe/email/doctype/newsletter/newsletter.json +++ b/frappe/email/doctype/newsletter/newsletter.json @@ -244,7 +244,7 @@ "fieldname": "campaign", "fieldtype": "Link", "label": "Campaign", - "options": "Marketing Campaign" + "options": "UTM Campaign" } ], "has_web_view": 1, @@ -253,7 +253,7 @@ "index_web_pages_for_search": 1, "is_published_field": "published", "links": [], - "modified": "2024-03-23 16:03:30.890080", + "modified": "2024-09-03 18:48:07.263679", "modified_by": "Administrator", "module": "Email", "name": "Newsletter", diff --git a/frappe/email/doctype/newsletter/newsletter.py b/frappe/email/doctype/newsletter/newsletter.py index 5b39a00d7e..6653d43054 100644 --- a/frappe/email/doctype/newsletter/newsletter.py +++ b/frappe/email/doctype/newsletter/newsletter.py @@ -22,9 +22,7 @@ class Newsletter(WebsiteGenerator): if TYPE_CHECKING: from frappe.email.doctype.newsletter_attachment.newsletter_attachment import NewsletterAttachment - from frappe.email.doctype.newsletter_email_group.newsletter_email_group import ( - NewsletterEmailGroup, - ) + from frappe.email.doctype.newsletter_email_group.newsletter_email_group import NewsletterEmailGroup from frappe.types import DF attachments: DF.Table[NewsletterAttachment] diff --git a/frappe/public/js/frappe/utils/utils.js b/frappe/public/js/frappe/utils/utils.js index 1a89614904..66d120f993 100644 --- a/frappe/public/js/frappe/utils/utils.js +++ b/frappe/public/js/frappe/utils/utils.js @@ -1718,8 +1718,9 @@ Object.assign(frappe.utils, { { fieldname: "source", label: __("Source"), - fieldtype: "Data", + fieldtype: "Link", reqd: 1, + options: "UTM Source", description: "The referrer (e.g. google, newsletter)", default: localStorage.getItem("tracker_url:source"), }, @@ -1728,13 +1729,14 @@ Object.assign(frappe.utils, { label: __("Campaign"), fieldtype: "Link", ignore_link_validation: 1, - options: "Marketing Campaign", + options: "UTM Campaign", default: localStorage.getItem("tracker_url:campaign"), }, { fieldname: "medium", label: __("Medium"), - fieldtype: "Data", + fieldtype: "Link", + options: "UTM Medium", description: "Marketing medium (e.g. cpc, banner, email)", default: localStorage.getItem("tracker_url:medium"), }, @@ -1746,21 +1748,32 @@ Object.assign(frappe.utils, { default: localStorage.getItem("tracker_url:content"), }, ], - function (data) { + async function (data) { let url = data.url; localStorage.setItem("tracker_url:url", data.url); - url += "?utm_source=" + encodeURIComponent(data.source); + const { message } = await frappe.db.get_value("UTM Source", data.source, "slug"); + url += "?utm_source=" + encodeURIComponent(message.slug || data.source); localStorage.setItem("tracker_url:source", data.source); if (data.campaign) { - url += "&utm_campaign=" + encodeURIComponent(data.campaign); + const { message } = await frappe.db.get_value( + "UTM Campaign", + data.campaign, + "slug" + ); + url += "&utm_campaign=" + encodeURIComponent(message.slug || data.campaign); localStorage.setItem("tracker_url:campaign", data.campaign); } if (data.medium) { - url += "&utm_medium=" + encodeURIComponent(data.medium); + const { message } = await frappe.db.get_value( + "UTM Medium", + data.medium, + "slug" + ); + url += "&utm_medium=" + encodeURIComponent(message.slug || data.medium); localStorage.setItem("tracker_url:medium", data.medium); } - if (data.medium) { + if (data.content) { url += "&utm_content=" + encodeURIComponent(data.content); localStorage.setItem("tracker_url:content", data.content); } diff --git a/frappe/website/doctype/marketing_campaign/__init__.py b/frappe/website/doctype/utm_campaign/__init__.py similarity index 100% rename from frappe/website/doctype/marketing_campaign/__init__.py rename to frappe/website/doctype/utm_campaign/__init__.py diff --git a/frappe/website/doctype/utm_campaign/test_utm_campaign.py b/frappe/website/doctype/utm_campaign/test_utm_campaign.py new file mode 100644 index 0000000000..a7929b1547 --- /dev/null +++ b/frappe/website/doctype/utm_campaign/test_utm_campaign.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe Technologies and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestUTMCampaign(FrappeTestCase): + pass diff --git a/frappe/website/doctype/utm_campaign/utm_campaign.js b/frappe/website/doctype/utm_campaign/utm_campaign.js new file mode 100644 index 0000000000..a11b27e381 --- /dev/null +++ b/frappe/website/doctype/utm_campaign/utm_campaign.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, Frappe Technologies and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("UTM Campaign", { +// refresh(frm) { + +// }, +// }); diff --git a/frappe/website/doctype/marketing_campaign/marketing_campaign.json b/frappe/website/doctype/utm_campaign/utm_campaign.json similarity index 75% rename from frappe/website/doctype/marketing_campaign/marketing_campaign.json rename to frappe/website/doctype/utm_campaign/utm_campaign.json index ad6cd8acbc..85de90ec5d 100644 --- a/frappe/website/doctype/marketing_campaign/marketing_campaign.json +++ b/frappe/website/doctype/utm_campaign/utm_campaign.json @@ -7,6 +7,7 @@ "editable_grid": 1, "engine": "InnoDB", "field_order": [ + "slug", "campaign_description" ], "fields": [ @@ -17,14 +18,20 @@ "in_filter": 1, "in_list_view": 1, "label": "Campaign Description (Optional)" + }, + { + "fieldname": "slug", + "fieldtype": "Data", + "label": "Slug", + "unique": 1 } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-03-23 16:03:29.592624", + "modified": "2024-06-28 15:05:14.714600", "modified_by": "Administrator", "module": "Website", - "name": "Marketing Campaign", + "name": "UTM Campaign", "naming_rule": "Set by user", "owner": "Administrator", "permissions": [ @@ -55,6 +62,18 @@ { "role": "Desk User", "select": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Marketing Manager", + "share": 1, + "write": 1 } ], "quick_entry": 1, diff --git a/frappe/website/doctype/marketing_campaign/marketing_campaign.py b/frappe/website/doctype/utm_campaign/utm_campaign.py similarity index 73% rename from frappe/website/doctype/marketing_campaign/marketing_campaign.py rename to frappe/website/doctype/utm_campaign/utm_campaign.py index 26ae1c427e..feedfc5434 100644 --- a/frappe/website/doctype/marketing_campaign/marketing_campaign.py +++ b/frappe/website/doctype/utm_campaign/utm_campaign.py @@ -1,11 +1,11 @@ # Copyright (c) 2023, Frappe Technologies and contributors # For license information, please see license.txt -# import frappe +import frappe from frappe.model.document import Document -class MarketingCampaign(Document): +class UTMCampaign(Document): # begin: auto-generated types # This code is auto-generated. Do not modify anything in this block. @@ -15,6 +15,9 @@ class MarketingCampaign(Document): from frappe.types import DF campaign_description: DF.SmallText | None + slug: DF.Data | None # end: auto-generated types - pass + def before_save(self): + if self.slug: + self.slug = frappe.utils.slug(self.slug) diff --git a/frappe/website/doctype/utm_medium/__init__.py b/frappe/website/doctype/utm_medium/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/website/doctype/utm_medium/test_utm_medium.py b/frappe/website/doctype/utm_medium/test_utm_medium.py new file mode 100644 index 0000000000..86450594a4 --- /dev/null +++ b/frappe/website/doctype/utm_medium/test_utm_medium.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe Technologies and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestUTMMedium(FrappeTestCase): + pass diff --git a/frappe/website/doctype/utm_medium/utm_medium.js b/frappe/website/doctype/utm_medium/utm_medium.js new file mode 100644 index 0000000000..bbea0c0ec9 --- /dev/null +++ b/frappe/website/doctype/utm_medium/utm_medium.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, Frappe Technologies and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("UTM Medium", { +// refresh(frm) { + +// }, +// }); diff --git a/frappe/website/doctype/utm_medium/utm_medium.json b/frappe/website/doctype/utm_medium/utm_medium.json new file mode 100644 index 0000000000..1343769434 --- /dev/null +++ b/frappe/website/doctype/utm_medium/utm_medium.json @@ -0,0 +1,72 @@ +{ + "actions": [], + "allow_rename": 1, + "autoname": "prompt", + "creation": "2024-06-28 09:46:10.102141", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "slug", + "description" + ], + "fields": [ + { + "fieldname": "description", + "fieldtype": "Small Text", + "label": "Description" + }, + { + "fieldname": "slug", + "fieldtype": "Data", + "label": "Slug", + "unique": 1 + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-06-28 15:04:51.679189", + "modified_by": "Administrator", + "module": "Website", + "name": "UTM Medium", + "naming_rule": "Set by user", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Marketing Manager", + "share": 1, + "write": 1 + }, + { + "email": 1, + "export": 1, + "print": 1, + "report": 1, + "role": "Desk User", + "select": 1, + "share": 1 + } + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/frappe/website/doctype/utm_medium/utm_medium.py b/frappe/website/doctype/utm_medium/utm_medium.py new file mode 100644 index 0000000000..ae22177879 --- /dev/null +++ b/frappe/website/doctype/utm_medium/utm_medium.py @@ -0,0 +1,23 @@ +# Copyright (c) 2024, Frappe Technologies and contributors +# For license information, please see license.txt + +import frappe +from frappe.model.document import Document + + +class UTMMedium(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + description: DF.SmallText | None + slug: DF.Data | None + # end: auto-generated types + + def before_save(self): + if self.slug: + self.slug = frappe.utils.slug(self.slug) diff --git a/frappe/website/doctype/utm_source/__init__.py b/frappe/website/doctype/utm_source/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/website/doctype/utm_source/test_utm_source.py b/frappe/website/doctype/utm_source/test_utm_source.py new file mode 100644 index 0000000000..dc05b28326 --- /dev/null +++ b/frappe/website/doctype/utm_source/test_utm_source.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe Technologies and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestUTMSource(FrappeTestCase): + pass diff --git a/frappe/website/doctype/utm_source/utm_source.js b/frappe/website/doctype/utm_source/utm_source.js new file mode 100644 index 0000000000..cb04f46f45 --- /dev/null +++ b/frappe/website/doctype/utm_source/utm_source.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, Frappe Technologies and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("UTM Source", { +// refresh(frm) { + +// }, +// }); diff --git a/frappe/website/doctype/utm_source/utm_source.json b/frappe/website/doctype/utm_source/utm_source.json new file mode 100644 index 0000000000..270d09aaec --- /dev/null +++ b/frappe/website/doctype/utm_source/utm_source.json @@ -0,0 +1,72 @@ +{ + "actions": [], + "allow_rename": 1, + "autoname": "prompt", + "creation": "2024-06-28 09:42:04.478212", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "slug", + "description" + ], + "fields": [ + { + "fieldname": "description", + "fieldtype": "Small Text", + "label": "Description" + }, + { + "fieldname": "slug", + "fieldtype": "Data", + "label": "Slug", + "unique": 1 + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-06-28 15:04:59.643513", + "modified_by": "Administrator", + "module": "Website", + "name": "UTM Source", + "naming_rule": "Set by user", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Marketing Manager", + "share": 1, + "write": 1 + }, + { + "email": 1, + "export": 1, + "print": 1, + "report": 1, + "role": "Desk User", + "select": 1, + "share": 1 + } + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/frappe/website/doctype/utm_source/utm_source.py b/frappe/website/doctype/utm_source/utm_source.py new file mode 100644 index 0000000000..715997c503 --- /dev/null +++ b/frappe/website/doctype/utm_source/utm_source.py @@ -0,0 +1,23 @@ +# Copyright (c) 2024, Frappe Technologies and contributors +# For license information, please see license.txt + +import frappe +from frappe.model.document import Document + + +class UTMSource(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + description: DF.SmallText | None + slug: DF.Data | None + # end: auto-generated types + + def before_save(self): + if self.slug: + self.slug = frappe.utils.slug(self.slug)