"""Tests for parser services writing directly to organization source storage.""" from decimal import Decimal from apps.parsers.clients.common import GenericParserItem from apps.parsers.clients.fns.schemas import ReportLine from apps.parsers.clients.minpromtorg.schemas import ( IndustrialCertificate, IndustrialProduct, Manufacturer, ) from apps.parsers.clients.proverki.schemas import Inspection from apps.parsers.clients.zakupki.schemas import Procurement from apps.parsers.models import ( FinancialReport, GenericParserRecord, IndustrialCertificateRecord, IndustrialProductRecord, InspectionRecord, ManufacturerRecord, ParserLoadLog, ProcurementRecord, ) from apps.parsers.services import ( FNSReportService, GenericParserRecordService, IndustrialCertificateService, IndustrialProductService, InspectionService, ManufacturerService, ProcurementService, ) from django.test import TestCase from organizations.models import ( OrganizationSourceFinancialLine, OrganizationSourceRecord, ) class DirectIngestionParserServicesTest(TestCase): """Parser save services should not write legacy parser record rows.""" def test_industrial_certificate_save_records_writes_organization_source_records(self): saved = IndustrialCertificateService.save_certificates( [ IndustrialCertificate( issue_date="01.02.2026", certificate_number="CERT-DIRECT-1", expiry_date="2029-02-01", certificate_file_url="https://example.test/cert.pdf", organisation_name='ООО "Сертификат"', inn="7707083801", ogrn="1027700132001", ) ], batch_id=47, ) self.assertEqual(saved, 1) self.assertEqual(IndustrialCertificateRecord.objects.count(), 0) record = OrganizationSourceRecord.objects.get( source=ParserLoadLog.Source.INDUSTRIAL, external_id="CERT-DIRECT-1", ) self.assertEqual(record.record_type, "industrial_certificate") self.assertEqual(record.payload["issue_date_normalized"], "2026-02-01") self.assertEqual(record.payload["expiry_date_normalized"], "2029-02-01") self.assertEqual(record.url, "https://example.test/cert.pdf") def test_industrial_certificate_save_records_skips_records_without_certificate_number(self): saved = IndustrialCertificateService.save_certificates( [ IndustrialCertificate( issue_date="01.02.2026", certificate_number="", expiry_date="2029-02-01", certificate_file_url="-", organisation_name='ООО "Без номера"', inn="7707083801", ogrn="1027700132001", ), IndustrialCertificate( issue_date="01.02.2026", certificate_number="CERT-DIRECT-2", expiry_date="2029-02-01", certificate_file_url="https://example.test/cert-2.pdf", organisation_name='ООО "С номером"', inn="7707083802", ogrn="1027700132002", ), ], batch_id=48, ) self.assertEqual(saved, 1) self.assertEqual( OrganizationSourceRecord.objects.filter( source=ParserLoadLog.Source.INDUSTRIAL, ).count(), 1, ) self.assertTrue( OrganizationSourceRecord.objects.filter( source=ParserLoadLog.Source.INDUSTRIAL, external_id="CERT-DIRECT-2", ).exists() ) self.assertFalse( OrganizationSourceRecord.objects.filter( source=ParserLoadLog.Source.INDUSTRIAL, external_id="", ).exists() ) def test_manufacturer_save_records_writes_organization_source_records(self): saved = ManufacturerService.save_manufacturers( [ Manufacturer( full_legal_name='ООО "Производитель"', inn="7707083802", ogrn="1027700132002", address="Москва", ) ], batch_id=48, ) self.assertEqual(saved, 1) self.assertEqual(ManufacturerRecord.objects.count(), 0) record = OrganizationSourceRecord.objects.get( source=ParserLoadLog.Source.MANUFACTURES, external_id="7707083802", ) self.assertEqual(record.record_type, "manufacturer") self.assertEqual(record.title, 'ООО "Производитель"') self.assertEqual(record.payload["address"], "Москва") def test_industrial_product_save_records_writes_organization_source_records(self): saved = IndustrialProductService.save_products( [ IndustrialProduct( full_organisation_name='ООО "Продукция"', inn="7707083809", ogrn="1027700132009", registry_number="PROD-DIRECT-1", product_name="Станок", product_model="MODEL-1", okpd2_code="28.41", tnved_code="8457109000", regulatory_document="ГОСТ", ) ], batch_id=49, ) self.assertEqual(saved, 1) self.assertEqual(IndustrialProductRecord.objects.count(), 0) record = OrganizationSourceRecord.objects.get( source=ParserLoadLog.Source.INDUSTRIAL_PRODUCTS, external_id="PROD-DIRECT-1", ) self.assertEqual(record.record_type, "industrial_product") self.assertEqual(record.title, "Станок") self.assertEqual(record.payload["okpd2_code"], "28.41") def test_procurement_save_records_writes_organization_source_records(self): saved = ProcurementService.save_procurements( [ Procurement( purchase_number="PROC-DIRECT-1", purchase_name="Поставка оборудования", customer_inn="7707083810", customer_kpp="770701001", customer_ogrn="1027700132010", customer_name='ООО "Заказчик"', max_price="1 234 567,89", currency_code="RUB", placement_method="Аукцион", publish_date="01.03.2026", end_date="2026-03-15", status="published", law_type="44-FZ", purchase_object_info="Оборудование", href="https://example.test/procurement", ) ], batch_id=50, region_code="77", data_year=2026, data_month=3, ) self.assertEqual(saved, 1) self.assertEqual(ProcurementRecord.objects.count(), 0) record = OrganizationSourceRecord.objects.get( source=ParserLoadLog.Source.PROCUREMENTS, external_id="PROC-DIRECT-1", ) self.assertEqual(record.record_type, "procurement") self.assertEqual(record.amount, Decimal("1234567.89")) self.assertEqual(record.payload["publish_date_normalized"], "2026-03-01") self.assertEqual(record.payload["region_code"], "77") self.assertEqual(record.payload["data_month"], 3) def test_generic_save_records_writes_organization_source_records(self): saved = GenericParserRecordService.save_records( [ GenericParserItem( source=ParserLoadLog.Source.FAS_GOZ, external_id="fas-goz-1", inn="7707083803", ogrn="", organisation_name='ООО "ГОЗ"', title="Уклонение от ГОЗ", record_date="2026-05-18", amount=Decimal("12.30"), status="active", url="https://example.test/fas-goz-1", payload={"registry": "fas"}, ) ], batch_id=51, source=ParserLoadLog.Source.FAS_GOZ, ) self.assertEqual(saved, 1) self.assertEqual(GenericParserRecord.objects.count(), 0) record = OrganizationSourceRecord.objects.get( source=ParserLoadLog.Source.FAS_GOZ, external_id="fas-goz-1", ) self.assertEqual(record.title, "Уклонение от ГОЗ") self.assertEqual(record.payload["registry"], "fas") self.assertEqual(record.load_batch, 51) def test_inspection_save_records_writes_organization_source_records(self): saved = InspectionService.save_inspections( [ Inspection( registration_number="INSP-DIRECT-1", inn="7707083804", ogrn="1027700132004", organisation_name='ООО "Проверка"', control_authority="Контроль", inspection_type="Плановая", inspection_form="Документарная", start_date="01.03.2026", end_date="2026-03-15", status="planned", legal_basis="ФЗ", result="", ) ], batch_id=52, data_year=2026, data_month=3, ) self.assertEqual(saved, 1) self.assertEqual(InspectionRecord.objects.count(), 0) record = OrganizationSourceRecord.objects.get( source=ParserLoadLog.Source.INSPECTIONS, external_id="INSP-DIRECT-1", ) self.assertEqual(record.record_type, "inspection") self.assertEqual(record.payload["control_authority"], "Контроль") self.assertEqual(record.payload["start_date_normalized"], "2026-03-01") self.assertEqual(record.payload["data_year"], 2026) self.assertEqual(record.payload["data_month"], 3) def test_fns_save_report_writes_source_record_and_financial_lines(self): report = FNSReportService.save_report( external_id="fns-direct-1", ogrn="1027700132005", file_name="fin_001_1027700132005.xlsx", file_hash="b" * 64, source="file_watch", batch_id=53, lines_data=[ { "form_code": "1", "line_code": "1600", "line_name": "Баланс", "year": 2025, "period_start": 100, "period_end": 200, } ], ) self.assertEqual(FinancialReport.objects.count(), 0) self.assertEqual(str(report.external_id), "fns-direct-1") source_record = OrganizationSourceRecord.objects.get( source=ParserLoadLog.Source.FNS_REPORTS, external_id="fns-direct-1", ) self.assertEqual(report.uid, source_record.uid) self.assertEqual(source_record.payload["file_hash"], "b" * 64) line = OrganizationSourceFinancialLine.objects.get(source_record=source_record) self.assertEqual(line.line_code, "1600") self.assertEqual(line.period_end, 200) def test_fns_exists_by_hash_reads_source_record_payload(self): FNSReportService.save_report( external_id="fns-direct-2", ogrn="1027700132006", file_name="fin_002_1027700132006.xlsx", file_hash="c" * 64, source="file_watch", batch_id=54, lines_data=[ ReportLine( form_code="2", line_code="2110", line_name="Выручка", year=2025, period_end=500, ).__dict__ ], ) self.assertTrue(FNSReportService.exists_by_hash("c" * 64)) self.assertTrue(FNSReportService.exists_by_external_id("fns-direct-2"))