Files
public/rsbu_fns_reporting/models/rsbu_pers_info.py

117 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""Персонифицированные сведения о физических лицах (ПСВ, КНД 1151162).
Форма ФНС NO_PERSSVFL версии 5.01. Подаётся ЕЖЕМЕСЯЧНО в налоговый орган:
по каждому застрахованному лицу — ФИО, СНИЛС, ИНН и сумма выплат за месяц.
Автозаполнение строк из помесячных итогов выплат rsbu.rsv.summary
(поле payments) за отчётный месяц.
"""
from odoo import api, fields, models
class RsbuPersInfo(models.Model):
_name = 'rsbu.pers.info'
_description = 'РСБУ — Персонифицированные сведения (ПСВ)'
_order = 'year desc, month desc, id desc'
_check_company_auto = True
name = fields.Char(string='Наименование', compute='_compute_name',
store=True)
company_id = fields.Many2one(
'res.company', string='Компания', required=True, index=True,
default=lambda self: self.env.company)
year = fields.Integer(string='Год', required=True,
default=lambda self: fields.Date.today().year)
month = fields.Integer(
string='Отчётный месяц', required=True,
default=lambda self: fields.Date.today().month,
help='Календарный месяц, за который подаются сведения.')
date_doc = fields.Date(
string='Дата документа', default=fields.Date.context_today)
currency_id = fields.Many2one(
'res.currency', related='company_id.currency_id')
state = fields.Selection(
selection=[('draft', 'Черновик'), ('computed', 'Рассчитано')],
default='draft', string='Состояние', copy=False)
line_ids = fields.One2many(
'rsbu.pers.info.line', 'report_id', string='Сведения по физлицам')
@api.depends('year', 'month')
def _compute_name(self):
names = ['', 'январь', 'февраль', 'март', 'апрель', 'май', 'июнь',
'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь']
for rec in self:
m = names[rec.month] if rec.month and 1 <= rec.month <= 12 else '?'
rec.name = 'Перс. сведения: %s %s' % (m, rec.year or '?')
def _month_bounds(self):
import calendar
self.ensure_one()
last = calendar.monthrange(self.year, self.month)[1]
return (fields.Date.to_date('%04d-%02d-01' % (self.year, self.month)),
fields.Date.to_date('%04d-%02d-%02d' % (
self.year, self.month, last)))
# ------------------------------------------------------------------
def action_compute(self):
"""Пересобрать итоги выплат за месяц и автозаполнить строки."""
Summary = self.env['rsbu.rsv.summary'].sudo()
for rec in self:
df, dt = rec._month_bounds()
Summary.recompute_period(df, dt, rec.company_id)
return self.fill_lines()
def fill_lines(self):
"""Автозаполнить строки по сотрудникам из итогов выплат за месяц.
Отделено от action_compute, чтобы заполнять по существующим данным
без принудительного пересбора (тесты, повторный расчёт).
"""
Summary = self.env['rsbu.rsv.summary'].sudo()
Line = self.env['rsbu.pers.info.line']
for rec in self:
rec.line_ids.unlink()
recs = Summary.search([
('company_id', '=', rec.company_id.id),
('year', '=', rec.year),
('month', '=', rec.month),
])
# Суммируем выплаты по сотруднику (на случай нескольких записей).
by_emp = {}
for r in recs:
by_emp.setdefault(r.employee_id, 0.0)
by_emp[r.employee_id] += r.payments
vals = []
for emp, pay in by_emp.items():
vals.append({
'report_id': rec.id,
'employee_id': emp.id,
'amount': round(pay, 2),
})
if vals:
Line.create(vals)
rec.state = 'computed'
return True
class RsbuPersInfoLine(models.Model):
_name = 'rsbu.pers.info.line'
_description = 'РСБУ — Строка ПСВ (физлицо)'
_order = 'report_id, employee_id'
report_id = fields.Many2one(
'rsbu.pers.info', string='Сведения', required=True,
ondelete='cascade', index=True)
currency_id = fields.Many2one(
'res.currency', related='report_id.currency_id')
employee_id = fields.Many2one('hr.employee', string='Сотрудник',
required=True)
snils = fields.Char(string='СНИЛС', related='employee_id.rsbu_snils')
inn = fields.Char(string='ИНН', related='employee_id.rsbu_inn')
amount = fields.Monetary(string='Сумма выплат',
currency_field='currency_id')
cancelled = fields.Boolean(
string='Аннулирующие сведения',
help='Признак аннулирования ранее поданных сведений (ПрАннулир).')