220 lines
8.3 KiB
Python
220 lines
8.3 KiB
Python
"""Tests for organization source backfill from legacy parser tables."""
|
||
|
||
from apps.parsers.models import (
|
||
FinancialReport,
|
||
FinancialReportLine,
|
||
GenericParserRecord,
|
||
ParserLoadLog,
|
||
)
|
||
from django.core.management import call_command
|
||
from django.test import TestCase
|
||
from organizations.models import (
|
||
DefenseSupplierExtension,
|
||
FinancialIndicatorsExtension,
|
||
Organization,
|
||
OrganizationSourceFinancialLine,
|
||
OrganizationSourceRecord,
|
||
PlannedInspectionExtension,
|
||
SourceGroup,
|
||
)
|
||
from organizations.source_backfill import OrganizationSourceBackfillService
|
||
|
||
from tests.apps.parsers.factories import (
|
||
InspectionRecordFactory,
|
||
ManufacturerRecordFactory,
|
||
)
|
||
from tests.apps.registers.factories import (
|
||
OrganizationFactory as RegistryOrganizationFactory,
|
||
)
|
||
|
||
|
||
class OrganizationSourceBackfillServiceTest(TestCase):
|
||
"""Checks idempotent migration from legacy source records."""
|
||
|
||
def test_backfills_inspection_records_into_planned_inspection_extension(self):
|
||
organization = Organization.objects.create(
|
||
name='ООО "Проверка"',
|
||
inn="7707083801",
|
||
ogrn="1027700132001",
|
||
)
|
||
inspection = InspectionRecordFactory(
|
||
load_batch=77,
|
||
inn=organization.inn,
|
||
ogrn=organization.ogrn,
|
||
organisation_name=organization.name,
|
||
registration_number="INSP-77",
|
||
)
|
||
|
||
result = OrganizationSourceBackfillService.backfill(
|
||
source=ParserLoadLog.Source.INSPECTIONS,
|
||
batch_id=77,
|
||
)
|
||
|
||
self.assertEqual(result.scanned, 1)
|
||
self.assertEqual(result.created_extensions, 1)
|
||
self.assertEqual(result.created_records, 1)
|
||
extension = PlannedInspectionExtension.objects.get(organization=organization)
|
||
self.assertEqual(extension.source_group, SourceGroup.PLANNED_INSPECTIONS)
|
||
self.assertEqual(extension.records_count, 1)
|
||
record = OrganizationSourceRecord.objects.get(extension=extension)
|
||
self.assertEqual(record.source, ParserLoadLog.Source.INSPECTIONS)
|
||
self.assertEqual(record.external_id, inspection.registration_number)
|
||
self.assertEqual(record.legacy_model, "apps.parsers.InspectionRecord")
|
||
self.assertEqual(record.legacy_pk, str(inspection.pk))
|
||
self.assertEqual(record.payload["registration_number"], "INSP-77")
|
||
|
||
second_result = OrganizationSourceBackfillService.backfill(
|
||
source=ParserLoadLog.Source.INSPECTIONS,
|
||
batch_id=77,
|
||
)
|
||
|
||
self.assertEqual(second_result.created_extensions, 0)
|
||
self.assertEqual(second_result.created_records, 0)
|
||
self.assertEqual(second_result.updated_records, 1)
|
||
self.assertEqual(OrganizationSourceRecord.objects.count(), 1)
|
||
|
||
def test_backfill_payload_serializes_registry_organization_fk_as_id(self):
|
||
organization = Organization.objects.create(
|
||
name='ООО "FK Payload"',
|
||
inn="7707083815",
|
||
ogrn="1027700132015",
|
||
)
|
||
registry_organization = RegistryOrganizationFactory(
|
||
mn_inn=int(organization.inn),
|
||
mn_ogrn=int(organization.ogrn),
|
||
)
|
||
InspectionRecordFactory(
|
||
load_batch=78,
|
||
inn=organization.inn,
|
||
ogrn=organization.ogrn,
|
||
organisation_name=organization.name,
|
||
registration_number="INSP-FK",
|
||
registry_organization=registry_organization,
|
||
)
|
||
|
||
OrganizationSourceBackfillService.backfill(
|
||
source=ParserLoadLog.Source.INSPECTIONS,
|
||
batch_id=78,
|
||
)
|
||
|
||
record = OrganizationSourceRecord.objects.get(external_id="INSP-FK")
|
||
self.assertEqual(record.payload["registry_organization"], registry_organization.pk)
|
||
|
||
def test_backfills_financial_report_lines(self):
|
||
organization = Organization.objects.create(
|
||
name='ООО "Финансы"',
|
||
inn="7707083802",
|
||
ogrn="1027700132002",
|
||
)
|
||
report = FinancialReport.objects.create(
|
||
external_id="fns-report-1",
|
||
ogrn=organization.ogrn,
|
||
file_name="fns_report.xlsx",
|
||
file_hash="a" * 64,
|
||
load_batch=88,
|
||
status=FinancialReport.Status.SUCCESS,
|
||
source=FinancialReport.SourceType.API,
|
||
)
|
||
FinancialReportLine.objects.create(
|
||
report=report,
|
||
form_code="1",
|
||
line_code="1100",
|
||
line_name="Нематериальные активы",
|
||
year=2025,
|
||
period_start=100,
|
||
period_end=200,
|
||
)
|
||
|
||
result = OrganizationSourceBackfillService.backfill(
|
||
source=ParserLoadLog.Source.FNS_REPORTS,
|
||
batch_id=88,
|
||
)
|
||
|
||
self.assertEqual(result.created_extensions, 1)
|
||
self.assertEqual(result.created_records, 1)
|
||
extension = FinancialIndicatorsExtension.objects.get(organization=organization)
|
||
record = OrganizationSourceRecord.objects.get(extension=extension)
|
||
self.assertEqual(record.external_id, "fns-report-1")
|
||
self.assertEqual(OrganizationSourceFinancialLine.objects.count(), 1)
|
||
self.assertEqual(record.financial_lines.get().period_end, 200)
|
||
|
||
def test_backfills_generic_defense_supplier_records(self):
|
||
organization = Organization.objects.create(
|
||
name='ООО "ГОЗ"',
|
||
inn="7707083803",
|
||
)
|
||
generic_record = GenericParserRecord.objects.create(
|
||
load_batch=99,
|
||
source=ParserLoadLog.Source.UNFAIR_SUPPLIERS,
|
||
external_id="unfair-1",
|
||
inn=organization.inn,
|
||
ogrn="",
|
||
organisation_name=organization.name,
|
||
title="Реестр недобросовестных поставщиков",
|
||
record_date="2026-05-18",
|
||
status="active",
|
||
payload={"reason": "test"},
|
||
)
|
||
|
||
result = OrganizationSourceBackfillService.backfill(
|
||
source=ParserLoadLog.Source.UNFAIR_SUPPLIERS,
|
||
batch_id=99,
|
||
)
|
||
|
||
self.assertEqual(result.created_extensions, 1)
|
||
self.assertEqual(result.created_records, 1)
|
||
extension = DefenseSupplierExtension.objects.get(organization=organization)
|
||
record = OrganizationSourceRecord.objects.get(extension=extension)
|
||
self.assertEqual(record.source, ParserLoadLog.Source.UNFAIR_SUPPLIERS)
|
||
self.assertEqual(record.external_id, generic_record.external_id)
|
||
self.assertEqual(record.payload["reason"], "test")
|
||
|
||
def test_backfill_drops_invalid_identity_values_when_creating_organization(self):
|
||
manufacturer = ManufacturerRecordFactory(
|
||
load_batch=100,
|
||
full_legal_name='ИП "Грязный ИНН"',
|
||
inn="396440000001000",
|
||
ogrn="5385025402942",
|
||
)
|
||
|
||
result = OrganizationSourceBackfillService.backfill(
|
||
source=ParserLoadLog.Source.MANUFACTURES,
|
||
batch_id=100,
|
||
)
|
||
|
||
self.assertEqual(result.scanned, 1)
|
||
self.assertEqual(result.created_organizations, 1)
|
||
self.assertEqual(result.created_records, 1)
|
||
self.assertEqual(result.unresolved, 0)
|
||
organization = Organization.objects.get(name=manufacturer.full_legal_name)
|
||
self.assertEqual(organization.inn, "")
|
||
self.assertEqual(organization.ogrn, manufacturer.ogrn)
|
||
record = OrganizationSourceRecord.objects.get(legacy_pk=str(manufacturer.pk))
|
||
self.assertEqual(record.payload["inn"], "396440000001000")
|
||
|
||
def test_management_command_runs_source_backfill(self):
|
||
organization = Organization.objects.create(
|
||
name='ООО "Команда"',
|
||
inn="7707083804",
|
||
ogrn="1027700132004",
|
||
)
|
||
InspectionRecordFactory(
|
||
load_batch=101,
|
||
inn=organization.inn,
|
||
ogrn=organization.ogrn,
|
||
organisation_name=organization.name,
|
||
registration_number="INSP-101",
|
||
)
|
||
|
||
call_command(
|
||
"backfill_organization_sources",
|
||
source=ParserLoadLog.Source.INSPECTIONS,
|
||
batch_id=101,
|
||
verbosity=0,
|
||
)
|
||
|
||
self.assertTrue(
|
||
PlannedInspectionExtension.objects.filter(organization=organization).exists()
|
||
)
|
||
self.assertEqual(OrganizationSourceRecord.objects.get().external_id, "INSP-101")
|