feat(fns): парсер ФНС бухгалтерской отчетности
- Модели FinancialReport и FinancialReportLine
- FNSExcelParser для файлов fin_{id}_{ogrn}.xlsx
- FNSReportService с дедупликацией по хешу файла
- Celery задачи для мониторинга папки (каждые 5 мин)
- API: POST /fns/upload/, GET /fns/reports/
- Django admin интеграция
- 25 unit-тестов
This commit is contained in:
@@ -1,7 +1,83 @@
|
||||
"""
|
||||
Сериализаторы для приложения парсеров.
|
||||
|
||||
TODO: Добавить сериализаторы по мере необходимости.
|
||||
"""
|
||||
|
||||
# Сериализаторы будут добавлены по мере разработки конкретных парсеров
|
||||
from apps.parsers.models import FinancialReport, FinancialReportLine
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
class FinancialReportLineSerializer(serializers.ModelSerializer):
|
||||
"""Сериализатор строки финансового отчета."""
|
||||
|
||||
class Meta:
|
||||
model = FinancialReportLine
|
||||
fields = [
|
||||
"id",
|
||||
"form_code",
|
||||
"line_code",
|
||||
"line_name",
|
||||
"year",
|
||||
"period_start",
|
||||
"period_end",
|
||||
]
|
||||
|
||||
|
||||
class FinancialReportSerializer(serializers.ModelSerializer):
|
||||
"""Сериализатор финансового отчета."""
|
||||
|
||||
lines_count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = FinancialReport
|
||||
fields = [
|
||||
"id",
|
||||
"external_id",
|
||||
"ogrn",
|
||||
"file_name",
|
||||
"file_hash",
|
||||
"load_batch",
|
||||
"status",
|
||||
"source",
|
||||
"error_message",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"lines_count",
|
||||
]
|
||||
read_only_fields = fields
|
||||
|
||||
def get_lines_count(self, obj) -> int:
|
||||
return obj.lines.count()
|
||||
|
||||
|
||||
class FinancialReportDetailSerializer(FinancialReportSerializer):
|
||||
"""Сериализатор финансового отчета с детализацией строк."""
|
||||
|
||||
lines = FinancialReportLineSerializer(many=True, read_only=True)
|
||||
|
||||
class Meta(FinancialReportSerializer.Meta):
|
||||
fields = FinancialReportSerializer.Meta.fields + ["lines"]
|
||||
|
||||
|
||||
class FNSFileUploadSerializer(serializers.Serializer):
|
||||
"""Сериализатор для загрузки файлов FNS."""
|
||||
|
||||
files = serializers.ListField(
|
||||
child=serializers.FileField(),
|
||||
allow_empty=False,
|
||||
help_text="Список файлов для загрузки (fin_*.xlsx)",
|
||||
)
|
||||
|
||||
def validate_files(self, value):
|
||||
"""Валидация файлов."""
|
||||
import re
|
||||
|
||||
pattern = re.compile(r"^fin_\d+_\d{13,15}\.xlsx$")
|
||||
|
||||
for file in value:
|
||||
if not pattern.match(file.name):
|
||||
raise serializers.ValidationError(
|
||||
f"Неверный формат имени файла: {file.name}. "
|
||||
"Ожидается: fin_{{id}}_{{ogrn}}.xlsx"
|
||||
)
|
||||
|
||||
return value
|
||||
|
||||
Reference in New Issue
Block a user