diff --git a/crm/api/comment.py b/crm/api/comment.py
index 0333d174c..7aa2fee52 100644
--- a/crm/api/comment.py
+++ b/crm/api/comment.py
@@ -3,6 +3,7 @@
import frappe
from frappe import _
from bs4 import BeautifulSoup
+from crm.fcrm.doctype.crm_notification.crm_notification import notify_user
def on_update(self, method):
notify_mentions(self)
@@ -29,22 +30,17 @@ def notify_mentions(doc):
{ doc.reference_name }
"""
- values = frappe._dict(
- doctype="CRM Notification",
- from_user=doc.owner,
- to_user=mention.email,
- type="Mention",
- message=doc.content,
- notification_text=notification_text,
- notification_type_doctype="Comment",
- notification_type_doc=doc.name,
- reference_doctype=doc.reference_doctype,
- reference_name=doc.reference_name,
- )
-
- if frappe.db.exists("CRM Notification", values):
- return
- frappe.get_doc(values).insert()
+ notify_user({
+ "owner": doc.owner,
+ "assigned_to": mention.email,
+ "notification_type": "Mention",
+ "message": doc.content,
+ "notification_text": notification_text,
+ "reference_doctype": "Comment",
+ "reference_docname": doc.name,
+ "redirect_to_doctype": doc.reference_doctype,
+ "redirect_to_docname": doc.reference_name,
+ })
def extract_mentions(html):
diff --git a/crm/api/todo.py b/crm/api/todo.py
index 7792e848f..e4bb50b5b 100644
--- a/crm/api/todo.py
+++ b/crm/api/todo.py
@@ -1,8 +1,103 @@
import frappe
+from frappe import _
+from crm.fcrm.doctype.crm_notification.crm_notification import notify_user
def after_insert(doc, method):
if doc.reference_type in ["CRM Lead", "CRM Deal"] and doc.reference_name and doc.allocated_to:
fieldname = "lead_owner" if doc.reference_type == "CRM Lead" else "deal_owner"
lead_owner = frappe.db.get_value(doc.reference_type, doc.reference_name, fieldname)
if not lead_owner:
- frappe.db.set_value(doc.reference_type, doc.reference_name, fieldname, doc.allocated_to)
\ No newline at end of file
+ frappe.db.set_value(doc.reference_type, doc.reference_name, fieldname, doc.allocated_to)
+
+ if doc.reference_type in ["CRM Lead", "CRM Deal", "CRM Task"] and doc.reference_name and doc.allocated_to:
+ notify_assigned_user(doc)
+
+def on_update(doc, method):
+ if doc.has_value_changed("status") and doc.status == "Cancelled" and doc.reference_type in ["CRM Lead", "CRM Deal", "CRM Task"] and doc.reference_name and doc.allocated_to:
+ notify_assigned_user(doc, is_cancelled=True)
+
+def notify_assigned_user(doc, is_cancelled=False):
+ _doc = frappe.get_doc(doc.reference_type, doc.reference_name)
+ owner = frappe.get_cached_value("User", frappe.session.user, "full_name")
+ notification_text = get_notification_text(owner, doc, _doc, is_cancelled)
+
+ message = _("Your assignment on {0} {1} has been removed by {2}").format(
+ doc.reference_type,
+ doc.reference_name,
+ owner
+ ) if is_cancelled else _("{0} assigned a {1} {2} to you").format(
+ owner,
+ doc.reference_type,
+ doc.reference_name
+ )
+
+ redirect_to_doctype, redirect_to_name = get_redirect_to_doc(doc)
+
+ notify_user({
+ "owner": frappe.session.user,
+ "assigned_to": doc.allocated_to,
+ "notification_type": "Assignment",
+ "message": message,
+ "notification_text": notification_text,
+ "reference_doctype": doc.reference_type,
+ "reference_docname": doc.reference_name,
+ "redirect_to_doctype": redirect_to_doctype,
+ "redirect_to_docname": redirect_to_name,
+ })
+
+def get_notification_text(owner, doc, reference_doc, is_cancelled=False):
+ name = doc.reference_name
+ doctype = doc.reference_type
+
+ if doctype.startswith("CRM "):
+ doctype = doctype[4:].lower()
+
+ if doctype in ["CRM Lead", "CRM Deal"]:
+ name = reference_doc.lead_name or name if doctype == "CRM Lead" else reference_doc.organization or reference_doc.lead_name or name
+
+ if is_cancelled:
+ return f"""
+
+ { _('Your assignment on {0} {1} has been removed by {2}').format(
+ doctype,
+ f'{ name }',
+ f'{ owner }'
+ ) }
+
+ """
+
+ return f"""
+
+ { owner }
+ { _('assigned a {0} {1} to you').format(
+ doctype,
+ f'{ name }'
+ ) }
+
+ """
+
+ if doc.reference_type == "CRM Task":
+ if is_cancelled:
+ return f"""
+
+ { _('Your assignment on task {0} has been removed by {1}').format(
+ f'{ reference_doc.title }',
+ f'{ owner }'
+ ) }
+
+ """
+ return f"""
+
+ { owner }
+ { _('assigned a new task {0} to you').format(
+ f'{ reference_doc.title }'
+ ) }
+
+ """
+
+def get_redirect_to_doc(doc):
+ if doc.reference_type == "CRM Task":
+ reference_doc = frappe.get_doc(doc.reference_type, doc.reference_name)
+ return reference_doc.reference_doctype, reference_doc.reference_docname
+
+ return doc.reference_type, doc.reference_name
diff --git a/crm/api/whatsapp.py b/crm/api/whatsapp.py
index 6bbc2424f..1a0f52fd2 100644
--- a/crm/api/whatsapp.py
+++ b/crm/api/whatsapp.py
@@ -2,6 +2,7 @@
import json
from frappe import _
from crm.api.doc import get_assigned_users
+from crm.fcrm.doctype.crm_notification.crm_notification import notify_user
def validate(doc, method):
@@ -29,30 +30,25 @@ def notify_agent(doc):
if doctype.startswith("CRM "):
doctype = doctype[4:].lower()
notification_text = f"""
-
- { _('You') }
- { _('received a whatsapp message in {0}').format(doctype) }
- { doc.reference_name }
-
- """
+
+ { _('You') }
+ { _('received a whatsapp message in {0}').format(doctype) }
+ { doc.reference_name }
+
+ """
assigned_users = get_assigned_users(doc.reference_doctype, doc.reference_name)
for user in assigned_users:
- values = frappe._dict(
- doctype="CRM Notification",
- from_user=doc.owner,
- to_user=user,
- type="WhatsApp",
- message=doc.message,
- notification_text=notification_text,
- notification_type_doctype="WhatsApp Message",
- notification_type_doc=doc.name,
- reference_doctype=doc.reference_doctype,
- reference_name=doc.reference_name,
- )
-
- if frappe.db.exists("CRM Notification", values):
- return
- frappe.get_doc(values).insert(ignore_permissions=True)
+ notify_user({
+ "owner": doc.owner,
+ "assigned_to": user,
+ "notification_type": "WhatsApp",
+ "message": doc.message,
+ "notification_text": notification_text,
+ "reference_doctype": "WhatsApp Message",
+ "reference_docname": doc.name,
+ "redirect_to_doctype": doc.reference_doctype,
+ "redirect_to_docname": doc.reference_name,
+ })
def get_lead_or_deal_from_number(number):
@@ -62,10 +58,10 @@ def find_record(doctype, mobile_no, where=""):
mobile_no = parse_mobile_no(mobile_no)
query = f"""
- SELECT name, mobile_no
- FROM `tab{doctype}`
- WHERE CONCAT('+', REGEXP_REPLACE(mobile_no, '[^0-9]', '')) = {mobile_no}
- """
+ SELECT name, mobile_no
+ FROM `tab{doctype}`
+ WHERE CONCAT('+', REGEXP_REPLACE(mobile_no, '[^0-9]', '')) = {mobile_no}
+ """
data = frappe.db.sql(query + where, as_dict=True)
return data[0].name if data else None
diff --git a/crm/fcrm/doctype/crm_notification/crm_notification.json b/crm/fcrm/doctype/crm_notification/crm_notification.json
index be7ac1f69..f6bc0380b 100644
--- a/crm/fcrm/doctype/crm_notification/crm_notification.json
+++ b/crm/fcrm/doctype/crm_notification/crm_notification.json
@@ -34,7 +34,7 @@
"fieldtype": "Select",
"in_list_view": 1,
"label": "Type",
- "options": "Mention\nWhatsApp",
+ "options": "Mention\nTask\nAssignment\nWhatsApp",
"reqd": 1
},
{
@@ -116,7 +116,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2024-04-25 16:26:07.484857",
+ "modified": "2024-09-23 19:34:08.635305",
"modified_by": "Administrator",
"module": "FCRM",
"name": "CRM Notification",
diff --git a/crm/fcrm/doctype/crm_notification/crm_notification.py b/crm/fcrm/doctype/crm_notification/crm_notification.py
index 28f4ab80f..69aa127d3 100644
--- a/crm/fcrm/doctype/crm_notification/crm_notification.py
+++ b/crm/fcrm/doctype/crm_notification/crm_notification.py
@@ -2,9 +2,35 @@
# For license information, please see license.txt
import frappe
+from frappe import _
from frappe.model.document import Document
class CRMNotification(Document):
- def on_update(self):
- frappe.publish_realtime("crm_notification")
+ def on_update(self):
+ frappe.publish_realtime("crm_notification")
+
+def notify_user(args):
+ """
+ Notify the assigned user
+ """
+ args = frappe._dict(args)
+ if args.owner == args.assigned_to:
+ return
+
+ values = frappe._dict(
+ doctype="CRM Notification",
+ from_user=args.owner,
+ to_user=args.assigned_to,
+ type=args.notification_type,
+ message=args.message,
+ notification_text=args.notification_text,
+ notification_type_doctype=args.reference_doctype,
+ notification_type_doc=args.reference_docname,
+ reference_doctype=args.redirect_to_doctype,
+ reference_name=args.redirect_to_docname,
+ )
+
+ if frappe.db.exists("CRM Notification", values):
+ return
+ frappe.get_doc(values).insert(ignore_permissions=True)
\ No newline at end of file
diff --git a/crm/fcrm/doctype/crm_task/crm_task.py b/crm/fcrm/doctype/crm_task/crm_task.py
index cf1bc963a..06b50c4de 100644
--- a/crm/fcrm/doctype/crm_task/crm_task.py
+++ b/crm/fcrm/doctype/crm_task/crm_task.py
@@ -1,11 +1,38 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
-# import frappe
+import frappe
+from frappe import _
from frappe.model.document import Document
+from frappe.desk.form.assign_to import add as assign, remove as unassign
+from crm.fcrm.doctype.crm_notification.crm_notification import notify_user
class CRMTask(Document):
+ def after_insert(self):
+ self.assign_to()
+
+ def validate(self):
+ if self.is_new() or not self.assigned_to:
+ return
+
+ if self.get_doc_before_save().assigned_to != self.assigned_to:
+ self.unassign_from_previous_user(self.get_doc_before_save().assigned_to)
+ self.assign_to()
+
+ def unassign_from_previous_user(self, user):
+ unassign(self.doctype, self.name, user)
+
+ def assign_to(self):
+ if self.assigned_to:
+ assign({
+ "assign_to": [self.assigned_to],
+ "doctype": self.doctype,
+ "name": self.name,
+ "description": self.title or self.description,
+ })
+
+
@staticmethod
def default_list_data():
columns = [
diff --git a/crm/hooks.py b/crm/hooks.py
index fa7e606a8..286eee4d4 100644
--- a/crm/hooks.py
+++ b/crm/hooks.py
@@ -144,6 +144,7 @@
},
"ToDo": {
"after_insert": ["crm.api.todo.after_insert"],
+ "on_update": ["crm.api.todo.on_update"],
},
"Comment": {
"on_update": ["crm.api.comment.on_update"],
@@ -152,8 +153,8 @@
"validate": ["crm.api.whatsapp.validate"],
"on_update": ["crm.api.whatsapp.on_update"],
},
- "CRM Deal": {
- "on_update": ["crm.fcrm.doctype.erpnext_crm_settings.erpnext_crm_settings.create_customer_in_erpnext"],
+ "CRM Deal": {
+ "on_update": ["crm.fcrm.doctype.erpnext_crm_settings.erpnext_crm_settings.create_customer_in_erpnext"],
},
}