# 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, }