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

@@ -3,6 +3,7 @@
from __future__ import annotations
import csv
import hashlib
import io
import os
import tempfile
@@ -34,12 +35,6 @@ from tests.apps.parsers.factories import (
ManufacturerRecordFactory,
ParserLoadLogFactory,
)
from tests.apps.registers.factories import (
OrganizationFactory as RegisterOrganizationFactory,
)
from tests.apps.registers.factories import (
RegistryMembershipPeriodFactory,
)
from tests.apps.user.factories import UserFactory
from tests.utils.fixtures import fake
@@ -48,6 +43,35 @@ def _digits(length: int) -> str:
return "".join(str(fake.random_int(0, 9)) for _ in range(length))
def RegisterOrganizationFactory(**kwargs) -> Organization:
kwargs.setdefault("name", kwargs.get("pn_name") or fake.company())
kwargs.setdefault("okpo", kwargs.get("mn_okpo") or _digits(8))
return Organization.objects.create(**kwargs)
def RegistryMembershipPeriodFactory(
*,
organization: Organization,
**_kwargs,
):
if not organization.ropk_razdel_num:
organization.ropk_razdel_num = str(fake.random_int(min=1, max=9999))
organization.opk_registry_membership = True
organization.ropk_num = organization.ropk_num or "test-registry"
organization.ropk_razdel_name = (
organization.ropk_razdel_name or f"Реестр {organization.ropk_razdel_num}"
)
organization.save(
update_fields=[
"opk_registry_membership",
"ropk_num",
"ropk_razdel_num",
"ropk_razdel_name",
]
)
return Mock(organization=organization, registry_id=organization.ropk_razdel_num)
def _build_fns_excel_bytes() -> bytes:
wb = Workbook()
ws = wb.active
@@ -81,6 +105,27 @@ def _save_source_record(
title: str = "Source record",
payload: dict | None = None,
) -> None:
payload = dict(payload or {})
if inn or ogrn:
query = {}
if inn:
query["inn"] = inn
if ogrn:
query["ogrn"] = ogrn
if not Organization.objects.filter(**query).exists():
Organization.objects.create(
name=organization_name,
inn=inn,
ogrn=ogrn,
)
else:
rn_key = organization_name or title or external_id
rn = str(int(hashlib.sha256(rn_key.encode()).hexdigest()[:12], 16) % 10**12)
payload.setdefault("rn", rn)
Organization.objects.get_or_create(
rn=rn,
defaults={"name": organization_name},
)
OrganizationSourceIngestionService.save_records(
source=source,
load_batch=1,
@@ -91,7 +136,7 @@ def _save_source_record(
organization_name=organization_name,
inn=inn,
ogrn=ogrn,
payload=payload or {},
payload=payload,
)
],
)
@@ -1153,8 +1198,10 @@ class ParsersViewSetTest(APITestCase):
processed_dir = os.path.join(tmpdir, "processed")
failed_dir = os.path.join(tmpdir, "failed")
content = _build_fns_excel_bytes()
ogrn = _digits(13)
Organization.objects.create(name=f"ФНС {ogrn}", ogrn=ogrn)
upload = SimpleUploadedFile(
f"fin_{_digits(5)}_{_digits(13)}.xlsx",
f"fin_{_digits(5)}_{ogrn}.xlsx",
content,
content_type=(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
@@ -1178,8 +1225,10 @@ class ParsersViewSetTest(APITestCase):
processed_dir = os.path.join(tmpdir, "processed")
failed_dir = os.path.join(tmpdir, "failed")
content = _build_fns_excel_bytes()
ogrn = _digits(13)
Organization.objects.create(name=f"ФНС {ogrn}", ogrn=ogrn)
upload = SimpleUploadedFile(
f"fin_{_digits(5)}_{_digits(13)}.xlsx",
f"fin_{_digits(5)}_{ogrn}.xlsx",
content,
content_type=(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
@@ -1201,6 +1250,7 @@ class ParsersViewSetTest(APITestCase):
self.client.force_authenticate(self.admin)
external_id = _digits(5)
ogrn = _digits(13)
Organization.objects.create(name=f"ФНС {ogrn}", ogrn=ogrn)
filename = f"fin_{external_id}_{ogrn}.xlsx"
upload = SimpleUploadedFile(
"fns_reports.zip",