diff --git a/dokogen/models.py b/dokogen/models.py index c52120e..6cd5a84 100644 --- a/dokogen/models.py +++ b/dokogen/models.py @@ -80,6 +80,12 @@ class InformationSystem: org_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 class Company: diff --git a/dokogen/variables.py b/dokogen/variables.py index 2f9420e..6940962 100644 --- a/dokogen/variables.py +++ b/dokogen/variables.py @@ -768,6 +768,8 @@ def _build_categorization_indicators(company, is_list): rows = [] first_cat_num = None # номер показателя, по которому объект отнесён к I категории (п. 6 ПП-127) + # Введённые значения показателей (из опросника/окна авторасчёта): {num: значение} + crit_in = dict(getattr(isys, 'criterion_input', None) or {}) if isys else {} for grp in criteria: section = grp.get('criteria', '') for ind in grp.get('indicators', []): @@ -814,13 +816,30 @@ def _build_categorization_indicators(company, is_list): else: category = '—' else: - # Применимый показатель без авторасчёта — оператор заполняет значение - value = '—' - justification = (just.get(num) or just.get(grp_num) - or 'Показатель применим к объекту КИИ; значение определяется по данным объекта.') + # Применимый показатель без формульного авторасчёта (1–7, 11–14): + # если значение введено (опросник/окно авторасчёта) — считаем категорию по порогам + if num in crit_in and str(crit_in.get(num, '')).strip(): + 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 категория — фиксируем для остановки расчёта - 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 rows.append({