promotions/apps/promotions/views.py
Sayyid Hamid Mahdavi 61f3c8a920 get plan details
2026-02-22 13:59:48 +03:30

271 lines
11 KiB
Python

from drf_spectacular.utils import extend_schema
from rest_framework import mixins, status
from rest_framework.decorators import action
from rest_framework import exceptions
from rest_framework.generics import CreateAPIView, get_object_or_404, RetrieveAPIView, ListAPIView
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements
from apps.gooyal_oauth2.utils import get_application
from utils.exceptions import UnprocessableEntity
from .models import Plan, Promotion, EventSaver
from .serializers import PlanSerializer, PromotionSerializer, EventSerializer, PromoteSerializer, UserPlanSerializer
from .tasks import analyze_event_task
from ..users.models import User
# class ApplicationPlanViewSet(mixins.ListModelMixin,
# mixins.CreateModelMixin,
# GenericViewSet):
# queryset = Plan.objects.all()
# serializer_class = PlanSerializer
#
# permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
# required_alternate_scopes = {
# "POST": [["promotions.application.user-plans:submit"]],
# "GET": [["promotions.application.user-promotions:list-retrieve"]],
# }
#
# def get_queryset(self):
# user_uuid = self.kwargs.get('user_uuid')
# user = User.objects.get(uuid=user_uuid)
# application = get_application(self.request)
# return Plan.objects.filter(application=application)
#
class ApplicationPromotionViewSet(
mixins.RetrieveModelMixin,
mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericViewSet
):
serializer_class = PromotionSerializer
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
required_alternate_scopes = {
"POST": [["promotions.application.user-promotions:promote"]],
"GET": [["promotions.application.user-promotions:list-retrieve"]],
}
def get_queryset(self):
user_uuid = self.kwargs.get('user_uuid')
user = User.objects.get(uuid=user_uuid)
application = get_application(self.request)
return Promotion.objects.filter(application=application, user=user)
def perform_create(self, serializer):
user_uuid = self.kwargs.get('user_uuid')
user = User.objects.get(uuid=user_uuid)
application = get_application(self.request)
plan = serializer.validated_data['plan']
promotion_args = dict(user=user, application=application, **serializer.validated_data)
promotion_amount = plan.calculate_promotion(**promotion_args)
if promotion_amount:
promotion = serializer.save(promotion_amount=promotion_amount, user=user, application=application)
promotion.promote(**promotion_args)
@action(detail=False, methods=['post'], serializer_class=EventSerializer)
def submit_event(self, request):
pass
class ApplicationViewSet(
mixins.CreateModelMixin,
GenericViewSet
):
serializer_class = EventSerializer
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
required_alternate_scopes = {
"POST": [["promotions.application.event:submit"]],
}
def perform_create(self, serializer: EventSerializer):
if hasattr(self.request, 'user'):
user = self.request.user
else:
user = None
application = get_application(self.request)
# EventSaver.objects.first(event_label=serializer.validated_data['event_label'], valid_application__contains=application.uuid)
event_saver: EventSaver = EventSaver.objects.filter(event_label=serializer.validated_data['label']).first()
try:
event = event_saver.save_event(user=user, application=application, **serializer.validated_data)
except Exception as e:
raise exceptions.ValidationError(str(e))
analyze_event_task.delay(event.uuid)
serializer.instance = event
class UserPlanViewSet(mixins.RetrieveModelMixin,
# mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericViewSet):
serializer_class = UserPlanSerializer
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
required_alternate_scopes = {
"GET": [["promotions.user.plans:list-retrieve"]],
"POST": [["promotions.user.plans:list-retrieve"]],
}
def get_queryset(self):
user = self.request.user
application = get_application(self.request)
queryset = Plan.objects.all()
return queryset
# @extend_schema(responses=PlanSerializer(many=True))
# @action(detail=False, methods=['POST'], serializer_class=PlanSerializer)
# def available(self, request):
# serializer = self.get_serializer(data=self.request.data)
# serializer.is_valid(raise_exception=True)
# print(serializer.validated_data)
# plans = self.paginate_queryset(self.filter_queryset(self.get_queryset()))
# for plan in plans:
# plan.calculate_promotion(**serializer.validated_data)
# serializer = self.get_serializer(plans, many=True)
# return self.get_paginated_response(serializer.data)
@action(detail=True, methods=['POST'], serializer_class=PromoteSerializer)
def promote(self, request, pk=None):
plan = self.get_object()
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
application = get_application(self.request)
event_saver: EventSaver = EventSaver.objects.filter(event_label=serializer.validated_data['label']).first()
user = self.request.user.pk or serializer.validated_data['user']
# try:
event = event_saver.save_event(user=user, application=application, **serializer.validated_data)
# except Exception as e:
# raise exceptions.ValidationError(str(e))
result_list = plan.process_event(event)
data["promotions"] = result_list
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class ApplicationPromoteUserApiView(CreateAPIView):
model = Promotion
serializer_class = PromoteSerializer
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
required_alternate_scopes = {
"POST": [[]],
}
def get_plan(self):
plan_uuid = self.kwargs.get('plan')
plan = get_object_or_404(Plan, uuid=plan_uuid)
return plan
def create(self, request, *args, **kwargs):
plan = self.get_plan()
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
application = get_application(self.request)
event_saver: EventSaver = EventSaver.objects.filter(event_label=serializer.validated_data['label']).first()
user = self.request.user.pk or serializer.validated_data['user']
# try:
event = event_saver.save_event(user=user, application=application, **serializer.validated_data)
# except Exception as e:
# raise exceptions.ValidationError(str(e))
result_list = plan.process_event(event)
data["promotions"] = result_list
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class ApplicationPromotionListApiView(ListAPIView):
model = Promotion
serializer_class = PromotionSerializer
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
required_alternate_scopes = {
"GET": [[]],
}
def get_plan(self):
plan_uuid = self.kwargs.get('plan')
plan = get_object_or_404(Plan, uuid=plan_uuid)
return plan
def get_queryset(self):
user = self.request.user
plan = self.get_plan()
qs = Promotion.objects.filter(user_uuid=user.uuid, plan=plan)
return qs
# def create(self, request, *args, **kwargs):
# plan = self.get_plan()
# serializer = self.get_serializer(data=request.data)
# serializer.is_valid(raise_exception=True)
# data = serializer.validated_data
# application = get_application(self.request)
# event_saver: EventSaver = EventSaver.objects.filter(event_label=serializer.validated_data['label']).first()
# # try:
# event = event_saver.save_event(user=None, application=application, **serializer.validated_data)
# # except Exception as e:
# # raise exceptions.ValidationError(str(e))
#
# result_list = plan.process_event(event)
# data["promotions"] = result_list
#
# headers = self.get_success_headers(serializer.data)
# return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class ApplicationEventSubmitAPIView(CreateAPIView):
model = Promotion
serializer_class = PromoteSerializer
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
required_alternate_scopes = {
"POST": [[]],
}
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
application = get_application(self.request)
event_saver: EventSaver = EventSaver.objects.filter(event_label=serializer.validated_data['label']).first()
user = self.request.user.pk or serializer.validated_data['user']
try:
event = event_saver.save_event(user=user, application=application, **serializer.validated_data)
except Exception as e:
raise UnprocessableEntity(str(e))
analyze_event_task.delay(event.uuid)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class ApplicationEventRetrieveAPIView(RetrieveAPIView):
model = Promotion
serializer_class = PromoteSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
application = get_application(self.request)
event_saver: EventSaver = EventSaver.objects.filter(event_label=serializer.validated_data['label']).first()
event = event_saver.save_event(user=None, application=application, **serializer.validated_data)
analyze_event_task.delay(event.uuid)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)