Skip to content

G1 : Integrate Other Academic Procedures V1 Module #1895

Open
SayanChakraborty08 wants to merge 24 commits into
FusionIIIT:o-academic-procedures-v1from
SayanChakraborty08:o-academic-procedures-v1
Open

G1 : Integrate Other Academic Procedures V1 Module #1895
SayanChakraborty08 wants to merge 24 commits into
FusionIIIT:o-academic-procedures-v1from
SayanChakraborty08:o-academic-procedures-v1

Conversation

@SayanChakraborty08
Copy link
Copy Markdown

Overview

This PR integrates the complete Other Academic Procedures V1 module (G1) into the o-academic-procedures-v1 branch.
All changes have been consolidated from the development branch (test-OAP-V1) and are ready for Team Lead review and merge.

What's Changed

📋 Core Features Added

  • TA Assignment Management: Full workflow for assigning graduate students as Teaching Assistants with validation rules
  • Thesis Assignment: PG thesis supervision assignment and tracking
  • Assistantship Claims: Student claims for assistantships with approval workflows
  • PG Faculty Supervisor Assignment: Assignment and management of PG faculty supervisors

🗂️ Files Modified (21 total)

  • Models (otheracademic/models.py): +259 lines

    • Added models for TA assignments, thesis assignments, faculty supervisors, and history tracking
    • Extended leave form models with contact fields
  • API Layer:

    • Serializers (otheracademic/api/serializers.py): +355 lines with comprehensive validation
    • Views (otheracademic/api/views.py): +2082 lines (refactored, net +818)
    • URLs (otheracademic/api/urls.py): +17 new endpoints
  • Business Logic (NEW):

    • services.py: +1294 lines (service layer for core business logic)
    • selectors.py: +650 lines (query optimizations and data retrieval)
    • test_*.py: Comprehensive unit and integration tests (+412 lines)
  • Notifications: Enhanced notification system for assignment approvals

  • Templates: Updated UI templates for bonafide forms and status pages

  • Migrations: 5 new migrations for database schema updates

🔍 Technical Highlights

  • Business logic separated into services/selectors (clean architecture)
  • Comprehensive test coverage for APIs, services, and selectors
  • All business rules (BRs) and validation checks enforced
  • Stable workflows implemented with proper state transitions

✅ Quality Assurance

  • All test suites passing
  • No dependencies on incomplete features
  • Database migrations included and tested
  • Follows project architecture and coding standards

📦 Changes Summary

  • Insertions: 4,330
  • Deletions: 1,264
  • Migration Version: 0006

Notes for Reviewer

  1. Code Review Focus: Verify business logic in services.py, API validation in serializers.py, and test coverage
  2. Testing: Run test suite to confirm all functionality works end-to-end
  3. Database: Migration 0006 should be applied cleanly to staging/production

Checklist

  • All commits squashed and properly described
  • Code follows project conventions
  • Tests included and passing
  • Migrations prepared
  • Ready for production deployment

SayanChakraborty08 and others added 24 commits March 23, 2026 15:59
…T17 deployment features

- Add analytics dashboard with system health checks and API call logging
- Implement feedback system with helpfulness tracking
- Add no-dues escalation and audit logging
- Add rejection remarks to Bonafide Certificate form
- Update URL routing and API serializers for new features
- Add database migrations for all new models
- Update docker entrypoint script

Task: Complete all 24 project tasks with full-stack implementation
feat: Implement T22/T23/T24 analytics, T14/T16 audit/escalation, and T17 deployment features
Revert "feat: Implement T22/T23/T24 analytics, T14/T16 audit/escalation, and T17 deployment features"
	modified:   FusionIIIT/applications/otheracademic/api/serializers.py
	modified:   FusionIIIT/applications/otheracademic/api/urls.py
	modified:   FusionIIIT/applications/otheracademic/api/views.py
Restore stable no-dues workflow
Copilot AI review requested due to automatic review settings May 8, 2026 13:47
@FusionIIIT-Bot
Copy link
Copy Markdown
Collaborator

Congratulations for making your first Pull Request at Fusion!! 🎉 Someone from our team will review it soon.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR integrates the “Other Academic Procedures V1 (G1)” module into the codebase by introducing a services/selectors layer, refactoring the otheracademic REST API endpoints around that architecture, and updating related templates/notifications to support new workflows (leave, bonafide, assistantship, assignments, and no-dues).

Changes:

  • Added a service + selector layer for otheracademic business logic and DB access, and refactored API views to call into it.
  • Extended/updated otheracademic models and introduced migrations for PG TA/faculty-supervisor assignment tracking and leave contact fields.
  • Updated bonafide templates to support file upload and safer rendering; enhanced notifications with a recipient_role for filtering.

Reviewed changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
FusionIIIT/templates/otheracademic/bonafideStatus.html Avoids crashing when download_file is missing by conditionally rendering the download link.
FusionIIIT/templates/otheracademic/bonafideForm.html Adds multipart upload support and a “Supporting Document” file input.
FusionIIIT/notification/views.py Extends otheracademic_notif to attach recipient_role into notifications.
FusionIIIT/applications/otheracademic/views.py Adjusts leave/bonafide handling (student name formatting, semester parsing, bonafide user lookup).
FusionIIIT/applications/otheracademic/services.py New services layer implementing workflows for leave, bonafide, assistantship, TA assignment, and faculty supervisor assignment.
FusionIIIT/applications/otheracademic/selectors.py New selectors layer implementing standardized DB read/query helpers and serializers.
FusionIIIT/applications/otheracademic/api/views.py Major refactor of otheracademic API views; adds new endpoints (withdraw flows, assignments, no-dues).
FusionIIIT/applications/otheracademic/api/urls.py Registers new API endpoints for withdraw, certificate upload, assignments, and no-dues.
FusionIIIT/applications/otheracademic/api/serializers.py Adds many input/output serializers for validation and response shapes.
FusionIIIT/applications/otheracademic/models.py Updates choice enums and adds TA/faculty supervisor assignment + history models; bonafide file field converted to FileField.
FusionIIIT/applications/otheracademic/migrations/0002_pgtaassignment.py Introduces initial PG TA assignment model.
FusionIIIT/applications/otheracademic/migrations/0003_pgfacultysupervisorassignment.py Introduces PG faculty supervisor assignment model.
FusionIIIT/applications/otheracademic/migrations/0004_assignment_history.py Adds immutable history tables for assignments.
FusionIIIT/applications/otheracademic/migrations/0005_alter_pgtaassignment_multiple_subjects.py Adjusts TA assignment schema and adds a uniqueness constraint.
FusionIIIT/applications/otheracademic/migrations/0006_leaveformtable_contact_fields.py Adds UG leave contact/semester fields.
FusionIIIT/applications/otheracademic/tests/test_services.py Adds service-layer tests (leave/bonafide/assistantship).
FusionIIIT/applications/otheracademic/tests/test_selectors.py Adds selector-layer tests (user lookup, pending queues, assignment query behavior).
FusionIIIT/applications/otheracademic/tests/test_api.py Adds API authentication/authorization tests for endpoints.
FusionIIIT/applications/otheracademic/tests/init.py Initializes the tests package.
FusionIIIT/applications/otheracademic/tempCodeRunnerFile.py New scratch file added (should not be committed).
FusionIIIT/applications/globals/api/views.py Filters notifications by recipient_role vs user’s active role.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 59 to +80
class LeaveFormSerializer(serializers.ModelSerializer):
"""Output serializer for leave form."""
class Meta:
model = LeaveFormTable
fields = '__all__'
fields = [
'id',
'student_name',
'roll_no',
'date_from',
'date_to',
'date_of_application',
'upload_file',
'address',
'purpose',
'leave_type',
'status',
'hod',
'stud_mobile_no',
'parent_mobile_no',
'leave_mobile_no',
'curr_sem',
]
Comment on lines +98 to +105
'status',
'hod',
'ta_supervisor',
'thesis_supervisor',
'stud_mobile_no',
'parent_mobile_no',
'leave_mobile_no',
'curr_sem',

class NoDuesStatusSerializer(serializers.ModelSerializer):
"""Output serializer for no-dues status."""
roll_no_value = serializers.CharField(source='roll_no.roll_no', read_only=True)
Comment on lines +39 to +55
@patch('applications.otheracademic.services.selectors.get_first_user_for_designation')
@patch('applications.otheracademic.services.otheracademic_notif')
def test_submit_bonafide_creates_record(self, mock_notif, mock_get_admin):
"""Test that submitting bonafide creates a record."""
mock_get_admin.return_value = None # No admin to notify

user = MagicMock()
user.first_name = 'Test'
user.last_name = 'User'
user.extrainfo = MagicMock()

result = services.submit_bonafide(
user=user,
branch='CSE',
semester='3',
purpose='Test Purpose',
)
Comment on lines +582 to +587
def get_pg_students_for_assignment():
"""Get PG students (M.Tech/PhD/M.Des) for assignment workflows."""
return Student.objects.select_related("id__user").filter(
programme__in=["M.Tech", "PhD", "M.Des"]
).exclude(id__id__iexact="23BCS229").order_by("id__id")

Comment on lines +2 to +82
from applications.otheracademic.models import (
LeaveFormTable,
LeavePG,
BonafideFormTableUpdated,
AssistantshipClaimFormStatusUpd,
NoDues,
LeaveStatusChoices,
)
from applications.globals.models import ExtraInfo, HoldsDesignation, Designation


# ==================== USER/DESIGNATION SELECTORS ====================

def get_user_by_username(username):
"""Get a user by username, returns None if not found."""
try:
return User.objects.get(username=username)
except User.DoesNotExist:
return None


def get_user_by_extrainfo_id(extrainfo_id):
"""Get a user by their extrainfo ID."""
try:
return User.objects.get(extrainfo=extrainfo_id)
except User.DoesNotExist:
return None


def get_user_by_extrainfo(extrainfo):
"""Get a user by their extrainfo object."""
try:
return User.objects.get(extrainfo=extrainfo)
except User.DoesNotExist:
return None


def get_first_designation_for_user(user):
"""Get the first designation for a user."""
designations = HoldsDesignation.objects.filter(user=user)
if designations.exists():
return designations.first().designation
return None


def get_first_user_for_designation(designation_name):
"""
Get the first user who holds a specific designation.
Used for routing notifications to admin roles.
"""
try:
designation = Designation.objects.get(name=designation_name)
user_ids = HoldsDesignation.objects.filter(
designation_id=designation.id
).values_list('user_id', flat=True)

if user_ids.exists():
return User.objects.get(id=user_ids[0])
except (Designation.DoesNotExist, User.DoesNotExist):
pass
return None


# ==================== LEAVE SELECTORS ====================

def get_pending_ug_leaves():
"""Get all pending UG leave requests."""
return LeaveFormTable.objects.filter(status=LeaveStatusChoices.PENDING)


def get_pending_pg_leaves_for_ta():
"""Get all pending PG leave requests (for TA approval)."""
return LeavePG.objects.filter(status=LeaveStatusChoices.PENDING)


def get_pending_pg_leaves_for_thesis():
"""Get PG leave requests pending thesis supervisor approval."""
return LeavePG.objects.filter(status=F('ta_supervisor'))


def get_pending_pg_leaves_for_hod():
Comment on lines +1 to +2
import ast

Comment on lines +124 to +130
if isinstance(data, dict):
parsed_data = data
elif isinstance(data, str):
try:
parsed_data = ast.literal_eval(data)
except Exception:
parsed_data = {}
Comment on lines 721 to 727
leave_entry = BonafideFormTableUpdated.objects.get(id=leave_id)
leave_entry.approve = True
leave_entry.save()
bonafide_aceptor = User.objects.get(username=leave_entry.roll_nos_id)
bonafide_aceptor = leave_entry.roll_nos.user
message='A Bonafide uploaded'
otheracademic_notif(request.user,bonafide_aceptor, 'bonafide_accept', 1, 'student', message)
return redirect('/otheracademic/bonafideApproveForm') # Redirect to appropriate page after approval
Comment on lines +689 to +698
# Create assistantship form
assistantship_form = AssistantshipClaimFormStatusUpd.objects.create(
roll_no=user.extrainfo,
student_name=f"{user.first_name} {user.last_name}",
discipline=discipline,
dateFrom=date_from,
dateTo=date_to,
bank_account=bank_account,
student_signature=signature_file,
dateApplied=date_applied,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants