from rest_framework import status from rest_framework.viewsets import ViewSet from rest_framework.permissions import IsAuthenticated from drf_spectacular.utils import extend_schema, OpenApiResponse, OpenApiExample from rest_framework.decorators import action from rest_framework.response import Response from django.http import HttpResponse from api.account.serializers.alert_serializers import AlertSerializer from sitemanagement.models import Alert from api.utils.decorators import handle_exceptions from api.utils.error_serializer import ErrorResponseSerializer from api.utils.report_generators import generate_csv_report, generate_pdf_report from django.utils import timezone @extend_schema(tags=['Алерты']) class AlertView(ViewSet): permission_classes = [IsAuthenticated] @extend_schema( summary="Получение списка алертов", description="Возвращает список всех алертов в системе", responses={ 200: OpenApiResponse(response=AlertSerializer(many=True), description="Список алертов успешно получен", examples=[OpenApiExample( 'Успешный ответ', value=[{ "id": 1, "name": "Датчик 1", "object": "Объект 1", "metric_value": "12.5 °C", "sensor_type_name": "Инклинометр", "message": "alert message", "severity": "warning", "created_at": "2025-10-06T15:53:11.759725+03:00", "resolved": False }] )]) }) @action(detail=False, methods=['get']) @handle_exceptions def get_alerts(self, request): alerts = Alert.objects.all() serializer = AlertSerializer(alerts, many=True) return Response(serializer.data) @extend_schema( summary="Изменение статуса алерта", description="Изменяет статус обработки алерта на противоположный", responses={ 200: OpenApiResponse(response=AlertSerializer, description="Статус алерта успешно изменен", examples=[OpenApiExample( 'Успешный ответ', value={ "message": "Статус алерта успешно изменен" } )]), 404: OpenApiResponse( response=ErrorResponseSerializer, description="Алерт не найден", examples=[ OpenApiExample( 'Алерт не найден', value={"error": "Алерт не найден"}, status_codes=['404'] ) ] ) }) @action(detail=True, methods=['patch']) @handle_exceptions def change_alert_status(self, request, pk=None): try: alert = Alert.objects.get(pk=pk) alert.resolved = not alert.resolved alert.save() return Response({"message": "Статус алерта успешно изменен"}, status=status.HTTP_200_OK) except Alert.DoesNotExist: return Response( {"error": "Алерт не найден"}, status=status.HTTP_404_NOT_FOUND) @extend_schema(tags=['Репорты']) class ReportView(ViewSet): # permission_classes = [IsAuthenticated] @extend_schema( summary="Генерация отчета", description="Генерирует отчет в выбранном формате (PDF или CSV)", request={'application/json': {'type': 'object', 'properties': {'report_format': {'type': 'string', 'enum': ['pdf', 'csv']}}}}, responses={ 200: OpenApiResponse(response=AlertSerializer(many=True), description="Список репортов успешно получен", examples=[OpenApiExample( 'Успешный ответ', value=[{ "message" : "Отчет успешно сгенерирован" }] )]), 400: OpenApiResponse( response=ErrorResponseSerializer, description="Неверный формат", examples=[OpenApiExample( 'Неверный формат', value={"error": "Неверный формат"}, status_codes=['400'] )] ) }) @action(detail=False, methods=['post']) @handle_exceptions def get_reports(self, request): """Генерация отчета в выбранном формате""" report_format = request.data.get('report_format', '').lower() if not report_format: report_format = request.query_params.get('format', '').lower() if report_format not in ["pdf", "csv"]: return Response( {"error": "Неверный формат. Допустимые значения: pdf, csv"}, status=status.HTTP_400_BAD_REQUEST ) alerts = Alert.objects.select_related( 'sensor', 'sensor__signal_format', 'sensor_type', 'metric' ).prefetch_related( 'sensor__zones', 'sensor__zones__object' ).all() # текущая дата для имени файла timestamp = timezone.now().strftime("%Y%m%d_%H%M%S") if report_format == "csv": response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = f'attachment; filename="alerts_report_{timestamp}.csv"' response.write(generate_csv_report(alerts)) return response else: # pdf response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = f'attachment; filename="alerts_report_{timestamp}.pdf"' response.write(generate_pdf_report(alerts)) return response