Вкладка «Организация»: вместо 5 полей доходов по годам — одна строка «Доход за 5 лет (суммарно)» + «Снижение уровня дохода», жирный заголовок убран; миграция старых файлов (сумма по годам → income_5y), авторасчёт/автозаполнение/DaData/шаблоны обновлены

This commit is contained in:
LocoAgent
2026-08-05 14:54:31 +04:00
parent 829a1a98e3
commit 5bb6a2f5e9
3 changed files with 50 additions and 18 deletions
+17 -1
View File
@@ -130,7 +130,9 @@ class Company:
profit_tax: str = "" # Сумма налога с прибыли за предыдущий год profit_tax: str = "" # Сумма налога с прибыли за предыдущий год
# Показатель 8 (ущерб субъекту КИИ): доходы за 5 лет и суммарный ущерб # Показатель 8 (ущерб субъекту КИИ): доходы за 5 лет и суммарный ущерб
income_year_1: str = "" # Доход за 5 лет назад (руб.) # В форме — одна строка «Доход за 5 лет (суммарно)»; по годам разбивает сам оператор.
income_5y: str = "" # Доход за 5 лет суммарно (руб.)
income_year_1: str = "" # Доход за 5 лет назад (руб.) — обратная совместимость
income_year_2: str = "" # Доход за 4 года назад (руб.) income_year_2: str = "" # Доход за 4 года назад (руб.)
income_year_3: str = "" # Доход за 3 года назад (руб.) income_year_3: str = "" # Доход за 3 года назад (руб.)
income_year_4: str = "" # Доход за 2 года назад (руб.) income_year_4: str = "" # Доход за 2 года назад (руб.)
@@ -224,6 +226,20 @@ class Company:
d["okved_extra"] = [] d["okved_extra"] = []
valid = {f.name for f in cls.__dataclass_fields__.values()} valid = {f.name for f in cls.__dataclass_fields__.values()}
obj = cls(**{k: v for k, v in d.items() if k in valid}) obj = cls(**{k: v for k, v in d.items() if k in valid})
# Миграция: старые файлы с доходами по годам → суммарный доход за 5 лет
if not (getattr(obj, 'income_5y', '') or '').strip():
_sum = 0.0
_has = False
for i in range(1, 6):
v = str(getattr(obj, f'income_year_{i}', '') or '').strip()
if v:
try:
_sum += float(v.replace(' ', '').replace(',', '.').replace('\u00a0', ''))
_has = True
except Exception:
pass
if _has:
obj.income_5y = f"{_sum:,.0f}".replace(',', ' ')
# Если в поле ФИО несколько человек — оставить одного (старые опросники) # Если в поле ФИО несколько человек — оставить одного (старые опросники)
for fio_field in ('chief_fio', 'responsible_fio', 'admin_fio'): for fio_field in ('chief_fio', 'responsible_fio', 'admin_fio'):
val = getattr(obj, fio_field, '') val = getattr(obj, fio_field, '')
+23 -12
View File
@@ -345,19 +345,12 @@ class DokoGenApp:
entry.grid(row=i, column=1, padx=10, sticky=tk.EW, pady=1) entry.grid(row=i, column=1, padx=10, sticky=tk.EW, pady=1)
self._company_entries[key] = entry self._company_entries[key] = entry
# Показатель 8 (ущерб субъекту КИИ): доходы за 5 лет + суммарный ущерб # Показатель 8 (ущерб субъекту КИИ): доход за 5 лет (суммарно) + суммарный ущерб
ttk.Label(f_fin, text="Доходы за 5 лет (показатель 8):",
font=('', 9, 'bold')).grid(row=len(fin_fields), column=0, columnspan=2,
sticky=tk.W, pady=(8, 2))
ttk.Button(f_fin, text="🌐 Загрузить доходы из DaData (по ИНН)", ttk.Button(f_fin, text="🌐 Загрузить доходы из DaData (по ИНН)",
command=self._load_incomes_from_dadata).grid( command=self._load_incomes_from_dadata).grid(
row=len(fin_fields), column=2, padx=5, sticky=tk.W) row=len(fin_fields), column=2, padx=5, sticky=tk.W)
income_fields = [ income_fields = [
("Доход за 5 лет назад (руб.):", "income_year_1"), ("Доход за 5 лет (суммарно, руб.):", "income_5y"),
("Доход за 4 года назад (руб.):", "income_year_2"),
("Доход за 3 года назад (руб.):", "income_year_3"),
("Доход за 2 года назад (руб.):", "income_year_4"),
("Доход за прошлый год (руб.):", "income_year_5"),
("Снижение уровня дохода от нарушения критических процессов (руб.):", "income_loss"), ("Снижение уровня дохода от нарушения критических процессов (руб.):", "income_loss"),
] ]
for j, (label, key) in enumerate(income_fields): for j, (label, key) in enumerate(income_fields):
@@ -2360,11 +2353,21 @@ class DokoGenApp:
return e return e
e_profit = e_tax = None e_profit = e_tax = None
# Доходы за 5 лет — из данных организации (поля «Доходы за 5 лет») # Доходы за 5 лет — из данных организации (поле «Доход за 5 лет (суммарно)»,
# иначе — обратная совместимость по годам)
_incs_raw = [getattr(self.model, f'income_year_{i}', '') or '' for i in range(1, 6)] _incs_raw = [getattr(self.model, f'income_year_{i}', '') or '' for i in range(1, 6)]
_incs = [_num(x) for x in _incs_raw] _incs = [_num(x) for x in _incs_raw]
_incs_filled = [x for x in _incs if x is not None] _incs_filled = [x for x in _incs if x is not None]
_d_avg = (sum(_incs_filled) / len(_incs_filled)) if _incs_filled else None _inc5 = _num(getattr(self.model, 'income_5y', '') or '')
if _inc5:
_d_avg = _inc5 / 5.0
_n_years = 5
elif _incs_filled:
_d_avg = sum(_incs_filled) / len(_incs_filled)
_n_years = len(_incs_filled)
else:
_d_avg = None
_n_years = 0
_d_loss = _num(getattr(self.model, 'income_loss', '') or '') _d_loss = _num(getattr(self.model, 'income_loss', '') or '')
_bv8 = getattr(isys, 'balance_value', '') or '' _bv8 = getattr(isys, 'balance_value', '') or ''
_bvn8 = _num(_bv8) _bvn8 = _num(_bv8)
@@ -4247,9 +4250,16 @@ class DokoGenApp:
# Последние 5 лет: income_year_5 (самый свежий) ... income_year_1 (самый старый) # Последние 5 лет: income_year_5 (самый свежий) ... income_year_1 (самый старый)
last5 = rows[-5:] last5 = rows[-5:]
mapping = [] mapping = []
total = 0.0
for i, (y, inc) in enumerate(last5): for i, (y, inc) in enumerate(last5):
# y — календарный год; income_year_1 — самый старый из пяти # y — календарный год; income_year_1 — самый старый из пяти
mapping.append((f'income_year_{i+1}', y, inc)) mapping.append((f'income_year_{i+1}', y, inc))
total += inc
# Основное поле формы — «Доход за 5 лет (суммарно)»
entry = self._company_entries.get('income_5y')
if entry:
entry.delete(0, tk.END)
entry.insert(0, f"{total:,.0f}".replace(',', ' '))
for key, y, inc in mapping: for key, y, inc in mapping:
entry = self._company_entries.get(key) entry = self._company_entries.get(key)
if entry: if entry:
@@ -4258,7 +4268,7 @@ class DokoGenApp:
self._collect_company() self._collect_company()
years = ', '.join(f"{y}: {inc:,.0f} руб." for _, y, inc in mapping) years = ', '.join(f"{y}: {inc:,.0f} руб." for _, y, inc in mapping)
self.log(f"🌐 Доходы из DaData загружены: {years}") self.log(f"🌐 Доходы из DaData загружены: {years}")
messagebox.showinfo("DaData", f"Доходы загружены из DaData:\n{years}") messagebox.showinfo("DaData", f"Доходы загружены из DaData (сумма за 5 лет: {total:,.0f} руб.):\n{years}")
def _select_main_okved(self): def _select_main_okved(self):
"""Выбор основного ОКВЭД из словаря (всегда один).""" """Выбор основного ОКВЭД из словаря (всегда один)."""
@@ -4623,6 +4633,7 @@ class DokoGenApp:
# Показатель 8: доходы за 5 лет + суммарный ущерб от нарушения критических процессов # Показатель 8: доходы за 5 лет + суммарный ущерб от нарушения критических процессов
income_map = [ income_map = [
('income_5y', ('income5Y', 'income_5y', 'income5y')),
('income_year_1', ('incomeYear1', 'income_year_1')), ('income_year_1', ('incomeYear1', 'income_year_1')),
('income_year_2', ('incomeYear2', 'income_year_2')), ('income_year_2', ('incomeYear2', 'income_year_2')),
('income_year_3', ('incomeYear3', 'income_year_3')), ('income_year_3', ('incomeYear3', 'income_year_3')),
+7 -2
View File
@@ -61,7 +61,8 @@ VARIABLE_DEFS = [
('{{company_okved_extra}}', 'A', 'Дополнительные ОКВЭД', 'company:okved_extra'), ('{{company_okved_extra}}', 'A', 'Дополнительные ОКВЭД', 'company:okved_extra'),
('{{company_profit}}', 'A', 'Сумма прибыли за предыдущий год (руб.)', 'company:profit'), ('{{company_profit}}', 'A', 'Сумма прибыли за предыдущий год (руб.)', 'company:profit'),
('{{company_profit_tax}}', 'A', 'Сумма налога с прибыли (руб.)', 'company:profit_tax'), ('{{company_profit_tax}}', 'A', 'Сумма налога с прибыли (руб.)', 'company:profit_tax'),
('{{company_income_year_1}}', 'A', 'Доход за 5 лет назад (руб.) — показатель 8', 'company:income_year_1'), ('{{company_income_5y}}', 'A', 'Доход за 5 лет суммарно (руб.) — показатель 8', 'company:income_5y'),
('{{company_income_year_1}}', 'A', 'Доход за 5 лет назад (руб.) — показатель 8 (обратная совместимость)', 'company:income_year_1'),
('{{company_income_year_2}}', 'A', 'Доход за 4 года назад (руб.) — показатель 8', 'company:income_year_2'), ('{{company_income_year_2}}', 'A', 'Доход за 4 года назад (руб.) — показатель 8', 'company:income_year_2'),
('{{company_income_year_3}}', 'A', 'Доход за 3 года назад (руб.) — показатель 8', 'company:income_year_3'), ('{{company_income_year_3}}', 'A', 'Доход за 3 года назад (руб.) — показатель 8', 'company:income_year_3'),
('{{company_income_year_4}}', 'A', 'Доход за 2 года назад (руб.) — показатель 8', 'company:income_year_4'), ('{{company_income_year_4}}', 'A', 'Доход за 2 года назад (руб.) — показатель 8', 'company:income_year_4'),
@@ -428,7 +429,11 @@ def _calc_criterion_8_9(company, isys, num):
d = _num(getattr(company, 'income_loss', '') or '') d = _num(getattr(company, 'income_loss', '') or '')
if d is None: if d is None:
d = _num(getattr(isys, 'balance_value', '') or '') d = _num(getattr(isys, 'balance_value', '') or '')
# Доходы за 5 лет # Доходы за 5 лет: основное поле income_5y (суммарно), иначе — обратная совместимость по годам
inc5 = _num(getattr(company, 'income_5y', '') or '')
if inc5:
r_avg = inc5 / 5.0
else:
incs = [_num(getattr(company, f'income_year_{i}', '') or '') for i in range(1, 6)] incs = [_num(getattr(company, f'income_year_{i}', '') or '') for i in range(1, 6)]
incs = [x for x in incs if x is not None] incs = [x for x in incs if x is not None]
r_avg = (sum(incs) / len(incs)) if incs else None r_avg = (sum(incs) / len(incs)) if incs else None