feat: use authoritative organization directory
Some checks failed
CI/CD Pipeline / Quality Gate (push) Failing after 9s
CI/CD Pipeline / Build and Push Images (push) Has been skipped
CI/CD Pipeline / Deploy Dev via Compose (push) Has been skipped
CI/CD Pipeline / Internal Notify (push) Successful in 0s

This commit is contained in:
2026-06-07 16:04:43 +02:00
parent 79f0f8ebf7
commit 6ba8fa8d88
41 changed files with 2781 additions and 1058 deletions

View File

@@ -23,6 +23,11 @@ class OrganizationSourceIngestionServiceTest(TestCase):
"""Checks runtime parser writes bypass legacy parser record tables."""
def test_save_generic_records_writes_source_records_without_legacy_rows(self):
Organization.objects.create(
name='ООО "ГОЗ"',
inn="7707083803",
)
result = OrganizationSourceIngestionService.save_records(
source=ParserLoadLog.Source.UNFAIR_SUPPLIERS,
load_batch=42,
@@ -47,6 +52,7 @@ class OrganizationSourceIngestionServiceTest(TestCase):
self.assertEqual(result.updated_records, 0)
self.assertEqual(result.created_extensions, 1)
self.assertEqual(result.unresolved, 0)
self.assertEqual(result.created_organizations, 0)
self.assertEqual(GenericParserRecord.objects.count(), 0)
organization = Organization.objects.get(inn="7707083803")
@@ -64,6 +70,11 @@ class OrganizationSourceIngestionServiceTest(TestCase):
self.assertEqual(record.legacy_pk, "")
def test_save_records_is_idempotent_by_source_external_id(self):
Organization.objects.create(
name='ООО "Идемпотентность"',
inn="7707083810",
)
first = SourceRecordInput(
external_id="unfair-idempotent",
title="Old title",
@@ -101,7 +112,7 @@ class OrganizationSourceIngestionServiceTest(TestCase):
self.assertEqual(record.payload["version"], 2)
self.assertEqual(record.load_batch, 44)
def test_save_records_does_not_attach_identified_record_to_name_only_org(self):
def test_save_records_skips_identified_record_without_directory_match(self):
name_only = Organization.objects.create(name="Acme Security")
result = OrganizationSourceIngestionService.save_records(
@@ -119,17 +130,19 @@ class OrganizationSourceIngestionServiceTest(TestCase):
],
)
self.assertEqual(result.created_records, 1)
organization = Organization.objects.get(inn="7713497980")
self.assertNotEqual(organization.uid, name_only.uid)
self.assertEqual(organization.ogrn, "1237700253306")
record = OrganizationSourceRecord.objects.get(external_id="fstec-5066")
self.assertEqual(record.extension.organization, organization)
self.assertEqual(result.created_records, 0)
self.assertEqual(result.unresolved, 1)
self.assertEqual(result.skipped_unmatched, 1)
self.assertFalse(Organization.objects.filter(inn="7713497980").exists())
self.assertFalse(
OrganizationSourceRecord.objects.filter(external_id="fstec-5066").exists()
)
self.assertFalse(name_only.source_extensions.exists())
def test_save_records_fills_missing_identity_on_resolved_organization(self):
def test_save_records_does_not_fill_missing_identity_on_resolved_organization(self):
partial = Organization.objects.create(
name="1237700253306",
name="Acme Security",
inn="7713497980",
ogrn="1237700253306",
)
@@ -154,6 +167,78 @@ class OrganizationSourceIngestionServiceTest(TestCase):
record = OrganizationSourceRecord.objects.get(external_id="fstec-5067")
self.assertEqual(record.extension.organization, partial)
def test_save_records_uses_single_head_organization_for_duplicate_inn_ogrn(self):
head = Organization.objects.create(
name="Head",
inn="7713497980",
ogrn="1237700253306",
filial=".F.",
is_branch=False,
)
Organization.objects.create(
name="Branch",
inn="7713497980",
ogrn="1237700253306",
filial=".T.",
is_branch=True,
)
result = OrganizationSourceIngestionService.save_records(
source=ParserLoadLog.Source.FSTEC,
load_batch=49,
records=[
SourceRecordInput(
external_id="fstec-head",
title="Weblock",
organization_name="Head",
inn="7713497980",
ogrn="1237700253306",
)
],
)
self.assertEqual(result.created_records, 1)
record = OrganizationSourceRecord.objects.get(external_id="fstec-head")
self.assertEqual(record.extension.organization, head)
def test_save_records_skips_ambiguous_duplicate_inn_ogrn(self):
Organization.objects.create(
name="Head 1",
inn="7713497980",
ogrn="1237700253306",
filial=".F.",
is_branch=False,
)
Organization.objects.create(
name="Head 2",
inn="7713497980",
ogrn="1237700253306",
filial=".F.",
is_branch=False,
)
result = OrganizationSourceIngestionService.save_records(
source=ParserLoadLog.Source.FSTEC,
load_batch=50,
records=[
SourceRecordInput(
external_id="fstec-ambiguous",
title="Weblock",
organization_name="Head",
inn="7713497980",
ogrn="1237700253306",
)
],
)
self.assertEqual(result.created_records, 0)
self.assertEqual(result.skipped_ambiguous, 1)
self.assertFalse(
OrganizationSourceRecord.objects.filter(
external_id="fstec-ambiguous"
).exists()
)
def test_save_records_ignores_ogrip_like_ogrn_for_legal_entity_inn(self):
result = OrganizationSourceIngestionService.save_records(
source=ParserLoadLog.Source.INDUSTRIAL,
@@ -169,10 +254,9 @@ class OrganizationSourceIngestionServiceTest(TestCase):
],
)
self.assertEqual(result.created_records, 1)
organization = Organization.objects.get(inn="7720525156")
self.assertEqual(organization.ogrn, "")
self.assertEqual(organization.ogrip, "")
self.assertEqual(result.created_records, 0)
self.assertEqual(result.unresolved, 1)
self.assertFalse(Organization.objects.filter(inn="7720525156").exists())
def test_save_records_does_not_add_ogrip_to_existing_legal_entity(self):
organization = Organization.objects.create(
@@ -196,11 +280,17 @@ class OrganizationSourceIngestionServiceTest(TestCase):
)
self.assertEqual(result.created_records, 1)
self.assertEqual(result.unresolved, 0)
organization.refresh_from_db()
self.assertEqual(organization.ogrn, "1057746645395")
self.assertEqual(organization.ogrip, "")
def test_save_financial_report_writes_financial_lines_without_legacy_report(self):
Organization.objects.create(
name='ООО "Финансовый отчет"',
ogrn="1027700132002",
)
result = OrganizationSourceIngestionService.save_records(
source=ParserLoadLog.Source.FNS_REPORTS,
load_batch=88,