Fakultas Ilmu Komputer UI

vacancies.py 9.47 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
154
155
156
157
158

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


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

    def list(self, request, student_id):
172
173
174
175
        """
        Get list of a student {student_id}'s bookmarked vacancies
        ---
        """
176
        student = get_object_or_404(Student.objects.all(), pk=student_id)
177
178
179
180
181
        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)
182
183

    def create(self, request, student_id):
184
185
186
187
188
189
190
191
192
193
        """
        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
        """
194
195
196
197
198
199
        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):
200
201
202
203
        """
        Remove bookmark {id} for student {student_id}
        ---
        """
204
205
206
207
        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)