Merge branch 'develop' into develop
This commit is contained in:
@@ -132,6 +132,7 @@ scheduler_events = {
|
||||
"lms.lms.doctype.lms_payment.lms_payment.send_payment_reminder",
|
||||
"lms.lms.doctype.lms_batch.lms_batch.send_batch_start_reminder",
|
||||
"lms.lms.doctype.lms_live_class.lms_live_class.send_live_class_reminder",
|
||||
"lms.lms.doctype.lms_course.lms_course.send_notification_for_published_courses",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,13 @@ from frappe.utils import (
|
||||
from frappe.utils.response import Response
|
||||
|
||||
from lms.lms.doctype.course_lesson.course_lesson import save_progress
|
||||
from lms.lms.utils import get_average_rating, get_batch_details, get_course_details, get_lesson_count
|
||||
from lms.lms.utils import (
|
||||
get_average_rating,
|
||||
get_batch_details,
|
||||
get_course_details,
|
||||
get_instructors,
|
||||
get_lesson_count,
|
||||
)
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@@ -1197,17 +1203,79 @@ def get_notifications(filters):
|
||||
notifications = frappe.get_all(
|
||||
"Notification Log",
|
||||
filters,
|
||||
["subject", "from_user", "link", "read", "name"],
|
||||
[
|
||||
"subject",
|
||||
"from_user",
|
||||
"link",
|
||||
"read",
|
||||
"name",
|
||||
"creation",
|
||||
"document_type",
|
||||
"document_name",
|
||||
"type",
|
||||
"email_content",
|
||||
],
|
||||
order_by="creation desc",
|
||||
)
|
||||
|
||||
for notification in notifications:
|
||||
notification = update_document_details(notification)
|
||||
notification = update_user_details(notification)
|
||||
|
||||
return notifications
|
||||
|
||||
|
||||
def update_user_details(notification):
|
||||
if (
|
||||
notification.document_details
|
||||
and len(notification.document_details.get("instructors", []))
|
||||
and not is_mention(notification)
|
||||
):
|
||||
from_user_details = notification.document_details["instructors"][0]
|
||||
else:
|
||||
from_user_details = frappe.db.get_value(
|
||||
"User", notification.from_user, ["full_name", "user_image"], as_dict=1
|
||||
)
|
||||
notification.update(from_user_details)
|
||||
notification["from_user_details"] = from_user_details
|
||||
return notification
|
||||
|
||||
return notifications
|
||||
|
||||
def is_mention(notification):
|
||||
if notification.type == "Mention":
|
||||
return True
|
||||
if "mentioned you" in notification.subject.lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def update_document_details(notification):
|
||||
if notification.document_type == "LMS Course":
|
||||
details = frappe.db.get_value(
|
||||
"LMS Course", notification.document_name, ["title", "video_link", "short_introduction"], as_dict=1
|
||||
)
|
||||
instructors = get_instructors("LMS Course", notification.document_name)
|
||||
details["instructors"] = instructors
|
||||
notification["document_details"] = details
|
||||
|
||||
elif notification.document_type == "LMS Batch":
|
||||
details = frappe.db.get_value(
|
||||
"LMS Batch",
|
||||
notification.document_name,
|
||||
[
|
||||
"title",
|
||||
"description as short_introduction",
|
||||
"video_link",
|
||||
"start_date",
|
||||
"end_date",
|
||||
"start_time",
|
||||
"timezone",
|
||||
],
|
||||
as_dict=1,
|
||||
)
|
||||
instructors = get_instructors("LMS Batch", notification.document_name)
|
||||
details["instructors"] = instructors
|
||||
notification["document_details"] = details
|
||||
return notification
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
|
||||
@@ -64,16 +64,21 @@ class LMSAssignmentSubmission(Document):
|
||||
def trigger_update_notification(self):
|
||||
notification = frappe._dict(
|
||||
{
|
||||
"subject": _("There has been an update on your submission for assignment {0}").format(
|
||||
self.assignment_title
|
||||
"subject": _("The instructor has left a comment on your assignment {0}").format(
|
||||
frappe.bold(self.assignment_title)
|
||||
),
|
||||
"email_content": self.comments,
|
||||
"document_type": self.doctype,
|
||||
"document_name": self.name,
|
||||
"for_user": self.owner,
|
||||
"from_user": self.evaluator,
|
||||
"type": "Alert",
|
||||
"link": f"/lms/assignment-submission/{self.assignment}/{self.name}",
|
||||
"link": f"/lms/assignment-submission/{self.assignment}/{self.name}",
|
||||
}
|
||||
)
|
||||
make_notification_logs(notification, [self.member])
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def upload_assignment(
|
||||
assignment_attachment=None,
|
||||
answer=None,
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
"column_break_flwy",
|
||||
"seat_count",
|
||||
"evaluation_end_date",
|
||||
"notification_sent",
|
||||
"section_break_jedp",
|
||||
"video_link",
|
||||
"column_break_kpct",
|
||||
"meta_image",
|
||||
"section_break_khcn",
|
||||
"batch_details",
|
||||
@@ -361,6 +365,26 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "Zoom Account",
|
||||
"options": "LMS Zoom Settings"
|
||||
},
|
||||
{
|
||||
"fieldname": "video_link",
|
||||
"fieldtype": "Attach",
|
||||
"label": "Preview Video"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "notification_sent",
|
||||
"fieldtype": "Check",
|
||||
"label": "Notification Sent",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_jedp",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_kpct",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
@@ -383,7 +407,7 @@
|
||||
"link_fieldname": "payment_for_document"
|
||||
}
|
||||
],
|
||||
"modified": "2025-12-23 11:27:00.424331",
|
||||
"modified": "2026-01-13 18:50:27.420712",
|
||||
"modified_by": "sayali@frappe.io",
|
||||
"module": "LMS",
|
||||
"name": "LMS Batch",
|
||||
|
||||
@@ -8,12 +8,14 @@ from datetime import timedelta
|
||||
import frappe
|
||||
import requests
|
||||
from frappe import _
|
||||
from frappe.desk.doctype.notification_log.notification_log import make_notification_logs
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import add_days, cint, format_datetime, get_time, nowdate
|
||||
|
||||
from lms.lms.utils import (
|
||||
generate_slug,
|
||||
get_assignment_details,
|
||||
get_instructors,
|
||||
get_lesson_index,
|
||||
get_lesson_url,
|
||||
get_quiz_details,
|
||||
@@ -33,6 +35,10 @@ class LMSBatch(Document):
|
||||
self.validate_timetable()
|
||||
self.validate_evaluation_end_date()
|
||||
|
||||
def on_update(self):
|
||||
if self.has_value_changed("published") and self.published:
|
||||
frappe.enqueue(send_notification_for_published_batch, batch=self, now=True)
|
||||
|
||||
def autoname(self):
|
||||
if not self.name:
|
||||
self.name = generate_slug(self.title, "LMS Batch")
|
||||
@@ -123,6 +129,77 @@ class LMSBatch(Document):
|
||||
update_payment_record("LMS Batch", self.name)
|
||||
|
||||
|
||||
def send_notification_for_published_batch(batch):
|
||||
send_notification = frappe.db.get_single_value("LMS Settings", "send_notification_for_published_batches")
|
||||
if not send_notification:
|
||||
return
|
||||
|
||||
if not batch.published:
|
||||
return
|
||||
if batch.notification_sent:
|
||||
return
|
||||
|
||||
if send_notification == "Email":
|
||||
send_email_notification_for_published_batch(batch)
|
||||
else:
|
||||
send_system_notification_for_published_batch(batch)
|
||||
|
||||
|
||||
def send_email_notification_for_published_batch(batch):
|
||||
brand_name = frappe.db.get_single_value("Website Settings", "app_name")
|
||||
brand_logo = frappe.db.get_single_value("Website Settings", "banner_image")
|
||||
subject = _("A new course has been published on {0}").format(brand_name)
|
||||
template = "published_batch_notification"
|
||||
students = frappe.get_all("User", {"enabled": 1}, pluck="name")
|
||||
instructors = get_instructors("LMS Batch", batch.name)
|
||||
|
||||
args = {
|
||||
"brand_logo": brand_logo,
|
||||
"brand_name": brand_name,
|
||||
"title": batch.title,
|
||||
"short_introduction": batch.description,
|
||||
"start_date": batch.start_date,
|
||||
"end_date": batch.end_date,
|
||||
"start_time": batch.start_time,
|
||||
"medium": batch.medium,
|
||||
"timezone": batch.timezone,
|
||||
"instructors": instructors,
|
||||
"batch_url": f"{frappe.utils.get_url()}/lms/batches/details/{batch.name}",
|
||||
}
|
||||
|
||||
frappe.sendmail(
|
||||
recipients=instructors,
|
||||
bcc=students,
|
||||
subject=subject,
|
||||
template=template,
|
||||
args=args,
|
||||
)
|
||||
frappe.db.set_value("LMS Batch", batch.name, "notification_sent", 1)
|
||||
|
||||
|
||||
def send_system_notification_for_published_batch(batch):
|
||||
students = frappe.get_all("User", {"enabled": 1}, pluck="name")
|
||||
instructors = frappe.get_all("Course Instructor", {"parent": batch.name}, pluck="instructor")
|
||||
instructor_name = frappe.db.get_value("User", instructors[0], "full_name")
|
||||
notification = frappe._dict(
|
||||
{
|
||||
"subject": _("{0} has published a new batch {1}").format(
|
||||
frappe.bold(instructor_name), frappe.bold(batch.title)
|
||||
),
|
||||
"email_content": _(
|
||||
"A new batch '{0}' has been published that might interest you. Check it out!"
|
||||
).format(batch.title),
|
||||
"document_type": "LMS Batch",
|
||||
"document_name": batch.name,
|
||||
"from_user": instructors[0] if instructors else None,
|
||||
"type": "Alert",
|
||||
"link": f"/lms/batches/details/{batch.name}",
|
||||
}
|
||||
)
|
||||
make_notification_logs(notification, students)
|
||||
frappe.db.set_value("LMS Batch", batch.name, "notification_sent", 1)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_live_class(
|
||||
batch_name,
|
||||
|
||||
@@ -48,7 +48,8 @@
|
||||
"statistics_section",
|
||||
"enrollments",
|
||||
"lessons",
|
||||
"rating"
|
||||
"rating",
|
||||
"notification_sent"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -288,6 +289,13 @@
|
||||
"fieldname": "timezone",
|
||||
"fieldtype": "Data",
|
||||
"label": "Timezone"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "notification_sent",
|
||||
"fieldtype": "Check",
|
||||
"label": "Notification Sent",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"is_published_field": "published",
|
||||
@@ -306,7 +314,7 @@
|
||||
}
|
||||
],
|
||||
"make_attachments_public": 1,
|
||||
"modified": "2025-12-15 15:15:42.226098",
|
||||
"modified": "2026-01-13 18:48:56.069280",
|
||||
"modified_by": "sayali@frappe.io",
|
||||
"module": "LMS",
|
||||
"name": "LMS Course",
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# Copyright (c) 2021, Frappe and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
import json
|
||||
import random
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.desk.doctype.notification_log.notification_log import make_notification_logs
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cint, today
|
||||
|
||||
from ...utils import generate_slug, update_payment_record, validate_image
|
||||
from ...utils import generate_slug, get_instructors, update_payment_record, validate_image
|
||||
|
||||
|
||||
class LMSCourse(Document):
|
||||
@@ -131,3 +131,79 @@ class LMSCourse(Document):
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Course#{self.name}>"
|
||||
|
||||
|
||||
def send_notification_for_published_courses():
|
||||
send_notification = frappe.db.get_single_value("LMS Settings", "send_notification_for_published_courses")
|
||||
if not send_notification:
|
||||
return
|
||||
|
||||
courses_published_today = frappe.get_all(
|
||||
"LMS Course",
|
||||
{
|
||||
"published_on": today(),
|
||||
"notification_sent": 0,
|
||||
},
|
||||
["name", "title", "short_introduction"],
|
||||
)
|
||||
|
||||
if not courses_published_today:
|
||||
return
|
||||
|
||||
if send_notification == "Email":
|
||||
send_email_notification_for_published_courses(courses_published_today)
|
||||
else:
|
||||
send_system_notification_for_published_courses(courses_published_today)
|
||||
|
||||
|
||||
def send_email_notification_for_published_courses(courses):
|
||||
brand_name = frappe.db.get_single_value("Website Settings", "app_name")
|
||||
brand_logo = frappe.db.get_single_value("Website Settings", "banner_image")
|
||||
subject = _("A new course has been published on {0}").format(brand_name)
|
||||
template = "published_course_notification"
|
||||
students = frappe.get_all("User", {"enabled": 1}, pluck="name")
|
||||
|
||||
for course in courses:
|
||||
instructors = get_instructors("LMS Course", course.name)
|
||||
|
||||
args = {
|
||||
"brand_logo": brand_logo,
|
||||
"brand_name": brand_name,
|
||||
"title": course.title,
|
||||
"short_introduction": course.short_introduction,
|
||||
"instructors": instructors,
|
||||
"course_url": f"{frappe.utils.get_url()}/lms/courses/{course.name}",
|
||||
}
|
||||
|
||||
frappe.sendmail(
|
||||
recipients=instructors,
|
||||
bcc=students,
|
||||
subject=subject,
|
||||
template=template,
|
||||
args=args,
|
||||
)
|
||||
frappe.db.set_value("LMS Course", course.name, "notification_sent", 1)
|
||||
|
||||
|
||||
def send_system_notification_for_published_courses(courses):
|
||||
for course in courses:
|
||||
students = frappe.get_all("User", {"enabled": 1}, pluck="name")
|
||||
instructors = frappe.get_all("Course Instructor", {"parent": course.name}, pluck="instructor")
|
||||
instructor_name = frappe.db.get_value("User", instructors[0], "full_name")
|
||||
notification = frappe._dict(
|
||||
{
|
||||
"subject": _("{0} has published a new course {1}").format(
|
||||
frappe.bold(instructor_name), frappe.bold(course.title)
|
||||
),
|
||||
"email_content": _(
|
||||
"A new course '{0}' has been published that might interest you. Check it out!"
|
||||
).format(course.title),
|
||||
"document_type": "LMS Course",
|
||||
"document_name": course.name,
|
||||
"from_user": instructors[0] if instructors else None,
|
||||
"type": "Alert",
|
||||
"link": f"/lms/courses/{course.name}",
|
||||
}
|
||||
)
|
||||
make_notification_logs(notification, students)
|
||||
frappe.db.set_value("LMS Course", course.name, "notification_sent", 1)
|
||||
|
||||
@@ -54,15 +54,15 @@ class LMSQuizSubmission(Document):
|
||||
notification = frappe._dict(
|
||||
{
|
||||
"subject": _("You have got a score of {0} for the quiz {1}").format(
|
||||
self.score, self.quiz_title
|
||||
(frappe.bold(self.score)), frappe.bold(self.quiz_title)
|
||||
),
|
||||
"email_content": _(
|
||||
"There has been an update on your submission. You have got a score of {0} for the quiz {1}"
|
||||
).format(self.score, self.quiz_title),
|
||||
).format(frappe.bold(self.score), frappe.bold(self.quiz_title)),
|
||||
"document_type": self.doctype,
|
||||
"document_name": self.name,
|
||||
"for_user": self.member,
|
||||
"from_user": "Administrator",
|
||||
"from_user": frappe.session.user,
|
||||
"type": "Alert",
|
||||
"link": "",
|
||||
}
|
||||
|
||||
@@ -6,16 +6,20 @@
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"general_tab",
|
||||
"default_home",
|
||||
"send_calendar_invite_for_evaluations",
|
||||
"persona_captured",
|
||||
"column_break_zdel",
|
||||
"allow_guest_access",
|
||||
"prevent_skipping_videos",
|
||||
"send_calendar_invite_for_evaluations",
|
||||
"column_break_zdel",
|
||||
"disable_pwa",
|
||||
"persona_captured",
|
||||
"default_home",
|
||||
"column_break_bjis",
|
||||
"unsplash_access_key",
|
||||
"livecode_url",
|
||||
"notifications_section",
|
||||
"send_notification_for_published_courses",
|
||||
"column_break_dtns",
|
||||
"send_notification_for_published_batches",
|
||||
"section_break_szgq",
|
||||
"show_day_view",
|
||||
"column_break_2",
|
||||
@@ -446,13 +450,34 @@
|
||||
"fieldname": "disable_pwa",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disable PWA"
|
||||
},
|
||||
{
|
||||
"fieldname": "send_notification_for_published_courses",
|
||||
"fieldtype": "Select",
|
||||
"label": "Send Notification for Published Courses",
|
||||
"options": "\nEmail\nIn-app"
|
||||
},
|
||||
{
|
||||
"fieldname": "send_notification_for_published_batches",
|
||||
"fieldtype": "Select",
|
||||
"label": "Send Notification for Published Batches",
|
||||
"options": "\nEmail\nIn-app"
|
||||
},
|
||||
{
|
||||
"fieldname": "notifications_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Notifications"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_dtns",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2025-12-22 11:30:13.868031",
|
||||
"modified": "2026-01-01 19:36:54.443390",
|
||||
"modified_by": "sayali@frappe.io",
|
||||
"module": "LMS",
|
||||
"name": "LMS Settings",
|
||||
|
||||
@@ -398,26 +398,47 @@ def handle_notifications(doc, method):
|
||||
notify_mentions_via_email(doc, topic)
|
||||
|
||||
|
||||
def create_notification_log(doc, topic):
|
||||
def get_course_details_for_notification(topic):
|
||||
users = []
|
||||
course = frappe.db.get_value("Course Lesson", topic.reference_docname, "course")
|
||||
course_title = frappe.db.get_value("LMS Course", course, "title")
|
||||
instructors = frappe.db.get_all(
|
||||
"Course Instructor", {"parent": course, "parenttype": "LMS Course"}, pluck="instructor"
|
||||
)
|
||||
|
||||
users.append(topic.owner)
|
||||
users += instructors
|
||||
|
||||
subject = _("New reply on the topic {0} in course {1}").format(topic.title, course_title)
|
||||
link = get_lesson_url(course, get_lesson_index(topic.reference_docname))
|
||||
|
||||
return subject, link, users
|
||||
|
||||
|
||||
def get_batch_details_for_notification(topic):
|
||||
users = []
|
||||
batch_title = frappe.db.get_value("LMS Batch", topic.reference_docname, "title")
|
||||
subject = _("New comment in batch {0}").format(batch_title)
|
||||
link = f"/lms/batches/{topic.reference_docname}"
|
||||
instructors = frappe.db.get_all(
|
||||
"Course Instructor",
|
||||
{"parenttype": "LMS Batch", "parent": topic.reference_docname},
|
||||
pluck="instructor",
|
||||
)
|
||||
students = frappe.db.get_all("LMS Batch Enrollment", {"batch": topic.reference_docname}, pluck="member")
|
||||
users += instructors
|
||||
users += students
|
||||
return subject, link, users
|
||||
|
||||
|
||||
def create_notification_log(doc, topic):
|
||||
if topic.reference_doctype == "Course Lesson":
|
||||
course = frappe.db.get_value("Course Lesson", topic.reference_docname, "course")
|
||||
course_title = frappe.db.get_value("LMS Course", course, "title")
|
||||
instructors = frappe.db.get_all("Course Instructor", {"parent": course}, pluck="instructor")
|
||||
|
||||
if doc.owner != topic.owner:
|
||||
users.append(topic.owner)
|
||||
|
||||
users += instructors
|
||||
subject = _("New reply on the topic {0} in course {1}").format(topic.title, course_title)
|
||||
link = get_lesson_url(course, get_lesson_index(topic.reference_docname))
|
||||
|
||||
subject, link, users = get_course_details_for_notification(topic)
|
||||
else:
|
||||
batch_title = frappe.db.get_value("LMS Batch", topic.reference_docname, "title")
|
||||
subject = _("New comment in batch {0}").format(batch_title)
|
||||
link = f"/batches/{topic.reference_docname}"
|
||||
moderators = frappe.get_all("Has Role", {"role": "Moderator"}, pluck="parent")
|
||||
users += moderators
|
||||
subject, link, users = get_batch_details_for_notification(topic)
|
||||
|
||||
if doc.owner in users:
|
||||
users.remove(doc.owner)
|
||||
|
||||
notification = frappe._dict(
|
||||
{
|
||||
@@ -425,7 +446,6 @@ def create_notification_log(doc, topic):
|
||||
"email_content": doc.reply,
|
||||
"document_type": topic.reference_doctype,
|
||||
"document_name": topic.reference_docname,
|
||||
"for_user": topic.owner,
|
||||
"from_user": doc.owner,
|
||||
"type": "Alert",
|
||||
"link": link,
|
||||
@@ -444,12 +464,16 @@ def notify_mentions_on_portal(doc, topic):
|
||||
|
||||
if topic.reference_doctype == "Course Lesson":
|
||||
course = frappe.db.get_value("Course Lesson", topic.reference_docname, "course")
|
||||
subject = _("{0} mentioned you in a comment in {1}").format(from_user_name, topic.title)
|
||||
subject = _("{0} mentioned you in a comment in {1}").format(
|
||||
frappe.bold(from_user_name), frappe.bold(topic.title)
|
||||
)
|
||||
link = get_lesson_url(course, get_lesson_index(topic.reference_docname))
|
||||
else:
|
||||
batch_title = frappe.db.get_value("LMS Batch", topic.reference_docname, "title")
|
||||
subject = _("{0} mentioned you in a comment in {1}").format(from_user_name, batch_title)
|
||||
link = f"/batches/{topic.reference_docname}"
|
||||
subject = _("{0} mentioned you in a comment in {1}").format(
|
||||
frappe.bold(from_user_name), frappe.bold(batch_title)
|
||||
)
|
||||
link = f"/lms/batches/{topic.reference_docname}#discussions"
|
||||
|
||||
for user in mentions:
|
||||
notification = frappe._dict(
|
||||
@@ -460,7 +484,7 @@ def notify_mentions_on_portal(doc, topic):
|
||||
"document_name": topic.reference_docname,
|
||||
"for_user": user,
|
||||
"from_user": doc.owner,
|
||||
"type": "Alert",
|
||||
"type": "Mention",
|
||||
"link": link,
|
||||
}
|
||||
)
|
||||
|
||||
376
lms/locale/ar.po
376
lms/locale/ar.po
File diff suppressed because it is too large
Load Diff
378
lms/locale/bs.po
378
lms/locale/bs.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/cs.po
376
lms/locale/cs.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/da.po
376
lms/locale/da.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/de.po
376
lms/locale/de.po
File diff suppressed because it is too large
Load Diff
378
lms/locale/eo.po
378
lms/locale/eo.po
File diff suppressed because it is too large
Load Diff
378
lms/locale/es.po
378
lms/locale/es.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/fa.po
376
lms/locale/fa.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/fr.po
376
lms/locale/fr.po
File diff suppressed because it is too large
Load Diff
378
lms/locale/hr.po
378
lms/locale/hr.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/hu.po
376
lms/locale/hu.po
File diff suppressed because it is too large
Load Diff
378
lms/locale/id.po
378
lms/locale/id.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/it.po
376
lms/locale/it.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/my.po
376
lms/locale/my.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/nb.po
376
lms/locale/nb.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/nl.po
376
lms/locale/nl.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/pl.po
376
lms/locale/pl.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/pt.po
376
lms/locale/pt.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
378
lms/locale/ru.po
378
lms/locale/ru.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/sl.po
376
lms/locale/sl.po
File diff suppressed because it is too large
Load Diff
378
lms/locale/sr.po
378
lms/locale/sr.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
378
lms/locale/sv.po
378
lms/locale/sv.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/ta.po
376
lms/locale/ta.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/th.po
376
lms/locale/th.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/tr.po
376
lms/locale/tr.po
File diff suppressed because it is too large
Load Diff
376
lms/locale/vi.po
376
lms/locale/vi.po
File diff suppressed because it is too large
Load Diff
378
lms/locale/zh.po
378
lms/locale/zh.po
File diff suppressed because it is too large
Load Diff
54
lms/templates/emails/published_batch_notification.html
Normal file
54
lms/templates/emails/published_batch_notification.html
Normal file
@@ -0,0 +1,54 @@
|
||||
<div style="width: 70%; margin: 0 auto;">
|
||||
<img src="{{ brand_logo }}" style="width: 30px; height: 30px;" />
|
||||
<p style="font-size: 16px; font-weight: 600;">
|
||||
{{ _("Hello Learner") }},
|
||||
</p>
|
||||
<p>
|
||||
{{ _("A new batch has been published on ")}} {{ brand_name }} {{ _("that might interest you!") }} {{ _("Here are the details:") }}
|
||||
</p>
|
||||
<div style="background-color: #F8F8F8; border-radius: 12px; padding: 12px; margin-bottom: 6px;">
|
||||
<div style="font-weight: 600; margin-bottom: 6px; font-size: 15px;">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div>
|
||||
{{ short_introduction }}
|
||||
</div>
|
||||
<div style="margin-top: 20px; font-size: 13px;">
|
||||
{% if end_date %}
|
||||
<span>
|
||||
{{ _("From ") }} {{ frappe.utils.format_date(start_date, "dd MMM YYYY") }} {{ _(" to ") }} {{ frappe.utils.format_date(end_date, "dd MMM YYYY") }}
|
||||
</span>
|
||||
{% else %}
|
||||
<span>
|
||||
{{ frappe.utils.format_date(start_date, "dd MMM YYYY") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div style="color: #525252; margin-top: 4px; font-size: 13px;">
|
||||
<span>
|
||||
{{ _("Time: ") }} {{ frappe.utils.format_time(start_time, "HH:mm a") }} {{ timezone }}
|
||||
</span>
|
||||
</div>
|
||||
<div style="margin-top: 20px;">
|
||||
{% for instructor in instructors %}
|
||||
<div style="display: flex; align-items: center; margin-bottom: 5px;">
|
||||
{% if instructor.user_image %}
|
||||
<img src="{{ instructor.user_image }}" style="width: 20px; height: 20px; border-radius: 50%; margin-right: 5px;" />
|
||||
{% else %}
|
||||
<div style="width: 20px; height: 20px; border-radius: 50%; background-color: #ccc; display: flex; align-items: center; justify-content: center; margin-right: 5px;">
|
||||
<span style="font-size: 12px; color: #fff;">
|
||||
{{ instructor.full_name.split("")[0] | upper }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
{{ instructor.full_name }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ batch_url }}" style="display: inline-block; padding: 4px 8px; background-color: #171717; color: #fff; text-decoration: none; cursor: pointer; border-radius: 8px; margin-top: 10px;">
|
||||
{{ _("Checkout the batch") }}
|
||||
</a>
|
||||
</div>
|
||||
38
lms/templates/emails/published_course_notification.html
Normal file
38
lms/templates/emails/published_course_notification.html
Normal file
@@ -0,0 +1,38 @@
|
||||
<div style="width: 70%; margin: 0 auto;">
|
||||
<img src="{{ brand_logo }}" style="width: 30px; height: 30px;" />
|
||||
<p style="font-size: 16px; font-weight: 600;">
|
||||
{{ _("Hello Learner") }},
|
||||
</p>
|
||||
<p>
|
||||
{{ _("A new course has been published on ")}} {{ brand_name }} {{ _("that might interest you!") }} {{ _("Here are the details:") }}
|
||||
</p>
|
||||
<div style="background-color: #F8F8F8; border-radius: 12px; padding: 12px; margin-bottom: 6px;">
|
||||
<div style="font-weight: 600; margin-bottom: 6px;">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div>
|
||||
{{ short_introduction }}
|
||||
</div>
|
||||
<div style="margin-top: 20px;">
|
||||
{% for instructor in instructors %}
|
||||
<div style="display: flex; align-items: center; margin-bottom: 5px;">
|
||||
{% if instructor.user_image %}
|
||||
<img src="{{ instructor.user_image }}" style="width: 20px; height: 20px; border-radius: 50%; margin-right: 5px;" />
|
||||
{% else %}
|
||||
<div style="width: 20px; height: 20px; border-radius: 50%; background-color: #ccc; display: flex; align-items: center; justify-content: center; margin-right: 5px;">
|
||||
<span style="font-size: 12px; color: #fff;">
|
||||
{{ instructor.full_name.split("")[0] | upper }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
{{ instructor.full_name }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ course_url }}" style="display: inline-block; padding: 4px 8px; background-color: #171717; color: #fff; text-decoration: none; cursor: pointer; border-radius: 8px; margin-top: 10px;">
|
||||
{{ _("Checkout the course") }}
|
||||
</a>
|
||||
</div>
|
||||
Reference in New Issue
Block a user