feat: пометка ★ для ОКВЭД, подходящих под 187-ФЗ (из 360-р)

- dictionaries/okved_187.json: 78 кодов ОКВЭД из Распоряжения ПРФ № 360-р
  (виды деятельности субъектов КИИ по типовым отраслевым объектам)
- okved.json: добавлен недостающий код 09.90 (всего 267)
- ui.py: _load_okved_187_codes/_is_okved_187 — проверка по коду/подкоду
- окно выбора основного ОКВЭД: радио-кнопки с пометкой «★ ...»
- окно выбора доп. ОКВЭД: display_map со звёздочками (в значение
  звёздочка не попадает), легенда «★ — код подходит под 187-ФЗ»
- при применении сохраняется чистый код без ★ (импорт/документы не ломаются)
This commit is contained in:
2026-08-04 23:07:28 +04:00
parent 29ba4b0532
commit 4bffd0e08d
3 changed files with 392 additions and 272 deletions
+44 -5
View File
@@ -3060,10 +3060,13 @@ class DokoGenApp:
listbox.delete(sel[0])
# ==================== ВЫБОР ИЗ СПИСКА (словари) ====================
def _select_from_dialog(self, title: str, items: list, listbox, allow_refine=False):
def _select_from_dialog(self, title: str, items: list, listbox, allow_refine=False,
display_map=None):
"""Открывает окно с чекбоксами для выбора элементов из списка.
allow_refine=True — показывать кнопку «✏️ Уточнить модель/кол-во».
display_map — dict {элемент: текст_для_отображения} (пометки, например «★»),
при применении сохраняется сам элемент (без пометки).
"""
dialog = tk.Toplevel(self.root)
dialog.title(title)
@@ -3099,10 +3102,14 @@ class DokoGenApp:
items_map = {}
for item in items:
var = tk.BooleanVar(value=item in existing)
cb = ttk.Checkbutton(check_frame, text=item, variable=var)
label = (display_map or {}).get(item, item)
cb = ttk.Checkbutton(check_frame, text=label, variable=var)
cb.pack(anchor=tk.W, pady=1)
vars[item] = var
items_map[item] = (var, cb)
if display_map:
ttk.Label(check_frame, text="★ — код подходит под 187-ФЗ (из Распоряжения ПРФ № 360-р)",
foreground='#1a6e1a').pack(anchor=tk.W, pady=(4, 0))
# Фильтр по поиску: скрываем неподходящие чекбоксы
def _apply_search(*_):
@@ -3238,6 +3245,32 @@ class DokoGenApp:
messagebox.showerror("Ошибка", f"Не удалось загрузить словарь ОКВЭД:\n{e}")
return []
def _load_okved_187_codes(self):
"""Коды ОКВЭД, подходящие под 187-ФЗ (из Распоряжения ПРФ № 360-р)."""
import json
dict_path = os.path.join(os.path.dirname(__file__), 'dictionaries', 'okved_187.json')
try:
with open(dict_path, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception:
return []
def _is_okved_187(self, item):
"""Подходит ли строка ОКВЭД под 187-ФЗ (код совпадает/является подкодом из 360-р)."""
import re
m = re.match(r'^(\d+(?:\.\d+)*)', item or '')
if not m:
return False
code = m.group(1)
codes = getattr(self, '_okved_187_cache', None)
if codes is None:
codes = self._load_okved_187_codes()
self._okved_187_cache = codes
for c in codes:
if code == c or code.startswith(c + '.') or c.startswith(code + '.'):
return True
return False
def _select_main_okved(self):
"""Выбор основного ОКВЭД из словаря (всегда один)."""
items = self._load_okved_dict()
@@ -3264,11 +3297,14 @@ class DokoGenApp:
canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
# Радио-кнопки: основной всегда один
# Радио-кнопки: основной всегда один (★ — подходит под 187-ФЗ)
var = tk.StringVar(value=current)
for item in items:
ttk.Radiobutton(check_frame, text=item, variable=var,
label = ('' + item) if self._is_okved_187(item) else item
ttk.Radiobutton(check_frame, text=label, variable=var,
value=item).pack(anchor=tk.W, pady=1)
ttk.Label(check_frame, text="★ — код подходит под 187-ФЗ (из Распоряжения ПРФ № 360-р)",
foreground='#1a6e1a').pack(anchor=tk.W, pady=(4, 0))
btn_frame = ttk.Frame(dialog, padding=10)
btn_frame.pack(fill=tk.X)
@@ -3291,7 +3327,10 @@ class DokoGenApp:
items = self._load_okved_dict()
if not items:
return
self._select_from_dialog("Выбор дополнительных ОКВЭД", items, self.okved_extra_listbox)
display_map = {item: ('' + item) if self._is_okved_187(item) else item
for item in items}
self._select_from_dialog("Выбор дополнительных ОКВЭД", items, self.okved_extra_listbox,
display_map=display_map)
def _add_okved_manual(self):
"""Ручное добавление дополнительного ОКВЭД."""