Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 118 #167

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
77 changes: 77 additions & 0 deletions server/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.contrib.auth.models import User, Group
from rest_framework import serializers
from .models import *
import datetime

"""
The HyperlinkedModelSerializer class is similar to the ModelSerializer
Expand Down Expand Up @@ -68,6 +69,52 @@ class Meta:
"num_instances",
]

class EquipmentItemSerializerWithTime(serializers.ModelSerializer):
"""
Helper class for EquipmentCategorySerializerWithTime
Has logic to find the number of item instances available based
on the time parameters in the GET request
"""
num_available = serializers.SerializerMethodField('get_num_available')
def get_num_available(self, obj):
available_count = 0
item_inst = obj.instances()
n = obj.num_instances()
time_out_string = self.context.get('request_out')
time_in_string = self.context.get('request_in')
time_out = datetime.datetime.strptime(time_out_string, "%Y-%m-%dT%H:%M:%S%z")
time_in = datetime.datetime.strptime(time_in_string, "%Y-%m-%dT%H:%M:%S%z")

for i in range(n):
instance = item_inst[i]
requests = instance.assoc_requests()
time_conflict = False

# logic to see if existing request overlaps with GET request time
for assoc_request in requests:
if (assoc_request.request_out <= time_out):
if (assoc_request.request_in >= time_out):
time_conflict = True
if (assoc_request.request_out > time_out):
if (assoc_request.request_out <= time_in):
time_conflict = True

if not time_conflict:
available_count += 1
return available_count

class Meta:
model = EquipmentItem
fields = [
"id",
"name",
"description",
"image",
"product_url",
"equipment_type_FK",
"num_instances",
"num_available",
]

class EquipmentTypeSerializer(serializers.ModelSerializer):
"""
Expand All @@ -81,6 +128,22 @@ class Meta:
fields = ["id", "name", "description",
"equipment_category_FK", "items"]

class EquipmentTypeSerializerWithTime(serializers.ModelSerializer):
"""
Helper class for EquipmentCategorySerializerWithTime
Redefined __init__ allows for context to be passed through
"""
items = EquipmentItemSerializerWithTime(many=True, read_only=True)

class Meta:
model = EquipmentType
fields = ["id", "name", "description",
"equipment_category_FK", "items"]
depth = 1

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['items'].context.update(self.context)

class EquipmentCategorySerializer(serializers.ModelSerializer):
"""
Expand All @@ -93,6 +156,20 @@ class Meta:
model = EquipmentCategory
fields = ["id", "name", "description", "types"]

class EquipmentCategorySerializerWithTime(serializers.ModelSerializer):
"""
Serialize EquipmentCategory restricted by time availability of request
"""
types = EquipmentTypeSerializerWithTime(many=True, read_only=True)

class Meta:
model = EquipmentCategory
fields = ["id", "name", "description", "types"]
depth = 2

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['types'].context.update(self.context)

class EquipmentRequestItemQtySerializer(serializers.ModelSerializer):
"""
Expand Down
38 changes: 37 additions & 1 deletion server/api/views/equipment.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,50 @@
from api.models import *
from api.serializers import *

import datetime

from django.http import JsonResponse

from django.shortcuts import get_object_or_404

"""
request in EquipmentCategoryViewSet => context object => pass into
EquipmentCategorySerializerWithTime => pass into EquipmentTypeSerializerWithTime =>
pass into EquipmentItemSerializerWithTime => EquipmentItemSerializerWithTime uses
SerializerMethodField to dynamically get num_available
"""

class EquipmentCategoryViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows Equipment Categories to be viewed or edited.
"""

queryset = EquipmentCategory.objects.all()
serializer_class = EquipmentCategorySerializer

# Pass the GET request time parameters as context if they are present
def get_serializer_context(self, *args, **kwargs):
req_args = self.request.query_params

# Check if time out and time in parameters are provided, if so
# then use a separate serializer to retrieve only available items
if ((req_args.get('out') == None) or (req_args.get('in') == None)):
return None
else:
return {
'request_out': req_args.get('out'),
'request_in' : req_args.get('in')
}

# Use the time serializer if time parameters passed in GET request
def get_serializer_class(self):
req_args = self.request.query_params

# Check if time out and time in parameters are provided, if so
# then use a separate serializer to retrieve only available items
if ((req_args.get('out') == None) or (req_args.get('in') == None)):
return EquipmentCategorySerializer
else:
return EquipmentCategorySerializerWithTime


class EquipmentTypeViewSet(viewsets.ModelViewSet):
Expand Down