Fakultas Ilmu Komputer UI

vacancies.py 10.8 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
        if not request.user.is_superuser and request.user != company.user:
            return Response({"error": "forbidden"}, status=status.HTTP_403_FORBIDDEN)
113
114
115
116
        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'])
117
118
119
        page = self.paginate_queryset(applications)
        if page is not None:
            return self.get_paginated_response(ApplicationSerializer(page, many=True, context={'request': request}).data)
120
121
        return Response(ApplicationSerializer(applications, many=True, context={'request': request}).data)

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
    @detail_route(methods=["get"])
    def by_vacancy(self, request, company_id, pk=None):
        if pk is None:
            return list(self, request, company_id)
        company = get_object_or_404(Company.objects.all().order_by('-updated'), pk=company_id)
        if not request.user.is_superuser and request.user != company.user:
            return Response({"error": "forbidden"}, status=status.HTTP_403_FORBIDDEN)
        vacancy = get_object_or_404(Vacancy.objects.all(), pk=pk)
        if vacancy.company != company:
            return Response({"error": "forbidden"}, status=status.HTTP_403_FORBIDDEN)
        applications = Application.objects.filter(vacancy=vacancy)
        page = self.paginate_queryset(applications)
        if page is not None:
            return self.get_paginated_response(
                ApplicationSerializer(page, many=True, context={'request': request}).data)
        return Response(ApplicationSerializer(applications, many=True, context={'request': request}).data)

139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
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)

154
155
156
157
158
159
160
161
    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']
162
            resp = s.post('https://api.cs.ui.ac.id/api-auth/login/', data={'username' : credentials["user"], 'password' : credentials["password"], 'csrfmiddlewaretoken' : csrf})
163
            response = s.get('https://api.cs.ui.ac.id/siakngcs/mahasiswa/' + str(student.npm) + '/riwayat/')
164
            return Response({'name' : student.full_name, 'transcript' : response.json()}, status=status.HTTP_200_OK)
165
        else:
166
            return Response({'name' : student.full_name, 'error' : 'student does not allow transcript to be shown'}, status=status.HTTP_200_OK)
167

168

169
class CompanyVacanciesViewSet(viewsets.GenericViewSet):
170
    queryset = Vacancy.objects.all()
171
    pagination_class = PageNumberPagination
172
    permission_classes = [IsAdminOrCompany]
173
174
175
176
177
178

    def list(self, request, company_id):
        """
        Get list of company {company_id}'s vacancies
        ---
        """
179
        company = get_object_or_404(Company.objects.all().order_by('-updated'), pk=company_id)
180
181
        if not request.user.is_superuser and request.user != company.user:
            return Response({"error": "forbidden"}, status=status.HTTP_403_FORBIDDEN)
182
        vacancies = Vacancy.objects.filter(company=company)
183
184
185
        page = self.paginate_queryset(vacancies)
        if page is not None:
            return self.get_paginated_response(VacancySerializer(page, many=True, context={'request': request}).data)
186
187
188
        return Response(VacancySerializer(vacancies, many=True, context={'request': request}).data)


189
190
191
192
193
class BookmarkedVacancyByStudentViewSet(viewsets.GenericViewSet):
    serializer_class = VacancySerializer
    permission_classes = [IsAdminOrStudent]

    def list(self, request, student_id):
194
195
196
197
        """
        Get list of a student {student_id}'s bookmarked vacancies
        ---
        """
198
        student = get_object_or_404(Student.objects.all(), pk=student_id)
199
200
201
202
203
        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)
204
205

    def create(self, request, student_id):
206
207
208
209
210
211
212
213
214
215
        """
        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
        """
216
217
218
219
220
221
        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):
222
223
224
225
        """
        Remove bookmark {id} for student {student_id}
        ---
        """
226
227
228
229
        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)