163 lines
9.0 KiB
XML
163 lines
9.0 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<odoo>
|
||
<!-- Правила расчёта — конфигурация модуля, должны обновляться при -u
|
||
(без noupdate). Счета РСБУ на правилах проставляет post_init hook. -->
|
||
<data>
|
||
|
||
<!-- Оклад. Базовый вариант — полный оклад контракта.
|
||
Пропорция по отработанным дням (worked_days.WORK100) может быть
|
||
добавлена при уточнении алгоритма; сейчас оклад берётся полностью
|
||
или из входа BASIC, если задан вручную. -->
|
||
<record id="rsbu_rule_basic" model="hr.salary.rule">
|
||
<field name="name">Оклад</field>
|
||
<field name="code">BASIC</field>
|
||
<field name="sequence" eval="10"/>
|
||
<field name="category_id" ref="rsbu_cat_basic"/>
|
||
<field name="condition_select">none</field>
|
||
<field name="amount_select">code</field>
|
||
<field name="amount_python_compute">
|
||
# Оклад пропорционально отработанным дням (норма и отработанные берутся из
|
||
# календаря и hr.leave автоматически: отпуск/больничный/за свой счёт
|
||
# уменьшают отработанные дни). Ручной ввод не требуется.
|
||
norm = payslip.rsbu_norm_days or 0.0
|
||
worked = payslip.rsbu_worked_days or 0.0
|
||
if norm:
|
||
result = contract.wage * worked / norm
|
||
else:
|
||
result = contract.wage
|
||
</field>
|
||
</record>
|
||
|
||
<!-- Премия: сумма из входа PREMIUM (hr.payslip.input), иначе 0. -->
|
||
<record id="rsbu_rule_premium" model="hr.salary.rule">
|
||
<field name="name">Премия</field>
|
||
<field name="code">PREMIUM</field>
|
||
<field name="sequence" eval="20"/>
|
||
<field name="category_id" ref="rsbu_cat_alw"/>
|
||
<field name="condition_select">none</field>
|
||
<field name="amount_select">code</field>
|
||
<field name="amount_python_compute">
|
||
result = inputs.PREMIUM.amount if 'PREMIUM' in inputs.dict else 0.0
|
||
</field>
|
||
</record>
|
||
|
||
<!-- Отпускные = средний дневной заработок × календарные дни отпуска.
|
||
Дни отпуска берутся из hr.leave (тип «Оплачиваемый отпуск»)
|
||
автоматически. -->
|
||
<record id="rsbu_rule_vacation" model="hr.salary.rule">
|
||
<field name="name">Отпускные</field>
|
||
<field name="code">VACATION</field>
|
||
<field name="sequence" eval="30"/>
|
||
<field name="category_id" ref="rsbu_cat_alw"/>
|
||
<field name="condition_select">none</field>
|
||
<field name="amount_select">code</field>
|
||
<field name="amount_python_compute">
|
||
avg = employee.rsbu_avg_daily_wage or 0.0
|
||
result = avg * (payslip.rsbu_vacation_cal_days or 0.0)
|
||
</field>
|
||
</record>
|
||
|
||
<!-- Больничный за счёт работодателя (первые 3 дня).
|
||
Пособие = средний дневной заработок × min(3, дни болезни) ×
|
||
процент по страховому стажу (≥8 лет 100%, 5-8 лет 80%, <5 лет 60%).
|
||
Дни болезни подаются входом SICK_DAYS. Первые 3 дня платит
|
||
работодатель, остальные — СФР (в наш учёт не попадают).
|
||
Облагается НДФЛ, но НЕ облагается страховыми взносами. -->
|
||
<record id="rsbu_rule_sick3" model="hr.salary.rule">
|
||
<field name="name">Больничный (3 дня за счёт работодателя)</field>
|
||
<field name="code">SICK3</field>
|
||
<field name="sequence" eval="40"/>
|
||
<field name="category_id" ref="rsbu_cat_alw"/>
|
||
<field name="condition_select">none</field>
|
||
<field name="amount_select">code</field>
|
||
<field name="amount_python_compute">
|
||
# Календарные дни больничного берутся из hr.leave (тип «Больничный»)
|
||
# автоматически. Работодатель оплачивает первые 3 календарных дня.
|
||
sick_days = payslip.rsbu_sick_cal_days or 0.0
|
||
employer_days = min(3.0, sick_days)
|
||
avg = employee.rsbu_avg_daily_wage or 0.0
|
||
rate = employee.rsbu_sick_rate()
|
||
result = avg * employer_days * rate
|
||
</field>
|
||
</record>
|
||
|
||
<!-- Начислено (итог, облагаемая НДФЛ база). -->
|
||
<record id="rsbu_rule_gross" model="hr.salary.rule">
|
||
<field name="name">Начислено</field>
|
||
<field name="code">GROSS</field>
|
||
<field name="sequence" eval="100"/>
|
||
<field name="category_id" ref="rsbu_cat_gross"/>
|
||
<field name="condition_select">none</field>
|
||
<field name="amount_select">code</field>
|
||
<field name="amount_python_compute">
|
||
result = categories.RSBU_BASIC + categories.RSBU_ALW
|
||
</field>
|
||
</record>
|
||
|
||
<!-- НДФЛ: прогрессивная шкала 13–22% нарастающим итогом с начала
|
||
года + стандартные вычеты (ст.224/225/218 НК). Расчёт вынесен
|
||
в rsbu_compute_ndfl (нужен доступ к листкам года и вычетам).
|
||
Результат отрицательный (удержание). -->
|
||
<record id="rsbu_rule_ndfl" model="hr.salary.rule">
|
||
<field name="name">НДФЛ</field>
|
||
<field name="code">NDFL</field>
|
||
<field name="sequence" eval="110"/>
|
||
<field name="category_id" ref="rsbu_cat_ndfl"/>
|
||
<field name="condition_select">none</field>
|
||
<field name="amount_select">code</field>
|
||
<field name="amount_python_compute">
|
||
result = - payslip.rsbu_compute_ndfl(current_gross=categories.RSBU_GROSS)
|
||
</field>
|
||
</record>
|
||
|
||
<!-- Страховые взносы (единый тариф): база = начислено минус больничный
|
||
(больничный взносами не облагается). Затраты работодателя.
|
||
Переменная SICK3 в localdict = сумма (total) правила больничного. -->
|
||
<record id="rsbu_rule_insurance" model="hr.salary.rule">
|
||
<field name="name">Страховые взносы (единый тариф)</field>
|
||
<field name="code">INSURANCE</field>
|
||
<field name="sequence" eval="120"/>
|
||
<field name="category_id" ref="rsbu_cat_insurance"/>
|
||
<field name="condition_select">none</field>
|
||
<field name="amount_select">code</field>
|
||
<field name="amount_python_compute">
|
||
# Сумма = разбивка ОПС+ОМС+ВНиМ (с учётом льготы МСП сверх 1.5 МРОТ).
|
||
# База берётся из localdict (RSBU_GROSS − SICK3), т.к. строки листка на
|
||
# момент расчёта ещё не сохранены. Разбивка по видам для РСВ доступна
|
||
# через payslip.rsbu_insurance_breakdown(base).
|
||
result = payslip.rsbu_insurance_breakdown(
|
||
base=max(0.0, categories.RSBU_GROSS - SICK3))['total']
|
||
</field>
|
||
</record>
|
||
|
||
<!-- Взносы на травматизм: та же база, тариф из настроек. -->
|
||
<record id="rsbu_rule_injury" model="hr.salary.rule">
|
||
<field name="name">Взносы на травматизм</field>
|
||
<field name="code">INJURY</field>
|
||
<field name="sequence" eval="130"/>
|
||
<field name="category_id" ref="rsbu_cat_injury"/>
|
||
<field name="condition_select">none</field>
|
||
<field name="amount_select">code</field>
|
||
<field name="amount_python_compute">
|
||
rate = payslip.company_id.rsbu_injury_rate or 0.0
|
||
base = categories.RSBU_GROSS - SICK3
|
||
result = base * rate / 100.0
|
||
</field>
|
||
</record>
|
||
|
||
<!-- К выплате: начислено минус НДФЛ (НДФЛ отрицательный). -->
|
||
<record id="rsbu_rule_net" model="hr.salary.rule">
|
||
<field name="name">К выплате</field>
|
||
<field name="code">NET</field>
|
||
<field name="sequence" eval="200"/>
|
||
<field name="category_id" ref="rsbu_cat_net"/>
|
||
<field name="condition_select">none</field>
|
||
<field name="amount_select">code</field>
|
||
<field name="amount_python_compute">
|
||
result = categories.RSBU_GROSS + categories.RSBU_NDFL
|
||
</field>
|
||
</record>
|
||
|
||
</data>
|
||
</odoo>
|