You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
5.8 KiB
179 lines
5.8 KiB
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')
|
|
try:
|
|
return Response(json.loads(adjustment_config) if adjustment_config else {})
|
|
except Exception:
|
|
return Response({})
|
|
|
|
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)
|