-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #496 from MetaPhase-Consulting/feature/handshake-m…
…odel Add model and endpoints handshake
- Loading branch information
Showing
9 changed files
with
294 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Generated by Django 2.2.18 on 2021-04-01 19:22 | ||
|
||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('user_profile', '0002_savedsearch_is_bureau'), | ||
('bidding', '0001_initial'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='BidHandshake', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('bidder_perdet', models.CharField(help_text='The bidder being offered a handshake', max_length=255)), | ||
('cp_id', models.CharField(help_text='The cycle position ID', max_length=255)), | ||
('status', models.CharField(choices=[('O', 'Handshake offered'), ('R', 'Handshake revoked'), ('A', 'Handshake accepted'), ('D', 'Handshake declined')], default='O', max_length=2)), | ||
('date_created', models.DateTimeField(auto_now_add=True)), | ||
('update_date', models.DateTimeField(auto_now_add=True)), | ||
('is_cdo_update', models.BooleanField(default=False)), | ||
('last_editing_bidder', models.ForeignKey(help_text='The last acceptee/cdo to edit', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='bidder', to='user_profile.UserProfile')), | ||
('last_editing_user', models.ForeignKey(help_text='The last offerer user to edit', on_delete=django.db.models.deletion.DO_NOTHING, related_name='bureau_user', to='user_profile.UserProfile')), | ||
], | ||
options={ | ||
'managed': True, | ||
'unique_together': {('cp_id', 'bidder_perdet')}, | ||
}, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from talentmap_api.common.serializers import PrefetchedSerializer, StaticRepresentationField | ||
from talentmap_api.bidding.models import BidHandshake | ||
|
||
|
||
class BidHandshakeSerializer(PrefetchedSerializer): | ||
class Meta: | ||
model = BidHandshake | ||
fields = "__all__" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from django.conf.urls import url | ||
from rest_framework import routers | ||
|
||
from talentmap_api.bidding.views import bidhandshake as views | ||
from talentmap_api.common.urls import get_list, get_retrieve, patch_update | ||
|
||
router = routers.SimpleRouter() | ||
|
||
urlpatterns = [ | ||
url(r'^handshake/bureau/(?P<pk>[0-9]+)/(?P<cp_id>[0-9]+)/$', views.BidHandshakeBureauActionView.as_view({'put': 'put', 'delete': 'delete'}), name='bidding.CyclePosition-designation'), | ||
url(r'^handshake/cdo/(?P<pk>[0-9]+)/(?P<cp_id>[0-9]+)/$', views.BidHandshakeCdoActionView.as_view({'put': 'put', 'delete': 'delete'}), name='bidding.CyclePosition-designation'), | ||
url(r'^handshake/bidder/(?P<cp_id>[0-9]+)/$', views.BidHandshakeBidderActionView.as_view({'put': 'put', 'delete': 'delete'}), name='bidding.CyclePosition-designation'), | ||
] | ||
|
||
|
||
urlpatterns += router.urls |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
import logging | ||
import coreapi | ||
from django.shortcuts import get_object_or_404 | ||
from django.core.exceptions import PermissionDenied | ||
from datetime import datetime | ||
|
||
|
||
from rest_framework.schemas import AutoSchema | ||
from rest_framework import mixins | ||
from rest_framework.viewsets import GenericViewSet | ||
from rest_framework.permissions import IsAuthenticated | ||
from rest_framework.views import APIView | ||
from rest_framework.response import Response | ||
from rest_framework import status | ||
|
||
from rest_condition import Or | ||
|
||
from talentmap_api.bidding.serializers import BidHandshakeSerializer | ||
import talentmap_api.cdo.services.available_bidders as services | ||
from talentmap_api.bidding.models import BidHandshake | ||
|
||
from talentmap_api.user_profile.models import UserProfile | ||
|
||
from talentmap_api.common.mixins import FieldLimitableSerializerMixin | ||
from talentmap_api.common.common_helpers import in_group_or_403 | ||
from talentmap_api.common.permissions import isDjangoGroupMember | ||
import talentmap_api.fsbid.services.client as client_services | ||
import talentmap_api.fsbid.services.employee as empservices | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class BidHandshakeBureauActionView(FieldLimitableSerializerMixin, | ||
GenericViewSet, | ||
mixins.ListModelMixin, | ||
mixins.RetrieveModelMixin): | ||
''' | ||
add, remove, update an Available Bidder instance | ||
''' | ||
serializer_class = BidHandshakeSerializer | ||
permission_classes = [Or(isDjangoGroupMember('bureau_user'), ) ] | ||
|
||
def put(self, serializer, pk, cp_id, **ars): | ||
''' | ||
Offers a handshake to a bidder for a cp_id | ||
''' | ||
# TODO: should we limit this endpoint to only bidder perdets of those who have actually bid on this cp? | ||
# Is it worth the extra network request for the extra validation? | ||
hasBureauPermissions = empservices.has_bureau_permissions(cp_id, self.request.META['HTTP_JWT']) | ||
|
||
if not hasBureauPermissions: | ||
raise PermissionDenied() | ||
|
||
user = UserProfile.objects.get(user=self.request.user) | ||
hs = BidHandshake.objects.filter(bidder_perdet=pk, cp_id=cp_id) | ||
|
||
if hs.exists(): | ||
hs.update(last_editing_user=user, status='O', update_date=datetime.now()) | ||
return Response(status=status.HTTP_204_NO_CONTENT) | ||
else: | ||
BidHandshake.objects.create(last_editing_user=user, bidder_perdet=pk, cp_id=cp_id, status='O') | ||
return Response(status=status.HTTP_204_NO_CONTENT) | ||
|
||
def delete(self, request, pk, cp_id, format=None): | ||
''' | ||
Revokes a handshake from a bidder for a cp_id | ||
''' | ||
hasBureauPermissions = empservices.has_bureau_permissions(cp_id, self.request.META['HTTP_JWT']) | ||
|
||
if not hasBureauPermissions: | ||
raise PermissionDenied() | ||
|
||
user = UserProfile.objects.get(user=self.request.user) | ||
hs = BidHandshake.objects.filter(bidder_perdet=pk, cp_id=cp_id) | ||
|
||
if not hs.exists(): | ||
return Response(status=status.HTTP_404_NOT_FOUND) | ||
else: | ||
user = UserProfile.objects.get(user=self.request.user) | ||
hs.update(last_editing_user=user, bidder_perdet=pk, cp_id=cp_id, status='R', update_date=datetime.now()) | ||
return Response(status=status.HTTP_204_NO_CONTENT) | ||
|
||
|
||
class BidHandshakeCdoActionView(FieldLimitableSerializerMixin, | ||
GenericViewSet, | ||
mixins.ListModelMixin, | ||
mixins.RetrieveModelMixin): | ||
''' | ||
add, remove, update an Available Bidder instance | ||
''' | ||
serializer_class = BidHandshakeSerializer | ||
permission_classes = [Or(isDjangoGroupMember('cdo'), ) ] | ||
|
||
def put(self, serializer, pk, cp_id, **ars): | ||
''' | ||
CDO accepts a handshake for a bidder for a cp_id | ||
''' | ||
user = UserProfile.objects.get(user=self.request.user) | ||
hs = BidHandshake.objects.filter(bidder_perdet=pk, cp_id=cp_id) | ||
|
||
if not BidHandshake.objects.filter(bidder_perdet=pk, cp_id=cp_id, status__in=['O', 'A', 'D']).exists(): | ||
return Response(status=status.HTTP_404_NOT_FOUND) | ||
else: | ||
hs.update(last_editing_bidder=user, status='A', is_cdo_update=True, update_date=datetime.now()) | ||
return Response(status=status.HTTP_204_NO_CONTENT) | ||
|
||
def delete(self, request, pk, cp_id, format=None): | ||
''' | ||
CDO declines a handshake for a bidder for a cp_id | ||
''' | ||
user = UserProfile.objects.get(user=self.request.user) | ||
hs = BidHandshake.objects.filter(bidder_perdet=pk, cp_id=cp_id) | ||
|
||
if not BidHandshake.objects.filter(bidder_perdet=pk, cp_id=cp_id, status__in=['O', 'A', 'D']).exists(): | ||
return Response(status=status.HTTP_404_NOT_FOUND) | ||
else: | ||
hs.update(last_editing_bidder=user, status='D', is_cdo_update=True, update_date=datetime.now()) | ||
return Response(status=status.HTTP_204_NO_CONTENT) | ||
|
||
|
||
class BidHandshakeBidderActionView(FieldLimitableSerializerMixin, | ||
GenericViewSet, | ||
mixins.ListModelMixin, | ||
mixins.RetrieveModelMixin): | ||
''' | ||
add, remove, update an Available Bidder instance | ||
''' | ||
serializer_class = BidHandshakeSerializer | ||
permission_classes = [Or(isDjangoGroupMember('bidder'), ) ] | ||
|
||
def put(self, serializer, cp_id, **ars): | ||
''' | ||
Bidder accepts a handshake for a cp_id | ||
''' | ||
user = UserProfile.objects.get(user=self.request.user) | ||
hs = BidHandshake.objects.filter(bidder_perdet=user.emp_id, cp_id=cp_id) | ||
|
||
if not BidHandshake.objects.filter(bidder_perdet=user.emp_id, cp_id=cp_id, status__in=['O', 'A', 'D']).exists(): | ||
return Response(status=status.HTTP_404_NOT_FOUND) | ||
else: | ||
hs.update(last_editing_bidder=user, status='A', is_cdo_update=False, update_date=datetime.now()) | ||
return Response(status=status.HTTP_204_NO_CONTENT) | ||
|
||
def delete(self, request, cp_id, format=None): | ||
''' | ||
Bidder declines handshake for a cp_id | ||
''' | ||
user = UserProfile.objects.get(user=self.request.user) | ||
hs = BidHandshake.objects.filter(bidder_perdet=user.emp_id, cp_id=cp_id) | ||
|
||
if not BidHandshake.objects.filter(bidder_perdet=user.emp_id, cp_id=cp_id, status__in=['O', 'A', 'D']).exists(): | ||
return Response(status=status.HTTP_404_NOT_FOUND) | ||
else: | ||
hs.update(last_editing_bidder=user, status='D', is_cdo_update=False, update_date=datetime.now()) | ||
return Response(status=status.HTTP_204_NO_CONTENT) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters