Merge pull request #19913 from nextchamp-saqib/cart-address-fix

fix: enable adding of address without enabling checkout feature
diff --git a/README.md b/README.md
index 64f8d67..ed57a17 100644
--- a/README.md
+++ b/README.md
@@ -13,9 +13,26 @@
 
 </div>
 
-Includes: Accounting, Inventory, Manufacturing, CRM, Sales, Purchase, Project Management, HRMS. Requires MariaDB.
+ERPNext as a monolith includes the following areas for managing businesses:
 
-ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a full-stack web app framework in Python & JavaScript.
+1. [Accounting](https://erpnext.com/docs/user/manual/en/accounts)
+1. [Inventory](https://erpnext.com/docs/user/manual/en/stock)
+1. [CRM](https://erpnext.com/docs/user/manual/en/CRM)
+1. [Sales](https://erpnext.com/docs/user/manual/en/selling)
+1. [Purchase](https://erpnext.com/docs/user/manual/en/buying)
+1. [HRMS](https://erpnext.com/docs/user/manual/en/human-resources)
+1. [Project Management](https://erpnext.com/docs/user/manual/en/projects)
+1. [Support](https://erpnext.com/docs/user/manual/en/support)
+1. [Asset Management](https://erpnext.com/docs/user/manual/en/asset)
+1. [Quality Management](https://erpnext.com/docs/user/manual/en/quality-management)
+1. [Manufacturing](https://erpnext.com/docs/user/manual/en/manufacturing)
+1. [Website Management](https://erpnext.com/docs/user/manual/en/website)
+1. [Customize ERPNext](https://erpnext.com/docs/user/manual/en/customize-erpnext)
+1. [And More](https://erpnext.com/docs/user/manual/en/)
+
+ERPNext requires MariaDB.
+
+ERPNext is built on the [Frappe Framework](https://github.com/frappe/frappe), a full-stack web app framework built with Python & JavaScript.
 
 - [User Guide](https://erpnext.com/docs/user)
 - [Discussion Forum](https://discuss.erpnext.com/)
diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py
index deedafd..33ae454 100644
--- a/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py
+++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py
@@ -15,8 +15,8 @@
 		with open(frappe.uploaded_file, "rb") as upfile:
 			fcontent = upfile.read()
 	else:
-		from frappe.utils.file_manager import get_uploaded_content
-		fname, fcontent = get_uploaded_content()
+		fcontent = frappe.local.uploaded_file
+		fname = frappe.local.uploaded_filename
 
 	if frappe.safe_encode(fname).lower().endswith("csv".encode('utf-8')):
 		from frappe.utils.csvutils import read_csv_content
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index 078e058..041e419 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -29,7 +29,6 @@
 		self.validate_and_set_fiscal_year()
 		self.pl_must_have_cost_center()
 		self.validate_cost_center()
-		self.validate_dimensions_for_pl_and_bs()
 
 		if not self.flags.from_repost:
 			self.check_pl_account()
@@ -39,6 +38,7 @@
 	def on_update_with_args(self, adv_adj, update_outstanding = 'Yes', from_repost=False):
 		if not from_repost:
 			self.validate_account_details(adv_adj)
+			self.validate_dimensions_for_pl_and_bs()
 			check_freezing_date(self.posting_date, adv_adj)
 
 		validate_frozen_account(self.account, adv_adj)
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index d6236cd..3604b60 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -190,7 +190,6 @@
 			if(jvd.reference_type==="Employee Advance") {
 				return {
 					filters: {
-						'status': ['=', 'Unpaid'],
 						'docstatus': 1
 					}
 				};
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index e25942c..8897337 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -968,7 +968,7 @@
 
 		# The date used to retreive the exchange rate here is the date passed
 		# in as an argument to this function.
-		elif (not exchange_rate or exchange_rate==1) and account_currency and posting_date:
+		elif (not exchange_rate or flt(exchange_rate)==1) and account_currency and posting_date:
 			exchange_rate = get_exchange_rate(account_currency, company_currency, posting_date)
 	else:
 		exchange_rate = 1
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index adf47ed..2192b7b 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -652,14 +652,16 @@
 						(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student")
 					) {
 						if(total_positive_outstanding > total_negative_outstanding)
-							frm.set_value("paid_amount",
-								total_positive_outstanding - total_negative_outstanding);
+							if (!frm.doc.paid_amount)
+								frm.set_value("paid_amount",
+									total_positive_outstanding - total_negative_outstanding);
 					} else if (
 						total_negative_outstanding &&
 						total_positive_outstanding < total_negative_outstanding
 					) {
-						frm.set_value("received_amount",
-							total_negative_outstanding - total_positive_outstanding);
+						if (!frm.doc.received_amount)
+							frm.set_value("received_amount",
+								total_negative_outstanding - total_positive_outstanding);
 					}
 				}
 
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
index 971d308..29d8378 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
@@ -389,8 +389,7 @@
    "fieldname": "rate_or_discount",
    "fieldtype": "Select",
    "label": "Rate or Discount",
-   "options": "\nRate\nDiscount Percentage\nDiscount Amount",
-   "reqd": 1
+   "options": "\nRate\nDiscount Percentage\nDiscount Amount"
   },
   {
    "default": "Grand Total",
@@ -439,19 +438,20 @@
   },
   {
    "default": "0",
-   "depends_on": "eval:!doc.mixed_conditions",
+   "depends_on": "eval:!doc.mixed_conditions && doc.apply_on != 'Transaction'",
    "fieldname": "same_item",
    "fieldtype": "Check",
    "label": "Same Item"
   },
   {
-   "depends_on": "eval:!doc.same_item || doc.mixed_conditions",
+   "depends_on": "eval:(!doc.same_item || doc.apply_on == 'Transaction') || doc.mixed_conditions",
    "fieldname": "free_item",
    "fieldtype": "Link",
    "label": "Free Item",
    "options": "Item"
   },
   {
+   "default": "0",
    "fieldname": "free_qty",
    "fieldtype": "Float",
    "label": "Qty"
@@ -554,7 +554,7 @@
  ],
  "icon": "fa fa-gift",
  "idx": 1,
- "modified": "2019-10-15 12:39:40.399792",
+ "modified": "2019-12-18 17:29:22.957077",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Pricing Rule",
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index e871d98..3c14819 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -47,6 +47,9 @@
 		if tocheck and not self.get(tocheck):
 			throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError)
 
+		if self.price_or_product_discount == 'Price' and not self.rate_or_discount:
+			throw(_("Rate or Discount is required for the price discount."), frappe.MandatoryError)
+
 	def validate_applicable_for_selling_or_buying(self):
 		if not self.selling and not self.buying:
 			throw(_("Atleast one of the Selling or Buying must be selected"))
@@ -182,7 +185,7 @@
 
 def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=False):
 	from erpnext.accounts.doctype.pricing_rule.utils import (get_pricing_rules,
-		get_applied_pricing_rules, get_pricing_rule_items)
+		get_applied_pricing_rules, get_pricing_rule_items, get_product_discount_rule)
 
 	if isinstance(doc, string_types):
 		doc = json.loads(doc)
@@ -241,9 +244,11 @@
 			if pricing_rule.coupon_code_based==1 and args.coupon_code==None:
 				return item_details
 				
-			if (not pricing_rule.validate_applied_rule and
-				pricing_rule.price_or_product_discount == "Price"):
-				apply_price_discount_pricing_rule(pricing_rule, item_details, args)
+			if not pricing_rule.validate_applied_rule:
+				if pricing_rule.price_or_product_discount == "Price":
+					apply_price_discount_rule(pricing_rule, item_details, args)
+				else:
+					get_product_discount_rule(pricing_rule, item_details, doc)
 
 		item_details.has_pricing_rule = 1
 
@@ -293,7 +298,7 @@
 		'child_docname': args.get('child_docname')
 	})
 
-def apply_price_discount_pricing_rule(pricing_rule, item_details, args):
+def apply_price_discount_rule(pricing_rule, item_details, args):
 	item_details.pricing_rule_for = pricing_rule.rate_or_discount
 
 	if ((pricing_rule.margin_type == 'Amount' and pricing_rule.currency == args.currency)
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 637e503..87f6822 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -7,7 +7,7 @@
 import frappe, copy, json
 from frappe import throw, _
 from six import string_types
-from frappe.utils import flt, cint, get_datetime
+from frappe.utils import flt, cint, get_datetime, get_link_to_form, today
 from erpnext.setup.doctype.item_group.item_group import get_child_item_groups
 from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
 from erpnext.stock.get_item_details import get_conversion_factor
@@ -284,7 +284,7 @@
 			status = True
 
 		# if user has created item price against the transaction UOM
-		if rule.get("uom") == args.get("uom"):
+		if args and rule.get("uom") == args.get("uom"):
 			conversion_factor = 1.0
 
 		if status and (flt(rate) >= (flt(rule.min_amt) * conversion_factor)
@@ -408,7 +408,8 @@
 	conditions = get_other_conditions(conditions, values, doc)
 
 	pricing_rules = frappe.db.sql(""" Select `tabPricing Rule`.* from `tabPricing Rule`
-		where {conditions} """.format(conditions = conditions), values, as_dict=1)
+		where  {conditions} and `tabPricing Rule`.disable = 0
+	""".format(conditions = conditions), values, as_dict=1)
 
 	if pricing_rules:
 		pricing_rules = filter_pricing_rules_for_qty_amount(doc.total_qty,
@@ -420,39 +421,65 @@
 					doc.set('apply_discount_on', d.apply_discount_on)
 
 				for field in ['additional_discount_percentage', 'discount_amount']:
-					if not d.get(field): continue
-
 					pr_field = ('discount_percentage'
 						if field == 'additional_discount_percentage' else field)
 
+					if not d.get(pr_field): continue
+
 					if d.validate_applied_rule and doc.get(field) < d.get(pr_field):
 						frappe.msgprint(_("User has not applied rule on the invoice {0}")
 							.format(doc.name))
 					else:
 						doc.set(field, d.get(pr_field))
+
+				doc.calculate_taxes_and_totals()
 			elif d.price_or_product_discount == 'Product':
-				apply_pricing_rule_for_free_items(doc, d)
+				item_details = frappe._dict({'parenttype': doc.doctype})
+				get_product_discount_rule(d, item_details, doc)
+				apply_pricing_rule_for_free_items(doc, item_details.free_item_data)
+				doc.set_missing_values()
 
 def get_applied_pricing_rules(item_row):
 	return (item_row.get("pricing_rules").split(',')
 		if item_row.get("pricing_rules") else [])
 
-def apply_pricing_rule_for_free_items(doc, pricing_rule):
-	if pricing_rule.get('free_item'):
+def get_product_discount_rule(pricing_rule, item_details, doc=None):
+	free_item = (pricing_rule.free_item
+		if not pricing_rule.same_item or pricing_rule.apply_on == 'Transaction' else item_details.item_code)
+
+	if not free_item:
+		frappe.throw(_("Free item not set in the pricing rule {0}")
+			.format(get_link_to_form("Pricing Rule", pricing_rule.name)))
+
+	item_details.free_item_data = {
+		'item_code': free_item,
+		'qty': pricing_rule.free_qty or 1,
+		'rate': pricing_rule.free_item_rate or 0,
+		'price_list_rate': pricing_rule.free_item_rate or 0,
+		'is_free_item': 1
+	}
+
+	item_data = frappe.get_cached_value('Item', free_item, ['item_name',
+		'description', 'stock_uom'], as_dict=1)
+
+	item_details.free_item_data.update(item_data)
+	item_details.free_item_data['uom'] = pricing_rule.free_item_uom or item_data.stock_uom
+	item_details.free_item_data['conversion_factor'] = get_conversion_factor(free_item, 
+		item_details.free_item_data['uom']).get("conversion_factor", 1)
+
+	if item_details.get("parenttype") == 'Purchase Order':
+		item_details.free_item_data['schedule_date'] = doc.schedule_date if doc else today()
+
+	if item_details.get("parenttype") == 'Sales Order':
+		item_details.free_item_data['delivery_date'] = doc.delivery_date if doc else today()
+
+def apply_pricing_rule_for_free_items(doc, pricing_rule_args, set_missing_values=False):
+	if pricing_rule_args.get('item_code'):
 		items = [d.item_code for d in doc.items
-			if d.item_code == (d.item_code
-			if pricing_rule.get('same_item') else pricing_rule.get('free_item')) and d.is_free_item]
+			if d.item_code == (pricing_rule_args.get("item_code")) and d.is_free_item]
 
 		if not items:
-			doc.append('items', {
-				'item_code': pricing_rule.get('free_item'),
-				'qty': pricing_rule.get('free_qty'),
-				'uom': pricing_rule.get('free_item_uom'),
-				'rate': pricing_rule.get('free_item_rate') or 0,
-				'is_free_item': 1
-			})
-
-			doc.set_missing_values()
+			doc.append('items', pricing_rule_args)
 
 def get_pricing_rule_items(pr_doc):
 	apply_on_data = []
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index d7e64cf..643de7d 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -382,21 +382,11 @@
 
 cur_frm.fields_dict['credit_to'].get_query = function(doc) {
 	// filter on Account
-	if (doc.supplier) {
-		return {
-			filters: {
-				'account_type': 'Payable',
-				'is_group': 0,
-				'company': doc.company
-			}
-		}
-	} else {
-		return {
-			filters: {
-				'report_type': 'Balance Sheet',
-				'is_group': 0,
-				'company': doc.company
-			}
+	return {
+		filters: {
+			'account_type': 'Payable',
+			'is_group': 0,
+			'company': doc.company
 		}
 	}
 }
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 6fe1811..3715d77 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "autoname": "naming_series:",
  "creation": "2013-05-21 16:16:39",
@@ -417,6 +418,7 @@
    "fieldname": "contact_email",
    "fieldtype": "Small Text",
    "label": "Contact Email",
+   "options": "Email",
    "print_hide": 1,
    "read_only": 1
   },
@@ -1287,7 +1289,8 @@
  "icon": "fa fa-file-text",
  "idx": 204,
  "is_submittable": 1,
- "modified": "2019-09-17 22:31:42.666601",
+ "links": [],
+ "modified": "2019-12-24 12:51:58.613538",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 7f4ae3c..db6ac55 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -556,22 +556,11 @@
 }
 
 cur_frm.set_query("debit_to", function(doc) {
-	// filter on Account
-	if (doc.customer) {
-		return {
-			filters: {
-				'account_type': 'Receivable',
-				'is_group': 0,
-				'company': doc.company
-			}
-		}
-	} else {
-		return {
-			filters: {
-				'report_type': 'Balance Sheet',
-				'is_group': 0,
-				'company': doc.company
-			}
+	return {
+		filters: {
+			'account_type': 'Receivable',
+			'is_group': 0,
+			'company': doc.company
 		}
 	}
 });
diff --git a/erpnext/accounts/doctype/share_transfer/share_transfer.json b/erpnext/accounts/doctype/share_transfer/share_transfer.json
index f17bf04..59a3053 100644
--- a/erpnext/accounts/doctype/share_transfer/share_transfer.json
+++ b/erpnext/accounts/doctype/share_transfer/share_transfer.json
@@ -188,7 +188,7 @@
   }
  ],
  "is_submittable": 1,
- "modified": "2019-11-07 13:31:17.999744",
+ "modified": "2019-12-20 14:48:01.990600",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Share Transfer",
@@ -196,6 +196,7 @@
  "permissions": [
   {
    "amend": 1,
+   "cancel": 1,
    "create": 1,
    "delete": 1,
    "email": 1,
@@ -221,6 +222,7 @@
    "write": 1
   },
   {
+   "cancel": 1,
    "create": 1,
    "delete": 1,
    "email": 1,
@@ -230,6 +232,7 @@
    "report": 1,
    "role": "Accounts Manager",
    "share": 1,
+   "submit": 1,
    "write": 1
   }
  ],
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index feb598a..bb1b7e3 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -90,8 +90,12 @@
 		else:
 			merged_gl_map.append(entry)
 
+	company = gl_map[0].company if gl_map else erpnext.get_default_company()
+	company_currency = erpnext.get_company_currency(company)
+	precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"), company_currency)
+
 	# filter zero debit and credit entries
-	merged_gl_map = filter(lambda x: flt(x.debit, 9)!=0 or flt(x.credit, 9)!=0, merged_gl_map)
+	merged_gl_map = filter(lambda x: flt(x.debit, precision)!=0 or flt(x.credit, precision)!=0, merged_gl_map)
 	merged_gl_map = list(merged_gl_map)
 
 	return merged_gl_map
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 2c53f6e..f82146a 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -171,7 +171,7 @@
 			row.outstanding = flt(row.invoiced - row.paid - row.credit_note, self.currency_precision)
 			row.invoice_grand_total = row.invoiced
 
-			if abs(row.outstanding) > 0.1/10 ** self.currency_precision:
+			if abs(row.outstanding) > 1.0/10 ** self.currency_precision:
 				# non-zero oustanding, we must consider this row
 
 				if self.is_invoice(row) and self.filters.based_on_payment_terms:
@@ -285,7 +285,7 @@
 
 	def set_party_details(self, row):
 		# customer / supplier name
-		party_details = self.get_party_details(row.party)
+		party_details = self.get_party_details(row.party) or {}
 		row.update(party_details)
 		if self.filters.get(scrub(self.filters.party_type)):
 			row.currency = row.account_currency
diff --git a/erpnext/accounts/report/budget_variance_report/budget_variance_report.js b/erpnext/accounts/report/budget_variance_report/budget_variance_report.js
index 2451187..3ec4d30 100644
--- a/erpnext/accounts/report/budget_variance_report/budget_variance_report.js
+++ b/erpnext/accounts/report/budget_variance_report/budget_variance_report.js
@@ -46,13 +46,24 @@
 			fieldtype: "Select",
 			options: ["Cost Center", "Project"],
 			default: "Cost Center",
-			reqd: 1
+			reqd: 1,
+			on_change: function() {
+				frappe.query_report.set_filter_value("budget_against_filter", []);
+				frappe.query_report.refresh();
+			}
 		},
 		{
-			fieldname: "cost_center",
-			label: __("Cost Center"),
-			fieldtype: "Link",
-			options: "Cost Center"
+			fieldname:"budget_against_filter",
+			label: __('Dimension Filter'),
+			fieldtype: "MultiSelectList",
+			get_data: function(txt) {
+				if (!frappe.query_report.filters) return;
+
+				let budget_against = frappe.query_report.get_filter_value('budget_against');
+				if (!budget_against) return;
+
+				return frappe.db.get_link_options(budget_against, txt);
+			}
 		},
 		{
 			fieldname:"show_cumulative",
diff --git a/erpnext/accounts/report/budget_variance_report/budget_variance_report.py b/erpnext/accounts/report/budget_variance_report/budget_variance_report.py
index 8d65ac8..39e218b 100644
--- a/erpnext/accounts/report/budget_variance_report/budget_variance_report.py
+++ b/erpnext/accounts/report/budget_variance_report/budget_variance_report.py
@@ -12,22 +12,22 @@
 from pprint import pprint
 def execute(filters=None):
 	if not filters: filters = {}
-	validate_filters(filters)
+
 	columns = get_columns(filters)
-	if filters.get("cost_center"):
-		cost_centers = [filters.get("cost_center")]
+	if filters.get("budget_against_filter"):
+		dimensions = filters.get("budget_against_filter")
 	else:
-		cost_centers = get_cost_centers(filters)
+		dimensions = get_cost_centers(filters)
 
 	period_month_ranges = get_period_month_ranges(filters["period"], filters["from_fiscal_year"])
-	cam_map = get_cost_center_account_month_map(filters)
+	cam_map = get_dimension_account_month_map(filters)
 
 	data = []
-	for cost_center in cost_centers:
-		cost_center_items = cam_map.get(cost_center)
-		if cost_center_items:
-			for account, monthwise_data in iteritems(cost_center_items):
-				row = [cost_center, account]
+	for dimension in dimensions:
+		dimension_items = cam_map.get(dimension)
+		if dimension_items:
+			for account, monthwise_data in iteritems(dimension_items):
+				row = [dimension, account]
 				totals = [0, 0, 0]
 				for year in get_fiscal_years(filters):
 					last_total = 0
@@ -55,10 +55,6 @@
 
 	return columns, data
 
-def validate_filters(filters):
-	if filters.get("budget_against") != "Cost Center" and filters.get("cost_center"):
-		frappe.throw(_("Filter based on Cost Center is only applicable if Budget Against is selected as Cost Center"))
-
 def get_columns(filters):
 	columns = [_(filters.get("budget_against")) + ":Link/%s:150"%(filters.get("budget_against")), _("Account") + ":Link/Account:150"]
 
@@ -98,11 +94,12 @@
 	else:
 		return frappe.db.sql_list("""select name from `tab{tab}`""".format(tab=filters.get("budget_against"))) #nosec
 
-#Get cost center & target details
-def get_cost_center_target_details(filters):
+#Get dimension & target details
+def get_dimension_target_details(filters):
 	cond = ""
-	if filters.get("cost_center"):
-		cond += " and b.cost_center=%s" % frappe.db.escape(filters.get("cost_center"))
+	if filters.get("budget_against_filter"):
+		cond += " and b.{budget_against} in (%s)".format(budget_against = \
+			frappe.scrub(filters.get('budget_against'))) % ', '.join(['%s']* len(filters.get('budget_against_filter')))
 
 	return frappe.db.sql("""
 			select b.{budget_against} as budget_against, b.monthly_distribution, ba.account, ba.budget_amount,b.fiscal_year
@@ -110,8 +107,8 @@
 			where b.name=ba.parent and b.docstatus = 1 and b.fiscal_year between %s and %s
 			and b.budget_against = %s and b.company=%s {cond} order by b.fiscal_year
 		""".format(budget_against=filters.get("budget_against").replace(" ", "_").lower(), cond=cond),
-		(filters.from_fiscal_year,filters.to_fiscal_year,filters.budget_against, filters.company), as_dict=True)
-
+		tuple([filters.from_fiscal_year,filters.to_fiscal_year,filters.budget_against, filters.company] + filters.get('budget_against_filter')), 
+		as_dict=True)
 
 
 #Get target distribution details of accounts of cost center
@@ -153,14 +150,14 @@
 
 	return cc_actual_details
 
-def get_cost_center_account_month_map(filters):
+def get_dimension_account_month_map(filters):
 	import datetime
-	cost_center_target_details = get_cost_center_target_details(filters)
+	dimension_target_details = get_dimension_target_details(filters)
 	tdd = get_target_distribution_details(filters)
 
 	cam_map = {}
 
-	for ccd in cost_center_target_details:
+	for ccd in dimension_target_details:
 		actual_details = get_actual_details(ccd.budget_against, filters)
 
 		for month_id in range(1, 13):
diff --git a/erpnext/accounts/report/financial_statements.html b/erpnext/accounts/report/financial_statements.html
index 4081723..50947ec 100644
--- a/erpnext/accounts/report/financial_statements.html
+++ b/erpnext/accounts/report/financial_statements.html
@@ -1,5 +1,6 @@
 {%
 	var report_columns = report.get_columns_for_print();
+	report_columns = report_columns.filter(col => !col.hidden);
 
 	if (report_columns.length > 8) {
 		frappe.throw(__("Too many columns. Export the report and print it using a spreadsheet application."));
@@ -15,34 +16,35 @@
 		height: 37px;
 	}
 </style>
-{% var letterhead= filters.letter_head || (frappe.get_doc(":Company", filters.company) && frappe.get_doc(":Company", filters.company).default_letter_head) %}
-{% if(letterhead) { %}
-<div style="margin-bottom: 7px;" class="text-center">
-	{%= frappe.boot.letter_heads[letterhead].header %}
-</div>
-{% } %}
+
 <h2 class="text-center">{%= __(report.report_name) %}</h2>
 <h3 class="text-center">{%= filters.company %}</h3>
+
 {% if 'cost_center' in filters %}
 	<h3 class="text-center">{%= filters.cost_center %}</h3>
 {% endif %}
+
 <h3 class="text-center">{%= filters.fiscal_year %}</h3>
-<h5 class="text-center">{%=  __("Currency") %} : {%= filters.presentation_currency || erpnext.get_currency(filters.company) %} </h4>
+<h5 class="text-center">
+	{%=  __("Currency") %} : {%= filters.presentation_currency || erpnext.get_currency(filters.company) %}
+</h5>
 {% if (filters.from_date) { %}
-	<h4 class="text-center">{%= frappe.datetime.str_to_user(filters.from_date) %} - {%= frappe.datetime.str_to_user(filters.to_date) %}</h3>
+	<h5 class="text-center">
+		{%= frappe.datetime.str_to_user(filters.from_date) %} - {%= frappe.datetime.str_to_user(filters.to_date) %}
+	</h5>
 {% } %}
 <hr>
 <table class="table table-bordered">
 	<thead>
 		<tr>
-			<th style="width: {%= 100 - (report_columns.length - 2) * 13 %}%"></th>
-			{% for(var i=2, l=report_columns.length; i<l; i++) { %}
+			<th style="width: {%= 100 - (report_columns.length - 1) * 13 %}%"></th>
+			{% for (let i=1, l=report_columns.length; i<l; i++) { %}
 				<th class="text-right">{%= report_columns[i].label %}</th>
 			{% } %}
 		</tr>
 	</thead>
 	<tbody>
-		{% for(var j=0, k=data.length-1; j<k; j++) { %}
+		{% for(let j=0, k=data.length-1; j<k; j++) { %}
 			{%
 				var row = data[j];
 				var row_class = data[j].parent_account ? "" : "financial-statements-important";
@@ -52,11 +54,11 @@
 				<td>
 					<span style="padding-left: {%= cint(data[j].indent) * 2 %}em">{%= row.account_name %}</span>
 				</td>
-				{% for(var i=2, l=report_columns.length; i<l; i++) { %}
+				{% for(let i=1, l=report_columns.length; i<l; i++) { %}
 					<td class="text-right">
-						{% var fieldname = report_columns[i].fieldname; %}
+						{% const fieldname = report_columns[i].fieldname; %}
 						{% if (!is_null(row[fieldname])) { %}
-							{%= format_currency(row[fieldname], filters.presentation_currency) %}
+							{%= frappe.format(row[fieldname], report_columns[i], {}, row) %}
 						{% } %}
 					</td>
 				{% } %}
@@ -64,4 +66,6 @@
 		{% } %}
 	</tbody>
 </table>
-<p class="text-right text-muted">Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}</p>
+<p class="text-right text-muted">
+	Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}
+</p>
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 3c8de60..40d5682 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -264,8 +264,8 @@
 
 def add_total_row(out, root_type, balance_must_be, period_list, company_currency):
 	total_row = {
-		"account_name": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
-		"account": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
+		"account_name": _("Total {0} ({1})").format(_(root_type), _(balance_must_be)),
+		"account": _("Total {0} ({1})").format(_(root_type), _(balance_must_be)),
 		"currency": company_currency
 	}
 
diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py
index 0e2821a..afdd31d 100644
--- a/erpnext/accounts/report/sales_register/sales_register.py
+++ b/erpnext/accounts/report/sales_register/sales_register.py
@@ -38,32 +38,46 @@
 		cost_center = list(set(invoice_cc_wh_map.get(inv.name, {}).get("cost_center", [])))
 		warehouse = list(set(invoice_cc_wh_map.get(inv.name, {}).get("warehouse", [])))
 
-		row = [
-			inv.name, inv.posting_date, inv.customer, inv.customer_name
-		]
+		row = {
+			'invoice': inv.name,
+			'posting_date': inv.posting_date,
+			'customer': inv.customer,
+			'customer_name': inv.customer_name
+		}
 
 		if additional_query_columns:
 			for col in additional_query_columns:
-				row.append(inv.get(col))
+				row.update({
+					col: inv.get(col)
+				})
 
-		row +=[
-			inv.get("customer_group"),
-			inv.get("territory"),
-			inv.get("tax_id"),
-			inv.debit_to, ", ".join(mode_of_payments.get(inv.name, [])),
-			inv.project, inv.owner, inv.remarks,
-			", ".join(sales_order), ", ".join(delivery_note),", ".join(cost_center),
-			", ".join(warehouse), company_currency
-		]
+		row.update({
+			'customer_group': inv.get("customer_group"),
+			'territory': inv.get("territory"),
+			'tax_id': inv.get("tax_id"),
+			'receivable_account': inv.debit_to,
+			'mode_of_payment':  ", ".join(mode_of_payments.get(inv.name, [])),
+			'project': inv.project,
+			'owner': inv.owner,
+			'remarks': inv.remarks,
+			'sales_order': ", ".join(sales_order),
+			'delivery_note': ", ".join(delivery_note),
+			'cost_center': ", ".join(cost_center),
+			'warehouse': ", ".join(warehouse),
+			'currency': company_currency
+		})
+
 		# map income values
 		base_net_total = 0
 		for income_acc in income_accounts:
 			income_amount = flt(invoice_income_map.get(inv.name, {}).get(income_acc))
 			base_net_total += income_amount
-			row.append(income_amount)
+			row.update({
+				frappe.scrub(income_acc): income_amount
+			})
 
 		# net total
-		row.append(base_net_total or inv.base_net_total)
+		row.update({'net_total': base_net_total or inv.base_net_total})
 
 		# tax account
 		total_tax = 0
@@ -72,10 +86,18 @@
 				tax_amount_precision = get_field_precision(frappe.get_meta("Sales Taxes and Charges").get_field("tax_amount"), currency=company_currency) or 2
 				tax_amount = flt(invoice_tax_map.get(inv.name, {}).get(tax_acc), tax_amount_precision)
 				total_tax += tax_amount
-				row.append(tax_amount)
+				row.update({
+					frappe.scrub(tax_acc): tax_amount
+				})
 
 		# total tax, grand total, outstanding amount & rounded total
-		row += [total_tax, inv.base_grand_total, inv.base_rounded_total, inv.outstanding_amount]
+
+		row.update({
+			'tax_total': total_tax,
+			'grand_total': inv.base_grand_total,
+			'rounded_total': inv.base_rounded_total,
+			'outstanding_amount': inv.outstanding_amount
+		})
 
 		data.append(row)
 
@@ -84,19 +106,118 @@
 def get_columns(invoice_list, additional_table_columns):
 	"""return columns based on filters"""
 	columns = [
-		_("Invoice") + ":Link/Sales Invoice:120", _("Posting Date") + ":Date:80",
-		_("Customer") + ":Link/Customer:120", _("Customer Name") + "::120"
+		{
+			'label': _("Invoice"),
+			'fieldname': 'invoice',
+			'fieldtype': 'Link',
+			'options': 'Sales Invoice',
+			'width': 120
+		},
+		{
+			'label': _("Posting Date"),
+			'fieldname': 'posting_date',
+			'fieldtype': 'Date',
+			'width': 80
+		},
+		{
+			'label': _("Customer"),
+			'fieldname': 'customer',
+			'fieldtype': 'Link',
+			'options': 'Customer',
+			'width': 120
+		},
+		{
+			'label': _("Customer Name"),
+			'fieldname': 'customer_name',
+			'fieldtype': 'Data',
+			'width': 120
+		},
 	]
 
 	if additional_table_columns:
 		columns += additional_table_columns
 
 	columns +=[
-		_("Customer Group") + ":Link/Customer Group:120", _("Territory") + ":Link/Territory:80",
-		_("Tax Id") + "::80", _("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + "::120",
-		_("Project") +":Link/Project:80", _("Owner") + "::150", _("Remarks") + "::150",
-		_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
-		_("Cost Center") + ":Link/Cost Center:100", _("Warehouse") + ":Link/Warehouse:100",
+		{
+			'label': _("Custmer Group"),
+			'fieldname': 'customer_group',
+			'fieldtype': 'Link',
+			'options': 'Customer Group',
+			'width': 120
+		},
+		{
+			'label': _("Territory"),
+			'fieldname': 'territory',
+			'fieldtype': 'Link',
+			'options': 'Territory',
+			'width': 80
+		},
+		{
+			'label': _("Tax Id"),
+			'fieldname': 'tax_id',
+			'fieldtype': 'Data',
+			'width': 120
+		},
+		{
+			'label': _("Receivable Account"),
+			'fieldname': 'receivable_account',
+			'fieldtype': 'Link',
+			'options': 'Account',
+			'width': 80
+		},
+		{
+			'label': _("Mode Of Payment"),
+			'fieldname': 'mode_of_payment',
+			'fieldtype': 'Data',
+			'width': 120
+		},
+		{
+			'label': _("Project"),
+			'fieldname': 'project',
+			'fieldtype': 'Link',
+			'options': 'project',
+			'width': 80
+		},
+		{
+			'label': _("Owner"),
+			'fieldname': 'owner',
+			'fieldtype': 'Data',
+			'width': 150
+		},
+		{
+			'label': _("Remarks"),
+			'fieldname': 'remarks',
+			'fieldtype': 'Data',
+			'width': 150
+		},
+		{
+			'label': _("Sales Order"),
+			'fieldname': 'sales_order',
+			'fieldtype': 'Link',
+			'options': 'Sales Order',
+			'width': 100
+		},
+		{
+			'label': _("Delivery Note"),
+			'fieldname': 'delivery_note',
+			'fieldtype': 'Link',
+			'options': 'Delivery Note',
+			'width': 100
+		},
+		{
+			'label': _("Cost Center"),
+			'fieldname': 'cost_center',
+			'fieldtype': 'Link',
+			'options': 'Cost Center',
+			'width': 100
+		},
+		{
+			'label': _("Warehouse"),
+			'fieldname': 'warehouse',
+			'fieldtype': 'Link',
+			'options': 'Warehouse',
+			'width': 100
+		},
 		{
 			"fieldname": "currency",
 			"label": _("Currency"),
@@ -105,7 +226,10 @@
 		}
 	]
 
-	income_accounts = tax_accounts = income_columns = tax_columns = []
+	income_accounts = []
+	tax_accounts = []
+	income_columns = []
+	tax_columns = []
 
 	if invoice_list:
 		income_accounts = frappe.db.sql_list("""select distinct income_account
@@ -119,14 +243,65 @@
 			and parent in (%s) order by account_head""" %
 			', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]))
 
-	income_columns = [(account + ":Currency/currency:120") for account in income_accounts]
+	for account in income_accounts:
+		income_columns.append({
+			"label": account,
+			"fieldname": frappe.scrub(account),
+			"fieldtype": "Currency",
+			"options": 'currency',
+			"width": 120
+		})
+
 	for account in tax_accounts:
 		if account not in income_accounts:
-			tax_columns.append(account + ":Currency/currency:120")
+			tax_columns.append({
+				"label": account,
+				"fieldname": frappe.scrub(account),
+				"fieldtype": "Currency",
+				"options": 'currency',
+				"width": 120
+			})
 
-	columns = columns + income_columns + [_("Net Total") + ":Currency/currency:120"] + tax_columns + \
-		[_("Total Tax") + ":Currency/currency:120", _("Grand Total") + ":Currency/currency:120",
-		_("Rounded Total") + ":Currency/currency:120", _("Outstanding Amount") + ":Currency/currency:120"]
+	net_total_column = [{
+		"label": _("Net Total"),
+		"fieldname": "net_total",
+		"fieldtype": "Currency",
+		"options": 'currency',
+		"width": 120
+	}]
+
+	total_columns = [
+		{
+			"label": _("Tax Total"),
+			"fieldname": "tax_total",
+			"fieldtype": "Currency",
+			"options": 'currency',
+			"width": 120
+		},
+		{
+			"label": _("Grand Total"),
+			"fieldname": "grand_total",
+			"fieldtype": "Currency",
+			"options": 'currency',
+			"width": 120
+		},
+		{
+			"label": _("Rounded Total"),
+			"fieldname": "rounded_total",
+			"fieldtype": "Currency",
+			"options": 'currency',
+			"width": 120
+		},
+		{
+			"label": _("Outstanding Amount"),
+			"fieldname": "outstanding_amount",
+			"fieldtype": "Currency",
+			"options": 'currency',
+			"width": 120
+		}
+	]
+
+	columns = columns + income_columns + net_total_column + tax_columns + total_columns
 
 	return columns, income_accounts, tax_accounts
 
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index 6b3f2c7..f6a7fa2 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -144,6 +144,10 @@
 			frm.set_df_property('purchase_invoice', 'read_only', 1);
 			frm.set_df_property('purchase_receipt', 'read_only', 1);
 		}
+		else if (frm.doc.is_existing_asset) {
+			frm.toggle_reqd('purchase_receipt', 0);
+			frm.toggle_reqd('purchase_invoice', 0);
+		}
 		else if (frm.doc.purchase_receipt) {
 			// if purchase receipt link is set then set PI disabled
 			frm.toggle_reqd('purchase_invoice', 0);
@@ -256,6 +260,7 @@
 	},
 
 	is_existing_asset: function(frm) {
+		frm.trigger("toggle_reference_doc");
 		// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
 	},
 
diff --git a/erpnext/assets/doctype/asset_movement/asset_movement.py b/erpnext/assets/doctype/asset_movement/asset_movement.py
index 4e1822b..3a08baa 100644
--- a/erpnext/assets/doctype/asset_movement/asset_movement.py
+++ b/erpnext/assets/doctype/asset_movement/asset_movement.py
@@ -110,7 +110,7 @@
 				ORDER BY
 					asm.transaction_date asc
 				""", (d.asset, self.company, 'Receipt'), as_dict=1)
-			if auto_gen_movement_entry[0].get('name') == self.name:
+			if auto_gen_movement_entry and auto_gen_movement_entry[0].get('name') == self.name:
 				frappe.throw(_('{0} will be cancelled automatically on asset cancellation as it was \
 					auto generated for Asset {1}').format(self.name, d.asset))
 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index 5dce349..d4c5ace 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "autoname": "naming_series:",
  "creation": "2013-05-21 16:16:39",
@@ -47,6 +48,7 @@
   "ignore_pricing_rule",
   "sec_warehouse",
   "set_warehouse",
+  "set_reserve_warehouse",
   "col_break_warehouse",
   "is_subcontracted",
   "supplier_warehouse",
@@ -340,6 +342,7 @@
    "fieldname": "contact_email",
    "fieldtype": "Small Text",
    "label": "Contact Email",
+   "options": "Email",
    "print_hide": 1,
    "read_only": 1
   },
@@ -1039,12 +1042,20 @@
    "fieldtype": "Link",
    "label": "Tax Category",
    "options": "Tax Category"
+  },
+  {
+   "depends_on": "supplied_items",
+   "fieldname": "set_reserve_warehouse",
+   "fieldtype": "Link",
+   "label": "Set Reserve Warehouse",
+   "options": "Warehouse"
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 105,
  "is_submittable": 1,
- "modified": "2019-07-11 18:25:49.509343",
+ "links": [],
+ "modified": "2019-12-24 12:44:13.137194",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order",
diff --git a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
index 9e201e3..af109ba 100644
--- a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
+++ b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
@@ -138,7 +138,7 @@
 		# Check to see if any new scorecard periods are created
 		if make_all_scorecards(sc.name) > 0:
 			# Save the scorecard to update the score and standings
-			sc.save()
+			frappe.get_doc('Supplier Scorecard', sc.name).save()
 
 
 @frappe.whitelist()
diff --git a/erpnext/buying/onboarding_slide/add_a_few_suppliers/add_a_few_suppliers.json b/erpnext/buying/onboarding_slide/add_a_few_suppliers/add_a_few_suppliers.json
index d3adcb7..ce3d8cf 100644
--- a/erpnext/buying/onboarding_slide/add_a_few_suppliers/add_a_few_suppliers.json
+++ b/erpnext/buying/onboarding_slide/add_a_few_suppliers/add_a_few_suppliers.json
@@ -12,9 +12,10 @@
   }
  ],
  "idx": 0,
- "image_src": "/assets/erpnext/images/illustrations/supplier-onboard.png",
+ "image_src": "",
+ "is_completed": 0,
  "max_count": 3,
- "modified": "2019-12-03 22:53:50.552445",
+ "modified": "2019-12-09 17:54:18.452038",
  "modified_by": "Administrator",
  "name": "Add A Few Suppliers",
  "owner": "Administrator",
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 75564af..6150516 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -319,8 +319,8 @@
 					if item.get('discount_amount'):
 						item.rate = item.price_list_rate - item.discount_amount
 
-			elif pricing_rule_args.get('free_item'):
-				apply_pricing_rule_for_free_items(self, pricing_rule_args)
+			elif pricing_rule_args.get('free_item_data'):
+				apply_pricing_rule_for_free_items(self, pricing_rule_args.get('free_item_data'))
 
 		elif pricing_rule_args.get("validate_applied_rule"):
 			for pricing_rule in get_applied_pricing_rules(item):
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 3ec7aff..75b896b 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -265,16 +265,17 @@
 
 			fg_yet_to_be_received = qty_to_be_received_map.get(item_key)
 
-			raw_material_data = backflushed_raw_materials_map.get(item_key, {})
-
-			consumed_qty = raw_material_data.get('qty', 0)
-			consumed_serial_nos = raw_material_data.get('serial_nos', '')
-			consumed_batch_nos = raw_material_data.get('batch_nos', '')
-
 			transferred_batch_qty_map = get_transferred_batch_qty_map(item.purchase_order, item.item_code)
 			backflushed_batch_qty_map = get_backflushed_batch_qty_map(item.purchase_order, item.item_code)
 
 			for raw_material in transferred_raw_materials + non_stock_items:
+				rm_item_key = '{}{}'.format(raw_material.rm_item_code, item.purchase_order)
+				raw_material_data = backflushed_raw_materials_map.get(rm_item_key, {})
+
+				consumed_qty = raw_material_data.get('qty', 0)
+				consumed_serial_nos = raw_material_data.get('serial_nos', '')
+				consumed_batch_nos = raw_material_data.get('batch_nos', '')
+
 				transferred_qty = raw_material.qty
 
 				rm_qty_to_be_consumed = transferred_qty - consumed_qty
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index 7b4a4c9..5c31900 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -311,6 +311,7 @@
 				and sle.item_code = %(item_code)s
 				and sle.warehouse = %(warehouse)s
 				and (sle.batch_no like %(txt)s
+				or batch.expiry_date like %(txt)s
 				or batch.manufacturing_date like %(txt)s)
 				and batch.docstatus < 2
 				{cond}
@@ -329,6 +330,7 @@
 			where batch.disabled = 0
 			and item = %(item_code)s
 			and (name like %(txt)s
+			or expiry_date like %(txt)s
 			or manufacturing_date like %(txt)s)
 			and docstatus < 2
 			{0}
diff --git a/erpnext/crm/doctype/appointment/appointment.py b/erpnext/crm/doctype/appointment/appointment.py
index b6c4c47..f502930 100644
--- a/erpnext/crm/doctype/appointment/appointment.py
+++ b/erpnext/crm/doctype/appointment/appointment.py
@@ -11,7 +11,7 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe.utils import get_url
+from frappe.utils import get_url, getdate
 from frappe.utils.verified_command import verify_request, get_signed_params
 
 
@@ -117,7 +117,7 @@
 		if self._assign:
 			return
 		available_agents = _get_agents_sorted_by_asc_workload(
-			self.scheduled_time.date())
+			getdate(self.scheduled_time))
 		for agent in available_agents:
 			if(_check_agent_availability(agent, self.scheduled_time)):
 				agent = agent[0]
@@ -189,7 +189,7 @@
 		assigned_to = frappe.parse_json(appointment._assign)
 		if not assigned_to:
 			continue
-		if (assigned_to[0] in agent_list) and appointment.scheduled_time.date() == date:
+		if (assigned_to[0] in agent_list) and getdate(appointment.scheduled_time) == date:
 			appointment_counter[assigned_to[0]] += 1
 	sorted_agent_list = appointment_counter.most_common()
 	sorted_agent_list.reverse()
diff --git a/erpnext/education/doctype/student/student.js b/erpnext/education/doctype/student/student.js
index b6e741c..1936dcb 100644
--- a/erpnext/education/doctype/student/student.js
+++ b/erpnext/education/doctype/student/student.js
@@ -31,7 +31,7 @@
 frappe.ui.form.on('Student Guardian', {
 	guardians_add: function(frm){
 		frm.fields_dict['guardians'].grid.get_field('guardian').get_query = function(doc){
-			var guardian_list = [];
+			let guardian_list = [];
 			if(!doc.__islocal) guardian_list.push(doc.guardian);
 			$.each(doc.guardians, function(idx, val){
 				if (val.guardian) guardian_list.push(val.guardian);
@@ -40,3 +40,18 @@
 		};
 	}
 });
+
+
+frappe.ui.form.on('Student Sibling', {
+	siblings_add: function(frm){
+		frm.fields_dict['siblings'].grid.get_field('student').get_query = function(doc){
+			let sibling_list = [frm.doc.name];
+			$.each(doc.siblings, function(idx, val){
+				if (val.student && val.studying_in_same_institute == 'YES') {
+					sibling_list.push(val.student);
+				}
+			});
+			return { filters: [['Student', 'name', 'not in', sibling_list]] };
+		};
+	}
+});
\ No newline at end of file
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 2a5e6d8..c99ae7d 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -180,6 +180,7 @@
 	{"title": _("Admission"), "route": "/admissions", "reference_doctype": "Student Admission", "role": "Student"},
 	{"title": _("Certification"), "route": "/certification", "reference_doctype": "Certification Application", "role": "Non Profit Portal User"},
 	{"title": _("Material Request"), "route": "/material-requests", "reference_doctype": "Material Request", "role": "Customer"},
+	{"title": _("Appointment Booking"), "route": "/book_appointment"},
 ]
 
 default_roles = [
diff --git a/erpnext/hr/doctype/employee/employee.json b/erpnext/hr/doctype/employee/employee.json
index 9291820..a45b41d 100644
--- a/erpnext/hr/doctype/employee/employee.json
+++ b/erpnext/hr/doctype/employee/employee.json
@@ -232,7 +232,6 @@
    "reqd": 1
   },
   {
-   "description": "You can enter any date manually",
    "fieldname": "date_of_birth",
    "fieldtype": "Date",
    "label": "Date of Birth",
@@ -831,4 +830,4 @@
  "sort_order": "DESC",
  "title_field": "employee_name",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.js b/erpnext/hr/doctype/employee_advance/employee_advance.js
index 77a2bbc..ba62853 100644
--- a/erpnext/hr/doctype/employee_advance/employee_advance.js
+++ b/erpnext/hr/doctype/employee_advance/employee_advance.js
@@ -34,7 +34,7 @@
 		}
 		else if (
 			frm.doc.docstatus === 1
-			&& flt(frm.doc.claimed_amount) < flt(frm.doc.paid_amount)
+			&& flt(frm.doc.claimed_amount) < flt(frm.doc.paid_amount) - flt(frm.doc.return_amount)
 			&& frappe.model.can_create("Expense Claim")
 		) {
 			frm.add_custom_button(
@@ -45,6 +45,15 @@
 				__('Create')
 			);
 		}
+
+		if (frm.doc.docstatus === 1
+			&& (flt(frm.doc.claimed_amount) < flt(frm.doc.paid_amount))
+			&& frappe.model.can_create("Journal Entry")) {
+
+			frm.add_custom_button(__("Return"),  function() {
+				frm.trigger('make_return_entry');
+			}, __('Create'));
+		}
 	},
 
 	make_payment_entry: function(frm) {
@@ -83,6 +92,24 @@
 		});
 	},
 
+	make_return_entry: function(frm) {
+		frappe.call({
+			method: 'erpnext.hr.doctype.employee_advance.employee_advance.make_return_entry',
+			args: {
+				'employee_name': frm.doc.employee,
+				'company': frm.doc.company,
+				'employee_advance_name': frm.doc.name,
+				'return_amount': flt(frm.doc.paid_amount - frm.doc.claimed_amount),
+				'mode_of_payment': frm.doc.mode_of_payment,
+				'advance_account': frm.doc.advance_account
+			},
+			callback: function(r) {
+				const doclist = frappe.model.sync(r.message);
+				frappe.set_route('Form', doclist[0].doctype, doclist[0].name);
+			}
+		});
+	},
+
 	employee: function (frm) {
 		if (frm.doc.employee) {
 			return frappe.call({
diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.json b/erpnext/hr/doctype/employee_advance/employee_advance.json
index 3597e76..d233a2b 100644
--- a/erpnext/hr/doctype/employee_advance/employee_advance.json
+++ b/erpnext/hr/doctype/employee_advance/employee_advance.json
@@ -1,737 +1,213 @@
 {
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 0, 
- "autoname": "naming_series:", 
- "beta": 0, 
- "creation": "2017-10-09 14:26:29.612365", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "allow_import": 1,
+ "autoname": "naming_series:",
+ "creation": "2017-10-09 14:26:29.612365",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "naming_series",
+  "employee",
+  "employee_name",
+  "column_break_4",
+  "posting_date",
+  "department",
+  "section_break_8",
+  "purpose",
+  "column_break_11",
+  "advance_amount",
+  "paid_amount",
+  "due_advance_amount",
+  "claimed_amount",
+  "return_amount",
+  "section_break_7",
+  "status",
+  "company",
+  "amended_from",
+  "column_break_18",
+  "advance_account",
+  "mode_of_payment"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "", 
-   "fieldname": "naming_series", 
-   "fieldtype": "Select", 
-   "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": "Series", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "HR-EAD-.YYYY.-", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Series",
+   "options": "HR-EAD-.YYYY.-"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "employee", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Employee", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Employee", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "employee",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Employee",
+   "options": "Employee",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "employee.employee_name", 
-   "fieldname": "employee_name", 
-   "fieldtype": "Read Only", 
-   "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": "Employee Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "employee.employee_name",
+   "fieldname": "employee_name",
+   "fieldtype": "Read Only",
+   "label": "Employee Name"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_4", 
-   "fieldtype": "Column Break", 
-   "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, 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "Today", 
-   "fieldname": "posting_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Posting Date", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "default": "Today",
+   "fieldname": "posting_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "Posting Date",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "employee.department", 
-   "fieldname": "department", 
-   "fieldtype": "Link", 
-   "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": "Department", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Department", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "employee.department",
+   "fieldname": "department",
+   "fieldtype": "Link",
+   "label": "Department",
+   "options": "Department",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_8", 
-   "fieldtype": "Section Break", 
-   "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, 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_8",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "purpose", 
-   "fieldtype": "Small Text", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Purpose", 
-   "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": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "purpose",
+   "fieldtype": "Small Text",
+   "in_list_view": 1,
+   "label": "Purpose",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_11", 
-   "fieldtype": "Column Break", 
-   "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, 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_11",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "advance_amount", 
-   "fieldtype": "Currency", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Advance Amount", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Company:company:default_currency", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "advance_amount",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Advance Amount",
+   "options": "Company:company:default_currency",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "paid_amount", 
-   "fieldtype": "Currency", 
-   "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": "Paid Amount", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Company:company:default_currency", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "paid_amount",
+   "fieldtype": "Currency",
+   "label": "Paid Amount",
+   "no_copy": 1,
+   "options": "Company:company:default_currency",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:cur_frm.doc.employee", 
-   "fieldname": "due_advance_amount", 
-   "fieldtype": "Currency", 
-   "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": "Due Advance Amount", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Company:company:default_currency", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:cur_frm.doc.employee",
+   "fieldname": "due_advance_amount",
+   "fieldtype": "Currency",
+   "label": "Due Advance Amount",
+   "options": "Company:company:default_currency",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "claimed_amount", 
-   "fieldtype": "Currency", 
-   "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": "Claimed Amount", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Company:company:default_currency", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "claimed_amount",
+   "fieldtype": "Currency",
+   "label": "Claimed Amount",
+   "no_copy": 1,
+   "options": "Company:company:default_currency",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_7", 
-   "fieldtype": "Section Break", 
-   "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, 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_7",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "status", 
-   "fieldtype": "Select", 
-   "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": "Status", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Draft\nPaid\nUnpaid\nClaimed\nCancelled", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "status",
+   "fieldtype": "Select",
+   "label": "Status",
+   "no_copy": 1,
+   "options": "Draft\nPaid\nUnpaid\nClaimed\nCancelled",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "company", 
-   "fieldtype": "Link", 
-   "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": "Company", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Company", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "company",
+   "fieldtype": "Link",
+   "label": "Company",
+   "options": "Company",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "amended_from", 
-   "fieldtype": "Link", 
-   "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": "Amended From", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Employee Advance", 
-   "permlevel": 0, 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Employee Advance",
+   "print_hide": 1,
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_18", 
-   "fieldtype": "Column Break", 
-   "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, 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_18",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "advance_account", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 1, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Advance Account", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Account", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "advance_account",
+   "fieldtype": "Link",
+   "ignore_user_permissions": 1,
+   "label": "Advance Account",
+   "options": "Account",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "mode_of_payment", 
-   "fieldtype": "Link", 
-   "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": "Mode of Payment", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Mode of Payment", 
-   "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, 
-   "translatable": 0, 
-   "unique": 0
+   "fieldname": "mode_of_payment",
+   "fieldtype": "Link",
+   "label": "Mode of Payment",
+   "options": "Mode of Payment"
+  },
+  {
+   "fieldname": "return_amount",
+   "fieldtype": "Currency",
+   "label": "Returned Amount",
+   "options": "Company:company:default_currency",
+   "read_only": 1
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 1, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2019-01-30 11:28:15.529649", 
- "modified_by": "Administrator", 
- "module": "HR", 
- "name": "Employee Advance", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2019-12-15 19:04:07.044505",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Employee Advance",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 0, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Employee", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Employee",
+   "share": 1,
    "write": 1
-  }, 
+  },
   {
-   "amend": 1, 
-   "cancel": 1, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Expense Approver", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 1, 
+   "amend": 1,
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Expense Approver",
+   "share": 1,
+   "submit": 1,
    "write": 1
   }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "search_fields": "employee,employee_name", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
-}
\ No newline at end of file
+ ],
+ "search_fields": "employee,employee_name",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.py b/erpnext/hr/doctype/employee_advance/employee_advance.py
index 7813da7..7fe2ebc 100644
--- a/erpnext/hr/doctype/employee_advance/employee_advance.py
+++ b/erpnext/hr/doctype/employee_advance/employee_advance.py
@@ -7,6 +7,7 @@
 from frappe import _
 from frappe.model.document import Document
 from frappe.utils import flt, nowdate
+from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
 
 class EmployeeAdvanceOverPayment(frappe.ValidationError):
 	pass
@@ -53,11 +54,25 @@
 				and party = %s
 		""", (self.name, self.employee), as_dict=1)[0].paid_amount
 
+		return_amount = frappe.db.sql("""
+			select name, ifnull(sum(credit_in_account_currency), 0) as return_amount
+			from `tabGL Entry`
+			where against_voucher_type = 'Employee Advance'
+				and voucher_type != 'Expense Claim'
+				and against_voucher = %s
+				and party_type = 'Employee'
+				and party = %s
+		""", (self.name, self.employee), as_dict=1)[0].return_amount
+
 		if flt(paid_amount) > self.advance_amount:
 			frappe.throw(_("Row {0}# Paid Amount cannot be greater than requested advance amount"),
 				EmployeeAdvanceOverPayment)
 
+		if flt(return_amount) > self.paid_amount - self.claimed_amount:
+			frappe.throw(_("Return amount cannot be greater unclaimed amount"))
+
 		self.db_set("paid_amount", paid_amount)
+		self.db_set("return_amount", return_amount)
 		self.set_status()
 		frappe.db.set_value("Employee Advance", self.name , "status", self.status)
 
@@ -88,8 +103,6 @@
 
 @frappe.whitelist()
 def make_bank_entry(dt, dn):
-	from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
-
 	doc = frappe.get_doc(dt, dn)
 	payment_account = get_default_bank_cash_account(doc.company, account_type="Cash",
 		mode_of_payment=doc.mode_of_payment)
@@ -118,3 +131,33 @@
 	})
 
 	return je.as_dict()
+
+@frappe.whitelist()
+def make_return_entry(employee_name, company, employee_advance_name, return_amount, mode_of_payment, advance_account):
+	return_account = get_default_bank_cash_account(company, account_type='Cash', mode_of_payment = mode_of_payment)
+	je = frappe.new_doc('Journal Entry')
+	je.posting_date = nowdate()
+	je.voucher_type = 'Bank Entry'
+	je.company = company
+	je.remark = 'Return against Employee Advance: ' + employee_advance_name
+
+	je.append('accounts', {
+		'account': advance_account,
+		'credit_in_account_currency': return_amount,
+		'reference_type': 'Employee Advance',
+		'reference_name': employee_advance_name,
+		'party_type': 'Employee',
+		'party': employee_name,
+		'is_advance': 'Yes'
+	})
+
+	je.append("accounts", {
+		"account": return_account.account,
+		"debit_in_account_currency": return_amount,
+		"account_currency": return_account.account_currency,
+		"account_type": return_account.account_type
+	})
+
+	return je.as_dict()
+	
+
diff --git a/erpnext/hr/doctype/employee_advance/employee_advance_dashboard.py b/erpnext/hr/doctype/employee_advance/employee_advance_dashboard.py
new file mode 100644
index 0000000..c3b4a3a
--- /dev/null
+++ b/erpnext/hr/doctype/employee_advance/employee_advance_dashboard.py
@@ -0,0 +1,19 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'employee_advance',
+        'non_standard_fieldnames': {
+            'Payment Entry': 'reference_name',
+            'Journal Entry': 'reference_name'
+        },
+		'transactions': [
+			{
+				'items': ['Expense Claim']
+			},
+			{
+				'items': ['Payment Entry', 'Journal Entry']
+			}
+		]
+	}
diff --git a/erpnext/hr/doctype/employee_onboarding/employee_onboarding.js b/erpnext/hr/doctype/employee_onboarding/employee_onboarding.js
index 996dcdf..c128567 100644
--- a/erpnext/hr/doctype/employee_onboarding/employee_onboarding.js
+++ b/erpnext/hr/doctype/employee_onboarding/employee_onboarding.js
@@ -7,6 +7,14 @@
 		frm.add_fetch("employee_onboarding_template", "department", "department");
 		frm.add_fetch("employee_onboarding_template", "designation", "designation");
 		frm.add_fetch("employee_onboarding_template", "employee_grade", "employee_grade");
+
+		frm.set_query('job_offer', function () {
+			return {
+				filters: {
+					'job_applicant': frm.doc.job_applicant
+				}
+			};
+		});
 	},
 
 	refresh: function(frm) {
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index 570f2ef..e0bfc83 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -243,11 +243,11 @@
 
 	update_employee_advance_claimed_amount: function(frm) {
 		let amount_to_be_allocated = frm.doc.grand_total;
-		$.each(frm.doc.advances || [], function(i, advance){
-			if (amount_to_be_allocated >= advance.unclaimed_amount){
+		$.each(frm.doc.advances || [], function(i, advance) {
+			if (amount_to_be_allocated >= advance.unclaimed_amount) {
 				frm.doc.advances[i].allocated_amount = frm.doc.advances[i].unclaimed_amount;
 				amount_to_be_allocated -= advance.allocated_amount;
-			} else{
+			} else {
 				frm.doc.advances[i].allocated_amount = amount_to_be_allocated;
 				amount_to_be_allocated = 0;
 			}
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index b5b6823..96baaab 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "autoname": "naming_series:",
  "creation": "2013-01-10 16:34:14",
@@ -43,6 +44,7 @@
   "accounting_dimensions_section",
   "project",
   "dimension_col_break",
+  "cost_center",
   "more_details",
   "status",
   "amended_from",
@@ -365,7 +367,8 @@
  "icon": "fa fa-money",
  "idx": 1,
  "is_submittable": 1,
- "modified": "2019-11-09 14:13:08.964547",
+ "links": [],
+ "modified": "2019-12-14 23:52:05.388458",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Expense Claim",
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index dfb0bb9..e01e7a4 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -43,9 +43,9 @@
 		}[cstr(self.docstatus or 0)]
 
 		paid_amount = flt(self.total_amount_reimbursed) + flt(self.total_advance_amount)
-		precision = self.precision("total_sanctioned_amount")
+		precision = self.precision("grand_total")
 		if (self.is_paid or (flt(self.total_sanctioned_amount) > 0
-			and flt(self.total_sanctioned_amount, precision) ==  flt(paid_amount, precision))) \
+			and flt(self.grand_total, precision) ==  flt(paid_amount, precision))) \
 			and self.docstatus == 1 and self.approval_status == 'Approved':
 				self.status = "Paid"
 		elif flt(self.total_sanctioned_amount) > 0 and self.docstatus == 1 and self.approval_status == 'Approved':
@@ -322,7 +322,7 @@
 @frappe.whitelist()
 def get_advances(employee, advance_id=None):
 	if not advance_id:
-		condition = 'docstatus=1 and employee={0} and paid_amount > 0 and paid_amount > claimed_amount'.format(frappe.db.escape(employee))
+		condition = 'docstatus=1 and employee={0} and paid_amount > 0 and paid_amount > claimed_amount + return_amount'.format(frappe.db.escape(employee))
 	else:
 		condition = 'name={0}'.format(frappe.db.escape(advance_id))
 
diff --git a/erpnext/hr/doctype/expense_claim_type/expense_claim_type.js b/erpnext/hr/doctype/expense_claim_type/expense_claim_type.js
index c487797..d007e1a 100644
--- a/erpnext/hr/doctype/expense_claim_type/expense_claim_type.js
+++ b/erpnext/hr/doctype/expense_claim_type/expense_claim_type.js
@@ -2,10 +2,10 @@
 // License: GNU General Public License v3. See license.txt
 
 frappe.ui.form.on("Expense Claim Type", {
-	refresh: function(frm){
-		frm.fields_dict["accounts"].grid.get_field("default_account").get_query = function(frm, cdt, cdn){
+	refresh: function(frm) {
+		frm.fields_dict["accounts"].grid.get_field("default_account").get_query = function(doc, cdt, cdn) {
 			var d = locals[cdt][cdn];
-			return{
+			return {
 				filters: {
 					"is_group": 0,
 					"root_type": frm.doc.deferred_expense_account ? "Asset" : "Expense",
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 915cea1..5222712 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -54,9 +54,11 @@
 		self.create_leave_ledger_entry()
 		self.reload()
 
+	def before_cancel(self):
+		self.status = "Cancelled"
+
 	def on_cancel(self):
 		self.create_leave_ledger_entry(submit=False)
-		self.status = "Cancelled"
 		# notify leave applier about cancellation
 		self.notify_employee()
 		self.cancel_attendance()
diff --git a/erpnext/hr/doctype/payroll_entry/payroll_entry.py b/erpnext/hr/doctype/payroll_entry/payroll_entry.py
index 2de01e6..dfd38eb 100644
--- a/erpnext/hr/doctype/payroll_entry/payroll_entry.py
+++ b/erpnext/hr/doctype/payroll_entry/payroll_entry.py
@@ -163,7 +163,7 @@
 		"""
 		cond = self.get_filter_condition()
 		return frappe.db.sql(""" select eld.loan_account, eld.loan,
-				eld.interest_income_account, eld.principal_amount, eld.interest_amount, eld.total_payment
+				eld.interest_income_account, eld.principal_amount, eld.interest_amount, eld.total_payment,t1.employee
 			from
 				`tabSalary Slip` t1, `tabSalary Slip Loan` eld
 			where
@@ -246,6 +246,7 @@
 				accounts.append({
 						"account": acc,
 						"debit_in_account_currency": flt(amount, precision),
+						"party_type": '',
 						"cost_center": self.cost_center,
 						"project": self.project
 					})
@@ -257,6 +258,7 @@
 						"account": acc,
 						"credit_in_account_currency": flt(amount, precision),
 						"cost_center": self.cost_center,
+						"party_type": '',
 						"project": self.project
 					})
 
@@ -264,7 +266,9 @@
 			for data in loan_details:
 				accounts.append({
 						"account": data.loan_account,
-						"credit_in_account_currency": data.principal_amount
+						"credit_in_account_currency": data.principal_amount,
+						"party_type": "Employee",
+						"party": data.employee
 					})
 
 				if data.interest_amount and not data.interest_income_account:
@@ -275,14 +279,17 @@
 						"account": data.interest_income_account,
 						"credit_in_account_currency": data.interest_amount,
 						"cost_center": self.cost_center,
-						"project": self.project
+						"project": self.project,
+						"party_type": "Employee",
+						"party": data.employee
 					})
 				payable_amount -= flt(data.total_payment, precision)
 
 			# Payable amount
 			accounts.append({
 				"account": default_payroll_payable_account,
-				"credit_in_account_currency": flt(payable_amount, precision)
+				"credit_in_account_currency": flt(payable_amount, precision),
+				"party_type": '',
 			})
 
 			journal_entry.set("accounts", accounts)
@@ -546,7 +553,6 @@
 		count += 1
 		if publish_progress:
 			frappe.publish_progress(count*100/len(salary_slips), title = _("Submitting Salary Slips..."))
-
 	if submitted_ss:
 		payroll_entry.make_accrual_jv_entry()
 		frappe.msgprint(_("Salary Slip submitted for period from {0} to {1}")
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.js b/erpnext/hr/doctype/salary_structure/salary_structure.js
index dd34ef2..9f42c91 100755
--- a/erpnext/hr/doctype/salary_structure/salary_structure.js
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.js
@@ -46,7 +46,7 @@
 		frm.trigger("toggle_fields");
 		frm.fields_dict['earnings'].grid.set_column_disp("default_amount", false);
 		frm.fields_dict['deductions'].grid.set_column_disp("default_amount", false);
-		
+
 		if(frm.doc.docstatus === 1) {
 			frm.add_custom_button(__("Preview Salary Slip"), function() {
 				frm.trigger('preview_salary_slip');
@@ -119,47 +119,52 @@
 			},
 			callback: function(r) {
 				var employees = r.message;
-				var d = new frappe.ui.Dialog({
-					title: __("Preview Salary Slip"),
-					fields: [
-						{
-							"label":__("Employee"),
-							"fieldname":"employee",
-							"fieldtype":"Select",
-							"reqd": true,
-							options: employees
-						}, {
-							fieldname:"fetch",
-							"label":__("Show Salary Slip"),
-							"fieldtype":"Button"
-						}
-					]
-				});
-				d.get_input("fetch").on("click", function() {
-					var values = d.get_values();
-					if(!values) return;
-					var print_format;
-					frm.doc.salary_slip_based_on_timesheet ?
-						print_format="Salary Slip based on Timesheet" :
-						print_format="Salary Slip Standard";
-
-					frappe.call({
-						method: "erpnext.hr.doctype.salary_structure.salary_structure.make_salary_slip",
-						args: {
-							source_name: frm.doc.name,
-							employee: values.employee,
-							as_print: 1,
-							print_format: print_format,
-							for_preview: 1
-						},
-						callback: function(r) {
-							var new_window = window.open();
-							new_window.document.write(r.message);
-							// frappe.msgprint(r.message);
-						}
+				if(!employees) return;
+				if (employees.length == 1){
+					frm.events.open_salary_slip(frm, employees[0]);
+				} else {
+						var d = new frappe.ui.Dialog({
+						title: __("Preview Salary Slip"),
+						fields: [
+							{
+								"label":__("Employee"),
+								"fieldname":"employee",
+								"fieldtype":"Select",
+								"reqd": true,
+								options: employees
+							}, {
+								fieldname:"fetch",
+								"label":__("Show Salary Slip"),
+								"fieldtype":"Button"
+							}
+						]
 					});
-				});
-				d.show();
+					d.get_input("fetch").on("click", function() {
+						var values = d.get_values();
+						if(!values) return;
+							frm.events.open_salary_slip(frm, values.employee)
+
+					});
+					d.show();
+				}
+			}
+		});
+	},
+
+	open_salary_slip: function(frm, employee){
+		var print_format = frm.doc.salary_slip_based_on_timesheet ? "Salary Slip based on Timesheet" : "Salary Slip Standard";
+		frappe.call({
+			method: "erpnext.hr.doctype.salary_structure.salary_structure.make_salary_slip",
+			args: {
+				source_name: frm.doc.name,
+				employee: employee,
+				as_print: 1,
+				print_format: print_format,
+				for_preview: 1
+			},
+			callback: function(r) {
+				var new_window = window.open();
+				new_window.document.write(r.message);
 			}
 		});
 	},
diff --git a/erpnext/hr/notification/training_scheduled/training_scheduled.html b/erpnext/hr/notification/training_scheduled/training_scheduled.html
index b1aeb2c..374038a 100644
--- a/erpnext/hr/notification/training_scheduled/training_scheduled.html
+++ b/erpnext/hr/notification/training_scheduled/training_scheduled.html
@@ -1,9 +1,44 @@
-<h3>{{_("Training Event")}}</h3>
+<table class="panel-header" border="0" cellpadding="0" cellspacing="0" width="100%">
+    <tr height="10"></tr>
+    <tr>
+        <td width="15"></td>
+        <td>
+            <div class="text-medium text-muted">
+                <span>{{_("Training Event:")}} {{ doc.event_name }}</span>
+            </div>
+        </td>
+        <td width="15"></td>
+    </tr>
+    <tr height="10"></tr>
+</table>
 
-<p>{{ doc.introduction }}</p>
-
-<h4>{{_("Details")}}</h4>
-{{_("Event Name")}}: {{ frappe.utils.get_link_to_form(doc.doctype, doc.name) }}
-<br>{{_("Event Location")}}: {{ doc.location }}
-<br>{{_("Start Time")}}: {{ doc.start_time }}
-<br>{{_("End Time")}}: {{ doc.end_time }}
+<table class="panel-body" border="0" cellpadding="0" cellspacing="0" width="100%">
+    <tr height="10"></tr>
+    <tr>
+        <td width="15"></td>
+        <td>
+            <div>
+                {{ doc.introduction }}
+                <ul class="list-unstyled" style="line-height: 1.7">
+                    <li>{{_("Event Location")}}: <b>{{ doc.location }}</b></li>
+                    {% set start = frappe.utils.get_datetime(doc.start_time) %}
+                    {% set end = frappe.utils.get_datetime(doc.end_time) %}
+                    {% if start.date() == end.date() %}
+                    <li>{{_("Date")}}: <b>{{ start.strftime("%A, %d %b %Y") }}</b></li>
+                    <li>
+                        {{_("Timing")}}: <b>{{ start.strftime("%I:%M %p") + ' to ' + end.strftime("%I:%M %p") }}</b>
+                    </li>
+                    {% else %}
+                    <li>{{_("Start Time")}}: <b>{{ start.strftime("%A, %d %b %Y at %I:%M %p") }}</b>
+                    </li>
+                    <li>{{_("End Time")}}: <b>{{ end.strftime("%A, %d %b %Y at %I:%M %p") }}</b>
+                    </li>
+                    {% endif %}
+                    <li>{{ _('Event Link') }}: {{ frappe.utils.get_link_to_form(doc.doctype, doc.name) }}</li>
+                </ul>
+            </div>
+        </td>
+        <td width="15"></td>
+    </tr>
+    <tr height="10"></tr>
+</table>
\ No newline at end of file
diff --git a/erpnext/hr/notification/training_scheduled/training_scheduled.json b/erpnext/hr/notification/training_scheduled/training_scheduled.json
index c07e1a6..966b887 100644
--- a/erpnext/hr/notification/training_scheduled/training_scheduled.json
+++ b/erpnext/hr/notification/training_scheduled/training_scheduled.json
@@ -1,5 +1,7 @@
 {
  "attach_print": 0,
+ "channel": "Email",
+ "condition": "",
  "creation": "2017-08-11 03:13:40.519614",
  "days_in_advance": 0,
  "docstatus": 0,
@@ -9,8 +11,8 @@
  "event": "Submit",
  "idx": 0,
  "is_standard": 1,
- "message": "<h3>{{_(\"Training Event\")}}</h3>\n\n<p>{{ doc.introduction }}</p>\n\n<h4>{{_(\"Details\")}}</h4>\n{{_(\"Event Name\")}}: {{ frappe.utils.get_link_to_form(doc.doctype, doc.name) }}\n<br>{{_(\"Event Location\")}}: {{ doc.location }}\n<br>{{_(\"Start Time\")}}: {{ doc.start_time }}\n<br>{{_(\"End Time\")}}: {{ doc.end_time }}\n",
- "modified": "2017-08-13 22:49:42.338881",
+ "message": "<table class=\"panel-header\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n    <tr height=\"10\"></tr>\n    <tr>\n        <td width=\"15\"></td>\n        <td>\n            <div class=\"text-medium text-muted\">\n                <span>{{_(\"Training Event:\")}} {{ doc.event_name }}</span>\n            </div>\n        </td>\n        <td width=\"15\"></td>\n    </tr>\n    <tr height=\"10\"></tr>\n</table>\n\n<table class=\"panel-body\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n    <tr height=\"10\"></tr>\n    <tr>\n        <td width=\"15\"></td>\n        <td>\n            <div>\n                <ul class=\"list-unstyled\" style=\"line-height: 1.7\">\n                    <li>{{ doc.introduction }}</li>\n                    <li>{{_(\"Event Location\")}}: <b>{{ doc.location }}</b></li>\n                    {% set start = frappe.utils.get_datetime(doc.start_time) %}\n                    {% set end = frappe.utils.get_datetime(doc.end_time) %}\n                    {% if start.date() == end.date() %}\n                    <li>{{_(\"Date\")}}: <b>{{ start.strftime(\"%A, %d %b %Y\") }}</b></li>\n                    <li>\n                        {{_(\"Timing\")}}: <b>{{ start.strftime(\"%I:%M %p\") + ' to ' + end.strftime(\"%I:%M %p\") }}</b>\n                    </li>\n                    {% else %}\n                    <li>{{_(\"Start Time\")}}: <b>{{ start.strftime(\"%A, %d %b %Y at %I:%M %p\") }}</b>\n                    </li>\n                    <li>{{_(\"End Time\")}}: <b>{{ end.strftime(\"%A, %d %b %Y at %I:%M %p\") }}</b>\n                    </li>\n                    {% endif %}\n                </ul>\n                {{ _('Event Link') }}: {{ frappe.utils.get_link_to_form(doc.doctype, doc.name) }}\n            </div>\n        </td>\n        <td width=\"15\"></td>\n    </tr>\n    <tr height=\"10\"></tr>\n</table>",
+ "modified": "2019-11-29 15:38:31.805409",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Training Scheduled",
diff --git a/erpnext/hr/notification/training_scheduled/training_scheduled.md b/erpnext/hr/notification/training_scheduled/training_scheduled.md
index bcadf7d..374038a 100644
--- a/erpnext/hr/notification/training_scheduled/training_scheduled.md
+++ b/erpnext/hr/notification/training_scheduled/training_scheduled.md
@@ -1,9 +1,44 @@
-<h3>{{_("Training Event")}}</h3>
-<p>{{ message }}</p>
+<table class="panel-header" border="0" cellpadding="0" cellspacing="0" width="100%">
+    <tr height="10"></tr>
+    <tr>
+        <td width="15"></td>
+        <td>
+            <div class="text-medium text-muted">
+                <span>{{_("Training Event:")}} {{ doc.event_name }}</span>
+            </div>
+        </td>
+        <td width="15"></td>
+    </tr>
+    <tr height="10"></tr>
+</table>
 
-<h4>{{_("Details")}}</h4>
-{{_("Event Name")}}: <a href="{{ event_link }}">{{ name }}</a>
-<br>{{_("Event Location")}}: {{ location }}
-<br>{{_("Start Time")}}: {{ start_time }}
-<br>{{_("End Time")}}: {{ end_time }}
-<br>{{_("Attendance")}}: {{ attendance }}
+<table class="panel-body" border="0" cellpadding="0" cellspacing="0" width="100%">
+    <tr height="10"></tr>
+    <tr>
+        <td width="15"></td>
+        <td>
+            <div>
+                {{ doc.introduction }}
+                <ul class="list-unstyled" style="line-height: 1.7">
+                    <li>{{_("Event Location")}}: <b>{{ doc.location }}</b></li>
+                    {% set start = frappe.utils.get_datetime(doc.start_time) %}
+                    {% set end = frappe.utils.get_datetime(doc.end_time) %}
+                    {% if start.date() == end.date() %}
+                    <li>{{_("Date")}}: <b>{{ start.strftime("%A, %d %b %Y") }}</b></li>
+                    <li>
+                        {{_("Timing")}}: <b>{{ start.strftime("%I:%M %p") + ' to ' + end.strftime("%I:%M %p") }}</b>
+                    </li>
+                    {% else %}
+                    <li>{{_("Start Time")}}: <b>{{ start.strftime("%A, %d %b %Y at %I:%M %p") }}</b>
+                    </li>
+                    <li>{{_("End Time")}}: <b>{{ end.strftime("%A, %d %b %Y at %I:%M %p") }}</b>
+                    </li>
+                    {% endif %}
+                    <li>{{ _('Event Link') }}: {{ frappe.utils.get_link_to_form(doc.doctype, doc.name) }}</li>
+                </ul>
+            </div>
+        </td>
+        <td width="15"></td>
+    </tr>
+    <tr height="10"></tr>
+</table>
\ No newline at end of file
diff --git a/erpnext/hub_node/api.py b/erpnext/hub_node/api.py
index 0d01c67..f362539 100644
--- a/erpnext/hub_node/api.py
+++ b/erpnext/hub_node/api.py
@@ -115,6 +115,16 @@
 
 	return valid_items
 
+@frappe.whitelist()
+def update_item(ref_doc, data):
+	data = json.loads(data)
+
+	data.update(dict(doctype='Hub Item', name=ref_doc))
+	try:
+		connection = get_hub_connection()
+		connection.update(data)
+	except Exception as e:
+		frappe.log_error(message=e, title='Hub Sync Error')
 
 @frappe.whitelist()
 def publish_selected_items(items_to_publish):
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index e3ece56..f8146bb 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -65,6 +65,7 @@
 		context.parents = [{'name': 'boms', 'title': _('All BOMs') }]
 
 	def on_update(self):
+		frappe.cache().hdel('bom_children', self.name)
 		self.check_recursion()
 		self.update_stock_qty()
 		self.update_exploded_items()
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js
index 8ca8917..176ca2e 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.js
+++ b/erpnext/manufacturing/doctype/work_order/work_order.js
@@ -605,6 +605,8 @@
 				description: __('Max: {0}', [max]),
 				default: max
 			}, data => {
+				max += (max * (frm.doc.__onload.overproduction_percentage || 0.0)) / 100;
+
 				if (data.qty > max) {
 					frappe.msgprint(__('Quantity must not be more than {0}', [max]));
 					reject();
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 227ef78..c4238ac 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -38,7 +38,7 @@
 		ms = frappe.get_doc("Manufacturing Settings")
 		self.set_onload("material_consumption", ms.material_consumption)
 		self.set_onload("backflush_raw_materials_based_on", ms.backflush_raw_materials_based_on)
-
+		self.set_onload("overproduction_percentage", ms.overproduction_percentage_for_work_order)
 
 	def validate(self):
 		self.validate_production_item()
@@ -657,8 +657,9 @@
 	wo_doc = frappe.new_doc("Work Order")
 	wo_doc.production_item = item
 	wo_doc.update(item_details)
-	if qty > 0:
-		wo_doc.qty = qty
+
+	if flt(qty) > 0:
+		wo_doc.qty = flt(qty)
 		wo_doc.get_items_and_operations_from_bom()
 
 	return wo_doc
diff --git a/erpnext/patches/v12_0/add_export_type_field_in_party_master.py b/erpnext/patches/v12_0/add_export_type_field_in_party_master.py
index c565b7e..5bb6e3f 100644
--- a/erpnext/patches/v12_0/add_export_type_field_in_party_master.py
+++ b/erpnext/patches/v12_0/add_export_type_field_in_party_master.py
@@ -27,6 +27,8 @@
 		tax_category = inter_state_category.name
 
 	for doctype in ('Sales Taxes and Charges Template', 'Purchase Taxes and Charges Template'):
+		if not frappe.get_meta(doctype).has_field('is_inter_state'): continue
+
 		template = frappe.db.get_value(doctype, {'is_inter_state': 1, 'disabled': 0}, ['name'])
 		if template:
 			frappe.db.set_value(doctype, template, 'tax_category', tax_category)
diff --git a/erpnext/patches/v12_0/set_gst_category.py b/erpnext/patches/v12_0/set_gst_category.py
index 54bc5b3..55bbdee 100644
--- a/erpnext/patches/v12_0/set_gst_category.py
+++ b/erpnext/patches/v12_0/set_gst_category.py
@@ -7,6 +7,8 @@
 	if not company:
 		return
 
+	frappe.reload_doc('accounts', 'doctype', 'Tax Category')
+
 	make_custom_fields()
 
 	for doctype in ['Sales Invoice', 'Purchase Invoice']:
diff --git a/erpnext/portal/product_configurator/utils.py b/erpnext/portal/product_configurator/utils.py
index 3a373a4..0993e69 100644
--- a/erpnext/portal/product_configurator/utils.py
+++ b/erpnext/portal/product_configurator/utils.py
@@ -52,7 +52,6 @@
 
 
 def get_products_for_website(field_filters=None, attribute_filters=None, search=None):
-
 	if attribute_filters:
 		item_codes = get_item_codes_by_attributes(attribute_filters)
 		items_by_attributes = get_items([['name', 'in', item_codes]])
@@ -302,6 +301,8 @@
 	if isinstance(filters, dict):
 		filters = [['Item', fieldname, '=', value] for fieldname, value in filters.items()]
 
+	enabled_items_filter = get_conditions({ 'disabled': 0 }, 'and')
+
 	show_in_website_condition = ''
 	if products_settings.hide_variants:
 		show_in_website_condition = get_conditions({'show_in_website': 1 }, 'and')
@@ -337,7 +338,8 @@
 	filter_condition = get_conditions(filters, 'and')
 
 	where_conditions = ' and '.join(
-		[condition for condition in [show_in_website_condition, search_condition, filter_condition] if condition]
+		[condition for condition in [enabled_items_filter, show_in_website_condition, \
+			search_condition, filter_condition] if condition]
 	)
 
 	left_joins = []
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 7083d69..45f2681 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -47,11 +47,11 @@
 		if not self.project or frappe.flags.in_test:
 			return
 
-		expected_end_date = getdate(frappe.db.get_value("Project", self.project, "expected_end_date"))
+		expected_end_date = frappe.db.get_value("Project", self.project, "expected_end_date")
 
 		if expected_end_date:
-			validate_project_dates(expected_end_date, self, "exp_start_date", "exp_end_date", "Expected")
-			validate_project_dates(expected_end_date, self, "act_start_date", "act_end_date", "Actual")
+			validate_project_dates(getdate(expected_end_date), self, "exp_start_date", "exp_end_date", "Expected")
+			validate_project_dates(getdate(expected_end_date), self, "act_start_date", "act_end_date", "Actual")
 
 	def validate_status(self):
 		if self.status!=self.get_db_value("status") and self.status == "Completed":
@@ -278,4 +278,4 @@
 		frappe.throw(_("Task's {0} Start Date cannot be after Project's End Date.").format(actual_or_expected_date))
 
 	if task.get(task_end) and date_diff(project_end_date, getdate(task.get(task_end))) < 0:
-		frappe.throw(_("Task's {0} End Date cannot be after Project's End Date.").format(actual_or_expected_date))
\ No newline at end of file
+		frappe.throw(_("Task's {0} End Date cannot be after Project's End Date.").format(actual_or_expected_date))
diff --git a/erpnext/public/images/illustrations/customers-onboard.png b/erpnext/public/images/illustrations/customers-onboard.png
deleted file mode 100644
index 4a517bd..0000000
--- a/erpnext/public/images/illustrations/customers-onboard.png
+++ /dev/null
Binary files differ
diff --git a/erpnext/public/images/illustrations/desk-onboard.png b/erpnext/public/images/illustrations/desk-onboard.png
deleted file mode 100644
index 74b632d..0000000
--- a/erpnext/public/images/illustrations/desk-onboard.png
+++ /dev/null
Binary files differ
diff --git a/erpnext/public/images/illustrations/letterhead-onboard.png b/erpnext/public/images/illustrations/letterhead-onboard.png
deleted file mode 100644
index fdfd16a..0000000
--- a/erpnext/public/images/illustrations/letterhead-onboard.png
+++ /dev/null
Binary files differ
diff --git a/erpnext/public/images/illustrations/products-onboard.png b/erpnext/public/images/illustrations/products-onboard.png
deleted file mode 100644
index 2dee203..0000000
--- a/erpnext/public/images/illustrations/products-onboard.png
+++ /dev/null
Binary files differ
diff --git a/erpnext/public/images/illustrations/supplier-onboard.png b/erpnext/public/images/illustrations/supplier-onboard.png
deleted file mode 100644
index 30335f2..0000000
--- a/erpnext/public/images/illustrations/supplier-onboard.png
+++ /dev/null
Binary files differ
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index 02c3058..926227b 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -30,7 +30,7 @@
 			&& frappe.meta.has_field(this.frm.doc.doctype, "disable_rounded_total")) {
 
 				var df = frappe.meta.get_docfield(this.frm.doc.doctype, "disable_rounded_total");
-				var disable = df.default || cint(frappe.sys_defaults.disable_rounded_total);
+				var disable = cint(df.default) || cint(frappe.sys_defaults.disable_rounded_total);
 				this.frm.set_value("disable_rounded_total", disable);
 		}
 
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 46a58fb..6ca0958 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -500,6 +500,9 @@
 								() => {
 									var d = locals[cdt][cdn];
 									me.add_taxes_from_item_tax_template(d.item_tax_rate);
+									if (d.free_item_data) {
+										me.apply_product_discount(d.free_item_data);
+									}
 								},
 								() => me.frm.script_manager.trigger("price_list_rate", cdt, cdn),
 								() => me.toggle_conversion_factor(item),
@@ -1305,6 +1308,10 @@
 				me.remove_pricing_rule(frappe.get_doc(d.doctype, d.name));
 			}
 
+			if (d.free_item_data) {
+				me.apply_product_discount(d.free_item_data);
+			}
+
 			if (d.apply_rule_on_other_items) {
 				items_rule_dict[d.name] = d;
 			}
@@ -1334,6 +1341,20 @@
 		}
 	},
 
+	apply_product_discount: function(free_item_data) {
+		const items = this.frm.doc.items.filter(d => (d.item_code == free_item_data.item_code
+			&& d.is_free_item)) || [];
+
+		if (!items.length) {
+			let row_to_modify = frappe.model.add_child(this.frm.doc,
+				this.frm.doc.doctype + ' Item', 'items');
+
+			for (let key in free_item_data) {
+				row_to_modify[key] = free_item_data[key];
+			}
+		}
+	},
+
 	apply_price_list: function(item, reset_plc_conversion) {
 		// We need to reset plc_conversion_rate sometimes because the call to
 		// `erpnext.stock.get_item_details.apply_price_list` is sensitive to its value
@@ -1754,14 +1775,28 @@
 		}
 	},
 
+	set_reserve_warehouse: function() {
+		this.autofill_warehouse("reserve_warehouse");
+	},
+
 	set_warehouse: function() {
+		this.autofill_warehouse("warehouse");
+	},
+
+	autofill_warehouse : function (warehouse_field) {
+		// set warehouse in all child table rows
 		var me = this;
-		if(this.frm.doc.set_warehouse) {
-			$.each(this.frm.doc.items || [], function(i, item) {
-				frappe.model.set_value(me.frm.doctype + " Item", item.name, "warehouse", me.frm.doc.set_warehouse);
+		let warehouse = (warehouse_field === "warehouse") ? me.frm.doc.set_warehouse : me.frm.doc.set_reserve_warehouse;
+		let child_table = (warehouse_field === "warehouse") ? me.frm.doc.items : me.frm.doc.supplied_items;
+		let doctype = (warehouse_field === "warehouse") ? (me.frm.doctype + " Item") : (me.frm.doctype + " Item Supplied");
+
+		if(warehouse) {
+			$.each(child_table || [], function(i, item) {
+				frappe.model.set_value(doctype, item.name, warehouse_field, warehouse);
 			});
 		}
 	},
+
 	coupon_code: function() {
 		var me = this;
 		frappe.run_serially([
diff --git a/erpnext/public/js/hub/components/edit_details_dialog.js b/erpnext/public/js/hub/components/edit_details_dialog.js
new file mode 100644
index 0000000..97c5f83
--- /dev/null
+++ b/erpnext/public/js/hub/components/edit_details_dialog.js
@@ -0,0 +1,41 @@
+function edit_details_dialog(params) {
+	let dialog = new frappe.ui.Dialog({
+		title: __('Update Details'),
+		fields: [
+			{
+				label: 'Item Name',
+				fieldname: 'item_name',
+				fieldtype: 'Data',
+				default: params.defaults.item_name,
+				reqd: 1
+			},
+			{
+				label: 'Hub Category',
+				fieldname: 'hub_category',
+				fieldtype: 'Autocomplete',
+				default: params.defaults.hub_category,
+				options: [],
+				reqd: 1
+			},
+			{
+				label: 'Description',
+				fieldname: 'description',
+				fieldtype: 'Text',
+				default: params.defaults.description,
+				options: [],
+				reqd: 1
+			}
+		],
+		primary_action_label: params.primary_action.label || __('Update Details'),
+		primary_action: params.primary_action.fn
+	});
+
+	hub.call('get_categories').then(categories => {
+		categories = categories.map(d => d.name);
+		dialog.fields_dict.hub_category.set_data(categories);
+	});
+
+	return dialog;
+}
+
+export { edit_details_dialog };
diff --git a/erpnext/public/js/hub/pages/Item.vue b/erpnext/public/js/hub/pages/Item.vue
index 841d004..1174478 100644
--- a/erpnext/public/js/hub/pages/Item.vue
+++ b/erpnext/public/js/hub/pages/Item.vue
@@ -1,10 +1,5 @@
 <template>
-	<div
-		class="marketplace-page"
-		:data-page-name="page_name"
-		v-if="init || item"
-	>
-
+	<div class="marketplace-page" :data-page-name="page_name" v-if="init || item">
 		<detail-view
 			:title="title"
 			:image="image"
@@ -12,20 +7,15 @@
 			:menu_items="menu_items"
 			:show_skeleton="init"
 		>
-			<detail-header-item slot="detail-header-item"
-				:value="item_subtitle"
-			></detail-header-item>
-			<detail-header-item slot="detail-header-item"
-				:value="item_views_and_ratings"
-			></detail-header-item>
+			<detail-header-item slot="detail-header-item" :value="item_subtitle"></detail-header-item>
+			<detail-header-item slot="detail-header-item" :value="item_views_and_ratings"></detail-header-item>
 
-			<button v-if="primary_action" slot="detail-header-item"
+			<button
+				v-if="primary_action"
+				slot="detail-header-item"
 				class="btn btn-primary btn-sm margin-top"
 				@click="primary_action.action"
-			>
-				{{ primary_action.label }}
-			</button>
-
+			>{{ primary_action.label }}</button>
 		</detail-view>
 
 		<review-area v-if="!init" :hub_item_name="hub_item_name"></review-area>
@@ -35,6 +25,7 @@
 <script>
 import ReviewArea from '../components/ReviewArea.vue';
 import { get_rating_html } from '../components/reviews';
+import { edit_details_dialog } from '../components/edit_details_dialog';
 
 export default {
 	name: 'item-page',
@@ -51,21 +42,20 @@
 			item: null,
 			title: null,
 			image: null,
-			sections: [],
-
+			sections: []
 		};
 	},
 	computed: {
 		is_own_item() {
 			let is_own_item = false;
-			if(this.item) {
-				if(this.item.hub_seller === hub.settings.hub_seller_name) {
+			if (this.item) {
+				if (this.item.hub_seller === hub.settings.hub_seller_name) {
 					is_own_item = true;
 				}
 			}
 			return is_own_item;
 		},
-		menu_items(){
+		menu_items() {
 			return [
 				{
 					label: __('Save Item'),
@@ -92,11 +82,11 @@
 					condition: hub.is_user_registered() && this.is_own_item,
 					action: this.unpublish_item
 				}
-			]
+			];
 		},
 
 		item_subtitle() {
-			if(!this.item) {
+			if (!this.item) {
 				return '';
 			}
 
@@ -105,25 +95,31 @@
 			const rating = this.item.average_rating;
 
 			if (rating > 0) {
-				subtitle_items.push(rating + `<i class='fa fa-fw fa-star-o'></i>`)
+				subtitle_items.push(rating + `<i class='fa fa-fw fa-star-o'></i>`);
 			}
 
-			subtitle_items.push({value:this.item.company,on_click:this.go_to_seller_profile_page});
+			subtitle_items.push({
+				value: this.item.company,
+				on_click: this.go_to_seller_profile_page
+			});
 
 			return subtitle_items;
 		},
 
 		item_views_and_ratings() {
-			if(!this.item) {
+			if (!this.item) {
 				return '';
 			}
 
 			let stats = __('No views yet');
-			if(this.item.view_count) {
+			if (this.item.view_count) {
 				const views_message = __(`${this.item.view_count} Views`);
 
 				const rating_html = get_rating_html(this.item.average_rating);
-				const rating_count = this.item.no_of_ratings > 0 ? `${this.item.no_of_ratings} reviews` : __('No reviews yet');
+				const rating_count =
+					this.item.no_of_ratings > 0
+						? `${this.item.no_of_ratings} reviews`
+						: __('No reviews yet');
 
 				stats = [views_message, rating_html, rating_count];
 			}
@@ -136,7 +132,7 @@
 				return {
 					label: __('Contact Seller'),
 					action: this.contact_seller.bind(this)
-				}
+				};
 			} else {
 				return undefined;
 			}
@@ -156,7 +152,7 @@
 			setTimeout(() => {
 				hub.call('add_item_view', {
 					hub_item_name: this.hub_item_name
-				})
+				});
 				// .then(() => {
 				// 	erpnext.hub.item_view_cache.push(this.hub_item_name);
 				// });
@@ -167,12 +163,12 @@
 		get_item_details() {
 			this.item_received = hub.call('get_item_details', { hub_item_name: this.hub_item_name })
 				.then(item => {
-				this.init = false;
-				this.item = item;
+					this.init = false;
+					this.item = item;
 
-				this.build_data();
-				this.make_dialogs();
-			});
+					this.build_data();
+					this.make_dialogs();
+				});
 		},
 		go_to_seller_profile_page(seller_name) {
 			frappe.set_route(`marketplace/seller/${seller_name}`);
@@ -200,36 +196,41 @@
 		make_dialogs() {
 			this.make_contact_seller_dialog();
 			this.make_report_item_dialog();
+			this.make_editing_dialog();
 		},
 
 		add_to_saved_items() {
 			hub.call('add_item_to_user_saved_items', {
-				hub_item_name: this.hub_item_name,
-				hub_user: frappe.session.user
-			})
-			.then(() => {
-				const saved_items_link = `<b><a href="#marketplace/saved-items">${__('Saved')}</a></b>`
-				frappe.show_alert(saved_items_link);
-				erpnext.hub.trigger('action:item_save');
-			})
-			.catch(e => {
-				console.error(e);
-			});
+					hub_item_name: this.hub_item_name,
+					hub_user: frappe.session.user
+				})
+				.then(() => {
+					const saved_items_link = `<b><a href="#marketplace/saved-items">${__(
+						'Saved'
+					)}</a></b>`;
+					frappe.show_alert(saved_items_link);
+					erpnext.hub.trigger('action:item_save');
+				})
+				.catch(e => {
+					console.error(e);
+				});
 		},
 
 		add_to_featured_items() {
 			hub.call('add_item_to_seller_featured_items', {
-				hub_item_name: this.hub_item_name,
-				hub_user: frappe.session.user
-			},)
-			.then(() => {
-				const featured_items_link = `<b><a href="#marketplace/featured-items">${__('Added to Featured Items')}</a></b>`
-				frappe.show_alert(featured_items_link);
-				erpnext.hub.trigger('action:item_feature');
-			})
-			.catch(e => {
-				console.error(e);
-			});
+					hub_item_name: this.hub_item_name,
+					hub_user: frappe.session.user
+				})
+				.then(() => {
+					const featured_items_link = `<b><a href="#marketplace/featured-items">${__(
+						'Added to Featured Items'
+					)}</a></b>`;
+					frappe.show_alert(featured_items_link);
+					erpnext.hub.trigger('action:item_feature');
+				})
+				.catch(e => {
+					console.error(e);
+				});
 		},
 
 		make_contact_seller_dialog() {
@@ -252,13 +253,13 @@
 					if (!message) return;
 
 					hub.call('send_message', {
-						hub_item: this.item.name,
-						message
-					})
+							hub_item: this.item.name,
+							message
+						})
 						.then(() => {
 							this.contact_seller_dialog.hide();
 							frappe.set_route('marketplace', 'buying', this.item.name);
-							erpnext.hub.trigger('action:send_message')
+							erpnext.hub.trigger('action:send_message');
 						});
 				}
 			});
@@ -275,7 +276,10 @@
 					}
 				],
 				primary_action: ({ message }) => {
-					hub.call('add_reported_item', { hub_item_name: this.item.name, message })
+					hub.call('add_reported_item', {
+							hub_item_name: this.item.name,
+							message
+						})
 						.then(() => {
 							d.hide();
 							frappe.show_alert(__('Item Reported'));
@@ -284,26 +288,62 @@
 			});
 		},
 
+		make_editing_dialog() {
+			this.edit_dialog = edit_details_dialog({
+				primary_action: {
+					fn: values => {
+						this.update_details(values);
+						this.edit_dialog.hide();
+					}
+				},
+				defaults: {
+					item_name: this.item.item_name,
+					hub_category: this.item.hub_category,
+					description: this.item.description
+				}
+			});
+		},
+
+		update_details(values) {
+			frappe.call('erpnext.hub_node.api.update_item', {
+					ref_doc: this.item.name,
+					data: values
+				})
+				.then(r => {
+					return this.get_item_details();
+				})
+				.then(() => {
+					frappe.show_alert(__(`${this.item.item_name} Updated`));
+				});
+		},
+
 		contact_seller() {
 			this.contact_seller_dialog.show();
 		},
 
 		report_item() {
 			if (!hub.is_seller_registered()) {
-				frappe.throw(__('Please login as a Marketplace User to report this item.'));
+				frappe.throw(
+					__('Please login as a Marketplace User to report this item.')
+				);
 			}
 			this.report_item_dialog.show();
 		},
 
 		edit_details() {
-			frappe.msgprint(__('This feature is under development...'));
+			if (!hub.is_seller_registered()) {
+				frappe.throw(
+					__('Please login as a Marketplace User to edit this item.')
+				);
+			}
+			this.edit_dialog.show();
 		},
 
 		unpublish_item() {
 			frappe.msgprint(__('This feature is under development...'));
 		}
 	}
-}
+};
 </script>
 
 <style scoped></style>
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index d5a78d4..f363999 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -501,6 +501,7 @@
 	frm.doc[opts.child_docname].forEach(d => {
 		dialog.fields_dict.trans_items.df.data.push({
 			"docname": d.name,
+			"name": d.name,
 			"item_code": d.item_code,
 			"qty": d.qty,
 			"rate": d.rate,
diff --git a/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.json b/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.json
index 74370cc..a4e6aed 100644
--- a/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.json
+++ b/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.json
@@ -13,7 +13,7 @@
    "fieldname": "problem",
    "fieldtype": "Long Text",
    "in_list_view": 1,
-   "label": "Problem"
+   "label": "Review"
   },
   {
    "fieldname": "sb_00",
diff --git a/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json b/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json
index f5c0fbc..0a67fa5 100644
--- a/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json
+++ b/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json
@@ -18,7 +18,7 @@
    "fieldname": "procedure",
    "fieldtype": "Link",
    "in_list_view": 1,
-   "label": "Procedure",
+   "label": "Child Procedure",
    "options": "Quality Procedure"
   }
  ],
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 77bcc80..0f9156a 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -179,6 +179,8 @@
 
 	if not party_details.place_of_supply: return
 
+	if not party_details.company_gstin: return
+
 	if ((doctype in ("Sales Invoice", "Delivery Note", "Sales Order") and party_details.company_gstin
 		and party_details.company_gstin[:2] != party_details.place_of_supply[:2]) or (doctype in ("Purchase Invoice",
 		"Purchase Order", "Purchase Receipt") and party_details.supplier_gstin and party_details.supplier_gstin[:2] != party_details.place_of_supply[:2])):
diff --git a/erpnext/regional/report/gstr_2/gstr_2.py b/erpnext/regional/report/gstr_2/gstr_2.py
index a362269..f326fe0 100644
--- a/erpnext/regional/report/gstr_2/gstr_2.py
+++ b/erpnext/regional/report/gstr_2/gstr_2.py
@@ -44,12 +44,16 @@
 		for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
 			invoice_details = self.invoices.get(inv)
 			for rate, items in items_based_on_rate.items():
-				row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
-				tax_amount = taxable_value * rate / 100
-				if inv in self.igst_invoices:
-					row += [tax_amount, 0, 0]
+				if inv not in self.igst_invoices:
+					rate = rate / 2
+					row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
+					tax_amount = taxable_value * rate / 100
+					row += [0, tax_amount, tax_amount]
 				else:
-					row += [0, tax_amount / 2, tax_amount / 2]
+					row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
+					tax_amount = taxable_value * rate / 100
+					row += [tax_amount, 0, 0]
+
 
 				row += [
 					self.invoice_cess.get(inv),
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index cca8efe..aa1b92f 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -5,13 +5,13 @@
 	setup: function(frm) {
 
 		frm.make_methods = {
-			'Quotation': () => erpnext.utils.create_new_doc('Quotation', {
-				'quotation_to': frm.doc.doctype,
-				'party_name': frm.doc.name
+			'Quotation': () => frappe.model.open_mapped_doc({
+				method: "erpnext.selling.doctype.customer.customer.make_quotation",
+				frm: cur_frm
 			}),
-			'Opportunity': () => erpnext.utils.create_new_doc('Opportunity', {
-				'opportunity_from': frm.doc.doctype,
-				'party_name': frm.doc.name
+			'Opportunity': () => frappe.model.open_mapped_doc({
+				method: "erpnext.selling.doctype.customer.customer.make_opportunity",
+				frm: cur_frm
 			})
 		}
 
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 57308ce..136236c 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -12,6 +12,7 @@
 from erpnext.accounts.party import validate_party_accounts, get_dashboard_info, get_timeline_data # keep this
 from frappe.contacts.address_and_contact import load_address_and_contact, delete_contact_and_address
 from frappe.model.rename_doc import update_linked_doctypes
+from frappe.model.mapper import get_mapped_doc
 
 class Customer(TransactionBase):
 	def get_feed(self):
@@ -239,6 +240,66 @@
 	contact.insert()
 
 @frappe.whitelist()
+def make_quotation(source_name, target_doc=None):
+
+	def set_missing_values(source, target):
+		_set_missing_values(source, target)
+
+	target_doc = get_mapped_doc("Customer", source_name,
+		{"Customer": {
+			"doctype": "Quotation",
+			"field_map": {
+				"name":"party_name"
+			}
+		}}, target_doc, set_missing_values)
+
+	target_doc.quotation_to = "Customer"
+	target_doc.run_method("set_missing_values")
+	target_doc.run_method("set_other_charges")
+	target_doc.run_method("calculate_taxes_and_totals")
+
+	price_list = frappe.get_value("Customer", source_name, 'default_price_list')
+	if price_list:
+		target_doc.selling_price_list = price_list
+
+	return target_doc
+
+@frappe.whitelist()
+def make_opportunity(source_name, target_doc=None):
+	def set_missing_values(source, target):
+		_set_missing_values(source, target)
+
+	target_doc = get_mapped_doc("Customer", source_name,
+		{"Customer": {
+			"doctype": "Opportunity",
+			"field_map": {
+				"name": "party_name",
+				"doctype": "opportunity_from",
+			}
+		}}, target_doc, set_missing_values)
+
+	return target_doc
+
+def _set_missing_values(source, target):
+	address = frappe.get_all('Dynamic Link', {
+			'link_doctype': source.doctype,
+			'link_name': source.name,
+			'parenttype': 'Address',
+		}, ['parent'], limit=1)
+
+	contact = frappe.get_all('Dynamic Link', {
+			'link_doctype': source.doctype,
+			'link_name': source.name,
+			'parenttype': 'Contact',
+		}, ['parent'], limit=1)
+
+	if address:
+		target.customer_address = address[0].parent
+
+	if contact:
+		target.contact_person = contact[0].parent
+
+@frappe.whitelist()
 def get_loyalty_programs(doc):
 	''' returns applicable loyalty programs for a customer '''
 	from frappe.desk.treeview import get_children
diff --git a/erpnext/selling/onboarding_slide/add_a_few_customers/add_a_few_customers.json b/erpnext/selling/onboarding_slide/add_a_few_customers/add_a_few_customers.json
index f39fea4..92d00bc 100644
--- a/erpnext/selling/onboarding_slide/add_a_few_customers/add_a_few_customers.json
+++ b/erpnext/selling/onboarding_slide/add_a_few_customers/add_a_few_customers.json
@@ -12,9 +12,10 @@
   }
  ],
  "idx": 0,
- "image_src": "/assets/erpnext/images/illustrations/customers-onboard.png",
+ "image_src": "",
+ "is_completed": 0,
  "max_count": 3,
- "modified": "2019-12-03 22:54:28.959549",
+ "modified": "2019-12-09 17:54:01.686006",
  "modified_by": "Administrator",
  "name": "Add A Few Customers",
  "owner": "Administrator",
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js
index b213a29..33fbc22 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -286,14 +286,14 @@
 		if (in_list(['serial_no', 'batch_no'], field)) {
 			args[field] = value;
 		}
-
+		
 		// add to cur_frm
 		const item = this.frm.add_child('items', args);
 		frappe.flags.hide_serial_batch_dialog = true;
 
 		frappe.run_serially([
 			() => {
-				this.frm.script_manager.trigger('item_code', item.doctype, item.name)
+				return this.frm.script_manager.trigger('item_code', item.doctype, item.name)
 					.then(() => {
 						this.frm.script_manager.trigger('qty', item.doctype, item.name)
 							.then(() => {
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 2eee919..ff35154 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -14,6 +14,7 @@
 from frappe.contacts.address_and_contact import load_address_and_contact
 from frappe.utils.nestedset import NestedSet
 
+from past.builtins import cmp
 import functools
 
 class Company(NestedSet):
diff --git a/erpnext/setup/doctype/company/company_list.js b/erpnext/setup/doctype/company/company_list.js
new file mode 100644
index 0000000..0172865
--- /dev/null
+++ b/erpnext/setup/doctype/company/company_list.js
@@ -0,0 +1,10 @@
+frappe.listview_settings['Company'] = {
+    onload: () => {
+        frappe.breadcrumbs.add({
+            type: 'Custom',
+            module: __('Accounts'),
+            label: __('Accounts'),
+            route: '#modules/Accounts'
+        });
+    }
+}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/company/delete_company_transactions.py b/erpnext/setup/doctype/company/delete_company_transactions.py
index 637e655..1503adb 100644
--- a/erpnext/setup/doctype/company/delete_company_transactions.py
+++ b/erpnext/setup/doctype/company/delete_company_transactions.py
@@ -106,7 +106,10 @@
 		frappe.db.sql("""update tabCustomer set lead_name=NULL where lead_name in ({leads})""".format(leads=",".join(leads)))
 
 def delete_communications(doctype, company_name, company_fieldname):
-		frappe.db.sql("""
-			DELETE FROM `tabCommunication` WHERE reference_doctype = %s AND
-			EXISTS (SELECT name FROM `tab{0}` WHERE {1} = %s AND `tabCommunication`.reference_name = name)
-			""".format(doctype, company_fieldname), (doctype, company_name))
+		reference_docs = frappe.get_all(doctype, filters={company_fieldname:company_name})
+		reference_doc_names = [r.name for r in reference_docs]
+		
+		communications = frappe.get_all("Communication", filters={"reference_doctype":doctype,"reference_name":["in", reference_doc_names]})
+		communication_names = [c.name for c in communications]
+
+		frappe.delete_doc("Communication", communication_names)
diff --git a/erpnext/setup/doctype/company/test_company.py b/erpnext/setup/doctype/company/test_company.py
index 8d9c23a..1664b66 100644
--- a/erpnext/setup/doctype/company/test_company.py
+++ b/erpnext/setup/doctype/company/test_company.py
@@ -88,6 +88,57 @@
 					self.delete_mode_of_payment(template)
 					frappe.delete_doc("Company", template)
 
+	def test_delete_communication(self):
+		from erpnext.setup.doctype.company.delete_company_transactions import delete_communications
+		company = create_child_company()
+		lead = create_test_lead_in_company(company)
+		communication = create_company_communication("Lead", lead)
+		delete_communications("Lead", "Test Company", "company")
+		self.assertFalse(frappe.db.exists("Communcation", communication))
+		self.assertFalse(frappe.db.exists({"doctype":"Comunication Link", "link_name": communication}))
+
 	def delete_mode_of_payment(self, company):
 		frappe.db.sql(""" delete from `tabMode of Payment Account`
 			where company =%s """, (company))
+
+def create_company_communication(doctype, docname):
+	comm = frappe.get_doc({
+			"doctype": "Communication",
+			"communication_type": "Communication",
+			"content": "Deduplication of Links",
+			"communication_medium": "Email",
+			"reference_doctype":doctype,
+			"reference_name":docname
+		})
+	comm.insert()
+
+def create_child_company():
+	child_company = frappe.db.exists("Company", "Test Company")
+	if not child_company:
+		child_company = frappe.get_doc({
+			"doctype":"Company",
+			"company_name":"Test Company",
+			"abbr":"test_company",
+			"default_currency":"INR"
+		})
+		child_company.insert()
+	else:
+		child_company = frappe.get_doc("Company", child_company)
+	
+	return child_company.name
+
+def create_test_lead_in_company(company):
+	lead = frappe.db.exists("Lead", "Test Lead in new company")
+	if not lead:
+		lead = frappe.get_doc({
+			"doctype": "Lead",
+			"lead_name": "Test Lead in new company",
+			"scompany": company
+		})
+		lead.insert()
+	else:
+		lead = frappe.get_doc("Lead", lead)
+		lead.company = company
+		lead.save()
+	return lead.name
+
diff --git "a/erpnext/setup/onboarding_slide/welcome_back_to_erpnext\041/welcome_back_to_erpnext\041.json" "b/erpnext/setup/onboarding_slide/welcome_back_to_erpnext\041/welcome_back_to_erpnext\041.json"
index bf330d0..f00dc94 100644
--- "a/erpnext/setup/onboarding_slide/welcome_back_to_erpnext\041/welcome_back_to_erpnext\041.json"
+++ "b/erpnext/setup/onboarding_slide/welcome_back_to_erpnext\041/welcome_back_to_erpnext\041.json"
@@ -7,10 +7,10 @@
  "domains": [],
  "help_links": [],
  "idx": 0,
- "image_src": "/assets/erpnext/images/illustrations/desk-onboard.png",
+ "image_src": "",
  "is_completed": 0,
  "max_count": 3,
- "modified": "2019-12-04 19:21:39.995776",
+ "modified": "2019-12-09 17:53:53.849953",
  "modified_by": "Administrator",
  "name": "Welcome back to ERPNext!",
  "owner": "Administrator",
diff --git "a/erpnext/setup/onboarding_slide/welcome_to_erpnext\041/welcome_to_erpnext\041.json" "b/erpnext/setup/onboarding_slide/welcome_to_erpnext\041/welcome_to_erpnext\041.json"
index 4ea6985..37eb67b 100644
--- "a/erpnext/setup/onboarding_slide/welcome_to_erpnext\041/welcome_to_erpnext\041.json"
+++ "b/erpnext/setup/onboarding_slide/welcome_to_erpnext\041/welcome_to_erpnext\041.json"
@@ -7,13 +7,14 @@
  "domains": [],
  "help_links": [],
  "idx": 0,
- "image_src": "/assets/erpnext/images/illustrations/desk-onboard.png",
+ "image_src": "",
+ "is_completed": 0,
  "max_count": 0,
- "modified": "2019-12-03 22:49:12.871260",
+ "modified": "2019-12-22 21:26:28.414597",
  "modified_by": "Administrator",
  "name": "Welcome to ERPNext!",
  "owner": "Administrator",
- "slide_desc": "Setting up an ERP can be overwhelming. But don't worry, we have got your back!\nLet's setup your company.\nThis wizard will help you onboard to ERPNext in a short time!",
+ "slide_desc": "<div class=\"text center\">Setting up an ERP can be overwhelming. But don't worry, we have got your back! This wizard will help you onboard to ERPNext in a short time!</div>",
  "slide_fields": [],
  "slide_module": "Setup",
  "slide_order": 1,
diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py
index 3e890b4..1149254 100644
--- a/erpnext/stock/doctype/batch/batch.py
+++ b/erpnext/stock/doctype/batch/batch.py
@@ -261,15 +261,14 @@
 
 
 def get_batches(item_code, warehouse, qty=1, throw=False):
-	batches = frappe.db.sql(
-		'select batch_id, sum(actual_qty) as qty from `tabBatch` join `tabStock Ledger Entry` ignore index (item_code, warehouse) '
-		'on (`tabBatch`.batch_id = `tabStock Ledger Entry`.batch_no )'
-		'where `tabStock Ledger Entry`.item_code = %s and  `tabStock Ledger Entry`.warehouse = %s '
-		'and (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL)'
-		'group by batch_id '
-		'order by `tabBatch`.expiry_date ASC, `tabBatch`.creation ASC',
-		(item_code, warehouse),
-		as_dict=True
-	)
 
-	return batches
+	return frappe.db.sql("""
+		select batch_id, sum(`tabStock Ledger Entry`.actual_qty) as qty
+		from `tabBatch`
+			join `tabStock Ledger Entry` ignore index (item_code, warehouse)
+				on (`tabBatch`.batch_id = `tabStock Ledger Entry`.batch_no )
+		where `tabStock Ledger Entry`.item_code = %s and `tabStock Ledger Entry`.warehouse = %s
+			and (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL)
+		group by batch_id
+		order by `tabBatch`.expiry_date ASC, `tabBatch`.creation ASC'
+	""", (item_code, warehouse), as_dict=True)
\ No newline at end of file
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index a2aab3f..af8e132 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -135,8 +135,7 @@
   "publish_in_hub",
   "hub_category_to_publish",
   "hub_warehouse",
-  "synced_with_hub",
-  "manufacturers"
+  "synced_with_hub"
  ],
  "fields": [
   {
@@ -1017,12 +1016,6 @@
    "read_only": 1
   },
   {
-   "fieldname": "manufacturers",
-   "fieldtype": "Table",
-   "label": "Manufacturers",
-   "options": "Item Manufacturer"
-  },
-  {
    "depends_on": "eval:!doc.__islocal",
    "fieldname": "over_delivery_receipt_allowance",
    "fieldtype": "Float",
@@ -1049,7 +1042,7 @@
  "idx": 2,
  "image_field": "image",
  "max_attachments": 1,
- "modified": "2019-10-09 17:05:59.576119",
+ "modified": "2019-12-13 12:15:56.197246",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Item",
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 189261c..151be11 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -125,7 +125,6 @@
 		self.validate_auto_reorder_enabled_in_stock_settings()
 		self.cant_change()
 		self.update_show_in_website()
-		self.validate_manufacturer()
 
 		if not self.get("__islocal"):
 			self.old_item_group = frappe.db.get_value(self.doctype, self.name, "item_group")
@@ -145,13 +144,6 @@
 		if cint(frappe.db.get_single_value('Stock Settings', 'clean_description_html')):
 			self.description = clean_html(self.description)
 
-	def validate_manufacturer(self):
-		list_man = [(x.manufacturer, x.manufacturer_part_no) for x in self.get('manufacturers')]
-		set_man = set(list_man)
-
-		if len(list_man) != len(set_man):
-			frappe.throw(_("Duplicate entry in Manufacturers table"))
-
 	def validate_customer_provided_part(self):
 		if self.is_customer_provided_item:
 			if self.is_purchase_item:
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index d6bc1a9..27cd997 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "autoname": "naming_series:",
  "creation": "2013-05-21 16:16:39",
@@ -305,6 +306,7 @@
    "fieldname": "contact_email",
    "fieldtype": "Small Text",
    "label": "Contact Email",
+   "options": "Email",
    "print_hide": 1,
    "read_only": 1
   },
@@ -1056,7 +1058,8 @@
  "icon": "fa fa-truck",
  "idx": 261,
  "is_submittable": 1,
- "modified": "2019-09-27 14:24:49.044505",
+ "links": [],
+ "modified": "2019-12-24 12:52:17.216304",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt",
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 9b73d0f..691f92f 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -88,7 +88,7 @@
 
 		if getdate(self.posting_date) > getdate(nowdate()):
 			throw(_("Posting Date cannot be future date"))
-	
+
 	def validate_cwip_accounts(self):
 		for item in self.get('items'):
 			if item.is_fixed_asset and is_cwip_accounting_enabled(item.asset_category):
@@ -245,7 +245,7 @@
 					negative_expense_to_be_booked += flt(d.item_tax_amount)
 
 					# Amount added through landed-cost-voucher
-					if landed_cost_entries:
+					if d.landed_cost_voucher_amount and landed_cost_entries:
 						for account, amount in iteritems(landed_cost_entries[(d.item_code, d.name)]):
 							gl_entries.append(self.get_gl_dict({
 								"account": account,
@@ -362,7 +362,7 @@
 					# valuation rate is total of net rate, raw mat supp cost, tax amount, lcv amount per item
 					self.update_assets(item, item.valuation_rate)
 		return gl_entries
-	
+
 	def add_asset_gl_entries(self, item, gl_entries):
 		arbnb_account = self.get_company_default("asset_received_but_not_billed")
 		# This returns category's cwip account if not then fallback to company's default cwip account
@@ -395,7 +395,7 @@
 			"credit_in_account_currency": (base_asset_amount
 				if asset_rbnb_currency == self.company_currency else asset_amount)
 		}, item=item))
-	
+
 	def add_lcv_gl_entries(self, item, gl_entries):
 		expenses_included_in_asset_valuation = self.get_company_default("expenses_included_in_asset_valuation")
 		if not is_cwip_accounting_enabled(item.asset_category):
@@ -404,7 +404,7 @@
 		else:
 			# This returns company's default cwip account
 			asset_account = get_asset_account("capital_work_in_progress_account", company=self.company)
-		
+
 		gl_entries.append(self.get_gl_dict({
 			"account": expenses_included_in_asset_valuation,
 			"against": asset_account,
@@ -424,7 +424,7 @@
 		}, item=item))
 
 	def update_assets(self, item, valuation_rate):
-		assets = frappe.db.get_all('Asset', 
+		assets = frappe.db.get_all('Asset',
 			filters={ 'purchase_receipt': self.name, 'item_code': item.item_code }
 		)
 
@@ -610,28 +610,36 @@
 	return doclist
 
 def get_item_account_wise_additional_cost(purchase_document):
-	landed_cost_voucher = frappe.get_value("Landed Cost Purchase Receipt",
-		{"receipt_document": purchase_document}, "parent")
+	landed_cost_vouchers = frappe.get_all("Landed Cost Purchase Receipt", fields=["parent"],
+		filters = {"receipt_document": purchase_document, "docstatus": 1})
 
-	if not landed_cost_voucher:
+	if not landed_cost_vouchers:
 		return
 
 	total_item_cost = 0
 	item_account_wise_cost = {}
-	landed_cost_voucher_doc = frappe.get_doc("Landed Cost Voucher", landed_cost_voucher)
-	based_on_field = frappe.scrub(landed_cost_voucher_doc.distribute_charges_based_on)
+	item_cost_allocated = []
 
-	for item in landed_cost_voucher_doc.items:
-		if item.receipt_document == purchase_document:
-			total_item_cost += item.get(based_on_field)
+	for lcv in landed_cost_vouchers:
+		landed_cost_voucher_doc = frappe.get_cached_doc("Landed Cost Voucher", lcv.parent)
+		based_on_field = frappe.scrub(landed_cost_voucher_doc.distribute_charges_based_on)
 
-	for item in landed_cost_voucher_doc.items:
-		if item.receipt_document == purchase_document:
-			for account in landed_cost_voucher_doc.taxes:
-				item_account_wise_cost.setdefault((item.item_code, item.purchase_receipt_item), {})
-				item_account_wise_cost[(item.item_code, item.purchase_receipt_item)].setdefault(account.expense_account, 0.0)
-				item_account_wise_cost[(item.item_code, item.purchase_receipt_item)][account.expense_account] += \
-					account.amount * item.get(based_on_field) / total_item_cost
+		for item in landed_cost_voucher_doc.items:
+			if item.purchase_receipt_item not in item_cost_allocated:
+				total_item_cost += item.get(based_on_field)
+				item_cost_allocated.append(item.purchase_receipt_item)
+
+	for lcv in landed_cost_vouchers:
+		landed_cost_voucher_doc = frappe.get_cached_doc("Landed Cost Voucher", lcv.parent)
+		based_on_field = frappe.scrub(landed_cost_voucher_doc.distribute_charges_based_on)
+
+		for item in landed_cost_voucher_doc.items:
+			if item.receipt_document == purchase_document:
+				for account in landed_cost_voucher_doc.taxes:
+					item_account_wise_cost.setdefault((item.item_code, item.purchase_receipt_item), {})
+					item_account_wise_cost[(item.item_code, item.purchase_receipt_item)].setdefault(account.expense_account, 0.0)
+					item_account_wise_cost[(item.item_code, item.purchase_receipt_item)][account.expense_account] += \
+						account.amount * item.get(based_on_field) / total_item_cost
 
 	return item_account_wise_cost
 
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 4770471..79ce231 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -622,7 +622,7 @@
 					if(r.message) {
 						var d = locals[cdt][cdn];
 						$.each(r.message, function(k, v) {
-							d[k] = v;
+							frappe.model.set_value(cdt, cdn, k, v); // qty and it's subsequent fields weren't triggered
 						});
 						refresh_field("items");
 						erpnext.stock.select_batch_and_serial_no(frm, d);
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index f81fa68..1b9660e 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -372,7 +372,7 @@
 			elif d.t_warehouse and not d.basic_rate:
 				d.basic_rate = get_valuation_rate(d.item_code, d.t_warehouse,
 					self.doctype, self.name, d.allow_zero_valuation_rate,
-					currency=erpnext.get_company_currency(self.company))
+					currency=erpnext.get_company_currency(self.company), company=self.company)
 
 	def set_actual_qty(self):
 		allow_negative_stock = cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock"))
@@ -649,6 +649,12 @@
 		gl_entries = super(StockEntry, self).get_gl_entries(warehouse_account)
 
 		total_basic_amount = sum([flt(t.basic_amount) for t in self.get("items") if t.t_warehouse])
+		divide_based_on = total_basic_amount
+
+		if self.get("additional_costs") and not total_basic_amount:
+			# if total_basic_amount is 0, distribute additional charges based on qty
+			divide_based_on = sum(item.qty for item in list(self.get("items")))
+
 		item_account_wise_additional_cost = {}
 
 		for t in self.get("additional_costs"):
@@ -656,8 +662,11 @@
 				if d.t_warehouse:
 					item_account_wise_additional_cost.setdefault((d.item_code, d.name), {})
 					item_account_wise_additional_cost[(d.item_code, d.name)].setdefault(t.expense_account, 0.0)
+
+					multiply_based_on = d.basic_amount if total_basic_amount else d.qty
+
 					item_account_wise_additional_cost[(d.item_code, d.name)][t.expense_account] += \
-						(t.amount * d.basic_amount) / total_basic_amount
+						(t.amount * multiply_based_on) / divide_based_on
 
 		if item_account_wise_additional_cost:
 			for d in self.get("items"):
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index eddab5d..ee5f237 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -790,6 +790,50 @@
 			filters={"voucher_type": "Stock Entry", "voucher_no": mr.name}, fieldname="is_opening")
 		self.assertEqual(is_opening, "Yes")
 
+	def test_total_basic_amount_zero(self):
+		se = frappe.get_doc({"doctype":"Stock Entry",
+		"purpose":"Material Receipt",
+		"stock_entry_type":"Material Receipt",
+		"posting_date": nowdate(),
+		"company":"_Test Company with perpetual inventory",
+		"items":[
+			{
+				"item_code":"Basil Leaves",
+				"description":"Basil Leaves",
+				"qty": 1,
+				"basic_rate": 0,
+				"uom":"Nos",
+				"t_warehouse": "Stores - TCP1",
+				"allow_zero_valuation_rate": 1,
+				"cost_center": "Main - TCP1"
+			 },
+			 {
+				"item_code":"Basil Leaves",
+				"description":"Basil Leaves",
+				"qty": 2,
+				"basic_rate": 0,
+				"uom":"Nos",
+				"t_warehouse": "Stores - TCP1",
+				"allow_zero_valuation_rate": 1,
+				"cost_center": "Main - TCP1"
+			 },
+			 ],
+		"additional_costs":[
+			{"expense_account":"Miscellaneous Expenses - TCP1",
+			"amount":100,
+			"description": "miscellanous"}
+			]
+		})
+		se.insert()
+		se.submit()
+
+		self.check_gl_entries("Stock Entry", se.name,
+			sorted([
+				["Stock Adjustment - TCP1", 100.0, 0.0],
+				["Miscellaneous Expenses - TCP1", 0.0, 100.0]
+			])
+		)
+
 def make_serialized_item(item_code=None, serial_no=None, target_warehouse=None):
 	se = frappe.copy_doc(test_records[0])
 	se.get("items")[0].item_code = item_code or "_Test Serialized Item With Series"
diff --git a/erpnext/stock/onboarding_slide/add_a_few_products_you_buy_or_sell/add_a_few_products_you_buy_or_sell.json b/erpnext/stock/onboarding_slide/add_a_few_products_you_buy_or_sell/add_a_few_products_you_buy_or_sell.json
index 27a3062..5ee3167 100644
--- a/erpnext/stock/onboarding_slide/add_a_few_products_you_buy_or_sell/add_a_few_products_you_buy_or_sell.json
+++ b/erpnext/stock/onboarding_slide/add_a_few_products_you_buy_or_sell/add_a_few_products_you_buy_or_sell.json
@@ -7,9 +7,10 @@
  "domains": [],
  "help_links": [],
  "idx": 0,
- "image_src": "/assets/erpnext/images/illustrations/products-onboard.png",
+ "image_src": "",
+ "is_completed": 0,
  "max_count": 3,
- "modified": "2019-12-03 22:54:07.558632",
+ "modified": "2019-12-09 17:54:09.602885",
  "modified_by": "Administrator",
  "name": "Add A Few Products You Buy Or Sell",
  "owner": "Administrator",
diff --git a/erpnext/www/book_appointment/index.js b/erpnext/www/book_appointment/index.js
index c8dd501..262e31b 100644
--- a/erpnext/www/book_appointment/index.js
+++ b/erpnext/www/book_appointment/index.js
@@ -24,20 +24,15 @@
 }
 
 function setup_timezone_selector() {
-    /**
-     * window.timezones is a dictionary with the following structure
-     * { IANA name: Pretty name}
-     * For example : { Asia/Kolkata : "India Time - Asia/Kolkata"}
-     */
     let timezones_element = document.getElementById('appointment-timezone');
-    let offset = new Date().getTimezoneOffset();
-    Object.keys(window.timezones).forEach((timezone) => {
+    let local_timezone = moment.tz.guess()
+    window.timezones.forEach(timezone => {
         let opt = document.createElement('option');
         opt.value = timezone;
-        if (timezone == moment.tz.guess()) {
+        if (timezone == local_timezone) {
             opt.selected = true;
         }
-        opt.innerHTML = window.timezones[timezone]
+        opt.innerHTML = timezone;
         timezones_element.appendChild(opt)
     });
 }
@@ -114,7 +109,7 @@
         timeslot_div.classList.add('unavailable')
     }
     timeslot_div.innerHTML = get_slot_layout(start_time);
-    timeslot_div.id = timeslot.time.substr(11, 20);
+    timeslot_div.id = timeslot.time.substring(11, 19);
     timeslot_div.addEventListener('click', select_time);
     return timeslot_div
 }
diff --git a/erpnext/www/book_appointment/index.py b/erpnext/www/book_appointment/index.py
index 5b60dd5..7bfac89 100644
--- a/erpnext/www/book_appointment/index.py
+++ b/erpnext/www/book_appointment/index.py
@@ -25,18 +25,8 @@
 
 @frappe.whitelist(allow_guest=True)
 def get_timezones():
-	from babel.dates import get_timezone, get_timezone_name, Locale
-	from frappe.utils.momentjs import get_all_timezones
-
-	translated_dict = {}
-	locale = Locale.parse(frappe.local.lang, sep="-")
-
-	for tz in get_all_timezones():
-		timezone_name = get_timezone_name(get_timezone(tz), locale=locale, width='short')
-		if timezone_name:
-			translated_dict[tz] = timezone_name + ' - ' + tz
-
-	return translated_dict
+	import pytz
+	return pytz.all_timezones
 
 @frappe.whitelist(allow_guest=True)
 def get_appointment_slots(date, timezone):
@@ -90,7 +80,7 @@
 
 @frappe.whitelist(allow_guest=True)
 def create_appointment(date, time, tz, contact):
-	format_string = '%Y-%m-%d %H:%M:%S%z'
+	format_string = '%Y-%m-%d %H:%M:%S'
 	scheduled_time = datetime.datetime.strptime(date + " " + time, format_string)
 	# Strip tzinfo from datetime objects since it's handled by the doctype
 	scheduled_time = scheduled_time.replace(tzinfo = None)