1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/l10n_ch_hr_payroll/models/hr_employee.py
2024-12-10 09:04:09 +07:00

183 lines
10 KiB
Python

# -*- coding:utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.exceptions import UserError
CANTONS = [
('AG', 'Argovie'),
('AI', 'Appenzell Rhodes-Intérieures'),
('AR', 'Appenzell Rhodes-Extérieures'),
('BE', 'Berne'),
('BL', 'Bâle-Campagne'),
('BS', 'Bâle-Ville'),
('FR', 'Fribourg'),
('GE', 'Genève'),
('GL', 'Glaris'),
('GR', 'Grisons'),
('JU', 'Jura'),
('LU', 'Lucerne'),
('NE', 'Neuchâtel'),
('NW', 'Nidwald'),
('OW', 'Obwald'),
('SG', 'Saint-Gall'),
('SH', 'Schaffhouse'),
('SO', 'Soleure'),
('SZ', 'Schwytz'),
('TG', 'Thurgovie'),
('TI', 'Tessin'),
('UR', 'Uri'),
('VD', 'Vaud'),
('VS', 'Valais'),
('ZG', 'Zoug'),
('ZH', 'Zurich'),
('EX', 'Foreign')
]
class HrEmployee(models.Model):
_inherit = 'hr.employee'
l10n_ch_canton = fields.Selection(selection=CANTONS, string="Canton", groups="hr.group_hr_user")
l10n_ch_tax_scale = fields.Selection([
('A', 'Scale for single people'),
('B', 'Scale for married couples living in a common household with only one spouse is gainfully employed'),
('C', 'Scale for married couples with two incomes'),
('D', 'Scale for people whose AVS contributions are reimbursed'),
('E', 'Scale for income taxed under the procedure of simplified count'),
('F', 'Scale for Italian cross-border commuters whose spouse is working lucrative outside Switzerland'),
('G', 'Scale for income acquired as compensation which is paid to persons subject to withholding tax by a person other than that the employer'),
('H', 'Scale for single people living together with children or needy persons whom they take on maintenance essentials'),
('L', 'Scale for German cross-border commuters who fulfill the conditions of the scale A'),
('M', 'Scale for German cross-border commuters who fulfill the conditions of the scale B'),
('N', 'Scale for German cross-border commuters who fulfill the conditions of the scale C'),
('P', 'Scale for German cross-border commuters who fulfill the conditions of the scale H'),
('Q', 'Scale for German cross-border commuters who fulfill the conditions of the scale G'),
('R', 'Scale for Italian cross-border commuters who fulfill the conditions of the scale A'),
('S', 'Scale for Italian cross-border commuters who fulfill the conditions of the scale B'),
('T', 'Scale for Italian cross-border commuters who fulfill the conditions of the scale C'),
('U', 'Scale for Italian cross-border commuters who fulfill the conditions of the scale H'),
], string="Swiss Tax Scale", groups="hr.group_hr_user")
l10n_ch_municipality = fields.Char(string="Municipality ID", groups="hr.group_hr_user")
l10n_ch_religious_denomination = fields.Selection([
('romanCatholic', 'Roman Catholic'),
('christianCatholic', 'Christian Catholic'),
('reformedEvangelical', 'Reformed Evangelical'),
('jewishCommunity', 'Jewish Community'),
('otherOrNone', 'Other or None'),
], default='otherOrNone', string="Religious Denomination", groups="hr.group_hr_user")
l10n_ch_church_tax = fields.Boolean(string="Swiss Church Tax", groups="hr.group_hr_user")
l10n_ch_sv_as_number = fields.Char(
string="SV-AS Number",
groups="hr.group_hr_user",
help="Thirteen-digit AS number assigned by the Central Compensation Office (CdC)")
marital = fields.Selection(
selection_add=[
("separated", "Separated"),
("registered_partnership", "Registered Partnership"),
("partnership_dissolved_by_law", "Partnership Dissolved By Law"),
("partnership_dissolved_by_death", "Partnership Dissolved By Law"),
("partnership_dissolved_by_declaration_of_lost", "Partnership Dissolved By Declaration of Lost"),
],
ondelete={
'separated': 'set default',
'registered_partnership': 'set default',
'partnership_dissolved_by_law': 'set default',
'partnership_dissolved_by_death': 'set default',
'partnership_dissolved_by_declaration_of_lost': 'set default',
}, required=True)
l10n_ch_marital_from = fields.Date(string="Marital Status Start Date", groups="hr.group_hr_user")
l10n_ch_spouse_sv_as_number = fields.Char(string="Spouse SV-AS-Number", groups="hr.group_hr_user")
l10n_ch_spouse_work_canton = fields.Selection(string="Spouse Work Canton", selection=CANTONS, groups="hr.group_hr_user")
l10n_ch_spouse_work_start_date = fields.Date(string="Spouse Work Start Date", groups="hr.group_hr_user")
l10n_ch_children = fields.One2many('l10n.ch.hr.employee.children', 'employee_id', groups="hr_payroll.group_hr_payroll_user")
l10n_ch_has_withholding_tax = fields.Boolean(
string="Pay Withholding Taxes", compute='_compute_l10n_ch_has_withholding_tax', store=True, readonly=False, groups="hr.group_hr_user")
l10n_ch_residence_category = fields.Selection([
('shortTerm-L', 'Short Term (Cat. L)'),
('annual-B', 'Annual (Cat. B)'),
('settled-C', 'Settled (Cat. C)'),
('crossBorder-G', 'Cross Border (Cat. G)'),
('asylumSeeker-N', 'Asylum Seeker (Cat. N)'),
('needForProtection-S', 'Need For Protection (Cat. S)'),
('NotificationProcedureForShorttermWork90Days', 'Notification Procedure for Short Term Work (90 days)'),
('NotificationProcedureForShorttermWork120Days', 'Notification Procedure for Short Term Work (120 days)'),
('ProvisionallyAdmittedForeigners-F', 'Provisionally Admitted Foreigners (Cat. F)'),
('ResidentForeignNationalWithGainfulEmployment-Ci', 'Residence Permit with Gainful Employment (Ci)'),
('othersNotSwiss', 'Other (Without Swiss)'),
], string="Residence Category", groups="hr.group_hr_user")
certificate = fields.Selection(selection_add=[
('universityMaster', 'Swiss: University College Master (university, ETH)'),
('universityBachelor', 'Swiss: University College Bachelor (university, ETH)'),
('higherEducationMaster', 'Swiss: University of Applied Sciences Master'),
('higherEducationBachelor', 'Swiss: University of Applied Sciences Bachelor'),
('higherVocEducation', 'Swiss: Higher Vocational Education'),
('higherVocEducationMaster', 'Swiss: Higher Vocational Education Master'),
('higherVocEducationBachelor', 'Swiss: Higher Vocational Education Bachelor'),
('teacherCertificate', 'Swiss: Teaching certificate at different levels'),
('universityEntranceCertificate', 'Swiss: Matura'),
('vocEducationCompl', 'Swiss: Complete learning attested by a federal certificate of capacity (CFC)'),
('enterpriseEducation', 'Swiss: In-company training only'),
('mandatorySchoolOnly', 'Swiss: Compulsory schooling, without full vocational training'),
('doctorate', 'Swiss: Doctorate, habilitation'),
], ondelete={
'universityMaster': 'set default',
'universityBachelor': 'set default',
'higherEducationMaster': 'set default',
'higherEducationBachelor': 'set default',
'higherVocEducation': 'set default',
'higherVocEducationMaster': 'set default',
'higherVocEducationBachelor': 'set default',
'teacherCertificate': 'set default',
'universityEntranceCertificate': 'set default',
'vocEducationCompl': 'set default',
'enterpriseEducation': 'set default',
'mandatorySchoolOnly': 'set default',
'doctorate': 'set default'
})
# YTI TO Display on res.users + check 13 digits
l10n_ch_retirement_insurance_number = fields.Char(
string="Retirement insurance number", groups="hr.group_hr_user",
help="The Central Compensation Office in Geneva assigns a retirement insurance (RI) number to all newborns and immigrants, which is valid for the rest of your life and remains the same even after a name change. Further information on the structure of the RI number can be found on theSwiss Federal Social Insurance Office website (in Germnan).")
@api.depends('is_non_resident')
def _compute_l10n_ch_has_withholding_tax(self):
for employee in self:
employee.l10n_ch_has_withholding_tax = employee.is_non_resident
def _get_l10n_ch_declaration_marital(self):
self.ensure_one()
mapped_marital = {
False: 'unknown',
'single': 'single',
'married': 'married',
'widower': 'widowed',
'divorced': 'divorced',
'separated': 'separated',
'registered_partnership': 'registeredPartnership',
'partnership_dissolved_by_law': 'partnershipDissolvedByLaw',
'partnership_dissolved_by_death': 'partnershipDissolvedByDeath',
'partnership_dissolved_by_declaration_of_lost': 'partnershipDissolvedByDeclarationOfLost',
}
if self.marital not in mapped_marital:
raise UserError(_('Invalid marital status for employee %s', self.name))
return mapped_marital[self.marital]
@api.constrains('l10n_ch_sv_as_number')
def _check_sv_as_number(self):
for employee in self:
if not employee.l10n_ch_sv_as_number:
continue
if not employee.l10n_ch_sv_as_number.replace('.', '').isdigit() or len(employee.l10n_ch_sv_as_number) != 16:
raise UserError(_('The SV-AS number should be a thirteen-digit number, comma-separated (eg: 756.1848.4786.64)'))
@api.constrains('l10n_ch_spouse_sv_as_number')
def _check_sv_as_number(self):
for employee in self:
if not employee.l10n_ch_spouse_sv_as_number:
continue
if not employee.l10n_ch_spouse_sv_as_number.replace('.', '').isdigit() or len(employee.l10n_ch_spouse_sv_as_number) != 16:
raise UserError(_('The SV-AS number should be a thirteen-digit number, comma-separated (eg: 756.1848.4786.64)'))