feat: emails on messages
This commit is contained in:
@@ -8,14 +8,19 @@
|
|||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"enabled",
|
|
||||||
"full_name",
|
"full_name",
|
||||||
"email",
|
"email",
|
||||||
|
"enabled",
|
||||||
|
"column_break_4",
|
||||||
"role",
|
"role",
|
||||||
"photo",
|
|
||||||
"short_intro",
|
"short_intro",
|
||||||
|
"section_break_7",
|
||||||
"bio",
|
"bio",
|
||||||
|
"section_break_9",
|
||||||
"username",
|
"username",
|
||||||
|
"photo",
|
||||||
|
"column_break_12",
|
||||||
|
"email_preference",
|
||||||
"route"
|
"route"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
@@ -29,6 +34,7 @@
|
|||||||
"fieldname": "full_name",
|
"fieldname": "full_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
"label": "Full Name",
|
"label": "Full Name",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
@@ -64,6 +70,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "email",
|
"fieldname": "email",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
|
"in_standard_filter": 1,
|
||||||
"label": "Email",
|
"label": "Email",
|
||||||
"options": "Email",
|
"options": "Email",
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
@@ -74,12 +81,34 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "User Name",
|
"label": "User Name",
|
||||||
"unique": 1
|
"unique": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "email_preference",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Email preference",
|
||||||
|
"options": "Email on every Message\nOne Digest Mail per day\nNever"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_4",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_7",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_9",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_12",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 1,
|
"has_web_view": 1,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-03-22 12:16:18.823037",
|
"modified": "2021-03-30 17:25:57.075151",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Community",
|
"module": "Community",
|
||||||
"name": "Community Member",
|
"name": "Community Member",
|
||||||
|
|||||||
@@ -98,24 +98,11 @@ doc_events = {
|
|||||||
|
|
||||||
# Scheduled Tasks
|
# Scheduled Tasks
|
||||||
# ---------------
|
# ---------------
|
||||||
|
scheduler_events = {
|
||||||
# scheduler_events = {
|
"daily": [
|
||||||
# "all": [
|
"erpnext.stock.reorder_item.reorder_item"
|
||||||
# "community.tasks.all"
|
]
|
||||||
# ],
|
}
|
||||||
# "daily": [
|
|
||||||
# "community.tasks.daily"
|
|
||||||
# ],
|
|
||||||
# "hourly": [
|
|
||||||
# "community.tasks.hourly"
|
|
||||||
# ],
|
|
||||||
# "weekly": [
|
|
||||||
# "community.tasks.weekly"
|
|
||||||
# ]
|
|
||||||
# "monthly": [
|
|
||||||
# "community.tasks.monthly"
|
|
||||||
# ]
|
|
||||||
# }
|
|
||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
# -------
|
# -------
|
||||||
|
|||||||
@@ -3,8 +3,57 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
# import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import add_days, nowdate
|
||||||
class LMSMessage(Document):
|
class LMSMessage(Document):
|
||||||
pass
|
def after_insert(self):
|
||||||
|
membership = frappe.get_all("LMS Batch Membership", {"batch": self.batch}, ["member"])
|
||||||
|
for entry in membership:
|
||||||
|
member = frappe.get_doc("Community Member", entry.member)
|
||||||
|
if member.name != self.author and member.email_preference == "Email on every Message":
|
||||||
|
frappe.sendmail(
|
||||||
|
recipients = member.email,
|
||||||
|
subject = _("New Message on ") + self.batch,
|
||||||
|
header = _("New Message on ") + self.batch,
|
||||||
|
template = "lms_message",
|
||||||
|
args = {
|
||||||
|
"author": self.author,
|
||||||
|
"message": frappe.utils.md_to_html(self.message),
|
||||||
|
"creation": frappe.utils.format_datetime(self.creation, "medium"),
|
||||||
|
"course": frappe.db.get_value("LMS Batch", self.batch, ["course"])
|
||||||
|
}
|
||||||
|
)
|
||||||
|
def send_daily_digest():
|
||||||
|
emails = frappe._dict()
|
||||||
|
messages = frappe.get_all("LMS Message", {"creation": [">=", add_days(nowdate(), -1)]}, ["message", "batch", "author", "creation"])
|
||||||
|
for message in messages:
|
||||||
|
membership = frappe.get_all("LMS Batch Membership", {"batch": message.batch}, ["member"])
|
||||||
|
for entry in membership:
|
||||||
|
member = frappe.db.get_value("Community Member", entry.member, ["name", "email_preference", "email"], as_dict=1)
|
||||||
|
if member.name != message.author and member.email_preference == "One Digest Mail per day":
|
||||||
|
if member.name in emails.keys():
|
||||||
|
emails[member.name]["messages"].append(message)
|
||||||
|
else:
|
||||||
|
emails[member.name] = frappe._dict({
|
||||||
|
"email": member.email,
|
||||||
|
"messages": [message]
|
||||||
|
})
|
||||||
|
for email in emails:
|
||||||
|
group_by_batch = frappe._dict()
|
||||||
|
for message in emails[email]["messages"]:
|
||||||
|
if message.batch in group_by_batch.keys():
|
||||||
|
group_by_batch[message.batch].append(message)
|
||||||
|
else:
|
||||||
|
group_by_batch[message.batch] = [message]
|
||||||
|
frappe.sendmail(
|
||||||
|
recipients = frappe.db.get_value("Community Member", email, "email"),
|
||||||
|
subject = _("Message Digest"),
|
||||||
|
header = _("Message Digest"),
|
||||||
|
template = "lms_daily_digest",
|
||||||
|
args = {
|
||||||
|
"batches": group_by_batch
|
||||||
|
},
|
||||||
|
delayed = False
|
||||||
|
)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
community.patches.set_email_preferences
|
||||||
8
community/patches/set_email_preferences.py
Normal file
8
community/patches/set_email_preferences.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
members = frappe.get_all("Community Member", ["name", "email_preference"])
|
||||||
|
for member in members:
|
||||||
|
if not member.email_preference:
|
||||||
|
frappe.db.set_value("Community Member", member.name, "email_preference", "Email on every Message")
|
||||||
12
community/templates/emails/lms_daily_digest.html
Normal file
12
community/templates/emails/lms_daily_digest.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{% for batch in batches %}
|
||||||
|
<h3> {{ batch }}</h3>
|
||||||
|
<div>
|
||||||
|
{% for message in batches[batch] %}
|
||||||
|
<div style="border: 1px solid #DBDBDB;padding: 10px; margin: 10px;">
|
||||||
|
<p> {{ frappe.utils.md_to_html(message.message) }} </p>
|
||||||
|
<p class="text-right">By {{message.author}}</p>
|
||||||
|
<div class="small text-muted text-right">{{ frappe.utils.format_datetime(message.creation, "medium") }}</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
13
community/templates/emails/lms_message.html
Normal file
13
community/templates/emails/lms_message.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!-- <div style="border: 1px solid #DBDBDB; padding-bottom: 10px;">
|
||||||
|
<h6 style="padding-left: 10px;">{{ author }}</h6>
|
||||||
|
<hr style="border: 1px solid #DBDBDB;">
|
||||||
|
<div style="padding: 10px;">
|
||||||
|
{{ message }}
|
||||||
|
<div class="small text-muted text-right">{{ creation }}</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<p> {{ message }} </p>
|
||||||
|
<p class="text-right">By {{author}}</p>
|
||||||
|
<div class="small text-muted text-right">{{ creation }}</div>
|
||||||
|
<a href="courses/course?course={{course}}">Open Course</a>
|
||||||
@@ -61,9 +61,11 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="form-group">
|
<div class="border p-5">
|
||||||
<textarea class="form-control message-text" rows="3" placeholder="Enter your message here."></textarea>
|
<div class="form-group">
|
||||||
<button class="btn btn-primary mt-5 send-message" data-author="{{ author | urlencode}}" data-batch="{{ current_batch | urlencode }}">Send</button>
|
<textarea class="form-control message-text" rows="3" placeholder="Enter your message here."></textarea>
|
||||||
|
<button class="btn btn-primary mt-5 send-message" data-author="{{ author | urlencode}}" data-batch="{{ current_batch | urlencode }}">Send</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if discussions %}
|
{% if discussions %}
|
||||||
<div class="discussions">
|
<div class="discussions">
|
||||||
|
|||||||
Reference in New Issue
Block a user