feat(organizations): migrate source storage to polymorphic records

This commit is contained in:
2026-05-19 10:23:53 +02:00
parent 19a7d5a91c
commit 4ca2fa25d5
44 changed files with 7129 additions and 1551 deletions

View File

@@ -0,0 +1,143 @@
"""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)