from django.shortcuts import render import datetime import json from collections import OrderedDict from django.db.models import Q from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page from rest_framework.generics import ListAPIView from rest_framework.permissions import IsAuthenticated, AllowAny from rest_framework.response import Response from rest_framework.views import APIView, status from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from apps.account.models import User from apps.dobodbi_calendar.models import CalendarOccasions from apps.dobodbi_calendar.serializer import CalendarSerializer from utils.config_getter import get_config from utils.pagination import StandardResultsSetPagination class CalendarList(ListAPIView): serializer_class = CalendarSerializer pagination_class = StandardResultsSetPagination permission_classes = (AllowAny,) @swagger_auto_schema( operation_description="Get list of calendar occasions", tags=["Dobodbi - Calendar"], manual_parameters=[ openapi.Parameter( 'last_updated', openapi.IN_QUERY, description="Filter occasions updated after this timestamp", type=openapi.TYPE_STRING, required=False ) ], responses={ 200: openapi.Response( description="List of calendar occasions with metadata" ) } ) def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) # @method_decorator(cache_page(60 * 15)) # Cache for 1 Hour # def dispatch(self, *args, **kwargs): # return super().dispatch(*args, **kwargs) def get_queryset(self): queryset = CalendarOccasions.objects.all() req = self.request if v := req.query_params.get('last_updated'): query &= Q( updated_at__gte=v ) return queryset def list(self, request, *args, **kwargs): q = self.get_queryset() last_item_date = q.first() if last_item_date: last_updated = last_item_date.updated_at + datetime.timedelta(microseconds=1) last_updated = str(last_updated) else: last_updated = None d = self.get_serializer(q, many=True).data data = OrderedDict({ 'last_updated': last_updated, 'total': len(d), 'data': d, }) return Response(data) class AdjustmentConfigView(APIView): permission_classes = (AllowAny,) @swagger_auto_schema( operation_description="Get calendar adjustment configuration", tags=["Dobodbi - Calendar"], responses={ 200: openapi.Response( description="Calendar adjustment configuration" ) } ) def get(self, request): adjustment_config = get_config('calendar__Adjustment') return Response(json.loads(adjustment_config)) class OccasionsList(ListAPIView): serializer_class = CalendarSerializer pagination_class = StandardResultsSetPagination permission_classes = (AllowAny,) @swagger_auto_schema( operation_description="Get list of calendar occasions. Can filter by month.", tags=["Dobodbi - Calendar"], manual_parameters=[ openapi.Parameter( 'month', openapi.IN_QUERY, description="Filter by month number (e.g. 1, 02, 12)", type=openapi.TYPE_STRING, required=False ), openapi.Parameter( 'last_updated', openapi.IN_QUERY, description="Filter occasions updated after this timestamp", type=openapi.TYPE_STRING, required=False ) ], responses={ 200: openapi.Response( description="List of calendar occasions" ) } ) def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) def get_queryset(self): queryset = CalendarOccasions.objects.all() req = self.request # 1. Month Filter Logic month = req.query_params.get('month') if month: # Ensure month is two digits (e.g., '2' -> '02') to match your JSON data month_str = str(month).zfill(2) # This looks inside the JSON array. # It finds rows where the JSON list contains an object with this exact key/value. queryset = queryset.filter(dates__contains=[{'month': month_str}]) # 2. Last Updated Filter Logic if v := req.query_params.get('last_updated'): queryset = queryset.filter(updated_at__gte=v) return queryset def list(self, request, *args, **kwargs): q = self.get_queryset() # Calculate last_updated based on the specific filtered result last_item_date = q.order_by('-updated_at').first() if last_item_date: last_updated = last_item_date.updated_at + datetime.timedelta(microseconds=1) last_updated = str(last_updated) else: last_updated = None # Standard pagination handling (since you are inheriting ListAPIView) page = self.paginate_queryset(q) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) # Fallback if pagination is disabled d = self.get_serializer(q, many=True).data data = OrderedDict({ 'last_updated': last_updated, 'total': len(d), 'data': d, }) return Response(data)