mirror of
https://github.com/frappe/lms.git
synced 2026-05-02 13:39:31 +03:00
@@ -84,16 +84,10 @@
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {
|
||||
Dialog,
|
||||
createResource,
|
||||
Tooltip,
|
||||
FormControl,
|
||||
Autocomplete,
|
||||
toast,
|
||||
} from 'frappe-ui'
|
||||
import { Dialog, createResource, Tooltip, FormControl, toast } from 'frappe-ui'
|
||||
import { reactive, inject, onMounted } from 'vue'
|
||||
import { getTimezones, getUserTimezone } from '@/utils/'
|
||||
import Autocomplete from '@/components/Controls/Autocomplete.vue'
|
||||
|
||||
const liveClasses = defineModel('reloadLiveClasses')
|
||||
const show = defineModel()
|
||||
|
||||
@@ -202,7 +202,7 @@ const openEvalCall = (evl) => {
|
||||
|
||||
const evaluationCourses = computed(() => {
|
||||
return props.courses.filter((course) => {
|
||||
return course.evaluator != ''
|
||||
return course.evaluator && course.evaluator != ''
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -400,7 +400,7 @@ const sidebarStore = useSidebar()
|
||||
const plyrSources = ref([])
|
||||
const showInlineMenu = ref(false)
|
||||
const currentTab = ref('Notes')
|
||||
let timerInterval
|
||||
let timerInterval = null
|
||||
|
||||
const tabs = ref([
|
||||
{
|
||||
@@ -742,7 +742,7 @@ const updateVideoTime = (video) => {
|
||||
|
||||
const startTimer = () => {
|
||||
if (!lesson.data?.membership) return
|
||||
let timerInterval = setInterval(() => {
|
||||
timerInterval = setInterval(() => {
|
||||
timer.value++
|
||||
if (timer.value == 30) {
|
||||
clearInterval(timerInterval)
|
||||
|
||||
+2
-2
@@ -395,7 +395,7 @@ def get_all_users():
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def get_sidebar_settings():
|
||||
lms_settings = frappe.get_single("LMS Settings")
|
||||
if not lms_settings.allow_guest_access:
|
||||
if frappe.session.user == "Guest" and not lms_settings.allow_guest_access:
|
||||
return []
|
||||
|
||||
sidebar_items = frappe._dict()
|
||||
@@ -475,7 +475,7 @@ def delete_lesson(lesson: str, chapter: str):
|
||||
update_index(lessons, chapter)
|
||||
|
||||
frappe.db.delete("LMS Course Progress", {"lesson": lesson})
|
||||
frappe.db.delete("Course Lesson", lesson)
|
||||
frappe.delete_doc("Course Lesson", lesson)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
|
||||
@@ -4,25 +4,12 @@
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
from lms.lms.utils import get_course_progress, get_lesson_count
|
||||
from lms.lms.utils import get_lesson_count
|
||||
|
||||
|
||||
class CourseChapter(Document):
|
||||
def on_update(self):
|
||||
self.recalculate_course_progress()
|
||||
self.update_lesson_count()
|
||||
frappe.enqueue(method=self.recalculate_course_progress, queue="short", timeout=300, is_async=True)
|
||||
|
||||
def recalculate_course_progress(self):
|
||||
"""Recalculate course progress if a new lesson is added or removed"""
|
||||
previous_lessons = self.get_doc_before_save() and self.get_doc_before_save().as_dict().lessons
|
||||
current_lessons = self.lessons
|
||||
|
||||
if previous_lessons and previous_lessons != current_lessons:
|
||||
enrolled_members = frappe.get_all("LMS Enrollment", {"course": self.course}, ["member", "name"])
|
||||
for enrollment in enrolled_members:
|
||||
new_progress = get_course_progress(self.course, enrollment.member)
|
||||
frappe.db.set_value("LMS Enrollment", enrollment.name, "progress", new_progress)
|
||||
|
||||
def update_lesson_count(self):
|
||||
"""Update lesson count in the course"""
|
||||
|
||||
@@ -9,15 +9,39 @@ from frappe.model.document import Document
|
||||
from frappe.realtime import get_website_room
|
||||
from frappe.utils.telemetry import capture
|
||||
|
||||
from lms.lms.utils import get_course_progress
|
||||
from lms.lms.utils import get_course_progress, recalculate_course_progress
|
||||
|
||||
from ...md import find_macros
|
||||
|
||||
|
||||
class CourseLesson(Document):
|
||||
def after_insert(self):
|
||||
self.validate_progress_recalculation()
|
||||
|
||||
def after_delete(self):
|
||||
self.validate_progress_recalculation()
|
||||
|
||||
def on_update(self):
|
||||
self.validate_quiz_id()
|
||||
|
||||
def validate_progress_recalculation(self):
|
||||
if not self.course or not self.chapter:
|
||||
return
|
||||
|
||||
enrollments = frappe.db.get_all(
|
||||
"LMS Enrollment",
|
||||
filters={"course": self.course},
|
||||
fields=["name", "member"],
|
||||
)
|
||||
if not len(enrollments):
|
||||
return
|
||||
|
||||
frappe.enqueue(method=self.recalculate_progress, queue="long", is_async=True, enrollments=enrollments)
|
||||
|
||||
def recalculate_progress(self, enrollments):
|
||||
for enrollment in enrollments:
|
||||
recalculate_course_progress(self.course, enrollment.member)
|
||||
|
||||
def validate_quiz_id(self):
|
||||
if self.quiz_id and not frappe.db.exists("LMS Quiz", self.quiz_id):
|
||||
frappe.throw(_("Invalid Quiz ID"))
|
||||
|
||||
@@ -13,6 +13,7 @@ from frappe.utils import (
|
||||
format_time,
|
||||
get_datetime,
|
||||
get_fullname,
|
||||
get_system_timezone,
|
||||
get_time,
|
||||
getdate,
|
||||
nowtime,
|
||||
@@ -118,16 +119,7 @@ class LMSCertificateRequest(Document):
|
||||
def validate_timezone(self):
|
||||
if self.timezone:
|
||||
return
|
||||
if self.batch_name:
|
||||
timezone = frappe.db.get_value("LMS Batch", self.batch_name, "timezone")
|
||||
if timezone:
|
||||
self.timezone = timezone
|
||||
return
|
||||
if self.course:
|
||||
timezone = frappe.db.get_value("LMS Course", self.course, "timezone")
|
||||
if timezone:
|
||||
self.timezone = timezone
|
||||
return
|
||||
self.timezone = get_system_timezone()
|
||||
|
||||
def send_notification(self):
|
||||
outgoing_email_account = frappe.get_cached_value(
|
||||
|
||||
@@ -4,20 +4,9 @@
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
from lms.lms.doctype.lms_enrollment.lms_enrollment import update_program_progress
|
||||
from lms.lms.utils import get_course_progress
|
||||
from lms.lms.utils import recalculate_course_progress
|
||||
|
||||
|
||||
class LMSCourseProgress(Document):
|
||||
def after_delete(self):
|
||||
progress = get_course_progress(self.course, self.member)
|
||||
membership = frappe.db.get_value(
|
||||
"LMS Enrollment",
|
||||
{
|
||||
"member": self.member,
|
||||
"course": self.course,
|
||||
},
|
||||
"name",
|
||||
)
|
||||
frappe.db.set_value("LMS Enrollment", membership, "progress", progress)
|
||||
update_program_progress(self.member)
|
||||
recalculate_course_progress(self.course, self.member)
|
||||
|
||||
@@ -28,6 +28,7 @@ from frappe.utils import (
|
||||
from pypika import Case
|
||||
from pypika import functions as fn
|
||||
|
||||
from lms.lms.doctype.lms_enrollment.lms_enrollment import update_program_progress
|
||||
from lms.lms.md import find_macros
|
||||
|
||||
RE_SLUG_NOTALLOWED = re.compile("[^a-z0-9]+")
|
||||
@@ -2312,3 +2313,17 @@ def has_lms_role():
|
||||
lms_roles = set(LMS_ROLES)
|
||||
user_roles = set(roles)
|
||||
return not lms_roles.isdisjoint(user_roles)
|
||||
|
||||
|
||||
def recalculate_course_progress(course: str, member: str):
|
||||
progress = get_course_progress(course, member)
|
||||
membership = frappe.db.get_value(
|
||||
"LMS Enrollment",
|
||||
{
|
||||
"member": member,
|
||||
"course": course,
|
||||
},
|
||||
"name",
|
||||
)
|
||||
frappe.db.set_value("LMS Enrollment", membership, "progress", progress)
|
||||
update_program_progress(member)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<p> {{ _("Hey {0}").format(member_name) }} </p>
|
||||
<br>
|
||||
<p> {{ _('Your evaluation for the course {0} has been scheduled on {1} at {2} {3}.').format(course, date, start_time, timezone) }}</p>
|
||||
<p> {{ _('Your evaluation for the course {0} has been scheduled on {1} at {2} ({3} time).').format(course, date, start_time, timezone) }}</p>
|
||||
<br>
|
||||
<p> {{ _("Your evaluator is {0}").format(evaluator) }} </p>
|
||||
<br>
|
||||
|
||||
Reference in New Issue
Block a user