Files
enterprise-addons/l10n_ch_hr_payroll/models/l10n_avs.py
T

208 lines
8.8 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, models, fields, _
from odoo.exceptions import UserError, ValidationError
import re
avs_code_pattern = r'^[0-9]{3}\.[0-9]{3}$'
class L10nChSocialInsurance(models.Model):
_name = 'l10n.ch.social.insurance'
_description = 'Swiss: Social Insurances (AVS, AC)'
@api.model
def _get_default_avs_line_ids(self):
vals = [
(0, 0, {
'date_from': fields.Date.today().replace(month=1, day=1),
'employer_rate': 5.3,
'employee_rate': 5.3,
'admin_fees': 1.2,
})
]
return vals
@api.model
def _get_default_ac_line_ids(self):
vals = [
(0, 0, {
'date_from': fields.Date.today().replace(month=1, day=1),
'employer_rate': 1.1,
'employee_rate': 1.1,
'employee_additional_rate': 0,
'employer_additional_rate': 0,
})
]
return vals
@api.model
def _get_default_l10n_ch_avs_rente_ids(self):
vals = [
(0, 0, {
'date_from': fields.Date.today().replace(month=1, day=1),
'amount': 1400
})
]
return vals
@api.model
def _get_default_l10n_ch_avs_ac_threshold_ids(self):
vals = [
(0, 0, {
'date_from': fields.Date.today().replace(month=1, day=1),
'amount': 148200
})
]
return vals
@api.model
def _get_default_l10n_ch_avs_acc_threshold_ids(self):
vals = [
(0, 0, {
'date_from': fields.Date.today().replace(month=1, day=1),
'amount': 0
})
]
return vals
name = fields.Char(required=True)
member_number = fields.Char()
member_subnumber = fields.Char()
# https://www.swissdec.ch/fileadmin/user_upload/_Datenempfaenger/Empfaengerliste.pdf
insurance_code = fields.Char(required=True)
avs_line_ids = fields.One2many('l10n.ch.social.insurance.avs.line', 'insurance_id', default=_get_default_avs_line_ids)
ac_line_ids = fields.One2many('l10n.ch.social.insurance.ac.line', 'insurance_id', default=_get_default_ac_line_ids)
l10n_ch_avs_rente_ids = fields.One2many('l10n.ch.social.insurance.avs.retirement.rente', 'insurance_id', default=_get_default_l10n_ch_avs_rente_ids)
l10n_ch_avs_ac_threshold_ids = fields.One2many('l10n.ch.social.insurance.avs.ac.threshold', 'insurance_id', default=_get_default_l10n_ch_avs_ac_threshold_ids)
l10n_ch_avs_acc_threshold_ids = fields.One2many('l10n.ch.social.insurance.avs.acc.threshold', 'insurance_id', default=_get_default_l10n_ch_avs_acc_threshold_ids)
age_start = fields.Integer(string="Start of the obligation to contribute to the AVS", default=18, required=True)
age_stop_male = fields.Integer(string="Start of retirement age for men", default=65, required=True)
age_stop_female = fields.Integer(string="Start of retirement age for women", default=64, required=True)
laa_insurance_id = fields.Many2one("l10n.ch.accident.insurance", string="Company LAA Insurance")
laa_insurance_from = fields.Date(string="LAA: Valid as of")
lpp_insurance_id = fields.Many2one("l10n.ch.lpp.insurance", string="Company LPP Insurance")
lpp_insurance_from = fields.Date(string="LPP: Valid as of")
active = fields.Boolean(default=True)
company_id = fields.Many2one("res.company", default=lambda self: self.env.company)
no_laa_reason = fields.Char(help="If your company doesn't have a main LAA insurance, state the reason here.")
no_lpp_reason = fields.Char(help="If your company doesn't have a main LPP insurance, state the reason here.")
@api.constrains('insurance_code')
def _check_insurance_code(self):
"""
Format XXX.XXX with the first bloc greater than 0
"""
for record in self:
if record.insurance_code:
if re.fullmatch(avs_code_pattern, record.insurance_code):
if record.insurance_code.split(".")[0] == "000":
raise ValidationError(_("AVS Insurance code is not plausible."))
else:
raise ValidationError(_("AVS Insurance code is not plausible."))
def _get_avs_rates(self, target):
if not self:
return 0, 0, 0
for line in self.avs_line_ids:
if line.date_from <= target and (not line.date_to or target <= line.date_to):
return line.employee_rate, line.employer_rate, line.admin_fees
raise UserError(_('No AVS rates found for date %s', target))
def _get_ac_rates(self, target):
if not self:
return 0, 0
for line in self.ac_line_ids:
if line.date_from <= target and (not line.date_to or target <= line.date_to):
return line.employee_rate, line.employer_rate
raise UserError(_('No AC rates found for date %s', target))
def _get_additional_ac_rates(self, target):
if not self:
return 0, 0
for line in self.ac_line_ids:
if line.date_from <= target and (not line.date_to or target <= line.date_to):
return line.employee_additional_rate, line.employer_additional_rate
raise UserError(_('No AC rates found for date %s', target))
def _get_retirement_rente(self, target):
if not self:
return 0.0
for line in self.l10n_ch_avs_rente_ids:
if line.date_from <= target and (not line.date_to or target <= line.date_to):
return line.amount
raise UserError(_('No retirement exoneration amounts found for date date %s', target))
def _get_ac_threshold(self, target):
if not self:
return 0.0
for line in self.l10n_ch_avs_ac_threshold_ids:
if line.date_from <= target and (not line.date_to or target <= line.date_to):
return line.amount
raise UserError(_('No AC threshold rates found for date %s', target))
def _get_acc_threshold(self, target):
if not self:
return 0.0
for line in self.l10n_ch_avs_acc_threshold_ids:
if line.date_from <= target and (not line.date_to or target <= line.date_to):
return line.amount
raise UserError(_('No ACC threshold rates found for date %s', target))
class L10nChSocialInsuranceAvsLine(models.Model):
_name = 'l10n.ch.social.insurance.avs.line'
_description = 'Swiss: Social Insurances - AVS Line'
date_from = fields.Date(string="From", required=True)
date_to = fields.Date(string="To")
insurance_id = fields.Many2one('l10n.ch.social.insurance')
employee_rate = fields.Float(string="Employee Rate (%)", digits='Payroll Rate', default=5.3)
employer_rate = fields.Float(string="Company Rate (%)", digits='Payroll Rate', default=5.3)
admin_fees = fields.Float(string="Administrative Costs (%)", digits='Payroll Rate', default=1.2)
class L10nChSocialInsuranceAcLine(models.Model):
_name = 'l10n.ch.social.insurance.ac.line'
_description = 'Swiss: Social Insurances - AC Line'
date_from = fields.Date(string="From", required=True)
date_to = fields.Date(string="To")
insurance_id = fields.Many2one('l10n.ch.social.insurance')
employee_rate = fields.Float(string="Employee Rate (%)", digits='Payroll Rate', default=1.1)
employer_rate = fields.Float(string="Company Rate (%)", digits='Payroll Rate', default=1.1)
employee_additional_rate = fields.Float(string="Employee Additional Rate (%)", digits='Payroll Rate', default=0)
employer_additional_rate = fields.Float(string="Company Additional Rate (%)", digits='Payroll Rate', default=0)
class L10nChSocialInsuranceAvsRetirementRente(models.Model):
_name = 'l10n.ch.social.insurance.avs.retirement.rente'
_description = 'Swiss: Retired Employees Exoneration'
date_from = fields.Date(string="From", required=True)
date_to = fields.Date(string="To")
insurance_id = fields.Many2one('l10n.ch.social.insurance')
amount = fields.Float(string="Amount", default=1400)
class L10nChSocialInsuranceAvsAcThreshold(models.Model):
_name = 'l10n.ch.social.insurance.avs.ac.threshold'
_description = 'Swiss: AC: Rate Threshold'
date_from = fields.Date(string="From", required=True)
date_to = fields.Date(string="To")
insurance_id = fields.Many2one('l10n.ch.social.insurance')
amount = fields.Float(string="Amount", default=148200)
class L10nChSocialInsuranceAvsAccThreshold(models.Model):
_name = 'l10n.ch.social.insurance.avs.acc.threshold'
_description = 'Swiss: ACC: Rate Threshold'
date_from = fields.Date(string="From", required=True)
date_to = fields.Date(string="To")
insurance_id = fields.Many2one('l10n.ch.social.insurance')
amount = fields.Float(string="Amount", default=370500)