feat: export state corp package from backup endpoint
Some checks failed
CI/CD Pipeline / Quality Gate (push) Successful in 33s
CI/CD Pipeline / Build and Push Images (push) Successful in 10s
CI/CD Pipeline / Internal Notify (push) Successful in 0s
CI/CD Pipeline / Deploy Dev in Dokploy (push) Failing after 9s

This commit is contained in:
2026-05-12 15:12:56 +02:00
parent 15360a3c8e
commit 75c1d4cf1a
11 changed files with 925 additions and 301 deletions

View File

@@ -218,6 +218,94 @@ SOURCE_CARD_DEFINITIONS: tuple[SourceCardDefinition, ...] = (
),
),
),
SourceCardDefinition(
slug="bankruptcy-procedures",
title="Сведения о процедурах банкротства",
description="Сведения Федресурса о процедурах банкротства.",
order=50,
task_names=("apps.parsers.tasks.parse_fedresurs_bankruptcy",),
source_items=(
SourceItemDefinition(
code="fedresurs_bankruptcy",
title="Банкротства Федресурс",
description="Сведения о процедурах банкротства из ЕФРСБ.",
parser_source=ParserLoadLog.Source.FEDRESURS_BANKRUPTCY,
),
),
refresh_interval=timedelta(days=1),
),
SourceCardDefinition(
slug="defense-unreliable-suppliers",
title="Недобросовестные поставщики ГОЗ",
description="Реестры недобросовестных поставщиков и уклонения от ГОЗ.",
order=60,
task_names=(
"apps.parsers.tasks.parse_unfair_suppliers",
"apps.parsers.tasks.parse_fas_goz_evasion",
),
source_items=(
SourceItemDefinition(
code="unfair_suppliers",
title="Недобросовестные поставщики",
description="Реестр недобросовестных поставщиков ФАС и ЕИС.",
parser_source=ParserLoadLog.Source.UNFAIR_SUPPLIERS,
),
SourceItemDefinition(
code="fas_goz",
title="Уклонение от ГОЗ",
description="Юрлица, привлеченные за отказ или уклонение от ГОЗ.",
parser_source=ParserLoadLog.Source.FAS_GOZ,
),
),
refresh_interval=timedelta(days=1),
),
SourceCardDefinition(
slug="arbitration-cases",
title="Арбитражные дела",
description="Арбитражные дела по организациям.",
order=70,
task_names=("apps.parsers.tasks.parse_arbitration_cases",),
source_items=(
SourceItemDefinition(
code="arbitration",
title="Арбитражные дела",
description="Карточки арбитражных дел по ИНН/ОГРН организаций.",
parser_source=ParserLoadLog.Source.ARBITRATION,
),
),
refresh_interval=timedelta(days=1),
),
SourceCardDefinition(
slug="information-security-registries",
title="Реестры по информационной безопасности",
description="Реестры ФСТЭК по информационной безопасности.",
order=80,
task_names=("apps.parsers.tasks.parse_fstec_registers",),
source_items=(
SourceItemDefinition(
code="fstec",
title="Реестры ФСТЭК",
description="Официальные реестры ФСТЭК по информационной безопасности.",
parser_source=ParserLoadLog.Source.FSTEC,
),
),
refresh_interval=timedelta(days=30),
),
SourceCardDefinition(
slug="labor-vacancies",
title="Вакансии Работа России",
description="Вакансии работодателей, состоящих в активных реестрах.",
order=90,
task_names=("apps.parsers.tasks.parse_trudvsem_vacancies",),
source_items=(
SourceItemDefinition(
code="trudvsem",
title="Вакансии Работа России",
description="Вакансии работодателей из Работа России, HH и SuperJob.",
parser_source=ParserLoadLog.Source.TRUDVSEM,
),
),
),
)
SOURCE_CARD_BY_SLUG = {item.slug: item for item in SOURCE_CARD_DEFINITIONS}
@@ -231,6 +319,12 @@ GENERIC_RECORD_SOURCES_BY_ITEM_CODE = {
"procurements_44fz": ParserLoadLog.Source.PROCUREMENTS_44FZ,
"procurements_223fz": ParserLoadLog.Source.PROCUREMENTS_223FZ,
"contracts": ParserLoadLog.Source.CONTRACTS,
"unfair_suppliers": ParserLoadLog.Source.UNFAIR_SUPPLIERS,
"fas_goz": ParserLoadLog.Source.FAS_GOZ,
"arbitration": ParserLoadLog.Source.ARBITRATION,
"fedresurs_bankruptcy": ParserLoadLog.Source.FEDRESURS_BANKRUPTCY,
"fstec": ParserLoadLog.Source.FSTEC,
"trudvsem": ParserLoadLog.Source.TRUDVSEM,
}
@@ -545,8 +639,81 @@ class SourceCardService:
)
return [task_info]
task_specs = cls._get_simple_refresh_task_specs(definition.slug)
if task_specs:
return [
cls._enqueue_task(
task=task,
task_name=task_name,
requested_by_id=requested_by_id,
meta={
"source_card": definition.slug,
"source": parser_source,
},
kwargs={"requested_by_id": requested_by_id},
)
for task, task_name, parser_source in task_specs
]
raise ValidationError({"detail": "Обновление для карточки не поддерживается."})
@staticmethod
def _get_simple_refresh_task_specs(
slug: str,
) -> tuple[tuple[Any, str, str], ...]:
from apps.parsers.tasks import (
parse_arbitration_cases,
parse_fas_goz_evasion,
parse_fedresurs_bankruptcy,
parse_fstec_registers,
parse_trudvsem_vacancies,
parse_unfair_suppliers,
)
specs = {
"bankruptcy-procedures": (
(
parse_fedresurs_bankruptcy,
"apps.parsers.tasks.parse_fedresurs_bankruptcy",
ParserLoadLog.Source.FEDRESURS_BANKRUPTCY,
),
),
"defense-unreliable-suppliers": (
(
parse_unfair_suppliers,
"apps.parsers.tasks.parse_unfair_suppliers",
ParserLoadLog.Source.UNFAIR_SUPPLIERS,
),
(
parse_fas_goz_evasion,
"apps.parsers.tasks.parse_fas_goz_evasion",
ParserLoadLog.Source.FAS_GOZ,
),
),
"arbitration-cases": (
(
parse_arbitration_cases,
"apps.parsers.tasks.parse_arbitration_cases",
ParserLoadLog.Source.ARBITRATION,
),
),
"information-security-registries": (
(
parse_fstec_registers,
"apps.parsers.tasks.parse_fstec_registers",
ParserLoadLog.Source.FSTEC,
),
),
"labor-vacancies": (
(
parse_trudvsem_vacancies,
"apps.parsers.tasks.parse_trudvsem_vacancies",
ParserLoadLog.Source.TRUDVSEM,
),
),
}
return specs.get(slug, ())
@classmethod
def _enqueue_task(
cls,
@@ -717,6 +884,7 @@ class SourceCardService:
source_items: list[dict[str, Any]],
) -> int:
if definition.slug == "public-procurements":
generic_sources = cls._get_generic_sources_for_definition(definition)
legacy_inns = (
ProcurementRecord.objects.exclude(customer_inn="")
.order_by()
@@ -724,9 +892,7 @@ class SourceCardService:
.distinct()
)
generic_inns = (
GenericParserRecord.objects.filter(
source__in=GENERIC_RECORD_SOURCES_BY_ITEM_CODE.values()
)
GenericParserRecord.objects.filter(source__in=generic_sources)
.exclude(inn="")
.order_by()
.values_list("inn", flat=True)
@@ -735,6 +901,15 @@ class SourceCardService:
return legacy_inns.union(generic_inns).count()
if definition.slug != "manufacturers-and-products":
generic_sources = cls._get_generic_sources_for_definition(definition)
if generic_sources and len(generic_sources) == len(definition.source_items):
return (
GenericParserRecord.objects.filter(source__in=generic_sources)
.exclude(inn="")
.values("inn")
.distinct()
.count()
)
return sum(item["organizations_count"] for item in source_items)
industrial_inns = (
@@ -757,6 +932,18 @@ class SourceCardService:
)
return industrial_inns.union(manufacturer_inns, product_inns).count()
@staticmethod
def _get_generic_sources_for_definition(
definition: SourceCardDefinition,
) -> list[str]:
return list(
dict.fromkeys(
GENERIC_RECORD_SOURCES_BY_ITEM_CODE[item.code]
for item in definition.source_items
if item.code in GENERIC_RECORD_SOURCES_BY_ITEM_CODE
)
)
@classmethod
def _get_latest_load(
cls,