test: Employee Leave Balance Summary
diff --git a/erpnext/hr/report/employee_leave_balance/test_employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/test_employee_leave_balance.py
index f844be5..aecf0a4 100644
--- a/erpnext/hr/report/employee_leave_balance/test_employee_leave_balance.py
+++ b/erpnext/hr/report/employee_leave_balance/test_employee_leave_balance.py
@@ -31,13 +31,13 @@
 		frappe.set_user('Administrator')
 
 		self.employee_id = make_employee('test_emp_leave_balance@example.com', company='_Test Company')
-		self.holiday_list = make_holiday_list('_Test Emp Balance Holiday List', get_year_start(getdate()), get_year_ending(getdate()))
 
 		self.date = getdate()
 		self.year_start = getdate(get_year_start(self.date))
 		self.mid_year = add_months(self.year_start, 6)
 		self.year_end = getdate(get_year_ending(self.date))
 
+		self.holiday_list = make_holiday_list('_Test Emp Balance Holiday List', self.year_start, self.year_end)
 
 	def tearDown(self):
 		frappe.db.rollback()
@@ -56,7 +56,7 @@
 
 		# 4 days leave
 		first_sunday = get_first_sunday(self.holiday_list, for_date=self.year_start)
-		leave_application = make_leave_application(self.employee_id, first_sunday, add_days(first_sunday, 3), '_Test Leave Type')
+		leave_application = make_leave_application(self.employee_id, add_days(first_sunday, 1), add_days(first_sunday, 4), '_Test Leave Type')
 		leave_application.reload()
 
 		filters = {
@@ -89,7 +89,7 @@
 		allocation1 = make_allocation_record(employee=self.employee_id, from_date=self.year_start, to_date=self.year_end)
 		# 4 days leave application in the first allocation
 		first_sunday = get_first_sunday(self.holiday_list, for_date=self.year_start)
-		leave_application = make_leave_application(self.employee_id, first_sunday, add_days(first_sunday, 3), '_Test Leave Type')
+		leave_application = make_leave_application(self.employee_id, add_days(first_sunday, 1), add_days(first_sunday, 4), '_Test Leave Type')
 		leave_application.reload()
 
 		# Case 1: opening balance for first alloc boundary
diff --git a/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py b/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py
index 71c18bb..eee2eb8 100644
--- a/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py
+++ b/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py
@@ -12,6 +12,7 @@
 
 
 def execute(filters=None):
+	filters = frappe._dict(filters or {})
 	leave_types = frappe.db.sql_list("select name from `tabLeave Type` order by name asc")
 
 	columns = get_columns(leave_types)
diff --git a/erpnext/hr/report/employee_leave_balance_summary/test_employee_leave_balance_summary.py b/erpnext/hr/report/employee_leave_balance_summary/test_employee_leave_balance_summary.py
new file mode 100644
index 0000000..9b953de
--- /dev/null
+++ b/erpnext/hr/report/employee_leave_balance_summary/test_employee_leave_balance_summary.py
@@ -0,0 +1,117 @@
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+
+import unittest
+
+import frappe
+from frappe.utils import add_days, flt, get_year_ending, get_year_start, getdate
+
+from erpnext.hr.doctype.employee.test_employee import make_employee
+from erpnext.hr.doctype.holiday_list.test_holiday_list import set_holiday_list
+from erpnext.hr.doctype.leave_application.test_leave_application import (
+	get_first_sunday,
+	make_allocation_record,
+)
+from erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry import process_expired_allocation
+from erpnext.hr.report.employee_leave_balance_summary.employee_leave_balance_summary import execute
+from erpnext.payroll.doctype.salary_slip.test_salary_slip import (
+	make_holiday_list,
+	make_leave_application,
+)
+
+test_records = frappe.get_test_records('Leave Type')
+
+class TestEmployeeLeaveBalance(unittest.TestCase):
+	def setUp(self):
+		for dt in ['Leave Application', 'Leave Allocation', 'Salary Slip', 'Leave Ledger Entry', 'Leave Type']:
+			frappe.db.delete(dt)
+
+		frappe.set_user('Administrator')
+
+		self.employee_id = make_employee('test_emp_leave_balance@example.com', company='_Test Company')
+		self.employee_id = make_employee('test_emp_leave_balance@example.com', company='_Test Company')
+
+		self.date = getdate()
+		self.year_start = getdate(get_year_start(self.date))
+		self.year_end = getdate(get_year_ending(self.date))
+
+		self.holiday_list = make_holiday_list('_Test Emp Balance Holiday List', self.year_start, self.year_end)
+
+	def tearDown(self):
+		frappe.db.rollback()
+
+	@set_holiday_list('_Test Emp Balance Holiday List', '_Test Company')
+	def test_employee_leave_balance_summary(self):
+		frappe.get_doc(test_records[0]).insert()
+
+		# 5 leaves
+		allocation1 = make_allocation_record(employee=self.employee_id, from_date=add_days(self.year_start, -11),
+			to_date=add_days(self.year_start, -1), leaves=5)
+		# 30 leaves
+		allocation2 = make_allocation_record(employee=self.employee_id, from_date=self.year_start, to_date=self.year_end)
+
+		# 2 days leave within the first allocation
+		leave_application1 = make_leave_application(self.employee_id, add_days(self.year_start, -11), add_days(self.year_start, -10),
+			'_Test Leave Type')
+		leave_application1.reload()
+
+		# expires 3 leaves
+		process_expired_allocation()
+
+		# 4 days leave within the second allocation
+		first_sunday = get_first_sunday(self.holiday_list, for_date=self.year_start)
+		leave_application2 = make_leave_application(self.employee_id, add_days(first_sunday, 1), add_days(first_sunday, 4), '_Test Leave Type')
+		leave_application2.reload()
+
+		filters = {
+			'date': self.date,
+			'company': '_Test Company',
+			'employee': self.employee_id
+		}
+
+		report = execute(filters)
+
+		expected_data = [[
+			self.employee_id,
+			'test_emp_leave_balance@example.com',
+			frappe.db.get_value('Employee', self.employee_id, 'department'),
+			flt(
+				allocation1.new_leaves_allocated # allocated = 5
+				+ allocation2.new_leaves_allocated # allocated = 30
+				- leave_application1.total_leave_days # leaves taken in the 1st alloc = 2
+				- (allocation1.new_leaves_allocated - leave_application1.total_leave_days) # leaves expired from 1st alloc = 3
+				- leave_application2.total_leave_days # leaves taken in the 2nd alloc = 4
+			)
+		]]
+
+		self.assertEqual(report[1], expected_data)
+
+	@set_holiday_list('_Test Emp Balance Holiday List', '_Test Company')
+	def test_get_leave_balance_near_alloc_expiry(self):
+		frappe.get_doc(test_records[0]).insert()
+
+		# 30 leaves allocated
+		allocation = make_allocation_record(employee=self.employee_id, from_date=self.year_start, to_date=self.year_end)
+		# 4 days leave application in the first allocation
+		first_sunday = get_first_sunday(self.holiday_list, for_date=self.year_start)
+		leave_application = make_leave_application(self.employee_id, add_days(first_sunday, 1), add_days(first_sunday, 4), '_Test Leave Type')
+		leave_application.reload()
+
+		# Leave balance should show actual balance, and not "consumption balance as per remaining days", near alloc end date
+		# eg: 3 days left for alloc to end, leave balance should still be 26 and not 3
+		filters = {
+			'date': add_days(self.year_end, -3),
+			'company': '_Test Company',
+			'employee': self.employee_id
+		}
+		report = execute(filters)
+
+		expected_data = [[
+			self.employee_id,
+			'test_emp_leave_balance@example.com',
+			frappe.db.get_value('Employee', self.employee_id, 'department'),
+			flt(allocation.new_leaves_allocated - leave_application.total_leave_days)
+		]]
+
+		self.assertEqual(report[1], expected_data)