From f97c21c40cc48c09a127a1efb25a6a3bbd7bc602 Mon Sep 17 00:00:00 2001 From: mtr Date: Wed, 4 May 2011 18:26:27 +0530 Subject: [PATCH 01/34] [IMP] hr_payroll: added payslip_sum method to compute 'payslip' on other payslip' bzr revid: mtr@mtr-20110504125627-5zyck6tp8438gyd5 --- addons/hr_payroll/hr_payroll.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 132d8fc1104..1a45e89b3dd 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -612,6 +612,19 @@ class hr_payslip(osv.osv): res['value'].update({'struct_id': False}) return self.onchange_employee_id(cr, uid, ids, date_from=date_from, date_to=date_to, employee_id=employee_id, contract_id=contract_id, context=context) + def payslip_sum(self, cr, uid, code, from_date, to_date=datetime.now().strftime('%Y-%m-%d'), employee, context=None): + if context is None: + context = {} + if not employee: + employee = 0 + cr.execute("SELECT sum(pl.total) \ + FROM hr_payslip as hp, hr_payslip_line as pl \ + WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ + AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND pl.code = %s", + (employee, from_date, to_date, code )) + res = cr.fetchone() + return res and res[0] or 0.0 + hr_payslip() class hr_payslip_input(osv.osv): From 89a6e522025e3df4daca7269898a5ed7309f794c Mon Sep 17 00:00:00 2001 From: mtr Date: Thu, 5 May 2011 11:17:45 +0530 Subject: [PATCH 02/34] [IMP] hr_payroll: added worked_days_sum method to compute 'payslip' on 'other payslip' bzr revid: mtr@mtr-20110505054745-hkbzoothm3bqa46u --- addons/hr_payroll/hr_payroll.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 1a45e89b3dd..41ec6b9072e 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -625,6 +625,27 @@ class hr_payslip(osv.osv): res = cr.fetchone() return res and res[0] or 0.0 + def worked_days_sum(self, cr, uid, code, field, from_date, to_date=datetime.now().strftime('%Y-%m-%d'), employee, context=None): + payslip_input_obj = self.pool.get('hr.payslip.input') + if context is None: + context = {} + if not employee: + employee = 0 + result = 0.0 + cr.execute("SELECT pi.id \ + FROM hr_payslip as hp, hr_payslip_input as pi \ + WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ + AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s", + (employee, from_date, to_date, code)) + res = cr.fetchall() + for r in res: + input_line = payslip_input_obj.browse(cr, uid, r[0], context=context) + if field == 'number_of_days': + result += input_line.number_of_days + elif field == 'number_of_hours': + result += input_line.number_of_hours + return result + hr_payslip() class hr_payslip_input(osv.osv): From e04c62a5f9855d03ac5b2c3bd2a4d798f1665308 Mon Sep 17 00:00:00 2001 From: mtr Date: Thu, 5 May 2011 12:50:04 +0530 Subject: [PATCH 03/34] [IMP] hr_payroll: if employee is not provided in an argument it returns 0 bzr revid: mtr@mtr-20110505072004-1254kzo59rv9z97e --- addons/hr_payroll/hr_payroll.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 41ec6b9072e..85c109e9501 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -612,11 +612,11 @@ class hr_payslip(osv.osv): res['value'].update({'struct_id': False}) return self.onchange_employee_id(cr, uid, ids, date_from=date_from, date_to=date_to, employee_id=employee_id, contract_id=contract_id, context=context) - def payslip_sum(self, cr, uid, code, from_date, to_date=datetime.now().strftime('%Y-%m-%d'), employee, context=None): + def payslip_sum(self, cr, uid, code, from_date, to_date=datetime.now().strftime('%Y-%m-%d'), employee=False, context=None): if context is None: context = {} if not employee: - employee = 0 + return 0 cr.execute("SELECT sum(pl.total) \ FROM hr_payslip as hp, hr_payslip_line as pl \ WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ @@ -625,12 +625,12 @@ class hr_payslip(osv.osv): res = cr.fetchone() return res and res[0] or 0.0 - def worked_days_sum(self, cr, uid, code, field, from_date, to_date=datetime.now().strftime('%Y-%m-%d'), employee, context=None): + def worked_days_sum(self, cr, uid, code, field, from_date, to_date=datetime.now().strftime('%Y-%m-%d'), employee=False, context=None): payslip_input_obj = self.pool.get('hr.payslip.input') if context is None: context = {} if not employee: - employee = 0 + return 0 result = 0.0 cr.execute("SELECT pi.id \ FROM hr_payslip as hp, hr_payslip_input as pi \ From 0f0a6246d709ddab83f7517774051b34033a9bcc Mon Sep 17 00:00:00 2001 From: mtr Date: Thu, 5 May 2011 18:00:27 +0530 Subject: [PATCH 04/34] [IMP] hr_payroll: improved two methods and moved worked_days_sum method to 'hr.payslip.input' object bzr revid: mtr@mtr-20110505123027-jluag8sqpp12gtwk --- addons/hr_payroll/hr_payroll.py | 49 +++++++++++++++++---------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 85c109e9501..31a92976bf0 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -612,11 +612,13 @@ class hr_payslip(osv.osv): res['value'].update({'struct_id': False}) return self.onchange_employee_id(cr, uid, ids, date_from=date_from, date_to=date_to, employee_id=employee_id, contract_id=contract_id, context=context) - def payslip_sum(self, cr, uid, code, from_date, to_date=datetime.now().strftime('%Y-%m-%d'), employee=False, context=None): + def sum(self, cr, uid, code, from_date, to_date=None, employee=False, context=None): if context is None: context = {} + if to_date is None: + to_date = datetime.now().strftime('%Y-%m-%d') if not employee: - return 0 + return 0.0 cr.execute("SELECT sum(pl.total) \ FROM hr_payslip as hp, hr_payslip_line as pl \ WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ @@ -625,27 +627,6 @@ class hr_payslip(osv.osv): res = cr.fetchone() return res and res[0] or 0.0 - def worked_days_sum(self, cr, uid, code, field, from_date, to_date=datetime.now().strftime('%Y-%m-%d'), employee=False, context=None): - payslip_input_obj = self.pool.get('hr.payslip.input') - if context is None: - context = {} - if not employee: - return 0 - result = 0.0 - cr.execute("SELECT pi.id \ - FROM hr_payslip as hp, hr_payslip_input as pi \ - WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ - AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s", - (employee, from_date, to_date, code)) - res = cr.fetchall() - for r in res: - input_line = payslip_input_obj.browse(cr, uid, r[0], context=context) - if field == 'number_of_days': - result += input_line.number_of_days - elif field == 'number_of_hours': - result += input_line.number_of_hours - return result - hr_payslip() class hr_payslip_input(osv.osv): @@ -668,6 +649,28 @@ class hr_payslip_input(osv.osv): _defaults = { 'sequence': 10, } + + def sum(self, cr, uid, code, field, from_date, to_date=None, employee=False, context=None): + if context is None: + context = {} + if to_date is None: + to_date = datetime.now().strftime('%Y-%m-%d') + if not employee: + return 0.0 + result = 0.0 + input_ids = [] + cr.execute("SELECT pi.id \ + FROM hr_payslip as hp, hr_payslip_input as pi \ + WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ + AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s", + (employee, from_date, to_date, code)) + res = cr.fetchall() + input_ids = [r[0] for r in res] + input_lines = self.read(cr, uid, input_ids, [field],context=context) + for dict in input_lines: + result += dict.get(field) + return result + hr_payslip_input() class hr_salary_rule(osv.osv): From 12aeaca5533922ab38badba0cec649553f87fb20 Mon Sep 17 00:00:00 2001 From: mtr Date: Thu, 5 May 2011 18:05:15 +0530 Subject: [PATCH 05/34] [IMP] hr_payroll: minor changes bzr revid: mtr@mtr-20110505123515-in7313mb4ryqeb0f --- addons/hr_payroll/hr_payroll.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 31a92976bf0..628fd03ecbc 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -658,7 +658,6 @@ class hr_payslip_input(osv.osv): if not employee: return 0.0 result = 0.0 - input_ids = [] cr.execute("SELECT pi.id \ FROM hr_payslip as hp, hr_payslip_input as pi \ WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ @@ -666,7 +665,7 @@ class hr_payslip_input(osv.osv): (employee, from_date, to_date, code)) res = cr.fetchall() input_ids = [r[0] for r in res] - input_lines = self.read(cr, uid, input_ids, [field],context=context) + input_lines = self.read(cr, uid, input_ids, [field], context=context) for dict in input_lines: result += dict.get(field) return result From 3bca5dc9c83da08f0bfcd860e36f2c8c145ce75f Mon Sep 17 00:00:00 2001 From: mtr Date: Thu, 5 May 2011 18:19:59 +0530 Subject: [PATCH 06/34] [IMP] hr_payroll: minor improvement in methods for parameter employee bzr revid: mtr@mtr-20110505124959-062hns4ca03vltbu --- addons/hr_payroll/hr_payroll.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 628fd03ecbc..61b156263c5 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -613,12 +613,12 @@ class hr_payslip(osv.osv): return self.onchange_employee_id(cr, uid, ids, date_from=date_from, date_to=date_to, employee_id=employee_id, contract_id=contract_id, context=context) def sum(self, cr, uid, code, from_date, to_date=None, employee=False, context=None): + if not employee: + return 0.0 if context is None: context = {} if to_date is None: to_date = datetime.now().strftime('%Y-%m-%d') - if not employee: - return 0.0 cr.execute("SELECT sum(pl.total) \ FROM hr_payslip as hp, hr_payslip_line as pl \ WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ @@ -651,12 +651,12 @@ class hr_payslip_input(osv.osv): } def sum(self, cr, uid, code, field, from_date, to_date=None, employee=False, context=None): + if not employee: + return 0.0 if context is None: context = {} if to_date is None: to_date = datetime.now().strftime('%Y-%m-%d') - if not employee: - return 0.0 result = 0.0 cr.execute("SELECT pi.id \ FROM hr_payslip as hp, hr_payslip_input as pi \ From 7f97f2e2b3e34fda9c8ecc33073edade0e84e906 Mon Sep 17 00:00:00 2001 From: Mustufa Rangwala Date: Fri, 6 May 2011 12:09:03 +0530 Subject: [PATCH 07/34] [IMP] Payroll: Clean the code bzr revid: mra@mra-laptop-20110506063903-4hno1tb6enrd0bk4 --- addons/hr_payroll/hr_payroll.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 61b156263c5..31806a6f2ec 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -623,10 +623,10 @@ class hr_payslip(osv.osv): FROM hr_payslip as hp, hr_payslip_line as pl \ WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND pl.code = %s", - (employee, from_date, to_date, code )) + (employee, from_date, to_date, code)) res = cr.fetchone() return res and res[0] or 0.0 - + hr_payslip() class hr_payslip_input(osv.osv): @@ -649,7 +649,7 @@ class hr_payslip_input(osv.osv): _defaults = { 'sequence': 10, } - + def sum(self, cr, uid, code, field, from_date, to_date=None, employee=False, context=None): if not employee: return 0.0 @@ -663,13 +663,12 @@ class hr_payslip_input(osv.osv): WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s", (employee, from_date, to_date, code)) - res = cr.fetchall() - input_ids = [r[0] for r in res] - input_lines = self.read(cr, uid, input_ids, [field], context=context) - for dict in input_lines: - result += dict.get(field) + input_ids = [r[0] for r in cr.fetchall()] + input_data = self.read(cr, uid, input_ids, [field], context=context) + for input in input_data: + result += input.get(field) return result - + hr_payslip_input() class hr_salary_rule(osv.osv): From 4058da5295ef02e4600492e7110d251a9ff1fb00 Mon Sep 17 00:00:00 2001 From: mtr Date: Wed, 11 May 2011 11:43:49 +0530 Subject: [PATCH 08/34] [IMP] hr_payroll: improved code to take into account credit_note while calculating the sum bzr revid: mtr@mtr-20110511061349-dj6jlpmnhjn13iij --- addons/hr_payroll/hr_payroll.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 31806a6f2ec..b5b9f338b33 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -619,13 +619,18 @@ class hr_payslip(osv.osv): context = {} if to_date is None: to_date = datetime.now().strftime('%Y-%m-%d') - cr.execute("SELECT sum(pl.total) \ + sum = 0.0 + cr.execute("SELECT pl.total, hp.credit_note\ FROM hr_payslip as hp, hr_payslip_line as pl \ WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND pl.code = %s", (employee, from_date, to_date, code)) - res = cr.fetchone() - return res and res[0] or 0.0 + for r in cr.dictfetchall(): + if r['credit_note'] == False: + sum += r['total'] + else: + sum -= r['total'] + return sum hr_payslip() From c866c963e35c47d5d2b542f81ad76ca899bb6711 Mon Sep 17 00:00:00 2001 From: mtr Date: Wed, 11 May 2011 11:53:12 +0530 Subject: [PATCH 09/34] [IMP] hr_payroll: removed context,as we don't use the context later in the function bzr revid: mtr@mtr-20110511062312-r3lzjbdp10nqa28a --- addons/hr_payroll/hr_payroll.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index b5b9f338b33..a39d273b416 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -615,8 +615,6 @@ class hr_payslip(osv.osv): def sum(self, cr, uid, code, from_date, to_date=None, employee=False, context=None): if not employee: return 0.0 - if context is None: - context = {} if to_date is None: to_date = datetime.now().strftime('%Y-%m-%d') sum = 0.0 @@ -658,8 +656,6 @@ class hr_payslip_input(osv.osv): def sum(self, cr, uid, code, field, from_date, to_date=None, employee=False, context=None): if not employee: return 0.0 - if context is None: - context = {} if to_date is None: to_date = datetime.now().strftime('%Y-%m-%d') result = 0.0 From 30dee04d10164809b3f4bbb992da5029863ae0fc Mon Sep 17 00:00:00 2001 From: mtr Date: Thu, 12 May 2011 17:37:52 +0530 Subject: [PATCH 10/34] [IMP] hr_payroll: improved method of hr.payslip,to call it without passing(cr,uid) bzr revid: mtr@mtr-20110512120752-sdqi99qim652kwk0 --- addons/hr_payroll/hr_payroll.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 911d35f9bca..4e4e63826d6 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -21,6 +21,7 @@ ############################################################################## import time +import pooler from datetime import date from datetime import datetime from datetime import timedelta @@ -210,6 +211,10 @@ class hr_payslip(osv.osv): _name = 'hr.payslip' _description = 'Pay Slip' + def __init__(self, pool, cr): + super(hr_payslip, self).__init__(pool, cr) + self.cr = cr + def _get_lines_salary_category(self, cr, uid, ids, field_names, arg=None, context=None): result = {} if not ids: return result @@ -609,24 +614,26 @@ class hr_payslip(osv.osv): res['value'].update({'struct_id': False}) return self.onchange_employee_id(cr, uid, ids, date_from=date_from, date_to=date_to, employee_id=employee_id, contract_id=contract_id, context=context) - def sum(self, cr, uid, code, from_date, to_date=None, employee=False, context=None): + def sum(self, code, from_date, to_date=None, employee=False, context=None): + sum = 0.0 if not employee: return 0.0 if to_date is None: to_date = datetime.now().strftime('%Y-%m-%d') - sum = 0.0 + cr = pooler.get_db(self.cr.dbname).cursor() cr.execute("SELECT pl.total, hp.credit_note\ FROM hr_payslip as hp, hr_payslip_line as pl \ WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND pl.code = %s", - (employee, from_date, to_date, code)) + (employee, from_date, to_date, code)) for r in cr.dictfetchall(): if r['credit_note'] == False: sum += r['total'] else: sum -= r['total'] + cr.close() return sum - + hr_payslip() class hr_payslip_input(osv.osv): @@ -649,7 +656,7 @@ class hr_payslip_input(osv.osv): _defaults = { 'sequence': 10, } - + def sum(self, cr, uid, code, field, from_date, to_date=None, employee=False, context=None): if not employee: return 0.0 From 54586b7d55b5de75528e95bc56b571ff728064af Mon Sep 17 00:00:00 2001 From: mtr Date: Thu, 12 May 2011 18:06:19 +0530 Subject: [PATCH 11/34] [IMP] hr_payroll: updated localdict to copmute payslip on payslip bzr revid: mtr@mtr-20110512123619-bss3lcy1dlrbi9r7 --- addons/hr_payroll/hr_payroll.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 4e4e63826d6..386ecbc37e9 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -485,12 +485,13 @@ class hr_payslip(osv.osv): #we keep a dict with the result because a value can be overwritten by another rule with the same code result_dict = {} blacklist = [] + payslip_obj = self.pool.get('hr.payslip') obj_rule = self.pool.get('hr.salary.rule') - payslip = self.pool.get('hr.payslip').browse(cr, uid, payslip_id, context=context) + payslip = payslip_obj.browse(cr, uid, payslip_id, context=context) worked_days = {} for input_line in payslip.input_line_ids: worked_days[input_line.code] = input_line - localdict = {'categories': {}, 'payslip': payslip, 'worked_days': worked_days} + localdict = {'categories': {}, 'payslip': payslip, 'worked_days': worked_days, 'payslip_obj': payslip_obj} #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 From 8ff806bea3d2f47e780ce74318d411a774d68da9 Mon Sep 17 00:00:00 2001 From: mtr Date: Thu, 12 May 2011 19:28:25 +0530 Subject: [PATCH 12/34] [IMP] hr_payroll: improved sum method of worked days bzr revid: mtr@mtr-20110512135825-r6ighyds5xusu4cd --- addons/hr_payroll/hr_payroll.py | 51 +++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 87c996e9690..5397c673210 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -480,6 +480,7 @@ class hr_payslip(osv.osv): result_dict = {} blacklist = [] payslip_obj = self.pool.get('hr.payslip') + inputs_obj = self.pool.get('hr.payslip.worked_days') obj_rule = self.pool.get('hr.salary.rule') payslip = payslip_obj.browse(cr, uid, payslip_id, context=context) worked_days = {} @@ -488,7 +489,7 @@ class hr_payslip(osv.osv): inputs = {} for input_line in payslip.input_line_ids: inputs[input_line.code] = input_line - localdict = {'categories': {}, 'payslip': payslip, 'worked_days': worked_days, 'inputs': inputs, 'payslip_obj': payslip_obj} + localdict = {'categories': {}, 'payslip': payslip, 'worked_days': worked_days, 'inputs': inputs, 'payslip_obj': payslip_obj, 'inputs_obj':inputs_obj} #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 @@ -670,6 +671,35 @@ class hr_payslip_worked_days(osv.osv): _defaults = { 'sequence': 10, } + def __init__(self, pool, cr): + super(hr_payslip_worked_days, self).__init__(pool, cr) + self.cr = cr + + def sum(self, code, field, from_date, to_date=None, employee=False, context=None): + if not employee: + return 0.0 + if to_date is None: + to_date = datetime.now().strftime('%Y-%m-%d') + result = 0.0 + cr = pooler.get_db(self.cr.dbname).cursor() + cr.execute("SELECT pi.id\ + FROM hr_payslip as hp, hr_payslip_worked_days as pi \ + WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ + AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s", + (employee, from_date, to_date, code)) + input_ids = [r[0] for r in cr.fetchall()] + if len(input_ids) == 1: + input_ids = tuple(input_ids[0],) + else: + input_ids = tuple(input_ids) +# input_data = self.read(cr, uid, input_ids, [field], context=context) + cr = pooler.get_db(self.cr.dbname).cursor() + cr.execute("select %s from hr_payslip_worked_days as wd where wd.id in %s"%(field, input_ids)) + input_data = cr.dictfetchall() + for input in input_data: + result += input.get(field) + cr.close() + return result hr_payslip_worked_days() class hr_payslip_input(osv.osv): @@ -692,24 +722,7 @@ class hr_payslip_input(osv.osv): 'sequence': 10, 'quantity': 0.0, } - - def sum(self, cr, uid, code, field, from_date, to_date=None, employee=False, context=None): - if not employee: - return 0.0 - if to_date is None: - to_date = datetime.now().strftime('%Y-%m-%d') - result = 0.0 - cr.execute("SELECT pi.id \ - FROM hr_payslip as hp, hr_payslip_input as pi \ - WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ - AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s", - (employee, from_date, to_date, code)) - input_ids = [r[0] for r in cr.fetchall()] - input_data = self.read(cr, uid, input_ids, [field], context=context) - for input in input_data: - result += input.get(field) - return result - + hr_payslip_input() class hr_salary_rule(osv.osv): From f595581803776d5beaa2ba0d3ba277dca38eede7 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Thu, 12 May 2011 18:16:28 +0200 Subject: [PATCH 13/34] [IMP] hr_payroll: implemented the feature worked_days.WORK100.number_of_hours + improved worked_days.sum() method bzr revid: qdp-launchpad@openerp.com-20110512161628-wc8zvq62nqldc5jt --- addons/hr_payroll/hr_payroll.py | 74 ++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 5397c673210..95ecf8e6cdf 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -476,6 +476,47 @@ class hr_payslip(osv.osv): localdict['categories'][category.code] = category.code in localdict['categories'] and localdict['categories'][category.code] + amount or amount return localdict + class InputLine(object): + """a class that will be used into the python code, mainly for usability purposes""" + def __init__(self, pool, cr, uid, employee_id, dict): + self.pool = pool + self.cr = cr + self.uid = uid + self.employee_id = employee_id + self.dict = dict + def __getattr__(self, attr): + return self.dict.__getitem__(attr) + def sum(self, code, from_date, to_date=None): + if to_date is None: + to_date = datetime.now().strftime('%Y-%m-%d') + result = 0.0 + self.cr.execute("SELECT sum(quantity) as sum\ + FROM hr_payslip as hp, hr_payslip_input as pi \ + WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ + AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s", + (self.employee_id, from_date, to_date, code)) + res = self.cr.fetchone()[0] + return res or 0.0 + + class WorkedDays(InputLine): + """a class that will be used into the python code, mainly for usability purposes""" + def _sum(self, code, from_date, to_date=None): + if to_date is None: + to_date = datetime.now().strftime('%Y-%m-%d') + result = 0.0 + self.cr.execute("SELECT sum(number_of_days) as number_of_days, sum(number_of_hours) as number_of_hours\ + FROM hr_payslip as hp, hr_payslip_worked_days as pi \ + WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ + AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s", + (self.employee_id, from_date, to_date, code)) + return self.cr.fetchone() + def sum(self, code, from_date, to_date=None): + res = self._sum(code, from_date, to_date) + return res and res[0] or 0.0 + def sum_hours(self, code, from_date, to_date=None): + res = self._sum(code, from_date, to_date, ) + return res and res[1] or 0.0 + #we keep a dict with the result because a value can be overwritten by another rule with the same code result_dict = {} blacklist = [] @@ -489,7 +530,9 @@ class hr_payslip(osv.osv): inputs = {} for input_line in payslip.input_line_ids: inputs[input_line.code] = input_line - localdict = {'categories': {}, 'payslip': payslip, 'worked_days': worked_days, 'inputs': inputs, 'payslip_obj': payslip_obj, 'inputs_obj':inputs_obj} + input_obj = InputLine(self.pool, cr, uid, payslip.employee_id.id, inputs) + worked_days_obj = WorkedDays(self.pool, cr, uid, payslip.employee_id.id,worked_days) + localdict = {'categories': {}, 'payslip': payslip, 'worked_days': worked_days_obj, 'inputs': input_obj, 'payslip_obj': payslip_obj} #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 @@ -671,35 +714,6 @@ class hr_payslip_worked_days(osv.osv): _defaults = { 'sequence': 10, } - def __init__(self, pool, cr): - super(hr_payslip_worked_days, self).__init__(pool, cr) - self.cr = cr - - def sum(self, code, field, from_date, to_date=None, employee=False, context=None): - if not employee: - return 0.0 - if to_date is None: - to_date = datetime.now().strftime('%Y-%m-%d') - result = 0.0 - cr = pooler.get_db(self.cr.dbname).cursor() - cr.execute("SELECT pi.id\ - FROM hr_payslip as hp, hr_payslip_worked_days as pi \ - WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ - AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s", - (employee, from_date, to_date, code)) - input_ids = [r[0] for r in cr.fetchall()] - if len(input_ids) == 1: - input_ids = tuple(input_ids[0],) - else: - input_ids = tuple(input_ids) -# input_data = self.read(cr, uid, input_ids, [field], context=context) - cr = pooler.get_db(self.cr.dbname).cursor() - cr.execute("select %s from hr_payslip_worked_days as wd where wd.id in %s"%(field, input_ids)) - input_data = cr.dictfetchall() - for input in input_data: - result += input.get(field) - cr.close() - return result hr_payslip_worked_days() class hr_payslip_input(osv.osv): From 5439b7eb5896934be848792d143bf5b3fd572522 Mon Sep 17 00:00:00 2001 From: Mustufa Rangwala Date: Fri, 13 May 2011 11:30:12 +0530 Subject: [PATCH 14/34] [IMP] Payroll: Payslips with python code bzr revid: mra@mra-laptop-20110513060012-q0qcwg6wbe9vk613 --- addons/hr_payroll/hr_payroll.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index fba5679f582..591362f13e3 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -519,6 +519,26 @@ class hr_payslip(osv.osv): res = self._sum(code, from_date, to_date, ) return res and res[1] or 0.0 + class Payslips(InputLine): + """a class that will be used into the python code, mainly for usability purposes""" + + def sum(self, code, from_date, to_date=None): + if to_date is None: + to_date = datetime.now().strftime('%Y-%m-%d') + sum = 0.0 + self.cr.execute("SELECT pl.total, hp.credit_note\ + FROM hr_payslip as hp, hr_payslip_line as pl \ + WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ + AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND pl.code = %s", + (self.employee_id, from_date, to_date, code)) + for r in cr.dictfetchall(): + print r + if not r['credit_note']: + sum += r['total'] + else: + sum -= r['total'] + return sum + #we keep a dict with the result because a value can be overwritten by another rule with the same code result_dict = {} blacklist = [] @@ -532,9 +552,12 @@ class hr_payslip(osv.osv): inputs = {} for input_line in payslip.input_line_ids: inputs[input_line.code] = input_line + input_obj = InputLine(self.pool, cr, uid, payslip.employee_id.id, inputs) - worked_days_obj = WorkedDays(self.pool, cr, uid, payslip.employee_id.id,worked_days) - localdict = {'categories': {}, 'payslip': payslip, 'worked_days': worked_days_obj, 'inputs': input_obj, 'payslip_obj': payslip_obj} + worked_days_obj = WorkedDays(self.pool, cr, uid, payslip.employee_id.id, worked_days) + payslip_obj = Payslips(self.pool, cr, uid, payslip.employee_id.id, payslip) + + localdict = {'categories': {}, 'payslip': payslip_obj, 'worked_days': worked_days_obj, 'inputs': input_obj} #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 @@ -738,7 +761,7 @@ class hr_payslip_input(osv.osv): 'sequence': 10, 'quantity': 0.0, } - + hr_payslip_input() class hr_salary_rule(osv.osv): From e85341722fe5f561aee2ff76b7529cb3727d69de Mon Sep 17 00:00:00 2001 From: Mustufa Rangwala Date: Fri, 13 May 2011 11:32:06 +0530 Subject: [PATCH 15/34] [IMP] Payroll: remove print bzr revid: mra@mra-laptop-20110513060206-59oo6dc2arw8bps0 --- addons/hr_payroll/hr_payroll.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 591362f13e3..494af9cda55 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -532,7 +532,6 @@ class hr_payslip(osv.osv): AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND pl.code = %s", (self.employee_id, from_date, to_date, code)) for r in cr.dictfetchall(): - print r if not r['credit_note']: sum += r['total'] else: From 340a1a11d6f979f50195ce36657eee699e81c169 Mon Sep 17 00:00:00 2001 From: Mustufa Rangwala Date: Fri, 13 May 2011 11:33:27 +0530 Subject: [PATCH 16/34] [IMP] Payroll: remove unused mehtod def sum from payslip now...it will work now with payslips class .. bzr revid: mra@mra-laptop-20110513060327-viq49sr0cx0nj1zp --- addons/hr_payroll/hr_payroll.py | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 494af9cda55..4188dc610a3 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -234,10 +234,6 @@ class hr_payslip(osv.osv): _name = 'hr.payslip' _description = 'Pay Slip' - def __init__(self, pool, cr): - super(hr_payslip, self).__init__(pool, cr) - self.cr = cr - def _get_lines_salary_rule_category(self, cr, uid, ids, field_names, arg=None, context=None): result = {} if not ids: return result @@ -696,26 +692,6 @@ class hr_payslip(osv.osv): res['value'].update({'struct_id': False}) return self.onchange_employee_id(cr, uid, ids, date_from=date_from, date_to=date_to, employee_id=employee_id, contract_id=contract_id, context=context) - def sum(self, code, from_date, to_date=None, employee=False, context=None): - sum = 0.0 - if not employee: - return 0.0 - if to_date is None: - to_date = datetime.now().strftime('%Y-%m-%d') - cr = pooler.get_db(self.cr.dbname).cursor() - cr.execute("SELECT pl.total, hp.credit_note\ - FROM hr_payslip as hp, hr_payslip_line as pl \ - WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ - AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND pl.code = %s", - (employee, from_date, to_date, code)) - for r in cr.dictfetchall(): - if r['credit_note'] == False: - sum += r['total'] - else: - sum -= r['total'] - cr.close() - return sum - hr_payslip() class hr_payslip_worked_days(osv.osv): From 62c0ddad7863b50bdfe8e429661c8525828c7da9 Mon Sep 17 00:00:00 2001 From: Mustufa Rangwala Date: Fri, 13 May 2011 11:54:05 +0530 Subject: [PATCH 17/34] [IMP] Payroll: demo and default string improvements bzr revid: mra@mra-laptop-20110513062405-pf57a2ntrsze36mp --- addons/hr_payroll/hr_payroll.py | 16 ++++++++-------- addons/hr_payroll/hr_payroll_demo.xml | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 4188dc610a3..bd2ec144af1 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -728,7 +728,7 @@ 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"), - '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."), + '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.SASUS.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' @@ -746,7 +746,7 @@ class hr_salary_rule(osv.osv): 'name':fields.char('Name', size=256, required=True, readonly=False), 'code':fields.char('Code', size=64, required=True, help="The code of salary rules can be used as reference in computation of other rules. In that case, it is case sensitive."), 'sequence': fields.integer('Sequence', required=True, help='Use to arrange calculation sequence'), - 'quantity': fields.char('Quantity', size=256, help="It is used in computation for percentage and fixed amount.For e.g. A rule for Meal Voucher having fixed amount of 1€ per worked day can have its quantity defined in expression like worked_days['WORK100']['number_of_days']."), + 'quantity': fields.char('Quantity', size=256, help="It is used in computation for percentage and fixed amount.For e.g. A rule for Meal Voucher having fixed amount of 1€ per worked day can have its quantity defined in expression like worked_days.WORK100.number_of_days."), 'category_id':fields.many2one('hr.salary.rule.category', 'Category', required=True), 'active':fields.boolean('Active', help="If the active field is set to false, it will allow you to hide the salary rule without removing it."), 'appears_on_payslip': fields.boolean('Appears on Payslip', help="Used for the display of rule on payslip"), @@ -784,13 +784,13 @@ class hr_salary_rule(osv.osv): 'amount_python_compute': ''' # Available variables: #---------------------- -# payslip: hr.payslip object +# payslip: object containing the payslips # employee: hr.employee object # contract: hr.contract object # rules: rules code (previously computed) # categories: dictionary containing the computed salary rule 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. +# worked_days: object containing the computed worked days. +# inputs: object containing the computed inputs. # Note: returned value have to be set in the variable 'result' @@ -799,13 +799,13 @@ result = contract.wage * 0.10''', ''' # Available variables: #---------------------- -# payslip: hr.payslip object +# payslip: object containing the payslips # employee: hr.employee object # contract: hr.contract object # rules: rules code (previously computed) # categories: dictionary containing the computed salary rule 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. +# worked_days: object containing the computed worked days +# inputs: object containing the computed inputs # Note: returned value have to be set in the variable 'result' diff --git a/addons/hr_payroll/hr_payroll_demo.xml b/addons/hr_payroll/hr_payroll_demo.xml index 5a6ccc2c995..4abd6cdeb8a 100644 --- a/addons/hr_payroll/hr_payroll_demo.xml +++ b/addons/hr_payroll/hr_payroll_demo.xml @@ -54,7 +54,7 @@ fix - worked_days['WORK100']['number_of_days'] + worked_days.WORK100.number_of_days MA Meal Voucher @@ -67,19 +67,19 @@ Get 1% of sales - result = (inputs['S-ASUS']['quantity'] + inputs['S-CHINA']['quantity']) * contract.wage * 0.01 + result = (inputs.SASUS.quantity + inputs.SCHINA.quantity) * contract.wage * 0.01 - S-ASUS + SASUS Sale to ASUStek - S-CHINA + SCHINA Sale to China Export From 83345d5af58d56ba16ccaf86a5101e436126ea1c Mon Sep 17 00:00:00 2001 From: Mustufa Rangwala Date: Fri, 13 May 2011 12:06:39 +0530 Subject: [PATCH 18/34] [IMP] Payroll: clean codee bzr revid: mra@mra-laptop-20110513063639-kx4lbs2gq3bef6py --- addons/hr_payroll/hr_payroll.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index bd2ec144af1..a25c3aca2d9 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -482,8 +482,10 @@ class hr_payslip(osv.osv): self.uid = uid self.employee_id = employee_id self.dict = dict + def __getattr__(self, attr): return self.dict.__getitem__(attr) + def sum(self, code, from_date, to_date=None): if to_date is None: to_date = datetime.now().strftime('%Y-%m-%d') @@ -508,11 +510,13 @@ class hr_payslip(osv.osv): AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s", (self.employee_id, from_date, to_date, code)) return self.cr.fetchone() + def sum(self, code, from_date, to_date=None): res = self._sum(code, from_date, to_date) return res and res[0] or 0.0 + def sum_hours(self, code, from_date, to_date=None): - res = self._sum(code, from_date, to_date, ) + res = self._sum(code, from_date, to_date) return res and res[1] or 0.0 class Payslips(InputLine): From f46219d2669d065b7c04fe5219da58f6c5aa6fa4 Mon Sep 17 00:00:00 2001 From: Mustufa Rangwala Date: Fri, 13 May 2011 12:09:31 +0530 Subject: [PATCH 19/34] [REF] Payroll: remove unused import bzr revid: mra@mra-laptop-20110513063931-g83470vtp5z9o5lv --- addons/hr_payroll/hr_payroll.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index a25c3aca2d9..2889936cf17 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -21,7 +21,6 @@ ############################################################################## import time -import pooler from datetime import date from datetime import datetime from datetime import timedelta From 8d903b60aa00db74156f0476cba58c854a7ce238 Mon Sep 17 00:00:00 2001 From: mtr Date: Fri, 13 May 2011 16:53:15 +0530 Subject: [PATCH 20/34] [IMP] hr_payroll: improved query for sum method of Payslips class bzr revid: mtr@mtr-20110513112315-qcaemrufa22gdnag --- addons/hr_payroll/hr_payroll.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 2889936cf17..4cf55582456 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -524,18 +524,13 @@ class hr_payslip(osv.osv): def sum(self, code, from_date, to_date=None): if to_date is None: to_date = datetime.now().strftime('%Y-%m-%d') - sum = 0.0 - self.cr.execute("SELECT pl.total, hp.credit_note\ + self.cr.execute("SELECT sum(case when hp.credit_note = False then (pl.total) else (-pl.total) end)\ FROM hr_payslip as hp, hr_payslip_line as pl \ WHERE hp.employee_id = %s AND hp.state in ('confirm','done') \ AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND pl.code = %s", (self.employee_id, from_date, to_date, code)) - for r in cr.dictfetchall(): - if not r['credit_note']: - sum += r['total'] - else: - sum -= r['total'] - return sum + res = self.cr.fetchone() + return res and res[0] or 0.0 #we keep a dict with the result because a value can be overwritten by another rule with the same code result_dict = {} From 83a34f56c9384cd7baf41934c0c43dd8a9091b52 Mon Sep 17 00:00:00 2001 From: "psi (Open ERP)" Date: Mon, 16 May 2011 15:16:55 +0530 Subject: [PATCH 21/34] [IMP] split payslip report in to two. Employee payslip report will show the payslip lines appears on payslip and the payslip details report will show all the payslip line by category as well as by contribution register bzr revid: psi@tinyerp.co.in-20110516094655-gj6qtu29b6us3lh2 --- addons/hr_payroll/hr_payroll_report.xml | 126 ++--- addons/hr_payroll/report/__init__.py | 3 +- addons/hr_payroll/report/report_payslip.py | 127 ------ addons/hr_payroll/report/report_payslip.rml | 309 ++++--------- .../report/report_payslip_details.py | 113 +++++ .../report/report_payslip_details.rml | 431 ++++++++++++++++++ 6 files changed, 695 insertions(+), 414 deletions(-) create mode 100644 addons/hr_payroll/report/report_payslip_details.py create mode 100644 addons/hr_payroll/report/report_payslip_details.rml diff --git a/addons/hr_payroll/hr_payroll_report.xml b/addons/hr_payroll/hr_payroll_report.xml index 23e72d511f0..5a6816da317 100644 --- a/addons/hr_payroll/hr_payroll_report.xml +++ b/addons/hr_payroll/hr_payroll_report.xml @@ -1,65 +1,73 @@ - - - - + + + - - - - - + - - - - - + + + diff --git a/addons/hr_payroll/report/__init__.py b/addons/hr_payroll/report/__init__.py index 3113f281326..e4d936e9197 100644 --- a/addons/hr_payroll/report/__init__.py +++ b/addons/hr_payroll/report/__init__.py @@ -3,7 +3,7 @@ ############################################################################## # -# OpenERP, Open Source Management Solution +# OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved # d$ # @@ -23,6 +23,7 @@ ############################################################################## import report_payslip +import report_payslip_details import report_payroll_advice import report_year_salary import report_payroll_register diff --git a/addons/hr_payroll/report/report_payslip.py b/addons/hr_payroll/report/report_payslip.py index f1f658e40d2..f666e2f4606 100644 --- a/addons/hr_payroll/report/report_payslip.py +++ b/addons/hr_payroll/report/report_payslip.py @@ -22,7 +22,6 @@ # ############################################################################## -from datetime import datetime from report import report_sxw from tools import amount_to_text_en @@ -31,61 +30,9 @@ class payslip_report(report_sxw.rml_parse): def __init__(self, cr, uid, name, context): super(payslip_report, self).__init__(cr, uid, name, context) self.localcontext.update({ - 'convert': self.convert, - 'get_month': self.get_month, - 'get_earnings': self.get_earnings, - 'get_deductions':self.get_deductions, - 'get_leave': self.get_leave, 'get_payslip_lines': self.get_payslip_lines, - 'get_details_by_rule_category': self.get_details_by_rule_category, - 'get_lines_by_contribution_register': self.get_lines_by_contribution_register, }) - def convert(self, amount, cur): - amt_en = amount_to_text_en.amount_to_text(amount, 'en', cur) - return amt_en - - def get_leave(self, obj): - payslip_line = self.pool.get('hr.payslip.line') - res = [] -# ids = [] -# for id in range(len(obj)): -# if obj[id].type == 'leaves': -# ids.append(obj[id].id) -# if ids: -# res = payslip_line.browse(self.cr, self.uid, ids) - return res - - def get_earnings(self, obj): - payslip_line = self.pool.get('hr.payslip.line') - res = [] - ids = [] - for id in range(len(obj)): - if obj[id].category_id.parent_id.name == 'Allowance': - ids.append(obj[id].id) - if ids: - res = payslip_line.browse(self.cr, self.uid, ids) - return res - - def get_deductions(self, obj): - payslip_line = self.pool.get('hr.payslip.line') - res = [] - ids = [] - for id in range(len(obj)): - if obj[id].category_id.parent_id.name == 'Deduction': - ids.append(obj[id].id) - if ids: - res = payslip_line.browse(self.cr, self.uid, ids) - return res - - def get_month(self, obj): - res = { - 'mname':'' - } - date = datetime.strptime(obj.date, '%Y-%m-%d') - res['mname']= date.strftime('%B')+"-"+date.strftime('%Y') - return res['mname'] - def get_payslip_lines(self, obj): payslip_line = self.pool.get('hr.payslip.line') res = [] @@ -97,80 +44,6 @@ class payslip_report(report_sxw.rml_parse): res = payslip_line.browse(self.cr, self.uid, ids) return res - def get_recursive_parent(self, rule_categories): - if not rule_categories: - return [] - if rule_categories[0].parent_id: - rule_categories.insert(0, rule_categories[0].parent_id) - self.get_recursive_parent(rule_categories) - return rule_categories - - def get_details_by_rule_category(self, obj): - payslip_line = self.pool.get('hr.payslip.line') - rule_cate_obj = self.pool.get('hr.salary.rule.category') - res = [] - result = {} - ids = [] - - for id in range(len(obj)): - ids.append(obj[id].id) - if ids: - self.cr.execute('''SELECT pl.id, pl.category_id FROM hr_payslip_line as pl \ - LEFT JOIN hr_salary_rule_category AS rc on (pl.category_id = rc.id) \ - WHERE pl.id in %s \ - GROUP BY rc.parent_id, pl.sequence, pl.id, pl.category_id \ - ORDER BY pl.sequence, rc.parent_id''',(tuple(ids),)) - for x in self.cr.fetchall(): - result.setdefault(x[1], []) - result[x[1]].append(x[0]) - for key, value in result.iteritems(): - rule_categories = rule_cate_obj.browse(self.cr, self.uid, [key]) - parents = self.get_recursive_parent(rule_categories) - category_total = 0 - for line in payslip_line.browse(self.cr, self.uid, value): - category_total += line.total - level = 0 - for parent in parents: - res.append({ - 'rule_category': parent.name, - 'name': parent.name, - 'code': parent.code, - 'level': level, - 'total': category_total, - }) - level += 1 - for line in payslip_line.browse(self.cr, self.uid, value): - res.append({ - 'rule_category': line.name, - 'name': line.name, - 'code': line.code, - 'total': line.total, - 'level': level - }) - return res - - def get_lines_by_contribution_register(self, obj): - payslip_line = self.pool.get('hr.payslip.line') - result = {} - res = [] - - for id in range(len(obj)): - if obj[id].register_id: - result.setdefault(obj[id].register_id.name, []) - result[obj[id].register_id.name].append(obj[id].id) - for key, value in result.iteritems(): - res.append({ - 'register_name': key, - }) - for line in payslip_line.browse(self.cr, self.uid, value): - res.append({ - 'name': line.name, - 'code': line.code, - 'total': line.total, - }) - return res - -#report_sxw.report_sxw('report.payslip.pdf', 'hr.payslip', 'hr_payroll/report/payslip.rml', parser=payslip_report) report_sxw.report_sxw('report.test.pdf', 'hr.payslip', 'hr_payroll/report/report_payslip.rml', parser=payslip_report) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/hr_payroll/report/report_payslip.rml b/addons/hr_payroll/report/report_payslip.rml index 02c97e1ec62..2cc45847d0a 100644 --- a/addons/hr_payroll/report/report_payslip.rml +++ b/addons/hr_payroll/report/report_payslip.rml @@ -114,67 +114,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + @@ -184,36 +126,28 @@ - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -229,7 +163,6 @@ - @@ -239,11 +172,11 @@ - [[repeatIn(objects,'o')]] + [[repeatIn(objects,'o')]] - Pay Slip + Pay Slip @@ -253,20 +186,20 @@ Note - ([[o.name]]) + ([[o.name]]) - Name + Name - [[o.employee_id.name]] + [[o.employee_id.name]] - Designation + Designation - [[ o.employee_id.job_id.name or '' ]] + [[ o.employee_id.job_id.name or '' ]] @@ -278,17 +211,17 @@ - [[o.employee_id.address_home_id and o.employee_id.address_home_id.name or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.street or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.street2 or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.zip or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.city or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.state_id and o.employee_id.address_home_id.state_id.name or '' ]] [[o.employee_id.address_home_id and o.employee_id.address_home_id.country_id and o.employee_id.address_home_id.country_id.name or '' ]] + [[o.employee_id.address_home_id and o.employee_id.address_home_id.name or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.street or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.street2 or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.zip or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.city or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.state_id and o.employee_id.address_home_id.state_id.name or '' ]] [[o.employee_id.address_home_id and o.employee_id.address_home_id.country_id and o.employee_id.address_home_id.country_id.name or '' ]] - Email + Email - [[ o.employee_id.work_email or '' ]] + [[ o.employee_id.work_email or '' ]] @@ -296,33 +229,33 @@ - [[ o.employee_id.identification_id or '' ]] + [[ o.employee_id.identification_id or '' ]] - Reference + Reference - [[ o.number or '' ]] + [[ o.number or '' ]] - Bank Account + Bank Account - [[ o.employee_id.otherid or '' ]] + [[ o.employee_id.otherid or '' ]] - Date From + Date From - [[ o.date_from or '']] + [[ o.date_from or '']] @@ -330,168 +263,90 @@ - [[ o.date_to or '' ]] + [[ o.date_to or '' ]] - + - + - Payslip Lines: + Payslip Lines: - Code + Code - Name + Name - Amount (in [[o.company_id and o.company_id.currency_id.symbol or '']]) + Amount (in [[o.company_id and o.company_id.currency_id.symbol or '']]) -
- [[repeatIn(get_payslip_lines(o.line_ids),'p') ]] - - - - [[ p.code ]] - - - [[ p.name ]] - - - [[ p.total or '0.0']] - - - -
- - - - Details by Salary Rule Category: - - - - - - - Code - - - Salary Rule Category - - - Name - - - Amount(in [[o.company_id and o.company_id.currency_id.symbol or '']]) - - - +
+ [[repeatIn(get_payslip_lines(o.line_ids),'p') ]] + + + + [[ p.code ]] + + + [[ p.name ]] + + + [[ p.total or '0.0']] + + + + + + +
+ + + + + + + + + -
- [[repeatIn(get_details_by_rule_category(o.details_by_salary_rule_category),'h') ]] - - - - - [[ h['code'] ]] - [[ h['level']!=0 and ( setTag('para','para',{'style':'terp_default_8'})) or removeParentNode('font')]] - - - - [[ '..'*h['level'] ]][[ h['rule_category'] ]][[ h['level']!=0 and ( setTag('para','para',{'style':'terp_default_8'})) or removeParentNode('font') ]] - - - [[ h['name'] ]][[ h['level']!=0 and ( setTag('para','para',{'style':'terp_default_8'})) or removeParentNode('font')]] - - - [[ h['total'] ]] [[ h['level']!=0 and ( setTag('para','para',{'style':'terp_default_10'})) or removeParentNode('font') ]] - - - -
- - - - - - - Payslip Lines by Contribution Register: - - - - - - - Register Name - - - Code - - - Name - - - Amount (in [[o.company_id and o.company_id.currency_id.symbol or '']]) - - - -
- [[repeatIn(get_lines_by_contribution_register(o.details_by_salary_rule_category),'r') ]] - - - - [[ r.get('register_name', False) ]][[ h.get('register_name', False) and ( setTag('para','para',{'style':'terp_default_8'})) or removeParentNode('font')]] - - - [[ r['code'] ]] - - - [[ r['name'] ]] - - - [[ r['total'] or '0.0']] - - - -
- + - + - + - + - Authorized Signature + Authorized Signature - +
diff --git a/addons/hr_payroll/report/report_payslip_details.py b/addons/hr_payroll/report/report_payslip_details.py new file mode 100644 index 00000000000..6bc737a385f --- /dev/null +++ b/addons/hr_payroll/report/report_payslip_details.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- + +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved +# d$ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from report import report_sxw +from tools import amount_to_text_en + +class payslip_details_report(report_sxw.rml_parse): + + def __init__(self, cr, uid, name, context): + super(payslip_details_report, self).__init__(cr, uid, name, context) + self.localcontext.update({ + 'get_details_by_rule_category': self.get_details_by_rule_category, + 'get_lines_by_contribution_register': self.get_lines_by_contribution_register, + }) + + def get_details_by_rule_category(self, obj): + payslip_line = self.pool.get('hr.payslip.line') + rule_cate_obj = self.pool.get('hr.salary.rule.category') + + def get_recursive_parent(rule_categories): + if not rule_categories: + return [] + if rule_categories[0].parent_id: + rule_categories.insert(0, rule_categories[0].parent_id) + self.get_recursive_parent(rule_categories) + return rule_categories + + res = [] + result = {} + ids = [] + + for id in range(len(obj)): + ids.append(obj[id].id) + if ids: + self.cr.execute('''SELECT pl.id, pl.category_id FROM hr_payslip_line as pl \ + LEFT JOIN hr_salary_rule_category AS rc on (pl.category_id = rc.id) \ + WHERE pl.id in %s \ + GROUP BY rc.parent_id, pl.sequence, pl.id, pl.category_id \ + ORDER BY pl.sequence, rc.parent_id''',(tuple(ids),)) + for x in self.cr.fetchall(): + result.setdefault(x[1], []) + result[x[1]].append(x[0]) + for key, value in result.iteritems(): + rule_categories = rule_cate_obj.browse(self.cr, self.uid, [key]) + parents = get_recursive_parent(rule_categories) + category_total = 0 + for line in payslip_line.browse(self.cr, self.uid, value): + category_total += line.total + level = 0 + for parent in parents: + res.append({ + 'rule_category': parent.name, + 'name': parent.name, + 'code': parent.code, + 'level': level, + 'total': category_total, + }) + level += 1 + for line in payslip_line.browse(self.cr, self.uid, value): + res.append({ + 'rule_category': line.name, + 'name': line.name, + 'code': line.code, + 'total': line.total, + 'level': level + }) + return res + + def get_lines_by_contribution_register(self, obj): + payslip_line = self.pool.get('hr.payslip.line') + result = {} + res = [] + + for id in range(len(obj)): + if obj[id].register_id: + result.setdefault(obj[id].register_id.name, []) + result[obj[id].register_id.name].append(obj[id].id) + for key, value in result.iteritems(): + res.append({ + 'register_name': key, + }) + for line in payslip_line.browse(self.cr, self.uid, value): + res.append({ + 'name': line.name, + 'code': line.code, + 'total': line.total, + }) + return res + +report_sxw.report_sxw('report.paylip.details', 'hr.payslip', 'hr_payroll/report/report_payslip_details.rml', parser=payslip_details_report) + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/hr_payroll/report/report_payslip_details.rml b/addons/hr_payroll/report/report_payslip_details.rml new file mode 100644 index 00000000000..132e793cb3a --- /dev/null +++ b/addons/hr_payroll/report/report_payslip_details.rml @@ -0,0 +1,431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[repeatIn(objects,'o')]] + + + + Pay Slip Details + + + + + [[o.credit_note==False and removeParentNode('para')]] + Credit + + Note + + ([[o.name]]) + + + + Name + + + [[o.employee_id.name]] + + + Designation + + + [[ o.employee_id.job_id.name or '' ]] + + + + + + + + Address + + + + [[o.employee_id.address_home_id and o.employee_id.address_home_id.name or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.street or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.street2 or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.zip or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.city or '' ]],[[o.employee_id.address_home_id and o.employee_id.address_home_id.state_id and o.employee_id.address_home_id.state_id.name or '' ]] [[o.employee_id.address_home_id and o.employee_id.address_home_id.country_id and o.employee_id.address_home_id.country_id.name or '' ]] + + + + + + + Email + + + [[ o.employee_id.work_email or '' ]] + + + + Identification No + + + + [[ o.employee_id.identification_id or '' ]] + + + + + + + Reference + + + [[ o.number or '' ]] + + + Bank Account + + + [[ o.employee_id.otherid or '' ]] + + + + + + + Date From + + + [[ o.date_from or '']] + + + + Date To + + + + [[ o.date_to or '' ]] + + + + + + + + + + + + + + Details by Salary Rule Category: + + + + + + + Code + + + Salary Rule Category + + + Name + + + Amount(in [[o.company_id and o.company_id.currency_id.symbol or '']]) + + + + + + +
+ [[repeatIn(get_details_by_rule_category(o.details_by_salary_rule_category),'h') ]] + + + + + [[ h['code'] ]] + [[ h['level']!=0 and ( setTag('para','para',{'style':'terp_default_8'})) or removeParentNode('font')]] + + + + [[ '..'*h['level'] ]][[ h['rule_category'] ]][[ h['level']!=0 and ( setTag('para','para',{'style':'terp_default_8'})) or removeParentNode('font') ]] + + + [[ h['name'] ]][[ h['level']!=0 and ( setTag('para','para',{'style':'terp_default_8'})) or removeParentNode('font')]] + + + [[ h['total'] ]] [[ h['level']!=0 and ( setTag('para','para',{'style':'terp_default_10'})) or removeParentNode('font') ]] + + + +
+ + + + + + + + Payslip Lines by Contribution Register: + + + + + + + Register Name + + + Code + + + Name + + + Amount (in [[o.company_id and o.company_id.currency_id.symbol or '']]) + + + +
+ [[repeatIn(get_lines_by_contribution_register(o.details_by_salary_rule_category),'r')]] + + + + [[ r.get('register_name', False) ]][[ h.get('register_name', False) and ( setTag('para','para',{'style':'terp_default_8'})) or removeParentNode('font')]] + + + [[ r['code'] ]] + + + [[ r['name'] ]] + + + [[ r['total'] or '0.0']] + + + +
+ + + + + + + + + + + + + + + + + + Authorized Signature + + + + + + +
+
+ From 22c2b27b3a70b11603b18da9eff7373f15ccce80 Mon Sep 17 00:00:00 2001 From: mtr Date: Mon, 16 May 2011 18:57:39 +0530 Subject: [PATCH 22/34] [IMP] hr_payroll: changed label of field quantity on Payslip input into 'Amount' bzr revid: mtr@mtr-20110516132739-bay9gf9tpolxagsx --- 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 b70b30676a8..cd7c08144bf 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -660,7 +660,7 @@ 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"), - '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."), + 'quantity': fields.float('Amount', 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' From 0df1f0680159cb8713ba4b194664076cf171bed5 Mon Sep 17 00:00:00 2001 From: mtr Date: Tue, 17 May 2011 16:21:55 +0530 Subject: [PATCH 23/34] [IMP] hr_payroll: improved payslip states(draft, verify, done) and workflow bzr revid: mtr@mtr-20110517105155-d4dp2tt7d7ut4jxd --- addons/hr_payroll/hr_payroll.py | 27 +++++--- addons/hr_payroll/hr_payroll_view.xml | 7 +- addons/hr_payroll/hr_payroll_workflow.xml | 81 ++++++++++++++--------- 3 files changed, 72 insertions(+), 43 deletions(-) diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index b70b30676a8..9ac05332801 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -255,12 +255,16 @@ class hr_payslip(osv.osv): 'date_from': fields.date('Date From', readonly=True, states={'draft': [('readonly', False)]}, required=True), 'date_to': fields.date('Date To', readonly=True, states={'draft': [('readonly', False)]}, required=True), 'state': fields.selection([ - ('draft', 'Waiting for Verification'), - ('hr_check', 'Waiting for HR Verification'), - ('accont_check', 'Waiting for Account Verification'), - ('confirm', 'Confirm Sheet'), - ('done', 'Paid Salary'), + ('draft', 'Draft'), + ('verify', 'Verify'), + ('done', 'Done'), ('cancel', 'Reject'), +# ('draft', 'Waiting for Verification'), +# ('hr_check', 'Waiting for HR Verification'), +# ('accont_check', 'Waiting for Account Verification'), +# ('confirm', 'Confirm Sheet'), +# ('done', 'Paid Salary'), +# ('cancel', 'Reject'), ], 'State', select=True, readonly=True, help=' * When the payslip is created the state is \'Waiting for verification\'.\ \n* It is varified by the user and payslip is sent for HR varification, the state is \'Waiting for HR Verification\'. \ @@ -310,21 +314,23 @@ class hr_payslip(osv.osv): def account_check_sheet(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'accont_check'}, context=context) - + def hr_check_sheet(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'hr_check'}, context=context) - + def process_sheet(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'paid': True, 'state': 'done'}, context=context) + def hr_verify_sheet(self, cr, uid, ids, context=None): + return self.write(cr, uid, ids, {'state': 'verify'}, context=context) + def refund_sheet(self, cr, uid, ids, context=None): mod_obj = self.pool.get('ir.model.data') wf_service = netsvc.LocalService("workflow") for id in ids: id_copy = self.copy(cr, uid, id, {'credit_note': True}, context=context) self.compute_sheet(cr, uid, [id_copy], context=context) - wf_service.trg_validate(uid, 'hr.payslip', id_copy, 'verify_sheet', cr) - wf_service.trg_validate(uid, 'hr.payslip', id_copy, 'final_verify_sheet', cr) + wf_service.trg_validate(uid, 'hr.payslip', id_copy, 'hr_verify_sheet', cr) wf_service.trg_validate(uid, 'hr.payslip', id_copy, 'process_sheet', cr) form_id = mod_obj.get_object_reference(cr, uid, 'hr_payroll', 'view_hr_payslip_form') @@ -347,6 +353,9 @@ class hr_payslip(osv.osv): def verify_sheet(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'confirm'}, context=context) + + def check(self, cr, uid, ids, context=None): + return True #TODO move this function into hr_contract module, on hr.employee object def get_contract(self, cr, uid, employee, date_from, date_to, context=None): diff --git a/addons/hr_payroll/hr_payroll_view.xml b/addons/hr_payroll/hr_payroll_view.xml index 4d422d708de..4393f25b9d9 100644 --- a/addons/hr_payroll/hr_payroll_view.xml +++ b/addons/hr_payroll/hr_payroll_view.xml @@ -329,13 +329,14 @@ -