feat: словарь управлений ФСТЭК + переменная {{fstek_recipient_address}}

- dictionaries/fstek_offices.json: 7 управлений ФСТЭК по федеральным округам
  с адресами (из официальных реестров) и списками городов/регионов:
  ЦФО (Москва, Севастопольский пр-т 56/40), СЗФО (СПб, Исаакиевская пл. 11),
  ЮФО+СКФО (Ростов-на-Дону, ул. Ярослава Галана 1Е/25), ПФО (Н.Новгород,
  пр-т Гагарина 60 к11), УрФО (Екатеринбург, ул. Гагарина 28Б), СФО
  (Новосибирск, Красный пр-т 41), ДФО (Хабаровск, ул. Ленина 37)
- variables.py: _find_fstek_office(address) — определяет управление по городу/
  региону из адреса организации (с нормализацией сокращений обл./респ./г.о.)
- новые переменные: {{fstek_recipient_address}} (адрес управления для отправки),
  {{fstek_district}} (наименование управления)
- логика: адрес организации → управление ФСТЭК → адрес подставляется в документ
This commit is contained in:
2026-08-04 19:45:33 +04:00
parent 730551aeba
commit c4a8de57d1
2 changed files with 333 additions and 0 deletions
+283
View File
@@ -0,0 +1,283 @@
[
{
"name": "Управление ФСТЭК России по Центральному федеральному округу",
"address": "117342, г. Москва, Севастопольский проспект, д. 56/40, стр. 1",
"cities": [
"москва",
"белгород",
"брянск",
"владимир",
"воронеж",
"иваново",
"калуга",
"кострома",
"курск",
"липецк",
"орёл",
"орел",
"рязань",
"смоленск",
"тамбов",
"тверь",
"тула",
"ярославль",
"подольск",
"балашиха",
"химки",
"мытищи",
"королёв",
"люберцы",
"одинцово",
"домодедово",
"серпухов",
"электросталь",
"сергиев посад",
"коломна"
],
"regions": [
"московская область",
"белгородская область",
"брянская область",
"владимирская область",
"воронежская область",
"ивановская область",
"калужская область",
"костромская область",
"курская область",
"липецкая область",
"орловская область",
"рязанская область",
"смоленская область",
"тамбовская область",
"тверская область",
"тульская область",
"ярославская область"
]
},
{
"name": "Управление ФСТЭК России по Северо-Западному федеральному округу",
"address": "190121, г. Санкт-Петербург, Исаакиевская площадь, д. 11, лит. А",
"cities": [
"санкт-петербург",
"петербург",
"архангельск",
"вологда",
"калининград",
"мурманск",
"великий новгород",
"новгород",
"псков",
"петрозаводск",
"сыктывкар",
"нарьян-мар",
"северодвинск",
"череповец",
"гатчина"
],
"regions": [
"ленинградская область",
"архангельская область",
"вологодская область",
"калининградская область",
"мурманская область",
"новгородская область",
"псковская область",
"республика карелия",
"республика коми",
"ненецкий"
]
},
{
"name": "Управление ФСТЭК России по Южному и Северо-Кавказскому федеральным округам",
"address": "344079, г. Ростов-на-Дону, ул. Ярослава Галана, д. 1Е/25",
"cities": [
"ростов-на-дону",
"ростов",
"астрахань",
"волгоград",
"краснодар",
"майкоп",
"элиста",
"симферополь",
"севастополь",
"сочи",
"новороссийск",
"таганрог",
"шахты",
"волжский",
"камышин",
"махачкала",
"грозный",
"владикавказ",
"нальчик",
"черкесск",
"магас",
"ставрополь",
"пятигорск",
"кисловодск",
"ессентуки",
"минеральные воды",
"назрань"
],
"regions": [
"ростовская область",
"астраханская область",
"волгоградская область",
"краснодарский край",
"республика адыгея",
"республика калмыкия",
"республика крым",
"севастополь",
"республика дагестан",
"чеченская республика",
"республика северная осетия",
"кабардино-балкарская республика",
"карачаево-черкесская республика",
"республика ингушетия",
"ставропольский край"
]
},
{
"name": "Управление ФСТЭК России по Приволжскому федеральному округу",
"address": "603104, г. Нижний Новгород, проспект Гагарина, д. 60, корп. 11",
"cities": [
"нижний новгород",
"казань",
"самара",
"саратов",
"пенза",
"пермь",
"уфа",
"ижевск",
"оренбург",
"ульяновск",
"киров",
"саранск",
"чебоксары",
"йошкар-ола",
"тольятти",
"набережные челны",
"арзамас",
"дзержинск",
"балаково",
"новокуйбышевск",
"сызрань"
],
"regions": [
"нижегородская область",
"республика татарстан",
"самарская область",
"саратовская область",
"пензенская область",
"пермский край",
"республика башкортостан",
"удмуртская республика",
"оренбургская область",
"ульяновская область",
"кировская область",
"республика мордовия",
"чувашская республика",
"республика марий эл"
]
},
{
"name": "Управление ФСТЭК России по Уральскому федеральному округу",
"address": "620078, г. Екатеринбург, ул. Гагарина, д. 28Б",
"cities": [
"екатеринбург",
"челябинск",
"тюмень",
"курган",
"ханты-мансийск",
"салехард",
"сургут",
"нижневартовск",
"магнитогорск",
"нижний тагил",
"каменск-уральский",
"первоуральск",
"миасс",
"зубовой"
],
"regions": [
"свердловская область",
"челябинская область",
"тюменская область",
"курганская область",
"ханты-мансийский",
"ямало-ненецкий"
]
},
{
"name": "Управление ФСТЭК России по Сибирскому федеральному округу",
"address": "630091, г. Новосибирск, Красный проспект, д. 41",
"cities": [
"новосибирск",
"омск",
"томск",
"кемерово",
"барнаул",
"красноярск",
"иркутск",
"новокузнецк",
"абакан",
"горно-алтайск",
"кызыл",
"улан-удэ",
"чита",
"ангарск",
"братск",
"прокопьевск",
"бийск",
"рубцовск",
"бердск",
"северск"
],
"regions": [
"новосибирская область",
"омская область",
"томская область",
"кемеровская область",
"алтайский край",
"красноярский край",
"иркутская область",
"республика алтай",
"республика тыва",
"республика хакасия",
"республика бурятия",
"забайкальский край"
]
},
{
"name": "Управление ФСТЭК России по Дальневосточному федеральному округу",
"address": "680030, г. Хабаровск, ул. Ленина, д. 37",
"cities": [
"хабаровск",
"владивосток",
"благовещенск",
"якутск",
"петропавловск-камчатский",
"южно-сахалинск",
"магадан",
"биробиджан",
"анадырь",
"комсомольск-на-амуре",
"уссурийск",
"находка",
"артём",
"белогорск",
"свободный"
],
"regions": [
"хабаровский край",
"приморский край",
"амурская область",
"республика саха",
"камчатский край",
"сахалинская область",
"магаданская область",
"еврейская автономная область",
"чукотский"
]
}
]
+50
View File
@@ -64,6 +64,8 @@ VARIABLE_DEFS = [
# === Комиссия === # === Комиссия ===
('{{commission_list}}', 'A', 'Список комиссии', 'commission_list'), ('{{commission_list}}', 'A', 'Список комиссии', 'commission_list'),
('{{fstek_district}}', 'A', 'Наименование управления ФСТЭК России (по адресу организации)', 'fstek_district'),
('{{fstek_recipient_address}}', 'A', 'Адрес управления ФСТЭК России для направления сведений', 'fstek_recipient_address'),
# === Специальные переменные === # === Специальные переменные ===
('{{date_year}}', 'A', 'Текущий год', 'date:year'), ('{{date_year}}', 'A', 'Текущий год', 'date:year'),
@@ -370,6 +372,44 @@ def _build_loop_data(company: Company, is_list: List) -> Dict[str, List[Dict]]:
# РЕЗОЛВЕР ЗНАЧЕНИЙ # РЕЗОЛВЕР ЗНАЧЕНИЙ
# ============================================================ # ============================================================
def _find_fstek_office(address_text: str):
"""Определяет управление ФСТЭК России по адресу организации.
Ищет город/регион из адреса в словаре fstek_offices.json.
Возвращает dict {'name': ..., 'address': ...} или None.
"""
import json as _json
import os as _os
if not address_text:
return None
dict_path = _os.path.join(_os.path.dirname(__file__), 'dictionaries', 'fstek_offices.json')
try:
with open(dict_path, encoding='utf-8') as _f:
offices = _json.load(_f)
except Exception:
return None
hay = address_text.lower()
# Нормализация сокращений: обл.→область, респ.→республика, г.о.→городской округ
hay = hay.replace('обл.', 'область').replace('обл,', 'область')
hay = hay.replace('респ.', 'республика').replace('респ,', 'республика')
hay = hay.replace('г.о.', 'городской округ').replace('г.о,', 'городской округ')
hay = hay.replace('ао', 'автономный округ')
best = None
best_len = 0
for off in offices:
# Ищем по городам
for city in off.get('cities', []):
if city in hay and len(city) > best_len:
best = off
best_len = len(city)
# Ищем по регионам (область/край/республика)
for region in off.get('regions', []):
if region in hay and len(region) > best_len:
best = off
best_len = len(region)
return best
def _resolve(source: str, ctx: Dict) -> str: def _resolve(source: str, ctx: Dict) -> str:
"""Преобразует ключ-источник в значение, подставляя из контекста.""" """Преобразует ключ-источник в значение, подставляя из контекста."""
company = ctx.get('company') company = ctx.get('company')
@@ -417,6 +457,16 @@ def _resolve(source: str, ctx: Dict) -> str:
if source in commission_data: if source in commission_data:
return str(commission_data[source]) return str(commission_data[source])
# Управление ФСТЭК (адресат отправки сведений о категорировании)
if source in ('fstek_recipient_address', 'fstek_district', 'fstek_office_name'):
addr = getattr(company, 'address', '') or ''
off = _find_fstek_office(addr)
if off:
if source == 'fstek_recipient_address':
return off.get('address', '') or ''
return off.get('name', '') or ''
return ''
# Даты # Даты
if source.startswith('date:'): if source.startswith('date:'):
fmt = source.split(':', 1)[1] fmt = source.split(':', 1)[1]