diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py index 9b390691c33..55cadd1efc9 100644 --- a/addons/hr_payroll/hr_payroll.py +++ b/addons/hr_payroll/hr_payroll.py @@ -463,7 +463,7 @@ class hr_payslip(osv.osv): if res: 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 [] @@ -498,7 +498,7 @@ class hr_payslip(osv.osv): 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 = {} @@ -523,7 +523,7 @@ class hr_payslip(osv.osv): 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) @@ -658,18 +658,6 @@ 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 @@ -678,11 +666,10 @@ class hr_payslip(osv.osv): (emp.id=%s) AND (date_start <= %s) AND (date_end IS NULL OR date_end >= %s) - LIMIT 1 ''' cr.execute(sql_req, (employee.id, date, date)) - contract = cr.dictfetchone() - return contract and contract or {} + contracts = cr.dictfetchall() + return contracts and contracts or {} def _get_leaves(self, cr, user, ddate, employee, context=None): """ @@ -715,145 +702,159 @@ class hr_payslip(osv.osv): holiday_pool = self.pool.get('hr.holidays') sequence_obj = self.pool.get('ir.sequence') salary_rule_pool = self.pool.get('hr.salary.rule') + contract_obj = self.pool.get('hr.contract') resource_attendance_pool = self.pool.get('resource.calendar.attendance') if context is None: context = {} date = self.read(cr, uid, ids, ['date'], context=context)[0]['date'] for slip in self.browse(cr, uid, ids, context=context): - old_slip_ids = slip_line_pool.search(cr, uid, [('slip_id','=',slip.id)], context=context) + old_slip_ids = slip_line_pool.search(cr, uid, [('slip_id', '=', slip.id)], context=context) slip_line_pool.unlink(cr, uid, old_slip_ids, context=context) - 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: + contract_id = slip.contract_id.id + if not contract_id: + update.update({'struct_id': False}) + contracts = self.get_contract(cr, uid, slip.employee_id, date, context=context) + else: + contracts = [contract_obj.read(cr, uid, contract_id, ['wage', 'struct_id', 'id'], context=context)] update.update({ - 'basic': 0.0, + 'struct_id': contracts[0].get('struct_id', False), + 'contract_id': contract_id + }) + if not contracts: + update.update({ + '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: @@ -864,7 +865,7 @@ class hr_payslip(osv.osv): dates = prev_bounds(slip.date) calendar_id = slip.employee_id.contract_id.working_hours.id if not calendar_id: - raise osv.except_osv(_('Error !'), _("Please define working schedule on %s's contract") % (employee_id.name)) + raise osv.except_osv(_('Error !'), _("Please define working schedule on %s's contract") % (slip.employee_id.name)) week_days = {"0": "mon", "1": "tue", "2": "wed","3": "thu", "4": "fri", "5": "sat", "6": "sun"} wk_days = {} week_ids = resource_attendance_pool.search(cr, uid, [('calendar_id', '=', calendar_id)], context=context) @@ -919,7 +920,7 @@ class hr_payslip(osv.osv): elif salary_rule.amount_type == 'fix': value = salary_rule.amount * days elif salary_rule.amount_type=='code': - localdict = {'basic':amt, 'employee':slip.employee_id, 'contract':contract} + localdict = {'basic': amt, 'employee': slip.employee_id, 'contract': contract} exec salary_rule.python_compute in localdict value = localdict['result'] * days res['amount'] = salary_rule.amount @@ -949,6 +950,7 @@ class hr_payslip(osv.osv): holiday_pool = self.pool.get('hr.holidays') sequence_obj = self.pool.get('ir.sequence') empolyee_obj = self.pool.get('hr.employee') + contract_obj = self.pool.get('hr.contract') resource_attendance_pool = self.pool.get('resource.calendar.attendance') if context is None: @@ -965,144 +967,155 @@ class hr_payslip(osv.osv): employee_id = empolyee_obj.browse(cr, uid, employee_id, context=context) ttyme = datetime.fromtimestamp(time.mktime(time.strptime(ddate, "%Y-%m-%d"))) if not contract_id: + update['value'].update({'struct_id': False}) contracts = self.get_contract(cr, uid, employee_id, ddate, context=context) - if not contracts.get('id', False): - update['value'].update({ - 'basic_amount': 0.0, - 'basic_before_leaves': 0.0, - 'name':'Salary Slip of %s for %s' % (employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))), - 'contract_id':False, - 'company_id':employee_id.company_id.id - }) - return update - contract = employee_id.contract_id else: - 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 - - for line in rules: - if line.category_id.code in ad: + contracts = [contract_obj.read(cr, uid, contract_id, ['wage', 'struct_id', 'id'], context=context)] + update['value'].update({ + 'struct_id': contracts[0].get('struct_id', False), + 'contract_id': contract_id + }) + if not contracts: + update['value'].update({ + 'basic_amount': 0.0, + 'basic_before_leaves': 0.0, + 'name':'Salary Slip of %s for %s' % (employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))), + 'contract_id': False, + 'struct_id': False, + 'company_id':employee_id.company_id.id + }) + return update + final_total = 0.0 + all_basic = 0.0 + 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_id = self.pool.get('hr.contract').browse(cr, uid, contract_id, context=context) + function = contract_id.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_id.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_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 + 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_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 + if not calculate: + continue - elif line.amount_type=='code': - 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_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 + 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_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: + 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_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} + 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_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, + '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': employee_id.id, + 'base': line.computational_expression + } + if line.appears_on_payslip: + if line.condition_range_min or line.condition_range_max: + if not ((value < line.condition_range_min) or (value > line.condition_range_max)): + update['value']['line_ids'].append(vals) else: - value = val - - total += value - vals = { - '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': employee_id.id, - 'base': line.computational_expression - } - if line.appears_on_payslip: - if line.condition_range_min or line.condition_range_max: - if not ((value < line.condition_range_min) or (value > line.condition_range_max)): update['value']['line_ids'].append(vals) - else: - update['value']['line_ids'].append(vals) - basic = contract.wage - number = sequence_obj.get(cr, uid, 'salary.slip') - update['value'].update({ -# 'struct_id': function, - 'number': number, - 'basic_amount': basic, - 'basic_before_leaves': basic, - 'total_pay': basic + total, - 'name': 'Salary Slip of %s for %s' % (employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))), - 'contract_id': contract.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'] @@ -1124,7 +1137,7 @@ 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 = working_day and basic / working_day or 0.0 +# perday = working_day and basic / working_day or 0.0 total = 0.0 leave = 0.0 leave_ids = self._get_leaves(cr, uid, ddate, employee_id, context) @@ -1198,7 +1211,7 @@ class hr_payslip(osv.osv): value = salary_rule.amount * days elif salary_rule.amount_type=='code': - localdict = {'basic':amt, 'employee':employee_id, 'contract':contract} + localdict = {'basic':amt, 'employee':employee_id, 'contract':contract_id} exec salary_rule.python_compute in localdict val = localdict['result'] * days if salary_rule.child_depend == False: diff --git a/addons/hr_payroll/hr_payroll_view.xml b/addons/hr_payroll/hr_payroll_view.xml index 3926c9bb19d..65dbdc03049 100644 --- a/addons/hr_payroll/hr_payroll_view.xml +++ b/addons/hr_payroll/hr_payroll_view.xml @@ -212,9 +212,8 @@ - + - @@ -283,7 +282,7 @@ - + @@ -296,7 +295,7 @@