Fakultas Ilmu Komputer UI

vacancies.py 8.84 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
38
        return Response(VacancySerializer(vacancies, many=True, context={'request': request}).data)

39
40
41
42
43
44
45
    @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)

46
47
48
49
50
51
52
53
54
    @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)

55

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

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

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

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

100

101
102
class CompanyApplicationViewSet(viewsets.GenericViewSet):
    queryset = Application.objects.all()
103
    permission_classes = [IsAdminOrCompany]
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
        return Response(ApplicationSerializer(applications, many=True, context={'request': request}).data)


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

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

146

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

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


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

    def list(self, request, student_id):
166
167
168
169
        """
        Get list of a student {student_id}'s bookmarked vacancies
        ---
        """
170
171
172
173
174
        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):
175
176
177
178
179
180
181
182
183
184
        """
        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
        """
185
186
187
188
189
190
        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):
191
192
193
194
        """
        Remove bookmark {id} for student {student_id}
        ---
        """
195
196
197
198
        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)