diff --git a/addons/education_demo_data/__init__.py b/addons/education_demo_data/__init__.py
new file mode 100644
index 0000000..169d529
--- /dev/null
+++ b/addons/education_demo_data/__init__.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+from . import controllers
+
+def post_init_hook(env):
+ """
+ Hook to run after module installation.
+ Creates basic demo data if it doesn't exist.
+ """
+ from .demo_data_generator import generate_demo_data
+ try:
+ generate_demo_data(env)
+ except Exception as e:
+ import logging
+ logging.getLogger(__name__).error(f"Failed to generate demo data: {e}")
diff --git a/addons/education_demo_data/__manifest__.py b/addons/education_demo_data/__manifest__.py
new file mode 100644
index 0000000..6c4831f
--- /dev/null
+++ b/addons/education_demo_data/__manifest__.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+{
+ 'name': 'Education Demo Data',
+ 'version': '19.0.1.0.0',
+ 'summary': 'Demo Data & Secure Demo Login for Education ERP',
+ 'author': 'Metatroncube',
+ 'category': 'Education',
+ 'depends': [
+ 'education_base',
+ 'education_student',
+ 'education_lms',
+ 'education_portal',
+ 'education_exam',
+ 'education_timetable'
+ ],
+ 'data': [
+ 'data/demo_users.xml',
+ ],
+ 'demo': [],
+ 'installable': True,
+ 'application': False,
+ 'auto_install': False,
+ 'post_init_hook': 'post_init_hook',
+}
diff --git a/addons/education_demo_data/__pycache__/__init__.cpython-312.pyc b/addons/education_demo_data/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000..00e86a8
Binary files /dev/null and b/addons/education_demo_data/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_demo_data/__pycache__/demo_data_generator.cpython-312.pyc b/addons/education_demo_data/__pycache__/demo_data_generator.cpython-312.pyc
new file mode 100644
index 0000000..4df6429
Binary files /dev/null and b/addons/education_demo_data/__pycache__/demo_data_generator.cpython-312.pyc differ
diff --git a/addons/education_demo_data/controllers/__init__.py b/addons/education_demo_data/controllers/__init__.py
new file mode 100644
index 0000000..7a0f431
--- /dev/null
+++ b/addons/education_demo_data/controllers/__init__.py
@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+from . import demo_login
diff --git a/addons/education_demo_data/controllers/__pycache__/__init__.cpython-312.pyc b/addons/education_demo_data/controllers/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000..25d86ef
Binary files /dev/null and b/addons/education_demo_data/controllers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_demo_data/controllers/__pycache__/demo_login.cpython-312.pyc b/addons/education_demo_data/controllers/__pycache__/demo_login.cpython-312.pyc
new file mode 100644
index 0000000..4b5cf7a
Binary files /dev/null and b/addons/education_demo_data/controllers/__pycache__/demo_login.cpython-312.pyc differ
diff --git a/addons/education_demo_data/controllers/demo_login.py b/addons/education_demo_data/controllers/demo_login.py
new file mode 100644
index 0000000..49c08c3
--- /dev/null
+++ b/addons/education_demo_data/controllers/demo_login.py
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+# pyrefly: ignore [missing-import]
+from odoo import http, exceptions
+# pyrefly: ignore [missing-import]
+from odoo.http import request
+
+class EducationDemoController(http.Controller):
+
+ @http.route('/demo/login', type='http', auth='public', methods=['POST'], website=True, csrf=False)
+ def demo_login(self, role=None, **kw):
+ """
+ Secure Demo Login Endpoint.
+ Accepts only 'role' (admin, faculty, student).
+ Redirects to safe destinations.
+ """
+ if not role:
+ raise exceptions.AccessDenied("Missing role parameter.")
+
+ # Map allowed roles to specific, pre-configured demo user logins
+ # Do not allow arbitrary user login
+ demo_accounts = {
+ 'admin': {
+ 'login': 'demo.admin',
+ 'password': 'Demo@Admin2026',
+ 'redirect': '/web'
+ },
+ 'faculty': {
+ 'login': 'demo.faculty',
+ 'password': 'Demo@Faculty2026',
+ 'redirect': '/web'
+ },
+ 'student': {
+ 'login': 'demo.student',
+ 'password': 'Demo@Student2026',
+ 'redirect': '/my/education/dashboard'
+ }
+ }
+
+ if role not in demo_accounts:
+ raise exceptions.AccessDenied("Invalid role.")
+
+ account = demo_accounts[role]
+ db = request.db
+
+ if not db:
+ # If no DB is set, force it to the single DB (we can get it if there's only one)
+ dbs = http.db_list()
+ if len(dbs) == 1:
+ db = dbs[0]
+ else:
+ return request.redirect('/web/login')
+
+ try:
+ credential = {
+ 'login': account['login'],
+ 'password': account['password'],
+ 'type': 'password'
+ }
+ if request.env.cr:
+ auth_info = request.session.authenticate(request.env, credential)
+ uid = auth_info.get('uid') if auth_info else request.session.uid
+ else:
+ import odoo
+ with odoo.modules.registry.Registry(db).cursor() as cr:
+ env = odoo.api.Environment(cr, None, {})
+ auth_info = request.session.authenticate(env, credential)
+ request._save_session(env)
+ request.session.db = db
+ uid = auth_info.get('uid') if auth_info else request.session.uid
+ except Exception:
+ uid = False
+
+ if not uid:
+ # Maybe the demo user doesn't exist yet, or password was changed.
+ # Redirect to login with error.
+ return request.redirect('/web/login?error=Demo account not properly configured.')
+
+ # Protect against open redirects: Only use our pre-defined safe redirects
+ return request.redirect(account['redirect'])
diff --git a/addons/education_demo_data/data/demo_users.xml b/addons/education_demo_data/data/demo_users.xml
new file mode 100644
index 0000000..84af348
--- /dev/null
+++ b/addons/education_demo_data/data/demo_users.xml
@@ -0,0 +1,27 @@
+
+
+
+
+ Demo Admin
+ demo.admin
+ Demo@Admin2026
+ demo.admin@example.com
+
+
+
+
+ Demo Faculty
+ demo.faculty
+ Demo@Faculty2026
+ demo.faculty@example.com
+
+
+
+
+
+ Demo Student
+ demo.student
+ Demo@Student2026
+ demo.student@example.com
+
+
diff --git a/addons/education_demo_data/demo_data_generator.py b/addons/education_demo_data/demo_data_generator.py
new file mode 100644
index 0000000..4363a9b
--- /dev/null
+++ b/addons/education_demo_data/demo_data_generator.py
@@ -0,0 +1,224 @@
+# -*- coding: utf-8 -*-
+
+def generate_demo_data(env):
+ """
+ Generate realistic demo data for the Education ERP.
+ We do this via ORM to avoid complex XML constraint failures.
+ """
+ # 1. Company / Campus / Department
+ demo_company = env['res.company'].search([('name', '=', 'Metatron Demo Company')], limit=1)
+ if not demo_company:
+ demo_company = env['res.company'].create({
+ 'name': 'Metatron Demo Company',
+ 'email': 'demo@metatroncubesolutions.com'
+ })
+ # Explicitly ensure the main admin (ID 2) does not have access to this company
+ main_admin = env['res.users'].browse(2)
+ if main_admin.exists():
+ main_admin.sudo().write({'company_ids': [(3, demo_company.id)]})
+
+ company = demo_company
+
+ campus = env['education.campus'].search([('name', '=', 'Demo Campus')], limit=1)
+ if not campus:
+ campus = env['education.campus'].create({
+ 'name': 'Demo Campus',
+ 'code': 'DEMO-CAMPUS',
+ 'company_id': company.id
+ })
+
+ dept = env['education.department'].search([('name', '=', 'Computer Science Demo')], limit=1)
+ if not dept:
+ dept = env['education.department'].create({
+ 'name': 'Computer Science Demo',
+ 'code': 'CS-DEMO',
+ 'company_id': company.id,
+ 'campus_id': campus.id
+ })
+
+ # 2. Academic Level & Program
+ level = env['education.academic.level'].search([('name', '=', 'Undergraduate Demo')], limit=1)
+ if not level:
+ level = env['education.academic.level'].create({
+ 'name': 'Undergraduate Demo',
+ 'code': 'UG-DEMO',
+ 'company_id': company.id
+ })
+
+ program = env['education.program'].search([('code', '=', 'BTECH-CS-DEMO')], limit=1)
+ if not program:
+ program = env['education.program'].create({
+ 'name': 'B.Tech Computer Science (Demo)',
+ 'code': 'BTECH-CS-DEMO',
+ 'level_id': level.id,
+ 'department_id': dept.id,
+ 'duration': 4,
+ 'duration_unit': 'years'
+ })
+
+ # 3. Academic Year & Term
+ import datetime
+ today = datetime.date.today()
+
+ year = env['education.academic.year'].search([('name', '=', 'Demo Year 2026-2027')], limit=1)
+ if not year:
+ year = env['education.academic.year'].create({
+ 'name': 'Demo Year 2026-2027',
+ 'code': 'DY2627',
+ 'start_date': today,
+ 'end_date': today + datetime.timedelta(days=365),
+ 'company_id': company.id
+ })
+
+ term = env['education.academic.term'].search([('code', '=', 'DT-FALL-26')], limit=1)
+ if not term:
+ term = env['education.academic.term'].create({
+ 'name': 'Demo Fall 2026',
+ 'code': 'DT-FALL-26',
+ 'academic_year_id': year.id,
+ 'start_date': today,
+ 'end_date': today + datetime.timedelta(days=120)
+ })
+
+ # 4. Users & Roles
+ admin_user = env['res.users'].search([('login', '=', 'demo.admin')], limit=1)
+ faculty_user = env['res.users'].search([('login', '=', 'demo.faculty')], limit=1)
+ student_user = env['res.users'].search([('login', '=', 'demo.student')], limit=1)
+
+ # Assign groups dynamically
+ erp_manager_group = env.ref('base.group_erp_manager', raise_if_not_found=False)
+ system_group = env.ref('base.group_system', raise_if_not_found=False)
+ user_group = env.ref('base.group_user', raise_if_not_found=False)
+ portal_group = env.ref('base.group_portal', raise_if_not_found=False)
+
+ if admin_user:
+ admin_groups = []
+ if erp_manager_group: admin_groups.append(erp_manager_group.id)
+ if system_group: admin_groups.append(system_group.id)
+ if admin_groups:
+ admin_user.sudo().write({
+ 'groups_id': [(4, g) for g in admin_groups],
+ 'company_id': company.id,
+ 'company_ids': [(6, 0, [company.id])]
+ })
+
+ if faculty_user and user_group:
+ faculty_groups = [user_group.id]
+
+ # Give basic student read access
+ student_user_grp = env.ref('education_student.group_education_student_user', raise_if_not_found=False)
+ if student_user_grp: faculty_groups.append(student_user_grp.id)
+
+ # Give LMS Faculty access
+ lms_faculty_grp = env.ref('education_lms.group_education_lms_faculty', raise_if_not_found=False)
+ if lms_faculty_grp: faculty_groups.append(lms_faculty_grp.id)
+
+ faculty_user.sudo().write({
+ 'groups_id': [(4, g) for g in faculty_groups],
+ 'company_id': company.id,
+ 'company_ids': [(6, 0, [company.id])]
+ })
+
+ if student_user and portal_group:
+ student_user.sudo().write({
+ 'groups_id': [(4, portal_group.id)],
+ 'company_id': company.id,
+ 'company_ids': [(6, 0, [company.id])]
+ })
+
+ # 5. Create Student Record
+ if student_user:
+ student = env['education.student'].search([('partner_id', '=', student_user.partner_id.id)], limit=1)
+ if not student:
+ student = env['education.student'].create({
+ 'first_name': 'Demo',
+ 'last_name': 'Student',
+ 'partner_id': student_user.partner_id.id,
+ 'program_id': program.id,
+ 'campus_id': campus.id,
+ 'academic_year_id': year.id,
+ 'status': 'active'
+ })
+
+ # Map student ID to portal user if required by ERP architecture
+ student_user.partner_id.write({'is_student': True})
+
+ # 6. Create LMS Course with Faculty
+ if faculty_user:
+ course = env['education.lms.course'].search([('code', '=', 'CS101-DEMO')], limit=1)
+ if not course:
+ course = env['education.lms.course'].create({
+ 'name': 'Introduction to Computer Science (Demo)',
+ 'code': 'CS101-DEMO',
+ 'faculty_id': faculty_user.id,
+ 'program_id': program.id,
+ 'state': 'published',
+ 'description': 'A comprehensive demo course.'
+ })
+
+ # Create a section and material
+ section = env['education.lms.section'].create({
+ 'name': 'Week 1: Basics',
+ 'course_id': course.id,
+ 'sequence': 1
+ })
+
+ env['education.lms.material'].create({
+ 'name': 'Syllabus & Introduction',
+ 'section_id': section.id,
+ 'material_type': 'document',
+ 'content': 'Welcome to the course!'
+ })
+
+ # Create an assignment
+ env['education.lms.assignment'].create({
+ 'name': 'First Demo Assignment',
+ 'course_id': course.id,
+ 'due_date': today + datetime.timedelta(days=7),
+ 'max_marks': 100,
+ 'state': 'published'
+ })
+
+ # Enroll the demo student
+ if student_user:
+ student_record = env['education.student'].search([('partner_id', '=', student_user.partner_id.id)], limit=1)
+ if student_record:
+ env['education.lms.enrollment'].create({
+ 'course_id': course.id,
+ 'student_id': student_record.id,
+ 'state': 'enrolled'
+ })
+
+ # 7. Library Demo Data (Optional, if library module exists)
+ if 'education.library.book' in env:
+ book = env['education.library.book'].search([('isbn', '=', 'DEMO-ISBN-123')], limit=1)
+ if not book:
+ book = env['education.library.book'].create({
+ 'name': 'The Art of Computer Programming (Demo Edition)',
+ 'author': 'Donald Knuth',
+ 'isbn': 'DEMO-ISBN-123',
+ 'total_copies': 5
+ })
+
+ # If student is a library member, create a checkout
+ if student_user:
+ student_record = env['education.student'].search([('partner_id', '=', student_user.partner_id.id)], limit=1)
+ if student_record:
+ member = env['education.library.member'].search([('student_id', '=', student_record.id)], limit=1)
+ if not member:
+ member = env['education.library.member'].create({
+ 'student_id': student_record.id,
+ 'member_type': 'student',
+ 'state': 'active'
+ })
+
+ env['education.library.checkout'].create({
+ 'member_id': member.id,
+ 'book_id': book.id,
+ 'checkout_date': today,
+ 'due_date': today + datetime.timedelta(days=14),
+ 'state': 'issued'
+ })
+
+ env.cr.commit()
+
diff --git a/addons/education_demo_data/tests/__init__.py b/addons/education_demo_data/tests/__init__.py
new file mode 100644
index 0000000..f097086
--- /dev/null
+++ b/addons/education_demo_data/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_demo_login
diff --git a/addons/education_demo_data/tests/__pycache__/__init__.cpython-312.pyc b/addons/education_demo_data/tests/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000..49b6217
Binary files /dev/null and b/addons/education_demo_data/tests/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_demo_data/tests/__pycache__/test_demo_login.cpython-312.pyc b/addons/education_demo_data/tests/__pycache__/test_demo_login.cpython-312.pyc
new file mode 100644
index 0000000..22b42ca
Binary files /dev/null and b/addons/education_demo_data/tests/__pycache__/test_demo_login.cpython-312.pyc differ
diff --git a/addons/education_demo_data/tests/test_demo_login.py b/addons/education_demo_data/tests/test_demo_login.py
new file mode 100644
index 0000000..1b8cc5b
--- /dev/null
+++ b/addons/education_demo_data/tests/test_demo_login.py
@@ -0,0 +1,32 @@
+import odoo.tests
+from odoo.tests.common import HttpCase
+from unittest.mock import patch
+
+@odoo.tests.tagged('-at_install', 'post_install')
+class TestDemoLogin(HttpCase):
+
+ def test_01_demo_login_admin(self):
+ """ Test admin demo login via endpoint """
+ response = self.url_open('/demo/login', data={'role': 'admin'})
+ self.assertEqual(response.status_code, 200, "Should redirect or load a page")
+
+ def test_02_demo_login_faculty(self):
+ """ Test faculty demo login """
+ response = self.url_open('/demo/login', data={'role': 'faculty'})
+ self.assertEqual(response.status_code, 200, "Should redirect or load a page")
+
+ def test_03_demo_login_student(self):
+ """ Test student demo login """
+ response = self.url_open('/demo/login', data={'role': 'student'})
+ self.assertEqual(response.status_code, 200, "Should redirect or load a page")
+
+ def test_04_demo_login_invalid_role(self):
+ """ Test invalid roles get rejected """
+ response = self.url_open('/demo/login', data={'role': 'superadmin'})
+ self.assertEqual(response.status_code, 403, "Should be Access Denied")
+
+ def test_05_demo_login_missing_role(self):
+ """ Test missing role gets rejected """
+ # using GET instead of POST causes a 405 Method Not Allowed, or missing role in POST causes 403
+ response = self.url_open('/demo/login', data={})
+ self.assertEqual(response.status_code, 403, "Should be Access Denied")
diff --git a/addons/education_exam/__pycache__/__init__.cpython-312.pyc b/addons/education_exam/__pycache__/__init__.cpython-312.pyc
index 46d488b..a121821 100644
Binary files a/addons/education_exam/__pycache__/__init__.cpython-312.pyc and b/addons/education_exam/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_exam/controllers/__pycache__/__init__.cpython-312.pyc b/addons/education_exam/controllers/__pycache__/__init__.cpython-312.pyc
index 0841217..b31b027 100644
Binary files a/addons/education_exam/controllers/__pycache__/__init__.cpython-312.pyc and b/addons/education_exam/controllers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_exam/controllers/__pycache__/portal_exam.cpython-312.pyc b/addons/education_exam/controllers/__pycache__/portal_exam.cpython-312.pyc
index cb8e758..cc692a4 100644
Binary files a/addons/education_exam/controllers/__pycache__/portal_exam.cpython-312.pyc and b/addons/education_exam/controllers/__pycache__/portal_exam.cpython-312.pyc differ
diff --git a/addons/education_exam/models/__pycache__/__init__.cpython-312.pyc b/addons/education_exam/models/__pycache__/__init__.cpython-312.pyc
index a0607ea..9ead79c 100644
Binary files a/addons/education_exam/models/__pycache__/__init__.cpython-312.pyc and b/addons/education_exam/models/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_exam/models/__pycache__/education_exam.cpython-312.pyc b/addons/education_exam/models/__pycache__/education_exam.cpython-312.pyc
index 50b170e..7966f5c 100644
Binary files a/addons/education_exam/models/__pycache__/education_exam.cpython-312.pyc and b/addons/education_exam/models/__pycache__/education_exam.cpython-312.pyc differ
diff --git a/addons/education_exam/models/__pycache__/education_exam_result.cpython-312.pyc b/addons/education_exam/models/__pycache__/education_exam_result.cpython-312.pyc
index 4a089fe..256fcf8 100644
Binary files a/addons/education_exam/models/__pycache__/education_exam_result.cpython-312.pyc and b/addons/education_exam/models/__pycache__/education_exam_result.cpython-312.pyc differ
diff --git a/addons/education_exam/models/__pycache__/education_exam_type.cpython-312.pyc b/addons/education_exam/models/__pycache__/education_exam_type.cpython-312.pyc
index 762c176..c006b36 100644
Binary files a/addons/education_exam/models/__pycache__/education_exam_type.cpython-312.pyc and b/addons/education_exam/models/__pycache__/education_exam_type.cpython-312.pyc differ
diff --git a/addons/education_exam/models/__pycache__/education_grading.cpython-312.pyc b/addons/education_exam/models/__pycache__/education_grading.cpython-312.pyc
index 6611d29..c9561d4 100644
Binary files a/addons/education_exam/models/__pycache__/education_grading.cpython-312.pyc and b/addons/education_exam/models/__pycache__/education_grading.cpython-312.pyc differ
diff --git a/addons/education_exam/models/__pycache__/education_student_inherit.cpython-312.pyc b/addons/education_exam/models/__pycache__/education_student_inherit.cpython-312.pyc
index f9a45ea..6db2a93 100644
Binary files a/addons/education_exam/models/__pycache__/education_student_inherit.cpython-312.pyc and b/addons/education_exam/models/__pycache__/education_student_inherit.cpython-312.pyc differ
diff --git a/addons/education_exam/models/__pycache__/education_subject.cpython-312.pyc b/addons/education_exam/models/__pycache__/education_subject.cpython-312.pyc
index 36deab8..c5ef5b6 100644
Binary files a/addons/education_exam/models/__pycache__/education_subject.cpython-312.pyc and b/addons/education_exam/models/__pycache__/education_subject.cpython-312.pyc differ
diff --git a/addons/education_finance/__pycache__/__init__.cpython-312.pyc b/addons/education_finance/__pycache__/__init__.cpython-312.pyc
index ee307dc..c691670 100644
Binary files a/addons/education_finance/__pycache__/__init__.cpython-312.pyc and b/addons/education_finance/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_finance/models/__pycache__/__init__.cpython-312.pyc b/addons/education_finance/models/__pycache__/__init__.cpython-312.pyc
index 386df61..753dace 100644
Binary files a/addons/education_finance/models/__pycache__/__init__.cpython-312.pyc and b/addons/education_finance/models/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_finance/models/__pycache__/fee_assignment.cpython-312.pyc b/addons/education_finance/models/__pycache__/fee_assignment.cpython-312.pyc
index 7450b54..5117fbb 100644
Binary files a/addons/education_finance/models/__pycache__/fee_assignment.cpython-312.pyc and b/addons/education_finance/models/__pycache__/fee_assignment.cpython-312.pyc differ
diff --git a/addons/education_finance/models/__pycache__/fee_category.cpython-312.pyc b/addons/education_finance/models/__pycache__/fee_category.cpython-312.pyc
index 576fcc8..57498b6 100644
Binary files a/addons/education_finance/models/__pycache__/fee_category.cpython-312.pyc and b/addons/education_finance/models/__pycache__/fee_category.cpython-312.pyc differ
diff --git a/addons/education_finance/models/__pycache__/fee_structure.cpython-312.pyc b/addons/education_finance/models/__pycache__/fee_structure.cpython-312.pyc
index a033712..cc81745 100644
Binary files a/addons/education_finance/models/__pycache__/fee_structure.cpython-312.pyc and b/addons/education_finance/models/__pycache__/fee_structure.cpython-312.pyc differ
diff --git a/addons/education_finance/models/__pycache__/fee_type.cpython-312.pyc b/addons/education_finance/models/__pycache__/fee_type.cpython-312.pyc
index db904a2..dfbc7b6 100644
Binary files a/addons/education_finance/models/__pycache__/fee_type.cpython-312.pyc and b/addons/education_finance/models/__pycache__/fee_type.cpython-312.pyc differ
diff --git a/addons/education_finance/models/__pycache__/student_discount.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_discount.cpython-312.pyc
index 13c53d2..9d57a8e 100644
Binary files a/addons/education_finance/models/__pycache__/student_discount.cpython-312.pyc and b/addons/education_finance/models/__pycache__/student_discount.cpython-312.pyc differ
diff --git a/addons/education_finance/models/__pycache__/student_inherit.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_inherit.cpython-312.pyc
index 05ed766..8502dd6 100644
Binary files a/addons/education_finance/models/__pycache__/student_inherit.cpython-312.pyc and b/addons/education_finance/models/__pycache__/student_inherit.cpython-312.pyc differ
diff --git a/addons/education_finance/models/__pycache__/student_ledger.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_ledger.cpython-312.pyc
index 8dd416f..89e93a1 100644
Binary files a/addons/education_finance/models/__pycache__/student_ledger.cpython-312.pyc and b/addons/education_finance/models/__pycache__/student_ledger.cpython-312.pyc differ
diff --git a/addons/education_finance/models/__pycache__/student_payment.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_payment.cpython-312.pyc
index 0f28918..9bcad71 100644
Binary files a/addons/education_finance/models/__pycache__/student_payment.cpython-312.pyc and b/addons/education_finance/models/__pycache__/student_payment.cpython-312.pyc differ
diff --git a/addons/education_finance/models/__pycache__/student_refund.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_refund.cpython-312.pyc
index 9fd6a37..82601bd 100644
Binary files a/addons/education_finance/models/__pycache__/student_refund.cpython-312.pyc and b/addons/education_finance/models/__pycache__/student_refund.cpython-312.pyc differ
diff --git a/addons/education_finance/models/__pycache__/student_scholarship.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_scholarship.cpython-312.pyc
index 78f4f11..a209e9b 100644
Binary files a/addons/education_finance/models/__pycache__/student_scholarship.cpython-312.pyc and b/addons/education_finance/models/__pycache__/student_scholarship.cpython-312.pyc differ
diff --git a/addons/education_hostel/__pycache__/__init__.cpython-312.pyc b/addons/education_hostel/__pycache__/__init__.cpython-312.pyc
index fd0eccd..f0409b8 100644
Binary files a/addons/education_hostel/__pycache__/__init__.cpython-312.pyc and b/addons/education_hostel/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_hostel/controllers/__pycache__/__init__.cpython-312.pyc b/addons/education_hostel/controllers/__pycache__/__init__.cpython-312.pyc
index 948b789..43a2470 100644
Binary files a/addons/education_hostel/controllers/__pycache__/__init__.cpython-312.pyc and b/addons/education_hostel/controllers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_hostel/controllers/__pycache__/portal.cpython-312.pyc b/addons/education_hostel/controllers/__pycache__/portal.cpython-312.pyc
index dd81634..c9b271e 100644
Binary files a/addons/education_hostel/controllers/__pycache__/portal.cpython-312.pyc and b/addons/education_hostel/controllers/__pycache__/portal.cpython-312.pyc differ
diff --git a/addons/education_hostel/models/__pycache__/__init__.cpython-312.pyc b/addons/education_hostel/models/__pycache__/__init__.cpython-312.pyc
index 467def1..a462b4f 100644
Binary files a/addons/education_hostel/models/__pycache__/__init__.cpython-312.pyc and b/addons/education_hostel/models/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_hostel/models/__pycache__/hostel.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel.cpython-312.pyc
index c49a0b1..a23e14a 100644
Binary files a/addons/education_hostel/models/__pycache__/hostel.cpython-312.pyc and b/addons/education_hostel/models/__pycache__/hostel.cpython-312.pyc differ
diff --git a/addons/education_hostel/models/__pycache__/hostel_bed.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel_bed.cpython-312.pyc
index 6a768be..898a367 100644
Binary files a/addons/education_hostel/models/__pycache__/hostel_bed.cpython-312.pyc and b/addons/education_hostel/models/__pycache__/hostel_bed.cpython-312.pyc differ
diff --git a/addons/education_hostel/models/__pycache__/hostel_complaint.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel_complaint.cpython-312.pyc
index ff659af..f4ec46f 100644
Binary files a/addons/education_hostel/models/__pycache__/hostel_complaint.cpython-312.pyc and b/addons/education_hostel/models/__pycache__/hostel_complaint.cpython-312.pyc differ
diff --git a/addons/education_hostel/models/__pycache__/hostel_fee.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel_fee.cpython-312.pyc
index ef14388..a1a9364 100644
Binary files a/addons/education_hostel/models/__pycache__/hostel_fee.cpython-312.pyc and b/addons/education_hostel/models/__pycache__/hostel_fee.cpython-312.pyc differ
diff --git a/addons/education_hostel/models/__pycache__/hostel_floor.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel_floor.cpython-312.pyc
index 25daf3a..558c653 100644
Binary files a/addons/education_hostel/models/__pycache__/hostel_floor.cpython-312.pyc and b/addons/education_hostel/models/__pycache__/hostel_floor.cpython-312.pyc differ
diff --git a/addons/education_hostel/models/__pycache__/hostel_member.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel_member.cpython-312.pyc
index 8307786..1ea6558 100644
Binary files a/addons/education_hostel/models/__pycache__/hostel_member.cpython-312.pyc and b/addons/education_hostel/models/__pycache__/hostel_member.cpython-312.pyc differ
diff --git a/addons/education_hostel/models/__pycache__/hostel_room.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel_room.cpython-312.pyc
index 5236b4c..73b73e6 100644
Binary files a/addons/education_hostel/models/__pycache__/hostel_room.cpython-312.pyc and b/addons/education_hostel/models/__pycache__/hostel_room.cpython-312.pyc differ
diff --git a/addons/education_hostel/models/__pycache__/hostel_visitor.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel_visitor.cpython-312.pyc
index f2cf6fd..47b31bc 100644
Binary files a/addons/education_hostel/models/__pycache__/hostel_visitor.cpython-312.pyc and b/addons/education_hostel/models/__pycache__/hostel_visitor.cpython-312.pyc differ
diff --git a/addons/education_library/__pycache__/__init__.cpython-312.pyc b/addons/education_library/__pycache__/__init__.cpython-312.pyc
index 93b6d63..31c049d 100644
Binary files a/addons/education_library/__pycache__/__init__.cpython-312.pyc and b/addons/education_library/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_library/controllers/__pycache__/__init__.cpython-312.pyc b/addons/education_library/controllers/__pycache__/__init__.cpython-312.pyc
index 0715051..9ba5a68 100644
Binary files a/addons/education_library/controllers/__pycache__/__init__.cpython-312.pyc and b/addons/education_library/controllers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_library/controllers/__pycache__/main.cpython-312.pyc b/addons/education_library/controllers/__pycache__/main.cpython-312.pyc
index 28138f1..5c59771 100644
Binary files a/addons/education_library/controllers/__pycache__/main.cpython-312.pyc and b/addons/education_library/controllers/__pycache__/main.cpython-312.pyc differ
diff --git a/addons/education_library/models/__pycache__/__init__.cpython-312.pyc b/addons/education_library/models/__pycache__/__init__.cpython-312.pyc
index ccb8470..2fdf77a 100644
Binary files a/addons/education_library/models/__pycache__/__init__.cpython-312.pyc and b/addons/education_library/models/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_library/models/__pycache__/education_library.cpython-312.pyc b/addons/education_library/models/__pycache__/education_library.cpython-312.pyc
index 40b99b1..4b99d2e 100644
Binary files a/addons/education_library/models/__pycache__/education_library.cpython-312.pyc and b/addons/education_library/models/__pycache__/education_library.cpython-312.pyc differ
diff --git a/addons/education_library/models/__pycache__/education_library_book.cpython-312.pyc b/addons/education_library/models/__pycache__/education_library_book.cpython-312.pyc
index 9954297..5cfd56d 100644
Binary files a/addons/education_library/models/__pycache__/education_library_book.cpython-312.pyc and b/addons/education_library/models/__pycache__/education_library_book.cpython-312.pyc differ
diff --git a/addons/education_library/models/__pycache__/education_library_book_copy.cpython-312.pyc b/addons/education_library/models/__pycache__/education_library_book_copy.cpython-312.pyc
index e1ece55..3af4f50 100644
Binary files a/addons/education_library/models/__pycache__/education_library_book_copy.cpython-312.pyc and b/addons/education_library/models/__pycache__/education_library_book_copy.cpython-312.pyc differ
diff --git a/addons/education_library/models/__pycache__/education_library_category.cpython-312.pyc b/addons/education_library/models/__pycache__/education_library_category.cpython-312.pyc
index 791ddfa..6bcdef5 100644
Binary files a/addons/education_library/models/__pycache__/education_library_category.cpython-312.pyc and b/addons/education_library/models/__pycache__/education_library_category.cpython-312.pyc differ
diff --git a/addons/education_library/models/__pycache__/education_library_fine.cpython-312.pyc b/addons/education_library/models/__pycache__/education_library_fine.cpython-312.pyc
index 3e1b8ff..27ccd5b 100644
Binary files a/addons/education_library/models/__pycache__/education_library_fine.cpython-312.pyc and b/addons/education_library/models/__pycache__/education_library_fine.cpython-312.pyc differ
diff --git a/addons/education_library/models/__pycache__/education_library_issue.cpython-312.pyc b/addons/education_library/models/__pycache__/education_library_issue.cpython-312.pyc
index 5d40826..a9ea253 100644
Binary files a/addons/education_library/models/__pycache__/education_library_issue.cpython-312.pyc and b/addons/education_library/models/__pycache__/education_library_issue.cpython-312.pyc differ
diff --git a/addons/education_library/models/__pycache__/education_library_member.cpython-312.pyc b/addons/education_library/models/__pycache__/education_library_member.cpython-312.pyc
index a7c5c58..44721c2 100644
Binary files a/addons/education_library/models/__pycache__/education_library_member.cpython-312.pyc and b/addons/education_library/models/__pycache__/education_library_member.cpython-312.pyc differ
diff --git a/addons/education_library/models/__pycache__/education_library_reservation.cpython-312.pyc b/addons/education_library/models/__pycache__/education_library_reservation.cpython-312.pyc
index bb2024b..63d5a88 100644
Binary files a/addons/education_library/models/__pycache__/education_library_reservation.cpython-312.pyc and b/addons/education_library/models/__pycache__/education_library_reservation.cpython-312.pyc differ
diff --git a/addons/education_library/models/__pycache__/res_config_settings.cpython-312.pyc b/addons/education_library/models/__pycache__/res_config_settings.cpython-312.pyc
index f1a427d..2604486 100644
Binary files a/addons/education_library/models/__pycache__/res_config_settings.cpython-312.pyc and b/addons/education_library/models/__pycache__/res_config_settings.cpython-312.pyc differ
diff --git a/addons/education_lms/__pycache__/__init__.cpython-312.pyc b/addons/education_lms/__pycache__/__init__.cpython-312.pyc
index 2fc2cd3..14e1c68 100644
Binary files a/addons/education_lms/__pycache__/__init__.cpython-312.pyc and b/addons/education_lms/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_lms/controllers/__pycache__/__init__.cpython-312.pyc b/addons/education_lms/controllers/__pycache__/__init__.cpython-312.pyc
index 3c6e084..c319100 100644
Binary files a/addons/education_lms/controllers/__pycache__/__init__.cpython-312.pyc and b/addons/education_lms/controllers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_lms/controllers/__pycache__/main.cpython-312.pyc b/addons/education_lms/controllers/__pycache__/main.cpython-312.pyc
index 35a9ca2..a012dd9 100644
Binary files a/addons/education_lms/controllers/__pycache__/main.cpython-312.pyc and b/addons/education_lms/controllers/__pycache__/main.cpython-312.pyc differ
diff --git a/addons/education_lms/models/__pycache__/__init__.cpython-312.pyc b/addons/education_lms/models/__pycache__/__init__.cpython-312.pyc
index ceb59c7..b8a0554 100644
Binary files a/addons/education_lms/models/__pycache__/__init__.cpython-312.pyc and b/addons/education_lms/models/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_lms/models/__pycache__/education_lms_assignment.cpython-312.pyc b/addons/education_lms/models/__pycache__/education_lms_assignment.cpython-312.pyc
index 9088b0a..679171c 100644
Binary files a/addons/education_lms/models/__pycache__/education_lms_assignment.cpython-312.pyc and b/addons/education_lms/models/__pycache__/education_lms_assignment.cpython-312.pyc differ
diff --git a/addons/education_lms/models/__pycache__/education_lms_content.cpython-312.pyc b/addons/education_lms/models/__pycache__/education_lms_content.cpython-312.pyc
index 97f2297..ba70222 100644
Binary files a/addons/education_lms/models/__pycache__/education_lms_content.cpython-312.pyc and b/addons/education_lms/models/__pycache__/education_lms_content.cpython-312.pyc differ
diff --git a/addons/education_lms/models/__pycache__/education_lms_course.cpython-312.pyc b/addons/education_lms/models/__pycache__/education_lms_course.cpython-312.pyc
index 504824b..ea60a73 100644
Binary files a/addons/education_lms/models/__pycache__/education_lms_course.cpython-312.pyc and b/addons/education_lms/models/__pycache__/education_lms_course.cpython-312.pyc differ
diff --git a/addons/education_lms/models/__pycache__/education_lms_submission.cpython-312.pyc b/addons/education_lms/models/__pycache__/education_lms_submission.cpython-312.pyc
index 500977b..ee130cb 100644
Binary files a/addons/education_lms/models/__pycache__/education_lms_submission.cpython-312.pyc and b/addons/education_lms/models/__pycache__/education_lms_submission.cpython-312.pyc differ
diff --git a/addons/education_portal/__pycache__/__init__.cpython-312.pyc b/addons/education_portal/__pycache__/__init__.cpython-312.pyc
index ae25c90..21d9ab6 100644
Binary files a/addons/education_portal/__pycache__/__init__.cpython-312.pyc and b/addons/education_portal/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_portal/controllers/__pycache__/__init__.cpython-312.pyc b/addons/education_portal/controllers/__pycache__/__init__.cpython-312.pyc
index 4252d5d..200494e 100644
Binary files a/addons/education_portal/controllers/__pycache__/__init__.cpython-312.pyc and b/addons/education_portal/controllers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_portal/controllers/__pycache__/main.cpython-312.pyc b/addons/education_portal/controllers/__pycache__/main.cpython-312.pyc
index e0c7051..35eef4f 100644
Binary files a/addons/education_portal/controllers/__pycache__/main.cpython-312.pyc and b/addons/education_portal/controllers/__pycache__/main.cpython-312.pyc differ
diff --git a/addons/education_portal/controllers/__pycache__/payment.cpython-312.pyc b/addons/education_portal/controllers/__pycache__/payment.cpython-312.pyc
index 0c31549..680336f 100644
Binary files a/addons/education_portal/controllers/__pycache__/payment.cpython-312.pyc and b/addons/education_portal/controllers/__pycache__/payment.cpython-312.pyc differ
diff --git a/addons/education_portal/models/__pycache__/__init__.cpython-312.pyc b/addons/education_portal/models/__pycache__/__init__.cpython-312.pyc
index fd3aad1..f896689 100644
Binary files a/addons/education_portal/models/__pycache__/__init__.cpython-312.pyc and b/addons/education_portal/models/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_portal/models/__pycache__/announcement.cpython-312.pyc b/addons/education_portal/models/__pycache__/announcement.cpython-312.pyc
index 25f1cb7..5654ea7 100644
Binary files a/addons/education_portal/models/__pycache__/announcement.cpython-312.pyc and b/addons/education_portal/models/__pycache__/announcement.cpython-312.pyc differ
diff --git a/addons/education_portal/models/__pycache__/fee_assignment_inherit.cpython-312.pyc b/addons/education_portal/models/__pycache__/fee_assignment_inherit.cpython-312.pyc
index 18265b2..679c75c 100644
Binary files a/addons/education_portal/models/__pycache__/fee_assignment_inherit.cpython-312.pyc and b/addons/education_portal/models/__pycache__/fee_assignment_inherit.cpython-312.pyc differ
diff --git a/addons/education_portal/models/__pycache__/payment_transaction.cpython-312.pyc b/addons/education_portal/models/__pycache__/payment_transaction.cpython-312.pyc
index 0a66ca4..7686ffc 100644
Binary files a/addons/education_portal/models/__pycache__/payment_transaction.cpython-312.pyc and b/addons/education_portal/models/__pycache__/payment_transaction.cpython-312.pyc differ
diff --git a/addons/education_portal/models/__pycache__/res_config_settings.cpython-312.pyc b/addons/education_portal/models/__pycache__/res_config_settings.cpython-312.pyc
index 51c2130..69d8e73 100644
Binary files a/addons/education_portal/models/__pycache__/res_config_settings.cpython-312.pyc and b/addons/education_portal/models/__pycache__/res_config_settings.cpython-312.pyc differ
diff --git a/addons/education_portal/models/__pycache__/student_inherit.cpython-312.pyc b/addons/education_portal/models/__pycache__/student_inherit.cpython-312.pyc
index 025fe33..f512dc0 100644
Binary files a/addons/education_portal/models/__pycache__/student_inherit.cpython-312.pyc and b/addons/education_portal/models/__pycache__/student_inherit.cpython-312.pyc differ
diff --git a/addons/education_portal/services/__pycache__/__init__.cpython-312.pyc b/addons/education_portal/services/__pycache__/__init__.cpython-312.pyc
index 9abd365..494afc4 100644
Binary files a/addons/education_portal/services/__pycache__/__init__.cpython-312.pyc and b/addons/education_portal/services/__pycache__/__init__.cpython-312.pyc differ
diff --git a/addons/education_portal/services/__pycache__/payment_service.cpython-312.pyc b/addons/education_portal/services/__pycache__/payment_service.cpython-312.pyc
index 854affb..35a4cd0 100644
Binary files a/addons/education_portal/services/__pycache__/payment_service.cpython-312.pyc and b/addons/education_portal/services/__pycache__/payment_service.cpython-312.pyc differ
diff --git a/addons/education_portal/services/__pycache__/razorpay_service.cpython-312.pyc b/addons/education_portal/services/__pycache__/razorpay_service.cpython-312.pyc
index 7ac0c7a..a986414 100644
Binary files a/addons/education_portal/services/__pycache__/razorpay_service.cpython-312.pyc and b/addons/education_portal/services/__pycache__/razorpay_service.cpython-312.pyc differ
diff --git a/addons/education_portal/services/__pycache__/reconciliation_service.cpython-312.pyc b/addons/education_portal/services/__pycache__/reconciliation_service.cpython-312.pyc
index 29917b0..c6d7ecd 100644
Binary files a/addons/education_portal/services/__pycache__/reconciliation_service.cpython-312.pyc and b/addons/education_portal/services/__pycache__/reconciliation_service.cpython-312.pyc differ
diff --git a/addons/education_portal/views/login_templates.xml b/addons/education_portal/views/login_templates.xml
index e9df3cd..32e1ca2 100644
--- a/addons/education_portal/views/login_templates.xml
+++ b/addons/education_portal/views/login_templates.xml
@@ -319,10 +319,10 @@