Fakultas Ilmu Komputer UI

vacancies.py 9.51 KB
Newer Older
1
2
import requests
from django.conf import settings
3
from rest_framework import viewsets, status
4
from rest_framework.decorators import detail_route
5
from rest_framework.exceptions import ValidationError
6
from rest_framework.generics import get_object_or_404
7
from rest_framework.permissions import IsAuthenticated
8
from rest_framework.response import Response
9
from rest_framework.pagination import PageNumberPagination
10
from core.lib.mixins import MultiSerializerViewSetMixin
11
from core.lib.permissions import IsAdminOrStudent, IsAdminOrCompany, IsAdminOrVacancyOwner
12
from core.models import Student, Company
13
from core.models.vacancies import Vacancy, Application
14
from core.serializers.vacancies import VacancySerializer, ApplicationSerializer, ApplicationStatusSerializer, \
15
    PostVacancySerializer
16
17


18
class VacancyViewSet(MultiSerializerViewSetMixin, viewsets.ModelViewSet):
19
    queryset = Vacancy.objects.all()
20
    serializer_class = VacancySerializer
21
22
23
    serializer_action_classes = {
        'create': PostVacancySerializer
    }
24
    permission_classes = [IsAdminOrCompany]
25
    pagination_class = PageNumberPagination
26

27
    def get_permissions(self):
28
        if self.action in ["retrieve", "list"]:
29
30
31
            return [IsAuthenticated()]
        return super(VacancyViewSet, self).get_permissions()

32
33
    def list(self, request, *args, **kwargs):
        vacancies = Vacancy.objects.all()
34
35
        verified = request.query_params['verified'] if 'verified' in request.query_params else "True"
        if verified.lower() in ("yes", "true", "t", "1"):
36
            vacancies = vacancies.filter(verified=True)
37
38
39
        page = self.paginate_queryset(vacancies)
        if page is not None:
            return self.get_paginated_response(VacancySerializer(page, many=True, context={'request': request}).data)
40
41
        return Response(VacancySerializer(vacancies, many=True, context={'request': request}).data)

42
43
44
45
46
47
48
    @detail_route(permission_classes=[IsAdminOrCompany])
    def count(self, request, pk=None):
        vacancy = self.get_object()
        count = Application.objects.filter(vacancy=vacancy).count()
        count_new = Application.objects.filter(vacancy=vacancy, status=Application.NEW).count()
        return Response({"count": count, "count_new": count_new}, status=status.HTTP_200_OK)

49

50
class ApplicationViewSet(viewsets.GenericViewSet):
51
    serializer_class = ApplicationSerializer
52
    permission_classes = [IsAdminOrStudent]
53
    pagination_class = PageNumberPagination
54

55
    def list(self, request, student_id):
56
        """
57
        Get list of a student {student_id}'s applied vacancies
58
59
        ---
        """
60
        student = get_object_or_404(Student.objects.all(), pk=student_id)
61
62
63
64
65
66
        vacancy_ids = Application.objects.filter(student=student).values('vacancy')
        vacancies = Vacancy.objects.filter(id__in=vacancy_ids)
        page = self.paginate_queryset(vacancies)
        if page is not None:
            return self.get_paginated_response(VacancySerializer(page, many=True, context={'request': request}).data)
        return Response(VacancySerializer(vacancies, many=True, context={'request': request}).data)
67
68

    def create(self, request, student_id):
69
70
71
72
73
        """
        Create a new application for student {student_id}
        ---
        parameters:
            - name: body
74
              description: JSON object containing an integer 'vacancy_id' and a string 'cover_letter'
75
76
77
78
              required: true
              type: string
              paramType: body
        """
79
80
        cover_letter = request.data.get('cover_letter')
        vacancy = get_object_or_404(Vacancy.objects.all(), pk=request.data.get('vacancy_id'))
81
        student = get_object_or_404(Student.objects.all(), pk=student_id)
82
83
        if Application.objects.filter(vacancy=vacancy, student=student).exists():
            raise ValidationError("You have already applied for the vacancy")
84
85
86
        application = Application(vacancy=vacancy, student=student, cover_letter=cover_letter)
        application.save()
        return Response(ApplicationSerializer(application, context={'request': request}).data)
87
88

    def destroy(self, request, student_id, pk):
89
90
91
92
        """
        Remove a application {id} for student {student_id}
        ---
        """
93
94
        vacancy = get_object_or_404(Vacancy.objects.all(), pk=pk)
        student = get_object_or_404(Student.objects.all(), pk=student_id)
95
        application = get_object_or_404(Application.objects.all(), student=student, vacancy=vacancy)
96
        application.delete()
97
        return Response(ApplicationSerializer(application, context={'request': request}).data)
98

99

100
101
class CompanyApplicationViewSet(viewsets.GenericViewSet):
    queryset = Application.objects.all()
102
    permission_classes = [IsAdminOrCompany]
103
    pagination_class = PageNumberPagination
104
105
106
107
108
109
110

    def list(self, request, company_id):
        """
        Get list of company {company_id}'s applications
        ---
        """
        company = get_object_or_404(Company.objects.all(), pk=company_id)
111
112
113
114
        vacancies = Vacancy.objects.filter(company=company)
        applications = Application.objects.filter(vacancy__in=vacancies)
        if 'status' in request.query_params:
            applications = applications.filter(status=request.query_params['status'])
115
116
117
        page = self.paginate_queryset(applications)
        if page is not None:
            return self.get_paginated_response(ApplicationSerializer(page, many=True, context={'request': request}).data)
118
119
120
        return Response(ApplicationSerializer(applications, many=True, context={'request': request}).data)


121
122
123
124
125
126
127
128
129
130
131
132
133
134
class CompanyApplicationStatusViewSet(viewsets.GenericViewSet):
    queryset = Application.objects.all()
    serializer_class = ApplicationStatusSerializer
    permission_classes = [IsAdminOrVacancyOwner]

    def partial_update(self, request, pk=None):
        application = self.get_object()
        serializer = self.get_serializer_class()(application, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

135
136
137
138
139
140
141
142
    def retrieve(self, request, pk=None):
        application = self.get_object()
        student = application.student
        if student.show_transcript:
            s = requests.Session()
            credentials = settings.API_CS_CREDENTIALS
            s.get('https://api.cs.ui.ac.id/api-auth/login/')
            csrf = s.cookies['csrftoken']
143
            resp = s.post('https://api.cs.ui.ac.id/api-auth/login/', data={'username' : credentials["user"], 'password' : credentials["password"], 'csrfmiddlewaretoken' : csrf})
144
            response = s.get('https://api.cs.ui.ac.id/siakngcs/mahasiswa/' + str(student.npm) + '/riwayat/')
145
            return Response({'name' : student.full_name, 'transcript' : response.json()}, status=status.HTTP_200_OK)
146
        else:
147
            return Response({'name' : student.full_name, 'error' : 'student does not allow transcript to be shown'}, status=status.HTTP_200_OK)
148

149

150
class CompanyVacanciesViewSet(viewsets.GenericViewSet):
151
    queryset = Vacancy.objects.all()
152
    pagination_class = PageNumberPagination
153
    permission_classes = [IsAdminOrCompany]
154
155
156
157
158
159

    def list(self, request, company_id):
        """
        Get list of company {company_id}'s vacancies
        ---
        """
160
161
        company = get_object_or_404(Company.objects.all().order_by('-updated'), pk=company_id)
        vacancies = Vacancy.objects.filter(company=company)
162
163
164
        page = self.paginate_queryset(vacancies)
        if page is not None:
            return self.get_paginated_response(VacancySerializer(page, many=True, context={'request': request}).data)
165
166
167
        return Response(VacancySerializer(vacancies, many=True, context={'request': request}).data)


168
169
170
171
172
class BookmarkedVacancyByStudentViewSet(viewsets.GenericViewSet):
    serializer_class = VacancySerializer
    permission_classes = [IsAdminOrStudent]

    def list(self, request, student_id):
173
174
175
176
        """
        Get list of a student {student_id}'s bookmarked vacancies
        ---
        """
177
        student = get_object_or_404(Student.objects.all(), pk=student_id)
178
179
180
181
182
        vacancies = student.bookmarked_vacancies.all()
        page = self.paginate_queryset(vacancies)
        if page is not None:
            return self.get_paginated_response(VacancySerializer(page, many=True, context={'request': request}).data)
        return Response(VacancySerializer(vacancies, many=True, context={'request': request}).data)
183
184

    def create(self, request, student_id):
185
186
187
188
189
190
191
192
193
194
        """
        Bookmarks a vacancy for student {student_id}
        ---
        parameters:
            - name: body
              description: JSON object containing only one string: vacancy_id
              required: true
              type: string
              paramType: body
        """
195
196
197
198
199
200
        vacancy = get_object_or_404(Vacancy.objects.all(), pk=request.data['vacancy_id'])
        student = get_object_or_404(Student.objects.all(), pk=student_id)
        student.bookmarked_vacancies.add(vacancy)
        return Response(self.serializer_class(student.bookmarked_vacancies, many=True, context={'request': request}).data)

    def destroy(self, request, student_id, pk):
201
202
203
204
        """
        Remove bookmark {id} for student {student_id}
        ---
        """
205
206
207
208
        vacancy = get_object_or_404(Vacancy.objects.all(), pk=pk)
        student = get_object_or_404(Student.objects.all(), pk=student_id)
        student.bookmarked_vacancies.remove(vacancy)
        return Response(self.serializer_class(student.bookmarked_vacancies, many=True, context={'request': request}).data)