diff --git a/dokogen/dictionaries/fstek_offices.json b/dokogen/dictionaries/fstek_offices.json new file mode 100644 index 0000000..5712d9a --- /dev/null +++ b/dokogen/dictionaries/fstek_offices.json @@ -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": [ + "хабаровский край", + "приморский край", + "амурская область", + "республика саха", + "камчатский край", + "сахалинская область", + "магаданская область", + "еврейская автономная область", + "чукотский" + ] + } +] \ No newline at end of file diff --git a/dokogen/variables.py b/dokogen/variables.py index 0923711..abd2e2f 100644 --- a/dokogen/variables.py +++ b/dokogen/variables.py @@ -64,6 +64,8 @@ VARIABLE_DEFS = [ # === Комиссия === ('{{commission_list}}', 'A', 'Список комиссии', 'commission_list'), + ('{{fstek_district}}', 'A', 'Наименование управления ФСТЭК России (по адресу организации)', 'fstek_district'), + ('{{fstek_recipient_address}}', 'A', 'Адрес управления ФСТЭК России для направления сведений', 'fstek_recipient_address'), # === Специальные переменные === ('{{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: """Преобразует ключ-источник в значение, подставляя из контекста.""" company = ctx.get('company') @@ -417,6 +457,16 @@ def _resolve(source: str, ctx: Dict) -> str: if source in commission_data: 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:'): fmt = source.split(':', 1)[1]