"""Models for external read-only registries.""" from __future__ import annotations from apps.core.mixins import TimestampMixin, UUIDPrimaryKeyMixin from apps.organization.models import Organization from django.db import models from django.utils.translation import gettext_lazy as _ class IndustrialProduct(UUIDPrimaryKeyMixin, TimestampMixin, models.Model): organization = models.ForeignKey( Organization, on_delete=models.CASCADE, related_name="industrial_products", verbose_name=_("организация"), ) product_name = models.CharField( _("наименование продукции"), max_length=500, db_index=True ) product_class = models.CharField( _("класс продукции"), max_length=100, db_index=True ) okpd2_code = models.CharField(_("код ОКПД2"), max_length=32, blank=True, default="") tnved_code = models.CharField(_("код ТНВЭД"), max_length=32, blank=True, default="") registry_number = models.CharField( _("реестровый номер"), max_length=64, blank=True, default="" ) class Meta: ordering = ["product_name", "created_at"] def __str__(self) -> str: return f"{self.product_name} ({self.organization_id})" class IndustrialCertificate(UUIDPrimaryKeyMixin, TimestampMixin, models.Model): organization = models.ForeignKey( Organization, on_delete=models.CASCADE, related_name="industrial_certificates", verbose_name=_("организация"), ) certificate_number = models.CharField( _("номер сертификата"), max_length=100, db_index=True ) issue_date = models.DateField(_("дата выдачи"), null=True, blank=True) expiry_date = models.DateField(_("дата окончания"), null=True, blank=True) certificate_file_url = models.TextField( _("ссылка на файл сертификата"), blank=True, default="" ) organisation_name = models.CharField( _("наименование организации из источника"), max_length=500, blank=True, default="", ) ogrn = models.CharField(_("ОГРН"), max_length=15, blank=True, default="") class Meta: ordering = ["-issue_date", "certificate_number"] def __str__(self) -> str: return f"{self.certificate_number} ({self.organization_id})" class ManufacturerRegistryEntry(UUIDPrimaryKeyMixin, TimestampMixin, models.Model): organization = models.ForeignKey( Organization, on_delete=models.CASCADE, related_name="manufacturer_registry_entries", verbose_name=_("организация"), ) full_legal_name = models.CharField( _("полное наименование"), max_length=1024, db_index=True ) inn = models.CharField(_("ИНН"), max_length=12, db_index=True) ogrn = models.CharField(_("ОГРН"), max_length=15, blank=True, default="") address = models.TextField(_("адрес"), blank=True, default="") class Meta: ordering = ["full_legal_name", "created_at"] def __str__(self) -> str: return f"{self.full_legal_name} ({self.organization_id})" class ProsecutorCheck(UUIDPrimaryKeyMixin, TimestampMixin, models.Model): organization = models.ForeignKey( Organization, on_delete=models.CASCADE, related_name="prosecutor_checks", verbose_name=_("организация"), ) registration_number = models.CharField( _("регистрационный номер"), max_length=64, db_index=True ) law_type = models.CharField(_("тип закона"), max_length=32, db_index=True) control_authority = models.CharField(_("контрольный орган"), max_length=255) prosecutor_office = models.CharField( _("прокуратура"), max_length=255, blank=True, default="" ) start_date = models.DateField(_("дата начала"), db_index=True) status = models.CharField(_("статус"), max_length=64, db_index=True) class Meta: ordering = ["-start_date", "registration_number"] def __str__(self) -> str: return f"{self.registration_number} ({self.organization_id})" class PublicProcurement(UUIDPrimaryKeyMixin, TimestampMixin, models.Model): organization = models.ForeignKey( Organization, on_delete=models.CASCADE, related_name="public_procurements", verbose_name=_("организация"), ) purchase_number = models.CharField(_("номер закупки"), max_length=64, db_index=True) law_type = models.CharField(_("тип закона"), max_length=32, db_index=True) status = models.CharField(_("статус"), max_length=64, db_index=True) contract_amount = models.DecimalField( _("сумма контракта"), max_digits=20, decimal_places=2, null=True, blank=True, ) contract_date = models.DateField(_("дата контракта"), db_index=True) execution_start_date = models.DateField( _("дата начала исполнения"), null=True, blank=True ) execution_end_date = models.DateField( _("дата окончания исполнения"), null=True, blank=True ) purchase_name = models.TextField(_("предмет закупки")) class Meta: ordering = ["-contract_date", "purchase_number"] def __str__(self) -> str: return f"{self.purchase_number} ({self.organization_id})" class ArbitrationCase(UUIDPrimaryKeyMixin, TimestampMixin, models.Model): organization = models.ForeignKey( Organization, on_delete=models.CASCADE, related_name="arbitration_cases", verbose_name=_("организация"), ) case_number = models.CharField(_("номер дела"), max_length=64, db_index=True) court_name = models.CharField(_("суд"), max_length=255) party_role = models.CharField(_("роль стороны"), max_length=64, db_index=True) status = models.CharField(_("статус"), max_length=64, db_index=True) decision_date = models.DateField(_("дата решения"), db_index=True) class Meta: ordering = ["-decision_date", "case_number"] def __str__(self) -> str: return f"{self.case_number} ({self.organization_id})" class BankruptcyProcedure(UUIDPrimaryKeyMixin, TimestampMixin, models.Model): organization = models.ForeignKey( Organization, on_delete=models.CASCADE, related_name="bankruptcy_procedures", verbose_name=_("организация"), ) external_id = models.CharField(_("внешний ID"), max_length=255, db_index=True) message_type = models.CharField(_("тип сообщения"), max_length=255, db_index=True) message_date = models.DateField( _("дата сообщения"), null=True, blank=True, db_index=True ) case_number = models.CharField( _("номер дела"), max_length=128, blank=True, default="", db_index=True ) status = models.CharField( _("статус"), max_length=64, blank=True, default="", db_index=True ) source_url = models.TextField(_("ссылка на источник"), blank=True, default="") class Meta: ordering = ["-message_date", "case_number", "message_type"] def __str__(self) -> str: return f"{self.message_type} ({self.organization_id})" class DefenseUnreliableSupplier(UUIDPrimaryKeyMixin, TimestampMixin, models.Model): organization = models.ForeignKey( Organization, on_delete=models.CASCADE, related_name="defense_unreliable_suppliers", verbose_name=_("организация"), ) external_id = models.CharField(_("внешний ID"), max_length=255, db_index=True) registry_source = models.CharField( _("источник реестра"), max_length=50, db_index=True ) registry_number = models.CharField( _("номер записи"), max_length=128, blank=True, default="", db_index=True ) supplier_name = models.CharField( _("наименование поставщика"), max_length=500, blank=True, default="" ) reason = models.TextField(_("основание"), blank=True, default="") included_at = models.DateField( _("дата включения"), null=True, blank=True, db_index=True ) status = models.CharField( _("статус"), max_length=64, blank=True, default="", db_index=True ) source_url = models.TextField(_("ссылка на источник"), blank=True, default="") class Meta: ordering = ["-included_at", "registry_source", "registry_number"] def __str__(self) -> str: return f"{self.registry_source}:{self.registry_number} ({self.organization_id})" class InformationSecurityRegistryEntry( UUIDPrimaryKeyMixin, TimestampMixin, models.Model ): class PresenceStatus(models.TextChoices): PRESENT = "present", _("В реестре") ABSENT = "absent", _("Не в реестре") organization = models.ForeignKey( Organization, on_delete=models.CASCADE, related_name="information_security_registry_entries", verbose_name=_("организация"), ) external_id = models.CharField( _("внешний ID"), max_length=255, blank=True, default="", db_index=True ) registry_name = models.CharField( _("название реестра"), max_length=255, db_index=True ) presence_status = models.CharField( _("статус присутствия"), max_length=16, choices=PresenceStatus.choices, db_index=True, ) entry_number = models.CharField( _("регистрационный номер"), max_length=64, blank=True, default="", ) issued_at = models.DateField(_("дата выдачи"), null=True, blank=True) expires_at = models.DateField(_("дата окончания"), null=True, blank=True) class Meta: verbose_name = _("запись реестра безопасности") verbose_name_plural = _("записи реестра безопасности") ordering = ["registry_name", "-issued_at"] def __str__(self) -> str: return f"{self.registry_name} ({self.organization_id})" class LaborVacancy(UUIDPrimaryKeyMixin, TimestampMixin, models.Model): organization = models.ForeignKey( Organization, on_delete=models.CASCADE, related_name="labor_vacancies", verbose_name=_("организация"), ) external_id = models.CharField(_("внешний ID"), max_length=255, db_index=True) vacancy_source = models.CharField( _("источник вакансии"), max_length=50, db_index=True ) title = models.CharField(_("название вакансии"), max_length=500, db_index=True) status = models.CharField( _("статус"), max_length=64, blank=True, default="", db_index=True ) published_at = models.DateField( _("дата публикации"), null=True, blank=True, db_index=True ) salary_amount = models.DecimalField( _("зарплата"), max_digits=20, decimal_places=2, null=True, blank=True, ) source_url = models.TextField(_("ссылка на источник"), blank=True, default="") class Meta: ordering = ["-published_at", "title"] def __str__(self) -> str: return f"{self.title} ({self.organization_id})" class FinancialReport(UUIDPrimaryKeyMixin, TimestampMixin, models.Model): organization = models.ForeignKey( Organization, on_delete=models.CASCADE, related_name="financial_reports", verbose_name=_("организация"), ) external_id = models.CharField(_("внешний ID"), max_length=255, db_index=True) ogrn = models.CharField(_("ОГРН"), max_length=15, blank=True, default="") file_name = models.CharField(_("имя файла"), max_length=255, blank=True, default="") file_hash = models.CharField(_("хеш файла"), max_length=64, blank=True, default="") load_batch = models.PositiveIntegerField( _("ID пакета загрузки"), null=True, blank=True, db_index=True ) status = models.CharField( _("статус"), max_length=64, blank=True, default="", db_index=True ) source = models.CharField(_("источник"), max_length=64, blank=True, default="") error_message = models.TextField(_("сообщение об ошибке"), blank=True, default="") class Meta: ordering = ["-created_at", "external_id"] def __str__(self) -> str: return f"{self.external_id} ({self.organization_id})" class FinancialReportLine(UUIDPrimaryKeyMixin, TimestampMixin, models.Model): report = models.ForeignKey( FinancialReport, on_delete=models.CASCADE, related_name="lines", verbose_name=_("финансовый отчет"), ) form_code = models.CharField(_("код формы"), max_length=10, db_index=True) line_code = models.CharField(_("код строки"), max_length=10, db_index=True) line_name = models.CharField(_("наименование строки"), max_length=255) year = models.PositiveSmallIntegerField(_("год"), db_index=True) period_start = models.BigIntegerField( _("на начало периода"), null=True, blank=True, ) period_end = models.BigIntegerField( _("на конец периода"), null=True, blank=True, ) class Meta: ordering = ["year", "form_code", "line_code"] constraints = [ models.UniqueConstraint( fields=["report", "form_code", "line_code", "year"], name="unique_external_financial_report_line_year", ), ] indexes = [ models.Index(fields=["report", "form_code", "line_code"]), models.Index(fields=["year", "line_code"]), ] def __str__(self) -> str: return f"{self.line_code} ({self.line_name[:30]}) - {self.year}"