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

@@ -19,7 +19,6 @@ from apps.parsers.models import (
ProcurementRecord,
)
from django.db.models import Count, Prefetch, Q
from registers.models import RegistryMembershipPeriod
from organizations.data_sources import to_api_data_source, to_internal_data_source
from organizations.models import Organization
@@ -71,20 +70,27 @@ def active_registry_identity_values(
registry_name: str | None = None,
) -> tuple[set[str], set[str]]:
"""Return INN/OGRN values of organizations with active registry membership."""
memberships = RegistryMembershipPeriod.objects.filter(ended_at__isnull=True)
organizations = Organization.objects.filter(
Q(opk_registry_membership=True) | Q(goz_participation=True) | ~Q(ropk_num="")
)
if registry_id:
memberships = memberships.filter(registry_id=registry_id)
organizations = organizations.filter(
Q(ropk_razdel_num=str(registry_id)) | Q(gk_code=str(registry_id))
)
if registry_name:
memberships = memberships.filter(registry__name__icontains=registry_name)
organizations = organizations.filter(
Q(ropk_razdel_name__icontains=registry_name)
| Q(gk_name__icontains=registry_name)
| Q(business_activity__icontains=registry_name)
)
inn_values: set[str] = set()
ogrn_values: set[str] = set()
for inn, ogrn in memberships.values_list(
"organization__mn_inn",
"organization__mn_ogrn",
):
inn_values.add(str(inn))
ogrn_values.add(str(ogrn))
for inn, ogrn in organizations.values_list("inn", "ogrn"):
if inn:
inn_values.add(str(inn))
if ogrn:
ogrn_values.add(str(ogrn))
return inn_values, ogrn_values
@@ -696,44 +702,27 @@ class OrganizationApiEnrichmentService:
identifiers: dict[str, set[str]],
) -> dict[str, list[RegistrySummary]]:
registries = {str(organization.uid): [] for organization in organizations}
if not identifiers["inn"] and not identifiers["ogrn"]:
return registries
identity_filter = Q()
if identifiers["inn"]:
identity_filter |= Q(organization__mn_inn__in=identifiers["inn"])
if identifiers["ogrn"]:
identity_filter |= Q(organization__mn_ogrn__in=identifiers["ogrn"])
memberships = (
RegistryMembershipPeriod.objects.filter(ended_at__isnull=True)
.filter(identity_filter)
.select_related("registry", "organization")
.order_by("registry__name")
)
membership_by_inn: dict[str, list[RegistrySummary]] = {}
membership_by_ogrn: dict[str, list[RegistrySummary]] = {}
for membership in memberships:
summary = RegistrySummary(
id=str(membership.registry_id),
name=membership.registry.name,
)
membership_by_inn.setdefault(
str(membership.organization.mn_inn),
[],
).append(summary)
membership_by_ogrn.setdefault(
str(membership.organization.mn_ogrn),
[],
).append(summary)
for organization in organizations:
seen: set[str] = set()
summaries = []
for summary in membership_by_inn.get(
organization.inn, []
) + membership_by_ogrn.get(organization.ogrn, []):
candidates = []
if organization.opk_registry_membership:
candidates.append(
RegistrySummary(
id=organization.ropk_razdel_num or "opk",
name=organization.ropk_razdel_name or "Реестр ОПК",
)
)
if organization.goz_participation:
candidates.append(RegistrySummary(id="goz", name="Участие в ГОЗ"))
if organization.gk_name:
candidates.append(
RegistrySummary(
id=organization.gk_code or "gk",
name=organization.gk_name,
)
)
for summary in candidates:
if summary.id in seen:
continue
seen.add(summary.id)