Fakultas Ilmu Komputer UI

Commit 39ff0f1e authored by Ichlasul Affan's avatar Ichlasul Affan
Browse files

Implement create new milestones

Also updates permission and serializer
parent f88e9355
......@@ -6,6 +6,7 @@ from core.models import Student
from core.models import Supervisor
from core.models import Application
from core.models import Vacancy
from core.models import VacancyMilestone
def is_admin_or_student(user):
......@@ -159,3 +160,22 @@ class VacancyApprovalPermission(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
return isinstance(obj, Vacancy)
class IsAdminOrVacancyOwnerOrAuthenticatedReadOnly(permissions.IsAuthenticated):
def has_permission(self, request, view):
is_authenticated = super(IsAdminOrVacancyOwnerOrAuthenticatedReadOnly, self).has_permission(request, view)
if is_authenticated and request.method in permissions.SAFE_METHODS:
return True
return is_admin_or_company(request.user)
def has_object_permission(self, request, view, obj):
user = request.user
if user and request.method in permissions.SAFE_METHODS:
return True
if user.is_superuser or user.is_staff:
return True
if isinstance(obj, VacancyMilestone):
return user.company == obj.vacancy.company
raise PermissionDenied(
"Checking owner permission on non-milestone object"
)
# -*- coding: utf-8 -*-
# Generated by Django 1.11.17 on 2019-10-06 03:23
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('core', '0013_auto_20170602_1130'),
]
operations = [
migrations.CreateModel(
name='VacancyMilestone',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('detail', models.TextField()),
('expected_start', models.DateField()),
('expected_finish', models.DateField()),
('vacancy', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='milestones', to='core.Vacancy')),
],
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.17 on 2019-10-06 08:13
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('core', '0014_vacancymilestone'),
('core', '0017_vacancy_amount'),
('core', '0019_merge_20191006_0852'),
]
operations = [
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.17 on 2019-10-07 17:48
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('core', '0020_merge_20191006_1513'),
('core', '0024_auto_20191007_1533'),
]
operations = [
]
......@@ -4,7 +4,4 @@ from core.models.accounts import Student
from core.models.accounts import Supervisor
from core.models.vacancies import Vacancy
from core.models.vacancies import Application
from core.models.vacancies import VacancyMilestone
from django.db import models
from django.core.exceptions import ValidationError
from core.models.accounts import Company, Student
......@@ -36,3 +36,15 @@ class Application(models.Model):
class Meta:
unique_together = (("student", "vacancy"),)
class VacancyMilestone(models.Model):
vacancy = models.ForeignKey(Vacancy, on_delete=models.CASCADE, related_name="milestones", null=False)
name = models.CharField(max_length=100, null=False)
detail = models.TextField()
expected_start = models.DateField()
expected_finish = models.DateField()
def clean(self):
super(VacancyMilestone, self).clean()
if self.expected_start >= self.expected_finish:
raise ValidationError("Expected start must be earlier than expected finish.")
from rest_framework import serializers
from core.models import Company
from core.models.vacancies import Vacancy, Application
from core.models.vacancies import Vacancy, Application, VacancyMilestone
from core.serializers.accounts import StudentSerializer, CompanySerializer
......@@ -95,3 +95,14 @@ class VacancyVerifiedSerializer(serializers.ModelSerializer):
class Meta:
model = Vacancy
fields = ['verified']
class VacancyMilestoneSerializer(serializers.ModelSerializer):
def validate(self, data):
if data['expected_start'] > data['expected_finish']:
raise serializers.ValidationError("Expected start must be earlier than expected finish.")
return data
class Meta:
model = VacancyMilestone
fields = ['name', 'detail', 'expected_start', 'expected_finish']
......@@ -2,15 +2,15 @@ from datetime import datetime, timedelta
from django.utils import timezone
import json
import requests_mock
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User
from rest_framework import status
from rest_framework.test import APITestCase
from core.models.accounts import Company, Student, Supervisor
from core.models.vacancies import Vacancy, Application
from core.models.vacancies import Vacancy, Application, VacancyMilestone
from core.serializers.vacancies import VacancySerializer
class ApplicationTests(APITestCase):
@requests_mock.Mocker()
def test_application_list(self, m):
......@@ -209,11 +209,11 @@ class VacancyTest(APITestCase):
url = '/api/vacancies/?verified=false'
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_filter_vacancy_list_by_company_ids(self):
superuser = User.objects.create_superuser('dummy.company', 'dummy.company@company.com', 'lalala123')
self.client.force_authenticate(user=superuser)
new_user = User.objects.create_user('dummy.company3', 'dummy.company3@company.com', 'lalala123')
new_company = Company.objects.create(user=new_user, description="lalala", status=Company.VERIFIED, logo=None,
address=None)
......@@ -224,9 +224,9 @@ class VacancyTest(APITestCase):
address=None)
open_time = datetime(2019, 10, 20)
close_time = datetime(2019, 12, 20)
vacancy1 = Vacancy.objects.create(company=new_company, verified=True, open_time=open_time,
vacancy1 = Vacancy.objects.create(company=new_company, verified=True, open_time=open_time,
description='', close_time=close_time, name='vacancy1')
vacancy2 = Vacancy.objects.create(company=new_company2, verified=True, open_time=open_time,
vacancy2 = Vacancy.objects.create(company=new_company2, verified=True, open_time=open_time,
description='', close_time=close_time, name='vacancy2')
url = '/api/vacancies/?company={}&company={}'.format(new_company.id, new_company2.id)
response = self.client.get(url, format='json')
......@@ -255,7 +255,7 @@ class VacancyTest(APITestCase):
url = '/api/vacancies/?opened_only=false'
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
@requests_mock.Mocker()
def test_closed_vacancy_not_included(self, m):
m.get('https://akun.cs.ui.ac.id/oauth/token/verify/?client_id=X3zNkFmepkdA47ASNMDZRX3Z9gqSU1Lwywu5WepG', json={"username": 'dummy.mahasiswa', "role": 'mahasiswa', "identity_number": '1234567890'}, status_code=200)
......@@ -494,7 +494,7 @@ class CompanyListsTests(APITestCase):
url = '/api/companies/' + str(new_company.pk) + '/applications/' + str(new_vacancy.pk) + '/by_vacancy/?status=5'
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
def test_company_application_list_with_major(self):
new_user = User.objects.create_user('dummy.company4', 'dummy.company4@company.com', 'lalala123')
new_company = Company.objects.create(user=new_user, description="lalala", status=Company.VERIFIED, logo=None, address=None)
......@@ -602,7 +602,7 @@ class ValidationPositionNameinCreateLowonganKP(APITestCase):
response_status_code = response.status_code
self.assertEqual(response_status_code, 200)
def test_name_contains_alphabets_and_numerics(self):
self.payload["name"] = "Software18 Engineer"
......@@ -639,20 +639,177 @@ class ValidationPositionNameinCreateLowonganKP(APITestCase):
response_status_code = response.status_code
self.assertEqual(response_status_code, 400)
class AcceptOneOfferTests(APITestCase):
class VacancyMilestoneTests(APITestCase):
def setUp(self):
super(VacancyMilestoneTests, self).setUp()
self.user = User.objects.create_user('dummy.student', 'dummy.student@home.com', 'lalala123')
self.company_user = User.objects.create_user('dummy.company2', 'dummy.compan2y@company.com', 'lalala123')
self.company = Company.objects.create(user=self.company_user, description="lalala", status=Company.VERIFIED, logo=None,
address=None)
self.vacancy = Vacancy.objects.create(company=self.company, verified=True, open_time=datetime.fromtimestamp(0),
description="lalala", close_time=datetime.today())
def create_milestone_object(self):
return VacancyMilestone.objects.create(vacancy=self.vacancy, name="initiate", detail="install things",
expected_start=datetime.fromtimestamp(0),
expected_finish=datetime.fromtimestamp(86400))
def test_vacancy_milestone_model(self):
milestone1 = VacancyMilestone(vacancy=self.vacancy, name="initiate", detail="install things",
expected_start=datetime.fromtimestamp(0),
expected_finish=datetime.fromtimestamp(86400))
milestone1.full_clean()
milestone2 = VacancyMilestone(vacancy=self.vacancy, name="a"*101, detail="install things",
expected_start=datetime.fromtimestamp(0),
expected_finish=datetime.fromtimestamp(86400))
with self.assertRaises(ValidationError, msg="Name with more than 100 character should raise ValidationError"):
milestone2.full_clean()
milestone3 = VacancyMilestone(vacancy=self.vacancy, name="initiate", detail="install things",
expected_start=datetime.fromtimestamp(86400),
expected_finish=datetime.fromtimestamp(0))
with self.assertRaises(ValidationError, msg="Expected finish earlier than tart should raise ValidationError"):
milestone3.full_clean()
def test_vacancy_milestones_list(self):
milestone1 = self.create_milestone_object()
self.client.force_authenticate(user=self.user)
url = '/api/vacancies/' + str(self.vacancy.pk) + '/milestones/'
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data["results"]), 1)
self.assertEqual(response.data["results"][0]["name"], milestone1.name)
self.assertEqual(response.data["results"][0]["detail"], milestone1.detail)
def test_create_new_milestone_on_a_vacancy_success(self):
self.client.force_authenticate(user=self.company_user)
url = '/api/vacancies/' + str(self.vacancy.pk) + '/milestones/'
data = {"name": "initiate", "detail": "install things", "expected_start": "2019-01-20",
"expected_finish": "2019-01-21"}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(self.vacancy.milestones.count(), 1)
new_milestone = self.vacancy.milestones.first()
self.assertEqual(new_milestone.name, data["name"])
self.assertEqual(new_milestone.detail, data["detail"])
def test_create_new_milestone_on_a_vacancy_invalid_data(self):
self.client.force_authenticate(user=self.company_user)
url = '/api/vacancies/' + str(self.vacancy.pk) + '/milestones/'
data = {"name": "initiate", "detail": "install things", "expected_start": "2019-01-20",
"expected_finish": "2019-01-01"}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(self.vacancy.milestones.count(), 0)
def test_create_new_milestone_on_a_vacancy_unauthorized_user(self):
self.client.force_authenticate(user=self.user)
url = '/api/vacancies/' + str(self.vacancy.pk) + '/milestones/'
data = {"name": "initiate", "detail": "install things", "expected_start": "2019-01-20",
"expected_finish": "2019-01-21"}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(self.vacancy.milestones.count(), 0)
def test_modify_milestone_on_a_vacancy_success(self):
milestone = self.create_milestone_object()
self.client.force_authenticate(user=self.company_user)
url = '/api/vacancies/' + str(self.vacancy.pk) + '/milestones/' + str(milestone.pk) + '/'
data = {"name": "initiate env", "detail": "install all things", "expected_start": "2019-01-20",
"expected_finish": "2019-01-21"}
response = self.client.put(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(self.vacancy.milestones.count(), 1)
new_milestone = self.vacancy.milestones.first()
self.assertEqual(new_milestone.name, data["name"])
self.assertEqual(new_milestone.detail, data["detail"])
def test_modify_milestone_on_a_vacancy_not_found(self):
milestone = self.create_milestone_object()
self.client.force_authenticate(user=self.company_user)
url = '/api/vacancies/1000/milestones/' + str(milestone.pk) + '/'
data = {"name": "initiate env", "detail": "install all things", "expected_start": "2019-01-20",
"expected_finish": "2019-01-21"}
response = self.client.put(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
url2 = '/api/vacancies/' + str(self.vacancy.pk) + '/milestones/1000/'
response2 = self.client.put(url2, data, format='json')
self.assertEqual(response2.status_code, status.HTTP_404_NOT_FOUND)
self.assertEqual(self.vacancy.milestones.count(), 1)
new_milestone = self.vacancy.milestones.first()
self.assertEqual(new_milestone.name, milestone.name)
self.assertEqual(new_milestone.detail, milestone.detail)
def test_modify_milestone_on_a_vacancy_invalid_data(self):
milestone = self.create_milestone_object()
self.client.force_authenticate(user=self.company_user)
url = '/api/vacancies/' + str(self.vacancy.pk) + '/milestones/' + str(milestone.pk) + '/'
data = {"name": "a" * 101, "detail": "install all things", "expected_start": "2019-01-21",
"expected_finish": "2019-01-19"}
response = self.client.put(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(self.vacancy.milestones.count(), 1)
new_milestone = self.vacancy.milestones.first()
self.assertEqual(new_milestone.name, milestone.name)
self.assertEqual(new_milestone.detail, milestone.detail)
def test_modify_milestone_on_a_vacancy_unauthorized_user(self):
milestone = self.create_milestone_object()
self.client.force_authenticate(user=self.user)
url = '/api/vacancies/' + str(self.vacancy.pk) + '/milestones/' + str(milestone.pk) + '/'
data = {"name": "initiate env", "detail": "install all things", "expected_start": "2019-01-20",
"expected_finish": "2019-01-21"}
response = self.client.put(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(self.vacancy.milestones.count(), 1)
new_milestone = self.vacancy.milestones.first()
self.assertEqual(new_milestone.name, milestone.name)
self.assertEqual(new_milestone.detail, milestone.detail)
def test_delete_milestone_on_a_vacancy_success(self):
milestone = self.create_milestone_object()
self.client.force_authenticate(user=self.company_user)
url = '/api/vacancies/' + str(self.vacancy.pk) + '/milestones/' + str(milestone.pk) + '/'
response = self.client.delete(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(self.vacancy.milestones.count(), 0)
def test_delete_milestone_on_a_vacancy_not_found(self):
milestone = self.create_milestone_object()
self.client.force_authenticate(user=self.company_user)
url = '/api/vacancies/1000/milestones/' + str(milestone.pk) + '/'
response = self.client.delete(url, format='json')
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
url2 = '/api/vacancies/' + str(self.vacancy.pk) + '/milestones/1000/'
response2 = self.client.delete(url2, format='json')
self.assertEqual(response2.status_code, status.HTTP_404_NOT_FOUND)
self.assertEqual(self.vacancy.milestones.count(), 1)
def test_delete_milestone_on_a_vacancy_unauthorized_user(self):
milestone = self.create_milestone_object()
self.client.force_authenticate(user=self.user)
url = '/api/vacancies/' + str(self.vacancy.pk) + '/milestones/' + str(milestone.pk) + '/'
response = self.client.delete(url, format='json')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(self.vacancy.milestones.count(), 1)
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())
......@@ -662,9 +819,9 @@ class AcceptOneOfferTests(APITestCase):
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")
......@@ -677,7 +834,7 @@ class AcceptOneOfferTests(APITestCase):
status_response = []
for app in body:
status_response.append(app['status'])
status_response.append(app['status'])
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertTrue(len(body) >= 2)
......@@ -699,7 +856,7 @@ class AcceptOneOfferTests(APITestCase):
url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/'
response = self.client.patch(url, format='json')
body = json.loads(response.content)
body = json.loads(response.content)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertTrue(len(body) == 0)
......@@ -714,19 +871,19 @@ class AcceptOneOfferTests(APITestCase):
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)
body = json.loads(response.content)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
......@@ -2,7 +2,7 @@ import requests
from django.utils import timezone
from django.conf import settings
from rest_framework import viewsets, status
from rest_framework.decorators import detail_route
from rest_framework.decorators import detail_route, permission_classes
from rest_framework.exceptions import ValidationError
from rest_framework.generics import get_object_or_404
from rest_framework.pagination import PageNumberPagination
......@@ -11,11 +11,12 @@ from rest_framework.response import Response
from core.lib.mixins import MultiSerializerViewSetMixin
from core.lib.permissions import IsAdminOrStudent, IsAdminOrCompany, IsAdminOrVacancyOwner, AsAdminOrSupervisor, \
VacancyApprovalPermission
VacancyApprovalPermission, IsAdminOrVacancyOwnerOrAuthenticatedReadOnly
from core.models import Student, Company
from core.models.vacancies import Vacancy, Application
from core.models.vacancies import Vacancy, Application, VacancyMilestone
from core.serializers.vacancies import VacancySerializer, ApplicationSerializer, ApplicationStatusSerializer, \
PostVacancySerializer, VacancyVerifiedSerializer, SupervisorStudentApplicationSerializer
PostVacancySerializer, VacancyVerifiedSerializer, SupervisorStudentApplicationSerializer, \
VacancyMilestoneSerializer
from core.views.accounts import StudentViewSet
from datetime import datetime, timedelta, time
......@@ -388,6 +389,77 @@ class BookmarkedVacancyByStudentViewSet(viewsets.GenericViewSet):
return Response(
self.serializer_class(student.bookmarked_vacancies, many=True, context={'request': request}).data)
class VacancyMilestoneViewSet(viewsets.GenericViewSet):
serializer_class = VacancyMilestoneSerializer
permission_classes = [IsAdminOrVacancyOwnerOrAuthenticatedReadOnly]
def list(self, request, vacancy_id):
"""
Get list of a vacancy {vacancy_id}'s milestone plans
---
"""
vacancy = get_object_or_404(Vacancy.objects.all(), pk=vacancy_id)
milestones = vacancy.milestones.all()
page = self.paginate_queryset(milestones)
if page is not None:
return self.get_paginated_response(
self.serializer_class(page, many=True, context={'request': request}).data)
return Response(self.serializer_class(milestones, many=True, context={'request': request}).data)
def create(self, request, vacancy_id):
"""
Create a new milestone for vacancy {vacancy_id}
---
parameters:
- name: body
description: JSON object containing 'name' string, 'detail' string, 'expected_start' date string, and
'expected_finish' date string
required: true
type: string
paramType: body
"""
vacancy = get_object_or_404(Vacancy.objects.all(), pk=vacancy_id)
milestone_serializer = self.serializer_class(data=request.data)
if milestone_serializer.is_valid():
milestone = milestone_serializer.save(vacancy=vacancy)
return Response(self.serializer_class(milestone, context={'request': request}).data,
status=status.HTTP_200_OK)
return Response(milestone_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def update(self, request, vacancy_id, pk):
"""
Create existing milestone {pk} for vacancy {vacancy_id}
---
parameters:
- name: body
description: JSON object containing 'name' string, 'detail' string, 'expected_start' date string, and
'expected_finish' date string
required: true
type: string
paramType: body
"""
vacancy = get_object_or_404(Vacancy.objects.all(), pk=vacancy_id)
old_milestone = get_object_or_404(vacancy.milestones.all(), pk=pk)
milestone_serializer = self.serializer_class(old_milestone, data=request.data)
if milestone_serializer.is_valid():
milestone = milestone_serializer.save(vacancy=vacancy)
return Response(self.serializer_class(milestone, context={'request': request}).data,
status=status.HTTP_200_OK)
return Response(milestone_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def destroy(self, request, vacancy_id, pk):
"""
Remove existing milestone {pk} from vacancy {vacancy_id}
---
"""
vacancy = get_object_or_404(Vacancy.objects.all(), pk=vacancy_id)
milestone = get_object_or_404(vacancy.milestones.all(), pk=pk)
milestone.delete()
return Response(
self.serializer_class(vacancy.milestones.all(), many=True, context={'request': request}).data)
class AcceptOfferByStudentViewSet(MultiSerializerViewSetMixin, viewsets.GenericViewSet):
queryset = Application.objects.all()
permission_classes = [IsAdminOrStudent]
......@@ -399,11 +471,11 @@ class AcceptOfferByStudentViewSet(MultiSerializerViewSetMixin, viewsets.GenericV
"""
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
return Response(SupervisorStudentApplicationSerializer(apps, many=True, context={'request': request}).data)
......@@ -25,7 +25,8 @@ 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, AcceptOfferByStudentViewSet
CompanyApplicationViewSet, CompanyVacanciesViewSet, ApplicationViewSet, VacancyMilestoneViewSet, \
AcceptOfferByStudentViewSet
from core.views.feedbacks import FeedbackViewSet
schema_view = get_swagger_view()
......@@ -40,6 +41,8 @@ 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)