Fixed Test Cases frappe/frappe#478
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 41be553..04a9959 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -6,14 +6,12 @@
 import frappe.defaults
 
 from frappe.utils import add_days, cint, cstr, date_diff, flt, getdate, nowdate, \
-	get_first_day, get_last_day
-
-from frappe.utils import comma_and
+	get_first_day, get_last_day, comma_and
 from frappe.model.naming import make_autoname
-
 from frappe import _, msgprint
 
 from erpnext.accounts.party import get_party_account, get_due_date
+from erpnext.controllers.stock_controller import update_gl_entries_after
 
 month_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, 'Yearly': 12}
 
@@ -68,24 +66,24 @@
 		self.validate_c_form()
 		self.validate_time_logs_are_submitted()
 		self.validate_recurring_invoice()
-		self.validate_multiple_billing("Delivery Note", "dn_detail", "amount", 
+		self.validate_multiple_billing("Delivery Note", "dn_detail", "amount",
 			"delivery_note_details")
 
 	def on_submit(self):
-		if cint(self.update_stock) == 1:			
+		if cint(self.update_stock) == 1:
 			self.update_stock_ledger()
 		else:
 			# Check for Approving Authority
 			if not self.recurring_id:
-				frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype, 
+				frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
 				 	self.company, self.grand_total, self)
-				
+
 		self.check_prev_docstatus()
-		
+
 		self.update_status_updater_args()
 		self.update_prevdoc_status()
 		self.update_billing_status_for_zero_amount_refdoc("Sales Order")
-		
+
 		# this sequence because outstanding may get -ve
 		self.make_gl_entries()
 		self.check_credit_limit(self.debit_to)
@@ -103,18 +101,18 @@
 	def on_cancel(self):
 		if cint(self.update_stock) == 1:
 			self.update_stock_ledger()
-		
+
 		self.check_stop_sales_order("sales_order")
-		
+
 		from erpnext.accounts.utils import remove_against_link_from_jv
 		remove_against_link_from_jv(self.doctype, self.name, "against_invoice")
 
 		self.update_status_updater_args()
 		self.update_prevdoc_status()
 		self.update_billing_status_for_zero_amount_refdoc("Sales Order")
-		
+
 		self.make_cancel_gl_entries()
-		
+
 	def update_status_updater_args(self):
 		if cint(self.update_stock):
 			self.status_updater.append({
@@ -133,31 +131,31 @@
 				'second_source_field': 'qty',
 				'second_join_field': 'prevdoc_detail_docname'
 			})
-		
+
 	def on_update_after_submit(self):
 		self.validate_recurring_invoice()
 		self.convert_to_recurring()
-		
+
 	def get_portal_page(self):
 		return "invoice" if self.docstatus==1 else None
-		
+
 	def set_missing_values(self, for_validate=False):
 		self.set_pos_fields(for_validate)
-		
+
 		if not self.debit_to:
 			self.debit_to = get_party_account(self.company, self.customer, "Customer")
 		if not self.due_date:
 			self.due_date = get_due_date(self.posting_date, self.customer, "Customer",
 				self.debit_to, self.company)
-		
+
 		super(SalesInvoice, self).set_missing_values(for_validate)
-					
+
 	def update_time_log_batch(self, sales_invoice):
 		for d in self.get(self.fname):
 			if d.time_log_batch:
 				tlb = frappe.get_doc("Time Log Batch", d.time_log_batch)
 				tlb.sales_invoice = sales_invoice
-				tlb.update_after_submit()
+				tlb.save()
 
 	def validate_time_logs_are_submitted(self):
 		for d in self.get(self.fname):
@@ -171,10 +169,10 @@
 		"""Set retail related fields from pos settings"""
 		if cint(self.is_pos) != 1:
 			return
-		
-		from erpnext.stock.get_item_details import get_pos_settings_item_details, get_pos_settings	
+
+		from erpnext.stock.get_item_details import get_pos_settings_item_details, get_pos_settings
 		pos = get_pos_settings(self.company)
-			
+
 		if pos:
 			if not for_validate and not self.customer:
 				self.customer = pos.customer
@@ -184,31 +182,31 @@
 				'selling_price_list', 'company', 'select_print_heading', 'cash_bank_account'):
 					if (not for_validate) or (for_validate and not self.get(fieldname)):
 						self.set(fieldname, pos.get(fieldname))
-						
+
 			if not for_validate:
 				self.update_stock = cint(pos.get("update_stock"))
 
 			# set pos values in items
 			for item in self.get("entries"):
 				if item.get('item_code'):
-					for fname, val in get_pos_settings_item_details(pos, 
+					for fname, val in get_pos_settings_item_details(pos,
 						frappe._dict(item.as_dict()), pos).items():
-						
+
 						if (not for_validate) or (for_validate and not item.get(fname)):
 							item.set(fname, val)
 
-			# fetch terms	
+			# fetch terms
 			if self.tc_name and not self.terms:
 				self.terms = frappe.db.get_value("Terms and Conditions", self.tc_name, "terms")
-			
+
 			# fetch charges
 			if self.taxes_and_charges and not len(self.get("other_charges")):
 				self.set_taxes("other_charges", "taxes_and_charges")
-	
+
 	def get_advances(self):
-		super(SalesInvoice, self).get_advances(self.debit_to, 
+		super(SalesInvoice, self).get_advances(self.debit_to,
 			"Sales Invoice Advance", "advance_adjustment_details", "credit")
-		
+
 	def get_company_abbr(self):
 		return frappe.db.sql("select abbr from tabCompany where name=%s", self.company)[0][0]
 
@@ -219,32 +217,32 @@
 				2. split into multiple rows if partially adjusted, assign against voucher
 				3. submit advance voucher
 		"""
-		
+
 		lst = []
 		for d in self.get('advance_adjustment_details'):
 			if flt(d.allocated_amount) > 0:
 				args = {
-					'voucher_no' : d.journal_voucher, 
-					'voucher_detail_no' : d.jv_detail_no, 
-					'against_voucher_type' : 'Sales Invoice', 
+					'voucher_no' : d.journal_voucher,
+					'voucher_detail_no' : d.jv_detail_no,
+					'against_voucher_type' : 'Sales Invoice',
 					'against_voucher'  : self.name,
-					'account' : self.debit_to, 
-					'is_advance' : 'Yes', 
-					'dr_or_cr' : 'credit', 
+					'account' : self.debit_to,
+					'is_advance' : 'Yes',
+					'dr_or_cr' : 'credit',
 					'unadjusted_amt' : flt(d.advance_amount),
 					'allocated_amt' : flt(d.allocated_amount)
 				}
 				lst.append(args)
-		
+
 		if lst:
 			from erpnext.accounts.utils import reconcile_against_document
 			reconcile_against_document(lst)
-			
+
 	def validate_customer_account(self):
 		"""Validates Debit To Account and Customer Matches"""
 		if self.customer and self.debit_to and not cint(self.is_pos):
 			acc_head = frappe.db.sql("select master_name from `tabAccount` where name = %s and docstatus != 2", self.debit_to)
-			
+
 			if (acc_head and cstr(acc_head[0][0]) != cstr(self.customer)) or \
 				(not acc_head and (self.debit_to != cstr(self.customer) + " - " + self.get_company_abbr())):
 				msgprint("Debit To: %s do not match with Customer: %s for Company: %s.\n If both correctly entered, please select Master Type \
@@ -254,20 +252,20 @@
 	def validate_debit_acc(self):
 		if frappe.db.get_value("Account", self.debit_to, "report_type") != "Balance Sheet":
 			frappe.throw(_("Account must be a balance sheet account"))
-			
+
 	def validate_fixed_asset_account(self):
 		"""Validate Fixed Asset and whether Income Account Entered Exists"""
 		for d in self.get('entries'):
-			item = frappe.db.sql("""select name,is_asset_item,is_sales_item from `tabItem` 
-				where name = %s and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' 
+			item = frappe.db.sql("""select name,is_asset_item,is_sales_item from `tabItem`
+				where name = %s and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00'
 					or end_of_life > now())""", d.item_code)
-			acc =	frappe.db.sql("""select account_type from `tabAccount` 
+			acc =	frappe.db.sql("""select account_type from `tabAccount`
 				where name = %s and docstatus != 2""", d.income_account)
 			if not acc:
 				msgprint("Account: "+d.income_account+" does not exist in the system", raise_exception=True)
 			elif item and item[0][1] == 'Yes' and not acc[0][0] == 'Fixed Asset':
-				msgprint("Please select income head with account type 'Fixed Asset' as Item %s is an asset item" % d.item_code, raise_exception=True)				
-		
+				msgprint("Please select income head with account type 'Fixed Asset' as Item %s is an asset item" % d.item_code, raise_exception=True)
+
 	def validate_with_previous_doc(self):
 		super(SalesInvoice, self).validate_with_previous_doc(self.tname, {
 			"Sales Order": {
@@ -281,7 +279,7 @@
 					["currency", "="]],
 			},
 		})
-		
+
 		if cint(frappe.defaults.get_global_default('maintain_same_sales_rate')):
 			super(SalesInvoice, self).validate_with_previous_doc(self.tname, {
 				"Sales Order Item": {
@@ -296,7 +294,7 @@
 					"is_child_table": True
 				}
 			})
-			
+
 
 	def set_aging_date(self):
 		if self.is_opening != 'Yes':
@@ -304,7 +302,7 @@
 		elif not self.aging_date:
 			msgprint("Aging Date is mandatory for opening entry")
 			raise Exception
-			
+
 
 	def set_against_income_account(self):
 		"""Set against account for debit to account"""
@@ -333,8 +331,8 @@
 	def validate_proj_cust(self):
 		"""check for does customer belong to same project as entered.."""
 		if self.project_name and self.customer:
-			res = frappe.db.sql("""select name from `tabProject` 
-				where name = %s and (customer = %s or 
+			res = frappe.db.sql("""select name from `tabProject`
+				where name = %s and (customer = %s or
 					ifnull(customer,'')='')""", (self.project_name, self.customer))
 			if not res:
 				msgprint("Customer - %s does not belong to project - %s. \n\nIf you want to use project for multiple customers then please make customer details blank in that project."%(self.customer,self.project_name))
@@ -355,7 +353,7 @@
 			if not d.item_code:
 				msgprint("Please enter Item Code at line no : %s to update stock or remove check from Update Stock in Basic Info Tab." % (d.idx),
 				raise_exception=True)
-				
+
 	def validate_delivery_note(self):
 		for d in self.get("entries"):
 			if d.delivery_note:
@@ -374,7 +372,7 @@
 					and parent = %s""", (self.amended_from,	self.c_form_no))
 
 			frappe.db.set(self, 'c_form_no', '')
-			
+
 	def update_current_stock(self):
 		for d in self.get('entries'):
 			if d.item_code and d.warehouse:
@@ -385,15 +383,15 @@
 			bin = frappe.db.sql("select actual_qty, projected_qty from `tabBin` where item_code =	%s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
 			d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
 			d.projected_qty = bin and flt(bin[0]['projected_qty']) or 0
-	 
-	
+
+
 	def get_warehouse(self):
-		w = frappe.db.sql("""select warehouse from `tabPOS Setting` 
-			where ifnull(user,'') = %s and company = %s""", 
+		w = frappe.db.sql("""select warehouse from `tabPOS Setting`
+			where ifnull(user,'') = %s and company = %s""",
 			(frappe.session['user'], self.company))
 		w = w and w[0][0] or ''
 		if not w:
-			ps = frappe.db.sql("""select name, warehouse from `tabPOS Setting` 
+			ps = frappe.db.sql("""select name, warehouse from `tabPOS Setting`
 				where ifnull(user,'') = '' and company = %s""", self.company)
 			if not ps:
 				msgprint("To make POS entry, please create POS Setting from Accounts --> POS Setting page and refresh the system.", raise_exception=True)
@@ -417,11 +415,11 @@
 			make_packing_list(self, 'entries')
 		else:
 			self.set('packing_details', [])
-			
+
 		if cint(self.is_pos) == 1:
 			if flt(self.paid_amount) == 0:
-				if self.cash_bank_account: 
-					frappe.db.set(self, 'paid_amount', 
+				if self.cash_bank_account:
+					frappe.db.set(self, 'paid_amount',
 						(flt(self.grand_total) - flt(self.write_off_amount)))
 				else:
 					# show message that the amount is not paid
@@ -429,18 +427,18 @@
 					frappe.msgprint("Note: Payment Entry will not be created since 'Cash/Bank Account' was not specified.")
 		else:
 			frappe.db.set(self,'paid_amount',0)
-		
+
 	def check_prev_docstatus(self):
 		for d in self.get('entries'):
 			if d.sales_order:
-				submitted = frappe.db.sql("""select name from `tabSales Order` 
+				submitted = frappe.db.sql("""select name from `tabSales Order`
 					where docstatus = 1 and name = %s""", d.sales_order)
 				if not submitted:
 					msgprint("Sales Order : "+ cstr(d.sales_order) +" is not submitted")
 					raise Exception , "Validation Error."
 
 			if d.delivery_note:
-				submitted = frappe.db.sql("""select name from `tabDelivery Note` 
+				submitted = frappe.db.sql("""select name from `tabDelivery Note`
 					where docstatus = 1 and name = %s""", d.delivery_note)
 				if not submitted:
 					msgprint("Delivery Note : "+ cstr(d.delivery_note) +" is not submitted")
@@ -455,45 +453,44 @@
 					"actual_qty": -1*flt(d.qty),
 					"stock_uom": frappe.db.get_value("Item", d.item_code, "stock_uom")
 				}))
-		
+
 		self.make_sl_entries(sl_entries)
-		
+
 	def make_gl_entries(self, repost_future_gle=True):
 		gl_entries = self.get_gl_entries()
-		
+
 		if gl_entries:
 			from erpnext.accounts.general_ledger import make_gl_entries
-			
+
 			update_outstanding = cint(self.is_pos) and self.write_off_account \
 				and 'No' or 'Yes'
-			make_gl_entries(gl_entries, cancel=(self.docstatus == 2), 
+			make_gl_entries(gl_entries, cancel=(self.docstatus == 2),
 				update_outstanding=update_outstanding, merge_entries=False)
 
 			if repost_future_gle and cint(self.update_stock) \
 				and cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
 					items, warehouse_account = self.get_items_and_warehouse_accounts()
-					from controllers.stock_controller import update_gl_entries_after
-					update_gl_entries_after(self.posting_date, self.posting_time, 
+					update_gl_entries_after(self.posting_date, self.posting_time,
 						warehouse_account, items)
-				
+
 	def get_gl_entries(self, warehouse_account=None):
 		from erpnext.accounts.general_ledger import merge_similar_entries
-		
+
 		gl_entries = []
-		
+
 		self.make_customer_gl_entry(gl_entries)
-		
+
 		self.make_tax_gl_entries(gl_entries)
-		
+
 		self.make_item_gl_entries(gl_entries)
-		
+
 		# merge gl entries before adding pos entries
 		gl_entries = merge_similar_entries(gl_entries)
-		
+
 		self.make_pos_gl_entries(gl_entries)
-		
+
 		return gl_entries
-		
+
 	def make_customer_gl_entry(self, gl_entries):
 		if self.grand_total:
 			gl_entries.append(
@@ -506,7 +503,7 @@
 					"against_voucher_type": self.doctype,
 				})
 			)
-				
+
 	def make_tax_gl_entries(self, gl_entries):
 		for tax in self.get("other_charges"):
 			if flt(tax.tax_amount_after_discount_amount):
@@ -519,9 +516,9 @@
 						"cost_center": tax.cost_center
 					})
 				)
-				
-	def make_item_gl_entries(self, gl_entries):			
-		# income account gl entries	
+
+	def make_item_gl_entries(self, gl_entries):
+		# income account gl entries
 		for item in self.get("entries"):
 			if flt(item.base_amount):
 				gl_entries.append(
@@ -533,12 +530,12 @@
 						"cost_center": item.cost_center
 					})
 				)
-				
+
 		# expense account gl entries
 		if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) \
 				and cint(self.update_stock):
 			gl_entries += super(SalesInvoice, self).get_gl_entries()
-				
+
 	def make_pos_gl_entries(self, gl_entries):
 		if cint(self.is_pos) and self.cash_bank_account and self.paid_amount:
 			# POS, make payment entries
@@ -581,81 +578,81 @@
 						"cost_center": self.write_off_cost_center
 					})
 				)
-			
+
 	def update_c_form(self):
 		"""Update amended id in C-form"""
 		if self.c_form_no and self.amended_from:
 			frappe.db.sql("""update `tabC-Form Invoice Detail` set invoice_no = %s,
 				invoice_date = %s, territory = %s, net_total = %s,
-				grand_total = %s where invoice_no = %s and parent = %s""", 
+				grand_total = %s where invoice_no = %s and parent = %s""",
 				(self.name, self.amended_from, self.c_form_no))
-	
+
 	def validate_recurring_invoice(self):
 		if self.convert_into_recurring_invoice:
 			self.validate_notification_email_id()
-		
+
 			if not self.recurring_type:
 				msgprint(_("Please select: ") + self.meta.get_label("recurring_type"),
 				raise_exception=1)
-		
+
 			elif not (self.invoice_period_from_date and \
 					self.invoice_period_to_date):
 				msgprint(comma_and([self.meta.get_label("invoice_period_from_date"),
 					self.meta.get_label("invoice_period_to_date")])
 					+ _(": Mandatory for a Recurring Invoice."),
 					raise_exception=True)
-	
+
 	def convert_to_recurring(self):
 		if self.convert_into_recurring_invoice:
 			if not self.recurring_id:
 				frappe.db.set(self, "recurring_id",
 					make_autoname("RECINV/.#####"))
-			
+
 			self.set_next_date()
 
 		elif self.recurring_id:
 			frappe.db.sql("""update `tabSales Invoice`
 				set convert_into_recurring_invoice = 0
 				where recurring_id = %s""", (self.recurring_id,))
-			
+
 	def validate_notification_email_id(self):
 		if self.notification_email_address:
 			email_list = filter(None, [cstr(email).strip() for email in
 				self.notification_email_address.replace("\n", "").split(",")])
-			
+
 			from frappe.utils import validate_email_add
 			for email in email_list:
 				if not validate_email_add(email):
 					msgprint(self.meta.get_label("notification_email_address") \
 						+ " - " + _("Invalid Email Address") + ": \"%s\"" % email,
 						raise_exception=1)
-					
+
 		else:
 			msgprint("Notification Email Addresses not specified for recurring invoice",
 				raise_exception=1)
-				
+
 	def set_next_date(self):
 		""" Set next date on which auto invoice will be created"""
 		if not self.repeat_on_day_of_month:
-			msgprint("""Please enter 'Repeat on Day of Month' field value. 
-				The day of the month on which auto invoice 
+			msgprint("""Please enter 'Repeat on Day of Month' field value.
+				The day of the month on which auto invoice
 				will be generated e.g. 05, 28 etc.""", raise_exception=1)
-		
+
 		next_date = get_next_date(self.posting_date,
 			month_map[self.recurring_type], cint(self.repeat_on_day_of_month))
-		
+
 		frappe.db.set(self, 'next_date', next_date)
-	
+
 def get_next_date(dt, mcount, day=None):
 	dt = getdate(dt)
-	
+
 	from dateutil.relativedelta import relativedelta
 	dt += relativedelta(months=mcount, day=day)
-	
+
 	return dt
-	
+
 def manage_recurring_invoices(next_date=None, commit=True):
-	""" 
+	"""
 		Create recurring invoices on specific date by copying the original one
 		and notify the concerned people
 	"""
@@ -664,7 +661,7 @@
 		from `tabSales Invoice` where ifnull(convert_into_recurring_invoice, 0)=1
 		and docstatus=1 and next_date=%s
 		and next_date <= ifnull(end_date, '2199-12-31')""", next_date)
-	
+
 	exception_list = []
 	for ref_invoice, recurring_id in recurring_invoices:
 		if not frappe.db.sql("""select name from `tabSales Invoice`
@@ -690,21 +687,20 @@
 			finally:
 				if commit:
 					frappe.db.begin()
-			
+
 	if exception_list:
 		exception_message = "\n\n".join([cstr(d) for d in exception_list])
 		raise Exception, exception_message
 
 def make_new_invoice(ref_wrapper, posting_date):
-	from frappe.model.doc import clone
 	from erpnext.accounts.utils import get_fiscal_year
-	new_invoice = clone(ref_wrapper)
-	
+	new_invoice = frappe.copy_doc(ref_wrapper)
+
 	mcount = month_map[ref_wrapper.recurring_type]
-	
+
 	invoice_period_from_date = get_next_date(ref_wrapper.invoice_period_from_date, mcount)
-	
-	# get last day of the month to maintain period if the from date is first day of its own month 
+
+	# get last day of the month to maintain period if the from date is first day of its own month
 	# and to date is the last day of its own month
 	if (cstr(get_first_day(ref_wrapper.invoice_period_from_date)) == \
 			cstr(ref_wrapper.invoice_period_from_date)) and \
@@ -714,7 +710,7 @@
 			mcount))
 	else:
 		invoice_period_to_date = get_next_date(ref_wrapper.invoice_period_to_date, mcount)
-	
+
 	new_invoice.update({
 		"posting_date": posting_date,
 		"aging_date": posting_date,
@@ -725,30 +721,30 @@
 		"fiscal_year": get_fiscal_year(posting_date)[0],
 		"owner": ref_wrapper.owner,
 	})
-	
+
 	new_invoice.submit()
-	
+
 	return new_invoice
-	
+
 def send_notification(new_rv):
 	"""Notify concerned persons about recurring invoice generation"""
-	
+
 	from frappe.core.doctype.print_format.print_format import get_html
-	frappe.sendmail(new_rv.notification_email_address, 
-		subject="New Invoice : " + new_rv.name, 
+	frappe.sendmail(new_rv.notification_email_address,
+		subject="New Invoice : " + new_rv.name,
 		message = get_html(new_rv, new_rv, "SalesInvoice"))
-		
+
 def notify_errors(inv, customer, owner):
 	from frappe.utils.user import get_system_managers
 	recipients=get_system_managers()
-	
+
 	frappe.sendmail(recipients + [frappe.db.get_value("User", owner, "email")],
 		subject="[Urgent] Error while creating recurring invoice for %s" % inv,
 		message = frappe.get_template("template/emails/recurring_invoice_failed.html").render({
 			"name": inv,
 			"customer": customer
 		}))
-	
+
 	assign_task_to_owner(inv, "Recurring Invoice Failed", recipients)
 
 def assign_task_to_owner(inv, msg, users):
@@ -776,64 +772,64 @@
 def get_income_account(doctype, txt, searchfield, start, page_len, filters):
 	from erpnext.controllers.queries import get_match_cond
 
-	# income account can be any Credit account, 
-	# but can also be a Asset account with account_type='Income Account' in special circumstances. 
+	# income account can be any Credit account,
+	# but can also be a Asset account with account_type='Income Account' in special circumstances.
 	# Hence the first condition is an "OR"
-	return frappe.db.sql("""select tabAccount.name from `tabAccount` 
+	return frappe.db.sql("""select tabAccount.name from `tabAccount`
 			where (tabAccount.report_type = "Profit and Loss"
-					or tabAccount.account_type = "Income Account") 
-				and tabAccount.group_or_ledger="Ledger" 
+					or tabAccount.account_type = "Income Account")
+				and tabAccount.group_or_ledger="Ledger"
 				and tabAccount.docstatus!=2
 				and ifnull(tabAccount.master_type, "")=""
 				and ifnull(tabAccount.master_name, "")=""
-				and tabAccount.company = '%(company)s' 
+				and tabAccount.company = '%(company)s'
 				and tabAccount.%(key)s LIKE '%(txt)s'
-				%(mcond)s""" % {'company': filters['company'], 'key': searchfield, 
+				%(mcond)s""" % {'company': filters['company'], 'key': searchfield,
 			'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype)})
 
 
 @frappe.whitelist()
 def make_delivery_note(source_name, target_doc=None):
 	from frappe.model.mapper import get_mapped_doc
-	
+
 	def set_missing_values(source, target):
 		doc = frappe.get_doc(target)
 		doc.run_method("onload_post_render")
-		
+
 	def update_item(source_doc, target_doc, source_parent):
 		target_doc.base_amount = (flt(source_doc.qty) - flt(source_doc.delivered_qty)) * \
 			flt(source_doc.base_rate)
 		target_doc.amount = (flt(source_doc.qty) - flt(source_doc.delivered_qty)) * \
 			flt(source_doc.rate)
 		target_doc.qty = flt(source_doc.qty) - flt(source_doc.delivered_qty)
-	
+
 	doclist = get_mapped_doc("Sales Invoice", source_name, 	{
 		"Sales Invoice": {
-			"doctype": "Delivery Note", 
+			"doctype": "Delivery Note",
 			"validation": {
 				"docstatus": ["=", 1]
 			}
-		}, 
+		},
 		"Sales Invoice Item": {
-			"doctype": "Delivery Note Item", 
+			"doctype": "Delivery Note Item",
 			"field_map": {
-				"name": "prevdoc_detail_docname", 
-				"parent": "against_sales_invoice", 
+				"name": "prevdoc_detail_docname",
+				"parent": "against_sales_invoice",
 				"serial_no": "serial_no"
 			},
 			"postprocess": update_item
-		}, 
+		},
 		"Sales Taxes and Charges": {
-			"doctype": "Sales Taxes and Charges", 
+			"doctype": "Sales Taxes and Charges",
 			"add_if_empty": True
-		}, 
+		},
 		"Sales Team": {
-			"doctype": "Sales Team", 
+			"doctype": "Sales Team",
 			"field_map": {
 				"incentives": "incentives"
 			},
 			"add_if_empty": True
 		}
 	}, target_doc, set_missing_values)
-	
-	return doclist.as_dict()
\ No newline at end of file
+
+	return doclist
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 8baeb76..2a0bc24 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -2,7 +2,7 @@
 # License: GNU General Public License v3. See license.txt
 
 import frappe
-import unittest, json
+import unittest, json, copy
 from frappe.utils import flt
 from erpnext.accounts.utils import get_stock_and_account_difference
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
@@ -14,57 +14,46 @@
 		w.insert()
 		w.submit()
 		return w
-		
-	def test_double_submission(self):
-		w = frappe.copy_doc(test_records[0])
-		w.docstatus = '0'
-		w.insert()
-		
-		w2 = frappe.copy_doc(test_records[0])
-		w.submit()
-		
-		w = frappe.get_doc(w2)
-		self.assertRaises(frappe.DocstatusTransitionError, w.submit)
-		
+
 	def test_timestamp_change(self):
 		w = frappe.copy_doc(test_records[0])
-		w.docstatus = '0'
+		w.docstatus = 0
 		w.insert()
 
-		w2 = frappe.copy_doc(w)
-		
+		w2 = frappe.get_doc(w.doctype, w.name)
+
 		import time
 		time.sleep(1)
 		w.save()
-		
+
 		import time
 		time.sleep(1)
 		self.assertRaises(frappe.TimestampMismatchError, w2.save)
-		
+
 	def test_sales_invoice_calculation_base_currency(self):
 		si = frappe.copy_doc(test_records[2])
 		si.insert()
-		
+
 		expected_values = {
-			"keys": ["price_list_rate", "discount_percentage", "rate", "amount", 
+			"keys": ["price_list_rate", "discount_percentage", "rate", "amount",
 				"base_price_list_rate", "base_rate", "base_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.get("entries")),
 			len(expected_values)-1)
-		
+
 		# check if item values are calculated
 		for d in si.get("entries"):
 			for i, k in enumerate(expected_values["keys"]):
 				self.assertEquals(d.get(k), expected_values[d.item_code][i])
-		
+
 		# check net total
 		self.assertEquals(si.net_total, 1250)
 		self.assertEquals(si.net_total_export, 1250)
-		
+
 		# check tax calculation
 		expected_values = {
 			"keys": ["tax_amount", "total"],
@@ -77,14 +66,14 @@
 			"_Test Account VAT - _TC": [156.25, 1807.83],
 			"_Test Account Discount - _TC": [-180.78, 1627.05]
 		}
-		
+
 		for d in si.get("other_charges"):
 			for i, k in enumerate(expected_values["keys"]):
 				self.assertEquals(d.get(k), expected_values[d.account_head][i])
-				
+
 		self.assertEquals(si.grand_total, 1627.05)
 		self.assertEquals(si.grand_total_export, 1627.05)
-		
+
 	def test_sales_invoice_calculation_export_currency(self):
 		si = frappe.copy_doc(test_records[2])
 		si.currency = "USD"
@@ -94,27 +83,27 @@
 		si.get("entries")[1].rate = 3
 		si.get("entries")[1].price_list_rate = 3
 		si.insert()
-		
+
 		expected_values = {
-			"keys": ["price_list_rate", "discount_percentage", "rate", "amount", 
+			"keys": ["price_list_rate", "discount_percentage", "rate", "amount",
 				"base_price_list_rate", "base_rate", "base_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.get("entries")),
 			len(expected_values)-1)
-		
+
 		# check if item values are calculated
 		for d in si.get("entries"):
 			for i, k in enumerate(expected_values["keys"]):
 				self.assertEquals(d.get(k), expected_values[d.item_code][i])
-		
+
 		# check net total
 		self.assertEquals(si.net_total, 1250)
 		self.assertEquals(si.net_total_export, 25)
-		
+
 		# check tax calculation
 		expected_values = {
 			"keys": ["tax_amount", "total"],
@@ -127,11 +116,11 @@
 			"_Test Account VAT - _TC": [156.25, 1807.83],
 			"_Test Account Discount - _TC": [-180.78, 1627.05]
 		}
-		
+
 		for d in si.get("other_charges"):
 			for i, k in enumerate(expected_values["keys"]):
 				self.assertEquals(d.get(k), expected_values[d.account_head][i])
-				
+
 		self.assertEquals(si.grand_total, 1627.05)
 		self.assertEquals(si.grand_total_export, 32.54)
 
@@ -148,27 +137,27 @@
 			"row_id": 8,
 		})
 		si.insert()
-		
+
 		expected_values = {
-			"keys": ["price_list_rate", "discount_percentage", "rate", "amount", 
+			"keys": ["price_list_rate", "discount_percentage", "rate", "amount",
 				"base_price_list_rate", "base_rate", "base_amount"],
 			"_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 50, 50, 465.37],
 			"_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 150, 150, 698.08],
 		}
-		
+
 		# check if children are saved
 		self.assertEquals(len(si.get("entries")),
 			len(expected_values)-1)
-		
+
 		# check if item values are calculated
 		for d in si.get("entries"):
 			for i, k in enumerate(expected_values["keys"]):
 				self.assertEquals(d.get(k), expected_values[d.item_code][i])
-		
+
 		# check net total
 		self.assertEquals(si.net_total, 1163.45)
 		self.assertEquals(si.net_total_export, 1578.3)
-		
+
 		# check tax calculation
 		expected_values = {
 			"keys": ["tax_amount", "tax_amount_after_discount_amount", "total"],
@@ -182,11 +171,11 @@
 			"_Test Account Discount - _TC": [-180.33, -168.54, 1516.88],
 			"_Test Account Service Tax - _TC": [-18.03, -16.88, 1500]
 		}
-		
+
 		for d in si.get("other_charges"):
 			for i, k in enumerate(expected_values["keys"]):
 				self.assertEquals(d.get(k), expected_values[d.account_head][i])
-				
+
 		self.assertEquals(si.grand_total, 1500)
 		self.assertEquals(si.grand_total_export, 1500)
 
@@ -213,15 +202,15 @@
 
 		expected_values = sorted([
 			[si.debit_to, 1500, 0.0],
-			[test_records[3][1]["income_account"], 0.0, 1163.45],
-			[test_records[3][3]["account_head"], 0.0, 130.31],
-			[test_records[3][4]["account_head"], 0.0, 2.61],
-			[test_records[3][5]["account_head"], 0.0, 1.31],
-			[test_records[3][6]["account_head"], 0.0, 25.96],
-			[test_records[3][7]["account_head"], 0.0, 145.43],
-			[test_records[3][8]["account_head"], 0.0, 116.35],
-			[test_records[3][9]["account_head"], 0.0, 100],
-			[test_records[3][10]["account_head"], 168.54, 0.0],
+			[test_records[3]["entries"][0]["income_account"], 0.0, 1163.45],
+			[test_records[3]["other_charges"][0]["account_head"], 0.0, 130.31],
+			[test_records[3]["other_charges"][1]["account_head"], 0.0, 2.61],
+			[test_records[3]["other_charges"][2]["account_head"], 0.0, 1.31],
+			[test_records[3]["other_charges"][3]["account_head"], 0.0, 25.96],
+			[test_records[3]["other_charges"][4]["account_head"], 0.0, 145.43],
+			[test_records[3]["other_charges"][5]["account_head"], 0.0, 116.35],
+			[test_records[3]["other_charges"][6]["account_head"], 0.0, 100],
+			[test_records[3]["other_charges"][7]["account_head"], 168.54, 0.0],
 			["_Test Account Service Tax - _TC", 16.88, 0.0],
 		])
 
@@ -233,7 +222,7 @@
 		# cancel
 		si.cancel()
 
-		gle = frappe.db.sql("""select * from `tabGL Entry` 
+		gle = frappe.db.sql("""select * from `tabGL Entry`
 			where voucher_type='Sales Invoice' and voucher_no=%s""", si.name)
 
 		self.assertFalse(gle)
@@ -242,44 +231,44 @@
 		si = frappe.copy_doc(test_records[2])
 		for i, tax in enumerate(si.get("other_charges")):
 			tax.idx = i+1
-		
+
 		si.get("entries")[0].price_list_rate = 62.5
 		si.get("entries")[0].price_list_rate = 191
-		for i in [2, 4, 5, 6, 7, 8]:
+		for i in xrange(6):
 			si.get("other_charges")[i].included_in_print_rate = 1
-		
+
 		# tax type "Actual" cannot be inclusive
 		self.assertRaises(frappe.ValidationError, si.insert)
-		
+
 		# taxes above included type 'On Previous Row Total' should also be included
 		si.get("other_charges")[0].included_in_print_rate = 0
 		self.assertRaises(frappe.ValidationError, si.insert)
-		
+
 	def test_sales_invoice_calculation_base_currency_with_tax_inclusive_price(self):
 		# prepare
 		si = frappe.copy_doc(test_records[3])
 		si.insert()
-		
+
 		expected_values = {
-			"keys": ["price_list_rate", "discount_percentage", "rate", "amount", 
+			"keys": ["price_list_rate", "discount_percentage", "rate", "amount",
 				"base_price_list_rate", "base_rate", "base_amount"],
 			"_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 50, 50, 499.98],
 			"_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 150, 150, 750],
 		}
-		
+
 		# check if children are saved
 		self.assertEquals(len(si.get("entries")),
 			len(expected_values)-1)
-		
+
 		# check if item values are calculated
 		for d in si.get("entries"):
 			for i, k in enumerate(expected_values["keys"]):
 				self.assertEquals(d.get(k), expected_values[d.item_code][i])
-		
+
 		# check net total
 		self.assertEquals(si.net_total, 1249.98)
 		self.assertEquals(si.net_total_export, 1578.3)
-		
+
 		# check tax calculation
 		expected_values = {
 			"keys": ["tax_amount", "total"],
@@ -292,14 +281,14 @@
 			"_Test Account Shipping Charges - _TC": [100, 1803.31],
 			"_Test Account Discount - _TC": [-180.33, 1622.98]
 		}
-		
+
 		for d in si.get("other_charges"):
 			for i, k in enumerate(expected_values["keys"]):
 				self.assertEquals(d.get(k), expected_values[d.account_head][i])
-		
+
 		self.assertEquals(si.grand_total, 1622.98)
 		self.assertEquals(si.grand_total_export, 1622.98)
-		
+
 	def test_sales_invoice_calculation_export_currency_with_tax_inclusive_price(self):
 		# prepare
 		si = frappe.copy_doc(test_records[3])
@@ -309,30 +298,29 @@
 		si.get("entries")[0].discount_percentage = 10
 		si.get("entries")[1].price_list_rate = 187.5
 		si.get("entries")[1].discount_percentage = 20
-		si.get("other_charges")[5].rate = 5000
-		
+		si.get("other_charges")[6].rate = 5000
+
 		si.insert()
-		
+
 		expected_values = {
-			"keys": ["price_list_rate", "discount_percentage", "rate", "amount", 
+			"keys": ["price_list_rate", "discount_percentage", "rate", "amount",
 				"base_price_list_rate", "base_rate", "base_amount"],
 			"_Test Item Home Desktop 100": [55.56, 10, 50, 500, 2222.11, 1999.9, 19999.04],
 			"_Test Item Home Desktop 200": [187.5, 20, 150, 750, 7375.66, 5900.53, 29502.66],
 		}
-		
+
 		# check if children are saved
-		self.assertEquals(len(si.get("entries")),
-			len(expected_values)-1)
-		
+		self.assertEquals(len(si.get("entries")), len(expected_values)-1)
+
 		# check if item values are calculated
 		for d in si.get("entries"):
 			for i, k in enumerate(expected_values["keys"]):
 				self.assertEquals(d.get(k), expected_values[d.item_code][i])
-		
+
 		# check net total
 		self.assertEquals(si.net_total, 49501.7)
 		self.assertEquals(si.net_total_export, 1250)
-		
+
 		# check tax calculation
 		expected_values = {
 			"keys": ["tax_amount", "total"],
@@ -345,134 +333,134 @@
 			"_Test Account Shipping Charges - _TC": [5000, 72450.17],
 			"_Test Account Discount - _TC": [-7245.01, 65205.16]
 		}
-		
+
 		for d in si.get("other_charges"):
 			for i, k in enumerate(expected_values["keys"]):
 				self.assertEquals(d.get(k), expected_values[d.account_head][i])
-		
+
 		self.assertEquals(si.grand_total, 65205.16)
 		self.assertEquals(si.grand_total_export, 1304.1)
 
 	def test_outstanding(self):
 		w = self.make()
 		self.assertEquals(w.outstanding_amount, w.grand_total)
-		
+
 	def test_payment(self):
 		frappe.db.sql("""delete from `tabGL Entry`""")
 		w = self.make()
-		
+
 		from erpnext.accounts.doctype.journal_voucher.test_journal_voucher \
 			import test_records as jv_test_records
-			
+
 		jv = frappe.get_doc(frappe.copy_doc(jv_test_records[0]))
 		jv.get("entries")[0].against_invoice = w.name
 		jv.insert()
 		jv.submit()
-		
+
 		self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"),
 			161.8)
-	
+
 		jv.cancel()
 		self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"),
 			561.8)
-			
+
 	def test_time_log_batch(self):
 		tlb = frappe.get_doc("Time Log Batch", "_T-Time Log Batch-00001")
 		tlb.submit()
-		
+
 		si = frappe.get_doc(frappe.copy_doc(test_records[0]))
 		si.get("entries")[0].time_log_batch = "_T-Time Log Batch-00001"
 		si.insert()
 		si.submit()
-		
+
 		self.assertEquals(frappe.db.get_value("Time Log Batch", "_T-Time Log Batch-00001",
 		 	"status"), "Billed")
 
-		self.assertEquals(frappe.db.get_value("Time Log", "_T-Time Log-00001", "status"), 
+		self.assertEquals(frappe.db.get_value("Time Log", "_T-Time Log-00001", "status"),
 			"Billed")
 
 		si.cancel()
 
-		self.assertEquals(frappe.db.get_value("Time Log Batch", "_T-Time Log Batch-00001", 
+		self.assertEquals(frappe.db.get_value("Time Log Batch", "_T-Time Log Batch-00001",
 			"status"), "Submitted")
 
-		self.assertEquals(frappe.db.get_value("Time Log", "_T-Time Log-00001", "status"), 
+		self.assertEquals(frappe.db.get_value("Time Log", "_T-Time Log-00001", "status"),
 			"Batched for Billing")
-			
+
 	def test_sales_invoice_gl_entry_without_aii(self):
 		self.clear_stock_account_balance()
 		set_perpetual_inventory(0)
 		si = frappe.copy_doc(test_records[1])
 		si.insert()
 		si.submit()
-		
+
 		gl_entries = frappe.db.sql("""select account, debit, credit
 			from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
 			order by account asc""", si.name, as_dict=1)
-		
+
 		self.assertTrue(gl_entries)
-		
+
 		expected_values = sorted([
 			[si.debit_to, 630.0, 0.0],
-			[test_records[1][1]["income_account"], 0.0, 500.0],
-			[test_records[1][2]["account_head"], 0.0, 80.0],
-			[test_records[1][3]["account_head"], 0.0, 50.0],
+			[test_records[1]["entries"][0]["income_account"], 0.0, 500.0],
+			[test_records[1]["other_charges"][0]["account_head"], 0.0, 80.0],
+			[test_records[1]["other_charges"][1]["account_head"], 0.0, 50.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)
-			
+
 		# cancel
 		si.cancel()
-		
-		gle = frappe.db.sql("""select * from `tabGL Entry` 
+
+		gle = frappe.db.sql("""select * from `tabGL Entry`
 			where voucher_type='Sales Invoice' and voucher_no=%s""", si.name)
-		
+
 		self.assertFalse(gle)
-		
+
 	def test_pos_gl_entry_with_aii(self):
 		self.clear_stock_account_balance()
 		set_perpetual_inventory()
-		
+
 		self._insert_purchase_receipt()
 		self._insert_pos_settings()
-		
-		pos = frappe.copy_doc(test_records[1])
-		pos[0]["is_pos"] = 1
-		pos[0]["update_stock"] = 1
-		pos[0]["posting_time"] = "12:05"
-		pos[0]["cash_bank_account"] = "_Test Account Bank Account - _TC"
-		pos[0]["paid_amount"] = 600.0
+
+		pos = copy.deepcopy(test_records[1])
+		pos["is_pos"] = 1
+		pos["update_stock"] = 1
+		pos["posting_time"] = "12:05"
+		pos["cash_bank_account"] = "_Test Account Bank Account - _TC"
+		pos["paid_amount"] = 600.0
 
 		si = frappe.copy_doc(pos)
 		si.insert()
 		si.submit()
-		
+
 		# check stock ledger entries
-		sle = frappe.db.sql("""select * from `tabStock Ledger Entry` 
-			where voucher_type = 'Sales Invoice' and voucher_no = %s""", 
+		sle = frappe.db.sql("""select * from `tabStock Ledger Entry`
+			where voucher_type = 'Sales Invoice' and voucher_no = %s""",
 			si.name, as_dict=1)[0]
 		self.assertTrue(sle)
-		self.assertEquals([sle.item_code, sle.warehouse, sle.actual_qty], 
+		self.assertEquals([sle.item_code, sle.warehouse, sle.actual_qty],
 			["_Test Item", "_Test Warehouse - _TC", -1.0])
-		
+
 		# check gl entries
 		gl_entries = frappe.db.sql("""select account, debit, credit
 			from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
 			order by account asc, debit asc""", si.name, as_dict=1)
 		self.assertTrue(gl_entries)
-		
+
 		stock_in_hand = frappe.db.get_value("Account", {"master_name": "_Test Warehouse - _TC"})
-				
+
 		expected_gl_entries = sorted([
 			[si.debit_to, 630.0, 0.0],
-			[pos[1]["income_account"], 0.0, 500.0],
-			[pos[2]["account_head"], 0.0, 80.0],
-			[pos[3]["account_head"], 0.0, 50.0],
+			[pos["entries"][0]["income_account"], 0.0, 500.0],
+			[pos["other_charges"][0]["account_head"], 0.0, 80.0],
+			[pos["other_charges"][1]["account_head"], 0.0, 50.0],
 			[stock_in_hand, 0.0, 75.0],
-			[pos[1]["expense_account"], 75.0, 0.0],
+			[pos["entries"][0]["expense_account"], 75.0, 0.0],
 			[si.debit_to, 0.0, 600.0],
 			["_Test Account Bank Account - _TC", 600.0, 0.0]
 		])
@@ -480,57 +468,57 @@
 			self.assertEquals(expected_gl_entries[i][0], gle.account)
 			self.assertEquals(expected_gl_entries[i][1], gle.debit)
 			self.assertEquals(expected_gl_entries[i][2], gle.credit)
-		
+
 		si.cancel()
-		gle = frappe.db.sql("""select * from `tabGL Entry` 
+		gle = frappe.db.sql("""select * from `tabGL Entry`
 			where voucher_type='Sales Invoice' and voucher_no=%s""", si.name)
-		
+
 		self.assertFalse(gle)
-		
+
 		self.assertFalse(get_stock_and_account_difference([stock_in_hand]))
-		
+
 		set_perpetual_inventory(0)
-		
+
 	def test_si_gl_entry_with_aii_and_update_stock_with_warehouse_but_no_account(self):
 		self.clear_stock_account_balance()
 		set_perpetual_inventory()
 		frappe.delete_doc("Account", "_Test Warehouse No Account - _TC")
-		
+
 		# insert purchase receipt
 		from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import test_records \
 			as pr_test_records
 		pr = frappe.copy_doc(pr_test_records[0])
 		pr.naming_series = "_T-Purchase Receipt-"
-		pr.get("entries")[0].warehouse = "_Test Warehouse No Account - _TC"
+		pr.get("purchase_receipt_details")[0].warehouse = "_Test Warehouse No Account - _TC"
 		pr.insert()
 		pr.submit()
-		
-		si_doc = frappe.copy_doc(test_records[1])
+
+		si_doc = copy.deepcopy(test_records[1])
 		si_doc["update_stock"] = 1
 		si_doc["posting_time"] = "12:05"
-		si_doc.get("entries")["warehouse"] = "_Test Warehouse No Account - _TC"
+		si_doc.get("entries")[0]["warehouse"] = "_Test Warehouse No Account - _TC"
 
 		si = frappe.copy_doc(si_doc)
 		si.insert()
 		si.submit()
-		
+
 		# check stock ledger entries
-		sle = frappe.db.sql("""select * from `tabStock Ledger Entry` 
-			where voucher_type = 'Sales Invoice' and voucher_no = %s""", 
+		sle = frappe.db.sql("""select * from `tabStock Ledger Entry`
+			where voucher_type = 'Sales Invoice' and voucher_no = %s""",
 			si.name, as_dict=1)[0]
 		self.assertTrue(sle)
-		self.assertEquals([sle.item_code, sle.warehouse, sle.actual_qty], 
+		self.assertEquals([sle.item_code, sle.warehouse, sle.actual_qty],
 			["_Test Item", "_Test Warehouse No Account - _TC", -1.0])
-		
+
 		# check gl entries
 		gl_entries = frappe.db.sql("""select account, debit, credit
 			from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
 			order by account asc, debit asc""", si.name, as_dict=1)
 		self.assertTrue(gl_entries)
-		
+
 		expected_gl_entries = sorted([
 			[si.debit_to, 630.0, 0.0],
-			[si_doc.get("entries")["income_account"], 0.0, 500.0],
+			[si_doc.get("entries")[0]["income_account"], 0.0, 500.0],
 			[si_doc.get("other_charges")[0]["account_head"], 0.0, 80.0],
 			[si_doc.get("other_charges")[1]["account_head"], 0.0, 50.0],
 		])
@@ -538,69 +526,67 @@
 			self.assertEquals(expected_gl_entries[i][0], gle.account)
 			self.assertEquals(expected_gl_entries[i][1], gle.debit)
 			self.assertEquals(expected_gl_entries[i][2], gle.credit)
-				
+
 		si.cancel()
-		gle = frappe.db.sql("""select * from `tabGL Entry` 
+		gle = frappe.db.sql("""select * from `tabGL Entry`
 			where voucher_type='Sales Invoice' and voucher_no=%s""", si.name)
-		
+
 		self.assertFalse(gle)
 		set_perpetual_inventory(0)
-		
+
 	def test_sales_invoice_gl_entry_with_aii_no_item_code(self):
 		self.clear_stock_account_balance()
 		set_perpetual_inventory()
-				
-		si_copy = frappe.copy_doc(test_records[1])
-		si_copy[1]["item_code"] = None
-		si = frappe.get_doc(si_copy)		
+
+		si = frappe.get_doc(test_records[1])
+		si.get("entries")[0].item_code = None
 		si.insert()
 		si.submit()
-		
+
 		gl_entries = frappe.db.sql("""select account, debit, credit
 			from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
 			order by account asc""", si.name, as_dict=1)
 		self.assertTrue(gl_entries)
-		
+
 		expected_values = sorted([
 			[si.debit_to, 630.0, 0.0],
-			[test_records[1][1]["income_account"], 0.0, 500.0],
-			[test_records[1][2]["account_head"], 0.0, 80.0],
-			[test_records[1][3]["account_head"], 0.0, 50.0],
+			[test_records[1]["entries"][0]["income_account"], 0.0, 500.0],
+			[test_records[1]["other_charges"][0]["account_head"], 0.0, 80.0],
+			[test_records[1]["other_charges"][1]["account_head"], 0.0, 50.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)
-		
+
 		set_perpetual_inventory(0)
-	
+
 	def test_sales_invoice_gl_entry_with_aii_non_stock_item(self):
 		self.clear_stock_account_balance()
 		set_perpetual_inventory()
-		si_copy = frappe.copy_doc(test_records[1])
-		si_copy[1]["item_code"] = "_Test Non Stock Item"
-		si = frappe.get_doc(si_copy)
+		si = frappe.get_doc(test_records[1])
+		si.get("entries")[0].item_code = "_Test Non Stock Item"
 		si.insert()
 		si.submit()
-		
+
 		gl_entries = frappe.db.sql("""select account, debit, credit
 			from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
 			order by account asc""", si.name, as_dict=1)
 		self.assertTrue(gl_entries)
-		
+
 		expected_values = sorted([
 			[si.debit_to, 630.0, 0.0],
-			[test_records[1][1]["income_account"], 0.0, 500.0],
-			[test_records[1][2]["account_head"], 0.0, 80.0],
-			[test_records[1][3]["account_head"], 0.0, 50.0],
+			[test_records[1]["entries"][0]["income_account"], 0.0, 500.0],
+			[test_records[1]["other_charges"][0]["account_head"], 0.0, 80.0],
+			[test_records[1]["other_charges"][1]["account_head"], 0.0, 50.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)
-				
+
 		set_perpetual_inventory(0)
-		
+
 	def _insert_purchase_receipt(self):
 		from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import test_records \
 			as pr_test_records
@@ -608,7 +594,7 @@
 		pr.naming_series = "_T-Purchase Receipt-"
 		pr.insert()
 		pr.submit()
-		
+
 	def _insert_delivery_note(self):
 		from erpnext.stock.doctype.delivery_note.test_delivery_note import test_records \
 			as dn_test_records
@@ -617,23 +603,23 @@
 		dn.insert()
 		dn.submit()
 		return dn
-		
+
 	def _insert_pos_settings(self):
 		from erpnext.accounts.doctype.pos_setting.test_pos_setting \
 			import test_records as pos_setting_test_records
 		frappe.db.sql("""delete from `tabPOS Setting`""")
-		
+
 		ps = frappe.copy_doc(pos_setting_test_records[0])
 		ps.insert()
-		
+
 	def test_sales_invoice_with_advance(self):
 		from erpnext.accounts.doctype.journal_voucher.test_journal_voucher \
 			import test_records as jv_test_records
-			
+
 		jv = frappe.copy_doc(jv_test_records[0])
 		jv.insert()
 		jv.submit()
-		
+
 		si = frappe.copy_doc(test_records[0])
 		si.append("advance_adjustment_details", {
 			"doctype": "Sales Invoice Advance",
@@ -646,20 +632,20 @@
 		si.insert()
 		si.submit()
 		si.load_from_db()
-		
+
 		self.assertTrue(frappe.db.sql("""select name from `tabJournal Voucher Detail`
 			where against_invoice=%s""", si.name))
-		
+
 		self.assertTrue(frappe.db.sql("""select name from `tabJournal Voucher Detail`
 			where against_invoice=%s and credit=300""", si.name))
-			
+
 		self.assertEqual(si.outstanding_amount, 261.8)
-		
+
 		si.cancel()
-		
+
 		self.assertTrue(not frappe.db.sql("""select name from `tabJournal Voucher Detail`
 			where against_invoice=%s""", si.name))
-			
+
 	def test_recurring_invoice(self):
 		from frappe.utils import get_first_day, get_last_day, add_to_date, nowdate, getdate
 		from erpnext.accounts.utils import get_fiscal_year
@@ -675,13 +661,13 @@
 			"invoice_period_from_date": get_first_day(today),
 			"invoice_period_to_date": get_last_day(today)
 		})
-		
+
 		# monthly
 		si1 = frappe.copy_doc(base_si)
 		si1.insert()
 		si1.submit()
 		self._test_recurring_invoice(si1, True)
-		
+
 		# monthly without a first and last day period
 		si2 = frappe.copy_doc(base_si)
 		si2.update({
@@ -691,7 +677,7 @@
 		si2.insert()
 		si2.submit()
 		self._test_recurring_invoice(si2, False)
-		
+
 		# quarterly
 		si3 = frappe.copy_doc(base_si)
 		si3.update({
@@ -702,7 +688,7 @@
 		si3.insert()
 		si3.submit()
 		self._test_recurring_invoice(si3, True)
-		
+
 		# quarterly without a first and last day period
 		si4 = frappe.copy_doc(base_si)
 		si4.update({
@@ -713,7 +699,7 @@
 		si4.insert()
 		si4.submit()
 		self._test_recurring_invoice(si4, False)
-		
+
 		# yearly
 		si5 = frappe.copy_doc(base_si)
 		si5.update({
@@ -724,7 +710,7 @@
 		si5.insert()
 		si5.submit()
 		self._test_recurring_invoice(si5, True)
-		
+
 		# yearly without a first and last day period
 		si6 = frappe.copy_doc(base_si)
 		si6.update({
@@ -735,7 +721,7 @@
 		si6.insert()
 		si6.submit()
 		self._test_recurring_invoice(si6, False)
-		
+
 		# change posting date but keep recuring day to be today
 		si7 = frappe.copy_doc(base_si)
 		si7.update({
@@ -743,7 +729,7 @@
 		})
 		si7.insert()
 		si7.submit()
-		
+
 		# setting so that _test function works
 		si7.posting_date = today
 		self._test_recurring_invoice(si7, True)
@@ -752,52 +738,52 @@
 		from frappe.utils import add_months, get_last_day
 		from erpnext.accounts.doctype.sales_invoice.sales_invoice \
 			import manage_recurring_invoices, get_next_date
-		
+
 		no_of_months = ({"Monthly": 1, "Quarterly": 3, "Yearly": 12})[base_si.recurring_type]
-		
+
 		def _test(i):
 			self.assertEquals(i+1, frappe.db.sql("""select count(*) from `tabSales Invoice`
 				where recurring_id=%s and docstatus=1""", base_si.recurring_id)[0][0])
-			
-			next_date = get_next_date(base_si.posting_date, no_of_months, 
+
+			next_date = get_next_date(base_si.posting_date, no_of_months,
 				base_si.repeat_on_day_of_month)
 
 			manage_recurring_invoices(next_date=next_date, commit=False)
-			
+
 			recurred_invoices = frappe.db.sql("""select name from `tabSales Invoice`
 				where recurring_id=%s and docstatus=1 order by name desc""",
 				base_si.recurring_id)
-			
+
 			self.assertEquals(i+2, len(recurred_invoices))
-			
+
 			new_si = frappe.get_doc("Sales Invoice", recurred_invoices[0][0])
-			
+
 			for fieldname in ["convert_into_recurring_invoice", "recurring_type",
 				"repeat_on_day_of_month", "notification_email_address"]:
 					self.assertEquals(base_si.get(fieldname),
 						new_si.get(fieldname))
 
 			self.assertEquals(new_si.posting_date, unicode(next_date))
-			
+
 			self.assertEquals(new_si.invoice_period_from_date,
 				unicode(add_months(base_si.invoice_period_from_date, no_of_months)))
-			
+
 			if first_and_last_day:
-				self.assertEquals(new_si.invoice_period_to_date, 
+				self.assertEquals(new_si.invoice_period_to_date,
 					unicode(get_last_day(add_months(base_si.invoice_period_to_date,
 						no_of_months))))
 			else:
-				self.assertEquals(new_si.invoice_period_to_date, 
+				self.assertEquals(new_si.invoice_period_to_date,
 					unicode(add_months(base_si.invoice_period_to_date, no_of_months)))
-					
-			
+
+
 			return new_si
-		
+
 		# if yearly, test 1 repetition, else test 5 repetitions
 		count = 1 if (no_of_months == 12) else 5
 		for i in xrange(count):
 			base_si = _test(i)
-			
+
 	def clear_stock_account_balance(self):
 		frappe.db.sql("delete from `tabStock Ledger Entry`")
 		frappe.db.sql("delete from tabBin")
@@ -806,10 +792,10 @@
 	def test_serialized(self):
 		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
 		from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
-		
+
 		se = make_serialized_item()
-		serial_nos = get_serial_nos(se.get("entries")[0].serial_no)
-		
+		serial_nos = get_serial_nos(se.get("mtn_details")[0].serial_no)
+
 		si = frappe.copy_doc(test_records[0])
 		si.update_stock = 1
 		si.get("entries")[0].item_code = "_Test Serialized Item With Series"
@@ -817,14 +803,14 @@
 		si.get("entries")[0].serial_no = serial_nos[0]
 		si.insert()
 		si.submit()
-		
+
 		self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0], "status"), "Delivered")
 		self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0], "warehouse"))
-		self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0], 
+		self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0],
 			"delivery_document_no"), si.name)
-			
+
 		return si
-			
+
 	def test_serialized_cancel(self):
 		from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
 		si = self.test_serialized()
@@ -834,20 +820,20 @@
 
 		self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0], "status"), "Available")
 		self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0], "warehouse"), "_Test Warehouse - _TC")
-		self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0], 
+		self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0],
 			"delivery_document_no"))
 
 	def test_serialize_status(self):
 		from erpnext.stock.doctype.serial_no.serial_no import SerialNoStatusError, get_serial_nos
 		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
-		
+
 		se = make_serialized_item()
-		serial_nos = get_serial_nos(se.get("entries")[0].serial_no)
-		
+		serial_nos = get_serial_nos(se.get("mtn_details")[0].serial_no)
+
 		sr = frappe.get_doc("Serial No", serial_nos[0])
 		sr.status = "Not Available"
 		sr.save()
-		
+
 		si = frappe.copy_doc(test_records[0])
 		si.update_stock = 1
 		si.get("entries")[0].item_code = "_Test Serialized Item With Series"
@@ -858,5 +844,4 @@
 		self.assertRaises(SerialNoStatusError, si.submit)
 
 test_dependencies = ["Journal Voucher", "POS Setting", "Contact", "Address"]
-
-test_records = frappe.get_test_records('Sales Invoice')
\ No newline at end of file
+test_records = frappe.get_test_records('Sales Invoice')
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 25bdfa9..720a1d5 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -8,7 +8,7 @@
 
 from frappe import msgprint
 
-	
+
 from erpnext.controllers.buying_controller import BuyingController
 class PurchaseOrder(BuyingController):
 	tname = 'Purchase Order Item'
@@ -24,15 +24,15 @@
 		'source_field': 'qty',
 		'percent_join_field': 'prevdoc_docname',
 	}]
-		
+
 	def validate(self):
 		super(PurchaseOrder, self).validate()
-		
+
 		if not self.status:
 			self.status = "Draft"
 
 		from erpnext.utilities import validate_status
-		validate_status(self.status, ["Draft", "Submitted", "Stopped", 
+		validate_status(self.status, ["Draft", "Submitted", "Stopped",
 			"Cancelled"])
 
 		pc_obj = frappe.get_doc('Purchase Common')
@@ -45,7 +45,7 @@
 		self.validate_with_previous_doc()
 		self.validate_for_subcontracting()
 		self.update_raw_materials_supplied("po_raw_material_details")
-		
+
 	def validate_with_previous_doc(self):
 		super(PurchaseOrder, self).validate_with_previous_doc(self.tname, {
 			"Supplier Quotation": {
@@ -54,7 +54,7 @@
 			},
 			"Supplier Quotation Item": {
 				"ref_dn_field": "supplier_quotation_item",
-				"compare_fields": [["rate", "="], ["project_name", "="], ["item_code", "="], 
+				"compare_fields": [["rate", "="], ["project_name", "="], ["item_code", "="],
 					["uom", "="]],
 				"is_child_table": True
 			}
@@ -65,11 +65,11 @@
 			if d.prevdoc_detail_docname and not d.schedule_date:
 				d.schedule_date = frappe.db.get_value("Material Request Item",
 						d.prevdoc_detail_docname, "schedule_date")
-	
+
 	def get_last_purchase_rate(self):
 		frappe.get_doc('Purchase Common').get_last_purchase_rate(self)
 
-	# Check for Stopped status 
+	# Check for Stopped status
 	def check_for_stopped_status(self, pc_obj):
 		check_list =[]
 		for d in self.get('po_details'):
@@ -77,7 +77,7 @@
 				check_list.append(d.prevdoc_docname)
 				pc_obj.check_for_stopped_status( d.prevdoc_doctype, d.prevdoc_docname)
 
-		
+
 	def update_bin(self, is_submit, is_stopped = 0):
 		from erpnext.stock.utils import update_bin
 		pc_obj = frappe.get_doc('Purchase Common')
@@ -87,29 +87,29 @@
 				# this happens when item is changed from non-stock to stock item
 				if not d.warehouse:
 					continue
-				
+
 				ind_qty, po_qty = 0, flt(d.qty) * flt(d.conversion_factor)
 				if is_stopped:
 					po_qty = flt(d.qty) > flt(d.received_qty) and \
-						flt( flt(flt(d.qty) - flt(d.received_qty))*flt(d.conversion_factor)) or 0 
-				
+						flt( flt(flt(d.qty) - flt(d.received_qty))*flt(d.conversion_factor)) or 0
+
 				# No updates in Material Request on Stop / Unstop
 				if cstr(d.prevdoc_doctype) == 'Material Request' and not is_stopped:
-					# get qty and pending_qty of prevdoc 
+					# get qty and pending_qty of prevdoc
 					curr_ref_qty = pc_obj.get_qty(d.doctype, 'prevdoc_detail_docname',
-					 	d.prevdoc_detail_docname, 'Material Request Item', 
+					 	d.prevdoc_detail_docname, 'Material Request Item',
 						'Material Request - Purchase Order', self.name)
 					max_qty, qty, curr_qty = flt(curr_ref_qty.split('~~~')[1]), \
 					 	flt(curr_ref_qty.split('~~~')[0]), 0
-					
+
 					if flt(qty) + flt(po_qty) > flt(max_qty):
 						curr_qty = flt(max_qty) - flt(qty)
-						# special case as there is no restriction 
-						# for Material Request - Purchase Order 
+						# special case as there is no restriction
+						# for Material Request - Purchase Order
 						curr_qty = curr_qty > 0 and curr_qty or 0
 					else:
 						curr_qty = flt(po_qty)
-					
+
 					ind_qty = -flt(curr_qty)
 
 				# Update ordered_qty and indented_qty in bin
@@ -121,12 +121,12 @@
 					"posting_date": self.transaction_date
 				}
 				update_bin(args)
-				
+
 	def check_modified_date(self):
-		mod_db = frappe.db.sql("select modified from `tabPurchase Order` where name = %s", 
+		mod_db = frappe.db.sql("select modified from `tabPurchase Order` where name = %s",
 			self.name)
 		date_diff = frappe.db.sql("select TIMEDIFF('%s', '%s')" % ( mod_db[0][0],cstr(self.modified)))
-		
+
 		if date_diff and date_diff[0][0]:
 			msgprint(cstr(self.doctype) +" => "+ cstr(self.name) +" has been modified. Please Refresh. ")
 			raise Exception
@@ -144,28 +144,28 @@
 
 	def on_submit(self):
 		purchase_controller = frappe.get_doc("Purchase Common")
-		
+
 		self.update_prevdoc_status()
 		self.update_bin(is_submit = 1, is_stopped = 0)
-		
-		frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype, 
+
+		frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
 			self.company, self.grand_total)
-		
+
 		purchase_controller.update_last_purchase_rate(self, is_submit = 1)
-		
+
 		frappe.db.set(self,'status','Submitted')
-	 
+
 	def on_cancel(self):
-		pc_obj = frappe.get_doc(dt = 'Purchase Common')		
+		pc_obj = frappe.get_doc(dt = 'Purchase Common')
 		self.check_for_stopped_status(pc_obj)
-		
+
 		# Check if Purchase Receipt has been submitted against current Purchase Order
 		pc_obj.check_docstatus(check = 'Next', doctype = 'Purchase Receipt', docname = self.name, detail_doctype = 'Purchase Receipt Item')
 
 		# Check if Purchase Invoice has been submitted against current Purchase Order
-		submitted = frappe.db.sql("""select t1.name 
-			from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 
-			where t1.name = t2.parent and t2.purchase_order = %s and t1.docstatus = 1""",  
+		submitted = frappe.db.sql("""select t1.name
+			from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2
+			where t1.name = t2.parent and t2.purchase_order = %s and t1.docstatus = 1""",
 			self.name)
 		if submitted:
 			msgprint("Purchase Invoice : " + cstr(submitted[0][0]) + " has already been submitted !")
@@ -175,14 +175,14 @@
 		self.update_prevdoc_status()
 		self.update_bin( is_submit = 0, is_stopped = 0)
 		pc_obj.update_last_purchase_rate(self, is_submit = 0)
-				
+
 	def on_update(self):
 		pass
-		
+
 @frappe.whitelist()
 def make_purchase_receipt(source_name, target_doc=None):
 	from frappe.model.mapper import get_mapped_doc
-	
+
 	def set_missing_values(source, target):
 		doc = frappe.get_doc(target)
 		doc.run_method("set_missing_values")
@@ -193,35 +193,35 @@
 		target.amount = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.rate)
 		target.base_amount = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.base_rate)
 
-	doclist = get_mapped_doc("Purchase Order", source_name,	{
+	doc = get_mapped_doc("Purchase Order", source_name,	{
 		"Purchase Order": {
-			"doctype": "Purchase Receipt", 
+			"doctype": "Purchase Receipt",
 			"validation": {
 				"docstatus": ["=", 1],
 			}
-		}, 
+		},
 		"Purchase Order Item": {
-			"doctype": "Purchase Receipt Item", 
+			"doctype": "Purchase Receipt Item",
 			"field_map": {
-				"name": "prevdoc_detail_docname", 
-				"parent": "prevdoc_docname", 
-				"parenttype": "prevdoc_doctype", 
+				"name": "prevdoc_detail_docname",
+				"parent": "prevdoc_docname",
+				"parenttype": "prevdoc_doctype",
 			},
 			"postprocess": update_item,
 			"condition": lambda doc: doc.received_qty < doc.qty
-		}, 
+		},
 		"Purchase Taxes and Charges": {
-			"doctype": "Purchase Taxes and Charges", 
+			"doctype": "Purchase Taxes and Charges",
 			"add_if_empty": True
 		}
 	}, target_doc, set_missing_values)
 
-	return doclist.as_dict()
-	
+	return doc
+
 @frappe.whitelist()
 def make_purchase_invoice(source_name, target_doc=None):
 	from frappe.model.mapper import get_mapped_doc
-	
+
 	def set_missing_values(source, target):
 		doc = frappe.get_doc(target)
 		doc.run_method("set_missing_values")
@@ -232,26 +232,26 @@
 		if flt(obj.base_rate):
 			target.qty = target.base_amount / flt(obj.base_rate)
 
-	doclist = get_mapped_doc("Purchase Order", source_name,	{
+	doc = get_mapped_doc("Purchase Order", source_name,	{
 		"Purchase Order": {
-			"doctype": "Purchase Invoice", 
+			"doctype": "Purchase Invoice",
 			"validation": {
 				"docstatus": ["=", 1],
 			}
-		}, 
+		},
 		"Purchase Order Item": {
-			"doctype": "Purchase Invoice Item", 
+			"doctype": "Purchase Invoice Item",
 			"field_map": {
-				"name": "po_detail", 
-				"parent": "purchase_order", 
+				"name": "po_detail",
+				"parent": "purchase_order",
 			},
 			"postprocess": update_item,
-			"condition": lambda doc: doc.base_amount==0 or doc.billed_amt < doc.amount 
-		}, 
+			"condition": lambda doc: doc.base_amount==0 or doc.billed_amt < doc.amount
+		},
 		"Purchase Taxes and Charges": {
-			"doctype": "Purchase Taxes and Charges", 
+			"doctype": "Purchase Taxes and Charges",
 			"add_if_empty": True
 		}
 	}, target_doc, set_missing_values)
 
-	return doclist.as_dict()
\ No newline at end of file
+	return doc
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
index f8b03f0..d1d183a 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
@@ -8,90 +8,87 @@
 from frappe.utils import flt
 
 class TestPurchaseOrder(unittest.TestCase):
-	def test_make_purchase_receipt(self):		
+	def test_make_purchase_receipt(self):
 		from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt
 
 		po = frappe.copy_doc(test_records[0]).insert()
 
-		self.assertRaises(frappe.ValidationError, make_purchase_receipt, 
+		self.assertRaises(frappe.ValidationError, make_purchase_receipt,
 			po.name)
 
 		po = frappe.get_doc("Purchase Order", po.name)
 		po.submit()
-		
+
 		pr = make_purchase_receipt(po.name)
-		pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC"
-		pr[0]["posting_date"] = "2013-05-12"
-		self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
-		self.assertEquals(len(pr), len(test_records[0]))
-		
-		pr[0]["naming_series"] = "_T-Purchase Receipt-"
-		pr_doc = frappe.get_doc(pr)
-		pr_doc.insert()
-			
+		pr.supplier_warehouse = "_Test Warehouse 1 - _TC"
+		pr.posting_date = "2013-05-12"
+		self.assertEquals(pr.doctype, "Purchase Receipt")
+		self.assertEquals(len(pr.get("purchase_receipt_details")), len(test_records[0]["po_details"]))
+
+		pr.naming_series = "_T-Purchase Receipt-"
+		frappe.get_doc(pr).insert()
+
 	def test_ordered_qty(self):
 		frappe.db.sql("delete from tabBin")
-		
+
 		from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt
 
 		po = frappe.copy_doc(test_records[0]).insert()
 
-		self.assertRaises(frappe.ValidationError, make_purchase_receipt, 
+		self.assertRaises(frappe.ValidationError, make_purchase_receipt,
 			po.name)
 
 		po = frappe.get_doc("Purchase Order", po.name)
 		po.is_subcontracted = "No"
 		po.get("po_details")[0].item_code = "_Test Item"
 		po.submit()
-		
-		self.assertEquals(frappe.db.get_value("Bin", {"item_code": "_Test Item", 
+
+		self.assertEquals(frappe.db.get_value("Bin", {"item_code": "_Test Item",
 			"warehouse": "_Test Warehouse - _TC"}, "ordered_qty"), 10)
-		
+
 		pr = make_purchase_receipt(po.name)
-		
-		self.assertEquals(pr[0]["doctype"], "Purchase Receipt")
-		self.assertEquals(len(pr), len(test_records[0]))
-		pr[0]["posting_date"] = "2013-05-12"
-		pr[0]["naming_series"] = "_T-Purchase Receipt-"
-		pr[1]["qty"] = 4.0
-		pr_doc = frappe.get_doc(pr)
-		pr_doc.insert()
-		pr_doc.submit()
-		
-		self.assertEquals(flt(frappe.db.get_value("Bin", {"item_code": "_Test Item", 
+
+		self.assertEquals(pr.doctype, "Purchase Receipt")
+		self.assertEquals(len(pr.get("purchase_receipt_details", [])), len(test_records[0]["po_details"]))
+		pr.posting_date = "2013-05-12"
+		pr.naming_series = "_T-Purchase Receipt-"
+		pr.purchase_receipt_details[0].qty = 4.0
+		pr.insert()
+		pr.submit()
+
+		self.assertEquals(flt(frappe.db.get_value("Bin", {"item_code": "_Test Item",
 			"warehouse": "_Test Warehouse - _TC"}, "ordered_qty")), 6.0)
-			
+
 		frappe.db.set_value('Item', '_Test Item', 'tolerance', 50)
-			
+
 		pr1 = make_purchase_receipt(po.name)
-		pr1[0]["naming_series"] = "_T-Purchase Receipt-"
-		pr1[0]["posting_date"] = "2013-05-12"
-		pr1[1]["qty"] = 8
-		pr1_doc = frappe.get_doc(pr1)
-		pr1_doc.insert()
-		pr1_doc.submit()
-		
-		self.assertEquals(flt(frappe.db.get_value("Bin", {"item_code": "_Test Item", 
+		pr1.naming_series = "_T-Purchase Receipt-"
+		pr1.posting_date = "2013-05-12"
+		pr1.get("purchase_receipt_details")[0].qty = 8
+		pr1.insert()
+		pr1.submit()
+
+		self.assertEquals(flt(frappe.db.get_value("Bin", {"item_code": "_Test Item",
 			"warehouse": "_Test Warehouse - _TC"}, "ordered_qty")), 0.0)
-		
+
 	def test_make_purchase_invoice(self):
 		from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_invoice
 
 		po = frappe.copy_doc(test_records[0]).insert()
 
-		self.assertRaises(frappe.ValidationError, make_purchase_invoice, 
+		self.assertRaises(frappe.ValidationError, make_purchase_invoice,
 			po.name)
 
 		po = frappe.get_doc("Purchase Order", po.name)
 		po.submit()
 		pi = make_purchase_invoice(po.name)
-		
-		self.assertEquals(pi[0]["doctype"], "Purchase Invoice")
-		self.assertEquals(len(pi), len(test_records[0]))
-		pi[0]["posting_date"] = "2013-05-12"
-		pi[0]["bill_no"] = "NA"
+
+		self.assertEquals(pi.doctype, "Purchase Invoice")
+		self.assertEquals(len(pi.get("entries", [])), len(test_records[0]["po_details"]))
+		pi.posting_date = "2013-05-12"
+		pi.bill_no = "NA"
 		frappe.get_doc(pi).insert()
-		
+
 	def test_subcontracting(self):
 		po = frappe.copy_doc(test_records[0])
 		po.insert()
@@ -113,4 +110,4 @@
 
 test_dependencies = ["BOM"]
 
-test_records = frappe.get_test_records('Purchase Order')
\ No newline at end of file
+test_records = frappe.get_test_records('Purchase Order')
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
index e937735..fa48488 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
@@ -88,4 +88,4 @@
 		},
 	}, target_doc, set_missing_values)
 
-	return doclist.as_dict()
\ No newline at end of file
+	return doclist
\ No newline at end of file
diff --git a/erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.py
index 708b5e7..3f22fd5 100644
--- a/erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.py
+++ b/erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.py
@@ -13,22 +13,22 @@
 
 		sq = frappe.copy_doc(test_records[0]).insert()
 
-		self.assertRaises(frappe.ValidationError, make_purchase_order, 
+		self.assertRaises(frappe.ValidationError, make_purchase_order,
 			sq.name)
 
 		sq = frappe.get_doc("Supplier Quotation", sq.name)
 		sq.submit()
 		po = make_purchase_order(sq.name)
-		
-		self.assertEquals(po[0]["doctype"], "Purchase Order")
-		self.assertEquals(len(po), len(sq))
-		
-		po[0]["naming_series"] = "_T-Purchase Order-"
 
-		for doc in po:
+		self.assertEquals(po.doctype, "Purchase Order")
+		self.assertEquals(len(po.get("po_details")), len(sq.get("quotation_items")))
+
+		po.naming_series = "_T-Purchase Order-"
+
+		for doc in po.get("po_details"):
 			if doc.get("item_code"):
-				doc["schedule_date"] = "2013-04-12"
+				doc.set("schedule_date", "2013-04-12")
 
-		frappe.get_doc(po).insert()
-		
-test_records = frappe.get_test_records('Supplier Quotation')
\ No newline at end of file
+		po.insert()
+
+test_records = frappe.get_test_records('Supplier Quotation')
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index ffe6a6a..ec6fe1f 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -18,16 +18,16 @@
 			self.calculate_taxes_and_totals()
 			self.validate_value("grand_total", ">=", 0)
 			self.set_total_in_words()
-			
+
 		self.validate_for_freezed_account()
-		
+
 	def set_missing_values(self, for_validate=False):
 		for fieldname in ["posting_date", "transaction_date"]:
 			if not self.get(fieldname) and self.meta.get_field(fieldname):
 				self.set(fieldname, today())
 				if not self.fiscal_year:
 					self.fiscal_year = get_fiscal_year(self.get(fieldname))[0]
-					
+
 	def validate_date_with_fiscal_year(self):
 		if self.meta.get_field("fiscal_year") :
 			date_field = ""
@@ -35,40 +35,40 @@
 				date_field = "posting_date"
 			elif self.meta.get_field("transaction_date"):
 				date_field = "transaction_date"
-				
+
 			if date_field and self.get(date_field):
-				validate_fiscal_year(self.get(date_field), self.fiscal_year, 
+				validate_fiscal_year(self.get(date_field), self.fiscal_year,
 					label=self.meta.get_label(date_field))
-					
+
 	def validate_for_freezed_account(self):
 		for fieldname in ["customer", "supplier"]:
 			if self.meta.get_field(fieldname) and self.get(fieldname):
-				accounts = frappe.db.get_values("Account", 
-					{"master_type": fieldname.title(), "master_name": self.get(fieldname), 
+				accounts = frappe.db.get_values("Account",
+					{"master_type": fieldname.title(), "master_name": self.get(fieldname),
 					"company": self.company}, "name")
 				if accounts:
 					from erpnext.accounts.doctype.gl_entry.gl_entry import validate_frozen_account
-					for account in accounts:						
+					for account in accounts:
 						validate_frozen_account(account[0])
-			
+
 	def set_price_list_currency(self, buying_or_selling):
 		if self.meta.get_field("currency"):
 			company_currency = get_company_currency(self.company)
-			
+
 			# price list part
 			fieldname = "selling_price_list" if buying_or_selling.lower() == "selling" \
 				else "buying_price_list"
 			if self.meta.get_field(fieldname) and self.get(fieldname):
 				self.price_list_currency = frappe.db.get_value("Price List",
 					self.get(fieldname), "currency")
-				
+
 				if self.price_list_currency == company_currency:
 					self.plc_conversion_rate = 1.0
 
 				elif not self.plc_conversion_rate:
 					self.plc_conversion_rate = self.get_exchange_rate(
 						self.price_list_currency, company_currency)
-			
+
 			# currency
 			if not self.currency:
 				self.currency = self.price_list_currency
@@ -96,44 +96,44 @@
 						if item.meta.get_field(fieldname) and \
 							item.get(fieldname) is None and value is not None:
 								item.set(fieldname, value)
-							
+
 	def set_taxes(self, tax_parentfield, tax_master_field):
 		if not self.meta.get_field(tax_parentfield):
 			return
-			
+
 		tax_master_doctype = self.meta.get_field(tax_master_field).options
-			
+
 		if not self.get(tax_parentfield):
 			if not self.get(tax_master_field):
 				# get the default tax master
 				self.set(tax_master_field, frappe.db.get_value(tax_master_doctype, {"is_default": 1}))
-					
+
 			self.append_taxes_from_master(tax_parentfield, tax_master_field, tax_master_doctype)
-				
+
 	def append_taxes_from_master(self, tax_parentfield, tax_master_field, tax_master_doctype=None):
 		if self.get(tax_master_field):
 			if not tax_master_doctype:
 				tax_master_doctype = self.meta.get_field(tax_master_field).options
-			
+
 			tax_doctype = self.meta.get_field(tax_parentfield).options
-			
+
 			from frappe.model import default_fields
 			tax_master = frappe.get_doc(tax_master_doctype, self.get(tax_master_field))
-			
+
 			for i, tax in enumerate(tax_master.get(tax_parentfield)):
 				for fieldname in default_fields:
 					tax.set(fieldname, None)
-								
+
 				self.append(tax_parentfield, tax)
 
 	def get_other_charges(self):
 		self.set("other_charges", [])
 		self.set_taxes("other_charges", "taxes_and_charges")
-					
+
 	def calculate_taxes_and_totals(self):
 		self.discount_amount_applied = False
 		self._calculate_taxes_and_totals()
-		
+
 		if self.meta.get_field("discount_amount"):
 			self.apply_discount_amount()
 
@@ -151,23 +151,23 @@
 		self.conversion_rate = flt(self.conversion_rate)
 		self.item_doclist = self.get(self.fname)
 		self.tax_doclist = self.get(self.other_fname)
-		
+
 		self.calculate_item_values()
 		self.initialize_taxes()
-		
+
 		if hasattr(self, "determine_exclusive_rate"):
 			self.determine_exclusive_rate()
-		
+
 		self.calculate_net_total()
 		self.calculate_taxes()
 		self.calculate_totals()
 		self._cleanup()
-		
+
 	def initialize_taxes(self):
 		for tax in self.tax_doclist:
 			tax.item_wise_tax_detail = {}
-			tax_fields = ["total", "tax_amount_after_discount_amount", 
-				"tax_amount_for_current_item", "grand_total_for_current_item", 
+			tax_fields = ["total", "tax_amount_after_discount_amount",
+				"tax_amount_for_current_item", "grand_total_for_current_item",
 				"tax_fraction_for_current_item", "grand_total_fraction_for_current_item"]
 
 			if not self.discount_amount_applied:
@@ -179,7 +179,7 @@
 			self.validate_on_previous_row(tax)
 			self.validate_inclusive_tax(tax)
 			self.round_floats_in(tax)
-			
+
 	def validate_on_previous_row(self, tax):
 		"""
 			validate if a valid row id is mentioned in case of
@@ -194,7 +194,7 @@
 					"row_id_label": self.meta.get_label("row_id",
 						parentfield=self.other_fname)
 				})
-				
+
 	def validate_inclusive_tax(self, tax):
 		def _on_previous_row_error(row_range):
 			throw((_("Row") + " # %(idx)s [%(doctype)s]: " +
@@ -202,24 +202,21 @@
 				" [" + _("Row") + " # %(row_range)s] " + _("also be included in Item's rate")) % {
 					"idx": tax.idx,
 					"doctype": tax.doctype,
-					"inclusive_label": self.meta.get_label("included_in_print_rate",
-						parentfield=self.other_fname),
-					"charge_type_label": self.meta.get_label("charge_type",
-						parentfield=self.other_fname),
+					"inclusive_label": frappe.get_meta(tax.doctype).get_label("included_in_print_rate"),
+					"charge_type_label": frappe.get_meta(tax.doctype).get_label("charge_type"),
 					"charge_type": tax.charge_type,
 					"row_range": row_range
 				})
-		
+
 		if cint(getattr(tax, "included_in_print_rate", None)):
 			if tax.charge_type == "Actual":
 				# inclusive tax cannot be of type Actual
-				throw((_("Row") 
-					+ " # %(idx)s [%(doctype)s]: %(charge_type_label)s = \"%(charge_type)s\" " 
+				throw((_("Row")
+					+ " # %(idx)s [%(doctype)s]: %(charge_type_label)s = \"%(charge_type)s\" "
 					+ "cannot be included in Item's rate") % {
 						"idx": tax.idx,
 						"doctype": tax.doctype,
-						"charge_type_label": self.meta.get_label("charge_type",
-							parentfield=self.other_fname),
+						"charge_type_label": frappe.get_meta(tax.doctype).get_label("charge_type"),
 						"charge_type": tax.charge_type,
 					})
 			elif tax.charge_type == "On Previous Row Amount" and \
@@ -230,10 +227,10 @@
 					not all([cint(t.included_in_print_rate) for t in self.tax_doclist[:cint(tax.row_id) - 1]]):
 				# all rows about the reffered tax should be inclusive
 				_on_previous_row_error("1 - %d" % (tax.row_id,))
-				
+
 	def calculate_taxes(self):
 		# maintain actual tax rate based on idx
-		actual_tax_dict = dict([[tax.idx, tax.rate] for tax in self.tax_doclist 
+		actual_tax_dict = dict([[tax.idx, tax.rate] for tax in self.tax_doclist
 			if tax.charge_type == "Actual"])
 
 		for n, item in enumerate(self.item_doclist):
@@ -258,26 +255,26 @@
 					tax.tax_amount += current_tax_amount
 
 				tax.tax_amount_after_discount_amount += current_tax_amount
-				
+
 				if getattr(tax, "category", None):
 					# if just for valuation, do not add the tax amount in total
 					# hence, setting it as 0 for further steps
 					current_tax_amount = 0.0 if (tax.category == "Valuation") \
 						else current_tax_amount
-					
+
 					current_tax_amount *= -1.0 if (tax.add_deduct_tax == "Deduct") else 1.0
-				
+
 				# Calculate tax.total viz. grand total till that step
-				# note: grand_total_for_current_item contains the contribution of 
+				# 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.base_amount + current_tax_amount,
 						self.precision("total", tax))
 				else:
 					tax.grand_total_for_current_item = \
-						flt(self.tax_doclist[i-1].grand_total_for_current_item + 
+						flt(self.tax_doclist[i-1].grand_total_for_current_item +
 							current_tax_amount, self.precision("total", tax))
-				
+
 				# in tax.total, accumulate grand total of each item
 				tax.total += tax.grand_total_for_current_item
 
@@ -292,12 +289,12 @@
 	def round_off_totals(self, tax):
 		tax.total = flt(tax.total, self.precision("total", tax))
 		tax.tax_amount = flt(tax.tax_amount, self.precision("tax_amount", tax))
-		tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount, 
+		tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount,
 			self.precision("tax_amount", tax))
 
 	def adjust_discount_amount_loss(self, tax):
 		discount_amount_loss = self.grand_total - flt(self.discount_amount) - tax.total
-		tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount + 
+		tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount +
 			discount_amount_loss, self.precision("tax_amount", tax))
 		tax.total = flt(tax.total + discount_amount_loss, self.precision("total", tax))
 
@@ -331,40 +328,40 @@
 			tax.item_wise_tax_detail[key] = [tax_rate, current_tax_amount]
 
 		return current_tax_amount
-		
+
 	def _load_item_tax_rate(self, item_tax_rate):
 		return json.loads(item_tax_rate) if item_tax_rate else {}
-		
+
 	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("rate", tax))
 		else:
 			return tax.rate
-	
+
 	def _cleanup(self):
 		for tax in self.tax_doclist:
 			tax.item_wise_tax_detail = json.dumps(tax.item_wise_tax_detail)
-			
+
 	def _set_in_company_currency(self, item, print_field, base_field):
 		"""set values in base currency"""
-		value_in_company_currency = flt(self.conversion_rate * 
+		value_in_company_currency = flt(self.conversion_rate *
 			flt(item.get(print_field), self.precision(print_field, item)),
 			self.precision(base_field, item))
 		item.set(base_field, value_in_company_currency)
-			
+
 	def calculate_total_advance(self, parenttype, advance_parentfield):
 		if self.doctype == parenttype and self.docstatus < 2:
-			sum_of_allocated_amount = sum([flt(adv.allocated_amount, self.precision("allocated_amount", adv)) 
+			sum_of_allocated_amount = sum([flt(adv.allocated_amount, self.precision("allocated_amount", adv))
 				for adv in self.get(advance_parentfield)])
 
 			self.total_advance = flt(sum_of_allocated_amount, self.precision("total_advance"))
-			
+
 			self.calculate_outstanding_amount()
 
 	def get_gl_dict(self, args):
 		"""this method populates the common properties of a gl entry record"""
 		gl_dict = frappe._dict({
-			'company': self.company, 
+			'company': self.company,
 			'posting_date': self.posting_date,
 			'voucher_type': self.doctype,
 			'voucher_no': self.name,
@@ -377,24 +374,24 @@
 		})
 		gl_dict.update(args)
 		return gl_dict
-				
+
 	def clear_unallocated_advances(self, childtype, parentfield):
 		self.set(parentfield, self.get(parentfield, {"allocated_amount": ["not in", [0, None, ""]]}))
 
-		frappe.db.sql("""delete from `tab%s` where parentfield=%s and parent = %s 
+		frappe.db.sql("""delete from `tab%s` where parentfield=%s and parent = %s
 			and ifnull(allocated_amount, 0) = 0""" % (childtype, '%s', '%s'), (parentfield, self.name))
-		
+
 	def get_advances(self, account_head, child_doctype, parentfield, dr_or_cr):
-		res = frappe.db.sql("""select t1.name as jv_no, t1.remark, 
+		res = frappe.db.sql("""select t1.name as jv_no, t1.remark,
 			t2.%s as amount, t2.name as jv_detail_no
-			from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 
-			where t1.name = t2.parent and t2.account = %s and t2.is_advance = 'Yes' 
+			from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
+			where t1.name = t2.parent and t2.account = %s and t2.is_advance = 'Yes'
 			and (t2.against_voucher is null or t2.against_voucher = '')
-			and (t2.against_invoice is null or t2.against_invoice = '') 
-			and (t2.against_jv is null or t2.against_jv = '') 
-			and t1.docstatus = 1 order by t1.posting_date""" % 
+			and (t2.against_invoice is null or t2.against_invoice = '')
+			and (t2.against_jv is null or t2.against_jv = '')
+			and t1.docstatus = 1 order by t1.posting_date""" %
 			(dr_or_cr, '%s'), account_head, as_dict=1)
-			
+
 		self.set(parentfield, [])
 		for d in res:
 			self.append(parentfield, {
@@ -405,74 +402,74 @@
 				"advance_amount": flt(d.amount),
 				"allocate_amount": 0
 			})
-			
+
 	def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
 		from erpnext.controllers.status_updater import get_tolerance_for
 		item_tolerance = {}
 		global_tolerance = None
-		
+
 		for item in self.get("entries"):
 			if item.get(item_ref_dn):
-				ref_amt = flt(frappe.db.get_value(ref_dt + " Item", 
+				ref_amt = flt(frappe.db.get_value(ref_dt + " Item",
 					item.get(item_ref_dn), based_on), self.precision(based_on, item))
 				if not ref_amt:
-					frappe.msgprint(_("As amount for item") + ": " + item.item_code + _(" in ") + 
+					frappe.msgprint(_("As amount for item") + ": " + item.item_code + _(" in ") +
 						ref_dt + _(" is zero, system will not check for over-billed"))
 				else:
-					already_billed = frappe.db.sql("""select sum(%s) from `tab%s` 
-						where %s=%s and docstatus=1 and parent != %s""" % 
-						(based_on, self.tname, item_ref_dn, '%s', '%s'), 
+					already_billed = frappe.db.sql("""select sum(%s) from `tab%s`
+						where %s=%s and docstatus=1 and parent != %s""" %
+						(based_on, self.tname, item_ref_dn, '%s', '%s'),
 						(item.get(item_ref_dn), self.name))[0][0]
-				
-					total_billed_amt = flt(flt(already_billed) + flt(item.get(based_on)), 
+
+					total_billed_amt = flt(flt(already_billed) + flt(item.get(based_on)),
 						self.precision(based_on, item))
-				
-					tolerance, item_tolerance, global_tolerance = get_tolerance_for(item.item_code, 
+
+					tolerance, item_tolerance, global_tolerance = get_tolerance_for(item.item_code,
 						item_tolerance, global_tolerance)
-					
+
 					max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100)
-				
+
 					if total_billed_amt - max_allowed_amt > 0.01:
 						reduce_by = total_billed_amt - max_allowed_amt
-					
-						frappe.throw(_("Row #") + cstr(item.idx) + ": " + 
-							_(" Max amount allowed for Item ") + cstr(item.item_code) + 
-							_(" against ") + ref_dt + " " + 
-							cstr(item.get(ref_dt.lower().replace(" ", "_"))) + _(" is ") + 
-							cstr(max_allowed_amt) + ". \n" + 
+
+						frappe.throw(_("Row #") + cstr(item.idx) + ": " +
+							_(" Max amount allowed for Item ") + cstr(item.item_code) +
+							_(" against ") + ref_dt + " " +
+							cstr(item.get(ref_dt.lower().replace(" ", "_"))) + _(" is ") +
+							cstr(max_allowed_amt) + ". \n" +
 							_("""If you want to increase your overflow tolerance, please increase \
-							tolerance % in Global Defaults or Item master. 				
-							Or, you must reduce the amount by """) + cstr(reduce_by) + "\n" + 
+							tolerance % in Global Defaults or Item master.
+							Or, you must reduce the amount by """) + cstr(reduce_by) + "\n" +
 							_("""Also, please check if the order item has already been billed \
 								in the Sales Order"""))
-				
+
 	def get_company_default(self, fieldname):
 		from erpnext.accounts.utils import get_company_default
 		return get_company_default(self.company, fieldname)
-		
+
 	def get_stock_items(self):
 		stock_items = []
-		item_codes = list(set(item.item_code for item in 
+		item_codes = list(set(item.item_code for item in
 			self.get(self.fname)))
 		if item_codes:
 			stock_items = [r[0] for r in frappe.db.sql("""select name
 				from `tabItem` where name in (%s) and is_stock_item='Yes'""" % \
 				(", ".join((["%s"]*len(item_codes))),), item_codes)]
-				
+
 		return stock_items
-		
+
 	@property
 	def company_abbr(self):
 		if not hasattr(self, "_abbr"):
 			self._abbr = frappe.db.get_value("Company", self.company, "abbr")
-			
+
 		return self._abbr
 
 	def check_credit_limit(self, account):
 		total_outstanding = frappe.db.sql("""
-			select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) 
+			select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
 			from `tabGL Entry` where account = %s""", account)
-		
+
 		total_outstanding = total_outstanding[0][0] if total_outstanding else 0
 		if total_outstanding:
 			frappe.get_doc('Account', account).check_credit_limit(total_outstanding)
@@ -480,4 +477,4 @@
 
 @frappe.whitelist()
 def get_tax_rate(account_head):
-	return frappe.db.get_value("Account", account_head, "tax_rate")
\ No newline at end of file
+	return frappe.db.get_value("Account", account_head, "tax_rate")
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 027bfd2..3f78fe6 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -13,52 +13,52 @@
 	def onload_post_render(self):
 		# contact, address, item details and pos details (if applicable)
 		self.set_missing_values()
-		
+
 	def validate(self):
 		super(SellingController, self).validate()
 		self.validate_max_discount()
 		check_active_sales_items(self)
-	
+
 	def get_sender(self, comm):
 		return frappe.db.get_value('Sales Email Settings', None, 'email_id')
-	
+
 	def set_missing_values(self, for_validate=False):
 		super(SellingController, self).set_missing_values(for_validate)
-		
+
 		# set contact and address details for customer, if they are not mentioned
 		self.set_missing_lead_customer_details()
 		self.set_price_list_and_item_details()
 		if self.get("__islocal"):
 			self.set_taxes("other_charges", "taxes_and_charges")
-					
+
 	def set_missing_lead_customer_details(self):
 		if getattr(self, "customer", None):
 			from erpnext.accounts.party import _get_party_details
 			self.update_if_missing(_get_party_details(self.customer,
 				ignore_permissions=getattr(self, "ignore_permissions", None)))
-		
+
 		elif getattr(self, "lead", None):
 			from erpnext.selling.doctype.lead.lead import get_lead_details
 			self.update_if_missing(get_lead_details(self.lead))
-	
+
 	def set_price_list_and_item_details(self):
 		self.set_price_list_currency("Selling")
 		self.set_missing_item_details()
-										
+
 	def apply_shipping_rule(self):
 		if self.shipping_rule:
 			shipping_rule = frappe.get_doc("Shipping Rule", self.shipping_rule)
 			value = self.net_total
-			
+
 			# TODO
 			# shipping rule calculation based on item's net weight
-			
+
 			shipping_amount = 0.0
 			for condition in shipping_rule.get("shipping_rule_conditions"):
 				if not condition.to_value or (flt(condition.from_value) <= value <= flt(condition.to_value)):
 					shipping_amount = condition.shipping_amount
 					break
-			
+
 			self.append("other_charges", {
 				"doctype": "Sales Taxes and Charges",
 				"charge_type": "Actual",
@@ -67,86 +67,86 @@
 				"description": shipping_rule.label,
 				"rate": shipping_amount
 			})
-		
+
 	def set_total_in_words(self):
 		from frappe.utils import money_in_words
 		company_currency = get_company_currency(self.company)
-		
-		disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, 
+
+		disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None,
 			"disable_rounded_total"))
-			
+
 		if self.meta.get_field("in_words"):
-			self.in_words = money_in_words(disable_rounded_total and 
+			self.in_words = money_in_words(disable_rounded_total and
 				self.grand_total or self.rounded_total, company_currency)
 		if self.meta.get_field("in_words_export"):
-			self.in_words_export = money_in_words(disable_rounded_total and 
+			self.in_words_export = money_in_words(disable_rounded_total and
 				self.grand_total_export or self.rounded_total_export, self.currency)
-				
+
 	def calculate_taxes_and_totals(self):
 		self.other_fname = "other_charges"
-		
+
 		super(SellingController, self).calculate_taxes_and_totals()
-		
+
 		self.calculate_total_advance("Sales Invoice", "advance_adjustment_details")
 		self.calculate_commission()
 		self.calculate_contribution()
-				
+
 	def determine_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):
 				tax.tax_fraction_for_current_item = self.get_current_tax_fraction(tax, item_tax_map)
-				
+
 				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 and not self.discount_amount_applied:
 				item.base_amount = flt((item.amount * self.conversion_rate) /
 					(1 + cumulated_tax_fraction), self.precision("base_amount", item))
-					
+
 				item.base_rate = flt(item.base_amount / item.qty, self.precision("base_rate", item))
-				
+
 				if item.discount_percentage == 100:
 					item.base_price_list_rate = item.base_rate
 					item.base_rate = 0.0
 				else:
 					item.base_price_list_rate = flt(item.base_rate / (1 - (item.discount_percentage / 100.0)),
 						self.precision("base_price_list_rate", item))
-			
+
 	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):
 		if not self.discount_amount_applied:
 			for item in self.item_doclist:
@@ -171,22 +171,22 @@
 		for item in self.item_doclist:
 			self.net_total += item.base_amount
 			self.net_total_export += item.amount
-		
+
 		self.round_floats_in(self, ["net_total", "net_total_export"])
-				
+
 	def calculate_totals(self):
 		self.grand_total = flt(self.tax_doclist and \
 			self.tax_doclist[-1].total or self.net_total, self.precision("grand_total"))
-		self.grand_total_export = flt(self.grand_total / self.conversion_rate, 
+		self.grand_total_export = flt(self.grand_total / self.conversion_rate,
 			self.precision("grand_total_export"))
-			
+
 		self.other_charges_total = flt(self.grand_total - self.net_total,
 			self.precision("other_charges_total"))
 
-		self.other_charges_total_export = flt(self.grand_total_export - 
-			self.net_total_export + flt(self.discount_amount), 
+		self.other_charges_total_export = flt(self.grand_total_export -
+			self.net_total_export + flt(self.discount_amount),
 			self.precision("other_charges_total_export"))
-		
+
 		self.rounded_total = _round(self.grand_total)
 		self.rounded_total_export = _round(self.grand_total_export)
 
@@ -214,12 +214,12 @@
 					flt(tax.rate) / 100
 				actual_taxes_dict.setdefault(tax.idx, actual_tax_amount)
 
-		grand_total_for_discount_amount = flt(self.grand_total - sum(actual_taxes_dict.values()), 
+		grand_total_for_discount_amount = flt(self.grand_total - sum(actual_taxes_dict.values()),
 			self.precision("grand_total"))
 		return grand_total_for_discount_amount
 
 	def calculate_outstanding_amount(self):
-		# NOTE: 
+		# NOTE:
 		# write_off_amount is only for POS Invoice
 		# total_advance is only for non POS Invoice
 		if self.doctype == "Sales Invoice" and self.docstatus == 0:
@@ -228,14 +228,14 @@
 			total_amount_to_pay = self.grand_total - self.write_off_amount
 			self.outstanding_amount = flt(total_amount_to_pay - self.total_advance \
 				- self.paid_amount,	self.precision("outstanding_amount"))
-		
+
 	def calculate_commission(self):
 		if self.meta.get_field("commission_rate"):
 			self.round_floats_in(self, ["net_total", "commission_rate"])
 			if self.commission_rate > 100.0:
-				msgprint(_(self.meta.get_label("commission_rate")) + " " + 
+				msgprint(_(self.meta.get_label("commission_rate")) + " " +
 					_("cannot be greater than 100"), raise_exception=True)
-		
+
 			self.total_commission = flt(self.net_total * self.commission_rate / 100.0,
 				self.precision("total_commission"))
 
@@ -248,66 +248,66 @@
 			sales_person.allocated_amount = flt(
 				self.net_total * sales_person.allocated_percentage / 100.0,
 				self.precision("allocated_amount", sales_person))
-			
+
 			total += sales_person.allocated_percentage
-		
+
 		if sales_team and total != 100.0:
-			msgprint(_("Total") + " " + 
-				_(self.meta.get_label("allocated_percentage", parentfield="sales_team")) + 
+			msgprint(_("Total") + " " +
+				_(self.meta.get_label("allocated_percentage", parentfield="sales_team")) +
 				" " + _("should be 100%"), raise_exception=True)
-			
+
 	def validate_order_type(self):
 		valid_types = ["Sales", "Maintenance", "Shopping Cart"]
 		if not self.order_type:
 			self.order_type = "Sales"
 		elif self.order_type not in valid_types:
-			msgprint(_(self.meta.get_label("order_type")) + " " + 
+			msgprint(_(self.meta.get_label("order_type")) + " " +
 				_("must be one of") + ": " + comma_or(valid_types), raise_exception=True)
-				
+
 	def check_credit(self, grand_total):
-		customer_account = frappe.db.get_value("Account", {"company": self.company, 
+		customer_account = frappe.db.get_value("Account", {"company": self.company,
 			"master_name": self.customer}, "name")
 		if customer_account:
-			total_outstanding = frappe.db.sql("""select 
-				sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) 
+			total_outstanding = frappe.db.sql("""select
+				sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
 				from `tabGL Entry` where account = %s""", customer_account)
 			total_outstanding = total_outstanding[0][0] if total_outstanding else 0
-			
+
 			outstanding_including_current = flt(total_outstanding) + flt(grand_total)
-			frappe.get_doc('Account', customer_account).run_method("check_credit_limit", 
+			frappe.get_doc('Account', customer_account).run_method("check_credit_limit",
 				outstanding_including_current)
-				
+
 	def validate_max_discount(self):
 		for d in self.get(self.fname):
 			discount = flt(frappe.db.get_value("Item", d.item_code, "max_discount"))
-			
+
 			if discount and flt(d.discount_percentage) > discount:
-				frappe.throw(_("You cannot give more than ") + cstr(discount) + "% " + 
+				frappe.throw(_("You cannot give more than ") + cstr(discount) + "% " +
 					_("discount on Item Code") + ": " + cstr(d.item_code))
-					
+
 	def get_item_list(self):
 		il = []
 		for d in self.get(self.fname):
 			reserved_warehouse = ""
 			reserved_qty_for_main_item = 0
-			
+
 			if self.doctype == "Sales Order":
-				if (frappe.db.get_value("Item", d.item_code, "is_stock_item") == 'Yes' or 
+				if (frappe.db.get_value("Item", d.item_code, "is_stock_item") == 'Yes' or
 					self.has_sales_bom(d.item_code)) and not d.warehouse:
-						frappe.throw(_("Please enter Reserved Warehouse for item ") + 
+						frappe.throw(_("Please enter Reserved Warehouse for item ") +
 							d.item_code + _(" as it is stock Item or packing item"))
 				reserved_warehouse = d.warehouse
 				if flt(d.qty) > flt(d.delivered_qty):
 					reserved_qty_for_main_item = flt(d.qty) - flt(d.delivered_qty)
-				
-			if self.doctype == "Delivery Note" and d.against_sales_order:
+
+			elif self.doctype == "Delivery Note" and d.against_sales_order:
 				# if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12.
 				# But in this case reserved qty should only be reduced by 10 and not 12
-				
-				already_delivered_qty = self.get_already_delivered_qty(self.name, 
+
+				already_delivered_qty = self.get_already_delivered_qty(self.name,
 					d.against_sales_order, d.prevdoc_detail_docname)
 				so_qty, reserved_warehouse = self.get_so_qty_and_warehouse(d.prevdoc_detail_docname)
-				
+
 				if already_delivered_qty + d.qty > so_qty:
 					reserved_qty_for_main_item = -(so_qty - already_delivered_qty)
 				else:
@@ -341,15 +341,15 @@
 					'name': d.name
 				}))
 		return il
-		
+
 	def has_sales_bom(self, item_code):
-		return frappe.db.sql("""select name from `tabSales BOM` 
+		return frappe.db.sql("""select name from `tabSales BOM`
 			where new_item_code=%s and docstatus != 2""", item_code)
-			
+
 	def get_already_delivered_qty(self, dn, so, so_detail):
-		qty = frappe.db.sql("""select sum(qty) from `tabDelivery Note Item` 
-			where prevdoc_detail_docname = %s and docstatus = 1 
-			and against_sales_order = %s 
+		qty = frappe.db.sql("""select sum(qty) from `tabDelivery Note Item`
+			where prevdoc_detail_docname = %s and docstatus = 1
+			and against_sales_order = %s
 			and parent != %s""", (so_detail, so, dn))
 		return qty and flt(qty[0][0]) or 0.0
 
@@ -359,24 +359,24 @@
 		so_qty = so_item and flt(so_item[0]["qty"]) or 0.0
 		so_warehouse = so_item and so_item[0]["warehouse"] or ""
 		return so_qty, so_warehouse
-		
+
 	def check_stop_sales_order(self, ref_fieldname):
 		for d in self.get(self.fname):
 			if d.get(ref_fieldname):
 				status = frappe.db.get_value("Sales Order", d.get(ref_fieldname), "status")
 				if status == "Stopped":
-					frappe.throw(self.doctype + 
-						_(" can not be created/modified against stopped Sales Order ") + 
+					frappe.throw(self.doctype +
+						_(" can not be created/modified against stopped Sales Order ") +
 						d.get(ref_fieldname))
-		
+
 def check_active_sales_items(obj):
 	for d in obj.get(obj.fname):
 		if d.item_code:
-			item = frappe.db.sql("""select docstatus, is_sales_item, 
-				is_service_item, income_account from tabItem where name = %s""", 
+			item = frappe.db.sql("""select docstatus, is_sales_item,
+				is_service_item, income_account from tabItem where name = %s""",
 				d.item_code, as_dict=True)[0]
 			if item.is_sales_item == 'No' and item.is_service_item == 'No':
 				frappe.throw(_("Item is neither Sales nor Service Item") + ": " + d.item_code)
 			if getattr(d, "income_account", None) and not item.income_account:
-				frappe.db.set_value("Item", d.item_code, "income_account", 
+				frappe.db.set_value("Item", d.item_code, "income_account",
 					d.income_account)
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index aa96b7c..206c963 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -14,15 +14,15 @@
 class BOM(Document):
 
 	def autoname(self):
-		last_name = frappe.db.sql("""select max(name) from `tabBOM` 
+		last_name = frappe.db.sql("""select max(name) from `tabBOM`
 			where name like "BOM/%s/%%" """ % cstr(self.item).replace('"', '\\"'))
 		if last_name:
 			idx = cint(cstr(last_name[0][0]).split('/')[-1].split('-')[0]) + 1
-			
+
 		else:
 			idx = 1
 		self.name = 'BOM/' + self.item + ('/%.3i' % idx)
-	
+
 	def validate(self):
 		self.clear_operations()
 		self.validate_main_item()
@@ -34,12 +34,11 @@
 		self.validate_materials()
 		self.set_bom_material_details()
 		self.calculate_cost()
-		
+
 	def on_update(self):
 		self.check_recursion()
 		self.update_exploded_items()
-		self.db_update()
-	
+
 	def on_submit(self):
 		self.manage_default_bom()
 
@@ -50,48 +49,48 @@
 		# check if used in any other bom
 		self.validate_bom_links()
 		self.manage_default_bom()
-				
+
 	def on_update_after_submit(self):
 		self.validate_bom_links()
 		self.manage_default_bom()
 
 	def get_item_det(self, item_code):
-		item = frappe.db.sql("""select name, is_asset_item, is_purchase_item, 
-			docstatus, description, is_sub_contracted_item, stock_uom, default_bom, 
-			last_purchase_rate, standard_rate, is_manufactured_item 
+		item = frappe.db.sql("""select name, is_asset_item, is_purchase_item,
+			docstatus, description, is_sub_contracted_item, stock_uom, default_bom,
+			last_purchase_rate, standard_rate, is_manufactured_item
 			from `tabItem` where name=%s""", item_code, as_dict = 1)
 
 		return item
-		
+
 	def validate_rm_item(self, item):
 		if item[0]['name'] == self.item:
-			msgprint("Item_code: %s in materials tab cannot be same as FG Item", 
+			msgprint("Item_code: %s in materials tab cannot be same as FG Item",
 				item[0]['name'], raise_exception=1)
-		
+
 		if not item or item[0]['docstatus'] == 2:
 			msgprint("Item %s does not exist in system" % item[0]['item_code'], raise_exception = 1)
-			
+
 	def set_bom_material_details(self):
 		for item in self.get("bom_materials"):
-			ret = self.get_bom_material_detail({"item_code": item.item_code, "bom_no": item.bom_no, 
+			ret = self.get_bom_material_detail({"item_code": item.item_code, "bom_no": item.bom_no,
 				"qty": item.qty})
 
 			for r in ret:
 				if not item.get(r):
 					item.set(r, ret[r])
-		
+
 	def get_bom_material_detail(self, args=None):
 		""" Get raw material details like uom, desc and rate"""
 		if not args:
 			args = frappe.form_dict.get('args')
-		
+
 		if isinstance(args, basestring):
 			import json
 			args = json.loads(args)
-				
+
 		item = self.get_item_det(args['item_code'])
 		self.validate_rm_item(item)
-		
+
 		args['bom_no'] = args['bom_no'] or item and cstr(item[0]['default_bom']) or ''
 		args.update(item[0])
 
@@ -117,27 +116,23 @@
 			elif self.rm_cost_as_per == "Price List":
 				if not self.buying_price_list:
 					frappe.throw(_("Please select Price List"))
-				rate = frappe.db.get_value("Item Price", {"price_list": self.buying_price_list, 
+				rate = frappe.db.get_value("Item Price", {"price_list": self.buying_price_list,
 					"item_code": arg["item_code"]}, "price_list_rate") or 0
 			elif self.rm_cost_as_per == 'Standard Rate':
 				rate = arg['standard_rate']
 
 		return rate
-		
+
 	def update_cost(self):
 		for d in self.get("bom_materials"):
 			d.rate = self.get_bom_material_detail({
-				'item_code': d.item_code, 
+				'item_code': d.item_code,
 				'bom_no': d.bom_no,
 				'qty': d.qty
 			})["rate"]
-		
-		if self.docstatus == 0:
+
+		if self.docstatus in (0, 1):
 			self.save()
-		elif self.docstatus == 1:
-			self.calculate_cost()
-			self.update_exploded_items()
-			self.update_after_submit()
 
 	def get_bom_unitcost(self, bom_no):
 		bom = frappe.db.sql("""select name, total_cost/quantity as unit_cost from `tabBOM`
@@ -145,9 +140,9 @@
 		return bom and bom[0]['unit_cost'] or 0
 
 	def get_valuation_rate(self, args):
-		""" Get average valuation rate of relevant warehouses 
-			as per valuation method (MAR/FIFO) 
-			as on costing date	
+		""" Get average valuation rate of relevant warehouses
+			as per valuation method (MAR/FIFO)
+			as on costing date
 		"""
 		from erpnext.stock.utils import get_incoming_rate
 		dt = self.costing_date or nowdate()
@@ -168,19 +163,19 @@
 		return rate and flt(sum(rate))/len(rate) or 0
 
 	def manage_default_bom(self):
-		""" Uncheck others if current one is selected as default, 
+		""" Uncheck others if current one is selected as default,
 			update default bom in item master
 		"""
 		if self.is_default and self.is_active:
 			from frappe.model.utils import set_default
 			set_default(self, "item")
 			frappe.db.set_value("Item", self.item, "default_bom", self.name)
-		
+
 		else:
 			if not self.is_active:
 				frappe.db.set(self, "is_default", 0)
-			
-			frappe.db.sql("update `tabItem` set default_bom = null where name = %s and default_bom = %s", 
+
+			frappe.db.sql("update `tabItem` set default_bom = null where name = %s and default_bom = %s",
 				 (self.item, self.name))
 
 	def clear_operations(self):
@@ -193,7 +188,7 @@
 		""" Validate main FG item"""
 		item = self.get_item_det(self.item)
 		if not item:
-			msgprint("Item %s does not exists in the system or expired." % 
+			msgprint("Item %s does not exists in the system or expired." %
 				self.item, raise_exception = 1)
 		elif item[0]['is_manufactured_item'] != 'Yes' \
 				and item[0]['is_sub_contracted_item'] != 'Yes':
@@ -209,7 +204,7 @@
 		self.op = []
 		for d in self.get('bom_operations'):
 			if cstr(d.operation_no) in self.op:
-				msgprint("Operation no: %s is repeated in Operations Table" % 
+				msgprint("Operation no: %s is repeated in Operations Table" %
 					d.operation_no, raise_exception=1)
 			else:
 				# add operation in op list
@@ -222,36 +217,36 @@
 			# check if operation no not in op table
 			if self.with_operations and cstr(m.operation_no) not in self.op:
 				msgprint("""Operation no: %s against item: %s at row no: %s \
-					is not present at Operations table""" % 
+					is not present at Operations table""" %
 					(m.operation_no, m.item_code, m.idx), raise_exception = 1)
-			
+
 			item = self.get_item_det(m.item_code)
 			if item[0]['is_manufactured_item'] == 'Yes':
 				if not m.bom_no:
-					msgprint("Please enter BOM No aginst item: %s at row no: %s" % 
+					msgprint("Please enter BOM No aginst item: %s at row no: %s" %
 						(m.item_code, m.idx), raise_exception=1)
 				else:
 					self.validate_bom_no(m.item_code, m.bom_no, m.idx)
 
 			elif m.bom_no:
 				msgprint("""As Item %s is not a manufactured / sub-contracted item, \
-					you can not enter BOM against it (Row No: %s).""" % 
+					you can not enter BOM against it (Row No: %s).""" %
 					(m.item_code, m.idx), raise_exception = 1)
 
 			if flt(m.qty) <= 0:
-				msgprint("Please enter qty against raw material: %s at row no: %s" % 
+				msgprint("Please enter qty against raw material: %s at row no: %s" %
 					(m.item_code, m.idx), raise_exception = 1)
 
 			self.check_if_item_repeated(m.item_code, m.operation_no, check_list)
 
 	def validate_bom_no(self, item, bom_no, idx):
 		"""Validate BOM No of sub-contracted items"""
-		bom = frappe.db.sql("""select name from `tabBOM` where name = %s and item = %s 
-			and is_active=1 and docstatus=1""", 
+		bom = frappe.db.sql("""select name from `tabBOM` where name = %s and item = %s
+			and is_active=1 and docstatus=1""",
 			(bom_no, item), as_dict =1)
 		if not bom:
 			msgprint("""Incorrect BOM No: %s against item: %s at row no: %s.
-				It may be inactive or not submitted or does not belong to this item.""" % 
+				It may be inactive or not submitted or does not belong to this item.""" %
 				(bom_no, item, idx), raise_exception = 1)
 
 	def check_if_item_repeated(self, item, op, check_list):
@@ -268,7 +263,7 @@
 		for d in check_list:
 			bom_list, count = [self.name], 0
 			while (len(bom_list) > count ):
-				boms = frappe.db.sql(" select %s from `tabBOM Item` where %s = %s " % 
+				boms = frappe.db.sql(" select %s from `tabBOM Item` where %s = %s " %
 					(d[0], d[1], '%s'), cstr(bom_list[count]))
 				count = count + 1
 				for b in boms:
@@ -277,24 +272,24 @@
 							""" % (cstr(b[0]), cstr(d[2]), self.name), raise_exception = 1)
 					if b[0]:
 						bom_list.append(b[0])
-	
+
 	def update_cost_and_exploded_items(self, bom_list=[]):
 		bom_list = self.traverse_tree(bom_list)
 		for bom in bom_list:
 			bom_obj = frappe.get_doc("BOM", bom)
 			bom_obj.on_update()
-			
+
 		return bom_list
-			
+
 	def traverse_tree(self, bom_list=[]):
 		def _get_children(bom_no):
-			return [cstr(d[0]) for d in frappe.db.sql("""select bom_no from `tabBOM Item` 
+			return [cstr(d[0]) for d in frappe.db.sql("""select bom_no from `tabBOM Item`
 				where parent = %s and ifnull(bom_no, '') != ''""", bom_no)]
-				
+
 		count = 0
 		if self.name not in bom_list:
 			bom_list.append(self.name)
-		
+
 		while(count < len(bom_list)):
 			for child_bom in _get_children(bom_list[count]):
 				if child_bom not in bom_list:
@@ -302,7 +297,7 @@
 			count += 1
 		bom_list.reverse()
 		return bom_list
-	
+
 	def calculate_cost(self):
 		"""Calculate bom totals"""
 		self.calculate_op_cost()
@@ -319,7 +314,7 @@
 				d.operating_cost = flt(d.hour_rate) * flt(d.time_in_mins) / 60.0
 			total_op_cost += flt(d.operating_cost)
 		self.operating_cost = total_op_cost
-		
+
 	def calculate_rm_cost(self):
 		"""Fetch RM rate as per today's valuation rate and calculate totals"""
 		total_rm_cost = 0
@@ -329,7 +324,7 @@
 			d.amount = flt(d.rate) * flt(d.qty)
 			d.qty_consumed_per_unit = flt(d.qty) / flt(self.quantity)
 			total_rm_cost += d.amount
-			
+
 		self.raw_material_cost = total_rm_cost
 
 	def update_exploded_items(self):
@@ -345,38 +340,38 @@
 				self.get_child_exploded_items(d.bom_no, d.qty)
 			else:
 				self.add_to_cur_exploded_items(frappe._dict({
-					'item_code'				: d.item_code, 
-					'description'			: d.description, 
-					'stock_uom'				: d.stock_uom, 
+					'item_code'				: d.item_code,
+					'description'			: d.description,
+					'stock_uom'				: d.stock_uom,
 					'qty'					: flt(d.qty),
 					'rate'					: flt(d.rate),
 				}))
-				
+
 	def add_to_cur_exploded_items(self, args):
 		if self.cur_exploded_items.get(args.item_code):
 			self.cur_exploded_items[args.item_code]["qty"] += args.qty
 		else:
 			self.cur_exploded_items[args.item_code] = args
-	
+
 	def get_child_exploded_items(self, bom_no, qty):
 		""" Add all items from Flat BOM of child BOM"""
-		
-		child_fb_items = frappe.db.sql("""select item_code, description, stock_uom, qty, rate, 
-			qty_consumed_per_unit from `tabBOM Explosion Item` 
+
+		child_fb_items = frappe.db.sql("""select item_code, description, stock_uom, qty, rate,
+			qty_consumed_per_unit from `tabBOM Explosion Item`
 			where parent = %s and docstatus = 1""", bom_no, as_dict = 1)
-			
+
 		for d in child_fb_items:
 			self.add_to_cur_exploded_items(frappe._dict({
-				'item_code'				: d['item_code'], 
-				'description'			: d['description'], 
-				'stock_uom'				: d['stock_uom'], 
+				'item_code'				: d['item_code'],
+				'description'			: d['description'],
+				'stock_uom'				: d['stock_uom'],
 				'qty'					: flt(d['qty_consumed_per_unit'])*qty,
 				'rate'					: flt(d['rate']),
 			}))
 
 	def add_exploded_items(self):
 		"Add items to Flat BOM table"
-		self.set('flat_bom_details', [])
+		frappe.db.sql("""delete from `tabBOM Explosion Item` where parent=%s""", self.name)
 		for d in self.cur_exploded_items:
 			ch = self.append('flat_bom_details', {})
 			for i in self.cur_exploded_items[d].keys():
@@ -384,7 +379,7 @@
 			ch.amount = flt(ch.qty) * flt(ch.rate)
 			ch.qty_consumed_per_unit = flt(ch.qty) / flt(self.quantity)
 			ch.docstatus = self.docstatus
-			ch.db_update()
+			ch.db_insert()
 
 	def validate_bom_links(self):
 		if not self.is_active:
@@ -399,26 +394,27 @@
 					raise_exception=1)
 
 def get_bom_items_as_dict(bom, qty=1, fetch_exploded=1):
+	import json
 	item_dict = {}
-		
-	query = """select 
+
+	query = """select
 				bom_item.item_code,
 				item.item_name,
-				ifnull(sum(bom_item.qty_consumed_per_unit),0) * %(qty)s as qty, 
-				item.description, 
+				ifnull(sum(bom_item.qty_consumed_per_unit),0) * %(qty)s as qty,
+				item.description,
 				item.stock_uom,
 				item.default_warehouse,
 				item.expense_account as expense_account,
 				item.buying_cost_center as cost_center
-			from 
-				`tab%(table)s` bom_item, `tabItem` item 
-			where 
-				bom_item.docstatus < 2 
+			from
+				`tab%(table)s` bom_item, `tabItem` item
+			where
+				bom_item.docstatus < 2
 				and bom_item.parent = "%(bom)s"
-				and item.name = bom_item.item_code 
+				and item.name = bom_item.item_code
 				%(conditions)s
 				group by item_code, stock_uom"""
-	
+
 	if fetch_exploded:
 		items = frappe.db.sql(query % {
 			"qty": qty,
@@ -441,7 +437,7 @@
 			item_dict[item.item_code]["qty"] += flt(item.qty)
 		else:
 			item_dict[item.item_code] = item
-		
+
 	return item_dict
 
 @frappe.whitelist()
diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py
index 074daa4..28ee49a 100644
--- a/erpnext/manufacturing/doctype/bom/test_bom.py
+++ b/erpnext/manufacturing/doctype/bom/test_bom.py
@@ -12,19 +12,19 @@
 	def test_get_items(self):
 		from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
 		items_dict = get_bom_items_as_dict(bom="BOM/_Test FG Item 2/001", qty=1, fetch_exploded=0)
-		self.assertTrue(test_records[2][1]["item_code"] in items_dict)
-		self.assertTrue(test_records[2][2]["item_code"] in items_dict)
+		self.assertTrue(test_records[2]["bom_materials"][0]["item_code"] in items_dict)
+		self.assertTrue(test_records[2]["bom_materials"][1]["item_code"] in items_dict)
 		self.assertEquals(len(items_dict.values()), 2)
-		
+
 	def test_get_items_exploded(self):
 		from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
 		items_dict = get_bom_items_as_dict(bom="BOM/_Test FG Item 2/001", qty=1, fetch_exploded=1)
-		self.assertTrue(test_records[2][1]["item_code"] in items_dict)
-		self.assertFalse(test_records[2][2]["item_code"] in items_dict)
-		self.assertTrue(test_records[0][1]["item_code"] in items_dict)
-		self.assertTrue(test_records[0][2]["item_code"] in items_dict)
+		self.assertTrue(test_records[2]["bom_materials"][0]["item_code"] in items_dict)
+		self.assertFalse(test_records[2]["bom_materials"][1]["item_code"] in items_dict)
+		self.assertTrue(test_records[0]["bom_materials"][0]["item_code"] in items_dict)
+		self.assertTrue(test_records[0]["bom_materials"][1]["item_code"] in items_dict)
 		self.assertEquals(len(items_dict.values()), 3)
-		
+
 	def test_get_items_list(self):
 		from erpnext.manufacturing.doctype.bom.bom import get_bom_items
-		self.assertEquals(len(get_bom_items(bom="BOM/_Test FG Item 2/001", qty=1, fetch_exploded=1)), 3)
\ No newline at end of file
+		self.assertEquals(len(get_bom_items(bom="BOM/_Test FG Item 2/001", qty=1, fetch_exploded=1)), 3)
diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py
index 81fc616..9bc001d 100644
--- a/erpnext/manufacturing/doctype/production_order/test_production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py
@@ -16,51 +16,53 @@
 		frappe.db.sql("delete from `tabStock Ledger Entry`")
 		frappe.db.sql("""delete from `tabBin`""")
 		frappe.db.sql("""delete from `tabGL Entry`""")
-		
+
 		pro_doc = frappe.copy_doc(test_records[0])
 		pro_doc.insert()
 		pro_doc.submit()
-		
+
 		from erpnext.stock.doctype.stock_entry.test_stock_entry import test_records as se_test_records
 		mr1 = frappe.copy_doc(se_test_records[0])
 		mr1.insert()
 		mr1.submit()
-		
+
 		mr2 = frappe.copy_doc(se_test_records[0])
 		mr2.get("mtn_details")[0].item_code = "_Test Item Home Desktop 100"
 		mr2.insert()
 		mr2.submit()
-		
+
 		stock_entry = make_stock_entry(pro_doc.name, "Manufacture/Repack")
 		stock_entry = frappe.get_doc(stock_entry)
 		stock_entry.fiscal_year = "_Test Fiscal Year 2013"
 		stock_entry.fg_completed_qty = 4
 		stock_entry.posting_date = "2013-05-12"
 		stock_entry.fiscal_year = "_Test Fiscal Year 2013"
+		stock_entry.set("mtn_details", [])
 		stock_entry.run_method("get_items")
 		stock_entry.submit()
-		
-		self.assertEqual(frappe.db.get_value("Production Order", pro_doc.name, 
+
+		self.assertEqual(frappe.db.get_value("Production Order", pro_doc.name,
 			"produced_qty"), 4)
-		self.assertEqual(frappe.db.get_value("Bin", {"item_code": "_Test FG Item", 
+		self.assertEqual(frappe.db.get_value("Bin", {"item_code": "_Test FG Item",
 			"warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty"), 6)
-			
+
 		return pro_doc.name
-			
+
 	def test_over_production(self):
 		from erpnext.stock.doctype.stock_entry.stock_entry import StockOverProductionError
 		pro_order = self.test_planned_qty()
-		
+
 		stock_entry = make_stock_entry(pro_order, "Manufacture/Repack")
 		stock_entry = frappe.get_doc(stock_entry)
 		stock_entry.posting_date = "2013-05-12"
 		stock_entry.fiscal_year = "_Test Fiscal Year 2013"
 		stock_entry.fg_completed_qty = 15
+		stock_entry.set("mtn_details", [])
 		stock_entry.run_method("get_items")
 		stock_entry.insert()
-		
-		self.assertRaises(StockOverProductionError, stock_entry.submit)
-			
-		
 
-test_records = frappe.get_test_records('Production Order')
\ No newline at end of file
+		self.assertRaises(StockOverProductionError, stock_entry.submit)
+
+
+
+test_records = frappe.get_test_records('Production Order')
diff --git a/erpnext/projects/doctype/time_log/test_time_log.py b/erpnext/projects/doctype/time_log/test_time_log.py
index eedad0b..7aadf5c 100644
--- a/erpnext/projects/doctype/time_log/test_time_log.py
+++ b/erpnext/projects/doctype/time_log/test_time_log.py
@@ -7,8 +7,9 @@
 from erpnext.projects.doctype.time_log.time_log import OverlapError
 
 class TestTimeLog(unittest.TestCase):
-	def test_duplication(self):		
+	def test_duplication(self):
 		ts = frappe.get_doc(frappe.copy_doc(test_records[0]))
 		self.assertRaises(OverlapError, ts.insert)
 
-test_records = frappe.get_test_records('Time Log')
\ No newline at end of file
+test_records = frappe.get_test_records('Time Log')
+test_ignore = ["Time Log Batch", "Sales Invoice"]
diff --git a/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py b/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
index 004c364..fdbc210 100644
--- a/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
+++ b/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
@@ -14,10 +14,10 @@
 		})
 		time_log.insert()
 		time_log.submit()
-		
+
 		self.assertEquals(frappe.db.get_value("Time Log", time_log.name, "status"), "Submitted")
 		tlb = frappe.copy_doc(test_records[0])
-		tlb["time_log_batch_details"][0].time_log = time_log.name
+		tlb.get("time_log_batch_details")[0].time_log = time_log.name
 		tlb.insert()
 		tlb.submit()
 
@@ -25,4 +25,6 @@
 		tlb.cancel()
 		self.assertEquals(frappe.db.get_value("Time Log", time_log.name, "status"), "Submitted")
 
-test_records = frappe.get_test_records('Time Log Batch')
\ No newline at end of file
+test_records = frappe.get_test_records('Time Log Batch')
+test_dependencies = ["Time Log"]
+test_ignore = ["Sales Invoice"]
diff --git a/erpnext/projects/doctype/time_log_batch/time_log_batch.py b/erpnext/projects/doctype/time_log_batch/time_log_batch.py
index 4ad8130..b8204e4 100644
--- a/erpnext/projects/doctype/time_log_batch/time_log_batch.py
+++ b/erpnext/projects/doctype/time_log_batch/time_log_batch.py
@@ -31,17 +31,17 @@
 		if tl.status != "Submitted" and self.docstatus == 0:
 			frappe.msgprint(_("Time Log must have status 'Submitted'") + \
 				" :" + tl.name + " (" + _(tl.status) + ")", raise_exception=True)
-	
+
 	def set_status(self):
 		self.status = {
 			"0": "Draft",
 			"1": "Submitted",
 			"2": "Cancelled"
 		}[str(self.docstatus or 0)]
-		
+
 		if self.sales_invoice:
 			self.status = "Billed"
-	
+
 	def on_submit(self):
 		self.update_status(self.name)
 
@@ -57,4 +57,4 @@
 			tl = frappe.get_doc("Time Log", d.time_log)
 			tl.time_log_batch = time_log_batch
 			tl.sales_invoice = self.sales_invoice
-			tl.update_after_submit()
\ No newline at end of file
+			tl.save()
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index e5364d0..361f4fa 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -12,7 +12,7 @@
 from erpnext.accounts.party import create_party_account
 
 class Customer(TransactionBase):
-				
+
 	def autoname(self):
 		cust_master_name = frappe.defaults.get_global_default('cust_master_name')
 		if cust_master_name == 'Customer Name':
@@ -24,7 +24,7 @@
 
 	def get_company_abbr(self):
 		return frappe.db.get_value('Company', self.company, 'abbr')
-	
+
 	def validate_values(self):
 		if frappe.defaults.get_global_default('cust_master_name') == 'Naming Series' and not self.naming_series:
 			frappe.throw("Series is Mandatory.", frappe.MandatoryError)
@@ -37,28 +37,27 @@
 			frappe.db.sql("update `tabLead` set status='Converted' where name = %s", self.lead_name)
 
 	def update_address(self):
-		frappe.db.sql("""update `tabAddress` set customer_name=%s, modified=NOW() 
+		frappe.db.sql("""update `tabAddress` set customer_name=%s, modified=NOW()
 			where customer=%s""", (self.customer_name, self.name))
 
 	def update_contact(self):
-		frappe.db.sql("""update `tabContact` set customer_name=%s, modified=NOW() 
+		frappe.db.sql("""update `tabContact` set customer_name=%s, modified=NOW()
 			where customer=%s""", (self.customer_name, self.name))
 
 	def update_credit_days_limit(self):
-		frappe.db.sql("""update tabAccount set credit_days = %s, credit_limit = %s 
-			where master_type='Customer' and master_name = %s""", 
+		frappe.db.sql("""update tabAccount set credit_days = %s, credit_limit = %s
+			where master_type='Customer' and master_name = %s""",
 			(self.credit_days or 0, self.credit_limit or 0, self.name))
 
 	def create_lead_address_contact(self):
 		if self.lead_name:
-			if not frappe.db.get_value("Address", {"lead": self.lead_name, "customer": self.customer}):
-				frappe.db.sql("""update `tabAddress` set customer=%s, customer_name=%s where lead=%s""", 
+			if not frappe.db.get_value("Address", {"lead": self.lead_name, "customer": self.name}):
+				frappe.db.sql("""update `tabAddress` set customer=%s, customer_name=%s where lead=%s""",
 					(self.name, self.customer_name, self.lead_name))
 
 			lead = frappe.db.get_value("Lead", self.lead_name, ["lead_name", "email_id", "phone", "mobile_no"], as_dict=True)
-			c = frappe.get_doc('Contact')
-			c.set("__islocal", 1)
-			c.first_name = lead.lead_name 
+			c = frappe.new_doc('Contact')
+			c.first_name = lead.lead_name
 			c.email_id = lead.email_id
 			c.phone = lead.phone
 			c.mobile_no = lead.mobile_no
@@ -72,7 +71,7 @@
 
 	def on_update(self):
 		self.validate_name_with_customer_group()
-		
+
 		self.update_lead_status()
 		self.update_address()
 		self.update_contact()
@@ -84,29 +83,29 @@
 		self.update_credit_days_limit()
 		#create address and contact from lead
 		self.create_lead_address_contact()
-		
+
 	def validate_name_with_customer_group(self):
 		if frappe.db.exists("Customer Group", self.name):
 			frappe.msgprint("An Customer Group exists with same name (%s), \
-				please change the Customer name or rename the Customer Group" % 
+				please change the Customer name or rename the Customer Group" %
 				self.name, raise_exception=1)
 
 	def delete_customer_address(self):
 		addresses = frappe.db.sql("""select name, lead from `tabAddress`
 			where customer=%s""", (self.name,))
-		
+
 		for name, lead in addresses:
 			if lead:
 				frappe.db.sql("""update `tabAddress` set customer=null, customer_name=null
 					where name=%s""", name)
 			else:
 				frappe.db.sql("""delete from `tabAddress` where name=%s""", name)
-	
+
 	def delete_customer_contact(self):
-		for contact in frappe.db.sql_list("""select name from `tabContact` 
+		for contact in frappe.db.sql_list("""select name from `tabContact`
 			where customer=%s""", self.name):
 				frappe.delete_doc("Contact", contact)
-	
+
 	def delete_customer_account(self):
 		"""delete customer's ledger if exist and check balance before deletion"""
 		acc = frappe.db.sql("select name from `tabAccount` where master_type = 'Customer' \
@@ -120,7 +119,7 @@
 		self.delete_customer_account()
 		if self.lead_name:
 			frappe.db.sql("update `tabLead` set status='Interested' where name=%s",self.lead_name)
-			
+
 	def before_rename(self, olddn, newdn, merge=False):
 		from erpnext.accounts.utils import rename_account_for
 		rename_account_for("Customer", olddn, newdn, merge, self.company)
@@ -134,7 +133,7 @@
 		self.update_customer_address(newdn, set_field)
 
 	def update_customer_address(self, newdn, set_field):
-		frappe.db.sql("""update `tabAddress` set address_title=%(newdn)s 
+		frappe.db.sql("""update `tabAddress` set address_title=%(newdn)s
 			{set_field} where customer=%(newdn)s"""\
 			.format(set_field=set_field), ({"newdn": newdn}))
 
@@ -142,21 +141,21 @@
 def get_dashboard_info(customer):
 	if not frappe.has_permission("Customer", "read", customer):
 		frappe.msgprint("No Permission", raise_exception=True)
-	
+
 	out = {}
 	for doctype in ["Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
-		out[doctype] = frappe.db.get_value(doctype, 
+		out[doctype] = frappe.db.get_value(doctype,
 			{"customer": customer, "docstatus": ["!=", 2] }, "count(*)")
-	
-	billing = frappe.db.sql("""select sum(grand_total), sum(outstanding_amount) 
-		from `tabSales Invoice` 
-		where customer=%s 
+
+	billing = frappe.db.sql("""select sum(grand_total), sum(outstanding_amount)
+		from `tabSales Invoice`
+		where customer=%s
 			and docstatus = 1
 			and fiscal_year = %s""", (customer, frappe.db.get_default("fiscal_year")))
-	
+
 	out["total_billing"] = billing[0][0]
 	out["total_unpaid"] = billing[0][1]
-	
+
 	return out
 
 
@@ -165,11 +164,11 @@
 		fields = ["name", "customer_group", "territory"]
 	else:
 		fields = ["name", "customer_name", "customer_group", "territory"]
-		
-	return frappe.db.sql("""select %s from `tabCustomer` where docstatus < 2 
-		and (%s like %s or customer_name like %s) order by 
+
+	return frappe.db.sql("""select %s from `tabCustomer` where docstatus < 2
+		and (%s like %s or customer_name like %s) order by
 		case when name like %s then 0 else 1 end,
 		case when customer_name like %s then 0 else 1 end,
-		name, customer_name limit %s, %s""" % 
-		(", ".join(fields), searchfield, "%s", "%s", "%s", "%s", "%s", "%s"), 
-		("%%%s%%" % txt, "%%%s%%" % txt, "%%%s%%" % txt, "%%%s%%" % txt, start, page_len))
\ No newline at end of file
+		name, customer_name limit %s, %s""" %
+		(", ".join(fields), searchfield, "%s", "%s", "%s", "%s", "%s", "%s"),
+		("%%%s%%" % txt, "%%%s%%" % txt, "%%%s%%" % txt, "%%%s%%" % txt, start, page_len))
diff --git a/erpnext/selling/doctype/lead/lead.py b/erpnext/selling/doctype/lead/lead.py
index 57e73d0..8163be3 100644
--- a/erpnext/selling/doctype/lead/lead.py
+++ b/erpnext/selling/doctype/lead/lead.py
@@ -96,7 +96,7 @@
 			}
 		}}, target_doc, set_missing_values, ignore_permissions=ignore_permissions)
 		
-	return doclist.as_dict()
+	return doclist
 	
 @frappe.whitelist()
 def make_opportunity(source_name, target_doc=None):
diff --git a/erpnext/selling/doctype/lead/test_lead.py b/erpnext/selling/doctype/lead/test_lead.py
index 504f839..606e328 100644
--- a/erpnext/selling/doctype/lead/test_lead.py
+++ b/erpnext/selling/doctype/lead/test_lead.py
@@ -13,9 +13,9 @@
 		from erpnext.selling.doctype.lead.lead import make_customer
 
 		customer = make_customer("_T-Lead-00001")
-		self.assertEquals(customer[0]["doctype"], "Customer")
-		self.assertEquals(customer[0]["lead_name"], "_T-Lead-00001")
+		self.assertEquals(customer.doctype, "Customer")
+		self.assertEquals(customer.lead_name, "_T-Lead-00001")
 
-		customer[0]["company"] = "_Test Company"
-		customer[0]["customer_group"] = "_Test Customer Group"
-		frappe.get_doc(customer).insert()
+		customer.company = "_Test Company"
+		customer.customer_group = "_Test Customer Group"
+		customer.insert()
diff --git a/erpnext/selling/doctype/opportunity/opportunity.py b/erpnext/selling/doctype/opportunity/opportunity.py
index a2358a3..c87c983 100644
--- a/erpnext/selling/doctype/opportunity/opportunity.py
+++ b/erpnext/selling/doctype/opportunity/opportunity.py
@@ -161,4 +161,4 @@
 		}
 	}, target_doc, set_missing_values)
 		
-	return doclist.as_dict()
\ No newline at end of file
+	return doclist
\ No newline at end of file
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index f5c2050..d6ade9e 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -137,7 +137,7 @@
 		
 	# postprocess: fetch shipping address, set missing values
 		
-	return doclist.as_dict()
+	return doclist
 
 def _make_customer(source_name, ignore_permissions=False):
 	quotation = frappe.db.get_value("Quotation", source_name, ["lead", "order_type"])
diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py
index 54aa1c4..d393a3d 100644
--- a/erpnext/selling/doctype/quotation/test_quotation.py
+++ b/erpnext/selling/doctype/quotation/test_quotation.py
@@ -10,26 +10,26 @@
 class TestQuotation(unittest.TestCase):
 	def test_make_sales_order(self):
 		from erpnext.selling.doctype.quotation.quotation import make_sales_order
-		
+
 		quotation = frappe.copy_doc(test_records[0])
 		quotation.insert()
-		
+
 		self.assertRaises(frappe.ValidationError, make_sales_order, quotation.name)
-		
+
 		quotation.submit()
 
 		sales_order = make_sales_order(quotation.name)
-				
-		self.assertEquals(sales_order[0]["doctype"], "Sales Order")
-		self.assertEquals(len(sales_order), 2)
-		self.assertEquals(sales_order[1]["doctype"], "Sales Order Item")
-		self.assertEquals(sales_order[1]["prevdoc_docname"], quotation.name)
-		self.assertEquals(sales_order[0]["customer"], "_Test Customer")
-		
-		sales_order[0]["delivery_date"] = "2014-01-01"
-		sales_order[0]["naming_series"] = "_T-Quotation-"
-		sales_order[0]["transaction_date"] = "2013-05-12"
-		frappe.get_doc(sales_order).insert()
+
+		self.assertEquals(sales_order.doctype, "Sales Order")
+		self.assertEquals(len(sales_order.get("sales_order_details")), 2)
+		self.assertEquals(sales_order.get("sales_order_details")[0]["doctype"], "Sales Order Item")
+		self.assertEquals(sales_order.get("sales_order_details")[0]["prevdoc_docname"], quotation.name)
+		self.assertEquals(sales_order.customer, "_Test Customer")
+
+		sales_order.delivery_date = "2014-01-01"
+		sales_order.naming_series = "_T-Quotation-"
+		sales_order.transaction_date = "2013-05-12"
+		sales_order.insert()
 
 
-test_records = frappe.get_test_records('Quotation')
\ No newline at end of file
+test_records = frappe.get_test_records('Quotation')
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index d420e96..f4b6833 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -18,28 +18,28 @@
 	person_tname = 'Target Detail'
 	partner_tname = 'Partner Target Detail'
 	territory_tname = 'Territory Target Detail'
-	
+
 	def validate_mandatory(self):
 		# validate transaction date v/s delivery date
 		if self.delivery_date:
 			if getdate(self.transaction_date) > getdate(self.delivery_date):
 				msgprint("Expected Delivery Date cannot be before Sales Order Date")
 				raise Exception
-	
+
 	def validate_po(self):
 		# validate p.o date v/s delivery date
 		if self.po_date and self.delivery_date and getdate(self.po_date) > getdate(self.delivery_date):
 			msgprint("Expected Delivery Date cannot be before Purchase Order Date")
-			raise Exception	
-		
+			raise Exception
+
 		if self.po_no and self.customer:
 			so = frappe.db.sql("select name from `tabSales Order` \
 				where ifnull(po_no, '') = %s and name != %s and docstatus < 2\
 				and customer = %s", (self.po_no, self.name, self.customer))
 			if so and so[0][0]:
-				msgprint("""Another Sales Order (%s) exists against same PO No and Customer. 
+				msgprint("""Another Sales Order (%s) exists against same PO No and Customer.
 					Please be sure, you are not making duplicate entry.""" % so[0][0])
-	
+
 	def validate_for_items(self):
 		check_list, flag = [], 0
 		chk_dupl_itm = []
@@ -49,9 +49,9 @@
 
 			if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 'Yes':
 				if not d.warehouse:
-					msgprint("""Please enter Reserved Warehouse for item %s 
+					msgprint("""Please enter Reserved Warehouse for item %s
 						as it is stock Item""" % d.item_code, raise_exception=1)
-				
+
 				if e in check_list:
 					msgprint("Item %s has been entered twice." % d.item_code)
 				else:
@@ -64,7 +64,7 @@
 
 			# used for production plan
 			d.transaction_date = self.transaction_date
-			
+
 			tot_avail_qty = frappe.db.sql("select projected_qty from `tabBin` \
 				where item_code = %s and warehouse = %s", (d.item_code,d.warehouse))
 			d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0
@@ -79,26 +79,26 @@
 
 	def validate_order_type(self):
 		super(SalesOrder, self).validate_order_type()
-		
+
 	def validate_delivery_date(self):
 		if self.order_type == 'Sales' and not self.delivery_date:
 			msgprint("Please enter 'Expected Delivery Date'")
 			raise Exception
-		
+
 		self.validate_sales_mntc_quotation()
 
 	def validate_proj_cust(self):
 		if self.project_name and self.customer_name:
-			res = frappe.db.sql("""select name from `tabProject` where name = %s 
-				and (customer = %s or ifnull(customer,'')='')""", 
+			res = frappe.db.sql("""select name from `tabProject` where name = %s
+				and (customer = %s or ifnull(customer,'')='')""",
 					(self.project_name, self.customer))
 			if not res:
 				msgprint("Customer - %s does not belong to project - %s. \n\nIf you want to use project for multiple customers then please make customer details blank in project - %s."%(self.customer,self.project_name,self.project_name))
 				raise Exception
-	
+
 	def validate(self):
 		super(SalesOrder, self).validate()
-		
+
 		self.validate_order_type()
 		self.validate_delivery_date()
 		self.validate_mandatory()
@@ -111,28 +111,28 @@
 		from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
 
 		make_packing_list(self,'sales_order_details')
-		
+
 		self.validate_with_previous_doc()
-		
+
 		if not self.status:
 			self.status = "Draft"
 
 		from erpnext.utilities import validate_status
-		validate_status(self.status, ["Draft", "Submitted", "Stopped", 
+		validate_status(self.status, ["Draft", "Submitted", "Stopped",
 			"Cancelled"])
 
 		if not self.billing_status: self.billing_status = 'Not Billed'
-		if not self.delivery_status: self.delivery_status = 'Not Delivered'		
-		
+		if not self.delivery_status: self.delivery_status = 'Not Delivered'
+
 	def validate_warehouse(self):
 		from erpnext.stock.utils import validate_warehouse_company
-		
-		warehouses = list(set([d.warehouse for d in 
+
+		warehouses = list(set([d.warehouse for d in
 			self.get(self.fname) if d.warehouse]))
-				
+
 		for w in warehouses:
 			validate_warehouse_company(w, self.company)
-		
+
 	def validate_with_previous_doc(self):
 		super(SalesOrder, self).validate_with_previous_doc(self.tname, {
 			"Quotation": {
@@ -141,31 +141,31 @@
 			}
 		})
 
-		
+
 	def update_enquiry_status(self, prevdoc, flag):
 		enq = frappe.db.sql("select t2.prevdoc_docname from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.name=%s", prevdoc)
 		if enq:
 			frappe.db.sql("update `tabOpportunity` set status = %s where name=%s",(flag,enq[0][0]))
 
-	def update_prevdoc_status(self, flag):				
+	def update_prevdoc_status(self, flag):
 		for quotation in list(set([d.prevdoc_docname for d in self.get(self.fname)])):
 			if quotation:
 				doc = frappe.get_doc("Quotation", quotation)
 				if doc.docstatus==2:
 					frappe.throw(quotation + ": " + frappe._("Quotation is cancelled."))
-				
+
 				doc.set_status(update=True)
 
 	def on_submit(self):
 		self.update_stock_ledger(update_stock = 1)
 
 		self.check_credit(self.grand_total)
-		
+
 		frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype, self.grand_total, self)
-		
+
 		self.update_prevdoc_status('submit')
 		frappe.db.set(self, 'status', 'Submitted')
-	
+
 	def on_cancel(self):
 		# Cannot cancel stopped SO
 		if self.status == 'Stopped':
@@ -173,45 +173,45 @@
 			raise Exception
 		self.check_nextdoc_docstatus()
 		self.update_stock_ledger(update_stock = -1)
-		
+
 		self.update_prevdoc_status('cancel')
-		
+
 		frappe.db.set(self, 'status', 'Cancelled')
-		
+
 	def check_nextdoc_docstatus(self):
 		# Checks Delivery Note
 		submit_dn = frappe.db.sql("select t1.name from `tabDelivery Note` t1,`tabDelivery Note Item` t2 where t1.name = t2.parent and t2.against_sales_order = %s and t1.docstatus = 1", self.name)
 		if submit_dn:
 			msgprint("Delivery Note : " + cstr(submit_dn[0][0]) + " has been submitted against " + cstr(self.doctype) + ". Please cancel Delivery Note : " + cstr(submit_dn[0][0]) + " first and then cancel "+ cstr(self.doctype), raise_exception = 1)
-			
+
 		# Checks Sales Invoice
-		submit_rv = frappe.db.sql("""select t1.name 
-			from `tabSales Invoice` t1,`tabSales Invoice Item` t2 
-			where t1.name = t2.parent and t2.sales_order = %s and t1.docstatus = 1""", 
+		submit_rv = frappe.db.sql("""select t1.name
+			from `tabSales Invoice` t1,`tabSales Invoice Item` t2
+			where t1.name = t2.parent and t2.sales_order = %s and t1.docstatus = 1""",
 			self.name)
 		if submit_rv:
 			msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted against " +cstr(self.doctype)+ ". Please cancel Sales Invoice : "+ cstr(submit_rv[0][0]) + " first and then cancel "+ cstr(self.doctype), raise_exception = 1)
-			
+
 		#check maintenance schedule
 		submit_ms = frappe.db.sql("select t1.name from `tabMaintenance Schedule` t1, `tabMaintenance Schedule Item` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.name)
 		if submit_ms:
 			msgprint("Maintenance Schedule : " + cstr(submit_ms[0][0]) + " has already been submitted against " +cstr(self.doctype)+ ". Please cancel Maintenance Schedule : "+ cstr(submit_ms[0][0]) + " first and then cancel "+ cstr(self.doctype), raise_exception = 1)
-			
+
 		# check maintenance visit
 		submit_mv = frappe.db.sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.name)
 		if submit_mv:
 			msgprint("Maintenance Visit : " + cstr(submit_mv[0][0]) + " has already been submitted against " +cstr(self.doctype)+ ". Please cancel Maintenance Visit : " + cstr(submit_mv[0][0]) + " first and then cancel "+ cstr(self.doctype), raise_exception = 1)
-		
+
 		# check production order
 		pro_order = frappe.db.sql("""select name from `tabProduction Order` where sales_order = %s and docstatus = 1""", self.name)
 		if pro_order:
-			msgprint("""Production Order: %s exists against this sales order. 
-				Please cancel production order first and then cancel this sales order""" % 
+			msgprint("""Production Order: %s exists against this sales order.
+				Please cancel production order first and then cancel this sales order""" %
 				pro_order[0][0], raise_exception=1)
 
 	def check_modified_date(self):
 		mod_db = frappe.db.get_value("Sales Order", self.name, "modified")
-		date_diff = frappe.db.sql("select TIMEDIFF('%s', '%s')" % 
+		date_diff = frappe.db.sql("select TIMEDIFF('%s', '%s')" %
 			( mod_db, cstr(self.modified)))
 		if date_diff and date_diff[0][0]:
 			msgprint("%s: %s has been modified after you have opened. Please Refresh"
@@ -221,7 +221,7 @@
 		self.check_modified_date()
 		self.update_stock_ledger(-1)
 		frappe.db.set(self, 'status', 'Stopped')
-		msgprint("""%s: %s has been Stopped. To make transactions against this Sales Order 
+		msgprint("""%s: %s has been Stopped. To make transactions against this Sales Order
 			you need to Unstop it.""" % (self.doctype, self.name))
 
 	def unstop_sales_order(self):
@@ -237,7 +237,7 @@
 			if frappe.db.get_value("Item", d['item_code'], "is_stock_item") == "Yes":
 				args = {
 					"item_code": d['item_code'],
-					"warehouse": d['reserved_warehouse'], 
+					"warehouse": d['reserved_warehouse'],
 					"reserved_qty": flt(update_stock) * flt(d['reserved_qty']),
 					"posting_date": self.transaction_date,
 					"voucher_type": self.doctype,
@@ -248,76 +248,76 @@
 
 	def on_update(self):
 		pass
-		
+
 	def get_portal_page(self):
 		return "order" if self.docstatus==1 else None
-		
+
 def set_missing_values(source, target):
 	doc = frappe.get_doc(target)
 	doc.run_method("onload_post_render")
-	
+
 @frappe.whitelist()
-def make_material_request(source_name, target_doc=None):	
-	def postprocess(source, doclist):
-		doclist[0].material_request_type = "Purchase"
-	
-	doclist = get_mapped_doc("Sales Order", source_name, {
+def make_material_request(source_name, target_doc=None):
+	def postprocess(source, doc):
+		doc.material_request_type = "Purchase"
+
+	doc = get_mapped_doc("Sales Order", source_name, {
 		"Sales Order": {
-			"doctype": "Material Request", 
+			"doctype": "Material Request",
 			"validation": {
 				"docstatus": ["=", 1]
 			}
-		}, 
+		},
 		"Sales Order Item": {
-			"doctype": "Material Request Item", 
+			"doctype": "Material Request Item",
 			"field_map": {
-				"parent": "sales_order_no", 
+				"parent": "sales_order_no",
 				"stock_uom": "uom"
 			}
 		}
 	}, target_doc, postprocess)
-	
-	return doclist
+
+	return doc
 
 @frappe.whitelist()
-def make_delivery_note(source_name, target_doc=None):	
+def make_delivery_note(source_name, target_doc=None):
 	def update_item(obj, target, source_parent):
 		target.base_amount = (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.base_rate)
 		target.amount = (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.rate)
 		target.qty = flt(obj.qty) - flt(obj.delivered_qty)
-			
+
 	doclist = get_mapped_doc("Sales Order", source_name, {
 		"Sales Order": {
-			"doctype": "Delivery Note", 
+			"doctype": "Delivery Note",
 			"field_map": {
-				"shipping_address": "address_display", 
-				"shipping_address_name": "customer_address", 
+				"shipping_address": "address_display",
+				"shipping_address_name": "customer_address",
 			},
 			"validation": {
 				"docstatus": ["=", 1]
 			}
-		}, 
+		},
 		"Sales Order Item": {
-			"doctype": "Delivery Note Item", 
+			"doctype": "Delivery Note Item",
 			"field_map": {
-				"rate": "rate", 
-				"name": "prevdoc_detail_docname", 
-				"parent": "against_sales_order", 
+				"rate": "rate",
+				"name": "prevdoc_detail_docname",
+				"parent": "against_sales_order",
 			},
 			"postprocess": update_item,
 			"condition": lambda doc: doc.delivered_qty < doc.qty
-		}, 
+		},
 		"Sales Taxes and Charges": {
-			"doctype": "Sales Taxes and Charges", 
+			"doctype": "Sales Taxes and Charges",
 			"add_if_empty": True
-		}, 
+		},
 		"Sales Team": {
 			"doctype": "Sales Team",
 			"add_if_empty": True
 		}
 	}, target_doc, set_missing_values)
-	
-	return doclist.as_dict()
+
+	return doclist
 
 @frappe.whitelist()
 def make_sales_invoice(source_name, target_doc=None):
@@ -325,94 +325,94 @@
 		doc = frappe.get_doc(target)
 		doc.is_pos = 0
 		doc.run_method("onload_post_render")
-		
+
 	def update_item(obj, target, source_parent):
 		target.amount = flt(obj.amount) - flt(obj.billed_amt)
 		target.base_amount = target.amount * flt(source_parent.conversion_rate)
 		target.qty = obj.rate and target.amount / flt(obj.rate) or obj.qty
-			
+
 	doclist = get_mapped_doc("Sales Order", source_name, {
 		"Sales Order": {
-			"doctype": "Sales Invoice", 
+			"doctype": "Sales Invoice",
 			"validation": {
 				"docstatus": ["=", 1]
 			}
-		}, 
+		},
 		"Sales Order Item": {
-			"doctype": "Sales Invoice Item", 
+			"doctype": "Sales Invoice Item",
 			"field_map": {
-				"name": "so_detail", 
-				"parent": "sales_order", 
+				"name": "so_detail",
+				"parent": "sales_order",
 			},
 			"postprocess": update_item,
 			"condition": lambda doc: doc.base_amount==0 or doc.billed_amt < doc.amount
-		}, 
+		},
 		"Sales Taxes and Charges": {
-			"doctype": "Sales Taxes and Charges", 
+			"doctype": "Sales Taxes and Charges",
 			"add_if_empty": True
-		}, 
+		},
 		"Sales Team": {
-			"doctype": "Sales Team", 
+			"doctype": "Sales Team",
 			"add_if_empty": True
 		}
 	}, target_doc, set_missing_values)
-	
-	return doclist.as_dict()
-	
+
+	return doclist
+
 @frappe.whitelist()
 def make_maintenance_schedule(source_name, target_doc=None):
-	maint_schedule = frappe.db.sql("""select t1.name 
-		from `tabMaintenance Schedule` t1, `tabMaintenance Schedule Item` t2 
+	maint_schedule = frappe.db.sql("""select t1.name
+		from `tabMaintenance Schedule` t1, `tabMaintenance Schedule Item` t2
 		where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1""", source_name)
-		
+
 	if not maint_schedule:
 		doclist = get_mapped_doc("Sales Order", source_name, {
 			"Sales Order": {
-				"doctype": "Maintenance Schedule", 
+				"doctype": "Maintenance Schedule",
 				"field_map": {
 					"name": "sales_order_no"
-				}, 
+				},
 				"validation": {
 					"docstatus": ["=", 1]
 				}
-			}, 
+			},
 			"Sales Order Item": {
-				"doctype": "Maintenance Schedule Item", 
+				"doctype": "Maintenance Schedule Item",
 				"field_map": {
 					"parent": "prevdoc_docname"
 				},
 				"add_if_empty": True
 			}
 		}, target_doc)
-	
-		return doclist.as_dict()
-	
+
+		return doclist
+
 @frappe.whitelist()
 def make_maintenance_visit(source_name, target_doc=None):
-	visit = frappe.db.sql("""select t1.name 
-		from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 
-		where t2.parent=t1.name and t2.prevdoc_docname=%s 
+	visit = frappe.db.sql("""select t1.name
+		from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2
+		where t2.parent=t1.name and t2.prevdoc_docname=%s
 		and t1.docstatus=1 and t1.completion_status='Fully Completed'""", source_name)
-		
+
 	if not visit:
 		doclist = get_mapped_doc("Sales Order", source_name, {
 			"Sales Order": {
-				"doctype": "Maintenance Visit", 
+				"doctype": "Maintenance Visit",
 				"field_map": {
 					"name": "sales_order_no"
 				},
 				"validation": {
 					"docstatus": ["=", 1]
 				}
-			}, 
+			},
 			"Sales Order Item": {
-				"doctype": "Maintenance Visit Purpose", 
+				"doctype": "Maintenance Visit Purpose",
 				"field_map": {
-					"parent": "prevdoc_docname", 
+					"parent": "prevdoc_docname",
 					"parenttype": "prevdoc_doctype"
 				},
 				"add_if_empty": True
 			}
 		}, target_doc)
-	
-		return doclist.as_dict()
+
+		return doclist
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index af52028..b41027b 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -4,82 +4,82 @@
 import frappe
 from frappe.utils import flt
 import unittest
+import copy
 
 class TestSalesOrder(unittest.TestCase):
 	def tearDown(self):
 		frappe.set_user("Administrator")
-		
+
 	def test_make_material_request(self):
 		from erpnext.selling.doctype.sales_order.sales_order import make_material_request
-		
+
 		so = frappe.copy_doc(test_records[0]).insert()
-		
-		self.assertRaises(frappe.ValidationError, make_material_request, 
+
+		self.assertRaises(frappe.ValidationError, make_material_request,
 			so.name)
 
 		sales_order = frappe.get_doc("Sales Order", so.name)
 		sales_order.submit()
 		mr = make_material_request(so.name)
-		
-		self.assertEquals(mr[0]["material_request_type"], "Purchase")
-		self.assertEquals(len(mr), len(sales_order))
+
+		self.assertEquals(mr.material_request_type, "Purchase")
+		self.assertEquals(len(mr.get("indent_details")), len(sales_order.get("sales_order_details")))
 
 	def test_make_delivery_note(self):
 		from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note
 
 		so = frappe.copy_doc(test_records[0]).insert()
 
-		self.assertRaises(frappe.ValidationError, make_delivery_note, 
+		self.assertRaises(frappe.ValidationError, make_delivery_note,
 			so.name)
 
 		sales_order = frappe.get_doc("Sales Order", so.name)
 		sales_order.submit()
 		dn = make_delivery_note(so.name)
-		
-		self.assertEquals(dn[0]["doctype"], "Delivery Note")
-		self.assertEquals(len(dn), len(sales_order))
+
+		self.assertEquals(dn.doctype, "Delivery Note")
+		self.assertEquals(len(dn.get("delivery_note_details")), len(sales_order.get("sales_order_details")))
 
 	def test_make_sales_invoice(self):
 		from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
 
 		so = frappe.copy_doc(test_records[0]).insert()
 
-		self.assertRaises(frappe.ValidationError, make_sales_invoice, 
+		self.assertRaises(frappe.ValidationError, make_sales_invoice,
 			so.name)
 
 		sales_order = frappe.get_doc("Sales Order", so.name)
 		sales_order.submit()
 		si = make_sales_invoice(so.name)
-		
-		self.assertEquals(si[0]["doctype"], "Sales Invoice")
-		self.assertEquals(len(si), len(sales_order))
-		self.assertEquals(len([d for d in si if d["doctype"]=="Sales Invoice Item"]), 1)
-		
-		si = frappe.get_doc(si)
+
+		self.assertEquals(si.doctype, "Sales Invoice")
+		self.assertEquals(len(si.get("entries")), len(sales_order.get("sales_order_details")))
+		self.assertEquals(len(si.get("entries")), 1)
+
 		si.posting_date = "2013-10-10"
 		si.insert()
 		si.submit()
 
 		si1 = make_sales_invoice(so.name)
-		self.assertEquals(len([d for d in si1 if d["doctype"]=="Sales Invoice Item"]), 0)
-		
+		self.assertEquals(len(si1.get("entries")), 0)
+
 
 	def create_so(self, so_doc = None):
 		if not so_doc:
 			so_doc = test_records[0]
-		
+
 		w = frappe.copy_doc(so_doc)
 		w.insert()
 		w.submit()
 
 		return w
-		
+
 	def create_dn_against_so(self, so, delivered_qty=0):
 		from erpnext.stock.doctype.delivery_note.test_delivery_note import test_records as dn_test_records
 		from erpnext.stock.doctype.delivery_note.test_delivery_note import _insert_purchase_receipt
 
 		_insert_purchase_receipt(so.get("sales_order_details")[0].item_code)
-		
+
 		dn = frappe.get_doc(frappe.copy_doc(dn_test_records[0]))
 		dn.get("delivery_note_details")[0].item_code = so.get("sales_order_details")[0].item_code
 		dn.get("delivery_note_details")[0].against_sales_order = so.name
@@ -89,76 +89,79 @@
 		dn.insert()
 		dn.submit()
 		return dn
-		
+
 	def get_bin_reserved_qty(self, item_code, warehouse):
-		return flt(frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse}, 
+		return flt(frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse},
 			"reserved_qty"))
-	
+
 	def delete_bin(self, item_code, warehouse):
-		bin = frappe.db.exists({"doctype": "Bin", "item_code": item_code, 
+		bin = frappe.db.exists({"doctype": "Bin", "item_code": item_code,
 			"warehouse": warehouse})
 		if bin:
 			frappe.delete_doc("Bin", bin[0][0])
-			
+
 	def check_reserved_qty(self, item_code, warehouse, qty):
 		bin_reserved_qty = self.get_bin_reserved_qty(item_code, warehouse)
 		self.assertEqual(bin_reserved_qty, qty)
-		
+
 	def test_reserved_qty_for_so(self):
 		# reset bin
-		self.delete_bin(test_records[0][1]["item_code"], test_records[0][1]["warehouse"])
-		
+		so_item = test_records[0]["sales_order_details"][0]
+		self.delete_bin(so_item["item_code"], so_item["warehouse"])
+
 		# submit
 		so = self.create_so()
 		self.check_reserved_qty(so.get("sales_order_details")[0].item_code, so.get("sales_order_details")[0].warehouse, 10.0)
-		
+
 		# cancel
 		so.cancel()
 		self.check_reserved_qty(so.get("sales_order_details")[0].item_code, so.get("sales_order_details")[0].warehouse, 0.0)
-		
-	
+
+
 	def test_reserved_qty_for_partial_delivery(self):
 		# reset bin
-		self.delete_bin(test_records[0][1]["item_code"], test_records[0][1]["warehouse"])
-		
+		so_item = test_records[0]["sales_order_details"][0]
+		self.delete_bin(so_item["item_code"], so_item["warehouse"])
+
 		# submit so
 		so = self.create_so()
-		
+
 		# allow negative stock
 		frappe.db.set_default("allow_negative_stock", 1)
-		
+
 		# submit dn
 		dn = self.create_dn_against_so(so)
-		
+
 		self.check_reserved_qty(so.get("sales_order_details")[0].item_code, so.get("sales_order_details")[0].warehouse, 5.0)
-		
+
 		# stop so
 		so.load_from_db()
-		so.obj.stop_sales_order()
+		so.stop_sales_order()
 		self.check_reserved_qty(so.get("sales_order_details")[0].item_code, so.get("sales_order_details")[0].warehouse, 0.0)
-		
+
 		# unstop so
 		so.load_from_db()
-		so.obj.unstop_sales_order()
+		so.unstop_sales_order()
 		self.check_reserved_qty(so.get("sales_order_details")[0].item_code, so.get("sales_order_details")[0].warehouse, 5.0)
-		
+
 		# cancel dn
 		dn.cancel()
 		self.check_reserved_qty(so.get("sales_order_details")[0].item_code, so.get("sales_order_details")[0].warehouse, 10.0)
-		
+
 	def test_reserved_qty_for_over_delivery(self):
 		# reset bin
-		self.delete_bin(test_records[0][1]["item_code"], test_records[0][1]["warehouse"])
-		
+		so_item = test_records[0]["sales_order_details"][0]
+		self.delete_bin(so_item["item_code"], so_item["warehouse"])
+
 		# submit so
 		so = self.create_so()
-		
+
 		# allow negative stock
 		frappe.db.set_default("allow_negative_stock", 1)
-		
+
 		# set over-delivery tolerance
 		frappe.db.set_value('Item', so.get("sales_order_details")[0].item_code, 'tolerance', 50)
-		
+
 		# submit dn
 		dn = self.create_dn_against_so(so, 15)
 		self.check_reserved_qty(so.get("sales_order_details")[0].item_code, so.get("sales_order_details")[0].warehouse, 0.0)
@@ -166,127 +169,127 @@
 		# cancel dn
 		dn.cancel()
 		self.check_reserved_qty(so.get("sales_order_details")[0].item_code, so.get("sales_order_details")[0].warehouse, 10.0)
-		
+
 	def test_reserved_qty_for_so_with_packing_list(self):
 		from erpnext.selling.doctype.sales_bom.test_sales_bom import test_records as sbom_test_records
-		
+
 		# change item in test so record
-		test_record = test_records[0][:]
-		test_record[1]["item_code"] = "_Test Sales BOM Item"
-		
+		test_record = copy.deepcopy(test_records[0])
+		test_record["sales_order_details"][0]["item_code"] = "_Test Sales BOM Item"
+
 		# reset bin
-		self.delete_bin(sbom_test_records[0][1]["item_code"], test_record[1]["warehouse"])
-		self.delete_bin(sbom_test_records[0][2]["item_code"], test_record[1]["warehouse"])
-		
+		self.delete_bin(sbom_test_records[0]["sales_bom_items"][0]["item_code"], test_record.get("sales_order_details")[0]["warehouse"])
+		self.delete_bin(sbom_test_records[0]["sales_bom_items"][1]["item_code"], test_record.get("sales_order_details")[0]["warehouse"])
+
 		# submit
 		so = self.create_so(test_record)
-		
-		
-		self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 
+
+
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][0]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 50.0)
-		self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][1]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 20.0)
-		
+
 		# cancel
 		so.cancel()
-		self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][0]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 0.0)
-		self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][1]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 0.0)
-			
+
 	def test_reserved_qty_for_partial_delivery_with_packing_list(self):
 		from erpnext.selling.doctype.sales_bom.test_sales_bom import test_records as sbom_test_records
-		
+
 		# change item in test so record
-		
+
 		test_record = frappe.copy_doc(test_records[0])
-		test_record[1]["item_code"] = "_Test Sales BOM Item"
+		test_record.get("sales_order_details")[0].item_code = "_Test Sales BOM Item"
 
 		# reset bin
-		self.delete_bin(sbom_test_records[0][1]["item_code"], test_record[1]["warehouse"])
-		self.delete_bin(sbom_test_records[0][2]["item_code"], test_record[1]["warehouse"])
-		
+		self.delete_bin(sbom_test_records[0]["sales_bom_items"][0]["item_code"], test_record.get("sales_order_details")[0].warehouse)
+		self.delete_bin(sbom_test_records[0]["sales_bom_items"][1]["item_code"], test_record.get("sales_order_details")[0].warehouse)
+
 		# submit
 		so = self.create_so(test_record)
-		
+
 		# allow negative stock
 		frappe.db.set_default("allow_negative_stock", 1)
-		
+
 		# submit dn
 		dn = self.create_dn_against_so(so)
-		
-		self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 
+
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][0]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 25.0)
-		self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][1]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 10.0)
-				
+
 		# stop so
 		so.load_from_db()
-		so.obj.stop_sales_order()
-		
-		self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 
+		so.stop_sales_order()
+
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][0]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 0.0)
-		self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][1]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 0.0)
-		
+
 		# unstop so
 		so.load_from_db()
-		so.obj.unstop_sales_order()
-		self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 
+		so.unstop_sales_order()
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][0]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 25.0)
-		self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][1]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 10.0)
-		
+
 		# cancel dn
 		dn.cancel()
-		self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][0]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 50.0)
-		self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][1]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 20.0)
-			
+
 	def test_reserved_qty_for_over_delivery_with_packing_list(self):
 		from erpnext.selling.doctype.sales_bom.test_sales_bom import test_records as sbom_test_records
-		
+
 		# change item in test so record
 		test_record = frappe.copy_doc(test_records[0])
-		test_record[1]["item_code"] = "_Test Sales BOM Item"
+		test_record.get("sales_order_details")[0].item_code = "_Test Sales BOM Item"
 
 		# reset bin
-		self.delete_bin(sbom_test_records[0][1]["item_code"], test_record[1]["warehouse"])
-		self.delete_bin(sbom_test_records[0][2]["item_code"], test_record[1]["warehouse"])
-		
+		self.delete_bin(sbom_test_records[0]["sales_bom_items"][0]["item_code"], test_record.get("sales_order_details")[0].warehouse)
+		self.delete_bin(sbom_test_records[0]["sales_bom_items"][1]["item_code"], test_record.get("sales_order_details")[0].warehouse)
+
 		# submit
 		so = self.create_so(test_record)
-		
+
 		# allow negative stock
 		frappe.db.set_default("allow_negative_stock", 1)
-		
+
 		# set over-delivery tolerance
 		frappe.db.set_value('Item', so.get("sales_order_details")[0].item_code, 'tolerance', 50)
-		
+
 		# submit dn
 		dn = self.create_dn_against_so(so, 15)
-		
-		self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 
+
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][0]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 0.0)
-		self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][1]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 0.0)
 
 		# cancel dn
 		dn.cancel()
-		self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][0]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 50.0)
-		self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 
+		self.check_reserved_qty(sbom_test_records[0]["sales_bom_items"][1]["item_code"],
 			so.get("sales_order_details")[0].warehouse, 20.0)
 
 	def test_warehouse_user(self):
 		frappe.defaults.add_default("Warehouse", "_Test Warehouse 1 - _TC1", "test@example.com", "Restriction")
 		frappe.get_doc("User", "test@example.com")\
 			.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
-			
+
 		frappe.get_doc("User", "test2@example.com")\
 			.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
-		
+
 		frappe.set_user("test@example.com")
 
 		so = frappe.copy_doc(test_records[0])
@@ -298,9 +301,9 @@
 
 		frappe.set_user("test2@example.com")
 		so.insert()
-		
+
 		frappe.defaults.clear_default("Warehouse", "_Test Warehouse 1 - _TC1", "test@example.com", parenttype="Restriction")
 
 test_dependencies = ["Sales BOM", "Currency Exchange"]
-	
-test_records = frappe.get_test_records('Sales Order')
\ No newline at end of file
+
+test_records = frappe.get_test_records('Sales Order')
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 347b1f4..ba1509f 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -28,21 +28,21 @@
 		'status_field': 'delivery_status',
 		'keyword': 'Delivered'
 	}]
-		
+
 	def onload(self):
 		billed_qty = frappe.db.sql("""select sum(ifnull(qty, 0)) from `tabSales Invoice Item`
 			where docstatus=1 and delivery_note=%s""", self.name)
 		if billed_qty:
 			total_qty = sum((item.qty for item in self.get("delivery_note_details")))
 			self.set("__billing_complete", billed_qty[0][0] == total_qty)
-			
+
 	def get_portal_page(self):
 		return "shipment" if self.docstatus==1 else None
 
 	def set_actual_qty(self):
 		for d in self.get('delivery_note_details'):
 			if d.item_code and d.warehouse:
-				actual_qty = frappe.db.sql("""select actual_qty from `tabBin` 
+				actual_qty = frappe.db.sql("""select actual_qty from `tabBin`
 					where item_code = %s and warehouse = %s""", (d.item_code, d.warehouse))
 				d.actual_qty = actual_qty and flt(actual_qty[0][0]) or 0
 
@@ -57,7 +57,7 @@
 
 	def validate(self):
 		super(DeliveryNote, self).validate()
-		
+
 		from erpnext.utilities import validate_status
 		validate_status(self.status, ["Draft", "Submitted", "Cancelled"])
 
@@ -67,18 +67,18 @@
 		self.validate_for_items()
 		self.validate_warehouse()
 		self.validate_uom_is_integer("stock_uom", "qty")
-		self.update_current_stock()		
+		self.update_current_stock()
 		self.validate_with_previous_doc()
-		
+
 		from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
 		make_packing_list(self, 'delivery_note_details')
-		
+
 		self.status = 'Draft'
-		if not self.installation_status: self.installation_status = 'Not Installed'	
-		
+		if not self.installation_status: self.installation_status = 'Not Installed'
+
 	def validate_with_previous_doc(self):
 		items = self.get("delivery_note_details")
-		
+
 		for fn in (("Sales Order", "against_sales_order"), ("Sales Invoice", "against_sales_invoice")):
 			if filter(None, [getattr(d, fn[1], None) for d in items]):
 				super(DeliveryNote, self).validate_with_previous_doc(self.tname, {
@@ -97,12 +97,12 @@
 							"is_child_table": True
 						}
 					})
-						
+
 	def validate_proj_cust(self):
 		"""check for does customer belong to same project as entered.."""
 		if self.project_name and self.customer:
-			res = frappe.db.sql("""select name from `tabProject` 
-				where name = %s and (customer = %s or 
+			res = frappe.db.sql("""select name from `tabProject`
+				where name = %s and (customer = %s or
 					ifnull(customer,'')='')""", (self.project_name, self.customer))
 			if not res:
 				msgprint("Customer - %s does not belong to project - %s. \n\nIf you want to use project for multiple customers then please make customer details blank in project - %s."%(self.customer,self.project_name,self.project_name))
@@ -116,13 +116,13 @@
 
 			if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 'Yes':
 				if e in check_list:
-					msgprint("Please check whether item %s has been entered twice wrongly." 
+					msgprint("Please check whether item %s has been entered twice wrongly."
 						% d.item_code)
 				else:
 					check_list.append(e)
 			else:
 				if f in chk_dupl_itm:
-					msgprint("Please check whether item %s has been entered twice wrongly." 
+					msgprint("Please check whether item %s has been entered twice wrongly."
 						% d.item_code)
 				else:
 					chk_dupl_itm.append(f)
@@ -133,7 +133,7 @@
 				if not d['warehouse']:
 					msgprint("Please enter Warehouse for item %s as it is stock item"
 						% d['item_code'], raise_exception=1)
-				
+
 
 	def update_current_stock(self):
 		for d in self.get('delivery_note_details'):
@@ -150,15 +150,15 @@
 
 		# Check for Approving Authority
 		frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype, self.company, self.grand_total, self)
-		
-		# update delivered qty in sales order	
+
+		# update delivered qty in sales order
 		self.update_prevdoc_status()
-		
+
 		# create stock ledger entry
 		self.update_stock_ledger()
 
 		self.credit_limit()
-		
+
 		self.make_gl_entries()
 
 		# set DN status
@@ -168,14 +168,14 @@
 	def on_cancel(self):
 		self.check_stop_sales_order("against_sales_order")
 		self.check_next_docstatus()
-				
+
 		self.update_prevdoc_status()
-		
+
 		self.update_stock_ledger()
 
 		frappe.db.set(self, 'status', 'Cancelled')
 		self.cancel_packing_slips()
-		
+
 		self.make_cancel_gl_entries()
 
 	def validate_packed_qty(self):
@@ -198,17 +198,17 @@
 			frappe.msgprint("Packing Error:\n" + err_msg, raise_exception=1)
 
 	def check_next_docstatus(self):
-		submit_rv = frappe.db.sql("""select t1.name 
-			from `tabSales Invoice` t1,`tabSales Invoice Item` t2 
-			where t1.name = t2.parent and t2.delivery_note = %s and t1.docstatus = 1""", 
+		submit_rv = frappe.db.sql("""select t1.name
+			from `tabSales Invoice` t1,`tabSales Invoice Item` t2
+			where t1.name = t2.parent and t2.delivery_note = %s and t1.docstatus = 1""",
 			(self.name))
 		if submit_rv:
 			msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted !")
 			raise Exception , "Validation Error."
 
-		submit_in = frappe.db.sql("""select t1.name 
-			from `tabInstallation Note` t1, `tabInstallation Note Item` t2 
-			where t1.name = t2.parent and t2.prevdoc_docname = %s and t1.docstatus = 1""", 
+		submit_in = frappe.db.sql("""select t1.name
+			from `tabInstallation Note` t1, `tabInstallation Note Item` t2
+			where t1.name = t2.parent and t2.prevdoc_docname = %s and t1.docstatus = 1""",
 			(self.name))
 		if submit_in:
 			msgprint("Installation Note : "+cstr(submit_in[0][0]) +" has already been submitted !")
@@ -218,7 +218,7 @@
 		"""
 			Cancel submitted packing slips related to this delivery note
 		"""
-		res = frappe.db.sql("""SELECT name FROM `tabPacking Slip` WHERE delivery_note = %s 
+		res = frappe.db.sql("""SELECT name FROM `tabPacking Slip` WHERE delivery_note = %s
 			AND docstatus = 1""", self.name)
 
 		if res:
@@ -234,19 +234,19 @@
 			if frappe.db.get_value("Item", d.item_code, "is_stock_item") == "Yes" \
 					and d.warehouse:
 				self.update_reserved_qty(d)
-										
+
 				sl_entries.append(self.get_sl_entries(d, {
 					"actual_qty": -1*flt(d['qty']),
 				}))
-					
+
 		self.make_sl_entries(sl_entries)
-			
+
 	def update_reserved_qty(self, d):
 		if d['reserved_qty'] < 0 :
 			# Reduce reserved qty from reserved warehouse mentioned in so
 			if not d["reserved_warehouse"]:
 				frappe.throw(_("Reserved Warehouse is missing in Sales Order"))
-				
+
 			args = {
 				"item_code": d['item_code'],
 				"warehouse": d["reserved_warehouse"],
@@ -271,88 +271,88 @@
 def get_invoiced_qty_map(delivery_note):
 	"""returns a map: {dn_detail: invoiced_qty}"""
 	invoiced_qty_map = {}
-	
+
 	for dn_detail, qty in frappe.db.sql("""select dn_detail, qty from `tabSales Invoice Item`
 		where delivery_note=%s and docstatus=1""", delivery_note):
 			if not invoiced_qty_map.get(dn_detail):
 				invoiced_qty_map[dn_detail] = 0
 			invoiced_qty_map[dn_detail] += qty
-	
+
 	return invoiced_qty_map
 
 @frappe.whitelist()
 def make_sales_invoice(source_name, target_doc=None):
 	invoiced_qty_map = get_invoiced_qty_map(source_name)
-	
+
 	def update_accounts(source, target):
 		si = frappe.get_doc(target)
 		si.is_pos = 0
 		si.run_method("onload_post_render")
-				
+
 		if len(si.get("entries")) == 0:
 			frappe.msgprint(_("All these items have already been invoiced."),
 				raise_exception=True)
-		
+
 	def update_item(source_doc, target_doc, source_parent):
 		target_doc.qty = source_doc.qty - invoiced_qty_map.get(source_doc.name, 0)
-	
+
 	doc = get_mapped_doc("Delivery Note", source_name, 	{
 		"Delivery Note": {
-			"doctype": "Sales Invoice", 
+			"doctype": "Sales Invoice",
 			"validation": {
 				"docstatus": ["=", 1]
 			}
-		}, 
+		},
 		"Delivery Note Item": {
-			"doctype": "Sales Invoice Item", 
+			"doctype": "Sales Invoice Item",
 			"field_map": {
-				"name": "dn_detail", 
-				"parent": "delivery_note", 
-				"prevdoc_detail_docname": "so_detail", 
-				"against_sales_order": "sales_order", 
+				"name": "dn_detail",
+				"parent": "delivery_note",
+				"prevdoc_detail_docname": "so_detail",
+				"against_sales_order": "sales_order",
 				"serial_no": "serial_no"
 			},
 			"postprocess": update_item,
-			"filter": lambda d: d.qty - invoiced_qty_map.get(d.name, 0)<=0 
-		}, 
+			"filter": lambda d: d.qty - invoiced_qty_map.get(d.name, 0)<=0
+		},
 		"Sales Taxes and Charges": {
-			"doctype": "Sales Taxes and Charges", 
+			"doctype": "Sales Taxes and Charges",
 			"add_if_empty": True
-		}, 
+		},
 		"Sales Team": {
-			"doctype": "Sales Team", 
+			"doctype": "Sales Team",
 			"field_map": {
 				"incentives": "incentives"
 			},
 			"add_if_empty": True
 		}
 	}, target_doc, update_accounts)
-	
-	return doc.as_dict()
-	
+
+	return doc
+
 @frappe.whitelist()
 def make_installation_note(source_name, target_doc=None):
 	def update_item(obj, target, source_parent):
 		target.qty = flt(obj.qty) - flt(obj.installed_qty)
 		target.serial_no = obj.serial_no
-	
+
 	doclist = get_mapped_doc("Delivery Note", source_name, 	{
 		"Delivery Note": {
-			"doctype": "Installation Note", 
+			"doctype": "Installation Note",
 			"validation": {
 				"docstatus": ["=", 1]
 			}
-		}, 
+		},
 		"Delivery Note Item": {
-			"doctype": "Installation Note Item", 
+			"doctype": "Installation Note Item",
 			"field_map": {
-				"name": "prevdoc_detail_docname", 
-				"parent": "prevdoc_docname", 
-				"parenttype": "prevdoc_doctype", 
+				"name": "prevdoc_detail_docname",
+				"parent": "prevdoc_docname",
+				"parenttype": "prevdoc_doctype",
 			},
 			"postprocess": update_item,
 			"condition": lambda doc: doc.installed_qty < doc.qty
 		}
 	}, target_doc)
 
-	return doclist.as_dict()
\ No newline at end of file
+	return doclist
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index bd14784..3f67cd2 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -245,7 +245,7 @@
 		}
 	}, target_doc, set_missing_values)
 
-	return doclist.as_dict()
+	return doclist
 
 @frappe.whitelist()
 def make_purchase_order_based_on_supplier(source_name, target_doc=None):
@@ -325,7 +325,7 @@
 		}
 	}, target_doc, set_missing_values)
 
-	return doclist.as_dict()
+	return doclist
 
 @frappe.whitelist()
 def make_stock_entry(source_name, target_doc=None):
@@ -361,4 +361,4 @@
 		}
 	}, target_doc, set_missing_values)
 
-	return doclist.as_dict()
+	return doclist
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 9a137a1..03250a6 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -323,4 +323,4 @@
 		}
 	}, target_doc, set_missing_values)
 
-	return doclist.as_dict()
\ No newline at end of file
+	return doclist
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 9a28033..b6ffb83 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -234,6 +234,7 @@
 
 	def validate_finished_goods(self):
 		"""validation: finished good quantity should be same as manufacturing quantity"""
+		import json
 		for d in self.get('mtn_details'):
 			if d.bom_no and flt(d.transfer_qty) != flt(self.fg_completed_qty):
 				msgprint(_("Row #") + " %s: " % d.idx
diff --git a/erpnext/support/doctype/customer_issue/customer_issue.py b/erpnext/support/doctype/customer_issue/customer_issue.py
index f82488a..7c6e1b2 100644
--- a/erpnext/support/doctype/customer_issue/customer_issue.py
+++ b/erpnext/support/doctype/customer_issue/customer_issue.py
@@ -59,4 +59,4 @@
 			}
 		}, target_doc)
 	
-		return doclist.as_dict()
\ No newline at end of file
+		return doclist
\ No newline at end of file
diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py
index 7178fa2..afc08e8 100644
--- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py
+++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py
@@ -295,4 +295,4 @@
 		}
 	}, target_doc)
 
-	return doclist.as_dict()
\ No newline at end of file
+	return doclist
\ No newline at end of file