Merge branch 'develop' of https://github.com/frappe/erpnext into hub-multiuser
diff --git a/erpnext/hub_node/api.py b/erpnext/hub_node/api.py
index fe41919..df3e7ef 100644
--- a/erpnext/hub_node/api.py
+++ b/erpnext/hub_node/api.py
@@ -1,11 +1,61 @@
 from __future__ import unicode_literals
-import frappe, json
-import io, base64, os, requests
+
+import frappe
+import json
+import io
+import base64
+import os
+import requests
+
+from frappe import _
 from frappe.frappeclient import FrappeClient
 from frappe.desk.form.load import get_attachments
 from frappe.utils.file_manager import get_file_path
 from six import string_types
 
+current_user = frappe.session.user
+
+
+@frappe.whitelist()
+def register_marketplace(company, company_description):
+	validate_registerer()
+
+	settings = frappe.get_single('Marketplace Settings')
+	message = settings.register_seller(company, company_description)
+
+	if message.get('hub_seller_name'):
+		settings.registered = 1
+		settings.hub_seller_name = message.get('hub_seller_name')
+		settings.save()
+
+		settings.add_hub_user(frappe.session.user)
+
+	return { 'ok': 1 }
+
+
+@frappe.whitelist()
+def register_users(user_list):
+	user_list = json.loads(user_list)
+
+	settings = frappe.get_single('Marketplace Settings')
+
+	for user in user_list:
+		settings.add_hub_user(user)
+
+	return user_list
+
+
+def validate_registerer():
+	if current_user == 'Administrator':
+		frappe.throw(_('Please login as another user to register on Marketplace'))
+
+	valid_roles = ['System Manager', 'Item Manager']
+
+	if not frappe.utils.is_subset(valid_roles, frappe.get_roles()):
+		frappe.throw(_('Only users with {0} role can register on Marketplace').format(', '.join(valid_roles)),
+			frappe.PermissionError)
+
+
 @frappe.whitelist()
 def call_hub_method(method, params=None):
 	connection = get_hub_connection()
@@ -20,11 +70,12 @@
 	response = connection.post_request(params)
 	return response
 
+
 def map_fields(items):
 	field_mappings = get_field_mappings()
 	table_fields = [d.fieldname for d in frappe.get_meta('Item').get_table_fields()]
 
-	hub_seller = frappe.db.get_value('Marketplace Settings' , 'Marketplace Settings', 'company_email')
+	hub_seller_name = frappe.db.get_value('Marketplace Settings' , 'Marketplace Settings', 'hub_seller_name')
 
 	for item in items:
 		for fieldname in table_fields:
@@ -39,11 +90,12 @@
 			item[remote_fieldname] = value
 
 		item['doctype'] = 'Hub Item'
-		item['hub_seller'] = hub_seller
+		item['hub_seller'] = hub_seller_name
 		item.pop('attachments', None)
 
 	return items
 
+
 @frappe.whitelist()
 def get_valid_items(search_value=''):
 	items = frappe.get_list(
@@ -68,6 +120,7 @@
 
 	return valid_items
 
+
 @frappe.whitelist()
 def publish_selected_items(items_to_publish):
 	items_to_publish = json.loads(items_to_publish)
@@ -85,7 +138,6 @@
 			'image_list': item.get('image_list')
 		}).insert(ignore_if_duplicate=True)
 
-
 	items = map_fields(items_to_publish)
 
 	try:
@@ -100,6 +152,15 @@
 	except Exception as e:
 		frappe.log_error(message=e, title='Hub Sync Error')
 
+@frappe.whitelist()
+def get_unregistered_users():
+	settings = frappe.get_single('Marketplace Settings')
+	registered_users = [user.user for user in settings.users] + ['Administrator', 'Guest']
+	all_users = [user.name for user in frappe.db.get_all('User', filters={'enabled': 1})]
+	unregistered_users = [user for user in all_users if user not in registered_users]
+	return unregistered_users
+
+
 def item_sync_preprocess(intended_item_publish_count):
 	response = call_hub_method('pre_items_publish', {
 		'intended_item_publish_count': intended_item_publish_count
@@ -111,6 +172,7 @@
 	else:
 		frappe.throw('Unable to update remote activity')
 
+
 def item_sync_postprocess():
 	response = call_hub_method('post_items_publish', {})
 	if response:
@@ -147,24 +209,18 @@
 
 
 def get_hub_connection():
-	read_only = True
+	settings = frappe.get_single('Marketplace Settings')
+	marketplace_url = settings.marketplace_url
+	hub_user = settings.get_hub_user(frappe.session.user)
 
-	if frappe.db.exists('Data Migration Connector', 'Hub Connector'):
-		hub_connector = frappe.get_doc('Data Migration Connector', 'Hub Connector')
-
-		# full rights to user who registered as hub_seller
-		if hub_connector.username == frappe.session.user:
-			read_only = False
-
-		if not read_only:
-			hub_connection = hub_connector.get_connection()
-			return hub_connection.connection
-
-	# read-only connection
-	if read_only:
-		hub_url = frappe.db.get_single_value('Marketplace Settings', 'hub_url')
-		hub_connection = FrappeClient(hub_url)
+	if hub_user:
+		password = hub_user.get_password()
+		hub_connection = FrappeClient(marketplace_url, hub_user.user, password)
 		return hub_connection
+	else:
+		read_only_hub_connection = FrappeClient(marketplace_url)
+		return read_only_hub_connection
+
 
 def get_field_mappings():
 	return []
diff --git a/erpnext/hub_node/doctype/hub_user/__init__.py b/erpnext/hub_node/doctype/hub_user/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hub_node/doctype/hub_user/__init__.py
diff --git a/erpnext/hub_node/doctype/hub_user/hub_user.json b/erpnext/hub_node/doctype/hub_user/hub_user.json
new file mode 100644
index 0000000..a660022
--- /dev/null
+++ b/erpnext/hub_node/doctype/hub_user/hub_user.json
@@ -0,0 +1,140 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "autoname": "", 
+ "beta": 0, 
+ "creation": "2018-08-31 12:36:45.627531", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "user", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "User", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "User", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 1
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "hub_user_name", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Hub User", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "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, 
+   "fieldname": "password", 
+   "fieldtype": "Password", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Hub Password", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 1, 
+ "max_attachments": 0, 
+ "modified": "2018-09-01 13:56:07.816894", 
+ "modified_by": "netchamp@rawcoderz.com", 
+ "module": "Hub Node", 
+ "name": "Hub User", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_changes": 1, 
+ "track_seen": 0, 
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/hub_node/doctype/hub_user/hub_user.py b/erpnext/hub_node/doctype/hub_user/hub_user.py
new file mode 100644
index 0000000..de43f4e
--- /dev/null
+++ b/erpnext/hub_node/doctype/hub_user/hub_user.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class HubUser(Document):
+	pass
diff --git a/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json b/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json
index 5243f38..1283711 100644
--- a/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json
+++ b/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json
@@ -95,7 +95,7 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Marketplace URL", 
+   "label": "Marketplace URL (to hide and update label)", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -215,16 +215,16 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "company_email", 
+   "fieldname": "hub_seller_name", 
    "fieldtype": "Data", 
-   "hidden": 0, 
+   "hidden": 1, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Company Email", 
+   "label": "Hub Seller Name", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -247,8 +247,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "site_name", 
-   "fieldtype": "Data", 
+   "fieldname": "users", 
+   "fieldtype": "Table", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -256,138 +256,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Site Name", 
+   "label": "Users", 
    "length": 0, 
    "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "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, 
-   "fieldname": "country", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Country", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Country", 
-   "permlevel": 0, 
-   "precision": "", 
-   "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, 
-   "fieldname": "currency", 
-   "fieldtype": "Currency", 
-   "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": "Currency", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "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, 
-   "fieldname": "logo", 
-   "fieldtype": "Attach Image", 
-   "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": "Company Logo", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "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, 
-   "fieldname": "company_description", 
-   "fieldtype": "Text Editor", 
-   "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": "Description", 
-   "length": 0, 
-   "no_copy": 0, 
+   "options": "Hub User", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -479,8 +351,8 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-31 17:30:37.305704", 
- "modified_by": "netchamp@rawcoderz.com", 
+ "modified": "2018-09-01 17:05:59.600583", 
+ "modified_by": "cave@aperture.com", 
  "module": "Hub Node", 
  "name": "Marketplace Settings", 
  "name_case": "", 
diff --git a/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.py b/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.py
index 9b83898..5ea3011 100644
--- a/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.py
+++ b/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.py
@@ -7,98 +7,80 @@
 from frappe.model.document import Document
 from frappe.utils import add_years, now, get_datetime, get_datetime_str
 from frappe import _
+from frappe.frappeclient import FrappeClient
 from erpnext.utilities.product import get_price, get_qty_in_stock
 from six import string_types
 
 class MarketplaceSettings(Document):
 
-	def validate(self):
-		self.site_name = frappe.utils.get_url()
+	def register_seller(self, company, company_description):
 
-	def get_marketplace_url(self):
-		return self.marketplace_url
+		country, currency, company_logo = frappe.db.get_value('Company', company,
+			['country', 'default_currency', 'company_logo'])
 
-	def register(self):
-		""" Create a User on hub.erpnext.org and return username/password """
-
-		if frappe.session.user == 'Administrator':
-			frappe.throw(_('Please login as another user to register on Marketplace'))
-
-		if 'System Manager' not in frappe.get_roles():
-			frappe.throw(_('Only users with System Manager role can register on Marketplace'), frappe.PermissionError)
-
-		self.site_name = frappe.utils.get_url()
-
-		data = {
-			'profile': self.as_json()
+		company_details = {
+			'company': company,
+			'country': country,
+			'currency': currency,
+			'company_description': company_description,
+			'company_logo': company_logo,
+			'site_name': frappe.utils.get_url()
 		}
-		post_url = self.get_marketplace_url() + '/api/method/hub.hub.api.register'
 
-		response = requests.post(post_url, data=data, headers = {'accept': 'application/json'})
+		hub_connection = self.get_connection()
 
-		response.raise_for_status()
+		response = hub_connection.post_request({
+			'cmd': 'hub.hub.api.add_hub_seller',
+			'company_details': json.dumps(company_details)
+		})
 
-		if response.ok:
-			message = response.json().get('message')
-		else:
-			frappe.throw(json.loads(response.text))
+		return response
 
-		if message.get('email'):
-			self.create_hub_connector(message)
-			self.registered = 1
-			self.save()
 
-		return message or None
+	def add_hub_user(self, user_email):
+		'''Create a Hub User and User record on hub server
+		and if successfull append it to Hub User table
+		'''
 
-	# def unregister(self):
-	# 	""" Disable the User on hub.erpnext.org"""
-
-	# 	hub_connector = frappe.get_doc(
-	# 		'Data Migration Connector', 'Hub Connector')
-
-	# 	connection = hub_connector.get_connection()
-	# 	response_doc = connection.update('User', frappe._dict({'enabled': 0}), hub_connector.username)
-
-	# 	if response_doc['enabled'] == 0:
-	# 		self.enabled = 0
-	# 		self.save()
-
-	def create_hub_connector(self, message):
-		if frappe.db.exists('Data Migration Connector', 'Hub Connector'):
-			hub_connector = frappe.get_doc('Data Migration Connector', 'Hub Connector')
-			hub_connector.hostname = self.get_marketplace_url()
-			hub_connector.username = message['email']
-			hub_connector.password = message['password']
-			hub_connector.save()
+		if not self.registered:
 			return
 
-		frappe.get_doc({
-			'doctype': 'Data Migration Connector',
-			'connector_type': 'Frappe',
-			'connector_name': 'Hub Connector',
-			'hostname': self.get_marketplace_url(),
-			'username': message['email'],
-			'password': message['password']
-		}).insert()
+		hub_connection = self.get_connection()
 
-def reset_hub_publishing_settings(last_sync_datetime = ""):
-	doc = frappe.get_doc("Marketplace Settings", "Marketplace Settings")
-	doc.reset_publishing_settings(last_sync_datetime)
-	doc.in_callback = 1
-	doc.save()
+		first_name, last_name = frappe.db.get_value('User', user_email, ['first_name', 'last_name'])
 
-def reset_hub_settings(last_sync_datetime = ""):
-	doc = frappe.get_doc("Marketplace Settings", "Marketplace Settings")
-	doc.reset_publishing_settings(last_sync_datetime)
-	doc.reset_enable()
-	doc.in_callback = 1
-	doc.save()
-	frappe.msgprint(_("Successfully unregistered."))
+		hub_user = hub_connection.post_request({
+			'cmd': 'hub.hub.api.add_hub_user',
+			'user_email': user_email,
+			'first_name': first_name,
+			'last_name': last_name,
+			'hub_seller': self.hub_seller_name
+		})
 
-@frappe.whitelist()
-def register_seller(**kwargs):
-	settings = frappe.get_doc('Marketplace Settings')
-	settings.update(kwargs)
-	message = settings.register()
+		self.append('users', {
+			'user': hub_user.get('user_email'),
+			'hub_user_name': hub_user.get('hub_user_name'),
+			'password': hub_user.get('password')
+		})
 
-	return message.get('email')
+		self.save()
+
+	def get_hub_user(self, user):
+		'''Return the Hub User doc from the `users` table if password is set'''
+
+		filtered_users = filter(
+			lambda x: x.user == user and x.password,
+			self.users
+		)
+
+		if filtered_users:
+			return filtered_users[0]
+
+
+	def get_connection(self):
+		return FrappeClient(self.marketplace_url)
+
+
+	def unregister(self):
+		"""Disable the User on hubmarket.org"""
+		pass
diff --git a/erpnext/hub_node/doctype/marketplace_settings/test_marketplace_settings.js b/erpnext/hub_node/doctype/marketplace_settings/test_marketplace_settings.js
new file mode 100644
index 0000000..fba3e09
--- /dev/null
+++ b/erpnext/hub_node/doctype/marketplace_settings/test_marketplace_settings.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Marketplace Settings", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Marketplace Settings
+		() => frappe.tests.make('Marketplace Settings', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/hub_node/doctype/marketplace_settings/test_marketplace_settings.py b/erpnext/hub_node/doctype/marketplace_settings/test_marketplace_settings.py
new file mode 100644
index 0000000..549b991
--- /dev/null
+++ b/erpnext/hub_node/doctype/marketplace_settings/test_marketplace_settings.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestMarketplaceSettings(unittest.TestCase):
+	pass
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 1af75e8..512e33b 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -560,6 +560,6 @@
 erpnext.patches.v11_0.add_expense_claim_default_account
 execute:frappe.delete_doc("Page", "hub")
 erpnext.patches.v11_0.reset_publish_in_hub_for_all_items
-erpnext.patches.v11_0.update_hub_url # 2018-08-31
+erpnext.patches.v11_0.update_hub_url # 2018-08-31  # 2018-09-03
 erpnext.patches.v10_0.set_discount_amount
 erpnext.patches.v10_0.recalculate_gross_margin_for_project
diff --git a/erpnext/patches/v11_0/update_hub_url.py b/erpnext/patches/v11_0/update_hub_url.py
index abddfd6..40181a2 100644
--- a/erpnext/patches/v11_0/update_hub_url.py
+++ b/erpnext/patches/v11_0/update_hub_url.py
@@ -2,4 +2,4 @@
 
 def execute():
 	frappe.reload_doc('hub_node', 'doctype', 'Marketplace Settings')
-	frappe.db.set_value('Marketplace Settings', 'Marketplace Settings', 'hub_url', 'https://hubmarket.org')
+	frappe.db.set_value('Marketplace Settings', 'Marketplace Settings', 'marketplace_url', 'https://hubmarket.org')
diff --git a/erpnext/public/js/hub/PageContainer.vue b/erpnext/public/js/hub/PageContainer.vue
index cec4c8d..981c44e 100644
--- a/erpnext/public/js/hub/PageContainer.vue
+++ b/erpnext/public/js/hub/PageContainer.vue
@@ -20,23 +20,29 @@
 import Profile from './pages/Profile.vue';
 import NotFound from './pages/NotFound.vue';
 
-const route_map = {
-	'marketplace/home': Home,
-	'marketplace/search/:keyword': Search,
-	'marketplace/category/:category': Category,
-	'marketplace/item/:item': Item,
-	'marketplace/seller/:seller': Seller,
-	'marketplace/not-found': NotFound,
-
-	// Registered seller routes
-	'marketplace/profile': Profile,
-	'marketplace/saved-items': SavedItems,
-	'marketplace/publish': Publish,
-	'marketplace/published-items': PublishedItems,
-	'marketplace/buying': Buying,
-	'marketplace/buying/:item': Messages,
-	'marketplace/selling': Selling,
-	'marketplace/selling/:buyer/:item': Messages
+function get_route_map() {
+	const read_only_routes = {
+		'marketplace/home': Home,
+		'marketplace/search/:keyword': Search,
+		'marketplace/category/:category': Category,
+		'marketplace/item/:item': Item,
+		'marketplace/seller/:seller': Seller,
+		'marketplace/not-found': NotFound,
+	}
+	const registered_routes = {
+		'marketplace/profile': Profile,
+		'marketplace/saved-items': SavedItems,
+		'marketplace/publish': Publish,
+		'marketplace/published-items': PublishedItems,
+		'marketplace/buying': Buying,
+		'marketplace/buying/:item': Messages,
+		'marketplace/selling': Selling,
+		'marketplace/selling/:buyer/:item': Messages
+	}
+	const hub_registered = hub.settings.registered;
+	return hub_registered
+		? Object.assign({}, read_only_routes, registered_routes)
+		: read_only_routes;
 }
 
 export default {
@@ -56,6 +62,7 @@
 			this.current_page = this.get_current_page();
 		},
 		get_current_page() {
+			const route_map = get_route_map();
 			const curr_route = frappe.get_route_str();
 			let route = Object.keys(route_map).filter(route => route == curr_route)[0];
 			if (!route) {
diff --git a/erpnext/public/js/hub/Sidebar.vue b/erpnext/public/js/hub/Sidebar.vue
index cff580e..164e78d 100644
--- a/erpnext/public/js/hub/Sidebar.vue
+++ b/erpnext/public/js/hub/Sidebar.vue
@@ -19,7 +19,7 @@
 export default {
 	data() {
 		return {
-			hub_registered: hub.settings.registered && frappe.session.user === hub.settings.company_email,
+			hub_registered: hub.is_user_registered(),
 			items: [
 				{
 					label: __('Browse'),
diff --git a/erpnext/public/js/hub/components/ReviewArea.vue b/erpnext/public/js/hub/components/ReviewArea.vue
index 070d0a6..159fdd1 100644
--- a/erpnext/public/js/hub/components/ReviewArea.vue
+++ b/erpnext/public/js/hub/components/ReviewArea.vue
@@ -56,8 +56,6 @@
 		},
 
 		on_submit_review(values) {
-			values.user = hub.settings.company_email;
-
 			this.review_area.reset();
 
 			hub.call('add_item_review', {
diff --git a/erpnext/public/js/hub/components/detail_view.js b/erpnext/public/js/hub/components/detail_view.js
deleted file mode 100644
index d80720c..0000000
--- a/erpnext/public/js/hub/components/detail_view.js
+++ /dev/null
@@ -1,138 +0,0 @@
-import { get_rating_html } from './reviews';
-
-function get_detail_view_html(item, allow_edit) {
-	const title = item.item_name || item.name;
-	const seller = item.company;
-
-	const who = __('Posted By {0}', [seller]);
-	const when = comment_when(item.creation);
-
-	const city = item.city ? item.city + ', ' : '';
-	const country = item.country ? item.country : '';
-	const where = `${city}${country}`;
-
-	const dot_spacer = '<span aria-hidden="true"> · </span>';
-
-	const description = item.description || '';
-
-	let stats = __('No views yet');
-	if(item.view_count) {
-		const views_message = __(`${item.view_count} Views`);
-
-		const rating_html = get_rating_html(item.average_rating);
-		const rating_count = item.no_of_ratings > 0 ? `${item.no_of_ratings} reviews` : __('No reviews yet');
-
-		stats = `${views_message}${dot_spacer}${rating_html} (${rating_count})`;
-	}
-
-	let favourite_button = ''
-	if (hub.settings.registered) {
-		favourite_button = !item.favourited
-			? `<button class="btn btn-default text-muted favourite-button" data-action="add_to_favourites">
-				${__('Save')} <i class="octicon octicon-heart text-extra-muted"></i>
-			</button>`
-			: `<button class="btn btn-default text-muted favourite-button disabled" data-action="add_to_favourites">
-				${__('Saved')}
-			</button>`;
-	}
-
-	const contact_seller_button = item.hub_seller !== hub.settings.company_email
-		? `<button class="btn btn-primary" data-action="contact_seller">
-			${__('Contact Seller')}
-		</button>`
-		: '';
-
-	let menu_items = '';
-
-	if(allow_edit) {
-		menu_items = `
-			<li><a data-action="edit_details">${__('Edit Details')}</a></li>
-			<li><a data-action="unpublish_item">${__('Unpublish')}</a></li>`;
-	} else {
-		menu_items = `
-			<li><a data-action="report_item">${__('Report this item')}</a></li>
-		`;
-	}
-
-	const html = `
-		<div class="hub-item-container">
-			<div class="row visible-xs">
-				<div class="col-xs-12 margin-bottom">
-					<button class="btn btn-xs btn-default" data-route="marketplace/home">${__('Back to home')}</button>
-				</div>
-			</div>
-			<div class="row detail-page-section margin-bottom">
-				<div class="col-md-3">
-					<div class="hub-item-image">
-						<img src="${item.image}">
-					</div>
-				</div>
-				<div class="col-md-8 flex flex-column">
-					<div class="detail-page-header">
-						<h2>${title}</h2>
-						<div class="text-muted">
-							<p>${where}${dot_spacer}${when}</p>
-							<p>${stats}</p>
-						</div>
-					</div>
-
-					<div class="page-actions detail-page-actions">
-						${favourite_button}
-						${contact_seller_button}
-					</div>
-				</div>
-				<div class="col-md-1">
-					<div class="dropdown pull-right hub-item-dropdown">
-						<a class="dropdown-toggle btn btn-xs btn-default" data-toggle="dropdown">
-							<span class="caret"></span>
-						</a>
-						<ul class="dropdown-menu dropdown-right" role="menu">
-							${menu_items}
-						</ul>
-					</div>
-				</div>
-			</div>
-			<div class="row hub-item-description">
-				<h6 class="col-md-12 margin-top">
-					<b class="text-muted">Item Description</b>
-				</h6>
-				<p class="col-md-12">
-					${description ? description : __('No details')}
-				</p>
-			</div>
-			<div class="row hub-item-seller">
-
-				<h6 class="col-md-12 margin-top margin-bottom">
-					<b class="text-muted">Seller Information</b>
-				</h6>
-				<div class="col-md-1">
-					<img src="https://picsum.photos/200">
-				</div>
-				<div class="col-md-8">
-					<div class="margin-bottom"><a href="#marketplace/seller/${seller}" class="bold">${seller}</a></div>
-				</div>
-			</div>
-			<!-- review area -->
-			<div class="row hub-item-review-container">
-				<div class="col-md-12 form-footer">
-					<div class="form-comments">
-						<div class="timeline">
-							 <div class="timeline-head"></div>
-							<div class="timeline-items"></div>
-						</div>
-					</div>
-					<div class="pull-right scroll-to-top">
-						<a onclick="frappe.utils.scroll_to(0)"><i class="fa fa-chevron-up text-muted"></i></a>
-					</div>
-				</div>
-			</div>
-		</div>
-	`;
-
-	return html;
-}
-
-export {
-	get_detail_view_html,
-	get_profile_html
-}
diff --git a/erpnext/public/js/hub/components/item_card.js b/erpnext/public/js/hub/components/item_card.js
deleted file mode 100644
index 41ab33a..0000000
--- a/erpnext/public/js/hub/components/item_card.js
+++ /dev/null
@@ -1,80 +0,0 @@
-function get_buying_item_message_card_html(item) {
-	const item_name = item.item_name || item.name;
-	const title = strip_html(item_name);
-
-	const message = item.recent_message
-	const sender = message.sender === frappe.session.user ? 'You' : message.sender
-	const content = strip_html(message.content)
-
-	// route
-	item.route = `marketplace/buying/${item.name}`
-
-	const item_html = `
-		<div class="col-md-7">
-			<div class="hub-list-item" data-route="${item.route}">
-				<div class="hub-list-left">
-					<img class="hub-list-image" src="${item.image}">
-					<div class="hub-list-body ellipsis">
-						<div class="hub-list-title">${item_name}</div>
-						<div class="hub-list-subtitle ellipsis">
-							<span>${sender}: </span>
-							<span>${content}</span>
-						</div>
-					</div>
-				</div>
-				<div class="hub-list-right">
-					<span class="text-muted">${comment_when(message.creation, true)}</span>
-				</div>
-			</div>
-		</div>
-	`;
-
-	return item_html;
-}
-
-function get_selling_item_message_card_html(item) {
-	const item_name = item.item_name || item.name;
-	const title = strip_html(item_name);
-
-	// route
-	if (!item.route) {
-		item.route = `marketplace/item/${item.name}`
-	}
-
-	let received_messages = '';
-	item.received_messages.forEach(message => {
-		const sender = message.sender === frappe.session.user ? 'You' : message.sender
-		const content = strip_html(message.content)
-
-		received_messages += `
-			<div class="received-message">
-				<span class="text-muted">${comment_when(message.creation, true)}</span>
-				<div class="ellipsis">
-					<span class="bold">${sender}: </span>
-					<span>${content}</span>
-				</div>
-			</div>
-		`
-	});
-
-	const item_html = `
-		<div class="selling-item-message-card">
-			<div class="selling-item-detail" data-route="${item.route}">
-				<img class="item-image" src="${item.image}">
-				<h5 class="item-name">${item_name}</h5>
-				<div class="received-message-container">
-					${received_messages}
-				</div>
-			</div>
-		</div>
-	`;
-
-	return item_html;
-}
-
-export {
-	get_item_card_html,
-	get_local_item_card_html,
-	get_buying_item_message_card_html,
-	get_selling_item_message_card_html
-}
diff --git a/erpnext/public/js/hub/components/profile_dialog.js b/erpnext/public/js/hub/components/profile_dialog.js
index ae44659..636bf14 100644
--- a/erpnext/public/js/hub/components/profile_dialog.js
+++ b/erpnext/public/js/hub/components/profile_dialog.js
@@ -1,43 +1,33 @@
 const ProfileDialog = (title = __('Edit Profile'), action={}) => {
 	const fields = [
 		{
+			fieldname: 'company_email',
+			label: __('Email'),
+			fieldtype: 'Read Only'
+		},
+		{
 			fieldtype: 'Link',
 			fieldname: 'company',
 			label: __('Company'),
 			options: 'Company',
 			onchange: () => {
 				const value = dialog.get_value('company');
-
 				if (value) {
 					frappe.db.get_doc('Company', value)
 						.then(company => {
+							console.log(company.company_logo);
 							dialog.set_values({
-								country: company.country,
-								currency: company.default_currency
+								company_logo: company.company_logo,
+								company_description: company.company_description
 							});
 						});
 				}
 			}
 		},
 		{
-			fieldname: 'company_email',
-			label: __('Email'),
-			fieldtype: 'Read Only'
-		},
-		{
-			fieldname: 'country',
-			label: __('Country'),
-			fieldtype: 'Read Only'
-		},
-		{
-			fieldname: 'currency',
-			label: __('Currency'),
-			fieldtype: 'Read Only'
-		},
-		{
-			fieldtype: 'Text',
-			label: __('About your Company'),
-			fieldname: 'company_description'
+			label: __('About your company'),
+			fieldname: 'company_description',
+			fieldtype: 'Text'
 		}
 	];
 
@@ -48,7 +38,11 @@
 		primary_action: () => {
 			const form_values = dialog.get_values();
 			let values_filled = true;
-			const mandatory_fields = ['company', 'company_email', 'company_description'];
+
+			// TODO: Say "we notice that the company description and logo isn't set. Please set them in master."
+			// Only then allow to register
+
+			const mandatory_fields = ['company', 'company_description'];
 			mandatory_fields.forEach(field => {
 				const value = form_values[field];
 				if (!value) {
@@ -65,7 +59,7 @@
 	// Post create
 	const default_company = frappe.defaults.get_default('company');
 	dialog.set_value('company', default_company);
-	dialog.set_value('company_email', frappe.session.user);
+	dialog.set_value('email', frappe.session.user);
 
 	return dialog;
 }
diff --git a/erpnext/public/js/hub/marketplace.js b/erpnext/public/js/hub/marketplace.js
index 7659a36..bacca47 100644
--- a/erpnext/public/js/hub/marketplace.js
+++ b/erpnext/public/js/hub/marketplace.js
@@ -22,15 +22,20 @@
 
 		frappe.model.with_doc('Marketplace Settings').then(doc => {
 			hub.settings = doc;
-			const is_registered = hub.settings.registered;
-			const is_registered_seller = hub.settings.company_email === frappe.session.user;
+
 			this.setup_header();
 			this.make_sidebar();
 			this.make_body();
 			this.setup_events();
 			this.refresh();
-			if (!is_registered && !is_registered_seller && frappe.user_roles.includes('System Manager')) {
-				this.page.set_primary_action('Become a Seller', this.show_register_dialog.bind(this))
+
+			if (is_subset(['System Manager', 'Item Manager'], frappe.user_roles)) {
+				// show buttons only to System Manager
+				if (!hub.is_seller_registered()) {
+					this.page.set_primary_action('Become a Seller', this.show_register_dialog.bind(this))
+				} else {
+					this.page.set_secondary_action('Add Users', this.show_add_user_dialog.bind(this));
+				}
 			}
 		});
 	}
@@ -92,23 +97,97 @@
 			__('Become a Seller'),
 			{
 				label: __('Register'),
-				on_submit: this.register_seller.bind(this)
+				on_submit: this.register_marketplace.bind(this)
 			}
 		);
 
 		this.register_dialog.show();
 	}
 
-	register_seller(form_values) {
+	register_marketplace({company, company_description}) {
 		frappe.call({
-		    method: 'erpnext.hub_node.doctype.marketplace_settings.marketplace_settings.register_seller',
-		    args: form_values
-		}).then(() => {
-			this.register_dialog.hide();
-			frappe.set_route('marketplace', 'publish');
-
-		    erpnext.hub.trigger('seller-registered');
+		    method: 'erpnext.hub_node.api.register_marketplace',
+		    args: {
+				company,
+				company_description
+			}
+		}).then((r) => {
+			if (r.message && r.message.ok) {
+				this.register_dialog.hide();
+				frappe.set_route('marketplace', 'publish');
+				erpnext.hub.trigger('seller-registered');
+			}
 		});
 	}
 
+	show_add_user_dialog() {
+		this.get_unregistered_users()
+			.then(r => {
+				const user_list = r.message;
+
+				const d = new frappe.ui.Dialog({
+					title: __('Add Users to Marketplace'),
+					fields: [
+						{
+							label: __('Users'),
+							fieldname: 'users',
+							fieldtype: 'MultiSelect',
+							reqd: 1,
+							get_data() {
+								return user_list;
+							}
+						}
+					],
+					primary_action({ users }) {
+						const selected_users = users.split(',').map(d => d.trim()).filter(Boolean);
+
+						if (!selected_users.every(user => user_list.includes(user))) {
+							d.set_df_property('users', 'description', __('Some emails are invalid'));
+							return;
+						} else {
+							d.set_df_property('users', 'description', '');
+						}
+
+						frappe.call('erpnext.hub_node.api.register_users', {
+							user_list: selected_users
+						})
+						.then(r => {
+							d.hide();
+
+							if (r.message && r.message.length) {
+								frappe.show_alert(__('Added {0} users', [r.message.length]));
+							}
+						});
+					}
+				});
+
+				d.show();
+			});
+	}
+
+	get_unregistered_users() {
+		return frappe.call('erpnext.hub_node.api.get_unregistered_users')
+	}
+
+}
+
+Object.assign(hub, {
+	is_seller_registered() {
+		return hub.settings.registered;
+	},
+
+	is_user_registered() {
+		return this.is_seller_registered() && hub.settings.users
+			.filter(hub_user => hub_user.user === frappe.session.user)
+			.length === 1;
+	},
+});
+
+/**
+ * Returns true if list_a is subset of list_b
+ * @param {Array} list_a
+ * @param {Array} list_b
+ */
+function is_subset(list_a, list_b) {
+	return list_a.every(item => list_b.includes(item));
 }
diff --git a/erpnext/public/js/hub/pages/Buying.vue b/erpnext/public/js/hub/pages/Buying.vue
index ddb4b11..ebf593a 100644
--- a/erpnext/public/js/hub/pages/Buying.vue
+++ b/erpnext/public/js/hub/pages/Buying.vue
@@ -13,8 +13,8 @@
 					v-route="'marketplace/buying/' + item.name"
 				>
 					<div slot="subtitle">
-						<span>{{item.recent_message.sender}}: </span>
-						<span>{{item.recent_message.content | striphtml}}</span>
+						<span>{{ get_sender(item.recent_message) }}: </span>
+						<span>{{ item.recent_message.message | striphtml }}</span>
 					</div>
 				</item-list-card>
 			</div>
@@ -47,6 +47,9 @@
 	methods: {
 		get_items_for_messages() {
 			return hub.call('get_buying_items_for_messages', {}, 'action:send_message');
+		},
+		get_sender(message) {
+			return message.sender === frappe.session.user ? __('You') : (message.sender_name || message.sender);
 		}
 	}
 }
diff --git a/erpnext/public/js/hub/pages/Item.vue b/erpnext/public/js/hub/pages/Item.vue
index 3305b1d..272be58 100644
--- a/erpnext/public/js/hub/pages/Item.vue
+++ b/erpnext/public/js/hub/pages/Item.vue
@@ -81,7 +81,7 @@
 		is_own_item() {
 			let is_own_item = false;
 			if(this.item) {
-				if(this.item.hub_seller === hub.setting.company_email) {
+				if(this.item.hub_seller === hub.settings.hub_seller_name) {
 					is_own_item = true;
 				}
 			}
@@ -190,9 +190,9 @@
 		},
 
 		add_to_saved_items() {
-			hub.call('add_item_to_seller_saved_items', {
+			hub.call('add_item_to_user_saved_items', {
 				hub_item_name: this.hub_item_name,
-				hub_seller: hub.settings.company_email
+				hub_user: frappe.session.user
 			})
 			.then(() => {
 				const saved_items_link = `<b><a href="#marketplace/saved-items">${__('Saved')}</a></b>`
@@ -224,13 +224,11 @@
 					if (!message) return;
 
 					hub.call('send_message', {
-						from_seller: hub.settings.company_email,
-						to_seller: this.item.hub_seller,
 						hub_item: this.item.name,
 						message
 					})
 						.then(() => {
-							d.hide();
+							this.contact_seller_dialog.hide();
 							frappe.set_route('marketplace', 'buying', this.item.name);
 							erpnext.hub.trigger('action:send_message')
 						});
diff --git a/erpnext/public/js/hub/pages/Messages.vue b/erpnext/public/js/hub/pages/Messages.vue
index 1930bcb..73506e9 100644
--- a/erpnext/public/js/hub/pages/Messages.vue
+++ b/erpnext/public/js/hub/pages/Messages.vue
@@ -16,7 +16,7 @@
 						<div class="level margin-bottom" v-for="message in messages" :key="message.name">
 							<div class="level-left ellipsis" style="width: 80%;">
 								<div v-html="frappe.avatar(message.sender)" />
-								<div style="white-space: normal;" v-html="message.content" />
+								<div style="white-space: normal;" v-html="message.message" />
 							</div>
 							<div class="level-right text-muted" v-html="frappe.datetime.comment_when(message.creation, true)" />
 						</div>
@@ -64,13 +64,12 @@
 	methods: {
 		send_message(message) {
 			this.messages.push({
-				sender: hub.settings.company_email,
-				content: message,
+				sender: frappe.session.user,
+				message: message,
 				creation: Date.now(),
 				name: frappe.utils.get_random(6)
 			});
 			hub.call('send_message', {
-				from_seller: hub.settings.company_email,
 				to_seller: this.get_against_seller(),
 				hub_item: this.item_details.name,
 				message
diff --git a/erpnext/public/js/hub/pages/Profile.vue b/erpnext/public/js/hub/pages/Profile.vue
index a0bc6cb..91ed946 100644
--- a/erpnext/public/js/hub/pages/Profile.vue
+++ b/erpnext/public/js/hub/pages/Profile.vue
@@ -52,7 +52,7 @@
 		get_profile() {
 			hub.call(
 				'get_hub_seller_profile',
-				{ hub_seller: hub.settings.company_email }
+				{ hub_seller: hub.settings.hub_seller_name }
 			).then(profile => {
 				this.init = false;
 
diff --git a/erpnext/public/js/hub/pages/PublishedItems.vue b/erpnext/public/js/hub/pages/PublishedItems.vue
index 114259b..6559f79 100644
--- a/erpnext/public/js/hub/pages/PublishedItems.vue
+++ b/erpnext/public/js/hub/pages/PublishedItems.vue
@@ -5,10 +5,10 @@
 	>
 		<section-header>
 			<div>
-				<h5>{{ page_title }}</h5>
+				<h5>{{ __('Published Items') }}</h5>
 				<p v-if="items.length"
 					class="text-muted margin-bottom">
-					{{ published_items_message }}
+					{{ __('You can publish upto 200 items.') }}
 				</p>
 			</div>
 
@@ -16,7 +16,7 @@
 				class="btn btn-default btn-xs publish-items"
 				v-route="'marketplace/publish'"
 			>
-				<span>{{ publish_button_text }}</span>
+				<span>{{ __('Publish More Items') }}</span>
 			</button>
 
 		</section-header>
@@ -26,7 +26,7 @@
 			:items="items"
 			:item_id_fieldname="item_id_fieldname"
 			:on_click="go_to_item_details_page"
-			:empty_state_message="empty_state_message"
+			:empty_state_message="__('You haven\'t published any items yet.')"
 			:empty_state_action="publish_page_action"
 		>
 		</item-cards-container>
@@ -44,16 +44,9 @@
 			publish_page_action: {
 				label: __('Publish Your First Items'),
 				on_click: () => {
-					frappe.set_route(`marketplace/home`);
+					frappe.set_route(`marketplace/publish`);
 				}
-			},
-
-			// Constants
-			page_title: __('Published Items'),
-			publish_button_text: __('Publish More Items'),
-			published_items_message: __('You can publish upto 200 items.'),
-			// TODO: Add empty state action
-			empty_state_message: __('You haven\'t published any items yet.')
+			}
 		};
 	},
 	created() {
@@ -63,7 +56,7 @@
 		get_items() {
 			hub.call('get_items', {
 				filters: {
-					hub_seller: hub.settings.company_email
+					hub_seller: hub.settings.hub_seller_name
 				}
 			})
 			.then((items) => {
diff --git a/erpnext/public/js/hub/pages/SavedItems.vue b/erpnext/public/js/hub/pages/SavedItems.vue
index e5d21cd..c29675a 100644
--- a/erpnext/public/js/hub/pages/SavedItems.vue
+++ b/erpnext/public/js/hub/pages/SavedItems.vue
@@ -38,7 +38,7 @@
 	methods: {
 		get_items() {
 			hub.call(
-				'get_saved_items_of_seller', {},
+				'get_saved_items_of_user', {},
 				'action:item_save'
 			)
 			.then((items) => {
@@ -83,9 +83,9 @@
 
 		remove_item_from_saved_items(hub_item_name) {
 			erpnext.hub.trigger('action:item_save');
-			hub.call('remove_item_from_seller_saved_items', {
+			hub.call('remove_item_from_user_saved_items', {
 				hub_item_name,
-				hub_seller: hub.settings.company_email
+				hub_user: frappe.session.user
 			})
 			.then(() => {
 				this.get_items();
diff --git a/erpnext/public/js/hub/vue-plugins.js b/erpnext/public/js/hub/vue-plugins.js
index e18af0c..439c1f2 100644
--- a/erpnext/public/js/hub/vue-plugins.js
+++ b/erpnext/public/js/hub/vue-plugins.js
@@ -62,5 +62,5 @@
 });
 
 Vue.filter('striphtml', function (text) {
-	return strip_html(text);
+	return strip_html(text || '');
 });
\ No newline at end of file
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index a4c81c5..96d1116 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -312,6 +312,102 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "sb_about", 
+   "fieldtype": "Section Break", 
+   "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": "About the Company", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "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, 
+   "fieldname": "company_logo", 
+   "fieldtype": "Attach Image", 
+   "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": "Company Logo", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "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, 
+   "fieldname": "company_description", 
+   "fieldtype": "Text Editor", 
+   "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": "Company Description", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "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, 
    "fieldname": "sales_settings", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -741,7 +837,7 @@
    "label": "Create Chart Of Accounts Based On", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "\nStandard Template\nExisting Company", 
+   "options": "\nStandard Template\nExisting Company\n\n\n", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -775,7 +871,7 @@
    "label": "Chart Of Accounts Template", 
    "length": 0, 
    "no_copy": 1, 
-   "options": "", 
+   "options": "\n\n\n", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -2637,38 +2733,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "company_logo", 
-   "fieldtype": "Attach Image", 
-   "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": "Company Logo", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "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, 
    "fieldname": "lft", 
    "fieldtype": "Int", 
    "hidden": 1, 
@@ -2772,8 +2836,8 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2018-08-28 15:47:50.757131", 
- "modified_by": "Administrator", 
+ "modified": "2018-09-01 16:03:30.716918", 
+ "modified_by": "cave@aperture.com", 
  "module": "Setup", 
  "name": "Company", 
  "owner": "Administrator", 
@@ -2918,5 +2982,6 @@
  "show_name_in_global_search": 1, 
  "sort_order": "ASC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file