Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clefincode_chat/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.3.910'
__version__ = '1.3.911'
99 changes: 87 additions & 12 deletions clefincode_chat/api/api_1_3_4/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10889,18 +10889,32 @@ def _normalize_reference_row(row):

def _normalize_topic_doc(topic_doc):
refs = []
for row in (topic_doc.references or []):
parsed = _normalize_reference_row(row)
if parsed:
refs.append(parsed)

if not topic_doc.topic_color:
topic_doc.topic_color = get_random_topic_color()
topic_doc.save(ignore_permissions=True)
try:
for row in (topic_doc.references or []):
parsed = _normalize_reference_row(row)
if parsed:
refs.append(parsed)
except Exception:
frappe.log_error(
title="Failed to normalize topic references",
message=frappe.get_traceback()
)
refs = []

try:
if not topic_doc.topic_color:
topic_doc.topic_color = get_random_topic_color()
topic_doc.save(ignore_permissions=True)
except Exception:
frappe.log_error(
title=f"Failed to set topic color for {topic_doc.name}",
message=frappe.get_traceback()
)

return {
"name": topic_doc.name,
"date":str(topic_doc.creation),
"date": str(topic_doc.creation),
"subject": topic_doc.subject,
"chat_channel": topic_doc.chat_channel,
"topic_status": topic_doc.topic_status,
Expand Down Expand Up @@ -10949,30 +10963,91 @@ def remove_message_topic(message_name):
}

@frappe.whitelist()
def get_channel_topics(chat_channel, topic_status=None):

def get_channel_topics(chat_channel, topic_status=None, limit=10, offset=0, query=None):
if not chat_channel:
frappe.throw(_("chat_channel is required"))

filters = {"chat_channel": chat_channel}
limit = cint(limit) if limit is not None else 10
offset = cint(offset) if offset is not None else 0

if limit <= 0:
limit = 10

if offset < 0:
offset = 0

filters = {
"chat_channel": chat_channel
}

if topic_status and topic_status != "All":
filters["topic_status"] = topic_status

or_filters = []

if query:
query = query.strip()

if query:
reference_rows = frappe.get_all(
"ClefinCode Chat Topic Reference",
filters={
"parenttype": "ClefinCode Chat Topic",
},
or_filters=[
["ClefinCode Chat Topic Reference", "doctype_link", "like", f"%{query}%"],
["ClefinCode Chat Topic Reference", "docname", "like", f"%{query}%"],
],
fields=["parent"],
distinct=True,
)

reference_topic_names = [row.parent for row in reference_rows if row.parent]

or_filters = [

["ClefinCode Chat Topic", "subject", "like", f"%{query}%"],
]

if reference_topic_names:
or_filters.append(
["ClefinCode Chat Topic", "name", "in", reference_topic_names]
)

count_rows = frappe.get_all(
"ClefinCode Chat Topic",
filters=filters,
or_filters=or_filters,
fields=["count(name) as count"],
)

total_count = count_rows[0].count if count_rows else 0

topic_names = frappe.get_all(
"ClefinCode Chat Topic",
filters=filters,
or_filters=or_filters,
fields=["name"],
order_by="modified desc",
limit_start=offset,
limit_page_length=limit,
)

topics = []

for row in topic_names:
doc = frappe.get_doc("ClefinCode Chat Topic", row.name)
topics.append(_normalize_topic_doc(doc))

next_offset = offset + len(topics)

return {
"chat_channel": chat_channel,
"count": len(topics),
"total_count": total_count,
"limit": limit,
"offset": offset,
"next_offset": next_offset,
"has_more": next_offset < total_count,
"topics": topics,
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Copyright (c) 2024, ClefinCode L.L.C-FZ and contributors
// For license information, please see license.txt

frappe.ui.form.on('ClefinCode WhatsApp Profile', {
refresh: function(frm){
frm.fields_dict['message_template'].get_query = function(doc) {
return {
filters:[{
"whatsapp_profile": doc.name
}
]
}
}
}
});
// frappe.ui.form.on('ClefinCode WhatsApp Profile', {
// refresh: function(frm){
// frm.fields_dict['message_template'].get_query = function(doc) {
// return {
// filters:[{
// "whatsapp_profile": doc.name
// }
// ]
// }
// }
// }
// });
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,104 @@

import frappe
from frappe.model.document import Document
from frappe import _
from frappe.utils import get_url_to_form
from bs4 import BeautifulSoup

class ClefinCodeWhatsAppProfile(Document):
def before_validate(self):
if self.type == "Personal":
get_whatsapp_numbers_for_profile(self.name , self.user)
else:
for user in self.authorized_users:
get_whatsapp_numbers_for_profile(self.name, user.user)

def after_insert(self):
self.create_whatsapp_template()

def create_whatsapp_template(self):
doc = frappe.get_doc({
"doctype" : "ClefinCode WhatsApp Template",
"whatsapp_profile": self.name,
"template_name": f"{self.business_account_id}_confirm_message",
"meta_template_name": self.meta_template_name,
"category": "Utility",
"body": self.template_content,
"buttons": [{"type" : "Custom" , "button_text" : "Yes" }, {"type" : "Custom" , "button_text" : "No" } ],
}).insert(ignore_permissions = True)
doc.submit()
self.message_template = doc.name
self.save()
def before_validate(self):
if self.type == "Personal":
get_whatsapp_numbers_for_profile(self.name , self.user)
else:
for user in self.authorized_users:
get_whatsapp_numbers_for_profile(self.name, user.user)

def after_insert(self):
self.create_whatsapp_template()

def create_whatsapp_template(self):
template_language = "en"

temp_doc = frappe.new_doc("ClefinCode WhatsApp Template")

temp_doc.template_language = template_language
temp_doc.body = self.template_content
temp_doc.buttons = [
{"type": "Custom", "button_text": "Yes"},
{"type": "Custom", "button_text": "No"},
]

existing_template = temp_doc.find_existing_same_content_language()

if existing_template:

self.message_template = existing_template.name
self.db_set("message_template", existing_template.name)

url = get_url_to_form(
"ClefinCode WhatsApp Template",
existing_template.name
)

frappe.msgprint(
msg=_(
"An existing WhatsApp template was found: {0}.<br><br>"
"This template will be used for this profile instead of creating a new one."
).format(
f"<a href='{url}' target='_blank'><b>{existing_template.meta_template_name or existing_template.name}</b></a>"
),
title=_("Existing WhatsApp Template Found"),
indicator="orange"
)

return existing_template


doc = frappe.get_doc({
"doctype": "ClefinCode WhatsApp Template",
"whatsapp_profile": self.name,
"template_name": f"{self.business_account_id}_confirm_message",
"meta_template_name": self.meta_template_name,
"category": "Utility",
"template_language": template_language,
"body": self.template_content,
"buttons": [
{"type": "Custom", "button_text": "Yes"},
{"type": "Custom", "button_text": "No"},
],
}).insert(ignore_permissions=True)

doc.submit()

self.message_template = doc.name
self.db_set("message_template", doc.name)

return doc

def get_whatsapp_numbers_for_profile(doc_name, user):
whatsapp_numbers_list = []
personal_numbers = frappe.db.sql(f"""
SELECT name AS number
FROM `tabClefinCode WhatsApp Profile`
WHERE type = 'Personal' AND user = '{user}' AND name <> '{doc_name}'
""", as_dict=True)

if personal_numbers:
for n in personal_numbers:
whatsapp_numbers_list.append(n['number'])

support_numbers = frappe.db.sql(f"""
SELECT DISTINCT wp.name AS number
FROM `tabClefinCode WhatsApp Profile` AS wp
INNER JOIN `tabAuthorized Users` users ON users.parent = wp.name
WHERE type = 'Support' AND users.user = '{user}' AND wp.name <> '{doc_name}'
""", as_dict=True)

if support_numbers:
for n in support_numbers:
whatsapp_numbers_list.append(n['number'])
if whatsapp_numbers_list and len(whatsapp_numbers_list) > 0:
frappe.throw(f"The user <b>{user}</b> already has WhatsApp number {frappe.utils.get_link_to_form('ClefinCode WhatsApp Profile' , whatsapp_numbers_list[0])} ")
whatsapp_numbers_list = []
personal_numbers = frappe.db.sql(f"""
SELECT name AS number
FROM `tabClefinCode WhatsApp Profile`
WHERE type = 'Personal' AND user = '{user}' AND name <> '{doc_name}'
""", as_dict=True)

if personal_numbers:
for n in personal_numbers:
whatsapp_numbers_list.append(n['number'])

support_numbers = frappe.db.sql(f"""
SELECT DISTINCT wp.name AS number
FROM `tabClefinCode WhatsApp Profile` AS wp
INNER JOIN `tabAuthorized Users` users ON users.parent = wp.name
WHERE type = 'Support' AND users.user = '{user}' AND wp.name <> '{doc_name}'
""", as_dict=True)

if support_numbers:
for n in support_numbers:
whatsapp_numbers_list.append(n['number'])
if whatsapp_numbers_list and len(whatsapp_numbers_list) > 0:
frappe.throw(f"The user <b>{user}</b> already has WhatsApp number {frappe.utils.get_link_to_form('ClefinCode WhatsApp Profile' , whatsapp_numbers_list[0])} ")

Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2025-12-11 11:22:21.293278",
"modified": "2026-07-05 12:34:22.780581",
"modified_by": "Administrator",
"module": "ClefinCode Chat",
"name": "ClefinCode WhatsApp Template",
Expand Down
Loading