G1 : Integrate Other Academic Procedures V1 Module #1895
Open
SayanChakraborty08 wants to merge 24 commits into
Open
G1 : Integrate Other Academic Procedures V1 Module #1895SayanChakraborty08 wants to merge 24 commits into
SayanChakraborty08 wants to merge 24 commits into
Conversation
…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
…on, 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
fix notifications
lots of bug fixes
final commit hopefully
Collaborator
|
Congratulations for making your first Pull Request at Fusion!! 🎉 Someone from our team will review it soon. |
There was a problem hiding this comment.
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_rolefor 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, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This PR integrates the complete Other Academic Procedures V1 module (G1) into the
o-academic-procedures-v1branch.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
🗂️ Files Modified (21 total)
Models (otheracademic/models.py): +259 lines
API Layer:
Business Logic (NEW):
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
✅ Quality Assurance
📦 Changes Summary
Notes for Reviewer
Checklist