Merge branch 'main' of https://github.com/frappe/community into miscellaneous-fixes
This commit is contained in:
@@ -11,54 +11,71 @@ import random
|
||||
|
||||
class CommunityMember(Document):
|
||||
|
||||
def validate(self):
|
||||
self.validate_username()
|
||||
self.abbr = ("").join([ s[0] for s in self.full_name.split() ])
|
||||
if self.route != self.username:
|
||||
self.route = self.username
|
||||
|
||||
def validate_username(self):
|
||||
if not self.username:
|
||||
self.username = create_username_from_email(self.email)
|
||||
def validate(self):
|
||||
self.validate_username()
|
||||
self.abbr = ("").join([ s[0] for s in self.full_name.split() ])
|
||||
if self.route != self.username:
|
||||
self.route = self.username
|
||||
|
||||
if self.username:
|
||||
if len(self.username) < 4:
|
||||
frappe.throw(_("Username must be atleast 4 characters long."))
|
||||
if not re.match("^[A-Za-z0-9_]*$", self.username):
|
||||
frappe.throw(_("Username can only contain alphabets, numbers and underscore."))
|
||||
self.username = self.username.lower()
|
||||
def validate_username(self):
|
||||
if not self.username:
|
||||
self.username = create_username_from_email(self.email)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<CommunityMember: {self.email}>"
|
||||
if self.username:
|
||||
if len(self.username) < 4:
|
||||
frappe.throw(_("Username must be atleast 4 characters long."))
|
||||
if not re.match("^[A-Za-z0-9_]*$", self.username):
|
||||
frappe.throw(_("Username can only contain alphabets, numbers and underscore."))
|
||||
self.username = self.username.lower()
|
||||
|
||||
def get_course_count(self) -> int:
|
||||
"""Returns the number of courses authored by this user.
|
||||
"""
|
||||
return frappe.db.count(
|
||||
'LMS Course', {
|
||||
'owner': self.email
|
||||
})
|
||||
|
||||
def get_batch_count(self) -> int:
|
||||
"""Returns the number of batches authored by this user.
|
||||
"""
|
||||
return frappe.db.count(
|
||||
'LMS Batch Membership', {
|
||||
'member': self.name,
|
||||
'member_role': 'Mentor'
|
||||
})
|
||||
|
||||
def __repr__(self):
|
||||
return f"<CommunityMember: {self.email}>"
|
||||
|
||||
def create_member_from_user(doc, method):
|
||||
username = doc.username
|
||||
username = doc.username
|
||||
|
||||
if ( doc.username and username_exists(doc.username)) or not doc.username:
|
||||
username = create_username_from_email(doc.email)
|
||||
if ( doc.username and username_exists(doc.username)) or not doc.username:
|
||||
username = create_username_from_email(doc.email)
|
||||
|
||||
elif len(doc.username) < 4:
|
||||
username = adjust_username(doc.username)
|
||||
elif len(doc.username) < 4:
|
||||
username = adjust_username(doc.username)
|
||||
|
||||
if username_exists(username):
|
||||
username = username + str(random.randint(0,9))
|
||||
if username_exists(username):
|
||||
username = username + str(random.randint(0,9))
|
||||
|
||||
member = frappe.get_doc({
|
||||
"doctype": "Community Member",
|
||||
"full_name": doc.full_name,
|
||||
"username": username,
|
||||
"email": doc.email,
|
||||
"route": doc.username,
|
||||
"owner": doc.email
|
||||
})
|
||||
member.save(ignore_permissions=True)
|
||||
member = frappe.get_doc({
|
||||
"doctype": "Community Member",
|
||||
"full_name": doc.full_name,
|
||||
"username": username,
|
||||
"email": doc.email,
|
||||
"route": doc.username,
|
||||
"owner": doc.email
|
||||
})
|
||||
member.save(ignore_permissions=True)
|
||||
|
||||
def username_exists(username):
|
||||
return frappe.db.exists("Community Member", dict(username=username))
|
||||
return frappe.db.exists("Community Member", dict(username=username))
|
||||
|
||||
def create_username_from_email(email):
|
||||
string = email.split("@")[0]
|
||||
return ''.join(e for e in string if e.isalnum())
|
||||
string = email.split("@")[0]
|
||||
return ''.join(e for e in string if e.isalnum())
|
||||
|
||||
def adjust_username(username):
|
||||
return username.ljust(4, str(random.randint(0,9)))
|
||||
return username.ljust(4, str(random.randint(0,9)))
|
||||
|
||||
0
community/lms/doctype/chapter/__init__.py
Normal file
0
community/lms/doctype/chapter/__init__.py
Normal file
8
community/lms/doctype/chapter/chapter.js
Normal file
8
community/lms/doctype/chapter/chapter.js
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2021, FOSS United and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Chapter', {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
||||
72
community/lms/doctype/chapter/chapter.json
Normal file
72
community/lms/doctype/chapter/chapter.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "format:{####} {title}",
|
||||
"creation": "2021-05-03 05:49:08.383057",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"course",
|
||||
"title",
|
||||
"description",
|
||||
"locked"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "title",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Title"
|
||||
},
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Markdown Editor",
|
||||
"label": "Description"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "locked",
|
||||
"fieldtype": "Check",
|
||||
"label": "Locked"
|
||||
},
|
||||
{
|
||||
"fieldname": "course",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Course",
|
||||
"options": "LMS Course"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [
|
||||
{
|
||||
"group": "Lessons",
|
||||
"link_doctype": "Lesson",
|
||||
"link_fieldname": "chapter"
|
||||
}
|
||||
],
|
||||
"modified": "2021-05-03 06:52:10.894328",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "Chapter",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"search_fields": "title",
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "title",
|
||||
"track_changes": 1
|
||||
}
|
||||
14
community/lms/doctype/chapter/chapter.py
Normal file
14
community/lms/doctype/chapter/chapter.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021, FOSS United and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class Chapter(Document):
|
||||
def get_lessons(self):
|
||||
rows = frappe.db.get_all("Lesson",
|
||||
filters={"chapter": self.name},
|
||||
fields='*')
|
||||
return [frappe.get_doc(dict(row, doctype='Lesson')) for row in rows]
|
||||
10
community/lms/doctype/chapter/test_chapter.py
Normal file
10
community/lms/doctype/chapter/test_chapter.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021, FOSS United and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestChapter(unittest.TestCase):
|
||||
pass
|
||||
0
community/lms/doctype/lesson/__init__.py
Normal file
0
community/lms/doctype/lesson/__init__.py
Normal file
8
community/lms/doctype/lesson/lesson.js
Normal file
8
community/lms/doctype/lesson/lesson.js
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2021, FOSS United and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Lesson', {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
||||
60
community/lms/doctype/lesson/lesson.json
Normal file
60
community/lms/doctype/lesson/lesson.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "format:{####} {title}",
|
||||
"creation": "2021-05-03 06:21:12.995987",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"chapter",
|
||||
"lesson_type",
|
||||
"title"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "chapter",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Chapter",
|
||||
"options": "Chapter"
|
||||
},
|
||||
{
|
||||
"default": "Video",
|
||||
"fieldname": "lesson_type",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Lesson Type",
|
||||
"options": "Video\nText\nQuiz"
|
||||
},
|
||||
{
|
||||
"fieldname": "title",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Title"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-05-03 06:51:43.588969",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "Lesson",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
10
community/lms/doctype/lesson/lesson.py
Normal file
10
community/lms/doctype/lesson/lesson.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021, FOSS United and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class Lesson(Document):
|
||||
pass
|
||||
10
community/lms/doctype/lesson/test_lesson.py
Normal file
10
community/lms/doctype/lesson/test_lesson.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021, FOSS United and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestLesson(unittest.TestCase):
|
||||
pass
|
||||
@@ -74,8 +74,8 @@
|
||||
"is_published_field": "is_published",
|
||||
"links": [
|
||||
{
|
||||
"group": "Topics",
|
||||
"link_doctype": "LMS Topic",
|
||||
"group": "Chapters",
|
||||
"link_doctype": "Chapter",
|
||||
"link_fieldname": "course"
|
||||
},
|
||||
{
|
||||
@@ -89,7 +89,7 @@
|
||||
"link_fieldname": "course"
|
||||
}
|
||||
],
|
||||
"modified": "2021-04-21 14:45:41.658056",
|
||||
"modified": "2021-05-03 05:52:30.396824",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Course",
|
||||
|
||||
@@ -8,6 +8,18 @@ from frappe.model.document import Document
|
||||
from ...utils import slugify
|
||||
|
||||
class LMSCourse(Document):
|
||||
@staticmethod
|
||||
def find(slug):
|
||||
"""Returns the course with specified slug.
|
||||
"""
|
||||
return find("LMS Course", is_published=True, slug=slug)
|
||||
|
||||
@staticmethod
|
||||
def find_all():
|
||||
"""Returns all published courses.
|
||||
"""
|
||||
return find_all("LMS Course", is_published=True)
|
||||
|
||||
def before_save(self):
|
||||
if not self.slug:
|
||||
self.slug = self.generate_slug(title=self.title)
|
||||
@@ -50,7 +62,7 @@ class LMSCourse(Document):
|
||||
"""Returns the name of Community Member document for a give user.
|
||||
"""
|
||||
try:
|
||||
return frappe.db.get_value("Community Member", {"email": email}, ["name"])
|
||||
return frappe.db.get_value("Community Member", {"email": email}, "name")
|
||||
except frappe.DoesNotExistError:
|
||||
return None
|
||||
|
||||
@@ -85,18 +97,65 @@ class LMSCourse(Document):
|
||||
for mentor in mentors:
|
||||
member = frappe.get_doc("Community Member", mentor.mentor)
|
||||
# TODO: change this to count query
|
||||
member.batch_count = len(frappe.get_all("LMS Batch Membership", {"member": member.name, "member_type": "Mentor"}))
|
||||
member.batch_count = len(frappe.get_all("LMS Batch Membership", {"member": member, "member_type": "Mentor"}))
|
||||
course_mentors.append(member)
|
||||
return course_mentors
|
||||
|
||||
def get_instructor(self):
|
||||
return frappe.get_doc("User", self.owner)
|
||||
|
||||
@staticmethod
|
||||
def find_all():
|
||||
"""Returns all published courses.
|
||||
def is_mentor(self, email):
|
||||
"""Checks if given user is a mentor for this course.
|
||||
"""
|
||||
rows = frappe.db.get_all("LMS Course",
|
||||
filters={"is_published": True},
|
||||
fields='*')
|
||||
return [frappe.get_doc(dict(row, doctype='LMS Course')) for row in rows]
|
||||
if not email:
|
||||
return False
|
||||
member = self.get_community_member(email)
|
||||
return frappe.db.exists({
|
||||
'doctype': 'LMS Course Mentor Mapping',
|
||||
"course": self.name,
|
||||
"member": member
|
||||
})
|
||||
|
||||
def get_instructor(self):
|
||||
member_name = self.get_community_member(self.owner)
|
||||
return frappe.get_doc("Community Member", member_name)
|
||||
|
||||
def get_chapters(self):
|
||||
"""Returns all chapters of this course.
|
||||
"""
|
||||
# TODO: chapters should have a way to specify the order
|
||||
return find_all("Chapter", course=self.name, order_by="creation")
|
||||
|
||||
def get_batches(self, mentor=None):
|
||||
batches = find_all("LMS Batch", course=self.name)
|
||||
if mentor:
|
||||
# TODO: optimize this
|
||||
member = self.get_community_member(email=mentor)
|
||||
memberships = frappe.db.get_all(
|
||||
"LMS Batch Membership",
|
||||
{"member": member},
|
||||
["name"], as_dict=1)
|
||||
batch_names = {m.batch for m in memberships}
|
||||
return [b for b in batches if b.name in batch_names]
|
||||
|
||||
def get_upcoming_batches(self):
|
||||
now = frappe.utils.nowdate()
|
||||
return find_all("LMS Batch",
|
||||
course=self.name,
|
||||
start_date=[">", now])
|
||||
|
||||
def find_all(doctype, order_by=None, **filters):
|
||||
"""Queries the database for documents of a doctype matching given filters.
|
||||
"""
|
||||
rows = frappe.db.get_all(doctype,
|
||||
filters=filters,
|
||||
fields='*',
|
||||
order_by=order_by)
|
||||
return [frappe.get_doc(dict(row, doctype=doctype)) for row in rows]
|
||||
|
||||
def find(doctype, **filters):
|
||||
"""Queries the database for a document of given doctype matching given filters.
|
||||
"""
|
||||
rows = frappe.db.get_all(doctype,
|
||||
filters=filters,
|
||||
fields='*')
|
||||
if rows:
|
||||
row = rows[0]
|
||||
return frappe.get_doc(dict(row, doctype=doctype))
|
||||
|
||||
15
community/lms/widgets/ChapterTeaser.html
Normal file
15
community/lms/widgets/ChapterTeaser.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<div class="chapter-teaser">
|
||||
<div class="teaser-body">
|
||||
<h3 class="chapter-title">{{ chapter.title }}</h3>
|
||||
<div class="chapter-description">
|
||||
{{ chapter.description or "" }}
|
||||
</div>
|
||||
<div class="chapter-lessons">
|
||||
{% for lesson in chapter.get_lessons() %}
|
||||
<div class="lesson-teaser">
|
||||
{{lesson.title}}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -4,6 +4,13 @@
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #ddd;
|
||||
|
||||
.teaser-body {
|
||||
padding: 20px;
|
||||
}
|
||||
.teaser-footer {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.sketch-teaser {
|
||||
@@ -67,6 +74,17 @@ section.lightgray {
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
.chapter-teaser {
|
||||
.teaser();
|
||||
color: #444;
|
||||
margin: 20px 0px;
|
||||
|
||||
h3, h4 {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.field-width {
|
||||
width: 40%;
|
||||
display: inline-block;
|
||||
|
||||
@@ -17,18 +17,18 @@
|
||||
<div class="col-lg-9 col-md-12">
|
||||
<div class="course-details">
|
||||
{{ CourseDescription(course) }}
|
||||
{{ BatchSection(course, is_mentor, upcoming_batches, mentor_batches) }}
|
||||
{{ BatchSection(course) }}
|
||||
{{ CourseOutline(course) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3 col-md-12">
|
||||
<div class="sidebar">
|
||||
{{ InstructorsSection(instructor) }}
|
||||
{{ InstructorsSection(course.get_instructor()) }}
|
||||
</div>
|
||||
|
||||
<div class="sidebar">
|
||||
{{ MentorsSection(mentors, is_mentor) }}
|
||||
{{ MentorsSection(course.get_mentors(), course.is_mentor(frappe.session.user)) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -57,11 +57,11 @@
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro BatchSection(course, is_mentor, upcoming_batches, mentor_batches) %}
|
||||
{% if is_mentor %}
|
||||
{{ BatchSectionForMentors(course, mentor_batches) }}
|
||||
{% macro BatchSection(course) %}
|
||||
{% if course.is_mentor(frappe.session.user) %}
|
||||
{{ BatchSectionForMentors(course, course.get_batches(mentor=frappe.session.user)) }}
|
||||
{% else %}
|
||||
{{ BatchSectionForStudents(course, upcoming_batches) }}
|
||||
{{ BatchSectionForStudents(course, course.get_upcoming_batches()) }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
@@ -131,25 +131,9 @@
|
||||
{% endmacro %}
|
||||
|
||||
{% macro CourseOutline(course) %}
|
||||
<h2>Course Outline</h2>
|
||||
<h2>Course Outline</h2>
|
||||
|
||||
{% for chapter in course.topics %}
|
||||
<div class="chapter-plan">
|
||||
<h3><span class="chapter-number">{{loop.index}}</span> {{chapter.title}}</h3>
|
||||
<div class="chapter-description">
|
||||
{{chapter.preview | markdown}}
|
||||
</div>
|
||||
|
||||
{#
|
||||
<div class="lessons">
|
||||
{% for lesson in chapter.lessons %}
|
||||
<div class="lesson">
|
||||
<span class="lesson-type"><i class="{{lesson.icon}}"></i></span>
|
||||
<span class="lesson-title">{{lesson.title}}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
#}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for chapter in course.get_chapters() %}
|
||||
{{ widgets.ChapterTeaser(chapter=chapter)}}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
@@ -1,101 +1,21 @@
|
||||
import frappe
|
||||
from community.www.courses.utils import get_instructor
|
||||
from frappe.utils import nowdate, getdate
|
||||
from community.lms.models import Course
|
||||
|
||||
def get_context(context):
|
||||
context.no_cache = 1
|
||||
|
||||
|
||||
try:
|
||||
course_id = frappe.form_dict["course"]
|
||||
course_slug = frappe.form_dict["course"]
|
||||
except KeyError:
|
||||
frappe.local.flags.redirect_location = "/courses"
|
||||
raise frappe.Redirect
|
||||
|
||||
context.course = get_course(course_id)
|
||||
context.batches = get_course_batches(context.course.name)
|
||||
context.is_mentor = is_mentor(context.course.name)
|
||||
context.memberships = get_membership(context.batches)
|
||||
if len(context.memberships) and not context.is_mentor:
|
||||
frappe.local.flags.redirect_location = "/courses/" + course_id + "/" + context.memberships[0].code + "/learn"
|
||||
|
||||
course = Course.find(course_slug)
|
||||
if course is None:
|
||||
frappe.local.flags.redirect_location = "/courses"
|
||||
raise frappe.Redirect
|
||||
context.upcoming_batches = get_upcoming_batches(context.course.name)
|
||||
context.instructor = get_instructor(context.course.owner)
|
||||
context.mentors = get_mentors(context.course.name)
|
||||
|
||||
if context.is_mentor:
|
||||
context.mentor_batches = get_mentor_batches(context.memberships) # Your Bacthes for mentor
|
||||
|
||||
def get_course(slug):
|
||||
course = frappe.db.get_value("LMS Course", {"slug": slug},
|
||||
["name", "slug", "title", "description", "short_introduction", "video_link", "owner"], as_dict=1)
|
||||
|
||||
course["topics"] = frappe.db.get_all("LMS Topic",
|
||||
filters={
|
||||
"course": course["name"]
|
||||
},
|
||||
fields=["name", "slug", "title", "preview"],
|
||||
order_by="creation"
|
||||
)
|
||||
return course
|
||||
|
||||
def get_upcoming_batches(course):
|
||||
batches = frappe.get_all("LMS Batch", {"course": course, "start_date": [">", nowdate()]}, ["start_date", "start_time", "end_time", "sessions_on", "name"])
|
||||
batches = get_batch_mentors(batches)
|
||||
return batches
|
||||
|
||||
def get_batch_mentors(batches):
|
||||
for batch in batches:
|
||||
batch.mentors = []
|
||||
mentors = frappe.get_all("LMS Batch Membership", {"batch": batch.name, "member_type": "Mentor"}, ["member"])
|
||||
for mentor in mentors:
|
||||
member = frappe.db.get_value("Community Member", mentor.member, ["full_name", "photo", "abbr"], as_dict=1)
|
||||
batch.mentors.append(member)
|
||||
return batches
|
||||
|
||||
def get_membership(batches):
|
||||
memberships = []
|
||||
member = frappe.db.get_value("Community Member", {"email": frappe.session.user}, "name")
|
||||
for batch in batches:
|
||||
membership = frappe.db.get_value("LMS Batch Membership", {"member": member, "batch": batch.name}, ["batch", "member", "member_type"], as_dict=1)
|
||||
if membership:
|
||||
membership.code = batch.code
|
||||
memberships.append(membership)
|
||||
return memberships
|
||||
|
||||
def get_mentors(course):
|
||||
course_mentors = []
|
||||
mentors = frappe.get_all("LMS Course Mentor Mapping", {"course": course}, ["mentor"])
|
||||
for mentor in mentors:
|
||||
member = frappe.get_doc("Community Member", mentor.mentor)
|
||||
member.batch_count = len(frappe.get_all("LMS Batch Membership", {"member": member.name, "member_type": "Mentor"}))
|
||||
course_mentors.append(member)
|
||||
return course_mentors
|
||||
|
||||
def get_course_batches(course):
|
||||
return frappe.get_all("LMS Batch", {"course": course}, ["name", "code"])
|
||||
|
||||
def get_mentor_batches(memberships):
|
||||
mentor_batches = []
|
||||
memberships_as_mentor = list(filter(lambda x: x.member_type == "Mentor", memberships))
|
||||
for membership in memberships_as_mentor:
|
||||
batch = frappe.get_doc("LMS Batch", membership.batch)
|
||||
mentor_batches.append(batch)
|
||||
for batch in mentor_batches:
|
||||
if getdate(batch.start_date) < getdate():
|
||||
batch.status = "active"
|
||||
batch.badge_class = "green_badge"
|
||||
else:
|
||||
batch.status = "scheduled"
|
||||
batch.badge_class = "yellow_badge"
|
||||
mentor_batches = get_batch_mentors(mentor_batches)
|
||||
return mentor_batches
|
||||
|
||||
def is_mentor(course):
|
||||
try:
|
||||
member = frappe.db.get_value("Community Member", {"email": frappe.session.user}, ["name"])
|
||||
except frappe.DoesNotExistError:
|
||||
return False
|
||||
mapping = frappe.get_all("LMS Course Mentor Mapping", {"course": course, "mentor": member})
|
||||
if len(mapping):
|
||||
return True
|
||||
context.course = course
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<h3>Instructor</h3>
|
||||
<div class="instructor">
|
||||
<div class="instructor-title">{{instructor.full_name}}</div>
|
||||
<div class="instructor-subtitle">Created {{instructor.course_count}} courses</div>
|
||||
<div class="instructor-subtitle">Created {{instructor.get_course_count()}} courses</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
{% for m in mentors %}
|
||||
<div class="instructor">
|
||||
<div class="instructor-title">{{m.full_name}}</div>
|
||||
<div class="instructor-subtitle">Mentored {{m.batch_count}} batches</div>
|
||||
<div class="instructor-subtitle">Mentored {{m.get_batch_count()}} batches</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if not is_mentor %}
|
||||
@@ -29,4 +29,4 @@
|
||||
<h3>{{course_name}}</h3>
|
||||
<div class="text-muted">{{member_count}} members</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
{% endmacro %}
|
||||
|
||||
Reference in New Issue
Block a user