[MOV] hr_payroll: Split models and views into separate files
This commit is contained in:
@@ -30,12 +30,15 @@ Generic Payroll system.
|
||||
'security/hr_payroll_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/hr_payroll_payslips_by_employees_views.xml',
|
||||
'views/hr_payroll_views.xml',
|
||||
'views/hr_contract_views.xml',
|
||||
'views/hr_salary_rule_views.xml',
|
||||
'views/hr_payslip_views.xml',
|
||||
'views/hr_employee_views.xml',
|
||||
'data/hr_payroll_sequence.xml',
|
||||
'views/hr_payroll_report.xml',
|
||||
'data/hr_payroll_data.xml',
|
||||
'wizard/hr_payroll_contribution_register_report_views.xml',
|
||||
'views/res_config_views.xml',
|
||||
'views/hr_payroll_config_settings_views.xml',
|
||||
'views/report_contributionregister_templates.xml',
|
||||
'views/report_payslip_templates.xml',
|
||||
'views/report_payslipdetails_templates.xml',
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import hr_payroll
|
||||
import res_config
|
||||
import hr_contract
|
||||
import hr_employee
|
||||
import hr_payroll_config_settings
|
||||
import hr_salary_rule
|
||||
import hr_payslip
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class HrContract(models.Model):
|
||||
"""
|
||||
Employee contract based on the visa, work permits
|
||||
allows to configure different Salary structure
|
||||
"""
|
||||
_inherit = 'hr.contract'
|
||||
_description = 'Employee Contract'
|
||||
|
||||
struct_id = fields.Many2one('hr.payroll.structure', string='Salary Structure')
|
||||
schedule_pay = fields.Selection([
|
||||
('monthly', 'Monthly'),
|
||||
('quarterly', 'Quarterly'),
|
||||
('semi-annually', 'Semi-annually'),
|
||||
('annually', 'Annually'),
|
||||
('weekly', 'Weekly'),
|
||||
('bi-weekly', 'Bi-weekly'),
|
||||
('bi-monthly', 'Bi-monthly'),
|
||||
], string='Scheduled Pay', index=True, default='monthly')
|
||||
resource_calendar_id = fields.Many2one(required=True)
|
||||
|
||||
@api.multi
|
||||
def get_all_structures(self):
|
||||
"""
|
||||
@return: the structures linked to the given contracts, ordered by hierachy (parent=False first,
|
||||
then first level children and so on) and without duplicata
|
||||
"""
|
||||
structures = self.mapped('struct_id')
|
||||
if not structures:
|
||||
return []
|
||||
# YTI TODO return browse records
|
||||
return list(set(structures._get_parent_structure().ids))
|
||||
|
||||
@api.multi
|
||||
def get_attribute(self, code, attribute):
|
||||
return getattr(self.env['hr.contract.advantage.template'].search([('code', '=', code)], limit=1), attribute)
|
||||
|
||||
|
||||
class HrContractAdvandageTemplate(models.Model):
|
||||
_name = 'hr.contract.advantage.template'
|
||||
_description = "Employee's Advantage on Contract"
|
||||
|
||||
name = fields.Char('Name', required=True)
|
||||
code = fields.Char('Code', required=True)
|
||||
lower_bound = fields.Float('Lower Bound', help="Lower bound authorized by the employer for this advantage")
|
||||
upper_bound = fields.Float('Upper Bound', help="Upper bound authorized by the employer for this advantage")
|
||||
default_value = fields.Float('Default value for this advantage')
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class HrEmployee(models.Model):
|
||||
_inherit = 'hr.employee'
|
||||
_description = 'Employee'
|
||||
|
||||
slip_ids = fields.One2many('hr.payslip', 'employee_id', string='Payslips', readonly=True)
|
||||
payslip_count = fields.Integer(compute='_compute_payslip_count', string='Payslips', groups="hr_payroll.group_hr_payroll_user")
|
||||
|
||||
@api.multi
|
||||
def _compute_payslip_count(self):
|
||||
for employee in self:
|
||||
employee.payslip_count = len(employee.slip_ids)
|
||||
@@ -2,172 +2,15 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from datetime import time as datetime_time
|
||||
from dateutil import relativedelta
|
||||
|
||||
import babel
|
||||
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
|
||||
class HrPayrollStructure(models.Model):
|
||||
"""
|
||||
Salary structure used to defined
|
||||
- Basic
|
||||
- Allowances
|
||||
- Deductions
|
||||
"""
|
||||
_name = 'hr.payroll.structure'
|
||||
_description = 'Salary Structure'
|
||||
|
||||
@api.model
|
||||
def _get_parent(self):
|
||||
return self.env.ref('hr_payroll.structure_base', False)
|
||||
|
||||
name = fields.Char(required=True)
|
||||
code = fields.Char(string='Reference', required=True)
|
||||
company_id = fields.Many2one('res.company', string='Company', required=True,
|
||||
copy=False, default=lambda self: self.env['res.company']._company_default_get())
|
||||
note = fields.Text(string='Description')
|
||||
parent_id = fields.Many2one('hr.payroll.structure', string='Parent', default=_get_parent)
|
||||
children_ids = fields.One2many('hr.payroll.structure', 'parent_id', string='Children', copy=True)
|
||||
rule_ids = fields.Many2many('hr.salary.rule', 'hr_structure_salary_rule_rel', 'struct_id', 'rule_id', string='Salary Rules')
|
||||
|
||||
@api.constrains('parent_id')
|
||||
def _check_parent_id(self):
|
||||
if not self._check_recursion():
|
||||
raise ValidationError(_('Error ! You cannot create a recursive Salary Structure.'))
|
||||
|
||||
@api.multi
|
||||
def copy(self, default=None):
|
||||
self.ensure_one()
|
||||
default = dict(default or {}, code=_("%s (copy)") % (self.code))
|
||||
return super(HrPayrollStructure, self).copy(default)
|
||||
|
||||
@api.multi
|
||||
def get_all_rules(self):
|
||||
"""
|
||||
@return: returns a list of tuple (id, sequence) of rules that are maybe to apply
|
||||
"""
|
||||
all_rules = []
|
||||
for struct in self:
|
||||
all_rules += struct.rule_ids._recursive_search_of_rules()
|
||||
return all_rules
|
||||
|
||||
@api.multi
|
||||
def _get_parent_structure(self):
|
||||
parent = self.mapped('parent_id')
|
||||
if parent:
|
||||
parent = parent._get_parent_structure()
|
||||
return parent + self
|
||||
|
||||
|
||||
class HrContract(models.Model):
|
||||
"""
|
||||
Employee contract based on the visa, work permits
|
||||
allows to configure different Salary structure
|
||||
"""
|
||||
_inherit = 'hr.contract'
|
||||
_description = 'Employee Contract'
|
||||
|
||||
struct_id = fields.Many2one('hr.payroll.structure', string='Salary Structure')
|
||||
schedule_pay = fields.Selection([
|
||||
('monthly', 'Monthly'),
|
||||
('quarterly', 'Quarterly'),
|
||||
('semi-annually', 'Semi-annually'),
|
||||
('annually', 'Annually'),
|
||||
('weekly', 'Weekly'),
|
||||
('bi-weekly', 'Bi-weekly'),
|
||||
('bi-monthly', 'Bi-monthly'),
|
||||
], string='Scheduled Pay', index=True, default='monthly')
|
||||
resource_calendar_id = fields.Many2one(required=True)
|
||||
|
||||
@api.multi
|
||||
def get_all_structures(self):
|
||||
"""
|
||||
@return: the structures linked to the given contracts, ordered by hierachy (parent=False first,
|
||||
then first level children and so on) and without duplicata
|
||||
"""
|
||||
structures = self.mapped('struct_id')
|
||||
if not structures:
|
||||
return []
|
||||
# YTI TODO return browse records
|
||||
return list(set(structures._get_parent_structure().ids))
|
||||
|
||||
@api.multi
|
||||
def get_attribute(self, code, attribute):
|
||||
return getattr(self.env['hr.contract.advantage.template'].search([('code', '=', code)], limit=1), attribute)
|
||||
|
||||
|
||||
class HrContractAdvandageTemplate(models.Model):
|
||||
_name = 'hr.contract.advantage.template'
|
||||
_description = "Employee's Advantage on Contract"
|
||||
|
||||
name = fields.Char('Name', required=True)
|
||||
code = fields.Char('Code', required=True)
|
||||
lower_bound = fields.Float('Lower Bound', help="Lower bound authorized by the employer for this advantage")
|
||||
upper_bound = fields.Float('Upper Bound', help="Upper bound authorized by the employer for this advantage")
|
||||
default_value = fields.Float('Default value for this advantage')
|
||||
|
||||
class HrContributionRegister(models.Model):
|
||||
_name = 'hr.contribution.register'
|
||||
_description = 'Contribution Register'
|
||||
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
default=lambda self: self.env['res.company']._company_default_get())
|
||||
partner_id = fields.Many2one('res.partner', string='Partner')
|
||||
name = fields.Char(required=True)
|
||||
register_line_ids = fields.One2many('hr.payslip.line', 'register_id',
|
||||
string='Register Line', readonly=True)
|
||||
note = fields.Text(string='Description')
|
||||
|
||||
|
||||
class HrSalaryRuleCategory(models.Model):
|
||||
_name = 'hr.salary.rule.category'
|
||||
_description = 'Salary Rule Category'
|
||||
|
||||
name = fields.Char(required=True)
|
||||
code = fields.Char(required=True)
|
||||
parent_id = fields.Many2one('hr.salary.rule.category', string='Parent',
|
||||
help="Linking a salary category to its parent is used only for the reporting purpose.")
|
||||
children_ids = fields.One2many('hr.salary.rule.category', 'parent_id', string='Children')
|
||||
note = fields.Text(string='Description')
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
default=lambda self: self.env['res.company']._company_default_get())
|
||||
|
||||
|
||||
class HrPayslipRun(models.Model):
|
||||
_name = 'hr.payslip.run'
|
||||
_description = 'Payslip Batches'
|
||||
|
||||
name = fields.Char(required=True, readonly=True, states={'draft': [('readonly', False)]})
|
||||
slip_ids = fields.One2many('hr.payslip', 'payslip_run_id', string='Payslips', readonly=True,
|
||||
states={'draft': [('readonly', False)]})
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('close', 'Close'),
|
||||
], string='Status', index=True, readonly=True, copy=False, default='draft')
|
||||
date_start = fields.Date(string='Date From', required=True, readonly=True,
|
||||
states={'draft': [('readonly', False)]}, default=time.strftime('%Y-%m-01'))
|
||||
date_end = fields.Date(string='Date To', required=True, readonly=True,
|
||||
states={'draft': [('readonly', False)]},
|
||||
default=str(datetime.now() + relativedelta.relativedelta(months=+1, day=1, days=-1))[:10])
|
||||
credit_note = fields.Boolean(string='Credit Note', readonly=True,
|
||||
states={'draft': [('readonly', False)]},
|
||||
help="If its checked, indicates that all payslips generated from here are refund payslips.")
|
||||
|
||||
@api.multi
|
||||
def draft_payslip_run(self):
|
||||
return self.write({'state': 'draft'})
|
||||
|
||||
@api.multi
|
||||
def close_payslip_run(self):
|
||||
return self.write({'state': 'close'})
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class HrPayslip(models.Model):
|
||||
@@ -286,7 +129,7 @@ class HrPayslip(models.Model):
|
||||
raise UserError(_('You cannot delete a payslip which is not draft or cancelled!'))
|
||||
return super(HrPayslip, self).unlink()
|
||||
|
||||
#TODO move this function into hr_contract module, on hr.employee object
|
||||
# TODO move this function into hr_contract module, on hr.employee object
|
||||
@api.model
|
||||
def get_contract(self, employee, date_from, date_to):
|
||||
"""
|
||||
@@ -295,11 +138,11 @@ class HrPayslip(models.Model):
|
||||
@param date_to: date field
|
||||
@return: returns the ids of all the contracts for the given employee that need to be considered for the given dates
|
||||
"""
|
||||
#a contract is valid if it ends between the given dates
|
||||
# a contract is valid if it ends between the given dates
|
||||
clause_1 = ['&', ('date_end', '<=', date_to), ('date_end', '>=', date_from)]
|
||||
#OR if it starts between the given dates
|
||||
# OR if it starts between the given dates
|
||||
clause_2 = ['&', ('date_start', '<=', date_to), ('date_start', '>=', date_from)]
|
||||
#OR if it starts before the date_from and finish after the date_end (or never finish)
|
||||
# OR if it starts before the date_from and finish after the date_end (or never finish)
|
||||
clause_3 = ['&', ('date_start', '<=', date_from), '|', ('date_end', '=', False), ('date_end', '>=', date_to)]
|
||||
clause_final = [('employee_id', '=', employee.id), ('state', '=', 'open'), '|', '|'] + clause_1 + clause_2 + clause_3
|
||||
return self.env['hr.contract'].search(clause_final).ids
|
||||
@@ -308,7 +151,7 @@ class HrPayslip(models.Model):
|
||||
def compute_sheet(self):
|
||||
for payslip in self:
|
||||
number = payslip.number or self.env['ir.sequence'].next_by_code('salary.slip')
|
||||
#delete old payslip lines
|
||||
# delete old payslip lines
|
||||
payslip.line_ids.unlink()
|
||||
# set the list of contract for which the rules have to be applied
|
||||
# if we don't give the contract, then the rules to apply should be for all current contracts of the employee
|
||||
@@ -642,186 +485,6 @@ class HrPayslip(models.Model):
|
||||
else:
|
||||
return 0.0
|
||||
|
||||
class HrPayslipWorkedDays(models.Model):
|
||||
_name = 'hr.payslip.worked_days'
|
||||
_description = 'Payslip Worked Days'
|
||||
_order = 'payslip_id, sequence'
|
||||
|
||||
name = fields.Char(string='Description', required=True)
|
||||
payslip_id = fields.Many2one('hr.payslip', string='Pay Slip', required=True, ondelete='cascade', index=True)
|
||||
sequence = fields.Integer(required=True, index=True, default=10)
|
||||
code = fields.Char(required=True, help="The code that can be used in the salary rules")
|
||||
number_of_days = fields.Float(string='Number of Days')
|
||||
number_of_hours = fields.Float(string='Number of Hours')
|
||||
contract_id = fields.Many2one('hr.contract', string='Contract', required=True,
|
||||
help="The contract for which applied this input")
|
||||
|
||||
|
||||
class HrPayslipInput(models.Model):
|
||||
_name = 'hr.payslip.input'
|
||||
_description = 'Payslip Input'
|
||||
_order = 'payslip_id, sequence'
|
||||
|
||||
name = fields.Char(string='Description', required=True)
|
||||
payslip_id = fields.Many2one('hr.payslip', string='Pay Slip', required=True, ondelete='cascade', index=True)
|
||||
sequence = fields.Integer(required=True, index=True, default=10)
|
||||
code = fields.Char(required=True, help="The code that can be used in the salary rules")
|
||||
amount = fields.Float(help="It is used in computation. For e.g. A rule for sales having "
|
||||
"1% commission of basic salary for per product can defined in expression "
|
||||
"like result = inputs.SALEURO.amount * contract.wage*0.01.")
|
||||
contract_id = fields.Many2one('hr.contract', string='Contract', required=True,
|
||||
help="The contract for which applied this input")
|
||||
|
||||
|
||||
class HrSalaryRule(models.Model):
|
||||
_name = 'hr.salary.rule'
|
||||
|
||||
name = fields.Char(required=True)
|
||||
code = fields.Char(required=True,
|
||||
help="The code of salary rules can be used as reference in computation of other rules. "
|
||||
"In that case, it is case sensitive.")
|
||||
sequence = fields.Integer(required=True, index=True, default=5,
|
||||
help='Use to arrange calculation sequence')
|
||||
quantity = fields.Char(default='1.0',
|
||||
help="It is used in computation for percentage and fixed amount. "
|
||||
"For e.g. A rule for Meal Voucher having fixed amount of "
|
||||
u"1€ per worked day can have its quantity defined in expression "
|
||||
"like worked_days.WORK100.number_of_days.")
|
||||
category_id = fields.Many2one('hr.salary.rule.category', string='Category', required=True)
|
||||
active = fields.Boolean(default=True,
|
||||
help="If the active field is set to false, it will allow you to hide the salary rule without removing it.")
|
||||
appears_on_payslip = fields.Boolean(string='Appears on Payslip', default=True,
|
||||
help="Used to display the salary rule on payslip.")
|
||||
parent_rule_id = fields.Many2one('hr.salary.rule', string='Parent Salary Rule', index=True)
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
default=lambda self: self.env['res.company']._company_default_get())
|
||||
condition_select = fields.Selection([
|
||||
('none', 'Always True'),
|
||||
('range', 'Range'),
|
||||
('python', 'Python Expression')
|
||||
], string="Condition Based on", default='none', required=True)
|
||||
condition_range = fields.Char(string='Range Based on', default='contract.wage',
|
||||
help='This will be used to compute the % fields values; in general it is on basic, '
|
||||
'but you can also use categories code fields in lowercase as a variable names '
|
||||
'(hra, ma, lta, etc.) and the variable basic.')
|
||||
condition_python = fields.Text(string='Python Condition', required=True,
|
||||
default='''
|
||||
# Available variables:
|
||||
#----------------------
|
||||
# payslip: object containing the payslips
|
||||
# employee: hr.employee object
|
||||
# contract: hr.contract object
|
||||
# rules: object containing the rules code (previously computed)
|
||||
# categories: object containing the computed salary rule categories (sum of amount of all rules belonging to that category).
|
||||
# worked_days: object containing the computed worked days
|
||||
# inputs: object containing the computed inputs
|
||||
|
||||
# Note: returned value have to be set in the variable 'result'
|
||||
|
||||
result = rules.NET > categories.NET * 0.10''',
|
||||
help='Applied this rule for calculation if condition is true. You can specify condition like basic > 1000.')
|
||||
condition_range_min = fields.Float(string='Minimum Range', help="The minimum amount, applied for this rule.")
|
||||
condition_range_max = fields.Float(string='Maximum Range', help="The maximum amount, applied for this rule.")
|
||||
amount_select = fields.Selection([
|
||||
('percentage', 'Percentage (%)'),
|
||||
('fix', 'Fixed Amount'),
|
||||
('code', 'Python Code'),
|
||||
], string='Amount Type', index=True, required=True, default='fix', help="The computation method for the rule amount.")
|
||||
amount_fix = fields.Float(string='Fixed Amount', digits=dp.get_precision('Payroll'))
|
||||
amount_percentage = fields.Float(string='Percentage (%)', digits=dp.get_precision('Payroll Rate'),
|
||||
help='For example, enter 50.0 to apply a percentage of 50%')
|
||||
amount_python_compute = fields.Text(string='Python Code',
|
||||
default='''
|
||||
# Available variables:
|
||||
#----------------------
|
||||
# payslip: object containing the payslips
|
||||
# employee: hr.employee object
|
||||
# contract: hr.contract object
|
||||
# rules: object containing the rules code (previously computed)
|
||||
# categories: object containing the computed salary rule categories (sum of amount of all rules belonging to that category).
|
||||
# worked_days: object containing the computed worked days.
|
||||
# inputs: object containing the computed inputs.
|
||||
|
||||
# Note: returned value have to be set in the variable 'result'
|
||||
|
||||
result = contract.wage * 0.10''')
|
||||
amount_percentage_base = fields.Char(string='Percentage based on', help='result will be affected to a variable')
|
||||
child_ids = fields.One2many('hr.salary.rule', 'parent_rule_id', string='Child Salary Rule', copy=True)
|
||||
register_id = fields.Many2one('hr.contribution.register', string='Contribution Register',
|
||||
help="Eventual third party involved in the salary payment of the employees.")
|
||||
input_ids = fields.One2many('hr.rule.input', 'input_id', string='Inputs', copy=True)
|
||||
note = fields.Text(string='Description')
|
||||
|
||||
@api.multi
|
||||
def _recursive_search_of_rules(self):
|
||||
"""
|
||||
@return: returns a list of tuple (id, sequence) which are all the children of the passed rule_ids
|
||||
"""
|
||||
children_rules = []
|
||||
for rule in self.filtered(lambda rule: rule.child_ids):
|
||||
children_rules += rule.child_ids._recursive_search_of_rules()
|
||||
return [(rule.id, rule.sequence) for rule in self] + children_rules
|
||||
|
||||
#TODO should add some checks on the type of result (should be float)
|
||||
@api.multi
|
||||
def compute_rule(self, localdict):
|
||||
"""
|
||||
:param localdict: dictionary containing the environement in which to compute the rule
|
||||
:return: returns a tuple build as the base/amount computed, the quantity and the rate
|
||||
:rtype: (float, float, float)
|
||||
"""
|
||||
self.ensure_one()
|
||||
if self.amount_select == 'fix':
|
||||
try:
|
||||
return self.amount_fix, float(safe_eval(self.quantity, localdict)), 100.0
|
||||
except:
|
||||
raise UserError(_('Wrong quantity defined for salary rule %s (%s).') % (self.name, self.code))
|
||||
elif self.amount_select == 'percentage':
|
||||
try:
|
||||
return (float(safe_eval(self.amount_percentage_base, localdict)),
|
||||
float(safe_eval(self.quantity, localdict)),
|
||||
self.amount_percentage)
|
||||
except:
|
||||
raise UserError(_('Wrong percentage base or quantity defined for salary rule %s (%s).') % (self.name, self.code))
|
||||
else:
|
||||
try:
|
||||
safe_eval(self.amount_python_compute, localdict, mode='exec', nocopy=True)
|
||||
return float(localdict['result']), 'result_qty' in localdict and localdict['result_qty'] or 1.0, 'result_rate' in localdict and localdict['result_rate'] or 100.0
|
||||
except:
|
||||
raise UserError(_('Wrong python code defined for salary rule %s (%s).') % (self.name, self.code))
|
||||
|
||||
@api.multi
|
||||
def satisfy_condition(self, localdict):
|
||||
"""
|
||||
@param contract_id: id of hr.contract to be tested
|
||||
@return: returns True if the given rule match the condition for the given contract. Return False otherwise.
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
if self.condition_select == 'none':
|
||||
return True
|
||||
elif self.condition_select == 'range':
|
||||
try:
|
||||
result = safe_eval(self.condition_range, localdict)
|
||||
return self.condition_range_min <= result and result <= self.condition_range_max or False
|
||||
except:
|
||||
raise UserError(_('Wrong range condition defined for salary rule %s (%s).') % (self.name, self.code))
|
||||
else: # python code
|
||||
try:
|
||||
safe_eval(self.condition_python, localdict, mode='exec', nocopy=True)
|
||||
return 'result' in localdict and localdict['result'] or False
|
||||
except:
|
||||
raise UserError(_('Wrong python condition defined for salary rule %s (%s).') % (self.name, self.code))
|
||||
|
||||
|
||||
class HrRuleInput(models.Model):
|
||||
_name = 'hr.rule.input'
|
||||
_description = 'Salary Rule Input'
|
||||
|
||||
name = fields.Char(string='Description', required=True)
|
||||
code = fields.Char(required=True, help="The code that can be used in the salary rules")
|
||||
input_id = fields.Many2one('hr.salary.rule', string='Salary Rule Input', required=True)
|
||||
|
||||
|
||||
class HrPayslipLine(models.Model):
|
||||
_name = 'hr.payslip.line'
|
||||
@@ -853,14 +516,62 @@ class HrPayslipLine(models.Model):
|
||||
raise UserError(_('You must set a contract to create a payslip line.'))
|
||||
return super(HrPayslipLine, self).create(values)
|
||||
|
||||
class HrEmployee(models.Model):
|
||||
_inherit = 'hr.employee'
|
||||
_description = 'Employee'
|
||||
|
||||
slip_ids = fields.One2many('hr.payslip', 'employee_id', string='Payslips', readonly=True)
|
||||
payslip_count = fields.Integer(compute='_compute_payslip_count', string='Payslips', groups="hr_payroll.group_hr_payroll_user")
|
||||
class HrPayslipWorkedDays(models.Model):
|
||||
_name = 'hr.payslip.worked_days'
|
||||
_description = 'Payslip Worked Days'
|
||||
_order = 'payslip_id, sequence'
|
||||
|
||||
name = fields.Char(string='Description', required=True)
|
||||
payslip_id = fields.Many2one('hr.payslip', string='Pay Slip', required=True, ondelete='cascade', index=True)
|
||||
sequence = fields.Integer(required=True, index=True, default=10)
|
||||
code = fields.Char(required=True, help="The code that can be used in the salary rules")
|
||||
number_of_days = fields.Float(string='Number of Days')
|
||||
number_of_hours = fields.Float(string='Number of Hours')
|
||||
contract_id = fields.Many2one('hr.contract', string='Contract', required=True,
|
||||
help="The contract for which applied this input")
|
||||
|
||||
|
||||
class HrPayslipInput(models.Model):
|
||||
_name = 'hr.payslip.input'
|
||||
_description = 'Payslip Input'
|
||||
_order = 'payslip_id, sequence'
|
||||
|
||||
name = fields.Char(string='Description', required=True)
|
||||
payslip_id = fields.Many2one('hr.payslip', string='Pay Slip', required=True, ondelete='cascade', index=True)
|
||||
sequence = fields.Integer(required=True, index=True, default=10)
|
||||
code = fields.Char(required=True, help="The code that can be used in the salary rules")
|
||||
amount = fields.Float(help="It is used in computation. For e.g. A rule for sales having "
|
||||
"1% commission of basic salary for per product can defined in expression "
|
||||
"like result = inputs.SALEURO.amount * contract.wage*0.01.")
|
||||
contract_id = fields.Many2one('hr.contract', string='Contract', required=True,
|
||||
help="The contract for which applied this input")
|
||||
|
||||
|
||||
class HrPayslipRun(models.Model):
|
||||
_name = 'hr.payslip.run'
|
||||
_description = 'Payslip Batches'
|
||||
|
||||
name = fields.Char(required=True, readonly=True, states={'draft': [('readonly', False)]})
|
||||
slip_ids = fields.One2many('hr.payslip', 'payslip_run_id', string='Payslips', readonly=True,
|
||||
states={'draft': [('readonly', False)]})
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('close', 'Close'),
|
||||
], string='Status', index=True, readonly=True, copy=False, default='draft')
|
||||
date_start = fields.Date(string='Date From', required=True, readonly=True,
|
||||
states={'draft': [('readonly', False)]}, default=time.strftime('%Y-%m-01'))
|
||||
date_end = fields.Date(string='Date To', required=True, readonly=True,
|
||||
states={'draft': [('readonly', False)]},
|
||||
default=str(datetime.now() + relativedelta.relativedelta(months=+1, day=1, days=-1))[:10])
|
||||
credit_note = fields.Boolean(string='Credit Note', readonly=True,
|
||||
states={'draft': [('readonly', False)]},
|
||||
help="If its checked, indicates that all payslips generated from here are refund payslips.")
|
||||
|
||||
@api.multi
|
||||
def _compute_payslip_count(self):
|
||||
for employee in self:
|
||||
employee.payslip_count = len(employee.slip_ids)
|
||||
def draft_payslip_run(self):
|
||||
return self.write({'state': 'draft'})
|
||||
|
||||
@api.multi
|
||||
def close_payslip_run(self):
|
||||
return self.write({'state': 'close'})
|
||||
@@ -0,0 +1,236 @@
|
||||
# -*- 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
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
class HrPayrollStructure(models.Model):
|
||||
"""
|
||||
Salary structure used to defined
|
||||
- Basic
|
||||
- Allowances
|
||||
- Deductions
|
||||
"""
|
||||
_name = 'hr.payroll.structure'
|
||||
_description = 'Salary Structure'
|
||||
|
||||
@api.model
|
||||
def _get_parent(self):
|
||||
return self.env.ref('hr_payroll.structure_base', False)
|
||||
|
||||
name = fields.Char(required=True)
|
||||
code = fields.Char(string='Reference', required=True)
|
||||
company_id = fields.Many2one('res.company', string='Company', required=True,
|
||||
copy=False, default=lambda self: self.env['res.company']._company_default_get())
|
||||
note = fields.Text(string='Description')
|
||||
parent_id = fields.Many2one('hr.payroll.structure', string='Parent', default=_get_parent)
|
||||
children_ids = fields.One2many('hr.payroll.structure', 'parent_id', string='Children', copy=True)
|
||||
rule_ids = fields.Many2many('hr.salary.rule', 'hr_structure_salary_rule_rel', 'struct_id', 'rule_id', string='Salary Rules')
|
||||
|
||||
@api.constrains('parent_id')
|
||||
def _check_parent_id(self):
|
||||
if not self._check_recursion():
|
||||
raise ValidationError(_('Error ! You cannot create a recursive Salary Structure.'))
|
||||
|
||||
@api.multi
|
||||
def copy(self, default=None):
|
||||
self.ensure_one()
|
||||
default = dict(default or {}, code=_("%s (copy)") % (self.code))
|
||||
return super(HrPayrollStructure, self).copy(default)
|
||||
|
||||
@api.multi
|
||||
def get_all_rules(self):
|
||||
"""
|
||||
@return: returns a list of tuple (id, sequence) of rules that are maybe to apply
|
||||
"""
|
||||
all_rules = []
|
||||
for struct in self:
|
||||
all_rules += struct.rule_ids._recursive_search_of_rules()
|
||||
return all_rules
|
||||
|
||||
@api.multi
|
||||
def _get_parent_structure(self):
|
||||
parent = self.mapped('parent_id')
|
||||
if parent:
|
||||
parent = parent._get_parent_structure()
|
||||
return parent + self
|
||||
|
||||
|
||||
class HrContributionRegister(models.Model):
|
||||
_name = 'hr.contribution.register'
|
||||
_description = 'Contribution Register'
|
||||
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
default=lambda self: self.env['res.company']._company_default_get())
|
||||
partner_id = fields.Many2one('res.partner', string='Partner')
|
||||
name = fields.Char(required=True)
|
||||
register_line_ids = fields.One2many('hr.payslip.line', 'register_id',
|
||||
string='Register Line', readonly=True)
|
||||
note = fields.Text(string='Description')
|
||||
|
||||
|
||||
class HrSalaryRuleCategory(models.Model):
|
||||
_name = 'hr.salary.rule.category'
|
||||
_description = 'Salary Rule Category'
|
||||
|
||||
name = fields.Char(required=True)
|
||||
code = fields.Char(required=True)
|
||||
parent_id = fields.Many2one('hr.salary.rule.category', string='Parent',
|
||||
help="Linking a salary category to its parent is used only for the reporting purpose.")
|
||||
children_ids = fields.One2many('hr.salary.rule.category', 'parent_id', string='Children')
|
||||
note = fields.Text(string='Description')
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
default=lambda self: self.env['res.company']._company_default_get())
|
||||
|
||||
|
||||
class HrSalaryRule(models.Model):
|
||||
_name = 'hr.salary.rule'
|
||||
|
||||
name = fields.Char(required=True)
|
||||
code = fields.Char(required=True,
|
||||
help="The code of salary rules can be used as reference in computation of other rules. "
|
||||
"In that case, it is case sensitive.")
|
||||
sequence = fields.Integer(required=True, index=True, default=5,
|
||||
help='Use to arrange calculation sequence')
|
||||
quantity = fields.Char(default='1.0',
|
||||
help="It is used in computation for percentage and fixed amount. "
|
||||
"For e.g. A rule for Meal Voucher having fixed amount of "
|
||||
u"1€ per worked day can have its quantity defined in expression "
|
||||
"like worked_days.WORK100.number_of_days.")
|
||||
category_id = fields.Many2one('hr.salary.rule.category', string='Category', required=True)
|
||||
active = fields.Boolean(default=True,
|
||||
help="If the active field is set to false, it will allow you to hide the salary rule without removing it.")
|
||||
appears_on_payslip = fields.Boolean(string='Appears on Payslip', default=True,
|
||||
help="Used to display the salary rule on payslip.")
|
||||
parent_rule_id = fields.Many2one('hr.salary.rule', string='Parent Salary Rule', index=True)
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
default=lambda self: self.env['res.company']._company_default_get())
|
||||
condition_select = fields.Selection([
|
||||
('none', 'Always True'),
|
||||
('range', 'Range'),
|
||||
('python', 'Python Expression')
|
||||
], string="Condition Based on", default='none', required=True)
|
||||
condition_range = fields.Char(string='Range Based on', default='contract.wage',
|
||||
help='This will be used to compute the % fields values; in general it is on basic, '
|
||||
'but you can also use categories code fields in lowercase as a variable names '
|
||||
'(hra, ma, lta, etc.) and the variable basic.')
|
||||
condition_python = fields.Text(string='Python Condition', required=True,
|
||||
default='''
|
||||
# Available variables:
|
||||
#----------------------
|
||||
# payslip: object containing the payslips
|
||||
# employee: hr.employee object
|
||||
# contract: hr.contract object
|
||||
# rules: object containing the rules code (previously computed)
|
||||
# categories: object containing the computed salary rule categories (sum of amount of all rules belonging to that category).
|
||||
# worked_days: object containing the computed worked days
|
||||
# inputs: object containing the computed inputs
|
||||
|
||||
# Note: returned value have to be set in the variable 'result'
|
||||
|
||||
result = rules.NET > categories.NET * 0.10''',
|
||||
help='Applied this rule for calculation if condition is true. You can specify condition like basic > 1000.')
|
||||
condition_range_min = fields.Float(string='Minimum Range', help="The minimum amount, applied for this rule.")
|
||||
condition_range_max = fields.Float(string='Maximum Range', help="The maximum amount, applied for this rule.")
|
||||
amount_select = fields.Selection([
|
||||
('percentage', 'Percentage (%)'),
|
||||
('fix', 'Fixed Amount'),
|
||||
('code', 'Python Code'),
|
||||
], string='Amount Type', index=True, required=True, default='fix', help="The computation method for the rule amount.")
|
||||
amount_fix = fields.Float(string='Fixed Amount', digits=dp.get_precision('Payroll'))
|
||||
amount_percentage = fields.Float(string='Percentage (%)', digits=dp.get_precision('Payroll Rate'),
|
||||
help='For example, enter 50.0 to apply a percentage of 50%')
|
||||
amount_python_compute = fields.Text(string='Python Code',
|
||||
default='''
|
||||
# Available variables:
|
||||
#----------------------
|
||||
# payslip: object containing the payslips
|
||||
# employee: hr.employee object
|
||||
# contract: hr.contract object
|
||||
# rules: object containing the rules code (previously computed)
|
||||
# categories: object containing the computed salary rule categories (sum of amount of all rules belonging to that category).
|
||||
# worked_days: object containing the computed worked days.
|
||||
# inputs: object containing the computed inputs.
|
||||
|
||||
# Note: returned value have to be set in the variable 'result'
|
||||
|
||||
result = contract.wage * 0.10''')
|
||||
amount_percentage_base = fields.Char(string='Percentage based on', help='result will be affected to a variable')
|
||||
child_ids = fields.One2many('hr.salary.rule', 'parent_rule_id', string='Child Salary Rule', copy=True)
|
||||
register_id = fields.Many2one('hr.contribution.register', string='Contribution Register',
|
||||
help="Eventual third party involved in the salary payment of the employees.")
|
||||
input_ids = fields.One2many('hr.rule.input', 'input_id', string='Inputs', copy=True)
|
||||
note = fields.Text(string='Description')
|
||||
|
||||
@api.multi
|
||||
def _recursive_search_of_rules(self):
|
||||
"""
|
||||
@return: returns a list of tuple (id, sequence) which are all the children of the passed rule_ids
|
||||
"""
|
||||
children_rules = []
|
||||
for rule in self.filtered(lambda rule: rule.child_ids):
|
||||
children_rules += rule.child_ids._recursive_search_of_rules()
|
||||
return [(rule.id, rule.sequence) for rule in self] + children_rules
|
||||
|
||||
#TODO should add some checks on the type of result (should be float)
|
||||
@api.multi
|
||||
def compute_rule(self, localdict):
|
||||
"""
|
||||
:param localdict: dictionary containing the environement in which to compute the rule
|
||||
:return: returns a tuple build as the base/amount computed, the quantity and the rate
|
||||
:rtype: (float, float, float)
|
||||
"""
|
||||
self.ensure_one()
|
||||
if self.amount_select == 'fix':
|
||||
try:
|
||||
return self.amount_fix, float(safe_eval(self.quantity, localdict)), 100.0
|
||||
except:
|
||||
raise UserError(_('Wrong quantity defined for salary rule %s (%s).') % (self.name, self.code))
|
||||
elif self.amount_select == 'percentage':
|
||||
try:
|
||||
return (float(safe_eval(self.amount_percentage_base, localdict)),
|
||||
float(safe_eval(self.quantity, localdict)),
|
||||
self.amount_percentage)
|
||||
except:
|
||||
raise UserError(_('Wrong percentage base or quantity defined for salary rule %s (%s).') % (self.name, self.code))
|
||||
else:
|
||||
try:
|
||||
safe_eval(self.amount_python_compute, localdict, mode='exec', nocopy=True)
|
||||
return float(localdict['result']), 'result_qty' in localdict and localdict['result_qty'] or 1.0, 'result_rate' in localdict and localdict['result_rate'] or 100.0
|
||||
except:
|
||||
raise UserError(_('Wrong python code defined for salary rule %s (%s).') % (self.name, self.code))
|
||||
|
||||
@api.multi
|
||||
def satisfy_condition(self, localdict):
|
||||
"""
|
||||
@param contract_id: id of hr.contract to be tested
|
||||
@return: returns True if the given rule match the condition for the given contract. Return False otherwise.
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
if self.condition_select == 'none':
|
||||
return True
|
||||
elif self.condition_select == 'range':
|
||||
try:
|
||||
result = safe_eval(self.condition_range, localdict)
|
||||
return self.condition_range_min <= result and result <= self.condition_range_max or False
|
||||
except:
|
||||
raise UserError(_('Wrong range condition defined for salary rule %s (%s).') % (self.name, self.code))
|
||||
else: # python code
|
||||
try:
|
||||
safe_eval(self.condition_python, localdict, mode='exec', nocopy=True)
|
||||
return 'result' in localdict and localdict['result'] or False
|
||||
except:
|
||||
raise UserError(_('Wrong python condition defined for salary rule %s (%s).') % (self.name, self.code))
|
||||
|
||||
|
||||
class HrRuleInput(models.Model):
|
||||
_name = 'hr.rule.input'
|
||||
_description = 'Salary Rule Input'
|
||||
|
||||
name = fields.Char(string='Description', required=True)
|
||||
code = fields.Char(required=True, help="The code that can be used in the salary rules")
|
||||
input_id = fields.Many2one('hr.salary.rule', string='Salary Rule Input', required=True)
|
||||
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Root Menus -->
|
||||
|
||||
<menuitem id="menu_hr_payroll_root" name="Payroll" sequence="45" web_icon="hr_payroll,static/description/icon.png"/>
|
||||
<menuitem id="menu_hr_payroll_configuration" name="Configuration" parent="menu_hr_payroll_root"
|
||||
sequence="100" groups="hr_payroll.group_hr_payroll_manager"/>
|
||||
|
||||
<!-- Contract View -->
|
||||
<record id="hr_contract_form_inherit" model="ir.ui.view">
|
||||
<field name="name">hr.contract.view.form.inherit</field>
|
||||
<field name="model">hr.contract</field>
|
||||
<field name="inherit_id" ref="hr_contract.hr_contract_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='type_id']" position="after">
|
||||
<field name="struct_id" required="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='type_id']" position="before">
|
||||
<field name="company_id"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='resource_calendar_id']" position="after">
|
||||
<field name="schedule_pay"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_contract_advantage_template_view_form" model="ir.ui.view">
|
||||
<field name="name">hr.contract.advantage.template.form</field>
|
||||
<field name="model">hr.contract.advantage.template</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name" placeholder="Advantage Name"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="code"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<group>
|
||||
<field name="default_value"/>
|
||||
<field name="lower_bound"/>
|
||||
<field name="upper_bound"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_contract_advantage_template_view_tree" model="ir.ui.view">
|
||||
<field name="name">hr.contract.advantage.template.tree</field>
|
||||
<field name="model">hr.contract.advantage.template</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="lower_bound"/>
|
||||
<field name="upper_bound"/>
|
||||
<field name="default_value"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_contract_advantage_template_action" model="ir.actions.act_window">
|
||||
<field name="name">Contract Advantage Templates</field>
|
||||
<field name="res_model">hr.contract.advantage.template</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
id="hr_contract_advantage_template_menu_action"
|
||||
action="hr_contract_advantage_template_action"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="50"/>
|
||||
</odoo>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Employee View -->
|
||||
<record id="payroll_hr_employee_view_form" model="ir.ui.view">
|
||||
<field name="name">payroll.hr.employee.view.form</field>
|
||||
<field name="model">hr.employee</field>
|
||||
<field name="inherit_id" ref="hr.view_employee_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<button name="toggle_active" position="before">
|
||||
<button name="%(act_hr_employee_payslip_list)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-money"
|
||||
type="action"
|
||||
groups="hr_payroll.group_hr_payroll_user">
|
||||
<field name="payslip_count" widget="statinfo" string="Payslips"/>
|
||||
</button>
|
||||
</button>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -1,800 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Root Menus -->
|
||||
|
||||
<menuitem id="menu_hr_payroll_root" name="Payroll" sequence="45" web_icon="hr_payroll,static/description/icon.png"/>
|
||||
<menuitem id="menu_hr_payroll_configuration" name="Configuration" parent="menu_hr_payroll_root"
|
||||
sequence="100" groups="hr_payroll.group_hr_payroll_manager"/>
|
||||
|
||||
<!-- Contract View -->
|
||||
<record id="hr_contract_form_inherit" model="ir.ui.view">
|
||||
<field name="name">hr.contract.view.form.inherit</field>
|
||||
<field name="model">hr.contract</field>
|
||||
<field name="inherit_id" ref="hr_contract.hr_contract_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='type_id']" position="after">
|
||||
<field name="struct_id" required="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='type_id']" position="before">
|
||||
<field name="company_id"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='resource_calendar_id']" position="after">
|
||||
<field name="schedule_pay"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_contract_advantage_template_view_form" model="ir.ui.view">
|
||||
<field name="name">hr.contract.advantage.template.form</field>
|
||||
<field name="model">hr.contract.advantage.template</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name" placeholder="Advantage Name"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="code"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<group>
|
||||
<field name="default_value"/>
|
||||
<field name="lower_bound"/>
|
||||
<field name="upper_bound"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_contract_advantage_template_view_tree" model="ir.ui.view">
|
||||
<field name="name">hr.contract.advantage.template.tree</field>
|
||||
<field name="model">hr.contract.advantage.template</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="lower_bound"/>
|
||||
<field name="upper_bound"/>
|
||||
<field name="default_value"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_contract_advantage_template_action" model="ir.actions.act_window">
|
||||
<field name="name">Contract Advantage Templates</field>
|
||||
<field name="res_model">hr.contract.advantage.template</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
id="hr_contract_advantage_template_menu_action"
|
||||
action="hr_contract_advantage_template_action"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="50"/>
|
||||
|
||||
|
||||
<!-- End Contract View-->
|
||||
|
||||
<!-- Salary structure -->
|
||||
<record id="view_hr_payroll_structure_list_view" model="ir.ui.view">
|
||||
<field name="name">hr.payroll.structure.tree</field>
|
||||
<field name="model">hr.payroll.structure</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Employee Function">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="rule_ids"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_hr_payroll_structure_tree" model="ir.ui.view">
|
||||
<field name="name">hr.payroll.structure.tree</field>
|
||||
<field name="model">hr.payroll.structure</field>
|
||||
<field name="field_parent">children_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Structure">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_payroll_structure_filter" model="ir.ui.view">
|
||||
<field name="name">hr.payroll.structure.select</field>
|
||||
<field name="model">hr.payroll.structure</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Payroll Structures">
|
||||
<field name="name" string="Payroll Structures" filter_domain="['|',('name','ilike',self),('code','ilike',self)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_employee_grade_form" model="ir.ui.view">
|
||||
<field name="name">hr.payroll.structure.form</field>
|
||||
<field name="model">hr.payroll.structure</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Employee Function">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Salary Rules">
|
||||
<field name="rule_ids" domain="[('parent_rule_id','=',False)]">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="category_id"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="register_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_hr_payroll_structure_list_form" model="ir.actions.act_window">
|
||||
<field name="name">Salary Structures</field>
|
||||
<field name="res_model">hr.payroll.structure</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_hr_payroll_structure_list_view"/>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_hr_payroll_structure_view"
|
||||
action="action_view_hr_payroll_structure_list_form"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="2"
|
||||
/>
|
||||
<record id="action_view_hr_payroll_structure_tree" model="ir.actions.act_window">
|
||||
<field name="name">Salary Structures Hierarchy</field>
|
||||
<field name="res_model">hr.payroll.structure</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="domain">[('parent_id','=',False)]</field>
|
||||
<field name="view_id" ref="view_hr_payroll_structure_tree"/>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_hr_payroll_structure_tree"
|
||||
action="action_view_hr_payroll_structure_tree"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="2"
|
||||
/>
|
||||
<!-- End Salary structure -->
|
||||
|
||||
<!-- Payslip Line -->
|
||||
<record id="view_hr_payslip_line_tree" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.line.tree</field>
|
||||
<field name="model">hr.payslip.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Structure" editable="bottom" decoration-info="total == 0">
|
||||
<field name="category_id"/>
|
||||
<field name="employee_id" invisible="1"/>
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="quantity"/>
|
||||
<field name="rate"/>
|
||||
<field name="amount"/>
|
||||
<field name="total"/>
|
||||
<field name="amount_select" invisible="1"/>
|
||||
<field name="register_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_hr_payslip_line_form" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.line.form</field>
|
||||
<field name="model">hr.payslip.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payslip Line">
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="slip_id"/>
|
||||
<field name="employee_id"/>
|
||||
</group>
|
||||
<group string="Calculations">
|
||||
<field name="category_id"/>
|
||||
<field name="amount_select"/>
|
||||
<field name="amount_fix" attrs="{'readonly':[('amount_select','!=','fix')]}"/>
|
||||
<field name="amount_percentage" attrs="{'readonly':[('amount_select','!=','percentage')]}"/>
|
||||
<field name="sequence"/>
|
||||
</group>
|
||||
<field name="note"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_payslip_line_filter" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.line.select</field>
|
||||
<field name="model">hr.payslip.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Payslip Lines">
|
||||
<field name="name" string="Payslip Lines" filter_domain="['|',('name','ilike',self),('code','ilike',self)]"/>
|
||||
<field name="amount_select"/>
|
||||
<field name="slip_id"/>
|
||||
<group col="8" colspan="4" expand="0" string="Group By">
|
||||
<filter string="Salary Rule Category" name="category_id" context="{'group_by':'category_id'}"/>
|
||||
<filter string="Contribution Register" name="register_id" context="{'group_by':'register_id'}"/>
|
||||
<filter string="Amount Type" name="amount_select" context="{'group_by':'amount_select'}"/>
|
||||
<filter string="Employees" name="employee_id" context="{'group_by':'employee_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- payslip -->
|
||||
|
||||
<record id="view_hr_payslip_tree" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.tree</field>
|
||||
<field name="model">hr.payslip</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-info="state in ('confirm','hr_check','accont_check')" decoration-muted="state == 'cancel'" string="Payslips">
|
||||
<field name="number"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="name"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="state"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
<field name="payslip_run_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window name="Payslip Computation Details"
|
||||
context="{'default_slip_id': active_id,'search_default_slip_id': active_id}"
|
||||
res_model="hr.payslip.line"
|
||||
src_model="hr.payslip"
|
||||
id="act_payslip_lines"/>
|
||||
|
||||
<record id="view_hr_payslip_form" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.form</field>
|
||||
<field name="model">hr.payslip</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payslip">
|
||||
<header>
|
||||
<button string="Confirm" name="action_payslip_done" type="object" states="draft" class="oe_highlight"/>
|
||||
<button string="Refund" name="refund_sheet" states="confirm,done" type='object' />
|
||||
<button string="Set to Draft" name="action_payslip_draft" type="object" states="cancel"/>
|
||||
<button string="Compute Sheet" name="compute_sheet" type="object" states="draft" class="oe_highlight"/>
|
||||
<button string="Cancel Payslip" name="action_payslip_cancel" type="object" states="draft,hr_check,confirm,verify"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirm"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(act_payslip_lines)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-money"
|
||||
type="action">
|
||||
<field name="payslip_count" widget="statinfo" string="Payslip" help="Payslip Computation Details"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="employee_id" class="oe_edit_only"/>
|
||||
<h1><field name="employee_id" placeholder="Employee"/></h1>
|
||||
</div>
|
||||
<group col="4">
|
||||
<label for="date_from" string="Period"/>
|
||||
<div>
|
||||
<field name="date_from" class="oe_inline"/> - <field name="date_to" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="contract_id" domain="[('employee_id','=',employee_id),('date_start','<=',date_to),'|',('date_end','>=',date_from),('date_end','=',False)]" context="{'default_employee_id': employee_id}"/>
|
||||
<field name="number"/>
|
||||
<field name="struct_id" attrs="{'required':[('contract_id','!=',False)]}"/>
|
||||
<field name="name"/>
|
||||
<field name="credit_note"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Worked Days & Inputs">
|
||||
<separator string="Worked Days"/>
|
||||
<field name="worked_days_line_ids">
|
||||
<tree string="Worked Days" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="number_of_days" sum="Total Working Days"/>
|
||||
<field name="number_of_hours"/>
|
||||
<field name="contract_id"/>
|
||||
<field name="sequence" invisible="True"/>
|
||||
</tree>
|
||||
<form string="Worked Day">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="sequence"/>
|
||||
<field name="number_of_days"/>
|
||||
<field name="number_of_hours"/>
|
||||
<field name="contract_id"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
<separator string="Other Inputs"/>
|
||||
<field name="input_line_ids" colspan="4" nolabel="1">
|
||||
<tree string="Input Data" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="amount"/>
|
||||
<field name="contract_id"/>
|
||||
<field name="sequence" invisible="True"/>
|
||||
</tree>
|
||||
<form string="Payslip Line">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="sequence"/>
|
||||
<field name="amount"/>
|
||||
<field name="contract_id"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Salary Computation" >
|
||||
<field name="line_ids" colspan="4" nolabel="1">
|
||||
<tree string="Salary Structure" editable="bottom" decoration-info="total == 0">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="category_id"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="quantity"/>
|
||||
<field name="rate"/>
|
||||
<field name="salary_rule_id"/>
|
||||
<field name="amount"/>
|
||||
<field name="total"/>
|
||||
</tree>
|
||||
<form string="Payslip Line">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="category_id"/>
|
||||
<field name="sequence"/>
|
||||
<field name="quantity"/>
|
||||
<field name="rate"/>
|
||||
<field name="amount"/>
|
||||
<field name="total"/>
|
||||
<field name="salary_rule_id"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Details By Salary Rule Category">
|
||||
<field name="details_by_salary_rule_category" context="{'group_by':'category_id'}" domain="[('appears_on_payslip', '=', True)]">
|
||||
<tree string="Payslip Lines" decoration-info="total == 0">
|
||||
<field name="category_id"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="total"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Accounting Information">
|
||||
<group>
|
||||
<group string="Miscellaneous">
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="payslip_run_id" domain="[('state','=','draft')]"/>
|
||||
</group>
|
||||
<group name="accounting" string="Accounting">
|
||||
<field name="paid" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<div colspan="4">
|
||||
<field name="note" placeholder="Add an internal note..."/>
|
||||
</div>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_payslip_filter" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.select</field>
|
||||
<field name="model">hr.payslip</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Payslips">
|
||||
<field name="name" string="Payslips" filter_domain="['|',('name','ilike',self),('number','ilike',self)]"/>
|
||||
<field name="date_from"/>
|
||||
<filter string="Draft" domain="[('state','=','draft')]" help="Draft Slip"/>
|
||||
<filter string="Done" domain="[('state','=','done')]" help="Done Slip"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="payslip_run_id"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Employees" name="employee_id" context="{'group_by':'employee_id'}"/>
|
||||
<filter string="PaySlip Batch" name="payslip_run_id" context="{'group_by':'payslip_run_id'}"/>
|
||||
<filter string="Companies" name="company_id" groups="base.group_multi_company" context="{'group_by':'company_id'}"/>
|
||||
<filter string="States" name="state" context="{'group_by':'state'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_view_hr_payslip_form" model="ir.actions.act_window">
|
||||
<field name="name">Employee Payslips</field>
|
||||
<field name="res_model">hr.payslip</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_hr_payslip_tree"/>
|
||||
<field name="search_view_id" ref="view_hr_payslip_filter"/>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_view_hr_payslip_form" id="menu_department_tree" parent="menu_hr_payroll_root" groups="hr_payroll.group_hr_payroll_user"/>
|
||||
|
||||
<record id="act_hr_employee_payslip_list" model="ir.actions.act_window">
|
||||
<field name="res_model">hr.payslip</field>
|
||||
<field name="name">Payslips</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_employee_id': [active_id], 'default_employee_id': active_id}</field>
|
||||
</record>
|
||||
|
||||
<!-- Employee View -->
|
||||
<record id="payroll_hr_employee_view_form" model="ir.ui.view">
|
||||
<field name="name">payroll.hr.employee.view.form</field>
|
||||
<field name="model">hr.employee</field>
|
||||
<field name="inherit_id" ref="hr.view_employee_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<button name="toggle_active" position="before">
|
||||
<button name="%(act_hr_employee_payslip_list)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-money"
|
||||
type="action"
|
||||
groups="hr_payroll.group_hr_payroll_user">
|
||||
<field name="payslip_count" widget="statinfo" string="Payslips"/>
|
||||
</button>
|
||||
</button>
|
||||
</field>
|
||||
</record>
|
||||
<!-- Salary Category-->
|
||||
<record id="hr_salary_rule_category_form" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.category.form</field>
|
||||
<field name="model">hr.salary.rule.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Salary Categories">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="parent_id"/>
|
||||
</group>
|
||||
<group string="Notes">
|
||||
<field name="note" nolabel="1"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_salary_rule_category_tree" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.category.tree</field>
|
||||
<field name="model">hr.salary.rule.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Rule Categories">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="hr_salary_rule_category_tree_view" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.category.tree.view</field>
|
||||
<field name="model">hr.salary.rule.category</field>
|
||||
<field name="field_parent">children_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Rule Categories">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_salary_rule_category_filter" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.category.select</field>
|
||||
<field name="model">hr.salary.rule.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Salary Rule Categories">
|
||||
<field name="name" string="Salary Rule Categories" filter_domain="['|',('name','ilike',self),('code','ilike',self)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_hr_salary_rule_category" model="ir.actions.act_window">
|
||||
<field name="name">Salary Rule Categories</field>
|
||||
<field name="res_model">hr.salary.rule.category</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="hr_salary_rule_category_tree"/>
|
||||
<field name="search_view_id" ref="view_hr_salary_rule_category_filter"/>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_hr_salary_rule_category"
|
||||
action="action_hr_salary_rule_category"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="11"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
<record id="action_hr_salary_rule_category_tree_view" model="ir.actions.act_window">
|
||||
<field name="name">Salary Rule Categories Hierarchy</field>
|
||||
<field name="res_model">hr.salary.rule.category</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="domain">[('parent_id','=',False)]</field>
|
||||
<field name="view_id" ref="hr_salary_rule_category_tree_view"/>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_hr_salary_rule_category_tree_view"
|
||||
action="action_hr_salary_rule_category_tree_view"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="12"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Contribution Register
|
||||
-->
|
||||
<record id="hr_contribution_register_tree" model="ir.ui.view">
|
||||
<field name="name">hr.contribution.register.tree</field>
|
||||
<field name="model">hr.contribution.register</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Contribution Registers">
|
||||
<field name="name" />
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="hr_contribution_register_filter" model="ir.ui.view">
|
||||
<field name="name">hr.contribution.register.search</field>
|
||||
<field name="model">hr.contribution.register</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Contribution Registers">
|
||||
<field name="name" string="Contribution Registers"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="hr_contribution_register_form" model="ir.ui.view">
|
||||
<field name="name">hr.contribution.register.form</field>
|
||||
<field name="model">hr.contribution.register</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Contribution">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}" class="oe_inline"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group>
|
||||
<separator string="Description"/><newline/>
|
||||
<field name="note" nolabel="1"/></group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_contribution_register_form" model="ir.actions.act_window">
|
||||
<field name="name">Contribution Registers</field>
|
||||
<field name="res_model">hr.contribution.register</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to add a new contribution register.
|
||||
</p><p>
|
||||
A contribution register is a third party involved in the salary
|
||||
payment of the employees. It can be the social security, the
|
||||
estate or anyone that collect or inject money on payslips.
|
||||
</p>
|
||||
</field>
|
||||
<field name="view_id" ref="hr_contribution_register_tree"/>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_action_hr_contribution_register_form"
|
||||
action="action_contribution_register_form"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="14"
|
||||
/>
|
||||
|
||||
<!-- Salary Rules -->
|
||||
|
||||
<record id="hr_salary_rule_list" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.list</field>
|
||||
<field name="model">hr.salary.rule</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Rules">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="category_id"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="register_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_salary_rule_tree" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.tree</field>
|
||||
<field name="model">hr.salary.rule</field>
|
||||
<field name="field_parent">child_ids</field>
|
||||
<field eval="20" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Rules">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="category_id" invisible="True"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="hr_salary_rule_form" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.form</field>
|
||||
<field name="model">hr.salary.rule</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Salary Rules">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1><field name="name"/></h1>
|
||||
<label for="category_id" class="oe_edit_only"/>
|
||||
<h2><field name="category_id"/></h2>
|
||||
|
||||
<group col="4">
|
||||
<field name="code"/>
|
||||
<field name="sequence" />
|
||||
<field name="active"/>
|
||||
<field name="appears_on_payslip"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
<notebook colspan="6">
|
||||
<page string="General">
|
||||
<group col="4">
|
||||
<separator colspan="4" string="Conditions"/>
|
||||
<field name="condition_select"/><newline/>
|
||||
<field name="condition_python" attrs="{'invisible':[('condition_select','!=','python')], 'required': [('condition_select','=','python')]}" colspan="4"/> <newline/>
|
||||
<field name="condition_range" attrs="{'invisible':[('condition_select','!=','range')], 'required':[('condition_select','=','range')]}"/><newline/>
|
||||
<field name="condition_range_min" colspan="2" attrs="{'invisible':[('condition_select','!=','range')], 'required':[('condition_select','=','range')]}"/><newline/>
|
||||
<field name="condition_range_max" colspan="2" attrs="{'invisible':[('condition_select','!=','range')], 'required':[('condition_select','=','range')]}"/><newline/>
|
||||
<separator colspan="4" string="Computation"/>
|
||||
<field name="amount_select"/><newline/>
|
||||
<field name="amount_percentage_base" attrs="{'invisible':[('amount_select','!=','percentage')], 'required': [('amount_select','=','percentage')]}"/><newline/>
|
||||
<field name="quantity" attrs="{'invisible':[('amount_select','=','code')], 'required':[('amount_select','!=','code')]}"/><newline/>
|
||||
<field name="amount_fix" attrs="{'invisible':[('amount_select','!=','fix')], 'required':[('amount_select','=','fix')]}"/><newline/>
|
||||
<field colspan="4" name="amount_python_compute" attrs="{'invisible':[('amount_select','!=','code')], 'required':[('amount_select','=','code')]}"/>
|
||||
<field name="amount_percentage" attrs="{'invisible':[('amount_select','!=','percentage')], 'required':[('amount_select','=','percentage')]}"/>
|
||||
<separator colspan="4" string="Company Contribution"/>
|
||||
<field name="register_id"/>
|
||||
</group>
|
||||
</page>
|
||||
<page name="rules" string="Child Rules">
|
||||
<field name="parent_rule_id"/>
|
||||
<separator string="Children Definition"/>
|
||||
<field name="child_ids"/>
|
||||
</page>
|
||||
<page string="Inputs">
|
||||
<field name="input_ids" mode="tree">
|
||||
<tree string="Input Data" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Description">
|
||||
<field name="note"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_rule_filter" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.select</field>
|
||||
<field name="model">hr.salary.rule</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Salary Rule">
|
||||
<field name="name" string="Salary Rules" filter_domain="['|',('name','ilike',self),('code','ilike',self)]"/>
|
||||
<field name="category_id"/>
|
||||
<field name="condition_range_min"/>
|
||||
<group col="8" colspan="4" expand="0" string="Group By">
|
||||
<filter string="Category" name="head" context="{'group_by':'category_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_salary_rule_form" model="ir.actions.act_window">
|
||||
<field name="name">Salary Rules</field>
|
||||
<field name="res_model">hr.salary.rule</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="hr_salary_rule_list"/>
|
||||
<field name="domain">[('parent_rule_id','=',False)]</field>
|
||||
<field name="search_view_id" ref="view_hr_rule_filter"/>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_action_hr_salary_rule_form" action="action_salary_rule_form" parent="menu_hr_payroll_configuration" sequence="12"/>
|
||||
|
||||
|
||||
<act_window name="All Children Rules"
|
||||
domain="[('parent_rule_id', '=', active_id)]"
|
||||
res_model="hr.salary.rule"
|
||||
src_model="hr.salary.rule"
|
||||
view_id="hr_salary_rule_list"
|
||||
id="act_children_salary_rules"/>
|
||||
|
||||
<!-- payslip runs -->
|
||||
|
||||
<record id="hr_payslip_run_filter" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.run.search</field>
|
||||
<field name="model">hr.payslip.run</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Payslip Batches">
|
||||
<field name="name" string="Payslip Batches"/>
|
||||
<field name="date_start"/>
|
||||
<field name="date_end"/>
|
||||
<filter string="Draft" domain="[('state','=','draft')]" help="Draft Payslip Batches"/>
|
||||
<filter name="done_filter" string="Done" domain="[('state','=','close')]" help="Done Payslip Batches"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_payslip_run_tree" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.run.tree</field>
|
||||
<field name="model">hr.payslip.run</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Payslips Batches">
|
||||
<field name="name"/>
|
||||
<field name="date_start"/>
|
||||
<field name="date_end"/>
|
||||
<field name="credit_note"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_payslip_run_form" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.run.form</field>
|
||||
<field name="model">hr.payslip.run</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payslips Batches">
|
||||
<header>
|
||||
<button name="close_payslip_run" type="object" string="Close" states="draft" class="oe_highlight"/>
|
||||
<button name="%(action_hr_payslip_by_employees)d" type="action" states="draft" string="Generate Payslips" class="oe_highlight"/>
|
||||
<button string="Set to Draft" name="draft_payslip_run" type="object" states="close" />
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="name"/>
|
||||
</h1>
|
||||
<group col="4">
|
||||
<label for="date_start" string="Period"/>
|
||||
<div>
|
||||
<field name="date_start" class="oe_inline"/> - <field name="date_end" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="credit_note"/>
|
||||
</group>
|
||||
<separator string="Payslips"/>
|
||||
<field name="slip_ids"/>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_hr_payslip_run_tree" model="ir.actions.act_window">
|
||||
<field name="name">Payslips Batches</field>
|
||||
<field name="res_model">hr.payslip.run</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="hr_payslip_run_tree"/>
|
||||
<field name="search_view_id" ref="hr_payslip_run_filter"/>
|
||||
</record>
|
||||
<menuitem action="action_hr_payslip_run_tree" id="menu_hr_payslip_run" parent="menu_hr_payroll_root"/>
|
||||
|
||||
<!-- Shortcuts -->
|
||||
|
||||
<act_window name="Payslip Lines"
|
||||
domain="[('register_id', '=', active_id)]"
|
||||
context="{'default_register_id': active_id, 'search_default_register_id': 1}"
|
||||
res_model="hr.payslip.line"
|
||||
src_model="hr.contribution.register"
|
||||
id="act_contribution_reg_payslip_lines"/>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,346 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Payslip Line -->
|
||||
<record id="view_hr_payslip_line_tree" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.line.tree</field>
|
||||
<field name="model">hr.payslip.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Structure" editable="bottom" decoration-info="total == 0">
|
||||
<field name="category_id"/>
|
||||
<field name="employee_id" invisible="1"/>
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="quantity"/>
|
||||
<field name="rate"/>
|
||||
<field name="amount"/>
|
||||
<field name="total"/>
|
||||
<field name="amount_select" invisible="1"/>
|
||||
<field name="register_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_hr_payslip_line_form" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.line.form</field>
|
||||
<field name="model">hr.payslip.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payslip Line">
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="slip_id"/>
|
||||
<field name="employee_id"/>
|
||||
</group>
|
||||
<group string="Calculations">
|
||||
<field name="category_id"/>
|
||||
<field name="amount_select"/>
|
||||
<field name="amount_fix" attrs="{'readonly':[('amount_select','!=','fix')]}"/>
|
||||
<field name="amount_percentage" attrs="{'readonly':[('amount_select','!=','percentage')]}"/>
|
||||
<field name="sequence"/>
|
||||
</group>
|
||||
<field name="note"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_payslip_line_filter" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.line.select</field>
|
||||
<field name="model">hr.payslip.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Payslip Lines">
|
||||
<field name="name" string="Payslip Lines" filter_domain="['|',('name','ilike',self),('code','ilike',self)]"/>
|
||||
<field name="amount_select"/>
|
||||
<field name="slip_id"/>
|
||||
<group col="8" colspan="4" expand="0" string="Group By">
|
||||
<filter string="Salary Rule Category" name="category_id" context="{'group_by':'category_id'}"/>
|
||||
<filter string="Contribution Register" name="register_id" context="{'group_by':'register_id'}"/>
|
||||
<filter string="Amount Type" name="amount_select" context="{'group_by':'amount_select'}"/>
|
||||
<filter string="Employees" name="employee_id" context="{'group_by':'employee_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- payslip -->
|
||||
|
||||
<record id="view_hr_payslip_tree" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.tree</field>
|
||||
<field name="model">hr.payslip</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-info="state in ('confirm','hr_check','accont_check')" decoration-muted="state == 'cancel'" string="Payslips">
|
||||
<field name="number"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="name"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="state"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
<field name="payslip_run_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window name="Payslip Computation Details"
|
||||
context="{'default_slip_id': active_id,'search_default_slip_id': active_id}"
|
||||
res_model="hr.payslip.line"
|
||||
src_model="hr.payslip"
|
||||
id="act_payslip_lines"/>
|
||||
|
||||
<record id="view_hr_payslip_form" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.form</field>
|
||||
<field name="model">hr.payslip</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payslip">
|
||||
<header>
|
||||
<button string="Confirm" name="action_payslip_done" type="object" states="draft" class="oe_highlight"/>
|
||||
<button string="Refund" name="refund_sheet" states="confirm,done" type='object' />
|
||||
<button string="Set to Draft" name="action_payslip_draft" type="object" states="cancel"/>
|
||||
<button string="Compute Sheet" name="compute_sheet" type="object" states="draft" class="oe_highlight"/>
|
||||
<button string="Cancel Payslip" name="action_payslip_cancel" type="object" states="draft,hr_check,confirm,verify"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirm"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(act_payslip_lines)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-money"
|
||||
type="action">
|
||||
<field name="payslip_count" widget="statinfo" string="Payslip" help="Payslip Computation Details"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="employee_id" class="oe_edit_only"/>
|
||||
<h1><field name="employee_id" placeholder="Employee"/></h1>
|
||||
</div>
|
||||
<group col="4">
|
||||
<label for="date_from" string="Period"/>
|
||||
<div>
|
||||
<field name="date_from" class="oe_inline"/> - <field name="date_to" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="contract_id" domain="[('employee_id','=',employee_id),('date_start','<=',date_to),'|',('date_end','>=',date_from),('date_end','=',False)]" context="{'default_employee_id': employee_id}"/>
|
||||
<field name="number"/>
|
||||
<field name="struct_id" attrs="{'required':[('contract_id','!=',False)]}"/>
|
||||
<field name="name"/>
|
||||
<field name="credit_note"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Worked Days & Inputs">
|
||||
<separator string="Worked Days"/>
|
||||
<field name="worked_days_line_ids">
|
||||
<tree string="Worked Days" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="number_of_days" sum="Total Working Days"/>
|
||||
<field name="number_of_hours"/>
|
||||
<field name="contract_id"/>
|
||||
<field name="sequence" invisible="True"/>
|
||||
</tree>
|
||||
<form string="Worked Day">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="sequence"/>
|
||||
<field name="number_of_days"/>
|
||||
<field name="number_of_hours"/>
|
||||
<field name="contract_id"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
<separator string="Other Inputs"/>
|
||||
<field name="input_line_ids" colspan="4" nolabel="1">
|
||||
<tree string="Input Data" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="amount"/>
|
||||
<field name="contract_id"/>
|
||||
<field name="sequence" invisible="True"/>
|
||||
</tree>
|
||||
<form string="Payslip Line">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="sequence"/>
|
||||
<field name="amount"/>
|
||||
<field name="contract_id"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Salary Computation" >
|
||||
<field name="line_ids" colspan="4" nolabel="1">
|
||||
<tree string="Salary Structure" editable="bottom" decoration-info="total == 0">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="category_id"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="quantity"/>
|
||||
<field name="rate"/>
|
||||
<field name="salary_rule_id"/>
|
||||
<field name="amount"/>
|
||||
<field name="total"/>
|
||||
</tree>
|
||||
<form string="Payslip Line">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="category_id"/>
|
||||
<field name="sequence"/>
|
||||
<field name="quantity"/>
|
||||
<field name="rate"/>
|
||||
<field name="amount"/>
|
||||
<field name="total"/>
|
||||
<field name="salary_rule_id"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Details By Salary Rule Category">
|
||||
<field name="details_by_salary_rule_category" context="{'group_by':'category_id'}" domain="[('appears_on_payslip', '=', True)]">
|
||||
<tree string="Payslip Lines" decoration-info="total == 0">
|
||||
<field name="category_id"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="total"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Accounting Information">
|
||||
<group>
|
||||
<group string="Miscellaneous">
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="payslip_run_id" domain="[('state','=','draft')]"/>
|
||||
</group>
|
||||
<group name="accounting" string="Accounting">
|
||||
<field name="paid" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<div colspan="4">
|
||||
<field name="note" placeholder="Add an internal note..."/>
|
||||
</div>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_payslip_filter" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.select</field>
|
||||
<field name="model">hr.payslip</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Payslips">
|
||||
<field name="name" string="Payslips" filter_domain="['|',('name','ilike',self),('number','ilike',self)]"/>
|
||||
<field name="date_from"/>
|
||||
<filter string="Draft" domain="[('state','=','draft')]" help="Draft Slip"/>
|
||||
<filter string="Done" domain="[('state','=','done')]" help="Done Slip"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="payslip_run_id"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Employees" name="employee_id" context="{'group_by':'employee_id'}"/>
|
||||
<filter string="PaySlip Batch" name="payslip_run_id" context="{'group_by':'payslip_run_id'}"/>
|
||||
<filter string="Companies" name="company_id" groups="base.group_multi_company" context="{'group_by':'company_id'}"/>
|
||||
<filter string="States" name="state" context="{'group_by':'state'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_view_hr_payslip_form" model="ir.actions.act_window">
|
||||
<field name="name">Employee Payslips</field>
|
||||
<field name="res_model">hr.payslip</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_hr_payslip_tree"/>
|
||||
<field name="search_view_id" ref="view_hr_payslip_filter"/>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_view_hr_payslip_form" id="menu_department_tree" parent="menu_hr_payroll_root" groups="hr_payroll.group_hr_payroll_user"/>
|
||||
|
||||
<record id="act_hr_employee_payslip_list" model="ir.actions.act_window">
|
||||
<field name="res_model">hr.payslip</field>
|
||||
<field name="name">Payslips</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_employee_id': [active_id], 'default_employee_id': active_id}</field>
|
||||
</record>
|
||||
|
||||
<!-- payslip runs -->
|
||||
|
||||
<record id="hr_payslip_run_filter" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.run.search</field>
|
||||
<field name="model">hr.payslip.run</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Payslip Batches">
|
||||
<field name="name" string="Payslip Batches"/>
|
||||
<field name="date_start"/>
|
||||
<field name="date_end"/>
|
||||
<filter string="Draft" domain="[('state','=','draft')]" help="Draft Payslip Batches"/>
|
||||
<filter name="done_filter" string="Done" domain="[('state','=','close')]" help="Done Payslip Batches"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_payslip_run_tree" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.run.tree</field>
|
||||
<field name="model">hr.payslip.run</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Payslips Batches">
|
||||
<field name="name"/>
|
||||
<field name="date_start"/>
|
||||
<field name="date_end"/>
|
||||
<field name="credit_note"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_payslip_run_form" model="ir.ui.view">
|
||||
<field name="name">hr.payslip.run.form</field>
|
||||
<field name="model">hr.payslip.run</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payslips Batches">
|
||||
<header>
|
||||
<button name="close_payslip_run" type="object" string="Close" states="draft" class="oe_highlight"/>
|
||||
<button name="%(action_hr_payslip_by_employees)d" type="action" states="draft" string="Generate Payslips" class="oe_highlight"/>
|
||||
<button string="Set to Draft" name="draft_payslip_run" type="object" states="close" />
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="name"/>
|
||||
</h1>
|
||||
<group col="4">
|
||||
<label for="date_start" string="Period"/>
|
||||
<div>
|
||||
<field name="date_start" class="oe_inline"/> - <field name="date_end" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="credit_note"/>
|
||||
</group>
|
||||
<separator string="Payslips"/>
|
||||
<field name="slip_ids"/>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_hr_payslip_run_tree" model="ir.actions.act_window">
|
||||
<field name="name">Payslips Batches</field>
|
||||
<field name="res_model">hr.payslip.run</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="hr_payslip_run_tree"/>
|
||||
<field name="search_view_id" ref="hr_payslip_run_filter"/>
|
||||
</record>
|
||||
<menuitem action="action_hr_payslip_run_tree" id="menu_hr_payslip_run" parent="menu_hr_payroll_root"/>
|
||||
|
||||
<!-- Shortcuts -->
|
||||
|
||||
<act_window name="Payslip Lines"
|
||||
domain="[('register_id', '=', active_id)]"
|
||||
context="{'default_register_id': active_id, 'search_default_register_id': 1}"
|
||||
res_model="hr.payslip.line"
|
||||
src_model="hr.contribution.register"
|
||||
id="act_contribution_reg_payslip_lines"/>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,356 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Salary structure -->
|
||||
<record id="view_hr_payroll_structure_list_view" model="ir.ui.view">
|
||||
<field name="name">hr.payroll.structure.tree</field>
|
||||
<field name="model">hr.payroll.structure</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Employee Function">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="rule_ids"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_hr_payroll_structure_tree" model="ir.ui.view">
|
||||
<field name="name">hr.payroll.structure.tree</field>
|
||||
<field name="model">hr.payroll.structure</field>
|
||||
<field name="field_parent">children_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Structure">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_payroll_structure_filter" model="ir.ui.view">
|
||||
<field name="name">hr.payroll.structure.select</field>
|
||||
<field name="model">hr.payroll.structure</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Payroll Structures">
|
||||
<field name="name" string="Payroll Structures" filter_domain="['|',('name','ilike',self),('code','ilike',self)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_employee_grade_form" model="ir.ui.view">
|
||||
<field name="name">hr.payroll.structure.form</field>
|
||||
<field name="model">hr.payroll.structure</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Employee Function">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Salary Rules">
|
||||
<field name="rule_ids" domain="[('parent_rule_id','=',False)]">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="category_id"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="register_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_hr_payroll_structure_list_form" model="ir.actions.act_window">
|
||||
<field name="name">Salary Structures</field>
|
||||
<field name="res_model">hr.payroll.structure</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_hr_payroll_structure_list_view"/>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_hr_payroll_structure_view"
|
||||
action="action_view_hr_payroll_structure_list_form"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="2"
|
||||
/>
|
||||
<record id="action_view_hr_payroll_structure_tree" model="ir.actions.act_window">
|
||||
<field name="name">Salary Structures Hierarchy</field>
|
||||
<field name="res_model">hr.payroll.structure</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="domain">[('parent_id','=',False)]</field>
|
||||
<field name="view_id" ref="view_hr_payroll_structure_tree"/>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_hr_payroll_structure_tree"
|
||||
action="action_view_hr_payroll_structure_tree"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="2"
|
||||
/>
|
||||
<!-- Salary Category-->
|
||||
<record id="hr_salary_rule_category_form" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.category.form</field>
|
||||
<field name="model">hr.salary.rule.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Salary Categories">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="parent_id"/>
|
||||
</group>
|
||||
<group string="Notes">
|
||||
<field name="note" nolabel="1"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_salary_rule_category_tree" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.category.tree</field>
|
||||
<field name="model">hr.salary.rule.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Rule Categories">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="hr_salary_rule_category_tree_view" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.category.tree.view</field>
|
||||
<field name="model">hr.salary.rule.category</field>
|
||||
<field name="field_parent">children_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Rule Categories">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_salary_rule_category_filter" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.category.select</field>
|
||||
<field name="model">hr.salary.rule.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Salary Rule Categories">
|
||||
<field name="name" string="Salary Rule Categories" filter_domain="['|',('name','ilike',self),('code','ilike',self)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_hr_salary_rule_category" model="ir.actions.act_window">
|
||||
<field name="name">Salary Rule Categories</field>
|
||||
<field name="res_model">hr.salary.rule.category</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="hr_salary_rule_category_tree"/>
|
||||
<field name="search_view_id" ref="view_hr_salary_rule_category_filter"/>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_hr_salary_rule_category"
|
||||
action="action_hr_salary_rule_category"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="11"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
<record id="action_hr_salary_rule_category_tree_view" model="ir.actions.act_window">
|
||||
<field name="name">Salary Rule Categories Hierarchy</field>
|
||||
<field name="res_model">hr.salary.rule.category</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="domain">[('parent_id','=',False)]</field>
|
||||
<field name="view_id" ref="hr_salary_rule_category_tree_view"/>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_hr_salary_rule_category_tree_view"
|
||||
action="action_hr_salary_rule_category_tree_view"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="12"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Contribution Register
|
||||
-->
|
||||
<record id="hr_contribution_register_tree" model="ir.ui.view">
|
||||
<field name="name">hr.contribution.register.tree</field>
|
||||
<field name="model">hr.contribution.register</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Contribution Registers">
|
||||
<field name="name" />
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="hr_contribution_register_filter" model="ir.ui.view">
|
||||
<field name="name">hr.contribution.register.search</field>
|
||||
<field name="model">hr.contribution.register</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Contribution Registers">
|
||||
<field name="name" string="Contribution Registers"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="hr_contribution_register_form" model="ir.ui.view">
|
||||
<field name="name">hr.contribution.register.form</field>
|
||||
<field name="model">hr.contribution.register</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Contribution">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}" class="oe_inline"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group>
|
||||
<separator string="Description"/><newline/>
|
||||
<field name="note" nolabel="1"/></group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_contribution_register_form" model="ir.actions.act_window">
|
||||
<field name="name">Contribution Registers</field>
|
||||
<field name="res_model">hr.contribution.register</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to add a new contribution register.
|
||||
</p><p>
|
||||
A contribution register is a third party involved in the salary
|
||||
payment of the employees. It can be the social security, the
|
||||
estate or anyone that collect or inject money on payslips.
|
||||
</p>
|
||||
</field>
|
||||
<field name="view_id" ref="hr_contribution_register_tree"/>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_action_hr_contribution_register_form"
|
||||
action="action_contribution_register_form"
|
||||
parent="menu_hr_payroll_configuration"
|
||||
sequence="14"
|
||||
/>
|
||||
|
||||
<!-- Salary Rules -->
|
||||
|
||||
<record id="hr_salary_rule_list" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.list</field>
|
||||
<field name="model">hr.salary.rule</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Rules">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="category_id"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="register_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_salary_rule_tree" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.tree</field>
|
||||
<field name="model">hr.salary.rule</field>
|
||||
<field name="field_parent">child_ids</field>
|
||||
<field eval="20" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Salary Rules">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="category_id" invisible="True"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="hr_salary_rule_form" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.form</field>
|
||||
<field name="model">hr.salary.rule</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Salary Rules">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1><field name="name"/></h1>
|
||||
<label for="category_id" class="oe_edit_only"/>
|
||||
<h2><field name="category_id"/></h2>
|
||||
|
||||
<group col="4">
|
||||
<field name="code"/>
|
||||
<field name="sequence" />
|
||||
<field name="active"/>
|
||||
<field name="appears_on_payslip"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
<notebook colspan="6">
|
||||
<page string="General">
|
||||
<group col="4">
|
||||
<separator colspan="4" string="Conditions"/>
|
||||
<field name="condition_select"/><newline/>
|
||||
<field name="condition_python" attrs="{'invisible':[('condition_select','!=','python')], 'required': [('condition_select','=','python')]}" colspan="4"/> <newline/>
|
||||
<field name="condition_range" attrs="{'invisible':[('condition_select','!=','range')], 'required':[('condition_select','=','range')]}"/><newline/>
|
||||
<field name="condition_range_min" colspan="2" attrs="{'invisible':[('condition_select','!=','range')], 'required':[('condition_select','=','range')]}"/><newline/>
|
||||
<field name="condition_range_max" colspan="2" attrs="{'invisible':[('condition_select','!=','range')], 'required':[('condition_select','=','range')]}"/><newline/>
|
||||
<separator colspan="4" string="Computation"/>
|
||||
<field name="amount_select"/><newline/>
|
||||
<field name="amount_percentage_base" attrs="{'invisible':[('amount_select','!=','percentage')], 'required': [('amount_select','=','percentage')]}"/><newline/>
|
||||
<field name="quantity" attrs="{'invisible':[('amount_select','=','code')], 'required':[('amount_select','!=','code')]}"/><newline/>
|
||||
<field name="amount_fix" attrs="{'invisible':[('amount_select','!=','fix')], 'required':[('amount_select','=','fix')]}"/><newline/>
|
||||
<field colspan="4" name="amount_python_compute" attrs="{'invisible':[('amount_select','!=','code')], 'required':[('amount_select','=','code')]}"/>
|
||||
<field name="amount_percentage" attrs="{'invisible':[('amount_select','!=','percentage')], 'required':[('amount_select','=','percentage')]}"/>
|
||||
<separator colspan="4" string="Company Contribution"/>
|
||||
<field name="register_id"/>
|
||||
</group>
|
||||
</page>
|
||||
<page name="rules" string="Child Rules">
|
||||
<field name="parent_rule_id"/>
|
||||
<separator string="Children Definition"/>
|
||||
<field name="child_ids"/>
|
||||
</page>
|
||||
<page string="Inputs">
|
||||
<field name="input_ids" mode="tree">
|
||||
<tree string="Input Data" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Description">
|
||||
<field name="note"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_hr_rule_filter" model="ir.ui.view">
|
||||
<field name="name">hr.salary.rule.select</field>
|
||||
<field name="model">hr.salary.rule</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Salary Rule">
|
||||
<field name="name" string="Salary Rules" filter_domain="['|',('name','ilike',self),('code','ilike',self)]"/>
|
||||
<field name="category_id"/>
|
||||
<field name="condition_range_min"/>
|
||||
<group col="8" colspan="4" expand="0" string="Group By">
|
||||
<filter string="Category" name="head" context="{'group_by':'category_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_salary_rule_form" model="ir.actions.act_window">
|
||||
<field name="name">Salary Rules</field>
|
||||
<field name="res_model">hr.salary.rule</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="hr_salary_rule_list"/>
|
||||
<field name="domain">[('parent_rule_id','=',False)]</field>
|
||||
<field name="search_view_id" ref="view_hr_rule_filter"/>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_action_hr_salary_rule_form" action="action_salary_rule_form" parent="menu_hr_payroll_configuration" sequence="12"/>
|
||||
|
||||
<act_window name="All Children Rules"
|
||||
domain="[('parent_rule_id', '=', active_id)]"
|
||||
res_model="hr.salary.rule"
|
||||
src_model="hr.salary.rule"
|
||||
view_id="hr_salary_rule_list"
|
||||
id="act_children_salary_rules"/>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user