fix: restore code-less FNS financial reports
This commit is contained in:
95
tests/apps/organizations/test_restore_fns_financial_lines.py
Normal file
95
tests/apps/organizations/test_restore_fns_financial_lines.py
Normal file
@@ -0,0 +1,95 @@
|
||||
"""Tests for restoring normalized FNS financial lines."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
from apps.parsers.models import ParserLoadLog
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase, override_settings
|
||||
from openpyxl import Workbook
|
||||
from organizations.models import (
|
||||
FinancialIndicatorsExtension,
|
||||
OrganizationSourceFinancialLine,
|
||||
OrganizationSourceRecord,
|
||||
)
|
||||
|
||||
from tests.apps.parsers.organization_helpers import create_directory_organization
|
||||
|
||||
|
||||
class RestoreFNSFinancialLinesCommandTests(TestCase):
|
||||
"""Restore only empty reports and keep reruns idempotent."""
|
||||
|
||||
def test_dry_run_then_restores_codeless_processed_workbook(self):
|
||||
ogrn = "1187700006273"
|
||||
external_id = "0130160"
|
||||
organization = create_directory_organization(
|
||||
name="Тестовая организация",
|
||||
inn="7700000001",
|
||||
kpp="770001001",
|
||||
okpo="12345678",
|
||||
ogrn=ogrn,
|
||||
)
|
||||
extension = FinancialIndicatorsExtension.objects.create(
|
||||
organization=organization,
|
||||
title="Финансово-экономические показатели",
|
||||
)
|
||||
file_name = f"fin_{external_id}_{ogrn}.xlsx"
|
||||
record = OrganizationSourceRecord.objects.create(
|
||||
extension=extension,
|
||||
source=ParserLoadLog.Source.FNS_REPORTS,
|
||||
record_type="financial_report",
|
||||
external_id=external_id,
|
||||
title=file_name,
|
||||
status="success",
|
||||
payload={
|
||||
"external_id": external_id,
|
||||
"file_name": file_name,
|
||||
"lines_count": 0,
|
||||
"ogrn": ogrn,
|
||||
},
|
||||
)
|
||||
|
||||
with TemporaryDirectory() as temp_directory:
|
||||
workbook = Workbook()
|
||||
worksheet = workbook.active
|
||||
worksheet.append(["Форма №1", 2020, None, 2021, None])
|
||||
worksheet.append(
|
||||
["Бухгалтерский баланс", "Начало", "Конец", "Начало", "Конец"]
|
||||
)
|
||||
worksheet.append(["Баланс", 60_232, 234_841, 234_841, 244_479])
|
||||
workbook.save(Path(temp_directory) / file_name)
|
||||
|
||||
with override_settings(FNS_PROCESSED_DIRECTORY=temp_directory):
|
||||
call_command(
|
||||
"restore_fns_financial_lines",
|
||||
"--ogrn",
|
||||
ogrn,
|
||||
"--dry-run",
|
||||
"--silent",
|
||||
)
|
||||
self.assertFalse(
|
||||
OrganizationSourceFinancialLine.objects.filter(
|
||||
source_record=record
|
||||
).exists()
|
||||
)
|
||||
|
||||
call_command(
|
||||
"restore_fns_financial_lines",
|
||||
"--ogrn",
|
||||
ogrn,
|
||||
"--silent",
|
||||
)
|
||||
call_command(
|
||||
"restore_fns_financial_lines",
|
||||
"--ogrn",
|
||||
ogrn,
|
||||
"--silent",
|
||||
)
|
||||
|
||||
lines = OrganizationSourceFinancialLine.objects.filter(source_record=record)
|
||||
self.assertEqual(lines.count(), 2)
|
||||
self.assertEqual(set(lines.values_list("year", flat=True)), {2020, 2021})
|
||||
record.refresh_from_db()
|
||||
self.assertEqual(record.payload["lines_count"], 2)
|
||||
@@ -2,6 +2,9 @@
|
||||
Тесты для FNS парсера бухгалтерской отчетности.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
from apps.parsers.clients.fns.parser import FNSExcelParser, FNSParserError
|
||||
from apps.parsers.clients.fns.schemas import ParsedReport, ReportLine
|
||||
from apps.parsers.models import FinancialReport
|
||||
@@ -10,6 +13,7 @@ from apps.parsers.services import (
|
||||
FNSReportService,
|
||||
)
|
||||
from django.test import TestCase
|
||||
from openpyxl import Workbook
|
||||
from organizations.models import Organization
|
||||
|
||||
from tests.apps.parsers.organization_helpers import create_directory_organization
|
||||
@@ -274,6 +278,103 @@ class TestFNSParserParseValue(TestCase):
|
||||
self.assertIsNone(FNSExcelParser._parse_value(fake.word()))
|
||||
|
||||
|
||||
class TestFNSExcelParserWorkbook(TestCase):
|
||||
"""Регрессии поддерживаемых структур бухгалтерских XLSX."""
|
||||
|
||||
def test_parses_workbook_without_line_code_column(self):
|
||||
with TemporaryDirectory() as temp_directory:
|
||||
path = Path(temp_directory) / "fin_0130160_1187700006273.xlsx"
|
||||
workbook = Workbook()
|
||||
worksheet = workbook.active
|
||||
worksheet.append(["Форма №1", 2020, None, 2021, None])
|
||||
worksheet.append(
|
||||
["Бухгалтерский баланс", "Начало", "Конец", "Начало", "Конец"]
|
||||
)
|
||||
worksheet.append(["Баланс", 60_232, 234_841, 234_841, 244_479])
|
||||
worksheet.append(["Внеоборотные активы", None, None, None, None])
|
||||
worksheet.append(["Итого", 1_878, 7_071, 7_071, 18_709])
|
||||
worksheet.append(["Форма №3", 2020, None, 2021, None])
|
||||
worksheet.append(
|
||||
[
|
||||
"Отчет об изменении капитала",
|
||||
"Начало",
|
||||
"Конец",
|
||||
"Начало",
|
||||
"Конец",
|
||||
]
|
||||
)
|
||||
worksheet.append(["Добавочный капитал", None, None, None, None])
|
||||
worksheet.append(["Увеличение - всего", 0, 10, 10, 20])
|
||||
worksheet.append(["переоценка имущества", 0, 10, 10, 20])
|
||||
worksheet.append(["Уменьшение - всего", 0, 5, 5, 6])
|
||||
worksheet.append(["реорганизация ЮЛ", 0, 5, 5, 6])
|
||||
worksheet.append(["Резервный капитал", None, None, None, None])
|
||||
worksheet.append(["переоценка имущества", 0, -5, -5, -6])
|
||||
worksheet.append(["Форма №4", 2020, None, 2021, None])
|
||||
worksheet.append(
|
||||
[
|
||||
"Отчет о движении денежных средств",
|
||||
"Начало",
|
||||
"Конец",
|
||||
"Начало",
|
||||
"Конец",
|
||||
]
|
||||
)
|
||||
worksheet.append(["Денежные потоки от инвестиционных операций", None, None])
|
||||
worksheet.append(["Поступления – всего", 0, 100, 100, 200])
|
||||
worksheet.append(["Сальдо", 0, 100, 100, 200])
|
||||
worksheet.append(["Форма №6", 2020, None, 2021, None])
|
||||
worksheet.append(
|
||||
[
|
||||
"Отчет о целевом использовании полученных средств",
|
||||
"Начало",
|
||||
"Конец",
|
||||
"Начало",
|
||||
"Конец",
|
||||
]
|
||||
)
|
||||
worksheet.append(["Поступило средств", None, None, None, None])
|
||||
worksheet.append(["Итого", 0, 10, 10, 20])
|
||||
worksheet.append(["Использовано средств", None, None, None, None])
|
||||
worksheet.append(["Итого", 0, 5, 5, 6])
|
||||
workbook.save(path)
|
||||
|
||||
report = FNSExcelParser.parse_file(path)
|
||||
|
||||
self.assertEqual(report.external_id, "0130160")
|
||||
self.assertEqual(report.ogrn, "1187700006273")
|
||||
self.assertEqual(report.years, {2020, 2021})
|
||||
self.assertEqual(
|
||||
{line.line_code for line in report.lines},
|
||||
{
|
||||
"1100",
|
||||
"1600",
|
||||
"3310",
|
||||
"3312",
|
||||
"3320",
|
||||
"3322",
|
||||
"3326",
|
||||
"4200",
|
||||
"4210",
|
||||
"6200",
|
||||
"6300",
|
||||
},
|
||||
)
|
||||
|
||||
def test_rejects_codeless_value_row_without_known_accounting_code(self):
|
||||
with TemporaryDirectory() as temp_directory:
|
||||
path = Path(temp_directory) / "fin_0000001_1187700006273.xlsx"
|
||||
workbook = Workbook()
|
||||
worksheet = workbook.active
|
||||
worksheet.append(["Форма №1", 2021, None])
|
||||
worksheet.append(["Бухгалтерский баланс", "Начало", "Конец"])
|
||||
worksheet.append(["Неизвестная строка", 1, 2])
|
||||
workbook.save(path)
|
||||
|
||||
with self.assertRaisesMessage(FNSParserError, "не определен код строки"):
|
||||
FNSExcelParser.parse_file(path)
|
||||
|
||||
|
||||
class TestFNSReportServiceIntegration(TestCase):
|
||||
"""Интеграционные тесты сервиса FNSReportService."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user