feat: allow creating Days Before / After notifications for child table (#26982)

This commit is contained in:
Sagar Vora 2024-07-11 19:11:29 +05:30 committed by GitHub
parent c199a76aaf
commit b193cde7c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 56 additions and 41 deletions

View file

@ -1,6 +1,8 @@
// Copyright (c) 2018, Frappe Technologies and contributors
// For license information, please see license.txt
const DATE_BASED_EVENTS = ["Days Before", "Days After"];
frappe.notification = {
setup_fieldname_select: function (frm) {
// get the doctype to update fields
@ -129,6 +131,8 @@ Last comment: {{ comments[-1].comment }} by {{ comments[-1].by }}
frappe.ui.form.on("Notification", {
onload: function (frm) {
frm.set_query("document_type", function () {
if (DATE_BASED_EVENTS.includes(frm.doc.event)) return;
return {
filters: {
istable: 0,
@ -166,23 +170,23 @@ frappe.ui.form.on("Notification", {
frappe.set_route("Form", "Customize Form");
},
event: function (frm) {
if (["Days Before", "Days After"].includes(frm.doc.event)) {
frm.add_custom_button(__("Get Alerts for Today"), function () {
frappe.call({
method: "frappe.email.doctype.notification.notification.get_documents_for_today",
args: {
notification: frm.doc.name,
},
callback: function (r) {
if (r.message && r.message.length > 0) {
frappe.msgprint(r.message.toString());
} else {
frappe.msgprint(__("No alerts for today"));
}
},
});
if (!DATE_BASED_EVENTS.includes(frm.doc.event) || frm.is_new()) return;
frm.add_custom_button(__("Get Alerts for Today"), function () {
frappe.call({
method: "frappe.email.doctype.notification.notification.get_documents_for_today",
args: {
notification: frm.doc.name,
},
callback: function (r) {
if (r.message && r.message.length > 0) {
frappe.msgprint(r.message.toString());
} else {
frappe.msgprint(__("No alerts for today"));
}
},
});
}
});
},
channel: function (frm) {
frm.toggle_reqd("recipients", frm.doc.channel == "Email");

View file

@ -8,16 +8,16 @@
"engine": "InnoDB",
"field_order": [
"enabled",
"is_standard",
"module",
"column_break_2",
"channel",
"slack_webhook_url",
"filters",
"subject",
"document_type",
"is_standard",
"module",
"col_break_1",
"event",
"document_type",
"col_break_1",
"method",
"date_changed",
"days_in_advance",
@ -119,7 +119,6 @@
"fieldtype": "Column Break"
},
{
"depends_on": "eval: doc.document_type",
"fieldname": "event",
"fieldtype": "Select",
"in_list_view": 1,
@ -292,7 +291,7 @@
"icon": "fa fa-envelope",
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-06-17 04:03:22.591781",
"modified": "2024-07-04 05:53:40.595130",
"modified_by": "Administrator",
"module": "Email",
"name": "Notification",
@ -315,4 +314,4 @@
"states": [],
"title_field": "subject",
"track_changes": 1
}
}

View file

@ -18,6 +18,8 @@ from frappe.utils.jinja import validate_template
from frappe.utils.safe_exec import get_safe_globals
FORMATS = {"HTML": ".html", "Markdown": ".md", "Plain Text": ".txt"}
FORBIDDEN_DOCUMENT_TYPES = frozenset(("Email Queue",))
DATE_BASED_EVENTS = frozenset(("Days Before", "Days After"))
class Notification(Document):
@ -27,9 +29,7 @@ class Notification(Document):
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from frappe.email.doctype.notification_recipient.notification_recipient import (
NotificationRecipient,
)
from frappe.email.doctype.notification_recipient.notification_recipient import NotificationRecipient
from frappe.types import DF
attach_print: DF.Check
@ -90,7 +90,7 @@ class Notification(Document):
if self.event == "Value Change" and not self.value_changed:
frappe.throw(_("Please specify which value field must be checked"))
self.validate_forbidden_types()
self.validate_forbidden_document_types()
self.validate_condition()
self.validate_standard()
frappe.cache.hdel("notifications", self.document_type)
@ -130,12 +130,16 @@ def get_context(context):
except Exception:
frappe.throw(_("The Condition '{0}' is invalid").format(self.condition))
def validate_forbidden_types(self):
forbidden_document_types = ("Email Queue",)
if self.document_type in forbidden_document_types or frappe.get_meta(self.document_type).istable:
# currently notifications don't work on child tables as events are not fired for each record of child table
frappe.throw(_("Cannot set Notification on Document Type {0}").format(self.document_type))
def validate_forbidden_document_types(self):
if self.document_type in FORBIDDEN_DOCUMENT_TYPES or (
frappe.get_meta(self.document_type).istable and self.event not in DATE_BASED_EVENTS
):
# only date based events are allowed for child tables
frappe.throw(
_("Cannot set Notification with event {0} on Document Type {1}").format(
_(self.event), _(self.document_type)
)
)
def get_documents_for_today(self):
"""get list of documents that will be triggered today"""
@ -237,8 +241,8 @@ def get_context(context):
notification_doc = {
"type": "Alert",
"document_type": doc.doctype,
"document_name": doc.name,
"document_type": get_reference_doctype(doc),
"document_name": get_reference_name(doc),
"subject": subject,
"from_user": doc.modified_by or doc.owner,
"email_content": frappe.render_template(self.message, context),
@ -270,8 +274,8 @@ def get_context(context):
# No need to add if it is already a communication.
if doc.doctype != "Communication":
communication = make_communication(
doctype=doc.doctype,
name=doc.name,
doctype=get_reference_doctype(doc),
name=get_reference_name(doc),
content=message,
subject=subject,
sender=sender,
@ -294,8 +298,8 @@ def get_context(context):
cc=cc,
bcc=bcc,
message=message,
reference_doctype=doc.doctype,
reference_name=doc.name,
reference_doctype=get_reference_doctype(doc),
reference_name=get_reference_name(doc),
attachments=attachments,
expose_recipients="header",
print_letterhead=((attachments and attachments[0].get("print_letterhead")) or False),
@ -306,8 +310,8 @@ def get_context(context):
send_slack_message(
webhook_url=self.slack_webhook_url,
message=frappe.render_template(self.message, context),
reference_doctype=doc.doctype,
reference_name=doc.name,
reference_doctype=get_reference_doctype(doc),
reference_name=get_reference_name(doc),
)
def send_sms(self, doc, context):
@ -543,3 +547,11 @@ def get_emails_from_template(template, context):
emails = frappe.render_template(template, context) if "{" in template else template
return filter(None, emails.replace(",", "\n").split("\n"))
def get_reference_doctype(doc):
return doc.parenttype if doc.meta.istable else doc.doctype
def get_reference_name(doc):
return doc.parent if doc.meta.istable else doc.name