feat: migrate parser data to source records
This commit is contained in:
@@ -14,14 +14,23 @@ from organizations.name_normalization import normalize_organization_name
|
||||
class SourceGroup(models.TextChoices):
|
||||
"""Product-level organization source groups."""
|
||||
|
||||
FINANCIAL_INDICATORS = "financial_indicators", _("Финансово-экономические показатели")
|
||||
FINANCIAL_INDICATORS = (
|
||||
"financial_indicators",
|
||||
_("Финансово-экономические показатели"),
|
||||
)
|
||||
GOVERNMENT_PROCUREMENTS = "government_procurements", _("Государственные закупки")
|
||||
INDUSTRIAL_PRODUCTION = "industrial_production", _("Производители и продукция России")
|
||||
INDUSTRIAL_PRODUCTION = (
|
||||
"industrial_production",
|
||||
_("Производители и продукция России"),
|
||||
)
|
||||
PLANNED_INSPECTIONS = "planned_inspections", _("Плановые проверки")
|
||||
BANKRUPTCY = "bankruptcy", _("Сведения о процедурах банкротства")
|
||||
DEFENSE_SUPPLIERS = "defense_suppliers", _("Недобросовестные поставщики ГОЗ")
|
||||
ARBITRATION = "arbitration", _("Арбитражные дела")
|
||||
SECURITY_REGISTRIES = "security_registries", _("Реестры по информационной безопасности")
|
||||
SECURITY_REGISTRIES = (
|
||||
"security_registries",
|
||||
_("Реестры по информационной безопасности"),
|
||||
)
|
||||
VACANCIES = "vacancies", _("Вакансии")
|
||||
|
||||
|
||||
@@ -472,6 +481,100 @@ class OrganizationSourceRecord(models.Model):
|
||||
def __str__(self) -> str:
|
||||
return self.title or self.external_id or str(self.uid)
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""Compatibility alias for legacy parser services that exposed integer id."""
|
||||
return self.pk
|
||||
|
||||
@property
|
||||
def lines(self):
|
||||
"""Compatibility alias for financial reports stored as source records."""
|
||||
return self.financial_lines
|
||||
|
||||
@property
|
||||
def inn(self) -> str:
|
||||
"""Return the canonical organization INN or source payload INN."""
|
||||
organization = self.extension.organization
|
||||
return organization.inn or str((self.payload or {}).get("inn") or "")
|
||||
|
||||
@property
|
||||
def kpp(self) -> str:
|
||||
"""Return the canonical organization KPP or source payload KPP."""
|
||||
organization = self.extension.organization
|
||||
return organization.kpp or str((self.payload or {}).get("kpp") or "")
|
||||
|
||||
@property
|
||||
def ogrn(self) -> str:
|
||||
"""Return the canonical organization OGRN or source payload OGRN."""
|
||||
organization = self.extension.organization
|
||||
return organization.ogrn or str((self.payload or {}).get("ogrn") or "")
|
||||
|
||||
@property
|
||||
def ogrip(self) -> str:
|
||||
"""Return the canonical organization OGRIP or source payload OGRIP."""
|
||||
organization = self.extension.organization
|
||||
return organization.ogrip or str((self.payload or {}).get("ogrip") or "")
|
||||
|
||||
@property
|
||||
def registry_organization(self):
|
||||
"""Best-effort active registry organization matched by canonical identity."""
|
||||
from django.db.models import CharField
|
||||
from django.db.models.functions import Cast
|
||||
from registers.models import Organization as RegistryOrganization
|
||||
from registers.models import RegistryMembershipPeriod
|
||||
|
||||
def _registry_numeric_values(value: str) -> list[str]:
|
||||
stripped = str(value or "").lstrip("0")
|
||||
return [value, stripped] if stripped and stripped != value else [value]
|
||||
|
||||
identity_filter = Q()
|
||||
inn = self.inn
|
||||
ogrn = self.ogrn
|
||||
ogrip = self.ogrip
|
||||
if inn:
|
||||
identity_filter |= Q(registry_inn_text__in=_registry_numeric_values(inn))
|
||||
if ogrn:
|
||||
identity_filter |= Q(registry_ogrn_text__in=_registry_numeric_values(ogrn))
|
||||
if ogrip:
|
||||
identity_filter |= Q(registry_ogrn_text__in=_registry_numeric_values(ogrip))
|
||||
if not identity_filter:
|
||||
return None
|
||||
|
||||
membership = (
|
||||
RegistryMembershipPeriod.objects.filter(ended_at__isnull=True)
|
||||
.select_related("organization")
|
||||
.annotate(
|
||||
registry_inn_text=Cast(
|
||||
"organization__mn_inn",
|
||||
output_field=CharField(),
|
||||
),
|
||||
registry_ogrn_text=Cast(
|
||||
"organization__mn_ogrn",
|
||||
output_field=CharField(),
|
||||
),
|
||||
)
|
||||
.filter(identity_filter)
|
||||
.order_by("organization__pn_name", "organization_id")
|
||||
.first()
|
||||
)
|
||||
if membership is not None:
|
||||
return membership.organization
|
||||
|
||||
return (
|
||||
RegistryOrganization.objects.annotate(
|
||||
registry_inn_text=Cast("mn_inn", output_field=CharField()),
|
||||
registry_ogrn_text=Cast("mn_ogrn", output_field=CharField()),
|
||||
)
|
||||
.filter(identity_filter)
|
||||
.order_by("pn_name", "id")
|
||||
.first()
|
||||
)
|
||||
|
||||
@property
|
||||
def registry_organization_id(self):
|
||||
registry_organization = self.registry_organization
|
||||
return registry_organization.id if registry_organization is not None else None
|
||||
|
||||
|
||||
class OrganizationSourceFinancialLine(models.Model):
|
||||
"""Structured financial report line under a source record."""
|
||||
|
||||
Reference in New Issue
Block a user