Public release from ruodoo-project: 19.0 - 2026-11-01 22:52:25 UTC

This commit is contained in:
CI Publish Bot
2026-11-01 22:54:30 +00:00
commit 26250aa580
2492 changed files with 664277 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
from odoo import fields, models
class HrEmployee(models.Model):
_inherit = 'hr.employee'
# --- Персональные данные для отчётности (перс. сведения, РСВ, ЕФС-1,
# 6-НДФЛ). Дата рождения/гражданство берутся из штатных hr-полей
# (birthday, country_id). TODO(сверка форматов/справочников). ---
rsbu_snils = fields.Char(
string='СНИЛС',
help='Страховой номер индивидуального лицевого счёта (формат '
'XXX-XXX-XXX YY). Обязателен для персонифицированной отчётности '
'и ЕФС-1.')
rsbu_inn = fields.Char(
string='ИНН физлица',
help='ИНН сотрудника (12 знаков). Для 6-НДФЛ и РСВ.')
rsbu_insured_category = fields.Char(
string='Код категории застрахованного',
default='НР',
help='Код категории застрахованного лица для РСВ/перс. сведений '
'(напр. «НР» — наёмные работники по единому тарифу, «МС» — '
'выплаты сверх МРОТ по льготному тарифу МСП). TODO(сверка '
'справочника кодов).')
# --- Реквизиты для раздела 3 РСВ (персонифицированные сведения) ---
rsbu_citizenship_code = fields.Char(
string='Гражданство (ОКСМ)', default='643', size=3,
help='Числовой код страны гражданства по ОКСМ (643 — Россия). '
'Атрибут «Гражд» в разделе 3 РСВ.')
rsbu_sex = fields.Selection(
selection=[('1', 'Мужской'), ('2', 'Женский')],
string='Пол',
help='Пол застрахованного лица (атрибут «Пол» в разделе 3 РСВ).')
rsbu_id_doc_code = fields.Char(
string='Код вида документа (ДУЛ)', default='21', size=2,
help='Код вида документа, удостоверяющего личность (21 — паспорт '
'гражданина РФ). Атрибут «КодВидДок» в разделе 3 РСВ.')
rsbu_id_doc_number = fields.Char(
string='Серия и номер документа',
help='Серия и номер документа, удостоверяющего личность (атрибут '
'«СерНомДок» в разделе 3 РСВ), напр. «45 04 123456».')
rsbu_okz_code = fields.Char(
string='Код по ОКЗ', size=6,
help='Кодовое обозначение занятия по Общероссийскому классификатору '
'занятий (ОКЗ), формат NNNN.N (напр. «2512.1»). Элемент '
'«КодВФпоОКЗ» мероприятия ЕФС-1 (СЗВ-ТД); обязателен для приёма, '
'перевода, увольнения и ряда других мероприятий.')
rsbu_taxpayer_status = fields.Selection(
selection=[
('1', 'Резидент РФ'),
('2', 'Нерезидент РФ'),
('3', 'Высококвалифицированный специалист'),
('4', 'Участник госпрограммы переселения'),
('5', 'Беженец / временное убежище'),
('6', 'Иностранец по патенту'),
('7', 'Гражданин ЕАЭС'),
],
string='Статус налогоплательщика', default='1',
help='Статус для 6-НДФЛ и порядка исчисления НДФЛ (ст.224 НК): '
'резидент, ВКС, патент, ЕАЭС — прогрессивная шкала 13–22%; '
'обычный нерезидент — 30% без вычетов. TODO(сверка справочника).')
# --- Стандартные вычеты по НДФЛ (ст. 218 НК) ---
rsbu_child_ids = fields.One2many(
'rsbu.employee.child', 'employee_id', string='Дети (для вычетов)',
help='Дети сотрудника для стандартного вычета по НДФЛ. Очередность '
'и возраст определяют размер вычета; система прекращает вычет '
'по достижении лимита дохода 450 000 ₽ и по возрасту ребёнка.')
rsbu_personal_deduction_code = fields.Selection(
selection=[
('none', 'Нет'),
('104', '500 ₽/мес (код 104)'),
('105', '3000 ₽/мес (код 105)'),
],
string='Личный вычет', default='none',
help='Личный стандартный вычет на работника (пп.1–2 п.1 ст.218 НК): '
'3000 ₽ (чернобыльцы, инвалиды ВОВ), 500 ₽ (Герои, инвалиды '
'I–II гр., ветераны). Лимита по доходу нет.')
rsbu_gto_deduction = fields.Boolean(
string='Вычет ГТО (18 000 ₽/год)',
help='Сотрудник сдал нормативы ГТО и получил знак отличия — разовый '
'годовой вычет 18 000 ₽ (пп.2.1 п.1 ст.218 НК, с 2025).')
def rsbu_is_progressive_ndfl(self):
"""Применяется ли прогрессивная шкала 13–22% (иначе 30% нерезидент).
Прогрессия — резиденты (1), ВКС (3), патент (6), ЕАЭС (7). Обычный
нерезидент (2) — 30% без вычетов. Переселенцы (4) и беженцы (5)
облагаются как резиденты по трудовым доходам — прогрессия. (ст.224 НК)
"""
self.ensure_one()
return self.rsbu_taxpayer_status != '2'
def rsbu_allows_deductions(self):
"""Право на стандартные вычеты (только резиденты-статус для шкалы).
Нерезиденты (в т.ч. ВКС/патент/ЕАЭС до приобретения резидентства)
вычеты не получают (п.3 ст.210, п.3 ст.224 НК). В базовом сценарии
вычеты даём статусу «резидент РФ»; для остальных — TODO по факту
резидентства (нужен учёт дней пребывания).
"""
self.ensure_one()
return self.rsbu_taxpayer_status == '1'
# Данные для расчёта пособий (больничный и т.п.).
# Позже средний заработок будет вычисляться калькулятором за 2 года.
rsbu_insurance_years = fields.Float(
string='Страховой стаж, лет',
default=0.0,
help='Страховой стаж сотрудника. Определяет процент оплаты больничного: '
'≥8 лет — 100%, 5–8 лет — 80%, <5 лет — 60%.')
rsbu_avg_daily_wage = fields.Monetary(
string='Средний дневной заработок',
currency_field='rsbu_currency_id',
help='Средний дневной заработок для расчёта пособий (больничный, '
'отпускные). Пока задаётся вручную; позже — калькулятор за 2 года.')
rsbu_currency_id = fields.Many2one(
'res.currency', related='company_id.currency_id', readonly=True)
def rsbu_sick_rate(self):
"""Процент оплаты больничного по страховому стажу (доля 0..1)."""
self.ensure_one()
years = self.rsbu_insurance_years or 0.0
if years >= 8:
return 1.0
if years >= 5:
return 0.8
return 0.6