From aa9be1c5b4d89fbb46067a28d2894795628cdbb9 Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sat, 5 Oct 2019 13:08:52 +0700 Subject: [PATCH 01/12] add test to accept only one job and abort the rest application --- core/tests/test_vacancies.py | 93 ++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/core/tests/test_vacancies.py b/core/tests/test_vacancies.py index 1667ac14..a2a8b1b9 100644 --- a/core/tests/test_vacancies.py +++ b/core/tests/test_vacancies.py @@ -1,5 +1,6 @@ from datetime import datetime +import json import requests_mock from django.contrib.auth.models import User from rest_framework import status @@ -433,3 +434,95 @@ class SupervisorApprovalTests(APITestCase): response = self.client.patch(url, format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertEqual(new_vacancy.verified, False) + +class AcceptOneOfferTests(APITestCase): + + def generateObject(self): + new_user = User.objects.create_user('dummy.company', 'dummy.company@company.com', 'lalala123') + new_company = Company.objects.create(user=new_user, description="lalala", status=Company.VERIFIED, logo=None, + address=None) + + new_user2 = User.objects.create_user('dummy.company2', 'dummy.company2@company.com', 'lalala123') + new_company2 = Company.objects.create(user=new_user2, description="lalala", status=Company.VERIFIED, logo=None, + address=None) + + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(0), + description="lalala", close_time=datetime.today()) + + new_vacancy2 = Vacancy.objects.create(company=new_company2, verified=True, open_time=datetime.fromtimestamp(0), + description="lalala", close_time=datetime.today()) + + new_user3 = User.objects.create_user('dummy.student', 'dummy.student@company.com', 'lalala123') + new_student = Student.objects.create(user=new_user3, npm=1234123412) + + return new_user3, new_vacancy, new_vacancy2, new_student + + def test_number_of_content_response_object_given_id_auth(self): + + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + status_response = [] + for app in body: + status_response.append(app['status']) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertTrue(len(body) >= 2) + self.assertFalse(len(body) == 0) + self.assertTrue('new' in status_response) + self.assertTrue('aborted' in status_response) + + def test_student_not_exist_given_auth(self): + new_user3,new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + user4 = User.objects.create_user('student_user_4', 'student_user_4@company.com', 'lalala123') + other_student = Student.objects.create(user=user4, npm=1098765432) + + Application.objects.create(student=other_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=other_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertTrue(len(body) == 0) + + def test_type_error_if_input_null(self): + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + with self.assertRaises(TypeError): + url = '/api/acceptoffer/' + None + '/vacancy/' + str(new_vacancy.pk) + '/' + + with self.assertRaises(TypeError): + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + None + '/' + + def test_if_requester_is_not_authenticated(self): + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) -- GitLab From b9dd731de845d73ae795d034ce68de6abd2f4cdf Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sat, 5 Oct 2019 13:12:27 +0700 Subject: [PATCH 02/12] add new endpoint & model attr to accept only one job and --- core/models/vacancies.py | 1 + core/serializers/vacancies.py | 2 +- core/views/vacancies.py | 20 ++++++++++++++++++++ kape/urls.py | 3 ++- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/core/models/vacancies.py b/core/models/vacancies.py index f2b5dc49..8968e626 100644 --- a/core/models/vacancies.py +++ b/core/models/vacancies.py @@ -23,6 +23,7 @@ class Application(models.Model): BOOKMARKED = 2 REJECTED = 3 ACCEPTED = 4 + ABORTED = 5 cover_letter = models.TextField(null=True, blank=True) student = models.ForeignKey(Student, on_delete=models.CASCADE) diff --git a/core/serializers/vacancies.py b/core/serializers/vacancies.py index 313f2064..a2bd2e4f 100644 --- a/core/serializers/vacancies.py +++ b/core/serializers/vacancies.py @@ -61,7 +61,7 @@ class ApplicationStatusSerializer(serializers.ModelSerializer): class SupervisorStudentApplicationSerializer(serializers.ModelSerializer): def to_representation(self, instance): - status_map = ["new", "read", "bookmarked", "rejected", "accepted" ] + status_map = ["new", "read", "bookmarked", "rejected", "accepted","aborted" ] return { 'name' : instance.student.full_name, 'npm' : instance.student.npm, diff --git a/core/views/vacancies.py b/core/views/vacancies.py index e4b8b989..12fdbef6 100644 --- a/core/views/vacancies.py +++ b/core/views/vacancies.py @@ -275,3 +275,23 @@ class BookmarkedVacancyByStudentViewSet(viewsets.GenericViewSet): student.bookmarked_vacancies.remove(vacancy) return Response( self.serializer_class(student.bookmarked_vacancies, many=True, context={'request': request}).data) + +class AcceptOfferByStudentViewSet(MultiSerializerViewSetMixin, viewsets.GenericViewSet): + queryset = Application.objects.all() + permission_classes = [IsAdminOrStudent] + + def partial_update(self, request, student_id, pk=None): + """ + Get list of a student {student_id}'s cancel offered vacancies + --- + """ + student = get_object_or_404(Student.objects.all().order_by('-updated'), pk=student_id) + apps = Application.objects.filter(student=student) + + for a in apps: + if a.vacancy_id != int(pk): + serializer = ApplicationStatusSerializer(a, data={'status': 5}, partial=True) + if serializer.is_valid(): + serializer.save() + + return Response(SupervisorStudentApplicationSerializer(apps, many=True, context={'request': request}).data) \ No newline at end of file diff --git a/kape/urls.py b/kape/urls.py index 21a1d46b..5cb90a79 100755 --- a/kape/urls.py +++ b/kape/urls.py @@ -25,7 +25,7 @@ from core import apps from core.views.accounts import StudentViewSet, CompanyViewSet, SupervisorViewSet, UserViewSet, LoginViewSet, \ CompanyRegisterViewSet from core.views.vacancies import VacancyViewSet, BookmarkedVacancyByStudentViewSet, StudentApplicationViewSet, \ - CompanyApplicationViewSet, CompanyVacanciesViewSet, ApplicationViewSet + CompanyApplicationViewSet, CompanyVacanciesViewSet, ApplicationViewSet, AcceptOfferByStudentViewSet schema_view = get_swagger_view() router = routers.DefaultRouter() @@ -38,6 +38,7 @@ router.register(r'register', CompanyRegisterViewSet) router.register(r'vacancies', VacancyViewSet) router.register(r'applications', ApplicationViewSet) # router.register(r'students/(?P<student_id>\d+)/profile', StudentProfileViewSet) +router.register(r'acceptoffer/(?P<student_id>\d+)/vacancy', AcceptOfferByStudentViewSet) router.register(r'students/(?P<student_id>\d+)/bookmarked-vacancies', BookmarkedVacancyByStudentViewSet, base_name='bookmarked-vacancy-list') router.register(r'students/(?P<student_id>\d+)/applied-vacancies', StudentApplicationViewSet, -- GitLab From ea9810a2e8712df42d96fbabd4835e8eef61a9f8 Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sat, 5 Oct 2019 13:08:52 +0700 Subject: [PATCH 03/12] add test to accept only one job and abort the rest application --- core/tests/test_vacancies.py | 93 ++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/core/tests/test_vacancies.py b/core/tests/test_vacancies.py index d8c654f6..f6ab7938 100644 --- a/core/tests/test_vacancies.py +++ b/core/tests/test_vacancies.py @@ -1,6 +1,7 @@ from datetime import datetime from django.utils import timezone +import json import requests_mock from django.contrib.auth.models import User from rest_framework import status @@ -434,3 +435,95 @@ class SupervisorApprovalTests(APITestCase): response = self.client.patch(url, format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertEqual(new_vacancy.verified, False) + +class AcceptOneOfferTests(APITestCase): + + def generateObject(self): + new_user = User.objects.create_user('dummy.company', 'dummy.company@company.com', 'lalala123') + new_company = Company.objects.create(user=new_user, description="lalala", status=Company.VERIFIED, logo=None, + address=None) + + new_user2 = User.objects.create_user('dummy.company2', 'dummy.company2@company.com', 'lalala123') + new_company2 = Company.objects.create(user=new_user2, description="lalala", status=Company.VERIFIED, logo=None, + address=None) + + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(0), + description="lalala", close_time=datetime.today()) + + new_vacancy2 = Vacancy.objects.create(company=new_company2, verified=True, open_time=datetime.fromtimestamp(0), + description="lalala", close_time=datetime.today()) + + new_user3 = User.objects.create_user('dummy.student', 'dummy.student@company.com', 'lalala123') + new_student = Student.objects.create(user=new_user3, npm=1234123412) + + return new_user3, new_vacancy, new_vacancy2, new_student + + def test_number_of_content_response_object_given_id_auth(self): + + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + status_response = [] + for app in body: + status_response.append(app['status']) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertTrue(len(body) >= 2) + self.assertFalse(len(body) == 0) + self.assertTrue('new' in status_response) + self.assertTrue('aborted' in status_response) + + def test_student_not_exist_given_auth(self): + new_user3,new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + user4 = User.objects.create_user('student_user_4', 'student_user_4@company.com', 'lalala123') + other_student = Student.objects.create(user=user4, npm=1098765432) + + Application.objects.create(student=other_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=other_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertTrue(len(body) == 0) + + def test_type_error_if_input_null(self): + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + with self.assertRaises(TypeError): + url = '/api/acceptoffer/' + None + '/vacancy/' + str(new_vacancy.pk) + '/' + + with self.assertRaises(TypeError): + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + None + '/' + + def test_if_requester_is_not_authenticated(self): + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) -- GitLab From e34cc05612e23a1c53fe5914bcec8d3890252ba6 Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sat, 5 Oct 2019 13:12:27 +0700 Subject: [PATCH 04/12] add new endpoint & model attr to accept only one job and --- core/models/vacancies.py | 1 + core/serializers/vacancies.py | 2 +- core/views/vacancies.py | 20 ++++++++++++++++++++ kape/urls.py | 3 ++- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/core/models/vacancies.py b/core/models/vacancies.py index f2b5dc49..8968e626 100644 --- a/core/models/vacancies.py +++ b/core/models/vacancies.py @@ -23,6 +23,7 @@ class Application(models.Model): BOOKMARKED = 2 REJECTED = 3 ACCEPTED = 4 + ABORTED = 5 cover_letter = models.TextField(null=True, blank=True) student = models.ForeignKey(Student, on_delete=models.CASCADE) diff --git a/core/serializers/vacancies.py b/core/serializers/vacancies.py index 313f2064..a2bd2e4f 100644 --- a/core/serializers/vacancies.py +++ b/core/serializers/vacancies.py @@ -61,7 +61,7 @@ class ApplicationStatusSerializer(serializers.ModelSerializer): class SupervisorStudentApplicationSerializer(serializers.ModelSerializer): def to_representation(self, instance): - status_map = ["new", "read", "bookmarked", "rejected", "accepted" ] + status_map = ["new", "read", "bookmarked", "rejected", "accepted","aborted" ] return { 'name' : instance.student.full_name, 'npm' : instance.student.npm, diff --git a/core/views/vacancies.py b/core/views/vacancies.py index 56165caa..2f805138 100644 --- a/core/views/vacancies.py +++ b/core/views/vacancies.py @@ -350,3 +350,23 @@ class BookmarkedVacancyByStudentViewSet(viewsets.GenericViewSet): student.bookmarked_vacancies.remove(vacancy) return Response( self.serializer_class(student.bookmarked_vacancies, many=True, context={'request': request}).data) + +class AcceptOfferByStudentViewSet(MultiSerializerViewSetMixin, viewsets.GenericViewSet): + queryset = Application.objects.all() + permission_classes = [IsAdminOrStudent] + + def partial_update(self, request, student_id, pk=None): + """ + Get list of a student {student_id}'s cancel offered vacancies + --- + """ + student = get_object_or_404(Student.objects.all().order_by('-updated'), pk=student_id) + apps = Application.objects.filter(student=student) + + for a in apps: + if a.vacancy_id != int(pk): + serializer = ApplicationStatusSerializer(a, data={'status': 5}, partial=True) + if serializer.is_valid(): + serializer.save() + + return Response(SupervisorStudentApplicationSerializer(apps, many=True, context={'request': request}).data) \ No newline at end of file diff --git a/kape/urls.py b/kape/urls.py index 5ae9c078..ade154c6 100755 --- a/kape/urls.py +++ b/kape/urls.py @@ -25,7 +25,7 @@ from core import apps from core.views.accounts import StudentViewSet, CompanyViewSet, SupervisorViewSet, UserViewSet, LoginViewSet, \ CompanyRegisterViewSet from core.views.vacancies import VacancyViewSet, BookmarkedVacancyByStudentViewSet, StudentApplicationViewSet, \ - CompanyApplicationViewSet, CompanyVacanciesViewSet, ApplicationViewSet + CompanyApplicationViewSet, CompanyVacanciesViewSet, ApplicationViewSet, AcceptOfferByStudentViewSet from core.views.feedbacks import FeedbackViewSet schema_view = get_swagger_view() @@ -40,6 +40,7 @@ router.register(r'vacancies', VacancyViewSet) router.register(r'applications', ApplicationViewSet) router.register(r'feedbacks', FeedbackViewSet) # router.register(r'students/(?P<student_id>\d+)/profile', StudentProfileViewSet) +router.register(r'acceptoffer/(?P<student_id>\d+)/vacancy', AcceptOfferByStudentViewSet) router.register(r'students/(?P<student_id>\d+)/bookmarked-vacancies', BookmarkedVacancyByStudentViewSet, base_name='bookmarked-vacancy-list') router.register(r'students/(?P<student_id>\d+)/applied-vacancies', StudentApplicationViewSet, -- GitLab From c5a4a8730df433bc2db50996b0da66cc9cf783c6 Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sun, 6 Oct 2019 00:32:37 +0700 Subject: [PATCH 05/12] merge --- core/migrations/0015_merge_20191005_2038.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 core/migrations/0015_merge_20191005_2038.py diff --git a/core/migrations/0015_merge_20191005_2038.py b/core/migrations/0015_merge_20191005_2038.py new file mode 100644 index 00000000..d4afc1b8 --- /dev/null +++ b/core/migrations/0015_merge_20191005_2038.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2019-10-05 13:38 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0014_feedback'), + ('core', '0014_company_category'), + ] + + operations = [ + ] -- GitLab From 93c84527c135e250ded2eba2f99f2d051f4cb1ea Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sat, 5 Oct 2019 13:08:52 +0700 Subject: [PATCH 06/12] add test to accept only one job and abort the rest application --- core/tests/test_vacancies.py | 93 ++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/core/tests/test_vacancies.py b/core/tests/test_vacancies.py index d8c654f6..f6ab7938 100644 --- a/core/tests/test_vacancies.py +++ b/core/tests/test_vacancies.py @@ -1,6 +1,7 @@ from datetime import datetime from django.utils import timezone +import json import requests_mock from django.contrib.auth.models import User from rest_framework import status @@ -434,3 +435,95 @@ class SupervisorApprovalTests(APITestCase): response = self.client.patch(url, format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertEqual(new_vacancy.verified, False) + +class AcceptOneOfferTests(APITestCase): + + def generateObject(self): + new_user = User.objects.create_user('dummy.company', 'dummy.company@company.com', 'lalala123') + new_company = Company.objects.create(user=new_user, description="lalala", status=Company.VERIFIED, logo=None, + address=None) + + new_user2 = User.objects.create_user('dummy.company2', 'dummy.company2@company.com', 'lalala123') + new_company2 = Company.objects.create(user=new_user2, description="lalala", status=Company.VERIFIED, logo=None, + address=None) + + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(0), + description="lalala", close_time=datetime.today()) + + new_vacancy2 = Vacancy.objects.create(company=new_company2, verified=True, open_time=datetime.fromtimestamp(0), + description="lalala", close_time=datetime.today()) + + new_user3 = User.objects.create_user('dummy.student', 'dummy.student@company.com', 'lalala123') + new_student = Student.objects.create(user=new_user3, npm=1234123412) + + return new_user3, new_vacancy, new_vacancy2, new_student + + def test_number_of_content_response_object_given_id_auth(self): + + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + status_response = [] + for app in body: + status_response.append(app['status']) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertTrue(len(body) >= 2) + self.assertFalse(len(body) == 0) + self.assertTrue('new' in status_response) + self.assertTrue('aborted' in status_response) + + def test_student_not_exist_given_auth(self): + new_user3,new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + user4 = User.objects.create_user('student_user_4', 'student_user_4@company.com', 'lalala123') + other_student = Student.objects.create(user=user4, npm=1098765432) + + Application.objects.create(student=other_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=other_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertTrue(len(body) == 0) + + def test_type_error_if_input_null(self): + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + with self.assertRaises(TypeError): + url = '/api/acceptoffer/' + None + '/vacancy/' + str(new_vacancy.pk) + '/' + + with self.assertRaises(TypeError): + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + None + '/' + + def test_if_requester_is_not_authenticated(self): + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) -- GitLab From 3aeff43bb67e48db465b6b4e29f97620748023d6 Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sat, 5 Oct 2019 13:12:27 +0700 Subject: [PATCH 07/12] add new endpoint & model attr to accept only one job and --- core/models/vacancies.py | 1 + core/serializers/vacancies.py | 2 +- core/views/vacancies.py | 20 ++++++++++++++++++++ kape/urls.py | 3 ++- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/core/models/vacancies.py b/core/models/vacancies.py index f2b5dc49..8968e626 100644 --- a/core/models/vacancies.py +++ b/core/models/vacancies.py @@ -23,6 +23,7 @@ class Application(models.Model): BOOKMARKED = 2 REJECTED = 3 ACCEPTED = 4 + ABORTED = 5 cover_letter = models.TextField(null=True, blank=True) student = models.ForeignKey(Student, on_delete=models.CASCADE) diff --git a/core/serializers/vacancies.py b/core/serializers/vacancies.py index 313f2064..a2bd2e4f 100644 --- a/core/serializers/vacancies.py +++ b/core/serializers/vacancies.py @@ -61,7 +61,7 @@ class ApplicationStatusSerializer(serializers.ModelSerializer): class SupervisorStudentApplicationSerializer(serializers.ModelSerializer): def to_representation(self, instance): - status_map = ["new", "read", "bookmarked", "rejected", "accepted" ] + status_map = ["new", "read", "bookmarked", "rejected", "accepted","aborted" ] return { 'name' : instance.student.full_name, 'npm' : instance.student.npm, diff --git a/core/views/vacancies.py b/core/views/vacancies.py index 56165caa..2f805138 100644 --- a/core/views/vacancies.py +++ b/core/views/vacancies.py @@ -350,3 +350,23 @@ class BookmarkedVacancyByStudentViewSet(viewsets.GenericViewSet): student.bookmarked_vacancies.remove(vacancy) return Response( self.serializer_class(student.bookmarked_vacancies, many=True, context={'request': request}).data) + +class AcceptOfferByStudentViewSet(MultiSerializerViewSetMixin, viewsets.GenericViewSet): + queryset = Application.objects.all() + permission_classes = [IsAdminOrStudent] + + def partial_update(self, request, student_id, pk=None): + """ + Get list of a student {student_id}'s cancel offered vacancies + --- + """ + student = get_object_or_404(Student.objects.all().order_by('-updated'), pk=student_id) + apps = Application.objects.filter(student=student) + + for a in apps: + if a.vacancy_id != int(pk): + serializer = ApplicationStatusSerializer(a, data={'status': 5}, partial=True) + if serializer.is_valid(): + serializer.save() + + return Response(SupervisorStudentApplicationSerializer(apps, many=True, context={'request': request}).data) \ No newline at end of file diff --git a/kape/urls.py b/kape/urls.py index 5ae9c078..ade154c6 100755 --- a/kape/urls.py +++ b/kape/urls.py @@ -25,7 +25,7 @@ from core import apps from core.views.accounts import StudentViewSet, CompanyViewSet, SupervisorViewSet, UserViewSet, LoginViewSet, \ CompanyRegisterViewSet from core.views.vacancies import VacancyViewSet, BookmarkedVacancyByStudentViewSet, StudentApplicationViewSet, \ - CompanyApplicationViewSet, CompanyVacanciesViewSet, ApplicationViewSet + CompanyApplicationViewSet, CompanyVacanciesViewSet, ApplicationViewSet, AcceptOfferByStudentViewSet from core.views.feedbacks import FeedbackViewSet schema_view = get_swagger_view() @@ -40,6 +40,7 @@ router.register(r'vacancies', VacancyViewSet) router.register(r'applications', ApplicationViewSet) router.register(r'feedbacks', FeedbackViewSet) # router.register(r'students/(?P<student_id>\d+)/profile', StudentProfileViewSet) +router.register(r'acceptoffer/(?P<student_id>\d+)/vacancy', AcceptOfferByStudentViewSet) router.register(r'students/(?P<student_id>\d+)/bookmarked-vacancies', BookmarkedVacancyByStudentViewSet, base_name='bookmarked-vacancy-list') router.register(r'students/(?P<student_id>\d+)/applied-vacancies', StudentApplicationViewSet, -- GitLab From f129948728d7208bf3f4ef337cc8c93e8c8dfd50 Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sun, 6 Oct 2019 00:32:37 +0700 Subject: [PATCH 08/12] merge --- core/migrations/0015_merge_20191005_2038.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 core/migrations/0015_merge_20191005_2038.py diff --git a/core/migrations/0015_merge_20191005_2038.py b/core/migrations/0015_merge_20191005_2038.py new file mode 100644 index 00000000..d4afc1b8 --- /dev/null +++ b/core/migrations/0015_merge_20191005_2038.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2019-10-05 13:38 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0014_feedback'), + ('core', '0014_company_category'), + ] + + operations = [ + ] -- GitLab From 262d51ace3fc12219fbfc13681b5ce10a0b357c2 Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sun, 6 Oct 2019 00:49:37 +0700 Subject: [PATCH 09/12] merge --- core/migrations/0017_merge_20191006_0049.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 core/migrations/0017_merge_20191006_0049.py diff --git a/core/migrations/0017_merge_20191006_0049.py b/core/migrations/0017_merge_20191006_0049.py new file mode 100644 index 00000000..a492afcb --- /dev/null +++ b/core/migrations/0017_merge_20191006_0049.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2019-10-05 17:49 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0015_merge_20191005_2038'), + ('core', '0016_merge_20191005_2235'), + ] + + operations = [ + ] -- GitLab From b684ce4ea19bb192f6d1aa67c435816fd09219de Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sun, 6 Oct 2019 01:16:03 +0700 Subject: [PATCH 10/12] delete --- core/migrations/0015_merge_20191005_2038.py | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 core/migrations/0015_merge_20191005_2038.py diff --git a/core/migrations/0015_merge_20191005_2038.py b/core/migrations/0015_merge_20191005_2038.py deleted file mode 100644 index d4afc1b8..00000000 --- a/core/migrations/0015_merge_20191005_2038.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.5 on 2019-10-05 13:38 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0014_feedback'), - ('core', '0014_company_category'), - ] - - operations = [ - ] -- GitLab From ebc020d1079d3c216dfaaeaaa249ab5f804b19d1 Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sun, 6 Oct 2019 01:19:24 +0700 Subject: [PATCH 11/12] delete --- core/migrations/0017_merge_20191006_0049.py | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 core/migrations/0017_merge_20191006_0049.py diff --git a/core/migrations/0017_merge_20191006_0049.py b/core/migrations/0017_merge_20191006_0049.py deleted file mode 100644 index a492afcb..00000000 --- a/core/migrations/0017_merge_20191006_0049.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.5 on 2019-10-05 17:49 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0015_merge_20191005_2038'), - ('core', '0016_merge_20191005_2235'), - ] - - operations = [ - ] -- GitLab From 377c2042fa0bb50fb422cb071f75ec3a5d6e359c Mon Sep 17 00:00:00 2001 From: atthoriq <at.thoriq@outlook.com> Date: Sun, 6 Oct 2019 01:35:22 +0700 Subject: [PATCH 12/12] merge migration --- core/migrations/0017_merge_20191006_0134.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 core/migrations/0017_merge_20191006_0134.py diff --git a/core/migrations/0017_merge_20191006_0134.py b/core/migrations/0017_merge_20191006_0134.py new file mode 100644 index 00000000..d41f21a8 --- /dev/null +++ b/core/migrations/0017_merge_20191006_0134.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2019-10-05 18:34 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0015_merge_20191005_2038'), + ('core', '0016_merge_20191005_2235'), + ] + + operations = [ + ] -- GitLab