Merge pull request #16610 from jay-parikh/hotfix

fix: (POS) Item listing issue in pos after submit for Multi Company POS Profile
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 89ac6d9..465c283 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
 from erpnext.hooks import regional_overrides
 from frappe.utils import getdate
 
-__version__ = '11.1.4'
+__version__ = '11.1.6'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/deferred_revenue.py b/erpnext/accounts/deferred_revenue.py
index 9ff8b04..e638fc7 100644
--- a/erpnext/accounts/deferred_revenue.py
+++ b/erpnext/accounts/deferred_revenue.py
@@ -60,7 +60,7 @@
 	deferred_account = "deferred_revenue_account" if doc.doctype=="Sales Invoice" else "deferred_expense_account"
 	last_gl_entry, skip = False, False
 
-	booking_end_date = getdate(add_days(today(), -1)) if not end_date else end_date
+	booking_end_date = getdate(add_days(today(), -1) if not end_date else end_date)
 	if booking_end_date < item.service_start_date or \
 		(item.service_stop_date and booking_end_date.month > item.service_stop_date.month):
 		return None, None, None, True
@@ -71,7 +71,7 @@
 		last_gl_entry = True
 		booking_end_date = item.service_stop_date
 
-	booking_start_date = getdate(add_months(today(), -1)) if not start_date else start_date
+	booking_start_date = getdate(add_months(today(), -1) if not start_date else start_date)
 	booking_start_date = booking_start_date \
 		if booking_start_date > item.service_start_date else item.service_start_date
 
@@ -113,7 +113,6 @@
 			group by voucher_detail_no
 		'''.format(total_credit_debit, total_credit_debit_currency),
 			(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
-
 		already_booked_amount = gl_entries_details[0].total_credit if gl_entries_details else 0
 		base_amount = flt(item.base_net_amount - already_booked_amount, item.precision("base_net_amount"))
 		if account_currency==doc.company_currency:
@@ -128,15 +127,19 @@
 	# book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
 	# start_date: 1st of the last month or the start date
 	# end_date: end_date or today-1
+	enable_check = "enable_deferred_revenue" \
+		if doc.doctype=="Sales Invoice" else "enable_deferred_expense"
 
 	gl_entries = []
 	for item in doc.get('items'):
+		if not item.get(enable_check): continue
+
 		skip = False
 		last_gl_entry, booking_start_date, booking_end_date, skip = \
 			get_booking_dates(doc, item, start_date, end_date)
 
 		if skip: continue
-		total_days = date_diff(item.service_end_date, item.service_start_date)
+		total_days = date_diff(item.service_end_date, item.service_start_date) + 1
 		total_booking_days = date_diff(booking_end_date, booking_start_date) + 1
 
 		account_currency = get_account_currency(item.expense_account)
@@ -175,6 +178,10 @@
 				'project': project
 			}, account_currency)
 		)
-
 	if gl_entries:
-		make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
+		try:
+			make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
+			frappe.db.commit()
+		except:
+			frappe.db.rollback()
+			frappe.log_error(message = frappe.get_traceback(), title = _("Error while processing deferred accounting for {0}").format(doc.name))
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 7f1f550..f303301 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -171,7 +171,7 @@
 			if not frappe.db.exists(self.party_type, self.party):
 				frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party))
 
-			if self.party_account:
+			if self.party_account and self.party_type in ("Customer", "Supplier"):
 				self.validate_account_type(self.party_account,
 					[erpnext.get_party_account_type(self.party_type)])
 
@@ -689,7 +689,7 @@
 
 	account_currency = get_account_currency(party_account)
 	account_balance = get_balance_on(party_account, date, cost_center=cost_center)
-	_party_name = "title" if party_type == "Student" else party_type.lower() + "_name"
+	_party_name = "title" if party_type in ("Student", "Shareholder") else party_type.lower() + "_name"
 	party_name = frappe.db.get_value(party_type, party, _party_name)
 	party_balance = get_balance_on(party_type=party_type, party=party, cost_center=cost_center)
 	if party_type in ["Customer", "Supplier"]:
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index 8c3deaf..be66332 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -101,7 +101,7 @@
 					frappe.db.get_value(filters.party_type, filters.party[0], "default_currency"))
 
 		filters["account_currency"] = account_currency or filters.company_currency
-		if filters.account_currency != filters.company_currency:
+		if filters.account_currency != filters.company_currency and not filters.presentation_currency:
 			filters.presentation_currency = filters.account_currency
 
 	return filters
diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py
index 5d24096..e33b90d 100644
--- a/erpnext/accounts/report/purchase_register/purchase_register.py
+++ b/erpnext/accounts/report/purchase_register/purchase_register.py
@@ -193,7 +193,7 @@
 	pi_items = frappe.db.sql("""
 		select parent, purchase_order, purchase_receipt, po_detail, project
 		from `tabPurchase Invoice Item`
-		where parent in (%s) and (ifnull(purchase_order, '') != '' or ifnull(purchase_receipt, '') != '')
+		where parent in (%s)
 	""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
 
 	invoice_po_pr_map = {}
diff --git a/erpnext/accounts/report/utils.py b/erpnext/accounts/report/utils.py
index a8ae94f..8a39744 100644
--- a/erpnext/accounts/report/utils.py
+++ b/erpnext/accounts/report/utils.py
@@ -104,7 +104,7 @@
 		credit_in_account_currency = flt(entry['credit_in_account_currency'])
 		account_currency = entry['account_currency']
 
-		if account_currency != presentation_currency or (account_currency == presentation_currency and not is_p_or_l_account(account)):
+		if account_currency != presentation_currency:
 			value = debit or credit
 
 			date = currency_info['report_date'] if not is_p_or_l_account(account) else entry['posting_date']
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 58e3e87..d4e1840 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -615,7 +615,7 @@
 	return held_invoices
 
 
-def get_outstanding_invoices(party_type, party, account, condition=None, limit=1000):
+def get_outstanding_invoices(party_type, party, account, condition=None, limit=None):
 	outstanding_invoices = []
 	precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
 
@@ -628,7 +628,7 @@
 
 	invoice = 'Sales Invoice' if erpnext.get_party_account_type(party_type) == 'Receivable' else 'Purchase Invoice'
 	held_invoices = get_held_invoices(party_type, party)
-	limit_cond = "limit %s" % (limit or 1000)
+	limit_cond = "limit %s" % limit if limit else ""
 
 	invoice_list = frappe.db.sql("""
 		select
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index 6b3c3cc73..bbe92f6 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -1812,8 +1812,9 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_from": "company.default_finance_book",
    "fieldname": "default_finance_book", 
-   "fieldtype": "Read Only", 
+   "fieldtype": "Link",
    "hidden": 1, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -1824,12 +1825,12 @@
    "label": "Default Finance Book", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "company.default_finance_book", 
+   "options": "Finance Book",
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1,
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -1882,7 +1883,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2019-01-15 16:12:48.314196",
+ "modified": "2019-02-12 11:29:01.747819",
  "modified_by": "Administrator", 
  "module": "Assets", 
  "name": "Asset", 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 3c4ef2b..a4a636d 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -456,7 +456,7 @@
 					items_dict = {
 						rm_item_code: {
 							"item_name": rm_item_data["item_name"],
-							"description": item_wh[rm_item_code].get('description'),
+							"description": item_wh.get(rm_item_code, {}).get('description', ""),
 							'qty': rm_item_data["qty"],
 							'from_warehouse': rm_item_data["warehouse"],
 							'stock_uom': rm_item_data["stock_uom"],
diff --git a/erpnext/buying/report/purchase_analytics/purchase_analytics.json b/erpnext/buying/report/purchase_analytics/purchase_analytics.json
index 996e3ee..7ce779d 100644
--- a/erpnext/buying/report/purchase_analytics/purchase_analytics.json
+++ b/erpnext/buying/report/purchase_analytics/purchase_analytics.json
@@ -1,12 +1,13 @@
 {
- "add_total_row": 0, 
+ "add_total_row": 1, 
  "creation": "2018-10-05 16:08:24.156448", 
+ "disable_prepared_report": 0, 
  "disabled": 0, 
  "docstatus": 0, 
  "doctype": "Report", 
  "idx": 0, 
  "is_standard": "Yes", 
- "modified": "2018-10-05 16:08:33.272201", 
+ "modified": "2019-02-12 14:32:29.107109", 
  "modified_by": "Administrator", 
  "module": "Buying", 
  "name": "Purchase Analytics", 
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
index df56918..26564a3 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0,
  "allow_guest_to_view": 0, 
  "allow_import": 1, 
  "allow_rename": 1, 
@@ -55,7 +56,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "fieldname": "item_code", 
-   "fieldtype": "Read Only", 
+   "fieldtype": "Link",
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -71,7 +72,7 @@
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1,
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -707,7 +708,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-08 13:00:06.260997", 
+ "modified": "2019-02-12 11:37:18.713344",
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Clinical Procedure Template", 
diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.js b/erpnext/hr/doctype/employee_advance/employee_advance.js
index c73df62..f4285a2 100644
--- a/erpnext/hr/doctype/employee_advance/employee_advance.js
+++ b/erpnext/hr/doctype/employee_advance/employee_advance.js
@@ -19,7 +19,6 @@
 				filters: {
 					"root_type": "Asset",
 					"is_group": 0,
-					"account_type": "Payable",
 					"company": frm.doc.company
 				}
 			};
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.json b/erpnext/hr/doctype/salary_slip/salary_slip.json
index 83afa8c..76e43d6 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.json
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.json
@@ -195,7 +195,7 @@
    "columns": 0, 
    "fetch_from": "employee.branch", 
    "fieldname": "branch", 
-   "fieldtype": "Read Only", 
+   "fieldtype": "Link",
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -208,11 +208,11 @@
    "no_copy": 0, 
    "oldfieldname": "branch", 
    "oldfieldtype": "Link", 
-   "options": "", 
+   "options": "Branch",
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1,
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -1906,7 +1906,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2019-01-30 11:28:11.774739", 
+ "modified": "2019-02-12 11:24:20.848207",
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Salary Slip", 
diff --git a/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json b/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json
index 1283711..4b49f19 100644
--- a/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json
+++ b/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
@@ -351,8 +352,8 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-09-01 17:05:59.600583", 
- "modified_by": "cave@aperture.com", 
+ "modified": "2019-02-01 14:21:16.729848", 
+ "modified_by": "Administrator", 
  "module": "Hub Node", 
  "name": "Marketplace Settings", 
  "name_case": "", 
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index d17adf6..97a8ea7 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -276,8 +276,8 @@
 				item_dict[(d.item_code, d.material_request_item, d.warehouse)] = item_details
 			else:
 				item_details.update({
-					"qty":flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),{})
-						.get("qty")) + flt(d.planned_qty)
+					"qty": flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),{})
+						.get("qty")) + (flt(d.planned_qty) - flt(d.ordered_qty))
 				})
 				item_dict[(d.item_code, d.sales_order, d.warehouse)] = item_details
 
diff --git a/erpnext/manufacturing/report/production_analytics/production_analytics.json b/erpnext/manufacturing/report/production_analytics/production_analytics.json
index 023e0a8..946cd33 100644
--- a/erpnext/manufacturing/report/production_analytics/production_analytics.json
+++ b/erpnext/manufacturing/report/production_analytics/production_analytics.json
@@ -1,13 +1,14 @@
 {
- "add_total_row": 0, 
+ "add_total_row": 1, 
  "creation": "2018-10-11 19:28:37.085066", 
+ "disable_prepared_report": 0, 
  "disabled": 0, 
  "docstatus": 0, 
  "doctype": "Report", 
  "idx": 0, 
  "is_standard": "Yes", 
  "letter_head": "", 
- "modified": "2018-10-11 19:28:37.085066", 
+ "modified": "2019-02-12 14:32:16.392521", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Analytics", 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 29c8619..2199491 100755
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -488,7 +488,6 @@
 erpnext.patches.v10_0.update_assessment_result
 erpnext.patches.v10_0.set_default_payment_terms_based_on_company
 erpnext.patches.v10_0.update_sales_order_link_to_purchase_order
-erpnext.patches.v10_0.item_barcode_childtable_migrate
 erpnext.patches.v10_0.rename_price_to_rate_in_pricing_rule
 erpnext.patches.v10_0.set_currency_in_pricing_rule
 erpnext.patches.v10_0.set_b2c_limit
@@ -585,3 +584,5 @@
 erpnext.patches.v11_0.renamed_from_to_fields_in_project
 erpnext.patches.v11_0.add_permissions_in_gst_settings
 erpnext.patches.v11_1.setup_guardian_role
+execute:frappe.delete_doc('DocType', 'Notification Control')
+erpnext.patches.v10_0.item_barcode_childtable_migrate # 16-02-2019
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/item_barcode_childtable_migrate.py b/erpnext/patches/v10_0/item_barcode_childtable_migrate.py
index c939dd5..bc60056 100644
--- a/erpnext/patches/v10_0/item_barcode_childtable_migrate.py
+++ b/erpnext/patches/v10_0/item_barcode_childtable_migrate.py
@@ -7,20 +7,25 @@
 
 
 def execute():
-	items_barcode = frappe.get_all('Item', ['name', 'barcode'], { 'barcode': ('!=', '') })
-
-	frappe.reload_doc("stock", "doctype", "item")
 	frappe.reload_doc("stock", "doctype", "item_barcode")
 
+	items_barcode = frappe.get_all('Item', ['name', 'barcode'], { 'barcode': ('!=', '') })
+	frappe.reload_doc("stock", "doctype", "item")
+
+
+
 	for item in items_barcode:
 		barcode = item.barcode.strip()
 
 		if barcode and '<' not in barcode:
-			frappe.get_doc({
-				'idx': 0,
-				'doctype': 'Item Barcode',
-				'barcode': barcode,
-				'parenttype': 'Item',
-				'parent': item.name,
-				'parentfield': 'barcodes'
-			}).insert()
+			try:
+				frappe.get_doc({
+					'idx': 0,
+					'doctype': 'Item Barcode',
+					'barcode': barcode,
+					'parenttype': 'Item',
+					'parent': item.name,
+					'parentfield': 'barcodes'
+				}).insert()
+			except frappe.DuplicateEntryError:
+				continue
diff --git a/erpnext/patches/v11_0/create_department_records_for_each_company.py b/erpnext/patches/v11_0/create_department_records_for_each_company.py
index 1257f19..b5a7bd9 100644
--- a/erpnext/patches/v11_0/create_department_records_for_each_company.py
+++ b/erpnext/patches/v11_0/create_department_records_for_each_company.py
@@ -27,8 +27,10 @@
 		for company in companies:
 			copy_doc = frappe.copy_doc(department_doc)
 			copy_doc.update({"company": company.name})
-			copy_doc.insert()
-
+			try:
+				copy_doc.insert()
+			except frappe.DuplicateEntryError:
+				pass
 			# append list of new department for each company
 			comp_dict[company.name][department.name] = copy_doc.name
 
diff --git a/erpnext/patches/v11_0/update_total_qty_field.py b/erpnext/patches/v11_0/update_total_qty_field.py
index fcb76af..992454a 100644
--- a/erpnext/patches/v11_0/update_total_qty_field.py
+++ b/erpnext/patches/v11_0/update_total_qty_field.py
@@ -19,9 +19,10 @@
 			SELECT
 				parent, SUM(qty) as qty
 			FROM
-				`tab%s Item`
+				`tab{0} Item`
+			where parenttype = '{0}'
 			GROUP BY parent
-		''' % (doctype), as_dict = True)
+		'''.format(doctype), as_dict = True)
 
 		# Query to update total_qty might become too big, Update in batches
 		# batch_size is chosen arbitrarily, Don't try too hard to reason about it
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 3b42f6a6..e3fd1a8 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -66,11 +66,11 @@
 
 	def validate(self):
 		self.validate_project_name()
-		self.validate_dates()
 		self.validate_weights()
 		self.sync_tasks()
 		self.tasks = []
 		self.load_tasks()
+		self.validate_dates()
 		self.send_welcome_email()
 		self.update_percent_complete()
 
@@ -79,6 +79,24 @@
 			frappe.throw(_("Project {0} already exists").format(frappe.safe_decode(self.project_name)))
 
 	def validate_dates(self):
+		if self.tasks:
+			for d in self.tasks:
+				if self.expected_start_date:
+					if d.start_date and getdate(d.start_date) < getdate(self.expected_start_date):
+						frappe.throw(_("Start date of task <b>{0}</b> cannot be less than <b>{1}</b> expected start date <b>{2}</b>")
+							.format(d.title, self.name, self.expected_start_date))
+					if d.end_date and getdate(d.end_date) < getdate(self.expected_start_date):
+						frappe.throw(_("End date of task <b>{0}</b> cannot be less than <b>{1}</b> expected start date <b>{2}</b>")
+							.format(d.title, self.name, self.expected_start_date))
+
+				if self.expected_end_date:
+					if d.start_date and getdate(d.start_date) > getdate(self.expected_end_date):
+						frappe.throw(_("Start date of task <b>{0}</b> cannot be greater than <b>{1}</b> expected end date <b>{2}</b>")
+							.format(d.title, self.name, self.expected_end_date))
+					if d.end_date and getdate(d.end_date) > getdate(self.expected_end_date):
+						frappe.throw(_("End date of task <b>{0}</b> cannot be greater than <b>{1}</b> expected end date <b>{2}</b>")
+							.format(d.title, self.name, self.expected_end_date))
+
 		if self.expected_start_date and self.expected_end_date:
 			if getdate(self.expected_end_date) < getdate(self.expected_start_date):
 				frappe.throw(_("Expected End Date can not be less than Expected Start Date"))
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 371fc5c..fffa9c1 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -44,12 +44,6 @@
 		if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date):
 			frappe.throw(_("'Actual Start Date' can not be greater than 'Actual End Date'"))
 
-		if(self.project):
-			if frappe.db.exists("Project", self.project):
-				expected_end_date = frappe.db.get_value("Project", self.project, "expected_end_date")
-				if  self.exp_end_date and expected_end_date and getdate(self.exp_end_date) > getdate(expected_end_date) :
-					frappe.throw(_("Expected end date cannot be after Project: <b>'{0}'</b> Expected end date").format(self.project), EndDateCannotBeGreaterThanProjectEndDateError)
-
 	def validate_status(self):
 		if self.status!=self.get_db_value("status") and self.status == "Closed":
 			for d in self.depends_on:
diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py
index 6fb5412..9971946 100644
--- a/erpnext/projects/doctype/task/test_task.py
+++ b/erpnext/projects/doctype/task/test_task.py
@@ -5,7 +5,7 @@
 import unittest
 from frappe.utils import getdate, nowdate, add_days
 
-from erpnext.projects.doctype.task.task import CircularReferenceError, EndDateCannotBeGreaterThanProjectEndDateError
+from erpnext.projects.doctype.task.task import CircularReferenceError
 
 class TestTask(unittest.TestCase):
 	def test_circular_reference(self):
@@ -97,15 +97,6 @@
 
 		self.assertEqual(frappe.db.get_value("Task", task.name, "status"), "Overdue")
 
-	def test_end_date_validation(self):
-		task_end = create_task("Testing_Enddate_validation", add_days(nowdate(), 35), add_days(nowdate(), 45), save=False)
-		pro = frappe.get_doc("Project", task_end.project)
-		pro.expected_end_date = add_days(nowdate(), 40)
-		pro.save()
-		self.assertRaises(EndDateCannotBeGreaterThanProjectEndDateError, task_end.save)
-
-
-
 def create_task(subject, start=None, end=None, depends_on=None, project=None, save=True):
 	if not frappe.db.exists("Task", subject):
 		task = frappe.new_doc('Task')
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index e890bef..8811ab9 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -18,7 +18,7 @@
 			return{
 				filters: {
 					'project': child.project,
-					'status': ["!=", "Closed"]
+					'status': ["!=", "Cancelled"]
 				}
 			}
 		}
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 3751d7b..cf62af7 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -276,13 +276,11 @@
 	scan_barcode: function() {
 		let scan_barcode_field = this.frm.fields_dict["scan_barcode"];
 
-		let show_description = function(idx, item_code, exist=null) {
-			if(exist) {
-				scan_barcode_field.set_new_description(__('Row : ') + idx + ' ' +
-					item_code + __(' Qty increased by 1'));
+		let show_description = function(idx, exist = null) {
+			if (exist) {
+				scan_barcode_field.set_new_description(__('Row #{0}: Qty increased by 1', [idx]));
 			} else {
-				scan_barcode_field.set_new_description(__('New row : ') + idx + ' ' +
-					item_code + __('  Created'));
+				scan_barcode_field.set_new_description(__('Row #{0}: Item added', [idx]));
 			}
 		}
 
@@ -291,39 +289,39 @@
 				method: "erpnext.selling.page.point_of_sale.point_of_sale.search_serial_or_batch_or_barcode_number",
 				args: { search_value: this.frm.doc.scan_barcode }
 			}).then(r => {
-
-				if(r && r.message && r.message.item_code) {
-					let child = "";
-					let add_row_index = -1;
-					let cur_grid= this.frm.fields_dict["items"].grid;
-
-					this.frm.doc.items.map(d => {
-						if(d.item_code==r.message.item_code){
-							add_row_index = d.idx;
-							return;
-						} else if(!d.item_code && add_row_index==-1) {
-							add_row_index = d.idx;
-						}
-					});
-
-					if(add_row_index == -1) {
-						child = frappe.model.add_child(this.frm.doc, cur_grid.doctype, "items", add_row_index);
-					} else {
-						child = cur_grid.get_grid_row(add_row_index-1).doc;
-					}
-					show_description(child.idx, r.message.item_code, child.item_code);
-
-					frappe.model.set_value(child.doctype, child.name, {
-						item_code: r.message.item_code,
-						qty: (child.qty || 0) + 1,
-						barcode: r.message.barcode
-					});
+				const data = r && r.message;
+				if (!data) {
+					scan_barcode_field.set_new_description(__('Cannot find Item with this barcode'));
+					return;
 				}
-				else{
-					scan_barcode_field.set_new_description(this.frm.doc.scan_barcode +__(' does not exist!'));
+
+				let cur_grid = this.frm.fields_dict.items.grid;
+
+				let row_to_modify = null;
+				const existing_item_row = this.frm.doc.items.find(d => d.item_code === data.item_code);
+				const blank_item_row = this.frm.doc.items.find(d => !d.item_code);
+
+				if (existing_item_row) {
+					row_to_modify = existing_item_row;
+				} else if (blank_item_row) {
+					row_to_modify = blank_item_row;
 				}
+
+				if (!row_to_modify) {
+					// add new row
+					row_to_modify = frappe.model.add_child(this.frm.doc, cur_grid.doctype, 'items');
+				}
+
+				show_description(row_to_modify.idx, row_to_modify.item_code);
+
+				frappe.model.set_value(row_to_modify.doctype, row_to_modify.name, {
+					item_code: data.item_code,
+					qty: (row_to_modify.qty || 0) + 1
+				});
+
+				this.frm.refresh_field('items');
 			});
-			scan_barcode_field.set_value("");
+			scan_barcode_field.set_value('');
 		}
 		return false;
 	},
diff --git a/erpnext/public/js/hub/PageContainer.vue b/erpnext/public/js/hub/PageContainer.vue
index a101eaf..f151add 100644
--- a/erpnext/public/js/hub/PageContainer.vue
+++ b/erpnext/public/js/hub/PageContainer.vue
@@ -10,14 +10,15 @@
 import Search from './pages/Search.vue';
 import Category from './pages/Category.vue';
 import SavedItems from './pages/SavedItems.vue';
+import FeaturedItems from './pages/FeaturedItems.vue';
 import PublishedItems from './pages/PublishedItems.vue';
 import Item from './pages/Item.vue';
 import Seller from './pages/Seller.vue';
+import SellerItems from './pages/SellerItems.vue';
 import Publish from './pages/Publish.vue';
 import Buying from './pages/Buying.vue';
 import Selling from './pages/Selling.vue';
 import Messages from './pages/Messages.vue';
-import Profile from './pages/Profile.vue';
 import NotFound from './pages/NotFound.vue';
 
 function get_route_map() {
@@ -27,11 +28,13 @@
 		'marketplace/category/:category': Category,
 		'marketplace/item/:item': Item,
 		'marketplace/seller/:seller': Seller,
+		'marketplace/seller/:seller/items': SellerItems,
 		'marketplace/not-found': NotFound,
 	}
 	const registered_routes = {
-		'marketplace/profile': Profile,
+		'marketplace/profile': Seller,
 		'marketplace/saved-items': SavedItems,
+		'marketplace/featured-items': FeaturedItems,
 		'marketplace/publish': Publish,
 		'marketplace/published-items': PublishedItems,
 		'marketplace/buying': Buying,
diff --git a/erpnext/public/js/hub/Sidebar.vue b/erpnext/public/js/hub/Sidebar.vue
index ef3510d..66c291e 100644
--- a/erpnext/public/js/hub/Sidebar.vue
+++ b/erpnext/public/js/hub/Sidebar.vue
@@ -31,6 +31,11 @@
 					condition: () => this.hub_registered
 				},
 				{
+					label: __('Your Featured Items'),
+					route: 'marketplace/featured-items',
+					condition: () => this.hub_registered
+				},
+				{
 					label: __('Your Profile'),
 					route: 'marketplace/profile',
 					condition: () => this.hub_registered
diff --git a/erpnext/public/js/hub/components/DetailHeaderItem.vue b/erpnext/public/js/hub/components/DetailHeaderItem.vue
index 8ca4379..a6c5f06 100644
--- a/erpnext/public/js/hub/components/DetailHeaderItem.vue
+++ b/erpnext/public/js/hub/components/DetailHeaderItem.vue
@@ -1,5 +1,12 @@
 <template>
-	<p class="text-muted" v-html="header_item"></p>
+	<p class="text-muted" v-if="!Array.isArray(this.header_items)" v-html="header_items"></p>
+	<p class="text-muted" v-else>
+		<span v-for="(header_item , index) in header_items" :key="index">
+			<span v-if="index" v-html="spacer"></span>
+			<span v-if="typeof(header_item) == 'string'" v-html="header_item"></span>
+			<a v-else-if="typeof(header_item) == 'object'" @click="header_item.on_click(header_item.value)" v-html="header_item.value"></a>
+		</span>
+	</p>
 </template>
 
 <script>
@@ -11,9 +18,8 @@
 	props: ['value'],
 	data() {
 		return {
-			header_item: Array.isArray(this.value)
-				? this.value.join(spacer)
-				: this.value
+			header_items: this.value,
+			spacer: spacer
 		}
 	},
 }
diff --git a/erpnext/public/js/hub/components/EmptyState.vue b/erpnext/public/js/hub/components/EmptyState.vue
index d6216c9..e3a33a0 100644
--- a/erpnext/public/js/hub/components/EmptyState.vue
+++ b/erpnext/public/js/hub/components/EmptyState.vue
@@ -3,7 +3,7 @@
 		:class="{ 'bordered': bordered, 'align-center': centered, 'justify-center': centered }"
 		:style="{ height: height + 'px' }"
 	>
-		<p class="text-muted">{{ message }}</p>
+		<p class="text-muted" v-html="message" ></p>
 		<p v-if="action">
 			<button class="btn btn-default btn-xs"
 				@click="action.on_click"
diff --git a/erpnext/public/js/hub/pages/FeaturedItems.vue b/erpnext/public/js/hub/pages/FeaturedItems.vue
new file mode 100644
index 0000000..ab9990a
--- /dev/null
+++ b/erpnext/public/js/hub/pages/FeaturedItems.vue
@@ -0,0 +1,118 @@
+<template>
+	<div
+		class="marketplace-page"
+		:data-page-name="page_name"
+	>
+		<h5>{{ page_title }}</h5>
+		<p v-if="items.length"
+			class="text-muted margin-bottom">
+			{{ __('You can Feature upto 8 items.') }}
+		</p>
+
+		<item-cards-container
+			:container_name="page_title"
+			:items="items"
+			:item_id_fieldname="item_id_fieldname"
+			:on_click="go_to_item_details_page"
+			:editable="true"
+			@remove-item="on_item_remove"
+			:empty_state_message="empty_state_message"
+		>
+		</item-cards-container>
+	</div>
+</template>
+
+<script>
+export default {
+	name: 'featured-items-page',
+	data() {
+		return {
+			page_name: frappe.get_route()[1],
+			items: [],
+			item_id_fieldname: 'name',
+
+			// Constants
+			page_title: __('Your Featured Items'),
+            empty_state_message: __(`No featured items yet. Got to your 
+                                <a href="#marketplace/published-items">
+                                Published Items</a> 
+                                and feature upto 8 items that you want to highlight to your customers.`)
+		};
+	},
+	created() {
+		this.get_items();
+	},
+	methods: {
+		get_items() {
+			hub.call(
+				'get_featured_items_of_seller', {},
+				'action:item_feature'
+			)
+			.then((items) => {
+				this.items = items;
+			})
+		},
+
+		go_to_item_details_page(hub_item_name) {
+			frappe.set_route(`marketplace/item/${hub_item_name}`);
+		},
+
+		on_item_remove(hub_item_name) {
+			const grace_period = 5000;
+			let reverted = false;
+			let alert;
+
+			const undo_remove = () => {
+				this.toggle_item(hub_item_name);;
+				reverted = true;
+				alert.hide();
+				return false;
+			}
+
+			const item_name = this.items.filter(item => item.hub_item_name === hub_item_name);
+
+			alert = frappe.show_alert(__(`<span>${item_name} removed.
+				<a href="#" data-action="undo-remove"><b>Undo</b></a></span>`),
+				grace_period/1000,
+				{
+					'undo-remove': undo_remove.bind(this)
+				}
+			);
+
+			this.toggle_item(hub_item_name, false);
+
+			setTimeout(() => {
+				if(!reverted) {
+					this.remove_item_from_featured_items(hub_item_name);
+				}
+			}, grace_period);
+		},
+
+		remove_item_from_featured_items(hub_item_name) {
+			erpnext.hub.trigger('action:item_feature');
+			hub.call('remove_item_from_seller_featured_items', {
+				hub_item_name,
+				hub_user: frappe.session.user
+			})
+			.then(() => {
+				this.get_items();
+			})
+			.catch(e => {
+				console.log(e);
+			});
+		},
+
+		// By default show
+		toggle_item(hub_item_name, show=true) {
+			this.items = this.items.map(item => {
+				if(item.name === hub_item_name) {
+					item.seen = show;
+				}
+				return item;
+			});
+		}
+	}
+}
+</script>
+
+<style scoped></style>
diff --git a/erpnext/public/js/hub/pages/Item.vue b/erpnext/public/js/hub/pages/Item.vue
index 8dbd397..841d004 100644
--- a/erpnext/public/js/hub/pages/Item.vue
+++ b/erpnext/public/js/hub/pages/Item.vue
@@ -73,6 +73,11 @@
 					action: this.add_to_saved_items
 				},
 				{
+					label: __('Add to Featured Item'),
+					condition: hub.is_user_registered() && this.is_own_item,
+					action: this.add_to_featured_items
+				},
+				{
 					label: __('Report this Item'),
 					condition: !this.is_own_item,
 					action: this.report_item
@@ -103,7 +108,7 @@
 				subtitle_items.push(rating + `<i class='fa fa-fw fa-star-o'></i>`)
 			}
 
-			subtitle_items.push(this.item.company);
+			subtitle_items.push({value:this.item.company,on_click:this.go_to_seller_profile_page});
 
 			return subtitle_items;
 		},
@@ -169,7 +174,9 @@
 				this.make_dialogs();
 			});
 		},
-
+		go_to_seller_profile_page(seller_name) {
+			frappe.set_route(`marketplace/seller/${seller_name}`);
+		},
 		build_data() {
 			this.title = this.item.item_name || this.item.name;
 			this.image = this.item.image;
@@ -210,6 +217,21 @@
 			});
 		},
 
+		add_to_featured_items() {
+			hub.call('add_item_to_seller_featured_items', {
+				hub_item_name: this.hub_item_name,
+				hub_user: frappe.session.user
+			},)
+			.then(() => {
+				const featured_items_link = `<b><a href="#marketplace/featured-items">${__('Added to Featured Items')}</a></b>`
+				frappe.show_alert(featured_items_link);
+				erpnext.hub.trigger('action:item_feature');
+			})
+			.catch(e => {
+				console.error(e);
+			});
+		},
+
 		make_contact_seller_dialog() {
 			this.contact_seller_dialog = new frappe.ui.Dialog({
 				title: __('Send a message'),
diff --git a/erpnext/public/js/hub/pages/Profile.vue b/erpnext/public/js/hub/pages/Profile.vue
deleted file mode 100644
index 91ed946..0000000
--- a/erpnext/public/js/hub/pages/Profile.vue
+++ /dev/null
@@ -1,81 +0,0 @@
-<template>
-	<div
-		class="marketplace-page"
-		:data-page-name="page_name"
-		v-if="init || profile"
-	>
-
-		<detail-view
-			:title="title"
-			:image="image"
-			:sections="sections"
-			:show_skeleton="init"
-		>
-
-			<detail-header-item slot="detail-header-item"
-				:value="country"
-			></detail-header-item>
-			<detail-header-item slot="detail-header-item"
-				:value="site_name"
-			></detail-header-item>
-			<detail-header-item slot="detail-header-item"
-				:value="joined_when"
-			></detail-header-item>
-
-		</detail-view>
-	</div>
-</template>
-
-<script>
-export default {
-	name: 'profile-page',
-	data() {
-		return {
-			page_name: frappe.get_route()[1],
-
-			init: true,
-
-			profile: null,
-			title: null,
-			image: null,
-			sections: [],
-
-			country: '',
-			site_name: '',
-			joined_when: '',
-		};
-	},
-	created() {
-		this.get_profile();
-	},
-	methods: {
-		get_profile() {
-			hub.call(
-				'get_hub_seller_profile',
-				{ hub_seller: hub.settings.hub_seller_name }
-			).then(profile => {
-				this.init = false;
-
-				this.profile = profile;
-				this.title = profile.company;
-
-				this.country = __(profile.country);
-				this.site_name = __(profile.site_name);
-				this.joined_when = __(`Joined ${comment_when(profile.creation)}`);
-
-				this.image = profile.logo;
-				this.sections = [
-					{
-						title: __('About the Company'),
-						content: profile.company_description
-							? __(profile.company_description)
-							: __('No description')
-					}
-				];
-			});
-		}
-	}
-}
-</script>
-
-<style scoped></style>
diff --git a/erpnext/public/js/hub/pages/Seller.vue b/erpnext/public/js/hub/pages/Seller.vue
index c80865b..e339eaa 100644
--- a/erpnext/public/js/hub/pages/Seller.vue
+++ b/erpnext/public/js/hub/pages/Seller.vue
@@ -22,30 +22,77 @@
 
 		</detail-view>
 
-		<h5 v-if="profile">{{ item_container_heading }}</h5>
-		<item-cards-container
-			:container_name="item_container_heading"
-			:items="items"
-			:item_id_fieldname="item_id_fieldname"
-			:on_click="go_to_item_details_page"
-		>
-		</item-cards-container>
+		<div v-if="items.length">
+			<h5>
+				{{ item_container_heading }} 
+				<small v-if="is_user_registered() && is_own_company">
+					<a class="pull-right" href="#marketplace/featured-items">Customize your Featured Items</a>
+				</small>
+			</h5>
+			<item-cards-container
+				:container_name="item_container_heading"
+				:items="items"
+				:item_id_fieldname="item_id_fieldname"
+				:on_click="go_to_item_details_page"
+			>
+			</item-cards-container>
+			<a class="pull-right" @click="go_to_seller_items_page(seller_company)">Show all items</a>
+		</div>
+
+		<div v-if="recent_seller_reviews.length">
+			<h5>Customer Reviews</h5>
+			<div class="container" v-for="review in recent_seller_reviews" :key="review.name">
+				<br>
+				<span class="text-muted">
+					<rating :rating="review.rating" :max_rating="5"></rating>
+				</span>
+				<i class="octicon octicon-quote hidden-xs fa-fw"></i>
+				<span class="bold">{{ review.subject }}</span>
+				<i class="octicon octicon-quote hidden-xs fa-fw fa-rotate-180"></i>
+				<div class="container">
+					by {{ review.username }}
+					<a class="text-muted">
+						<span class="text-muted hidden-xs">&ndash;</span>
+						<span class="hidden-xs" v-html="comment_when(review.timestamp)"></span>
+					</a>
+				</div>
+			</div>
+		</div>
+
+		<div v-if="seller_product_view_stats.length">
+			<h5>Stats</h5>
+			<div id="seller_traffic_chart"></div>
+		</div>
+
+
+
 	</div>
 </template>
 
 <script>
+import Rating from '../components/Rating.vue';
+
+
 export default {
 	name: 'seller-page',
+	components: {
+        Rating
+    },
 	data() {
 		return {
 			page_name: frappe.get_route()[1],
 			seller_company: frappe.get_route()[2],
+			hub_seller: null,
 
 			init: true,
 
 			profile: null,
 			items:[],
+			recent_seller_reviews: [],
+			seller_product_view_stats: [],
+			seller_traffic_chart: null,
 			item_id_fieldname: 'name',
+			item_container_heading: 'Items',
 
 			title: null,
 			image: null,
@@ -60,19 +107,39 @@
 		this.get_seller_profile_and_items();
 	},
 	computed: {
-		item_container_heading() {
-			return __('Items by ' + this.seller_company);
-		}
+		is_own_company() {
+			let is_own_company = false;
+			if(this.hub_seller) {
+				if(this.hub_seller === hub.settings.hub_seller_name) {
+					is_own_company = true;
+				}
+			}
+			return is_own_company;
+		},
 	},
 	methods: {
+		comment_when(timestamp){
+			return comment_when(timestamp)
+		},
+		is_user_registered(){
+			return hub.is_user_registered()
+		},
 		get_seller_profile_and_items() {
-			hub.call(
-				'get_hub_seller_page_info',
-				{ company: this.seller_company }
-			).then(data => {
+			let post_data = {company: this.seller_company}
+			if (this.page_name == 'profile'){
+				this.seller_company = null;
+				this.hub_seller = hub.settings.hub_seller_name
+				post_data = {hub_seller: this.hub_seller}
+			}
+			hub.call('get_hub_seller_page_info', post_data)
+			.then(data => {
 				this.init = false;
 				this.profile = data.profile;
 				this.items = data.items;
+				this.item_container_heading = data.is_featured_item? "Features Items":"Popular Items";
+				this.hub_seller = this.items[0].hub_seller;
+				this.recent_seller_reviews = data.recent_seller_reviews;
+				this.seller_product_view_stats = data.seller_product_view_stats;
 
 				const profile = this.profile;
 
@@ -91,11 +158,41 @@
 							: __('No description')
 					}
 				];
+
+				setTimeout(() => this.init_seller_traffic_chart(), 1);
+				
 			});
 		},
 
 		go_to_item_details_page(hub_item_name) {
 			frappe.set_route(`marketplace/item/${hub_item_name}`);
+		},
+		go_to_seller_items_page(hub_seller) {
+			frappe.set_route(`marketplace/seller/${hub_seller}/items`);
+		},
+		init_seller_traffic_chart() {
+			let lables = []
+			let tooltip_lables = {}
+			let datasets = [{name:"Product Views",chartType: 'line',values: []}]
+			this.seller_product_view_stats.map((stat) => {
+				lables.push(stat.date.substring(5));
+				tooltip_lables[stat.date.substring(5)] = new Date(stat.date).toDateString();
+				datasets[0].values.push(stat.view_count);
+			});
+			let data = {labels: lables, datasets:datasets, tooltip_lables:tooltip_lables}
+			this.seller_traffic_chart = new Chart( "#seller_traffic_chart", { // or DOM element
+			data: data,
+
+			title: "Daily Product Views",
+			type: 'axis-mixed', // or 'bar', 'line', 'pie', 'percentage'
+			height: 300,
+			colors: ['purple', '#ffa3ef', 'light-blue'],
+
+			tooltipOptions: {
+			formatTooltipX: d => this.seller_traffic_chart.data.tooltip_lables[d],
+			formatTooltipY: d => d + ' Views',
+			}
+		});
 		}
 	}
 }
diff --git a/erpnext/public/js/hub/pages/SellerItems.vue b/erpnext/public/js/hub/pages/SellerItems.vue
new file mode 100644
index 0000000..852fbae
--- /dev/null
+++ b/erpnext/public/js/hub/pages/SellerItems.vue
@@ -0,0 +1,57 @@
+<template>
+	<div
+		class="marketplace-page"
+		:data-page-name="page_name"
+		v-if="init || items.length"
+	>
+		<h5>{{ item_container_heading }}</h5>
+		<item-cards-container
+			:container_name="item_container_heading"
+			:items="items"
+			:item_id_fieldname="item_id_fieldname"
+			:on_click="go_to_item_details_page"
+		>
+		</item-cards-container>
+	</div>
+</template>
+
+<script>
+export default {
+	name: 'seller-items-page',
+	data() {
+		return {
+			page_name: frappe.get_route()[1],
+			seller_company: frappe.get_route()[2],
+
+			init: true,
+			items:[],
+			item_id_fieldname: 'name',
+		};
+	},
+	created() {
+		this.get_seller_and_items();
+	},
+	computed: {
+		item_container_heading() {
+			return __('Items by ' + this.seller_company);
+		}
+	},
+	methods: {
+		get_seller_and_items() {
+			hub.call(
+				'get_items',
+				{ company: this.seller_company }
+			).then(data => {
+				this.init = false;
+				this.items = data;
+			});
+		},
+
+		go_to_item_details_page(hub_item_name) {
+			frappe.set_route(`marketplace/item/${hub_item_name}`);
+		}
+	}
+}
+</script>
+
+<style scoped></style>
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index a6d723a..c5498c7 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -345,13 +345,14 @@
 	if company and tds_account:
 		accounts = [dict(company=company, account=tds_account)]
 
-	fiscal_year = get_fiscal_year(today(), company=accounts[0].get('company'))[0]
+	fiscal_year = get_fiscal_year(today(), company=company)[0]
 	docs = get_tds_details(accounts, fiscal_year)
 
 	for d in docs:
 		try:
 			doc = frappe.get_doc(d)
 			doc.flags.ignore_permissions = True
+			doc.flags.ignore_mandatory = True
 			doc.insert()
 		except frappe.DuplicateEntryError:
 			doc = frappe.get_doc("Tax Withholding Category", d.get("name"))
diff --git a/erpnext/selling/report/address_and_contacts/address_and_contacts.py b/erpnext/selling/report/address_and_contacts/address_and_contacts.py
index a9e4303..eb242d0 100644
--- a/erpnext/selling/report/address_and_contacts/address_and_contacts.py
+++ b/erpnext/selling/report/address_and_contacts/address_and_contacts.py
@@ -102,7 +102,8 @@
 	records = frappe.get_list(doctype, filters=filters, fields=fields, as_list=True)
 	for d in records:
 		details = party_details.get(d[0])
-		details.setdefault(frappe.scrub(doctype), []).append(d[1:])
+		if details:
+			details.setdefault(frappe.scrub(doctype), []).append(d[1:])
 
 	return party_details
 
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.json b/erpnext/selling/report/sales_analytics/sales_analytics.json
index 5c95f28..bd82302 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.json
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.json
@@ -1,12 +1,13 @@
 {
- "add_total_row": 0, 
+ "add_total_row": 1, 
  "creation": "2018-09-21 12:46:29.451048", 
+ "disable_prepared_report": 0, 
  "disabled": 0, 
  "docstatus": 0, 
  "doctype": "Report", 
  "idx": 0, 
  "is_standard": "Yes", 
- "modified": "2018-09-21 12:46:29.451048", 
+ "modified": "2019-02-12 14:30:40.043652", 
  "modified_by": "Administrator", 
  "module": "Selling", 
  "name": "Sales Analytics", 
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index 81997ed..58c9077 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -38,6 +38,7 @@
    "oldfieldtype": "Section Break", 
    "options": "fa fa-flag", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -70,6 +71,7 @@
    "no_copy": 0, 
    "options": "STO-ITEM-.YYYY.-", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -104,6 +106,7 @@
    "oldfieldname": "item_code", 
    "oldfieldtype": "Data", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -172,6 +175,7 @@
    "oldfieldname": "item_name", 
    "oldfieldtype": "Data", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -190,37 +194,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "barcode", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Barcode", 
-   "length": 0, 
-   "no_copy": 1, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "description": "", 
    "fieldname": "item_group", 
    "fieldtype": "Link", 
@@ -238,6 +211,7 @@
    "oldfieldtype": "Link", 
    "options": "Item Group", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -305,6 +279,7 @@
    "oldfieldtype": "Link", 
    "options": "UOM", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -335,6 +310,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -435,6 +411,7 @@
    "oldfieldtype": "Select", 
    "options": "", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -701,6 +678,7 @@
    "oldfieldname": "tolerance", 
    "oldfieldtype": "Currency", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -800,6 +778,7 @@
    "oldfieldtype": "Link", 
    "options": "Brand", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -833,6 +812,7 @@
    "oldfieldname": "description", 
    "oldfieldtype": "Text", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -933,6 +913,7 @@
    "oldfieldtype": "Section Break", 
    "options": "fa fa-truck", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1000,6 +981,7 @@
    "oldfieldname": "end_of_life", 
    "oldfieldtype": "Date", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1067,6 +1049,7 @@
    "no_copy": 0, 
    "options": "\nFIFO\nMoving Average", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1099,6 +1082,7 @@
    "no_copy": 0, 
    "oldfieldtype": "Column Break", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1134,6 +1118,7 @@
    "oldfieldname": "warranty_period", 
    "oldfieldtype": "Data", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1167,6 +1152,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1200,6 +1186,7 @@
    "no_copy": 0, 
    "options": "UOM", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1234,6 +1221,7 @@
    "no_copy": 0, 
    "options": "fa fa-rss", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1268,6 +1256,7 @@
    "no_copy": 0, 
    "options": "Item Reorder", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1337,6 +1326,7 @@
    "oldfieldtype": "Table", 
    "options": "UOM Conversion Detail", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1407,6 +1397,7 @@
    "oldfieldtype": "Select", 
    "options": "", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1643,6 +1634,7 @@
    "oldfieldtype": "Select", 
    "options": "", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1676,6 +1668,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1913,6 +1906,7 @@
    "oldfieldtype": "Section Break", 
    "options": "fa fa-shopping-cart", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -2015,6 +2009,7 @@
    "oldfieldname": "min_order_qty", 
    "oldfieldtype": "Currency", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -2114,6 +2109,7 @@
    "oldfieldname": "lead_time_days", 
    "oldfieldtype": "Int", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -2148,6 +2144,7 @@
    "oldfieldname": "last_purchase_rate", 
    "oldfieldtype": "Currency", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
@@ -2246,6 +2243,7 @@
    "no_copy": 0, 
    "options": "Manufacturer", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -2278,6 +2276,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -2311,6 +2310,7 @@
    "no_copy": 0, 
    "oldfieldtype": "Column Break", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -2345,6 +2345,7 @@
    "no_copy": 0, 
    "options": "Item Supplier", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -2507,6 +2508,7 @@
    "oldfieldtype": "Section Break", 
    "options": "fa fa-tag", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -2606,6 +2608,7 @@
    "no_copy": 0, 
    "oldfieldtype": "Column Break", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -2641,6 +2644,7 @@
    "oldfieldname": "max_discount", 
    "oldfieldtype": "Currency", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3031,6 +3035,7 @@
    "no_copy": 0, 
    "options": "Item Customer Detail", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3064,6 +3069,7 @@
    "oldfieldtype": "Section Break", 
    "options": "fa fa-money", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3099,6 +3105,7 @@
    "oldfieldtype": "Table", 
    "options": "Item Tax", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3132,6 +3139,7 @@
    "oldfieldtype": "Section Break", 
    "options": "fa fa-search", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3167,6 +3175,7 @@
    "oldfieldtype": "Select", 
    "options": "", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3267,6 +3276,7 @@
    "oldfieldtype": "Section Break", 
    "options": "fa fa-cogs", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3302,6 +3312,7 @@
    "oldfieldtype": "Link", 
    "options": "BOM", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
@@ -3338,6 +3349,7 @@
    "oldfieldtype": "Select", 
    "options": "", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3400,6 +3412,7 @@
    "length": 0, 
    "no_copy": 1, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3432,6 +3445,7 @@
    "no_copy": 0, 
    "options": "fa fa-globe", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3464,6 +3478,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3563,6 +3578,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3597,6 +3613,7 @@
    "no_copy": 0, 
    "options": "Website Slideshow", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3631,6 +3648,7 @@
    "no_copy": 0, 
    "options": "", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3693,6 +3711,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3727,6 +3746,7 @@
    "no_copy": 0, 
    "options": "Warehouse", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3761,6 +3781,7 @@
    "no_copy": 0, 
    "options": "Website Item Group", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3794,6 +3815,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3826,6 +3848,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3859,6 +3882,7 @@
    "no_copy": 0, 
    "options": "Item Website Specification", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -3891,6 +3915,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -4114,10 +4139,11 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 1, 
- "modified": "2019-01-07 16:52:05.096907", 
+ "modified": "2019-02-16 17:43:56.039611", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Item", 
+ "name_case": "", 
  "owner": "Administrator", 
  "permissions": [
   {
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 566b638..bd06688 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -700,15 +700,14 @@
                         frappe.db.get_single_value('Item Variant Settings', 'do_not_update_variants'):
 			return
 		if self.has_variants:
-			updated = []
 			variants = frappe.db.get_all("Item", fields=["item_code"], filters={"variant_of": self.name})
-			for d in variants:
-				variant = frappe.get_doc("Item", d)
-				copy_attributes_to_variant(self, variant)
-				variant.save()
-				updated.append(d.item_code)
-			if updated:
-				frappe.msgprint(_("Item Variants {0} updated").format(", ".join(updated)))
+			if variants:
+				if len(variants) <= 30:
+					update_variants(variants, self, publish_progress=False)
+					frappe.msgprint(_("Item Variants updated"))
+				else:
+					frappe.enqueue("erpnext.stock.doctype.item.item.update_variants",
+						variants=variants, template=self, now=frappe.flags.in_test, timeout=600)
 
 	def validate_has_variants(self):
 		if not self.has_variants and frappe.db.get_value("Item", self.name, "has_variants"):
@@ -997,3 +996,13 @@
 
 	return frappe.get_all("Item Attribute Value", fields = ["attribute_value"],
 		filters = {'parent': parent, 'attribute_value': ("like", "%%%s%%" % attribute_value)})
+
+def update_variants(variants, template, publish_progress=True):
+	count=0
+	for d in variants:
+		variant = frappe.get_doc("Item", d)
+		copy_attributes_to_variant(template, variant)
+		variant.save()
+		count+=1
+		if publish_progress:
+				frappe.publish_progress(count*100/len(variants), title = _("Updating Variants..."))
\ No newline at end of file
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index f3e3abf..47d61f8 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -81,9 +81,9 @@
 
 	def set_title(self):
 		'''Set title as comma separated list of items'''
-		items = ', '.join([d.item_name for d in self.items][:4])
-
-		self.title = _('{0} for {1}'.format(self.material_request_type, items))[:100]
+		if not self.title:
+			items = ', '.join([d.item_name for d in self.items][:3])
+			self.title = _('{0} Request for {1}').format(self.material_request_type, items)[:100]
 
 	def on_submit(self):
 		# frappe.db.set(self, 'status', 'Submitted')
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 5d3c6c4..3a52530 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -293,8 +293,9 @@
 			total_completed_qty = flt(self.fg_completed_qty) + flt(prod_order.produced_qty)
 			completed_qty = d.completed_qty + (allowance_percentage/100 * d.completed_qty)
 			if total_completed_qty > flt(completed_qty):
-				frappe.throw(_("Row #{0}: Operation {1} is not completed for {2} qty of finished goods in Work Order # {3}. Please update operation status via Time Logs")
-					.format(d.idx, d.operation, total_completed_qty, self.work_order), OperationsNotCompleteError)
+				job_card = frappe.db.get_value('Job Card', {'operation_id': d.name}, 'name')
+				frappe.throw(_("Row #{0}: Operation {1} is not completed for {2} qty of finished goods in Work Order # {3}. Please update operation status via Job Card # {4}")
+					.format(d.idx, d.operation, total_completed_qty, self.work_order, job_card), OperationsNotCompleteError)
 
 	def check_duplicate_entry_for_work_order(self):
 		other_ste = [t[0] for t in frappe.db.get_values("Stock Entry",  {
@@ -914,6 +915,11 @@
 				filters={'parent': self.work_order, 'item_code': item_code},
 				fields=["required_qty", "consumed_qty"]
 				)
+			if not req_items:
+				frappe.msgprint(_("Did not found transfered item {0} in Work Order {1}, the item not added in Stock Entry")
+					.format(item_code, self.work_order))
+				continue
+
 			req_qty = flt(req_items[0].required_qty)
 			req_qty_each = flt(req_qty / manufacturing_qty)
 			consumed_qty = flt(req_items[0].consumed_qty)
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index eb60ce5..a00d279 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -259,6 +259,7 @@
 
 	def submit(self):
 		if len(self.items) > 100:
+			msgprint(_("The task has been enqueued as a background job. In case there is any issue on processing in background, the system will add a comment about the error on this Stock Reconciliation and revert to the Draft stage"))
 			self.queue_action('submit')
 		else:
 			self._submit()
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index ef63740..da97bc6 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -157,6 +157,8 @@
 	# return warehouses
 	for wh in warehouses:
 		wh["balance"] = get_stock_value_from_bin(warehouse=wh.value)
+		if company:
+			wh["company_currency"] = frappe.db.get_value('Company', company, 'default_currency')
 	return warehouses
 
 @frappe.whitelist()
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index ec1031c..74f3595 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -16,6 +16,9 @@
 
 from six import string_types, iteritems
 
+sales_doctypes = ['Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice']
+purchase_doctypes = ['Material Request', 'Supplier Quotation', 'Purchase Order', 'Purchase Receipt', 'Purchase Invoice']
+
 @frappe.whitelist()
 def get_item_details(args):
 	"""
@@ -228,7 +231,7 @@
 
 	#Set the UOM to the Default Sales UOM or Default Purchase UOM if configured in the Item Master
 	if not args.uom:
-		if args.get('doctype') in ['Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice']:
+		if args.get('doctype') in sales_doctypes:
 			args.uom = item.sales_uom if item.sales_uom else item.stock_uom
 		elif (args.get('doctype') in ['Purchase Order', 'Purchase Receipt', 'Purchase Invoice']) or \
 			(args.get('doctype') == 'Material Request' and args.get('material_request_type') == 'Purchase'):
@@ -281,14 +284,15 @@
 		out.conversion_factor = 1.0
 	else:
 		out.conversion_factor = args.conversion_factor or \
-			get_conversion_factor(item.item_code, args.uom).get("conversion_factor")
+			get_conversion_factor(item.name, args.uom).get("conversion_factor")
 
 	args.conversion_factor = out.conversion_factor
 	out.stock_qty = out.qty * out.conversion_factor
 
 	# calculate last purchase rate
-	from erpnext.buying.doctype.purchase_order.purchase_order import item_last_purchase_rate
-	out.last_purchase_rate = item_last_purchase_rate(args.name, args.conversion_rate, item.item_code, out.conversion_factor)
+	if args.get('doctype') in purchase_doctypes:
+		from erpnext.buying.doctype.purchase_order.purchase_order import item_last_purchase_rate
+		out.last_purchase_rate = item_last_purchase_rate(args.name, args.conversion_rate, item.name, out.conversion_factor)
 
 	# if default specified in item is for another company, fetch from company
 	for d in [
diff --git a/erpnext/stock/report/stock_analytics/stock_analytics.json b/erpnext/stock/report/stock_analytics/stock_analytics.json
index efd5e99..7a2ed2b 100644
--- a/erpnext/stock/report/stock_analytics/stock_analytics.json
+++ b/erpnext/stock/report/stock_analytics/stock_analytics.json
@@ -1,12 +1,13 @@
 {
- "add_total_row": 0, 
+ "add_total_row": 1, 
  "creation": "2018-10-08 12:11:32.133020", 
+ "disable_prepared_report": 0, 
  "disabled": 0, 
  "docstatus": 0, 
  "doctype": "Report", 
  "idx": 0, 
  "is_standard": "Yes", 
- "modified": "2018-10-08 12:18:42.834270", 
+ "modified": "2019-02-12 14:32:22.874082", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Stock Analytics", 
diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py
index e72e94b..0ece78f 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.py
+++ b/erpnext/stock/report/stock_balance/stock_balance.py
@@ -173,15 +173,15 @@
 		qty_dict.val_rate = d.valuation_rate
 		qty_dict.bal_qty += qty_diff
 		qty_dict.bal_val += value_diff
-		
+
 	iwb_map = filter_items_with_no_transactions(iwb_map)
 
 	return iwb_map
-	
+
 def filter_items_with_no_transactions(iwb_map):
 	for (company, item, warehouse) in sorted(iwb_map):
 		qty_dict = iwb_map[(company, item, warehouse)]
-		
+
 		no_transactions = True
 		float_precision = cint(frappe.db.get_default("float_precision")) or 3
 		for key, val in iteritems(qty_dict):
@@ -189,7 +189,7 @@
 			qty_dict[key] = val
 			if key != "val_rate" and val:
 				no_transactions = False
-		
+
 		if no_transactions:
 			iwb_map.pop((company, item, warehouse))
 
@@ -216,20 +216,28 @@
 	if not items:
 		items = list(set([d.item_code for d in sle]))
 
-	if items:
-		cf_field = cf_join = ""
-		if filters.get("include_uom"):
-			cf_field = ", ucd.conversion_factor"
-			cf_join = "left join `tabUOM Conversion Detail` ucd on ucd.parent=item.name and ucd.uom=%(include_uom)s"
+	if not items:
+		return item_details
 
-		for item in frappe.db.sql("""
-			select item.name, item.item_name, item.description, item.item_group, item.brand, item.stock_uom{cf_field}
-			from `tabItem` item
+	cf_field = cf_join = ""
+	if filters.get("include_uom"):
+		cf_field = ", ucd.conversion_factor"
+		cf_join = "left join `tabUOM Conversion Detail` ucd on ucd.parent=item.name and ucd.uom='%s'" \
+			% frappe.db.escape(filters.get("include_uom"))
+
+	item_codes = ', '.join(['"' + frappe.db.escape(i, percent=False) + '"' for i in items])
+	res = frappe.db.sql("""
+		select
+			item.name, item.item_name, item.description, item.item_group, item.brand, item.stock_uom {cf_field}
+		from
+			`tabItem` item
 			{cf_join}
-			where item.name in ({names}) and ifnull(item.disabled, 0) = 0
-			""".format(cf_field=cf_field, cf_join=cf_join, names=', '.join(['"' + frappe.db.escape(i, percent=False) + '"' for i in items])),
-			{"include_uom": filters.get("include_uom")}, as_dict=1):
-				item_details.setdefault(item.name, item)
+		where
+			item.name in ({item_codes}) and ifnull(item.disabled, 0) = 0
+	""".format(cf_field=cf_field, cf_join=cf_join, item_codes=item_codes), as_dict=1)
+
+	for item in res:
+		item_details.setdefault(item.name, item)
 
 	if filters.get('show_variant_attributes', 0) == 1:
 		variant_values = get_variant_values_for(list(item_details))