Fakultas Ilmu Komputer UI

vacancies.py 8.28 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
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
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
class ApplicationViewSet(viewsets.GenericViewSet):
48
    serializer_class = ApplicationSerializer
49
    permission_classes = [IsAdminOrStudent]
50

51
    def list(self, request, student_id):
52
        """
53
        Get list of a student {student_id}'s applications
54
55
        ---
        """
56
        student = get_object_or_404(Student.objects.all(), pk=student_id)
57
58
        applications = Application.objects.filter(student=student)
        return Response(VacancyApplicationSerializer(applications, many=True, context={'request': request}).data)
59
60

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

    def destroy(self, request, student_id, pk):
81
82
83
84
        """
        Remove a application {id} for student {student_id}
        ---
        """
85
86
        vacancy = get_object_or_404(Vacancy.objects.all(), pk=pk)
        student = get_object_or_404(Student.objects.all(), pk=student_id)
87
        application = get_object_or_404(Application.objects.all(), student=student, vacancy=vacancy)
88
        application.delete()
89
        return Response(ApplicationSerializer(application, context={'request': request}).data)
90

91

92
93
class CompanyApplicationViewSet(viewsets.GenericViewSet):
    queryset = Application.objects.all()
94
    permission_classes = [IsAdminOrCompany]
95
96
97
98
99
100
101

    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)
102
103
104
105
        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'])
106
107
108
        return Response(ApplicationSerializer(applications, many=True, context={'request': request}).data)


109
110
111
112
113
114
115
116
117
118
119
120
121
122
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)

123
124
125
126
127
128
129
130
    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']
131
            resp = s.post('https://api.cs.ui.ac.id/api-auth/login/', data={'username' : credentials["user"], 'password' : credentials["password"], 'csrfmiddlewaretoken' : csrf})
132
            response = s.get('https://api.cs.ui.ac.id/siakngcs/mahasiswa/' + str(student.npm) + '/riwayat/')
133
            return Response({'name' : student.full_name, 'transcript' : response.json()}, status=status.HTTP_200_OK)
134
        else:
135
            return Response({'name' : student.full_name, 'error' : 'student does not allow transcript to be shown'}, status=status.HTTP_200_OK)
136

137

138
class CompanyVacanciesViewSet(viewsets.GenericViewSet):
139
    queryset = Vacancy.objects.all()
140
    permission_classes = [IsAdminOrCompany]
141
142
143
144
145
146

    def list(self, request, company_id):
        """
        Get list of company {company_id}'s vacancies
        ---
        """
147
148
        company = get_object_or_404(Company.objects.all().order_by('-updated'), pk=company_id)
        vacancies = Vacancy.objects.filter(company=company)
149
150
151
        return Response(VacancySerializer(vacancies, many=True, context={'request': request}).data)


152
153
154
155
156
class BookmarkedVacancyByStudentViewSet(viewsets.GenericViewSet):
    serializer_class = VacancySerializer
    permission_classes = [IsAdminOrStudent]

    def list(self, request, student_id):
157
158
159
160
        """
        Get list of a student {student_id}'s bookmarked vacancies
        ---
        """
161
162
163
164
165
        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):
166
167
168
169
170
171
172
173
174
175
        """
        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
        """
176
177
178
179
180
181
        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):
182
183
184
185
        """
        Remove bookmark {id} for student {student_id}
        ---
        """
186
187
188
189
        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)