105 lines
4.3 KiB
Python
105 lines
4.3 KiB
Python
# pyrefly: ignore [missing-import]
|
|
from odoo import http
|
|
# pyrefly: ignore [missing-import]
|
|
from odoo.http import request
|
|
|
|
|
|
class EducationDashboardController(http.Controller):
|
|
|
|
@http.route(['/web/education/dashboard/kpis'], type='json', auth="user")
|
|
def get_dashboard_kpis(self, campus_id=None, program_id=None, academic_year_id=None, semester_id=None, env=None, **kw):
|
|
env = env or request.env
|
|
# Base Student Domain
|
|
student_domain = []
|
|
payment_domain = [('status', '=', 'posted')]
|
|
|
|
# Apply Filters
|
|
if campus_id:
|
|
student_domain.append(('campus_id', '=', int(campus_id)))
|
|
payment_domain.append(('student_id.campus_id', '=', int(campus_id)))
|
|
if program_id:
|
|
student_domain.append(('program_id', '=', int(program_id)))
|
|
payment_domain.append(('student_id.program_id', '=', int(program_id)))
|
|
if academic_year_id:
|
|
student_domain.append(('academic_year_id', '=', int(academic_year_id)))
|
|
payment_domain.append(('student_id.academic_year_id', '=', int(academic_year_id)))
|
|
if semester_id:
|
|
student_domain.append(('semester_id', '=', int(semester_id)))
|
|
payment_domain.append(('student_id.semester_id', '=', int(semester_id)))
|
|
|
|
# Fetch Student Records
|
|
students = env['education.student'].search(student_domain)
|
|
|
|
# Executive KPIs
|
|
total_students = len(students)
|
|
active_students = len(students.filtered(lambda s: s.status == 'active'))
|
|
admissions = len(students.filtered(lambda s: s.status == 'admitted'))
|
|
graduates = len(students.filtered(lambda s: s.status == 'graduated'))
|
|
withdrawn = len(students.filtered(lambda s: s.status == 'withdrawn'))
|
|
|
|
# Finance KPIs
|
|
total_fees = sum(students.mapped('total_fees'))
|
|
collected_fees = sum(students.mapped('total_paid'))
|
|
outstanding_fees = sum(students.mapped('outstanding_amount'))
|
|
|
|
# Academic KPIs
|
|
programs_count = env['education.program'].search_count([])
|
|
dept_count = env['education.department'].search_count([])
|
|
campus_count = env['education.campus'].search_count([])
|
|
years_count = env['education.academic.year'].search_count([])
|
|
|
|
# Charts: Program Distribution (using read_group for speed)
|
|
program_data = env['education.student'].read_group(
|
|
student_domain, ['program_id'], ['program_id']
|
|
)
|
|
program_chart = []
|
|
for gd in program_data:
|
|
if gd.get('program_id'):
|
|
program_chart.append({
|
|
'name': gd['program_id'][1],
|
|
'count': gd['program_id_count'],
|
|
})
|
|
|
|
# Charts: Campus Distribution
|
|
campus_data = env['education.student'].read_group(
|
|
student_domain, ['campus_id'], ['campus_id']
|
|
)
|
|
campus_chart = []
|
|
for gd in campus_data:
|
|
if gd.get('campus_id'):
|
|
campus_chart.append({
|
|
'name': gd['campus_id'][1],
|
|
'count': gd['campus_id_count'],
|
|
})
|
|
|
|
# Master Data lists for Filters
|
|
campuses = [{'id': c.id, 'name': c.name} for c in env['education.campus'].search([])]
|
|
programs = [{'id': p.id, 'name': p.name} for p in env['education.program'].search([])]
|
|
years = [{'id': y.id, 'name': y.name} for y in env['education.academic.year'].search([])]
|
|
semesters = [{'id': s.id, 'name': s.name} for s in env['education.semester'].search([])]
|
|
|
|
return {
|
|
'total_students': total_students,
|
|
'active_students': active_students,
|
|
'admissions': admissions,
|
|
'graduates': graduates,
|
|
'withdrawn': withdrawn,
|
|
|
|
'total_fees': total_fees,
|
|
'collected_fees': collected_fees,
|
|
'outstanding_fees': outstanding_fees,
|
|
|
|
'programs_count': programs_count,
|
|
'dept_count': dept_count,
|
|
'campus_count': campus_count,
|
|
'years_count': years_count,
|
|
|
|
'program_chart': program_chart,
|
|
'campus_chart': campus_chart,
|
|
|
|
'campuses': campuses,
|
|
'programs': programs,
|
|
'years': years,
|
|
'semesters': semesters,
|
|
}
|