Leave application overlap validation for half day and test cases
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index d869e0a..c53c230 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -64,8 +64,11 @@
 		if self.from_date and self.to_date and (getdate(self.to_date) < getdate(self.from_date)):
 			frappe.throw(_("To date cannot be before from date"))
 			
-		if self.half_day and (getdate(self.half_day_date) < getdate(self.from_date) or (getdate(self.half_day_date) > getdate(self.to_date))):
-			frappe.throw(_("Half Day Date should be between From Date and To Date"))
+		if self.half_day and self.half_day_date \
+			and (getdate(self.half_day_date) < getdate(self.from_date) 
+			or getdate(self.half_day_date) > getdate(self.to_date)):
+				
+				frappe.throw(_("Half Day Date should be between From Date and To Date"))
 			
 		if not is_lwp(self.leave_type):
 			self.validate_dates_acorss_allocation()
@@ -154,7 +157,9 @@
 			# hack! if name is null, it could cause problems with !=
 			self.name = "New Leave Application"
 
-		for d in frappe.db.sql("""select name, leave_type, posting_date, from_date, to_date, total_leave_days
+		for d in frappe.db.sql("""
+			select 
+				name, leave_type, posting_date, from_date, to_date, total_leave_days, half_day_date
 			from `tabLeave Application`
 			where employee = %(employee)s and docstatus < 2 and status in ("Open", "Approved")
 			and to_date >= %(from_date)s and from_date <= %(to_date)s
@@ -164,10 +169,14 @@
 				"to_date": self.to_date,
 				"name": self.name
 			}, as_dict = 1):
-
-			if d['total_leave_days']==0.5 and cint(self.half_day)==1:
-				sum_leave_days = self.get_total_leaves_on_half_day()
-				if sum_leave_days==1:
+			
+			if cint(self.half_day)==1 and getdate(self.half_day_date) == getdate(d.half_day_date) and (
+				flt(self.total_leave_days)==0.5 
+				or getdate(self.from_date) == getdate(d.to_date) 
+				or getdate(self.to_date) == getdate(d.from_date)):
+				
+				total_leaves_on_half_day = self.get_total_leaves_on_half_day()
+				if total_leaves_on_half_day >= 1:
 					self.throw_overlap_error(d)
 			else:
 				self.throw_overlap_error(d)
@@ -179,18 +188,19 @@
 		frappe.throw(msg, OverlapError)
 
 	def get_total_leaves_on_half_day(self):
-		return frappe.db.sql("""select sum(total_leave_days) from `tabLeave Application`
+		leave_count_on_half_day_date = frappe.db.sql("""select count(name) from `tabLeave Application`
 			where employee = %(employee)s
 			and docstatus < 2
 			and status in ("Open", "Approved")
-			and from_date = %(from_date)s
-			and to_date = %(to_date)s
+			and half_day = 1
+			and half_day_date = %(half_day_date)s
 			and name != %(name)s""", {
 				"employee": self.employee,
-				"from_date": self.from_date,
-				"to_date": self.to_date,
+				"half_day_date": self.half_day_date,
 				"name": self.name
 			})[0][0]
+			
+		return leave_count_on_half_day_date * 0.5
 
 	def validate_max_days(self):
 		max_days = frappe.db.get_value("Leave Type", self.leave_type, "max_days_allowed")
diff --git a/erpnext/hr/doctype/leave_application/test_leave_application.py b/erpnext/hr/doctype/leave_application/test_leave_application.py
index 83fdd58..f7a996b 100644
--- a/erpnext/hr/doctype/leave_application/test_leave_application.py
+++ b/erpnext/hr/doctype/leave_application/test_leave_application.py
@@ -134,7 +134,7 @@
 		application.leave_approver = "test2@example.com"
 		self.assertRaises(OverlapError, application.insert)
 
-	def test_overlap_with_half_day(self):
+	def test_overlap_with_half_day_1(self):
 		self._clear_roles()
 		self._clear_applications()
 
@@ -146,25 +146,33 @@
 
 		make_allocation_record()
 
-		# allow second half-day on the same day if available
+		# leave from 1-5, half day on 3rd
 		application = self.get_application(_test_records[0])
 		application.leave_approver = "test2@example.com"
 		application.half_day = 1
+		application.half_day_date = "2013-01-03"
 		application.insert()
 
-		# allow second half-day on the same day if available
+		# Apply again for a half day leave on 3rd
 		application = self.get_application(_test_records[0])
 		application.leave_approver = "test2@example.com"
+		application.from_date = "2013-01-03"
+		application.to_date = "2013-01-03"
 		application.half_day = 1
+		application.half_day_date = "2013-01-03"
 		application.insert()
 
+		# Apply again for a half day leave on 3rd
 		application = self.get_application(_test_records[0])
 		application.leave_approver = "test2@example.com"
+		application.from_date = "2013-01-03"
+		application.to_date = "2013-01-03"
 		application.half_day = 1
+		application.half_day_date = "2013-01-03"
 
 		self.assertRaises(OverlapError, application.insert)
 
-	def test_overlap_with_half_day_not_applicable(self):
+	def test_overlap_with_half_day_2(self):
 		self._clear_roles()
 		self._clear_applications()
 
@@ -176,17 +184,56 @@
 
 		make_allocation_record()
 
-		# allow second half-day on the same day if available
+		# leave from 1-5, no half day
 		application = self.get_application(_test_records[0])
 		application.leave_approver = "test2@example.com"
 		application.insert()
 
-		# allow second half-day on the same day if available
+		# Apply again for a half day leave on 1st
 		application = self.get_application(_test_records[0])
 		application.leave_approver = "test2@example.com"
 		application.half_day = 1
+		application.half_day_date = application.from_date
 
 		self.assertRaises(OverlapError, application.insert)
+		
+	def test_overlap_with_half_day_3(self):
+		self._clear_roles()
+		self._clear_applications()
+
+		from frappe.utils.user import add_role
+		add_role("test@example.com", "Employee")
+		add_role("test2@example.com", "Leave Approver")
+
+		frappe.set_user("test@example.com")
+
+		make_allocation_record()
+
+		# leave from 1-5, half day on 5th
+		application = self.get_application(_test_records[0])
+		application.leave_approver = "test2@example.com"
+		application.half_day = 1
+		application.half_day_date = "2013-01-05"
+		application.insert()
+		
+		# Apply leave from 4-7, half day on 5th
+		application = self.get_application(_test_records[0])
+		application.leave_approver = "test2@example.com"
+		application.from_date = "2013-01-04"
+		application.to_date = "2013-01-07"
+		application.half_day = 1
+		application.half_day_date = "2013-01-05"
+		
+		self.assertRaises(OverlapError, application.insert)
+
+		# Apply leave from 5-7, half day on 5th
+		application = self.get_application(_test_records[0])
+		application.leave_approver = "test2@example.com"
+		application.from_date = "2013-01-05"
+		application.to_date = "2013-01-07"
+		application.half_day = 1
+		application.half_day_date = "2013-01-05"
+		application.insert()
 
 	def test_global_block_list(self):
 		self._clear_roles()
diff --git a/erpnext/patches/v7_2/arrear_leave_encashment_as_salary_component.py b/erpnext/patches/v7_2/arrear_leave_encashment_as_salary_component.py
index 0e5dab3..13a2bb8 100644
--- a/erpnext/patches/v7_2/arrear_leave_encashment_as_salary_component.py
+++ b/erpnext/patches/v7_2/arrear_leave_encashment_as_salary_component.py
@@ -2,13 +2,14 @@
 
 def execute():
 	frappe.reload_doctype('Salary Slip', 'Salary Component')
-	salary_components = ['Arrear', 'Leave Encashment']
-	for salary_component in salary_components:
+	salary_components = [['Arrear', "ARR"], ['Leave Encashment', 'LENC']]
+	for salary_component, salary_abbr in salary_components:
 		if not frappe.db.exists('Salary Component', salary_component):
 			sal_comp = frappe.get_doc({
 				"doctype": "Salary Component",
 				"salary_component": salary_component,
-				"type": "Earning"
+				"type": "Earning",
+				"salary_component_abbr": salary_abbr
 			}).insert()
 
 	salary_slips = frappe.db.sql("""select name, arrear_amount, leave_encashment_amount from `tabSalary Slip`