set permissions to membership actions
This commit is contained in:
@@ -9,17 +9,20 @@ from django.core.validators import validate_email
|
|||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from datetime import datetime, timedelta
|
from datetime import timedelta
|
||||||
from django.utils import timezone
|
from rest_framework.exceptions import PermissionDenied
|
||||||
|
from django.utils.timezone import now as timezone_now
|
||||||
|
|
||||||
|
|
||||||
from .serializers import RouteSerializer, CreateRouteSerializer, CitySerializer, CountrySerializer, PlanChangeSerializer, PricingSerializer, LeadSerializer, LeadResponseSerializer
|
from .serializers import RouteSerializer, CreateRouteSerializer, CitySerializer, CountrySerializer, PlanChangeSerializer, PricingSerializer, LeadSerializer, LeadResponseSerializer
|
||||||
from api.auth.serializers import UserResponseSerializer
|
from api.auth.serializers import UserResponseSerializer
|
||||||
from api.models import UserProfile
|
from api.models import UserProfile
|
||||||
from routes.models import Route, City, Country, Leads
|
from routes.models import Route, City, Country, Leads
|
||||||
from sitemanagement.models import Pricing
|
from sitemanagement.models import Pricing, RoutePromotionLog
|
||||||
|
|
||||||
from api.utils.decorators import handle_exceptions
|
from api.utils.decorators import handle_exceptions
|
||||||
from api.utils.emailSender import send_email
|
from api.utils.emailSender import send_email
|
||||||
|
from api.utils.permissionChecker import check_monthly_limit
|
||||||
|
|
||||||
class UserDataView(ViewSet):
|
class UserDataView(ViewSet):
|
||||||
"""Эндпоинт для наполнения стора фронта данными"""
|
"""Эндпоинт для наполнения стора фронта данными"""
|
||||||
@@ -314,32 +317,54 @@ class LeadViewSet(ViewSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
class PremiumMembershipActionsView(ViewSet):
|
class PremiumMembershipActionsView(ViewSet):
|
||||||
"""Выделение объявления"""
|
"""Выделение и поднятие объявления"""
|
||||||
|
|
||||||
@action(detail=False, methods=['patch'])
|
@action(detail=False, methods=['patch'])
|
||||||
@handle_exceptions
|
@handle_exceptions
|
||||||
def highlight_route(self, request):
|
def highlight_route(self, request):
|
||||||
"""Выделяем объявление"""
|
"""Выделяем объявление"""
|
||||||
route_id = request.data.get('route_id')
|
route_id = request.data.get('route_id')
|
||||||
route = get_object_or_404(Route, id=route_id)
|
route = get_object_or_404(Route, id=route_id)
|
||||||
|
|
||||||
|
if not check_monthly_limit(request.user, route, 'highlight'):
|
||||||
|
raise PermissionDenied("Превышен лимит выделений за месяц")
|
||||||
|
|
||||||
# подсвечиваем объявление на 24 часа
|
# подсвечиваем объявление на 24 часа
|
||||||
now = timezone.now()
|
now = timezone_now()
|
||||||
route.highlight_end_DT = now + timedelta(days=1)
|
route.highlight_end_DT = now + timedelta(days=1)
|
||||||
route.is_highlighted = True
|
route.is_highlighted = True
|
||||||
route.save()
|
route.save()
|
||||||
|
|
||||||
|
# логируем действие
|
||||||
|
RoutePromotionLog.objects.create(
|
||||||
|
user=request.user,
|
||||||
|
route=route,
|
||||||
|
action_type='highlight'
|
||||||
|
)
|
||||||
|
|
||||||
return Response({
|
return Response({
|
||||||
"message": "Объявление выделено",
|
"message": "Объявление выделено",
|
||||||
"is_highlighted": route.is_highlighted
|
"is_highlighted": route.is_highlighted
|
||||||
}, status=status.HTTP_200_OK)
|
}, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
@action(detail=False, methods=['patch'])
|
@action(detail=False, methods=['patch'])
|
||||||
@handle_exceptions
|
@handle_exceptions
|
||||||
def upper_route(self, request):
|
def upper_route(self, request):
|
||||||
"""Поднимаем объявление"""
|
"""Поднимаем объявление"""
|
||||||
route_id = request.data.get('route_id')
|
route_id = request.data.get('route_id')
|
||||||
route = get_object_or_404(Route, id=route_id)
|
route = get_object_or_404(Route, id=route_id)
|
||||||
route.rising_DT = datetime.now()
|
|
||||||
|
if not check_monthly_limit(request.user, route, 'rising'):
|
||||||
|
raise PermissionDenied("Превышен лимит поднятий за месяц")
|
||||||
|
|
||||||
|
route.rising_DT = timezone_now()
|
||||||
route.save()
|
route.save()
|
||||||
return Response({"message": "Объявление поднято"}, status=status.HTTP_200_OK)
|
|
||||||
|
# логируем действие
|
||||||
|
RoutePromotionLog.objects.create(
|
||||||
|
user=request.user,
|
||||||
|
route=route,
|
||||||
|
action_type='rising'
|
||||||
|
)
|
||||||
|
|
||||||
|
return Response({"message": "Объявление поднято"}, status=status.HTTP_200_OK)
|
||||||
14
backend/api/utils/permissionChecker.py
Normal file
14
backend/api/utils/permissionChecker.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from django.utils.timezone import now
|
||||||
|
from datetime import timedelta
|
||||||
|
from sitemanagement.models import RoutePromotionLog
|
||||||
|
|
||||||
|
MAX_ACTIONS_PER_MONTH = 5
|
||||||
|
|
||||||
|
def check_monthly_limit(user, route, action_type):
|
||||||
|
month_ago = now() - timedelta(days=30)
|
||||||
|
return RoutePromotionLog.objects.filter(
|
||||||
|
user=user,
|
||||||
|
route=route,
|
||||||
|
action_type=action_type,
|
||||||
|
created_at__gte=month_ago
|
||||||
|
).count() < MAX_ACTIONS_PER_MONTH
|
||||||
@@ -7,6 +7,7 @@ from django.dispatch import receiver
|
|||||||
from transliterate import translit
|
from transliterate import translit
|
||||||
from routes.constants.account_types import account_types
|
from routes.constants.account_types import account_types
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from routes.models import Route
|
||||||
|
|
||||||
class FAQ (models.Model):
|
class FAQ (models.Model):
|
||||||
title = models.CharField(max_length=250)
|
title = models.CharField(max_length=250)
|
||||||
@@ -89,4 +90,17 @@ class Transactions(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'{self.user} - {self.amount}'
|
return f'{self.user} - {self.amount}'
|
||||||
|
|
||||||
|
class RoutePromotionLog(models.Model):
|
||||||
|
ACTION_CHOICES = [
|
||||||
|
('highlight', 'Выделение'),
|
||||||
|
('rising', 'Поднятие'),
|
||||||
|
]
|
||||||
|
|
||||||
|
route = models.ForeignKey(Route, on_delete=models.CASCADE, related_name='promotion_logs')
|
||||||
|
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
action_type = models.CharField(max_length=20, choices=ACTION_CHOICES)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.user} - {self.action_type} for route {self.route.id} at {self.created_at}"
|
||||||
Reference in New Issue
Block a user