diff --git a/server/api/serializers.py b/server/api/serializers.py index 417f733..0374419 100644 --- a/server/api/serializers.py +++ b/server/api/serializers.py @@ -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 @@ -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): """ @@ -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): """ @@ -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): """ diff --git a/server/api/views/equipment.py b/server/api/views/equipment.py index 7dd0f58..47a2aac 100644 --- a/server/api/views/equipment.py +++ b/server/api/views/equipment.py @@ -11,6 +11,18 @@ 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): """ @@ -18,7 +30,31 @@ class EquipmentCategoryViewSet(viewsets.ModelViewSet): """ 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):