Add organizations v2 API and registry enrichment
This commit is contained in:
131
src/organizations/models.py
Normal file
131
src/organizations/models.py
Normal file
@@ -0,0 +1,131 @@
|
||||
"""Models for the canonical organizations directory."""
|
||||
|
||||
import uuid
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from organizations.name_normalization import normalize_organization_name
|
||||
|
||||
|
||||
class Organization(models.Model):
|
||||
"""Canonical organization without source-specific relations."""
|
||||
|
||||
uid = models.UUIDField(
|
||||
_("UID"),
|
||||
primary_key=True,
|
||||
default=uuid.uuid4,
|
||||
editable=False,
|
||||
)
|
||||
name = models.CharField(
|
||||
_("наименование"),
|
||||
max_length=1024,
|
||||
db_index=True,
|
||||
help_text=_("Наименование организации или ИП"),
|
||||
)
|
||||
inn = models.CharField(
|
||||
_("ИНН"),
|
||||
max_length=12,
|
||||
blank=True,
|
||||
db_index=True,
|
||||
help_text=_("ИНН ЮЛ или ИП"),
|
||||
)
|
||||
kpp = models.CharField(
|
||||
_("КПП"),
|
||||
max_length=9,
|
||||
blank=True,
|
||||
db_index=True,
|
||||
help_text=_("КПП только для юридических лиц"),
|
||||
)
|
||||
ogrn = models.CharField(
|
||||
_("ОГРН"),
|
||||
max_length=13,
|
||||
blank=True,
|
||||
db_index=True,
|
||||
help_text=_("ОГРН только для юридических лиц"),
|
||||
)
|
||||
ogrip = models.CharField(
|
||||
_("ОГРИП"),
|
||||
max_length=15,
|
||||
blank=True,
|
||||
db_index=True,
|
||||
help_text=_("ОГРИП только для индивидуальных предпринимателей"),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "organizations_organization"
|
||||
verbose_name = _("организация")
|
||||
verbose_name_plural = _("организации")
|
||||
ordering = ["name"]
|
||||
indexes = [
|
||||
models.Index(fields=["inn", "kpp"]),
|
||||
models.Index(fields=["inn", "ogrn"]),
|
||||
models.Index(fields=["inn", "ogrip"]),
|
||||
]
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
fields=["inn", "kpp"],
|
||||
condition=~Q(inn="") & ~Q(kpp=""),
|
||||
name="unique_org_inn_kpp_not_blank",
|
||||
),
|
||||
models.UniqueConstraint(
|
||||
fields=["inn"],
|
||||
condition=~Q(inn="") & Q(kpp="") & Q(ogrip=""),
|
||||
name="unique_org_inn_without_kpp",
|
||||
),
|
||||
models.UniqueConstraint(
|
||||
fields=["ogrip"],
|
||||
condition=~Q(ogrip=""),
|
||||
name="unique_organizations_ogrip_not_blank",
|
||||
),
|
||||
models.CheckConstraint(
|
||||
check=Q(ogrip="") | (Q(kpp="") & Q(ogrn="")),
|
||||
name="check_entrepreneur_has_no_kpp_ogrn",
|
||||
),
|
||||
]
|
||||
|
||||
def __str__(self) -> str:
|
||||
identifier = self.inn or self.ogrn or self.ogrip
|
||||
if identifier:
|
||||
return f"{self.name} ({identifier})"
|
||||
return self.name
|
||||
|
||||
@property
|
||||
def normalized_name(self) -> str:
|
||||
return normalize_organization_name(self.name)
|
||||
|
||||
|
||||
class OrganizationDataSnapshot(models.Model):
|
||||
"""Precomputed API v2 data payload for one canonical organization."""
|
||||
|
||||
organization = models.OneToOneField(
|
||||
Organization,
|
||||
on_delete=models.CASCADE,
|
||||
primary_key=True,
|
||||
related_name="data_snapshot",
|
||||
verbose_name=_("организация"),
|
||||
)
|
||||
data = models.JSONField(
|
||||
_("данные источников"),
|
||||
default=dict,
|
||||
help_text=_("Готовый JSON data для API v2"),
|
||||
)
|
||||
registries = models.JSONField(
|
||||
_("реестры"),
|
||||
default=list,
|
||||
help_text=_("Готовый JSON registries для API v2"),
|
||||
)
|
||||
updated_at = models.DateTimeField(
|
||||
_("дата обновления"),
|
||||
auto_now=True,
|
||||
db_index=True,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "organizations_data_snapshot"
|
||||
verbose_name = _("снапшот данных организации")
|
||||
verbose_name_plural = _("снапшоты данных организаций")
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Snapshot for {self.organization_id}"
|
||||
Reference in New Issue
Block a user