feat: cancel evaluations

This commit is contained in:
Jannat Patel
2025-02-19 22:29:24 +05:30
parent db4c7424b3
commit f9fd36f77e
6 changed files with 153 additions and 11 deletions

View File

@@ -9,7 +9,7 @@
</Button>
</div>
<div v-if="upcoming_evals.data?.length">
<div class="grid grid-cols-2 gap-4">
<div class="grid grid-cols-3 gap-4">
<div v-for="evl in upcoming_evals.data">
<div class="border rounded-md p-3">
<div class="font-semibold mb-3">
@@ -28,11 +28,33 @@
</span>
</div>
<div class="flex items-center">
<UserCog2 class="w-4 h-4 stroke-1.5" />
<span class="ml-2 font-medium">
<GraduationCap class="w-4 h-4 stroke-1.5" />
<span class="ml-2">
{{ evl.evaluator_name }}
</span>
</div>
<div class="flex items-center justify-between space-x-2 mt-4">
<Button
v-if="evl.google_meet_link"
@click="openEvalCall(evl)"
class="w-full"
>
<template #prefix>
<HeadsetIcon class="w-4 h-4 stroke-1.5" />
</template>
{{ __('Join Call') }}
</Button>
<Button
v-if="evl.date > dayjs().format()"
@click="cancelEvaluation(evl)"
class="w-full"
>
<template #prefix>
<Ban class="w-4 h-4 stroke-1.5" />
</template>
{{ __('Cancel') }}
</Button>
</div>
</div>
</div>
</div>
@@ -50,15 +72,23 @@
/>
</template>
<script setup>
import { Calendar, Clock, UserCog2 } from 'lucide-vue-next'
import { inject, ref } from 'vue'
import {
Ban,
Calendar,
Clock,
GraduationCap,
HeadsetIcon,
} from 'lucide-vue-next'
import { inject, ref, getCurrentInstance } from 'vue'
import { formatTime } from '../utils'
import { Button, createResource } from 'frappe-ui'
import { Button, createResource, call } from 'frappe-ui'
import EvaluationModal from '@/components/Modals/EvaluationModal.vue'
const dayjs = inject('$dayjs')
const user = inject('$user')
const showEvalModal = ref(false)
const app = getCurrentInstance()
const { $dialog } = app.appContext.config.globalProperties
const props = defineProps({
batch: {
@@ -88,4 +118,32 @@ const upcoming_evals = createResource({
function openEvalModal() {
showEvalModal.value = true
}
const openEvalCall = (evl) => {
window.open(evl.google_meet_link, '_blank')
}
const cancelEvaluation = (evl) => {
$dialog({
title: __('Cancel this evaluation?'),
message: __(
'Are you sure you want to cancel this evaluation? This action cannot be undone.'
),
actions: [
{
label: __('Cancel'),
theme: 'red',
variant: 'solid',
onClick(close) {
call('lms.lms.api.cancel_evaluation', { evaluation: evl }).then(
() => {
upcoming_evals.reload()
}
)
close()
},
},
],
})
}
</script>

View File

@@ -12,6 +12,7 @@ from frappe.translate import get_all_translations
from frappe import _
from frappe.utils import (
get_datetime,
getdate,
cint,
flt,
now,
@@ -1228,3 +1229,39 @@ def get_notifications(filters):
@frappe.whitelist(allow_guest=True)
def is_guest_allowed():
return frappe.get_cached_value("LMS Settings", None, "allow_guest_access")
@frappe.whitelist()
def cancel_evaluation(evaluation):
evaluation = frappe._dict(evaluation)
if evaluation.member != frappe.session.user:
return
frappe.db.set_value("LMS Certificate Request", evaluation.name, "status", "Cancelled")
events = frappe.get_all(
"Event Participants",
{
"email": evaluation.member,
},
["parent", "name"],
)
for event in events:
info = frappe.db.get_value("Event", event.parent, ["starts_on", "subject"], as_dict=1)
date = str(info.starts_on).split(" ")[0]
if (
date == str(evaluation.date.format("YYYY-MM-DD"))
and evaluation.member_name in info.subject
):
communication = frappe.db.get_value(
"Communication",
{"reference_doctype": "Event", "reference_name": event.parent},
"name",
)
if communication:
frappe.delete_doc("Communication", communication, ignore_permissions=True)
frappe.delete_doc("Event Participants", event.name, ignore_permissions=True)
frappe.delete_doc("Event", event.parent, ignore_permissions=True)

View File

@@ -24,7 +24,8 @@
"google_meet_link",
"column_break_ddyh",
"start_time",
"end_time"
"end_time",
"status"
],
"fields": [
{
@@ -144,11 +145,19 @@
"fieldtype": "Data",
"hidden": 1,
"label": "Batch Title"
},
{
"fieldname": "status",
"fieldtype": "Select",
"in_standard_filter": 1,
"label": "Status",
"options": "Upcoming\nCompleted\nCancelled",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-09-11 11:19:44.669132",
"modified": "2025-02-19 17:20:02.526294",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Certificate Request",
@@ -204,6 +213,19 @@
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"states": [
{
"color": "Blue",
"title": "Upcoming"
},
{
"color": "Green",
"title": "Completed"
},
{
"color": "Red",
"title": "Cancelled"
}
],
"title_field": "member_name"
}

View File

@@ -874,8 +874,18 @@ def get_upcoming_evals(student, courses):
"member": student,
"course": ["in", courses],
"date": [">=", frappe.utils.nowdate()],
"status": "Upcoming",
},
["date", "start_time", "course", "evaluator", "google_meet_link"],
[
"name",
"date",
"start_time",
"course",
"evaluator",
"google_meet_link",
"member",
"member_name",
],
order_by="date",
)

View File

@@ -100,4 +100,5 @@ lms.patches.v2_0.convert_quiz_duration_to_minutes
lms.patches.v2_0.allow_guest_access #05-02-2025
lms.patches.v2_0.migrate_batch_student_data #10-02-2025
lms.patches.v2_0.delete_old_enrollment_doctypes
lms.patches.v2_0.delete_unused_custom_fields
lms.patches.v2_0.delete_unused_custom_fields
lms.patches.v2_0.update_certificate_request_status

View File

@@ -0,0 +1,14 @@
import frappe
from frappe.utils import getdate
def execute():
evaluations = frappe.get_all("LMS Certificate Request", fields=["name", "date"])
for evaluation in evaluations:
if evaluation.date > getdate():
frappe.db.set_value("LMS Certificate Request", evaluation.name, "status", "Upcoming")
else:
frappe.db.set_value(
"LMS Certificate Request", evaluation.name, "status", "Completed"
)