193 lines
7.8 KiB
Python
193 lines
7.8 KiB
Python
from rest_framework import status
|
|
from rest_framework.viewsets import ViewSet
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.decorators import action
|
|
from rest_framework.response import Response
|
|
|
|
from django.shortcuts import get_object_or_404
|
|
from django.core.validators import validate_email
|
|
from django.core.exceptions import ValidationError
|
|
from django.db import models
|
|
from django.contrib.auth.models import User
|
|
|
|
from api.auth.serializers import UserResponseSerializer
|
|
from api.models import UserProfile
|
|
from api.utils.decorators import handle_exceptions
|
|
from routes.models import Route, City, Country
|
|
from sitemanagement.models import Pricing
|
|
from .serializers import RouteSerializer, CreateRouteSerializer, CitySerializer, CountrySerializer, PlanChangeSerializer, PricingSerializer
|
|
|
|
class UserDataView(ViewSet):
|
|
"""Эндпоинт для наполнения стора фронта данными"""
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def initial(self, request, *args, **kwargs):
|
|
try:
|
|
super().initial(request, *args, **kwargs)
|
|
except Exception as e:
|
|
print(f"Authentication error: {e}")
|
|
raise
|
|
|
|
@action(detail=False, methods=['get'])
|
|
@handle_exceptions
|
|
def user_data(self, request):
|
|
user = request.user
|
|
|
|
try:
|
|
user_data = UserResponseSerializer(user).data
|
|
return Response(user_data, status=status.HTTP_200_OK)
|
|
except UserProfile.DoesNotExist:
|
|
return Response(
|
|
{"error": "User profile not found"},
|
|
status=status.HTTP_404_NOT_FOUND
|
|
)
|
|
|
|
class AccountActionsView(ViewSet):
|
|
"""Действия в аккаунте пользователя:
|
|
- PATCH данных в account/main
|
|
- POST новых заявок"""
|
|
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
@action(detail=False, methods=['patch'])
|
|
@handle_exceptions
|
|
|
|
def change_data_main_tab(self, request):
|
|
"""Обновление данных на главной странице аккаунта"""
|
|
|
|
user = request.user
|
|
user_profile = get_object_or_404(UserProfile, user=user)
|
|
|
|
# обновляем данные пользователя
|
|
if 'firstName' in request.data:
|
|
user.first_name = request.data['firstName']
|
|
if 'lastName' in request.data:
|
|
user.last_name = request.data['lastName']
|
|
if 'email' in request.data:
|
|
email = request.data['email']
|
|
validate_email(email) # handle_exceptions обработает ValidationError
|
|
user.email = email
|
|
user.username = email
|
|
|
|
# обновляем номер телефона
|
|
if 'phone_number' in request.data:
|
|
phone = request.data['phone_number']
|
|
if phone:
|
|
if len(phone) < 13: # +375XXXXXXXXX
|
|
raise ValidationError("Номер телефона слишком короткий")
|
|
|
|
if len(phone) > 18:
|
|
raise ValidationError("Номер телефона слишком длинный")
|
|
|
|
# проверка на уникальность
|
|
if UserProfile.objects.filter(phone_number=phone).exclude(user=user).exists():
|
|
raise ValidationError("Этот номер телефона уже используется")
|
|
|
|
user_profile.phone_number = phone
|
|
|
|
# сохраняем изменения
|
|
user.save()
|
|
user_profile.save()
|
|
|
|
return Response({
|
|
"message": "Данные успешно обновлены",
|
|
"user": UserResponseSerializer(user).data
|
|
}, status=status.HTTP_200_OK)
|
|
|
|
@action(detail=False, methods=['get'])
|
|
@handle_exceptions
|
|
def user_routes(self, request):
|
|
"""Получаем список заявок юзера"""
|
|
|
|
user = request.user
|
|
routes = Route.objects.filter(owner=user)
|
|
return Response(RouteSerializer(routes, many=True).data, status=status.HTTP_200_OK)
|
|
|
|
@action(detail=False, methods=['post'])
|
|
@handle_exceptions
|
|
def create_route(self, request):
|
|
"""Создаем новую заявку"""
|
|
|
|
serializer = CreateRouteSerializer(data=request.data, context={'request': request})
|
|
if not serializer.is_valid():
|
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
route = serializer.save()
|
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
|
|
|
|
class CityView(ViewSet):
|
|
"""Получаем список городов из базы для автокомплита"""
|
|
|
|
@action(detail=False, methods=['get'])
|
|
@handle_exceptions
|
|
def get_cities(self, request):
|
|
# получаем параметр country_id из query params
|
|
country_id = request.query_params.get('country_id')
|
|
|
|
# базовый QuerySet
|
|
cities = City.objects.all()
|
|
|
|
# фильтруем города по стране, если указан country_id
|
|
if country_id:
|
|
cities = cities.filter(country_id=country_id)
|
|
|
|
# поиск по названию города
|
|
search = request.query_params.get('search')
|
|
if search:
|
|
cities = cities.filter(name__icontains=search)
|
|
|
|
# ограничиваем количество результатов и сортируем по имени
|
|
cities = cities.order_by('name')[:100]
|
|
|
|
return Response(CitySerializer(cities, many=True).data, status=status.HTTP_200_OK)
|
|
|
|
class CountryView(ViewSet):
|
|
"""Получаем список стран из базы для автокомплита"""
|
|
|
|
@action(detail=False, methods=['get'])
|
|
@handle_exceptions
|
|
def get_countries(self, request):
|
|
# базовый QuerySet
|
|
countries = Country.objects.all()
|
|
|
|
# поиск по названию страны
|
|
search = request.query_params.get('search')
|
|
if search:
|
|
countries = countries.filter(
|
|
models.Q(international_name__icontains=search) |
|
|
models.Q(official_name__icontains=search)
|
|
)
|
|
|
|
# сортируем по международному названию
|
|
countries = countries.order_by('international_name')
|
|
|
|
return Response(CountrySerializer(countries, many=True).data, status=status.HTTP_200_OK)
|
|
|
|
class ChangeUserMembership(ViewSet):
|
|
"""Меняем тарифный план пользователя"""
|
|
|
|
@action(detail=False, methods=['post'])
|
|
@handle_exceptions
|
|
def change_plan(self, request):
|
|
"""Меняем пользователю тарифный план"""
|
|
user = request.user
|
|
user_profile = get_object_or_404(UserProfile, user=user)
|
|
|
|
serializer = PlanChangeSerializer(user_profile, data=request.data)
|
|
|
|
if serializer.is_valid():
|
|
serializer.save()
|
|
return Response({"message": "Тариф успешно изменен"}, status=status.HTTP_200_OK)
|
|
|
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
class GetMembershipData(ViewSet):
|
|
"""Получаем все тарифные планы"""
|
|
|
|
@action(detail=False, methods=['get'])
|
|
@handle_exceptions
|
|
def get_pricing_data(self, request):
|
|
"""Получаем данные по тарифам"""
|
|
pricing_data = Pricing.objects.all().order_by('price')
|
|
serializer = PricingSerializer(pricing_data, many=True)
|
|
return Response(serializer.data, status=status.HTTP_200_OK) |