Files
mostovik-backend/src/apps/parsers/views.py
Aleksandr Meshchriakov eacb1527c4 refactor(fns): переместить роуты /api/v1/parsers/fns → /api/v1/fns
- Упростить URL: /api/v1/fns/reports/, /api/v1/fns/upload/
- Добавить swagger теги для группировки в документации
2026-02-01 14:49:43 +01:00

123 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Views для приложения парсеров.
"""
import hashlib
from pathlib import Path
from apps.parsers.models import FinancialReport
from apps.parsers.serializers import (
FinancialReportDetailSerializer,
FinancialReportSerializer,
FNSFileUploadSerializer,
)
from apps.parsers.tasks import process_fns_file
from django.conf import settings
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.parsers import MultiPartParser
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ReadOnlyModelViewSet
FNS_TAG = "ФНС - Бухгалтерская отчетность"
class FinancialReportViewSet(ReadOnlyModelViewSet):
"""
API для просмотра финансовых отчетов ФНС.
list:
Получить список всех отчетов.
Поддерживает фильтрацию по: ogrn, external_id, status.
retrieve:
Получить детальную информацию об отчете, включая все строки.
"""
queryset = FinancialReport.objects.all().order_by("-created_at")
filterset_fields = ["ogrn", "external_id", "status", "source"]
def get_serializer_class(self):
if self.action == "retrieve":
return FinancialReportDetailSerializer
return FinancialReportSerializer
@swagger_auto_schema(tags=[FNS_TAG])
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
@swagger_auto_schema(tags=[FNS_TAG])
def retrieve(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)
class FNSReportUploadView(APIView):
"""
API для загрузки файлов бухгалтерской отчетности ФНС.
POST:
Пакетная загрузка файлов.
Файлы сохраняются во временную директорию и ставятся в очередь
на обработку через Celery.
Request:
multipart/form-data с полем 'files' (можно несколько файлов)
Response:
{
"queued": 3,
"skipped": 1,
"task_ids": ["uuid1", "uuid2", "uuid3"]
}
"""
parser_classes = [MultiPartParser]
@swagger_auto_schema(tags=[FNS_TAG], request_body=FNSFileUploadSerializer)
def post(self, request):
serializer = FNSFileUploadSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
files = serializer.validated_data["files"]
task_ids = []
queued = 0
skipped = 0
# Создаём директорию для загрузки
upload_dir = Path(settings.FNS_WATCH_DIRECTORY)
upload_dir.mkdir(parents=True, exist_ok=True)
from apps.parsers.services import FNSReportService
for file in files:
# Вычисляем хеш файла
file_content = file.read()
file_hash = hashlib.sha256(file_content).hexdigest()
file.seek(0)
# Проверяем дубликат
if FNSReportService.exists_by_hash(file_hash):
skipped += 1
continue
# Сохраняем файл
file_path = upload_dir / file.name
with open(file_path, "wb") as f:
for chunk in file.chunks():
f.write(chunk)
# Ставим в очередь
task = process_fns_file.delay(str(file_path))
task_ids.append(task.id)
queued += 1
return Response(
{
"queued": queued,
"skipped": skipped,
"task_ids": task_ids,
},
status=status.HTTP_202_ACCEPTED,
)