Merge pull request #17703 from rmehta/yeah-form-js

refactor: deprecate old API as per https://github.com/frappe/frappe/pull/7537
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 29bae4b..26e445b 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -463,8 +463,8 @@
 	after = add_years(None, -1).strftime('%Y-%m-%d')
 	group_by='group by date(creation)'
 
-	data = get_communication_data(doctype, name, after=after, group_by='group by date(`tabCommunication`.creation)',
-		fields='date(`tabCommunication`.creation), count(`tabCommunication`.name)',as_dict=False)
+	data = get_communication_data(doctype, name, after=after, group_by='group by date(creation)',
+		fields='date(C.creation) as creation, count(C.name)',as_dict=False)
 
 	# fetch and append data from Activity Log
 	data += frappe.db.sql("""select {fields}
diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js
index 9dd552f..9560b2a 100644
--- a/erpnext/accounts/report/accounts_payable/accounts_payable.js
+++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js
@@ -45,6 +45,13 @@
 			"reqd": 1
 		},
 		{
+			"fieldname":"range4",
+			"label": __("Ageing Range 4"),
+			"fieldtype": "Int",
+			"default": "120",
+			"reqd": 1
+		},
+		{
 			"fieldname":"finance_book",
 			"label": __("Finance Book"),
 			"fieldtype": "Link",
diff --git a/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js b/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js
index 31c0193..06499ad 100644
--- a/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js
+++ b/erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js
@@ -45,6 +45,13 @@
 			"reqd": 1
 		},
 		{
+			"fieldname":"range4",
+			"label": __("Ageing Range 4"),
+			"fieldtype": "Int",
+			"default": "120",
+			"reqd": 1
+		},
+		{
 			"fieldname":"finance_book",
 			"label": __("Finance Book"),
 			"fieldtype": "Link",
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
index 3d19402..27c7993 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
@@ -45,6 +45,13 @@
 			"reqd": 1
 		},
 		{
+			"fieldname":"range4",
+			"label": __("Ageing Range 4"),
+			"fieldtype": "Int",
+			"default": "120",
+			"reqd": 1
+		},
+		{
 			"fieldname":"finance_book",
 			"label": __("Finance Book"),
 			"fieldtype": "Link",
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index eb41ef6..f277a8b 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -100,11 +100,14 @@
 			self.filters["range2"] = "60"
 		if not "range3" in self.filters:
 			self.filters["range3"] = "90"
+		if not "range4" in self.filters:
+			self.filters["range4"] = "120"
 
 		for label in ("0-{range1}".format(range1=self.filters["range1"]),
 			"{range1}-{range2}".format(range1=cint(self.filters["range1"])+ 1, range2=self.filters["range2"]),
 			"{range2}-{range3}".format(range2=cint(self.filters["range2"])+ 1, range3=self.filters["range3"]),
-			"{range3}-{above}".format(range3=cint(self.filters["range3"])+ 1, above=_("Above"))):
+			"{range3}-{range4}".format(range3=cint(self.filters["range3"])+ 1, range4=self.filters["range4"]),
+			"{range4}-{above}".format(range4=cint(self.filters["range4"])+ 1, above=_("Above"))):
 				columns.append({
 					"label": label,
 					"fieldname":label,
@@ -329,18 +332,17 @@
 			entry_date = gle.posting_date
 
 		row += get_ageing_data(cint(self.filters.range1), cint(self.filters.range2),
-			cint(self.filters.range3), self.age_as_on, entry_date, outstanding_amount)
-
+			cint(self.filters.range3), cint(self.filters.range4), self.age_as_on, entry_date, outstanding_amount)
 
 		# issue 6371-Ageing buckets should not have amounts if due date is not reached
 		if self.filters.ageing_based_on == "Due Date" \
 				and getdate(due_date) > getdate(self.filters.report_date):
-			row[-1]=row[-2]=row[-3]=row[-4]=0
+			row[-1]=row[-2]=row[-3]=row[-4]=row[-5]=0
 
 		if self.filters.ageing_based_on == "Supplier Invoice Date" \
 				and getdate(bill_date) > getdate(self.filters.report_date):
 
-			row[-1]=row[-2]=row[-3]=row[-4]=0
+			row[-1]=row[-2]=row[-3]=row[-4]=row[-5]=0
 
 		if self.filters.get(scrub(args.get("party_type"))):
 			row.append(gle.account_currency)
@@ -586,13 +588,13 @@
 		return payment_term_map
 
 	def get_chart_data(self, columns, data):
-		ageing_columns = columns[self.ageing_col_idx_start : self.ageing_col_idx_start+4]
+		ageing_columns = columns[self.ageing_col_idx_start : self.ageing_col_idx_start+5]
 
 		rows = []
 		for d in data:
 			rows.append(
 				{
-					'values': d[self.ageing_col_idx_start : self.ageing_col_idx_start+4]
+					'values': d[self.ageing_col_idx_start : self.ageing_col_idx_start+5]
 				}
 			)
 
@@ -611,21 +613,22 @@
 	}
 	return ReceivablePayableReport(filters).run(args)
 
-def get_ageing_data(first_range, second_range, third_range, age_as_on, entry_date, outstanding_amount):
-	# [0-30, 30-60, 60-90, 90-above]
-	outstanding_range = [0.0, 0.0, 0.0, 0.0]
+def get_ageing_data(first_range, second_range, third_range,
+	fourth_range, age_as_on, entry_date, outstanding_amount):
+	# [0-30, 30-60, 60-90, 90-120, 120-above]
+	outstanding_range = [0.0, 0.0, 0.0, 0.0, 0.0]
 
 	if not (age_as_on and entry_date):
 		return [0] + outstanding_range
 
 	age = (getdate(age_as_on) - getdate(entry_date)).days or 0
 	index = None
-	for i, days in enumerate([first_range, second_range, third_range]):
+	for i, days in enumerate([first_range, second_range, third_range, fourth_range]):
 		if age <= days:
 			index = i
 			break
 
-	if index is None: index = 3
+	if index is None: index = 4
 	outstanding_range[index] = outstanding_amount
 
 	return [age] + outstanding_range
diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js
index 47b087d..f9162ad 100644
--- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js
+++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js
@@ -45,6 +45,13 @@
 			"reqd": 1
 		},
 		{
+			"fieldname":"range4",
+			"label": __("Ageing Range 4"),
+			"fieldtype": "Int",
+			"default": "120",
+			"reqd": 1
+		},
+		{
 			"fieldname":"finance_book",
 			"label": __("Finance Book"),
 			"fieldtype": "Link",
diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
index 244aa8a..ec24aec 100644
--- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
+++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
@@ -82,8 +82,15 @@
 				"width": 160
 			},
 			{
-				"label": _(str(self.filters.range3) + _("-Above")),
-				"fieldname": scrub(str(self.filters.range3) + _("-Above")),
+				"label": _(str(self.filters.range3) + "-" + str(self.filters.range4)),
+				"fieldname": scrub(str(self.filters.range3) + "-" + str(self.filters.range4)),
+				"fieldtype": "Currency",
+				"options": "currency",
+				"width": 160
+			},
+			{
+				"label": _(str(self.filters.range4) + _("-Above")),
+				"fieldname": scrub(str(self.filters.range4) + _("-Above")),
 				"fieldtype": "Currency",
 				"options": "currency",
 				"width": 160
@@ -152,7 +159,7 @@
 
 			row += [
 				party_dict.invoiced_amt, paid_amt, party_dict.credit_amt, party_dict.outstanding_amt,
-				party_dict.range1, party_dict.range2, party_dict.range3, party_dict.range4,
+				party_dict.range1, party_dict.range2, party_dict.range3, party_dict.range4, party_dict.range5
 			]
 
 			if args.get("party_type") == "Customer":
@@ -178,6 +185,7 @@
 					"range2": 0,
 					"range3": 0,
 					"range4": 0,
+					"range5": 0,
 					"sales_person": []
 				})
 			)
@@ -209,7 +217,7 @@
 			cols += ["bill_no", "bill_date"]
 
 		cols += ["invoiced_amt", "paid_amt", "credit_amt",
-		"outstanding_amt", "age", "range1", "range2", "range3", "range4", "currency", "pdc/lc_date", "pdc/lc_ref",
+		"outstanding_amt", "age", "range1", "range2", "range3", "range4", "range5", "currency", "pdc/lc_date", "pdc/lc_ref",
 		"pdc/lc_amount"]
 
 		if args.get("party_type") == "Supplier":
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index d11c644..cee7e5a 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -80,6 +80,7 @@
 							"cost_center": item_row.cost_center,
 							"remarks": self.get("remarks") or "Accounting Entry for Stock",
 							"debit": flt(sle.stock_value_difference, 2),
+							"is_opening": item_row.get("is_opening"),
 						}, warehouse_account[sle.warehouse]["account_currency"]))
 
 						# to target warehouse / expense account
@@ -89,7 +90,8 @@
 							"cost_center": item_row.cost_center,
 							"remarks": self.get("remarks") or "Accounting Entry for Stock",
 							"credit": flt(sle.stock_value_difference, 2),
-							"project": item_row.get("project") or self.get("project")
+							"project": item_row.get("project") or self.get("project"),
+							"is_opening": item_row.get("is_opening")
 						}))
 					elif sle.warehouse not in warehouse_with_no_account:
 						warehouse_with_no_account.append(sle.warehouse)
@@ -123,8 +125,17 @@
 
 	def get_voucher_details(self, default_expense_account, default_cost_center, sle_map):
 		if self.doctype == "Stock Reconciliation":
-			return [frappe._dict({ "name": voucher_detail_no, "expense_account": default_expense_account,
-				"cost_center": default_cost_center }) for voucher_detail_no, sle in sle_map.items()]
+			reconciliation_purpose = frappe.db.get_value(self.doctype, self.name, "purpose")
+			is_opening = "Yes" if reconciliation_purpose == "Opening Stock" else "No"
+			details = []
+			for voucher_detail_no, sle in sle_map.items():
+				details.append(frappe._dict({
+					"name": voucher_detail_no,
+					"expense_account": default_expense_account,
+					"cost_center": default_cost_center,
+					"is_opening": is_opening
+				}))
+			return details
 		else:
 			details = self.get("items")
 
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index 6e98ebb..4f507f1 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -110,7 +110,7 @@
 	def set_lead_name(self):
 		if not self.lead_name:
 			# Check for leads being created through data import
-			if not self.company_name:
+			if not self.company_name and not self.flags.ignore_mandatory:
 				frappe.throw(_("A Lead requires either a person's name or an organization's name"))
 
 			self.lead_name = self.company_name
diff --git a/erpnext/hr/doctype/training_feedback/training_feedback.py b/erpnext/hr/doctype/training_feedback/training_feedback.py
index b47e2b4..1a33450 100644
--- a/erpnext/hr/doctype/training_feedback/training_feedback.py
+++ b/erpnext/hr/doctype/training_feedback/training_feedback.py
@@ -15,11 +15,11 @@
 
 	def on_submit(self):
 		training_event = frappe.get_doc("Training Event", self.training_event)
-		status = None
+		event_status = None
 		for e in training_event.employees:
 			if e.employee == self.employee:
-				status = 'Feedback Submitted'
+				event_status = 'Feedback Submitted'
 				break
 
-		if status:
-			frappe.db.set_value("Training Event", self.training_event, "status", status)
+		if event_status:
+			frappe.db.set_value("Training Event", self.training_event, "event_status", event_status)
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 3c35e6c..9248ac0 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -205,7 +205,12 @@
 				'item_code': d.item_code,
 				'bom_no': d.bom_no != null ? d.bom_no: '',
 				"scrap_items": scrap_items,
-				'qty': d.qty
+				'qty': d.qty,
+				"stock_qty": d.stock_qty,
+				"include_item_in_manufacturing": d.include_item_in_manufacturing,
+				"uom": d.uom,
+				"stock_uom": d.stock_uom,
+				"conversion_factor": d.conversion_factor
 			},
 			callback: function(r) {
 				d = locals[cdt][cdn];
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 1063340..5c73758 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -172,13 +172,14 @@
 			#Customer Provided parts will have zero rate
 			if not frappe.db.get_value('Item', arg["item_code"], 'is_customer_provided_item'):
 				if arg.get('bom_no') and self.set_rate_of_sub_assembly_item_based_on_bom:
-					rate = self.get_bom_unitcost(arg['bom_no'])
+					rate = self.get_bom_unitcost(arg['bom_no']) * (arg.get("conversion_factor") or 1)
 				else:
 					if self.rm_cost_as_per == 'Valuation Rate':
-						rate = self.get_valuation_rate(arg)
+						rate = self.get_valuation_rate(arg) * (arg.get("conversion_factor") or 1)
 					elif self.rm_cost_as_per == 'Last Purchase Rate':
-						rate = arg.get('last_purchase_rate') \
-							or frappe.db.get_value("Item", arg['item_code'], "last_purchase_rate")
+						rate = (arg.get('last_purchase_rate') \
+							or frappe.db.get_value("Item", arg['item_code'], "last_purchase_rate")) \
+								* (arg.get("conversion_factor") or 1)
 					elif self.rm_cost_as_per == "Price List":
 						if not self.buying_price_list:
 							frappe.throw(_("Please select Price List"))
@@ -191,7 +192,7 @@
 							"transaction_type": "buying",
 							"company": self.company,
 							"currency": self.currency,
-							"conversion_rate": self.conversion_rate or 1,
+							"conversion_rate": 1, # Passed conversion rate as 1 purposefully, as conversion rate is applied at the end of the function
 							"conversion_factor": arg.get("conversion_factor") or 1,
 							"plc_conversion_rate": 1,
 							"ignore_party": True
@@ -203,13 +204,13 @@
 
 					if not rate:
 						if self.rm_cost_as_per == "Price List":
-							frappe.msgprint(_("Price not found for item {0} and price list {1}")
+							frappe.msgprint(_("Price not found for item {0} in price list {1}")
 								.format(arg["item_code"], self.buying_price_list), alert=True)
 						else:
 							frappe.msgprint(_("{0} not found for item {1}")
 								.format(self.rm_cost_as_per, arg["item_code"]), alert=True)
 
-		return flt(rate)
+		return flt(rate) / (self.conversion_rate or 1)
 
 	def update_cost(self, update_parent=True, from_child_bom=False, save=True):
 		if self.docstatus == 2:
diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py
index 6d85ef3..e230e59 100644
--- a/erpnext/manufacturing/doctype/bom/test_bom.py
+++ b/erpnext/manufacturing/doctype/bom/test_bom.py
@@ -9,6 +9,7 @@
 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
+from six import string_types
 
 test_records = frappe.get_test_records('BOM')
 
@@ -63,16 +64,8 @@
 			and item_code='_Test Item 2' and docstatus=1 and parenttype='BOM'""")
 		rm_rate = rm_rate[0][0] if rm_rate else 0
 
-		# update valuation rate of item '_Test Item 2'
-		warehouse_list = frappe.db.sql_list("""select warehouse from `tabBin`
-			where item_code='_Test Item 2' and actual_qty > 0""")
-
-		if not warehouse_list:
-			warehouse_list.append("_Test Warehouse - _TC")
-
-		for warehouse in warehouse_list:
-			create_stock_reconciliation(item_code="_Test Item 2", warehouse=warehouse,
-				qty=200, rate=rm_rate + 10)
+		# Reset item valuation rate
+		reset_item_valuation_rate(item_code='_Test Item 2', qty=200, rate=rm_rate + 10)
 
 		# update cost of all BOMs based on latest valuation rate
 		update_cost()
@@ -96,7 +89,7 @@
 		self.assertEqual(bom.base_raw_material_cost, 480000)
 		self.assertEqual(bom.base_total_cost, 486000)
 
-	def test_bom_cost_multi_uom_multi_currency(self):
+	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_dependant", 1)
 		for item_code, rate in (("_Test Item", 3600), ("_Test Item Home Desktop Manufactured", 3000)):
 			frappe.db.sql("delete from `tabItem Price` where price_list='_Test Price List' and item_code=%s",
@@ -131,5 +124,35 @@
 		self.assertEqual(bom.base_raw_material_cost, 27000)
 		self.assertEqual(bom.base_total_cost, 33000)
 
+	def test_bom_cost_multi_uom_based_on_valuation_rate(self):
+		bom = frappe.copy_doc(test_records[2])
+		bom.set_rate_of_sub_assembly_item_based_on_bom = 0
+		bom.rm_cost_as_per = "Valuation Rate"
+		bom.items[0].uom = "_Test UOM 1"
+		bom.items[0].conversion_factor = 6
+		bom.insert()
+
+		reset_item_valuation_rate(item_code='_Test Item', qty=200, rate=200)
+
+		bom.update_cost()
+
+		self.assertEqual(bom.items[0].rate, 20)
+
 def get_default_bom(item_code="_Test FG Item 2"):
-	return frappe.db.get_value("BOM", {"item": item_code, "is_active": 1, "is_default": 1})
\ No newline at end of file
+	return frappe.db.get_value("BOM", {"item": item_code, "is_active": 1, "is_default": 1})
+
+def reset_item_valuation_rate(item_code, warehouse_list=None, qty=None, rate=None):
+	if warehouse_list and isinstance(warehouse_list, string_types):
+		warehouse_list = [warehouse_list]
+
+	if not warehouse_list:
+		warehouse_list = frappe.db.sql_list("""
+			select warehouse from `tabBin`
+			where item_code=%s and actual_qty > 0
+		""", item_code)
+
+		if not warehouse_list:
+			warehouse_list.append("_Test Warehouse - _TC")
+
+	for warehouse in warehouse_list:
+		create_stock_reconciliation(item_code=item_code, warehouse=warehouse, qty=qty, rate=rate)
diff --git a/erpnext/regional/italy/utils.py b/erpnext/regional/italy/utils.py
index 88e7c3e..0c42124 100644
--- a/erpnext/regional/italy/utils.py
+++ b/erpnext/regional/italy/utils.py
@@ -75,7 +75,7 @@
 	invoice.tax_data = tax_data
 
 	#Check if stamp duty (Bollo) of 2 EUR exists.
-	stamp_duty_charge_row = next((tax for tax in invoice.taxes if tax.charge_type == _("Actual") and tax.tax_amount == 2.0 ), None)
+	stamp_duty_charge_row = next((tax for tax in invoice.taxes if tax.charge_type == "Actual" and tax.tax_amount == 2.0 ), None)
 	if stamp_duty_charge_row:
 		invoice.stamp_duty = stamp_duty_charge_row.tax_amount
 
@@ -222,7 +222,7 @@
 	#Validate customer details
 	customer = frappe.get_doc("Customer", doc.customer)
 
-	if customer.customer_type == _("Individual"):
+	if customer.customer_type == "Individual":
 		doc.customer_fiscal_code = customer.fiscal_code
 		if not doc.customer_fiscal_code:
 			frappe.throw(_("Please set Fiscal Code for the customer '%s'" % doc.customer), title=_("E-Invoicing Information Missing"))
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 37df150..cab2116 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -113,8 +113,9 @@
 	data = frappe.db.sql(query, {"product_group": product_group,"search": search, "today": nowdate()}, as_dict=1)
 	data = adjust_qty_for_expired_items(data)
 
-	for item in data:
-		set_product_info_for_website(item)
+	if cint(frappe.db.get_single_value("Shopping Cart Settings", "enabled")):
+		for item in data:
+			set_product_info_for_website(item)
 
 	return data
 
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 5d4dbf4..4869335 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -723,7 +723,18 @@
 						'income_account': item.income_account
 					})
 			else:
-				self.append("item_defaults", {"company": frappe.defaults.get_defaults().company})
+				warehouse = ''
+				defaults = frappe.defaults.get_defaults() or {}
+
+				# To check default warehouse is belong to the default company
+				if defaults.get("default_warehouse") and frappe.db.exists("Warehouse",
+					{'name': defaults.default_warehouse, 'company': defaults.company}):
+					warehouse = defaults.default_warehouse
+
+				self.append("item_defaults", {
+					"company": defaults.get("company"),
+					"default_warehouse": warehouse
+				})
 
 	def update_variants(self):
 		if self.flags.dont_update_variants or \
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 30a45dd..f694af8 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -220,17 +220,18 @@
 	if item.variant_of:
 		item.update_template_tables()
 
-	from frappe.defaults import get_user_default_as_list
-	user_default_warehouse_list = get_user_default_as_list('Warehouse')
-	user_default_warehouse = user_default_warehouse_list[0] \
-		if len(user_default_warehouse_list) == 1 else ""
-
 	item_defaults = get_item_defaults(item.name, args.company)
 	item_group_defaults = get_item_group_defaults(item.name, args.company)
 	brand_defaults = get_brand_defaults(item.name, args.company)
 
-	warehouse = args.get("set_warehouse") or user_default_warehouse or item_defaults.get("default_warehouse") or\
-		item_group_defaults.get("default_warehouse") or brand_defaults.get("default_warehouse") or args.warehouse
+	warehouse = (args.get("set_warehouse") or item_defaults.get("default_warehouse") or
+		item_group_defaults.get("default_warehouse") or brand_defaults.get("default_warehouse") or args.warehouse)
+
+	if not warehouse:
+		defaults = frappe.defaults.get_defaults() or {}
+		if defaults.get("default_warehouse") and frappe.db.exists("Warehouse",
+			{'name': defaults.default_warehouse, 'company': args.company}):
+			warehouse = defaults.default_warehouse
 
 	if args.get('doctype') == "Material Request" and not args.get('material_request_type'):
 		args['material_request_type'] = frappe.db.get_value('Material Request',
@@ -438,7 +439,7 @@
 		pl_details = get_price_list_currency_and_exchange_rate(args)
 		args.update(pl_details)
 		validate_price_list(args)
-		if meta.get_field("currency") and args.price_list:
+		if meta.get_field("currency"):
 			validate_conversion_rate(args, meta)
 
 		price_list_rate = get_price_list_rate_for(args, item_doc.name) or 0
@@ -615,21 +616,22 @@
 		get_field_precision(meta.get_field("conversion_rate"),
 			frappe._dict({"fields": args})))
 
-	if (not args.plc_conversion_rate
-		and args.price_list_currency==frappe.db.get_value("Price List", args.price_list, "currency", cache=True)):
-		args.plc_conversion_rate = 1.0
+	if args.price_list:
+		if (not args.plc_conversion_rate
+			and args.price_list_currency==frappe.db.get_value("Price List", args.price_list, "currency", cache=True)):
+			args.plc_conversion_rate = 1.0
 
-	# validate price list currency conversion rate
-	if not args.get("price_list_currency"):
-		throw(_("Price List Currency not selected"))
-	else:
-		validate_conversion_rate(args.price_list_currency, args.plc_conversion_rate,
-			meta.get_label("plc_conversion_rate"), args.company)
+		# validate price list currency conversion rate
+		if not args.get("price_list_currency"):
+			throw(_("Price List Currency not selected"))
+		else:
+			validate_conversion_rate(args.price_list_currency, args.plc_conversion_rate,
+				meta.get_label("plc_conversion_rate"), args.company)
 
-		if meta.get_field("plc_conversion_rate"):
-			args.plc_conversion_rate = flt(args.plc_conversion_rate,
-				get_field_precision(meta.get_field("plc_conversion_rate"),
-				frappe._dict({"fields": args})))
+			if meta.get_field("plc_conversion_rate"):
+				args.plc_conversion_rate = flt(args.plc_conversion_rate,
+					get_field_precision(meta.get_field("plc_conversion_rate"),
+					frappe._dict({"fields": args})))
 
 def get_party_item_code(args, item_doc, out):
 	if args.transaction_type=="selling" and args.customer: