Merge branch 'develop' into issue-condition-fix
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
index 03c3eb0..f96f591 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
@@ -293,6 +293,11 @@
 	accounts_dict = {}
 	for account in accounts:
 		accounts_dict.setdefault(account["account_name"], account)
+		if not hasattr(account, "parent_account"):
+			msg = _("Please make sure the file you are using has 'Parent Account' column present in the header.")
+			msg += "<br><br>"
+			msg += _("Alternatively, you can download the template and fill your data in.")
+			frappe.throw(msg, title=_("Parent Account Missing"))
 		if account["parent_account"] and accounts_dict.get(account["parent_account"]):
 			accounts_dict[account["parent_account"]]["is_group"] = 1
 
diff --git a/erpnext/selling/doctype/lead_source/__init__.py b/erpnext/crm/doctype/lead_source/__init__.py
similarity index 100%
rename from erpnext/selling/doctype/lead_source/__init__.py
rename to erpnext/crm/doctype/lead_source/__init__.py
diff --git a/erpnext/crm/doctype/lead_source/lead_source.js b/erpnext/crm/doctype/lead_source/lead_source.js
new file mode 100644
index 0000000..3cbe649
--- /dev/null
+++ b/erpnext/crm/doctype/lead_source/lead_source.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Lead Source', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/crm/doctype/lead_source/lead_source.json b/erpnext/crm/doctype/lead_source/lead_source.json
new file mode 100644
index 0000000..723c6d9
--- /dev/null
+++ b/erpnext/crm/doctype/lead_source/lead_source.json
@@ -0,0 +1,62 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "field:source_name",
+ "creation": "2016-09-16 01:47:47.382372",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "source_name",
+  "details"
+ ],
+ "fields": [
+  {
+   "fieldname": "source_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Source Name",
+   "reqd": 1,
+   "unique": 1
+  },
+  {
+   "fieldname": "details",
+   "fieldtype": "Text Editor",
+   "label": "Details"
+  }
+ ],
+ "links": [],
+ "modified": "2021-02-08 12:51:48.971517",
+ "modified_by": "Administrator",
+ "module": "CRM",
+ "name": "Lead Source",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Sales Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Sales User",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC"
+}
\ No newline at end of file
diff --git a/erpnext/selling/doctype/lead_source/lead_source.py b/erpnext/crm/doctype/lead_source/lead_source.py
similarity index 71%
rename from erpnext/selling/doctype/lead_source/lead_source.py
rename to erpnext/crm/doctype/lead_source/lead_source.py
index d2d7558..5c64fb8 100644
--- a/erpnext/selling/doctype/lead_source/lead_source.py
+++ b/erpnext/crm/doctype/lead_source/lead_source.py
@@ -1,9 +1,9 @@
 # -*- coding: utf-8 -*-
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
-import frappe
+# import frappe
 from frappe.model.document import Document
 
 class LeadSource(Document):
diff --git a/erpnext/crm/doctype/lead_source/test_lead_source.py b/erpnext/crm/doctype/lead_source/test_lead_source.py
new file mode 100644
index 0000000..b5bc649
--- /dev/null
+++ b/erpnext/crm/doctype/lead_source/test_lead_source.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestLeadSource(unittest.TestCase):
+	pass
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index c2798a3..2e26fd2 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -260,7 +260,10 @@
 			"erpnext.regional.italy.utils.sales_invoice_on_cancel",
 			"erpnext.erpnext_integrations.taxjar_integration.delete_transaction"
 		],
-		"on_trash": "erpnext.regional.check_deletion_permission"
+		"on_trash": "erpnext.regional.check_deletion_permission",
+		"validate": [
+			"erpnext.regional.india.utils.validate_document_name"
+		]
 	},
 	"Purchase Invoice": {
 		"validate": [
@@ -282,9 +285,6 @@
 	('Sales Invoice', 'Sales Order', 'Delivery Note', 'Purchase Invoice', 'Purchase Order', 'Purchase Receipt'): {
 		'validate': ['erpnext.regional.india.utils.set_place_of_supply']
 	},
-	('Sales Invoice', 'Purchase Invoice'): {
-		'validate': ['erpnext.regional.india.utils.validate_document_name']
-	},
 	"Contact": {
 		"on_trash": "erpnext.support.doctype.issue.issue.update_issue",
 		"after_insert": "erpnext.telephony.doctype.call_log.call_log.link_existing_conversations",
diff --git a/erpnext/hr/workspace/hr/hr.json b/erpnext/hr/workspace/hr/hr.json
index f650b24..f4b56a0 100644
--- a/erpnext/hr/workspace/hr/hr.json
+++ b/erpnext/hr/workspace/hr/hr.json
@@ -15,6 +15,7 @@
  "hide_custom": 0,
  "icon": "hr",
  "idx": 0,
+ "is_default": 0,
  "is_standard": 1,
  "label": "HR",
  "links": [
@@ -227,41 +228,11 @@
    "type": "Card Break"
   },
   {
-   "dependencies": "Employee",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Leave Application",
-   "link_to": "Leave Application",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Employee",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Leave Allocation",
-   "link_to": "Leave Allocation",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Leave Type",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Leave Policy",
-   "link_to": "Leave Policy",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
    "dependencies": "",
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Leave Period",
-   "link_to": "Leave Period",
+   "label": "Holiday List",
+   "link_to": "Holiday List",
    "link_type": "DocType",
    "onboard": 0,
    "type": "Link"
@@ -280,8 +251,28 @@
    "dependencies": "",
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Holiday List",
-   "link_to": "Holiday List",
+   "label": "Leave Period",
+   "link_to": "Leave Period",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Leave Type",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Leave Policy",
+   "link_to": "Leave Policy",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Leave Policy",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Leave Policy Assignment",
+   "link_to": "Leave Policy Assignment",
    "link_type": "DocType",
    "onboard": 0,
    "type": "Link"
@@ -290,8 +281,18 @@
    "dependencies": "Employee",
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Compensatory Leave Request",
-   "link_to": "Compensatory Leave Request",
+   "label": "Leave Application",
+   "link_to": "Leave Application",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Employee",
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Leave Allocation",
+   "link_to": "Leave Allocation",
    "link_type": "DocType",
    "onboard": 0,
    "type": "Link"
@@ -317,12 +318,12 @@
    "type": "Link"
   },
   {
-   "dependencies": "Leave Application",
+   "dependencies": "Employee",
    "hidden": 0,
-   "is_query_report": 1,
-   "label": "Employee Leave Balance",
-   "link_to": "Employee Leave Balance",
-   "link_type": "Report",
+   "is_query_report": 0,
+   "label": "Compensatory Leave Request",
+   "link_to": "Compensatory Leave Request",
+   "link_type": "DocType",
    "onboard": 0,
    "type": "Link"
   },
@@ -384,16 +385,6 @@
    "type": "Link"
   },
   {
-   "dependencies": "Attendance",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Monthly Attendance Sheet",
-   "link_to": "Monthly Attendance Sheet",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
    "hidden": 0,
    "is_query_report": 0,
    "label": "Expense Claims",
@@ -423,6 +414,15 @@
   {
    "hidden": 0,
    "is_query_report": 0,
+   "label": "Travel Request",
+   "link_to": "Travel Request",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
    "label": "Settings",
    "onboard": 0,
    "type": "Card Break"
@@ -465,6 +465,15 @@
    "type": "Card Break"
   },
   {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Driver",
+   "link_to": "Driver",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
    "dependencies": "",
    "hidden": 0,
    "is_query_report": 0,
@@ -544,6 +553,24 @@
   {
    "hidden": 0,
    "is_query_report": 0,
+   "label": "Appointment Letter",
+   "link_to": "Appointment Letter",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Appointment Letter Template",
+   "link_to": "Appointment Letter Template",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
    "label": "Loans",
    "onboard": 0,
    "type": "Card Break"
@@ -628,33 +655,6 @@
   {
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Reports",
-   "onboard": 0,
-   "type": "Card Break"
-  },
-  {
-   "dependencies": "Employee",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Employee Birthday",
-   "link_to": "Employee Birthday",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Employee",
-   "hidden": 0,
-   "is_query_report": 1,
-   "label": "Employees working on a holiday",
-   "link_to": "Employees working on a holiday",
-   "link_type": "Report",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "hidden": 0,
-   "is_query_report": 0,
    "label": "Performance",
    "onboard": 0,
    "type": "Card Break"
@@ -702,7 +702,74 @@
   {
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Employee Tax and Benefits",
+   "label": "Key Reports",
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "dependencies": "Attendance",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Monthly Attendance Sheet",
+   "link_to": "Monthly Attendance Sheet",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Staffing Plan",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Recruitment Analytics",
+   "link_to": "Recruitment Analytics",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Employee",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Employee Analytics",
+   "link_to": "Employee Analytics",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Employee",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Employee Leave Balance",
+   "link_to": "Employee Leave Balance",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Employee",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Employee Leave Balance Summary",
+   "link_to": "Employee Leave Balance Summary",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "dependencies": "Employee Advance",
+   "hidden": 0,
+   "is_query_report": 1,
+   "label": "Employee Advance Summary",
+   "link_to": "Employee Advance Summary",
+   "link_type": "Report",
+   "onboard": 0,
+   "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Other Reports",
    "onboard": 0,
    "type": "Card Break"
   },
@@ -710,74 +777,44 @@
    "dependencies": "Employee",
    "hidden": 0,
    "is_query_report": 0,
-   "label": "Employee Tax Exemption Declaration",
-   "link_to": "Employee Tax Exemption Declaration",
-   "link_type": "DocType",
+   "label": "Employee Information",
+   "link_to": "Employee Information",
+   "link_type": "Report",
    "onboard": 0,
    "type": "Link"
   },
   {
    "dependencies": "Employee",
    "hidden": 0,
-   "is_query_report": 0,
-   "label": "Employee Tax Exemption Proof Submission",
-   "link_to": "Employee Tax Exemption Proof Submission",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Employee, Payroll Period",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Employee Other Income",
-   "link_to": "Employee Other Income",
-   "link_type": "DocType",
+   "is_query_report": 1,
+   "label": "Employee Birthday",
+   "link_to": "Employee Birthday",
+   "link_type": "Report",
    "onboard": 0,
    "type": "Link"
   },
   {
    "dependencies": "Employee",
    "hidden": 0,
-   "is_query_report": 0,
-   "label": "Employee Benefit Application",
-   "link_to": "Employee Benefit Application",
-   "link_type": "DocType",
+   "is_query_report": 1,
+   "label": "Employees Working on a Holiday",
+   "link_to": "Employees working on a holiday",
+   "link_type": "Report",
    "onboard": 0,
    "type": "Link"
   },
   {
-   "dependencies": "Employee",
+   "dependencies": "Daily Work Summary",
    "hidden": 0,
-   "is_query_report": 0,
-   "label": "Employee Benefit Claim",
-   "link_to": "Employee Benefit Claim",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Employee",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Employee Tax Exemption Category",
-   "link_to": "Employee Tax Exemption Category",
-   "link_type": "DocType",
-   "onboard": 0,
-   "type": "Link"
-  },
-  {
-   "dependencies": "Employee",
-   "hidden": 0,
-   "is_query_report": 0,
-   "label": "Employee Tax Exemption Sub Category",
-   "link_to": "Employee Tax Exemption Sub Category",
-   "link_type": "DocType",
+   "is_query_report": 1,
+   "label": "Daily Work Summary Replies",
+   "link_to": "Daily Work Summary Replies",
+   "link_type": "Report",
    "onboard": 0,
    "type": "Link"
   }
  ],
- "modified": "2021-01-21 13:38:38.941001",
+ "modified": "2021-03-24 17:35:21.483297",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "HR",
diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
index a88e183..5d57ced 100644
--- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
+++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
@@ -21,6 +21,7 @@
 	def validate(self):
 		amounts = calculate_amounts(self.against_loan, self.posting_date)
 		self.set_missing_values(amounts)
+		self.check_future_entries()
 		self.validate_amount()
 		self.allocate_amounts(amounts)
 
@@ -69,6 +70,13 @@
 		if amounts.get('due_date'):
 			self.due_date = amounts.get('due_date')
 
+	def check_future_entries(self):
+		future_repayment_date = frappe.db.get_value("Loan Repayment", {"posting_date": (">", self.posting_date),
+			"docstatus": 1, "against_loan": self.against_loan}, 'posting_date')
+
+		if future_repayment_date:
+			frappe.throw("Repayment already made till date {0}".format(getdate(future_repayment_date)))
+
 	def validate_amount(self):
 		precision = cint(frappe.db.get_default("currency_precision")) or 2
 
@@ -307,7 +315,9 @@
 
 	return lr
 
-def get_accrued_interest_entries(against_loan):
+def get_accrued_interest_entries(against_loan, posting_date=None):
+	if not posting_date:
+		posting_date = getdate()
 
 	unpaid_accrued_entries = frappe.db.sql(
 		"""
@@ -318,12 +328,13 @@
 				`tabLoan Interest Accrual`
 			WHERE
 				loan = %s
+			AND posting_date <= %s
 			AND (interest_amount - paid_interest_amount > 0 OR
 				payable_principal_amount - paid_principal_amount > 0)
 			AND
 				docstatus = 1
 			ORDER BY posting_date
-		""", (against_loan), as_dict=1)
+		""", (against_loan, posting_date), as_dict=1)
 
 	return unpaid_accrued_entries
 
@@ -335,7 +346,7 @@
 
 	against_loan_doc = frappe.get_doc("Loan", against_loan)
 	loan_type_details = frappe.get_doc("Loan Type", against_loan_doc.loan_type)
-	accrued_interest_entries = get_accrued_interest_entries(against_loan_doc.name)
+	accrued_interest_entries = get_accrued_interest_entries(against_loan_doc.name, posting_date)
 
 	pending_accrual_entries = {}
 
diff --git a/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json b/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json
index 2f4fe24..3d07081 100644
--- a/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json
+++ b/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json
@@ -70,7 +70,9 @@
   {
    "fieldname": "loan_repayment_entry",
    "fieldtype": "Link",
+   "hidden": 1,
    "label": "Loan Repayment Entry",
+   "no_copy": 1,
    "options": "Loan Repayment",
    "read_only": 1
   },
@@ -83,9 +85,10 @@
    "read_only": 1
   }
  ],
+ "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-04-16 13:17:04.798335",
+ "modified": "2021-03-14 20:47:11.725818",
  "modified_by": "Administrator",
  "module": "Loan Management",
  "name": "Salary Slip Loan",
diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py
index 4050a7d..cd61d2a 100644
--- a/erpnext/manufacturing/doctype/bom/test_bom.py
+++ b/erpnext/manufacturing/doctype/bom/test_bom.py
@@ -5,7 +5,7 @@
 from __future__ import unicode_literals
 import unittest
 import frappe
-from frappe.utils import cstr
+from frappe.utils import cstr, flt
 from frappe.test_runner import make_test_records
 from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
 from erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool import update_cost
@@ -81,15 +81,27 @@
 		bom = frappe.copy_doc(test_records[2])
 		bom.insert()
 
-		# test amounts in selected currency
-		self.assertEqual(bom.operating_cost, 100)
-		self.assertEqual(bom.raw_material_cost, 351.68)
-		self.assertEqual(bom.total_cost, 451.68)
+		raw_material_cost = 0.0
+		op_cost = 0.0
+
+		for op_row in bom.operations:
+			op_cost += op_row.operating_cost
+
+		for row in bom.items:
+			raw_material_cost += row.amount
+
+		base_raw_material_cost = raw_material_cost * flt(bom.conversion_rate, bom.precision("conversion_rate"))
+		base_op_cost = op_cost * flt(bom.conversion_rate, bom.precision("conversion_rate"))
 
 		# test amounts in selected currency
-		self.assertEqual(bom.base_operating_cost, 6000)
-		self.assertEqual(bom.base_raw_material_cost, 21100.80)
-		self.assertEqual(bom.base_total_cost, 27100.80)
+		self.assertEqual(bom.operating_cost, op_cost)
+		self.assertEqual(bom.raw_material_cost, raw_material_cost)
+		self.assertEqual(bom.total_cost, raw_material_cost + op_cost)
+
+		# test amounts in selected currency
+		self.assertEqual(bom.base_operating_cost, base_op_cost)
+		self.assertEqual(bom.base_raw_material_cost, base_raw_material_cost)
+		self.assertEqual(bom.base_total_cost, base_raw_material_cost + base_op_cost)
 
 	def test_bom_cost_multi_uom_multi_currency_based_on_price_list(self):
 		frappe.db.set_value("Price List", "_Test Price List", "price_not_uom_dependent", 1)
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index 8aa0ffd..92074c6 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -47,6 +47,8 @@
 				if d.completed_qty:
 					self.total_completed_qty += d.completed_qty
 
+			self.total_completed_qty = flt(self.total_completed_qty, self.precision("total_completed_qty"))
+
 	def get_overlap_for(self, args, check_next_available_slot=False):
 		production_capacity = 1
 
diff --git a/erpnext/patches/v7_1/update_lead_source.py b/erpnext/patches/v7_1/update_lead_source.py
index 517e66c..a2a48a6 100644
--- a/erpnext/patches/v7_1/update_lead_source.py
+++ b/erpnext/patches/v7_1/update_lead_source.py
@@ -5,7 +5,7 @@
 def execute():
 	from erpnext.setup.setup_wizard.operations.install_fixtures import default_lead_sources
 
-	frappe.reload_doc('selling', 'doctype', 'lead_source')
+	frappe.reload_doc('crm', 'doctype', 'lead_source')
 
 	frappe.local.lang = frappe.db.get_default("lang") or 'en'
 
diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js
index 395e56f..85bb651 100644
--- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js
+++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js
@@ -133,45 +133,59 @@
 				}
 			};
 		});
+
+		frm.set_query('employee', 'employees', () => {
+			if (!frm.doc.company) {
+				frappe.msgprint(__("Please set a Company"));
+				return [];
+			}
+			return {
+				query: "erpnext.payroll.doctype.payroll_entry.payroll_entry.employee_query",
+				filters: frm.events.get_employee_filters(frm)
+			};
+		});
+	},
+
+	get_employee_filters: function (frm) {
+		let filters = {};
+		filters['company'] = frm.doc.company;
+		filters['start_date'] = frm.doc.start_date;
+		filters['end_date'] = frm.doc.end_date;
+
+		if (frm.doc.department) {
+			filters['department'] = frm.doc.department;
+		}
+		if (frm.doc.branch) {
+			filters['branch'] = frm.doc.branch;
+		}
+		if (frm.doc.designation) {
+			filters['designation'] = frm.doc.designation;
+		}
+		if (frm.doc.employees) {
+			filters['employees'] = frm.doc.employees.filter(d => d.employee).map(d => d.employee);
+		}
+		return filters;
 	},
 
 	payroll_frequency: function (frm) {
 		frm.trigger("set_start_end_dates").then( ()=> {
 			frm.events.clear_employee_table(frm);
-			frm.events.get_employee_with_salary_slip_and_set_query(frm);
-		});
-	},
-
-	employee_filters: function (frm, emp_list) {
-		frm.set_query('employee', 'employees', () => {
-			return {
-				filters: {
-					name: ["not in", emp_list]
-				}
-			};
-		});
-	},
-
-	get_employee_with_salary_slip_and_set_query: function (frm) {
-		frappe.db.get_list('Salary Slip', {
-			filters: {
-				start_date: frm.doc.start_date,
-				end_date: frm.doc.end_date,
-				docstatus: 1,
-			},
-			fields: ['employee']
-		}).then((emp) => {
-			var emp_list = [];
-			emp.forEach((employee_data) => {
-				emp_list.push(Object.values(employee_data)[0]);
-			});
-			frm.events.employee_filters(frm, emp_list);
 		});
 	},
 
 	company: function (frm) {
 		frm.events.clear_employee_table(frm);
 		erpnext.accounts.dimensions.update_dimension(frm, frm.doctype);
+		frm.trigger("set_payable_account_and_currency");
+	},
+
+	set_payable_account_and_currency: function (frm) {
+		frappe.db.get_value("Company", {"name": frm.doc.company}, "default_currency", (r) => {
+			frm.set_value('currency', r.default_currency);
+		});
+		frappe.db.get_value("Company", {"name": frm.doc.company}, "default_payroll_payable_account", (r) => {
+			frm.set_value('payroll_payable_account', r.default_payroll_payable_account);
+		});
 	},
 
 	currency: function (frm) {
@@ -345,11 +359,3 @@
 		})
 	);
 };
-
-frappe.ui.form.on('Payroll Employee Detail', {
-	employee: function(frm) {
-		if (!frm.doc.payroll_frequency) {
-			frappe.throw(__("Please set a Payroll Frequency"));
-		}
-	}
-});
diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py
index 7890471..fde2e07 100644
--- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py
+++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py
@@ -10,16 +10,17 @@
 from frappe import _
 from erpnext.accounts.utils import get_fiscal_year
 from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee
+from frappe.desk.reportview import get_match_cond, get_filters_cond
 
 class PayrollEntry(Document):
 	def onload(self):
 		if not self.docstatus==1 or self.salary_slips_submitted:
-    			return
+			return
 
 		# check if salary slips were manually submitted
 		entries = frappe.db.count("Salary Slip", {'payroll_entry': self.name, 'docstatus': 1}, ['name'])
 		if cint(entries) == len(self.employees):
-				self.set_onload("submitted_ss", True)
+			self.set_onload("submitted_ss", True)
 
 	def validate(self):
 		self.number_of_employees = len(self.employees)
@@ -59,16 +60,16 @@
 			condition = """and payroll_frequency = '%(payroll_frequency)s'"""% {"payroll_frequency": self.payroll_frequency}
 
 		sal_struct = frappe.db.sql_list("""
-				select
-					name from `tabSalary Structure`
-				where
-					docstatus = 1 and
-					is_active = 'Yes'
-					and company = %(company)s
-					and currency = %(currency)s and
-					ifnull(salary_slip_based_on_timesheet,0) = %(salary_slip_based_on_timesheet)s
-					{condition}""".format(condition=condition),
-				{"company": self.company, "currency": self.currency, "salary_slip_based_on_timesheet":self.salary_slip_based_on_timesheet})
+			select
+				name from `tabSalary Structure`
+			where
+				docstatus = 1 and
+				is_active = 'Yes'
+				and company = %(company)s
+				and currency = %(currency)s and
+				ifnull(salary_slip_based_on_timesheet,0) = %(salary_slip_based_on_timesheet)s
+				{condition}""".format(condition=condition),
+			{"company": self.company, "currency": self.currency, "salary_slip_based_on_timesheet":self.salary_slip_based_on_timesheet})
 
 		if sal_struct:
 			cond += "and t2.salary_structure IN %(sal_struct)s "
@@ -176,15 +177,15 @@
 		"""
 			Returns list of salary slips based on selected criteria
 		"""
-		cond = self.get_filter_condition()
 
 		ss_list = frappe.db.sql("""
 			select t1.name, t1.salary_structure, t1.payroll_cost_center from `tabSalary Slip` t1
-			where t1.docstatus = %s and t1.start_date >= %s and t1.end_date <= %s
-			and (t1.journal_entry is null or t1.journal_entry = "") and ifnull(salary_slip_based_on_timesheet,0) = %s %s
-		""" % ('%s', '%s', '%s','%s', cond), (ss_status, self.start_date, self.end_date, self.salary_slip_based_on_timesheet), as_dict=as_dict)
+			where t1.docstatus = %s and t1.start_date >= %s and t1.end_date <= %s and t1.payroll_entry = %s
+			and (t1.journal_entry is null or t1.journal_entry = "") and ifnull(salary_slip_based_on_timesheet,0) = %s
+		""", (ss_status, self.start_date, self.end_date, self.name, self.salary_slip_based_on_timesheet), as_dict=as_dict)
 		return ss_list
 
+	@frappe.whitelist()
 	def submit_salary_slips(self):
 		self.check_permission('write')
 		ss_list = self.get_sal_slip_list(ss_status=0)
@@ -270,26 +271,26 @@
 				exchange_rate, amt = self.get_amount_and_exchange_rate_for_journal_entry(acc_cc[0], amount, company_currency, currencies)
 				payable_amount += flt(amount, precision)
 				accounts.append({
-						"account": acc_cc[0],
-						"debit_in_account_currency": flt(amt, precision),
-						"exchange_rate": flt(exchange_rate),
-						"party_type": '',
-						"cost_center": acc_cc[1] or self.cost_center,
-						"project": self.project
-					})
+					"account": acc_cc[0],
+					"debit_in_account_currency": flt(amt, precision),
+					"exchange_rate": flt(exchange_rate),
+					"party_type": '',
+					"cost_center": acc_cc[1] or self.cost_center,
+					"project": self.project
+				})
 
 			# Deductions
 			for acc_cc, amount in deductions.items():
 				exchange_rate, amt = self.get_amount_and_exchange_rate_for_journal_entry(acc_cc[0], amount, company_currency, currencies)
 				payable_amount -= flt(amount, precision)
 				accounts.append({
-						"account": acc_cc[0],
-						"credit_in_account_currency": flt(amt, precision),
-						"exchange_rate": flt(exchange_rate),
-						"cost_center": acc_cc[1] or self.cost_center,
-						"party_type": '',
-						"project": self.project
-					})
+					"account": acc_cc[0],
+					"credit_in_account_currency": flt(amt, precision),
+					"exchange_rate": flt(exchange_rate),
+					"cost_center": acc_cc[1] or self.cost_center,
+					"party_type": '',
+					"project": self.project
+				})
 
 			# Payable amount
 			exchange_rate, payable_amt = self.get_amount_and_exchange_rate_for_journal_entry(payroll_payable_account, payable_amount, company_currency, currencies)
@@ -335,10 +336,9 @@
 	def make_payment_entry(self):
 		self.check_permission('write')
 
-		cond = self.get_filter_condition()
 		salary_slip_name_list = frappe.db.sql(""" select t1.name from `tabSalary Slip` t1
-			where t1.docstatus = 1 and start_date >= %s and end_date <= %s %s
-			""" % ('%s', '%s', cond), (self.start_date, self.end_date), as_list = True)
+			where t1.docstatus = 1 and start_date >= %s and end_date <= %s and t1.payroll_entry = %s
+			""", (self.start_date, self.end_date, self.name), as_list = True)
 
 		if salary_slip_name_list and len(salary_slip_name_list) > 0:
 			salary_slip_total = 0
@@ -370,20 +370,20 @@
 
 		exchange_rate, amount = self.get_amount_and_exchange_rate_for_journal_entry(self.payment_account, je_payment_amount, company_currency, currencies)
 		accounts.append({
-				"account": self.payment_account,
-				"bank_account": self.bank_account,
-				"credit_in_account_currency": flt(amount, precision),
-				"exchange_rate": flt(exchange_rate),
-			})
+			"account": self.payment_account,
+			"bank_account": self.bank_account,
+			"credit_in_account_currency": flt(amount, precision),
+			"exchange_rate": flt(exchange_rate),
+		})
 
 		exchange_rate, amount = self.get_amount_and_exchange_rate_for_journal_entry(payroll_payable_account, je_payment_amount, company_currency, currencies)
 		accounts.append({
-				"account": payroll_payable_account,
-				"debit_in_account_currency": flt(amount, precision),
-				"exchange_rate": flt(exchange_rate),
-				"reference_type": self.doctype,
-				"reference_name": self.name
-			})
+			"account": payroll_payable_account,
+			"debit_in_account_currency": flt(amount, precision),
+			"exchange_rate": flt(exchange_rate),
+			"reference_type": self.doctype,
+			"reference_name": self.name
+		})
 
 		if len(currencies) > 1:
 				multi_currency = 1
@@ -409,6 +409,7 @@
 		self.update(get_start_end_dates(self.payroll_frequency,
 			self.start_date or self.posting_date, self.company))
 
+	@frappe.whitelist()
 	def validate_employee_attendance(self):
 		employees_to_mark_attendance = []
 		days_in_payroll, days_holiday, days_attendance_marked = 0, 0, 0
@@ -424,7 +425,7 @@
 				employees_to_mark_attendance.append({
 					"employee": employee_detail.employee,
 					"employee_name": employee_detail.employee_name
-					})
+				})
 		return employees_to_mark_attendance
 
 	def get_count_holidays_of_employee(self, employee, start_date):
@@ -441,11 +442,11 @@
 	def get_count_employee_attendance(self, employee, start_date):
 		marked_days = 0
 		attendances = frappe.get_all("Attendance",
-				fields = ["count(*)"],
-				filters = {
-					"employee": employee,
-					"attendance_date": ('between', [start_date, self.end_date])
-				}, as_list=1)
+			fields = ["count(*)"],
+			filters = {
+				"employee": employee,
+				"attendance_date": ('between', [start_date, self.end_date])
+			}, as_list=1)
 		if attendances and attendances[0][0]:
 			marked_days = attendances[0][0]
 		return marked_days
@@ -553,6 +554,7 @@
 def create_salary_slips_for_employees(employees, args, publish_progress=True):
 	salary_slips_exists_for = get_existing_salary_slips(employees, args)
 	count=0
+	salary_slips_not_created = []
 	for emp in employees:
 		if emp not in salary_slips_exists_for:
 			args.update({
@@ -566,33 +568,24 @@
 				frappe.publish_progress(count*100/len(set(employees) - set(salary_slips_exists_for)),
 					title = _("Creating Salary Slips..."))
 		else:
-			salary_slip_name = frappe.db.sql(
-				'''SELECT
-						name
-					FROM `tabSalary Slip`
-					WHERE company=%s
-					AND start_date >= %s
-					AND end_date <= %s
-					AND employee = %s
-				''', (args.company, args.start_date, args.end_date, emp), as_dict=True)
-
-			salary_slip_doc = frappe.get_doc('Salary Slip', salary_slip_name[0].name)
-			salary_slip_doc.exchange_rate = args.exchange_rate
-			salary_slip_doc.set_totals()
-			salary_slip_doc.db_update()
+			salary_slips_not_created.append(emp)
 
 	payroll_entry = frappe.get_doc("Payroll Entry", args.payroll_entry)
 	payroll_entry.db_set("salary_slips_created", 1)
 	payroll_entry.notify_update()
 
+	if salary_slips_not_created:
+		frappe.msgprint(_("Salary Slips already exists for employees {}, and will not be processed by this payroll.")
+			.format(frappe.bold(", ".join([emp for emp in salary_slips_not_created]))) , title=_("Message"), indicator="orange")
+
 def get_existing_salary_slips(employees, args):
 	return frappe.db.sql_list("""
 		select distinct employee from `tabSalary Slip`
-		where docstatus!= 2 and company = %s
+		where docstatus!= 2 and company = %s and payroll_entry = %s
 			and start_date >= %s and end_date <= %s
 			and employee in (%s)
-	""" % ('%s', '%s', '%s', ', '.join(['%s']*len(employees))),
-		[args.company, args.start_date, args.end_date] + employees)
+	""" % ('%s', '%s', '%s', '%s', ', '.join(['%s']*len(employees))),
+		[args.company, args.payroll_entry, args.start_date, args.end_date] + employees)
 
 def submit_salary_slips_for_employees(payroll_entry, salary_slips, publish_progress=True):
 	submitted_ss = []
@@ -644,3 +637,61 @@
 			'txt': "%%%s%%" % frappe.db.escape(txt),
 			'start': start, 'page_len': page_len
 		})
+
+def get_employee_with_existing_salary_slip(start_date, end_date, company):
+	return frappe.db.sql_list("""
+		select employee from `tabSalary Slip`
+		where
+			(start_date between %(start_date)s and %(end_date)s
+		or
+			end_date between %(start_date)s and %(end_date)s
+		or
+			%(start_date)s between start_date and end_date)
+		and company = %(company)s
+		and docstatus = 1
+	""", {'start_date': start_date, 'end_date': end_date, 'company': company})
+
+@frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
+def employee_query(doctype, txt, searchfield, start, page_len, filters):
+	filters = frappe._dict(filters)
+	conditions = []
+	exclude_employees = []
+	emp_cond = ''
+	if filters.start_date and filters.end_date:
+		employee_list = get_employee_with_existing_salary_slip(filters.start_date, filters.end_date, filters.company)
+		emp = filters.get('employees')
+		filters.pop('start_date')
+		filters.pop('end_date')
+		if filters.employees is not None:
+			filters.pop('employees')
+		if employee_list:
+			exclude_employees.extend(employee_list)
+		if emp:
+			exclude_employees.extend(emp)
+		if exclude_employees:
+			emp_cond += 'and employee not in %(exclude_employees)s'
+
+	return frappe.db.sql("""select name, employee_name from `tabEmployee`
+		where status = 'Active'
+			and docstatus < 2
+			and ({key} like %(txt)s
+				or employee_name like %(txt)s)
+			{emp_cond}
+			{fcond} {mcond}
+		order by
+			if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
+			if(locate(%(_txt)s, employee_name), locate(%(_txt)s, employee_name), 99999),
+			idx desc,
+			name, employee_name
+		limit %(start)s, %(page_len)s""".format(**{
+			'key': searchfield,
+			'fcond': get_filters_cond(doctype, filters, conditions),
+			'mcond': get_match_cond(doctype),
+			'emp_cond': emp_cond
+		}), {
+			'txt': "%%%s%%" % txt,
+			'_txt': txt.replace("%", ""),
+			'start': start,
+			'page_len': page_len,
+			'exclude_employees': exclude_employees})
diff --git a/erpnext/payroll/doctype/payroll_entry/test_payroll_entry.py b/erpnext/payroll/doctype/payroll_entry/test_payroll_entry.py
index 84c3814..7528bf7 100644
--- a/erpnext/payroll/doctype/payroll_entry/test_payroll_entry.py
+++ b/erpnext/payroll/doctype/payroll_entry/test_payroll_entry.py
@@ -51,21 +51,22 @@
 
 		company_doc = frappe.get_doc('Company', company)
 		salary_structure = make_salary_structure("_Test Multi Currency Salary Structure", "Monthly", company=company, currency='USD')
-		create_salary_structure_assignment(employee, salary_structure.name, company=company)
+		create_salary_structure_assignment(employee, salary_structure.name, company=company, currency='USD')
 		frappe.db.sql("""delete from `tabSalary Slip` where employee=%s""",(frappe.db.get_value("Employee", {"user_id": "test_muti_currency_employee@payroll.com"})))
 		salary_slip = get_salary_slip("test_muti_currency_employee@payroll.com", "Monthly", "_Test Multi Currency Salary Structure")
 		dates = get_start_end_dates('Monthly', nowdate())
-		payroll_entry = make_payroll_entry(start_date=dates.start_date, end_date=dates.end_date, 
+		payroll_entry = make_payroll_entry(start_date=dates.start_date, end_date=dates.end_date,
 			payable_account=company_doc.default_payroll_payable_account, currency='USD', exchange_rate=70)
 		payroll_entry.make_payment_entry()
 
 		salary_slip.load_from_db()
 
 		payroll_je = salary_slip.journal_entry
-		payroll_je_doc = frappe.get_doc('Journal Entry', payroll_je)
+		if payroll_je:
+			payroll_je_doc = frappe.get_doc('Journal Entry', payroll_je)
 
-		self.assertEqual(salary_slip.base_gross_pay, payroll_je_doc.total_debit)
-		self.assertEqual(salary_slip.base_gross_pay, payroll_je_doc.total_credit)
+			self.assertEqual(salary_slip.base_gross_pay, payroll_je_doc.total_debit)
+			self.assertEqual(salary_slip.base_gross_pay, payroll_je_doc.total_credit)
 
 		payment_entry = frappe.db.sql('''
 			Select ifnull(sum(je.total_debit),0) as total_debit, ifnull(sum(je.total_credit),0) as total_credit from `tabJournal Entry` je, `tabJournal Entry Account` jea
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.js b/erpnext/payroll/doctype/salary_slip/salary_slip.js
index 3e8a213..e3993fa 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.js
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.js
@@ -39,7 +39,8 @@
 
 		frm.set_query("employee", function() {
 			return {
-				query: "erpnext.controllers.queries.employee_query"
+				query: "erpnext.controllers.queries.employee_query",
+				filters: frm.doc.company
 			};
 		});
 	},
@@ -93,28 +94,31 @@
 	},
 
 	set_exchange_rate: function(frm, company_currency) {
-		if (frm.doc.currency) {
-			var from_currency = frm.doc.currency;
-			if (from_currency != company_currency) {
-				frm.events.hide_loan_section(frm);
-				frappe.call({
-					method: "erpnext.setup.utils.get_exchange_rate",
-					args: {
-						from_currency: from_currency,
-						to_currency: company_currency,
-					},
-					callback: function(r) {
-						frm.set_value("exchange_rate", flt(r.message));
-						frm.set_df_property("exchange_rate", "hidden", 0);
-						frm.set_df_property("exchange_rate", "description", "1 " + frm.doc.currency
-							+ " = [?] " + company_currency);
-					}
-				});
-			} else {
-				frm.set_value("exchange_rate", 1.0);
-				frm.set_df_property("exchange_rate", "hidden", 1);
-				frm.set_df_property("exchange_rate", "description", "");
-			}
+		if (frm.doc.docstatus === 0) {
+			if (frm.doc.currency) {
+				var from_currency = frm.doc.currency;
+				if (from_currency != company_currency) {
+					frm.events.hide_loan_section(frm);
+					frappe.call({
+						method: "erpnext.setup.utils.get_exchange_rate",
+						args: {
+							from_currency: from_currency,
+							to_currency: company_currency,
+						},
+						callback: function(r) {
+							if (r.message) {
+								frm.set_value("exchange_rate", flt(r.message));
+								frm.set_df_property('exchange_rate', 'hidden', 0);
+								frm.set_df_property("exchange_rate", "description", "1 " + frm.doc.currency
+									+ " = [?] " + company_currency);
+							}
+						}
+					});
+				} else {
+					frm.set_value("exchange_rate", 1.0);
+					frm.set_df_property('exchange_rate', 'hidden', 1);
+					frm.set_df_property("exchange_rate", "description", "" );
+				}
 		}
 	},
 
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.py b/erpnext/payroll/doctype/salary_slip/salary_slip.py
index aa9acd8..f6d4c7b 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.py
@@ -124,9 +124,12 @@
 
 	def check_existing(self):
 		if not self.salary_slip_based_on_timesheet:
+			cond = ""
+			if self.payroll_entry:
+				cond += "and payroll_entry = '{0}'".format(self.payroll_entry)
 			ret_exist = frappe.db.sql("""select name from `tabSalary Slip`
 						where start_date = %s and end_date = %s and docstatus != 2
-						and employee = %s and name != %s""",
+						and employee = %s and name != %s {0}""".format(cond),
 						(self.start_date, self.end_date, self.employee, self.name))
 			if ret_exist:
 				self.employee = ''
@@ -1053,7 +1056,7 @@
 			repayment_entry.save()
 			repayment_entry.submit()
 
-			loan.loan_repayment_entry = repayment_entry.name
+			frappe.db.set_value("Salary Slip Loan", loan.name, "loan_repayment_entry", repayment_entry.name)
 
 	def cancel_loan_repayment_entry(self):
 		for loan in self.loans:
diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py
index a92bad1..70139c6 100644
--- a/erpnext/projects/doctype/project/test_project.py
+++ b/erpnext/projects/doctype/project/test_project.py
@@ -33,12 +33,16 @@
 
 	def test_project_template_having_parent_child_tasks(self):
 		project_name = "Test Project with Template - Tasks with Parent-Child Relation"
+
+		if frappe.db.get_value('Project', {'project_name': project_name}, 'name'):
+			project_name = frappe.db.get_value('Project', {'project_name': project_name}, 'name')
+
 		frappe.db.sql(""" delete from tabTask where project = %s """, project_name)
 		frappe.delete_doc('Project', project_name)
 
 		task1 = task_exists("Test Template Task Parent")
 		if not task1:
-			task1 = create_task(subject="Test Template Task Parent", is_group=1, is_template=1, begin=1, duration=4)
+			task1 = create_task(subject="Test Template Task Parent", is_group=1, is_template=1, begin=1, duration=10)
 
 		task2 = task_exists("Test Template Task Child 1")
 		if not task2:
@@ -53,7 +57,7 @@
 		tasks = frappe.get_all('Task', ['subject','exp_end_date','depends_on_tasks', 'name', 'parent_task'], dict(project=project.name), order_by='creation asc')
 
 		self.assertEqual(tasks[0].subject, 'Test Template Task Parent')
-		self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, 1, 4))
+		self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, 1, 10))
 
 		self.assertEqual(tasks[1].subject, 'Test Template Task Child 1')
 		self.assertEqual(getdate(tasks[1].exp_end_date), calculate_end_date(project, 1, 3))
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 21a20a7..6c2144d 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -737,28 +737,34 @@
 				this.frm.trigger("item_code", cdt, cdn);
 			}
 			else {
-				var valid_serial_nos = [];
-				var serialnos = [];
 				// Replacing all occurences of comma with carriage return
 				item.serial_no = item.serial_no.replace(/,/g, '\n');
-				serialnos = item.serial_no.split("\n");
-				for (var i = 0; i < serialnos.length; i++) {
-					if (serialnos[i] != "") {
-						valid_serial_nos.push(serialnos[i]);
-					}
-				}
 				item.conversion_factor = item.conversion_factor || 1;
-
 				refresh_field("serial_no", item.name, item.parentfield);
-				if(!doc.is_return && cint(user_defaults.set_qty_in_transactions_based_on_serial_no_input)) {
-					frappe.model.set_value(item.doctype, item.name,
-						"qty", valid_serial_nos.length / item.conversion_factor);
-					frappe.model.set_value(item.doctype, item.name, "stock_qty", valid_serial_nos.length);
+				if (!doc.is_return && cint(frappe.user_defaults.set_qty_in_transactions_based_on_serial_no_input)) {
+					setTimeout(() => {
+						me.update_qty(cdt, cdn);
+					}, 10000);
 				}
 			}
 		}
 	},
 
+	update_qty: function(cdt, cdn) {
+		var valid_serial_nos = [];
+		var serialnos = [];
+		var item = frappe.get_doc(cdt, cdn);
+		serialnos = item.serial_no.split("\n");
+		for (var i = 0; i < serialnos.length; i++) {
+			if (serialnos[i] != "") {
+				valid_serial_nos.push(serialnos[i]);
+			}
+		}
+		frappe.model.set_value(item.doctype, item.name,
+			"qty", valid_serial_nos.length / item.conversion_factor);
+		frappe.model.set_value(item.doctype, item.name, "stock_qty", valid_serial_nos.length);
+	},
+
 	validate: function() {
 		this.calculate_taxes_and_totals(false);
 	},
diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py
index 8eccc3f..3dd1b36 100644
--- a/erpnext/regional/india/e_invoice/utils.py
+++ b/erpnext/regional/india/e_invoice/utils.py
@@ -787,6 +787,8 @@
 
 		self.invoice.irn = res.get('Irn')
 		self.invoice.ewaybill = res.get('EwbNo')
+		self.invoice.ack_no = res.get('AckNo')
+		self.invoice.ack_date = res.get('AckDt')
 		self.invoice.signed_einvoice = dec_signed_invoice
 		self.invoice.signed_qr_code = res.get('SignedQRCode')
 
diff --git a/erpnext/selling/doctype/lead_source/lead_source.js b/erpnext/selling/doctype/lead_source/lead_source.js
deleted file mode 100644
index 6af6a4f..0000000
--- a/erpnext/selling/doctype/lead_source/lead_source.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Lead Source', {
-	refresh: function(frm) {
-
-	}
-});
diff --git a/erpnext/selling/doctype/lead_source/lead_source.json b/erpnext/selling/doctype/lead_source/lead_source.json
deleted file mode 100644
index 373e83a..0000000
--- a/erpnext/selling/doctype/lead_source/lead_source.json
+++ /dev/null
@@ -1,131 +0,0 @@
-{
- "allow_copy": 0, 
- "allow_import": 0, 
- "allow_rename": 1, 
- "autoname": "field:source_name", 
- "beta": 0, 
- "creation": "2016-09-16 01:47:47.382372", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "fields": [
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "source_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Source Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "details", 
-   "fieldtype": "Text Editor", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Details", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }
- ], 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
-
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2020-09-16 02:03:01.441622", 
- "modified_by": "Administrator", 
- "module": "Selling", 
- "name": "Lead Source", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Sales Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 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": "Sales User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_seen": 0
-}
diff --git a/erpnext/selling/doctype/lead_source/test_lead_source.py b/erpnext/selling/doctype/lead_source/test_lead_source.py
deleted file mode 100644
index 42df18f..0000000
--- a/erpnext/selling/doctype/lead_source/test_lead_source.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import frappe
-import unittest
-
-# test_records = frappe.get_test_records('Lead Source')
-
-class TestLeadSource(unittest.TestCase):
-	pass
diff --git a/erpnext/setup/doctype/global_defaults/global_defaults.js b/erpnext/setup/doctype/global_defaults/global_defaults.js
index 552331a..942dd59 100644
--- a/erpnext/setup/doctype/global_defaults/global_defaults.js
+++ b/erpnext/setup/doctype/global_defaults/global_defaults.js
@@ -17,7 +17,7 @@
 			method: "frappe.client.get_list",
 			args: {
 				doctype: "UOM Conversion Factor",
-				filters: { "category": "Length" },
+				filters: { "category": __("Length") },
 				fields: ["to_uom"],
 				limit_page_length: 500
 			},
diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js
index 95cb92b..933ca8a 100644
--- a/erpnext/stock/dashboard/item_dashboard.js
+++ b/erpnext/stock/dashboard/item_dashboard.js
@@ -1,14 +1,14 @@
 frappe.provide('erpnext.stock');
 
 erpnext.stock.ItemDashboard = Class.extend({
-	init: function(opts) {
+	init: function (opts) {
 		$.extend(this, opts);
 		this.make();
 	},
-	make: function() {
+	make: function () {
 		var me = this;
 		this.start = 0;
-		if(!this.sort_by) {
+		if (!this.sort_by) {
 			this.sort_by = 'projected_qty';
 			this.sort_order = 'asc';
 		}
@@ -16,22 +16,25 @@
 		this.content = $(frappe.render_template('item_dashboard')).appendTo(this.parent);
 		this.result = this.content.find('.result');
 
-		this.content.on('click', '.btn-move', function() {
-			handle_move_add($(this), "Move")
+		this.content.on('click', '.btn-move', function () {
+			handle_move_add($(this), "Move");
 		});
 
-		this.content.on('click', '.btn-add', function() {
-			handle_move_add($(this), "Add")
+		this.content.on('click', '.btn-add', function () {
+			handle_move_add($(this), "Add");
 		});
 
-		this.content.on('click', '.btn-edit', function() {
+		this.content.on('click', '.btn-edit', function () {
 			let item = unescape($(this).attr('data-item'));
 			let warehouse = unescape($(this).attr('data-warehouse'));
 			let company = unescape($(this).attr('data-company'));
-			frappe.db.get_value('Putaway Rule',
-				{'item_code': item, 'warehouse': warehouse, 'company': company}, 'name', (r) => {
-					frappe.set_route("Form", "Putaway Rule", r.name);
-				});
+			frappe.db.get_value('Putaway Rule', {
+				'item_code': item,
+				'warehouse': warehouse,
+				'company': company
+			}, 'name', (r) => {
+				frappe.set_route("Form", "Putaway Rule", r.name);
+			});
 		});
 
 		function handle_move_add(element, action) {
@@ -39,23 +42,26 @@
 			let warehouse = unescape(element.attr('data-warehouse'));
 			let actual_qty = unescape(element.attr('data-actual_qty'));
 			let disable_quick_entry = Number(unescape(element.attr('data-disable_quick_entry')));
-			let entry_type = action === "Move" ? "Material Transfer": null;
+			let entry_type = action === "Move" ? "Material Transfer" : null;
 
 			if (disable_quick_entry) {
 				open_stock_entry(item, warehouse, entry_type);
 			} else {
 				if (action === "Add") {
 					let rate = unescape($(this).attr('data-rate'));
-					erpnext.stock.move_item(item, null, warehouse, actual_qty, rate, function() { me.refresh(); });
-				}
-				else {
-					erpnext.stock.move_item(item, warehouse, null, actual_qty, null, function() { me.refresh(); });
+					erpnext.stock.move_item(item, null, warehouse, actual_qty, rate, function () {
+						me.refresh();
+					});
+				} else {
+					erpnext.stock.move_item(item, warehouse, null, actual_qty, null, function () {
+						me.refresh();
+					});
 				}
 			}
 		}
 
 		function open_stock_entry(item, warehouse, entry_type) {
-			frappe.model.with_doctype('Stock Entry', function() {
+			frappe.model.with_doctype('Stock Entry', function () {
 				var doc = frappe.model.get_new_doc('Stock Entry');
 				if (entry_type) doc.stock_entry_type = entry_type;
 
@@ -64,18 +70,18 @@
 				row.s_warehouse = warehouse;
 
 				frappe.set_route('Form', doc.doctype, doc.name);
-			})
+			});
 		}
 
 		// more
-		this.content.find('.btn-more').on('click', function() {
+		this.content.find('.btn-more').on('click', function () {
 			me.start += me.page_length;
 			me.refresh();
 		});
 
 	},
-	refresh: function() {
-		if(this.before_refresh) {
+	refresh: function () {
+		if (this.before_refresh) {
 			this.before_refresh();
 		}
 
@@ -94,13 +100,13 @@
 		frappe.call({
 			method: this.method,
 			args: args,
-			callback: function(r) {
+			callback: function (r) {
 				me.render(r.message);
 			}
 		});
 	},
-	render: function(data) {
-		if (this.start===0) {
+	render: function (data) {
+		if (this.start === 0) {
 			this.max_count = 0;
 			this.result.empty();
 		}
@@ -115,7 +121,7 @@
 		this.max_count = this.max_count;
 
 		// show more button
-		if (data && data.length===(this.page_length + 1)) {
+		if (data && data.length === (this.page_length + 1)) {
 			this.content.find('.more').removeClass('hidden');
 
 			// remove the last element
@@ -137,15 +143,15 @@
 		}
 	},
 
-	get_item_dashboard_data: function(data, max_count, show_item) {
-		if(!max_count) max_count = 0;
-		if(!data) data = [];
+	get_item_dashboard_data: function (data, max_count, show_item) {
+		if (!max_count) max_count = 0;
+		if (!data) data = [];
 
-		data.forEach(function(d) {
+		data.forEach(function (d) {
 			d.actual_or_pending = d.projected_qty + d.reserved_qty + d.reserved_qty_for_production + d.reserved_qty_for_sub_contract;
 			d.pending_qty = 0;
 			d.total_reserved = d.reserved_qty + d.reserved_qty_for_production + d.reserved_qty_for_sub_contract;
-			if(d.actual_or_pending > d.actual_qty) {
+			if (d.actual_or_pending > d.actual_qty) {
 				d.pending_qty = d.actual_or_pending - d.actual_qty;
 			}
 
@@ -161,16 +167,16 @@
 		return {
 			data: data,
 			max_count: max_count,
-			can_write:can_write,
+			can_write: can_write,
 			show_item: show_item || false
 		};
 	},
 
-	get_capacity_dashboard_data: function(data) {
+	get_capacity_dashboard_data: function (data) {
 		if (!data) data = [];
 
-		data.forEach(function(d) {
-			d.color =  d.percent_occupied >=80 ? "#f8814f" : "#2490ef";
+		data.forEach(function (d) {
+			d.color = d.percent_occupied >= 80 ? "#f8814f" : "#2490ef";
 		});
 
 		let can_write = 0;
@@ -185,53 +191,77 @@
 	}
 });
 
-erpnext.stock.move_item = function(item, source, target, actual_qty, rate, callback) {
+erpnext.stock.move_item = function (item, source, target, actual_qty, rate, callback) {
 	var dialog = new frappe.ui.Dialog({
 		title: target ? __('Add Item') : __('Move Item'),
-		fields: [
-			{fieldname: 'item_code', label: __('Item'),
-				fieldtype: 'Link', options: 'Item', read_only: 1},
-			{fieldname: 'source', label: __('Source Warehouse'),
-				fieldtype: 'Link', options: 'Warehouse', read_only: 1},
-			{fieldname: 'target', label: __('Target Warehouse'),
-				fieldtype: 'Link', options: 'Warehouse', reqd: 1},
-			{fieldname: 'qty', label: __('Quantity'), reqd: 1,
-				fieldtype: 'Float', description: __('Available {0}', [actual_qty]) },
-			{fieldname: 'rate', label: __('Rate'), fieldtype: 'Currency', hidden: 1 },
+		fields: [{
+			fieldname: 'item_code',
+			label: __('Item'),
+			fieldtype: 'Link',
+			options: 'Item',
+			read_only: 1
+		},
+		{
+			fieldname: 'source',
+			label: __('Source Warehouse'),
+			fieldtype: 'Link',
+			options: 'Warehouse',
+			read_only: 1
+		},
+		{
+			fieldname: 'target',
+			label: __('Target Warehouse'),
+			fieldtype: 'Link',
+			options: 'Warehouse',
+			reqd: 1
+		},
+		{
+			fieldname: 'qty',
+			label: __('Quantity'),
+			reqd: 1,
+			fieldtype: 'Float',
+			description: __('Available {0}', [actual_qty])
+		},
+		{
+			fieldname: 'rate',
+			label: __('Rate'),
+			fieldtype: 'Currency',
+			hidden: 1
+		},
 		],
-	})
+	});
 	dialog.show();
 	dialog.get_field('item_code').set_input(item);
 
-	if(source) {
+	if (source) {
 		dialog.get_field('source').set_input(source);
 	} else {
 		dialog.get_field('source').df.hidden = 1;
 		dialog.get_field('source').refresh();
 	}
 
-	if(rate) {
+	if (rate) {
 		dialog.get_field('rate').set_value(rate);
 		dialog.get_field('rate').df.hidden = 0;
 		dialog.get_field('rate').refresh();
 	}
 
-	if(target) {
+	if (target) {
 		dialog.get_field('target').df.read_only = 1;
 		dialog.get_field('target').value = target;
 		dialog.get_field('target').refresh();
 	}
 
-	dialog.set_primary_action(__('Submit'), function() {
+	dialog.set_primary_action(__('Submit'), function () {
 		var values = dialog.get_values();
-		if(!values) {
+		if (!values) {
 			return;
 		}
-		if(source && values.qty > actual_qty) {
+		if (source && values.qty > actual_qty) {
 			frappe.msgprint(__('Quantity must be less than or equal to {0}', [actual_qty]));
 			return;
 		}
-		if(values.source === values.target) {
+		if (values.source === values.target) {
 			frappe.msgprint(__('Source and target warehouse must be different'));
 		}
 
@@ -239,21 +269,21 @@
 			method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
 			args: values,
 			freeze: true,
-			callback: function(r) {
+			callback: function (r) {
 				frappe.show_alert(__('Stock Entry {0} created',
-					['<a href="/app/stock-entry/'+r.message.name+'">' + r.message.name+ '</a>']));
+					['<a href="/app/stock-entry/' + r.message.name + '">' + r.message.name + '</a>']));
 				dialog.hide();
 				callback(r);
 			},
 		});
 	});
 
-	$('<p style="margin-left: 10px;"><a class="link-open text-muted small">'
-		+ __("Add more items or open full form") + '</a></p>')
+	$('<p style="margin-left: 10px;"><a class="link-open text-muted small">' +
+			__("Add more items or open full form") + '</a></p>')
 		.appendTo(dialog.body)
 		.find('.link-open')
-		.on('click', function() {
-			frappe.model.with_doctype('Stock Entry', function() {
+		.on('click', function () {
+			frappe.model.with_doctype('Stock Entry', function () {
 				var doc = frappe.model.get_new_doc('Stock Entry');
 				doc.from_warehouse = dialog.get_value('source');
 				doc.to_warehouse = dialog.get_value('target');
@@ -266,6 +296,6 @@
 				row.transfer_qty = dialog.get_value('qty');
 				row.basic_rate = dialog.get_value('rate');
 				frappe.set_route('Form', doc.doctype, doc.name);
-			})
+			});
 		});
-}
+};
diff --git a/erpnext/stock/dashboard/item_dashboard.py b/erpnext/stock/dashboard/item_dashboard.py
index cafb5c3..45e6628 100644
--- a/erpnext/stock/dashboard/item_dashboard.py
+++ b/erpnext/stock/dashboard/item_dashboard.py
@@ -2,6 +2,7 @@
 
 import frappe
 from frappe.model.db_query import DatabaseQuery
+from frappe.utils import flt, cint
 
 @frappe.whitelist()
 def get_data(item_code=None, warehouse=None, item_group=None,
@@ -42,11 +43,20 @@
 		limit_start=start,
 		limit_page_length='21')
 
+	precision = cint(frappe.db.get_single_value("System Settings", "float_precision"))
+
 	for item in items:
 		item.update({
-			'item_name': frappe.get_cached_value("Item", item.item_code, 'item_name'),
-			'disable_quick_entry': frappe.get_cached_value("Item", item.item_code, 'has_batch_no')
-				or frappe.get_cached_value("Item", item.item_code, 'has_serial_no'),
+			'item_name': frappe.get_cached_value(
+				"Item", item.item_code, 'item_name'),
+			'disable_quick_entry': frappe.get_cached_value(
+				"Item", item.item_code, 'has_batch_no')
+			or frappe.get_cached_value(
+				"Item", item.item_code, 'has_serial_no'),
+			'projected_qty': flt(item.projected_qty, precision),
+			'reserved_qty': flt(item.reserved_qty, precision),
+			'reserved_qty_for_production': flt(item.reserved_qty_for_production, precision),
+			'reserved_qty_for_sub_contract': flt(item.reserved_qty_for_sub_contract, precision),
+			'actual_qty': flt(item.actual_qty, precision),
 		})
-
 	return items
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 36d0de1..e0b89d8 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -494,7 +494,8 @@
 
 test_records = frappe.get_test_records('Item')
 
-def create_item(item_code, is_stock_item=None, valuation_rate=0, warehouse=None, is_customer_provided_item=None, customer=None, is_purchase_item=None, opening_stock=None):
+def create_item(item_code, is_stock_item=None, valuation_rate=0, warehouse=None, is_customer_provided_item=None,
+	customer=None, is_purchase_item=None, opening_stock=None, company=None):
 	if not frappe.db.exists("Item", item_code):
 		item = frappe.new_doc("Item")
 		item.item_code = item_code
@@ -509,7 +510,7 @@
 		item.customer = customer or ''
 		item.append("item_defaults", {
 			"default_warehouse": warehouse or '_Test Warehouse - _TC',
-			"company": "_Test Company"
+			"company": company or "_Test Company"
 		})
 		item.save()
 	else:
diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py
index 61b7209..755fa61 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.py
+++ b/erpnext/stock/doctype/pick_list/pick_list.py
@@ -346,7 +346,7 @@
 
 		if dn_item:
 			dn_item.warehouse = location.warehouse
-			dn_item.qty = location.picked_qty
+			dn_item.qty = flt(location.picked_qty) / (flt(location.conversion_factor) or 1)
 			dn_item.batch_no = location.batch_no
 			dn_item.serial_no = location.serial_no
 
diff --git a/erpnext/stock/doctype/pick_list/test_pick_list.py b/erpnext/stock/doctype/pick_list/test_pick_list.py
index 01f2b0b..c4da05a 100644
--- a/erpnext/stock/doctype/pick_list/test_pick_list.py
+++ b/erpnext/stock/doctype/pick_list/test_pick_list.py
@@ -9,6 +9,7 @@
 
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
 from erpnext.stock.doctype.item.test_item import create_item
+from erpnext.stock.doctype.pick_list.pick_list import create_delivery_note
 from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation \
 		import EmptyStockReconciliationItemsError
 
@@ -291,6 +292,61 @@
 		self.assertEqual(pick_list.locations[1].qty, 5)
 		self.assertEqual(pick_list.locations[1].sales_order_item, sales_order.items[0].name)
 
+	def test_pick_list_for_items_with_multiple_UOM(self):
+		purchase_receipt = make_purchase_receipt(item_code="_Test Item", qty=10)
+		purchase_receipt.submit()
+
+		sales_order = frappe.get_doc({
+				'doctype': 'Sales Order',
+				'customer': '_Test Customer',
+				'company': '_Test Company',
+				'items': [{
+					'item_code': '_Test Item',
+					'qty': 1,
+					'conversion_factor': 5,
+					'delivery_date': frappe.utils.today()
+				}, {
+					'item_code': '_Test Item',
+					'qty': 1,
+					'conversion_factor': 1,
+					'delivery_date': frappe.utils.today()
+				}],
+			}).insert()
+		sales_order.submit()
+
+		pick_list = frappe.get_doc({
+			'doctype': 'Pick List',
+			'company': '_Test Company',
+			'customer': '_Test Customer',
+			'items_based_on': 'Sales Order',
+			'locations': [{
+				'item_code': '_Test Item',
+				'qty': 1,
+				'stock_qty': 5,
+				'conversion_factor': 5,
+				'sales_order': sales_order.name,
+				'sales_order_item': sales_order.items[0].name ,
+			}, {
+				'item_code': '_Test Item',
+				'qty': 1,
+				'stock_qty': 1,
+				'conversion_factor': 1,
+				'sales_order': sales_order.name,
+				'sales_order_item': sales_order.items[1].name ,
+			}]
+		})
+		pick_list.set_item_locations()
+		pick_list.submit()
+
+		delivery_note = create_delivery_note(pick_list.name)
+
+		self.assertEqual(pick_list.locations[0].qty, delivery_note.items[0].qty)
+		self.assertEqual(pick_list.locations[1].qty, delivery_note.items[1].qty)
+		self.assertEqual(sales_order.items[0].conversion_factor, delivery_note.items[0].conversion_factor)
+
+		pick_list.cancel()
+		sales_order.cancel()
+		purchase_receipt.cancel()
 
 	# def test_pick_list_skips_items_in_expired_batch(self):
 	# 	pass
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index 123f0c8..a0e7051 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -179,11 +179,15 @@
 	def test_material_transfer_gl_entry(self):
 		company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')
 
-		mtn = make_stock_entry(item_code="_Test Item", source="Stores - TCP1",
+		item_code = 'Hand Sanitizer - 001'
+		create_item(item_code =item_code, is_stock_item = 1,
+			is_purchase_item=1, opening_stock=1000, valuation_rate=10, company=company, warehouse="Stores - TCP1")
+
+		mtn = make_stock_entry(item_code=item_code, source="Stores - TCP1",
 			target="Finished Goods - TCP1", qty=45, company=company)
 
 		self.check_stock_ledger_entries("Stock Entry", mtn.name,
-			[["_Test Item", "Stores - TCP1", -45.0], ["_Test Item", "Finished Goods - TCP1", 45.0]])
+			[[item_code, "Stores - TCP1", -45.0], [item_code, "Finished Goods - TCP1", 45.0]])
 
 		source_warehouse_account = get_inventory_account(mtn.company, mtn.get("items")[0].s_warehouse)