contact, address list views and allow their deletion from customer / supplier form
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index 2334cdd..a5b928f 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -62,24 +62,9 @@
 			},
 			as_dict: 1,
 			no_results_message: 'No addresses created',
-			render_row: function(wrapper, data) {
-				$(wrapper).css('padding','5px 0px');
-				var link = $ln(wrapper,cstr(data.name), function() { loaddoc("Address", this.dn); }, {fontWeight:'bold'});
-				link.dn = data.name
-				
-				$a(wrapper,'span','',{marginLeft:'5px', color: '#666'},(data.is_primary_address ? '[Primary]' : '') + (data.is_shipping_address ? '[Shipping]' : ''));
-				$a(wrapper,'div','',{marginTop:'5px', color:'#555'}, 
-					(data.address_line1 ? data.address_line1 + '<br />' : '') + 
-					(data.address_line2 ? data.address_line2 + '<br />' : '') + 
-					(data.city ? data.city + '<br />' : '') + 
-					(data.state ? data.state + ', ' : '') + 
-					(data.country ? data.country  + '<br />' : '') + 
-					(data.pincode ? 'Pincode: ' + data.pincode + '<br />' : '') + 
-					(data.phone ? 'Phone: ' + data.phone + '<br />' : '') + 
-					(data.fax ? 'Fax: ' + data.fax + '<br />' : '') + 
-					(data.email_id ? 'Email: ' + data.email_id + '<br />' : ''));			
-			}
+			render_row: cur_frm.cscript.render_address_row,
 		});
+		// note: render_address_row is defined in contact_control.js
 	}
 	cur_frm.address_list.run();
 }
@@ -95,15 +80,9 @@
 			},
 			as_dict: 1,
 			no_results_message: 'No contacts created',
-			render_row: function(wrapper, data) {
-				$(wrapper).css('padding', '5px 0px');
-				var link = $ln(wrapper, cstr(data.name), function() { loaddoc("Contact", this.dn); }, {fontWeight:'bold'});
-				link.dn = data.name
-
-				$a(wrapper,'span','',{marginLeft:'5px', color: '#666'},(data.is_primary_contact ? '[Primary]' : ''));
-				$a(wrapper,'div', '',{marginTop:'5px', color:'#555'}, data.first_name + (data.last_name ? ' ' + data.last_name + '<br />' : '<br>') + (data.phone ? 'Tel: ' + data.phone + '<br />' : '') + (data.mobile_no ? 'Mobile: ' + data.mobile_no + '<br />' : '') + (data.email_id ? 'Email: ' + data.email_id + '<br />' : '') + (data.department ? 'Department: ' + data.department + '<br />' : '') + (data.designation ? 'Designation: ' + data.designation + '<br />' : ''));
-			}
+			render_row: cur_frm.cscript.render_contact_row,
 		});
+		// note: render_contact_row is defined in contact_control.js
 	}
 	cur_frm.contact_list.run();
 }
diff --git a/erpnext/buying/page/buying_home/buying_home.html b/erpnext/buying/page/buying_home/buying_home.html
index ff8b0ab..8e28e1b 100644
--- a/erpnext/buying/page/buying_home/buying_home.html
+++ b/erpnext/buying/page/buying_home/buying_home.html
@@ -14,6 +14,12 @@
 			<br>
 			<h4><a href="#!List/Item">Item</a></h4>
 			<p class="help">Item Master</p>
+			<br>
+			<h4><a href="#!List/Contact">Contact</a></h4>
+			<p class="help">Contact Master</p>
+			<br>
+			<h4><a href="#!List/Address">Address</a></h4>
+			<p class="help">Address Master</p>
 		</div>
 		<div style="clear: both"></div>
 		<hr>
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index f49a1ab..708573d 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -81,24 +81,9 @@
 			},
 			as_dict: 1,
 			no_results_message: 'No addresses created',
-			render_row: function(wrapper, data) {
-				$(wrapper).css('padding','5px 0px');
-				var link = $ln(wrapper,cstr(data.name), function() { loaddoc("Address", this.dn); }, {fontWeight:'bold'});
-				link.dn = data.name
-				
-				$a(wrapper,'span','',{marginLeft:'5px', color: '#666'},(data.is_primary_address ? '[Primary]' : '') + (data.is_shipping_address ? '[Shipping]' : ''));				
-				$a(wrapper,'div','',{marginTop:'5px', color:'#555'}, 
-					(data.address_line1 ? data.address_line1 + '<br />' : '') + 
-					(data.address_line2 ? data.address_line2 + '<br />' : '') + 
-					(data.city ? data.city + '<br />' : '') + 
-					(data.state ? data.state + ', ' : '') + 
-					(data.country ? data.country  + '<br />' : '') + 
-					(data.pincode ? 'Pincode: ' + data.pincode + '<br />' : '') + 
-					(data.phone ? 'Phone: ' + data.phone + '<br />' : '') + 
-					(data.fax ? 'Fax: ' + data.fax + '<br />' : '') + 
-					(data.email_id ? 'Email: ' + data.email_id + '<br />' : ''));
-			}
+			render_row: cur_frm.cscript.render_address_row,
 		});
+		// note: render_address_row is defined in contact_control.js
 	}
 	cur_frm.address_list.run();
 }
@@ -114,15 +99,9 @@
 			},
 			as_dict: 1,
 			no_results_message: 'No contacts created',
-			render_row: function(wrapper, data) {
-				$(wrapper).css('padding', '5px 0px');
-				var link = $ln(wrapper, cstr(data.name), function() { loaddoc("Contact", this.dn); }, {fontWeight:'bold'});
-				link.dn = data.name
-
-				$a(wrapper,'span','',{marginLeft:'5px', color: '#666'},(data.is_primary_contact ? '[Primary]' : ''));
-				$a(wrapper,'div', '',{marginTop:'5px', color:'#555'}, data.first_name + (data.last_name ? ' ' + data.last_name + '<br />' : '<br>') + (data.phone ? 'Tel: ' + data.phone + '<br />' : '') + (data.mobile_no ? 'Mobile: ' + data.mobile_no + '<br />' : '') + (data.email_id ? 'Email: ' + data.email_id + '<br />' : '') + (data.department ? 'Department: ' + data.department + '<br />' : '') + (data.designation ? 'Designation: ' + data.designation + '<br />' : ''));
-			}
+			render_row: cur_frm.cscript.render_contact_row,
 		});
+		// note: render_contact_row is defined in contact_control.js
 	}
 	cur_frm.contact_list.run();
 
diff --git a/erpnext/selling/page/selling_home/selling_home.html b/erpnext/selling/page/selling_home/selling_home.html
index acadfd6..4857def 100644
--- a/erpnext/selling/page/selling_home/selling_home.html
+++ b/erpnext/selling/page/selling_home/selling_home.html
@@ -20,6 +20,12 @@
 			<br>
 			<h4><a href="#!List/Item">Item</a></h4>
 			<p class="help">Item Master</p>
+			<br>
+			<h4><a href="#!List/Contact">Contact</a></h4>
+			<p class="help">Contact Master</p>
+			<br>
+			<h4><a href="#!List/Address">Address</a></h4>
+			<p class="help">Address Master</p>
 		</div>
 		<div style="clear: both"></div>
 		<hr>
diff --git a/erpnext/setup/doctype/contact_control/contact_control.js b/erpnext/setup/doctype/contact_control/contact_control.js
index a07fd83..b64b589 100755
--- a/erpnext/setup/doctype/contact_control/contact_control.js
+++ b/erpnext/setup/doctype/contact_control/contact_control.js
@@ -77,3 +77,140 @@
 		return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s"  ORDER BY  `tabTerritory`.`name` ASC LIMIT 50';
 	}
 }
+
+cur_frm.cscript.render_contact_row = function(wrapper, data) {
+	// prepare data
+	data.fullname = (data.first_name || '') 
+		+ (data.last_name ? ' ' + data.last_name : '');
+	data.primary = data.is_primary_contact ? ' [Primary]' : '';
+	
+	// prepare description
+	var description = [];
+	$.each([
+		['phone', 'Tel'],
+		['mobile_no', 'Mobile'],
+		['email_id', 'Email'],
+		['department', 'Department'],
+		['designation', 'Designation']],
+		function(i, v) {
+			if(v[0] && data[v[0]]) {
+				description.push(repl('<h6>%(label)s:</h6> %(value)s', {
+					label: v[1],
+					value: data[v[0]],
+				}));
+			}
+		});
+	data.description = description.join('<br />');
+	
+	cur_frm.cscript.render_row_in_wrapper(wrapper, data, 'Contact');
+}
+
+cur_frm.cscript.render_address_row = function(wrapper, data) {
+	// prepare data
+	data.fullname = data.address_type;
+	data.primary = '';
+	if (data.is_primary_address) data.primary += ' [Primary]';
+	if (data.is_shipping_address) data.primary += ' [Shipping]';
+	
+	// prepare address
+	var address = [];
+	$.each(['address_line1', 'address_line2', 'city', 'state', 'country', 'pincode'],
+		function(i, v) {
+			if(data[v]) address.push(data[v]);
+		});
+	
+	data.address = address.join('<br />');
+	data.address = "<p class='address-list'>" + data.address + "</p>";
+	
+	// prepare description
+	var description = [];
+	$.each([
+		['address', 'Address'],
+		['phone', 'Tel'],
+		['fax', 'Fax'],
+		['email_id', 'Email']],
+		function(i, v) {
+			if(data[v[0]]) {
+				description.push(repl('<h6>%(label)s:</h6> %(value)s', {
+					label: v[1],
+					value: data[v[0]],
+				}));
+			}
+		});
+	data.description = description.join('<br />');
+	
+	cur_frm.cscript.render_row_in_wrapper(wrapper, data, 'Address');
+	
+	$(wrapper).find('p.address-list').css({
+		'padding-left': '10px',
+		'margin-bottom': '-10px'
+	});
+}
+
+cur_frm.cscript.render_row_in_wrapper = function(wrapper, data, doctype) {
+	// render
+	var $wrapper = $(wrapper);
+	
+	data.doctype = doctype.toLowerCase();
+	
+	$wrapper.append(repl("\
+		<h4><a class='link_type'>%(fullname)s</a>%(primary)s</h4>\
+		<div class='description'>\
+			%(description)s\
+			<p><a class='delete link_type'>delete this %(doctype)s</a></p>\
+		</div>", data));
+	
+	// make link
+	$wrapper.find('h4 a.link_type').click(function() {
+		loaddoc(doctype, data.name);
+	});
+	
+	// css
+	$wrapper.css({ 'padding': '5px 0px' });
+	$wrapper.find('div.description').css({
+		'padding': '5px 2px',
+		'line-height': '150%',
+	});
+	$wrapper.find('h6').css({ 'display': 'inline-block' });
+	
+	// show delete
+	var $delete_doc = $wrapper.find('a.delete');
+	if (wn.model.can_delete(doctype)) {
+		$delete_doc.toggle(true);
+	} else {
+		$delete_doc.toggle(false);
+	}
+	$delete_doc.css({
+		'padding-left': '0px'
+	});
+
+	$delete_doc.click(function() {
+		cur_frm.cscript.delete_doc(doctype, data.name);
+		return false;
+	});
+}
+
+cur_frm.cscript.delete_doc = function(doctype, name) {
+	// confirm deletion
+	var go_ahead = confirm(repl('Delete %(doctype)s "%(name)s"', {
+		doctype: doctype,
+		name: name
+	}));
+	if (!go_ahead) return;
+
+	wn.call({
+		method: 'webnotes.model.delete_doc',
+		args: {
+			dt: doctype,
+			dn: name
+		},
+		callback: function(r) {
+			//console.log(r);
+			if (!r.exc) {
+				// run the correct list
+				var list_name = doctype.toLowerCase() + '_list';
+				cur_frm[list_name].run();
+			}
+		}
+	});
+}
diff --git a/erpnext/setup/doctype/permission_control/permission_control.py b/erpnext/setup/doctype/permission_control/permission_control.py
index 42f0c97..9d6f428 100644
--- a/erpnext/setup/doctype/permission_control/permission_control.py
+++ b/erpnext/setup/doctype/permission_control/permission_control.py
@@ -43,10 +43,11 @@
 	# ----------------------------------------------------- 
 	def get_doctype_list(self):
 		ret = sql("""SELECT `name` FROM tabDocType 
-			WHERE ifnull(docstatus,0)=0 
+			WHERE ifnull(docstatus,0)=0
 			AND ifnull(istable,0)=0
 			AND ifnull(issingle,0)=0
-			AND `module` NOT IN ('System','Utilities','Setup Masters','Roles','Recycle Bin','Mapper','Application Internal','Development', 'Core')
+			AND (`module` NOT IN ('System','Utilities','Setup Masters','Roles','Recycle Bin','Mapper','Application Internal','Development', 'Core')
+			OR name IN ('Contact', 'Address'))
 			ORDER BY `name` ASC""")
 		
 		rl = [''] + [a[0] for a in sql("select name from tabRole where ifnull(docstatus,0)=0")]
diff --git a/erpnext/utilities/doctype/address/address.py b/erpnext/utilities/doctype/address/address.py
index f4a72fd..cd6a188 100644
--- a/erpnext/utilities/doctype/address/address.py
+++ b/erpnext/utilities/doctype/address/address.py
@@ -21,7 +21,6 @@
 from webnotes import session, form, msgprint, errprint
 
 # -----------------------------------------------------------------------------------------
-
 class DocType:
 	def __init__(self, doc, doclist=[]):
 		self.doc = doc
diff --git a/erpnext/utilities/doctype/address/listview.js b/erpnext/utilities/doctype/address/listview.js
new file mode 100644
index 0000000..325c059
--- /dev/null
+++ b/erpnext/utilities/doctype/address/listview.js
@@ -0,0 +1,55 @@
+wn.doclistviews['Address'] = wn.views.ListView.extend({
+	init: function(d) {
+		this._super(d)
+		this.fields = this.fields.concat([
+			"`tabAddress`.customer_name",
+			"`tabAddress`.supplier",
+			"`tabAddress`.supplier_name",
+			"`tabAddress`.sales_partner",
+			"`tabAddress`.city",
+			"`tabAddress`.country",
+			"ifnull(`tabAddress`.is_shipping_address, 0) as is_shipping_address",
+		]);
+	},
+
+	prepare_data: function(data) {
+		this._super(data);
+		
+		// prepare address
+		var address = []
+		$.each(['city', 'country'], function(i, v) {
+			if(data[v]) address.push(data[v]);
+		});
+		data.address = address.join(", ");
+		
+		// prepare shipping tag
+		if(data.is_shipping_address) {
+			data.shipping = '<span class="label label-info">Shipping</span>';
+		}
+		
+
+		// prepare description
+		if(data.customer) {
+			data.description = (data.customer_name || data.customer);
+			data.contact_type = 'Customer';
+		} else if (data.supplier) {
+			data.description = (data.supplier_name || data.supplier);
+			data.contact_type = 'Supplier';
+		} else if (data.sales_partner) {
+			data.description = data.sales_partner;
+			data.contact_type = 'Sales Partner'
+		} else {
+			data.description = '';
+			data.contact_type = '';
+		}
+},
+	
+	columns: [
+		{width: '3%', content: 'check'},
+		{width: '20%', content: 'name'},
+		{width: '15%', content: 'contact_type'},
+		{width: '20%', content: 'description'},
+		{width: '30%', content: 'address+shipping+tags', css: {'padding': '2px 0px'}},
+		{width: '12%', content: 'modified', css: {'text-align': 'right', 'color':'#777'}}
+	]
+});
diff --git a/erpnext/utilities/doctype/contact/contact.py b/erpnext/utilities/doctype/contact/contact.py
index 6b47b59..3b5131f 100644
--- a/erpnext/utilities/doctype/contact/contact.py
+++ b/erpnext/utilities/doctype/contact/contact.py
@@ -21,7 +21,6 @@
 from webnotes import session, form, msgprint, errprint
 
 # -----------------------------------------------------------------------------------------
-
 class DocType:
 	def __init__(self, doc, doclist=[]):
 		self.doc = doc
diff --git a/erpnext/utilities/doctype/contact/listview.js b/erpnext/utilities/doctype/contact/listview.js
new file mode 100644
index 0000000..bbf5bf8
--- /dev/null
+++ b/erpnext/utilities/doctype/contact/listview.js
@@ -0,0 +1,50 @@
+wn.doclistviews['Contact'] = wn.views.ListView.extend({
+	init: function(d) {
+		this._super(d)
+		this.fields = this.fields.concat([
+			"`tabContact`.first_name",
+			"`tabContact`.last_name",
+			"`tabContact`.customer",
+			"`tabContact`.customer_name",
+			"`tabContact`.supplier",
+			"`tabContact`.supplier_name",
+			"`tabContact`.sales_partner",
+			"`tabContact`.email_id",
+		]);
+	},
+
+	prepare_data: function(data) {
+		this._super(data);
+		
+		// prepare fullname
+		data.fullname = (data.first_name || '') + 
+						(data.last_name ? ' ' + data.last_name : '');
+		if(!data.fullname) data.fullname = data.name;
+		data.fullname = repl("<a href='#!Form/Contact/%(name)s'>%(fullname)s\
+							</a>", data);
+
+		// prepare description
+		if(data.customer) {
+			data.description = (data.customer_name || data.customer);
+			data.contact_type = 'Customer';
+		} else if (data.supplier) {
+			data.description = (data.supplier_name || data.supplier);
+			data.contact_type = 'Supplier';
+		} else if (data.sales_partner) {
+			data.description = data.sales_partner;
+			data.contact_type = 'Sales Partner'
+		} else {
+			data.description = '';
+			data.contact_type = '';
+		}
+	},
+	
+	columns: [
+		{width: '3%', content: 'check'},
+		{width: '20%', content: 'fullname'},
+		{width: '15%', content: 'contact_type'},
+		{width: '20%', content: 'description+tags'},
+		{width: '30%', content: 'email_id'},
+		{width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}}
+	]
+});