Merge branch 'develop' into email-digest
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index e117471..9bdd26b 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -401,6 +401,8 @@
 
 	set_account_currency_and_balance: function(frm, account, currency_field,
 			balance_field, callback_function) {
+
+		var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
 		if (frm.doc.posting_date && account) {
 			frappe.call({
 				method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_account_details",
@@ -427,6 +429,14 @@
 
 									if(!frm.doc.paid_amount && frm.doc.received_amount)
 										frm.events.received_amount(frm);
+
+									if (frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency
+										&& frm.doc.paid_amount != frm.doc.received_amount) {
+											if (company_currency != frm.doc.paid_from_account_currency &&
+												frm.doc.payment_type == "Pay") {
+													frm.doc.paid_amount = frm.doc.received_amount;
+												}
+										}
 								}
 							},
 							() => {
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 50eb400..566734e 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -179,7 +179,7 @@
 
 		# this sequence because outstanding may get -ve
 		self.make_gl_entries()
-		
+
 		if self.update_stock == 1:
 			self.repost_future_sle_and_gle()
 
@@ -261,10 +261,10 @@
 			self.update_stock_ledger()
 
 		self.make_gl_entries_on_cancel()
-		
+
 		if self.update_stock == 1:
 			self.repost_future_sle_and_gle()
-		
+
 		frappe.db.set(self, 'status', 'Cancelled')
 
 		if frappe.db.get_single_value('Selling Settings', 'sales_update_frequency') == "Each Transaction":
@@ -551,7 +551,7 @@
 	def add_remarks(self):
 		if not self.remarks:
 			if self.po_no and self.po_date:
-				self.remarks = _("Against Customer Order {0} dated {1}").format(self.po_no, 
+				self.remarks = _("Against Customer Order {0} dated {1}").format(self.po_no,
 					formatdate(self.po_date))
 			else:
 				self.remarks = _("No Remarks")
@@ -1699,6 +1699,7 @@
 		where mpa.parent = mp.name and mpa.company = %s and mp.enabled = 1 and mp.name = %s""",
 	(company, mode_of_payment), as_dict=1)
 
+@frappe.whitelist()
 def create_dunning(source_name, target_doc=None):
 	from frappe.model.mapper import get_mapped_doc
 	from erpnext.accounts.doctype.dunning.dunning import get_dunning_letter_text, calculate_interest_and_amount
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 1c4b7a1..15affd8 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -411,7 +411,7 @@
 
 cur_frm.cscript.time_in_mins = cur_frm.cscript.hour_rate;
 
-cur_frm.cscript.bom_no	= function(doc, cdt, cdn) {
+cur_frm.cscript.bom_no = function(doc, cdt, cdn) {
 	get_bom_material_detail(doc, cdt, cdn, false);
 };
 
@@ -419,17 +419,22 @@
 	if (doc.is_default) cur_frm.set_value("is_active", 1);
 };
 
-var get_bom_material_detail= function(doc, cdt, cdn, scrap_items) {
+var get_bom_material_detail = function(doc, cdt, cdn, scrap_items) {
+	if (!doc.company) {
+		frappe.throw({message: __("Please select a Company first."), title: __("Mandatory")});
+	}
+
 	var d = locals[cdt][cdn];
 	if (d.item_code) {
 		return frappe.call({
 			doc: doc,
 			method: "get_bom_material_detail",
 			args: {
-				'item_code': d.item_code,
-				'bom_no': d.bom_no != null ? d.bom_no: '',
+				"company": doc.company,
+				"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,
@@ -468,7 +473,7 @@
 	}
 
 	if (d.bom_no) {
-		frappe.msgprint(__("You can not change rate if BOM mentioned agianst any item"));
+		frappe.msgprint(__("You cannot change the rate if BOM is mentioned against any Item."));
 		get_bom_material_detail(doc, cdt, cdn, scrap_items);
 	} else {
 		erpnext.bom.calculate_rm_cost(doc);
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 6363242..03beedb 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -65,6 +65,10 @@
 
 	def validate(self):
 		self.route = frappe.scrub(self.name).replace('_', '-')
+
+		if not self.company:
+			frappe.throw(_("Please select a Company first."), title=_("Mandatory"))
+
 		self.clear_operations()
 		self.validate_main_item()
 		self.validate_currency()
@@ -125,6 +129,7 @@
 			self.validate_bom_currecny(item)
 
 			ret = self.get_bom_material_detail({
+				"company": self.company,
 				"item_code": item.item_code,
 				"item_name": item.item_name,
 				"bom_no": item.bom_no,
@@ -213,6 +218,7 @@
 
 		for d in self.get("items"):
 			rate = self.get_rm_rate({
+				"company": self.company,
 				"item_code": d.item_code,
 				"bom_no": d.bom_no,
 				"qty": d.qty,
@@ -611,10 +617,20 @@
 	""" Get weighted average of valuation rate from all warehouses """
 
 	total_qty, total_value, valuation_rate = 0.0, 0.0, 0.0
-	for d in frappe.db.sql("""select actual_qty, stock_value from `tabBin`
-		where item_code=%s""", args['item_code'], as_dict=1):
-			total_qty += flt(d.actual_qty)
-			total_value += flt(d.stock_value)
+	item_bins = frappe.db.sql("""
+		select
+			bin.actual_qty, bin.stock_value
+		from
+			`tabBin` bin, `tabWarehouse` warehouse
+		where
+			bin.item_code=%(item)s
+			and bin.warehouse = warehouse.name
+			and warehouse.company=%(company)s""",
+		{"item": args['item_code'], "company": args['company']}, as_dict=1)
+
+	for d in item_bins:
+		total_qty += flt(d.actual_qty)
+		total_value += flt(d.stock_value)
 
 	if total_qty:
 		valuation_rate =  total_value / total_qty
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index cc93bf9..8e7fac8 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -725,6 +725,7 @@
 		args.update(item_data)
 
 		args["rate"] = get_bom_item_rate({
+			"company": wo_doc.company,
 			"item_code": args.get("item_code"),
 			"qty": args.get("required_qty"),
 			"uom": args.get("stock_uom"),
diff --git a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json
index dddb3d5..30ff1fe 100644
--- a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json
+++ b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json
@@ -137,7 +137,7 @@
    "label": "Status",
    "oldfieldname": "status",
    "oldfieldtype": "Select",
-   "options": "Accepted\nRejected"
+   "options": "\nAccepted\nRejected"
   },
   {
    "depends_on": "non_numeric",
@@ -215,7 +215,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-01-07 21:56:40.235579",
+ "modified": "2021-01-07 22:16:53.978410",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Quality Inspection Reading",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 98116ec..f75e8b7 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -524,7 +524,7 @@
 				})
 			);
 		}
-		
+
 		for (let i in frm.doc.items) {
 			let item = frm.doc.items[i];
 
@@ -675,7 +675,13 @@
 						});
 						refresh_field("items");
 
-						if (!d.serial_no) {
+						let no_batch_serial_number_value = !d.serial_no;
+						if (d.has_batch_no && !d.has_serial_no) {
+							// check only batch_no for batched item
+							no_batch_serial_number_value = !d.batch_no;
+						}
+
+						if (no_batch_serial_number_value) {
 							erpnext.stock.select_batch_and_serial_no(frm, d);
 						}
 					}