fix: discussion, batch home page, new fields for batches

This commit is contained in:
pateljannat
2021-05-26 12:13:04 +05:30
31 changed files with 371 additions and 225 deletions

View File

@@ -6,11 +6,15 @@
"engine": "InnoDB",
"field_order": [
"course",
"telegram_link",
"code",
"column_break_3",
"title",
"video_call_link",
"batch_schedule_section",
"start_date",
"start_time",
"column_break_3",
"code",
"column_break_10",
"sessions_on",
"end_time",
"section_break_5",
@@ -84,7 +88,8 @@
},
{
"fieldname": "section_break_5",
"fieldtype": "Section Break"
"fieldtype": "Section Break",
"label": "Batch Description"
},
{
"fieldname": "column_break_9",
@@ -92,7 +97,8 @@
},
{
"fieldname": "section_break_7",
"fieldtype": "Section Break"
"fieldtype": "Section Break",
"label": "Batch Settings"
},
{
"fieldname": "start_date",
@@ -116,6 +122,25 @@
"fieldtype": "Time",
"in_list_view": 1,
"label": "End Time"
},
{
"fieldname": "telegram_link",
"fieldtype": "Data",
"label": "Telegram Link"
},
{
"fieldname": "video_call_link",
"fieldtype": "Data",
"label": "Video Call Link"
},
{
"fieldname": "batch_schedule_section",
"fieldtype": "Section Break",
"label": "Batch Schedule"
},
{
"fieldname": "column_break_10",
"fieldtype": "Column Break"
}
],
"index_web_pages_for_search": 1,
@@ -126,7 +151,7 @@
"link_fieldname": "batch"
}
],
"modified": "2021-05-06 05:46:38.469120",
"modified": "2021-05-25 18:28:01.718521",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Batch",

View File

@@ -17,7 +17,7 @@ class LMSBatch(Document):
def validate_if_mentor(self):
course = frappe.get_doc("LMS Course", self.course)
if not course.is_mentor(frappe.session.user):
if not course.is_mentor(frappe.session.user) and self.is_new():
frappe.throw(_("You are not a mentor of the course {0}").format(course.title))
def after_insert(self):
@@ -69,6 +69,29 @@ class LMSBatch(Document):
message.is_author = True
return messages
def get_membership(self, email):
"""Returns the membership document of given user.
"""
name = frappe.get_value(
doctype="LMS Batch Membership",
filters={
"batch": self.name,
"member": email
},
fieldname="name")
return frappe.get_doc("LMS Batch Membership", name)
def get_current_lesson(self, user):
"""Returns the name of the current lesson for the given user.
"""
membership = self.get_membership(user)
return membership and membership.current_lesson
def get_learn_url(self, lesson_number):
if not lesson_number:
return
return f"/courses/{self.course}/{self.name}/learn/{lesson_number}"
@frappe.whitelist()
def save_message(message, batch):
doc = frappe.get_doc({

View File

@@ -2,7 +2,13 @@
// For license information, please see license.txt
frappe.ui.form.on('LMS Batch Membership', {
// refresh: function(frm) {
// }
onload: function(frm) {
frm.set_query('member', function(doc) {
return {
filters: {
"ignore_user_type": 1,
}
};
});
},
});

View File

@@ -8,11 +8,12 @@
"batch",
"member",
"member_name",
"member_email",
"member_username",
"column_break_3",
"course",
"member_type",
"role"
"role",
"current_lesson"
],
"fields": [
{
@@ -59,15 +60,6 @@
"fieldname": "column_break_3",
"fieldtype": "Column Break"
},
{
"fetch_from": "member.email",
"fieldname": "member_email",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Member Email",
"read_only": 1,
"read_only_depends_on": "member.email"
},
{
"fetch_from": "batch.course",
"fieldname": "course",
@@ -75,11 +67,24 @@
"in_list_view": 1,
"label": "Course",
"read_only": 1
},
{
"fieldname": "current_lesson",
"fieldtype": "Link",
"label": "Current Lesson",
"options": "Lesson"
},
{
"fetch_from": "member.username",
"fieldname": "member_username",
"fieldtype": "Data",
"label": "Memeber Username",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-05-24 09:32:04.128620",
"modified": "2021-05-24 12:40:57.125694",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Batch Membership",

View File

@@ -17,7 +17,8 @@ class LMSBatchMembership(Document):
previous_membership = frappe.db.get_value("LMS Batch Membership",
filters={
"member": self.member,
"batch": self.batch, "name": ["!=", self.name]
"batch": self.batch,
"name": ["!=", self.name]
},
fieldname=["member_type","member"],
as_dict=1)
@@ -30,7 +31,8 @@ class LMSBatchMembership(Document):
course = frappe.db.get_value("LMS Batch", self.batch, "course")
previous_membership = frappe.get_all("LMS Batch Membership",
filters={
"member": self.member
"member": self.member,
"name": ["!=", self.name]
},
fields=["batch", "member_type", "name"]
)

View File

@@ -3,8 +3,76 @@
# See license.txt
from __future__ import unicode_literals
# import frappe
import frappe
import unittest
class TestLMSBatchMembership(unittest.TestCase):
pass
def setUp(self):
frappe.db.sql("DELETE FROM `tabLMS Batch Membership`")
frappe.db.sql("DELETE FROM `tabLMS Batch`")
frappe.db.sql('delete from `tabLMS Course Mentor Mapping`')
frappe.db.sql("DELETE FROM `tabLMS Course`")
frappe.db.sql("DELETE FROM `tabUser` where email like '%@test.com'")
def new_course_batch(self):
course = frappe.get_doc({
"doctype": "LMS Course",
"name": "test-course",
"title": "Test Course",
"short_code": "XX"
})
course.insert()
self.new_user("mentor@test.com", "Test Mentor")
# without this, the creating batch will fail
course.add_mentor("mentor@test.com")
frappe.session.user = "mentor@test.com"
batch = frappe.get_doc({
"doctype": "LMS Batch",
"name": "test-batch",
"title": "Test Batch",
"course": course.name
})
batch.insert(ignore_permissions=True)
frappe.session.user = "Administrator"
return course, batch
def new_user(self, email="test@test.com", full_name="Test User"):
user = frappe.get_doc({
"doctype": "User",
"name": email,
"email": email,
"first_name": full_name,
})
user.insert()
return user
def add_membership(self, batch_name, member_name, member_type="Student"):
doc = frappe.get_doc({
"doctype": "LMS Batch Membership",
"batch": batch_name,
"member": member_name,
"member_type": member_type
})
doc.insert()
return doc
def test_membership(self):
course, batch = self.new_course_batch()
member = self.new_user("test01@test.com")
membership = self.add_membership(batch.name, member.name)
assert membership.course == course.name
assert membership.member_name == member.full_name
def test_membership_change_role(self):
course, batch = self.new_course_batch()
member = self.new_user("test01@test.com")
membership = self.add_membership(batch.name, member.name)
# it should be possible to change role
membership.role = "Admin"
membership.save()

View File

@@ -150,6 +150,13 @@ class LMSCourse(Document):
"name")
return lesson_name and frappe.get_doc("Lesson", lesson_name)
def get_lesson_index(self, lesson_name):
"""Returns the {chapter_index}.{lesson_index} for the lesson.
"""
lesson = frappe.get_doc("Lesson", lesson_name)
chapter = frappe.get_doc("Chapter", lesson.chapter)
return f"{chapter.index_}.{lesson.index_}"
def get_outline(self):
return CourseOutline(self)

View File

@@ -18,7 +18,7 @@ class LMSMessage(Document):
template = self.get_message_template()
message = frappe._dict({
"author_name": self.author_name,
"message_time": frappe.utils.pretty_date(self.creation),
"message_time": frappe.utils.format_datetime(self.creation, "dd-mm-yyyy HH:mm"),
"message": frappe.utils.md_to_html(self.message)
})
@@ -32,14 +32,16 @@ class LMSMessage(Document):
template = frappe.render_template(template, {{
"message": message
}})
$(".message-section").append(template);
$(".messages").append(template);
var message_element = document.getElementsByClassName("messages")[0]
message_element.scrollTo(0, message_element.scrollHeight);
""".format(template, message, self.owner)
frappe.publish_realtime(event="eval_js", message=js, after_commit=True)
def get_message_template(self):
return """
<div class="discussion {% if message.is_author %} is-author {% endif %}">
<li class="{% if message.is_author %} ours {% endif %}">
<div class="d-flex justify-content-between">
<div class="font-weight-bold">
{{ message.author_name }}
@@ -51,7 +53,7 @@ class LMSMessage(Document):
<div class="mt-5">
{{ message.message }}
</div>
</div>
</li>
"""
def send_email(self):