From 2dbdc402bb13915ba5b7c025951168b92615006a Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 14 Sep 2023 12:04:52 +0530 Subject: [PATCH] refactor!: remove social media post module --- .../crm/doctype/linkedin_settings/__init__.py | 0 .../linkedin_settings/linkedin_settings.js | 74 ------ .../linkedin_settings/linkedin_settings.json | 112 --------- .../linkedin_settings/linkedin_settings.py | 208 ----------------- .../test_linkedin_settings.py | 9 - .../crm/doctype/social_media_post/__init__.py | 0 .../social_media_post/social_media_post.js | 125 ---------- .../social_media_post/social_media_post.json | 169 -------------- .../social_media_post/social_media_post.py | 77 ------ .../social_media_post_list.js | 11 - .../test_social_media_post.py | 9 - erpnext/crm/workspace/crm/crm.json | 221 ++++++++---------- erpnext/hooks.py | 3 - erpnext/patches.txt | 2 + 14 files changed, 96 insertions(+), 924 deletions(-) delete mode 100644 erpnext/crm/doctype/linkedin_settings/__init__.py delete mode 100644 erpnext/crm/doctype/linkedin_settings/linkedin_settings.js delete mode 100644 erpnext/crm/doctype/linkedin_settings/linkedin_settings.json delete mode 100644 erpnext/crm/doctype/linkedin_settings/linkedin_settings.py delete mode 100644 erpnext/crm/doctype/linkedin_settings/test_linkedin_settings.py delete mode 100644 erpnext/crm/doctype/social_media_post/__init__.py delete mode 100644 erpnext/crm/doctype/social_media_post/social_media_post.js delete mode 100644 erpnext/crm/doctype/social_media_post/social_media_post.json delete mode 100644 erpnext/crm/doctype/social_media_post/social_media_post.py delete mode 100644 erpnext/crm/doctype/social_media_post/social_media_post_list.js delete mode 100644 erpnext/crm/doctype/social_media_post/test_social_media_post.py diff --git a/erpnext/crm/doctype/linkedin_settings/__init__.py b/erpnext/crm/doctype/linkedin_settings/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.js b/erpnext/crm/doctype/linkedin_settings/linkedin_settings.js deleted file mode 100644 index 7d6b3955cd..0000000000 --- a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.js +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('LinkedIn Settings', { - onload: function(frm) { - if (frm.doc.session_status == 'Expired' && frm.doc.consumer_key && frm.doc.consumer_secret) { - frappe.confirm( - __('Session not valid. Do you want to login?'), - function(){ - frm.trigger("login"); - }, - function(){ - window.close(); - } - ); - } - frm.dashboard.set_headline(__("For more information, {0}.", [`${__('click here')}`])); - }, - refresh: function(frm) { - if (frm.doc.session_status=="Expired"){ - let msg = __("Session not active. Save document to login."); - frm.dashboard.set_headline_alert( - `
-
- -
-
` - ); - } - - if (frm.doc.session_status=="Active"){ - let d = new Date(frm.doc.modified); - d.setDate(d.getDate()+60); - let dn = new Date(); - let days = d.getTime() - dn.getTime(); - days = Math.floor(days/(1000 * 3600 * 24)); - let msg,color; - - if (days>0){ - msg = __("Your session will be expire in {0} days.", [days]); - color = "green"; - } - else { - msg = __("Session is expired. Save doc to login."); - color = "red"; - } - - frm.dashboard.set_headline_alert( - `
-
- -
-
` - ); - } - }, - login: function(frm) { - if (frm.doc.consumer_key && frm.doc.consumer_secret){ - frappe.dom.freeze(); - frappe.call({ - doc: frm.doc, - method: "get_authorization_url", - callback : function(r) { - window.location.href = r.message; - } - }).fail(function() { - frappe.dom.unfreeze(); - }); - } - }, - after_save: function(frm) { - frm.trigger("login"); - } -}); diff --git a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.json b/erpnext/crm/doctype/linkedin_settings/linkedin_settings.json deleted file mode 100644 index f882e36c32..0000000000 --- a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "actions": [], - "creation": "2020-01-30 13:36:39.492931", - "doctype": "DocType", - "documentation": "https://docs.erpnext.com/docs/user/manual/en/CRM/linkedin-settings", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "account_name", - "column_break_2", - "company_id", - "oauth_details", - "consumer_key", - "column_break_5", - "consumer_secret", - "user_details_section", - "access_token", - "person_urn", - "session_status" - ], - "fields": [ - { - "fieldname": "account_name", - "fieldtype": "Data", - "label": "Account Name", - "read_only": 1 - }, - { - "fieldname": "oauth_details", - "fieldtype": "Section Break", - "label": "OAuth Credentials" - }, - { - "fieldname": "consumer_key", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Consumer Key", - "reqd": 1 - }, - { - "fieldname": "consumer_secret", - "fieldtype": "Password", - "in_list_view": 1, - "label": "Consumer Secret", - "reqd": 1 - }, - { - "fieldname": "access_token", - "fieldtype": "Data", - "hidden": 1, - "label": "Access Token", - "read_only": 1 - }, - { - "fieldname": "person_urn", - "fieldtype": "Data", - "hidden": 1, - "label": "Person URN", - "read_only": 1 - }, - { - "fieldname": "column_break_5", - "fieldtype": "Column Break" - }, - { - "fieldname": "user_details_section", - "fieldtype": "Section Break", - "label": "User Details" - }, - { - "fieldname": "session_status", - "fieldtype": "Select", - "hidden": 1, - "label": "Session Status", - "options": "Expired\nActive", - "read_only": 1 - }, - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "fieldname": "company_id", - "fieldtype": "Data", - "label": "Company ID", - "reqd": 1 - } - ], - "issingle": 1, - "links": [], - "modified": "2021-02-18 15:19:21.920725", - "modified_by": "Administrator", - "module": "CRM", - "name": "LinkedIn Settings", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "print": 1, - "read": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py b/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py deleted file mode 100644 index 64b3a017b4..0000000000 --- a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py +++ /dev/null @@ -1,208 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -from urllib.parse import urlencode - -import frappe -import requests -from frappe import _ -from frappe.model.document import Document -from frappe.utils import get_url_to_form -from frappe.utils.file_manager import get_file_path - - -class LinkedInSettings(Document): - @frappe.whitelist() - def get_authorization_url(self): - params = urlencode( - { - "response_type": "code", - "client_id": self.consumer_key, - "redirect_uri": "{0}/api/method/erpnext.crm.doctype.linkedin_settings.linkedin_settings.callback?".format( - frappe.utils.get_url() - ), - "scope": "r_emailaddress w_organization_social r_basicprofile r_liteprofile r_organization_social rw_organization_admin w_member_social", - } - ) - - url = "https://www.linkedin.com/oauth/v2/authorization?{}".format(params) - - return url - - def get_access_token(self, code): - url = "https://www.linkedin.com/oauth/v2/accessToken" - body = { - "grant_type": "authorization_code", - "code": code, - "client_id": self.consumer_key, - "client_secret": self.get_password(fieldname="consumer_secret"), - "redirect_uri": "{0}/api/method/erpnext.crm.doctype.linkedin_settings.linkedin_settings.callback?".format( - frappe.utils.get_url() - ), - } - headers = {"Content-Type": "application/x-www-form-urlencoded"} - - response = self.http_post(url=url, data=body, headers=headers) - response = frappe.parse_json(response.content.decode()) - self.db_set("access_token", response["access_token"]) - - def get_member_profile(self): - response = requests.get(url="https://api.linkedin.com/v2/me", headers=self.get_headers()) - response = frappe.parse_json(response.content.decode()) - - frappe.db.set_value( - self.doctype, - self.name, - { - "person_urn": response["id"], - "account_name": response["vanityName"], - "session_status": "Active", - }, - ) - frappe.local.response["type"] = "redirect" - frappe.local.response["location"] = get_url_to_form("LinkedIn Settings", "LinkedIn Settings") - - def post(self, text, title, media=None): - if not media: - return self.post_text(text, title) - else: - media_id = self.upload_image(media) - - if media_id: - return self.post_text(text, title, media_id=media_id) - else: - self.log_error("LinkedIn: Failed to upload media") - - def upload_image(self, media): - media = get_file_path(media) - register_url = "https://api.linkedin.com/v2/assets?action=registerUpload" - body = { - "registerUploadRequest": { - "recipes": ["urn:li:digitalmediaRecipe:feedshare-image"], - "owner": "urn:li:organization:{0}".format(self.company_id), - "serviceRelationships": [ - {"relationshipType": "OWNER", "identifier": "urn:li:userGeneratedContent"} - ], - } - } - headers = self.get_headers() - response = self.http_post(url=register_url, body=body, headers=headers) - - if response.status_code == 200: - response = response.json() - asset = response["value"]["asset"] - upload_url = response["value"]["uploadMechanism"][ - "com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest" - ]["uploadUrl"] - headers["Content-Type"] = "image/jpeg" - response = self.http_post(upload_url, headers=headers, data=open(media, "rb")) - if response.status_code < 200 and response.status_code > 299: - frappe.throw( - _("Error While Uploading Image"), - title="{0} {1}".format(response.status_code, response.reason), - ) - return None - return asset - - return None - - def post_text(self, text, title, media_id=None): - url = "https://api.linkedin.com/v2/shares" - headers = self.get_headers() - headers["X-Restli-Protocol-Version"] = "2.0.0" - headers["Content-Type"] = "application/json; charset=UTF-8" - - body = { - "distribution": {"linkedInDistributionTarget": {}}, - "owner": "urn:li:organization:{0}".format(self.company_id), - "subject": title, - "text": {"text": text}, - } - - reference_url = self.get_reference_url(text) - if reference_url: - body["content"] = {"contentEntities": [{"entityLocation": reference_url}]} - - if media_id: - body["content"] = {"contentEntities": [{"entity": media_id}], "shareMediaCategory": "IMAGE"} - - response = self.http_post(url=url, headers=headers, body=body) - return response - - def http_post(self, url, headers=None, body=None, data=None): - try: - response = requests.post(url=url, json=body, data=data, headers=headers) - if response.status_code not in [201, 200]: - raise - - except Exception as e: - self.api_error(response) - - return response - - def get_headers(self): - return {"Authorization": "Bearer {}".format(self.access_token)} - - def get_reference_url(self, text): - import re - - regex_url = r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+" - urls = re.findall(regex_url, text) - if urls: - return urls[0] - - def delete_post(self, post_id): - try: - response = requests.delete( - url="https://api.linkedin.com/v2/shares/urn:li:share:{0}".format(post_id), - headers=self.get_headers(), - ) - if response.status_code != 200: - raise - except Exception: - self.api_error(response) - - def get_post(self, post_id): - url = "https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:{0}&shares[0]=urn:li:share:{1}".format( - self.company_id, post_id - ) - - try: - response = requests.get(url=url, headers=self.get_headers()) - if response.status_code != 200: - raise - - except Exception: - self.api_error(response) - - response = frappe.parse_json(response.content.decode()) - if len(response.elements): - return response.elements[0] - - return None - - def api_error(self, response): - content = frappe.parse_json(response.content.decode()) - - if response.status_code == 401: - self.db_set("session_status", "Expired") - frappe.db.commit() - frappe.throw(content["message"], title=_("LinkedIn Error - Unauthorized")) - elif response.status_code == 403: - frappe.msgprint(_("You didn't have permission to access this API")) - frappe.throw(content["message"], title=_("LinkedIn Error - Access Denied")) - else: - frappe.throw(response.reason, title=response.status_code) - - -@frappe.whitelist(allow_guest=True) -def callback(code=None, error=None, error_description=None): - if not error: - linkedin_settings = frappe.get_doc("LinkedIn Settings") - linkedin_settings.get_access_token(code) - linkedin_settings.get_member_profile() - frappe.db.commit() - else: - frappe.local.response["type"] = "redirect" - frappe.local.response["location"] = get_url_to_form("LinkedIn Settings", "LinkedIn Settings") diff --git a/erpnext/crm/doctype/linkedin_settings/test_linkedin_settings.py b/erpnext/crm/doctype/linkedin_settings/test_linkedin_settings.py deleted file mode 100644 index 09732e405e..0000000000 --- a/erpnext/crm/doctype/linkedin_settings/test_linkedin_settings.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -# import frappe -import unittest - - -class TestLinkedInSettings(unittest.TestCase): - pass diff --git a/erpnext/crm/doctype/social_media_post/__init__.py b/erpnext/crm/doctype/social_media_post/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/crm/doctype/social_media_post/social_media_post.js b/erpnext/crm/doctype/social_media_post/social_media_post.js deleted file mode 100644 index 71d044c38d..0000000000 --- a/erpnext/crm/doctype/social_media_post/social_media_post.js +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt -frappe.ui.form.on('Social Media Post', { - validate: function(frm) { - if (frm.doc.linkedin === 0) { - frappe.throw(__("Select atleast one Social Media Platform to Share on.")); - } - if (frm.doc.scheduled_time) { - let scheduled_time = new Date(frm.doc.scheduled_time); - let date_time = new Date(); - if (scheduled_time.getTime() < date_time.getTime()) { - frappe.throw(__("Scheduled Time must be a future time.")); - } - } - frm.trigger('validate_tweet_length'); - }, - - text: function(frm) { - if (frm.doc.text) { - frm.set_df_property('text', 'description', `${frm.doc.text.length}/280`); - frm.refresh_field('text'); - frm.trigger('validate_tweet_length'); - } - }, - - validate_tweet_length: function(frm) { - if (frm.doc.text && frm.doc.text.length > 280) { - frappe.throw(__("Tweet length Must be less than 280.")); - } - }, - - onload: function(frm) { - frm.trigger('make_dashboard'); - }, - - make_dashboard: function(frm) { - if (frm.doc.post_status == "Posted") { - frappe.call({ - doc: frm.doc, - method: 'get_post', - freeze: true, - callback: (r) => { - if (!r.message) { - return; - } - - let datasets = [], colors = []; - if (r.message && r.message.linkedin) { - colors.push('#0077b5'); - datasets.push({ - name: 'LinkedIn', - values: [r.message.linkedin.totalShareStatistics.likeCount, r.message.linkedin.totalShareStatistics.shareCount] - }); - } - - if (datasets.length) { - frm.dashboard.render_graph({ - data: { - labels: ['Likes', 'Retweets/Shares'], - datasets: datasets - }, - - title: __("Post Metrics"), - type: 'bar', - height: 300, - colors: colors - }); - } - } - }); - } - }, - - refresh: function(frm) { - frm.trigger('text'); - - if (frm.doc.docstatus === 1) { - if (!['Posted', 'Deleted'].includes(frm.doc.post_status)) { - frm.trigger('add_post_btn'); - } - if (frm.doc.post_status !='Deleted') { - frm.add_custom_button(__('Delete Post'), function() { - frappe.confirm(__('Are you sure want to delete the Post from Social Media platforms?'), - function() { - frappe.call({ - doc: frm.doc, - method: 'delete_post', - freeze: true, - callback: () => { - frm.reload_doc(); - } - }); - } - ); - }); - } - - if (frm.doc.post_status !='Deleted') { - let html=''; - if (frm.doc.linkedin) { - let color = frm.doc.linkedin_post_id ? "green" : "red"; - let status = frm.doc.linkedin_post_id ? "Posted" : "Not Posted"; - html += `
- LinkedIn : ${status} -
` ; - } - html = `
${html}
`; - frm.dashboard.set_headline_alert(html); - } - } - }, - - add_post_btn: function(frm) { - frm.add_custom_button(__('Post Now'), function() { - frappe.call({ - doc: frm.doc, - method: 'post', - freeze: true, - callback: function() { - frm.reload_doc(); - } - }); - }); - } -}); diff --git a/erpnext/crm/doctype/social_media_post/social_media_post.json b/erpnext/crm/doctype/social_media_post/social_media_post.json deleted file mode 100644 index 1e3e01c36f..0000000000 --- a/erpnext/crm/doctype/social_media_post/social_media_post.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "actions": [], - "autoname": "format: CRM-SMP-{YYYY}-{MM}-{DD}-{###}", - "creation": "2020-01-30 11:53:13.872864", - "doctype": "DocType", - "documentation": "https://docs.erpnext.com/docs/user/manual/en/CRM/social-media-post", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "title", - "campaign_name", - "scheduled_time", - "post_status", - "column_break_6", - "linkedin", - "linkedin_post_id", - "linkedin_section", - "linkedin_post", - "column_break_15", - "attachments_section", - "image", - "amended_from" - ], - "fields": [ - { - "fieldname": "image", - "fieldtype": "Attach Image", - "label": "Image" - }, - { - "default": "1", - "fieldname": "linkedin", - "fieldtype": "Check", - "label": "LinkedIn" - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Social Media Post", - "print_hide": 1, - "read_only": 1 - }, - { - "allow_on_submit": 1, - "fieldname": "post_status", - "fieldtype": "Select", - "label": "Post Status", - "no_copy": 1, - "options": "\nScheduled\nPosted\nCancelled\nDeleted\nError", - "read_only": 1 - }, - { - "allow_on_submit": 1, - "fieldname": "linkedin_post_id", - "fieldtype": "Data", - "hidden": 1, - "label": "LinkedIn Post Id", - "no_copy": 1, - "read_only": 1 - }, - { - "fieldname": "campaign_name", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Campaign", - "options": "Campaign" - }, - { - "fieldname": "column_break_6", - "fieldtype": "Column Break", - "label": "Share On" - }, - { - "collapsible": 1, - "depends_on": "eval:doc.linkedin==1", - "fieldname": "linkedin_section", - "fieldtype": "Section Break", - "label": "LinkedIn" - }, - { - "collapsible": 1, - "fieldname": "attachments_section", - "fieldtype": "Section Break", - "label": "Attachments" - }, - { - "fieldname": "linkedin_post", - "fieldtype": "Text", - "label": "Post", - "mandatory_depends_on": "eval:doc.linkedin ==1" - }, - { - "fieldname": "column_break_15", - "fieldtype": "Column Break" - }, - { - "allow_on_submit": 1, - "fieldname": "scheduled_time", - "fieldtype": "Datetime", - "label": "Scheduled Time", - "read_only_depends_on": "eval:doc.post_status == \"Posted\"" - }, - { - "fieldname": "title", - "fieldtype": "Data", - "label": "Title", - "reqd": 1 - } - ], - "is_submittable": 1, - "links": [], - "modified": "2023-09-14 11:24:29.105683", - "modified_by": "Administrator", - "module": "CRM", - "name": "Social Media Post", - "naming_rule": "Expression", - "owner": "Administrator", - "permissions": [ - { - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "submit": 1, - "write": 1 - }, - { - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales User", - "share": 1, - "submit": 1, - "write": 1 - }, - { - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales Manager", - "share": 1, - "submit": 1, - "write": 1 - } - ], - "sort_field": "modified", - "sort_order": "DESC", - "states": [], - "title_field": "title", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/crm/doctype/social_media_post/social_media_post.py b/erpnext/crm/doctype/social_media_post/social_media_post.py deleted file mode 100644 index 9615a8389c..0000000000 --- a/erpnext/crm/doctype/social_media_post/social_media_post.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - - -import datetime - -import frappe -from frappe import _ -from frappe.model.document import Document - - -class SocialMediaPost(Document): - def validate(self): - if not self.linkedin: - frappe.throw(_("Select atleast one Social Media Platform to Share on.")) - - if self.scheduled_time: - current_time = frappe.utils.now_datetime() - scheduled_time = frappe.utils.get_datetime(self.scheduled_time) - if scheduled_time < current_time: - frappe.throw(_("Scheduled Time must be a future time.")) - - if self.text and len(self.text) > 280: - frappe.throw(_("Tweet length must be less than 280.")) - - def submit(self): - if self.scheduled_time: - self.post_status = "Scheduled" - super(SocialMediaPost, self).submit() - - def on_cancel(self): - self.db_set("post_status", "Cancelled") - - @frappe.whitelist() - def delete_post(self): - if self.linkedin and self.linkedin_post_id: - linkedin = frappe.get_doc("LinkedIn Settings") - linkedin.delete_post(self.linkedin_post_id) - - self.db_set("post_status", "Deleted") - - @frappe.whitelist() - def get_post(self): - response = {} - if self.linkedin and self.linkedin_post_id: - linkedin = frappe.get_doc("LinkedIn Settings") - response["linkedin"] = linkedin.get_post(self.linkedin_post_id) - return response - - @frappe.whitelist() - def post(self): - try: - if self.linkedin and not self.linkedin_post_id: - linkedin = frappe.get_doc("LinkedIn Settings") - linkedin_post = linkedin.post(self.linkedin_post, self.title, self.image) - self.db_set("linkedin_post_id", linkedin_post.headers["X-RestLi-Id"]) - self.db_set("post_status", "Posted") - - except Exception: - self.db_set("post_status", "Error") - self.log_error("Social posting failed") - - -def process_scheduled_social_media_posts(): - posts = frappe.get_all( - "Social Media Post", - filters={"post_status": "Scheduled", "docstatus": 1}, - fields=["name", "scheduled_time"], - ) - start = frappe.utils.now_datetime() - end = start + datetime.timedelta(minutes=10) - for post in posts: - if post.scheduled_time: - post_time = frappe.utils.get_datetime(post.scheduled_time) - if post_time > start and post_time <= end: - sm_post = frappe.get_doc("Social Media Post", post.name) - sm_post.post() diff --git a/erpnext/crm/doctype/social_media_post/social_media_post_list.js b/erpnext/crm/doctype/social_media_post/social_media_post_list.js deleted file mode 100644 index a8c8272ad0..0000000000 --- a/erpnext/crm/doctype/social_media_post/social_media_post_list.js +++ /dev/null @@ -1,11 +0,0 @@ -frappe.listview_settings['Social Media Post'] = { - add_fields: ["status", "post_status"], - get_indicator: function(doc) { - return [__(doc.post_status), { - "Scheduled": "orange", - "Posted": "green", - "Error": "red", - "Deleted": "red" - }[doc.post_status]]; - } -} diff --git a/erpnext/crm/doctype/social_media_post/test_social_media_post.py b/erpnext/crm/doctype/social_media_post/test_social_media_post.py deleted file mode 100644 index 75744767dc..0000000000 --- a/erpnext/crm/doctype/social_media_post/test_social_media_post.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -# import frappe -import unittest - - -class TestSocialMediaPost(unittest.TestCase): - pass diff --git a/erpnext/crm/workspace/crm/crm.json b/erpnext/crm/workspace/crm/crm.json index b107df76f8..4b5b9af714 100644 --- a/erpnext/crm/workspace/crm/crm.json +++ b/erpnext/crm/workspace/crm/crm.json @@ -122,131 +122,6 @@ "onboard": 0, "type": "Link" }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Campaign", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Campaign", - "link_count": 0, - "link_to": "Campaign", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Email Campaign", - "link_count": 0, - "link_to": "Email Campaign", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Social Media Post", - "link_count": 0, - "link_to": "Social Media Post", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "SMS Center", - "link_count": 0, - "link_to": "SMS Center", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "SMS Log", - "link_count": 0, - "link_to": "SMS Log", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Email Group", - "link_count": 0, - "link_to": "Email Group", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Settings", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "CRM Settings", - "link_count": 0, - "link_to": "CRM Settings", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "SMS Settings", - "link_count": 0, - "link_to": "SMS Settings", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "Twitter Settings", - "link_count": 0, - "link_to": "Twitter Settings", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "", - "hidden": 0, - "is_query_report": 0, - "label": "LinkedIn Settings", - "link_count": 0, - "link_to": "LinkedIn Settings", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, { "hidden": 0, "is_query_report": 0, @@ -450,9 +325,101 @@ "link_type": "DocType", "onboard": 0, "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "link_count": 2, + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "CRM Settings", + "link_count": 0, + "link_to": "CRM Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "", + "hidden": 0, + "is_query_report": 0, + "label": "SMS Settings", + "link_count": 0, + "link_to": "SMS Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Campaign", + "link_count": 5, + "onboard": 0, + "type": "Card Break" + }, + { + "dependencies": "", + "hidden": 0, + "is_query_report": 0, + "label": "Campaign", + "link_count": 0, + "link_to": "Campaign", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "", + "hidden": 0, + "is_query_report": 0, + "label": "Email Campaign", + "link_count": 0, + "link_to": "Email Campaign", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "", + "hidden": 0, + "is_query_report": 0, + "label": "SMS Center", + "link_count": 0, + "link_to": "SMS Center", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "", + "hidden": 0, + "is_query_report": 0, + "label": "SMS Log", + "link_count": 0, + "link_to": "SMS Log", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "", + "hidden": 0, + "is_query_report": 0, + "label": "Email Group", + "link_count": 0, + "link_to": "Email Group", + "link_type": "DocType", + "onboard": 0, + "type": "Link" } ], - "modified": "2023-05-26 16:49:04.298122", + "modified": "2023-09-14 12:11:03.968048", "modified_by": "Administrator", "module": "CRM", "name": "CRM", @@ -463,7 +430,7 @@ "quick_lists": [], "restrict_to_domain": "", "roles": [], - "sequence_id": 10.0, + "sequence_id": 17.0, "shortcuts": [ { "color": "Blue", diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 41db6b3a72..c7398cce99 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -423,9 +423,6 @@ scheduler_events = { "erpnext.stock.reorder_item.reorder_item", ], }, - "all": [ - "erpnext.crm.doctype.social_media_post.social_media_post.process_scheduled_social_media_posts", - ], "hourly": [ "erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.automatic_synchronization", "erpnext.projects.doctype.project.project.project_status_update_reminder", diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 22c37159cd..7a07f5679a 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -340,6 +340,8 @@ erpnext.patches.v15_0.remove_exotel_integration erpnext.patches.v14_0.single_to_multi_dunning execute:frappe.db.set_single_value('Selling Settings', 'allow_negative_rates_for_items', 0) execute:frappe.delete_doc('DocType', 'Twitter Settings', ignore_missing=True) +execute:frappe.delete_doc('DocType', 'LinkedIn Settings', ignore_missing=True) +execute:frappe.delete_doc('DocType', 'Social Media Post', ignore_missing=True) erpnext.patches.v15_0.correct_asset_value_if_je_with_workflow erpnext.patches.v15_0.delete_woocommerce_settings_doctype # below migration patch should always run last