diff --git a/crm/api/comment.py b/crm/api/comment.py
index 7d78f0d4..c3b7ca65 100644
--- a/crm/api/comment.py
+++ b/crm/api/comment.py
@@ -5,6 +5,7 @@ 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)
@@ -24,25 +25,31 @@ def notify_mentions(doc):
doctype = doc.reference_doctype
if doctype.startswith("CRM "):
doctype = doctype[4:].lower()
- name = reference_doc.lead_name or name if doctype == "lead" else reference_doc.organization or reference_doc.lead_name or name
+ name = (
+ reference_doc.lead_name
+ if doctype == "lead"
+ else reference_doc.organization or reference_doc.lead_name
+ )
notification_text = f"""
-
-
{ owner }
+
+ { owner }
{ _('mentioned you in {0}').format(doctype) }
- { name }
+ { name }
"""
- 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,
- })
+ 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):
@@ -56,39 +63,42 @@ def extract_mentions(html):
)
return mentions
+
@frappe.whitelist()
def add_attachments(name: str, attachments: Iterable[str | dict]) -> None:
- """Add attachments to the given Comment
+ """Add attachments to the given Comment
- :param name: Comment name
- :param attachments: File names or dicts with keys "fname" and "fcontent"
- """
- # loop through attachments
- for a in attachments:
- if isinstance(a, str):
- attach = frappe.db.get_value("File", {"name": a}, ["file_url", "is_private"], as_dict=1)
- file_args = {
- "file_url": attach.file_url,
- "is_private": attach.is_private,
- }
- elif isinstance(a, dict) and "fcontent" in a and "fname" in a:
- # dict returned by frappe.attach_print()
- file_args = {
- "file_name": a["fname"],
- "content": a["fcontent"],
- "is_private": 1,
- }
- else:
- continue
+ :param name: Comment name
+ :param attachments: File names or dicts with keys "fname" and "fcontent"
+ """
+ # loop through attachments
+ for a in attachments:
+ if isinstance(a, str):
+ attach = frappe.db.get_value(
+ "File", {"name": a}, ["file_url", "is_private"], as_dict=1
+ )
+ file_args = {
+ "file_url": attach.file_url,
+ "is_private": attach.is_private,
+ }
+ elif isinstance(a, dict) and "fcontent" in a and "fname" in a:
+ # dict returned by frappe.attach_print()
+ file_args = {
+ "file_name": a["fname"],
+ "content": a["fcontent"],
+ "is_private": 1,
+ }
+ else:
+ continue
- file_args.update(
- {
- "attached_to_doctype": "Comment",
- "attached_to_name": name,
- "folder": "Home/Attachments",
- }
- )
+ file_args.update(
+ {
+ "attached_to_doctype": "Comment",
+ "attached_to_name": name,
+ "folder": "Home/Attachments",
+ }
+ )
- _file = frappe.new_doc("File")
- _file.update(file_args)
- _file.save(ignore_permissions=True)
\ No newline at end of file
+ _file = frappe.new_doc("File")
+ _file.update(file_args)
+ _file.save(ignore_permissions=True)
diff --git a/crm/api/todo.py b/crm/api/todo.py
index f30e19f4..dc9dcf28 100644
--- a/crm/api/todo.py
+++ b/crm/api/todo.py
@@ -2,102 +2,131 @@ 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)
- if doc.reference_type in ["CRM Lead", "CRM Deal", "CRM Task"] and doc.reference_name and doc.allocated_to:
- notify_assigned_user(doc)
+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
+ )
+
+ 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)
+ 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)
+ _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
- )
+ 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)
+ 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,
+ }
+ )
- 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
+ name = doc.reference_name
+ doctype = doc.reference_type
- if doctype.startswith("CRM "):
- doctype = doctype[4:].lower()
+ if doctype.startswith("CRM "):
+ doctype = doctype[4:].lower()
- if doctype in ["lead", "deal"]:
- name = reference_doc.lead_name or name if doctype == "lead" else reference_doc.organization or reference_doc.lead_name or name
+ if doctype in ["lead", "deal"]:
+ name = (
+ reference_doc.lead_name or name
+ if doctype == "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 }'
- ) }
-
- """
+ 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 }'
- ) }
-
- """
+ return f"""
+
+ { owner }
+ { _('assigned a {0} {1} to you').format(
+ doctype,
+ f'{ name }'
+ ) }
+
+ """
+
+ if doctype == "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 }'
+ ) }
+
+ """
- if doctype == "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
+ 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
+ return doc.reference_type, doc.reference_name
diff --git a/crm/api/whatsapp.py b/crm/api/whatsapp.py
index a38c1194..3e04b5b6 100644
--- a/crm/api/whatsapp.py
+++ b/crm/api/whatsapp.py
@@ -30,25 +30,27 @@ def notify_agent(doc):
if doctype.startswith("CRM "):
doctype = doctype[4:].lower()
notification_text = f"""
-
-
{ _('You') }
+
+ { _('You') }
{ _('received a whatsapp message in {0}').format(doctype) }
- { doc.reference_name }
+ { doc.reference_name }
"""
assigned_users = get_assigned_users(doc.reference_doctype, doc.reference_name)
for user in assigned_users:
- 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,
- })
+ 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):
@@ -92,6 +94,7 @@ def is_whatsapp_enabled():
return False
return frappe.get_cached_value("WhatsApp Settings", "WhatsApp Settings", "enabled")
+
@frappe.whitelist()
def is_whatsapp_installed():
if not frappe.db.exists("DocType", "WhatsApp Settings"):
@@ -105,8 +108,8 @@ def get_whatsapp_messages(reference_doctype, reference_name):
return []
messages = []
- if reference_doctype == 'CRM Deal':
- lead = frappe.db.get_value(reference_doctype, reference_name, 'lead')
+ if reference_doctype == "CRM Deal":
+ lead = frappe.db.get_value(reference_doctype, reference_name, "lead")
if lead:
messages = frappe.get_all(
"WhatsApp Message",
diff --git a/frappe-ui b/frappe-ui
index 59415754..82150c95 160000
--- a/frappe-ui
+++ b/frappe-ui
@@ -1 +1 @@
-Subproject commit 59415754663693989ae5144b43370f4b0426aa50
+Subproject commit 82150c9591a36abc5dc8667ae5873651d4b2cc0d
diff --git a/frontend/src/components/Activities/AttachmentArea.vue b/frontend/src/components/Activities/AttachmentArea.vue
index b65015b1..4a956d16 100644
--- a/frontend/src/components/Activities/AttachmentArea.vue
+++ b/frontend/src/components/Activities/AttachmentArea.vue
@@ -18,7 +18,7 @@
/>
diff --git a/frontend/src/components/Activities/CallArea.vue b/frontend/src/components/Activities/CallArea.vue
index 91eddd56..d76ff040 100644
--- a/frontend/src/components/Activities/CallArea.vue
+++ b/frontend/src/components/Activities/CallArea.vue
@@ -25,7 +25,7 @@