Merge branch 'master' into edge
diff --git a/accounts/doctype/journal_voucher/test_journal_voucher.py b/accounts/doctype/journal_voucher/test_journal_voucher.py
index 67fd1c0..bb846d1 100644
--- a/accounts/doctype/journal_voucher/test_journal_voucher.py
+++ b/accounts/doctype/journal_voucher/test_journal_voucher.py
@@ -26,7 +26,6 @@
 		"fiscal_year": "_Test Fiscal Year 2013", 
 		"naming_series": "_T-Journal Voucher-",
 		"posting_date": "2013-02-14", 
-		"tds_applicable": "No",
 		"user_remark": "test",
 		"voucher_type": "Bank Voucher",
 		"cheque_no": "33",
diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py
index 96cfc00..be55e8a 100644
--- a/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -35,7 +35,7 @@
 		self.fname = 'entries'
 
 	def get_credit_to(self):
-		acc_head = sql("select name, credit_days from `tabAccount` where (name = %s or (master_name = %s and master_type = 'supplier')) and docstatus != 2", (cstr(self.doc.supplier) + " - " + self.get_company_abbr(),self.doc.supplier))		
+		acc_head = sql("select name, credit_days from `tabAccount` where (name = %s or (master_name = %s and master_type = 'supplier')) and docstatus != 2", (cstr(self.doc.supplier) + " - " + self.company_abbr,self.doc.supplier))		
 
 		ret = {}
 		if acc_head and acc_head[0][0]:
@@ -54,20 +54,32 @@
 			ret['due_date'] = add_days(cstr(self.doc.posting_date), acc and cint(acc[1]) or 0)
 			
 		return ret
-
-	def get_default_values(self,args):
-		import json
-		args = json.loads(args)
-		ret = {}
-		if sql("select name from `tabItem` where name = '%s'" % args['item_code']):
-			if not args['expense_head'] or args['expense_head'] == 'undefined':
-				expense_head = sql("select name from `tabAccount` where account_name in (select purchase_account from `tabItem` where name = '%s')" % args['item_code'])
-				ret['expense_head'] = expense_head and expense_head[0][0] or ''
-			if not args['cost_center'] or args['cost_center'] == 'undefined':
-				cost_center = sql("select cost_center from `tabItem` where name = '%s'" % args['item_code'])
-				ret['cost_center'] = cost_center and cost_center[0][0] or ''
-		return ret
-		 
+		
+	def get_default_values(self, args):
+		if isinstance(args, basestring):
+			import json
+			args = json.loads(args)
+		
+		out = webnotes._dict()
+		
+		item = webnotes.conn.sql("""select name, purchase_account, cost_center,
+			is_stock_item from `tabItem` where name=%s""", args.get("item_code"), as_dict=1)
+		
+		if item and item[0]:
+			item = item[0]
+			
+			if cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) and \
+				item.is_stock_item == "Yes":
+					# unset expense head for stock item and auto inventory accounting
+					out.expense_head = out.cost_center = None
+			else:
+				if not args.get("expense_head"):
+					out.expense_head = item.purchase_account
+				if not args.get("cost_center"):
+					out.cost_center = item.cost_center
+		
+		return out
+			
 	def pull_details(self):
 		if self.doc.purchase_receipt_main:
 			self.validate_duplicate_docname('purchase_receipt')
@@ -86,9 +98,7 @@
 	def get_expense_account(self, doctype):
 		for d in getlist(self.doclist, doctype):			
 			if d.item_code:
-				item = webnotes.conn.sql("select purchase_account, cost_center from tabItem where name = '%s'" %(d.item_code), as_dict=1)
-				d.expense_head = item and item[0]['purchase_account'] or ''
-				d.cost_center = item and item[0]['cost_center'] or ''
+				d.fields.update(self.get_default_values(d.fields))
 
 	def get_advances(self):
 		super(DocType, self).get_advances(self.doc.credit_to, 
@@ -110,9 +120,6 @@
 		ret={'add_tax_rate' :rate and flt(rate[0][0]) or 0 }
 		return ret
 
-	def get_company_abbr(self):
-		return sql("select abbr from tabCompany where name=%s", self.doc.company)[0][0]
-
 	def validate_duplicate_docname(self,doctype):
 		for d in getlist(self.doclist, 'entries'): 
 			if doctype == 'purchase_receipt' and cstr(self.doc.purchase_receipt_main) == cstr(d.purchase_receipt):
@@ -186,7 +193,7 @@
 		if self.doc.supplier and self.doc.credit_to:
 			acc_head = sql("select master_name from `tabAccount` where name = %s", self.doc.credit_to)
 			
-			if (acc_head and cstr(acc_head[0][0]) != cstr(self.doc.supplier)) or (not acc_head and (self.doc.credit_to != cstr(self.doc.supplier) + " - " + self.get_company_abbr())):
+			if (acc_head and cstr(acc_head[0][0]) != cstr(self.doc.supplier)) or (not acc_head and (self.doc.credit_to != cstr(self.doc.supplier) + " - " + self.company_abbr)):
 				msgprint("Credit To: %s do not match with Supplier: %s for Company: %s.\n If both correctly entered, please select Master Type and Master Name in account master." %(self.doc.credit_to,self.doc.supplier,self.doc.company), raise_exception=1)
 				
 	# Check for Stopped PO
@@ -256,11 +263,25 @@
 			raise Exception
 			
 	def set_against_expense_account(self):
-		against_acc = []
-		for d in getlist(self.doclist, 'entries'):
-			if d.expense_account not in against_acc:
-				against_acc.append(d.expense_account)
-		self.doc.against_expense_account = ','.join(against_acc)
+		auto_inventory_accounting = \
+			cint(webnotes.defaults.get_global_default("auto_inventory_accounting"))
+		stock_not_billed_account = "Stock Received But Not Billed - %s" % self.company_abbr
+		
+		against_accounts = []
+		for item in self.doclist.get({"parentfield": "entries"}):
+			if auto_inventory_accounting and item.item_code in self.stock_items:
+				# in case of auto inventory accounting, against expense account is always
+				# Stock Received But Not Billed for a stock item
+				item.expense_head = item.cost_center = None
+				
+				if stock_not_billed_account not in against_accounts:
+					against_accounts.append(stock_not_billed_account)
+			
+			elif item.expense_head not in against_accounts:
+				# if no auto_inventory_accounting or not a stock item
+				against_accounts.append(item.expense_head)
+				
+		self.doc.against_expense_account = ",".join(against_accounts)
 
 	def po_required(self):
 		res = sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = 'po_required'")
@@ -320,6 +341,8 @@
 		 	self.doc.posting_date,'Posting Date')
 		
 		self.validate_write_off_account()
+		self.update_raw_material_cost()
+		self.update_valuation_rate("entries")
 
 	def check_prev_docstatus(self):
 		for d in getlist(self.doclist,'entries'):
@@ -382,11 +405,10 @@
 
 	def make_gl_entries(self, is_cancel = 0):
 		from accounts.general_ledger import make_gl_entries
+		auto_inventory_accounting = \
+			cint(webnotes.defaults.get_global_default("auto_inventory_accounting"))
+		
 		gl_entries = []
-		valuation_tax = 0
-		auto_inventory_accounting = webnotes.conn.get_value("Global Defaults", None, 
-		 	"auto_inventory_accounting")
-		abbr = self.get_company_abbr()
 		
 		# parent's gl entry
 		if self.doc.grand_total:
@@ -402,11 +424,9 @@
 			)
 	
 		# tax table gl entries
-		for tax in getlist(self.doclist, "purchase_tax_details"):
+		valuation_tax = 0
+		for tax in self.doclist.get({"parentfield": "purchase_tax_details"}):
 			if tax.category in ("Total", "Valuation and Total") and flt(tax.tax_amount):
-				valuation_tax += tax.add_deduct_tax == "Add" \
-					and flt(tax.tax_amount) or -1 * flt(tax.tax_amount)
-				
 				gl_entries.append(
 					self.get_gl_dict({
 						"account": tax.account_head,
@@ -417,25 +437,31 @@
 						"cost_center": tax.cost_center
 					}, is_cancel)
 				)
+			
+			# accumulate valuation tax
+			if tax.category in ("Valuation", "Valuation and Total") and flt(tax.tax_amount):
+				valuation_tax += (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)
 					
 		# item gl entries
-		stock_item_and_auto_accounting = False
+		stock_item_and_auto_inventory_accounting = False
 		for item in self.doclist.get({"parentfield": "entries"}):
-			if auto_inventory_accounting and flt(item.valuation_rate) and \
-					webnotes.conn.get_value("Item", item.item_code, "is_stock_item")=="Yes":
-				# if auto inventory accounting enabled and stock item, 
-				# then do stock related gl entries, expense will be booked in sales invoice
-				gl_entries.append(
-					self.get_gl_dict({
-						"account": "Stock Received But Not Billed - %s" % (abbr,),
-						"against": self.doc.credit_to,
-						"debit": flt(item.valuation_rate) * flt(item.conversion_factor) \
-							*  item.qty,
-						"remarks": self.doc.remarks or "Accounting Entry for Stock"
-					}, is_cancel)
-				)
-			
-				stock_item_and_auto_accounting = True
+			if auto_inventory_accounting and item.item_code in self.stock_items:
+				if flt(item.valuation_rate):
+					# if auto inventory accounting enabled and stock item, 
+					# then do stock related gl entries
+					# expense will be booked in sales invoice
+					
+					stock_item_and_auto_inventory_accounting = True
+					
+					gl_entries.append(
+						self.get_gl_dict({
+							"account": "Stock Received But Not Billed - %s" % (self.company_abbr,),
+							"against": self.doc.credit_to,
+							"debit": flt(item.valuation_rate) * flt(item.conversion_factor) \
+								*  flt(item.qty),
+							"remarks": self.doc.remarks or "Accounting Entry for Stock"
+						}, is_cancel)
+					)
 			
 			elif flt(item.amount):
 				# if not a stock item or auto inventory accounting disabled, book the expense
@@ -449,13 +475,13 @@
 					}, is_cancel)
 				)
 				
-		if stock_item_and_auto_accounting and valuation_tax:
+		if stock_item_and_auto_inventory_accounting and valuation_tax:
 			# credit valuation tax amount in "Expenses Included In Valuation"
 			# this will balance out valuation amount included in cost of goods sold
 			gl_entries.append(
 				self.get_gl_dict({
-					"account": "Expenses Included In Valuation - %s" % (abbr,),
-					"cost_center": "ERP - %s" % abbr, # to-do
+					"account": "Expenses Included In Valuation - %s" % (self.company_abbr,),
+					"cost_center": "Auto Inventory Accounting - %s" % self.company_abbr,
 					"against": self.doc.credit_to,
 					"credit": valuation_tax,
 					"remarks": self.doc.remarks or "Accounting Entry for Stock"
@@ -464,12 +490,12 @@
 		
 		# writeoff account includes petty difference in the invoice amount 
 		# and the amount that is paid
-		if self.doc.write_off_account and self.doc.write_off_amount:
+		if self.doc.write_off_account and flt(self.doc.write_off_amount):
 			gl_entries.append(
 				self.get_gl_dict({
 					"account": self.doc.write_off_account,
 					"against": self.doc.credit_to,
-					"credit": self.doc.write_off_amount,
+					"credit": flt(self.doc.write_off_amount),
 					"remarks": self.doc.remarks,
 					"cost_center": self.doc.write_off_cost_center
 				}, is_cancel)
@@ -478,7 +504,6 @@
 		if gl_entries:
 			make_gl_entries(gl_entries, cancel=is_cancel)
 
-
 	def check_next_docstatus(self):
 		submit_jv = sql("select t1.name from `tabJournal Voucher` t1,`tabJournal Voucher Detail` t2 where t1.name = t2.parent and t2.against_voucher = '%s' and t1.docstatus = 1" % (self.doc.name))
 		if submit_jv:
@@ -493,4 +518,16 @@
 
 	def on_update(self):
 		pass
-
+	def update_raw_material_cost(self):
+		if self.sub_contracted_items:
+			for d in self.doclist.get({"parentfield": "entries"}):
+				rm_cost = webnotes.conn.sql(""" select raw_material_cost / quantity 
+					from `tabBOM` where item = %s and is_default = 1 and docstatus = 1 
+					and is_active = 1 """, (d.item_code,))
+				rm_cost = rm_cost and flt(rm_cost[0][0]) or 0
+			
+				d.conversion_factor = d.conversion_factor or webnotes.conn.get_value(
+					"UOM Conversion Detail", {"parent": d.item_code, "uom": d.uom}, 
+					"conversion_factor") or 1
+			
+				d.rm_supp_cost = rm_cost * flt(d.qty) * flt(d.conversion_factor)
diff --git a/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index 62296bf..b9f7ec9 100644
--- a/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -20,18 +20,18 @@
 import webnotes
 import webnotes.model
 import json	
+from webnotes.utils import cint
+import webnotes.defaults
 
 test_dependencies = ["Item", "Cost Center"]
 
 class TestPurchaseInvoice(unittest.TestCase):
-	def test_gl_entries(self):
-		wrapper = webnotes.bean(self.get_test_doclist())
+	def test_gl_entries_without_auto_inventory_accounting(self):
+		webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+		self.assertTrue(not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")))
 		
-		# circumvent the disabled calculation call
-		obj = webnotes.get_obj(doc=wrapper.doc, doclist=wrapper.doclist)
-		obj.calculate_taxes_and_totals()
-		wrapper.set_doclist(obj.doclist)
-		
+		wrapper = webnotes.bean(copy=test_records[0])
+		wrapper.run_method("calculate_taxes_and_totals")
 		wrapper.insert()
 		wrapper.submit()
 		wrapper.load_from_db()
@@ -53,14 +53,38 @@
 		for d in gl_entries:
 			self.assertEqual([d.debit, d.credit], expected_gl_entries.get(d.account))
 			
-	def test_purchase_invoice_calculation(self):
-		wrapper = webnotes.bean(self.get_test_doclist())
+	def test_gl_entries_with_auto_inventory_accounting(self):
+		webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+		self.assertEqual(cint(webnotes.defaults.get_global_default("auto_inventory_accounting")), 1)
 		
-		# circumvent the disabled calculation call
-		obj = webnotes.get_obj(doc=wrapper.doc, doclist=wrapper.doclist)
-		obj.calculate_taxes_and_totals()
-		wrapper.set_doclist(obj.doclist)
-
+		pi = webnotes.bean(copy=test_records[1])
+		pi.run_method("calculate_taxes_and_totals")
+		pi.insert()
+		pi.submit()
+		
+		gl_entries = webnotes.conn.sql("""select account, debit, credit
+			from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
+			order by account asc""", pi.doc.name, as_dict=1)
+		self.assertTrue(gl_entries)
+		
+		expected_values = sorted([
+			["_Test Supplier - _TC", 0, 720],
+			["Stock Received But Not Billed - _TC", 750.0, 0],
+			["_Test Account Shipping Charges - _TC", 100.0, 0],
+			["_Test Account VAT - _TC", 120.0, 0],
+			["Expenses Included In Valuation - _TC", 0, 250.0]
+		])
+		
+		for i, gle in enumerate(gl_entries):
+			self.assertEquals(expected_values[i][0], gle.account)
+			self.assertEquals(expected_values[i][1], gle.debit)
+			self.assertEquals(expected_values[i][2], gle.credit)
+		
+		webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+			
+	def test_purchase_invoice_calculation(self):
+		wrapper = webnotes.bean(copy=test_records[0])
+		wrapper.run_method("calculate_taxes_and_totals")
 		wrapper.insert()
 		wrapper.load_from_db()
 		
@@ -91,145 +115,210 @@
 		for i, item in enumerate(wrapper.doclist.get({"parentfield": "entries"})):
 			self.assertEqual(item.item_code, expected_values[i][0])
 			self.assertEqual(item.item_tax_amount, expected_values[i][1])
-			
-	def get_test_doclist(self):
-		return [
-			# parent
-			{
-				"doctype": "Purchase Invoice",
-				"naming_series": "BILL",
-				"supplier_name": "_Test Supplier",
-				"credit_to": "_Test Supplier - _TC",
-				"bill_no": "NA",
-				"posting_date": "2013-02-03",
-				"fiscal_year": "_Test Fiscal Year 2013",
-				"company": "_Test Company",
-				"currency": "INR",
-				"conversion_rate": 1,
-				"grand_total_import": 0 # for feed
-			},
-			# items
-			{
-				"doctype": "Purchase Invoice Item",
-				"parentfield": "entries",
-				"item_code": "_Test Item Home Desktop 100",
-				"item_name": "_Test Item Home Desktop 100",
-				"qty": 10,
-				"import_rate": 50,
-				"import_amount": 500,
-				"rate": 50,
-				"amount": 500,
-				"uom": "_Test UOM",
-				"item_tax_rate": json.dumps({"_Test Account Excise Duty - _TC": 10}),
-				"expense_head": "_Test Account Cost for Goods Sold - _TC",
-				"cost_center": "_Test Cost Center - _TC"
-				
-			},
-			{
-				"doctype": "Purchase Invoice Item",
-				"parentfield": "entries",
-				"item_code": "_Test Item Home Desktop 200",
-				"item_name": "_Test Item Home Desktop 200",
-				"qty": 5,
-				"import_rate": 150,
-				"import_amount": 750,
-				"rate": 150,
-				"amount": 750,
-				"uom": "_Test UOM",
-				"expense_head": "_Test Account Cost for Goods Sold - _TC",
-				"cost_center": "_Test Cost Center - _TC"
-			},
-			# taxes
-			{
-				"doctype": "Purchase Taxes and Charges",
-				"parentfield": "purchase_tax_details",
-				"charge_type": "Actual",
-				"account_head": "_Test Account Shipping Charges - _TC",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "Shipping Charges",
-				"category": "Valuation and Total",
-				"add_deduct_tax": "Add",
-				"rate": 100
-			},
-			{
-				"doctype": "Purchase Taxes and Charges",
-				"parentfield": "purchase_tax_details",
-				"charge_type": "On Net Total",
-				"account_head": "_Test Account Customs Duty - _TC",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "Customs Duty",
-				"category": "Valuation",
-				"add_deduct_tax": "Add",
-				"rate": 10
-			},
-			{
-				"doctype": "Purchase Taxes and Charges",
-				"parentfield": "purchase_tax_details",
-				"charge_type": "On Net Total",
-				"account_head": "_Test Account Excise Duty - _TC",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "Excise Duty",
-				"category": "Total",
-				"add_deduct_tax": "Add",
-				"rate": 12
-			},
-			{
-				"doctype": "Purchase Taxes and Charges",
-				"parentfield": "purchase_tax_details",
-				"charge_type": "On Previous Row Amount",
-				"account_head": "_Test Account Education Cess - _TC",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "Education Cess",
-				"category": "Total",
-				"add_deduct_tax": "Add",
-				"rate": 2,
-				"row_id": 3
-			},
-			{
-				"doctype": "Purchase Taxes and Charges",
-				"parentfield": "purchase_tax_details",
-				"charge_type": "On Previous Row Amount",
-				"account_head": "_Test Account S&H Education Cess - _TC",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "S&H Education Cess",
-				"category": "Total",
-				"add_deduct_tax": "Add",
-				"rate": 1,
-				"row_id": 3
-			},
-			{
-				"doctype": "Purchase Taxes and Charges",
-				"parentfield": "purchase_tax_details",
-				"charge_type": "On Previous Row Total",
-				"account_head": "_Test Account CST - _TC",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "CST",
-				"category": "Total",
-				"add_deduct_tax": "Add",
-				"rate": 2,
-				"row_id": 5
-			},
-			{
-				"doctype": "Purchase Taxes and Charges",
-				"parentfield": "purchase_tax_details",
-				"charge_type": "On Net Total",
-				"account_head": "_Test Account VAT - _TC",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "VAT",
-				"category": "Total",
-				"add_deduct_tax": "Add",
-				"rate": 12.5
-			},
-			{
-				"doctype": "Purchase Taxes and Charges",
-				"parentfield": "purchase_tax_details",
-				"charge_type": "On Previous Row Total",
-				"account_head": "_Test Account Discount - _TC",
-				"cost_center": "_Test Cost Center - _TC",
-				"description": "Discount",
-				"category": "Total",
-				"add_deduct_tax": "Deduct",
-				"rate": 10,
-				"row_id": 7
-			},
-		]
\ No newline at end of file
+	
+test_records = [
+	[
+		# parent
+		{
+			"doctype": "Purchase Invoice",
+			"naming_series": "BILL",
+			"supplier_name": "_Test Supplier",
+			"credit_to": "_Test Supplier - _TC",
+			"bill_no": "NA",
+			"posting_date": "2013-02-03",
+			"fiscal_year": "_Test Fiscal Year 2013",
+			"company": "_Test Company",
+			"currency": "INR",
+			"conversion_rate": 1,
+			"grand_total_import": 0 # for feed
+		},
+		# items
+		{
+			"doctype": "Purchase Invoice Item",
+			"parentfield": "entries",
+			"item_code": "_Test Item Home Desktop 100",
+			"item_name": "_Test Item Home Desktop 100",
+			"qty": 10,
+			"import_rate": 50,
+			"import_amount": 500,
+			"rate": 50,
+			"amount": 500,
+			"uom": "_Test UOM",
+			"item_tax_rate": json.dumps({"_Test Account Excise Duty - _TC": 10}),
+			"expense_head": "_Test Account Cost for Goods Sold - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"conversion_factor": 1.0,
+		
+		},
+		{
+			"doctype": "Purchase Invoice Item",
+			"parentfield": "entries",
+			"item_code": "_Test Item Home Desktop 200",
+			"item_name": "_Test Item Home Desktop 200",
+			"qty": 5,
+			"import_rate": 150,
+			"import_amount": 750,
+			"rate": 150,
+			"amount": 750,
+			"uom": "_Test UOM",
+			"expense_head": "_Test Account Cost for Goods Sold - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"conversion_factor": 1.0,
+		},
+		# taxes
+		{
+			"doctype": "Purchase Taxes and Charges",
+			"parentfield": "purchase_tax_details",
+			"charge_type": "Actual",
+			"account_head": "_Test Account Shipping Charges - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Shipping Charges",
+			"category": "Valuation and Total",
+			"add_deduct_tax": "Add",
+			"rate": 100
+		},
+		{
+			"doctype": "Purchase Taxes and Charges",
+			"parentfield": "purchase_tax_details",
+			"charge_type": "On Net Total",
+			"account_head": "_Test Account Customs Duty - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Customs Duty",
+			"category": "Valuation",
+			"add_deduct_tax": "Add",
+			"rate": 10
+		},
+		{
+			"doctype": "Purchase Taxes and Charges",
+			"parentfield": "purchase_tax_details",
+			"charge_type": "On Net Total",
+			"account_head": "_Test Account Excise Duty - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Excise Duty",
+			"category": "Total",
+			"add_deduct_tax": "Add",
+			"rate": 12
+		},
+		{
+			"doctype": "Purchase Taxes and Charges",
+			"parentfield": "purchase_tax_details",
+			"charge_type": "On Previous Row Amount",
+			"account_head": "_Test Account Education Cess - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Education Cess",
+			"category": "Total",
+			"add_deduct_tax": "Add",
+			"rate": 2,
+			"row_id": 3
+		},
+		{
+			"doctype": "Purchase Taxes and Charges",
+			"parentfield": "purchase_tax_details",
+			"charge_type": "On Previous Row Amount",
+			"account_head": "_Test Account S&H Education Cess - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "S&H Education Cess",
+			"category": "Total",
+			"add_deduct_tax": "Add",
+			"rate": 1,
+			"row_id": 3
+		},
+		{
+			"doctype": "Purchase Taxes and Charges",
+			"parentfield": "purchase_tax_details",
+			"charge_type": "On Previous Row Total",
+			"account_head": "_Test Account CST - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "CST",
+			"category": "Total",
+			"add_deduct_tax": "Add",
+			"rate": 2,
+			"row_id": 5
+		},
+		{
+			"doctype": "Purchase Taxes and Charges",
+			"parentfield": "purchase_tax_details",
+			"charge_type": "On Net Total",
+			"account_head": "_Test Account VAT - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "VAT",
+			"category": "Total",
+			"add_deduct_tax": "Add",
+			"rate": 12.5
+		},
+		{
+			"doctype": "Purchase Taxes and Charges",
+			"parentfield": "purchase_tax_details",
+			"charge_type": "On Previous Row Total",
+			"account_head": "_Test Account Discount - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Discount",
+			"category": "Total",
+			"add_deduct_tax": "Deduct",
+			"rate": 10,
+			"row_id": 7
+		},
+	],
+	[
+		# parent
+		{
+			"doctype": "Purchase Invoice",
+			"supplier_name": "_Test Supplier",
+			"credit_to": "_Test Supplier - _TC",
+			"bill_no": "NA",
+			"posting_date": "2013-02-03",
+			"fiscal_year": "_Test Fiscal Year 2013",
+			"company": "_Test Company",
+			"currency": "INR",
+			"conversion_rate": 1.0,
+			"grand_total_import": 0 # for feed
+		},
+		# items
+		{
+			"doctype": "Purchase Invoice Item",
+			"parentfield": "entries",
+			"item_code": "_Test Item",
+			"item_name": "_Test Item",
+			"qty": 10.0,
+			"import_rate": 50.0,
+			"uom": "_Test UOM",
+			"expense_head": "_Test Account Cost for Goods Sold - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"conversion_factor": 1.0,
+		},
+		# taxes
+		{
+			"doctype": "Purchase Taxes and Charges",
+			"parentfield": "purchase_tax_details",
+			"charge_type": "Actual",
+			"account_head": "_Test Account Shipping Charges - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Shipping Charges",
+			"category": "Valuation and Total",
+			"add_deduct_tax": "Add",
+			"rate": 100.0
+		},
+		{
+			"doctype": "Purchase Taxes and Charges",
+			"parentfield": "purchase_tax_details",
+			"charge_type": "Actual",
+			"account_head": "_Test Account VAT - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "VAT",
+			"category": "Total",
+			"add_deduct_tax": "Add",
+			"rate": 120.0
+		},
+		{
+			"doctype": "Purchase Taxes and Charges",
+			"parentfield": "purchase_tax_details",
+			"charge_type": "Actual",
+			"account_head": "_Test Account Customs Duty - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Customs Duty",
+			"category": "Valuation",
+			"add_deduct_tax": "Add",
+			"rate": 150.0
+		},
+	]
+]
\ No newline at end of file
diff --git a/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt b/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
index ecd981d..553041e 100755
--- a/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
+++ b/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-01-29 20:53:00", 
+  "creation": "2013-02-11 10:54:51", 
   "docstatus": 0, 
-  "modified": "2013-02-08 14:06:17", 
+  "modified": "2013-02-27 18:10:04", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -283,6 +283,35 @@
   "width": "150px"
  }, 
  {
+  "doctype": "DocField", 
+  "fieldname": "valuation_rate", 
+  "fieldtype": "Currency", 
+  "hidden": 1, 
+  "label": "Valuation Rate", 
+  "no_copy": 1, 
+  "options": "Company:company:default_currency", 
+  "print_hide": 1, 
+  "read_only": 1
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "conversion_factor", 
+  "fieldtype": "Float", 
+  "label": "Conversion Factor", 
+  "print_hide": 1
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "rm_supp_cost", 
+  "fieldtype": "Currency", 
+  "hidden": 1, 
+  "label": "Raw Materials Supplied Cost", 
+  "no_copy": 1, 
+  "options": "Company:company:default_currency", 
+  "print_hide": 1, 
+  "read_only": 1
+ }, 
+ {
   "allow_on_submit": 1, 
   "doctype": "DocField", 
   "fieldname": "page_break", 
diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py
index 47a0138..aa52b5e 100644
--- a/controllers/accounts_controller.py
+++ b/controllers/accounts_controller.py
@@ -86,4 +86,11 @@
 				from `tabItem` where name in (%s) and is_stock_item='Yes'""" % \
 				(", ".join((["%s"]*len(item_codes))),), item_codes)]
 
-		return self._stock_items
\ No newline at end of file
+		return self._stock_items
+		
+	@property
+	def company_abbr(self):
+		if not hasattr(self, "_abbr"):
+			self._abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
+			
+		return self._abbr
\ No newline at end of file
diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py
index bbcd492..c49bf2a 100644
--- a/controllers/buying_controller.py
+++ b/controllers/buying_controller.py
@@ -232,7 +232,7 @@
 		else:
 			self.doc.grand_total = flt(self.doc.net_total,
 				self.precision.main.grand_total)
-			self.doc.grand_total_print = flt(
+			self.doc.grand_total_import = flt(
 				self.doc.grand_total / self.doc.conversion_rate,
 				self.precision.main.grand_total_import)
 
@@ -250,7 +250,9 @@
 		if self.doc.doctype == "Purchase Invoice" and self.doc.docstatus == 0:
 			self.doc.total_advance = flt(self.doc.total_advance,
 				self.precision.main.total_advance)
-			self.doc.outstanding_amount = flt(self.doc.grand_total - self.doc.total_advance,
+			self.doc.total_amount_to_pay = flt(self.doc.grand_total - flt(self.doc.write_off_amount,
+				self.precision.main.write_off_amount), self.precision.main.total_amount_to_pay)
+			self.doc.outstanding_amount = flt(self.doc.total_amount_to_pay - self.doc.total_advance,
 				self.precision.main.outstanding_amount)
 			
 	def _cleanup(self):
@@ -325,6 +327,16 @@
 				item.item_code in self.stock_items:
 			item.item_tax_amount += flt(current_tax_amount,
 				self.precision.item.item_tax_amount)
+				
+	# update valuation rate
+	def update_valuation_rate(self, parentfield):
+		for d in self.doclist.get({"parentfield": parentfield}):
+			if d.qty:
+				d.valuation_rate = (flt(d.purchase_rate or d.rate)
+					+ (flt(d.item_tax_amount) + flt(d.rm_supp_cost)) / flt(d.qty)
+					) / flt(d.conversion_factor)
+			else:
+				d.valuation_rate = 0.0
 	
 	@property
 	def precision(self):
@@ -336,3 +348,25 @@
 				self._precision.tax = self.meta.get_precision_map(parentfield = \
 					"purchase_tax_details")
 		return self._precision
+
+	@property
+	def sub_contracted_items(self):
+		if not hasattr(self, "_sub_contracted_items"):
+			item_codes = list(set(item.item_code for item in 
+				self.doclist.get({"parentfield": self.fname})))
+			self._sub_contracted_items = [r[0] for r in webnotes.conn.sql("""select name
+				from `tabItem` where name in (%s) and is_sub_contracted_item='Yes'""" % \
+				(", ".join((["%s"]*len(item_codes))),), item_codes)]
+
+		return self._sub_contracted_items
+		
+	@property
+	def purchase_items(self):
+		if not hasattr(self, "_purchase_items"):
+			item_codes = list(set(item.item_code for item in 
+				self.doclist.get({"parentfield": self.fname})))
+			self._purchase_items = [r[0] for r in webnotes.conn.sql("""select name
+				from `tabItem` where name in (%s) and is_purchase_item='Yes'""" % \
+				(", ".join((["%s"]*len(item_codes))),), item_codes)]
+
+		return self._purchase_items
diff --git a/home/page/latest_updates/latest_updates.js b/home/page/latest_updates/latest_updates.js
index 79bd8aa..a2ea8ca 100644
--- a/home/page/latest_updates/latest_updates.js
+++ b/home/page/latest_updates/latest_updates.js
@@ -1,8 +1,14 @@
 erpnext.updates = [
+	["27th February", [
+		"Time Log: Created Time Log System, with Calendar View."
+	]],
 	["26th February", [
 		"Gross Profit: The report has been rewritten and now it is under Accounts module"
-	]
-	],
+	]],
+	["25th February", [
+		"Employee Leave Balance: New Report",
+		"Scripted Reports: Ability to create reports via Script",
+	]],
 	["21st February, 2013", [
 		"Item: Warehouse-wise Re-order Level and Quantity",
 		"Buying: Purchase Request renamed to Material Request"
diff --git a/hr/doctype/leave_allocation/leave_allocation.py b/hr/doctype/leave_allocation/leave_allocation.py
index 870a040..d2d940f 100755
--- a/hr/doctype/leave_allocation/leave_allocation.py
+++ b/hr/doctype/leave_allocation/leave_allocation.py
@@ -103,8 +103,10 @@
 	def get_carry_forwarded_leaves(self):
 		if self.doc.carry_forward:
 			self.allow_carry_forward()
-		prev_fiscal_year = sql("""select name from `tabFiscal Year`
-			where name < %s order by name desc limit 1""", self.doc.fiscal_year)
+		prev_fiscal_year = webnotes.conn.sql("""select name from `tabFiscal Year` 
+			where year_start_date = (select date_add(year_start_date, interval -1 year) 
+				from `tabFiscal Year` where name=%s) 
+			order by name desc limit 1""", self.doc.fiscal_year)
 		prev_fiscal_year = prev_fiscal_year and prev_fiscal_year[0][0] or ''
 		prev_bal = 0
 		if prev_fiscal_year and cint(self.doc.carry_forward) == 1:
diff --git a/hr/doctype/leave_application/leave_application.py b/hr/doctype/leave_application/leave_application.py
index 8117718..313f27f 100755
--- a/hr/doctype/leave_application/leave_application.py
+++ b/hr/doctype/leave_application/leave_application.py
@@ -236,14 +236,11 @@
 	match_conditions = build_match_conditions("Leave Application")
 	
 	# show department leaves for employee
-	show_department_leaves = match_conditions and \
-		len(match_conditions.split("or"))==1 and "employee" in match_conditions
-	
-	if show_department_leaves:
+	if "Employee" in webnotes.get_roles():
 		add_department_leaves(events, start, end, employee, company)
-	else:
-		add_leaves(events, start, end, employee, company, match_conditions)
-		
+
+	add_leaves(events, start, end, employee, company, match_conditions)
+	
 	add_block_dates(events, start, end, employee, company)
 	add_holidays(events, start, end, employee, company)
 	
@@ -273,7 +270,7 @@
 		query += " and " + match_conditions
 	
 	for d in webnotes.conn.sql(query, (start, end, start, end), as_dict=True):
-		events.append({
+		e = {
 			"name": d.name,
 			"doctype": "Leave Application",
 			"from_date": d.from_date,
@@ -282,7 +279,9 @@
 			"title": _("Leave by") + " " +  cstr(d.employee_name) + \
 				(d.half_day and _(" (Half Day)") or ""),
 			"docstatus": d.docstatus
-		})
+		}
+		if e not in events:
+			events.append(e)
 
 def add_block_dates(events, start, end, employee, company):
 	# block days
diff --git a/hr/report/employee_leave_balance/employee_leave_balance.js b/hr/report/employee_leave_balance/employee_leave_balance.js
index 9f63e04..d19b48f 100644
--- a/hr/report/employee_leave_balance/employee_leave_balance.js
+++ b/hr/report/employee_leave_balance/employee_leave_balance.js
@@ -6,6 +6,13 @@
 			"fieldtype": "Link",
 			"options": "Fiscal Year",
 			"default": wn.defaults.get_user_default("fiscal_year")
+		},
+		{
+			"fieldname":"company",
+			"label": "Company",
+			"fieldtype": "Link",
+			"options": "Company",
+			"default": wn.defaults.get_user_default("company")
 		}
 	]
 }
\ No newline at end of file
diff --git a/hr/report/employee_leave_balance/employee_leave_balance.py b/hr/report/employee_leave_balance/employee_leave_balance.py
index d7ad472..6d34c8a 100644
--- a/hr/report/employee_leave_balance/employee_leave_balance.py
+++ b/hr/report/employee_leave_balance/employee_leave_balance.py
@@ -4,17 +4,19 @@
 
 def execute(filters=None):
 	if not filters: filters = {}
-	employees = runreport(doctype="Employee", fields=["name", "employee_name", "department"])
+	
+	employee_filters = filters.get("company") and \
+		[["Employee", "company", "=", filters.get("company")]] or None
+	employees = runreport(doctype="Employee", fields=["name", "employee_name", "department"],
+		filters=employee_filters)
 	leave_types = webnotes.conn.sql_list("select name from `tabLeave Type`")
 	
 	if filters.get("fiscal_year"):
 		fiscal_years = [filters["fiscal_year"]]
 	else:
 		fiscal_years = webnotes.conn.sql_list("select name from `tabFiscal Year` order by name desc")
-
-	employee_in = '", "'.join([e.name for e in employees])
-	
 		
+	employee_in = '", "'.join([e.name for e in employees])
 	
 	allocations = webnotes.conn.sql("""select employee, fiscal_year, leave_type, total_leaves_allocated
 	 	from `tabLeave Allocation` 
diff --git a/manufacturing/doctype/bom/test_bom.py b/manufacturing/doctype/bom/test_bom.py
index 68d9ce8..e742c0c 100644
--- a/manufacturing/doctype/bom/test_bom.py
+++ b/manufacturing/doctype/bom/test_bom.py
@@ -18,130 +18,164 @@
 from __future__ import unicode_literals
 import unittest
 import webnotes
-import webnotes.model
-from webnotes.utils import nowdate, flt
-from accounts.utils import get_fiscal_year
-from webnotes.model.doclist import DocList
-import copy
 
-company = webnotes.conn.get_default("company")
-
-
-def load_data():
-	
-	# create default warehouse
-	if not webnotes.conn.exists("Warehouse", "Default Warehouse"):
-		webnotes.insert({"doctype": "Warehouse", 
-			"warehouse_name": "Default Warehouse",
-			"warehouse_type": "Stores"})
-			
-	# create UOM: Nos.
-	if not webnotes.conn.exists("UOM", "Nos"):
-		webnotes.insert({"doctype": "UOM", "uom_name": "Nos"})
-	
-	from webnotes.tests import insert_test_data
-	# create item groups and items
-	insert_test_data("Item Group", 
-		sort_fn=lambda ig: (ig[0].get('parent_item_group'), ig[0].get('name')))
-	insert_test_data("Item")
-
-base_bom_fg = [
-	{"doctype": "BOM", "item": "Android Jack D", "quantity": 1,
-		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
-	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
-		"opn_description": "Development", "hour_rate": 10, "time_in_mins": 90}, 
-	{"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1, 
-		"qty": 2, "rate": 20, "stock_uom": "Nos", "parentfield": "bom_materials"},
-	{"doctype": "BOM Item", "item_code": "Home Desktop 100", "operation_no": 1, 
-		"qty": 1, "rate": 300, "stock_uom": "Nos", "parentfield": "bom_materials"},
-	{"doctype": "BOM Item", "item_code": "Nebula 7", "operation_no": 1, 
-			"qty": 5, "stock_uom": "Nos", "parentfield": "bom_materials"},
-]
-
-base_bom_child = [
-	{"doctype": "BOM", "item": "Nebula 7", "quantity": 5,
-		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
-	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
-		"opn_description": "Development"}, 
-	{"doctype": "BOM Item", "item_code": "Android Jack S", "operation_no": 1, 
-		"qty": 10, "stock_uom": "Nos", "parentfield": "bom_materials"}
-]
-	
-base_bom_grandchild = [
-	{"doctype": "BOM", "item": "Android Jack S", "quantity": 1,
-		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
-	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
-		"opn_description": "Development"}, 
-	{"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1, 
-		"qty": 3, "rate": 10, "stock_uom": "Nos", 	"parentfield": "bom_materials"}
-]
-
-
-class TestPurchaseReceipt(unittest.TestCase):
-	def setUp(self):
-		webnotes.conn.begin()
-		load_data()
-		
-	def test_bom_validation(self):
-		# show throw error bacause bom no missing for sub-assembly item
-		bom_fg = copy.deepcopy(base_bom_fg)
-		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
-
-		# main item is not a manufacturing item
-		bom_fg = copy.deepcopy(base_bom_fg)
-		bom_fg[0]["item"] = "Home Desktop 200"
-		bom_fg.pop(4)
-		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
-		
-		# operation no mentioed in material table not matching with operation table
-		bom_fg = copy.deepcopy(base_bom_fg)
-		bom_fg.pop(4)
-		bom_fg[2]["operation_no"] = 2
-		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
-		
-	
-	def test_bom(self):
-		gc_wrapper = webnotes.insert(DocList(base_bom_grandchild))
-		gc_wrapper.submit()
-		
-		bom_child = copy.deepcopy(base_bom_child)
-		bom_child[2]["bom_no"] = gc_wrapper.doc.name
-		child_wrapper = webnotes.insert(DocList(bom_child))
-		child_wrapper.submit()
-		
-		bom_fg = copy.deepcopy(base_bom_fg)
-		bom_fg[4]["bom_no"] = child_wrapper.doc.name
-		fg_wrapper = webnotes.insert(DocList(bom_fg))
-		fg_wrapper.load_from_db()
-		
-		self.check_bom_cost(fg_wrapper)
-		
-		self.check_flat_bom(fg_wrapper, child_wrapper, gc_wrapper)
-		
-	def check_bom_cost(self, fg_wrapper):
-		expected_values = {
-			"operating_cost": 15,
-			"raw_material_cost": 640,
-			"total_cost": 655
+test_records = [
+	[
+		{
+			"doctype": "BOM", 
+			"item": "_Test FG Item", 
+			"quantity": 1.0,
+			"is_active": 1,
+			"is_default": 1,
+			"docstatus": 1
+		}, 
+		{
+			"doctype": "BOM Item", 
+			"item_code": "_Test Item", 
+			"parentfield": "bom_materials", 
+			"qty": 1.0, 
+			"rate": 5000.0, 
+			"amount": 5000.0, 
+			"stock_uom": "No."
+		}, 
+		{
+			"doctype": "BOM Item", 
+			"item_code": "_Test Item Home Desktop 100", 
+			"parentfield": "bom_materials", 
+			"qty": 2.0, 
+			"rate": 1000.0,
+			"amount": 2000.0,
+			"stock_uom": "No."
 		}
+	]
+]
 
-		for key in expected_values:
-			self.assertEqual(flt(expected_values[key]), flt(fg_wrapper.doc.fields.get(key)))
-			
-	def check_flat_bom(self, fg_wrapper, child_wrapper, gc_wrapper):
-		expected_flat_bom_items = {
-			("Home Desktop 300", fg_wrapper.doc.name): (2, 20),
-			("Home Desktop 100", fg_wrapper.doc.name): (1, 300),
-			("Home Desktop 300", gc_wrapper.doc.name): (30, 10)
-		}
-		
-		self.assertEqual(len(fg_wrapper.doclist.get({"parentfield": "flat_bom_details"})), 3)
-		
-		for key, val in expected_flat_bom_items.items():
-			flat_bom = fg_wrapper.doclist.get({"parentfield": "flat_bom_details", 
-				"item_code": key[0], "parent_bom": key[1]})[0]
-			self.assertEqual(val, (flat_bom.qty, flat_bom.rate))
-		
-		
-	def tearDown(self):
-		webnotes.conn.rollback()
\ No newline at end of file
+
+
+# import webnotes.model
+# from webnotes.utils import nowdate, flt
+# from accounts.utils import get_fiscal_year
+# from webnotes.model.doclist import DocList
+# import copy
+# 
+# company = webnotes.conn.get_default("company")
+# 
+# 
+# def load_data():
+# 	
+# 	# create default warehouse
+# 	if not webnotes.conn.exists("Warehouse", "Default Warehouse"):
+# 		webnotes.insert({"doctype": "Warehouse", 
+# 			"warehouse_name": "Default Warehouse",
+# 			"warehouse_type": "Stores"})
+# 			
+# 	# create UOM: Nos.
+# 	if not webnotes.conn.exists("UOM", "Nos"):
+# 		webnotes.insert({"doctype": "UOM", "uom_name": "Nos"})
+# 	
+# 	from webnotes.tests import insert_test_data
+# 	# create item groups and items
+# 	insert_test_data("Item Group", 
+# 		sort_fn=lambda ig: (ig[0].get('parent_item_group'), ig[0].get('name')))
+# 	insert_test_data("Item")
+# 
+# base_bom_fg = [
+# 	{"doctype": "BOM", "item": "Android Jack D", "quantity": 1,
+# 		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
+# 	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
+# 		"opn_description": "Development", "hour_rate": 10, "time_in_mins": 90}, 
+# 	{"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1, 
+# 		"qty": 2, "rate": 20, "stock_uom": "Nos", "parentfield": "bom_materials"},
+# 	{"doctype": "BOM Item", "item_code": "Home Desktop 100", "operation_no": 1, 
+# 		"qty": 1, "rate": 300, "stock_uom": "Nos", "parentfield": "bom_materials"},
+# 	{"doctype": "BOM Item", "item_code": "Nebula 7", "operation_no": 1, 
+# 			"qty": 5, "stock_uom": "Nos", "parentfield": "bom_materials"},
+# ]
+# 
+# base_bom_child = [
+# 	{"doctype": "BOM", "item": "Nebula 7", "quantity": 5,
+# 		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
+# 	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
+# 		"opn_description": "Development"}, 
+# 	{"doctype": "BOM Item", "item_code": "Android Jack S", "operation_no": 1, 
+# 		"qty": 10, "stock_uom": "Nos", "parentfield": "bom_materials"}
+# ]
+# 	
+# base_bom_grandchild = [
+# 	{"doctype": "BOM", "item": "Android Jack S", "quantity": 1,
+# 		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
+# 	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
+# 		"opn_description": "Development"}, 
+# 	{"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1, 
+# 		"qty": 3, "rate": 10, "stock_uom": "Nos", 	"parentfield": "bom_materials"}
+# ]
+# 
+# 
+# class TestPurchaseReceipt(unittest.TestCase):
+# 	def setUp(self):
+# 		webnotes.conn.begin()
+# 		load_data()
+# 		
+# 	def test_bom_validation(self):
+# 		# show throw error bacause bom no missing for sub-assembly item
+# 		bom_fg = copy.deepcopy(base_bom_fg)
+# 		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
+# 
+# 		# main item is not a manufacturing item
+# 		bom_fg = copy.deepcopy(base_bom_fg)
+# 		bom_fg[0]["item"] = "Home Desktop 200"
+# 		bom_fg.pop(4)
+# 		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
+# 		
+# 		# operation no mentioed in material table not matching with operation table
+# 		bom_fg = copy.deepcopy(base_bom_fg)
+# 		bom_fg.pop(4)
+# 		bom_fg[2]["operation_no"] = 2
+# 		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
+# 		
+# 	
+# 	def test_bom(self):
+# 		gc_wrapper = webnotes.insert(DocList(base_bom_grandchild))
+# 		gc_wrapper.submit()
+# 		
+# 		bom_child = copy.deepcopy(base_bom_child)
+# 		bom_child[2]["bom_no"] = gc_wrapper.doc.name
+# 		child_wrapper = webnotes.insert(DocList(bom_child))
+# 		child_wrapper.submit()
+# 		
+# 		bom_fg = copy.deepcopy(base_bom_fg)
+# 		bom_fg[4]["bom_no"] = child_wrapper.doc.name
+# 		fg_wrapper = webnotes.insert(DocList(bom_fg))
+# 		fg_wrapper.load_from_db()
+# 		
+# 		self.check_bom_cost(fg_wrapper)
+# 		
+# 		self.check_flat_bom(fg_wrapper, child_wrapper, gc_wrapper)
+# 		
+# 	def check_bom_cost(self, fg_wrapper):
+# 		expected_values = {
+# 			"operating_cost": 15,
+# 			"raw_material_cost": 640,
+# 			"total_cost": 655
+# 		}
+# 
+# 		for key in expected_values:
+# 			self.assertEqual(flt(expected_values[key]), flt(fg_wrapper.doc.fields.get(key)))
+# 			
+# 	def check_flat_bom(self, fg_wrapper, child_wrapper, gc_wrapper):
+# 		expected_flat_bom_items = {
+# 			("Home Desktop 300", fg_wrapper.doc.name): (2, 20),
+# 			("Home Desktop 100", fg_wrapper.doc.name): (1, 300),
+# 			("Home Desktop 300", gc_wrapper.doc.name): (30, 10)
+# 		}
+# 		
+# 		self.assertEqual(len(fg_wrapper.doclist.get({"parentfield": "flat_bom_details"})), 3)
+# 		
+# 		for key, val in expected_flat_bom_items.items():
+# 			flat_bom = fg_wrapper.doclist.get({"parentfield": "flat_bom_details", 
+# 				"item_code": key[0], "parent_bom": key[1]})[0]
+# 			self.assertEqual(val, (flat_bom.qty, flat_bom.rate))
+# 		
+# 		
+# 	def tearDown(self):
+# 		webnotes.conn.rollback()
\ No newline at end of file
diff --git a/patches/patch_list.py b/patches/patch_list.py
index f60b204..1160809 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -199,4 +199,5 @@
 	'execute:webnotes.reload_doc("accounts", "Print Format", "Sales Invoice Classic") # 2013-02-26',
 	'execute:webnotes.reload_doc("accounts", "Print Format", "Sales Invoice Modern") # 2013-02-26',
 	'execute:webnotes.reload_doc("accounts", "Print Format", "Sales Invoice Spartan") # 2013-02-26',
+	"execute:(not webnotes.conn.exists('Role', 'Projects Manager')) and webnotes.doc({'doctype':'Role', 'role_name':'Projects Manager'}).insert()",
 ]
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/_messages_doc.json b/production/doctype/bom_replace_tool/locale/_messages_doc.json
deleted file mode 100644
index d6c8d69..0000000
--- a/production/doctype/bom_replace_tool/locale/_messages_doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-[
- "BOM Replace Tool", 
- "The BOM which will be replaced", 
- "New BOM", 
- "The new BOM after replacement", 
- "Production", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM", 
- "Replace", 
- "Current BOM"
-]
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/ar-doc.json b/production/doctype/bom_replace_tool/locale/ar-doc.json
deleted file mode 100644
index f746131..0000000
--- a/production/doctype/bom_replace_tool/locale/ar-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "BOM Replace Tool": "BOM \u0627\u0633\u062a\u0628\u062f\u0627\u0644 \u0623\u062f\u0627\u0629", 
- "Current BOM": "BOM \u0627\u0644\u062d\u0627\u0644\u064a", 
- "New BOM": "BOM \u062c\u062f\u064a\u062f\u0629", 
- "Production": "\u0627\u0644\u0625\u0646\u062a\u0627\u062c", 
- "Replace": "\u0627\u0633\u062a\u0628\u062f\u0644", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM": "\u0627\u0633\u062a\u0628\u062f\u0627\u0644 BOM \u062e\u0627\u0635\u0629 \u0641\u064a \u062c\u0645\u064a\u0639 BOMs \u0627\u0644\u0623\u062e\u0631\u0649 \u0627\u0644\u062a\u064a \u064a\u0633\u062a\u062e\u062f\u0645 \u0641\u064a\u0647\u0627. \u0648\u0627\u0646\u0647 \u0633\u064a\u062d\u0644 \u0645\u062d\u0644 \u0627\u0644\u0631\u0627\u0628\u0637 BOM \u0627\u0644\u0642\u062f\u064a\u0645\u0629\u060c \u0648\u062a\u062d\u062f\u064a\u062b \u0648\u062a\u062c\u062f\u064a\u062f \u0627\u0644\u062a\u0643\u0644\u0641\u0629 &quot;\u0627\u0644\u0628\u0646\u062f \u0627\u0646\u0641\u062c\u0627\u0631 BOM&quot; \u0627\u0644\u062c\u062f\u0648\u0644 \u0627\u0644\u062c\u062f\u064a\u062f \u0648\u0641\u0642\u0627 BOM", 
- "The BOM which will be replaced": "\u0648BOM \u0627\u0644\u062a\u064a \u0633\u064a\u062a\u0645 \u0627\u0633\u062a\u0628\u062f\u0627\u0644\u0647\u0627", 
- "The new BOM after replacement": "\u0648BOM \u0627\u0644\u062c\u062f\u064a\u062f\u0629 \u0628\u0639\u062f \u0627\u0633\u062a\u0628\u062f\u0627\u0644"
-}
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/es-doc.json b/production/doctype/bom_replace_tool/locale/es-doc.json
deleted file mode 100644
index 9834598..0000000
--- a/production/doctype/bom_replace_tool/locale/es-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "BOM Replace Tool": "BOM Tool Reemplazar", 
- "Current BOM": "BOM actual", 
- "New BOM": "Nueva lista de materiales", 
- "Production": "Producci\u00f3n", 
- "Replace": "Reemplazar", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM": "Reemplazar un BOM particular en todas las listas de materiales de otros en los que se utiliza. Se sustituir\u00e1 el enlace BOM viejo, actualizar el costo y regenerar &quot;Explosi\u00f3n lista de materiales Item&quot; tabla seg\u00fan nueva lista de materiales", 
- "The BOM which will be replaced": "La lista de materiales que ser\u00e1 sustituido", 
- "The new BOM after replacement": "La lista de materiales nuevo despu\u00e9s de sustituirlo"
-}
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/fr-doc.json b/production/doctype/bom_replace_tool/locale/fr-doc.json
deleted file mode 100644
index 9284cad..0000000
--- a/production/doctype/bom_replace_tool/locale/fr-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "BOM Replace Tool": "Outil Remplacer BOM", 
- "Current BOM": "Nomenclature actuelle", 
- "New BOM": "Nouvelle nomenclature", 
- "Production": "Production", 
- "Replace": "Remplacer", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM": "Remplacer une nomenclature particuli\u00e8re dans toutes les nomenclatures d&#39;autres o\u00f9 il est utilis\u00e9. Il remplacera le lien de nomenclature ancienne, mettre \u00e0 jour les co\u00fbts et r\u00e9g\u00e9n\u00e9rer &quot;Explosion de nomenclature article&quot; la table comme pour une nouvelle nomenclature", 
- "The BOM which will be replaced": "La nomenclature qui sera remplac\u00e9", 
- "The new BOM after replacement": "La nouvelle nomenclature apr\u00e8s le remplacement"
-}
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/hi-doc.json b/production/doctype/bom_replace_tool/locale/hi-doc.json
deleted file mode 100644
index 3d9e9b4..0000000
--- a/production/doctype/bom_replace_tool/locale/hi-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "BOM Replace Tool": "\u092c\u0940\u0913\u090f\u092e \u092c\u0926\u0932\u0947\u0902 \u0909\u092a\u0915\u0930\u0923", 
- "Current BOM": "\u0935\u0930\u094d\u0924\u092e\u093e\u0928 \u092c\u0940\u0913\u090f\u092e", 
- "New BOM": "\u0928\u0908 \u092c\u0940\u0913\u090f\u092e", 
- "Production": "\u0909\u0924\u094d\u092a\u093e\u0926\u0928", 
- "Replace": "\u092c\u0926\u0932\u0947\u0902", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM": "\u0905\u0928\u094d\u092f \u0938\u092d\u0940 BOMs \u091c\u0939\u093e\u0902 \u092f\u0939 \u092a\u094d\u0930\u092f\u094b\u0917 \u0915\u093f\u092f\u093e \u091c\u093e\u0924\u093e \u0939\u0948 \u092e\u0947\u0902 \u090f\u0915 \u0935\u093f\u0936\u0947\u0937 \u092c\u0940\u0913\u090f\u092e \u092c\u0926\u0932\u0947\u0902. \u092f\u0939 \u092a\u0941\u0930\u093e\u0928\u0947 \u092c\u0940\u0913\u090f\u092e \u0932\u093f\u0902\u0915 \u0915\u0940 \u091c\u0917\u0939, \u0932\u093e\u0917\u0924 \u0905\u0926\u094d\u092f\u0924\u0928 \u0914\u0930 \u0928\u092f\u093e \u092c\u0940\u0913\u090f\u092e \u0915\u0947 \u0905\u0928\u0941\u0938\u093e\u0930 &quot;BOM \u0927\u092e\u093e\u0915\u093e \u0906\u0907\u091f\u092e&quot; \u0924\u093e\u0932\u093f\u0915\u093e \u092a\u0941\u0928\u0930\u094d\u091c\u0928\u094d\u092e", 
- "The BOM which will be replaced": "\u092c\u0940\u0913\u090f\u092e \u091c\u094b \u092a\u094d\u0930\u0924\u093f\u0938\u094d\u0925\u093e\u092a\u093f\u0924 \u0915\u093f\u092f\u093e \u091c\u093e\u090f\u0917\u093e", 
- "The new BOM after replacement": "\u092c\u0926\u0932\u0928\u0947 \u0915\u0947 \u092c\u093e\u0926 \u0928\u090f \u092c\u0940\u0913\u090f\u092e"
-}
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/hr-doc.json b/production/doctype/bom_replace_tool/locale/hr-doc.json
deleted file mode 100644
index c6ff6b6..0000000
--- a/production/doctype/bom_replace_tool/locale/hr-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "BOM Replace Tool": "BOM Zamijenite alat", 
- "Current BOM": "Trenutni BOM", 
- "New BOM": "Novi BOM", 
- "Production": "Proizvodnja", 
- "Replace": "Zamijeniti", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM": "Zamijenite odre\u0111eni BOM u svim drugim sastavnicama gdje se koriste. To \u0107e zamijeniti staru vezu BOM, a\u017eurirati tro\u0161kove i regenerirati &quot;BOM eksploziju predmeta&quot; stol kao i po novom BOM", 
- "The BOM which will be replaced": "BOM koji \u0107e biti zamijenjen", 
- "The new BOM after replacement": "Novi BOM nakon zamjene"
-}
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/nl-doc.json b/production/doctype/bom_replace_tool/locale/nl-doc.json
deleted file mode 100644
index 26a07e8..0000000
--- a/production/doctype/bom_replace_tool/locale/nl-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "BOM Replace Tool": "BOM Replace Tool", 
- "Current BOM": "Actueel BOM", 
- "New BOM": "Nieuwe BOM", 
- "Production": "Productie", 
- "Replace": "Vervang", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM": "Vervang een bepaalde BOM in alle andere BOMs waar het wordt gebruikt. Deze vervangt de oude BOM link, updaten kosten en regenereren &quot;BOM Explosion Item&quot; tafel als per nieuwe BOM", 
- "The BOM which will be replaced": "De BOM die zal worden vervangen", 
- "The new BOM after replacement": "De nieuwe BOM na vervanging"
-}
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/pt-BR-doc.json b/production/doctype/bom_replace_tool/locale/pt-BR-doc.json
deleted file mode 100644
index 69ebd0f..0000000
--- a/production/doctype/bom_replace_tool/locale/pt-BR-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "BOM Replace Tool": "Ferramenta de Substitui\u00e7\u00e3o da LDM", 
- "Current BOM": "LDM atual", 
- "New BOM": "Nova LDM", 
- "Production": "Produ\u00e7\u00e3o", 
- "Replace": "Substituir", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM": "Substituir uma LDM espec\u00edfica em todas as LDMs outros onde ela \u00e9 usada. Isso ir\u00e1 substituir o link da LDM antiga, atualizar o custo e regenerar a tabela &quot;Item de Explos\u00e3o da LDM&quot; com a nova LDM", 
- "The BOM which will be replaced": "A LDM que ser\u00e1 substitu\u00edda", 
- "The new BOM after replacement": "A nova LDM ap\u00f3s substitui\u00e7\u00e3o"
-}
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/pt-doc.json b/production/doctype/bom_replace_tool/locale/pt-doc.json
deleted file mode 100644
index a189dcd..0000000
--- a/production/doctype/bom_replace_tool/locale/pt-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "BOM Replace Tool": "BOM Ferramenta Substituir", 
- "Current BOM": "BOM atual", 
- "New BOM": "Novo BOM", 
- "Production": "Produ\u00e7\u00e3o", 
- "Replace": "Substituir", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM": "Substituir um BOM particular em todas as BOMs outros onde ele \u00e9 usado. Ele ir\u00e1 substituir o link BOM antigo, atualizar o custo e regenerar &quot;Explos\u00e3o BOM Item&quot; tabela como por novo BOM", 
- "The BOM which will be replaced": "O BOM que ser\u00e1 substitu\u00eddo", 
- "The new BOM after replacement": "O BOM novo ap\u00f3s substitui\u00e7\u00e3o"
-}
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/sr-doc.json b/production/doctype/bom_replace_tool/locale/sr-doc.json
deleted file mode 100644
index 6d0ecb0..0000000
--- a/production/doctype/bom_replace_tool/locale/sr-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "BOM Replace Tool": "\u0411\u041e\u041c \u0417\u0430\u043c\u0435\u043d\u0430 \u0430\u043b\u0430\u0442\u0430", 
- "Current BOM": "\u0422\u0440\u0435\u043d\u0443\u0442\u043d\u0438 \u0411\u041e\u041c", 
- "New BOM": "\u041d\u043e\u0432\u0438 \u0411\u041e\u041c", 
- "Production": "\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u045a\u0430", 
- "Replace": "\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u0438", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM": "\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u0435 \u043f\u043e\u0441\u0435\u0431\u043d\u0443 \u0431\u043e\u043c \u0443 \u0441\u0432\u0438\u043c \u043e\u0441\u0442\u0430\u043b\u0438\u043c \u0411\u041e\u041c\u0441 \u0433\u0434\u0435 \u0441\u0435 \u043e\u043d \u043a\u043e\u0440\u0438\u0441\u0442\u0438. \u041e\u043d\u0430 \u045b\u0435 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u0438 \u0441\u0442\u0430\u0440\u0443 \u0432\u0435\u0437\u0443 \u0431\u043e\u043c, \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045a\u0435 \u0442\u0440\u043e\u0448\u043a\u043e\u0432\u0435 \u0438 \u0440\u0435\u0433\u0435\u043d\u0435\u0440\u0438\u0448\u0443 &quot;\u0431\u043e\u043c \u0435\u043a\u0441\u043f\u043b\u043e\u0437\u0438\u0458\u0435 \u0458\u0435\u0434\u0438\u043d\u0438\u0446\u0435&quot; \u0442\u0430\u0431\u0435\u043b\u0443 \u043f\u043e \u043d\u043e\u0432\u043e\u043c \u0411\u041e\u041c", 
- "The BOM which will be replaced": "\u0411\u041e\u041c \u043a\u043e\u0458\u0438 \u045b\u0435 \u0431\u0438\u0442\u0438 \u0437\u0430\u043c\u0435\u045a\u0435\u043d", 
- "The new BOM after replacement": "\u041d\u043e\u0432\u0438 \u0411\u041e\u041c \u043d\u0430\u043a\u043e\u043d \u0437\u0430\u043c\u0435\u043d\u0435"
-}
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/ta-doc.json b/production/doctype/bom_replace_tool/locale/ta-doc.json
deleted file mode 100644
index c2e816d..0000000
--- a/production/doctype/bom_replace_tool/locale/ta-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "BOM Replace Tool": "BOM \u0baa\u0ba4\u0bbf\u0bb2\u0bbe\u0b95 \u0b95\u0bb0\u0bc1\u0bb5\u0bbf", 
- "Current BOM": "\u0ba4\u0bb1\u0bcd\u0baa\u0bc7\u0bbe\u0ba4\u0bc8\u0baf BOM", 
- "New BOM": "\u0baa\u0bc1\u0ba4\u0bbf\u0baf BOM", 
- "Production": "\u0b89\u0bb1\u0bcd\u0baa\u0ba4\u0bcd\u0ba4\u0bbf", 
- "Replace": "\u0baa\u0ba4\u0bbf\u0bb2\u0bbe\u0b95", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM": "\u0b87\u0ba4\u0bc1 \u0baa\u0baf\u0ba9\u0bcd\u0baa\u0b9f\u0bc1\u0ba4\u0bcd\u0ba4\u0baa\u0bcd\u0baa\u0b9f\u0bc1\u0b95\u0bbf\u0bb1\u0ba4\u0bc1 \u0b85\u0bae\u0bc8\u0ba8\u0bcd\u0ba4\u0bc1\u0bb3\u0bcd\u0bb3 \u0b85\u0ba9\u0bc8\u0ba4\u0bcd\u0ba4\u0bc1 \u0bae\u0bb1\u0bcd\u0bb1 BOM \u0b95\u0bb3\u0bcd \u0b92\u0bb0\u0bc1 \u0b95\u0bc1\u0bb1\u0bbf\u0baa\u0bcd\u0baa\u0bbf\u0b9f\u0bcd\u0b9f BOM \u0baa\u0ba4\u0bbf\u0bb2\u0bbe\u0b95. \u0b87\u0ba4\u0bc1, \u0baa\u0bb4\u0bc8\u0baf BOM \u0b87\u0ba3\u0bc8\u0baa\u0bcd\u0baa\u0bc1 \u0baa\u0ba4\u0bbf\u0bb2\u0bbe\u0b95 \u0b9a\u0bc6\u0bb2\u0bb5\u0bc1 \u0baa\u0bc1\u0ba4\u0bc1\u0baa\u0bcd\u0baa\u0bbf\u0b95\u0bcd\u0b95 \u0baa\u0bc1\u0ba4\u0bbf\u0baf BOM \u0baa\u0b9f\u0bbf &quot;BOM \u0bb5\u0bc6\u0b9f\u0bbf\u0baa\u0bcd\u0baa\u0bc1 \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0bb3\u0bcd&quot; \u0b85\u0b9f\u0bcd\u0b9f\u0bb5\u0ba3\u0bc8 \u0bae\u0bb1\u0bc1\u0b89\u0bb1\u0bcd\u0baa\u0ba4\u0bcd\u0ba4\u0bbf", 
- "The BOM which will be replaced": "\u0baa\u0ba4\u0bbf\u0bb2\u0bc0\u0b9f\u0bc1 \u0b9a\u0bc6\u0baf\u0bcd\u0baf\u0baa\u0bcd\u0baa\u0b9f\u0bc1\u0bae\u0bcd BOM", 
- "The new BOM after replacement": "\u0bae\u0bbe\u0bb1\u0bcd\u0bb1\u0bc1 \u0baa\u0bbf\u0ba9\u0bcd\u0ba9\u0bb0\u0bcd \u0baa\u0bc1\u0ba4\u0bbf\u0baf BOM"
-}
\ No newline at end of file
diff --git a/production/doctype/bom_replace_tool/locale/th-doc.json b/production/doctype/bom_replace_tool/locale/th-doc.json
deleted file mode 100644
index c699223..0000000
--- a/production/doctype/bom_replace_tool/locale/th-doc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "BOM Replace Tool": "\u0e40\u0e04\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e21\u0e37\u0e2d\u0e41\u0e17\u0e19\u0e17\u0e35\u0e48 BOM", 
- "Current BOM": "BOM \u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19", 
- "New BOM": "BOM \u0e43\u0e2b\u0e21\u0e48", 
- "Production": "\u0e01\u0e32\u0e23\u0e1c\u0e25\u0e34\u0e15", 
- "Replace": "\u0e41\u0e17\u0e19\u0e17\u0e35\u0e48", 
- "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM": "\u0e41\u0e17\u0e19\u0e17\u0e35\u0e48 BOM \u0e42\u0e14\u0e22\u0e40\u0e09\u0e1e\u0e32\u0e30\u0e43\u0e19 BOMs \u0e2d\u0e37\u0e48\u0e19 \u0e46 \u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\u0e17\u0e35\u0e48\u0e16\u0e39\u0e01\u0e19\u0e33\u0e21\u0e32\u0e43\u0e0a\u0e49 \u0e21\u0e31\u0e19\u0e08\u0e30\u0e40\u0e02\u0e49\u0e32\u0e21\u0e32\u0e41\u0e17\u0e19\u0e17\u0e35\u0e48\u0e01\u0e32\u0e23\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e42\u0e22\u0e07 BOM \u0e40\u0e01\u0e48\u0e32\u0e1b\u0e23\u0e31\u0e1a\u0e1b\u0e23\u0e38\u0e07\u0e04\u0e48\u0e32\u0e43\u0e0a\u0e49\u0e08\u0e48\u0e32\u0e22\u0e41\u0e25\u0e30\u0e43\u0e2b\u0e49\u0e0a\u0e35\u0e27\u0e34\u0e15\u0e43\u0e2b\u0e21\u0e48 &quot;\u0e23\u0e30\u0e40\u0e1a\u0e34\u0e14\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23 BOM&quot; \u0e15\u0e32\u0e23\u0e32\u0e07\u0e40\u0e1b\u0e47\u0e19\u0e15\u0e48\u0e2d\u0e43\u0e2b\u0e21\u0e48 BOM", 
- "The BOM which will be replaced": "BOM \u0e0b\u0e36\u0e48\u0e07\u0e08\u0e30\u0e16\u0e39\u0e01\u0e41\u0e17\u0e19\u0e17\u0e35\u0e48", 
- "The new BOM after replacement": "BOM \u0e43\u0e2b\u0e21\u0e48\u0e2b\u0e25\u0e31\u0e07\u0e08\u0e32\u0e01\u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19"
-}
\ No newline at end of file
diff --git a/projects/doctype/time_log/__init__.py b/projects/doctype/time_log/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/projects/doctype/time_log/__init__.py
diff --git a/projects/doctype/time_log/time_log.py b/projects/doctype/time_log/time_log.py
new file mode 100644
index 0000000..4188503
--- /dev/null
+++ b/projects/doctype/time_log/time_log.py
@@ -0,0 +1,45 @@
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import webnotes
+from webnotes import _
+
+from webnotes.widgets.reportview import build_match_conditions
+
+class DocType:
+	def __init__(self, d, dl):
+		self.doc, self.doclist = d, dl
+		
+	def validate(self):
+		self.validate_overlap()
+		
+	def validate_overlap(self):
+		existing = webnotes.conn.sql_list("""select name from `tabTime Log` where owner=%s and
+			((from_time between %s and %s) or (to_time between %s and %s)) and name!=%s""", 
+			(self.doc.owner, self.doc.from_time, self.doc.to_time, self.doc.from_time, 
+				self.doc.to_time, self.doc.name))
+
+		if existing:
+			webnotes.msgprint(_("This Time Log conflicts with") + ":" + ', '.join(existing),
+				raise_exception=True)
+		
+@webnotes.whitelist()
+def get_events(start, end):
+	match = build_match_conditions("Time Log")
+	data = webnotes.conn.sql("""select name, from_time, to_time, 
+		activity_type, task, project from `tabTime Log`
+		where from_time between '%(start)s' and '%(end)s' or to_time between '%(start)s' and '%(end)s'
+		%(match)s""" % {
+			"start": start,
+			"end": end,
+			"match": match and (" and " + match) or ""
+		}, as_dict=True, update={"allDay": 0})
+		
+	for d in data:
+		d.title = d.name + ": " + d.activity_type
+		if d.task:
+			d.title += " for Task: " + d.task
+		if d.project:
+			d.title += " for Project: " + d.project
+			
+	return data
diff --git a/projects/doctype/time_log/time_log.txt b/projects/doctype/time_log/time_log.txt
new file mode 100644
index 0000000..b8e927a
--- /dev/null
+++ b/projects/doctype/time_log/time_log.txt
@@ -0,0 +1,121 @@
+[
+ {
+  "creation": "2013-02-26 14:58:28", 
+  "docstatus": 0, 
+  "modified": "2013-02-26 16:09:53", 
+  "modified_by": "Administrator", 
+  "owner": "Administrator"
+ }, 
+ {
+  "autoname": "TL-.######", 
+  "description": "Log of Activities performed by users against Tasks that can be used for tracking time, billing.", 
+  "doctype": "DocType", 
+  "document_type": "Master", 
+  "module": "Projects", 
+  "name": "__common__"
+ }, 
+ {
+  "doctype": "DocField", 
+  "name": "__common__", 
+  "parent": "Time Log", 
+  "parentfield": "fields", 
+  "parenttype": "DocType", 
+  "permlevel": 0
+ }, 
+ {
+  "doctype": "DocPerm", 
+  "name": "__common__", 
+  "parent": "Time Log", 
+  "parentfield": "permissions", 
+  "parenttype": "DocType", 
+  "permlevel": 0, 
+  "read": 1, 
+  "write": 1
+ }, 
+ {
+  "doctype": "DocType", 
+  "name": "Time Log"
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "from_time", 
+  "fieldtype": "Datetime", 
+  "label": "From Time", 
+  "reqd": 1
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "to_time", 
+  "fieldtype": "Datetime", 
+  "label": "To Time", 
+  "reqd": 1
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "column_break_3", 
+  "fieldtype": "Column Break"
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "activity_type", 
+  "fieldtype": "Link", 
+  "in_list_view": 1, 
+  "label": "Activity Type", 
+  "options": "Activity Type", 
+  "reqd": 1
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "task", 
+  "fieldtype": "Link", 
+  "label": "Task", 
+  "options": "Task"
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "billable", 
+  "fieldtype": "Check", 
+  "label": "Billable"
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "section_break_7", 
+  "fieldtype": "Section Break"
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "note", 
+  "fieldtype": "Text Editor", 
+  "label": "Note"
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "section_break_9", 
+  "fieldtype": "Section Break"
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "project", 
+  "fieldtype": "Link", 
+  "in_list_view": 1, 
+  "label": "Project", 
+  "options": "Project"
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "sales_invoice", 
+  "fieldtype": "Link", 
+  "label": "Sales Invoice", 
+  "options": "Sales Invoice"
+ }, 
+ {
+  "create": 1, 
+  "doctype": "DocPerm", 
+  "match": "owner", 
+  "role": "Projects User"
+ }, 
+ {
+  "doctype": "DocPerm", 
+  "role": "Projects Manager"
+ }
+]
\ No newline at end of file
diff --git a/projects/doctype/time_log/time_log_calendar.js b/projects/doctype/time_log/time_log_calendar.js
new file mode 100644
index 0000000..e5bb774
--- /dev/null
+++ b/projects/doctype/time_log/time_log_calendar.js
@@ -0,0 +1,10 @@
+wn.views.calendar["Time Log"] = wn.views.Calendar.extend({
+	field_map: {
+		"start": "from_time",
+		"end": "to_time",
+		"id": "name",
+		"title": "title",
+		"allDay": "allDay"
+	},
+	get_events_method: "projects.doctype.time_log.time_log.get_events"
+})
\ No newline at end of file
diff --git a/projects/doctype/timesheet/timesheet.py b/projects/doctype/timesheet/timesheet.py
index 6e6e27a..560bc5f 100644
--- a/projects/doctype/timesheet/timesheet.py
+++ b/projects/doctype/timesheet/timesheet.py
@@ -91,4 +91,5 @@
 		webnotes.conn.set(self.doc, 'status', 'Submitted')
 	
 	def on_cancel(self):
-		webnotes.conn.set(self.doc, 'status', 'Cancelled')
\ No newline at end of file
+		webnotes.conn.set(self.doc, 'status', 'Cancelled')
+			
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/_messages_doc.json b/projects/module_def/projects/locale/_messages_doc.json
deleted file mode 100644
index da33435..0000000
--- a/projects/module_def/projects/locale/_messages_doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-[
- "Projects Home", 
- "Projects"
-]
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/ar-doc.json b/projects/module_def/projects/locale/ar-doc.json
deleted file mode 100644
index 7e4aaaf..0000000
--- a/projects/module_def/projects/locale/ar-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Projects": "\u0645\u0634\u0627\u0631\u064a\u0639", 
- "Projects Home": "\u0635\u0641\u062d\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639\u0627\u062a"
-}
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/es-doc.json b/projects/module_def/projects/locale/es-doc.json
deleted file mode 100644
index 7ca0100..0000000
--- a/projects/module_def/projects/locale/es-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Projects": "Proyectos", 
- "Projects Home": "Home Proyectos"
-}
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/fr-doc.json b/projects/module_def/projects/locale/fr-doc.json
deleted file mode 100644
index d292936..0000000
--- a/projects/module_def/projects/locale/fr-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Projects": "Projets", 
- "Projects Home": "Accueil Projets"
-}
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/hi-doc.json b/projects/module_def/projects/locale/hi-doc.json
deleted file mode 100644
index 6ec7020..0000000
--- a/projects/module_def/projects/locale/hi-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Projects": "\u092a\u0930\u093f\u092f\u094b\u091c\u0928\u093e\u0913\u0902", 
- "Projects Home": "\u092a\u0930\u093f\u092f\u094b\u091c\u0928\u093e\u0913\u0902 \u0918\u0930"
-}
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/hr-doc.json b/projects/module_def/projects/locale/hr-doc.json
deleted file mode 100644
index cdf6a7b..0000000
--- a/projects/module_def/projects/locale/hr-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Projects": "Projekti", 
- "Projects Home": "Projekti Po\u010detna"
-}
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/nl-doc.json b/projects/module_def/projects/locale/nl-doc.json
deleted file mode 100644
index a8b753e..0000000
--- a/projects/module_def/projects/locale/nl-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Projects": "Projecten", 
- "Projects Home": "Projecten Home"
-}
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/pt-BR-doc.json b/projects/module_def/projects/locale/pt-BR-doc.json
deleted file mode 100644
index d50cdd8..0000000
--- a/projects/module_def/projects/locale/pt-BR-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Projects": "Projetos", 
- "Projects Home": "In\u00edcio de Projetos"
-}
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/pt-doc.json b/projects/module_def/projects/locale/pt-doc.json
deleted file mode 100644
index 602e521..0000000
--- a/projects/module_def/projects/locale/pt-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Projects": "Projetos", 
- "Projects Home": "Home Projetos"
-}
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/sr-doc.json b/projects/module_def/projects/locale/sr-doc.json
deleted file mode 100644
index b831f42..0000000
--- a/projects/module_def/projects/locale/sr-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Projects": "\u041f\u0440\u043e\u0458\u0435\u043a\u0442\u0438", 
- "Projects Home": "\u041f\u0440\u043e\u0458\u0435\u043a\u0442\u0438"
-}
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/ta-doc.json b/projects/module_def/projects/locale/ta-doc.json
deleted file mode 100644
index 71fd303..0000000
--- a/projects/module_def/projects/locale/ta-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Projects": "\u0ba4\u0bbf\u0b9f\u0bcd\u0b9f\u0b99\u0bcd\u0b95\u0bb3\u0bcd", 
- "Projects Home": "\u0ba4\u0bbf\u0b9f\u0bcd\u0b9f\u0b99\u0bcd\u0b95\u0bb3\u0bcd \u0bae\u0bc1\u0b95\u0baa\u0bcd\u0baa\u0bc1"
-}
\ No newline at end of file
diff --git a/projects/module_def/projects/locale/th-doc.json b/projects/module_def/projects/locale/th-doc.json
deleted file mode 100644
index 17d8bfa..0000000
--- a/projects/module_def/projects/locale/th-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Projects": "\u0e42\u0e04\u0e23\u0e07\u0e01\u0e32\u0e23", 
- "Projects Home": "\u0e2b\u0e19\u0e49\u0e32\u0e41\u0e23\u0e01\u0e42\u0e04\u0e23\u0e07\u0e01\u0e32\u0e23"
-}
\ No newline at end of file
diff --git a/projects/page/projects_home/projects_home.js b/projects/page/projects_home/projects_home.js
index 3f91468..c9a6b93 100644
--- a/projects/page/projects_home/projects_home.js
+++ b/projects/page/projects_home/projects_home.js
@@ -21,6 +21,11 @@
 				description: wn._("Timesheet for tasks."),
 				doctype:"Timesheet"
 			},
+			{
+				label: wn._("Time Log"),
+				description: wn._("Time Log for tasks."),
+				doctype:"Time Log"
+			},
 		]
 	},
 	{
diff --git a/setup/doctype/company/company.py b/setup/doctype/company/company.py
index 552dae2..9cf722f 100644
--- a/setup/doctype/company/company.py
+++ b/setup/doctype/company/company.py
@@ -211,6 +211,12 @@
 				'company_name':self.doc.name,
 				'group_or_ledger':'Ledger',
 				'parent_cost_center':'Root - ' + self.doc.abbr
+			},
+			{
+				'cost_center_name': 'Auto Inventory Accounting', 
+				'company_name': self.doc.name,
+				'group_or_ledger': 'Ledger',
+				'parent_cost_center': 'Root - ' + self.doc.abbr
 			}
 		]
 		for cc in cc_list:
diff --git a/startup/install.py b/startup/install.py
index b42b716..5ddbf09 100644
--- a/startup/install.py
+++ b/startup/install.py
@@ -30,7 +30,7 @@
 		"HR Manager", "HR User", "Leave Approver", "Maintenance Manager",
 		"Maintenance User", "Manufacturing Manager", "Manufacturing User",
 		"Material Manager", "Material Master Manager", "Material User",
-		"Partner", "Projects User", "Purchase Manager", "Purchase Master Manager",
+		"Partner", "Projects User", "Projects Manager", "Purchase Manager", "Purchase Master Manager",
 		"Purchase User", "Quality Manager", "Sales Manager",
 		"Sales Master Manager", "Sales User", "Supplier", "Support Manager",
 		"Support Team", "Website Manager"]
diff --git a/stock/doctype/item/test_item.py b/stock/doctype/item/test_item.py
index 853283e..035774b 100644
--- a/stock/doctype/item/test_item.py
+++ b/stock/doctype/item/test_item.py
@@ -17,64 +17,8 @@
 from __future__ import unicode_literals
 import unittest
 import webnotes
-import copy
 
-from webnotes.model.bean import Bean
-from webnotes.model.doc import Document
-from webnotes.utils import flt
-
-sql = webnotes.conn.sql
-
-
-class TestItem(unittest.TestCase):
-	def setUp(self):
-		webnotes.conn.begin()
-
-	def tearDown(self):
-		webnotes.conn.rollback()
-		
-	def testInsert(self):
-		d = Bean()
-
-		count_before =  flt(sql("select count(*) from tab"+_doctype)[0][0])
-		if docok:
-			for i in docok:
-				d.doc = i
-				d.children = None
-				d.doc.fields['__islocal']=1
-				d.save(1)
-		count_after = flt(sql("select count(*) from tab"+_doctype)[0][0])
-		self.assertTrue(count_before+len(docok)==count_after)
-	
-	def testFailAssert(self):
-		if docnotok:
-			with self.assertRaises(Exception) as context:
-				d = Bean()
-				d.doc = docnotok[0]
-				d.children = None
-				d.doc.fields['__islocal']=1
-				d.save(1)
-
-# Test Data
-
-tabOK = [
-		{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Ink', 'default_warehouse': None, 'item_name': 'Gel Ink', 'item_group': 'Ink', 'item_code': 'GELINK', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'}, 
-		{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Refill', 'default_warehouse': None, 'item_name': 'Gel Refill', 'item_group': 'Refill', 'item_code': 'GELREF', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'}, 
-		{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Pen', 'default_warehouse': None, 'item_name': 'Gel Pen', 'item_group': 'Pen', 'item_code': 'GELPEN', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'}
-	]
-
-tabNotOK =	[
-			{'is_purchase_item': None, 'is_pro_applicable': None, 'is_manufactured_item': None, 'description': 'F Ink', 'default_warehouse': None, 'item_name': 'F Ink', 'item_group': 'F Ink', 'item_code': None, 'is_sub_contracted_item': None, 'is_stock_item': 'No', 'stock_uom': 'Nos', 'docstatus': '0'}
-		]
-	      
-_doctype = 'Item'
-
-for i in tabOK: i['doctype']=_doctype
-for i in tabNotOK: i['doctype']=_doctype
-
-docok = [Document(fielddata=r) for r in tabOK]
-docnotok = [Document(fielddata=r) for r in tabNotOK]
-
+test_ignore = ["BOM"]
 
 test_records = [
 	[{
@@ -164,4 +108,23 @@
 		"is_sub_contracted_item": "No",
 		"stock_uom": "_Test UOM"
 	}],
+	[{
+		"doctype": "Item",
+		"item_code": "_Test FG Item",
+		"item_name": "_Test FG Item",
+		"description": "_Test FG Item",
+		"item_group": "_Test Item Group Desktops",
+		"is_stock_item": "Yes",
+		"is_asset_item": "No",
+		"has_batch_no": "No",
+		"has_serial_no": "No",
+		"is_purchase_item": "Yes",
+		"is_sales_item": "Yes",
+		"is_service_item": "No",
+		"is_sample_item": "No",
+		"inspection_required": "No",
+		"is_pro_applicable": "Yes",
+		"is_sub_contracted_item": "Yes",
+		"stock_uom": "_Test UOM"
+	}],
 ]
\ No newline at end of file
diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py
index a957468..6772103 100644
--- a/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -18,10 +18,10 @@
 import webnotes
 
 from webnotes.utils import cstr, flt, cint
-from webnotes.model.doc import addchild
 from webnotes.model.bean import getlist
 from webnotes.model.code import get_obj
-from webnotes import msgprint
+from webnotes.model.doc import Document
+from webnotes import msgprint, _
 
 sql = webnotes.conn.sql
 
@@ -89,18 +89,6 @@
 				webnotes.msgprint("Another Purchase Receipt using the same Challan No. already exists.\
 			Please enter a valid Challan No.", raise_exception=1)
 
-
-	# update valuation rate
-	def update_valuation_rate(self):
-		for d in self.doclist.get({"parentfield": "purchase_receipt_details"}):
-			if d.qty:
-				d.valuation_rate = (flt(d.purchase_rate) + flt(d.item_tax_amount)/flt(d.qty)
-					+ flt(d.rm_supp_cost) / flt(d.qty)) / flt(d.conversion_factor)
-			else:
-				d.valuation_rate = 0.0
-
-	#check in manage account if purchase order required or not.
-	# ====================================================================================
 	def po_required(self):
 		res = sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = 'po_required'")
 		if res and res[0][0]== 'Yes':
@@ -109,8 +97,6 @@
 					 msgprint("Purchse Order No. required against item %s"%d.item_code)
 					 raise Exception
 
-
-	# validate
 	def validate(self):
 		super(DocType, self).validate()
 		
@@ -134,18 +120,17 @@
 		pc_obj.validate_reference_value(self)
 		self.check_for_stopped_status(pc_obj)
 
-		# update valuation rate
-		self.update_valuation_rate()
+		# sub-contracting
+		self.validate_for_subcontracting()
+		self.update_raw_materials_supplied()
+		
+		self.update_valuation_rate("purchase_receipt_details")
 
-
-	# On Update
-	# ----------------------------------------------------------------------------------------------------
 	def on_update(self):
 		if self.doc.rejected_warehouse:
 			for d in getlist(self.doclist,'purchase_receipt_details'):
 				d.rejected_warehouse = self.doc.rejected_warehouse
 
-		self.update_rw_material_detail()
 		get_obj('Stock Ledger').scrub_serial_nos(self)
 		self.scrub_rejected_serial_nos()
 
@@ -303,118 +288,66 @@
 		
 		self.make_gl_entries()
 
+	def validate_for_subcontracting(self):
+		if self.sub_contracted_items and self.purchase_items and not self.doc.is_subcontracted:
+			webnotes.msgprint(_("""Please enter whether Purchase Recipt is made for subcontracting 
+				or purchasing, in 'Is Subcontracted' field"""), raise_exception=1)
+			
+		if self.doc.is_subcontracted and not self.doc.supplier_warehouse:
+			webnotes.msgprint(_("Please Enter Supplier Warehouse for subcontracted Items"), 
+				raise_exception=1)
+				
+	def update_raw_materials_supplied(self):
+		self.doclist = self.doc.clear_table(self.doclist, 'pr_raw_material_details')
+		if self.sub_contracted_items:
+			for item in self.doclist.get({"parentfield": "purchase_receipt_details"}):
+				if item.item_code in self.sub_contracted_items:
+					self.add_bom_items(item)
 
-	def update_rw_material_detail(self):
+	def add_bom_items(self, d):
+		bom_items = self.get_items_from_default_bom(d.item_code)
+		raw_materials_cost = 0
+		for item in bom_items:
+			required_qty = flt(item.qty_consumed_per_unit) * flt(d.qty) * flt(d.conversion_factor)
+			self.doclist.append({
+				"parentfield": "pr_raw_material_details",
+				"doctype": "Purchase Receipt Item Supplied",
+				"reference_name": d.name,
+				"bom_detail_no": item.name,
+				"main_item_code": d.item_code,
+				"rm_item_code": item.item_code,
+				"description": item.description,
+				"stock_uom": item.stock_uom,
+				"required_qty": required_qty,
+				"consumed_qty": required_qty,
+				"conversion_factor": d.conversion_factor,
+				"rate": item.rate,
+				"amount": required_qty * flt(item.rate)
+			})
+			
+			raw_materials_cost += required_qty * flt(item.rate)
+			
+		d.rm_supp_cost = raw_materials_cost
 
-		for d in getlist(self.doclist,'purchase_receipt_details'):
-			item_det = sql("select is_sub_contracted_item, is_purchase_item from `tabItem` where name = '%s'"%(d.item_code))
-
-			if item_det[0][0] == 'Yes':
-				if item_det[0][1] == 'Yes':
-					if not self.doc.is_subcontracted:
-						msgprint("Please enter whether purchase receipt to be made for subcontracting or for purchase in 'Is Subcontracted' field .")
-						raise Exception
-					if self.doc.is_subcontracted == 'Yes':
-						if not self.doc.supplier_warehouse:
-							msgprint("Please Enter Supplier Warehouse for subcontracted Items")
-							raise Exception
-						self.add_bom(d)
-					else:
-						self.doclist = self.doc.clear_table(self.doclist,'pr_raw_material_details',1)
-						self.doc.save()
-				elif item_det[0][1] == 'No':
-					if not self.doc.supplier_warehouse:
-						msgprint("Please Enter Supplier Warehouse for subcontracted Items")
-						raise Exception
-					self.add_bom(d)
-
-			self.delete_irrelevant_raw_material()
-			#---------------calculate amt in	Purchase Receipt Item Supplied-------------
-			self.calculate_amount(d)
-
-
-	def add_bom(self, d):
-		#----- fetching default bom from Bill of Materials instead of Item Master --
-		bom_det = sql("""select t1.item, t2.item_code, t2.qty_consumed_per_unit, 
-			t2.moving_avg_rate, t2.value_as_per_mar, t2.stock_uom, t2.name, t2.description 
+	def get_items_from_default_bom(self, item_code):
+		# print webnotes.conn.sql("""select name from `tabBOM` where item = '_Test FG Item'""")
+		bom_items = sql("""select t2.item_code, t2.qty_consumed_per_unit, 
+			t2.rate, t2.stock_uom, t2.name, t2.description 
 			from `tabBOM` t1, `tabBOM Item` t2 
 			where t2.parent = t1.name and t1.item = %s and t1.is_default = 1 
-			and t1.docstatus = 1 and t2.docstatus =1 and t1.is_active = 1""", d.item_code)
-		if not bom_det:
-			msgprint("No default BOM exists for item: %s" % d.item_code)
-			raise Exception
-		else:
-			#-------------- add child function--------------------
-			chgd_rqd_qty = []
-			for i in bom_det:
+			and t1.docstatus = 1 and t1.is_active = 1""", item_code, as_dict=1)
+		if not bom_items:
+			msgprint(_("No default BOM exists for item: ") + item_code, raise_exception=1)
+		
+		return bom_items
 
-				if i and not sql("select name from `tabPurchase Receipt Item Supplied` where reference_name = '%s' and bom_detail_no = '%s' and parent = '%s' " %(d.name, i[6], self.doc.name)):
-
-					rm_child = addchild(self.doc, 'pr_raw_material_details', 'Purchase Receipt Item Supplied', self.doclist)
-
-					rm_child.reference_name = d.name
-					rm_child.bom_detail_no = i and i[6] or ''
-					rm_child.main_item_code = i and i[0] or ''
-					rm_child.rm_item_code = i and i[1] or ''
-					rm_child.description = i and i[7] or ''
-					rm_child.stock_uom = i and i[5] or ''
-					rm_child.rate = i and flt(i[3]) or flt(i[4])
-					rm_child.conversion_factor = d.conversion_factor
-					rm_child.required_qty = flt(i	and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
-					rm_child.consumed_qty = flt(i	and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
-					rm_child.amount = flt(flt(rm_child.consumed_qty)*flt(rm_child.rate))
-					rm_child.save()
-					chgd_rqd_qty.append(cstr(i[1]))
-				else:
-					act_qty = flt(i	and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
-					for pr_rmd in getlist(self.doclist, 'pr_raw_material_details'):
-						if i and i[6] == pr_rmd.bom_detail_no and (flt(act_qty) != flt(pr_rmd.required_qty) or i[1] != pr_rmd.rm_item_code or i[7] != pr_rmd.description):
-							chgd_rqd_qty.append(cstr(i[1]))
-							pr_rmd.main_item_code = i[0]
-							pr_rmd.rm_item_code = i[1]
-							pr_rmd.description = i[7]
-							pr_rmd.stock_uom = i[5]
-							pr_rmd.required_qty = flt(act_qty)
-							pr_rmd.consumed_qty = flt(act_qty)
-							pr_rmd.rate = i and flt(i[3]) or flt(i[4])
-							pr_rmd.amount = flt(flt(pr_rmd.consumed_qty)*flt(pr_rmd.rate))
-							pr_rmd.save()
-			if chgd_rqd_qty:
-				msgprint("Please check consumed quantity for Raw Material Item Code: '%s'in Raw materials Detail Table" % ((len(chgd_rqd_qty) > 1 and ','.join(chgd_rqd_qty[:-1]) +' and ' + cstr(chgd_rqd_qty[-1:][0]) ) or cstr(chgd_rqd_qty[0])))
-
-
-	# Delete irrelevant raw material from PR Raw material details
-	#--------------------------------------------------------------
-	def delete_irrelevant_raw_material(self):
-		for d in getlist(self.doclist,'pr_raw_material_details'):
-			if not sql("select name from `tabPurchase Receipt Item` where name = '%s' and parent = '%s' and item_code = '%s'" % (d.reference_name, self.doc.name, d.main_item_code)):
-				d.parent = 'old_par:'+self.doc.name
-				d.save()
-
-	def calculate_amount(self, d):
-		amt = 0
-		for i in getlist(self.doclist,'pr_raw_material_details'):
-
-			if(i.reference_name == d.name):
-				#if i.consumed_qty == 0:
-				 # msgprint("consumed qty cannot be 0. Please Enter consumed qty ")
-					#raise Exception
-				i.amount = flt(i.consumed_qty)* flt(i.rate)
-				amt += i.amount
-		d.rm_supp_cost = amt
-		d.save()
-
-
-	# --------------- Back Flush function called on submit and on cancel from update stock
 	def bk_flush_supp_wh(self, is_submit):
 		for d in getlist(self.doclist, 'pr_raw_material_details'):
-			#--------- -ve quantity is passed as raw material qty has to be decreased when PR is submitted and it has to be increased when PR is cancelled
+			# negative quantity is passed as raw material qty has to be decreased 
+			# when PR is submitted and it has to be increased when PR is cancelled
 			consumed_qty = - flt(d.consumed_qty)
 			self.make_sl_entry(d, self.doc.supplier_warehouse, flt(consumed_qty), 0, is_submit)
 
-
-	# get current_stock
-	# ----------------
 	def get_current_stock(self):
 		for d in getlist(self.doclist, 'pr_raw_material_details'):
 			if self.doc.supplier_warehouse:
diff --git a/stock/doctype/purchase_receipt/test_purchase_receipt.py b/stock/doctype/purchase_receipt/test_purchase_receipt.py
index d833d65..f3f6da8 100644
--- a/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -36,7 +36,6 @@
 		
 	def test_purchase_receipt_gl_entry(self):
 		webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
-		
 		self.assertEqual(cint(webnotes.defaults.get_global_default("auto_inventory_accounting")), 1)
 		
 		pr = webnotes.bean(copy=test_records[0])
@@ -47,7 +46,6 @@
 		gl_entries = webnotes.conn.sql("""select account, debit, credit
 			from `tabGL Entry` where voucher_type='Purchase Receipt' and voucher_no=%s
 			order by account desc""", pr.doc.name, as_dict=1)
-			
 		self.assertTrue(gl_entries)
 		
 		stock_in_hand_account = webnotes.conn.get_value("Company", pr.doc.company, 
@@ -64,6 +62,17 @@
 			self.assertEquals(expected_values[i][2], gle.credit)
 			
 		webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+		
+	def test_subcontracting(self):
+		pr = webnotes.bean(copy=test_records[1])
+		pr.run_method("calculate_taxes_and_totals")
+		pr.insert()
+		
+		self.assertEquals(pr.doclist[1].rm_supp_cost, 70000.0)
+		self.assertEquals(len(pr.doclist.get({"parentfield": "pr_raw_material_details"})), 2)
+
+
+test_dependencies = ["BOM"]
 
 test_records = [
 	[
@@ -129,4 +138,36 @@
 			"tax_amount": 150.0,
 		},
 	],
+	[
+		{
+			"company": "_Test Company", 
+			"conversion_rate": 1.0, 
+			"currency": "INR", 
+			"doctype": "Purchase Receipt", 
+			"fiscal_year": "_Test Fiscal Year 2013", 
+			"posting_date": "2013-02-12", 
+			"posting_time": "15:33:30", 
+			"is_subcontracted": "Yes",
+			"supplier_warehouse": "_Test Warehouse", 
+			"supplier": "_Test Supplier",
+			"net_total": 5000.0, 
+			"grand_total": 5000.0,
+		}, 
+		{
+			"conversion_factor": 1.0, 
+			"description": "_Test FG Item", 
+			"doctype": "Purchase Receipt Item", 
+			"item_code": "_Test FG Item", 
+			"item_name": "_Test FG Item", 
+			"parentfield": "purchase_receipt_details", 
+			"received_qty": 10.0,
+			"qty": 10.0,
+			"rejected_qty": 0.0,
+			"import_rate": 500.0,
+			"amount": 5000.0,
+			"warehouse": "_Test Warehouse", 
+			"stock_uom": "Nos", 
+			"uom": "_Test UOM",
+		}
+	],
 ]
\ No newline at end of file
diff --git a/website/utils.py b/website/utils.py
index 16d8505..0983f62 100644
--- a/website/utils.py
+++ b/website/utils.py
@@ -253,6 +253,9 @@
 		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)
+		
 	if not args.brand_html:
 		args.brand_html = "ERPNext"
 	if not args.top_bar_background: