[selling] [calculations] server side calculations, test cases and rounding based on currency number format
diff --git a/accounts/doctype/sales_invoice/sales_invoice.txt b/accounts/doctype/sales_invoice/sales_invoice.txt
index 9d8f54e..f1c0cab 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.txt
+++ b/accounts/doctype/sales_invoice/sales_invoice.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-04-19 11:00:14", 
+  "creation": "2013-05-06 12:03:41", 
   "docstatus": 0, 
-  "modified": "2013-04-22 11:59:40", 
+  "modified": "2013-05-09 17:34:14", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -10,6 +10,7 @@
   "allow_attach": 1, 
   "autoname": "naming_series:", 
   "doctype": "DocType", 
+  "document_type": "Transaction", 
   "is_submittable": 1, 
   "module": "Accounts", 
   "name": "__common__", 
@@ -30,6 +31,7 @@
   "parent": "Sales Invoice", 
   "parentfield": "permissions", 
   "parenttype": "DocType", 
+  "permlevel": 0, 
   "read": 1
  }, 
  {
@@ -251,7 +253,6 @@
   "width": "50%"
  }, 
  {
-  "description": "Will be calculated automatically when you enter the details", 
   "doctype": "DocField", 
   "fieldname": "net_total", 
   "fieldtype": "Currency", 
@@ -259,12 +260,21 @@
   "oldfieldname": "net_total", 
   "oldfieldtype": "Currency", 
   "options": "Company:company:default_currency", 
-  "print_hide": 0, 
+  "print_hide": 1, 
   "read_only": 1, 
   "reqd": 1
  }, 
  {
   "doctype": "DocField", 
+  "fieldname": "net_total_export", 
+  "fieldtype": "Currency", 
+  "label": "Net Total (Export)", 
+  "options": "currency", 
+  "print_hide": 0, 
+  "read_only": 1
+ }, 
+ {
+  "doctype": "DocField", 
   "fieldname": "recalculate_values", 
   "fieldtype": "Button", 
   "label": "Re-Calculate Values", 
@@ -1288,7 +1298,6 @@
   "cancel": 1, 
   "create": 1, 
   "doctype": "DocPerm", 
-  "permlevel": 0, 
   "report": 1, 
   "role": "Accounts User", 
   "submit": 1, 
@@ -1297,8 +1306,7 @@
  {
   "doctype": "DocPerm", 
   "match": "customer", 
-  "permlevel": 0, 
-  "report": 1, 
+  "report": 0, 
   "role": "Customer"
  }
 ]
\ No newline at end of file
diff --git a/accounts/doctype/sales_invoice/test_sales_invoice.py b/accounts/doctype/sales_invoice/test_sales_invoice.py
index b46cdd1..505848a 100644
--- a/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1,12 +1,226 @@
 import webnotes
-import unittest
+import unittest, json
+from webnotes.utils import flt
 
 class TestSalesInvoice(unittest.TestCase):
 	def make(self):
-		w = webnotes.bean(webnotes.copy_doclist(test_records[0]))
+		w = webnotes.bean(copy=test_records[0])
 		w.insert()
 		w.submit()
 		return w
+		
+	def test_sales_invoice_calculation_base_currency(self):
+		si = webnotes.bean(copy=test_records[2])
+		si.run_method("calculate_taxes_and_totals")
+		si.insert()
+		
+		expected_values = {
+			"keys": ["ref_rate", "adj_rate", "export_rate", "export_amount", 
+				"base_ref_rate", "basic_rate", "amount"],
+			"_Test Item Home Desktop 100": [50, 0, 50, 500, 50, 50, 500],
+			"_Test Item Home Desktop 200": [150, 0, 150, 750, 150, 150, 750],
+		}
+		
+		# check if children are saved
+		self.assertEquals(len(si.doclist.get({"parentfield": "entries"})),
+			len(expected_values)-1)
+		
+		# check if item values are calculated
+		for d in si.doclist.get({"parentfield": "entries"}):
+			for i, k in enumerate(expected_values["keys"]):
+				self.assertEquals(d.fields.get(k), expected_values[d.item_code][i])
+		
+		# check net total
+		self.assertEquals(si.doc.net_total, 1250)
+		self.assertEquals(si.doc.net_total_export, 1250)
+		
+		# check tax calculation
+		expected_values = {
+			"keys": ["tax_amount", "total"],
+			"_Test Account Shipping Charges - _TC": [100, 1350],
+			"_Test Account Customs Duty - _TC": [125, 1475],
+			"_Test Account Excise Duty - _TC": [140, 1615],
+			"_Test Account Education Cess - _TC": [2.8, 1617.8],
+			"_Test Account S&H Education Cess - _TC": [1.4, 1619.2],
+			"_Test Account CST - _TC": [32.38, 1651.58],
+			"_Test Account VAT - _TC": [156.25, 1807.83],
+			"_Test Account Discount - _TC": [-180.78, 1627.05]
+		}
+		
+		for d in si.doclist.get({"parentfield": "other_charges"}):
+			for i, k in enumerate(expected_values["keys"]):
+				self.assertEquals(d.fields.get(k), expected_values[d.account_head][i])
+				
+		self.assertEquals(si.doc.grand_total, 1627.05)
+		self.assertEquals(si.doc.grand_total_export, 1627.05)
+		
+	def test_sales_invoice_calculation_export_currency(self):
+		si = webnotes.bean(copy=test_records[2])
+		si.doc.currency = "USD"
+		si.doc.conversion_rate = 50
+		si.doclist[1].export_rate = 1
+		si.doclist[1].ref_rate = 1
+		si.doclist[2].export_rate = 3
+		si.doclist[2].ref_rate = 3
+		si.run_method("calculate_taxes_and_totals")
+		si.insert()
+		
+		expected_values = {
+			"keys": ["ref_rate", "adj_rate", "export_rate", "export_amount", 
+				"base_ref_rate", "basic_rate", "amount"],
+			"_Test Item Home Desktop 100": [1, 0, 1, 10, 50, 50, 500],
+			"_Test Item Home Desktop 200": [3, 0, 3, 15, 150, 150, 750],
+		}
+		
+		# check if children are saved
+		self.assertEquals(len(si.doclist.get({"parentfield": "entries"})),
+			len(expected_values)-1)
+		
+		# check if item values are calculated
+		for d in si.doclist.get({"parentfield": "entries"}):
+			for i, k in enumerate(expected_values["keys"]):
+				self.assertEquals(d.fields.get(k), expected_values[d.item_code][i])
+		
+		# check net total
+		self.assertEquals(si.doc.net_total, 1250)
+		self.assertEquals(si.doc.net_total_export, 25)
+		
+		# check tax calculation
+		expected_values = {
+			"keys": ["tax_amount", "total"],
+			"_Test Account Shipping Charges - _TC": [100, 1350],
+			"_Test Account Customs Duty - _TC": [125, 1475],
+			"_Test Account Excise Duty - _TC": [140, 1615],
+			"_Test Account Education Cess - _TC": [2.8, 1617.8],
+			"_Test Account S&H Education Cess - _TC": [1.4, 1619.2],
+			"_Test Account CST - _TC": [32.38, 1651.58],
+			"_Test Account VAT - _TC": [156.25, 1807.83],
+			"_Test Account Discount - _TC": [-180.78, 1627.05]
+		}
+		
+		for d in si.doclist.get({"parentfield": "other_charges"}):
+			for i, k in enumerate(expected_values["keys"]):
+				self.assertEquals(d.fields.get(k), expected_values[d.account_head][i])
+				
+		self.assertEquals(si.doc.grand_total, 1627.05)
+		self.assertEquals(si.doc.grand_total_export, 32.54)
+				
+	def test_inclusive_rate_validations(self):
+		si = webnotes.bean(copy=test_records[2])
+		for i, tax in enumerate(si.doclist.get({"parentfield": "other_charges"})):
+			tax.idx = i+1
+		
+		si.doclist[1].export_rate = 62.5
+		si.doclist[1].export_rate = 191
+		for i in [3, 5, 6, 7, 8, 9]:
+			si.doclist[i].included_in_print_rate = 1
+		
+		# tax type "Actual" cannot be inclusive
+		self.assertRaises(webnotes.ValidationError, si.run_method, "calculate_taxes_and_totals")
+		
+		# taxes above included type 'On Previous Row Total' should also be included
+		si.doclist[3].included_in_print_rate = 0
+		self.assertRaises(webnotes.ValidationError, si.run_method, "calculate_taxes_and_totals")
+		
+	def test_sales_invoice_calculation_base_currency_with_tax_inclusive_price(self):
+		# prepare
+		si = webnotes.bean(copy=test_records[3])
+		si.run_method("calculate_taxes_and_totals")
+		si.insert()
+		
+		expected_values = {
+			"keys": ["ref_rate", "adj_rate", "export_rate", "export_amount", 
+				"base_ref_rate", "basic_rate", "amount"],
+			"_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 50, 50, 500],
+			"_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 150, 150, 750],
+		}
+		
+		# check if children are saved
+		self.assertEquals(len(si.doclist.get({"parentfield": "entries"})),
+			len(expected_values)-1)
+		
+		# check if item values are calculated
+		for d in si.doclist.get({"parentfield": "entries"}):
+			for i, k in enumerate(expected_values["keys"]):
+				self.assertEquals(d.fields.get(k), expected_values[d.item_code][i])
+		
+		# check net total
+		self.assertEquals(si.doc.net_total, 1250)
+		self.assertEquals(si.doc.net_total_export, 1578.3)
+		
+		# check tax calculation
+		expected_values = {
+			"keys": ["tax_amount", "total"],
+			"_Test Account Excise Duty - _TC": [140, 1390],
+			"_Test Account Education Cess - _TC": [2.8, 1392.8],
+			"_Test Account S&H Education Cess - _TC": [1.4, 1394.2],
+			"_Test Account CST - _TC": [27.88, 1422.08],
+			"_Test Account VAT - _TC": [156.25, 1578.33],
+			"_Test Account Customs Duty - _TC": [125, 1703.33],
+			"_Test Account Shipping Charges - _TC": [100, 1803.33],
+			"_Test Account Discount - _TC": [-180.33, 1623]
+		}
+		
+		for d in si.doclist.get({"parentfield": "other_charges"}):
+			for i, k in enumerate(expected_values["keys"]):
+				self.assertEquals(flt(d.fields.get(k), 6), expected_values[d.account_head][i])
+		
+		self.assertEquals(si.doc.grand_total, 1623)
+		self.assertEquals(si.doc.grand_total_export, 1623)
+		
+	def test_sales_invoice_calculation_export_currency_with_tax_inclusive_price(self):
+		# prepare
+		si = webnotes.bean(copy=test_records[3])
+		si.doc.currency = "USD"
+		si.doc.conversion_rate = 50
+		si.doclist[1].export_rate = 50
+		si.doclist[1].adj_rate = 10
+		si.doclist[2].export_rate = 150
+		si.doclist[2].adj_rate = 20
+		si.doclist[9].rate = 5000
+		
+		si.run_method("calculate_taxes_and_totals")
+		si.insert()
+		
+		expected_values = {
+			"keys": ["ref_rate", "adj_rate", "export_rate", "export_amount", 
+				"base_ref_rate", "basic_rate", "amount"],
+			"_Test Item Home Desktop 100": [55.56, 10, 50, 500, 2222.11, 1999.9, 19999.0],
+			"_Test Item Home Desktop 200": [187.5, 20, 150, 750, 7375.66, 5900.53, 29502.65],
+		}
+		
+		# check if children are saved
+		self.assertEquals(len(si.doclist.get({"parentfield": "entries"})),
+			len(expected_values)-1)
+		
+		# check if item values are calculated
+		for d in si.doclist.get({"parentfield": "entries"}):
+			for i, k in enumerate(expected_values["keys"]):
+				self.assertEquals(d.fields.get(k), expected_values[d.item_code][i])
+		
+		# check net total
+		self.assertEquals(si.doc.net_total, 49501.65)
+		self.assertEquals(si.doc.net_total_export, 1250)
+		
+		# check tax calculation
+		expected_values = {
+			"keys": ["tax_amount", "total"],
+			"_Test Account Excise Duty - _TC": [5540.22, 55041.87],
+			"_Test Account Education Cess - _TC": [110.81, 55152.68],
+			"_Test Account S&H Education Cess - _TC": [55.4, 55208.08],
+			"_Test Account CST - _TC": [1104.16, 56312.24],
+			"_Test Account VAT - _TC": [6187.71, 62499.95],
+			"_Test Account Customs Duty - _TC": [4950.17, 67450.12],
+			"_Test Account Shipping Charges - _TC": [5000, 72450.12],
+			"_Test Account Discount - _TC": [-7245.01, 65205.11]
+		}
+		
+		for d in si.doclist.get({"parentfield": "other_charges"}):
+			for i, k in enumerate(expected_values["keys"]):
+				self.assertEquals(flt(d.fields.get(k), 6), expected_values[d.account_head][i])
+		
+		self.assertEquals(si.doc.grand_total, 65205.11)
+		self.assertEquals(si.doc.grand_total_export, 1304.1)
 
 	def test_outstanding(self):
 		w = self.make()
@@ -520,4 +734,263 @@
 			"tax_amount": 50.0,
 		}
 	],
+	[
+		{
+			"naming_series": "_T-Sales Invoice-",
+			"company": "_Test Company", 
+			"conversion_rate": 1.0, 
+			"currency": "INR", 
+			"debit_to": "_Test Customer - _TC",
+			"customer": "_Test Customer",
+			"customer_name": "_Test Customer",
+			"doctype": "Sales Invoice", 
+			"due_date": "2013-01-23", 
+			"fiscal_year": "_Test Fiscal Year 2013", 
+			"grand_total_export": 0, 
+			"plc_conversion_rate": 1.0, 
+			"posting_date": "2013-01-23", 
+			"price_list_currency": "INR", 
+			"price_list_name": "_Test Price List", 
+			"territory": "_Test Territory",
+		},
+		# items
+		{
+			"doctype": "Sales Invoice Item",
+			"parentfield": "entries",
+			"item_code": "_Test Item Home Desktop 100",
+			"item_name": "_Test Item Home Desktop 100",
+			"qty": 10,
+			"export_rate": 50,
+			"stock_uom": "_Test UOM",
+			"item_tax_rate": json.dumps({"_Test Account Excise Duty - _TC": 10}),
+			"income_account": "Sales - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+		
+		},
+		{
+			"doctype": "Sales Invoice Item",
+			"parentfield": "entries",
+			"item_code": "_Test Item Home Desktop 200",
+			"item_name": "_Test Item Home Desktop 200",
+			"qty": 5,
+			"export_rate": 150,
+			"stock_uom": "_Test UOM",
+			"income_account": "Sales - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+		
+		},
+		# taxes
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "Actual",
+			"account_head": "_Test Account Shipping Charges - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Shipping Charges",
+			"rate": 100
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Net Total",
+			"account_head": "_Test Account Customs Duty - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Customs Duty",
+			"rate": 10
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Net Total",
+			"account_head": "_Test Account Excise Duty - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Excise Duty",
+			"rate": 12
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Previous Row Amount",
+			"account_head": "_Test Account Education Cess - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Education Cess",
+			"rate": 2,
+			"row_id": 3
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"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",
+			"rate": 1,
+			"row_id": 3
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Previous Row Total",
+			"account_head": "_Test Account CST - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "CST",
+			"rate": 2,
+			"row_id": 5
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Net Total",
+			"account_head": "_Test Account VAT - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "VAT",
+			"rate": 12.5
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Previous Row Total",
+			"account_head": "_Test Account Discount - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Discount",
+			"rate": -10,
+			"row_id": 7
+		},
+	],
+	[
+		{
+			"naming_series": "_T-Sales Invoice-",
+			"company": "_Test Company", 
+			"conversion_rate": 1.0, 
+			"currency": "INR", 
+			"debit_to": "_Test Customer - _TC",
+			"customer": "_Test Customer",
+			"customer_name": "_Test Customer",
+			"doctype": "Sales Invoice", 
+			"due_date": "2013-01-23", 
+			"fiscal_year": "_Test Fiscal Year 2013", 
+			"grand_total_export": 0, 
+			"plc_conversion_rate": 1.0, 
+			"posting_date": "2013-01-23", 
+			"price_list_currency": "INR", 
+			"price_list_name": "_Test Price List", 
+			"territory": "_Test Territory",
+		},
+		# items
+		{
+			"doctype": "Sales Invoice Item",
+			"parentfield": "entries",
+			"item_code": "_Test Item Home Desktop 100",
+			"item_name": "_Test Item Home Desktop 100",
+			"qty": 10,
+			"export_rate": 62.5,
+			"stock_uom": "_Test UOM",
+			"item_tax_rate": json.dumps({"_Test Account Excise Duty - _TC": 10}),
+			"income_account": "Sales - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+		
+		},
+		{
+			"doctype": "Sales Invoice Item",
+			"parentfield": "entries",
+			"item_code": "_Test Item Home Desktop 200",
+			"item_name": "_Test Item Home Desktop 200",
+			"qty": 5,
+			"export_rate": 190.66,
+			"stock_uom": "_Test UOM",
+			"income_account": "Sales - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+		
+		},
+		# taxes
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Net Total",
+			"account_head": "_Test Account Excise Duty - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Excise Duty",
+			"rate": 12,
+			"included_in_print_rate": 1,
+			"idx": 1
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Previous Row Amount",
+			"account_head": "_Test Account Education Cess - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Education Cess",
+			"rate": 2,
+			"row_id": 1,
+			"included_in_print_rate": 1,
+			"idx": 2
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"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",
+			"rate": 1,
+			"row_id": 1,
+			"included_in_print_rate": 1,
+			"idx": 3
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Previous Row Total",
+			"account_head": "_Test Account CST - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "CST",
+			"rate": 2,
+			"row_id": 3,
+			"included_in_print_rate": 1,
+			"idx": 4
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Net Total",
+			"account_head": "_Test Account VAT - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "VAT",
+			"rate": 12.5,
+			"included_in_print_rate": 1,
+			"idx": 5
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Net Total",
+			"account_head": "_Test Account Customs Duty - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Customs Duty",
+			"rate": 10,
+			"idx": 6
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "Actual",
+			"account_head": "_Test Account Shipping Charges - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Shipping Charges",
+			"rate": 100,
+			"idx": 7
+		},
+		{
+			"doctype": "Sales Taxes and Charges",
+			"parentfield": "other_charges",
+			"charge_type": "On Previous Row Total",
+			"account_head": "_Test Account Discount - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Discount",
+			"rate": -10,
+			"row_id": 7,
+			"idx": 8
+		},
+	],
 ]
\ No newline at end of file
diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py
index 04e4bbd..19b2a50 100644
--- a/controllers/accounts_controller.py
+++ b/controllers/accounts_controller.py
@@ -97,4 +97,4 @@
 		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
+		return self._abbr
diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py
index 4802140..d4aa225 100644
--- a/controllers/buying_controller.py
+++ b/controllers/buying_controller.py
@@ -22,7 +22,6 @@
 
 from buying.utils import get_item_details
 from setup.utils import get_company_currency
-from webnotes.model.utils import round_floats_in_doc
 
 from controllers.stock_controller import StockController
 
@@ -138,19 +137,20 @@
 		def _set_base(item, print_field, base_field):
 			"""set values in base currency"""
 			item.fields[base_field] = flt((flt(item.fields[print_field],
-				self.precision.item[print_field]) * self.doc.conversion_rate),
-				self.precision.item[base_field])
+				self.precision_of(print_field, item.parentfield)) * self.doc.conversion_rate),
+				self.precision_of(base_field, item.parentfield))
 		
 		# hack! - cleaned up in _cleanup()
 		if self.doc.doctype != "Purchase Invoice":
-			self.precision.item["rate"] = self.precision.item.purchase_rate
+			df = self.meta.get_field("purchase_rate", parentfield=self.fname)
+			df.fieldname = "rate"
 			
 		for item in self.item_doclist:
 			# hack! - cleaned up in _cleanup()
 			if self.doc.doctype != "Purchase Invoice":
 				item.rate = item.purchase_rate
 				
-			round_floats_in_doc(item, self.precision.item)
+			self.round_floats_in_doc(item, item.parentfield)
 
 			if item.discount_rate == 100:
 				item.import_ref_rate = item.import_ref_rate or item.import_rate
@@ -158,14 +158,14 @@
 			else:
 				if item.import_ref_rate:
 					item.import_rate = flt(item.import_ref_rate * (1.0 - (item.discount_rate / 100.0)),
-						self.precision.item.import_rate)
+						self.precision_of("import_rate", item.parentfield))
 				else:
 					# assume that print rate and discount_rate are specified
 					item.import_ref_rate = flt(item.import_rate / (1.0 - (item.discount_rate / 100.0)),
-						self.precision.item.import_ref_rate)
+						self.precision_of("import_ref_rate", item.parentfield))
 						
 			item.import_amount = flt(item.import_rate * item.qty,
-				self.precision.item.import_amount)
+				self.precision_of("import_amount", item.parentfield))
 				
 			_set_base(item, "import_ref_rate", "purchase_ref_rate")
 			_set_base(item, "import_rate", "rate")
@@ -183,7 +183,7 @@
 			
 			self.validate_on_previous_row(tax)
 			
-			round_floats_in_doc(tax, self.precision.tax)
+			self.round_floats_in_doc(tax, tax.parentfield)
 		
 	def calculate_net_total(self):
 		self.doc.net_total = 0
@@ -193,9 +193,9 @@
 			self.doc.net_total += item.amount
 			self.doc.net_total_import += item.import_amount
 			
-		self.doc.net_total = flt(self.doc.net_total, self.precision.main.net_total)
+		self.doc.net_total = flt(self.doc.net_total, self.precision_of("net_total"))
 		self.doc.net_total_import = flt(self.doc.net_total_import,
-			self.precision.main.net_total_import)
+			self.precision_of("net_total_import"))
 		
 	def calculate_taxes(self):
 		for item in self.item_doclist:
@@ -213,7 +213,7 @@
 				# and tax.grand_total_for_current_item for the first such iteration
 				if not (current_tax_amount or self.doc.net_total or tax.tax_amount) and \
 						tax.charge_type=="Actual":
-					zero_net_total_adjustment = flt(tax.rate, self.precision.tax.tax_amount)
+					zero_net_total_adjustment = flt(tax.rate, self.precision_of("tax_amount", tax.parentfield))
 					current_tax_amount += zero_net_total_adjustment
 
 				# store tax_amount for current item as it will be used for
@@ -235,12 +235,12 @@
 				# item's amount, previously applied tax and the current tax on that item
 				if i==0:
 					tax.grand_total_for_current_item = flt(item.amount +
-						current_tax_amount, self.precision.tax.total)
+						current_tax_amount, self.precision_of("total", tax.parentfield))
 
 				else:
 					tax.grand_total_for_current_item = \
 						flt(self.tax_doclist[i-1].grand_total_for_current_item +
-							current_tax_amount, self.precision.tax.total)
+							current_tax_amount, self.precision_of("total", tax.parentfield))
 
 				# in tax.total, accumulate grand total of each item
 				tax.total += tax.grand_total_for_current_item
@@ -252,20 +252,20 @@
 	def calculate_totals(self):
 		if self.tax_doclist:
 			self.doc.grand_total = flt(self.tax_doclist[-1].total,
-				self.precision.main.grand_total)
+				self.precision_of("grand_total"))
 			self.doc.grand_total_import = flt(
 				self.doc.grand_total / self.doc.conversion_rate,
-				self.precision.main.grand_total_import)
+				self.precision_of("grand_total_import"))
 		else:
 			self.doc.grand_total = flt(self.doc.net_total,
-				self.precision.main.grand_total)
+				self.precision_of("grand_total"))
 			self.doc.grand_total_import = flt(
 				self.doc.grand_total / self.doc.conversion_rate,
-				self.precision.main.grand_total_import)
+				self.precision_of("grand_total_import"))
 
 		self.doc.total_tax = \
 			flt(self.doc.grand_total - self.doc.net_total,
-			self.precision.main.total_tax)
+			self.precision_of("total_tax"))
 
 		if self.meta.get_field("rounded_total"):
 			self.doc.rounded_total = round(self.doc.grand_total)
@@ -276,11 +276,11 @@
 	def calculate_outstanding_amount(self):
 		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.precision_of("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.precision_of("write_off_amount")), self.precision_of("total_amount_to_pay"))
 			self.doc.outstanding_amount = flt(self.doc.total_amount_to_pay - self.doc.total_advance,
-				self.precision.main.outstanding_amount)
+				self.precision_of("outstanding_amount"))
 			
 	def _cleanup(self):
 		for tax in self.tax_doclist:
@@ -319,7 +319,7 @@
 
 		if tax.charge_type == "Actual":
 			# distribute the tax amount proportionally to each item row
-			actual = flt(tax.rate, self.precision.tax.tax_amount)
+			actual = flt(tax.rate, self.precision_of("tax_amount", tax.parentfield))
 			current_tax_amount = (self.doc.net_total
 				and ((item.amount / self.doc.net_total) * actual)
 				or 0)
@@ -332,11 +332,11 @@
 			current_tax_amount = (tax_rate / 100.0) * \
 				self.tax_doclist[cint(tax.row_id) - 1].grand_total_for_current_item
 
-		return flt(current_tax_amount, self.precision.tax.tax_amount)
+		return flt(current_tax_amount, self.precision_of("tax_amount", tax.parentfield))
 		
 	def _get_tax_rate(self, tax, item_tax_map):
 		if item_tax_map.has_key(tax.account_head):
-			return flt(item_tax_map.get(tax.account_head), self.precision.tax.rate)
+			return flt(item_tax_map.get(tax.account_head), self.precision_of("rate", tax.parentfield))
 		else:
 			return tax.rate
 			
@@ -350,7 +350,7 @@
 		if tax.category in ["Valuation", "Valuation and Total"] and \
 				item.item_code in self.stock_items:
 			item.item_tax_amount += flt(current_tax_amount,
-				self.precision.item.item_tax_amount)
+				self.precision_of("item_tax_amount", item.parentfield))
 				
 	# update valuation rate
 	def update_valuation_rate(self, parentfield):
@@ -427,18 +427,6 @@
 		
 		return bom_items
 
-	
-	@property
-	def precision(self):
-		if not hasattr(self, "_precision"):
-			self._precision = webnotes._dict()
-			self._precision.main = self.meta.get_precision_map()
-			self._precision.item = self.meta.get_precision_map(parentfield = self.fname)
-			if self.meta.get_field("purchase_tax_details"):
-				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"):
diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py
index b22042d..b055ca4 100644
--- a/controllers/selling_controller.py
+++ b/controllers/selling_controller.py
@@ -16,9 +16,10 @@
 
 from __future__ import unicode_literals
 import webnotes
-from webnotes.utils import cint
+from webnotes.utils import cint, flt
 from setup.utils import get_company_currency
 from webnotes import msgprint, _
+import json
 
 from controllers.stock_controller import StockController
 
@@ -70,4 +71,280 @@
 				
 		if item.buying_amount and not item.cost_center:
 			msgprint(_("""Cost Center is mandatory for item: """) + item.item_code, 
-				raise_exception=1)
\ No newline at end of file
+				raise_exception=1)
+				
+	def calculate_taxes_and_totals(self):
+		self.doc.conversion_rate = flt(self.doc.conversion_rate)
+		self.item_doclist = self.doclist.get({"parentfield": self.fname})
+		self.tax_doclist = self.doclist.get({"parentfield": "other_charges"})
+		
+		self.calculate_item_values()
+		self.initialize_taxes()
+		
+		self.determin_exclusive_rate()
+		
+		# TODO
+		# code: save net_total_export on client side
+		# print format: show net_total_export instead of net_total
+		
+		self.calculate_net_total()
+		self.calculate_taxes()
+		self.calculate_totals()
+		# self.calculate_outstanding_amount()
+		# 
+		self._cleanup()
+		
+	def determin_exclusive_rate(self):
+		if not any((cint(tax.included_in_print_rate) for tax in self.tax_doclist)):
+			# no inclusive tax
+			return
+		
+		for item in self.item_doclist:
+			item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
+			cumulated_tax_fraction = 0
+			for i, tax in enumerate(self.tax_doclist):
+				if cint(tax.included_in_print_rate):
+					tax.tax_fraction_for_current_item = \
+						self.get_current_tax_fraction(tax, item_tax_map)
+				else:
+					tax.tax_fraction_for_current_item = 0
+					
+				if i==0:
+					tax.grand_total_fraction_for_current_item = 1 + \
+						tax.tax_fraction_for_current_item
+				else:
+					tax.grand_total_fraction_for_current_item = \
+						self.tax_doclist[i-1].grand_total_fraction_for_current_item \
+						+ tax.tax_fraction_for_current_item
+						
+				cumulated_tax_fraction += tax.tax_fraction_for_current_item
+			
+			if cumulated_tax_fraction:
+				item.basic_rate = flt((item.export_rate * self.doc.conversion_rate) / 
+					(1 + cumulated_tax_fraction), self.precision_of("basic_rate", item.parentfield))
+				
+				item.amount = flt(item.basic_rate * item.qty, self.precision_of("amount", item.parentfield))
+				
+				item.base_ref_rate = flt(item.basic_rate / (1 - (item.adj_rate / 100.0)),
+					self.precision_of("base_ref_rate", item.parentfield))
+			
+	def get_current_tax_fraction(self, tax, item_tax_map):
+		"""
+			Get tax fraction for calculating tax exclusive amount
+			from tax inclusive amount
+		"""
+		current_tax_fraction = 0
+		
+		if cint(tax.included_in_print_rate):
+			tax_rate = self._get_tax_rate(tax, item_tax_map)
+			
+			if tax.charge_type == "On Net Total":
+				current_tax_fraction = tax_rate / 100.0
+			
+			elif tax.charge_type == "On Previous Row Amount":
+				current_tax_fraction = (tax_rate / 100.0) * \
+					self.tax_doclist[cint(tax.row_id) - 1].tax_fraction_for_current_item
+			
+			elif tax.charge_type == "On Previous Row Total":
+				current_tax_fraction = (tax_rate / 100.0) * \
+					self.tax_doclist[cint(tax.row_id) - 1].grand_total_fraction_for_current_item
+						
+		return current_tax_fraction
+		
+	def calculate_item_values(self):
+		def _set_base(item, print_field, base_field):
+			"""set values in base currency"""
+			item.fields[base_field] = flt((flt(item.fields[print_field],
+				self.precision_of(print_field, item.parentfield)) * self.doc.conversion_rate),
+				self.precision_of(base_field, item.parentfield))
+
+		for item in self.item_doclist:
+			self.round_floats_in_doc(item, item.parentfield)
+			
+			if item.adj_rate == 100:
+				item.ref_rate = item.ref_rate or item.export_rate
+				item.export_rate = 0
+			else:
+				if item.ref_rate:
+					item.export_rate = flt(item.ref_rate * (1.0 - (item.adj_rate / 100.0)),
+						self.precision_of("export_rate", item.parentfield))
+				else:
+					# assume that print rate and discount are specified
+					item.ref_rate = flt(item.export_rate / (1.0 - (item.adj_rate / 100.0)),
+						self.precision_of("ref_rate", item.parentfield))
+						
+			item.export_amount = flt(item.export_rate * item.qty,
+				self.precision_of("export_amount", item.parentfield))
+				
+			_set_base(item, "ref_rate", "base_ref_rate")
+			_set_base(item, "export_rate", "basic_rate")
+			_set_base(item, "export_amount", "amount")
+	
+	def initialize_taxes(self):
+		for tax in self.tax_doclist:
+			tax.tax_amount = tax.total = 0.0
+			# temporary fields
+			tax.tax_amount_for_current_item = tax.grand_total_for_current_item = 0.0
+			tax.item_wise_tax_detail = {}
+			self.validate_on_previous_row(tax)
+			self.validate_inclusive_tax(tax)
+			self.round_floats_in_doc(tax, tax.parentfield)
+			
+	def calculate_net_total(self):
+		self.doc.net_total = 0
+		self.doc.net_total_export = 0
+
+		for item in self.item_doclist:
+			self.doc.net_total += item.amount
+			self.doc.net_total_export += item.export_amount
+			
+		self.doc.net_total = flt(self.doc.net_total, self.precision_of("net_total"))
+		self.doc.net_total_export = flt(self.doc.net_total_export,
+			self.precision_of("net_total_export"))
+		
+	def calculate_taxes(self):
+		for item in self.item_doclist:
+			item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
+
+			for i, tax in enumerate(self.tax_doclist):
+				# tax_amount represents the amount of tax for the current step
+				current_tax_amount = self.get_current_tax_amount(item, tax, item_tax_map)
+
+				# case when net total is 0 but there is an actual type charge
+				# in this case add the actual amount to tax.tax_amount
+				# and tax.grand_total_for_current_item for the first such iteration
+				if not (current_tax_amount or self.doc.net_total or tax.tax_amount) and \
+						tax.charge_type=="Actual":
+					zero_net_total_adjustment = flt(tax.rate, self.precision_of("tax_amount", tax.parentfield))
+					current_tax_amount += zero_net_total_adjustment
+
+				# store tax_amount for current item as it will be used for
+				# charge type = 'On Previous Row Amount'
+				tax.tax_amount_for_current_item = current_tax_amount
+
+				# accumulate tax amount into tax.tax_amount
+				tax.tax_amount += tax.tax_amount_for_current_item
+				
+				# Calculate tax.total viz. grand total till that step
+				# note: grand_total_for_current_item contains the contribution of 
+				# item's amount, previously applied tax and the current tax on that item
+				if i==0:
+					tax.grand_total_for_current_item = flt(item.amount +
+						current_tax_amount, self.precision_of("total", tax.parentfield))
+						
+				else:
+					tax.grand_total_for_current_item = \
+						flt(self.tax_doclist[i-1].grand_total_for_current_item +
+							current_tax_amount, self.precision_of("total", tax.parentfield))
+							
+				# in tax.total, accumulate grand total of each item
+				tax.total += tax.grand_total_for_current_item
+
+				# store tax_breakup for each item
+				# DOUBT: should valuation type amount also be stored?
+				tax.item_wise_tax_detail[item.item_code] = current_tax_amount
+				
+	def calculate_totals(self):
+		self.doc.grand_total = flt(self.tax_doclist and \
+			self.tax_doclist[-1].total or self.doc.net_total, self.precision_of("grand_total"))
+		self.doc.grand_total_export = flt(self.doc.grand_total / self.doc.conversion_rate, 
+			self.precision_of("grand_total_export"))
+		
+		self.doc.rounded_total = round(self.doc.grand_total)
+		self.doc.rounded_total_export = round(self.doc.grand_total_export)
+	
+	def get_current_tax_amount(self, item, tax, item_tax_map):
+		tax_rate = self._get_tax_rate(tax, item_tax_map)
+
+		if tax.charge_type == "Actual":
+			# distribute the tax amount proportionally to each item row
+			actual = flt(tax.rate, self.precision_of("tax_amount", tax.parentfield))
+			current_tax_amount = (self.doc.net_total
+				and ((item.amount / self.doc.net_total) * actual)
+				or 0)
+		elif tax.charge_type == "On Net Total":
+			current_tax_amount = (tax_rate / 100.0) * item.amount
+		elif tax.charge_type == "On Previous Row Amount":
+			current_tax_amount = (tax_rate / 100.0) * \
+				self.tax_doclist[cint(tax.row_id) - 1].tax_amount_for_current_item
+		elif tax.charge_type == "On Previous Row Total":
+			current_tax_amount = (tax_rate / 100.0) * \
+				self.tax_doclist[cint(tax.row_id) - 1].grand_total_for_current_item
+
+		return flt(current_tax_amount, self.precision_of("tax_amount", tax.parentfield))
+	
+	def validate_on_previous_row(self, tax):
+		"""
+			validate if a valid row id is mentioned in case of
+			On Previous Row Amount and On Previous Row Total
+		"""
+		if tax.charge_type in ["On Previous Row Amount", "On Previous Row Total"] and \
+				(not tax.row_id or cint(tax.row_id) >= tax.idx):
+			msgprint((_("Row") + " # %(idx)s [%(taxes_doctype)s]: " + \
+				_("Please specify a valid") + " %(row_id_label)s") % {
+					"idx": tax.idx,
+					"taxes_doctype": tax.parenttype,
+					"row_id_label": self.meta.get_label("row_id",
+						parentfield="other_charges")
+				}, raise_exception=True)
+				
+	def validate_inclusive_tax(self, tax):
+		def _on_previous_row_error(tax, row_range):
+			msgprint((_("Row") 
+				+ " # %(idx)s [%(taxes_doctype)s] [%(charge_type_label)s = \"%(charge_type)s\"]: " 
+				+ _("If:") + ' "%(inclusive_label)s" = ' + _("checked") + ", "
+				+ _("then it is required that:") + " [" + _("Row") + " # %(row_range)s] "
+				+ '"%(inclusive_label)s" = ' + _("checked")) % {
+					"idx": tax.idx,
+					"taxes_doctype": tax.doctype,
+					"inclusive_label": self.meta.get_label("included_in_print_rate",
+						parentfield="other_charges"),
+					"charge_type_label": self.meta.get_label("charge_type",
+						parentfield="other_charges"),
+					"charge_type": tax.charge_type,
+					"row_range": row_range
+				}, raise_exception=True)
+		
+		if cint(tax.included_in_print_rate):
+			if tax.charge_type == "Actual":
+				# inclusive cannot be of type Actual
+				msgprint((_("Row") 
+					+ " # %(idx)s [%(taxes_doctype)s]: %(charge_type_label)s = \"%(charge_type)s\" " 
+					+ "cannot be included in Item's rate") % {
+						"idx": tax.idx,
+						"taxes_doctype": tax.doctype,
+						"charge_type_label": self.meta.get_label("charge_type",
+							parentfield="other_charges"),
+						"charge_type": tax.charge_type,
+					}, raise_exception=True)
+			elif tax.charge_type == "On Previous Row Amount" and \
+					not cint(self.tax_doclist[tax.row_id - 1].included_in_print_rate):
+				# referred row should also be inclusive
+				_on_previous_row_error(tax, tax.row_id)
+			elif tax.charge_type == "On Previous Row Total" and \
+					not all([cint(t.included_in_print_rate) for t in self.tax_doclist[:tax.idx - 1]]):
+				# all rows about this tax should be inclusive
+				_on_previous_row_error(tax, "1 - %d" % (tax.idx - 1,))
+				
+	def _load_item_tax_rate(self, item_tax_rate):
+		if not item_tax_rate:
+			return {}
+		return json.loads(item_tax_rate)
+		
+	def _get_tax_rate(self, tax, item_tax_map):
+		if item_tax_map.has_key(tax.account_head):
+			return flt(item_tax_map.get(tax.account_head), self.precision_of("rate", tax.parentfield))
+		else:
+			return tax.rate
+				
+	def _cleanup(self):
+		for tax in self.tax_doclist:
+			del tax.fields["grand_total_for_current_item"]
+			del tax.fields["tax_amount_for_current_item"]
+			
+			for fieldname in ("tax_fraction_for_current_item", 
+				"grand_total_fraction_for_current_item"):
+				if fieldname in tax.fields:
+					del tax.fields[fieldname]
+			
+			tax.item_wise_tax_detail = json.dumps(tax.item_wise_tax_detail)
diff --git a/patches/may_2013/__init__.py b/patches/may_2013/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/patches/may_2013/__init__.py
diff --git a/patches/may_2013/p01_selling_net_total_export.py b/patches/may_2013/p01_selling_net_total_export.py
new file mode 100644
index 0000000..dd0f68a
--- /dev/null
+++ b/patches/may_2013/p01_selling_net_total_export.py
@@ -0,0 +1,10 @@
+from __future__ import unicode_literals
+import webnotes
+
+def execute():
+	for module, doctype in (("Accounts", "Sales Invoice"), ("Selling", "Sales Order"), ("Selling", "Quotation"), 
+		("Stock", "Delivery Note")):
+			webnotes.reload_doc(module, "DocType", doctype)
+			webnotes.conn.sql("""update `tab%s` 
+				set net_total_export = round(net_total / if(conversion_rate=0, 1, ifnull(conversion_rate, 1)), 2)""" %
+				(doctype,))
\ No newline at end of file
diff --git a/patches/patch_list.py b/patches/patch_list.py
index 432f8f9..0a1370e 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -250,4 +250,5 @@
 	"patches.april_2013.p07_update_file_data_2",
 	"patches.april_2013.rebuild_sales_browser",
 	"patches.april_2013.p08_price_list_country",
+	"patches.may_2013.p01_selling_net_total_export",
 ]
\ No newline at end of file
diff --git a/selling/doctype/quotation/quotation.txt b/selling/doctype/quotation/quotation.txt
index feda14c..24a080b 100644
--- a/selling/doctype/quotation/quotation.txt
+++ b/selling/doctype/quotation/quotation.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-04-03 09:10:44", 
+  "creation": "2013-05-06 12:03:40", 
   "docstatus": 0, 
-  "modified": "2013-04-03 09:58:02", 
+  "modified": "2013-05-06 13:07:37", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -239,13 +239,21 @@
   "oldfieldname": "net_total", 
   "oldfieldtype": "Currency", 
   "options": "Company:company:default_currency", 
-  "print_hide": 0, 
+  "print_hide": 1, 
   "read_only": 1, 
   "reqd": 0, 
   "width": "100px"
  }, 
  {
   "doctype": "DocField", 
+  "fieldname": "net_total_export", 
+  "fieldtype": "Currency", 
+  "label": "Net Total (Export)", 
+  "options": "currency", 
+  "read_only": 1
+ }, 
+ {
+  "doctype": "DocField", 
   "fieldname": "recalculate_values", 
   "fieldtype": "Button", 
   "label": "Re-Calculate Values", 
diff --git a/selling/doctype/sales_common/sales_common.js b/selling/doctype/sales_common/sales_common.js
index 8a8d8d0..1d020e6 100644
--- a/selling/doctype/sales_common/sales_common.js
+++ b/selling/doctype/sales_common/sales_common.js
@@ -518,6 +518,8 @@
 	if(flt(doc.conversion_rate)>1) {
 		net_total_incl *= flt(doc.conversion_rate);
 	}
+	
+	// TODO: store net_total_export
 
 	doc.net_total = inclusive_rate ? flt(net_total_incl) : flt(net_total);
 	doc.other_charges_total = roundNumber(flt(other_charges_total), 2);
diff --git a/selling/doctype/sales_order/sales_order.txt b/selling/doctype/sales_order/sales_order.txt
index ba0b1de..9780dc7 100644
--- a/selling/doctype/sales_order/sales_order.txt
+++ b/selling/doctype/sales_order/sales_order.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-03-07 14:48:34", 
+  "creation": "2013-05-06 12:03:43", 
   "docstatus": 0, 
-  "modified": "2013-01-29 17:14:58", 
+  "modified": "2013-05-06 13:06:37", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -251,13 +251,21 @@
   "oldfieldname": "net_total", 
   "oldfieldtype": "Currency", 
   "options": "Company:company:default_currency", 
-  "print_hide": 0, 
+  "print_hide": 1, 
   "read_only": 1, 
   "reqd": 0, 
   "width": "150px"
  }, 
  {
   "doctype": "DocField", 
+  "fieldname": "net_total_export", 
+  "fieldtype": "Currency", 
+  "label": "Net Total (Export)", 
+  "options": "currency", 
+  "read_only": 1
+ }, 
+ {
+  "doctype": "DocField", 
   "fieldname": "recalculate_values", 
   "fieldtype": "Button", 
   "label": "Re-Calculate Values", 
@@ -955,7 +963,6 @@
   "cancel": 0, 
   "create": 0, 
   "doctype": "DocPerm", 
-  "match": "", 
   "permlevel": 1, 
   "report": 0, 
   "role": "Sales Manager", 
@@ -978,7 +985,6 @@
   "cancel": 1, 
   "create": 1, 
   "doctype": "DocPerm", 
-  "match": "", 
   "permlevel": 0, 
   "report": 1, 
   "role": "Sales User", 
@@ -990,7 +996,6 @@
   "cancel": 0, 
   "create": 0, 
   "doctype": "DocPerm", 
-  "match": "", 
   "permlevel": 1, 
   "report": 0, 
   "role": "Sales User", 
@@ -1013,7 +1018,6 @@
   "cancel": 0, 
   "create": 0, 
   "doctype": "DocPerm", 
-  "match": "", 
   "permlevel": 1, 
   "role": "Maintenance Manager", 
   "submit": 0
@@ -1034,7 +1038,6 @@
   "cancel": 0, 
   "create": 0, 
   "doctype": "DocPerm", 
-  "match": "", 
   "permlevel": 1, 
   "role": "Maintenance User", 
   "submit": 0
diff --git a/stock/doctype/delivery_note/delivery_note.txt b/stock/doctype/delivery_note/delivery_note.txt
index 36c2789..6f299ef 100644
--- a/stock/doctype/delivery_note/delivery_note.txt
+++ b/stock/doctype/delivery_note/delivery_note.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-04-02 10:50:50", 
+  "creation": "2013-05-06 12:03:30", 
   "docstatus": 0, 
-  "modified": "2013-02-02 19:18:38", 
+  "modified": "2013-05-06 13:08:13", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -255,7 +255,7 @@
   "oldfieldname": "net_total", 
   "oldfieldtype": "Currency", 
   "options": "Company:company:default_currency", 
-  "print_hide": 0, 
+  "print_hide": 1, 
   "print_width": "150px", 
   "read_only": 1, 
   "reqd": 0, 
@@ -263,6 +263,14 @@
  }, 
  {
   "doctype": "DocField", 
+  "fieldname": "net_total_export", 
+  "fieldtype": "Currency", 
+  "label": "Net Total (Export)", 
+  "options": "currency", 
+  "read_only": 1
+ }, 
+ {
+  "doctype": "DocField", 
   "fieldname": "recalculate_values", 
   "fieldtype": "Button", 
   "label": "Re-Calculate Values", 
@@ -1136,7 +1144,6 @@
   "cancel": 0, 
   "create": 0, 
   "doctype": "DocPerm", 
-  "match": "", 
   "permlevel": 1, 
   "report": 0, 
   "role": "Material User", 
@@ -1159,7 +1166,6 @@
   "cancel": 0, 
   "create": 0, 
   "doctype": "DocPerm", 
-  "match": "", 
   "permlevel": 1, 
   "report": 0, 
   "role": "Material Manager", 
@@ -1171,7 +1177,6 @@
   "cancel": 1, 
   "create": 1, 
   "doctype": "DocPerm", 
-  "match": "", 
   "permlevel": 0, 
   "report": 1, 
   "role": "Sales User", 
@@ -1183,7 +1188,6 @@
   "cancel": 0, 
   "create": 0, 
   "doctype": "DocPerm", 
-  "match": "", 
   "permlevel": 1, 
   "report": 0, 
   "role": "Sales User", 
@@ -1205,7 +1209,6 @@
   "cancel": 0, 
   "create": 0, 
   "doctype": "DocPerm", 
-  "match": "", 
   "permlevel": 1, 
   "role": "Accounts User", 
   "submit": 0
diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py
index c3ce2d7..a9281cd 100644
--- a/stock/doctype/stock_entry/test_stock_entry.py
+++ b/stock/doctype/stock_entry/test_stock_entry.py
@@ -450,6 +450,7 @@
 		for d in pi.doclist.get({"parentfield": "entries"}):
 			d.expense_head = "_Test Account Cost for Goods Sold - _TC"
 			d.cost_center = "_Test Cost Center - _TC"
+			
 		for d in pi.doclist.get({"parentfield": "purchase_tax_details"}):
 			d.cost_center = "_Test Cost Center - _TC"