Merge branch 'master' into edge
diff --git a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
index ca5fae4..dee0e85 100644
--- a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
+++ b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-03-25 15:35:04", 
+  "creation": "2013-03-26 11:03:08", 
   "docstatus": 0, 
-  "modified": "2013-03-25 15:35:23", 
+  "modified": "2013-03-28 15:42:14", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -210,7 +210,7 @@
   "doctype": "DocField", 
   "fieldname": "expense_account", 
   "fieldtype": "Link", 
-  "hidden": 1, 
+  "hidden": 0, 
   "in_filter": 1, 
   "label": "Expense Account", 
   "options": "Account", 
diff --git a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
index b1cbbdc..1e72010 100644
--- a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
+++ b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
@@ -53,16 +53,14 @@
 		var new_val = flt(val)/flt(doc.conversion_rate);
 		return new_val;
 	}
+	
+	function print_hide(fieldname) {
+		var doc_field = wn.meta.get_docfield(doc.doctype, fieldname, doc.name);
+		return doc_field.print_hide;
+	}
+	
 	out ='';
 	if (!doc.print_without_amount) {
-		print_hide_dict = {};
-		for(var i in locals['DocField']) {
-			var doc_field = locals['DocField'][i];
-			if(doc_field.fieldname) {
-				print_hide_dict[doc_field.fieldname] = doc_field.print_hide;
-			}
-		}
-
 		var cl = getchildren('Sales Taxes and Charges',doc.name,'other_charges');
 
 		// outer table  
@@ -71,7 +69,7 @@
 		// main table
 
 		out +='<table class="noborder" style="width:100%">';
-		if(!print_hide_dict['net_total']) {
+		if(!print_hide('net_total')) {
 			out +=make_row('Net Total',convert_rate(doc.net_total),1);
 		}
 
@@ -84,15 +82,15 @@
 		}
 
 		// grand total
-		if(!print_hide_dict['grand_total_export']) {
+		if(!print_hide('grand_total_export')) {
 			out += make_row('Grand Total',doc.grand_total_export,1);
 		}
 		
-		if(!print_hide_dict['rounded_total_export']) {
+		if(!print_hide('rounded_total_export')) {
 			out += make_row('Rounded Total',doc.rounded_total_export,1);
 		}
 
-		if(doc.in_words_export && !print_hide_dict['in_words_export']){
+		if(doc.in_words_export && !print_hide('in_words_export')){
 			out +='</table></td></tr>';
 			out += '<tr><td colspan = "2">';
 			out += '<table><tr><td style="width:25%;"><b>In Words</b></td>'
diff --git a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
index 953269c..6cd2b4f 100644
--- a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
+++ b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.py
@@ -24,7 +24,7 @@
 
 	def get_rate(self, arg):
 		from webnotes.model.code import get_obj
-		return get_obj('Sales Common').get_rate(arg, self)
+		return get_obj('Sales Common').get_rate(arg)
 
 	def update_other_default_charges(self):
 		webnotes.conn.sql("update `tabSales Taxes and Charges Master` set is_default = 0 where ifnull(is_default,0) = 1 and name != '%s' and company = '%s'" % (self.doc.name, self.doc.company))
diff --git a/accounts/report/gross_profit/gross_profit.py b/accounts/report/gross_profit/gross_profit.py
index 7f6354b..9ccd320 100644
--- a/accounts/report/gross_profit/gross_profit.py
+++ b/accounts/report/gross_profit/gross_profit.py
@@ -14,7 +14,8 @@
 	
 	columns = ["Delivery Note/Sales Invoice::120", "Link::30", "Posting Date:Date", "Posting Time", 
 		"Item Code:Link/Item", "Item Name", "Description", "Warehouse:Link/Warehouse",
-		"Qty:Float", "Selling Rate:Currency", "Selling Amount:Currency", "Buying Amount:Currency",
+		"Qty:Float", "Selling Rate:Currency", "Avg. Buying Rate:Currency", 
+		"Selling Amount:Currency", "Buying Amount:Currency",
 		"Gross Profit:Currency", "Gross Profit %:Percent", "Project:Link/Project"]
 	
 	data = []
@@ -25,17 +26,18 @@
 			item_sales_bom.get(row.parenttype, {}).get(row.name, webnotes._dict()))
 		
 		buying_amount = buying_amount > 0 and buying_amount or 0
-		
+
+		gross_profit = selling_amount - buying_amount
 		if selling_amount:
-			gross_profit = selling_amount - buying_amount
 			gross_profit_percent = (gross_profit / selling_amount) * 100.0
 		else:
-			gross_profit = gross_profit_percent = 0.0
+			gross_profit_percent = 0.0
 		
 		icon = """<a href="%s"><i class="icon icon-share" style="cursor: pointer;"></i></a>""" \
 			% ("/".join(["#Form", row.parenttype, row.name]),)
 		data.append([row.name, icon, row.posting_date, row.posting_time, row.item_code, row.item_name,
-			row.description, row.warehouse, row.qty, row.basic_rate, row.amount, buying_amount,
+			row.description, row.warehouse, row.qty, row.basic_rate, 
+			row.qty and (buying_amount / row.qty) or 0, row.amount, buying_amount,
 			gross_profit, gross_profit_percent, row.project])
 			
 	return columns, data
diff --git a/accounts/utils.py b/accounts/utils.py
index 92173ab..d6b2043 100644
--- a/accounts/utils.py
+++ b/accounts/utils.py
@@ -294,18 +294,18 @@
 		jv.submit()
 		
 def get_stock_rbnb_value(company):	
-	total_received_amount = webnotes.conn.sql("""select sum(valuation_amount) 
+	total_received_amount = webnotes.conn.sql("""select sum(valuation_rate*qty) 
 		from `tabPurchase Receipt Item` pr_item where docstatus=1 
 		and exists(select name from `tabItem` where name = pr_item.item_code 
 			and is_stock_item='Yes')
-		and exist(select name from `tabPurchase Receipt` 
+		and exists(select name from `tabPurchase Receipt` 
 			where name = pr_item.parent and company = %s)""", company)
 		
-	total_billed_amount = webnotes.conn.sql("""select sum(valuation_amount) 
+	total_billed_amount = webnotes.conn.sql("""select sum(valuation_rate*qty) 
 		from `tabPurchase Invoice Item` pi_item where docstatus=1 
 		and exists(select name from `tabItem` where name = pi_item.item_code 
 			and is_stock_item='Yes')
-		and exist(select name from `tabPurchase Invoice` 
+		and exists(select name from `tabPurchase Invoice` 
 			where name = pi_item.parent and company = %s)""", company)
 		
 	return flt(total_received_amount[0][0]) - flt(total_billed_amount[0][0])
diff --git a/patches/april_2013/__init__.py b/patches/april_2013/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/patches/april_2013/__init__.py
diff --git a/patches/april_2013/p01_update_serial_no_valuation_rate.py b/patches/april_2013/p01_update_serial_no_valuation_rate.py
new file mode 100644
index 0000000..2ea0c26
--- /dev/null
+++ b/patches/april_2013/p01_update_serial_no_valuation_rate.py
@@ -0,0 +1,35 @@
+import webnotes
+from webnotes.utils import cstr
+from stock.stock_ledger import update_entries_after
+
+def execute():
+	webnotes.conn.auto_commit_on_many_writes = 1
+	
+	pr_items = webnotes.conn.sql("""select item_code, warehouse, serial_no, valuation_rate, name 
+		from `tabPurchase Receipt Item` where ifnull(serial_no, '') != '' and docstatus = 1""", 
+		as_dict=True)
+		
+	item_warehouse = []
+		
+	for item in pr_items:
+		serial_nos = cstr(item.serial_no).strip().split("\n")
+		serial_nos = map(lambda x: x.strip(), serial_nos)
+
+		if cstr(item.serial_no) != "\n".join(serial_nos):
+			webnotes.conn.sql("""update `tabPurchase Receipt Item` set serial_no = %s 
+				where name = %s""", ("\n".join(serial_nos), item.name))
+			
+			if [item.item_code, item.warehouse] not in item_warehouse:
+				item_warehouse.append([item.item_code, item.warehouse])
+		
+			webnotes.conn.sql("""update `tabSerial No` set purchase_rate = %s 
+				where name in (%s)""" % ('%s', ', '.join(['%s']*len(serial_nos))), 
+				tuple([item.valuation_rate] + serial_nos))
+
+	for d in item_warehouse:
+		try:
+			update_entries_after({"item_code": d[0], "warehouse": d[1] })
+		except:
+			continue
+			
+	webnotes.conn.auto_commit_on_many_writes = 0
\ No newline at end of file
diff --git a/patches/march_2013/p07_update_valuation_rate.py b/patches/march_2013/p07_update_valuation_rate.py
index 51e556b..7cc3e11 100644
--- a/patches/march_2013/p07_update_valuation_rate.py
+++ b/patches/march_2013/p07_update_valuation_rate.py
@@ -8,6 +8,6 @@
 		pi.update_raw_material_cost()
 		pi.update_valuation_rate("entries")
 		for item in pi.doclist.get({"parentfield": "entries"}):
-			webnotes.conn.set_value("Purchase Invoice Item", item.name, "valuation_rate",
-				item.valuation_rate)
+			webnotes.conn.sql("""update `tabPurchase Invoice Item` set valuation_rate = %s 
+				where name = %s""", (item.valuation_rate, item.name))
 	
\ No newline at end of file
diff --git a/patches/march_2013/p10_update_against_expense_account.py b/patches/march_2013/p10_update_against_expense_account.py
new file mode 100644
index 0000000..3506ac4
--- /dev/null
+++ b/patches/march_2013/p10_update_against_expense_account.py
@@ -0,0 +1,11 @@
+def execute():
+	import webnotes
+	from webnotes import get_obj
+	pi_list = webnotes.conn.sql("""select name from `tabPurchase Invoice` 
+		where docstatus = 1 and ifnull(against_expense_account, '') = ''""")
+		
+	for pi in pi_list:
+		pi_obj = get_obj("Purchase Invoice", pi[0], with_children=1)
+		pi_obj.set_against_expense_account()
+		webnotes.conn.sql("""update `tabPurchase Invoice` set against_expense_account = %s 
+			where name = %s""", (pi_obj.doc.against_expense_account, pi[0]))
\ No newline at end of file
diff --git a/patches/march_2013/p11_update_attach_files.py b/patches/march_2013/p11_update_attach_files.py
index 769463a..ef39ce8 100644
--- a/patches/march_2013/p11_update_attach_files.py
+++ b/patches/march_2013/p11_update_attach_files.py
@@ -11,6 +11,6 @@
 		else:
 			webnotes.conn.sql("""update `tab%(parent)s`
 				set %(fieldname)s = 
-					if(substr(%(fieldname)s,0,4)='http' or substr(%(fieldname)s, 0, 5)='files',
+					if(substr(%(fieldname)s,1,4)='http' or substr(%(fieldname)s,1,5)='files',
 					 	%(fieldname)s, 
 						concat('files/', %(fieldname)s))""" % f)
\ No newline at end of file
diff --git a/patches/march_2013/p12_set_item_tax_rate_in_json.py b/patches/march_2013/p12_set_item_tax_rate_in_json.py
new file mode 100644
index 0000000..de47c67
--- /dev/null
+++ b/patches/march_2013/p12_set_item_tax_rate_in_json.py
@@ -0,0 +1,19 @@
+import webnotes
+import json
+
+def execute():
+	"""replace item_tax_rate stored as string with a json string"""
+	webnotes.conn.auto_commit_on_many_writes = 1
+	for dt in ["Quotation Item", "Sales Order Item", "Sales Invoice Item", 
+			"Delivery Note Item", "Supplier Quotation Item", "Purchase Order Item",
+			"Purchase Invoice Item", "Purchase Receipt Item"]:
+		for d in webnotes.conn.sql("""select name, item_tax_rate from `tab%s`
+				where ifnull(item_tax_rate, '')!=''""" % (dt,), as_dict=1):
+			try:
+				json.loads(d["item_tax_rate"])
+			except ValueError, e:
+				webnotes.conn.sql("""update `tab%s` set item_tax_rate=%s
+					where name=%s""" % (dt, "%s", "%s"),
+					(json.dumps(eval(d["item_tax_rate"])), d["name"]))
+		
+	webnotes.conn.auto_commit_on_many_writes = 0
\ No newline at end of file
diff --git a/patches/patch_list.py b/patches/patch_list.py
index 5502385..544fc95 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -224,5 +224,8 @@
 	"execute:webnotes.conn.set_value('Email Settings', None, 'send_print_in_body_and_attachment', 1)",
 	"patches.march_2013.p09_unset_user_type_partner",
 	"patches.march_2013.p10_set_fiscal_year_for_stock",
+	"patches.march_2013.p10_update_against_expense_account",
 	"patches.march_2013.p11_update_attach_files",
+	"patches.march_2013.p12_set_item_tax_rate_in_json",
+	"patches.april_2013.p01_update_serial_no_valuation_rate",
 ]
\ No newline at end of file
diff --git a/setup/doctype/global_defaults/global_defaults.py b/setup/doctype/global_defaults/global_defaults.py
index 4b6707f..3f8de1d 100644
--- a/setup/doctype/global_defaults/global_defaults.py
+++ b/setup/doctype/global_defaults/global_defaults.py
@@ -45,7 +45,7 @@
 	'session_expiry': 'session_expiry',
 	'disable_rounded_total': 'disable_rounded_total',
 	"update_stock": "update_stock",
-	# "auto_inventory_accounting": "auto_inventory_accounting",
+	"auto_inventory_accounting": "auto_inventory_accounting",
 }
 
 class DocType:
diff --git a/setup/doctype/global_defaults/global_defaults.txt b/setup/doctype/global_defaults/global_defaults.txt
index ac1671e..7f81618 100644
--- a/setup/doctype/global_defaults/global_defaults.txt
+++ b/setup/doctype/global_defaults/global_defaults.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-02-21 12:28:24", 
+  "creation": "2013-03-25 11:08:14", 
   "docstatus": 0, 
-  "modified": "2013-03-21 15:42:59", 
+  "modified": "2013-03-28 15:41:03", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -27,6 +27,8 @@
   "permlevel": 0
  }, 
  {
+  "amend": 0, 
+  "cancel": 0, 
   "create": 1, 
   "doctype": "DocPerm", 
   "name": "__common__", 
@@ -48,19 +50,22 @@
   "doctype": "DocField", 
   "fieldname": "general", 
   "fieldtype": "Section Break", 
-  "label": "General"
+  "label": "General", 
+  "read_only": 0
  }, 
  {
   "description": "Session Expiry in Hours e.g. 06:00", 
   "doctype": "DocField", 
   "fieldname": "session_expiry", 
   "fieldtype": "Data", 
-  "label": "Session Expiry"
+  "label": "Session Expiry", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "column_break_3", 
-  "fieldtype": "Column Break"
+  "fieldtype": "Column Break", 
+  "read_only": 0
  }, 
  {
   "description": "For Server Side Print Formats", 
@@ -68,13 +73,15 @@
   "fieldname": "print_style", 
   "fieldtype": "Select", 
   "label": "Print Format Style", 
-  "options": "Standard\nClassic\nModern\nSpartan"
+  "options": "Standard\nClassic\nModern\nSpartan", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "company", 
   "fieldtype": "Section Break", 
-  "label": "Company"
+  "label": "Company", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
@@ -82,6 +89,7 @@
   "fieldtype": "Link", 
   "label": "Default Company", 
   "options": "Company", 
+  "read_only": 0, 
   "reqd": 0
  }, 
  {
@@ -90,6 +98,7 @@
   "fieldtype": "Link", 
   "label": "Current Fiscal Year", 
   "options": "Fiscal Year", 
+  "read_only": 0, 
   "reqd": 1
  }, 
  {
@@ -97,12 +106,14 @@
   "fieldname": "date_format", 
   "fieldtype": "Select", 
   "label": "Date Format", 
-  "options": "yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\nmm/dd/yyyy\nmm-dd-yyyy"
+  "options": "yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\nmm/dd/yyyy\nmm-dd-yyyy", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "column_break1", 
   "fieldtype": "Column Break", 
+  "read_only": 0, 
   "width": "50%"
  }, 
  {
@@ -111,7 +122,8 @@
   "fieldname": "hide_currency_symbol", 
   "fieldtype": "Select", 
   "label": "Hide Currency Symbol", 
-  "options": "\nNo\nYes"
+  "options": "\nNo\nYes", 
+  "read_only": 0
  }, 
  {
   "default": "INR", 
@@ -120,6 +132,7 @@
   "fieldtype": "Link", 
   "label": "Default Currency", 
   "options": "Currency", 
+  "read_only": 0, 
   "reqd": 1
  }, 
  {
@@ -128,7 +141,8 @@
   "fieldname": "number_format", 
   "fieldtype": "Select", 
   "label": "Number Format", 
-  "options": "\n#,###.##\n#.###,##\n# ###.##\n#,###.###\n#,##,###.##\n#.###\n#,###"
+  "options": "\n#,###.##\n#.###,##\n# ###.##\n#,###.###\n#,##,###.##\n#.###\n#,###", 
+  "read_only": 0
  }, 
  {
   "description": "Precision for Float fields (quantities, discounts, percentages etc) only for display. Floats will still be calculated up to 6 decimals.", 
@@ -136,18 +150,21 @@
   "fieldname": "float_precision", 
   "fieldtype": "Select", 
   "label": "Float Precision", 
-  "options": "\n2\n3\n4\n5\n6"
+  "options": "\n2\n3\n4\n5\n6", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "stock", 
   "fieldtype": "Section Break", 
-  "label": "Stock"
+  "label": "Stock", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "column_break2", 
   "fieldtype": "Column Break", 
+  "read_only": 0, 
   "width": "50%"
  }, 
  {
@@ -155,54 +172,62 @@
   "fieldname": "default_item_group", 
   "fieldtype": "Link", 
   "label": "Default Item Group", 
-  "options": "Item Group"
+  "options": "Item Group", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "ighelp", 
   "fieldtype": "HTML", 
   "label": "IGHelp", 
-  "options": "<a href=\"#!Sales Browser/Item Group\">To manage Item Groups, click here</a>"
+  "options": "<a href=\"#!Sales Browser/Item Group\">To manage Item Groups, click here</a>", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "default_stock_uom", 
   "fieldtype": "Link", 
   "label": "Default Stock UOM", 
-  "options": "UOM"
+  "options": "UOM", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "default_valuation_method", 
   "fieldtype": "Select", 
   "label": "Default Valuation Method", 
-  "options": "FIFO\nMoving Average"
+  "options": "FIFO\nMoving Average", 
+  "read_only": 0
  }, 
  {
   "description": "Applicable only if valuation method is moving average", 
   "doctype": "DocField", 
   "fieldname": "allow_negative_stock", 
   "fieldtype": "Check", 
-  "label": "Allow Negative Stock"
+  "label": "Allow Negative Stock", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "default_warehouse_type", 
   "fieldtype": "Link", 
   "label": "Default Warehouse Type", 
-  "options": "Warehouse Type"
+  "options": "Warehouse Type", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "auto_indent", 
   "fieldtype": "Check", 
-  "label": "Raise Material Request when stock reaches re-order level"
+  "label": "Raise Material Request when stock reaches re-order level", 
+  "read_only": 0
  }, 
  {
   "default": "1", 
   "doctype": "DocField", 
   "fieldname": "column_break3", 
   "fieldtype": "Column Break", 
+  "read_only": 0, 
   "width": "50%"
  }, 
  {
@@ -210,14 +235,16 @@
   "doctype": "DocField", 
   "fieldname": "tolerance", 
   "fieldtype": "Float", 
-  "label": "Allowance Percent"
+  "label": "Allowance Percent", 
+  "read_only": 0
  }, 
  {
   "description": "Stock level frozen up to this date, nobody can do / modify entry except authorized person", 
   "doctype": "DocField", 
   "fieldname": "stock_frozen_upto", 
   "fieldtype": "Date", 
-  "label": "Stock Frozen Upto"
+  "label": "Stock Frozen Upto", 
+  "read_only": 0
  }, 
  {
   "description": "Users with this role are allowed to do / modify stock entry before frozen date", 
@@ -225,20 +252,32 @@
   "fieldname": "stock_auth_role", 
   "fieldtype": "Link", 
   "label": "Authorized Role (Frozen Entry)", 
-  "options": "Role"
+  "options": "Role", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "accounts", 
   "fieldtype": "Section Break", 
-  "label": "Accounts"
+  "label": "Accounts", 
+  "read_only": 0
+ }, 
+ {
+  "description": "If enabled, the system will post accounting entries for inventory automatically", 
+  "doctype": "DocField", 
+  "fieldname": "auto_inventory_accounting", 
+  "fieldtype": "Check", 
+  "label": "Auto Inventory Accounting", 
+  "no_copy": 0, 
+  "print_hide": 1
  }, 
  {
   "description": "Accounting entry frozen up to this date, nobody can do / modify entry except authorized person", 
   "doctype": "DocField", 
   "fieldname": "acc_frozen_upto", 
   "fieldtype": "Date", 
-  "label": "Accounts Frozen Upto"
+  "label": "Accounts Frozen Upto", 
+  "read_only": 0
  }, 
  {
   "description": "Users with this role are allowed to do / modify accounting entry before frozen date", 
@@ -246,39 +285,45 @@
   "fieldname": "bde_auth_role", 
   "fieldtype": "Link", 
   "label": "Authourized Role (Frozen Entry)", 
-  "options": "Role"
+  "options": "Role", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "credit_controller", 
   "fieldtype": "Link", 
   "label": "Credit Controller", 
-  "options": "Role"
+  "options": "Role", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "column_break4", 
-  "fieldtype": "Column Break"
+  "fieldtype": "Column Break", 
+  "read_only": 0
  }, 
  {
   "description": "If checked, then in POS Sales Invoice, Update Stock gets checked by default", 
   "doctype": "DocField", 
   "fieldname": "update_stock", 
   "fieldtype": "Check", 
-  "label": "Update Stock when using POS Sales Invoice"
+  "label": "Update Stock when using POS Sales Invoice", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "account_info", 
   "fieldtype": "HTML", 
   "label": "Account Info", 
-  "options": "<div class=\"help-box\">For more accounting defaults, Open <a href=\"#!List/Company\">Company</a></div>"
+  "options": "<div class=\"help-box\">For more accounting defaults, Open <a href=\"#!List/Company\">Company</a></div>", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "selling", 
   "fieldtype": "Section Break", 
-  "label": "Selling"
+  "label": "Selling", 
+  "read_only": 0
  }, 
  {
   "default": "Customer Name", 
@@ -286,40 +331,46 @@
   "fieldname": "cust_master_name", 
   "fieldtype": "Select", 
   "label": "Customer Master created by ", 
-  "options": "Customer Name\nNaming Series"
+  "options": "Customer Name\nNaming Series", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "default_customer_group", 
   "fieldtype": "Link", 
   "label": "Default Customer Group", 
-  "options": "Customer Group"
+  "options": "Customer Group", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "cghelp", 
   "fieldtype": "HTML", 
   "label": "CGHelp", 
-  "options": "<a href=\"#!Sales Browser/Customer Group\">To manage Customer Groups, click here</a>"
+  "options": "<a href=\"#!Sales Browser/Customer Group\">To manage Customer Groups, click here</a>", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "default_territory", 
   "fieldtype": "Link", 
   "label": "Default Territory", 
-  "options": "Territory"
+  "options": "Territory", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "territoryhelp", 
   "fieldtype": "HTML", 
   "label": "TerritoryHelp", 
-  "options": "<a href=\"#!Sales Browser/Territory\">To manage Territory, click here</a>"
+  "options": "<a href=\"#!Sales Browser/Territory\">To manage Territory, click here</a>", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "column_break5", 
   "fieldtype": "Column Break", 
+  "read_only": 0, 
   "width": "50%"
  }, 
  {
@@ -327,14 +378,16 @@
   "fieldname": "default_price_list", 
   "fieldtype": "Link", 
   "label": "Default Price List", 
-  "options": "Price List"
+  "options": "Price List", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "default_price_list_currency", 
   "fieldtype": "Link", 
   "label": "Default Price List Currency", 
-  "options": "Currency"
+  "options": "Currency", 
+  "read_only": 0
  }, 
  {
   "default": "No", 
@@ -342,7 +395,8 @@
   "fieldname": "so_required", 
   "fieldtype": "Select", 
   "label": "Sales Order Required", 
-  "options": "No\nYes"
+  "options": "No\nYes", 
+  "read_only": 0
  }, 
  {
   "default": "No", 
@@ -350,27 +404,31 @@
   "fieldname": "dn_required", 
   "fieldtype": "Select", 
   "label": "Delivery Note Required", 
-  "options": "No\nYes"
+  "options": "No\nYes", 
+  "read_only": 0
  }, 
  {
   "description": "If disable, 'Rounded Total' field will not be visible in any transaction", 
   "doctype": "DocField", 
   "fieldname": "disable_rounded_total", 
   "fieldtype": "Check", 
-  "label": "Disable Rounded Total"
+  "label": "Disable Rounded Total", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "buying", 
   "fieldtype": "Section Break", 
-  "label": "Buying"
+  "label": "Buying", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "default_supplier_type", 
   "fieldtype": "Link", 
   "label": "Default Supplier Type", 
-  "options": "Supplier Type"
+  "options": "Supplier Type", 
+  "read_only": 0
  }, 
  {
   "default": "Supplier Name", 
@@ -378,12 +436,14 @@
   "fieldname": "supp_master_name", 
   "fieldtype": "Select", 
   "label": "Supplier Master created by ", 
-  "options": "Supplier Name\nNaming Series"
+  "options": "Supplier Name\nNaming Series", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "column_break6", 
   "fieldtype": "Column Break", 
+  "read_only": 0, 
   "width": "50%"
  }, 
  {
@@ -392,7 +452,8 @@
   "fieldname": "po_required", 
   "fieldtype": "Select", 
   "label": "Purchase Order Required", 
-  "options": "No\nYes"
+  "options": "No\nYes", 
+  "read_only": 0
  }, 
  {
   "default": "No", 
@@ -400,20 +461,23 @@
   "fieldname": "pr_required", 
   "fieldtype": "Select", 
   "label": "Purchase Receipt Required", 
-  "options": "No\nYes"
+  "options": "No\nYes", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "maintain_same_rate", 
   "fieldtype": "Check", 
-  "label": "Maintain same rate throughout purchase cycle"
+  "label": "Maintain same rate throughout purchase cycle", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "hr", 
   "fieldtype": "Section Break", 
   "label": "HR", 
-  "options": "<div style=\"padding-top: 8px;\" class=\"columnHeading\">HR</div>"
+  "options": "<div style=\"padding-top: 8px;\" class=\"columnHeading\">HR</div>", 
+  "read_only": 0
  }, 
  {
   "description": "Employee record is created using selected field. ", 
@@ -421,24 +485,22 @@
   "fieldname": "emp_created_by", 
   "fieldtype": "Select", 
   "label": "Employee Records to be created by ", 
-  "options": "Naming Series\nEmployee Number"
+  "options": "Naming Series\nEmployee Number", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "system", 
   "fieldtype": "Section Break", 
-  "label": "System"
+  "label": "System", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocField", 
   "fieldname": "sms_sender_name", 
   "fieldtype": "Data", 
-  "label": "SMS Sender Name"
- }, 
- {
-  "amend": 0, 
-  "cancel": 0, 
-  "doctype": "DocPerm"
+  "label": "SMS Sender Name", 
+  "read_only": 0
  }, 
  {
   "doctype": "DocPerm"
diff --git a/setup/doctype/item_group/item_group.py b/setup/doctype/item_group/item_group.py
index ba4ea77..1445f39 100644
--- a/setup/doctype/item_group/item_group.py
+++ b/setup/doctype/item_group/item_group.py
@@ -35,13 +35,13 @@
 		
 		
 		if self.doc.show_in_website:
-			from website.utils import update_page_name
+			from webnotes.webutils import update_page_name
 			# webpage updates
 			page_name = self.doc.name
 			if webnotes.conn.get_value("Product Settings", None, 
 				"default_product_category")==self.doc.name:
 				page_name = "products"
-				from website.utils import clear_cache
+				from webnotes.webutils import clear_cache
 				clear_cache()
 				
 			update_page_name(self.doc, page_name)
@@ -51,7 +51,7 @@
 		elif self.doc.page_name:
 			# if unchecked show in website
 			
-			from website.utils import delete_page_cache
+			from webnotes.webutils import delete_page_cache
 			delete_page_cache(self.doc.page_name)
 			
 			invalidate_cache_for(self.doc.name)
@@ -74,7 +74,7 @@
 		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.doc.items = get_product_list_for_group(product_group = self.doc.name, limit=100)
 		self.parent_groups = get_parent_item_groups(self.doc.name)
 		self.doc.title = self.doc.name
 
diff --git a/setup/doctype/item_group/item_group.txt b/setup/doctype/item_group/item_group.txt
index d9c6ffe..a8da12c 100644
--- a/setup/doctype/item_group/item_group.txt
+++ b/setup/doctype/item_group/item_group.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-01-23 20:00:16", 
+  "creation": "2013-03-28 10:35:29", 
   "docstatus": 0, 
-  "modified": "2013-03-20 15:09:28", 
+  "modified": "2013-04-01 12:06:52", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -124,6 +124,7 @@
   "label": "Description"
  }, 
  {
+  "depends_on": "show_in_website", 
   "doctype": "DocField", 
   "fieldname": "item_website_specifications", 
   "fieldtype": "Table", 
@@ -182,20 +183,6 @@
   "print_hide": 1
  }, 
  {
-  "cancel": 1, 
-  "create": 1, 
-  "doctype": "DocPerm", 
-  "role": "System Manager", 
-  "write": 1
- }, 
- {
-  "cancel": 1, 
-  "create": 1, 
-  "doctype": "DocPerm", 
-  "role": "Material Master Manager", 
-  "write": 1
- }, 
- {
   "amend": 0, 
   "cancel": 0, 
   "create": 0, 
@@ -210,5 +197,19 @@
   "doctype": "DocPerm", 
   "role": "Material User", 
   "write": 0
+ }, 
+ {
+  "cancel": 1, 
+  "create": 1, 
+  "doctype": "DocPerm", 
+  "role": "System Manager", 
+  "write": 1
+ }, 
+ {
+  "cancel": 1, 
+  "create": 1, 
+  "doctype": "DocPerm", 
+  "role": "Material Master Manager", 
+  "write": 1
  }
 ]
\ No newline at end of file
diff --git a/setup/page/setup/setup.js b/setup/page/setup/setup.js
index e59a18a..4ab7578 100644
--- a/setup/page/setup/setup.js
+++ b/setup/page/setup/setup.js
@@ -199,6 +199,18 @@
 			},
 		]
 	},
+	{
+		title: wn._("Update Manager"),
+		icon: "icon-magnet",
+		right: true,
+		items: [
+			{
+				"page":"update-manager",
+				label: wn._("Update This Application"),
+				"description":wn._("Apply latest updates and patches to this app")
+			},
+		]
+	},
 ]
 
 pscript['onload_Setup'] = function(wrapper) {
diff --git a/startup/website.py b/startup/website.py
new file mode 100644
index 0000000..1041039
--- /dev/null
+++ b/startup/website.py
@@ -0,0 +1,114 @@
+import webnotes, conf, os
+
+
+def get_templates_path():
+	return os.path.join(os.path.dirname(conf.__file__), "app", "website", "templates")
+
+standard_pages = [
+	"404", "about", "account", "attributions", "blog", "contact", "error", "index",
+	"login", "message", "order", "orders", "print", "product_search", "profile",
+	"ticket", "tickets", "writers"
+]
+
+page_map = {
+	'Web Page': webnotes._dict({
+		"template": 'html/web_page.html',
+		"condition_field": "published"
+	}),
+	'Blog Post': webnotes._dict({
+		"template": 'html/blog_page.html',
+		"condition_field": "published",
+	}),
+	'Item': webnotes._dict({
+		"template": 'html/product_page.html',
+		"condition_field": "show_in_website",
+	}),
+	'Item Group': webnotes._dict({
+		"template": "html/product_group.html",
+		"condition_field": "show_in_website"
+	})
+}
+
+page_settings_map = {
+	"about": "website.doctype.about_us_settings.about_us_settings.get_args",
+	"contact": "Contact Us Settings",
+	"blog": "website.helpers.blog.get_blog_template_args",
+	"writers": "website.helpers.blog.get_writers_args",
+	"print": "core.doctype.print_format.print_format.get_args",
+	"orders": "selling.doctype.sales_order.sales_order.get_currency_and_number_format",
+	"order": "selling.doctype.sales_order.sales_order.get_website_args",
+	"ticket": "support.doctype.support_ticket.support_ticket.get_website_args"
+}
+
+no_cache = ["message", "print", "order", "ticket"]
+
+def get_home_page():
+	doc_name = webnotes.conn.get_value('Website Settings', None, 'home_page')
+	if doc_name:
+		page_name = webnotes.conn.get_value('Web Page', doc_name, 'page_name')
+	else:
+		page_name = 'login'
+
+	return page_name
+
+def update_template_args(page_name, args):
+	
+	from webnotes.utils import get_request_site_address
+	from urllib import quote
+	
+	all_top_items = webnotes.conn.sql("""\
+		select * from `tabTop Bar Item`
+		where parent='Website Settings' and parentfield='top_bar_items'
+		order by idx asc""", as_dict=1)
+	
+	top_items = [d for d in all_top_items if not d['parent_label']]
+	
+	# attach child items to top bar
+	for d in all_top_items:
+		if d['parent_label']:
+			for t in top_items:
+				if t['label']==d['parent_label']:
+					if not 'child_items' in t:
+						t['child_items'] = []
+					t['child_items'].append(d)
+					break
+	
+	if top_items and ("products" in [d.url.split(".")[0] for d in top_items if d.url]):
+		# product categories
+		products = webnotes.conn.sql("""select t1.item_group as label, 
+			t2.page_name as url,
+			ifnull(t1.indent,0) as indent
+			from `tabWebsite Product Category` t1, `tabItem Group` t2 
+			where t1.item_group = t2.name
+			and ifnull(t2.show_in_website,0)=1 order by t1.idx""", as_dict=1)
+		products_item = filter(lambda d: d.url and d.url.split(".")[0]=="products", top_items)[0]			
+		products_item.child_items = products
+		
+	ret = webnotes._dict({
+		'top_bar_items': top_items,
+		'footer_items': webnotes.conn.sql("""\
+			select * from `tabTop Bar Item`
+			where parent='Website Settings' and parentfield='footer_items'
+			order by idx asc""", as_dict=1),
+			
+		'int':int,
+		"webnotes": webnotes,
+		"utils": webnotes.utils
+	})
+	
+	args.update(ret)
+	
+	settings = webnotes.doc("Website Settings", "Website Settings")
+	for k in ["banner_html", "brand_html", "copyright", "address", "twitter_share_via",
+		"favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share"]:
+		if k in settings.fields:
+			args[k] = settings.fields.get(k)
+
+	for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share"]:
+		args[k] = int(args.get(k) or 0)
+	
+	args.url = quote(str(get_request_site_address(full_address=True)), str(""))
+	args.encoded_title = quote(str(args.title or ""), str(""))
+	
+	return args
+	
\ No newline at end of file
diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py
index ded6897..daf7d61 100644
--- a/stock/doctype/delivery_note/delivery_note.py
+++ b/stock/doctype/delivery_note/delivery_note.py
@@ -366,6 +366,7 @@
 						
 				# Reduce actual qty from warehouse
 				self.make_sl_entry(d, d['warehouse'], - flt(d['qty']) , 0, update_stock)
+		
 		get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
 
 
diff --git a/stock/doctype/delivery_note_item/delivery_note_item.txt b/stock/doctype/delivery_note_item/delivery_note_item.txt
index 1961e6c..fb3dd41 100644
--- a/stock/doctype/delivery_note_item/delivery_note_item.txt
+++ b/stock/doctype/delivery_note_item/delivery_note_item.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-03-25 11:55:16", 
+  "creation": "2013-03-26 11:03:09", 
   "docstatus": 0, 
-  "modified": "2013-03-25 15:43:04", 
+  "modified": "2013-03-28 15:42:41", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -248,7 +248,7 @@
   "doctype": "DocField", 
   "fieldname": "expense_account", 
   "fieldtype": "Link", 
-  "hidden": 1, 
+  "hidden": 0, 
   "label": "Expense Account", 
   "no_copy": 1, 
   "options": "Account", 
@@ -260,11 +260,12 @@
   "doctype": "DocField", 
   "fieldname": "cost_center", 
   "fieldtype": "Link", 
-  "hidden": 1, 
+  "hidden": 0, 
   "label": "Cost Center", 
   "no_copy": 1, 
   "options": "Cost Center", 
   "print_hide": 1, 
+  "read_only": 0, 
   "width": "120px"
  }, 
  {
diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py
index 802771c..43bae2c 100644
--- a/stock/doctype/item/item.py
+++ b/stock/doctype/item/item.py
@@ -86,7 +86,7 @@
 				self.doclist.get({"doctype":"Website Item Group"})]
 		
 		if self.doc.show_in_website:
-			from website.utils import update_page_name
+			from webnotes.webutils import update_page_name
 			if self.doc.name==self.doc.item_name:
 				page_name_from = self.doc.name
 			else:
@@ -98,7 +98,7 @@
 		
 		elif self.doc.page_name:
 			# if unchecked show in website
-			from website.utils import delete_page_cache
+			from webnotes.webutils import delete_page_cache
 			delete_page_cache(self.doc.page_name)
 			
 			_invalidate_cache()
@@ -112,7 +112,7 @@
 			where item_code=%s and is_cancelled='Yes' """, self.doc.item_code)
 		
 		if self.doc.page_name:
-			from website.utils import clear_cache
+			from webnotes.webutils import clear_cache
 			clear_cache(self.doc.page_name)
 		
 	# Check whether Ref Rate is not entered twice for same Price List and Currency
@@ -231,7 +231,7 @@
 	def on_rename(self,newdn,olddn):
 		sql("update tabItem set item_code = %s where name = %s", (newdn, olddn))
 		if self.doc.page_name:
-			from website.utils import clear_cache
+			from webnotes.webutils import clear_cache
 			clear_cache(self.doc.page_name)
 			
 	def prepare_template_args(self):
diff --git a/stock/doctype/landed_cost_wizard/landed_cost_wizard.py b/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
index 1fb7b9a..e5fd12c 100644
--- a/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
+++ b/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
@@ -212,7 +212,8 @@
 				if flt(d.qty):
 					d.valuation_rate = (flt(d.purchase_rate) + (flt(d.rm_supp_cost)/flt(d.qty)) + (flt(d.item_tax_amount)/flt(d.qty))) / flt(d.conversion_factor)
 					d.save()
-					self.update_serial_no(d.serial_no, d.valuation_rate)
+					if d.serial_no:
+						self.update_serial_no(d.serial_no, d.valuation_rate)
 				sql("update `tabStock Ledger Entry` set incoming_rate = '%s' where voucher_detail_no = '%s'"%(flt(d.valuation_rate), d.name))
 				
 				res = sql("""select item_code, warehouse, posting_date, posting_time 
@@ -226,10 +227,10 @@
 	
 	def update_serial_no(self, sr_no, rate):
 		""" update valuation rate in serial no"""
-		sr_no = cstr(sr_no).split('\n')
-		for d in sr_no:
-			sql("update `tabSerial No` set purchase_rate = %s where name = %s", (rate, d))
-
+		sr_no = map(lambda x: x.strip(), cstr(sr_no).split('\n'))
+		
+		webnotes.conn.sql("""update `tabSerial No` set purchase_rate = %s where name in (%s)""" % 
+			('%s', ', '.join(['%s']*len(sr_no))), tuple([rate] + sr_no))
 				
 	def update_landed_cost(self):
 		""" 
diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js
index 9b89d78..3e21207 100644
--- a/stock/doctype/stock_entry/stock_entry.js
+++ b/stock/doctype/stock_entry/stock_entry.js
@@ -205,25 +205,27 @@
 	},
 	
 	make_return_jv: function() {
-		this.frm.call({
-			method: "make_return_jv",
-			args: {
-				stock_entry: this.frm.doc.name
-			},
-			callback: function(r) {
-				if(!r.exc) {
-					var jv_name = wn.model.make_new_doc_and_get_name('Journal Voucher');
-					var jv = locals["Journal Voucher"][jv_name];
-					$.extend(jv, r.message[0]);
-					$.each(r.message.slice(1), function(i, jvd) {
-						var child = wn.model.add_child(jv, "Journal Voucher Detail", "entries");
-						$.extend(child, jvd);
-					});
-					loaddoc("Journal Voucher", jv_name);
+		if(this.get_doctype_docname()) {
+			this.frm.call({
+				method: "make_return_jv",
+				args: {
+					stock_entry: this.frm.doc.name
+				},
+				callback: function(r) {
+					if(!r.exc) {
+						var jv_name = wn.model.make_new_doc_and_get_name('Journal Voucher');
+						var jv = locals["Journal Voucher"][jv_name];
+						$.extend(jv, r.message[0]);
+						$.each(r.message.slice(1), function(i, jvd) {
+							var child = wn.model.add_child(jv, "Journal Voucher Detail", "entries");
+							$.extend(child, jvd);
+						});
+						loaddoc("Journal Voucher", jv_name);
+					}
+
 				}
-				
-			}
-		});
+			});
+		}
 	},
 
 });
@@ -358,6 +360,8 @@
 
 cur_frm.cscript.validate = function(doc, cdt, cdn) {
 	cur_frm.cscript.validate_items(doc);
+	if($.inArray(cur_frm.doc.purpose, ["Purchase Return", "Sales Return"])!==-1)
+		validated = cur_frm.cscript.get_doctype_docname() ? true : false;
 }
 
 cur_frm.cscript.validate_items = function(doc) {
diff --git a/stock/doctype/stock_ledger/stock_ledger.py b/stock/doctype/stock_ledger/stock_ledger.py
index fcb4a54..469c94b 100644
--- a/stock/doctype/stock_ledger/stock_ledger.py
+++ b/stock/doctype/stock_ledger/stock_ledger.py
@@ -38,10 +38,10 @@
 		
 		for d in getlist(obj.doclist, table_name):
 			if d.serial_no:
-				d.serial_no = cstr(d.serial_no).strip().replace(',', '\n')
+				serial_nos = cstr(d.serial_no).strip().replace(',', '\n').split('\n')
+				d.serial_no = "\n".join(map(lambda x: x.strip(), serial_nos))
 				d.save()
 
-
 	def validate_serial_no_warehouse(self, obj, fname):
 		for d in getlist(obj.doclist, fname):
 			wh = d.warehouse or d.s_warehouse
@@ -84,6 +84,7 @@
 		item_details = webnotes.conn.sql("""select item_group, warranty_period 
 			from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or 
 			end_of_life = '0000-00-00' or end_of_life > now()) """ %(d.item_code), as_dict=1)
+		webnotes.errprint([d.item_code, d.valuation_rate])
 		
 		s.purchase_document_type	=	obj.doc.doctype
 		s.purchase_document_no		=	obj.doc.name
diff --git a/stock/utils.py b/stock/utils.py
index d75c1d4..a2541dc 100644
--- a/stock/utils.py
+++ b/stock/utils.py
@@ -171,7 +171,7 @@
 		buying_amount = 0.0
 		for bom_item in item_sales_bom[item_code]:
 			if bom_item.get("parent_detail_docname")==voucher_detail_no:
-				buying_amount += _get_buying_amount(voucher_type, voucher_no, "[** No Item Row **]",
+				buying_amount += _get_buying_amount(voucher_type, voucher_no, voucher_detail_no,
 					bom_item.item_code, bom_item.warehouse or warehouse, 
 					bom_item.total_qty or (bom_item.qty * qty), stock_ledger_entries)
 		return buying_amount
@@ -187,8 +187,7 @@
 		
 	for i, sle in enumerate(relevant_stock_ledger_entries):
 		if sle.voucher_type == voucher_type and sle.voucher_no == voucher_no and \
-			((sle.voucher_detail_no == item_row) or (sle.voucher_type != "Stock Reconciliation" 
-			and flt(sle.qty) == qty)):
+			sle.voucher_detail_no == item_row:
 				previous_stock_value = len(relevant_stock_ledger_entries) > i+1 and \
 					flt(relevant_stock_ledger_entries[i+1].stock_value) or 0.0
 				
diff --git a/website/doctype/about_us_settings/about_us_settings.py b/website/doctype/about_us_settings/about_us_settings.py
index fb3dcc9..0872015 100644
--- a/website/doctype/about_us_settings/about_us_settings.py
+++ b/website/doctype/about_us_settings/about_us_settings.py
@@ -8,7 +8,7 @@
 		self.doc, self.doclist = d, dl
 			
 	def on_update(self):
-		from website.utils import clear_cache
+		from webnotes.webutils import clear_cache
 		clear_cache("about")
 		
 def get_args():
diff --git a/website/doctype/blog_category/blog_category.py b/website/doctype/blog_category/blog_category.py
index c8c369c..41f8fb0 100644
--- a/website/doctype/blog_category/blog_category.py
+++ b/website/doctype/blog_category/blog_category.py
@@ -9,6 +9,6 @@
 		
 	def on_update(self):
 		# for blog footer
-		from website.utils import clear_cache
+		from webnotes.webutils import clear_cache
 		clear_cache()
 		
\ No newline at end of file
diff --git a/website/doctype/blog_post/blog_post.py b/website/doctype/blog_post/blog_post.py
index 90f72f2..05236a1 100644
--- a/website/doctype/blog_post/blog_post.py
+++ b/website/doctype/blog_post/blog_post.py
@@ -17,7 +17,7 @@
 from __future__ import unicode_literals
 
 import webnotes
-import website.utils
+import webnotes.webutils
 from webnotes import _
 
 class DocType:
@@ -25,7 +25,7 @@
 		self.doc, self.doclist = d, dl
 
 	def autoname(self):
-		from website.utils import page_name
+		from webnotes.webutils import page_name
 		self.doc.name = page_name(self.doc.title)
 
 	def validate(self):
@@ -38,8 +38,8 @@
 			where name=%s""", self.doc.blogger)
 
 	def on_update(self):
-		website.utils.update_page_name(self.doc, self.doc.title)
-		website.utils.delete_page_cache("writers")
+		webnotes.webutils.update_page_name(self.doc, self.doc.title)
+		webnotes.webutils.delete_page_cache("writers")
 
 	def send_emails(self):
 		"""send emails to subscribers"""
diff --git a/website/doctype/blogger/blogger.txt b/website/doctype/blogger/blogger.txt
index 7f741c5..f56df1f 100644
--- a/website/doctype/blogger/blogger.txt
+++ b/website/doctype/blogger/blogger.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-03-08 11:36:52", 
+  "creation": "2013-03-25 16:00:51", 
   "docstatus": 0, 
-  "modified": "2013-03-11 14:00:37", 
+  "modified": "2013-03-29 10:37:37", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -50,6 +50,7 @@
   "doctype": "DocField", 
   "fieldname": "full_name", 
   "fieldtype": "Data", 
+  "in_list_view": 1, 
   "label": "Full Name", 
   "reqd": 1
  }, 
@@ -77,6 +78,7 @@
   "doctype": "DocField", 
   "fieldname": "posts", 
   "fieldtype": "Int", 
+  "in_list_view": 1, 
   "label": "Posts", 
   "read_only": 1
  }, 
diff --git a/website/doctype/contact_us_settings/contact_us_settings.py b/website/doctype/contact_us_settings/contact_us_settings.py
index 8716e60..37e49a6 100644
--- a/website/doctype/contact_us_settings/contact_us_settings.py
+++ b/website/doctype/contact_us_settings/contact_us_settings.py
@@ -17,5 +17,5 @@
 			self.address = webnotes.bean("Address", self.doc.address).doc
 			
 	def on_update(self):
-		from website.utils import clear_cache
+		from webnotes.webutils import clear_cache
 		clear_cache("contact")
\ No newline at end of file
diff --git a/website/doctype/product_settings/product_settings.py b/website/doctype/product_settings/product_settings.py
index 980f123..0cb4b7b 100644
--- a/website/doctype/product_settings/product_settings.py
+++ b/website/doctype/product_settings/product_settings.py
@@ -9,7 +9,7 @@
 		
 	def on_update(self):
 		"""clear web cache"""
-		from website.utils import clear_cache
+		from webnotes.webutils import clear_cache
 		clear_cache()
 		
 		if self.doc.default_product_category:
diff --git a/website/doctype/style_settings/style_settings.py b/website/doctype/style_settings/style_settings.py
index 58dca7b..ddfcf5c 100644
--- a/website/doctype/style_settings/style_settings.py
+++ b/website/doctype/style_settings/style_settings.py
@@ -27,7 +27,7 @@
 	def validate(self):
 		"""make custom css"""
 		from jinja2 import Template
-		from website.utils import get_hex_shade
+		from webnotes.webutils import get_hex_shade
 		import os
 		
 		self.validate_colors()
@@ -46,7 +46,7 @@
 		from webnotes.sessions import clear_cache
 		clear_cache('Guest')
 
-		from website.utils import clear_cache
+		from webnotes.webutils import clear_cache
 		clear_cache()
 		
 		for f in ["small_font_size", "at_import", "heading_text_style"]:
diff --git a/website/doctype/web_page/web_page.py b/website/doctype/web_page/web_page.py
index d902744..d43bcb4 100644
--- a/website/doctype/web_page/web_page.py
+++ b/website/doctype/web_page/web_page.py
@@ -22,11 +22,11 @@
 		self.doc, self.doclist = d, dl
 
 	def autoname(self):
-		from website.utils import page_name
+		from webnotes.webutils import page_name
 		self.doc.name = page_name(self.doc.title)
 
 	def on_update(self):
-		from website.utils import update_page_name
+		from webnotes.webutils import update_page_name
 		update_page_name(self.doc, self.doc.title)
 		self.if_home_clear_cache()
 
@@ -36,7 +36,7 @@
 			from webnotes.sessions import clear_cache
 			clear_cache('Guest')
 			
-			from website.utils import clear_cache
+			from webnotes.webutils import clear_cache
 			clear_cache(self.doc.page_name)
 			clear_cache('index')
 			
diff --git a/website/doctype/website_settings/website_settings.py b/website/doctype/website_settings/website_settings.py
index 714b75a..77eb1c5 100644
--- a/website/doctype/website_settings/website_settings.py
+++ b/website/doctype/website_settings/website_settings.py
@@ -28,7 +28,7 @@
 		make()
 		
 		# clear web cache (for menus!)
-		from website.utils import clear_cache
+		from webnotes.webutils import clear_cache
 		clear_cache()
 
 	def set_home_page(self):
diff --git a/website/helpers/blog.py b/website/helpers/blog.py
index 4044353..fb85e0d 100644
--- a/website/helpers/blog.py
+++ b/website/helpers/blog.py
@@ -3,15 +3,15 @@
 
 from __future__ import unicode_literals
 import webnotes
-import website.utils
+import webnotes.webutils
 from webnotes import _
 
 def clear_blog_cache():
 	for blog in webnotes.conn.sql_list("""select page_name from 
 		`tabBlog Post` where ifnull(published,0)=1"""):
-		website.utils.delete_page_cache(blog)
+		webnotes.webutils.delete_page_cache(blog)
 	
-	website.utils.delete_page_cache("writers")
+	webnotes.webutils.delete_page_cache("writers")
 
 @webnotes.whitelist(allow_guest=True)
 def get_blog_list(start=0, by=None, category=None):
@@ -44,7 +44,7 @@
 		from webnotes.utils import global_date_format, get_fullname
 		res['published'] = global_date_format(res['creation'])
 		if not res['content']:
-			res['content'] = website.utils.get_html(res['page_name'])
+			res['content'] = webnotes.webutils.get_html(res['page_name'])
 		res['content'] = res['content'][:140]
 		
 	return result
@@ -71,13 +71,13 @@
 	comment = webnotes.widgets.form.comments.add_comment(args)
 	
 	# since comments are embedded in the page, clear the web cache
-	website.utils.clear_cache(args.get('page_name'))
+	webnotes.webutils.clear_cache(args.get('page_name'))
 	
 	comment['comment_date'] = webnotes.utils.global_date_format(comment['creation'])
 	template_args = { 'comment_list': [comment], 'template': 'html/comment.html' }
 	
 	# get html of comment row
-	comment_html = website.utils.build_html(template_args)
+	comment_html = webnotes.webutils.build_html(template_args)
 	
 	# notify commentors 
 	commentors = [d[0] for d in webnotes.conn.sql("""select comment_by from tabComment where
@@ -115,8 +115,8 @@
 	lead.save()
 
 def get_blog_content(blog_page_name):
-	import website.utils
-	content = website.utils.get_html(blog_page_name)
+	import webnotes.webutils
+	content = webnotes.webutils.get_html(blog_page_name)
 	import webnotes.utils
 	content = webnotes.utils.escape_html(content)
 	return content
diff --git a/website/helpers/make_web_include_files.py b/website/helpers/make_web_include_files.py
index 62b8c66..fe6f05c 100644
--- a/website/helpers/make_web_include_files.py
+++ b/website/helpers/make_web_include_files.py
@@ -3,14 +3,14 @@
 
 import os
 import webnotes
-import website.utils
+import webnotes.webutils
 
 def make():
 
 	if not webnotes.conn:
 		webnotes.connect()
 	
-	home_page = website.utils.get_home_page()
+	home_page = webnotes.webutils.get_home_page()
 
 	fname = 'js/wn-web.js'
 	if os.path.basename(os.path.abspath('.'))!='public':
diff --git a/website/helpers/product.py b/website/helpers/product.py
index f79d207..4a1cd40 100644
--- a/website/helpers/product.py
+++ b/website/helpers/product.py
@@ -5,7 +5,7 @@
 
 import webnotes
 from webnotes.utils import cstr
-from website.utils import build_html, delete_page_cache
+from webnotes.webutils import build_html, delete_page_cache
 
 
 @webnotes.whitelist(allow_guest=True)
diff --git a/website/helpers/sitemap.py b/website/helpers/sitemap.py
index d35ee56..201865a 100644
--- a/website/helpers/sitemap.py
+++ b/website/helpers/sitemap.py
@@ -13,7 +13,7 @@
 	global frame_xml, link_xml
 	import urllib, os
 	import webnotes
-	import website.utils
+	import webnotes.webutils
 
 	# settings
 	max_doctypes = 10
@@ -24,8 +24,8 @@
 	
 	if domain:
 		# list of all pages in web cache
-		for doctype in website.utils.page_map:
-			d = website.utils.page_map[doctype];
+		for doctype in webnotes.webutils.page_map:
+			d = webnotes.webutils.page_map[doctype];
 			pages = webnotes.conn.sql("""select page_name, `modified`
 				from `tab%s` where ifnull(%s,0)=1
 				order by modified desc""" % (doctype, d.condition_field))
diff --git a/website/page/website_home/website_home.js b/website/page/website_home/website_home.js
index e112207..71f2f4d 100644
--- a/website/page/website_home/website_home.js
+++ b/website/page/website_home/website_home.js
@@ -93,6 +93,7 @@
 	{
 		title: wn._("Advanced Scripting"),
 		icon: "icon-wrench",
+		right: true,
 		items: [
 			{
 				"route":"Form/Website Script",
diff --git a/website/settings.py b/website/settings.py
deleted file mode 100644
index 3fff19e..0000000
--- a/website/settings.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import webnotes
-
-page_map = {
-	'Web Page': webnotes._dict({
-		"template": 'html/web_page.html',
-		"condition_field": "published"
-	}),
-	'Blog Post': webnotes._dict({
-		"template": 'html/blog_page.html',
-		"condition_field": "published",
-	}),
-	'Item': webnotes._dict({
-		"template": 'html/product_page.html',
-		"condition_field": "show_in_website",
-	}),
-	'Item Group': webnotes._dict({
-		"template": "html/product_group.html",
-		"condition_field": "show_in_website"
-	})
-}
-
-page_settings_map = {
-	"about": "website.doctype.about_us_settings.about_us_settings.get_args",
-	"contact": "Contact Us Settings",
-	"blog": "website.helpers.blog.get_blog_template_args",
-	"writers": "website.helpers.blog.get_writers_args",
-	"print": "core.doctype.print_format.print_format.get_args",
-	"orders": "selling.doctype.sales_order.sales_order.get_currency_and_number_format",
-	"order": "selling.doctype.sales_order.sales_order.get_website_args",
-	"ticket": "support.doctype.support_ticket.support_ticket.get_website_args"
-}
-
-no_cache = ["message", "print", "order", "ticket"]
diff --git a/website/templates/html/product_group.html b/website/templates/html/product_group.html
index 2e80c43..510f994 100644
--- a/website/templates/html/product_group.html
+++ b/website/templates/html/product_group.html
@@ -29,8 +29,8 @@
 			{{ item }}
 		{% endfor %}
 	</div>
-		{% if len(items)==20 %}
-			<div class="alert info">Showing top 20</div>
+		{% if len(items)==100 %}
+			<div class="alert info">Showing top 100 items.</div>
 		{% endif %}
 	{% else %}
 		<div class="alert">No items listed.</div>
diff --git a/website/templates/html/product_in_list.html b/website/templates/html/product_in_list.html
index 97de596..bc62607 100644
--- a/website/templates/html/product_in_list.html
+++ b/website/templates/html/product_in_list.html
@@ -1,10 +1,12 @@
 <div class="span3">
 	<div style="height: 120px; overflow: hidden;">
-		{% if website_image %}
+		<a href="{{ page_name }}">
+		{%- if website_image -%}
 		<img class="product-image" style="width: 80%; margin: auto;" src="{{ website_image }}">
-		{% else %}
+		{%- else -%}
 		{% include 'html/product_missing_image.html' %}
-		{% endif %}
+		{%- endif -%}
+		</a>
 	</div>
 	<div style="height: 100px; overflow: hidden; font-size: 80%;">
 		<h4 style="margin-bottom: 2px;"><a href="{{ page_name }}">{{ item_name }}</a></h4>
diff --git a/website/utils.py b/website/utils.py
deleted file mode 100644
index 2528859..0000000
--- a/website/utils.py
+++ /dev/null
@@ -1,311 +0,0 @@
-# ERPNext - web based ERP (http://erpnext.com)
-# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-# 
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from __future__ import unicode_literals
-
-import os
-import conf
-from website.settings import *
-import webnotes
-import webnotes.utils
-
-def render(page_name):
-	"""render html page"""
-	try:
-		if page_name:
-			html = get_html(page_name)
-		else:
-			html = get_html('index')
-	except Exception:
-		html = get_html('error')
-
-	from webnotes.handler import eprint, print_zip
-	eprint("Content-Type: text/html")
-	print_zip(html)
-
-def get_html(page_name):
-	"""get page html"""
-	page_name = scrub_page_name(page_name)
-	
-	html = ''
-	
-	# load from cache, if auto cache clear is falsy
-	if not (hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0):
-		if not page_name in no_cache:
-			html = webnotes.cache().get_value("page:" + page_name)
-			from_cache = True
-
-	if not html:
-		from webnotes.auth import HTTPRequest
-		webnotes.http_request = HTTPRequest()
-		
-		#webnotes.connect()
-		html = load_into_cache(page_name)
-		from_cache = False
-	
-	if not html:
-		html = get_html("404")
-
-	if page_name=="error":
-		html = html.replace("%(error)s", webnotes.getTraceback())
-	else:
-		comments = "\n\npage:"+page_name+\
-			"\nload status: " + (from_cache and "cache" or "fresh")
-		html += """\n<!-- %s -->""" % webnotes.utils.cstr(comments)
-
-	return html
-	
-def scrub_page_name(page_name):
-	if page_name.endswith('.html'):
-		page_name = page_name[:-5]
-
-	return page_name
-
-def page_name(title):
-	"""make page name from title"""
-	import re
-	name = title.lower()
-	name = re.sub('[~!@#$%^&*()<>,."\']', '', name)
-	name = re.sub('[:/]', '-', name)
-
-	name = '-'.join(name.split())
-
-	# replace repeating hyphens
-	name = re.sub(r"(-)\1+", r"\1", name)
-	
-	return name
-
-def update_page_name(doc, title):
-	"""set page_name and check if it is unique"""
-	webnotes.conn.set(doc, "page_name", page_name(title))
-	
-	standard_pages = get_template_pages()
-	if doc.page_name in standard_pages:
-		webnotes.conn.sql("""Page Name cannot be one of %s""" % ', '.join(standard_pages))
-	
-	res = webnotes.conn.sql("""\
-		select count(*) from `tab%s`
-		where page_name=%s and name!=%s""" % (doc.doctype, '%s', '%s'),
-		(doc.page_name, doc.name))
-	if res and res[0][0] > 0:
-		webnotes.msgprint("""A %s with the same title already exists.
-			Please change the title of %s and save again."""
-			% (doc.doctype, doc.name), raise_exception=1)
-
-	delete_page_cache(doc.page_name)
-
-def load_into_cache(page_name):
-	args = prepare_args(page_name)
-	if not args:
-		return ""
-	html = build_html(args)
-	webnotes.cache().set_value("page:" + page_name, html)
-	return html
-
-def build_html(args):
-	from jinja2 import Environment, FileSystemLoader
-
-	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)
-	
-	return html
-	
-def prepare_args(page_name):
-	if page_name == 'index':
-		page_name = get_home_page()
-	
-	if page_name in get_template_pages():
-		args = webnotes._dict({
-			'template': 'pages/%s.html' % page_name,
-			'name': page_name,
-		})
-		if page_name in page_settings_map:
-			target = page_settings_map[page_name]
-			if "." in target:
-				args.update(webnotes.get_method(target)())
-			else:
-				args.obj = webnotes.bean(page_settings_map[page_name]).obj
-
-	else:
-		args = get_doc_fields(page_name)
-	
-	if not args:
-		return False
-	
-	get_outer_env(page_name, args)
-	
-	return args	
-
-def get_template_pages():
-	pages_path = os.path.join(os.path.dirname(conf.__file__), 'app', 
-		'website', 'templates', 'pages')
-	page_list = []
-	for page in os.listdir(pages_path):
-		page_list.append(scrub_page_name(page))
-
-	return page_list
-
-def get_doc_fields(page_name):
-	doc_type, doc_name = get_source_doc(page_name)
-	if not doc_type:
-		return False
-	
-	obj = webnotes.get_obj(doc_type, doc_name, with_children=True)
-
-	if hasattr(obj, 'prepare_template_args'):
-		obj.prepare_template_args()
-
-	args = obj.doc.fields
-	args['template'] = page_map[doc_type].template
-	args['obj'] = obj
-	args['int'] = int
-	
-	return args
-
-def get_source_doc(page_name):
-	"""get source doc for the given page name"""
-	for doctype in page_map:
-		name = webnotes.conn.sql("""select name from `tab%s` where 
-			page_name=%s and ifnull(%s, 0)=1""" % (doctype, "%s", 
-			page_map[doctype].condition_field), page_name)
-		if name:
-			return doctype, name[0][0]
-
-	return None, None
-	
-def get_outer_env(page_name, args):
-	
-	from webnotes.utils import get_request_site_address
-	from urllib import quote
-	
-	all_top_items = webnotes.conn.sql("""\
-		select * from `tabTop Bar Item`
-		where parent='Website Settings' and parentfield='top_bar_items'
-		order by idx asc""", as_dict=1)
-	
-	top_items = [d for d in all_top_items if not d['parent_label']]
-	
-	# attach child items to top bar
-	for d in all_top_items:
-		if d['parent_label']:
-			for t in top_items:
-				if t['label']==d['parent_label']:
-					if not 'child_items' in t:
-						t['child_items'] = []
-					t['child_items'].append(d)
-					break
-	
-	if top_items and ("products" in [d.url.split(".")[0] for d in top_items if d.url]):
-		# product categories
-		products = webnotes.conn.sql("""select t1.item_group as label, 
-			t2.page_name as url,
-			ifnull(t1.indent,0) as indent
-			from `tabWebsite Product Category` t1, `tabItem Group` t2 
-			where t1.item_group = t2.name
-			and ifnull(t2.show_in_website,0)=1 order by t1.idx""", as_dict=1)
-		products_item = filter(lambda d: d.url and d.url.split(".")[0]=="products", top_items)[0]			
-		products_item.child_items = products
-		
-	ret = webnotes._dict({
-		'top_bar_items': top_items,
-		'footer_items': webnotes.conn.sql("""\
-			select * from `tabTop Bar Item`
-			where parent='Website Settings' and parentfield='footer_items'
-			order by idx asc""", as_dict=1),
-			
-		'int':int,
-		"webnotes": webnotes,
-		"utils": webnotes.utils
-	})
-	
-	args.update(ret)
-	
-	settings = webnotes.doc("Website Settings", "Website Settings")
-	for k in ["banner_html", "brand_html", "copyright", "address", "twitter_share_via",
-		"favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share"]:
-		if k in settings.fields:
-			args[k] = settings.fields.get(k)
-
-	for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share"]:
-		args[k] = int(args.get(k) or 0)
-	
-	args.url = quote(str(get_request_site_address(full_address=True)), str(""))
-	args.encoded_title = quote(str(args.title or ""), str(""))
-	
-	return args
-
-def get_home_page():
-	doc_name = webnotes.conn.get_value('Website Settings', None, 'home_page')
-	if doc_name:
-		page_name = webnotes.conn.get_value('Web Page', doc_name, 'page_name')
-	else:
-		page_name = 'login'
-
-	return page_name
-	
-def clear_cache(page_name=None):
-	if page_name:
-		delete_page_cache(page_name)
-	else:
-		cache = webnotes.cache()
-		for p in get_all_pages():
-			cache.delete_value("page:" + p)
-
-def get_all_pages():
-	all_pages = get_template_pages()
-	all_pages += page_settings_map.keys()
-	for doctype in page_map:
-		all_pages += [p[0] for p in webnotes.conn.sql("""select distinct page_name 
-			from `tab%s`""" % doctype) if p[0]]
-
-	return all_pages
-
-def delete_page_cache(page_name):
-	if page_name:
-		webnotes.cache().delete_value("page:" + page_name)
-			
-def get_hex_shade(color, percent):
-	
-	def p(c):
-		v = int(c, 16) + int(int('ff', 16) * (float(percent)/100))
-		if v < 0: 
-			v=0
-		if v > 255: 
-			v=255
-		h = hex(v)[2:]
-		if len(h) < 2:
-			h = "0" + h
-		return h
-		
-	r, g, b = color[0:2], color[2:4], color[4:6]
-	
-	avg = (float(int(r, 16) + int(g, 16) + int(b, 16)) / 3)
-	# switch dark and light shades
-	if avg > 128:
-		percent = -percent
-
-	# stronger diff for darker shades
-	if percent < 25 and avg < 64:
-		percent = percent * 2
-	
-	return p(r) + p(g) + p(b)
-	
-	
\ No newline at end of file