fixes to website, item (added table for cross listing), modules_setup and form_header
diff --git a/home/page/attributions/attributions.html b/home/page/attributions/attributions.html
index 37ee25b..84f25c4 100644
--- a/home/page/attributions/attributions.html
+++ b/home/page/attributions/attributions.html
@@ -93,9 +93,9 @@
 	
 	<hr>
 	<h3>ERPNext License: GNU/General Public License</h3>
-	<div class="well">
+	<div class="well" style="width: 65%;">
 	<p><b>ERPNext - Open Source, web based ERP</b></p>
-	<p>Copyright &copy; 2008 onwards, Web Notes Technologies Pvt Ltd, India</p>
+	<p>Copyright &copy; 2012, Web Notes Technologies Pvt Ltd, India</p>
 
 	<p>This program is free software: you can redistribute it and/or modify
 	    it under the terms of the <b>GNU General Public License</b> as published by
diff --git a/patches/december_2012/rebuild_item_group_tree.py b/patches/december_2012/rebuild_item_group_tree.py
new file mode 100644
index 0000000..1dfac38
--- /dev/null
+++ b/patches/december_2012/rebuild_item_group_tree.py
@@ -0,0 +1,5 @@
+import webnotes
+
+def execute():
+	from webnotes.utils.nestedset import rebuild_tree
+	rebuild_tree("Item Group", "parent_item_group")
\ No newline at end of file
diff --git a/setup/doctype/item_group/item_group.py b/setup/doctype/item_group/item_group.py
index 4ce126b..01790eb 100644
--- a/setup/doctype/item_group/item_group.py
+++ b/setup/doctype/item_group/item_group.py
@@ -27,6 +27,7 @@
 		self.nsm_parent_field = 'parent_item_group';
 	
 	def on_update(self):
+		super(DocType, self).on_update()
 		if self.doc.show_in_website:
 			# webpage updates
 			from website.utils import update_page_name
@@ -38,6 +39,16 @@
 			update_page_name(self.doc, self.doc.name)
 	
 	def prepare_template_args(self):
+		from website.helpers.product import get_product_list_for_group, \
+			get_parent_item_groups, get_group_item_count
+
 		self.doc.sub_groups = webnotes.conn.sql("""select name, page_name
 			from `tabItem Group` where parent_item_group=%s
-			and ifnull(show_in_website,0)=1""", self.doc.name, as_dict=1)		
\ No newline at end of file
+			and ifnull(show_in_website,0)=1""", self.doc.name, as_dict=1)
+
+		for d in self.doc.sub_groups:
+			d.count = get_group_item_count(d.name)
+			
+		self.doc.items = get_product_list_for_group(product_group = self.doc.name, limit=20)
+		self.parent_groups = get_parent_item_groups(self.doc.name)
+		
\ No newline at end of file
diff --git a/setup/page/modules_setup/modules_setup.html b/setup/page/modules_setup/modules_setup.html
index ea136ff..26130de 100644
--- a/setup/page/modules_setup/modules_setup.html
+++ b/setup/page/modules_setup/modules_setup.html
@@ -3,7 +3,7 @@
 	<h1>Modules Setup</h1>
 	<hr>
 	<div class="help" style="width: 300px; float: right">
-		Select checkbox to show / hide module. Drag around to move order.
+		Select checkbox to show / hide module.
 	</div>
 	<div id="modules-list">
 	</div>
diff --git a/setup/page/modules_setup/modules_setup.js b/setup/page/modules_setup/modules_setup.js
index 7f5b125..5868b46 100644
--- a/setup/page/modules_setup/modules_setup.js
+++ b/setup/page/modules_setup/modules_setup.js
@@ -4,7 +4,7 @@
 	modules: ['Activity', 'Accounts', 'Selling', 'Buying', 'Stock', 'Manufacturing', 'Projects', 
 		'Support', 'HR', 'Website', 'To Do', 'Messages', 'Calendar', 'Knowledge Base'],	
 	onload: function(wrapper) {
-		wn.pages.modules_setup.refresh_page(wn.boot.modules_list);
+		wn.pages.modules_setup.refresh_page(JSON.parse(wn.boot.modules_list || "[]"));
 	},
 	refresh_page: function(ml) {
 		$('#modules-list').empty();
@@ -30,8 +30,6 @@
 			}
 		}
 		
-		$('#modules-list').sortable();
-		
 	},
 	update: function() {
 		var ml = [];
diff --git a/stock/doctype/item/item.js b/stock/doctype/item/item.js
index c651456..ab8fb43 100644
--- a/stock/doctype/item/item.js
+++ b/stock/doctype/item/item.js
@@ -95,7 +95,10 @@
 
 //get query select item group
 cur_frm.fields_dict['item_group'].get_query = function(doc,cdt,cdn) {
-  return 'SELECT `tabItem Group`.`name`,`tabItem Group`.`parent_item_group` FROM `tabItem Group` WHERE `tabItem Group`.`is_group` = "No" AND `tabItem Group`.`docstatus`!= 2 AND `tabItem Group`.%(key)s LIKE "%s"  ORDER BY  `tabItem Group`.`name` ASC LIMIT 50'
+  return 'SELECT `tabItem Group`.`name`,`tabItem Group`.`parent_item_group` \
+		FROM `tabItem Group` WHERE `tabItem Group`.`docstatus`!= 2 AND \
+		`tabItem Group`.%(key)s LIKE "%s"  ORDER BY  `tabItem Group`.`name` \
+		ASC LIMIT 50'
 }
 
 // for description from attachment
diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py
index a9f7ee7..e54df15 100644
--- a/stock/doctype/item/item.py
+++ b/stock/doctype/item/item.py
@@ -181,15 +181,10 @@
 		ret = {
 			'file_group'	:	file and file[0]['file_group'] or '',
 			'description'	:	file and file[0]['description'] or ''
-
 		}
 		return ret
 
 	def check_if_sle_exists(self):
-		"""
-			checks if any stock ledger entry exists for this item
-		"""
-
 		sle = sql("select name from `tabStock Ledger Entry` where item_code = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name)
 		return sle and 'exists' or 'not exists'
 
@@ -200,4 +195,5 @@
 			clear_cache(self.doc.page_name)
 			
 	def prepare_template_args(self):
-		self.doc.web_description_html = self.doc.description or ''
+		from website.helpers.product import get_parent_item_groups
+		self.parent_groups = get_parent_item_groups(self.doc.item_group) + [{"name":self.doc.name}]
diff --git a/stock/doctype/item/item.txt b/stock/doctype/item/item.txt
index 71adb4f..cdc3ae5 100644
--- a/stock/doctype/item/item.txt
+++ b/stock/doctype/item/item.txt
@@ -4,7 +4,7 @@
   "docstatus": 0, 
   "creation": "2012-12-17 14:56:32", 
   "modified_by": "Administrator", 
-  "modified": "2012-12-20 15:59:41"
+  "modified": "2012-12-25 13:52:47"
  }, 
  {
   "allow_attach": 1, 
@@ -816,6 +816,16 @@
   "permlevel": 0
  }, 
  {
+  "description": "List this Item in multiple groups on the website.", 
+  "depends_on": "show_in_website", 
+  "doctype": "DocField", 
+  "label": "Website Item Groups", 
+  "options": "Website Item Group", 
+  "fieldname": "website_item_groups", 
+  "fieldtype": "Table", 
+  "permlevel": 0
+ }, 
+ {
   "depends_on": "show_in_website", 
   "doctype": "DocField", 
   "fieldname": "sb72", 
diff --git a/website/css/website.css b/website/css/website.css
index 112d29c..a633be4 100644
--- a/website/css/website.css
+++ b/website/css/website.css
@@ -74,6 +74,14 @@
 	float: left;
 }
 
+.website-missing-image {
+	background-color: #eee;
+	padding: 40px;
+	width: 32px;
+	font-size: 32px;
+	color: #888;
+}
+
 .clear {
 	clear: both;
 }
diff --git a/website/doctype/website_item_group/__init__.py b/website/doctype/website_item_group/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/website/doctype/website_item_group/__init__.py
diff --git a/website/doctype/website_item_group/website_item_group.py b/website/doctype/website_item_group/website_item_group.py
new file mode 100644
index 0000000..928aa9f
--- /dev/null
+++ b/website/doctype/website_item_group/website_item_group.py
@@ -0,0 +1,8 @@
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import webnotes
+
+class DocType:
+	def __init__(self, d, dl):
+		self.doc, self.doclist = d, dl
\ No newline at end of file
diff --git a/website/doctype/website_item_group/website_item_group.txt b/website/doctype/website_item_group/website_item_group.txt
new file mode 100644
index 0000000..31c4c1f
--- /dev/null
+++ b/website/doctype/website_item_group/website_item_group.txt
@@ -0,0 +1,36 @@
+[
+ {
+  "owner": "Administrator", 
+  "docstatus": 0, 
+  "creation": "2012-12-25 13:52:11", 
+  "modified_by": "Administrator", 
+  "modified": "2012-12-25 13:52:11"
+ }, 
+ {
+  "istable": 1, 
+  "description": "Cross Listing of Item in multiple groups", 
+  "doctype": "DocType", 
+  "module": "Website", 
+  "document_type": "Other", 
+  "name": "__common__"
+ }, 
+ {
+  "parent": "Website Item Group", 
+  "doctype": "DocField", 
+  "name": "__common__", 
+  "label": "Item Group", 
+  "parenttype": "DocType", 
+  "options": "Item Group", 
+  "fieldname": "item_group", 
+  "fieldtype": "Link", 
+  "permlevel": 0, 
+  "parentfield": "fields"
+ }, 
+ {
+  "name": "Website Item Group", 
+  "doctype": "DocType"
+ }, 
+ {
+  "doctype": "DocField"
+ }
+]
\ No newline at end of file
diff --git a/website/helpers/product.py b/website/helpers/product.py
index 398049d..6fa422d 100644
--- a/website/helpers/product.py
+++ b/website/helpers/product.py
@@ -25,37 +25,78 @@
 	}
 
 @webnotes.whitelist(allow_guest=True)
-def get_product_list(search=None, product_group=None, start=0):
-	import webnotes
+def get_product_list(search=None, product_group=None, start=0, limit=10):
 	from webnotes.utils import cstr
 		
 	# base query
-	query = """\
-		select name, item_name, page_name, website_image, item_group, 
+	query = """select name, item_name, page_name, website_image, item_group, 
 			web_long_description as website_description
-		from `tabItem`
-		where docstatus = 0
-		and show_in_website = 1 """
+		from `tabItem` where docstatus = 0 and show_in_website = 1 """
 	
 	# search term condition
 	if search:
-		query += """
-			and (
-				web_long_description like %(search)s or
-				item_name like %(search)s or
-				name like %(search)s
-			)"""
+		query += """and (web_long_description like %(search)s or
+				item_name like %(search)s or name like %(search)s)"""
 		search = "%" + cstr(search) + "%"
 	
-	# product group condition
-	if product_group:
-		query += """
-			and item_group = %(product_group)s """
-	
 	# order by
-	query += """order by item_name asc, name asc limit %s, 10""" % start
+	query += """order by weightage desc, modified desc limit %s, %s""" % (start, limit)
 
-	return webnotes.conn.sql(query, {
+	data = webnotes.conn.sql(query, {
 		"search": search,
 		"product_group": product_group
-	}, as_dict=1)
\ No newline at end of file
+	}, as_dict=1)
+	
+	return [get_item_for_list_in_html(r) for r in data]
+
+
+def get_product_list_for_group(product_group=None, start=0, limit=10):
+	child_groups = ", ".join(['"' + i[0] + '"' for i in get_child_groups(product_group)])
+
+	# base query
+	query = """select name, item_name, page_name, website_image, item_group, 
+			web_long_description as website_description
+		from `tabItem` where docstatus = 0 and show_in_website = 1
+		and (item_group in (%s)
+			or name in (select parent from `tabWebsite Item Group` where item_group in (%s))) """ % (child_groups, child_groups)
+	
+	query += """order by weightage desc, modified desc limit %s, %s""" % (start, limit)
+
+	data = webnotes.conn.sql(query, {"product_group": product_group}, as_dict=1)
+
+	return [get_item_for_list_in_html(r) for r in data]
+
+def get_child_groups(item_group_name):
+	item_group = webnotes.doc("Item Group", item_group_name)
+	return webnotes.conn.sql("""select name 
+		from `tabItem Group` where lft>=%(lft)s and rgt<=%(rgt)s""" \
+			% item_group.fields)
+
+def get_group_item_count(item_group):
+	child_groups = ", ".join(['"' + i[0] + '"' for i in get_child_groups(item_group)])
+	return webnotes.conn.sql("""select count(*) from `tabItem` 
+		where docstatus = 0 and show_in_website = 1
+		and (item_group in (%s)
+			or name in (select parent from `tabWebsite Item Group` 
+				where item_group in (%s))) """ % (child_groups, child_groups))[0][0]
+
+def get_item_for_list_in_html(r):
+	from website.utils import build_html
+	scrub_item_for_list(r)
+	r.template = "html/product_in_list.html"
+	return build_html(r)
+
+def scrub_item_for_list(r):
+	if not r.website_description:
+		r.website_description = "No description given"
+	if len(r.website_description.split(" ")) > 24:
+		r.website_description = " ".join(r.website_description.split(" ")[:24]) + "..."
+	if r.website_image and not r.website_image.lower().startswith("http"):
+		r.website_image = "files/" + r.website_image
+
+def get_parent_item_groups(item_group_name):
+	item_group = webnotes.doc("Item Group", item_group_name)
+	return webnotes.conn.sql("""select name, page_name from `tabItem Group`
+		where lft <= %s and rgt >= %s 
+		and ifnull(show_in_website,0)=1
+		order by lft asc""", (item_group.lft, item_group.rgt), as_dict=True)
\ No newline at end of file
diff --git a/website/templates/html/product_breadcrumbs.html b/website/templates/html/product_breadcrumbs.html
new file mode 100644
index 0000000..2b2ea50
--- /dev/null
+++ b/website/templates/html/product_breadcrumbs.html
@@ -0,0 +1,8 @@
+{% if obj.parent_groups and len(obj.parent_groups) > 1 %}
+<ul class="breadcrumb">
+	{% for ig in obj.parent_groups[:-1] %}
+	<li><a href="{{ ig.page_name }}.html">{{ ig.name }}</a> <span class="divider">/</span></li>
+	{% endfor %}
+	<li class="active">{{ obj.parent_groups[-1].name }}</li>
+</ul>
+{% endif %}
\ No newline at end of file
diff --git a/website/templates/html/product_group.html b/website/templates/html/product_group.html
index 06335a5..c44f695 100644
--- a/website/templates/html/product_group.html
+++ b/website/templates/html/product_group.html
@@ -1,50 +1,39 @@
 {% extends "html/page.html" %}
 
-{% block javascript %}
-{% include "js/product_list.js" %}
-{% endblock %}
+{% block title %}{{ name }}{% endblock %}
 
 {% block content %}
 
-<script>
-$(document).ready(function() {
-	window.start = 0;
-	window.product_group = "{{ name }}";
-	window.get_product_list();
-});
-</script>
-
 <div class="layout-wrapper layout-wrapper-background">
 	<div class="web-content" id="content-product_group">
 		<div class="layout-main" style="padding: 30px;">
 			{% include 'html/product_search_box.html' %}
+			{% include 'html/product_breadcrumbs.html' %}
 			{% if description %}
 			<div>{{ description or ""}}</div>
 			{% else %}
 			<h3>{{ name }}</h3>
 			{% endif %}
 			{% if sub_groups %}
-			<div class="well">
-				<div class="container-fluid">
+			<div class="well well-small">
+				<div class="container-fluid" style="padding-left: 0px; margin-left:-10px; line-height: 2em;">
 				{% for d in sub_groups %}
 					<div class="span2">
-						<i class="icon-chevron-right"></i>
-						<a href="{{ d.page_name }}">{{ d.name }}</a></div>
+						<a href="{{ d.page_name }}">{{ d.name }} ({{ d.count }})</a>
+					</div>
 				{% endfor %}
 				</div>
 			</div>
 			{% endif %}
-			<hr>
-			<h3>Products</h3>
+			{% if items %}
 			<div id="search-list">
-				
+				<table class="table">
+					{% for item in items %}
+						{{ item }}
+					{% endfor %}
+				</table>
 			</div>
-			<div style="text-align: center;">
-				<div class="more-btn" 
-					style="display: none; text-align: center;">
-					<button class="btn">More...</button>
-				</div>
-			</div>
+			{% endif %}
 		</div>
 	</div>
 </div>
diff --git a/website/templates/html/product_in_list.html b/website/templates/html/product_in_list.html
new file mode 100644
index 0000000..e5e7b3e
--- /dev/null
+++ b/website/templates/html/product_in_list.html
@@ -0,0 +1,14 @@
+<tr>
+	<td style="width: 30%;">
+		{% if website_image %}
+		<img class="product-image" style="width: 80%;" src="{{ website_image }}">
+		{% else %}
+		{% include 'html/product_missing_image.html' %}
+		{% endif %}
+	</td>
+	<td>
+		<h4><a href="{{ page_name }}">{{ item_name }}</a></h4>
+		<p class="help">Item Code: {{ name }}</p>
+		<p>{{ website_description }}</p>
+	</td>
+</tr>
\ No newline at end of file
diff --git a/website/templates/html/product_missing_image.html b/website/templates/html/product_missing_image.html
new file mode 100644
index 0000000..81cc0d8
--- /dev/null
+++ b/website/templates/html/product_missing_image.html
@@ -0,0 +1 @@
+<div class='website-missing-image'><i class='icon-camera'></i></div>
\ No newline at end of file
diff --git a/website/templates/html/product_page.html b/website/templates/html/product_page.html
index dd94190..898a669 100644
--- a/website/templates/html/product_page.html
+++ b/website/templates/html/product_page.html
@@ -12,7 +12,7 @@
 	{% if item_name != name %}
 		{{ item_name }} [{{ name }}]
 	{% else %}
-		{{ item_name }}
+		{{ item_name or name }}
 	{% endif %}
 {% endblock %}
 
@@ -21,19 +21,17 @@
 		<div class="web-content" id="content-product-{{ name }}">
 			<div class="layout-main" style="padding: 30px;">
 				{% include 'html/product_search_box.html' %}
-				<h1>{{ item_name }}</h1>
+				{% include 'html/product_breadcrumbs.html' %}
+				<h3>{{ item_name }}</h3>
 				<p class="help">Item Code: {{ name }}</p>
 				<div class="product-page-content">
 					<div class="span6">
 					{% if website_image %}
-					<image class="item-main-image" src="files/{{ website_image }}" />
+					<image class="item-main-image" src="{% if website_image.lower().startswith('http') %}{{ website_image}}{% else %}files/{{ website_image }}{% endif %}" />
 					{% else %}
 					<div class="img-area">
-						<div style='background-color: #eee; padding: 40px;
-							width: 32px; font-size: 32px; color: #888;' title='No Image'>
-						<i class='icon-camera'></i></div>
+						{% include 'html/product_missing_image.html' %}
 					</div>
-					
 					{% endif %}
 					<br><br>
 					</div>
@@ -57,7 +55,7 @@
 							{% for d in obj.doclist.get(
 								{"doctype":"Item Website Specification"}) %}
 								<tr>
-									<td style="min-width: 150px;">{{ d.label }}</td>
+									<td style="width: 30%;">{{ d.label }}</td>
 									<td>{{ d.description }}</td>
 								</tr>
 							{% endfor %}
diff --git a/website/templates/js/product_list.js b/website/templates/js/product_list.js
index 04f92df..f8f21b3 100644
--- a/website/templates/js/product_list.js
+++ b/website/templates/js/product_list.js
@@ -31,28 +31,8 @@
 			var table = $("<table class='table'>").appendTo("#search-list");
 			
 		$.each(data, function(i, d) {
-			if(!d.web_short_description)
-				d.web_short_description = "No description given."
-			var $tr = $(repl('<tr>\
-				<td style="width: 30%;">\
-					<img class="product-image" \
-						style="width: 80%;" src="files/%(website_image)s">\
-				</td>\
-				<td>\
-					<h4><a href="%(page_name)s">%(item_name)s</a></h4>\
-					<p class="help">Item Code: %(name)s</p>\
-					<p>%(website_description)s</p>\
-				</td>\
-			</tr>', d)).appendTo(table);
-			
-			if(!d.website_image) {
-				$tr.find(".product-image").replaceWith("<div\
-					style='background-color: #eee; padding: 40px; \
-						width: 32px; font-size: 32px; color: #888;'>\
-					<i class='icon-camera'></i></div>");
-			}
+			$(d).appendTo(table);
 		});
-		
 	}
 	if(data.length < 10) {
 		if(!table) {
diff --git a/website/utils.py b/website/utils.py
index bac87ff..ef73672 100644
--- a/website/utils.py
+++ b/website/utils.py
@@ -123,6 +123,8 @@
 	templates_path = os.path.join(os.path.dirname(conf.__file__), 
 		'app', 'website', 'templates')
 	
+	args["len"] = len
+	
 	jenv = Environment(loader = FileSystemLoader(templates_path))
 	html = jenv.get_template(args['template']).render(args)