Website Listing
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 4e46fde..f3ff9e1 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -134,9 +134,6 @@
 					where name=`tabSales Invoice Item`.parent and ifnull(update_stock, 0) = 1)"""
 			})
 
-	def get_portal_page(self):
-		return "invoice" if self.docstatus==1 else None
-
 	def set_missing_values(self, for_validate=False):
 		self.set_pos_fields(for_validate)
 
@@ -576,6 +573,13 @@
 					})
 				)
 
+	@staticmethod
+	def get_list_context(context=None):
+		from erpnext.controllers.website_list_for_contact import get_list_context
+		list_context = get_list_context(context)
+		list_context["title"] = _("My Invoices")
+		return list_context
+
 @frappe.whitelist()
 def get_bank_cash_account(mode_of_payment, company):
 	account = frappe.db.get_value("Mode of Payment Account", {"parent": mode_of_payment, "company": company}, \
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 93a0145..5e27b3a 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -288,4 +288,3 @@
 				if not d.conversion_factor:
 					frappe.throw(_("Row {0}: Conversion Factor is mandatory"))
 				d.stock_qty = flt(d.qty) * flt(d.conversion_factor)
-
diff --git a/erpnext/controllers/website_list_for_contact.py b/erpnext/controllers/website_list_for_contact.py
new file mode 100644
index 0000000..4c729b6
--- /dev/null
+++ b/erpnext/controllers/website_list_for_contact.py
@@ -0,0 +1,78 @@
+# Copyright (c) 2015, Web Notes Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import json
+import frappe
+from frappe import _
+from frappe.utils import flt
+from frappe.utils.user import is_website_user
+
+def get_list_context(context=None):
+	return {
+		"global_number_format": frappe.db.get_default("number_format") or "#,###.##",
+		"currency": frappe.db.get_default("currency"),
+		"currency_symbols": json.dumps(dict(frappe.db.sql("""select name, symbol
+			from tabCurrency where ifnull(enabled,0)=1"""))),
+		"row_template": "templates/includes/transaction_row.html",
+		"get_list": get_transaction_list
+	}
+
+def get_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20):
+	from frappe.templates.pages.list import get_list
+	user = frappe.session.user
+
+	if user != "Guest" and is_website_user(user):
+		# find party for this contact
+		customers, suppliers = get_customers_suppliers(doctype, user)
+		if customers:
+			return post_process(get_list(doctype, txt, filters=[(doctype, "customer", "in", customers)],
+				limit_start=limit_start, limit_page_length=limit_page_length, ignore_permissions=True))
+
+		elif suppliers:
+			return post_process(get_list(doctype, txt, filters=[(doctype, "supplier", "in", suppliers)],
+				limit_start=limit_start, limit_page_length=limit_page_length, ignore_permissions=True))
+
+		else:
+			return []
+
+	return post_process(get_list(doctype, txt, filters, limit_start, limit_page_length))
+
+def post_process(result):
+	for r in result:
+		r.status_percent = 0
+		r.status_display = []
+
+		if r.get("per_billed"):
+			r.status_percent += flt(r.per_billed)
+			r.status_display.append(_("Billed") if r.per_billed==100 else _("{0}% Billed").format(r.per_billed))
+
+		if r.get("per_delivered"):
+			r.status_percent += flt(r.per_delivered)
+			r.status_display.append(_("Delivered") if r.per_delivered==100 else _("{0}% Delivered").format(r.per_delivered))
+
+		r.status_display = ", ".join(r.status_display)
+
+	return result
+
+def get_customers_suppliers(doctype, user):
+	meta = frappe.get_meta(doctype)
+	contacts = frappe.get_all("Contact", fields=["customer", "supplier", "email_id"],
+		filters={"email_id": user})
+
+	customers = [c.customer for c in contacts if c.customer] if meta.get_field("customer") else None
+	suppliers = [c.supplier for c in contacts if c.supplier] if meta.get_field("supplier") else None
+
+	return customers, suppliers
+
+def has_website_permission(doc, ptype, user, verbose=False):
+	doctype = doc.doctype
+	customers, suppliers = get_customers_suppliers(doctype, user)
+	if customers:
+		return frappe.get_all(doctype, filters=[(doctype, "customer", "in", customers),
+			(doctype, "name", "=", doc.name)]) and True or False
+	elif suppliers:
+		return frappe.get_all(doctype, filters=[(doctype, "suppliers", "in", suppliers),
+			(doctype, "name", "=", doc.name)]) and True or False
+	else:
+		return False
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index ffc9496..0edaa92 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -20,7 +20,28 @@
 
 on_session_creation = "erpnext.shopping_cart.utils.set_cart_count"
 on_logout = "erpnext.shopping_cart.utils.clear_cart_count"
-update_website_context = ["erpnext.shopping_cart.utils.update_website_context", "erpnext.startup.webutils.update_website_context"]
+
+# website
+update_website_context = "erpnext.shopping_cart.utils.update_website_context"
+my_account_context = "erpnext.shopping_cart.utils.update_my_account_context"
+
+website_route_rules = [
+	{"from_route": "/orders", "to_route": "Sales Order"},
+	{"from_route": "/orders/<name>", "to_route": "print", "defaults": {"doctype": "Sales Order"}},
+	{"from_route": "/invoices", "to_route": "Sales Invoice"},
+	{"from_route": "/invoices/<name>", "to_route": "print", "defaults": {"doctype": "Sales Invoice"}},
+	{"from_route": "/shipments", "to_route": "Delivery Note"},
+	{"from_route": "/shipments/<name>", "to_route": "print", "defaults": {"doctype": "Delivery Note"}},
+	{"from_route": "/issues", "to_route": "Issue"},
+	{"from_route": "/issues/<name>", "to_route": "print", "defaults": {"doctype": "Issue"}},
+	{"from_route": "/addresses", "to_route": "Address"},
+]
+
+has_website_permission = {
+	"Sales Order": "erpnext.controllers.website_list_for_contact.has_website_permission",
+	"Sales Invoice": "erpnext.controllers.website_list_for_contact.has_website_permission",
+	"Delivery Note": "erpnext.controllers.website_list_for_contact.has_website_permission"
+}
 
 dump_report_map = "erpnext.startup.report_data_map.data_map"
 
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 607f913..ba61b3c 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -204,7 +204,7 @@
 
 		if holiday_list not in self.holidays:
 			holiday_list_days = [getdate(d[0]) for d in frappe.get_all("Holiday", fields=["holiday_date"],
-				filters={"parent": holiday_list}, order_by="holiday_date", limit_page_length=0, as_list=1)]
+				filters={"parent": holiday_list}, order_by="holiday_date", as_list=1)]
 
 			self.holidays[holiday_list] = holiday_list_days
 
diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css
index 747311c..e524a7c 100644
--- a/erpnext/public/css/erpnext.css
+++ b/erpnext/public/css/erpnext.css
@@ -48,7 +48,6 @@
 .pos-item-image {
 	padding-bottom: 100%;
 	background-size: cover;
-	background-position: center;
 	border: 1px solid transparent;
 }
 
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 64523a9..b5659be 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -5,7 +5,7 @@
 import frappe
 import frappe.utils
 from frappe.utils import cstr, flt, getdate, comma_and
-from frappe import _ , msgprint
+from frappe import _
 from frappe.model.mapper import get_mapped_doc
 
 from erpnext.controllers.selling_controller import SellingController
@@ -231,8 +231,12 @@
 	def on_update(self):
 		pass
 
-	def get_portal_page(self):
-		return "order" if self.docstatus==1 else None
+	@staticmethod
+	def get_list_context(context=None):
+		from erpnext.controllers.website_list_for_contact import get_list_context
+		list_context = get_list_context(context)
+		list_context["title"] = _("My Orders")
+		return list_context
 
 @frappe.whitelist()
 def make_material_request(source_name, target_doc=None):
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index ba95bd0..6e313eb 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -12,9 +12,11 @@
 
 class ItemGroup(NestedSet, WebsiteGenerator):
 	nsm_parent_field = 'parent_item_group'
-	condition_field = "show_in_website"
-	template = "templates/generators/item_group.html"
-	parent_website_route_field = "parent_item_group"
+	website = frappe._dict(
+		condition_field = "show_in_website",
+		template = "templates/generators/item_group.html",
+		parent_website_route_field = "parent_item_group"
+	)
 
 	def autoname(self):
 		self.name = self.item_group_name
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.py b/erpnext/setup/doctype/sales_partner/sales_partner.py
index 0dfbe4c..b6a63ae 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.py
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.py
@@ -8,9 +8,12 @@
 from erpnext.utilities.address_and_contact import load_address_and_contact
 
 class SalesPartner(WebsiteGenerator):
-	page_title_field = "partner_name"
-	condition_field = "show_in_website"
-	template = "templates/generators/sales_partner.html"
+	website = frappe._dict(
+		page_title_field = "partner_name",
+		condition_field = "show_in_website",
+		template = "templates/generators/sales_partner.html"
+	)
+
 	def onload(self):
 		"""Load address and contacts in `__onload`"""
 		load_address_and_contact(self, "sales_partner")
diff --git a/erpnext/setup/page/setup_wizard/default_website.py b/erpnext/setup/page/setup_wizard/default_website.py
index 5dbb7fc..66a3df7 100644
--- a/erpnext/setup/page/setup_wizard/default_website.py
+++ b/erpnext/setup/page/setup_wizard/default_website.py
@@ -6,7 +6,6 @@
 
 from frappe import _
 from frappe.utils import nowdate
-from frappe.templates.pages.style_settings import default_properties
 
 class website_maker(object):
 	def __init__(self, company, tagline, user):
@@ -14,7 +13,6 @@
 		self.tagline = tagline
 		self.user = user
 		self.make_web_page()
-		self.make_style_settings()
 		self.make_website_settings()
 		self.make_blog()
 
@@ -34,12 +32,6 @@
 			})
 		}).insert()
 
-	def make_style_settings(self):
-		style_settings = frappe.get_doc("Style Settings", "Style Settings")
-		style_settings.update(default_properties)
-		style_settings.apply_style = 1
-		style_settings.save()
-
 	def make_website_settings(self):
 		# update in home page in settings
 		website_settings = frappe.get_doc("Website Settings", "Website Settings")
diff --git a/erpnext/shopping_cart/__init__.py b/erpnext/shopping_cart/__init__.py
index ddee6dc..28ba5f9 100644
--- a/erpnext/shopping_cart/__init__.py
+++ b/erpnext/shopping_cart/__init__.py
@@ -5,7 +5,7 @@
 import frappe
 from frappe import _
 from frappe.utils import get_fullname, flt
-from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import is_shopping_cart_enabled, get_default_territory
+from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import check_shopping_cart_enabled, get_default_territory
 
 # TODO
 # validate stock of each item in Website Warehouse or have a list of possible warehouses in Shopping Cart Settings
@@ -17,7 +17,7 @@
 	if user == "Guest":
 		raise frappe.PermissionError
 
-	is_shopping_cart_enabled()
+	check_shopping_cart_enabled()
 	party = get_party(user)
 	values = {
 		"order_type": "Shopping Cart",
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
index cdbe6c2..ec8fea3 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py
@@ -158,10 +158,13 @@
 
 	return frappe.local.shopping_cart_settings
 
+def is_cart_enabled():
+	return get_shopping_cart_settings().enabled
+
 def get_default_territory():
 	return get_shopping_cart_settings().default_territory
 
-def is_shopping_cart_enabled():
+def check_shopping_cart_enabled():
 	if not get_shopping_cart_settings().enabled:
 		frappe.throw(_("You need to enable Shopping Cart"), ShoppingCartSetupError)
 
diff --git a/erpnext/shopping_cart/utils.py b/erpnext/shopping_cart/utils.py
index ee011a4..67b6bc0 100644
--- a/erpnext/shopping_cart/utils.py
+++ b/erpnext/shopping_cart/utils.py
@@ -4,8 +4,10 @@
 from __future__ import unicode_literals
 
 import frappe
+from frappe import _
 import frappe.defaults
 from frappe.utils import cint
+from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import is_cart_enabled
 
 def show_cart_count():
 	if (frappe.db.get_default("shopping_cart_enabled") and
@@ -16,32 +18,32 @@
 
 def set_cart_count(login_manager):
 	if show_cart_count():
-		from .shopping_cart.cart import set_cart_count
+		from erpnext.shopping_cart.cart import set_cart_count
 		set_cart_count()
 
 def clear_cart_count(login_manager):
 	if show_cart_count():
 		frappe.local.cookie_manager.delete_cookie("cart_count")
 
-def update_website_context(context):
-	post_login = []
-	cart_enabled = cint(frappe.db.get_default("shopping_cart_enabled"))
+def update_website_params(context):
+	cart_enabled = is_cart_enabled()
 	context["shopping_cart_enabled"] = cart_enabled
 
 	if cart_enabled:
-		post_login += [
-			{"label": "Cart", "url": "cart", "icon": "icon-shopping-cart", "class": "cart-count"},
+		post_login = [
+			{"label": _("Cart"), "url": "cart", "class": "cart-count"},
 			{"class": "divider"}
 		]
+		context["post_login"] = post_login + context.get("post_login", [])
 
-	post_login += [
-		{"label": "User", "url": "user", "icon": "icon-user"},
-		{"label": "Addresses", "url": "addresses", "icon": "icon-map-marker"},
-		{"label": "My Orders", "url": "orders", "icon": "icon-list"},
-		{"label": "My Tickets", "url": "tickets", "icon": "icon-tags"},
-		{"label": "Invoices", "url": "invoices", "icon": "icon-file-text"},
-		{"label": "Shipments", "url": "shipments", "icon": "icon-truck"},
-		{"class": "divider"}
-	]
+def update_my_account_context(context):
+	if is_cart_enabled():
+		context["my_account_list"].append({"label": _("Cart"), "url": "cart"})
 
-	context["post_login"] = post_login + context.get("post_login", [])
+	context["my_account_list"].extend([
+		{"label": _("Orders"), "url": "orders"},
+		{"label": _("Invoices"), "url": "invoices"},
+		{"label": _("Shipments"), "url": "shipments"},
+		{"label": _("Issues"), "url": "tickets"},
+		{"label": _("Addresses"), "url": "addresses"},
+	])
diff --git a/erpnext/startup/webutils.py b/erpnext/startup/webutils.py
deleted file mode 100644
index 9942b1b..0000000
--- a/erpnext/startup/webutils.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-
-import frappe
-
-def update_website_context(context):
-	if not context.get("favicon"):
-		context["favicon"] = "app/images/favicon.ico"
\ No newline at end of file
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index ec45623..91b4af4 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -75,9 +75,6 @@
 			for f in fieldname:
 				toggle_print_hide(self.meta if key == "parent" else item_meta, f)
 
-	def get_portal_page(self):
-		return "shipment" if self.docstatus==1 else None
-
 	def set_actual_qty(self):
 		for d in self.get('items'):
 			if d.item_code and d.warehouse:
@@ -288,6 +285,13 @@
 			}
 			update_bin(args)
 
+	@staticmethod
+	def get_list_context(context=None):
+		from erpnext.controllers.website_list_for_contact import get_list_context
+		list_context = get_list_context(context)
+		list_context["title"] = _("My Shipments")
+		return list_context
+
 def get_invoiced_qty_map(delivery_note):
 	"""returns a map: {dn_detail: invoiced_qty}"""
 	invoiced_qty_map = {}
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 5eb6a9b..ef45a31 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -16,10 +16,12 @@
 class ItemTemplateCannotHaveStock(frappe.ValidationError): pass
 
 class Item(WebsiteGenerator):
-	page_title_field = "item_name"
-	condition_field = "show_in_website"
-	template = "templates/generators/item.html"
-	parent_website_route_field = "item_group"
+	website = frappe._dict(
+		page_title_field = "item_name",
+		condition_field = "show_in_website",
+		template = "templates/generators/item.html",
+		parent_website_route_field = "item_group",
+	)
 
 	def onload(self):
 		super(Item, self).onload()
@@ -82,6 +84,8 @@
 		if self.slideshow:
 			context.update(get_slideshow(self))
 
+		context["parents"] = self.get_parents(context)
+
 		return context
 
 	def check_warehouse_is_set_for_stock_item(self):
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index e322c9c..1c11065 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -7,14 +7,12 @@
 
 from frappe.model.document import Document
 from frappe.utils import now
+from frappe.utils.user import is_website_user
 
 class Issue(Document):
 	def get_feed(self):
 		return "{0}: {1}".format(_(self.status), self.subject)
 
-	def get_portal_page(self):
-		return "ticket"
-
 	def set_sender(self, sender):
 		"""Will be called by **Communication** when the Issue is created from an incoming email."""
 		self.raised_by = sender
@@ -50,6 +48,24 @@
 			# if no date, it should be set as None and not a blank string "", as per mysql strict config
 			self.resolution_date = None
 
+	@staticmethod
+	def get_list_context(context=None):
+		return {
+			"title": _("My Issues"),
+			"get_list": get_issue_list
+		}
+
+def get_issue_list(doctype, txt, filters, limit_start, limit_page_length=20):
+	from frappe.templates.pages.list import get_list
+	user = frappe.session.user
+	ignore_permissions = False
+	if is_website_user(user):
+		if not filters: filters = []
+		filters.append(("Issue", "raised_by", "=", user))
+		ignore_permissions = True
+
+	return get_list(doctype, txt, filters, limit_start, limit_page_length, ignore_permissions=ignore_permissions)
+
 @frappe.whitelist()
 def set_status(name, status):
 	st = frappe.get_doc("Issue", name)
diff --git a/erpnext/templates/generators/item_group.html b/erpnext/templates/generators/item_group.html
index 8597864..6cc4212 100644
--- a/erpnext/templates/generators/item_group.html
+++ b/erpnext/templates/generators/item_group.html
@@ -36,3 +36,36 @@
 </script>
 
 {% endblock %}
+
+{% block style %}
+<style>
+	.product-link {
+		display: block;
+		text-align: center;
+	}
+
+	.product-image-wrapper {
+		max-width: 300px;
+		margin: auto;
+	}
+
+	.product-image {
+		width: 100%;
+		height: 0;
+		padding-bottom: 100%;
+		border-radius: 4px;
+		border: 1px solid transparent;
+		background-size: cover;
+		background-repeat: no-repeat;
+	}
+
+	.product-image.missing-image {
+		border: 1px dashed {{ border_color or "#d1d8dd" }};
+	}
+
+	.product-text {
+		padding: 15px 0px;
+	}
+
+</style>
+{% endblock %}
diff --git a/erpnext/templates/includes/product_in_grid.html b/erpnext/templates/includes/product_in_grid.html
index 4c4be71..27cc321 100644
--- a/erpnext/templates/includes/product_in_grid.html
+++ b/erpnext/templates/includes/product_in_grid.html
@@ -1,14 +1,8 @@
-<div class="col-sm-3">
-	<div style="height: 120px; overflow: hidden;">
-		<a href="{{ route or page_name }}">
-		{%- if website_image -%}
-		<img class="product-image" style="width: 80%; margin: auto;" src="{{ website_image }}">
-		{%- else -%}
-		{% include 'templates/includes/product_missing_image.html' %}
-		{%- endif -%}
-		</a>
+<a class="product-link" href="{{ route or page_name }}">
+	<div class="col-sm-2 product-image-wrapper">
+		<div class="product-image {% if not website_image -%}missing-image{%- endif %}"
+			{% if website_image -%} style="background-image: url({{ website_image }});" {%- endif %}>
+		</div>
+		<div class="product-text small">{{ item_name }}</div>
 	</div>
-	<div style="height: 100px; overflow: hidden; font-size: 80%;">
-		<div style="margin-bottom: 2px;"><a href="{{ route or page_name }}">{{ item_name }}</a></div>
-	</div>
-</div>
+</a>
diff --git a/erpnext/templates/includes/sale.html b/erpnext/templates/includes/sale.html
deleted file mode 100644
index 6323995..0000000
--- a/erpnext/templates/includes/sale.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<div class="sale-content">
-    <ul class="breadcrumb">
-    	<li><a href="index">Home</a></li>
-    	<li><a href="{{ parent_link }}">{{ parent_title }}</a></li>
-    	<li class="active"><i class="icon-file icon-fixed-width"></i> {{ doc.name }}</li>
-    </ul>
-	<h3><i class="icon-file icon-fixed-width"></i> {{ doc.name }}</h3>
-	{% if doc.name == _("Not Allowed") -%}
-		<script>ask_to_login();</script>
-	{% else %}
-	<hr>
-	<div>
-	<div class="row">
-		<div class="col-xs-6">
-			{% if doc.status -%}{{ doc.status }}{%- endif %}
-		</div>
-		<div class="col-xs-6">
-			<span class="pull-right">{{ frappe.utils.formatdate(doc.posting_date or doc.transaction_date) }}</span>
-		</div>
-	</div>
-	<br>
-	<div class="row">
-		<div class="col-md-12">
-		<table class="table table-bordered">
-			<tbody>
-				<tr>
-					<th>Sr</th>
-					<th>Item Name</th>
-					<th>Description</th>
-					<th>Qty</th>
-					<th>UoM</th>
-					<th>Basic Rate</th>
-					<th>Amount</th>
-				</tr>
-				{%- for row in doc.get({"doctype": doc.doctype + " Item"}) %}
-				<tr>
-					<td style="width: 3%;">{{ row.idx }}</td>
-					<td style="width: 20%;">{{ row.item_name }}</td>
-					<td style="width: 37%;">{{ row.description }}</td>
-					<td style="width: 5%; text-align: right;">{{ row.qty }}</td>
-					<td style="width: 5%;">{{ row.stock_uom }}</td>
-					<td style="width: 15%; text-align: right;">{{ frappe.utils.fmt_money(row.rate, currency=doc.currency) }}</td>
-					<td style="width: 15%; text-align: right;">{{ frappe.utils.fmt_money(row.amount, currency=doc.currency) }}</td>
-				</tr>
-				{% endfor -%}
-			</tbody>
-		</table>
-		</div>
-	</div>
-	<div class="row">
-		<div class="col-md-6"></div>
-		<div class="col-md-6">
-		<table cellspacing=0 width=100%>
-		<tbody>
-			<tr>
-				<td>Net Total</td>
-				<td width=40% style="text-align: right;">{{
-					frappe.utils.fmt_money(doc.base_net_total/doc.conversion_rate, currency=doc.currency)
-				}}</td>
-			</tr>
-			{%- for charge in doc.get({"doctype":"Sales Taxes and Charges"}) -%}
-			{%- if not charge.included_in_print_rate -%}
-			<tr>
-				<td>{{ charge.description }}</td>
-				<td style="text-align: right;">{{ frappe.utils.fmt_money(charge.tax_amount / doc.conversion_rate, currency=doc.currency) }}</td>
-			</tr>
-			{%- endif -%}
-			{%- endfor -%}
-			<tr>
-				<td>Grand Total</td>
-				<td style="text-align: right;">{{ frappe.utils.fmt_money(doc.grand_total, currency=doc.currency) }}</td>
-			</tr>
-			<tr style='font-weight: bold'>
-				<td>Rounded Total</td>
-				<td style="text-align: right;">{{ frappe.utils.fmt_money(doc.rounded_total, currency=doc.currency) }}</td>
-			</tr>
-		</tbody>
-		</table>
-		</div>
-	</div>
-	</div>
-	{%- endif %}
-</div>
-
-<!-- no-sidebar -->
diff --git a/erpnext/templates/includes/sales_transactions.html b/erpnext/templates/includes/sales_transactions.html
deleted file mode 100644
index 465f5ed..0000000
--- a/erpnext/templates/includes/sales_transactions.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<script>
-$(document).ready(function() {
-	global_number_format = "{{ global_number_format }}";
-	currency = "{{ currency }}";
-	frappe.currency_symbols = {{ currency_symbols }};
-});
-</script>
-
-{% include "templates/includes/transactions.html" %}
-
-<script>
-	var render = function(doc) {
-		doc.grand_total = format_currency(doc.grand_total, doc.currency);
-		if(!doc.status) doc.status = "";
-
-		$(repl('<a href="{{ page }}?name=%(name)s" class="list-group-item">\
-				<div class="row">\
-					<div class="col-md-6">\
-						<div class="row col-md-12">%(name)s</div>\
-						<div class="row col-md-12 text-muted">%(items)s</div>\
-						<div class="row col-md-12">%(status)s</div>\
-					</div>\
-					<div class="col-md-3 text-right">%(grand_total)s</div>\
-					<div class="col-md-3 text-right text-muted">%(creation)s</div>\
-				</div>\
-			</a>', doc)).appendTo($list);
-	};
-</script>
-
-<!-- no-sidebar -->
diff --git a/erpnext/templates/includes/transaction_row.html b/erpnext/templates/includes/transaction_row.html
new file mode 100644
index 0000000..ca03bd3
--- /dev/null
+++ b/erpnext/templates/includes/transaction_row.html
@@ -0,0 +1,30 @@
+{% set doc = frappe.get_doc(doc) %}
+<a class="website-list-row" href="/{{ pathname }}/{{ doc.name }}" no-pjax>
+<div class="row">
+	<div class="col-sm-6 col-xs-7">
+		<div class="row">
+			<div class="col-sm-9">{{ doc.customer or doc.supplier }}</div>
+			<div class="col-sm-3">
+				{%- if doc.status_percent > 0 -%}
+					{%- if doc.status_percent % 100 == 0 -%}
+					<span class="indicator green">{{ doc.status_display }}</span>
+					{%- else -%}
+					<span class="indicator orange">{{ doc.status_display }}</span>
+					{%- endif -%}
+				{%- elif doc.status -%}
+					<span class="indicator">{{ doc.status }}</span>
+				{%- endif -%}
+			</div>
+		</div>
+	</div>
+	<div class="col-sm-2 col-xs-5 text-right">
+		{{ doc.get_formatted("grand_total") }}
+	</div>
+	<div class="col-sm-2 text-muted text-right">
+		{{ doc.name }}
+	</div>
+	<div class="col-sm-2 small text-muted text-right" title="{{ frappe.utils.format_datetime(doc.creation, "medium") }}">
+		{{ frappe.utils.pretty_date(doc.creation) }}</div>
+</div>
+</a>
+
diff --git a/erpnext/templates/includes/transactions.html b/erpnext/templates/includes/transactions.html
deleted file mode 100644
index fb570cd..0000000
--- a/erpnext/templates/includes/transactions.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<div class="transactions-content">
-    <ul class="breadcrumb">
-    	<li><a href="index">Home</a></li>
-    	<li class="active"><i class="{{ icon }} icon-fixed-width"></i> {{ title }}</li>
-    </ul>
-	<p id="msgprint-alert" class="alert alert-danger"
-		style="display: none;">&nbsp;</p>
-	<div class="list-group transaction-list">
-		<div class="text-muted progress">{{ _("Loading") }}...</div>
-	</div>
-	<div class="text-center">
-		<button class="btn btn-default btn-show-more hide">More</button>
-	</div>
-</div>
-<script>
-var get_transactions = function(btn) {
-	frappe.call({
-		method: "{{ method }}",
-		args: { start: start },
-		btn: btn,
-		callback: function(r) {
-			$list.find(".progress").remove();
-			$show_more.toggleClass("hide", !(r.message && r.message.length===20));
-			if(!(r.message && r.message.length)) {
-				if(!$list.html().trim()) {
-					$list.html("<div class='text-muted'>\
-						{{ empty_list_message }}</div>");
-				}
-				return;
-			}
-
-			start += r.message.length;
-
-			$.each(r.message, function(i, doc) {
-				render(doc);
-			});
-		}
-	})
-};
-
-$(document).ready(function() {
-	window.start = 0;
-	window.$list = $(".transaction-list");
-	window.$list.find(".list-group-item").remove();
-	window.$show_more = $(".btn-show-more").on("click", function() { get_transactions(this); })
-
-	get_transactions();
-});
-</script>
-
-<!-- no-sidebar -->
diff --git a/erpnext/templates/pages/invoice.html b/erpnext/templates/pages/invoice.html
deleted file mode 100644
index 13b0e72..0000000
--- a/erpnext/templates/pages/invoice.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{% block title %} {{ doc.name }} {% endblock %}
-
-{% block header %}<h2>{{ doc.name }}</h2>{% endblock %}
-
-{% block content%}{% include "templates/includes/sale.html" %}{% endblock %}
-
diff --git a/erpnext/templates/pages/invoice.py b/erpnext/templates/pages/invoice.py
deleted file mode 100644
index 8109109..0000000
--- a/erpnext/templates/pages/invoice.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe import _
-from frappe.utils import flt, fmt_money
-from erpnext.templates.utils import get_transaction_context
-
-no_cache = 1
-no_sitemap = 1
-
-def get_context(context):
-	invoice_context = frappe._dict({
-		"parent_link": "invoices",
-		"parent_title": "Invoices"
-	})
-	invoice_context.update(get_transaction_context("Sales Invoice", frappe.form_dict.name))
-	modify_status(invoice_context.doc)
-	return invoice_context
-	
-def modify_status(doc):
-	doc.status = ""
-	if flt(doc.outstanding_amount):
-		doc.status = '<span class="label %s"><i class="icon-fixed-width %s"></i> %s</span>' % \
-			("label-warning", "icon-exclamation-sign", 
-			_("To Pay") + " = " + fmt_money(doc.outstanding_amount, currency=doc.currency))
-	else:
-		doc.status = '<span class="label %s"><i class="icon-fixed-width %s"></i> %s</span>' % \
-			("label-success", "icon-ok", _("Paid"))
-		
\ No newline at end of file
diff --git a/erpnext/templates/pages/invoices.html b/erpnext/templates/pages/invoices.html
deleted file mode 100644
index 9f493ca..0000000
--- a/erpnext/templates/pages/invoices.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{% block title %} {{ title }} {% endblock %}
-
-{% block header %}<h2>{{ title }}</h2>{% endblock %}
-
-{% block content %}{% include "templates/includes/sales_transactions.html" %}{% endblock %}
-
diff --git a/erpnext/templates/pages/invoices.py b/erpnext/templates/pages/invoices.py
deleted file mode 100644
index 87aff21..0000000
--- a/erpnext/templates/pages/invoices.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-from erpnext.templates.utils import get_currency_context
-
-no_cache = 1
-no_sitemap = 1
-
-def get_context(context):
-	invoices_context = get_currency_context()
-	invoices_context.update({
-		"title": "Invoices",
-		"method": "erpnext.templates.pages.invoices.get_invoices",
-		"icon": "icon-file-text",
-		"empty_list_message": "No Invoices Found",
-		"page": "invoice"
-	})
-	return invoices_context
-	
-@frappe.whitelist()
-def get_invoices(start=0):
-	from erpnext.templates.utils import get_transaction_list
-	from erpnext.templates.pages.invoice import modify_status
-	invoices = get_transaction_list("Sales Invoice", start, ["outstanding_amount"])
-	for d in invoices:
-		modify_status(d)
-	return invoices
\ No newline at end of file
diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html
deleted file mode 100644
index 13b0e72..0000000
--- a/erpnext/templates/pages/order.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{% block title %} {{ doc.name }} {% endblock %}
-
-{% block header %}<h2>{{ doc.name }}</h2>{% endblock %}
-
-{% block content%}{% include "templates/includes/sale.html" %}{% endblock %}
-
diff --git a/erpnext/templates/pages/order.py b/erpnext/templates/pages/order.py
deleted file mode 100644
index 527caba..0000000
--- a/erpnext/templates/pages/order.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe import _
-from erpnext.templates.utils import get_transaction_context
-
-no_cache = 1
-no_sitemap = 1
-
-def get_context(context):
-	order_context = frappe._dict({
-		"parent_link": "orders",
-		"parent_title": "My Orders"
-	})
-
-	order_context.update(get_transaction_context("Sales Order", frappe.form_dict.name))
-	modify_status(order_context.doc)
-	return order_context
-
-def modify_status(doc):
-	doc.status = []
-	if 0 < doc.per_billed < 100:
-		doc.status.append(("label-warning", "icon-ok", _("Partially Billed")))
-	elif doc.per_billed == 100:
-		doc.status.append(("label-success", "icon-ok", _("Billed")))
-
-	if 0 < doc.per_delivered < 100:
-		doc.status.append(("label-warning", "icon-truck", _("Partially Delivered")))
-	elif doc.per_delivered == 100:
-		doc.status.append(("label-success", "icon-truck", _("Delivered")))
-	doc.status = " " + " ".join(('<span class="label %s"><i class="icon-fixed-width %s"></i> %s</span>' % s
-			for s in doc.status))
diff --git a/erpnext/templates/pages/orders.html b/erpnext/templates/pages/orders.html
deleted file mode 100644
index d58cbd8..0000000
--- a/erpnext/templates/pages/orders.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% block title %} {{ title }} {% endblock %}
-
-{% block header %}<h2>{{ title }}</h2>{% endblock %}
-
-{% block content %}{% include "templates/includes/sales_transactions.html" %}{% endblock %}
diff --git a/erpnext/templates/pages/orders.py b/erpnext/templates/pages/orders.py
deleted file mode 100644
index ebf75b3..0000000
--- a/erpnext/templates/pages/orders.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-from erpnext.templates.utils import get_currency_context, get_transaction_list
-from erpnext.templates.pages.order import modify_status
-
-no_cache = 1
-no_sitemap = 1
-
-def get_context(context):
-	orders_context = get_currency_context()
-	orders_context.update({
-		"title": "My Orders",
-		"method": "erpnext.templates.pages.orders.get_orders",
-		"icon": "icon-list",
-		"empty_list_message": "No Orders Yet",
-		"page": "order",
-	})
-	return orders_context
-	
-@frappe.whitelist()
-def get_orders(start=0):
-	orders = get_transaction_list("Sales Order", start, ["per_billed", "per_delivered"])
-	for d in orders:
-		modify_status(d)
-		
-	return orders
-	
\ No newline at end of file
diff --git a/erpnext/templates/pages/shipment.html b/erpnext/templates/pages/shipment.html
deleted file mode 100644
index 13b0e72..0000000
--- a/erpnext/templates/pages/shipment.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{% block title %} {{ doc.name }} {% endblock %}
-
-{% block header %}<h2>{{ doc.name }}</h2>{% endblock %}
-
-{% block content%}{% include "templates/includes/sale.html" %}{% endblock %}
-
diff --git a/erpnext/templates/pages/shipment.py b/erpnext/templates/pages/shipment.py
deleted file mode 100644
index a8047f5..0000000
--- a/erpnext/templates/pages/shipment.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-from erpnext.templates.utils import get_transaction_context
-
-no_cache = 1
-no_sitemap = 1
-
-def get_context(context):
-	shipment_context = frappe._dict({
-		"parent_link": "shipments",
-		"parent_title": "Shipments"
-	})
-	shipment_context.update(get_transaction_context("Delivery Note", frappe.form_dict.name))
-	return shipment_context
diff --git a/erpnext/templates/pages/shipments.html b/erpnext/templates/pages/shipments.html
deleted file mode 100644
index d58cbd8..0000000
--- a/erpnext/templates/pages/shipments.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% block title %} {{ title }} {% endblock %}
-
-{% block header %}<h2>{{ title }}</h2>{% endblock %}
-
-{% block content %}{% include "templates/includes/sales_transactions.html" %}{% endblock %}
diff --git a/erpnext/templates/pages/shipments.py b/erpnext/templates/pages/shipments.py
deleted file mode 100644
index 350b3e4..0000000
--- a/erpnext/templates/pages/shipments.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-from erpnext.templates.utils import get_currency_context
-
-no_cache = 1
-no_sitemap = 1
-
-def get_context(context):
-	shipments_context = get_currency_context()
-	shipments_context.update({
-		"title": "Shipments",
-		"method": "erpnext.templates.pages.shipments.get_shipments",
-		"icon": "icon-truck",
-		"empty_list_message": "No Shipments Found",
-		"page": "shipment"
-	})
-	return shipments_context
-	
-@frappe.whitelist()
-def get_shipments(start=0):
-	from erpnext.templates.utils import get_transaction_list
-	return get_transaction_list("Delivery Note", start)
diff --git a/erpnext/templates/utils.py b/erpnext/templates/utils.py
index 9108acf..9ce1111 100644
--- a/erpnext/templates/utils.py
+++ b/erpnext/templates/utils.py
@@ -21,47 +21,3 @@
 		"sent_or_received": "Received"
 	})
 	comm.insert(ignore_permissions=True)
-
-def get_transaction_list(doctype, start, additional_fields=None):
-	# find customer id
-	customer = frappe.db.get_value("Contact", {"email_id": frappe.session.user},
-		"customer")
-
-	if customer:
-		if additional_fields:
-			additional_fields = ", " + ", ".join(("`%s`" % f for f in additional_fields))
-		else:
-			additional_fields = ""
-
-		transactions = frappe.db.sql("""select name, creation, currency, grand_total
-			%s
-			from `tab%s` where customer=%s and docstatus=1
-			order by creation desc
-			limit %s, 20""" % (additional_fields, doctype, "%s", "%s"),
-			(customer, cint(start)), as_dict=True)
-		for doc in transactions:
-			items = frappe.db.sql_list("""select item_name
-				from `tab%s Item` where parent=%s limit 6""" % (doctype, "%s"), doc.name)
-			doc.items = ", ".join(items[:5]) + ("..." if (len(items) > 5) else "")
-			doc.creation = formatdate(doc.creation)
-		return transactions
-	else:
-		return []
-
-def get_currency_context():
-	return {
-		"global_number_format": frappe.db.get_default("number_format") or "#,###.##",
-		"currency": frappe.db.get_default("currency"),
-		"currency_symbols": json.dumps(dict(frappe.db.sql("""select name, symbol
-			from tabCurrency where ifnull(enabled,0)=1""")))
-	}
-
-def get_transaction_context(doctype, name):
-	customer = frappe.db.get_value("Contact", {"email_id": frappe.session.user},
-		"customer")
-
-	doc = frappe.get_doc(doctype, name)
-	if doc.customer != customer:
-		return { "doc": frappe._dict({"name": _("Not Allowed")}) }
-	else:
-		return { "doc": doc }
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index 58d3d5a..e5a4222 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -47,7 +47,7 @@
 				"ref_type": self.doctype,
 				"ref_name": self.name
 			})
-			
+
 			event.insert(ignore_permissions=True)
 
 			if frappe.db.exists("User", self.contact_by):
@@ -87,6 +87,7 @@
 					if prevdoc_values[field] is not None:
 						self.validate_value(field, condition, prevdoc_values[field], doc)
 
+
 def delete_events(ref_type, ref_name):
 	frappe.delete_doc("Event", frappe.db.sql_list("""select name from `tabEvent`
 		where ref_type=%s and ref_name=%s""", (ref_type, ref_name)), for_reload=True)