[MERGE] merged psi branch with new feature for input on payslip

bzr revid: qdp-launchpad@openerp.com-20110511131650-2en4cz4331u4ihnh
This commit is contained in:
Quentin (OpenERP)
2011-05-11 15:16:50 +02:00
4 changed files with 225 additions and 87 deletions
+81 -7
View File
@@ -247,6 +247,7 @@ class hr_payslip(osv.osv):
# 'line_ids': fields.one2many('hr.payslip.line', 'slip_id', 'Payslip Line', required=False, readonly=True, states={'draft': [('readonly', False)]}),
'line_ids': one2many_mod2('hr.payslip.line', 'slip_id', 'Payslip Line',readonly=True),
'company_id': fields.many2one('res.company', 'Company', required=False, readonly=True, states={'draft': [('readonly', False)]}),
'worked_days_line_ids': fields.one2many('hr.payslip.worked_days', 'payslip_id', 'Payslip Worked Days', required=False, readonly=True, states={'draft': [('readonly', False)]}),
'input_line_ids': fields.one2many('hr.payslip.input', 'payslip_id', 'Payslip Inputs', required=False, readonly=True, states={'draft': [('readonly', False)]}),
'paid': fields.boolean('Made Payment Order ? ', required=False, readonly=True, states={'draft': [('readonly', False)]}),
'note': fields.text('Description'),
@@ -413,7 +414,7 @@ class hr_payslip(osv.osv):
self.write(cr, uid, [payslip.id], {'line_ids': lines}, context=context)
return True
def get_input_lines(self, cr, uid, contract_ids, date_from, date_to, context=None):
def get_worked_day_lines(self, cr, uid, contract_ids, date_from, date_to, context=None):
"""
@param contract_ids: list of contract id
@return: returns a list of dict containing the input that should be applied for the given contract between date_from and date_to
@@ -470,6 +471,27 @@ class hr_payslip(osv.osv):
res += [attendances] + leaves
return res
def get_inputs(self, cr, uid, contract_ids, date_from, date_to, context=None):
res = []
contract_obj = self.pool.get('hr.contract')
rule_obj = self.pool.get('hr.salary.rule')
structure_ids = contract_obj.get_all_structures(cr, uid, contract_ids, context=context)
rule_ids = self.pool.get('hr.payroll.structure').get_all_rules(cr, uid, structure_ids, context=context)
sorted_rule_ids = [id for id, sequence in sorted(rule_ids, key=lambda x:x[1])]
for contract in contract_obj.browse(cr, uid, contract_ids, context=context):
for rule in rule_obj.browse(cr, uid, sorted_rule_ids, context=context):
if rule.input_ids:
for input in rule.input_ids:
inputs = {
'name': input.name,
'code': input.code,
'contract_id': contract.id,
}
res += [inputs]
return res
def get_payslip_lines(self, cr, uid, contract_ids, payslip_id, context):
def _sum_salary_category(localdict, category, amount):
if category.parent_id:
@@ -483,9 +505,12 @@ class hr_payslip(osv.osv):
obj_rule = self.pool.get('hr.salary.rule')
payslip = self.pool.get('hr.payslip').browse(cr, uid, payslip_id, context=context)
worked_days = {}
for worked_days_line in payslip.worked_days_line_ids:
worked_days[worked_days_line.code] = worked_days_line
inputs = {}
for input_line in payslip.input_line_ids:
worked_days[input_line.code] = input_line
localdict = {'categories': {}, 'payslip': payslip, 'worked_days': worked_days}
inputs[input_line.code] = input_line
localdict = {'heads': {}, 'payslip': payslip, 'worked_days': worked_days, 'inputs': inputs}
#get the ids of the structures on the contracts and their parent id as well
structure_ids = self.pool.get('hr.contract').get_all_structures(cr, uid, contract_ids, context=context)
#get the rules of the structure and thier children
@@ -543,15 +568,22 @@ class hr_payslip(osv.osv):
def onchange_employee_id(self, cr, uid, ids, date_from, date_to, employee_id=False, contract_id=False, context=None):
empolyee_obj = self.pool.get('hr.employee')
contract_obj = self.pool.get('hr.contract')
worked_days_obj = self.pool.get('hr.payslip.worked_days')
input_obj = self.pool.get('hr.payslip.input')
if context is None:
context = {}
#delete old worked days lines
old_worked_days_ids = ids and worked_days_obj.search(cr, uid, [('payslip_id', '=', ids[0])], context=context) or False
if old_worked_days_ids:
worked_days_obj.unlink(cr, uid, old_worked_days_ids, context=context)
#delete old input lines
old_input_ids = ids and input_obj.search(cr, uid, [('payslip_id', '=', ids[0])], context=context) or False
if old_input_ids:
input_obj.unlink(cr, uid, old_input_ids, context=context)
#defaults
res = {'value':{
'line_ids':[],
@@ -590,8 +622,10 @@ class hr_payslip(osv.osv):
return res
#computation of the salary input
input_line_ids = self.get_input_lines(cr, uid, contract_ids, date_from, date_to, context=context)
worked_days_line_ids = self.get_worked_day_lines(cr, uid, contract_ids, date_from, date_to, context=context)
input_line_ids = self.get_inputs(cr, uid, contract_ids, date_from, date_to, context=context)
res['value'].update({
'worked_days_line_ids': worked_days_line_ids,
'input_line_ids': input_line_ids,
})
return res
@@ -611,6 +645,28 @@ class hr_payslip(osv.osv):
hr_payslip()
class hr_payslip_worked_days(osv.osv):
'''
Payslip Worked Days
'''
_name = 'hr.payslip.worked_days'
_description = 'Payslip Worked Days'
_columns = {
'name': fields.char('Description', size=256, required=True),
'payslip_id': fields.many2one('hr.payslip', 'Pay Slip', required=True),
'sequence': fields.integer('Sequence', required=True,),
'code': fields.char('Code', size=52, required=True, help="The code that can be used in the salary rules"),
'number_of_days': fields.float('Number of Days'),
'number_of_hours': fields.float('Number of Hours'),
'contract_id': fields.many2one('hr.contract', 'Contract', required=True, help="The contract for which applied this input"),
}
_order = 'payslip_id, sequence'
_defaults = {
'sequence': 10,
}
hr_payslip_worked_days()
class hr_payslip_input(osv.osv):
'''
Payslip Input
@@ -623,13 +679,13 @@ class hr_payslip_input(osv.osv):
'payslip_id': fields.many2one('hr.payslip', 'Pay Slip', required=True),
'sequence': fields.integer('Sequence', required=True,),
'code': fields.char('Code', size=52, required=True, help="The code that can be used in the salary rules"),
'number_of_days': fields.float('Number of Days'),
'number_of_hours': fields.float('Number of Hours'),
'quantity': fields.float('Quantity', 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['S-ASUS']['qunatity']*contract.wage*0.01."),
'contract_id': fields.many2one('hr.contract', 'Contract', required=True, help="The contract for which applied this input"),
}
_order = 'payslip_id,sequence'
_order = 'payslip_id, sequence'
_defaults = {
'sequence': 10,
'quantity': 0.0,
}
hr_payslip_input()
@@ -671,6 +727,7 @@ class hr_salary_rule(osv.osv):
help="Contribution register based on company",
required=False
),
'input_ids': fields.one2many('hr.rule.input', 'input_id', 'Inputs'),
'note':fields.text('Description'),
}
_defaults = {
@@ -683,6 +740,7 @@ class hr_salary_rule(osv.osv):
# rules: rules code (previously computed)
# categories: dictionary containing the computed categories (sum of amount of all rules belonging to that category). Keys are the category codes.
# worked_days: dictionary containing the computed worked days. Keys are the worked days codes.
# inputs: dictionary containing the computed inputs. Keys are the inputs codes.
# Note: returned value have to be set in the variable 'result'
@@ -697,6 +755,7 @@ result = contract.wage * 0.10''',
# rules: rules code (previously computed)
# categories: dictionary containing the computed categories (sum of amount of all rules belonging to that category). Keys are the category codes.
# worked_days: dictionary containing the computed worked days. Keys are the worked days codes.
# inputs: dictionary containing the computed inputs. Keys are the inputs codes.
# Note: returned value have to be set in the variable 'result'
@@ -777,6 +836,21 @@ result = rules['NET'] > categories['NET'] * 0.10''',
hr_salary_rule()
class hr_rule_input(osv.osv):
'''
Salary Rule Input
'''
_name = 'hr.rule.input'
_description = 'Salary Rule Input'
_columns = {
'name': fields.char('Description', size=256, required=True),
'code': fields.char('Code', size=52, required=True, help="The code that can be used in the salary rules"),
'input_id': fields.many2one('hr.salary.rule', 'Salary Rule Input', required=True)
}
hr_rule_input()
class hr_payslip_line(osv.osv):
'''
Payslip Line
+24
View File
@@ -60,6 +60,30 @@
<field name="name">Meal Voucher</field>
<field name="sequence" eval="16"/>
</record>
<record id="hr_salary_rule_sales_commission" model="hr.salary.rule">
<field name="amount_select">code</field>
<field name="code">SALE</field>
<field name="category_id" ref="hr_payroll.ALW"/>
<field name="name">Get 1% of sales</field>
<field name="sequence" eval="17"/>
<field name="amount_python_compute">result = (inputs['S-ASUS']['quantity'] + inputs['S-CHINA']['quantity']) * contract.wage * 0.01</field>
</record>
<!-- Rule Inputs -->
<record id="hr_rule_input_sale_a" model="hr.rule.input">
<field name="code">S-ASUS</field>
<field name="name">Sale to ASUStek</field>
<field name="input_id" ref="hr_salary_rule_sales_commission"/>
</record>
<record id="hr_rule_input_sale_b" model="hr.rule.input">
<field name="code">S-CHINA</field>
<field name="name">Sale to China Export</field>
<field name="input_id" ref="hr_salary_rule_sales_commission"/>
</record>
<!-- Salary Structure -->
<record id="structure_001" model="hr.payroll.structure">
+117 -79
View File
@@ -260,7 +260,7 @@
</field>
</page>
<!-- TODO: put me back -->
<page string="Details By Salary Category">
<page string="Details By Salary Category">
<field name="details_by_salary_category" context="{'group_by':'category_id'}" domain="[('appears_on_payslip', '=', True)]" nolabel="1">
<tree string="Payslip Lines" colors="blue:total == 0">
<field name="category_id"/>
@@ -272,7 +272,7 @@
</page>
<page string="Worked Days">
<field name="input_line_ids" colspan="4" nolabel="1" mode="tree">
<field name="worked_days_line_ids" colspan="4" nolabel="1">
<tree string="Worked Days" editable="bottom">
<field name="name"/>
<field name="code"/>
@@ -281,6 +281,36 @@
<field name="contract_id" groups="base.group_extended"/>
<field name="sequence" invisible="True"/>
</tree>
<form string="Worked Day">
<group>
<field name="name" select="1"/>
<field name="code" select="1"/>
<field name="payslip_id"/>
<field name="sequence" groups="base.group_extended"/>
<field name="number_of_days"/>
<field name="number_of_hours"/>
<field name="contract_id" groups="base.group_extended"/>
</group>
</form>
</field>
<field name="input_line_ids" colspan="4" nolabel="1">
<tree string="Input Data" editable="bottom">
<field name="name"/>
<field name="code"/>
<field name="quantity"/>
<field name="contract_id" groups="base.group_extended"/>
<field name="sequence" invisible="True"/>
</tree>
<form string="Payslip Line">
<group>
<field name="name" select="1"/>
<field name="code" select="1"/>
<field name="payslip_id"/>
<field name="sequence" groups="base.group_extended"/>
<field name="quantity"/>
<field name="contract_id" groups="base.group_extended"/>
</group>
</form>
</field>
</page>
@@ -487,7 +517,7 @@
<!-- Salary Rules -->
<record id="hr_salary_rule_tree" model="ir.ui.view">
<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="type">tree</field>
@@ -501,86 +531,94 @@
</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="type">form</field>
<field name="arch" type="xml">
<form string="Salary Rules">
<group col="6" colspan="6">
<field name="name"/>
<field name="code" select="1"/>
<field name="category_id"/>
<field name="sequence" />
<field name="active"/>
<field name="appears_on_payslip" attrs="{'readonly':[('company_contribution','=', True)]}" />
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
</group>
<notebook colspan="6">
<page string="General">
<group col="4" colspan="6">
<separator colspan="4" string="Conditions"/>
<field name="condition_select"/><newline/>
<field name="condition_python" attrs="{'invisible':[('condition_select','&lt;&gt;','python')], 'required': [('condition_select','=','python')]}" colspan="4"/> <newline/>
<field name="condition_range" attrs="{'invisible':[('condition_select','&lt;&gt;','range')], 'required':[('condition_select','=','range')]}"/><newline/>
<field name="condition_range_min" colspan="2" attrs="{'invisible':[('condition_select','&lt;&gt;','range')], 'required':[('condition_select','=','range')]}"/>
<field name="condition_range_max" colspan="2" attrs="{'invisible':[('condition_select','&lt;&gt;','range')], 'required':[('condition_select','=','range')]}"/>
<separator colspan="4" string="Computation"/>
<field name="amount_select"/>
<field name="quantity" attrs="{'invisible':[('amount_select','=','code')], 'required':[('amount_select','!=','code')]}"/><newline/>
<field name="amount_fix" attrs="{'invisible':[('amount_select','&lt;&gt;','fix')], 'required':[('amount_select','=','fix')]}"/>
<field colspan="4" name="amount_python_compute" attrs="{'invisible':[('amount_select','&lt;&gt;','code')], 'required':[('amount_select','=','code')]}"/>
<field name="amount_percentage_base" attrs="{'invisible':[('amount_select','&lt;&gt;','percentage')], 'required': [('amount_select','=','percentage')]}"/>
<field name="amount_percentage" attrs="{'invisible':[('amount_select','&lt;&gt;','percentage')], 'required':[('amount_select','=','percentage')]}"/>
<separator colspan="4" string="Company contribution"/>
<field name="register_id"/>
</group>
</page>
<page string="Child Rules">
<field name="parent_rule_id"/>
<separator colspan="4" string="Children definition"/>
<field colspan="4" name="child_ids" nolabel="1"/>
</page>
<page string="Description">
<field name="note" colspan="4" nolabel="1"/>
</page>
</notebook>
</form>
</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="type">form</field>
<field name="arch" type="xml">
<form string="Salary Rules">
<group col="6" colspan="6">
<field name="name"/>
<field name="code" select="1"/>
<field name="category_id"/>
<field name="sequence" />
<field name="active"/>
<field name="appears_on_payslip" attrs="{'readonly':[('company_contribution','=', True)]}" />
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
</group>
<notebook colspan="6">
<page string="General">
<group col="4" colspan="6">
<separator colspan="4" string="Conditions"/>
<field name="condition_select"/><newline/>
<field name="condition_python" attrs="{'invisible':[('condition_select','&lt;&gt;','python')], 'required': [('condition_select','=','python')]}" colspan="4"/> <newline/>
<field name="condition_range" attrs="{'invisible':[('condition_select','&lt;&gt;','range')], 'required':[('condition_select','=','range')]}"/><newline/>
<field name="condition_range_min" colspan="2" attrs="{'invisible':[('condition_select','&lt;&gt;','range')], 'required':[('condition_select','=','range')]}"/>
<field name="condition_range_max" colspan="2" attrs="{'invisible':[('condition_select','&lt;&gt;','range')], 'required':[('condition_select','=','range')]}"/>
<separator colspan="4" string="Computation"/>
<field name="amount_select"/>
<field name="quantity" attrs="{'invisible':[('amount_select','=','code')], 'required':[('amount_select','!=','code')]}"/><newline/>
<field name="amount_fix" attrs="{'invisible':[('amount_select','&lt;&gt;','fix')], 'required':[('amount_select','=','fix')]}"/>
<field colspan="4" name="amount_python_compute" attrs="{'invisible':[('amount_select','&lt;&gt;','code')], 'required':[('amount_select','=','code')]}"/>
<field name="amount_percentage_base" attrs="{'invisible':[('amount_select','&lt;&gt;','percentage')], 'required': [('amount_select','=','percentage')]}"/>
<field name="amount_percentage" attrs="{'invisible':[('amount_select','&lt;&gt;','percentage')], 'required':[('amount_select','=','percentage')]}"/>
<separator colspan="4" string="Company contribution"/>
<field name="register_id"/>
</group>
</page>
<page string="Child Rules">
<field name="parent_rule_id"/>
<separator colspan="4" string="Children definition"/>
<field colspan="4" name="child_ids" nolabel="1"/>
</page>
<page string="Inputs">
<field name="input_ids" colspan="4" nolabel="1" mode="tree, form">
<tree string="Input Data" editable="bottom">
<field name="name"/>
<field name="code"/>
</tree>
</field>
</page>
<page string="Description">
<field name="note" colspan="4" nolabel="1"/>
</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="type">search</field>
<field name="arch" type="xml">
<search string="Search Salary Rule">
<group col="8" colspan="4">
<field name="name"/>
<field name="code" select="1"/>
<field name="category_id"/>
<field name="condition_range_min"/>
</group>
<newline/>
<group col="8" colspan="4" expand="0" string="Group By...">
<filter string="Category" icon="terp-folder-yellow" name="category" context="{'group_by':'category_id'}"/>
</group>
</search>
</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="type">search</field>
<field name="arch" type="xml">
<search string="Search Salary Rule">
<group col="8" colspan="4">
<field name="name"/>
<field name="code" select="1"/>
<field name="category_id"/>
<field name="condition_range_min"/>
</group>
<newline/>
<group col="8" colspan="4" expand="0" string="Group By...">
<filter string="Head" icon="terp-folder-yellow" 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_tree"/>
<field name="domain">[('parent_rule_id','=',False)]</field>
<field name="search_view_id" ref="view_hr_rule_filter"/>
</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_tree"/>
<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="payroll_configure" sequence="12"/>
<menuitem id="menu_action_hr_salary_rule_form" action="action_salary_rule_form" parent="payroll_configure" sequence="12"/>
<act_window domain="[('slip_id', '=', active_id)]" id="act_payslip_lines" name="Payslip Lines" res_model="hr.payslip.line" src_model="hr.payslip"/>
<act_window domain="[('slip_id', '=', active_id)]" id="act_payslip_lines" name="Payslip Lines" res_model="hr.payslip.line" src_model="hr.payslip"/>
</data>
</openerp>
@@ -8,5 +8,7 @@
"access_hr_payslip_manager","hr.payslip.manager","model_hr_payslip","base.group_hr_manager",1,1,1,1
"access_hr_payslip_line_manager","hr.payslip.line.manager","model_hr_payslip_line","base.group_hr_manager",1,1,1,1
"access_hr_payroll_structure_manager","hr.payroll.structure.manager","model_hr_payroll_structure","base.group_hr_manager",1,1,1,1
"access_hr_payslip_input ","hr.payslip.input","model_hr_payslip_input","base.group_hr_manager",1,1,1,1
"access_hr_payslip_worked_days ","hr.payslip.worked_days","model_hr_payslip_worked_days","base.group_hr_manager",1,1,1,1
"access_hr_salary_rule","hr.salary.rule","model_hr_salary_rule","base.group_hr_manager",1,1,1,1
"access_hr_payslip_input","hr.payslip.input","model_hr_payslip_input","base.group_hr_manager",1,1,1,1
"access_hr_rule_input","hr.rule.input","model_hr_rule_input","base.group_hr_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
8 access_hr_payslip_manager hr.payslip.manager model_hr_payslip base.group_hr_manager 1 1 1 1
9 access_hr_payslip_line_manager hr.payslip.line.manager model_hr_payslip_line base.group_hr_manager 1 1 1 1
10 access_hr_payroll_structure_manager hr.payroll.structure.manager model_hr_payroll_structure base.group_hr_manager 1 1 1 1
11 access_hr_payslip_input access_hr_payslip_worked_days hr.payslip.input hr.payslip.worked_days model_hr_payslip_input model_hr_payslip_worked_days base.group_hr_manager 1 1 1 1
12 access_hr_salary_rule hr.salary.rule model_hr_salary_rule base.group_hr_manager 1 1 1 1
13 access_hr_payslip_input hr.payslip.input model_hr_payslip_input base.group_hr_manager 1 1 1 1
14 access_hr_rule_input hr.rule.input model_hr_rule_input base.group_hr_manager 1 1 1 1