Авторасчёт всех показателей ПП-127: поле criterion_input в модели (введённые значения из опросника/окна), автогенерация шаблона считает категории по введённым значениям (1–7, 11–14); фикс остановки расчёта (I-я категория вместо startswith('I'))

This commit is contained in:
LocoAgent
2026-08-05 15:27:24 +04:00
parent 1840f1e2d4
commit b2b68258fd
2 changed files with 30 additions and 5 deletions
+6
View File
@@ -80,6 +80,12 @@ class InformationSystem:
org_measures: str = "" # Организационные меры (\n — разделитель) org_measures: str = "" # Организационные меры (\n — разделитель)
tech_measures: str = "" # Технические меры (\n — разделитель) tech_measures: str = "" # Технические меры (\n — разделитель)
# Введённые значения показателей ПП-127 для авторасчёта: {num: значение}
# num — «1», «2а», «2б», …, «14»; значение — число (количественные)
# или выбранный вариант (качественные). Заполняется окном авторасчёта,
# импортом из опросника или вручную; используется в _build_categorization_indicators.
criterion_input: Dict[str, str] = field(default_factory=dict)
@dataclass @dataclass
class Company: class Company:
+24 -5
View File
@@ -768,6 +768,8 @@ def _build_categorization_indicators(company, is_list):
rows = [] rows = []
first_cat_num = None # номер показателя, по которому объект отнесён к I категории (п. 6 ПП-127) first_cat_num = None # номер показателя, по которому объект отнесён к I категории (п. 6 ПП-127)
# Введённые значения показателей (из опросника/окна авторасчёта): {num: значение}
crit_in = dict(getattr(isys, 'criterion_input', None) or {}) if isys else {}
for grp in criteria: for grp in criteria:
section = grp.get('criteria', '') section = grp.get('criteria', '')
for ind in grp.get('indicators', []): for ind in grp.get('indicators', []):
@@ -814,13 +816,30 @@ def _build_categorization_indicators(company, is_list):
else: else:
category = '' category = ''
else: else:
# Применимый показатель без авторасчёта — оператор заполняет значение # Применимый показатель без формульного авторасчёта (1–7, 11–14):
value = '' # если значение введено (опросник/окно авторасчёта) — считаем категорию по порогам
justification = (just.get(num) or just.get(grp_num) if num in crit_in and str(crit_in.get(num, '')).strip():
or 'Показатель применим к объекту КИИ; значение определяется по данным объекта.') raw = str(crit_in.get(num, '')).strip()
# Число или выбранный вариант (качественный)
try:
_v = float(raw.replace(' ', '').replace(',', '.').replace('\u00a0', ''))
text, cat = _calc_criterion_other(company, isys, num, value=_v)
except ValueError:
text, cat = _calc_criterion_other(company, isys, num, choice=raw)
if text:
value = text
if cat:
category = f"{cat}-я категория"
else:
category = ''
else:
value = ''
justification = (just.get(num) or just.get(grp_num)
or 'Показатель применим к объекту КИИ; значение определяется по данным объекта.')
# Если по показателю присвоена I категория — фиксируем для остановки расчёта # Если по показателю присвоена I категория — фиксируем для остановки расчёта
if first_cat_num is None and category.startswith('I'): # (точное совпадение «I-я категория», а не startswith('I'), иначе ловится II/III)
if first_cat_num is None and category.startswith('I-я'):
first_cat_num = num first_cat_num = num
rows.append({ rows.append({