Skip to content
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