Skip to content

Commit

Permalink
test: monthly attendance sheet
Browse files Browse the repository at this point in the history
  • Loading branch information
ruchamahabal committed Mar 29, 2022
1 parent 1a17e3f commit 0733cfa
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 5 deletions.
7 changes: 5 additions & 2 deletions erpnext/hr/doctype/attendance/attendance.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ def add_attendance(events, start, end, conditions=None):
if e not in events:
events.append(e)

def mark_attendance(employee, attendance_date, status, shift=None, leave_type=None, ignore_validate=False):
def mark_attendance(employee, attendance_date, status, shift=None, leave_type=None, ignore_validate=False,
late_entry=False, early_exit=False):
if not get_duplicate_attendance_record(employee, attendance_date, shift):
company = frappe.db.get_value('Employee', employee, 'company')
attendance = frappe.get_doc({
Expand All @@ -159,7 +160,9 @@ def mark_attendance(employee, attendance_date, status, shift=None, leave_type=No
'status': status,
'company': company,
'shift': shift,
'leave_type': leave_type
'leave_type': leave_type,
'late_entry': late_entry,
'early_exit': early_exit
})
attendance.flags.ignore_validate = ignore_validate
attendance.insert()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import frappe
from dateutil.relativedelta import relativedelta
from frappe.tests.utils import FrappeTestCase
from frappe.utils import now_datetime
from frappe.utils import add_days, get_year_ending, get_year_start, getdate, now_datetime

from erpnext.hr.doctype.attendance.attendance import mark_attendance
from erpnext.hr.doctype.employee.test_employee import make_employee
from erpnext.hr.report.monthly_attendance_sheet.monthly_attendance_sheet import execute
from erpnext.hr.doctype.leave_application.test_leave_application import make_allocation_record
from erpnext.hr.report.monthly_attendance_sheet.monthly_attendance_sheet import (
execute,
get_total_days_in_month,
)
from erpnext.payroll.doctype.salary_slip.test_salary_slip import make_leave_application

test_dependencies = ['Shift Type']

class TestMonthlyAttendanceSheet(FrappeTestCase):
def setUp(self):
self.employee = make_employee("test_employee@example.com")
frappe.db.delete('Attendance', {'employee': self.employee})
frappe.db.delete('Attendance')

def test_monthly_attendance_sheet_report(self):
now = now_datetime()
Expand Down Expand Up @@ -43,3 +49,127 @@ def test_monthly_attendance_sheet_report(self):
self.assertEqual(absent[0], 1)
self.assertEqual(present[1], 1)
self.assertEqual(leaves[2], 1)

def test_monthly_attendance_sheet_with_detailed_view(self):
now = now_datetime()
previous_month = now.month - 1
previous_month_first = now.replace(day=1).replace(month=previous_month).date()

company = frappe.db.get_value('Employee', self.employee, 'company')

# attendance with shift
mark_attendance(self.employee, previous_month_first, 'Absent', 'Day Shift')
mark_attendance(self.employee, previous_month_first + relativedelta(days=1), 'Present', 'Day Shift')

# attendance without shift
mark_attendance(self.employee, previous_month_first + relativedelta(days=2), 'On Leave')
mark_attendance(self.employee, previous_month_first + relativedelta(days=3), 'Present')

filters = frappe._dict({
'month': previous_month,
'year': now.year,
'company': company,
})
report = execute(filters=filters)

day_shift_row = report[1][0]
row_without_shift = report[1][1]

self.assertEqual(day_shift_row['shift'], 'Day Shift')
self.assertEqual(day_shift_row[1], 'A') # absent on the 1st day of the month
self.assertEqual(day_shift_row[2], 'P') # present on the 2nd day

self.assertEqual(row_without_shift['shift'], None)
self.assertEqual(row_without_shift[3], 'L') # on leave on the 3rd day
self.assertEqual(row_without_shift[4], 'P') # present on the 4th day

def test_monthly_attendance_sheet_with_summarized_view(self):
now = now_datetime()
previous_month = now.month - 1
previous_month_first = now.replace(day=1).replace(month=previous_month).date()

company = frappe.db.get_value('Employee', self.employee, 'company')

# attendance with shift
mark_attendance(self.employee, previous_month_first, 'Absent', 'Day Shift')
mark_attendance(self.employee, previous_month_first + relativedelta(days=1), 'Present', 'Day Shift')

mark_attendance(self.employee, previous_month_first + relativedelta(days=3), 'Present') # attendance without shift
mark_attendance(self.employee, previous_month_first + relativedelta(days=4), 'Present', late_entry=1) # late entry
mark_attendance(self.employee, previous_month_first + relativedelta(days=5), 'Present', early_exit=1) # early exit

leave_application = get_leave_application(self.employee)

filters = frappe._dict({
'month': previous_month,
'year': now.year,
'company': company,
'summarized_view': 1
})
report = execute(filters=filters)

row = report[1][0]
self.assertEqual(row['employee'], self.employee)
self.assertEqual(row['total_present'], 4)
self.assertEqual(row['total_absent'], 1)
self.assertEqual(row['total_leaves'], leave_application.total_leave_days)

# total days - (days with attendance + leave days)
unmarked_days = get_total_days_in_month(filters) - (5 + leave_application.total_leave_days)

self.assertEqual(row['unmarked_days'], unmarked_days)
self.assertEqual(row['_test_leave_type'], leave_application.total_leave_days)
self.assertEqual(row['total_late_entries'], 1)
self.assertEqual(row['total_early_exits'], 1)

def test_attendance_with_group_by_filter(self):
now = now_datetime()
previous_month = now.month - 1
previous_month_first = now.replace(day=1).replace(month=previous_month).date()

company = frappe.db.get_value('Employee', self.employee, 'company')

# attendance with shift
mark_attendance(self.employee, previous_month_first, 'Absent', 'Day Shift')
mark_attendance(self.employee, previous_month_first + relativedelta(days=1), 'Present', 'Day Shift')

# attendance without shift
mark_attendance(self.employee, previous_month_first + relativedelta(days=2), 'On Leave')
mark_attendance(self.employee, previous_month_first + relativedelta(days=3), 'Present')

filters = frappe._dict({
'month': previous_month,
'year': now.year,
'company': company,
'group_by': 'Department'
})
report = execute(filters=filters)

department = frappe.db.get_value('Employee', self.employee, 'department')
department_row = report[1][0]
self.assertIn(department, department_row['department'])

day_shift_row = report[1][1]
row_without_shift = report[1][2]

self.assertEqual(day_shift_row['shift'], 'Day Shift')
self.assertEqual(day_shift_row[1], 'A') # absent on the 1st day of the month
self.assertEqual(day_shift_row[2], 'P') # present on the 2nd day

self.assertEqual(row_without_shift['shift'], None)
self.assertEqual(row_without_shift[3], 'L') # on leave on the 3rd day
self.assertEqual(row_without_shift[4], 'P') # present on the 4th day


def get_leave_application(employee):
now = now_datetime()
previous_month = now.month - 1

date = getdate()
year_start = getdate(get_year_start(date))
year_end = getdate(get_year_ending(date))
allocation = make_allocation_record(employee=employee, from_date=year_start, to_date=year_end)

from_date = now.replace(day=7).replace(month=previous_month).date()
to_date = now.replace(day=8).replace(month=previous_month).date()
return make_leave_application(employee, from_date, to_date, '_Test Leave Type')

0 comments on commit 0733cfa

Please sign in to comment.