Вкладка «Организация»: вместо 5 полей доходов по годам — одна строка «Доход за 5 лет (суммарно)» + «Снижение уровня дохода», жирный заголовок убран; миграция старых файлов (сумма по годам → income_5y), авторасчёт/автозаполнение/DaData/шаблоны обновлены
This commit is contained in:
+17
-1
@@ -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
@@ -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')),
|
||||||
|
|||||||
+10
-5
@@ -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,10 +429,14 @@ 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 (суммарно), иначе — обратная совместимость по годам
|
||||||
incs = [_num(getattr(company, f'income_year_{i}', '') or '') for i in range(1, 6)]
|
inc5 = _num(getattr(company, 'income_5y', '') or '')
|
||||||
incs = [x for x in incs if x is not None]
|
if inc5:
|
||||||
r_avg = (sum(incs) / len(incs)) if incs else None
|
r_avg = inc5 / 5.0
|
||||||
|
else:
|
||||||
|
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]
|
||||||
|
r_avg = (sum(incs) / len(incs)) if incs else None
|
||||||
|
|
||||||
if num == '8':
|
if num == '8':
|
||||||
# Фолбэк: ущерб не заполнен → оценка «доход за год × 5» (наихудший сценарий)
|
# Фолбэк: ущерб не заполнен → оценка «доход за год × 5» (наихудший сценарий)
|
||||||
|
|||||||
Reference in New Issue
Block a user