Fakultas Ilmu Komputer UI

vacancies.py 8.95 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

10
from core.lib.mixins import MultiSerializerViewSetMixin
11
from core.lib.permissions import IsAdminOrStudent, IsAdminOrCompany, IsAdminOrVacancyOwner, VacancyApprovalPermission
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
    VacancyApplicationSerializer, PostVacancySerializer, VacancyVerifiedSerializer
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

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

31
32
    def list(self, request, *args, **kwargs):
        vacancies = Vacancy.objects.all()
33
34
        verified = request.query_params['verified'] if 'verified' in request.query_params else "True"
        if verified.lower() in ("yes", "true", "t", "1"):
35
            vacancies = vacancies.filter(verified=True)
36
37
        if verified.lower() in {"no", "false", "f", "0"}:
            vacancies = vacancies.filter(verified=False)
38

39
40
        return Response(VacancySerializer(vacancies, many=True, context={'request': request}).data)

41
42
43
44
45
46
47
    @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)

48
49
50
51
52
53
54
55
56
    @detail_route(methods=['patch'], permission_classes=[VacancyApprovalPermission], serializer_class=VacancyVerifiedSerializer)
    def verify(self, request, pk=None):
        vacancy = self.get_object()
        serializer = self.get_serializer_class()(vacancy, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response({"error" : "bad request"}, status=status.HTTP_400_BAD_REQUEST)

57

58
class ApplicationViewSet(viewsets.GenericViewSet):
59
    serializer_class = ApplicationSerializer
60
    permission_classes = [IsAdminOrStudent]
61

62
    def list(self, request, student_id):
63
        """
64
        Get list of a student {student_id}'s applications
65
66
        ---
        """
67
        student = get_object_or_404(Student.objects.all(), pk=student_id)
68
69
        applications = Application.objects.filter(student=student)
        return Response(VacancyApplicationSerializer(applications, many=True, context={'request': request}).data)
70
71

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

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

102

103
104
class CompanyApplicationViewSet(viewsets.GenericViewSet):
    queryset = Application.objects.all()
105
    permission_classes = [IsAdminOrCompany]
106
107
108
109
110
111
112

    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)
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
        return Response(ApplicationSerializer(applications, many=True, context={'request': request}).data)


120
121
122
123
124
125
126
127
128
129
130
131
132
133
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)

134
135
136
137
138
139
140
141
    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']
142
            resp = s.post('https://api.cs.ui.ac.id/api-auth/login/', data={'username' : credentials["user"], 'password' : credentials["password"], 'csrfmiddlewaretoken' : csrf})
143
            response = s.get('https://api.cs.ui.ac.id/siakngcs/mahasiswa/' + str(student.npm) + '/riwayat/')
144
            return Response({'name' : student.full_name, 'transcript' : response.json()}, status=status.HTTP_200_OK)
145
        else:
146
            return Response({'name' : student.full_name, 'error' : 'student does not allow transcript to be shown'}, status=status.HTTP_200_OK)
147

148

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

    def list(self, request, company_id):
        """
        Get list of company {company_id}'s vacancies
        ---
        """
158
159
        company = get_object_or_404(Company.objects.all().order_by('-updated'), pk=company_id)
        vacancies = Vacancy.objects.filter(company=company)
160
161
162
        return Response(VacancySerializer(vacancies, many=True, context={'request': request}).data)


163
164
165
166
167
class BookmarkedVacancyByStudentViewSet(viewsets.GenericViewSet):
    serializer_class = VacancySerializer
    permission_classes = [IsAdminOrStudent]

    def list(self, request, student_id):
168
169
170
171
        """
        Get list of a student {student_id}'s bookmarked vacancies
        ---
        """
172
173
174
175
176
        student = get_object_or_404(Student.objects.all(), pk=student_id)
        vacancies = self.serializer_class(student.bookmarked_vacancies, many=True, context={'request': request})
        return Response(vacancies.data)

    def create(self, request, student_id):
177
178
179
180
181
182
183
184
185
186
        """
        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
        """
187
188
189
190
191
192
        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):
193
194
195
196
        """
        Remove bookmark {id} for student {student_id}
        ---
        """
197
198
199
200
        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)