144 lines
5.8 KiB
Python
144 lines
5.8 KiB
Python
"""Tests for direct parser ingestion into organization source storage."""
|
||
|
||
from decimal import Decimal
|
||
|
||
from apps.parsers.models import FinancialReport, GenericParserRecord, ParserLoadLog
|
||
from django.test import TestCase
|
||
from organizations.models import (
|
||
DefenseSupplierExtension,
|
||
FinancialIndicatorsExtension,
|
||
Organization,
|
||
OrganizationSourceFinancialLine,
|
||
OrganizationSourceRecord,
|
||
SourceGroup,
|
||
)
|
||
from organizations.source_ingestion import (
|
||
OrganizationSourceIngestionService,
|
||
SourceFinancialLineInput,
|
||
SourceRecordInput,
|
||
)
|
||
|
||
|
||
class OrganizationSourceIngestionServiceTest(TestCase):
|
||
"""Checks runtime parser writes bypass legacy parser record tables."""
|
||
|
||
def test_save_generic_records_writes_source_records_without_legacy_rows(self):
|
||
result = OrganizationSourceIngestionService.save_records(
|
||
source=ParserLoadLog.Source.UNFAIR_SUPPLIERS,
|
||
load_batch=42,
|
||
records=[
|
||
SourceRecordInput(
|
||
external_id="unfair-42",
|
||
title="Недобросовестный поставщик",
|
||
organization_name='ООО "ГОЗ"',
|
||
inn="7707083803",
|
||
ogrn="",
|
||
record_date="2026-05-18",
|
||
amount=Decimal("100.50"),
|
||
status="active",
|
||
url="https://example.test/unfair-42",
|
||
payload={"reason": "contract breach"},
|
||
)
|
||
],
|
||
)
|
||
|
||
self.assertEqual(result.scanned, 1)
|
||
self.assertEqual(result.created_records, 1)
|
||
self.assertEqual(result.updated_records, 0)
|
||
self.assertEqual(result.created_extensions, 1)
|
||
self.assertEqual(result.unresolved, 0)
|
||
self.assertEqual(GenericParserRecord.objects.count(), 0)
|
||
|
||
organization = Organization.objects.get(inn="7707083803")
|
||
extension = DefenseSupplierExtension.objects.get(organization=organization)
|
||
self.assertEqual(extension.source_group, SourceGroup.DEFENSE_SUPPLIERS)
|
||
self.assertEqual(extension.records_count, 1)
|
||
|
||
record = OrganizationSourceRecord.objects.get(extension=extension)
|
||
self.assertEqual(record.source, ParserLoadLog.Source.UNFAIR_SUPPLIERS)
|
||
self.assertEqual(record.record_type, "unfair_supplier")
|
||
self.assertEqual(record.external_id, "unfair-42")
|
||
self.assertEqual(record.amount, Decimal("100.50"))
|
||
self.assertEqual(record.payload["reason"], "contract breach")
|
||
self.assertEqual(record.legacy_model, "")
|
||
self.assertEqual(record.legacy_pk, "")
|
||
|
||
def test_save_records_is_idempotent_by_source_external_id(self):
|
||
first = SourceRecordInput(
|
||
external_id="unfair-idempotent",
|
||
title="Old title",
|
||
organization_name='ООО "Идемпотентность"',
|
||
inn="7707083810",
|
||
status="old",
|
||
payload={"version": 1},
|
||
)
|
||
second = SourceRecordInput(
|
||
external_id="unfair-idempotent",
|
||
title="New title",
|
||
organization_name='ООО "Идемпотентность"',
|
||
inn="7707083810",
|
||
status="new",
|
||
payload={"version": 2},
|
||
)
|
||
|
||
OrganizationSourceIngestionService.save_records(
|
||
source=ParserLoadLog.Source.UNFAIR_SUPPLIERS,
|
||
load_batch=43,
|
||
records=[first],
|
||
)
|
||
result = OrganizationSourceIngestionService.save_records(
|
||
source=ParserLoadLog.Source.UNFAIR_SUPPLIERS,
|
||
load_batch=44,
|
||
records=[second],
|
||
)
|
||
|
||
self.assertEqual(result.created_records, 0)
|
||
self.assertEqual(result.updated_records, 1)
|
||
self.assertEqual(OrganizationSourceRecord.objects.count(), 1)
|
||
record = OrganizationSourceRecord.objects.get()
|
||
self.assertEqual(record.title, "New title")
|
||
self.assertEqual(record.status, "new")
|
||
self.assertEqual(record.payload["version"], 2)
|
||
self.assertEqual(record.load_batch, 44)
|
||
|
||
def test_save_financial_report_writes_financial_lines_without_legacy_report(self):
|
||
result = OrganizationSourceIngestionService.save_records(
|
||
source=ParserLoadLog.Source.FNS_REPORTS,
|
||
load_batch=88,
|
||
records=[
|
||
SourceRecordInput(
|
||
external_id="fns-report-1",
|
||
title="fin_001_1027700132002.xlsx",
|
||
organization_name="",
|
||
ogrn="1027700132002",
|
||
status="success",
|
||
payload={
|
||
"file_name": "fin_001_1027700132002.xlsx",
|
||
"file_hash": "a" * 64,
|
||
},
|
||
financial_lines=[
|
||
SourceFinancialLineInput(
|
||
form_code="1",
|
||
line_code="1100",
|
||
line_name="Нематериальные активы",
|
||
year=2025,
|
||
period_start=100,
|
||
period_end=200,
|
||
)
|
||
],
|
||
)
|
||
],
|
||
)
|
||
|
||
self.assertEqual(result.created_records, 1)
|
||
self.assertEqual(result.created_financial_lines, 1)
|
||
self.assertEqual(FinancialReport.objects.count(), 0)
|
||
|
||
organization = Organization.objects.get(ogrn="1027700132002")
|
||
extension = FinancialIndicatorsExtension.objects.get(organization=organization)
|
||
record = OrganizationSourceRecord.objects.get(extension=extension)
|
||
self.assertEqual(record.source, ParserLoadLog.Source.FNS_REPORTS)
|
||
line = OrganizationSourceFinancialLine.objects.get(source_record=record)
|
||
self.assertEqual(line.line_code, "1100")
|
||
self.assertEqual(line.period_end, 200)
|