Skip to content

Commit aa1bf67

Browse files
Merge pull request #131 from YogeshUpdhyay/main
Stats API
2 parents b6c293a + a76ec0d commit aa1bf67

File tree

6 files changed

+90
-5
lines changed

6 files changed

+90
-5
lines changed

apps/applicants/serializers.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,7 @@ class Meta:
5151
]
5252

5353

54+
class ApplicationStatsResponseSerializer(serializers.Serializer):
55+
applied_jobs = serializers.IntegerField()
56+
recruiter_actions = serializers.IntegerField()
57+
shortlisted_jobs = serializers.IntegerField()

apps/applicants/urls.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
AllApplicantsOfCompany,
55
ApplyToJob,
66
UpdateApplicationStatus, GetAppliedJobs,
7+
ApplicationStats
78
)
89

910
urlpatterns = [
@@ -15,4 +16,9 @@
1516
UpdateApplicationStatus.as_view(),
1617
name="updateapplicationstatus",
1718
),
19+
path(
20+
"application/stats",
21+
ApplicationStats.as_view(),
22+
name="applicationstats"
23+
)
1824
]

apps/applicants/views.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
from rest_framework import exceptions, permissions, status
33
from rest_framework.response import Response
44
from rest_framework.views import APIView
5+
from django.db.models import Count, Q
56

67
from apps.accounts.permissions import IsEmployer, IsJobSeeker, IsProfileCompleted
78
from apps.applicants.models import Applicants
89
from apps.applicants.serializers import (
910
ApplicantModelSerializer,
1011
ApplyToJobSerializer,
1112
UpdateApplicationStatusSerializer, AppliedJobSerializer,
13+
ApplicationStatsResponseSerializer
1214
)
1315
from apps.jobs.models import Job
1416
from apps.userprofile.models import UserProfile
17+
from apps.utils.responses import InternalServerError
1518

1619

1720
class AllApplicantsOfCompany(APIView):
@@ -123,3 +126,23 @@ def get(self, request):
123126
AppliedJobSerializer(applicants, many=True).data,
124127
status=status.HTTP_200_OK
125128
)
129+
130+
131+
class ApplicationStats(APIView):
132+
133+
permission_classes = [permissions.IsAuthenticated, IsJobSeeker]
134+
135+
@extend_schema(responses={200: ApplicationStatsResponseSerializer}, tags=["applications"])
136+
def get(self, request):
137+
try:
138+
userprofile = UserProfile.objects.get(user=request.user)
139+
counts = Applicants.objects.filter(user=userprofile).aggregate(
140+
applied_jobs=Count('id'),
141+
recruiter_actions=Count('id', filter=~Q(status='applied')),
142+
shortlisted_jobs=Count('id', filter=Q(status='shortlisted'))
143+
)
144+
145+
return Response(ApplicationStatsResponseSerializer(counts).data, status=status.HTTP_200_OK)
146+
except Exception as e:
147+
raise InternalServerError()
148+

apps/jobs/serializers.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,10 @@ class JobsCountByCategoriesSerializer(serializers.Serializer):
8585
category = serializers.CharField()
8686
count = serializers.CharField()
8787

88+
89+
class CompanyStatsResponseSerializer(serializers.Serializer):
90+
job_count = serializers.IntegerField()
91+
applications_count = serializers.IntegerField()
92+
reviewed_count = serializers.IntegerField()
93+
shortlisted_count = serializers.IntegerField()
94+

apps/jobs/urls.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from apps.jobs.views import (
55
CompanyViewSets, ContactUsViewSet,
6-
JobViewSets
6+
JobViewSets, CompanyStats
77
)
88

99
# app name for namespace
@@ -17,4 +17,9 @@
1717

1818
urlpatterns = [
1919
path("", include(router.urls), name="Default"),
20+
path(
21+
"company/stats",
22+
CompanyStats.as_view(),
23+
name="companystats"
24+
)
2025
]

apps/jobs/views.py

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1-
1+
from django.db import connection
22
from django.db.models import Count
33
import django_filters.rest_framework as df_filters
4-
from django.db.models import BooleanField, Case, Value, When
54
from drf_spectacular.utils import extend_schema
6-
from rest_framework import exceptions, parsers, status, viewsets, filters
75
from rest_framework.decorators import action
86
from rest_framework.response import Response
7+
from rest_framework.views import APIView
98
from rest_framework.permissions import IsAuthenticated
9+
from django.db.models import BooleanField, Case, Value, When
10+
from rest_framework import exceptions, parsers, status, viewsets, filters
11+
1012

1113
from apps.accounts.permissions import Moderator
1214
from apps.jobs.constants import response, values
1315
from apps.userprofile.models import UserProfile
16+
from apps.applicants.models import Applicants
1417
from apps.jobs.models import Company, ContactMessage, Job
1518
from apps.accounts.permissions import IsEmployer
16-
from apps.jobs.serializers import CompanySerializer, ContactUsSerializer, JobSerializer, JobsCountByCategoriesSerializer
19+
from apps.jobs.serializers import CompanySerializer, ContactUsSerializer, JobSerializer, JobsCountByCategoriesSerializer, CompanyStatsResponseSerializer
1720
from apps.jobs.utils.validators import validationClass
1821
from apps.utils.responses import InternalServerError
1922
from apps.utils.pagination import DefaultPagination
@@ -403,3 +406,40 @@ def list(self, request, *args, **kwargs):
403406
return super().list(request, *args, **kwargs)
404407
else:
405408
return super().list(request, *args, **kwargs)
409+
410+
411+
class CompanyStats(APIView):
412+
413+
permission_classes = [IsAuthenticated, IsEmployer]
414+
415+
@extend_schema(tags=["company"], responses={200: CompanyStatsResponseSerializer})
416+
def get(self, request):
417+
"""Get company stats"""
418+
try:
419+
raw_query = """
420+
SELECT
421+
COUNT(DISTINCT(tj.job_id)) AS job_count,
422+
COUNT(ta.id) AS applications_count,
423+
COUNT(CASE WHEN ta.status != 'applied' THEN 1 ELSE NULL END) AS reviewed_count,
424+
COUNT(CASE WHEN ta.status = 'shortlisted' THEN 1 ELSE NULL END) AS shortlisted_count
425+
FROM tbl_job tj
426+
JOIN tbl_applicants ta ON tj.job_id = ta.job_id
427+
WHERE tj.employer_id = %s
428+
"""
429+
430+
# Execute the raw SQL query
431+
with connection.cursor() as cursor:
432+
cursor.execute(raw_query, [str(request.user.id).replace("-", "")])
433+
result = cursor.fetchone()
434+
435+
job_count, applications_count, reviewed_count, shortlisted_count = result
436+
company_stats = CompanyStatsResponseSerializer({
437+
"job_count": job_count,
438+
"applications_count": applications_count,
439+
"reviewed_count": reviewed_count,
440+
"shortlisted_count": shortlisted_count
441+
})
442+
443+
return Response(company_stats.data)
444+
except Exception as e:
445+
raise InternalServerError()

0 commit comments

Comments
 (0)