From a59188e080e21f8638c3a01d00974b4ea8642580 Mon Sep 17 00:00:00 2001 From: mtr Date: Thu, 24 Feb 2011 18:42:20 +0530 Subject: [PATCH 0001/1110] [IMP] hr_payroll: improvements-Salary Rules bzr revid: mtr@mtr-20110224131220-468gscq24wbr3pt6 --- addons/hr_payroll/hr_payroll.py | 123 ++++++++++++++++++------ addons/hr_payroll/hr_payroll_view.xml | 133 +++++++++++++++++++++++++- 2 files changed, 224 insertions(+), 32 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index b29bd1312ac..4318ef2de87 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -97,6 +97,8 @@ class hr_payroll_structure(osv.osv): 'line_ids':fields.one2many('hr.payslip.line', 'function_id', 'Salary Structure', required=False), 'company_id':fields.many2one('res.company', 'Company', required=False), 'note': fields.text('Description'), + 'struct_id':fields.many2one('hr.payroll.structure', 'Parent Salary Structure', select=True), + 'child_ids':fields.one2many('hr.payroll.structure', 'struct_id', 'Child Salary Sructure'), } _defaults = { 'company_id': lambda self, cr, uid, context: \ @@ -157,7 +159,11 @@ class hr_contract(osv.osv): sal_type = contract.wage_type_id.type # function = contract.struct_id.id - lines = contract.struct_id.line_ids + lines = contract.struct_id.rule_ids + if contract.struct_id.child_ids: + for child in contract.struct_id.child_ids: + for rule in self.pool.get('hr.payroll.structure').browse(cr, uid, [child.id]): + lines = rule.rule_ids if not contract.struct_id: res[contract.id] = obj['basic'] continue @@ -275,8 +281,12 @@ class hr_contract(osv.osv): } vals[rs.id] = record continue - - for line in rs.struct_id.line_ids: + lines = rs.struct_id.rule_ids + if rs.struct_id.child_ids: + for child in rs.struct_id.child_ids: + for rule in self.pool.get('hr.payroll.structure').browse(cr, uid, [child.id]): + lines = rule.rule_ids + for line in lines: amount = 0.0 if line.amount_type == 'per': try: @@ -680,7 +690,7 @@ class payment_category(osv.osv): 'user_id':fields.char('User', size=64, required=False, readonly=False), 'state':fields.char('Label', size=64, required=False, readonly=False), 'company_id':fields.many2one('res.company', 'Company', required=False), - 'contribute_ids':fields.one2many('company.contribution', 'category_id', 'Contributions', required=False), +# 'contribute_ids':fields.one2many('company.contribution', 'category_id', 'Contributions', required=False), } _defaults = { 'condition': lambda *a: 'True', @@ -701,7 +711,7 @@ class company_contribution(osv.osv): _name = 'company.contribution' _description = "Company Contribution" _columns = { - 'category_id':fields.many2one('hr.allounce.deduction.categoty', 'Heads', required=False), +# 'category_id':fields.many2one('hr.salary.rule', 'Heads', required=False), 'name':fields.char('Name', size=256, required=True, readonly=False), 'code':fields.char('Code', size=64, required=True, readonly=False), 'gratuity':fields.boolean('Use for Gratuity ?', required=False), @@ -965,22 +975,29 @@ class hr_payslip(osv.osv): 'net':slip.net, 'gross':slip.grows, } - for line in slip.line_ids: - base[line.code.lower()] = line.total - for contrib in line.category_id.contribute_ids: - if contrib.register_id: - value = eval(line.category_id.base, base) - company_contrib = register_pool.compute(cr, uid, contrib.id, value, context) - reg_line = { - 'name':line.name, - 'register_id': contrib.register_id.id, - 'code':line.code, - 'employee_id':slip.employee_id.id, - 'emp_deduction':line.total, - 'comp_deduction':company_contrib, - 'total':line.total + line.total - } - register_line_pool.create(cr, uid, reg_line) + rules = slip.contract_id.struct_id.rule_ids + if slip.contract_id.struct_id.child_ids: + for child in slip.contract_id.struct_id.child_ids: + for rule in self.pool.get('hr.payroll.structure').browse(cr, uid, [child.id]): + rules = rule.rule_ids + if rules: + for rl in rules: + if rl.contribute_ids: + base[rl.code.lower()] = rl.amount + for contrib in rl.contribute_ids: + if contrib.register_id: + value = eval(rl.category_id.base, base) + company_contrib = register_pool.compute(cr, uid, contrib.id, value, context) + reg_line = { + 'name':rl.name, + 'register_id': contrib.register_id.id, + 'code':rl.code, + 'employee_id':slip.employee_id.id, + 'emp_deduction':rl.amount, + 'comp_deduction':company_contrib, + 'total':rl.amount + rl.amount + } + register_line_pool.create(cr, uid, reg_line) self.write(cr, uid, ids, {'state':'confirm'}, context=context) return True @@ -1070,10 +1087,13 @@ class hr_payslip(osv.osv): contract = slip.employee_id.contract_id sal_type = contract.wage_type_id.type function = contract.struct_id.id + if contract.struct_id.child_ids: + for child in contract.struct_id.child_ids: + function = child.id lines = [] if function: - func = func_pool.read(cr, uid, function, ['line_ids'], context=context) - lines = slip_line_pool.browse(cr, uid, func['line_ids'], context=context) + func = func_pool.read(cr, uid, function, ['rule_ids'], context=context) + lines = self.pool.get('hr.salary.rule').browse(cr, uid, func['rule_ids'], context=context) #lines += slip.employee_id.line_ids @@ -1137,13 +1157,13 @@ class hr_payslip(osv.osv): elif line.amount_type == 'fix': value = line.amount elif line.amount_type == 'func': - value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) + value = self.pool.get('hr.salary.rule').execute_function(cr, uid, line.id, amt, context) line.amount = value else: if line.amount_type in ('fix', 'per'): value = line.amount elif line.amount_type == 'func': - value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) + value = self.pool.get('hr.salary.rule').execute_function(cr, uid, line.id, amt, context) line.amount = value if line.type == 'allowance': all_per += percent @@ -1151,14 +1171,29 @@ class hr_payslip(osv.osv): elif line.type == 'deduction': ded_per += percent ded_fix += value - vals = { +# vals = { +# 'amount':line.amount, +# 'slip_id':slip.id, +# 'employee_id':False, +# 'function_id':False, +# 'base':base +# } +# slip_line_pool.copy(cr, uid, line.id, vals, {}) + res = { + 'name':line.name, + 'code':line.code, + 'type':line.type, + 'amount_type':line.amount_type, + 'category_id':line.category_id.id, + 'sequence':line.sequence, 'amount':line.amount, 'slip_id':slip.id, 'employee_id':False, 'function_id':False, 'base':base } - slip_line_pool.copy(cr, uid, line.id, vals, {}) + if not((line.amount < line.min_range) or (line.amount > line.max_range)): + slip_line_pool.create(cr, uid, res, context=context) if sal_type in ('gross', 'net'): sal = contract.wage if sal_type == 'net': @@ -1353,6 +1388,22 @@ class hr_payslip_line(osv.osv): hr_payslip_line() +class hr_salary_rule(osv.osv): + + _inherit = 'hr.payslip.line' + _name = 'hr.salary.rule' + _columns = { + 'active': fields.boolean('Active'), + 'min_range': fields.float('Minimum Range', required=False), + 'max_range': fields.float('Maximum Range', required=False), + 'contribute_ids':fields.one2many('company.contribution', 'category_id', 'Contributions', required=False), + } + _defaults = { + 'active': 1 + } + +hr_salary_rule() + class hr_payslip_line_line(osv.osv): ''' Function Line @@ -1374,6 +1425,24 @@ class hr_payslip_line_line(osv.osv): } hr_payslip_line_line() +class hr_payroll_structure(osv.osv): + + _inherit = 'hr.payroll.structure' + _columns = { + 'rule_ids':fields.many2many('hr.salary.rule', 'structure_salary_rule_rel', 'struct_id', 'rule_id', 'Salary Rules', readonly=False), + } + +hr_payroll_structure() + +class company_contribution(osv.osv): + + _inherit = 'company.contribution' + _columns = { + 'category_id':fields.many2one('hr.salary.rule', 'Heads', required=False), + } + +company_contribution() + class hr_employee(osv.osv): ''' Employee diff --git a/addons/hr_payroll/hr_payroll_view.xml b/addons/hr_payroll/hr_payroll_view.xml index e2c54097cf7..da35aef070c 100644 --- a/addons/hr_payroll/hr_payroll_view.xml +++ b/addons/hr_payroll/hr_payroll_view.xml @@ -190,7 +190,8 @@ - + + @@ -207,7 +208,7 @@ - + + + + + + + + + + + + + + @@ -545,7 +559,7 @@ - + @@ -969,6 +983,115 @@ id="act_hr_employee_payslip_list" groups="base.group_hr_manager"/> + + + + hr.salary.rule.tree + hr.salary.rule + tree + + + + + + + + + hr.salary.rule.form + hr.salary.rule + form + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + Salary Rules + hr.salary.rule + form + + + + From deec616aa540616ac96fa6357c128b53114b1b89 Mon Sep 17 00:00:00 2001 From: mtr Date: Fri, 25 Feb 2011 18:37:26 +0530 Subject: [PATCH 0002/1110] [IMP] hr_payroll: improved Salary Head,added 'salary.head.type' object and 'salary rule' as m2m on employee,removed one2many 'Child Salary Structure' bzr revid: mtr@mtr-20110225130726-5bc1b5hf2cgefeo3 --- addons/hr_payroll/hr_payroll.py | 113 +++++++---------- addons/hr_payroll/hr_payroll_data.xml | 45 ++++--- addons/hr_payroll/hr_payroll_demo.xml | 8 +- addons/hr_payroll/hr_payroll_view.xml | 174 +++++++++----------------- 4 files changed, 136 insertions(+), 204 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 4318ef2de87..20af0cd4b4f 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -97,8 +97,7 @@ class hr_payroll_structure(osv.osv): 'line_ids':fields.one2many('hr.payslip.line', 'function_id', 'Salary Structure', required=False), 'company_id':fields.many2one('res.company', 'Company', required=False), 'note': fields.text('Description'), - 'struct_id':fields.many2one('hr.payroll.structure', 'Parent Salary Structure', select=True), - 'child_ids':fields.one2many('hr.payroll.structure', 'struct_id', 'Child Salary Sructure'), + 'struct_id':fields.many2one('hr.payroll.structure', 'Parent Structure'), } _defaults = { 'company_id': lambda self, cr, uid, context: \ @@ -160,10 +159,6 @@ class hr_contract(osv.osv): sal_type = contract.wage_type_id.type # function = contract.struct_id.id lines = contract.struct_id.rule_ids - if contract.struct_id.child_ids: - for child in contract.struct_id.child_ids: - for rule in self.pool.get('hr.payroll.structure').browse(cr, uid, [child.id]): - lines = rule.rule_ids if not contract.struct_id: res[contract.id] = obj['basic'] continue @@ -220,10 +215,10 @@ class hr_contract(osv.osv): elif line.amount_type == 'func': value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) line.amount = value - if line.type == 'allowance': + if line.type.name == 'allowance': all_per += percent all_fix += value - elif line.type == 'deduction': + elif line.type.name == 'deduction': ded_per += percent ded_fix += value if sal_type in ('gross', 'net'): @@ -282,10 +277,6 @@ class hr_contract(osv.osv): vals[rs.id] = record continue lines = rs.struct_id.rule_ids - if rs.struct_id.child_ids: - for child in rs.struct_id.child_ids: - for rule in self.pool.get('hr.payroll.structure').browse(cr, uid, [child.id]): - lines = rule.rule_ids for line in lines: amount = 0.0 if line.amount_type == 'per': @@ -298,16 +289,10 @@ class hr_contract(osv.osv): cd = line.category_id.code.lower() obj[cd] = amount - if line.type == 'allowance': + if line.type.name == 'allowance': allow += amount - elif line.type == 'deduction': + elif line.type.name == 'deduction': deduct += amount - elif line.type == 'advance': - others += amount - elif line.type == 'loan': - others += amount - elif line.type == 'otherpay': - others += amount record = { 'advantages_gross':round(allow), 'advantages_net':round(deduct), @@ -481,7 +466,7 @@ class payroll_register(osv.osv): 'advice_id':pid, 'name':slip.employee_id.bank_account_id.acc_number, 'employee_id':slip.employee_id.id, - 'amount':slip.other_pay + slip.net, + 'amount':slip.net, 'bysal':slip.net } id = advice_line_pool.create(cr, uid, pline, context=context) @@ -585,7 +570,7 @@ class payroll_advice_line(osv.osv): if sids: slip = slip_pool.browse(cr, uid, sids[0], context=context) vals['name'] = slip.employee_id.identification_id - vals['amount'] = slip.net + slip.other_pay + vals['amount'] = slip.net vals['bysal'] = slip.net return { 'value':vals @@ -661,6 +646,19 @@ class contrib_register_line(osv.osv): } contrib_register_line() +class salary_head_type(osv.osv): + """ + Salary Head Type + """ + + _name = 'salary.head.type' + _description = 'Salary Head Type' + _columns = { + 'name':fields.char('Type Name', size=64, required=True, readonly=False), + } + +salary_head_type() + class payment_category(osv.osv): """ Allowance, Deduction Heads @@ -673,16 +671,7 @@ class payment_category(osv.osv): _columns = { 'name':fields.char('Category Name', size=64, required=True, readonly=False), 'code':fields.char('Category Code', size=64, required=True, readonly=False), - 'type':fields.selection([ - ('allowance','Allowance'), - ('deduction','Deduction'), - ('leaves','Leaves'), - ('advance','Advance'), - ('loan','Loan'), - ('installment','Loan Installment'), - ('otherpay','Other Payment'), - ('otherdeduct','Other Deduction'), - ],'Type', select=True, required=True), + 'type':fields.many2one('salary.head.type', 'Type', required=True), 'base':fields.text('Based on', required=True, readonly=False, help='This will use to computer the % fields values, in general its on basic, but You can use all heads code field in small letter as a variable name i.e. hra, ma, lta, etc...., also you can use, static varible basic'), 'condition':fields.char('Condition', size=1024, required=True, readonly=False, help='Applied this head for calculation if condition is true'), 'sequence': fields.integer('Sequence', required=True, help='Use to arrange calculation sequence'), @@ -690,7 +679,11 @@ class payment_category(osv.osv): 'user_id':fields.char('User', size=64, required=False, readonly=False), 'state':fields.char('Label', size=64, required=False, readonly=False), 'company_id':fields.many2one('res.company', 'Company', required=False), -# 'contribute_ids':fields.one2many('company.contribution', 'category_id', 'Contributions', required=False), + 'active': fields.boolean('Active'), + 'computation_based':fields.selection([ + ('rules','List of Rules'), + ('exp','Expression'), + ],'Computation Based On', select=True, required=True), } _defaults = { 'condition': lambda *a: 'True', @@ -699,6 +692,8 @@ class payment_category(osv.osv): 'company_id': lambda self, cr, uid, context: \ self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id, + 'active': 1, + 'computation_based':'rules', } payment_category() @@ -848,20 +843,14 @@ class hr_payslip(osv.osv): cd = line.category_id.code.lower() obj[cd] = amount contrib = 0.0 - if line.type == 'allowance': + if line.type.name == 'allowance': allow += amount others += contrib amount -= contrib - elif line.type == 'deduction': + elif line.type.name == 'deduction': deduct += amount others -= contrib amount += contrib - elif line.type == 'advance': - others += amount - elif line.type == 'loan': - others += amount - elif line.type == 'otherpay': - others += amount slip_line_obj.write(cr, uid, [line.id], {'total':amount}, context=context) record = { @@ -976,10 +965,6 @@ class hr_payslip(osv.osv): 'gross':slip.grows, } rules = slip.contract_id.struct_id.rule_ids - if slip.contract_id.struct_id.child_ids: - for child in slip.contract_id.struct_id.child_ids: - for rule in self.pool.get('hr.payroll.structure').browse(cr, uid, [child.id]): - rules = rule.rule_ids if rules: for rl in rules: if rl.contribute_ids: @@ -1087,9 +1072,6 @@ class hr_payslip(osv.osv): contract = slip.employee_id.contract_id sal_type = contract.wage_type_id.type function = contract.struct_id.id - if contract.struct_id.child_ids: - for child in contract.struct_id.child_ids: - function = child.id lines = [] if function: func = func_pool.read(cr, uid, function, ['rule_ids'], context=context) @@ -1165,10 +1147,10 @@ class hr_payslip(osv.osv): elif line.amount_type == 'func': value = self.pool.get('hr.salary.rule').execute_function(cr, uid, line.id, amt, context) line.amount = value - if line.type == 'allowance': + if line.type.name == 'allowance': all_per += percent all_fix += value - elif line.type == 'deduction': + elif line.type.name == 'deduction': ded_per += percent ded_fix += value # vals = { @@ -1182,7 +1164,7 @@ class hr_payslip(osv.osv): res = { 'name':line.name, 'code':line.code, - 'type':line.type, + 'type':line.type.id, 'amount_type':line.amount_type, 'category_id':line.category_id.id, 'sequence':line.sequence, @@ -1192,8 +1174,11 @@ class hr_payslip(osv.osv): 'function_id':False, 'base':base } - if not((line.amount < line.min_range) or (line.amount > line.max_range)): - slip_line_pool.create(cr, uid, res, context=context) + if line.min_range or line.max_range: + if not((line.amount < line.min_range) or (line.amount > line.max_range)): + slip_line_pool.create(cr, uid, res, context=context) + else: + slip_line_pool.create(cr, uid, res, context=context) if sal_type in ('gross', 'net'): sal = contract.wage if sal_type == 'net': @@ -1326,7 +1311,7 @@ class hr_payslip_line(osv.osv): 'sequence':category.sequence, 'name':category.name, 'code':category.code, - 'type':category.type + 'type':category.type.id }) return {'value':res} @@ -1345,18 +1330,7 @@ class hr_payslip_line(osv.osv): 'base':fields.char('Formula', size=1024, required=False, readonly=False), 'code':fields.char('Code', size=64, required=False, readonly=False), 'category_id':fields.many2one('hr.allounce.deduction.categoty', 'Category', required=True), - 'type':fields.selection([ - ('allowance','Allowance'), - ('deduction','Deduction'), - ('leaves','Leaves'), - ('advance','Advance'), - ('loan','Loan'), - ('installment','Loan Installment'), - ('otherpay','Other Payment'), - ('otherdeduct','Other Deduction'), - ],'Type', select=True, required=True), - #TODO: link type to the category_id instead of define again - #'type': fields.related('category_id','type', type='selection', size=64, relation='hr.allounce.deduction.categoty', string='Type', store=True), + 'type':fields.many2one('salary.head.type', 'Type', required=True), 'amount_type':fields.selection([ ('per','Percentage (%)'), ('fix','Fixed Amount'), @@ -1429,7 +1403,7 @@ class hr_payroll_structure(osv.osv): _inherit = 'hr.payroll.structure' _columns = { - 'rule_ids':fields.many2many('hr.salary.rule', 'structure_salary_rule_rel', 'struct_id', 'rule_id', 'Salary Rules', readonly=False), + 'rule_ids':fields.many2many('hr.salary.rule', 'hr_structure_salary_rule_rel', 'struct_id', 'rule_id', 'Salary Rules', readonly=False), } hr_payroll_structure() @@ -1485,9 +1459,9 @@ class hr_employee(osv.osv): elif line.amount_type == 'fix': amount = line.amount - if line.type == 'allowance': + if line.type.name == 'allowance': allowance += amount - elif line.type == 'deduction': + elif line.type.name == 'deduction': deduction += amount vals[employee.id] = { @@ -1510,6 +1484,7 @@ class hr_employee(osv.osv): 'net': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Net Salary', digits=(14,2)), 'advantages_net': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Deductions', digits=(14,2)), 'advantages_gross': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Allowances', digits=(14,2)), + 'emp_sal_rule_ids':fields.many2many('hr.salary.rule', 'hr_emp_salary_rule_rel', 'employee_id', 'rule_id', 'Salary Rules', readonly=False), } hr_employee() diff --git a/addons/hr_payroll/hr_payroll_data.xml b/addons/hr_payroll/hr_payroll_data.xml index cafc02cc1db..10547e2b89b 100644 --- a/addons/hr_payroll/hr_payroll_data.xml +++ b/addons/hr_payroll/hr_payroll_data.xml @@ -1,119 +1,128 @@ + + + allowance + + + + deduction + + HRA - allowance + House Rent Allowance CA - allowance + Conveyance Allowance MA - allowance + Medical Allowance TELA - allowance + Telephone Allowance LTA - allowance + Leave Travel Allowance NA - allowance + Newspaper Allowance TA - allowance + Traveling Allowance FA - allowance + Food Allowance DA - allowance + Dearness Allowance PF - deduction + Provident Fund PT - deduction + Professional Tax WF - deduction + Welfare TDS - deduction + Tax Deduct at Source LWP - deduction + Leave without pay FC - deduction + Food Coupons ESI - deduction + Employee's State Insurance - + diff --git a/addons/hr_payroll/hr_payroll_demo.xml b/addons/hr_payroll/hr_payroll_demo.xml index bc94426999e..6d7bd5a65fc 100644 --- a/addons/hr_payroll/hr_payroll_demo.xml +++ b/addons/hr_payroll/hr_payroll_demo.xml @@ -14,7 +14,7 @@ HRA - allowance + House Rent Allowance @@ -25,7 +25,7 @@ CA - allowance + Conveyance Allowance @@ -36,7 +36,7 @@ PT - deduction + Professional Tax @@ -47,7 +47,7 @@ PF - deduction + Provident Fund diff --git a/addons/hr_payroll/hr_payroll_view.xml b/addons/hr_payroll/hr_payroll_view.xml index da35aef070c..91a0849c6c8 100644 --- a/addons/hr_payroll/hr_payroll_view.xml +++ b/addons/hr_payroll/hr_payroll_view.xml @@ -107,6 +107,11 @@ + + + + + @@ -190,7 +195,6 @@ - @@ -206,63 +210,14 @@ + - - - - - - - - - - - - - + + + + @@ -462,7 +417,6 @@ - @@ -544,59 +498,23 @@ + + - + + - - @@ -1004,10 +922,10 @@
- + @@ -1034,12 +952,8 @@ - - - - - + @@ -1076,22 +990,56 @@ + + + +
- - Salary Rules - hr.salary.rule - form - - - + + + Salary Rules + hr.salary.rule + form + + + + + + + salary.head.type.tree + salary.head.type + tree + + + + + + + + + salary.head.type.form + salary.head.type + form + +
+ + +
+
+ + + Salary Head Type + salary.head.type + form + + + + +
From e703cdfad180ecff6d11a766df983c30f250276c Mon Sep 17 00:00:00 2001 From: mtr Date: Fri, 25 Feb 2011 19:03:39 +0530 Subject: [PATCH 0003/1110] [IMP] hr_payroll:added Child Rules as one2many on Salary Rules bzr revid: mtr@mtr-20110225133339-0f0711n4kaijl6p6 --- addons/hr_payroll/hr_payroll.py | 3 +++ addons/hr_payroll/hr_payroll_view.xml | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 20af0cd4b4f..04499f54a74 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -1371,6 +1371,9 @@ class hr_salary_rule(osv.osv): 'min_range': fields.float('Minimum Range', required=False), 'max_range': fields.float('Maximum Range', required=False), 'contribute_ids':fields.one2many('company.contribution', 'category_id', 'Contributions', required=False), + 'sal_rule_id':fields.many2one('hr.salary.rule', 'Parent Salary Structure', select=True), + 'child_depend':fields.boolean('Tax on Children'), + 'child_ids':fields.one2many('hr.salary.rule', 'sal_rule_id', 'Child Salary Sructure'), } _defaults = { 'active': 1 diff --git a/addons/hr_payroll/hr_payroll_view.xml b/addons/hr_payroll/hr_payroll_view.xml index 91a0849c6c8..d73e6cc310c 100644 --- a/addons/hr_payroll/hr_payroll_view.xml +++ b/addons/hr_payroll/hr_payroll_view.xml @@ -940,6 +940,11 @@ + + + + + From 4196288c4ea565f8678d93f3d701ebc4f7c0348e Mon Sep 17 00:00:00 2001 From: mtr Date: Fri, 25 Feb 2011 19:05:52 +0530 Subject: [PATCH 0004/1110] [IMP] hr_payroll:improved the string for boolean field on salary rule bzr revid: mtr@mtr-20110225133552-po1y1y7gu14rhk6b --- addons/hr_payroll/hr_payroll.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 04499f54a74..3c6199ebef8 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -1372,7 +1372,7 @@ class hr_salary_rule(osv.osv): 'max_range': fields.float('Maximum Range', required=False), 'contribute_ids':fields.one2many('company.contribution', 'category_id', 'Contributions', required=False), 'sal_rule_id':fields.many2one('hr.salary.rule', 'Parent Salary Structure', select=True), - 'child_depend':fields.boolean('Tax on Children'), + 'child_depend':fields.boolean('Children Rule'), 'child_ids':fields.one2many('hr.salary.rule', 'sal_rule_id', 'Child Salary Sructure'), } _defaults = { From 3f1aeeef70aec162795cc901a11a032ed3027fc1 Mon Sep 17 00:00:00 2001 From: "psi (Open ERP)" Date: Fri, 25 Feb 2011 19:13:14 +0530 Subject: [PATCH 0005/1110] [IMP] hr_payroll: Add new tab Holiday on hr.payslip object and comment unwanted calculation for gross and net, remove wage_type_id bzr revid: psi@tinyerp.co.in-20110225134314-zopq8bwlwmh61glr --- addons/hr_contract/hr_contract.py | 8 +- addons/hr_contract/hr_contract_view.xml | 30 +- addons/hr_payroll/hr_payroll.py | 823 ++++++++++++++++-------- addons/hr_payroll/hr_payroll_view.xml | 29 +- 4 files changed, 607 insertions(+), 283 deletions(-) diff --git a/addons/hr_contract/hr_contract.py b/addons/hr_contract/hr_contract.py index 7ed2d16d6b7..e99eb43e849 100644 --- a/addons/hr_contract/hr_contract.py +++ b/addons/hr_contract/hr_contract.py @@ -71,11 +71,11 @@ class hr_contract_wage_type(osv.osv): _columns = { 'name': fields.char('Wage Type Name', size=50, required=True, select=True), 'period_id': fields.many2one('hr.contract.wage.type.period', 'Wage Period', required=True), - 'type': fields.selection([('gross','Gross'), ('net','Net')], 'Type', required=True), - 'factor_type': fields.float('Factor for hour cost', digits=(12,4), required=True, help='This field is used by the timesheet system to compute the price of an hour of work wased on the contract of the employee') +# 'type': fields.selection([('gross','Gross'), ('net','Net')], 'Type', required=True), + 'factor_type': fields.float('Factor for hour cost', digits=(12,4), required=True, help='This field is used by the timesheet system to compute the price of an hour of work based on the contract of the employee') } _defaults = { - 'type': 'gross', +# 'type': 'gross', 'factor_type': 1.8 } hr_contract_wage_type() @@ -103,7 +103,7 @@ class hr_contract(osv.osv): 'trial_date_start': fields.date('Trial Start Date'), 'trial_date_end': fields.date('Trial End Date'), 'working_hours': fields.many2one('resource.calendar','Working Schedule'), - 'wage_type_id': fields.many2one('hr.contract.wage.type', 'Wage Type', required=True), +# 'wage_type_id': fields.many2one('hr.contract.wage.type', 'Wage Type', required=True), 'wage': fields.float('Wage', digits=(16,2), required=True), 'advantages': fields.text('Advantages'), 'advantages_net': fields.float('Net Advantages Value', digits=(16,2)), diff --git a/addons/hr_contract/hr_contract_view.xml b/addons/hr_contract/hr_contract_view.xml index cae7885a754..f65b518bed2 100644 --- a/addons/hr_contract/hr_contract_view.xml +++ b/addons/hr_contract/hr_contract_view.xml @@ -132,9 +132,9 @@ - - - + + + @@ -143,11 +143,11 @@ - - + + - + @@ -165,7 +165,7 @@ - + @@ -175,10 +175,10 @@ - + - + @@ -204,10 +204,10 @@ - + - + @@ -270,11 +270,11 @@ - diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index b29bd1312ac..6d5574caf1c 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -43,25 +43,25 @@ def prev_bounds(cdate=False): prev_end = next_month - timedelta(days=1) return this_first, prev_end -class hr_contract_wage_type(osv.osv): - """ - Wage types - Basic = Basic Salary - Grows = Basic + Allowances - New = Grows - Deductions - """ - - _inherit = 'hr.contract.wage.type' - _columns = { - 'type': fields.selection([('basic','Basic'), ('gross','Gross'), ('net','Net')], 'Type', required=True), - } - -hr_contract_wage_type() +#class hr_contract_wage_type(osv.osv): +# """ +# Wage types +# Basic = Basic Salary +# Grows = Basic + Allowances +# Net = Grows - Deductions +# """ +# +# _inherit = 'hr.contract.wage.type' +# _columns = { +# 'type': fields.selection([('basic','Basic'), ('gross','Gross'), ('net','Net')], 'Type', required=True), +# } +# +#hr_contract_wage_type() class hr_passport(osv.osv): """ Employee Passport - Passport based Contratacts for Employees + Passport based Contracts for Employees """ _name = 'hr.passport' @@ -85,7 +85,7 @@ class hr_payroll_structure(osv.osv): """ Salary structure used to defined - Basic - - Allowlance + - Allowances - Deductions """ @@ -115,10 +115,9 @@ class hr_payroll_structure(osv.osv): @return: returns a id of newly created record """ - code = self.browse(cr, uid, id, context=context).code default = { - 'code':code+"(copy)", - 'company_id':self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id + 'code': self.browse(cr, uid, id, context=context).code+"(copy)", + 'company_id': self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id } return super(hr_payroll_structure, self).copy(cr, uid, id, default, context=context) @@ -127,151 +126,150 @@ hr_payroll_structure() class hr_contract(osv.osv): """ Employee contract based on the visa, work permits - allowas to configure different Salary structure + allows to configure different Salary structure """ - def compute_basic(self, cr, uid, ids, context=None): - res = {} - if context is None: - context = {} - ids += context.get('employee_structure', []) +# def compute_basic(self, cr, uid, ids, context=None): +# res = {} +# if context is None: +# context = {} +# ids += context.get('employee_structure', []) # Unused line employee_structure is not in context +# +# slip_line_pool = self.pool.get('hr.payslip.line') +# +# for contract in self.browse(cr, uid, ids, context=context): +# all_per = 0.0 +# ded_per = 0.0 +# all_fix = 0.0 +# ded_fix = 0.0 +# obj = {'basic':0.0} +# update = {} +# if contract.wage_type_id.type == 'gross': +# obj['gross'] = contract.wage +# update['gross'] = contract.wage +# if contract.wage_type_id.type == 'net': +# obj['net'] = contract.wage +# update['net'] = contract.wage +# if contract.wage_type_id.type == 'basic': +# obj['basic'] = contract.wage +# update['basic'] = contract.wage +# sal_type = contract.wage_type_id.type +## function = contract.struct_id.id +# lines = contract.struct_id.line_ids +# if not contract.struct_id: +# res[contract.id] = obj['basic'] +# continue +# +# ad = [] +# for line in lines: +# cd = line.code.lower() +# obj[cd] = line.amount or 0.0 +# +# for line in lines: +# if line.category_id.code in ad: +# continue +# ad.append(line.category_id.code) +# cd = line.category_id.code.lower() +# calculate = False +# try: +# exp = line.category_id.condition +# +# calculate = eval(exp, obj) +# except Exception, e: +# raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) +# +# if not calculate: +# continue +# +# percent = 0.0 +# value = 0.0 +# base = False +## company_contrib = 0.0 +# base = line.category_id.base +# +# try: +# #Please have a look at the configuration guide. +# amt = eval(base, obj) +# except Exception, e: +# raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) +# +# if sal_type in ('gross', 'net'): +# if line.amount_type == 'per': +# percent = line.amount +# if amt > 1: +# value = percent * amt +# elif amt > 0 and amt <= 1: +# percent = percent * amt +# if value > 0: +# percent = 0.0 +# elif line.amount_type == 'fix': +# value = line.amount +# elif line.amount_type == 'func': +# value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) +# line.amount = value +# else: +# if line.amount_type in ('fix', 'per'): +# value = line.amount +# elif line.amount_type == 'func': +# value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) +# line.amount = value +# if line.type == 'allowance': +# all_per += percent +# all_fix += value +# elif line.type == 'deduction': +# ded_per += percent +# ded_fix += value +# if sal_type in ('gross', 'net'): +# sal = contract.wage +# if sal_type == 'net': +# sal += ded_fix +# sal -= all_fix +# per = 0.0 +# if sal_type == 'net': +# per = (all_per - ded_per) +# else: +# per = all_per +# if per <=0: +# per *= -1 +# final = (per * 100) + 100 +# basic = (sal * 100) / final +# else: +# basic = contract.wage +# res[contract.id] = basic +# +# return res - slip_line_pool = self.pool.get('hr.payslip.line') - - for contract in self.browse(cr, uid, ids, context=context): - all_per = 0.0 - ded_per = 0.0 - all_fix = 0.0 - ded_fix = 0.0 - obj = {'basic':0.0} - update = {} - if contract.wage_type_id.type == 'gross': - obj['gross'] = contract.wage - update['gross'] = contract.wage - if contract.wage_type_id.type == 'net': - obj['net'] = contract.wage - update['net'] = contract.wage - if contract.wage_type_id.type == 'basic': - obj['basic'] = contract.wage - update['basic'] = contract.wage - - sal_type = contract.wage_type_id.type -# function = contract.struct_id.id - lines = contract.struct_id.line_ids - if not contract.struct_id: - res[contract.id] = obj['basic'] - continue - - ad = [] - for line in lines: - cd = line.code.lower() - obj[cd] = line.amount or 0.0 - - for line in lines: - if line.category_id.code in ad: - continue - ad.append(line.category_id.code) - cd = line.category_id.code.lower() - calculate = False - try: - exp = line.category_id.condition - calculate = eval(exp, obj) - except Exception, e: - raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) - - if not calculate: - continue - - percent = 0.0 - value = 0.0 - base = False -# company_contrib = 0.0 - base = line.category_id.base - - try: - #Please have a look at the configuration guide. - amt = eval(base, obj) - except Exception, e: - raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) - - if sal_type in ('gross', 'net'): - if line.amount_type == 'per': - percent = line.amount - if amt > 1: - value = percent * amt - elif amt > 0 and amt <= 1: - percent = percent * amt - if value > 0: - percent = 0.0 - elif line.amount_type == 'fix': - value = line.amount - elif line.amount_type == 'func': - value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) - line.amount = value - else: - if line.amount_type in ('fix', 'per'): - value = line.amount - elif line.amount_type == 'func': - value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) - line.amount = value - if line.type == 'allowance': - all_per += percent - all_fix += value - elif line.type == 'deduction': - ded_per += percent - ded_fix += value - if sal_type in ('gross', 'net'): - sal = contract.wage - if sal_type == 'net': - sal += ded_fix - sal -= all_fix - per = 0.0 - if sal_type == 'net': - per = (all_per - ded_per) - else: - per = all_per - if per <=0: - per *= -1 - final = (per * 100) + 100 - basic = (sal * 100) / final - else: - basic = contract.wage - - res[contract.id] = basic - - return res - - def check_vals(self, val1, val2): - if val1 == val2 and val1 == 0: - return True - return False +# def check_vals(self, val1, val2): +# if val1 == val2 and val1 == 0: +# return True +# return False def _calculate_salary(self, cr, uid, ids, field_names, arg, context=None): - res = self.compute_basic(cr, uid, ids, context=context) +# res = self.compute_basic(cr, uid, ids, context=context) vals = {} for rs in self.browse(cr, uid, ids, context=context): allow = 0.0 deduct = 0.0 others = 0.0 - obj = {'basic':res[rs.id], 'gross':0.0, 'net':0.0} - if rs.wage_type_id.type == 'gross': - obj['gross'] = rs.wage - if rs.wage_type_id.type == 'net': - obj['net'] = rs.net - +# obj = {'basic':res[rs.id], 'gross':0.0, 'net':0.0} +# if rs.wage_type_id.type == 'gross': +# obj['gross'] = rs.wage +# if rs.wage_type_id.type == 'net': +# obj['net'] = rs.net + obj = {'basic': rs.wage} if not rs.struct_id: - if self.check_vals(obj['basic'], obj['gross']): - obj['gross'] = obj['basic'] = obj['net'] - elif self.check_vals(obj['gross'], obj['net']): - obj['gross']= obj['net'] = obj['basic'] - elif self.check_vals(obj['net'], obj['basic']): - obj['net'] = obj['basic'] = obj['gross'] +# if self.check_vals(obj['basic'], obj['gross']): +# obj['gross'] = obj['basic'] = obj['net'] +# elif self.check_vals(obj['gross'], obj['net']): +# obj['gross']= obj['net'] = obj['basic'] +# elif self.check_vals(obj['net'], obj['basic']): +# obj['net'] = obj['basic'] = obj['gross'] record = { 'advantages_gross':0.0, 'advantages_net':0.0, 'basic':obj['basic'], - 'gross':obj['gross'], - 'net':obj['net'] +# 'gross':obj['gross'], +# 'net':obj['net'] } vals[rs.id] = record continue @@ -287,7 +285,6 @@ class hr_contract(osv.osv): amount = line.amount cd = line.category_id.code.lower() obj[cd] = amount - if line.type == 'allowance': allow += amount elif line.type == 'deduction': @@ -302,8 +299,8 @@ class hr_contract(osv.osv): 'advantages_gross':round(allow), 'advantages_net':round(deduct), 'basic':obj['basic'], - 'gross':round(obj['basic'] + allow), - 'net':round(obj['basic'] + allow - deduct) +# 'gross':round(obj['basic'] + allow), +# 'net':round(obj['basic'] + allow - deduct) } vals[rs.id] = record @@ -319,13 +316,13 @@ class hr_contract(osv.osv): 'struct_id': fields.many2one('hr.payroll.structure', 'Salary Structure'), 'working_days_per_week': fields.integer('Working Days', help="No of Working days / week for an employee"), 'basic': fields.function(_calculate_salary, method=True, store=True, multi='dc', type='float', string='Basic Salary', digits=(14,2)), - 'gross': fields.function(_calculate_salary, method=True, store=True, multi='dc', type='float', string='Gross Salary', digits=(14,2)), - 'net': fields.function(_calculate_salary, method=True, store=True, multi='dc', type='float', string='Net Salary', digits=(14,2)), +# 'gross': fields.function(_calculate_salary, method=True, store=True, multi='dc', type='float', string='Gross Salary', digits=(14,2)), +# 'net': fields.function(_calculate_salary, method=True, store=True, multi='dc', type='float', string='Net Salary', digits=(14,2)), 'advantages_net': fields.function(_calculate_salary, method=True, store=True, multi='dc', type='float', string='Deductions', digits=(14,2)), 'advantages_gross': fields.function(_calculate_salary, method=True, store=True, multi='dc', type='float', string='Allowances', digits=(14,2)), } _defaults = { - 'working_days_per_week': lambda *a: 5, + 'working_days_per_week': 5, } hr_contract() @@ -347,14 +344,14 @@ class payroll_register(osv.osv): for slip in register.line_ids: allounce += slip.allounce deduction += slip.deduction - net += slip.net - grows += slip.grows +# net += slip.net +# grows += slip.grows res[register.id] = { 'allounce':allounce, 'deduction':deduction, - 'net':net, - 'grows':grows +# 'net':net, +# 'grows':grows } return res @@ -374,8 +371,8 @@ class payroll_register(osv.osv): ],'State', select=True, readonly=True), 'active':fields.boolean('Active', required=False), 'company_id':fields.many2one('res.company', 'Company', required=False), - 'grows': fields.function(_calculate, method=True, store=True, multi='dc', string='Gross Salary', type='float', digits=(16, 4)), - 'net': fields.function(_calculate, method=True, store=True, multi='dc', string='Net Salary', digits=(16, 4)), +# 'grows': fields.function(_calculate, method=True, store=True, multi='dc', string='Gross Salary', type='float', digits=(16, 4)), +# 'net': fields.function(_calculate, method=True, store=True, multi='dc', string='Net Salary', digits=(16, 4)), 'allounce': fields.function(_calculate, method=True, store=True, multi='dc', string='Allowance', digits=(16, 4)), 'deduction': fields.function(_calculate, method=True, store=True, multi='dc', string='Deduction', digits=(16, 4)), 'note': fields.text('Description'), @@ -384,8 +381,8 @@ class payroll_register(osv.osv): _defaults = { 'date': lambda *a: time.strftime('%Y-%m-%d'), - 'state': lambda *a: 'new', - 'active': lambda *a: True, + 'state': 'new', + 'active': True, 'company_id': lambda self, cr, uid, context: \ self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id, @@ -471,8 +468,8 @@ class payroll_register(osv.osv): 'advice_id':pid, 'name':slip.employee_id.bank_account_id.acc_number, 'employee_id':slip.employee_id.id, - 'amount':slip.other_pay + slip.net, - 'bysal':slip.net +# 'amount':slip.other_pay + slip.net, #PSI@ Need to improve +# 'bysal':slip.net #PSI@ Need to improve } id = advice_line_pool.create(cr, uid, pline, context=context) @@ -517,7 +514,7 @@ class payroll_advice(osv.osv): } _defaults = { 'date': lambda *a: time.strftime('%Y-%m-%d'), - 'state': lambda *a: 'draft', + 'state': 'draft', 'company_id': lambda self, cr, uid, context: \ self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id, @@ -562,7 +559,7 @@ class payroll_advice_line(osv.osv): 'flag':fields.char('D/C', size=8, required=True, readonly=False), } _defaults = { - 'flag': lambda *a: 'C', + 'flag': 'C', } def onchange_employee_id(self, cr, uid, ids, ddate, employee_id, context=None): @@ -575,8 +572,8 @@ class payroll_advice_line(osv.osv): if sids: slip = slip_pool.browse(cr, uid, sids[0], context=context) vals['name'] = slip.employee_id.identification_id - vals['amount'] = slip.net + slip.other_pay - vals['bysal'] = slip.net +# vals['amount'] = slip.net + slip.other_pay #PSI@ Need to improve (slip.net should replace by someother value) +# vals['bysal'] = slip.net #PSI@ Need to improve (slip.net should replace by someother value) return { 'value':vals } @@ -815,17 +812,19 @@ class hr_payslip(osv.osv): _description = 'Pay Slip' def _calculate(self, cr, uid, ids, field_names, arg, context=None): + if not ids: return {} slip_line_obj = self.pool.get('hr.payslip.line') res = {} for rs in self.browse(cr, uid, ids, context=context): allow = 0.0 deduct = 0.0 others = 0.0 - obj = {'basic':rs.basic} - if rs.igross > 0: - obj['gross'] = rs.igross - if rs.inet > 0: - obj['net'] = rs.inet + contract = rs.employee_id.contract_id + obj = {'basic':contract.wage} +# if rs.igross > 0: +# obj['gross'] = rs.igross +# if rs.inet > 0: +# obj['net'] = rs.inet for line in rs.line_ids: amount = 0.0 if line.amount_type == 'per': @@ -855,12 +854,13 @@ class hr_payslip(osv.osv): slip_line_obj.write(cr, uid, [line.id], {'total':amount}, context=context) record = { - 'allounce':allow, - 'deduction':deduct, - 'grows':rs.basic + allow, - 'net':rs.basic + allow - deduct, - 'other_pay':others, - 'total_pay':rs.basic + allow - deduct +# 'allounce':allow, +# 'deduction':deduct, +# 'grows':rs.basic + allow, +# 'net':rs.basic + allow - deduct, +# 'other_pay':others, + 'state': 'draft', + 'total_pay': abs(contract.wage + allow - deduct) } res[rs.id] = record return res @@ -870,7 +870,7 @@ class hr_payslip(osv.osv): 'register_id':fields.many2one('hr.payroll.register', 'Register', required=False, readonly=True, states={'new': [('readonly', False)]}), 'name':fields.char('Name', size=64, required=False, readonly=True, states={'new': [('readonly', False)]}), 'number':fields.char('Number', size=64, required=False, readonly=True), - 'employee_id':fields.many2one('hr.employee', 'Employee', required=True, readonly=True, states={'new': [('readonly', False)]}), + 'employee_id':fields.many2one('hr.employee', 'Employee', required=True, readonly=True, states={'new': [('readonly', False)], 'draft': [('readonly', False)]}), 'date': fields.date('Date', readonly=True, states={'new': [('readonly', False)]}), 'state':fields.selection([ ('new','New Slip'), @@ -884,12 +884,13 @@ class hr_payslip(osv.osv): 'basic_before_leaves': fields.float('Basic Salary', readonly=True, digits_compute=dp.get_precision('Account')), 'leaves': fields.float('Leave Deductions', readonly=True, digits_compute=dp.get_precision('Account')), 'basic': fields.float('Net Basic', readonly=True, digits_compute=dp.get_precision('Account')), - 'grows': fields.function(_calculate, method=True, store=True, multi='dc', string='Gross Salary', digits_compute=dp.get_precision('Account')), - 'net': fields.function(_calculate, method=True, store=True, multi='dc', string='Net Salary', digits_compute=dp.get_precision('Account')), - 'allounce': fields.function(_calculate, method=True, store=True, multi='dc', string='Allowance', digits_compute=dp.get_precision('Account')), - 'deduction': fields.function(_calculate, method=True, store=True, multi='dc', string='Deduction', digits_compute=dp.get_precision('Account')), - 'other_pay': fields.function(_calculate, method=True, store=True, multi='dc', string='Others', digits_compute=dp.get_precision('Account')), - 'total_pay': fields.function(_calculate, method=True, store=True, multi='dc', string='Total Payment', digits_compute=dp.get_precision('Account')), +# 'grows': fields.function(_calculate, method=True, store=True, multi='dc', string='Gross Salary', digits_compute=dp.get_precision('Account')), +# 'net': fields.function(_calculate, method=True, store=True, multi='dc', string='Net Salary', digits_compute=dp.get_precision('Account')), +# 'allounce': fields.function(_calculate, method=True, store=True, multi='dc', string='Allowance', digits_compute=dp.get_precision('Account')), +# 'deduction': fields.function(_calculate, method=True, store=True, multi='dc', string='Deduction', digits_compute=dp.get_precision('Account')), +# 'other_pay': fields.function(_calculate, method=True, store=True, multi='dc', string='Others', digits_compute=dp.get_precision('Account')), +# 'total_pay': fields.function(_calculate, method=True, store=True, multi='dc', string='Total Payment', digits_compute=dp.get_precision('Account')), + 'total_pay': fields.float('Total Payment', readonly=True, digits_compute=dp.get_precision('Account')), 'line_ids':fields.one2many('hr.payslip.line', 'slip_id', 'Payslip Line', required=False, readonly=True, states={'draft': [('readonly', False)]}), 'company_id':fields.many2one('res.company', 'Company', required=False, readonly=True, states={'draft': [('readonly', False)]}), 'holiday_days': fields.float('No of Leaves', readonly=True), @@ -898,8 +899,9 @@ class hr_payslip(osv.osv): 'paid':fields.boolean('Paid ? ', required=False, readonly=True, states={'draft': [('readonly', False)]}), 'note':fields.text('Description'), 'contract_id':fields.many2one('hr.contract', 'Contract', required=False, readonly=True, states={'draft': [('readonly', False)]}), - 'igross': fields.float('Calculaton Field', readonly=True, digits=(16, 2), help="Calculation field used for internal calculation, do not place this on form"), - 'inet': fields.float('Calculaton Field', readonly=True, digits=(16, 2), help="Calculation field used for internal calculation, do not place this on form"), +# 'igross': fields.float('Calculaton Field', readonly=True, digits=(16, 2), help="Calculation field used for internal calculation, do not place this on form"), +# 'inet': fields.float('Calculaton Field', readonly=True, digits=(16, 2), help="Calculation field used for internal calculation, do not place this on form"), + 'holiday_ids':fields.one2many('hr.holidays', 'payslip_id', 'Payslip', required=False), } _defaults = { 'date': lambda *a: time.strftime('%Y-%m-%d'), @@ -962,8 +964,8 @@ class hr_payslip(osv.osv): for slip in self.browse(cr, uid, ids, context=context): base = { 'basic':slip.basic, - 'net':slip.net, - 'gross':slip.grows, +# 'net':slip.net, +# 'gross':slip.grows, } for line in slip.line_ids: base[line.code.lower()] = line.total @@ -986,12 +988,22 @@ class hr_payslip(osv.osv): return True def get_contract(self, cr, uid, employee, date, context=None): +# sql_req= ''' +# SELECT c.id as id, c.wage as wage, struct_id as function +# FROM hr_contract c +# LEFT JOIN hr_employee emp on (c.employee_id=emp.id) +# LEFT JOIN hr_contract_wage_type cwt on (cwt.id = c.wage_type_id) +# LEFT JOIN hr_contract_wage_type_period p on (cwt.period_id = p.id) #PSI@ improve as we need period but wage_type_id field removed +# WHERE +# (emp.id=%s) AND +# (date_start <= %s) AND +# (date_end IS NULL OR date_end >= %s) +# LIMIT 1 +# ''' sql_req= ''' SELECT c.id as id, c.wage as wage, struct_id as function FROM hr_contract c LEFT JOIN hr_employee emp on (c.employee_id=emp.id) - LEFT JOIN hr_contract_wage_type cwt on (cwt.id = c.wage_type_id) - LEFT JOIN hr_contract_wage_type_period p on (cwt.period_id = p.id) WHERE (emp.id=%s) AND (date_start <= %s) AND @@ -1025,10 +1037,33 @@ class hr_payslip(osv.osv): and state = 'validate' ''' % (dates[0], dates[1], slip.employee_id.id) cr.execute(sql) res = cr.fetchall() - if res: result = [x[0] for x in res] + return result + def _get_leaves1(self, cr, user, ddate, employee, context=None): + """ + Compute leaves for an employee + + @param cr: cursor to database + @param user: id of current user + @param slip: object of the hr.payroll.slip model + @param employee: object of the hr.employee model + @param context: context arguments, like lang, time zone + + @return: return a result + """ + result = [] + + dates = prev_bounds(ddate) + sql = '''select id from hr_holidays + where date_from >= '%s' and date_to <= '%s' + and employee_id = %s + and state = 'validate' ''' % (dates[0], dates[1], employee.id) + cr.execute(sql) + res = cr.fetchall() + if res: + result = [x[0] for x in res] return result def compute_sheet(self, cr, uid, ids, context=None): @@ -1039,7 +1074,6 @@ class hr_payslip(osv.osv): if context is None: context = {} date = self.read(cr, uid, ids, ['date'], context=context)[0]['date'] - #Check for the Holidays def get_days(start, end, month, year, calc_day): import datetime @@ -1068,7 +1102,7 @@ class hr_payslip(osv.osv): continue contract = slip.employee_id.contract_id - sal_type = contract.wage_type_id.type +# sal_type = contract.wage_type_id.type function = contract.struct_id.id lines = [] if function: @@ -1084,15 +1118,15 @@ class hr_payslip(osv.osv): ded_fix = 0.0 obj = {'basic':0.0} - if contract.wage_type_id.type == 'gross': - obj['gross'] = contract.wage - update['igross'] = contract.wage - if contract.wage_type_id.type == 'net': - obj['net'] = contract.wage - update['inet'] = contract.wage - if contract.wage_type_id.type == 'basic': - obj['basic'] = contract.wage - update['basic'] = contract.wage +# if contract.wage_type_id.type == 'gross': +# obj['gross'] = contract.wage +# update['igross'] = contract.wage +# if contract.wage_type_id.type == 'net': +# obj['net'] = contract.wage +# update['inet'] = contract.wage +# if contract.wage_type_id.type == 'basic': +# obj['basic'] = contract.wage +# update['basic'] = contract.wage for line in lines: cd = line.code.lower() @@ -1125,26 +1159,26 @@ class hr_payslip(osv.osv): except Exception, e: raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) - if sal_type in ('gross', 'net'): - if line.amount_type == 'per': - percent = line.amount - if amt > 1: - value = percent * amt - elif amt > 0 and amt <= 1: - percent = percent * amt - if value > 0: - percent = 0.0 - elif line.amount_type == 'fix': - value = line.amount - elif line.amount_type == 'func': - value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) - line.amount = value - else: - if line.amount_type in ('fix', 'per'): - value = line.amount - elif line.amount_type == 'func': - value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) - line.amount = value +# if sal_type in ('gross', 'net'): +# if line.amount_type == 'per': +# percent = line.amount +# if amt > 1: +# value = percent * amt +# elif amt > 0 and amt <= 1: +# percent = percent * amt +# if value > 0: +# percent = 0.0 +# elif line.amount_type == 'fix': +# value = line.amount +# elif line.amount_type == 'func': +# value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) +# line.amount = value +# else: + if line.amount_type in ('fix', 'per'): + value = line.amount + elif line.amount_type == 'func': + value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) + line.amount = value if line.type == 'allowance': all_per += percent all_fix += value @@ -1159,22 +1193,22 @@ class hr_payslip(osv.osv): 'base':base } slip_line_pool.copy(cr, uid, line.id, vals, {}) - if sal_type in ('gross', 'net'): - sal = contract.wage - if sal_type == 'net': - sal += ded_fix - sal -= all_fix - per = 0.0 - if sal_type == 'net': - per = (all_per - ded_per) - else: - per = all_per - if per <=0: - per *= -1 - final = (per * 100) + 100 - basic = (sal * 100) / final - else: - basic = contract.wage +# if sal_type in ('gross', 'net'): +# sal = contract.wage +# if sal_type == 'net': +# sal += ded_fix +# sal -= all_fix +# per = 0.0 +# if sal_type == 'net': +# per = (all_per - ded_per) +# else: +# per = all_per +# if per <=0: +# per *= -1 +# final = (per * 100) + 100 +# basic = (sal * 100) / final +# else: + basic = contract.wage number = sequence_obj.get(cr, uid, 'salary.slip') update.update({ @@ -1214,12 +1248,13 @@ class hr_payslip(osv.osv): off_days += get_days(1, dates[1].day, dates[1].month, dates[1].year, days_arr[dy]) total_off = off_days working_day = dates[1].day - total_off - perday = slip.net / working_day + perday = slip.basic / working_day total = 0.0 leave = 0.0 leave_ids = self._get_leaves(cr, uid, slip, slip.employee_id, context) total_leave = 0.0 paid_leave = 0.0 + h_ids = holiday_pool.browse(cr, uid, leave_ids, context=context) for hday in holiday_pool.browse(cr, uid, leave_ids, context=context): if not hday.holiday_status_id.head_id: raise osv.except_osv(_('Error !'), _('Please check configuration of %s, payroll head is missing') % (hday.holiday_status_id.name)) @@ -1260,6 +1295,7 @@ class hr_payslip(osv.osv): total += perday * days slip_line_pool.create(cr, uid, res, context=context) + holiday_pool.write(cr, uid, leave_ids, {'payslip_id': slip.id}, context=context) basic = basic - total # leaves = total update.update({ @@ -1272,8 +1308,292 @@ class hr_payslip(osv.osv): }) self.write(cr, uid, [slip.id], update, context=context) return True + + def onchange_employee_id(self, cr, uid, ids, ddate, employee_id, context=None): + func_pool = self.pool.get('hr.payroll.structure') + slip_line_pool = self.pool.get('hr.payslip.line') + holiday_pool = self.pool.get('hr.holidays') + sequence_obj = self.pool.get('ir.sequence') + empolyee_obj = self.pool.get('hr.employee') + if context is None: + context = {} + + old_slip_ids = ids and slip_line_pool.search(cr, uid, [('slip_id', '=', ids[0])], context=context) or False + if old_slip_ids: + slip_line_pool.unlink(cr, uid, old_slip_ids) + + update = {'value':{'line_ids':[], 'name':'', 'working_days': 0.0, 'holiday_days': 0.0, 'worked_days': 0.0, 'basic_before_leaves': 0.0, 'basic': 0.0}} + if not employee_id: + return update + + if not employee_id and ids: + old_slip_ids = slip_line_pool.search(cr, uid, [('slip_id', '=', ids[0])], context=context) + if old_slip_ids: + line_pool.unlink(cr, uid, old_slip_ids) + return update + + #Check for the Holidays + def get_days(start, end, month, year, calc_day): + import datetime + count = 0 + for day in range(start, end): + if datetime.date(year, month, day).weekday() == calc_day: + count += 1 + return count + + employee_id = empolyee_obj.browse(cr, uid, employee_id, context=context) + ttyme = datetime.fromtimestamp(time.mktime(time.strptime(ddate,"%Y-%m-%d"))) + contracts = self.get_contract(cr, uid, employee_id, ddate, context) + if contracts.get('id', False) == False: + update['value'].update({ + 'basic': round(0.0), + 'basic_before_leaves': round(0.0), + 'name':'Salary Slip of %s for %s' % (employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))), + 'state':'draft', + 'contract_id':False, + 'company_id':employee_id.company_id.id + }) + + contract = employee_id.contract_id +# sal_type = contract.wage_type_id.type + function = contract.struct_id.id + lines = [] + if function: + func = func_pool.read(cr, uid, function, ['line_ids'], context=context) + lines = slip_line_pool.browse(cr, uid, func['line_ids'], context=context) + #lines += slip.employee_id.line_ids + + ad = [] +# all_per = 0.0 +# ded_per = 0.0 +# all_fix = 0.0 +# ded_fix = 0.0 + allounce = 0.0 + deduction = 0.0 + + obj = {'basic':contract.wage} +# if contract.wage_type_id.type == 'gross': +# obj['gross'] = contract.wage +# update['value']['igross'] = contract.wage +# if contract.wage_type_id.type == 'net': +# obj['net'] = contract.wage +# update['value']['inet'] = contract.wage +# if contract.wage_type_id.type == 'basic': +# obj['basic'] = contract.wage +# update['value']['basic'] = contract.wage + + for line in lines: + cd = line.code.lower() + obj[cd] = line.amount or 0.0 + + for line in lines: + if line.category_id.code in ad: + continue + ad.append(line.category_id.code) + cd = line.category_id.code.lower() + calculate = False + try: + exp = line.category_id.condition + calculate = eval(exp, obj) + except Exception, e: + raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) + + if not calculate: + continue + + percent = 0.0 + value = 0.0 + base = False +# company_contrib = 0.0 + base = line.category_id.base + + try: + #Please have a look at the configuration guide. + amt = eval(base, obj) + except Exception, e: + raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) + +# if sal_type in ('gross', 'net'): +# if line.amount_type == 'per': +# percent = line.amount +# if amt > 1: +# value = percent * amt +# elif amt > 0 and amt <= 1: +# percent = percent * amt +# if value > 0: +# percent = 0.0 +# elif line.amount_type == 'fix': +# value = line.amount +# elif line.amount_type == 'func': +# value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) +# line.amount = value +# else: + if line.amount_type == 'per': + try: + value = line.amount * amt + except Exception, e: + raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) + elif line.amount_type == 'fix': + value = line.amount + elif line.amount_type == 'func': + value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) + line.amount = value + if line.type == 'allowance': +# all_per += percent +# all_fix += value + allounce += value + elif line.type == 'deduction': +# ded_per += percent +# ded_fix += value + deduction += value + vals = { + 'category_id': line.category_id.id, + 'name': line.name, + 'sequence': line.sequence, + 'type': line.type, + 'code': line.code, + 'amount_type': line.amount_type, + 'amount':line.amount, + 'total': value, + 'slip_id':line.id, + 'employee_id':False, + 'function_id':False, + 'base':line.category_id.base + } + update['value']['line_ids'].append(vals) +# if sal_type in ('gross', 'net'): +# sal = contract.wage +# if sal_type == 'net': +# sal += ded_fix +# sal -= all_fix +# per = 0.0 +# if sal_type == 'net': +# per = (all_per - ded_per) +# else: +# per = all_per +# if per <=0: +# per *= -1 +# final = (per * 100) + 100 +# basic = (sal * 100) / final +# else: + basic = contract.wage + + number = sequence_obj.get(cr, uid, 'salary.slip') + update['value'].update({ + 'deg_id':function, + 'number':number, + 'basic': round(basic), + 'basic_before_leaves': round(basic), + 'allounce': round(allounce), + 'deduction': round(deduction), +# 'total_pay': round(basic)+ allounce - deduction, + 'name':'Salary Slip of %s for %s' % (employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))), + 'state':'draft', + 'contract_id':contract.id, + 'company_id':employee_id.company_id.id + }) + + for line in employee_id.line_ids: + vals = { + 'category_id': line.category_id.id, + 'name': line.name, + 'sequence': line.sequence, + 'type': line.type, + 'code': line.code, + 'amount_type': line.amount_type, + 'amount':line.amount, + 'slip_id':line.id, + 'employee_id':False, + 'function_id':False, + 'base':base + } + update['value']['line_ids'].append(vals) + + basic_before_leaves = update['value']['basic'] + working_day = 0 + off_days = 0 + dates = prev_bounds(ddate) + + days_arr = [0, 1, 2, 3, 4, 5, 6] + for dy in range(employee_id.contract_id.working_days_per_week, 7): + off_days += get_days(1, dates[1].day, dates[1].month, dates[1].year, days_arr[dy]) + total_off = off_days + working_day = dates[1].day - total_off + perday = basic / working_day + total = 0.0 + leave = 0.0 + leave_ids = self._get_leaves1(cr, uid, ddate, employee_id, context) + total_leave = 0.0 + paid_leave = 0.0 + h_ids = holiday_pool.browse(cr, uid, leave_ids, context=context) + for hday in holiday_pool.browse(cr, uid, leave_ids, context=context): + if not hday.holiday_status_id.head_id: + raise osv.except_osv(_('Error !'), _('Please check configuration of %s, payroll head is missing') % (hday.holiday_status_id.name)) + + res = { + 'slip_id':hday.id, + 'name':hday.holiday_status_id.name + '-%s' % (hday.number_of_days), + 'code':hday.holiday_status_id.code, + 'amount_type':'fix', + 'category_id':hday.holiday_status_id.head_id.id, + 'sequence':hday.holiday_status_id.head_id.sequence + } + days = hday.number_of_days + if hday.number_of_days < 0: + days = hday.number_of_days * -1 + total_leave += days + if hday.holiday_status_id.type == 'paid': + paid_leave += days + continue +# res['name'] = hday.holiday_status_id.name + '-%s' % (days) +# res['amount'] = perday * days +# res['type'] = 'allowance' +# leave += days +# total += perday * days + + elif hday.holiday_status_id.type == 'halfpaid': + paid_leave += (days / 2) + res['name'] = hday.holiday_status_id.name + '-%s/2' % (days) + res['amount'] = perday * (days/2) + total += perday * (days/2) + res['total'] = total + leave += days / 2 + res['type'] = 'deduction' + else: + res['name'] = hday.holiday_status_id.name + '-%s' % (days) + res['amount'] = perday * days + res['type'] = 'deduction' + leave += days + total += perday * days + res['total'] = total +# slip_line_pool.create(cr, uid, res, context=context) + update['value']['line_ids'].append(res) + holiday_pool.write(cr, uid, leave_ids, {'payslip_id': ids and ids[0] or False}, context=context) + basic = basic - total +# leaves = total + update['value'].update({ + 'basic':basic, + 'basic_before_leaves': round(basic_before_leaves), + 'total_pay': round(basic_before_leaves)+ allounce - (deduction + total), + 'leaves':total, + 'holiday_days':leave, + 'worked_days':working_day - leave, + 'working_days':working_day, + }) +# self.write(cr, uid, [slip.id], update, context=context) + return update + hr_payslip() +class hr_holidays(osv.osv): + + _inherit = "hr.holidays" + _columns = { + 'payslip_id':fields.many2one('hr.payslip', 'Payslip', required=False), + } + +hr_holidays() + class hr_payslip_line(osv.osv): ''' Payslip Line @@ -1388,19 +1708,20 @@ class hr_employee(osv.osv): for employee in self.browse(cr, uid, ids, context=context): if not employee.contract_id: - vals[employee.id] = {'basic':0.0, 'gross':0.0, 'net':0.0, 'advantages_gross':0.0, 'advantages_net':0.0} +# vals[employee.id] = {'basic':0.0, 'gross':0.0, 'net':0.0, 'advantages_gross':0.0, 'advantages_net':0.0} + vals[employee.id] = {'basic':0.0, 'advantages_gross':0.0, 'advantages_net':0.0} continue basic = employee.contract_id.basic - gross = employee.contract_id.gross - net = employee.contract_id.net +# gross = employee.contract_id.gross +# net = employee.contract_id.net allowance = employee.contract_id.advantages_gross deduction = employee.contract_id.advantages_net obj = { 'basic':basic, - 'gross':gross, - 'net':net +# 'gross':gross, +# 'net':net } for line in employee.line_ids: base = line.category_id.base @@ -1424,9 +1745,9 @@ class hr_employee(osv.osv): vals[employee.id] = { 'basic':basic, 'advantages_gross':allowance, - 'gross':basic + allowance, +# 'gross':basic + allowance, 'advantages_net':deduction, - 'net':basic + allowance - deduction +# 'net':basic + allowance - deduction } return vals @@ -1437,8 +1758,8 @@ class hr_employee(osv.osv): 'otherid': fields.char('Other Id', size=64), 'basic': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Basic Salary', digits=(14,2)), - 'gross': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Gross Salary', digits=(14,2)), - 'net': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Net Salary', digits=(14,2)), +# 'gross': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Gross Salary', digits=(14,2)), +# 'net': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Net Salary', digits=(14,2)), 'advantages_net': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Deductions', digits=(14,2)), 'advantages_gross': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Allowances', digits=(14,2)), } diff --git a/addons/hr_payroll/hr_payroll_view.xml b/addons/hr_payroll/hr_payroll_view.xml index e2c54097cf7..8ae6cf6c1c1 100644 --- a/addons/hr_payroll/hr_payroll_view.xml +++ b/addons/hr_payroll/hr_payroll_view.xml @@ -137,7 +137,7 @@ - + @@ -368,8 +368,8 @@ - - + + @@ -383,7 +383,7 @@
- + @@ -446,14 +446,17 @@ - - - - - + + + + + + + + @@ -839,9 +842,9 @@ - + - + @@ -850,11 +853,11 @@ - + From 91f14201bf099a486528c27eb9e821ce50a035f8 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 28 Feb 2011 10:56:43 +0100 Subject: [PATCH 0006/1110] [IMP] hr_payroll: renamed struct_id field of hr.payroll.structure into parent_id bzr revid: qdp-launchpad@openerp.com-20110228095643-rji364bszjfq2a60 --- addons/hr_payroll/hr_payroll.py | 2 +- addons/hr_payroll/hr_payroll_view.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 3c6199ebef8..33f34973547 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -97,7 +97,7 @@ class hr_payroll_structure(osv.osv): 'line_ids':fields.one2many('hr.payslip.line', 'function_id', 'Salary Structure', required=False), 'company_id':fields.many2one('res.company', 'Company', required=False), 'note': fields.text('Description'), - 'struct_id':fields.many2one('hr.payroll.structure', 'Parent Structure'), + 'parent_id':fields.many2one('hr.payroll.structure', 'Parent Structure'), } _defaults = { 'company_id': lambda self, cr, uid, context: \ diff --git a/addons/hr_payroll/hr_payroll_view.xml b/addons/hr_payroll/hr_payroll_view.xml index d73e6cc310c..9ec9b4a9982 100644 --- a/addons/hr_payroll/hr_payroll_view.xml +++ b/addons/hr_payroll/hr_payroll_view.xml @@ -210,7 +210,7 @@ - + From 879838450442fdd0153521fde145fa4967cd781f Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 28 Feb 2011 11:55:24 +0100 Subject: [PATCH 0007/1110] [IMP] hr_payroll: some clearance bzr revid: qdp-launchpad@openerp.com-20110228105524-tymoxmlzi81dksz2 --- addons/hr_payroll/hr_payroll.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 33f34973547..de94738cac2 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -215,10 +215,10 @@ class hr_contract(osv.osv): elif line.amount_type == 'func': value = slip_line_pool.execute_function(cr, uid, line.id, amt, context) line.amount = value - if line.type.name == 'allowance': + if line.type.name == 'allowance': #FIXME: not good. We don't have to compute the gross or net on hr.contract nor hr.employee. We jsut need to define the basic; So the fields gross and net can be removed from view and object. all_per += percent all_fix += value - elif line.type.name == 'deduction': + elif line.type.name == 'deduction': #FIXME: not good ded_per += percent ded_fix += value if sal_type in ('gross', 'net'): @@ -276,8 +276,7 @@ class hr_contract(osv.osv): } vals[rs.id] = record continue - lines = rs.struct_id.rule_ids - for line in lines: + for line in rs.struct_id.rule_ids: amount = 0.0 if line.amount_type == 'per': try: From 250e2fc68e61b2363f378354b915bf80fb321cbf Mon Sep 17 00:00:00 2001 From: "psi (Open ERP)" Date: Mon, 28 Feb 2011 17:40:15 +0530 Subject: [PATCH 0008/1110] [IMP] hr_payroll: Improve the onchange_employee function so it will update the holidays details of the employee bzr revid: psi@tinyerp.co.in-20110228121015-vml7i72e1ey2ayv5 --- addons/hr_payroll/hr_payroll.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 6d5574caf1c..6084b0238d1 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -1029,7 +1029,6 @@ class hr_payslip(osv.osv): @return: return a result """ result = [] - dates = prev_bounds(slip.date) sql = '''select id from hr_holidays where date_from >= '%s' and date_to <= '%s' @@ -1059,7 +1058,7 @@ class hr_payslip(osv.osv): sql = '''select id from hr_holidays where date_from >= '%s' and date_to <= '%s' and employee_id = %s - and state = 'validate' ''' % (dates[0], dates[1], employee.id) + ''' % (dates[0], dates[1], employee.id) cr.execute(sql) res = cr.fetchall() if res: @@ -1322,7 +1321,7 @@ class hr_payslip(osv.osv): if old_slip_ids: slip_line_pool.unlink(cr, uid, old_slip_ids) - update = {'value':{'line_ids':[], 'name':'', 'working_days': 0.0, 'holiday_days': 0.0, 'worked_days': 0.0, 'basic_before_leaves': 0.0, 'basic': 0.0}} + update = {'value':{'line_ids':[], 'holiday_ids':[], 'name':'', 'working_days': 0.0, 'holiday_days': 0.0, 'worked_days': 0.0, 'basic_before_leaves': 0.0, 'basic': 0.0, 'leaves': 0.0, 'total_pay': 0.0}} if not employee_id: return update @@ -1568,19 +1567,20 @@ class hr_payslip(osv.osv): res['total'] = total # slip_line_pool.create(cr, uid, res, context=context) update['value']['line_ids'].append(res) - holiday_pool.write(cr, uid, leave_ids, {'payslip_id': ids and ids[0] or False}, context=context) +# holiday_pool.write(cr, uid, leave_ids, {'payslip_id': ids and ids[0] or False}, context=context) basic = basic - total # leaves = total update['value'].update({ 'basic':basic, 'basic_before_leaves': round(basic_before_leaves), 'total_pay': round(basic_before_leaves)+ allounce - (deduction + total), - 'leaves':total, - 'holiday_days':leave, - 'worked_days':working_day - leave, - 'working_days':working_day, + 'leaves': total, + 'holiday_days': leave, + 'worked_days': working_day - leave, + 'working_days': working_day, + 'holiday_ids': leave_ids }) -# self.write(cr, uid, [slip.id], update, context=context) +# self.write(cr, uid, uid, update, context=context) return update hr_payslip() @@ -1603,8 +1603,7 @@ class hr_payslip_line(osv.osv): _description = 'Payslip Line' def onchange_category(self, cr, uid, ids, category_id): - res = { - } + res = {} if category_id: category = self.pool.get('hr.allounce.deduction.categoty').browse(cr, uid, category_id) res.update({ From f672183ff142178f78df8ec70686bb9ff43057c3 Mon Sep 17 00:00:00 2001 From: "aag (OpenERP)" Date: Tue, 1 Mar 2011 12:51:34 +0530 Subject: [PATCH 0009/1110] [IMP] Rework-Addons :Improvement Config wiz , ON Addonse Side bzr revid: aag@tinyerp.co.in-20110301072134-3rrx10e53csav102 --- addons/account/account_installer.xml | 4 +-- .../account_sequence_installer_view.xml | 2 +- addons/base_setup/base_setup_todo.xml | 2 +- addons/base_setup/installer.py | 33 +++++++++++++++++++ addons/crm/crm_installer_view.xml | 2 +- .../wizard/document_configuration_view.xml | 2 +- addons/hr/hr_installer.xml | 2 +- addons/knowledge/knowledge_installer.xml | 2 +- addons/l10n_be/l10n_be_wizard.xml | 2 +- .../data/l10n_br_account_chart_template.xml | 2 +- addons/l10n_cr/l10n_wizard.xml | 2 +- addons/l10n_es/l10n_es_wizard.xml | 2 +- addons/l10n_fr/l10n_fr_wizard.xml | 2 +- addons/l10n_lu/l10n_lu_wizard.xml | 2 +- addons/l10n_ma/l10n_ma_wizard.xml | 2 +- addons/l10n_uk/l10n_uk_wizard.xml | 2 +- addons/mrp/mrp_installer.xml | 2 +- addons/profile_tools/misc_tools_installer.xml | 2 +- addons/project/project_installer.xml | 2 +- .../purchase_double_validation_installer.xml | 2 +- .../report_designer_installer.xml | 2 +- addons/sale/sale_installer.xml | 2 +- 22 files changed, 55 insertions(+), 22 deletions(-) diff --git a/addons/account/account_installer.xml b/addons/account/account_installer.xml index 6ebdf74b977..7e3836340b9 100644 --- a/addons/account/account_installer.xml +++ b/addons/account/account_installer.xml @@ -116,13 +116,13 @@ 3 - onskip + on_trigger 5 - always + on_trigger diff --git a/addons/account_sequence/account_sequence_installer_view.xml b/addons/account_sequence/account_sequence_installer_view.xml index 1051b133045..3a812a187c4 100644 --- a/addons/account_sequence/account_sequence_installer_view.xml +++ b/addons/account_sequence/account_sequence_installer_view.xml @@ -50,7 +50,7 @@ 3 - onskip + on_trigger diff --git a/addons/base_setup/base_setup_todo.xml b/addons/base_setup/base_setup_todo.xml index 7cd0563aafe..c3a1bc24a8b 100644 --- a/addons/base_setup/base_setup_todo.xml +++ b/addons/base_setup/base_setup_todo.xml @@ -67,7 +67,7 @@ 1 - onskip + on_trigger diff --git a/addons/base_setup/installer.py b/addons/base_setup/installer.py index e23f1171752..bb2626a59ae 100644 --- a/addons/base_setup/installer.py +++ b/addons/base_setup/installer.py @@ -19,6 +19,7 @@ # ############################################################################## from osv import fields, osv +import re class base_setup_installer(osv.osv_memory): _name = 'base.setup.installer' @@ -101,5 +102,37 @@ class base_setup_installer(osv.osv_memory): value.update({'progress':progress}) if progress < 10.: progress = 10. + return {'value':value} + + def execute(self, cr, uid, ids, context=None): + if context is None: + context = {} + modules = self.pool.get('ir.module.module') + modules_selected = [] + datas = self.read(cr, uid, ids, context=context)[0] + key = datas.keys() + key.remove("id") + key.remove("progress") + name_list = [] + for mod in key: + if datas[mod] == 1: + modules_selected.append(mod) + inst = modules.browse( + cr, uid, + modules.search(cr, uid, + [('name','in',modules_selected) + ], + context=context), + context=context) + for i in inst: + if i.state == 'uninstalled': + sect_mod_id = i.id + modules.button_install(cr, uid, [sect_mod_id], context=context) + elif i.state == 'installed': + if modules_selected: + for instl in modules_selected: + cr.execute("update ir_actions_todo set restart='on_trigger' , state='open' from ir_model_data as data where data.res_id = ir_actions_todo.id and data.model = 'ir.actions.todo' and data.module like '%"+instl+"%'") + + return base_setup_installer() diff --git a/addons/crm/crm_installer_view.xml b/addons/crm/crm_installer_view.xml index 35ff5a0a7cc..778ebd5646a 100644 --- a/addons/crm/crm_installer_view.xml +++ b/addons/crm/crm_installer_view.xml @@ -61,7 +61,7 @@ 3 - always + on_trigger diff --git a/addons/document/wizard/document_configuration_view.xml b/addons/document/wizard/document_configuration_view.xml index 156af432b0e..8aa874782b9 100644 --- a/addons/document/wizard/document_configuration_view.xml +++ b/addons/document/wizard/document_configuration_view.xml @@ -46,7 +46,7 @@ - + diff --git a/addons/hr/hr_installer.xml b/addons/hr/hr_installer.xml index 5ccbaefa3f5..3d04abf00e3 100644 --- a/addons/hr/hr_installer.xml +++ b/addons/hr/hr_installer.xml @@ -52,7 +52,7 @@ 3 - always + on_trigger diff --git a/addons/knowledge/knowledge_installer.xml b/addons/knowledge/knowledge_installer.xml index 068fa9b413b..79f6cfb178e 100644 --- a/addons/knowledge/knowledge_installer.xml +++ b/addons/knowledge/knowledge_installer.xml @@ -53,7 +53,7 @@ 3 - always + on_trigger diff --git a/addons/l10n_be/l10n_be_wizard.xml b/addons/l10n_be/l10n_be_wizard.xml index 0e691260425..5b3c42b22fa 100644 --- a/addons/l10n_be/l10n_be_wizard.xml +++ b/addons/l10n_be/l10n_be_wizard.xml @@ -4,7 +4,7 @@ - onskip + on_trigger diff --git a/addons/l10n_br/data/l10n_br_account_chart_template.xml b/addons/l10n_br/data/l10n_br_account_chart_template.xml index dd714bacab8..4b548f65c8c 100644 --- a/addons/l10n_br/data/l10n_br_account_chart_template.xml +++ b/addons/l10n_br/data/l10n_br_account_chart_template.xml @@ -19,7 +19,7 @@ This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template. open - onskip + on_trigger diff --git a/addons/l10n_cr/l10n_wizard.xml b/addons/l10n_cr/l10n_wizard.xml index 0e691260425..5b3c42b22fa 100644 --- a/addons/l10n_cr/l10n_wizard.xml +++ b/addons/l10n_cr/l10n_wizard.xml @@ -4,7 +4,7 @@ - onskip + on_trigger diff --git a/addons/l10n_es/l10n_es_wizard.xml b/addons/l10n_es/l10n_es_wizard.xml index 294f0a5e668..3bbda51e00c 100644 --- a/addons/l10n_es/l10n_es_wizard.xml +++ b/addons/l10n_es/l10n_es_wizard.xml @@ -4,7 +4,7 @@ - onskip + on_trigger diff --git a/addons/l10n_fr/l10n_fr_wizard.xml b/addons/l10n_fr/l10n_fr_wizard.xml index 985c3b81195..48147ac172d 100644 --- a/addons/l10n_fr/l10n_fr_wizard.xml +++ b/addons/l10n_fr/l10n_fr_wizard.xml @@ -4,7 +4,7 @@ - onskip + on_trigger diff --git a/addons/l10n_lu/l10n_lu_wizard.xml b/addons/l10n_lu/l10n_lu_wizard.xml index f0655f3dc99..5942e7800d0 100644 --- a/addons/l10n_lu/l10n_lu_wizard.xml +++ b/addons/l10n_lu/l10n_lu_wizard.xml @@ -4,7 +4,7 @@ - onskip + on_trigger diff --git a/addons/l10n_ma/l10n_ma_wizard.xml b/addons/l10n_ma/l10n_ma_wizard.xml index 4524c36fb10..4768ed60dee 100644 --- a/addons/l10n_ma/l10n_ma_wizard.xml +++ b/addons/l10n_ma/l10n_ma_wizard.xml @@ -4,7 +4,7 @@ - onskip + on_trigger diff --git a/addons/l10n_uk/l10n_uk_wizard.xml b/addons/l10n_uk/l10n_uk_wizard.xml index 63a56521bd8..62fe38a1642 100644 --- a/addons/l10n_uk/l10n_uk_wizard.xml +++ b/addons/l10n_uk/l10n_uk_wizard.xml @@ -8,7 +8,7 @@ This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template. open - onskip + on_trigger diff --git a/addons/mrp/mrp_installer.xml b/addons/mrp/mrp_installer.xml index ff0c01f8e18..4008385ff32 100644 --- a/addons/mrp/mrp_installer.xml +++ b/addons/mrp/mrp_installer.xml @@ -48,7 +48,7 @@ 3 - always + on_trigger diff --git a/addons/profile_tools/misc_tools_installer.xml b/addons/profile_tools/misc_tools_installer.xml index 235d2d6e392..c21f703b291 100644 --- a/addons/profile_tools/misc_tools_installer.xml +++ b/addons/profile_tools/misc_tools_installer.xml @@ -48,7 +48,7 @@ - always + on_trigger 3 diff --git a/addons/project/project_installer.xml b/addons/project/project_installer.xml index 32b235e4691..7200986beb2 100644 --- a/addons/project/project_installer.xml +++ b/addons/project/project_installer.xml @@ -50,7 +50,7 @@ - always + on_trigger 3 diff --git a/addons/purchase_double_validation/purchase_double_validation_installer.xml b/addons/purchase_double_validation/purchase_double_validation_installer.xml index c3369f68554..2cafbd7cd9a 100644 --- a/addons/purchase_double_validation/purchase_double_validation_installer.xml +++ b/addons/purchase_double_validation/purchase_double_validation_installer.xml @@ -44,7 +44,7 @@ - onskip + on_trigger diff --git a/addons/report_designer/report_designer_installer.xml b/addons/report_designer/report_designer_installer.xml index 2f838c0b74c..31f6d16ae22 100644 --- a/addons/report_designer/report_designer_installer.xml +++ b/addons/report_designer/report_designer_installer.xml @@ -45,7 +45,7 @@ - always + on_trigger 3 diff --git a/addons/sale/sale_installer.xml b/addons/sale/sale_installer.xml index 4149871ad36..ad707a1abec 100644 --- a/addons/sale/sale_installer.xml +++ b/addons/sale/sale_installer.xml @@ -47,7 +47,7 @@ - always + on_trigger 3 From 43690eb21f88759f76f591247f43cf6aa548e611 Mon Sep 17 00:00:00 2001 From: "aag (OpenERP)" Date: Tue, 1 Mar 2011 12:52:41 +0530 Subject: [PATCH 0010/1110] [IMP] REWORK-SERVERSIDE :Improvement Config wiz , ON SERVER SIDE bzr revid: aag@tinyerp.co.in-20110301072241-a8s1iialq6xeot23 --- openerp/addons/base/ir/ir.xml | 2 +- openerp/addons/base/ir/ir_actions.py | 4 +-- .../wizard/base_module_configuration_view.xml | 2 +- .../addons/base/res/partner/partner_view.xml | 4 ++- openerp/addons/base/res/res_config.py | 31 +------------------ 5 files changed, 8 insertions(+), 35 deletions(-) diff --git a/openerp/addons/base/ir/ir.xml b/openerp/addons/base/ir/ir.xml index a7e9922331b..d1917a4a52f 100644 --- a/openerp/addons/base/ir/ir.xml +++ b/openerp/addons/base/ir/ir.xml @@ -1908,7 +1908,7 @@ search - + diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 7a07ca40ef8..1d73ad70171 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -794,14 +794,14 @@ class ir_actions_todo(osv.osv): 'sequence': fields.integer('Sequence'), 'state': fields.selection(TODO_STATES, string='State', required=True), 'name':fields.char('Name', size=64), - 'restart': fields.selection([('onskip','On Skip'),('always','Always'),('never','Never')],'Restart',required=True), + 'restart': fields.selection([('on_trigger','On Trigger'),('always','Always'),('never','Never')],'Restart',required=True), 'groups_id':fields.many2many('res.groups', 'res_groups_action_rel', 'uid', 'gid', 'Groups'), 'note':fields.text('Text', translate=True), } _defaults={ 'state': 'open', 'sequence': 10, - 'restart': 'onskip', + 'restart': 'on_trigger', } _order="sequence,name,id" diff --git a/openerp/addons/base/module/wizard/base_module_configuration_view.xml b/openerp/addons/base/module/wizard/base_module_configuration_view.xml index f8abf1e2732..be86145a156 100644 --- a/openerp/addons/base/module/wizard/base_module_configuration_view.xml +++ b/openerp/addons/base/module/wizard/base_module_configuration_view.xml @@ -24,7 +24,7 @@ action = obj.start() - diff --git a/openerp/addons/base/res/partner/partner_view.xml b/openerp/addons/base/res/partner/partner_view.xml index 9d46404132c..e32e73deedb 100644 --- a/openerp/addons/base/res/partner/partner_view.xml +++ b/openerp/addons/base/res/partner/partner_view.xml @@ -3,7 +3,9 @@ + web_icon_hover="data/sales-hover.png" + groups="base.group_sale_salesman,base.group_sale_salesman"/> + diff --git a/openerp/addons/base/res/res_config.py b/openerp/addons/base/res/res_config.py index 3f8c6f20b8d..2f0b5c44509 100644 --- a/openerp/addons/base/res/res_config.py +++ b/openerp/addons/base/res/res_config.py @@ -120,7 +120,7 @@ class res_config_configurable(osv.osv_memory): def start(self, cr, uid, ids, context=None): ids2 = self.pool.get('ir.actions.todo').search(cr, uid, [], context=context) for todo in self.pool.get('ir.actions.todo').browse(cr, uid, ids2, context=context): - if (todo.restart=='always') or (todo.restart=='onskip' and (todo.state in ('skip','cancel'))): + if (todo.restart=='always') or (todo.restart=='on_trigger' and (todo.state in ('skip','cancel'))): todo.write({'state':'open'}) return self.next(cr, uid, ids, context) @@ -355,35 +355,6 @@ class res_config_installer(osv.osv_memory): return (base | hooks_results | additionals) - set( map(attrgetter('name'), self._already_installed(cr, uid, context))) - def default_get(self, cr, uid, fields_list, context=None): - ''' If an addon is already installed, check it by default - ''' - defaults = super(res_config_installer, self).default_get( - cr, uid, fields_list, context=context) - - return dict(defaults, - **dict.fromkeys( - map(attrgetter('name'), - self._already_installed(cr, uid, context=context)), - True)) - - def fields_get(self, cr, uid, fields=None, context=None, write_access=True): - """ If an addon is already installed, set it to readonly as - res.config.installer doesn't handle uninstallations of already - installed addons - """ - fields = super(res_config_installer, self).fields_get( - cr, uid, fields, context, write_access) - - for module in self._already_installed(cr, uid, context=context): - if module.name not in fields: - continue - fields[module.name].update( - readonly=True, - help= ustr(fields[module.name].get('help', '')) + - _('\n\nThis addon is already installed on your system')) - return fields - def execute(self, cr, uid, ids, context=None): modules = self.pool.get('ir.module.module') to_install = list(self.modules_to_install( From 73378da514dd636ddafcd6ca4d552ae9db637efe Mon Sep 17 00:00:00 2001 From: sus Date: Tue, 1 Mar 2011 13:10:35 +0530 Subject: [PATCH 0011/1110] [IMP] : Improvement in server(module.py file) bzr revid: sus@sus-desktop-20110301074035-7fx0v3gv8889slbb --- openerp/addons/__init__.py | 2 +- openerp/addons/base/module/module.py | 58 ++++++++++++++----- openerp/addons/base/module/module_view.xml | 2 +- .../base/module/wizard/base_module_upgrade.py | 31 ---------- .../wizard/base_module_upgrade_view.xml | 16 ++--- openerp/addons/base/res/res_user.py | 1 - 6 files changed, 50 insertions(+), 60 deletions(-) diff --git a/openerp/addons/__init__.py b/openerp/addons/__init__.py index af080724136..ee6cd5eba49 100644 --- a/openerp/addons/__init__.py +++ b/openerp/addons/__init__.py @@ -843,7 +843,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): if 'base' in tools.config['update'] or 'all' in tools.config['update']: cr.execute("update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed')) - # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps) + # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps) graph = create_graph(cr, ['base'], force) if not graph: logger.notifyChannel('init', netsvc.LOG_CRITICAL, 'module base cannot be loaded! (hint: verify addons-path)') diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 2e276433e63..fd701ba353e 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -200,6 +200,7 @@ class module(osv.osv): def _name_uniq_msg(self, cr, uid, ids, context=None): return _('The name of the module must be unique !') + def _certificate_uniq_msg(self, cr, uid, ids, context=None): return _('The certificate ID of the module must be unique !') @@ -285,8 +286,41 @@ class module(osv.osv): demo = demo or mdemo return demo + def upgrade(self, cr, uid, ids, context=None): + mod_obj = self.pool.get('ir.module.module') + ids = mod_obj.search(cr, uid, [('state', 'in', ['to upgrade', 'to remove', 'to install'])]) + unmet_packages = [] + mod_dep_obj = self.pool.get('ir.module.module.dependency') + for mod in mod_obj.browse(cr, uid, ids, context=context): + depends_mod_ids = mod_dep_obj.search(cr, uid, [('module_id', '=', mod.id)], context=context) + for dep_mod in mod_dep_obj.browse(cr, uid, depends_mod_ids): + if dep_mod.state in ('unknown','uninstalled'): + unmet_packages.append(dep_mod.name) + if len(unmet_packages): + raise osv.except_osv(_('Unmet dependency !'), _('Following modules are not installed or unknown: %s') % ('\n\n' + '\n'.join(unmet_packages))) + mod_obj.download(cr, uid, ids, context=context) + cr.commit() + _db, pool = pooler.restart_pool(cr.dbname, update_module=True) + return True + def button_install(self, cr, uid, ids, context=None): - return self.state_update(cr, uid, ids, 'to install', ['uninstalled'], context) + self.state_update(cr, uid, ids, 'to install', ['uninstalled'], context) + self.upgrade(cr, uid, ids, context=context) + data_obj = self.pool.get('ir.model.data') + id2 = data_obj._get_id(cr, uid, 'base', 'view_base_module_upgrade_install') + if id2: + id2 = data_obj.browse(cr, uid, id2, context=context).res_id + return { + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'base.module.upgrade', + 'views': [(id2, 'form')], + 'view_id': False, + 'type': 'ir.actions.act_window', + 'target': 'new', + 'nodestroy':True, + } + def button_install_cancel(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'uninstalled', 'demo':False}) @@ -305,49 +339,41 @@ class module(osv.osv): res = cr.fetchall() if res: raise orm.except_orm(_('Error'), _('Some installed modules depend on the module you plan to Uninstall :\n %s') % '\n'.join(map(lambda x: '\t%s: %s' % (x[0], x[1]), res))) + self.write(cr, uid, ids, {'state': 'to remove'}) + self.upgrade(cr, uid, ids, context=context) return True def button_uninstall_cancel(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'installed'}) return True + def button_upgrade(self, cr, uid, ids, context=None): depobj = self.pool.get('ir.module.module.dependency') todo = self.browse(cr, uid, ids, context=context) self.update_list(cr, uid) - i = 0 while i -