Skip to content

Commit 32e9add

Browse files
committed
feat: filter PDF reports by current year
Ensures that all generated PDF reports (grades, presence, academic, and financial) only include data relevant to the current year. Changes include: - **api/students/views.py**: - Updated `download_presence_pdf` to filter `Presence` records by `date__year=current_year`. - Modified `download_academic_report` and `download_financial_report` to define `current_year` and pass it to their respective report generation functions. - **api/utils/reports.py**: - Updated `generate_student_academic_report` to accept a `year` parameter (defaulting to current year) and apply it to all `Grade`, `Presence`, `Warning`, and `Suspension` queries. - Updated `generate_financial_report` to accept a `year` parameter (defaulting to current year) and apply it to `Tuition` queries using `reference_month__year=year`.
1 parent db9de86 commit 32e9add

2 files changed

Lines changed: 39 additions & 22 deletions

File tree

api/students/views.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,10 @@ def download_grades_pdf(self, request, pk=None):
9999
@action(detail=True, methods=["get"], url_path="download-presence")
100100
def download_presence_pdf(self, request, pk=None):
101101
student = self.get_object()
102-
presence_records = Presence.objects.filter(student=student)
102+
current_year = timezone.now().year
103+
presence_records = Presence.objects.filter(
104+
student=student, date__year=current_year
105+
)
103106
return pdfgen(
104107
"presence.html",
105108
{"student": student, "data": presence_records},
@@ -116,10 +119,9 @@ def academic_report(self, request, pk=None):
116119
@action(detail=True, methods=["get"], url_path="download-academic-report")
117120
def download_academic_report(self, request, pk=None):
118121
"""Download comprehensive academic report PDF"""
119-
from django.utils import timezone as tz
120-
122+
current_year = timezone.now().year
121123
student = self.get_object()
122-
report = generate_student_academic_report(student)
124+
report = generate_student_academic_report(student, year=current_year)
123125

124126
context = {
125127
"student": student,
@@ -364,11 +366,10 @@ def financial_report(self, request):
364366
@action(detail=False, methods=["get"], url_path="download-financial-report")
365367
def download_financial_report(self, request):
366368
"""Download financial report PDF"""
367-
from django.utils import timezone as tz
368-
369+
current_year = timezone.now().year
369370
student_id = request.query_params.get("student_id")
370371
student = Student.objects.get(id=student_id) if student_id else None
371-
report = generate_financial_report(student)
372+
report = generate_financial_report(student, year=current_year)
372373

373374
context = {
374375
"student": student,

api/utils/reports.py

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,19 @@
1919
)
2020

2121

22-
def generate_student_academic_report(student):
22+
def generate_student_academic_report(student, year=None):
2323
"""Generate comprehensive academic report for a single student"""
24+
if year is None:
25+
year = timezone.now().year
2426

2527
# Get all grades by subject and bimester
2628
grades_by_subject = {}
2729
all_subjects = Subject.objects.all()
2830

2931
for subject in all_subjects:
30-
grades = Grade.objects.filter(student=student, subject=subject).order_by(
31-
"bimester"
32-
)
32+
grades = Grade.objects.filter(
33+
student=student, subject=subject, year=year
34+
).order_by("bimester")
3335
bimester_grades = {"1B": None, "2B": None, "3B": None, "4B": None}
3436

3537
for grade in grades:
@@ -45,20 +47,28 @@ def generate_student_academic_report(student):
4547
}
4648

4749
# Get attendance statistics
48-
total_days = Presence.objects.filter(student=student).count()
49-
absences = Presence.objects.filter(student=student, presence=False).count()
50-
presences = Presence.objects.filter(student=student, presence=True).count()
50+
total_days = Presence.objects.filter(student=student, date__year=year).count()
51+
absences = Presence.objects.filter(
52+
student=student, presence=False, date__year=year
53+
).count()
54+
presences = Presence.objects.filter(
55+
student=student, presence=True, date__year=year
56+
).count()
5157
absence_rate = (absences / total_days * 100) if total_days > 0 else 0
5258

5359
# Get disciplinary records
54-
warnings_count = Warning.objects.filter(student=student).count()
55-
suspensions_count = Suspension.objects.filter(student=student).count()
60+
warnings_count = Warning.objects.filter(student=student, date__year=year).count()
61+
suspensions_count = Suspension.objects.filter(
62+
student=student, start_date__year=year
63+
).count()
5664

5765
# Get recent warnings and suspensions
58-
recent_warnings = Warning.objects.filter(student=student).order_by("-date")[:5]
59-
recent_suspensions = Suspension.objects.filter(student=student).order_by(
60-
"-start_date"
66+
recent_warnings = Warning.objects.filter(student=student, date__year=year).order_by(
67+
"-date"
6168
)[:5]
69+
recent_suspensions = Suspension.objects.filter(
70+
student=student, start_date__year=year
71+
).order_by("-start_date")[:5]
6272

6373
return {
6474
"student_id": student.id,
@@ -174,13 +184,19 @@ def generate_group_performance_report(group):
174184
}
175185

176186

177-
def generate_financial_report(student=None):
187+
def generate_financial_report(student=None, year=None):
178188
"""Generate financial report for tuition payments"""
189+
if year is None:
190+
year = timezone.now().year
179191

180192
if student:
181-
tuitions = Tuition.objects.filter(student=student).order_by("-reference_month")
193+
tuitions = Tuition.objects.filter(
194+
student=student, reference_month__year=year
195+
).order_by("-reference_month")
182196
else:
183-
tuitions = Tuition.objects.all().order_by("-reference_month")
197+
tuitions = Tuition.objects.filter(reference_month__year=year).order_by(
198+
"-reference_month"
199+
)
184200

185201
# Summary statistics
186202
total_pending = tuitions.filter(status="PENDING").count()

0 commit comments

Comments
 (0)