[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/hr_payroll_security.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'wizard/hr_payroll_payslips_by_employees_views.xml',
|
'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',
|
'data/hr_payroll_sequence.xml',
|
||||||
'views/hr_payroll_report.xml',
|
'views/hr_payroll_report.xml',
|
||||||
'data/hr_payroll_data.xml',
|
'data/hr_payroll_data.xml',
|
||||||
'wizard/hr_payroll_contribution_register_report_views.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_contributionregister_templates.xml',
|
||||||
'views/report_payslip_templates.xml',
|
'views/report_payslip_templates.xml',
|
||||||
'views/report_payslipdetails_templates.xml',
|
'views/report_payslipdetails_templates.xml',
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
import hr_payroll
|
import hr_contract
|
||||||
import res_config
|
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.
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime
|
||||||
from datetime import time as datetime_time
|
from datetime import time as datetime_time
|
||||||
from dateutil import relativedelta
|
from dateutil import relativedelta
|
||||||
|
|
||||||
import babel
|
import babel
|
||||||
|
|
||||||
from odoo import api, fields, models, tools, _
|
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
|
from odoo.addons import decimal_precision as dp
|
||||||
|
from odoo.exceptions import UserError, ValidationError
|
||||||
|
|
||||||
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'})
|
|
||||||
|
|
||||||
|
|
||||||
class HrPayslip(models.Model):
|
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!'))
|
raise UserError(_('You cannot delete a payslip which is not draft or cancelled!'))
|
||||||
return super(HrPayslip, self).unlink()
|
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
|
@api.model
|
||||||
def get_contract(self, employee, date_from, date_to):
|
def get_contract(self, employee, date_from, date_to):
|
||||||
"""
|
"""
|
||||||
@@ -295,11 +138,11 @@ class HrPayslip(models.Model):
|
|||||||
@param date_to: date field
|
@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
|
@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)]
|
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)]
|
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_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
|
clause_final = [('employee_id', '=', employee.id), ('state', '=', 'open'), '|', '|'] + clause_1 + clause_2 + clause_3
|
||||||
return self.env['hr.contract'].search(clause_final).ids
|
return self.env['hr.contract'].search(clause_final).ids
|
||||||
@@ -308,7 +151,7 @@ class HrPayslip(models.Model):
|
|||||||
def compute_sheet(self):
|
def compute_sheet(self):
|
||||||
for payslip in self:
|
for payslip in self:
|
||||||
number = payslip.number or self.env['ir.sequence'].next_by_code('salary.slip')
|
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()
|
payslip.line_ids.unlink()
|
||||||
# set the list of contract for which the rules have to be applied
|
# 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
|
# 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:
|
else:
|
||||||
return 0.0
|
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):
|
class HrPayslipLine(models.Model):
|
||||||
_name = 'hr.payslip.line'
|
_name = 'hr.payslip.line'
|
||||||
@@ -853,14 +516,62 @@ class HrPayslipLine(models.Model):
|
|||||||
raise UserError(_('You must set a contract to create a payslip line.'))
|
raise UserError(_('You must set a contract to create a payslip line.'))
|
||||||
return super(HrPayslipLine, self).create(values)
|
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)
|
class HrPayslipWorkedDays(models.Model):
|
||||||
payslip_count = fields.Integer(compute='_compute_payslip_count', string='Payslips', groups="hr_payroll.group_hr_payroll_user")
|
_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
|
@api.multi
|
||||||
def _compute_payslip_count(self):
|
def draft_payslip_run(self):
|
||||||
for employee in self:
|
return self.write({'state': 'draft'})
|
||||||
employee.payslip_count = len(employee.slip_ids)
|
|
||||||
|
@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