Help

Welcome!

This community is for professionals and enthusiasts of our products and services.
Share and discuss the best content and new marketing ideas, build your professional profile and become a better marketer together.

0

[Examples] Late Attendance and Overtime Calculation in Payroll

Avatar
David Tran

1.Work Absence
-If there are employee who doesn’t scan finger print at all on that date it will count as 1 day absence,
1 day absence mean employee doesn’t get paid on that specific day so the calculation will be like this
result = (contract.wage / 30) * days employee missed

start_dt = datetime.datetime.combine(fields.Date.from_string(payslip.date_from), datetime.datetime.min.time())
end_dt = datetime.datetime.combine(fields.Date.from_string(payslip.date_to), datetime.datetime.max.time())

start_dt_str = fields.Datetime.to_string(start_dt)
end_dt_str = fields.Datetime.to_string(end_dt)

resource_calendar_id = employee._get_resource_calendar()
attendance_ids = employee.attendance_ids.filtered(lambda att: att.check_in >= start_dt_str and att.check_out <= end_dt_str)

missed_days = 0
for dt in dateutil.rrule.rrule(dateutil.rrule.DAILY, dtstart=start_dt, until=end_dt):
    if not resource_calendar_id._is_work_day(dt.date(), resource_calendar_id.id):
        continue

    if not attendance_ids.filtered(lambda att: fields.Date.from_string(att.check_in) == dt.date() and fields.Date.from_string(att.check_out) == dt.date()):
        missed_days +=1

result = (contract.wage / 30) * missed_days


2.Late Absence (10 min Quota, 10 Times in a month)
-If an employees who come to late more than 10 minute , for than 10 times, employee will count as 1 Day absence, to calculate day of absence are
result = (contract.wage / 30) * lateabsence(10minconsecutive)
start_dt = datetime.datetime.combine(fields.Date.from_string(payslip.date_from), datetime.datetime.min.time())
end_dt = datetime.datetime.combine(fields.Date.from_string(payslip.date_to), datetime.datetime.max.time())

start_dt_str = fields.Datetime.to_string(start_dt)
end_dt_str = fields.Datetime.to_string(end_dt)

resource_calendar_id = employee._get_resource_calendar()
attendance_ids = employee.attendance_ids.filtered(lambda att: att.check_in >= start_dt_str and att.check_out <= end_dt_str)

lates_count = 0
for dt in dateutil.rrule.rrule(dateutil.rrule.DAILY, dtstart=start_dt, until=end_dt):
    employee_att_ids = attendance_ids.filtered(lambda att: fields.Date.from_string(att.check_in) == dt.date())
    if employee_att_ids:
        emp_check_in = fields.Datetime.from_string(employee_att_ids[0].check_in)
        calendar_att_ids = resource_calendar_id._get_day_attendances(dt.date(), dt.min.time(), dt.max.time())
        if calendar_att_ids:
            hour, minute = divmod(calendar_att_ids[0].hour_from * 60.0, 60)
            calendar_start_dt = dt.replace(hour=int(hour), minute=int(minute))
            if (emp_check_in - calendar_start_dt).seconds / 60 > 10.0:
                lates_count += 1

result = (contract.wage / 30) * (lates_count // 11)


3.Late Absence (4 Hours Monthly Quota)
-If an employees came late to work late in 4 hours of total, employee will count as 1 Day absence, to calculate day of absence are
result = (contract.wage / 30) * lateabsence(4hoursquota)
start_dt = datetime.datetime.combine(fields.Date.from_string(payslip.date_from), datetime.datetime.min.time())
end_dt = datetime.datetime.combine(fields.Date.from_string(payslip.date_to), datetime.datetime.max.time())

start_dt_str = fields.Datetime.to_string(start_dt)
end_dt_str = fields.Datetime.to_string(end_dt)

resource_calendar_id = employee._get_resource_calendar()
attendance_ids = employee.attendance_ids.filtered(lambda att: att.check_in >= start_dt_str and att.check_out <= end_dt_str)

cumm_lates_minutes= 0.0
for dt in dateutil.rrule.rrule(dateutil.rrule.DAILY, dtstart=start_dt, until=end_dt):
    employee_att_ids = attendance_ids.filtered(lambda att: fields.Date.from_string(att.check_in) == dt.date())
    if employee_att_ids:
        emp_check_in = fields.Datetime.from_string(employee_att_ids[0].check_in)
        calendar_att_ids = resource_calendar_id._get_day_attendances(dt.date(), dt.min.time(), dt.max.time())
        if calendar_att_ids:
            hour, minute = divmod(calendar_att_ids[0].hour_from * 60.0, 60)
            calendar_start_dt = dt.replace(hour=int(hour), minute=int(minute))
            late_minutes = (emp_check_in - calendar_start_dt).seconds / 60
            cumm_lates_minutes += late_minutes
        
late_hours = cumm_lates_minutes // 60
result = (contract.wage / 30) * (late_hours // 4)


4.OT on Normal Days
If an employee work on normal (Monday-Saturaday) But, the employee continue to work after 17:00 / checkin after 17:00 he or she will receive
result = ((contract.wage / 30) / 8 )*1.5
(1.5 TIMES HOURLY RATE)
5.OT on Holidays
If an employee work on Holiday like sunday and including in days in GLOBAL LEAVES he or she will receive
result = ((contract.wage / 30) / 8 )*2
(TWO TIMES HOURLY RATE)
# cost per hour
hour_cost = ((contract.wage / 30) / 8 )

# start calculating overtime cost
result = 0.0
if payslip.hr_overtime_line_ids:
    for line in payslip.hr_overtime_line_ids:
        if line.work_day_type_id and line.work_day_type_id.is_holiday:
            result += hour_cost * line.worked_hours * line.work_day_type_id.rate / 100.0
        else:
            result += hour_cost * line.worked_hours * line.rate / 100.0


NOTE: the above code requires the following modules to work properly:
https://www.odoo.com/apps/modules/11.0/to_hr_payroll_attendance/
https://apps.odoo.com/apps/modules/11.0/to_hr_overtime_payroll/
Avatar
Discard

Your Answer

Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!