diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 2c304d8fd17..dbd6f64b1c1 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -464,6 +464,66 @@ class hr_payslip(osv.osv): result[record.id] = [x[0] for x in res] return result + def _get_parent_structure(self, cr, uid, struct_id, context=None): + if not struct_id: + return [] + parent = [] + for line in self.pool.get('hr.payroll.structure').browse(cr, uid, struct_id): + if line.parent_id: + parent.append(line.parent_id.id) + if parent: + parent = self._get_parent_structure(cr, uid, parent, context) + return struct_id + parent + + def _applied_salary_rule(self, cr, uid, ids, field_names, arg=None, context=None): + structure_obj = self.pool.get('hr.payroll.structure') + result = {} + for record in self.browse(cr, uid, ids, context=context): + function = record.struct_id.id + sal_structure = [] + lines = [] + rules = [] + rule = [] + if function: + sal_structure = self._get_parent_structure(cr, uid, [function], context=context) + for struct in sal_structure: + lines = structure_obj.browse(cr, uid, struct, context=context).rule_ids + for rl in lines: + if rl.child_ids: + for r in rl.child_ids: + lines.append(r) + rules.append(rl) + for r in rules: + if r.id not in rule: + rule.append(r.id) + result[record.id] = rule + return result + + def _appears_on_payslip_rule(self, cr, uid, ids, field_names, arg=None, context=None): + struct_obj = self.pool.get('hr.payroll.structure') + result = {} + for record in self.browse(cr, uid, ids, context=context): + structure = record.struct_id.id + sal_struct = [] + lines = [] + rules = [] + rule = [] + if structure: + sal_struct = self._get_parent_structure(cr, uid, [structure], context=context) + for struct in sal_struct: + lines = struct_obj.browse(cr, uid, struct, context=context).rule_ids + for rl in lines: + if rl.child_ids: + for r in rl.child_ids: + lines.append(r) + rules.append(rl) + for r in rules: + if r.appears_on_payslip: + if r.id not in rule: + rule.append(r.id) + result[record.id] = rule + return result + def _compute(self, cr, uid, id, value, context=None): rule_obj = self.pool.get('hr.salary.rule') contrib = rule_obj.browse(cr, uid, id, context=context) @@ -509,6 +569,9 @@ class hr_payslip(osv.osv): '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.function(_get_holidays, method=True, type='one2many', relation='hr.holidays', string='Holiday Lines', required=False), + 'applied_salary_rule': fields.function(_applied_salary_rule, method=True, type='one2many', relation='hr.salary.rule', string='Applied Salary Rules', required=False), + 'appears_on_payslip_rule': fields.function(_appears_on_payslip_rule, method=True, type='one2many', relation='hr.salary.rule', string='Appears on Payslip', required=False), +# 'details_by_salary_head': fields.function(_get_salary_rules, method=True, type='one2many', relation='hr.salary.rule', string='Details by Salary Head'), } _defaults = { 'date': lambda *a: time.strftime('%Y-%m-%d'), @@ -633,17 +696,6 @@ class hr_payslip(osv.osv): result = [x[0] for x in res] return result - def _get_parent_structure(self, cr, uid, struct_id, context=None): - if not struct_id: - return [] - parent = [] - for line in self.pool.get('hr.payroll.structure').browse(cr, uid, struct_id): - if line.parent_id: - parent.append(line.parent_id.id) - if parent: - parent = self._get_parent_structure(cr, uid, parent, context) - return struct_id + parent - def compute_sheet(self, cr, uid, ids, context=None): func_pool = self.pool.get('hr.payroll.structure') slip_line_pool = self.pool.get('hr.payslip.line') @@ -662,133 +714,138 @@ class hr_payslip(osv.osv): update = {} ttyme = datetime.fromtimestamp(time.mktime(time.strptime(slip.date, "%Y-%m-%d"))) contracts = self.get_contract(cr, uid, slip.employee_id, date, context) - if contracts.get('id', False) == False: + if not contracts: update.update({ - 'basic': 0.0, + 'basic_amount': 0.0, 'basic_before_leaves': 0.0, 'name': 'Salary Slip of %s for %s' % (slip.employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))), 'state': 'draft', 'contract_id': False, + 'struct_id': False, 'company_id': slip.employee_id.company_id.id }) self.write(cr, uid, [slip.id], update, context=context) continue - contract = slip.employee_id.contract_id - function = contract.struct_id.id - sal_structure = [] - if function: - sal_structure = self._get_parent_structure(cr, uid, [function], context=context) - lines = [] - rules = [] - for struct in sal_structure: - lines = func_pool.browse(cr, uid, struct, context=context).rule_ids - for rl in lines: - if rl.child_ids: - for r in rl.child_ids: - lines.append(r) - rules.append(rl) - ad = [] - total = 0.0 - obj = {'basic': contract.wage} - for line in rules: - cd = line.code.lower() - obj[cd] = line.amount or 0.0 - - for line in rules: - if line.category_id.code in ad: + for contract in contracts: + if contract.get('id', False) == False: continue - ad.append(line.category_id.code) - cd = line.category_id.code.lower() - calculate = False - try: - exp = line.conditions - calculate = eval(exp, obj) - except Exception, e: - raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) + contract_id = contract.get('id') + contract = self.pool.get('hr.contract').browse(cr, uid, contract_id, context=context) + function = contract.struct_id.id + sal_structure = [] + if function: + sal_structure = self._get_parent_structure(cr, uid, [function], context=context) + lines = [] + rules = [] + for struct in sal_structure: + lines = func_pool.browse(cr, uid, struct, context=context).rule_ids + for rl in lines: + if rl.child_ids: + for r in rl.child_ids: + lines.append(r) + rules.append(rl) + ad = [] + total = 0.0 + obj = {'basic': contract.wage} + for line in rules: + cd = line.code.lower() + obj[cd] = line.amount or 0.0 - if not calculate: - continue - - value = 0.0 - base = line.computational_expression - try: - amt = eval(base, obj) - except Exception, e: - raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) - if line.amount_type == 'per': + for line in rules: + if line.category_id.code in ad: + continue + ad.append(line.category_id.code) + cd = line.category_id.code.lower() + calculate = False try: - if line.child_depend == False: - if line.parent_rule_id: - for rul in [line.parent_rule_id]: - val = rul.amount * amt - amt = val - value = line.amount * amt - if line.condition_range_min or line.condition_range_max: - if ((value < line.condition_range_min) or (value > line.condition_range_max)): - value = 0.0 - else: - value = value - else: - value = value + exp = line.conditions + calculate = eval(exp, obj) except Exception, e: raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) - elif line.amount_type == 'fix': - if line.child_depend == False: - if line.parent_rule_id: - for rul in [line.parent_rule_id]: - value = value - if line.condition_range_min or line.condition_range_max: - if ((line.amount < line.condition_range_min) or (line.amount > line.condition_range_max)): - value = value + if not calculate: + continue + + value = 0.0 + base = line.computational_expression + try: + amt = eval(base, obj) + except Exception, e: + raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) + if line.amount_type == 'per': + try: + if line.child_depend == False: + if line.parent_rule_id: + for rul in [line.parent_rule_id]: + val = rul.amount * amt + amt = val + value = line.amount * amt + if line.condition_range_min or line.condition_range_max: + if ((value < line.condition_range_min) or (value > line.condition_range_max)): + value = 0.0 + else: + value = value + else: + value = value + except Exception, e: + raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e)) + + elif line.amount_type == 'fix': + if line.child_depend == False: + if line.parent_rule_id: + for rul in [line.parent_rule_id]: + value = value + if line.condition_range_min or line.condition_range_max: + if ((line.amount < line.condition_range_min) or (line.amount > line.condition_range_max)): + value = value + else: + value = line.amount else: value = line.amount - else: - value = line.amount - elif line.amount_type=='code': - localdict = {'basic':amt, 'employee':slip.employee_id, 'contract':contract} - exec line.python_compute in localdict - value = localdict['result'] - total += value - vals = { - 'slip_id': slip.id, - 'category_id': line.category_id.id, - 'name': line.name, - 'sequence': line.sequence, - 'type': line.type.id, - 'code': line.code, - 'amount_type': line.amount_type, - 'amount': line.amount, - 'total': value, - 'employee_id': slip.employee_id.id, - 'base': line.computational_expression - } - if line.appears_on_payslip: - if line.parent_rule_id: - for l in salary_rule_pool.browse(cr, uid, [line.parent_rule_id.id], context=context): - slip_line_pool.create(cr, uid, vals, {}) - else: - if line.condition_range_min or line.condition_range_max: - if not ((value < line.condition_range_min) or (value > line.condition_range_max)): + elif line.amount_type=='code': + localdict = {'basic':amt, 'employee':slip.employee_id, 'contract':contract} + exec line.python_compute in localdict + value = localdict['result'] + total += value + vals = { + 'slip_id': slip.id, + 'category_id': line.category_id.id, + 'name': line.name, + 'sequence': line.sequence, + 'type': line.type.id, + 'code': line.code, + 'amount_type': line.amount_type, + 'amount': line.amount, + 'total': value, + 'employee_id': slip.employee_id.id, + 'base': line.computational_expression + } + if line.appears_on_payslip: + if line.parent_rule_id: + for l in salary_rule_pool.browse(cr, uid, [line.parent_rule_id.id], context=context): slip_line_pool.create(cr, uid, vals, {}) else: - slip_line_pool.create(cr, uid, vals, {}) + if line.condition_range_min or line.condition_range_max: + if not ((value < line.condition_range_min) or (value > line.condition_range_max)): + slip_line_pool.create(cr, uid, vals, {}) + else: + slip_line_pool.create(cr, uid, vals, {}) - basic = contract.wage - number = sequence_obj.get(cr, uid, 'salary.slip') - update.update({ - 'struct_id': function, - 'number': number, - 'basic_amount': basic, - 'basic_before_leaves': basic, - 'total_pay': basic + total, - 'name': 'Salary Slip of %s for %s' % (slip.employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))), - 'state':'draft', - 'contract_id': contract.id, - 'company_id': slip.employee_id.company_id.id - }) - self.write(cr, uid, [slip.id], update, context=context) + basic = contract.wage + number = sequence_obj.get(cr, uid, 'salary.slip') + update.update({ + 'struct_id': function, + 'number': number, + 'basic_amount': basic, + 'basic_before_leaves': basic, + 'total_pay': basic + total, + 'name': 'Salary Slip of %s for %s' % (slip.employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))), + 'state':'draft', + 'contract_id': contract.id, + 'company_id': slip.employee_id.company_id.id + }) + self.write(cr, uid, [slip.id], update, context=context) for slip in self.browse(cr, uid, ids, context=context): if not slip.contract_id: @@ -974,11 +1031,12 @@ class hr_payslip(osv.osv): val = rul.amount * amt amt = val value = line.amount * amt - if line.condition_range_min or line.condition_range_max: - if ((value < line.condition_range_min) or (value > line.condition_range_max)): - value = 0.0 - else: - value = value + if line.condition_select == 'range': + if line.condition_range_min or line.condition_range_max: + if ((value < line.condition_range_min) or (value > line.condition_range_max)): + value = 0.0 + else: + value = value else: value = value except Exception, e: @@ -989,30 +1047,31 @@ class hr_payslip(osv.osv): if line.parent_rule_id: for rul in [line.parent_rule_id]: value = value - if line.condition_range_min or line.condition_range_max: - if ((line.amount < line.condition_range_min) or (line.amount > line.condition_range_max)): - value = value - else: - value = line.amount + if line.condition_select == 'range': + if line.condition_range_min or line.condition_range_max: + if ((line.amount < line.condition_range_min) or (line.amount > line.condition_range_max)): + value = value + else: + value = line.amount else: value = line.amount elif line.amount_type=='code': - localdict = {'basic':amt, 'employee':employee_id, 'contract':contract_id} + localdict = {'basic':amt, 'employee':employee_id, 'contract':contract} exec line.python_compute in localdict val = localdict['result'] if line.child_depend == False: if line.parent_rule_id: for rul in [line.parent_rule_id]: value = val - if line.condition_range_min or line.condition_range_max: - if ((line.amount < line.condition_range_min) or (line.amount > line.condition_range_max)): - value = value - else: - value = val + if line.condition_select == 'range': + if line.condition_range_min or line.condition_range_max: + if ((line.amount < line.condition_range_min) or (line.amount > line.condition_range_max)): + value = value + else: + value = val else: value = val - total += value vals = { 'category_id': line.category_id.id, @@ -1033,20 +1092,20 @@ class hr_payslip(osv.osv): else: update['value']['line_ids'].append(vals) - basic = contract_id.wage - all_basic += basic - final_total += basic + total - number = sequence_obj.get(cr, uid, 'salary.slip') - update['value'].update({ -# 'struct_id': function, - 'number': number, - 'basic_amount': all_basic, - 'basic_before_leaves': basic, - 'total_pay': final_total, - 'name': 'Salary Slip of %s for %s' % (employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))), -# 'contract_id': contract_id.id, - 'company_id': employee_id.company_id.id - }) + basic = contract_id.wage + all_basic += basic + final_total += basic + total + number = sequence_obj.get(cr, uid, 'salary.slip') + update['value'].update({ + # 'struct_id': function, + 'number': number, + 'basic_amount': all_basic, + 'basic_before_leaves': basic, + 'total_pay': final_total, + 'name': 'Salary Slip of %s for %s' % (employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))), + # 'contract_id': contract_id.id, + 'company_id': employee_id.company_id.id + }) basic_before_leaves = update['value']['basic_amount'] total_before_leaves = update['value']['total_pay'] @@ -1115,11 +1174,12 @@ class hr_payslip(osv.osv): val = rul.amount * amt amt = val value = salary_rule.amount * amt * days - if salary_rule.condition_range_min or salary_rule.condition_range_max: - if ((value < salary_rule.condition_range_min) or (value > salary_rule.condition_range_max)): - value = 0.0 - else: - value = value + if line.condition_select == 'range': + if salary_rule.condition_range_min or salary_rule.condition_range_max: + if ((value < salary_rule.condition_range_min) or (value > salary_rule.condition_range_max)): + value = 0.0 + else: + value = value else: value = value @@ -1131,11 +1191,12 @@ class hr_payslip(osv.osv): if salary_rule.parent_rule_id: for rul in [salary_rule.parent_rule_id]: value = salary_rule.amount * days - if salary_rule.condition_range_min or salary_rule.condition_range_max: - if ((salary_rule.amount < salary_rule.condition_range_min) or (salary_rule.amount > salary_rule.condition_range_max)): - value = 0.0 - else: - value = salary_rule.amount * days + if line.condition_select == 'range': + if salary_rule.condition_range_min or salary_rule.condition_range_max: + if ((salary_rule.amount < salary_rule.condition_range_min) or (salary_rule.amount > salary_rule.condition_range_max)): + value = 0.0 + else: + value = salary_rule.amount * days else: value = salary_rule.amount * days @@ -1147,11 +1208,12 @@ class hr_payslip(osv.osv): if salary_rule.parent_rule_id: for rul in [salary_rule.parent_rule_id]: value = val - if salary_rule.condition_range_min or salary_rule.condition_range_max: - if ((salary_rule.amount < salary_rule.condition_range_min) or (salary_rule.amount > salary_rule.condition_range_max)): - value = value - else: - value = val + if line.condition_select == 'range': + if salary_rule.condition_range_min or salary_rule.condition_range_max: + if ((salary_rule.amount < salary_rule.condition_range_min) or (salary_rule.amount > salary_rule.condition_range_max)): + value = value + else: + value = val else: value = val res['amount'] = salary_rule.amount diff --git a/addons/hr_payroll/hr_payroll_view.xml b/addons/hr_payroll/hr_payroll_view.xml index 1a148f2e49a..8a64529989e 100644 --- a/addons/hr_payroll/hr_payroll_view.xml +++ b/addons/hr_payroll/hr_payroll_view.xml @@ -284,8 +284,10 @@ + +