Merge branch 'develop'
diff --git a/erpnext/__version__.py b/erpnext/__version__.py
index 418d94e..349cc44 100644
--- a/erpnext/__version__.py
+++ b/erpnext/__version__.py
@@ -1 +1 @@
-__version__ = '4.15.3'
+__version__ = '4.15.4'
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.js b/erpnext/accounts/doctype/sales_invoice/pos.js
index d9ef6d8..e7cbcb7 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.js
+++ b/erpnext/accounts/doctype/sales_invoice/pos.js
@@ -492,7 +492,7 @@
 		});
 
 		me.refresh_delete_btn();
-		if(me.frm.doc[this.party]) {
+		if(me.frm.doc[this.party.toLowerCase()]) {
 			this.barcode.$input.focus();
 		} else {
 			this.party_field.$input.focus();
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 49845f6..f6d47dd 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -119,6 +119,10 @@
 							item.get(fieldname) is None and value is not None:
 								item.set(fieldname, value)
 
+						if fieldname == "cost_center" and item.meta.get_field("cost_center") \
+							and not item.get("cost_center") and value is not None:
+								item.set(fieldname, value)
+
 					if ret.get("pricing_rule"):
 						for field in ["base_price_list_rate", "price_list_rate",
 							"discount_percentage", "base_rate", "rate"]:
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 6b3f1e9..f033d68 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -4,7 +4,7 @@
 app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
 app_icon = "icon-th"
 app_color = "#e74c3c"
-app_version = "4.15.3"
+app_version = "4.15.4"
 
 error_report_email = "support@erpnext.com"
 
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 199ade9..bab1b43 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -57,6 +57,9 @@
 			last_purchase_rate, is_manufactured_item
 			from `tabItem` where name=%s""", item_code, as_dict = 1)
 
+		if not item:
+			frappe.throw(_("Item: {0} does not exist in the system").format(item_code))
+
 		return item
 
 	def validate_rm_item(self, item):
diff --git a/erpnext/public/js/stock_analytics.js b/erpnext/public/js/stock_analytics.js
index 091836f..57b69cb 100644
--- a/erpnext/public/js/stock_analytics.js
+++ b/erpnext/public/js/stock_analytics.js
@@ -108,6 +108,7 @@
 			// otherwise, only reset values
 			$.each(this.data, function(i, d) {
 				me.reset_item_values(d);
+				d["closing_qty_value"] = 0;
 			});
 		}
 
diff --git a/erpnext/public/js/transaction.js b/erpnext/public/js/transaction.js
index 5a56a6d..acb841b 100644
--- a/erpnext/public/js/transaction.js
+++ b/erpnext/public/js/transaction.js
@@ -403,10 +403,14 @@
 
 	_set_values_for_item_list: function(children) {
 		var me = this;
+		var price_list_rate_changed = false;
 		$.each(children, function(i, d) {
 			var existing_pricing_rule = frappe.model.get_value(d.doctype, d.name, "pricing_rule");
 			$.each(d, function(k, v) {
 				if (["doctype", "name"].indexOf(k)===-1) {
+					if(k=="price_list_rate") {
+						if(flt(v) != flt(d.price_list_rate)) price_list_rate_changed = true;
+					}
 					frappe.model.set_value(d.doctype, d.name, k, v);
 				}
 			});
@@ -414,6 +418,8 @@
 			if(!me.frm.doc.ignore_pricing_rule && existing_pricing_rule && !d.pricing_rule) {
 				me.apply_price_list(frappe.get_doc(d.doctype, d.name));
 			}
+
+			if(!price_list_rate_changed) me.calculate_taxes_and_totals();
 		});
 	},
 
diff --git a/setup.py b/setup.py
index aaa3773..24e0155 100644
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,7 @@
 from setuptools import setup, find_packages
 import os
 
-version = "4.15.3"
+version = "4.15.4"
 
 with open("requirements.txt", "r") as f:
 	install_requires = f.readlines()