Merge pull request #4315 from rmehta/standard-in-web-form

Web form, make standard
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 2a76f8a..e1b01a1 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -21,11 +21,13 @@
 
 		if(doc.docstatus == 1 && !in_list(["Stopped", "Closed", "Delivered"], doc.status)) {
 
-			if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100) {
-				cur_frm.add_custom_button(__('Stop'), this.stop_purchase_order);
-			}
+			if (this.frm.has_perm("submit")) {
+				if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100) {
+					cur_frm.add_custom_button(__('Stop'), this.stop_purchase_order);
+				}
 
-			cur_frm.add_custom_button(__('Close'), this.close_purchase_order);
+				cur_frm.add_custom_button(__('Close'), this.close_purchase_order);
+			}
 
 			if(doc.delivered_by_supplier && doc.status!="Delivered"){
 				cur_frm.add_custom_button(__('Mark as Delivered'), this.delivered_by_supplier);
@@ -35,7 +37,7 @@
 				cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry);
 			}
 
-			if(flt(doc.per_received, 2) < 100) {
+			if(flt(doc.per_received, 2) < 100 && this.frm.doc.__onload.has_stock_item) {
 				cur_frm.add_custom_button(__('Receive'), this.make_purchase_receipt).addClass("btn-primary");
 
 				if(doc.is_subcontracted==="Yes") {
@@ -53,7 +55,9 @@
 		}
 
 		if(doc.docstatus == 1 && in_list(["Stopped", "Closed", "Delivered"], doc.status)) {
-			cur_frm.add_custom_button(__('Re-open'), this.unstop_purchase_order);
+			if (this.frm.has_perm("submit")) {
+				cur_frm.add_custom_button(__('Re-open'), this.unstop_purchase_order);
+			}
 		}
 	},
 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 01ebcb9..d069bc0 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -33,6 +33,9 @@
 			'overflow_type': 'order'
 		}]
 
+	def onload(self):
+		self.set_onload("has_stock_item", len(self.get_stock_items()) > 0)
+
 	def validate(self):
 		super(PurchaseOrder, self).validate()
 
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 27ec618..b348da6 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -398,17 +398,18 @@
 			return
 		
 		self.doc.round_floats_in(self.doc, ["grand_total", "total_advance", "write_off_amount"])
-		total_amount_to_pay = flt(self.doc.grand_total  - self.doc.total_advance - self.doc.write_off_amount,
-			self.doc.precision("grand_total"))
+		if self.doc.party_account_currency == self.doc.currency:
+			total_amount_to_pay = flt(self.doc.grand_total  - self.doc.total_advance 
+				- flt(self.doc.write_off_amount), self.doc.precision("grand_total"))
+		else:
+			total_amount_to_pay = flt(self.doc.base_grand_total  - self.doc.total_advance 
+				- flt(self.doc.base_write_off_amount), self.doc.precision("grand_total"))
 			
 		if self.doc.doctype == "Sales Invoice":
 			self.doc.round_floats_in(self.doc, ["paid_amount"])
-			outstanding_amount = flt(total_amount_to_pay - self.doc.paid_amount, self.doc.precision("outstanding_amount"))
+			paid_amount = self.doc.paid_amount \
+				if self.doc.party_account_currency == self.doc.currency else self.doc.base_paid_amount
+			self.doc.outstanding_amount = flt(total_amount_to_pay - flt(paid_amount), 
+				self.doc.precision("outstanding_amount"))
 		elif self.doc.doctype == "Purchase Invoice":
-			outstanding_amount = flt(total_amount_to_pay, self.doc.precision("outstanding_amount"))
-		
-		if self.doc.party_account_currency == self.doc.currency:
-			self.doc.outstanding_amount = outstanding_amount
-		else:
-			self.doc.outstanding_amount = flt(outstanding_amount * self.doc.conversion_rate, 
-				self.doc.precision("outstanding_amount"))
\ No newline at end of file
+			self.doc.outstanding_amount = flt(total_amount_to_pay, self.doc.precision("outstanding_amount"))
\ No newline at end of file
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 3b33e65..7e333f7 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -96,7 +96,8 @@
 	"Sales Order": "erpnext.controllers.website_list_for_contact.has_website_permission",
 	"Sales Invoice": "erpnext.controllers.website_list_for_contact.has_website_permission",
 	"Delivery Note": "erpnext.controllers.website_list_for_contact.has_website_permission",
-	"Issue": "erpnext.support.doctype.issue.issue.has_website_permission"
+	"Issue": "erpnext.support.doctype.issue.issue.has_website_permission",
+	"Address": "erpnext.utilities.doctype.address.address.has_website_permission"
 }
 
 permission_query_conditions = {
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index a8d56fb..a5e3972 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -19,7 +19,7 @@
    "ignore_user_permissions": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Series",  
+   "label": "Series", 
    "no_copy": 1, 
    "options": "EXP", 
    "permlevel": 0, 
@@ -44,7 +44,7 @@
    "ignore_user_permissions": 0, 
    "in_filter": 1, 
    "in_list_view": 0, 
-   "label": "Approval Status",  
+   "label": "Approval Status", 
    "no_copy": 1, 
    "oldfieldname": "approval_status", 
    "oldfieldtype": "Select", 
@@ -536,7 +536,7 @@
  "is_submittable": 1, 
  "issingle": 0, 
  "istable": 0, 
- "modified": "2015-10-02 07:38:50.191920", 
+ "modified": "2015-11-14 12:11:13.213073", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Expense Claim", 
@@ -564,7 +564,7 @@
   }, 
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
+   "apply_user_permissions": 1, 
    "cancel": 0, 
    "create": 1, 
    "delete": 0, 
@@ -580,6 +580,7 @@
    "set_user_permissions": 0, 
    "share": 1, 
    "submit": 0, 
+   "user_permission_doctypes": "[\"Employee\"]", 
    "write": 1
   }, 
   {
diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.js b/erpnext/hr/doctype/leave_allocation/leave_allocation.js
index 994dc3c..06c7693 100755
--- a/erpnext/hr/doctype/leave_allocation/leave_allocation.js
+++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.js
@@ -1,48 +1,62 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-cur_frm.cscript.onload = function(doc, dt, dn) {
-  if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()});
-}
-
-
 cur_frm.add_fetch('employee','employee_name','employee_name');
 
-cur_frm.cscript.employee = function(doc, dt, dn) {
-  calculate_total_leaves_allocated(doc, dt, dn);
-}
-
-cur_frm.cscript.leave_type = function(doc, dt, dn) {
-  calculate_total_leaves_allocated(doc, dt, dn);
-}
-
-cur_frm.cscript.fiscal_year = function(doc, dt, dn) {
-  calculate_total_leaves_allocated(doc, dt, dn);
-}
-
-cur_frm.cscript.carry_forward = function(doc, dt, dn) {
-  calculate_total_leaves_allocated(doc, dt, dn);
-}
-
-cur_frm.cscript.carry_forwarded_leaves = function(doc, dt, dn) {
-  set_multiple(dt,dn,{total_leaves_allocated : flt(doc.carry_forwarded_leaves)+flt(doc.new_leaves_allocated)});
-}
-
-cur_frm.cscript.new_leaves_allocated = function(doc, dt, dn) {
-  set_multiple(dt,dn,{total_leaves_allocated : flt(doc.carry_forwarded_leaves)+flt(doc.new_leaves_allocated)});
-}
-
-calculate_total_leaves_allocated = function(doc, dt, dn) {
-  if(cint(doc.carry_forward) == 1 && doc.leave_type && doc.fiscal_year && doc.employee){
-    return get_server_fields('get_carry_forwarded_leaves','','', doc, dt, dn, 1);
+frappe.ui.form.on("Leave Allocation", {
+	onload: function(frm) {
+		if(!frm.doc.from_date) frm.set_value("from_date", get_today());
+		
+		frm.set_query("employee", function() {
+			return {
+				query: "erpnext.controllers.queries.employee_query"
+			}
+		})
+	},
+	
+	employee: function(frm) {
+		frm.trigger("calculate_total_leaves_allocated");
+	},
+	
+	leave_type: function(frm) {
+		frm.trigger("calculate_total_leaves_allocated");
+	},
+	
+	carry_forward: function(frm) {
+		frm.trigger("calculate_total_leaves_allocated");
+	},
+	
+	carry_forwarded_leaves: function(frm) {
+		frm.set_value("total_leaves_allocated", 
+			flt(frm.doc.carry_forwarded_leaves) + flt(frm.doc.new_leaves_allocated));
+	},
+	
+	new_leaves_allocated: function(frm) {
+		frm.set_value("total_leaves_allocated", 
+			flt(frm.doc.carry_forwarded_leaves) + flt(frm.doc.new_leaves_allocated));
+	},
+	
+	calculate_total_leaves_allocated: function(frm) {
+		if (cint(frm.doc.carry_forward) == 1 && frm.doc.leave_type && frm.doc.employee) {
+			return frappe.call({
+				method: "erpnext.hr.doctype.leave_allocation.leave_allocation.get_carry_forwarded_leaves",
+				args: {
+					"employee": frm.doc.employee,
+					"date": frm.doc.from_date,
+					"leave_type": frm.doc.leave_type,
+					"carry_forward": frm.doc.carry_forward
+				},
+				callback: function(r) {
+					if (!r.exc && r.message) {
+						frm.set_value('carry_forwarded_leaves', r.message);
+						frm.set_value("total_leaves_allocated", 
+							flt(r.message) + flt(frm.doc.new_leaves_allocated));
+					}
+				}
+			})
+		} else if (cint(frm.doc.carry_forward) == 0) {
+			frm.set_value("carry_forwarded_leaves", 0);
+			frm.set_value("total_leaves_allocated", flt(frm.doc.new_leaves_allocated));
+		}
 	}
-  else if(cint(doc.carry_forward) == 0){
-    set_multiple(dt,dn,{carry_forwarded_leaves : 0,total_leaves_allocated : flt(doc.new_leaves_allocated)});
-  }
-}
-
-cur_frm.fields_dict.employee.get_query = function(doc,cdt,cdn) {
-  return{
-    query: "erpnext.controllers.queries.employee_query"
-  }
-}
+})
\ No newline at end of file
diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.py b/erpnext/hr/doctype/leave_allocation/leave_allocation.py
index f846124..57eb146 100755
--- a/erpnext/hr/doctype/leave_allocation/leave_allocation.py
+++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.py
@@ -3,93 +3,112 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe.utils import cint, flt, date_diff
+from frappe.utils import flt, date_diff, formatdate
 from frappe import _
 from frappe.model.document import Document
 from erpnext.hr.utils import set_employee_name
+from erpnext.hr.doctype.leave_application.leave_application import get_approved_leaves_for_period
+
+class OverlapError(frappe.ValidationError): pass
+class BackDatedAllocationError(frappe.ValidationError): pass
+class OverAllocationError(frappe.ValidationError): pass
+class LessAllocationError(frappe.ValidationError): pass
+class ValueMultiplierError(frappe.ValidationError): pass
 
 class LeaveAllocation(Document):
 	def validate(self):
 		self.validate_period()
 		self.validate_new_leaves_allocated_value()
-		self.check_existing_leave_allocation()
-		if not self.total_leaves_allocated:
-			self.total_leaves_allocated = self.new_leaves_allocated
-
+		self.validate_allocation_overlap()
+		self.validate_back_dated_allocation()
+		self.set_total_leaves_allocated()
+		self.validate_total_leaves_allocated()
 		set_employee_name(self)
 
 	def on_update_after_submit(self):
 		self.validate_new_leaves_allocated_value()
-
-	def on_update(self):
-		self.get_total_allocated_leaves()
+		self.set_total_leaves_allocated()
+		
+		frappe.db.set(self,'carry_forwarded_leaves', flt(self.carry_forwarded_leaves))
+		frappe.db.set(self,'total_leaves_allocated',flt(self.total_leaves_allocated))
+		
+		self.validate_against_leave_applications()
 
 	def validate_period(self):
 		if date_diff(self.to_date, self.from_date) <= 0:
-			frappe.throw(_("Invalid period"))
+			frappe.throw(_("To date cannot be before from date"))
 
 	def validate_new_leaves_allocated_value(self):
 		"""validate that leave allocation is in multiples of 0.5"""
 		if flt(self.new_leaves_allocated) % 0.5:
-			frappe.throw(_("Leaves must be allocated in multiples of 0.5"))
+			frappe.throw(_("Leaves must be allocated in multiples of 0.5"), ValueMultiplierError)
 
-	def check_existing_leave_allocation(self):
-		"""check whether leave for same type is already allocated or not"""
-		leave_allocation = frappe.db.sql("""select name from `tabLeave Allocation`
-			where employee='%s' and leave_type='%s' and to_date >= '%s' and from_date <= '%s' and docstatus=1
-		"""%(self.employee, self.leave_type, self.from_date, self.to_date))
+	def validate_allocation_overlap(self):
+		leave_allocation = frappe.db.sql("""
+			select name from `tabLeave Allocation`
+			where employee=%s and leave_type=%s and docstatus=1
+			and to_date >= %s and from_date <= %s""", 
+			(self.employee, self.leave_type, self.from_date, self.to_date))
 
 		if leave_allocation:
-			frappe.msgprint(_("Leaves for type {0} already allocated for Employee {1} for period {2} - {3}").format(self.leave_type,
-				self.employee, self.from_date, self.to_date))
-			frappe.throw(_('Reference') + ': <a href="#Form/Leave Allocation/{0}">{0}</a>'.format(leave_allocation[0][0]))
+			frappe.msgprint(_("{0} already allocated for Employee {1} for period {2} - {3}")
+				.format(self.leave_type, self.employee, formatdate(self.from_date), formatdate(self.to_date)))
+			
+			frappe.throw(_('Reference') + ': <a href="#Form/Leave Allocation/{0}">{0}</a>'
+				.format(leave_allocation[0][0]), OverlapError)
+				
+	def validate_back_dated_allocation(self):
+		future_allocation = frappe.db.sql("""select name, from_date from `tabLeave Allocation`
+			where employee=%s and leave_type=%s and docstatus=1 and from_date > %s 
+			and carry_forward=1""", (self.employee, self.leave_type, self.to_date), as_dict=1)
+		
+		if future_allocation:
+			frappe.throw(_("Leave cannot be allocated before {0}, as leave balance has already been carry-forwarded in the future leave allocation record {1}")
+				.format(formatdate(future_allocation[0].from_date), future_allocation[0].name), 
+					BackDatedAllocationError)
 
-	def get_leave_bal(self):
-		return self.get_leaves_allocated() - self.get_leaves_applied()
+	def set_total_leaves_allocated(self):
+		self.carry_forwarded_leaves = get_carry_forwarded_leaves(self.employee, 
+			self.leave_type, self.from_date, self.carry_forward)
+			
+		self.total_leaves_allocated = flt(self.carry_forwarded_leaves) + flt(self.new_leaves_allocated)
+		
+		if not self.total_leaves_allocated:
+			frappe.throw(_("Total leaves allocated is mandatory"))
 
-	def get_leaves_applied(self):
-		leaves_applied = frappe.db.sql("""select SUM(ifnull(total_leave_days, 0))
-			from `tabLeave Application` where employee=%s and leave_type=%s
-			and to_date<=%s and docstatus=1""",
-			(self.employee, self.leave_type, self.from_date))
-		return leaves_applied and flt(leaves_applied[0][0]) or 0
+	def validate_total_leaves_allocated(self):
+		if date_diff(self.to_date, self.from_date) <= flt(self.total_leaves_allocated):
+			frappe.throw(_("Total allocated leaves are more than days in the period"), OverAllocationError)
+			
+	def validate_against_leave_applications(self):
+		leaves_taken = get_approved_leaves_for_period(self.employee, self.leave_type, 
+			self.from_date, self.to_date)
+		
+		if flt(leaves_taken) > flt(self.total_leaves_allocated):
+			frappe.throw(_("Total allocated leaves {0} cannot be less than already approved leaves {1} for the period").format(self.total_leaves_allocated, leaves_taken), LessAllocationError)
 
-	def get_leaves_allocated(self):
-		leaves_allocated = frappe.db.sql("""select SUM(ifnull(total_leaves_allocated, 0))
-			from `tabLeave Allocation` where employee=%s and leave_type=%s
-			and to_date<=%s and docstatus=1 and name!=%s""",
-			(self.employee, self.leave_type, self.from_date, self.name))
-		return leaves_allocated and flt(leaves_allocated[0][0]) or 0
-
-	def allow_carry_forward(self):
-		"""check whether carry forward is allowed or not for this leave type"""
-		cf = frappe.db.sql("""select is_carry_forward from `tabLeave Type` where name = %s""",
-			self.leave_type)
-		cf = cf and cint(cf[0][0]) or 0
-		if not cf:
-			frappe.db.set(self,'carry_forward',0)
-			frappe.throw(_("Cannot carry forward {0}").format(self.leave_type))
-
-	def get_carry_forwarded_leaves(self):
-		if self.carry_forward:
-			self.allow_carry_forward()
-
-		prev_bal = 0
-		if cint(self.carry_forward) == 1:
-			prev_bal = self.get_leave_bal()
-
-		ret = {
-			'carry_forwarded_leaves': prev_bal,
-			'total_leaves_allocated': flt(prev_bal) + flt(self.new_leaves_allocated)
-		}
-		return ret
-
-	def get_total_allocated_leaves(self):
-		leave_det = self.get_carry_forwarded_leaves()
-		self.validate_total_leaves_allocated(leave_det)
-		frappe.db.set(self,'carry_forwarded_leaves',flt(leave_det['carry_forwarded_leaves']))
-		frappe.db.set(self,'total_leaves_allocated',flt(leave_det['total_leaves_allocated']))
-
-	def validate_total_leaves_allocated(self, leave_det):
-		if date_diff(self.to_date, self.from_date) <= leave_det['total_leaves_allocated']:
-			frappe.throw(_("Total allocated leaves are more than period"))
+@frappe.whitelist()
+def get_carry_forwarded_leaves(employee, leave_type, date, carry_forward=None):
+	carry_forwarded_leaves = 0
+	
+	if carry_forward:
+		validate_carry_forward(leave_type)
+		
+		previous_allocation = frappe.db.sql("""
+			select name, from_date, to_date, total_leaves_allocated
+			from `tabLeave Allocation`
+			where employee=%s and leave_type=%s and docstatus=1 and to_date < %s
+			order by to_date desc limit 1
+		""", (employee, leave_type, date), as_dict=1)
+		if previous_allocation:
+			leaves_taken = get_approved_leaves_for_period(employee, leave_type, 
+				previous_allocation[0].from_date, previous_allocation[0].to_date)
+		
+			carry_forwarded_leaves = flt(previous_allocation[0].total_leaves_allocated) - flt(leaves_taken)
+			
+	return carry_forwarded_leaves
+		
+def validate_carry_forward(leave_type):
+	if not frappe.db.get_value("Leave Type", leave_type, "is_carry_forward"):
+		frappe.throw(_("Leave Type {0} cannot be carry-forwarded").format(leave_type))
+	
\ No newline at end of file
diff --git a/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py b/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py
index d36fb2c..b3eee31 100644
--- a/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py
+++ b/erpnext/hr/doctype/leave_allocation/test_leave_allocation.py
@@ -13,7 +13,7 @@
 				"employee": employee.name,
 				"employee_name": employee.employee_name,
 				"leave_type": "_Test Leave Type",
-				"from_date": getdate("2015-10-1"),
+				"from_date": getdate("2015-10-01"),
 				"to_date": getdate("2015-10-31"),
 				"new_leaves_allocated": 5,
 				"docstatus": 1			
@@ -24,7 +24,7 @@
 				"employee": employee.name,
 				"employee_name": employee.employee_name,
 				"leave_type": "_Test Leave Type",
-				"from_date": getdate("2015-09-1"),
+				"from_date": getdate("2015-09-01"),
 				"to_date": getdate("2015-11-30"),
 				"new_leaves_allocated": 5			
 			}
diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js
index 835170a..e708b77 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.js
+++ b/erpnext/hr/doctype/leave_application/leave_application.js
@@ -66,14 +66,18 @@
 	},
 
 	get_leave_balance: function(frm) {
-		if(frm.doc.docstatus==0 && frm.doc.employee && frm.doc.leave_type && frm.doc.from_date && frm.doc.to_date) {
-			return frm.call({
-				method: "get_leave_balance",
+		if(frm.doc.docstatus==0 && frm.doc.employee && frm.doc.leave_type && frm.doc.from_date) {
+			return frappe.call({
+				method: "erpnext.hr.doctype.leave_application.leave_application.get_leave_balance_on",
 				args: {
 					employee: frm.doc.employee,
-					from_date: frm.doc.from_date,
-					to_date: frm.doc.to_date,
+					date: frm.doc.from_date,
 					leave_type: frm.doc.leave_type
+				},
+				callback: function(r) {
+					if (!r.exc && r.message) {
+						frm.set_value('leave_balance', r.message);
+					}
 				}
 			});
 		}
@@ -83,14 +87,20 @@
 		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 {
+			} else if (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_total_leave_days',
-					args: { leave_app: frm.doc },
-					callback: function(response) {
-						if (response && response.message) {
-							frm.set_value('total_leave_days', response.message.total_leave_days);
+					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");
 						}
 					}
diff --git a/erpnext/hr/doctype/leave_application/leave_application.json b/erpnext/hr/doctype/leave_application/leave_application.json
index 62e4cd8..10f6594 100644
--- a/erpnext/hr/doctype/leave_application/leave_application.json
+++ b/erpnext/hr/doctype/leave_application/leave_application.json
@@ -419,28 +419,6 @@
    "unique": 0
   }, 
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "fiscal_year", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "in_filter": 1, 
-   "in_list_view": 0, 
-   "label": "Fiscal Year", 
-   "no_copy": 0, 
-   "options": "Fiscal Year", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
    "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
@@ -559,7 +537,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 3, 
- "modified": "2015-10-28 16:14:25.640730", 
+ "modified": "2015-11-15 19:32:32.258397", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Leave Application", 
@@ -711,7 +689,7 @@
  ], 
  "read_only": 0, 
  "read_only_onload": 0, 
- "search_fields": "employee,employee_name,leave_type,from_date,to_date,total_leave_days,fiscal_year", 
+ "search_fields": "employee,employee_name,leave_type,from_date,to_date,total_leave_days", 
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "title_field": "employee_name"
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 8c91173..1d84a40 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -2,13 +2,13 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe, json
+import frappe
 from frappe import _
-
 from frappe.utils import cint, cstr, date_diff, flt, formatdate, getdate, get_link_to_form, \
 	comma_or, get_fullname
-from frappe import msgprint
 from erpnext.hr.utils import set_employee_name
+from erpnext.hr.doctype.leave_block_list.leave_block_list import get_applicable_block_dates
+
 
 class LeaveDayBlockedError(frappe.ValidationError): pass
 class OverlapError(frappe.ValidationError): pass
@@ -18,8 +18,7 @@
 from frappe.model.document import Document
 class LeaveApplication(Document):
 	def get_feed(self):
-		return _("{0}: From {0} of type {1}").format(self.status,
-			self.employee_name, self.leave_type)
+		return _("{0}: From {0} of type {1}").format(self.status, self.employee_name, self.leave_type)
 
 	def validate(self):
 		if not getattr(self, "__islocal", None) and frappe.db.exists(self.doctype, self.name):
@@ -29,7 +28,7 @@
 
 		set_employee_name(self)
 
-		self.validate_to_date()
+		self.validate_dates()
 		self.validate_balance_leaves()
 		self.validate_leave_overlap()
 		self.validate_max_days()
@@ -50,6 +49,8 @@
 	def on_submit(self):
 		if self.status != "Approved":
 			frappe.throw(_("Only Leave Applications with status 'Approved' can be submitted"))
+			
+		self.validate_back_dated_application()
 
 		# notify leave applier about approval
 		self.notify_employee(self.status)
@@ -57,10 +58,41 @@
 	def on_cancel(self):
 		# notify leave applier about cancellation
 		self.notify_employee("cancelled")
+		
+	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"))
+			
+		self.validate_dates_acorss_allocation()
+		self.validate_back_dated_application()
+		
+	def validate_dates_acorss_allocation(self):
+		def _get_leave_alloction_record(date):
+			allocation = frappe.db.sql("""select name from `tabLeave Allocation` 
+				where employee=%s and leave_type=%s and docstatus=1 
+				and %s between from_date and to_date""", (self.employee, self.leave_type, date))
+				
+			return allocation and allocation[0][0]
+			
+		allocation_based_on_from_date = _get_leave_alloction_record(self.from_date)
+		allocation_based_on_to_date = _get_leave_alloction_record(self.to_date)
+		
+		if not (allocation_based_on_from_date or allocation_based_on_to_date):
+			frappe.throw(_("Application period cannot be outside leave allocation period"))
+			
+		elif allocation_based_on_from_date != allocation_based_on_to_date:
+			frappe.throw(_("Application period cannot be across two alocation records"))
+			
+	def validate_back_dated_application(self):
+		future_allocation = frappe.db.sql("""select name, from_date from `tabLeave Allocation`
+			where employee=%s and leave_type=%s and docstatus=1 and from_date > %s 
+			and carry_forward=1""", (self.employee, self.leave_type, self.to_date), as_dict=1)
+		
+		if future_allocation:
+			frappe.throw(_("Leave cannot be applied/cancelled before {0}, as leave balance has already been carry-forwarded in the future leave allocation record {1}")
+				.format(formatdate(future_allocation[0].from_date), future_allocation[0].name))
 
 	def show_block_day_warning(self):
-		from erpnext.hr.doctype.leave_block_list.leave_block_list import get_applicable_block_dates
-
 		block_dates = get_applicable_block_dates(self.from_date, self.to_date,
 			self.employee, self.company, all_lists=True)
 
@@ -70,60 +102,39 @@
 				frappe.msgprint(formatdate(d.block_date) + ": " + d.reason)
 
 	def validate_block_days(self):
-		from erpnext.hr.doctype.leave_block_list.leave_block_list import get_applicable_block_dates
-
 		block_dates = get_applicable_block_dates(self.from_date, self.to_date,
 			self.employee, self.company)
 
-		if block_dates:
-			if self.status == "Approved":
-				frappe.throw(_("Cannot approve leave as you are not authorized to approve leaves on Block Dates"),
-					LeaveDayBlockedError)
-
-	def get_holidays(self):
-		return get_holidays(self)
-
-	def get_total_leave_days(self):
-		return get_total_leave_days(self)
-
-	def validate_to_date(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 block_dates and self.status == "Approved":
+			frappe.throw(_("You are not authorized to approve leaves on Block Dates"), LeaveDayBlockedError)
 
 	def validate_balance_leaves(self):
 		if self.from_date and self.to_date:
-			self.total_leave_days = self.get_total_leave_days()["total_leave_days"]
+			self.total_leave_days = get_number_of_leave_days(self.employee, self.leave_type, 
+				self.from_date, self.to_date, self.half_day)
 
 			if self.total_leave_days == 0:
-				frappe.throw(_("The day(s) on which you are applying for leave are holiday. You need not apply for leave."))
+				frappe.throw(_("The day(s) on which you are applying for leave are holidays. You need not apply for leave."))
 
 			if not is_lwp(self.leave_type):
-				self.leave_balance = get_leave_balance(self.employee,
-					self.leave_type, self.from_date, self.to_date)["leave_balance"]
+				self.leave_balance = get_leave_balance_on(self.employee, self.leave_type, self.from_date)
 
-				if self.status != "Rejected" \
-						and self.leave_balance - self.total_leave_days < 0:
-					#check if this leave type allow the remaining balance to be in negative. If yes then warn the user and continue to save else warn the user and don't save.
+				if self.status != "Rejected" and self.leave_balance < self.total_leave_days:
 					if frappe.db.get_value("Leave Type", self.leave_type, "allow_negative"):
-						frappe.msgprint(_("Note: There is not enough leave balance for Leave Type {0}").format(self.leave_type))
+						frappe.msgprint(_("Note: There is not enough leave balance for Leave Type {0}")
+							.format(self.leave_type))
 					else:
-						frappe.throw(_("There is not enough leave balance for Leave Type {0}").format(self.leave_type))
-
+						frappe.throw(_("There is not enough leave balance for Leave Type {0}")
+							.format(self.leave_type))
 
 	def validate_leave_overlap(self):
 		if not self.name:
 			self.name = "New Leave Application"
 
-		for d in frappe.db.sql("""select name, leave_type, posting_date,
-			from_date, to_date
+		for d in frappe.db.sql("""select name, leave_type, posting_date, from_date, to_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
+			where employee = %(employee)s and docstatus < 2 and status in ("Open", "Approved")
+			and to_date >= %(from_date)s and from_date <= %(to_date)s
 			and name != %(name)s""", {
 				"employee": self.employee,
 				"from_date": self.from_date,
@@ -131,9 +142,12 @@
 				"name": self.name
 			}, as_dict = 1):
 
-			frappe.msgprint(_("Employee {0} has already applied for {1} between {2} and {3}").format(self.employee,
-				cstr(d['leave_type']), formatdate(d['from_date']), formatdate(d['to_date'])))
-			frappe.throw('<a href="#Form/Leave Application/{0}">{0}</a>'.format(d["name"]), OverlapError)
+			frappe.msgprint(_("Employee {0} has already applied for {1} between {2} and {3}")
+				.format(self.employee, cstr(d['leave_type']), 
+					formatdate(d['from_date']), formatdate(d['to_date'])))
+			
+			frappe.throw("""Exising Application: <a href="#Form/Leave Application/{0}">{0}</a>"""
+				.format(d["name"]), OverlapError)
 
 	def validate_max_days(self):
 		max_days = frappe.db.get_value("Leave Type", self.leave_type, "max_days_allowed")
@@ -145,7 +159,8 @@
 		leave_approvers = [l.leave_approver for l in employee.get("leave_approvers")]
 
 		if len(leave_approvers) and self.leave_approver not in leave_approvers:
-			frappe.throw(_("Leave approver must be one of {0}").format(comma_or(leave_approvers)), InvalidLeaveApproverError)
+			frappe.throw(_("Leave approver must be one of {0}")
+				.format(comma_or(leave_approvers)), InvalidLeaveApproverError)
 
 		elif self.leave_approver and not frappe.db.sql("""select name from `tabUserRole`
 			where parent=%s and role='Leave Approver'""", self.leave_approver):
@@ -153,8 +168,8 @@
 				.format(get_fullname(self.leave_approver), self.leave_approver), InvalidLeaveApproverError)
 
 		elif self.docstatus==1 and len(leave_approvers) and self.leave_approver != frappe.session.user:
-			msgprint(_("Only the selected Leave Approver can submit this Leave Application"),
-				raise_exception=LeaveApproverIdentityError)
+			frappe.throw(_("Only the selected Leave Approver can submit this Leave Application"),
+				LeaveApproverIdentityError)
 
 	def notify_employee(self, status):
 		employee = frappe.get_doc("Employee", self.employee)
@@ -213,60 +228,89 @@
 		approver.parent = %s
 		and user.name like %s
 		and approver.leave_approver=user.name""", (filters.get("employee"), "%" + txt + "%"))
+		
+@frappe.whitelist()			
+def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day=None):
+	if half_day:
+		return 0.5
+	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
 
-def get_holidays(leave_app):
+@frappe.whitelist()
+def get_leave_balance_on(employee, leave_type, date, allocation_records=None):
+	if allocation_records == None:
+		allocation_records = get_leave_allocation_records(date, employee).get(employee, frappe._dict())
+		
+	allocation = allocation_records.get(leave_type, frappe._dict())
+	
+	leaves_taken = get_approved_leaves_for_period(employee, leave_type, allocation.from_date, date)
+	
+	return flt(allocation.total_leaves_allocated) - flt(leaves_taken)
+	
+def get_approved_leaves_for_period(employee, leave_type, from_date, to_date):
+	leave_applications = frappe.db.sql("""
+		select employee, leave_type, from_date, to_date, total_leave_days 
+		from `tabLeave Application` 
+		where employee=%(employee)s and leave_type=%(leave_type)s 
+			and status="Approved" and docstatus=1
+			and (from_date between %(from_date)s and %(to_date)s 
+				or to_date between %(from_date)s and %(to_date)s 
+				or (from_date < %(from_date)s and to_date > %(to_date)s))
+	""", {
+		"from_date": from_date,
+		"to_date": to_date,
+		"employee": employee,
+		"leave_type": leave_type
+	}, as_dict=1)
+	
+	leave_days = 0
+	for leave_app in leave_applications:
+		if leave_app.from_date >= getdate(from_date) and leave_app.to_date <= getdate(to_date):
+			leave_days += leave_app.total_leave_days
+		else:
+			if leave_app.from_date < getdate(from_date):
+				leave_app.from_date = from_date
+			if leave_app.to_date > getdate(to_date):
+				leave_app.to_date = to_date
+	
+			leave_days += get_number_of_leave_days(employee, leave_type, 
+				leave_app.from_date, leave_app.to_date)
+			
+	return leave_days
+	
+def get_leave_allocation_records(date, employee=None):
+	conditions = (" and employee='%s'" % employee) if employee else ""
+		
+	leave_allocation_records = frappe.db.sql("""
+		select employee, leave_type, total_leaves_allocated, from_date 
+		from `tabLeave Allocation` 
+		where %s between from_date and to_date and docstatus=1 {0}""".format(conditions), (date), as_dict=1)
+		
+	allocated_leaves = frappe._dict()
+	for d in leave_allocation_records:
+		allocated_leaves.setdefault(d.employee, frappe._dict()).setdefault(d.leave_type, frappe._dict({
+			"from_date": d.from_date,
+			"total_leaves_allocated": d.total_leaves_allocated
+		}))
+
+	return allocated_leaves
+		
+
+def get_holidays(employee, from_date, to_date):
 	tot_hol = frappe.db.sql("""select count(*) from `tabHoliday` h1, `tabHoliday List` h2, `tabEmployee` e1
 		where e1.name = %s and h1.parent = h2.name and e1.holiday_list = h2.name
-		and h1.holiday_date between %s and %s""", (leave_app.employee, leave_app.from_date,
-			leave_app.to_date))[0][0]
-	# below line is needed. If an employee hasn't been assigned with any holiday list then above will return 0 rows.
+		and h1.holiday_date between %s and %s""", (employee, from_date, to_date))[0][0]
+
 	if not tot_hol:
 		tot_hol = frappe.db.sql("""select count(*) from `tabHoliday` h1, `tabHoliday List` h2
 			where h1.parent = h2.name and h1.holiday_date between %s and %s
-			and ifnull(h2.is_default,0) = 1 and h2.fiscal_year = %s""",
-			(leave_app.from_date, leave_app.to_date, leave_app.fiscal_year))[0][0]
+			and ifnull(h2.is_default,0) = 1""", (from_date, to_date))[0][0]
+	
 	return tot_hol
 
-@frappe.whitelist()
-def get_total_leave_days(leave_app):
-	# Parse Leave Application if neccessary
-	if isinstance(leave_app, str) or isinstance(leave_app, unicode):
-		leave_app = frappe.get_doc(json.loads(leave_app))
-
-	"""Calculates total leave days based on input and holidays"""
-	ret = {'total_leave_days' : 0.5}
-	if not leave_app.half_day:
-		tot_days = date_diff(leave_app.to_date, leave_app.from_date) + 1
-		if frappe.db.get_value("Leave Type", leave_app.leave_type, "include_holiday"):
-			ret = {
-				'total_leave_days' : flt(tot_days)
-			}
-		else:
-			holidays = leave_app.get_holidays()
-			ret = {
-				'total_leave_days' : flt(tot_days)-flt(holidays)
-			}
-
-	return ret
-
-@frappe.whitelist()
-def get_leave_balance(employee, leave_type, from_date, to_date):
-	leave_all = frappe.db.sql("""select total_leaves_allocated
-		from `tabLeave Allocation` where employee = %s and leave_type = %s
-		and from_date<=%s and to_date>=%s and docstatus = 1""", (employee,
-			leave_type, from_date, to_date))
-
-	leave_all = leave_all and flt(leave_all[0][0]) or 0
-
-	leave_app = frappe.db.sql("""select SUM(total_leave_days)
-		from `tabLeave Application`
-		where employee = %s and leave_type = %s and to_date>=%s and from_date<=%s
-		and status="Approved" and docstatus = 1""", (employee, leave_type, from_date, to_date))
-	leave_app = leave_app and flt(leave_app[0][0]) or 0
-
-	ret = {'leave_balance': leave_all - leave_app}
-	return ret
-
 def is_lwp(leave_type):
 	lwp = frappe.db.sql("select is_lwp from `tabLeave Type` where name = %s", leave_type)
 	return lwp and cint(lwp[0][0]) or 0
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.py b/erpnext/hr/doctype/process_payroll/process_payroll.py
index 3658e65..b6b76c9 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.py
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.py
@@ -41,7 +41,7 @@
 
 
 	def get_joining_releiving_condition(self):
-		m = self.get_month_details(self.fiscal_year, self.month)
+		m = get_month_details(self.fiscal_year, self.month)
 		cond = """
 			and ifnull(t1.date_of_joining, '0000-00-00') <= '%(month_end_date)s'
 			and ifnull(t1.relieving_date, '2199-12-31') >= '%(month_start_date)s'
@@ -54,24 +54,6 @@
 			if not self.get(f):
 				frappe.throw(_("Please set {0}").format(f))
 
-	def get_month_details(self, year, month):
-		ysd = frappe.db.get_value("Fiscal Year", year, "year_start_date")
-		if ysd:
-			from dateutil.relativedelta import relativedelta
-			import calendar, datetime
-			diff_mnt = cint(month)-cint(ysd.month)
-			if diff_mnt<0:
-				diff_mnt = 12-int(ysd.month)+cint(month)
-			msd = ysd + relativedelta(months=diff_mnt) # month start date
-			month_days = cint(calendar.monthrange(cint(msd.year) ,cint(month))[1]) # days in month
-			med = datetime.date(msd.year, cint(month), month_days) # month end date
-			return {
-				'year': msd.year,
-				'month_start_date': msd,
-				'month_end_date': med,
-				'month_days': month_days
-			}
-
 	def create_sal_slip(self):
 		"""
 			Creates salary slip for selected employees if already not created
@@ -205,3 +187,22 @@
 		])
 
 		return journal_entry.as_dict()
+
+
+def get_month_details(year, month):
+	ysd = frappe.db.get_value("Fiscal Year", year, "year_start_date")
+	if ysd:
+		from dateutil.relativedelta import relativedelta
+		import calendar, datetime
+		diff_mnt = cint(month)-cint(ysd.month)
+		if diff_mnt<0:
+			diff_mnt = 12-int(ysd.month)+cint(month)
+		msd = ysd + relativedelta(months=diff_mnt) # month start date
+		month_days = cint(calendar.monthrange(cint(msd.year) ,cint(month))[1]) # days in month
+		med = datetime.date(msd.year, cint(month), month_days) # month end date
+		return frappe._dict({
+			'year': msd.year,
+			'month_start_date': msd,
+			'month_end_date': med,
+			'month_days': month_days
+		})
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 12fdc20..9a06c36 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -10,6 +10,7 @@
 from frappe import msgprint, _
 from erpnext.setup.utils import get_company_currency
 from erpnext.hr.utils import set_employee_name
+from erpnext.hr.doctype.process_payroll.process_payroll import get_month_details
 
 from erpnext.utilities.transaction_base import TransactionBase
 
@@ -25,11 +26,17 @@
 				self.pull_sal_struct(struct)
 
 	def check_sal_struct(self):
+		m = get_month_details(self.fiscal_year, self.month)
 		struct = frappe.db.sql("""select name from `tabSalary Structure`
-			where employee=%s and is_active = 'Yes'""", self.employee)
+			where employee=%s and is_active = 'Yes' 
+			and from_date <= %s and (to_date is null or to_date >= %s)""", 
+			(self.employee, m.month_start_date, m.month_end_date))
+		
 		if not struct:
-			msgprint(_("Please create Salary Structure for employee {0}").format(self.employee))
+			msgprint(_("No active Salary Structure found for employee {0} and the month")
+				.format(self.employee))
 			self.employee = None
+		
 		return struct and struct[0][0] or ''
 
 	def pull_sal_struct(self, struct):
@@ -49,7 +56,7 @@
 		if not self.month:
 			self.month = "%02d" % getdate(nowdate()).month
 
-		m = frappe.get_doc('Process Payroll').get_month_details(self.fiscal_year, self.month)
+		m = get_month_details(self.fiscal_year, self.month)
 		holidays = self.get_holidays_for_employee(m)
 
 		if not cint(frappe.db.get_value("HR Settings", "HR Settings",
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
index 2bb7f52..fb69440 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
@@ -10,8 +10,20 @@
 
 class TestSalarySlip(unittest.TestCase):
 	def setUp(self):
-		frappe.db.sql("""delete from `tabLeave Application`""")
-		frappe.db.sql("""delete from `tabSalary Slip`""")
+		for dt in ["Leave Application", "Leave Allocation", "Salary Slip"]:
+			frappe.db.sql("delete from `tab%s`" % dt)
+		
+		allocation = frappe.get_doc({
+			"doctype": "Leave Allocation",
+			"employee": "_T-Employee-0001",
+			"leave_type": "_Test Leave Type LWP",
+			"from_date": "2013-01-01",
+			"to_date": "2015-12-31",
+			"new_leaves_allocated": 5
+		})
+		
+		allocation.insert()
+		allocation.submit()
 		
 		frappe.db.set_value("Holiday List", "_Test Holiday List", "is_default", 1)
 		
diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.js b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.js
index 41b1421..5df4554 100644
--- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.js
+++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.js
@@ -7,12 +7,14 @@
 			"fieldname":"from_date",
 			"label": __("From Date"),
 			"fieldtype": "Date",
+			"reqd": 1,
 			"default": frappe.datetime.year_start()
 		},
 		{
 			"fieldname":"to_date",
 			"label": __("To Date"),
 			"fieldtype": "Date",
+			"reqd": 1,
 			"default": frappe.datetime.year_end()
 		},
 		{
@@ -20,6 +22,7 @@
 			"label": __("Company"),
 			"fieldtype": "Link",
 			"options": "Company",
+			"reqd": 1,
 			"default": frappe.defaults.get_user_default("company")
 		}
 	]
diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
index 0aa88a8..7f1c442 100644
--- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
+++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
@@ -4,67 +4,54 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _
-from frappe.desk.reportview import execute as runreport
+from erpnext.hr.doctype.leave_application.leave_application \
+	import get_leave_allocation_records, get_leave_balance_on, get_approved_leaves_for_period
+
 
 def execute(filters=None):
-	if not filters: filters = {}
-
-	employee_filters = {
-		"status": "Active"
-	}
+	leave_types = frappe.db.sql_list("select name from `tabLeave Type` order by name asc")
 	
-	if filters.get("company"):
-		filters["company"] = filters.company
-
-	employees = runreport(doctype="Employee", fields=["name", "employee_name", "department"],
-		filters=employee_filters, limit_page_length=None)
-
-	if not employees:
-		frappe.throw(_("No employee found!"))
-
-	leave_types = frappe.db.sql_list("select name from `tabLeave Type`")
-
-	employee_names = [d.name for d in employees]
-
-	allocations = frappe.db.sql("""select employee, leave_type, sum(new_leaves_allocated) as leaves_allocated
-	 	from `tabLeave Allocation`
-		where docstatus=1 and employee in (%s) and from_date >= '%s' and to_date <= '%s'""" %
-		(','.join(['%s']*len(employee_names)), filters.get("from_date"),
-		 filters.get("to_date")), employee_names, as_dict=True)
-		
-	applications = frappe.db.sql("""select employee, leave_type,
-			SUM(total_leave_days) as leaves
-		from `tabLeave Application`
-		where status="Approved" and docstatus = 1 and employee in (%s)
-		and from_date >= '%s' and to_date <= '%s'
-		group by employee, leave_type""" %
-		(','.join(['%s']*len(employee_names)), filters.get("from_date"),
-		 filters.get("to_date")), employee_names, as_dict=True)
-
+	columns = get_columns(leave_types)
+	data = get_data(filters, leave_types)
+	
+	return columns, data
+	
+def get_columns(leave_types):
 	columns = [
-		_("Employee") + ":Link/Employee:150", _("Employee Name") + "::200", _("Department") +"::150"
+		_("Employee") + ":Link/Employee:150", 
+		_("Employee Name") + "::200", 
+		_("Department") +"::150"
 	]
 
 	for leave_type in leave_types:
-		columns.append(_(leave_type) + " " + _("Opening") + ":Float")
-		columns.append(_(leave_type) + " " + _("Taken") + ":Float")
-		columns.append(_(leave_type) + " " + _("Balance") + ":Float")
+		columns.append(_(leave_type) + " " + _("Taken") + ":Float:160")
+		columns.append(_(leave_type) + " " + _("Balance") + ":Float:160")
+	
+	return columns
+	
+def get_data(filters, leave_types):
 
-	data = {}
-	for d in allocations:
-		data.setdefault((d.employee,d.leave_type), frappe._dict()).allocation = d.leaves_allocated
+	allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)
 
-	for d in applications:
-		data.setdefault((d.employee, d.leave_type), frappe._dict()).leaves = d.leaves
-
-	result = []
-	for employee in employees:
+	active_employees = frappe.get_all("Employee", 
+		filters = { "status": "Active", "company": filters.company}, 
+		fields = ["name", "employee_name", "department"])
+	
+	data = []
+	for employee in active_employees:
 		row = [employee.name, employee.employee_name, employee.department]
-		result.append(row)
-		for leave_type in leave_types:
-			tmp = data.get((employee.name, leave_type), frappe._dict())
-			row.append(tmp.allocation or 0)
-			row.append(tmp.leaves or 0)
-			row.append((tmp.allocation or 0) - (tmp.leaves or 0))
 
-	return columns, result
+		for leave_type in leave_types:	
+			# leaves taken
+			leaves_taken = get_approved_leaves_for_period(employee.name, leave_type, 
+				filters.from_date, filters.to_date)
+	
+			# closing balance
+			closing = get_leave_balance_on(employee.name, leave_type, filters.to_date, 
+				allocation_records_based_on_to_date.get(employee.name, frappe._dict()))
+
+			row += [leaves_taken, closing]
+			
+		data.append(row)
+		
+	return data
\ No newline at end of file
diff --git a/erpnext/projects/doctype/time_log/time_log.js b/erpnext/projects/doctype/time_log/time_log.js
index 5fce970..7b2faf9 100644
--- a/erpnext/projects/doctype/time_log/time_log.js
+++ b/erpnext/projects/doctype/time_log/time_log.js
@@ -4,11 +4,13 @@
 frappe.provide("erpnext.projects");
 
 frappe.ui.form.on("Time Log", "onload", function(frm) {
-	if (frm.doc.for_manufacturing) {
-		frappe.ui.form.trigger("Time Log", "production_order");
-	}
-	if (frm.doc.from_time && frm.doc.to_time) {
-		frappe.ui.form.trigger("Time Log", "to_time");
+	if (frm.doc.__islocal) {
+		if (frm.doc.for_manufacturing) {
+			frappe.ui.form.trigger("Time Log", "production_order");
+		}
+		if (frm.doc.from_time && frm.doc.to_time) {
+			frappe.ui.form.trigger("Time Log", "to_time");
+		}
 	}
 });
 
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index b1b24cf..413c7ae 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -500,9 +500,13 @@
 		if(this.frm.doc.is_return || this.frm.doc.docstatus > 0) return;
 		
 		frappe.model.round_floats_in(this.frm.doc, ["grand_total", "total_advance", "write_off_amount"]);
-		
-		var total_amount_to_pay = flt((this.frm.doc.grand_total - this.frm.doc.total_advance 
-			- this.frm.doc.write_off_amount), precision("grand_total"));
+		if(this.frm.doc.party_account_currency == this.frm.doc.currency) {	
+			var total_amount_to_pay = flt((this.frm.doc.grand_total - this.frm.doc.total_advance 
+				- this.frm.doc.write_off_amount), precision("grand_total"));
+		else {
+			var total_amount_to_pay = flt((this.frm.doc.base_grand_total - this.frm.doc.total_advance 
+				- this.frm.doc.base_write_off_amount), precision("base_grand_total"));
+		}
 		
 		if(this.frm.doc.doctype == "Sales Invoice") {
 			frappe.model.round_floats_in(this.frm.doc, ["paid_amount"]);
@@ -518,18 +522,15 @@
 			this.frm.refresh_field("paid_amount");
 			this.frm.refresh_field("base_paid_amount");
 			
-			var outstanding_amount =  flt(total_amount_to_pay - this.frm.doc.paid_amount, 
+			var paid_amount = (this.frm.doc.party_account_currency == this.frm.doc.currency) ? 
+				this.frm.doc.paid_amount : this.frm.doc.base_paid_amount;
+			
+			var outstanding_amount =  flt(total_amount_to_pay - flt(paid_amount), 
 				precision("outstanding_amount"));
 				
 		} else if(this.frm.doc.doctype == "Purchase Invoice") {
 			var outstanding_amount = flt(total_amount_to_pay, precision("outstanding_amount"));
-		}
-		
-		if(this.frm.doc.party_account_currency == this.frm.doc.currency) {	
-			this.frm.set_value("outstanding_amount", outstanding_amount);
-		} else {
-			this.frm.set_value("outstanding_amount", 
-				flt(outstanding_amount * this.frm.doc.conversion_rate, precision("outstanding_amount")));
-		}
+		}		
+		this.frm.set_value("outstanding_amount", outstanding_amount);
 	}
 })
diff --git a/erpnext/public/js/setup_wizard.js b/erpnext/public/js/setup_wizard.js
index e877737..bb3d272 100644
--- a/erpnext/public/js/setup_wizard.js
+++ b/erpnext/public/js/setup_wizard.js
@@ -5,404 +5,407 @@
 		frappe.set_route("desk");
 		return;
 	}
-}
+};
 
-$.extend(erpnext.wiz, {
-	region: {
-		title: __("Region"),
-		icon: "icon-flag",
-		help: __("Select your Country, Time Zone and Currency"),
-		fields: [
-			{ fieldname: "country", label: __("Country"), reqd:1,
-				fieldtype: "Select" },
-			{ fieldname: "timezone", label: __("Time Zone"), reqd:1,
-				fieldtype: "Select" },
-			{ fieldname: "currency", label: __("Currency"), reqd:1,
-				fieldtype: "Select" },
-		],
+function load_erpnext_slides() {
+	$.extend(erpnext.wiz, {
+		region: {
+			title: __("Region"),
+			icon: "icon-flag",
+			help: __("Select your Country, Time Zone and Currency"),
+			fields: [
+				{ fieldname: "country", label: __("Country"), reqd:1,
+					fieldtype: "Select" },
+				{ fieldname: "timezone", label: __("Time Zone"), reqd:1,
+					fieldtype: "Select" },
+				{ fieldname: "currency", label: __("Currency"), reqd:1,
+					fieldtype: "Select" },
+			],
 
-		onload: function(slide) {
-			frappe.call({
-				method:"frappe.geo.country_info.get_country_timezone_info",
-				callback: function(data) {
-					erpnext.wiz.region.data = data.message;
-					erpnext.wiz.region.setup_fields(slide);
-					erpnext.wiz.region.bind_events(slide);
-				}
-			});
-		},
-		css_class: "single-column",
-		setup_fields: function(slide) {
-			var data = erpnext.wiz.region.data;
-
-			slide.get_input("country").empty()
-				.add_options([""].concat(keys(data.country_info).sort()));
-
-			slide.get_input("currency").empty()
-				.add_options(frappe.utils.unique([""].concat($.map(data.country_info,
-					function(opts, country) { return opts.currency; }))).sort());
-
-			slide.get_input("timezone").empty()
-				.add_options([""].concat(data.all_timezones));
-
-			if (data.default_country) {
-				slide.set_input("country", data.default_country);
-			}
-		},
-
-		bind_events: function(slide) {
-			slide.get_input("country").on("change", function() {
-				var country = slide.get_input("country").val();
-				var $timezone = slide.get_input("timezone");
+			onload: function(slide) {
+				frappe.call({
+					method:"frappe.geo.country_info.get_country_timezone_info",
+					callback: function(data) {
+						erpnext.wiz.region.data = data.message;
+						erpnext.wiz.region.setup_fields(slide);
+						erpnext.wiz.region.bind_events(slide);
+					}
+				});
+			},
+			css_class: "single-column",
+			setup_fields: function(slide) {
 				var data = erpnext.wiz.region.data;
 
-				$timezone.empty();
+				slide.get_input("country").empty()
+					.add_options([""].concat(keys(data.country_info).sort()));
 
-				// add country specific timezones first
-				if(country) {
-					var timezone_list = data.country_info[country].timezones || [];
-					$timezone.add_options(timezone_list.sort());
-					slide.get_field("currency").set_input(data.country_info[country].currency);
-					slide.get_field("currency").$input.trigger("change");
+				slide.get_input("currency").empty()
+					.add_options(frappe.utils.unique([""].concat($.map(data.country_info,
+						function(opts, country) { return opts.currency; }))).sort());
+
+				slide.get_input("timezone").empty()
+					.add_options([""].concat(data.all_timezones));
+
+				if (data.default_country) {
+					slide.set_input("country", data.default_country);
 				}
+			},
 
-				// add all timezones at the end, so that user has the option to change it to any timezone
-				$timezone.add_options([""].concat(data.all_timezones));
+			bind_events: function(slide) {
+				slide.get_input("country").on("change", function() {
+					var country = slide.get_input("country").val();
+					var $timezone = slide.get_input("timezone");
+					var data = erpnext.wiz.region.data;
 
-				slide.get_field("timezone").set_input($timezone.val());
+					$timezone.empty();
 
-				// temporarily set date format
-				frappe.boot.sysdefaults.date_format = (data.country_info[country].date_format
-					|| "dd-mm-yyyy");
-			});
-
-			slide.get_input("currency").on("change", function() {
-				var currency = slide.get_input("currency").val();
-				if (!currency) return;
-				frappe.model.with_doc("Currency", currency, function() {
-					frappe.provide("locals.:Currency." + currency);
-					var currency_doc = frappe.model.get_doc("Currency", currency);
-					var number_format = currency_doc.number_format;
-					if (number_format==="#.###") {
-						number_format = "#.###,##";
-					} else if (number_format==="#,###") {
-						number_format = "#,###.##"
+					// add country specific timezones first
+					if(country) {
+						var timezone_list = data.country_info[country].timezones || [];
+						$timezone.add_options(timezone_list.sort());
+						slide.get_field("currency").set_input(data.country_info[country].currency);
+						slide.get_field("currency").$input.trigger("change");
 					}
 
-					frappe.boot.sysdefaults.number_format = number_format;
-					locals[":Currency"][currency] = $.extend({}, currency_doc);
+					// add all timezones at the end, so that user has the option to change it to any timezone
+					$timezone.add_options([""].concat(data.all_timezones));
+
+					slide.get_field("timezone").set_input($timezone.val());
+
+					// temporarily set date format
+					frappe.boot.sysdefaults.date_format = (data.country_info[country].date_format
+						|| "dd-mm-yyyy");
 				});
-			});
-		}
-	},
 
-	user: {
-		title: __("The First User: You"),
-		icon: "icon-user",
-		fields: [
-			{"fieldname": "first_name", "label": __("First Name"), "fieldtype": "Data",
-				reqd:1},
-			{"fieldname": "last_name", "label": __("Last Name"), "fieldtype": "Data"},
-			{"fieldname": "email", "label": __("Email Address"), "fieldtype": "Data",
-				reqd:1, "description": __("You will use it to Login"), "options":"Email"},
-			{"fieldname": "password", "label": __("Password"), "fieldtype": "Password",
-				reqd:1},
-			{fieldtype:"Attach Image", fieldname:"attach_user",
-				label: __("Attach Your Picture")},
-		],
-		help: __('The first user will become the System Manager (you can change this later).'),
-		onload: function(slide) {
-			if(user!=="Administrator") {
-				slide.form.fields_dict.password.$wrapper.toggle(false);
-				slide.form.fields_dict.email.$wrapper.toggle(false);
-				slide.form.fields_dict.first_name.set_input(frappe.boot.user.first_name);
-				slide.form.fields_dict.last_name.set_input(frappe.boot.user.last_name);
+				slide.get_input("currency").on("change", function() {
+					var currency = slide.get_input("currency").val();
+					if (!currency) return;
+					frappe.model.with_doc("Currency", currency, function() {
+						frappe.provide("locals.:Currency." + currency);
+						var currency_doc = frappe.model.get_doc("Currency", currency);
+						var number_format = currency_doc.number_format;
+						if (number_format==="#.###") {
+							number_format = "#.###,##";
+						} else if (number_format==="#,###") {
+							number_format = "#,###.##"
+						}
 
-				var user_image = frappe.get_cookie("user_image");
-				if(user_image) {
-					var $attach_user = slide.form.fields_dict.attach_user.$wrapper;
-					$attach_user.find(".missing-image").toggle(false);
-					$attach_user.find("img").attr("src", decodeURIComponent(user_image)).toggle(true);
-				}
-
-				delete slide.form.fields_dict.email;
-				delete slide.form.fields_dict.password;
+						frappe.boot.sysdefaults.number_format = number_format;
+						locals[":Currency"][currency] = $.extend({}, currency_doc);
+					});
+				});
 			}
 		},
-		css_class: "single-column"
-	},
 
-	org: {
-		title: __("The Organization"),
-		icon: "icon-building",
-		fields: [
-			{fieldname:'company_name', label: __('Company Name'), fieldtype:'Data', reqd:1,
-				placeholder: __('e.g. "My Company LLC"')},
-			{fieldname:'company_abbr', label: __('Company Abbreviation'), fieldtype:'Data',
-				description: __('Max 5 characters'), placeholder: __('e.g. "MC"'), reqd:1},
-			{fieldname:'company_tagline', label: __('What does it do?'), fieldtype:'Data',
-				placeholder:__('e.g. "Build tools for builders"'), reqd:1},
-			{fieldname:'bank_account', label: __('Bank Account'), fieldtype:'Data',
-				placeholder: __('e.g. "XYZ National Bank"'), reqd:1 },
-			{fieldname:'chart_of_accounts', label: __('Chart of Accounts'),
-				options: "", fieldtype: 'Select'},
+		user: {
+			title: __("The First User: You"),
+			icon: "icon-user",
+			fields: [
+				{"fieldname": "first_name", "label": __("First Name"), "fieldtype": "Data",
+					reqd:1},
+				{"fieldname": "last_name", "label": __("Last Name"), "fieldtype": "Data"},
+				{"fieldname": "email", "label": __("Email Address"), "fieldtype": "Data",
+					reqd:1, "description": __("You will use it to Login"), "options":"Email"},
+				{"fieldname": "password", "label": __("Password"), "fieldtype": "Password",
+					reqd:1},
+				{fieldtype:"Attach Image", fieldname:"attach_user",
+					label: __("Attach Your Picture")},
+			],
+			help: __('The first user will become the System Manager (you can change this later).'),
+			onload: function(slide) {
+				if(user!=="Administrator") {
+					slide.form.fields_dict.password.$wrapper.toggle(false);
+					slide.form.fields_dict.email.$wrapper.toggle(false);
+					slide.form.fields_dict.first_name.set_input(frappe.boot.user.first_name);
+					slide.form.fields_dict.last_name.set_input(frappe.boot.user.last_name);
 
-			// TODO remove this
-			{fieldtype: "Section Break"},
-			{fieldname:'fy_start_date', label:__('Financial Year Start Date'), fieldtype:'Date',
-				description: __('Your financial year begins on'), reqd:1},
-			{fieldname:'fy_end_date', label:__('Financial Year End Date'), fieldtype:'Date',
-				description: __('Your financial year ends on'), reqd:1},
-		],
-		help: __('The name of your company for which you are setting up this system.'),
+					var user_image = frappe.get_cookie("user_image");
+					if(user_image) {
+						var $attach_user = slide.form.fields_dict.attach_user.$wrapper;
+						$attach_user.find(".missing-image").toggle(false);
+						$attach_user.find("img").attr("src", decodeURIComponent(user_image)).toggle(true);
+					}
 
-		onload: function(slide) {
-			erpnext.wiz.org.load_chart_of_accounts(slide);
-			erpnext.wiz.org.bind_events(slide);
-			erpnext.wiz.org.set_fy_dates(slide);
+					delete slide.form.fields_dict.email;
+					delete slide.form.fields_dict.password;
+				}
+			},
+			css_class: "single-column"
 		},
 
-		css_class: "single-column",
+		org: {
+			title: __("The Organization"),
+			icon: "icon-building",
+			fields: [
+				{fieldname:'company_name', label: __('Company Name'), fieldtype:'Data', reqd:1,
+					placeholder: __('e.g. "My Company LLC"')},
+				{fieldname:'company_abbr', label: __('Company Abbreviation'), fieldtype:'Data',
+					description: __('Max 5 characters'), placeholder: __('e.g. "MC"'), reqd:1},
+				{fieldname:'company_tagline', label: __('What does it do?'), fieldtype:'Data',
+					placeholder:__('e.g. "Build tools for builders"'), reqd:1},
+				{fieldname:'bank_account', label: __('Bank Account'), fieldtype:'Data',
+					placeholder: __('e.g. "XYZ National Bank"'), reqd:1 },
+				{fieldname:'chart_of_accounts', label: __('Chart of Accounts'),
+					options: "", fieldtype: 'Select'},
 
-		set_fy_dates: function(slide) {
-			var country = slide.wiz.get_values().country;
+				// TODO remove this
+				{fieldtype: "Section Break"},
+				{fieldname:'fy_start_date', label:__('Financial Year Start Date'), fieldtype:'Date',
+					description: __('Your financial year begins on'), reqd:1},
+				{fieldname:'fy_end_date', label:__('Financial Year End Date'), fieldtype:'Date',
+					description: __('Your financial year ends on'), reqd:1},
+			],
+			help: __('The name of your company for which you are setting up this system.'),
 
-			if(country) {
-				var fy = erpnext.wiz.fiscal_years[country];
-				var current_year = moment(new Date()).year();
-				var next_year = current_year + 1;
-				if(!fy) {
-					fy = ["01-01", "12-31"];
-					next_year = current_year;
+			onload: function(slide) {
+				erpnext.wiz.org.load_chart_of_accounts(slide);
+				erpnext.wiz.org.bind_events(slide);
+				erpnext.wiz.org.set_fy_dates(slide);
+			},
+
+			css_class: "single-column",
+
+			set_fy_dates: function(slide) {
+				var country = slide.wiz.get_values().country;
+
+				if(country) {
+					var fy = erpnext.wiz.fiscal_years[country];
+					var current_year = moment(new Date()).year();
+					var next_year = current_year + 1;
+					if(!fy) {
+						fy = ["01-01", "12-31"];
+						next_year = current_year;
+					}
+
+					slide.get_field("fy_start_date").set_input(current_year + "-" + fy[0]);
+					slide.get_field("fy_end_date").set_input(next_year + "-" + fy[1]);
 				}
 
-				slide.get_field("fy_start_date").set_input(current_year + "-" + fy[0]);
-				slide.get_field("fy_end_date").set_input(next_year + "-" + fy[1]);
-			}
+			},
 
-		},
+			load_chart_of_accounts: function(slide) {
+				var country = slide.wiz.get_values().country;
 
-		load_chart_of_accounts: function(slide) {
-			var country = slide.wiz.get_values().country;
+				if(country) {
+					frappe.call({
+						method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.get_charts_for_country",
+						args: {"country": country},
+						callback: function(r) {
+							if(r.message) {
+								slide.get_input("chart_of_accounts").empty()
+									.add_options(r.message);
 
-			if(country) {
-				frappe.call({
-					method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.get_charts_for_country",
-					args: {"country": country},
-					callback: function(r) {
-						if(r.message) {
-							slide.get_input("chart_of_accounts").empty()
-								.add_options(r.message);
-
-							if (r.message.length===1) {
-								var field = slide.get_field("chart_of_accounts");
-								field.set_value(r.message[0]);
-								field.df.hidden = 1;
-								field.refresh();
+								if (r.message.length===1) {
+									var field = slide.get_field("chart_of_accounts");
+									field.set_value(r.message[0]);
+									field.df.hidden = 1;
+									field.refresh();
+								}
 							}
 						}
-					}
-				})
-			}
-		},
-
-		bind_events: function(slide) {
-			slide.get_input("company_name").on("change", function() {
-				var parts = slide.get_input("company_name").val().split(" ");
-				var abbr = $.map(parts, function(p) { return p ? p.substr(0,1) : null }).join("");
-				slide.get_field("company_abbr").set_input(abbr.slice(0, 5).toUpperCase());
-			}).val(frappe.boot.sysdefaults.company_name || "").trigger("change");
-
-			slide.get_input("company_abbr").on("change", function() {
-				if(slide.get_input("company_abbr").val().length > 5) {
-					msgprint("Company Abbreviation cannot have more than 5 characters");
-					slide.get_field("company_abbr").set_input("");
+					})
 				}
-			});
-
-			// TODO remove this
-			slide.get_input("fy_start_date").on("change", function() {
-				var year_end_date =
-					frappe.datetime.add_days(frappe.datetime.add_months(
-						frappe.datetime.user_to_obj(slide.get_input("fy_start_date").val()), 12), -1);
-				slide.get_input("fy_end_date").val(frappe.datetime.obj_to_user(year_end_date));
-
-			});
-		}
-	},
-
-	branding: {
-		icon: "icon-bookmark",
-		title: __("The Brand"),
-		help: __('Upload your letter head and logo. (you can edit them later).'),
-		fields: [
-			{fieldtype:"Attach Image", fieldname:"attach_letterhead",
-				label: __("Attach Letterhead"),
-				description: __("Keep it web friendly 900px (w) by 100px (h)")
 			},
-			{fieldtype: "Column Break"},
-			{fieldtype:"Attach Image", fieldname:"attach_logo",
-				label:__("Attach Logo"),
-				description: __("100px by 100px")},
-		],
 
-		css_class: "two-column"
-	},
+			bind_events: function(slide) {
+				slide.get_input("company_name").on("change", function() {
+					var parts = slide.get_input("company_name").val().split(" ");
+					var abbr = $.map(parts, function(p) { return p ? p.substr(0,1) : null }).join("");
+					slide.get_field("company_abbr").set_input(abbr.slice(0, 5).toUpperCase());
+				}).val(frappe.boot.sysdefaults.company_name || "").trigger("change");
 
-	users: {
-		icon: "icon-money",
-		"title": __("Add Users"),
-		"help": __("Add users to your organization, other than yourself"),
-		"fields": [],
-		before_load: function(slide) {
-			slide.fields = [];
-			for(var i=1; i<5; i++) {
-				slide.fields = slide.fields.concat([
-					{fieldtype:"Section Break"},
-					{fieldtype:"Data", fieldname:"user_fullname_"+ i,
-						label:__("Full Name")},
-					{fieldtype:"Data", fieldname:"user_email_" + i,
-						label:__("Email ID"), placeholder:__("user@example.com"),
-						options: "Email"},
-					{fieldtype:"Column Break"},
-					{fieldtype: "Check", fieldname: "user_sales_" + i,
-						label:__("Sales"), default: 1},
-					{fieldtype: "Check", fieldname: "user_purchaser_" + i,
-						label:__("Purchaser"), default: 1},
-					{fieldtype: "Check", fieldname: "user_accountant_" + i,
-						label:__("Accountant"), default: 1},
-				]);
+				slide.get_input("company_abbr").on("change", function() {
+					if(slide.get_input("company_abbr").val().length > 5) {
+						msgprint("Company Abbreviation cannot have more than 5 characters");
+						slide.get_field("company_abbr").set_input("");
+					}
+				});
+
+				// TODO remove this
+				slide.get_input("fy_start_date").on("change", function() {
+					var year_end_date =
+						frappe.datetime.add_days(frappe.datetime.add_months(
+							frappe.datetime.user_to_obj(slide.get_input("fy_start_date").val()), 12), -1);
+					slide.get_input("fy_end_date").val(frappe.datetime.obj_to_user(year_end_date));
+
+				});
 			}
 		},
-		css_class: "two-column"
-	},
 
-	taxes: {
-		icon: "icon-money",
-		"title": __("Add Taxes"),
-		"help": __("List your tax heads (e.g. VAT, Customs etc; they should have unique names) and their standard rates. This will create a standard template, which you can edit and add more later."),
-		"fields": [],
-		before_load: function(slide) {
-			slide.fields = [];
-			for(var i=1; i<4; i++) {
-				slide.fields = slide.fields.concat([
-					{fieldtype:"Section Break"},
-					{fieldtype:"Data", fieldname:"tax_"+ i, label:__("Tax") + " " + i,
-						placeholder:__("e.g. VAT") + " " + i},
-					{fieldtype:"Column Break"},
-					{fieldtype:"Float", fieldname:"tax_rate_" + i, label:__("Rate (%)"), placeholder:__("e.g. 5")},
-				]);
-			}
+		branding: {
+			icon: "icon-bookmark",
+			title: __("The Brand"),
+			help: __('Upload your letter head and logo. (you can edit them later).'),
+			fields: [
+				{fieldtype:"Attach Image", fieldname:"attach_letterhead",
+					label: __("Attach Letterhead"),
+					description: __("Keep it web friendly 900px (w) by 100px (h)")
+				},
+				{fieldtype: "Column Break"},
+				{fieldtype:"Attach Image", fieldname:"attach_logo",
+					label:__("Attach Logo"),
+					description: __("100px by 100px")},
+			],
+
+			css_class: "two-column"
 		},
-		css_class: "two-column"
-	},
 
-	customers: {
-		icon: "icon-group",
-		"title": __("Your Customers"),
-		"help": __("List a few of your customers. They could be organizations or individuals."),
-		"fields": [],
-		before_load: function(slide) {
-			slide.fields = [];
-			for(var i=1; i<6; i++) {
-				slide.fields = slide.fields.concat([
-					{fieldtype:"Section Break"},
-					{fieldtype:"Data", fieldname:"customer_" + i, label:__("Customer") + " " + i,
-						placeholder:__("Customer Name")},
-					{fieldtype:"Column Break"},
-					{fieldtype:"Data", fieldname:"customer_contact_" + i,
-						label:__("Contact Name") + " " + i, placeholder:__("Contact Name")}
-				])
-			}
-			slide.fields[1].reqd = 1;
+		users: {
+			icon: "icon-money",
+			"title": __("Add Users"),
+			"help": __("Add users to your organization, other than yourself"),
+			"fields": [],
+			before_load: function(slide) {
+				slide.fields = [];
+				for(var i=1; i<5; i++) {
+					slide.fields = slide.fields.concat([
+						{fieldtype:"Section Break"},
+						{fieldtype:"Data", fieldname:"user_fullname_"+ i,
+							label:__("Full Name")},
+						{fieldtype:"Data", fieldname:"user_email_" + i,
+							label:__("Email ID"), placeholder:__("user@example.com"),
+							options: "Email"},
+						{fieldtype:"Column Break"},
+						{fieldtype: "Check", fieldname: "user_sales_" + i,
+							label:__("Sales"), default: 1},
+						{fieldtype: "Check", fieldname: "user_purchaser_" + i,
+							label:__("Purchaser"), default: 1},
+						{fieldtype: "Check", fieldname: "user_accountant_" + i,
+							label:__("Accountant"), default: 1},
+					]);
+				}
+			},
+			css_class: "two-column"
 		},
-		css_class: "two-column"
-	},
 
-	suppliers: {
-		icon: "icon-group",
-		"title": __("Your Suppliers"),
-		"help": __("List a few of your suppliers. They could be organizations or individuals."),
-		"fields": [],
-		before_load: function(slide) {
-			slide.fields = [];
-			for(var i=1; i<6; i++) {
-				slide.fields = slide.fields.concat([
-					{fieldtype:"Section Break"},
-					{fieldtype:"Data", fieldname:"supplier_" + i, label:__("Supplier")+" " + i,
-						placeholder:__("Supplier Name")},
-					{fieldtype:"Column Break"},
-					{fieldtype:"Data", fieldname:"supplier_contact_" + i,
-						label:__("Contact Name") + " " + i, placeholder:__("Contact Name")},
-				])
-			}
-			slide.fields[1].reqd = 1;
+		taxes: {
+			icon: "icon-money",
+			"title": __("Add Taxes"),
+			"help": __("List your tax heads (e.g. VAT, Customs etc; they should have unique names) and their standard rates. This will create a standard template, which you can edit and add more later."),
+			"fields": [],
+			before_load: function(slide) {
+				slide.fields = [];
+				for(var i=1; i<4; i++) {
+					slide.fields = slide.fields.concat([
+						{fieldtype:"Section Break"},
+						{fieldtype:"Data", fieldname:"tax_"+ i, label:__("Tax") + " " + i,
+							placeholder:__("e.g. VAT") + " " + i},
+						{fieldtype:"Column Break"},
+						{fieldtype:"Float", fieldname:"tax_rate_" + i, label:__("Rate (%)"), placeholder:__("e.g. 5")},
+					]);
+				}
+			},
+			css_class: "two-column"
 		},
-		css_class: "two-column"
-	},
 
-	items: {
-		icon: "icon-barcode",
-		"title": __("Your Products or Services"),
-		"help": __("List your products or services that you buy or sell. Make sure to check the Item Group, Unit of Measure and other properties when you start."),
-		"fields": [],
-		before_load: function(slide) {
-			slide.fields = [];
-			for(var i=1; i<6; i++) {
-				slide.fields = slide.fields.concat([
-					{fieldtype:"Section Break", show_section_border: true},
-					{fieldtype:"Data", fieldname:"item_" + i, label:__("Item") + " " + i,
-						placeholder:__("A Product or Service")},
-					{fieldtype:"Select", label:__("Group"), fieldname:"item_group_" + i,
-						options:[__("Products"), __("Services"),
-							__("Raw Material"), __("Consumable"), __("Sub Assemblies")],
-						"default": __("Products")},
-					{fieldtype:"Select", fieldname:"item_uom_" + i, label:__("UOM"),
-						options:[__("Unit"), __("Nos"), __("Box"), __("Pair"), __("Kg"), __("Set"),
-							__("Hour"), __("Minute")],
-						"default": __("Unit")},
-					{fieldtype: "Check", fieldname: "is_sales_item_" + i, label:__("We sell this Item"), default: 1},
-					{fieldtype: "Check", fieldname: "is_purchase_item_" + i, label:__("We buy this Item")},
-					{fieldtype:"Column Break"},
-					{fieldtype:"Currency", fieldname:"item_price_" + i, label:__("Rate")},
-					{fieldtype:"Attach Image", fieldname:"item_img_" + i, label:__("Attach Image")},
-				])
-			}
-			slide.fields[1].reqd = 1;
-
-			// dummy data
-			slide.fields.push({fieldtype: "Section Break"});
-			slide.fields.push({fieldtype: "Check", fieldname: "add_sample_data",
-				label: __("Add a few sample records"), "default": 1});
+		customers: {
+			icon: "icon-group",
+			"title": __("Your Customers"),
+			"help": __("List a few of your customers. They could be organizations or individuals."),
+			"fields": [],
+			before_load: function(slide) {
+				slide.fields = [];
+				for(var i=1; i<6; i++) {
+					slide.fields = slide.fields.concat([
+						{fieldtype:"Section Break"},
+						{fieldtype:"Data", fieldname:"customer_" + i, label:__("Customer") + " " + i,
+							placeholder:__("Customer Name")},
+						{fieldtype:"Column Break"},
+						{fieldtype:"Data", fieldname:"customer_contact_" + i,
+							label:__("Contact Name") + " " + i, placeholder:__("Contact Name")}
+					])
+				}
+				slide.fields[1].reqd = 1;
+			},
+			css_class: "two-column"
 		},
-		css_class: "two-column"
-	},
-});
 
-// Source: https://en.wikipedia.org/wiki/Fiscal_year
-// default 1st Jan - 31st Dec
+		suppliers: {
+			icon: "icon-group",
+			"title": __("Your Suppliers"),
+			"help": __("List a few of your suppliers. They could be organizations or individuals."),
+			"fields": [],
+			before_load: function(slide) {
+				slide.fields = [];
+				for(var i=1; i<6; i++) {
+					slide.fields = slide.fields.concat([
+						{fieldtype:"Section Break"},
+						{fieldtype:"Data", fieldname:"supplier_" + i, label:__("Supplier")+" " + i,
+							placeholder:__("Supplier Name")},
+						{fieldtype:"Column Break"},
+						{fieldtype:"Data", fieldname:"supplier_contact_" + i,
+							label:__("Contact Name") + " " + i, placeholder:__("Contact Name")},
+					])
+				}
+				slide.fields[1].reqd = 1;
+			},
+			css_class: "two-column"
+		},
 
-erpnext.wiz.fiscal_years = {
-	"Afghanistan": ["12-20", "12-21"],
-	"Australia": ["07-01", "06-30"],
-	"Bangladesh": ["07-01", "06-30"],
-	"Canada": ["04-01", "03-31"],
-	"Costa Rica": ["10-01", "09-30"],
-	"Egypt": ["07-01", "06-30"],
-	"Hong Kong": ["04-01", "03-31"],
-	"India": ["04-01", "03-31"],
-	"Iran": ["06-23", "06-22"],
-	"Italy": ["07-01", "06-30"],
-	"Myanmar": ["04-01", "03-31"],
-	"New Zealand": ["04-01", "03-31"],
-	"Pakistan": ["07-01", "06-30"],
-	"Singapore": ["04-01", "03-31"],
-	"South Africa": ["03-01", "02-28"],
-	"Thailand": ["10-01", "09-30"],
-	"United Kingdom": ["04-01", "03-31"],
-}
+		items: {
+			icon: "icon-barcode",
+			"title": __("Your Products or Services"),
+			"help": __("List your products or services that you buy or sell. Make sure to check the Item Group, Unit of Measure and other properties when you start."),
+			"fields": [],
+			before_load: function(slide) {
+				slide.fields = [];
+				for(var i=1; i<6; i++) {
+					slide.fields = slide.fields.concat([
+						{fieldtype:"Section Break", show_section_border: true},
+						{fieldtype:"Data", fieldname:"item_" + i, label:__("Item") + " " + i,
+							placeholder:__("A Product or Service")},
+						{fieldtype:"Select", label:__("Group"), fieldname:"item_group_" + i,
+							options:[__("Products"), __("Services"),
+								__("Raw Material"), __("Consumable"), __("Sub Assemblies")],
+							"default": __("Products")},
+						{fieldtype:"Select", fieldname:"item_uom_" + i, label:__("UOM"),
+							options:[__("Unit"), __("Nos"), __("Box"), __("Pair"), __("Kg"), __("Set"),
+								__("Hour"), __("Minute")],
+							"default": __("Unit")},
+						{fieldtype: "Check", fieldname: "is_sales_item_" + i, label:__("We sell this Item"), default: 1},
+						{fieldtype: "Check", fieldname: "is_purchase_item_" + i, label:__("We buy this Item")},
+						{fieldtype:"Column Break"},
+						{fieldtype:"Currency", fieldname:"item_price_" + i, label:__("Rate")},
+						{fieldtype:"Attach Image", fieldname:"item_img_" + i, label:__("Attach Image")},
+					])
+				}
+				slide.fields[1].reqd = 1;
+
+				// dummy data
+				slide.fields.push({fieldtype: "Section Break"});
+				slide.fields.push({fieldtype: "Check", fieldname: "add_sample_data",
+					label: __("Add a few sample records"), "default": 1});
+			},
+			css_class: "two-column"
+		},
+	});
+
+	// Source: https://en.wikipedia.org/wiki/Fiscal_year
+	// default 1st Jan - 31st Dec
+
+	erpnext.wiz.fiscal_years = {
+		"Afghanistan": ["12-20", "12-21"],
+		"Australia": ["07-01", "06-30"],
+		"Bangladesh": ["07-01", "06-30"],
+		"Canada": ["04-01", "03-31"],
+		"Costa Rica": ["10-01", "09-30"],
+		"Egypt": ["07-01", "06-30"],
+		"Hong Kong": ["04-01", "03-31"],
+		"India": ["04-01", "03-31"],
+		"Iran": ["06-23", "06-22"],
+		"Italy": ["07-01", "06-30"],
+		"Myanmar": ["04-01", "03-31"],
+		"New Zealand": ["04-01", "03-31"],
+		"Pakistan": ["07-01", "06-30"],
+		"Singapore": ["04-01", "03-31"],
+		"South Africa": ["03-01", "02-28"],
+		"Thailand": ["10-01", "09-30"],
+		"United Kingdom": ["04-01", "03-31"],
+	};
+};
 
 frappe.wiz.on("before_load", function() {
+	load_erpnext_slides();
 	frappe.wiz.add_slide(erpnext.wiz.user);
 	frappe.wiz.add_slide(erpnext.wiz.org);
 	frappe.wiz.add_slide(erpnext.wiz.branding);
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 5926b25..56c8da0 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -56,13 +56,15 @@
 					cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry);
 				}
 
-				// stop
-				if(flt(doc.per_delivered, 2) < 100 || flt(doc.per_billed) < 100) {
-						cur_frm.add_custom_button(__('Stop'), this.stop_sales_order)
-					}
+				if (this.frm.has_perm("submit")) {
+					// stop
+					if(flt(doc.per_delivered, 2) < 100 || flt(doc.per_billed) < 100) {
+							cur_frm.add_custom_button(__('Stop'), this.stop_sales_order)
+						}
 
 
-				cur_frm.add_custom_button(__('Close'), this.close_sales_order)
+					cur_frm.add_custom_button(__('Close'), this.close_sales_order)
+				}
 
 				// maintenance
 				if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) {
@@ -82,8 +84,10 @@
 
 
 			} else {
-				// un-stop
-				cur_frm.add_custom_button(__('Re-open'), cur_frm.cscript['Unstop Sales Order']);
+				if (this.frm.has_perm("submit")) {
+					// un-stop
+					cur_frm.add_custom_button(__('Re-open'), cur_frm.cscript['Unstop Sales Order']);
+				}
 			}
 		}
 
diff --git a/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html b/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html
index 032eab9..5fe7a14 100644
--- a/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html
+++ b/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html
@@ -18,7 +18,7 @@
 
 			<br>
 			<hr>
-			<h3>Next Steps</h3>
+			<h3>{%= __("Next Steps") %}</h3>
 			<ul class="list-unstyled">
 				<li><a class="text-muted" href="#">{%= __("Go to the Desktop and start using ERPNext") %}</a></li>
 				<li><a class="text-muted" href="#Module/Learn">{%= __("View a list of all the help videos") %}</a></li>
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 9cd4936..4bef0d8 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -46,13 +46,14 @@
 			if (cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
 				this.show_general_ledger();
 			}
-
-			if(doc.status !== "Closed") {
-				cur_frm.add_custom_button(__("Close"), this.close_delivery_note)
+			if (this.frm.has_perm("submit") && (doc.status !== "Closed") 
+				&& this.frm.doc.__onload && this.frm.doc.__onload.has_return_entry) {
+					cur_frm.add_custom_button(__("Close"), this.close_delivery_note)
 			}
 		}
 
-		if(doc.__onload && !doc.__onload.billing_complete && doc.docstatus==1 && !doc.is_return && doc.status!="Closed") {
+		if(doc.__onload && !doc.__onload.billing_complete && doc.docstatus==1 
+				&& !doc.is_return && doc.status!="Closed") {
 			// show Make Invoice button only if Delivery Note is not created from Sales Invoice
 			var from_sales_invoice = false;
 			from_sales_invoice = cur_frm.doc.items.some(function(item) {
@@ -63,7 +64,7 @@
 				cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice).addClass("btn-primary");
 		}
 
-		if(doc.docstatus==1 && doc.status === "Closed") {
+		if(doc.docstatus==1 && doc.status === "Closed" && this.frm.has_perm("submit")) {
 			cur_frm.add_custom_button(__('Re-open'), this.reopen_delivery_note)
 		}
 		erpnext.stock.delivery_note.set_print_hide(doc, dt, dn);
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 6346c63..60cc430 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -69,7 +69,10 @@
 			where docstatus=1 and delivery_note=%s""", self.name)
 		if billed_qty:
 			total_qty = sum((item.qty for item in self.get("items")))
-			self.get("__onload").billing_complete = (billed_qty[0][0] == total_qty)
+			self.set_onload("billing_complete", (billed_qty[0][0] == total_qty))
+			
+		self.set_onload("has_return_entry", len(frappe.db.exists({"doctype": "Delivery Note", 
+			"is_return": 1, "return_against": self.name, "docstatus": 1})))
 
 	def before_print(self):
 		def toggle_print_hide(meta, fieldname):
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index a795de8..c02d9f1 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -105,7 +105,11 @@
 				frappe.local.message_log.pop()
 
 			except requests.exceptions.HTTPError:
-				frappe.msgprint(_("Warning: Invalid Attachment {0}").format(self.website_image))
+				frappe.msgprint(_("Warning: Invalid attachment {0}").format(self.website_image))
+				self.website_image = None
+
+			except requests.exceptions.SSLError:
+				frappe.msgprint(_("Warning: Invalid SSL certificate on attachment {0}").format(self.website_image))
 				self.website_image = None
 
 			# for CSV import
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index acf6809..af29cb8 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -57,14 +57,18 @@
 			if(this.frm.doc.docstatus == 1 && this.frm.doc.status!="Closed") {
 				cur_frm.add_custom_button(__('Return'), this.make_purchase_return);
 				if(this.frm.doc.__onload && !this.frm.doc.__onload.billing_complete) {
-					cur_frm.add_custom_button(__('Invoice'), this.make_purchase_invoice).addClass("btn-primary");
+					cur_frm.add_custom_button(__('Invoice'),
+						 this.make_purchase_invoice).addClass("btn-primary");
 				}
-				cur_frm.add_custom_button(__("Close"), this.close_purchase_receipt)
+				if (this.frm.has_perm("submit") && 
+					this.frm.doc.__onload && this.frm.doc.__onload.has_return_entry) {
+						cur_frm.add_custom_button(__("Close"), this.close_purchase_receipt)
+				}
 			}
 		}
 
 
-		if(this.frm.doc.docstatus==1 && this.frm.doc.status === "Closed") {
+		if(this.frm.doc.docstatus==1 && this.frm.doc.status === "Closed" && this.frm.has_perm("submit")) {
 			cur_frm.add_custom_button(__('Re-open'), this.reopen_purchase_receipt)
 		}
 
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index c1316f9..edd7be8 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -51,7 +51,10 @@
 			where purchase_receipt=%s and docstatus=1""", self.name)
 		if billed_qty:
 			total_qty = sum((item.qty for item in self.get("items")))
-			self.get("__onload").billing_complete = (billed_qty[0][0] == total_qty)
+			self.set_onload("billing_complete", (billed_qty[0][0] == total_qty))
+			
+		self.set_onload("has_return_entry", len(frappe.db.exists({"doctype": "Purchase Receipt", 
+			"is_return": 1, "return_against": self.name, "docstatus": 1})))
 
 	def validate(self):
 		super(PurchaseReceipt, self).validate()
diff --git a/erpnext/templates/includes/address_row.html b/erpnext/templates/includes/address_row.html
index fd287ad..717ca75 100644
--- a/erpnext/templates/includes/address_row.html
+++ b/erpnext/templates/includes/address_row.html
@@ -1,5 +1,5 @@
 <div class="web-list-item">
-    <a href="/addresses?name={{ doc.name }}" no-pjax class="no-decoration">
+    <a href="/addresses?name={{ doc.name | urlencode }}" no-pjax class="no-decoration">
         <h4 class="strong">{{ doc.address_title }}</h4>
         <p class="text-muted small">
             {{ frappe.get_doc(doc).get_display() }}
diff --git a/test_sites/apps.txt b/test_sites/apps.txt
index 3796729..ee64549 100644
--- a/test_sites/apps.txt
+++ b/test_sites/apps.txt
@@ -1 +1 @@
-erpnext
+erpnext
\ No newline at end of file
diff --git a/test_sites/languages.txt b/test_sites/languages.txt
index 0163b22..cf2b150 100644
--- a/test_sites/languages.txt
+++ b/test_sites/languages.txt
@@ -1 +1 @@
-en english
+en english
\ No newline at end of file
diff --git a/test_sites/test_site/site_config.json b/test_sites/test_site/site_config.json
index 7d1194a..48b330b 100644
--- a/test_sites/test_site/site_config.json
+++ b/test_sites/test_site/site_config.json
@@ -9,4 +9,4 @@
  "run_selenium_tests": 1,
  "host_name": "http://localhost:8000",
  "install_apps": ["erpnext"]
-}
+}
\ No newline at end of file