Leave Application Enchancement
diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js
index 79c6d95..3bf41bb 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.js
+++ b/erpnext/hr/doctype/leave_application/leave_application.js
@@ -23,6 +23,10 @@
 
 	},
 
+	validate: function(frm) {
+		frm.toggle_reqd("half_day_date", frm.doc.half_day == 1);
+	},
+
 	refresh: function(frm) {
 		if (frm.is_new()) {
 			frm.set_value("status", "Open");
@@ -45,28 +49,38 @@
 	},
 
 	half_day: function(frm) {
-		if (frm.doc.from_date) {
-			frm.set_value("to_date", frm.doc.from_date);
-			frm.trigger("calculate_total_days");
+		if (frm.doc.from_date == frm.doc.to_date) {
+			frm.set_value("half_day_date", frm.doc.from_date);
 		}
+		else {
+			frm.trigger("half_day_datepicker");
+		}
+		frm.trigger("calculate_total_days");
 	},
 
 	from_date: function(frm) {
-		if (cint(frm.doc.half_day)==1) {
-			frm.set_value("to_date", frm.doc.from_date);
-		}
+		frm.trigger("half_day_datepicker");
 		frm.trigger("calculate_total_days");
 	},
 
 	to_date: function(frm) {
-		if (cint(frm.doc.half_day)==1 && cstr(frm.doc.from_date) && frm.doc.from_date != frm.doc.to_date) {
-			msgprint(__("To Date should be same as From Date for Half Day leave"));
-			frm.set_value("to_date", frm.doc.from_date);
-		}
-
+		frm.trigger("half_day_datepicker");
 		frm.trigger("calculate_total_days");
 	},
 
+	half_day_date(frm) {
+		frm.trigger("calculate_total_days");
+	},
+
+	half_day_datepicker: function(frm) {
+		frm.set_value('half_day_date', '');
+		var half_day_datepicker = frm.fields_dict.half_day_date.datepicker;
+		half_day_datepicker.update({
+				minDate: frappe.datetime.str_to_obj(frm.doc.from_date),
+				maxDate: frappe.datetime.str_to_obj(frm.doc.to_date)
+			})
+	},
+
 	get_leave_balance: function(frm) {
 		if(frm.doc.docstatus==0 && frm.doc.employee && frm.doc.leave_type && frm.doc.from_date) {
 			return frappe.call({
@@ -87,29 +101,25 @@
 	},
 
 	calculate_total_days: function(frm) {
-		if(frm.doc.from_date && frm.doc.to_date) {
-			if (cint(frm.doc.half_day)==1) {
-				frm.set_value("total_leave_days", 0.5);
-			} else if (frm.doc.employee && frm.doc.leave_type){
+		if(frm.doc.from_date && frm.doc.to_date && frm.doc.employee && frm.doc.leave_type) {
 				// server call is done to include holidays in leave days calculations
-				return frappe.call({
-					method: 'erpnext.hr.doctype.leave_application.leave_application.get_number_of_leave_days',
-					args: {
-						"employee": frm.doc.employee,
-						"leave_type": frm.doc.leave_type,
-						"from_date": frm.doc.from_date,
-						"to_date": frm.doc.to_date,
-						"half_day": frm.doc.half_day
-					},
-					callback: function(r) {
-						if (r && r.message) {
-							frm.set_value('total_leave_days', r.message);
-							frm.trigger("get_leave_balance");
-						}
+			return frappe.call({
+				method: 'erpnext.hr.doctype.leave_application.leave_application.get_number_of_leave_days',
+				args: {
+					"employee": frm.doc.employee,
+					"leave_type": frm.doc.leave_type,
+					"from_date": frm.doc.from_date,
+					"to_date": frm.doc.to_date,
+					"half_day": frm.doc.half_day,
+					"half_day_date": frm.doc.half_day_date,
+				},
+				callback: function(r) {
+					if (r && r.message) {
+						frm.set_value('total_leave_days', r.message);
+						frm.trigger("get_leave_balance");
 					}
-				});
-			}
+				}
+			});
 		}
 	},
-
 });
diff --git a/erpnext/hr/doctype/leave_application/leave_application.json b/erpnext/hr/doctype/leave_application/leave_application.json
index 3939739..ca69417 100644
--- a/erpnext/hr/doctype/leave_application/leave_application.json
+++ b/erpnext/hr/doctype/leave_application/leave_application.json
@@ -274,6 +274,36 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "depends_on": "eval:doc.half_day && (doc.from_date != doc.to_date)", 
+   "fieldname": "half_day_date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Half Day Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "total_leave_days", 
    "fieldtype": "Float", 
    "hidden": 0, 
@@ -287,6 +317,7 @@
    "length": 0, 
    "no_copy": 1, 
    "permlevel": 0, 
+   "precision": "1", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
@@ -738,7 +769,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 3, 
- "modified": "2017-02-17 17:09:38.828496", 
+ "modified": "2017-02-24 07:33:08.907824", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Leave Application", 
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 84c14c9..d869e0a 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -63,7 +63,10 @@
 	def validate_dates(self):
 		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 not is_lwp(self.leave_type):
 			self.validate_dates_acorss_allocation()
 			self.validate_back_dated_application()
@@ -129,7 +132,7 @@
 	def validate_balance_leaves(self):
 		if self.from_date and self.to_date:
 			self.total_leave_days = get_number_of_leave_days(self.employee, self.leave_type,
-				self.from_date, self.to_date, self.half_day)
+				self.from_date, self.to_date, self.half_day, self.half_day_date)
 
 			if self.total_leave_days == 0:
 				frappe.throw(_("The day(s) on which you are applying for leave are holidays. You need not apply for leave."))
@@ -294,13 +297,18 @@
 	return approvers_list
 
 @frappe.whitelist()
-def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day=None):
-	if half_day==1:
-		return 0.5
-	number_of_days = date_diff(to_date, from_date) + 1
+def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day = None, half_day_date = None):
+	number_of_days = 0
+	if half_day == 1:
+		if from_date == to_date:
+			number_of_days = 0.5
+		else:
+			number_of_days = date_diff(to_date, from_date) + .5
+	else:
+		number_of_days = date_diff(to_date, from_date) + 1
+
 	if not frappe.db.get_value("Leave Type", leave_type, "include_holiday"):
 		number_of_days = flt(number_of_days) - flt(get_holidays(employee, from_date, to_date))
-
 	return number_of_days
 
 @frappe.whitelist()