Merge branch 'master' of github.com:webnotes/erpnext
diff --git a/accounts/doctype/budget_control/budget_control.py b/accounts/doctype/budget_control/budget_control.py
index 2fd321d..dcab3ac 100644
--- a/accounts/doctype/budget_control/budget_control.py
+++ b/accounts/doctype/budget_control/budget_control.py
@@ -8,80 +8,103 @@
 # 
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
 # GNU General Public License for more details.
 # 
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.	If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import unicode_literals
 import webnotes
-
 from webnotes.utils import cstr, flt, getdate
-from webnotes.model import db_exists
-from webnotes.model.wrapper import copy_doclist
-from webnotes.model.code import get_obj
 from webnotes import msgprint
 
-sql = webnotes.conn.sql
-
-
 class DocType:
-  def __init__(self,d,dl):
-    self.doc, self.doclist = d, dl
-    
-  # Get monthly budget
-  #-------------------
-  def get_monthly_budget(self, distribution_id, cfy, st_date, post_dt, budget_allocated):
-    
-    # get month_list
-    st_date, post_dt = getdate(st_date), getdate(post_dt)
-    
-    if distribution_id:
-      if st_date.month <= post_dt.month:
-        tot_per_allocated = sql("select ifnull(sum(percentage_allocation),0) from `tabBudget Distribution Detail` where parent='%s' and idx between '%s' and '%s'" % (distribution_id, st_date.month, post_dt.month))[0][0]
+	def __init__(self,d,dl):
+		self.doc, self.doclist = d, dl
+		
+	# Get monthly budget
+	#-------------------
+	def get_monthly_budget(self, distribution_id, cfy, st_date, post_dt, budget_allocated):
+		
+		# get month_list
+		st_date, post_dt = getdate(st_date), getdate(post_dt)
+		
+		if distribution_id:
+			if st_date.month <= post_dt.month:
+				tot_per_allocated = webnotes.conn.sql("select ifnull(sum(percentage_allocation),0) from `tabBudget Distribution Detail` where parent='%s' and idx between '%s' and '%s'" % (distribution_id, st_date.month, post_dt.month))[0][0]
 
-      if st_date.month > post_dt.month:
-    
-        tot_per_allocated = flt(sql("select ifnull(sum(percentage_allocation),0) from `tabBudget Distribution Detail` where parent='%s' and idx between '%s' and '%s'" % (distribution_id, st_date.month, 12 ))[0][0])
-        tot_per_allocated = flt(tot_per_allocated)  + flt(sql("select ifnull(sum(percentage_allocation),0) from `tabBudget Distribution Detail` where parent='%s' and idx between '%s' and '%s'" % (distribution_id, 1, post_dt.month))[0][0])
-     
-      return (flt(budget_allocated) * flt(tot_per_allocated)) / 100
-    period_diff = sql("select PERIOD_DIFF('%s','%s')" % (post_dt.strftime('%Y%m'), st_date.strftime('%Y%m')))
-    
-    return (flt(budget_allocated) * (flt(period_diff[0][0]) + 1)) / 12
-    
-  def validate_budget(self, acct, cost_center, actual, budget, action):
-    # action if actual exceeds budget
-    if flt(actual) > flt(budget):
-      msgprint("Your monthly expense "+ cstr((action == 'stop') and "will exceed" or "has exceeded") +" budget for <b>Account - "+cstr(acct)+" </b> under <b>Cost Center - "+ cstr(cost_center) + "</b>"+cstr((action == 'Stop') and ", you can not have this transaction." or "."))
-      if action == 'Stop': raise Exception
+			if st_date.month > post_dt.month:
+		
+				tot_per_allocated = flt(webnotes.conn.sql("select ifnull(sum(percentage_allocation),0) from `tabBudget Distribution Detail` where parent='%s' and idx between '%s' and '%s'" % (distribution_id, st_date.month, 12 ))[0][0])
+				tot_per_allocated = flt(tot_per_allocated)	+ flt(webnotes.conn.sql("select ifnull(sum(percentage_allocation),0) from `tabBudget Distribution Detail` where parent='%s' and idx between '%s' and '%s'" % (distribution_id, 1, post_dt.month))[0][0])
+		 
+			return (flt(budget_allocated) * flt(tot_per_allocated)) / 100
+		period_diff = webnotes.conn.sql("select PERIOD_DIFF('%s','%s')" % (post_dt.strftime('%Y%m'), st_date.strftime('%Y%m')))
+		
+		return (flt(budget_allocated) * (flt(period_diff[0][0]) + 1)) / 12
+		
+	def validate_budget(self, acct, cost_center, actual, budget, action):
+		# action if actual exceeds budget
+		if flt(actual) > flt(budget):
+			msgprint("Your monthly expense "+ cstr((action == 'stop') and "will exceed" or "has exceeded") +" budget for <b>Account - "+cstr(acct)+" </b> under <b>Cost Center - "+ cstr(cost_center) + "</b>"+cstr((action == 'Stop') and ", you can not have this transaction." or "."))
+			if action == 'Stop': raise Exception
 
-  def check_budget(self,le_list,cancel):
-    # get value from record
-    acct, cost_center, debit, credit, post_dt, cfy, company  = le_list
+	def check_budget(self,gle,cancel):
+		# get allocated budget
+		
+		bgt = webnotes.conn.sql("""select t1.budget_allocated, t1.actual, t2.distribution_id 
+			from `tabBudget Detail` t1, `tabCost Center` t2 
+			where t1.account='%s' and t1.parent=t2.name and t2.name = '%s' 
+			and t1.fiscal_year='%s'""" % 
+			(gle['account'], gle['cost_center'], gle['fiscal_year']), as_dict =1)
 
-    # get allocated budget
-    bgt = sql("select t1.budget_allocated, t1.actual, t2.distribution_id from `tabBudget Detail` t1, `tabCost Center` t2 where t1.account='%s' and t1.parent=t2.name and t2.name = '%s' and t1.fiscal_year='%s'" % (acct,cost_center,cfy), as_dict =1)
-    curr_amt = ((cancel and -1  or 1) * flt(debit)) + ((cancel and 1  or -1) *  flt(credit))
-    
-    if bgt and bgt[0]['budget_allocated']:
-      # check budget flag in Company
-      bgt_flag = sql("select yearly_bgt_flag, monthly_bgt_flag from `tabCompany` where name = '%s'" % company, as_dict =1)
-      
-      if bgt_flag and bgt_flag[0]['monthly_bgt_flag'] in ['Stop', 'Warn']:
-        # get start date and last date
-        st_date = webnotes.conn.get_value('Fiscal Year', cfy, 'year_start_date').strftime('%Y-%m-%d')
-        lt_date = sql("select LAST_DAY('%s')" % post_dt)
-        
-        # get Actual
-        actual = get_obj('GL Control').get_period_difference(acct + '~~~' + cstr(st_date) + '~~~' + cstr(lt_date[0][0]), cost_center)
-      
-        # Get Monthly  budget
-        budget = self.get_monthly_budget(bgt and bgt[0]['distribution_id'] or '' , cfy, st_date, post_dt, bgt[0]['budget_allocated'])
-      
-        # validate monthly budget
-        self.validate_budget(acct, cost_center, flt(actual) + flt(curr_amt), budget, 'monthly_bgt_flag')
+		curr_amt = flt(gle['debit']) - flt(gle['credit'])
+		if cancel: curr_amt = -1 * curr_amt
+		
+		if bgt and bgt[0]['budget_allocated']:
+			# check budget flag in Company
+			bgt_flag = webnotes.conn.sql("""select yearly_bgt_flag, monthly_bgt_flag 
+				from `tabCompany` where name = '%s'""" % gle['company'], as_dict =1)
+			
+			if bgt_flag and bgt_flag[0]['monthly_bgt_flag'] in ['Stop', 'Warn']:
+				# get start date and last date
+				start_date = webnotes.conn.get_value('Fiscal Year', gle['fiscal_year'], \
+				 	'year_start_date').strftime('%Y-%m-%d')
+				end_date = webnotes.conn.sql("select LAST_DAY('%s')" % gle['posting_date'])
+			
+				# get Actual
+				actual = self.get_period_difference(gle['account'] + 
+					'~~~' + cstr(start_date) + '~~~' + cstr(end_date[0][0]), gle['cost_center'])
+		
+				# Get Monthly	budget
+				budget = self.get_monthly_budget(bgt and bgt[0]['distribution_id'] or '' , \
+					gle['fiscal_year'], start_date, gle['posting_date'], bgt[0]['budget_allocated'])
+		
+				# validate monthly budget
+				self.validate_budget(gle['account'], gle['cost_center'], \
+					flt(actual) + flt(curr_amt), budget, 'monthly_bgt_flag')
 
-      # update actual against budget allocated in cost center
-      sql("update `tabBudget Detail` set actual = ifnull(actual,0) + %s where account = '%s' and fiscal_year = '%s' and parent = '%s'" % (curr_amt,cstr(acct),cstr(cfy),cstr(cost_center)))
\ No newline at end of file
+			# update actual against budget allocated in cost center
+			webnotes.conn.sql("""update `tabBudget Detail` set actual = ifnull(actual,0) + %s 
+				where account = '%s' and fiscal_year = '%s' and parent = '%s'""" % 
+				(curr_amt, gle['account'],gle['fiscal_year'], gle['cost_center']))
+
+
+	def get_period_difference(self, arg, cost_center =''):
+		# used in General Ledger Page Report
+		# used for Budget where cost center passed as extra argument
+		acc, f, t = arg.split('~~~')
+		c, fy = '', get_defaults()['fiscal_year']
+
+		det = webnotes.conn.sql("select debit_or_credit, lft, rgt, is_pl_account from tabAccount where name=%s", acc)
+		if f: c += (' and t1.posting_date >= "%s"' % f)
+		if t: c += (' and t1.posting_date <= "%s"' % t)
+		if cost_center: c += (' and t1.cost_center = "%s"' % cost_center)
+		bal = webnotes.conn.sql("select sum(ifnull(t1.debit,0))-sum(ifnull(t1.credit,0)) from `tabGL Entry` t1 where t1.account='%s' %s" % (acc, c))
+		bal = bal and flt(bal[0][0]) or 0
+
+		if det[0][0] != 'Debit':
+			bal = (-1) * bal
+
+		return flt(bal)
\ No newline at end of file
diff --git a/accounts/doctype/gl_control/__init__.py b/accounts/doctype/gl_control/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/accounts/doctype/gl_control/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/accounts/doctype/gl_control/gl_control.py b/accounts/doctype/gl_control/gl_control.py
deleted file mode 100644
index db927e9..0000000
--- a/accounts/doctype/gl_control/gl_control.py
+++ /dev/null
@@ -1,391 +0,0 @@
-# ERPNext - web based ERP (http://erpnext.com)
-# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-# 
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from __future__ import unicode_literals
-import webnotes
-
-from webnotes.utils import cstr, flt, get_defaults
-from webnotes.model.doc import Document, addchild
-from webnotes.model.wrapper import getlist
-from webnotes.model.code import get_obj
-from webnotes import msgprint
-
-class DocType:
-	def __init__(self,d,dl):
-		self.doc, self.doclist = d, dl
-		self.entries = []
-
-	def get_period_difference(self,arg, cost_center =''):
-		# used in General Ledger Page Report
-		# used for Budget where cost center passed as extra argument
-		acc, f, t = arg.split('~~~')
-		c, fy = '', get_defaults()['fiscal_year']
-
-		det = webnotes.conn.sql("select debit_or_credit, lft, rgt, is_pl_account from tabAccount where name=%s", acc)
-		if f: c += (' and t1.posting_date >= "%s"' % f)
-		if t: c += (' and t1.posting_date <= "%s"' % t)
-		if cost_center: c += (' and t1.cost_center = "%s"' % cost_center)
-		bal = webnotes.conn.sql("select sum(ifnull(t1.debit,0))-sum(ifnull(t1.credit,0)) from `tabGL Entry` t1 where t1.account='%s' %s" % (acc, c))
-		bal = bal and flt(bal[0][0]) or 0
-
-		if det[0][0] != 'Debit':
-			bal = (-1) * bal
-
-		return flt(bal)
-
-	def add_ac(self,arg):
-		ac = webnotes.model_wrapper(eval(arg))
-		ac.doc.doctype = "Account"
-		ac.doc.old_parent = ""
-		ac.doc.freeze_account = "No"
-		ac.ignore_permissions = 1
-		ac.insert()
-
-		return ac.doc.name
-
-	# Add a new cost center
-	#----------------------
-	def add_cc(self,arg):
-		cc = webnotes.model_wrapper(eval(arg))
-		cc.doc.doctype = "Cost Center"
-		cc.doc.old_parent = ""
-		cc.ignore_permissions = 1
-		cc.insert()
-
-		return cc.doc.name
-
-
-	# Get field values from the voucher
-	#------------------------------------------
-	def get_val(self, src, d, parent=None):
-		if not src:
-			return None
-		if src.startswith('parent:'):
-			return parent.fields[src.split(':')[1]]
-		elif src.startswith('value:'):
-			return eval(src.split(':')[1])
-		elif src:
-			return d.fields.get(src)
-
-	def check_if_in_list(self, le):
-		for e in self.entries:
-			if e.account == le.account and (cstr(e.against_voucher)==cstr(le.against_voucher)) and (cstr(e.against_voucher_type)==cstr(le.against_voucher_type)) and (cstr(e.cost_center)==cstr(le.cost_center)):
-				return [e]
-		return 0
-
-	# Make a dictionary(le) for every gl entry and append to a list(self.entries)
-	#----------------------------------------------------------------------------
-	def make_single_entry(self,parent,d,le_map,cancel, merge_entries):
-		if self.get_val(le_map['account'], d, parent) and \
-				(self.get_val(le_map['debit'], d, parent) \
-				or self.get_val(le_map['credit'], d, parent)):
-			flist = ['account', 'cost_center', 'against', 'debit', 'credit', 'remarks',
-			 	'voucher_type', 'voucher_no', 'posting_date', 'fiscal_year', 'against_voucher',
-			 	'against_voucher_type', 'company', 'is_opening', 'aging_date']
-
-			# Check budget before gl entry
-			#check budget only if account is expense account
-			is_expense_acct = webnotes.conn.sql("""select name from tabAccount 
-				where is_pl_account='Yes' and debit_or_credit='Debit' 
-				and name=%s""",self.get_val(le_map['account'], d, parent))
-				
-			if is_expense_acct and self.get_val(le_map['cost_center'], d, parent):
-				get_obj('Budget Control').check_budget([self.get_val(le_map[k], d, parent) 
-					for k in flist if k in ['account', 'cost_center', 'debit', 
-					'credit', 'posting_date', 'fiscal_year', 'company']],cancel)
-
-			# Create new GL entry object and map values
-			le = Document('GL Entry')
-			for k in flist:
-				le.fields[k] = self.get_val(le_map[k], d, parent)
-			# if there is already an entry in this account then just add it to that entry
-			same_head = self.check_if_in_list(le)
-			if same_head and merge_entries:
-				same_head = same_head[0]
-				same_head.debit	= flt(same_head.debit)	+ flt(le.debit)
-				same_head.credit = flt(same_head.credit) + flt(le.credit)
-			else:
-				self.entries.append(le)
-				
-
-	def manage_debit_credit(self, cancel):
-		total_debit, total_credit = 0, 0
-		for le in self.entries:
-			# round off upto 2 decimal
-			le.debit = flt(le.debit, 2)
-			le.credit = flt(le.credit, 2)
-
-			#toggle debit, credit if negative entry
-			if flt(le.debit) < 0 or flt(le.credit) < 0:
-				tmp=le.debit
-				le.debit, le.credit = abs(flt(le.credit)), abs(flt(tmp))
-			
-			# toggled debit/credit in two separate condition because both
-			# should be executed at the time of cancellation when there is 
-			# negative amount (tax discount)
-			if cancel:
-				tmp=le.debit
-				le.debit, le.credit = abs(flt(le.credit)), abs(flt(tmp))
-		
-			# update total debit / credit
-			total_debit += flt(le.debit, 2)
-			total_credit += flt(le.credit, 2)
-			
-		diff = flt(total_debit - total_credit, 2)
-		if abs(diff)==0.01:
-			if self.entries[0].debit:
-				self.entries[0].debit = self.entries[0].debit - diff
-			elif self.entries[0].credit:
-				self.entries[0].credit = self.entries[0].credit + diff
-		elif abs(diff) > 0.01 and not cancel:
-			# Due to old wrong entries(total debit!=total credit) some voucher should be cancelled
-			msgprint("""Debit and Credit not equal for this voucher: Diff (Debit) is %s""" %
-			 	diff, raise_exception=1)
-
-	def save_entries(self, cancel, adv_adj, update_outstanding):
-		self.manage_debit_credit(cancel)
-		
-		for le in self.entries:
-			le_obj = get_obj(doc=le)
-			# validate except on_cancel
-			if not cancel:
-				le_obj.validate()
-
-			le.save(1)
-			le_obj.on_update(adv_adj, cancel, update_outstanding)
-			
-			
-	# Make Multiple Entries
-	def make_gl_entries(self, doc, doclist, cancel=0, adv_adj = 0, use_mapper='', merge_entries = 1, update_outstanding='Yes'):
-		self.entries = []
-		# get entries
-		le_map_list = webnotes.conn.sql("select * from `tabGL Mapper Detail` where parent = %s", use_mapper or doc.doctype, as_dict=1)
-		for le_map in le_map_list:
-			if le_map['table_field']:
-				for d in getlist(doclist,le_map['table_field']):
-					# purchase_tax_details is the table of other charges in purchase cycle
-					if le_map['table_field'] != 'purchase_tax_details' or \
-							(le_map['table_field'] == 'purchase_tax_details' and \
-							d.fields.get('category') != 'Valuation'):
-						self.make_single_entry(doc,d,le_map,cancel, merge_entries)
-			else:
-				self.make_single_entry(None,doc,le_map,cancel, merge_entries)
-
-		# save entries
-		self.save_entries(cancel, adv_adj, update_outstanding)
-
-		# set as cancelled
-		if cancel:
-			vt = self.get_val(le_map['voucher_type'], doc, doc)
-			vn = self.get_val(le_map['voucher_no'],	doc, doc)
-			webnotes.conn.sql("update `tabGL Entry` set is_cancelled='Yes' where voucher_type=%s and voucher_no=%s", (vt, vn))
-	
-	# ADVANCE ALLOCATION
-	#-------------------
-	def get_advances(self, obj, account_head, table_name,table_field_name, dr_or_cr):
-		jv_detail = webnotes.conn.sql("""select t1.name, t1.remark, t2.%s, t2.name 
-			from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 
-			where t1.name = t2.parent 
-			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 t2.account = '%s' and t2.is_advance = 'Yes' and t1.docstatus = 1 
-			order by t1.posting_date""" % (dr_or_cr,account_head))
-		# clear advance table
-		obj.doclist = obj.doc.clear_table(obj.doclist,table_field_name)
-		# Create advance table
-		for d in jv_detail:
-			add = addchild(obj.doc, table_field_name, table_name, obj.doclist)
-			add.journal_voucher = d[0]
-			add.jv_detail_no = d[3]
-			add.remarks = d[1]
-			add.advance_amount = flt(d[2])
-			add.allocate_amount = 0
-			
-		return obj.doclist
-
-	# Clear rows which is not adjusted
-	#-------------------------------------
-	def clear_advances(self, obj,table_name,table_field_name):
-		for d in getlist(obj.doclist,table_field_name):
-			if not flt(d.allocated_amount):
-				webnotes.conn.sql("update `tab%s` set parent = '' where name = '%s' and parent = '%s'" % (table_name, d.name, d.parent))
-				d.parent = ''
-
-	# Update aginst document in journal voucher
-	#------------------------------------------
-	def update_against_document_in_jv(self, obj, table_field_name, against_document_no, against_document_doctype, account_head, dr_or_cr,doctype):
-		for d in getlist(obj.doclist, table_field_name):
-			self.validate_jv_entry(d, account_head, dr_or_cr)
-			if flt(d.advance_amount) == flt(d.allocated_amount):
-				# cancel JV
-				jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children=1)
-				get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj =1)
-
-				# update ref in JV Detail
-				webnotes.conn.sql("update `tabJournal Voucher Detail` set %s = '%s' where name = '%s'" % (doctype=='Purchase Invoice' and 'against_voucher' or 'against_invoice', cstr(against_document_no), d.jv_detail_no))
-
-				# re-submit JV
-				jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children =1)
-				get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel = 0, adv_adj =1)
-
-			elif flt(d.advance_amount) > flt(d.allocated_amount):
-				# cancel JV
-				jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children=1)
-				get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj = 1)
-
-				# add extra entries
-				self.add_extra_entry(jv_obj, d.journal_voucher, d.jv_detail_no, flt(d.allocated_amount), account_head, doctype, dr_or_cr, against_document_no)
-
-				# re-submit JV
-				jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children =1)
-				get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel = 0, adv_adj = 1)
-			else:
-				msgprint("Allocation amount cannot be greater than advance amount")
-				raise Exception
-				
-
-	# Add extra row in jv detail for unadjusted amount
-	#--------------------------------------------------
-	def add_extra_entry(self,jv_obj,jv,jv_detail_no, allocate, account_head, doctype, dr_or_cr, against_document_no):
-		# get old entry details
-
-		jvd = webnotes.conn.sql("select %s, cost_center, balance, against_account from `tabJournal Voucher Detail` where name = '%s'" % (dr_or_cr,jv_detail_no))
-		advance = jvd and flt(jvd[0][0]) or 0
-		balance = flt(advance) - flt(allocate)
-
-		# update old entry
-		webnotes.conn.sql("update `tabJournal Voucher Detail` set %s = '%s', %s = '%s' where name = '%s'" % (dr_or_cr, flt(allocate), doctype == "Purchase Invoice" and 'against_voucher' or 'against_invoice',cstr(against_document_no), jv_detail_no))
-
-		# new entry with balance amount
-		add = addchild(jv_obj.doc, 'entries', 'Journal Voucher Detail', jv_obj.doclist)
-		add.account = account_head
-		add.cost_center = cstr(jvd[0][1])
-		add.balance = cstr(jvd[0][2])
-		add.fields[dr_or_cr] = balance
-		add.against_account = cstr(jvd[0][3])
-		add.is_advance = 'Yes'
-		add.save(1)
-		
-	# check if advance entries are still valid
-	# ----------------------------------------
-	def validate_jv_entry(self, d, account_head, dr_or_cr):
-		# 1. check if there is already a voucher reference
-		# 2. check if amount is same
-		# 3. check if is_advance is 'Yes'
-		# 4. check if jv is submitted
-		ret = webnotes.conn.sql("select t2.%s from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 where t1.name = t2.parent and ifnull(t2.against_voucher, '') = '' and ifnull(t2.against_invoice, '') = '' and t2.account = '%s' and t1.name = '%s' and t2.name = '%s' and t2.is_advance = 'Yes' and t1.docstatus=1 and t2.%s = %s" % (dr_or_cr, account_head, d.journal_voucher, d.jv_detail_no, dr_or_cr, d.advance_amount))
-		if (not ret):
-			msgprint("Please click on 'Get Advances Paid' button as the advance entries have been changed.")
-			raise Exception
-		return
-
-
-	def reconcile_against_document(self, args):
-		"""
-			Cancel JV, Update aginst document, split if required and resubmit jv
-		"""
-		
-		for d in args:
-			self.check_if_jv_modified(d)
-
-			against_fld = {
-				'Journal Voucher' : 'against_jv',
-				'Sales Invoice' : 'against_invoice',
-				'Purchase Invoice' : 'against_voucher'
-			}
-			
-			d['against_fld'] = against_fld[d['against_voucher_type']]
-
-			# cancel JV
-			jv_obj = get_obj('Journal Voucher', d['voucher_no'], with_children=1)
-			self.make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj =1)
-
-			# update ref in JV Detail
-			self.update_against_doc(d, jv_obj)
-
-			# re-submit JV
-			jv_obj = get_obj('Journal Voucher', d['voucher_no'], with_children =1)
-			self.make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel = 0, adv_adj =1)
-
-	def update_against_doc(self, d, jv_obj):
-		"""
-			Updates against document, if partial amount splits into rows
-		"""
-
-		webnotes.conn.sql("""
-			update `tabJournal Voucher Detail` t1, `tabJournal Voucher` t2	
-			set t1.%(dr_or_cr)s = '%(allocated_amt)s', 
-			t1.%(against_fld)s = '%(against_voucher)s', t2.modified = now() 
-			where t1.name = '%(voucher_detail_no)s' and t1.parent = t2.name""" % d)
-		
-		if d['allocated_amt'] < d['unadjusted_amt']:
-			jvd = webnotes.conn.sql("select cost_center, balance, against_account, is_advance from `tabJournal Voucher Detail` where name = '%s'" % d['voucher_detail_no'])
-			# new entry with balance amount
-			ch = addchild(jv_obj.doc, 'entries', 'Journal Voucher Detail')
-			ch.account = d['account']
-			ch.cost_center = cstr(jvd[0][0])
-			ch.balance = cstr(jvd[0][1])
-			ch.fields[d['dr_or_cr']] = flt(d['unadjusted_amt']) - flt(d['allocated_amt'])
-			ch.fields[d['dr_or_cr']== 'debit' and 'credit' or 'debit'] = 0
-			ch.against_account = cstr(jvd[0][2])
-			ch.is_advance = cstr(jvd[0][3])
-			ch.docstatus = 1
-			ch.save(1)
-
-	def check_if_jv_modified(self, args):
-		"""
-			check if there is already a voucher reference
-			check if amount is same
-			check if jv is submitted
-		"""
-		ret = webnotes.conn.sql("""
-			select t2.%(dr_or_cr)s from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 
-			where t1.name = t2.parent and t2.account = '%(account)s' 
-			and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')='' and ifnull(t2.against_jv, '')=''
-			and t1.name = '%(voucher_no)s' and t2.name = '%(voucher_detail_no)s'
-			and t1.docstatus=1 and t2.%(dr_or_cr)s = %(unadjusted_amt)s
-		""" % (args))
-		
-		if not ret:
-			msgprint("Payment Entry has been modified after you pulled it. Please pull it again.", raise_exception=1)
-		
-
-	def repost_illegal_cancelled(self, after_date='2011-01-01'):
-		"""
-			Find vouchers that are not cancelled correctly and repost them
-		"""
-		vl = webnotes.conn.sql("""
-			select voucher_type, voucher_no, account, sum(debit) as sum_debit, sum(credit) as sum_credit
-			from `tabGL Entry`
-			where is_cancelled='Yes' and creation > %s
-			group by voucher_type, voucher_no, account
-			""", after_date, as_dict=1)
-
-		ac_list = []
-		for v in vl:
-			if v['sum_debit'] != 0 or v['sum_credit'] != 0:
-				ac_list.append(v['account'])
-
-		fy_list = webnotes.conn.sql("""select name from `tabFiscal Year`
-		where (%s between year_start_date and date_sub(date_add(year_start_date,interval 1 year), interval 1 day))
-		or year_start_date > %s
-		order by year_start_date ASC""", (after_date, after_date))
-
-		for fy in fy_list:
-			fy_obj = get_obj('Fiscal Year', fy[0])
-			for a in set(ac_list):
-				fy_obj.repost(a)
diff --git a/accounts/doctype/gl_control/gl_control.txt b/accounts/doctype/gl_control/gl_control.txt
deleted file mode 100644
index 7e0710c..0000000
--- a/accounts/doctype/gl_control/gl_control.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-[
- {
-  "owner": "Administrator", 
-  "docstatus": 0, 
-  "creation": "2012-03-27 14:35:42", 
-  "modified_by": "Administrator", 
-  "modified": "2012-03-27 14:35:42"
- }, 
- {
-  "section_style": "Simple", 
-  "name": "__common__", 
-  "colour": "White:FFF", 
-  "module": "Accounts", 
-  "show_in_menu": 0, 
-  "version": 288, 
-  "server_code_error": " ", 
-  "doctype": "DocType", 
-  "issingle": 1
- }, 
- {
-  "name": "GL Control", 
-  "doctype": "DocType"
- }
-]
\ No newline at end of file
diff --git a/accounts/doctype/gl_control/locale/_messages_doc.json b/accounts/doctype/gl_control/locale/_messages_doc.json
deleted file mode 100644
index e7bfed9..0000000
--- a/accounts/doctype/gl_control/locale/_messages_doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-[
- "GL Control", 
- "Accounts"
-]
\ No newline at end of file
diff --git a/accounts/doctype/gl_control/locale/ar-doc.json b/accounts/doctype/gl_control/locale/ar-doc.json
deleted file mode 100644
index 779b94f..0000000
--- a/accounts/doctype/gl_control/locale/ar-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Accounts": "\u062d\u0633\u0627\u0628\u0627\u062a", 
- "GL Control": "GL \u0627\u0644\u062a\u062d\u0643\u0645"
-}
\ No newline at end of file
diff --git a/accounts/doctype/gl_control/locale/es-doc.json b/accounts/doctype/gl_control/locale/es-doc.json
deleted file mode 100644
index f7a8eee..0000000
--- a/accounts/doctype/gl_control/locale/es-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Accounts": "Cuentas", 
- "GL Control": "GL control"
-}
\ No newline at end of file
diff --git a/accounts/doctype/gl_control/locale/fr-doc.json b/accounts/doctype/gl_control/locale/fr-doc.json
deleted file mode 100644
index a7d3b17..0000000
--- a/accounts/doctype/gl_control/locale/fr-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Accounts": "Comptes", 
- "GL Control": "GL contr\u00f4le"
-}
\ No newline at end of file
diff --git a/accounts/doctype/gl_control/locale/hi-doc.json b/accounts/doctype/gl_control/locale/hi-doc.json
deleted file mode 100644
index ab677fa..0000000
--- a/accounts/doctype/gl_control/locale/hi-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Accounts": "\u0932\u0947\u0916\u093e", 
- "GL Control": "\u091c\u0940\u090f\u0932 \u0928\u093f\u092f\u0902\u0924\u094d\u0930\u0923"
-}
\ No newline at end of file
diff --git a/accounts/doctype/gl_control/locale/nl-doc.json b/accounts/doctype/gl_control/locale/nl-doc.json
deleted file mode 100644
index af964d5..0000000
--- a/accounts/doctype/gl_control/locale/nl-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Accounts": "Accounts", 
- "GL Control": "GL Controle"
-}
\ No newline at end of file
diff --git a/accounts/doctype/gl_control/locale/pt-doc.json b/accounts/doctype/gl_control/locale/pt-doc.json
deleted file mode 100644
index bac28e1..0000000
--- a/accounts/doctype/gl_control/locale/pt-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Accounts": "Contas", 
- "GL Control": "GL Controle"
-}
\ No newline at end of file
diff --git a/accounts/doctype/gl_control/locale/sr-doc.json b/accounts/doctype/gl_control/locale/sr-doc.json
deleted file mode 100644
index 23ccd3e..0000000
--- a/accounts/doctype/gl_control/locale/sr-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Accounts": "\u0420\u0430\u0447\u0443\u043d\u0438", 
- "GL Control": "\u0413\u041b \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u0430"
-}
\ No newline at end of file
diff --git a/accounts/doctype/gl_control/locale/ta-doc.json b/accounts/doctype/gl_control/locale/ta-doc.json
deleted file mode 100644
index 3a8afb9..0000000
--- a/accounts/doctype/gl_control/locale/ta-doc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Accounts": "\u0b95\u0ba3\u0b95\u0bcd\u0b95\u0bc1\u0b95\u0bb3\u0bcd", 
- "GL Control": "\u0b9c\u0bc0 \u0b95\u0b9f\u0bcd\u0b9f\u0bc1\u0baa\u0bcd\u0baa\u0bbe\u0b9f\u0bc1"
-}
\ No newline at end of file
diff --git a/accounts/doctype/gl_entry/gl_entry.py b/accounts/doctype/gl_entry/gl_entry.py
index 8f6d527..eeb9c05 100644
--- a/accounts/doctype/gl_entry/gl_entry.py
+++ b/accounts/doctype/gl_entry/gl_entry.py
@@ -18,15 +18,11 @@
 import webnotes
 
 from webnotes.utils import flt, fmt_money, get_first_day, get_last_day, getdate
-from webnotes.model import db_exists
-from webnotes.model.wrapper import copy_doclist
 from webnotes.model.code import get_obj
 from webnotes import msgprint
 
 sql = webnotes.conn.sql
 	
-
-
 class DocType:
 	def __init__(self,d,dl):
 		self.doc, self.doclist = d, dl
@@ -38,28 +34,18 @@
 		mandatory = ['account','remarks','voucher_type','voucher_no','fiscal_year','company']
 		for k in mandatory:
 			if not self.doc.fields.get(k):
-				msgprint("%s is mandatory for GL Entry" % k)
-				raise Exception
+				msgprint("%s is mandatory for GL Entry" % k, raise_exception=1)
 				
 		# Zero value transaction is not allowed
 		if not (flt(self.doc.debit) or flt(self.doc.credit)):
 			msgprint("GL Entry: Debit or Credit amount is mandatory for %s" % self.doc.account)
 			raise Exception
 			
-			
-		# COMMMENTED below to allow zero amount (+ and -) entry in tax table
-		# Debit and credit can not done at the same time
-		#if flt(self.doc.credit) != 0 and flt(self.doc.debit) != 0:
-		#	msgprint("Sorry you cannot credit and debit under same account head.")
-		#	raise Exception, "Validation Error."
-		
-	# Cost center is required only if transaction made against pl account
-	#--------------------------------------------------------------------
 	def pl_must_have_cost_center(self):
 		if sql("select name from tabAccount where name=%s and is_pl_account='Yes'", self.doc.account):
 			if not self.doc.cost_center and self.doc.voucher_type != 'Period Closing Voucher':
-				msgprint("Error: Cost Center must be specified for PL Account: %s" % self.doc.account)
-				raise Exception
+				msgprint("Error: Cost Center must be specified for PL Account: %s" %
+				 	self.doc.account, raise_exception=1)
 		else: # not pl
 			if self.doc.cost_center:
 				self.doc.cost_center = ''
diff --git a/accounts/doctype/journal_voucher/journal_voucher.py b/accounts/doctype/journal_voucher/journal_voucher.py
index 551b07d..0a4a1a1 100644
--- a/accounts/doctype/journal_voucher/journal_voucher.py
+++ b/accounts/doctype/journal_voucher/journal_voucher.py
@@ -24,10 +24,9 @@
 from webnotes import msgprint
 from setup.utils import get_company_currency
 
-sql = webnotes.conn.sql
-	
+from controllers.accounts_controller import AccountsController
 
-class DocType:
+class DocType(AccountsController):
 	def __init__(self,d,dl):
 		self.doc, self.doclist = d,dl
 		self.master_type = {}
@@ -37,74 +36,160 @@
 
 	def autoname(self):
 		if not self.doc.naming_series:
-			webnotes.msgprint("""Naming Series is mandatory""", raise_exception=1)
-			
+			webnotes.msgprint("""Naming Series is mandatory""", raise_exception=1)	
 		self.doc.name = make_autoname(self.doc.naming_series+'.#####')
+		
+	def validate(self):
+		if not self.doc.is_opening:
+			self.doc.is_opening='No'
+			
+		self.validate_debit_credit()
+		self.validate_cheque_info()
+		self.validate_entries_for_advance()
+		self.validate_against_jv()
+		get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year, \
+			self.doc.posting_date, 'Posting Date')
+		
+		self.set_against_account()
+		self.create_remarks()		
+		self.set_aging_date()
+		self.set_print_format_fields()
 
-	def get_outstanding(self, args):
-		args = eval(args)
-		o_s = sql("select outstanding_amount from `tab%s` where name = '%s'" % (args['doctype'],args['docname']))
-		if args['doctype'] == 'Purchase Invoice':
-			return {'debit': o_s and flt(o_s[0][0]) or 0}
-		if args['doctype'] == 'Sales Invoice':
-			return {'credit': o_s and flt(o_s[0][0]) or 0}
+	
+	def on_submit(self):
+		if self.doc.voucher_type in ['Bank Voucher', 'Contra Voucher', 'Journal Entry']:
+			self.check_credit_days()
+		self.check_account_against_entries()
+		self.make_gl_entries()
+
+	def on_cancel(self):
+		self.make_gl_entries(cancel=1)
+
+	def validate_debit_credit(self):
+		for d in getlist(self.doclist, 'entries'):
+			if d.debit and d.credit:
+				msgprint("You cannot credit and debit same account at the same time.", 
+				 	raise_exception=1)
+
+	def validate_cheque_info(self):
+		if self.doc.voucher_type in ['Bank Voucher']:
+			if not self.doc.cheque_no or not self.doc.cheque_date:
+				msgprint("Reference No & Reference Date is required for %s" %
+				self.doc.voucher_type, raise_exception=1)
+				
+		if self.doc.cheque_date and not self.doc.cheque_no:
+			msgprint("Reference No is mandatory if you entered Reference Date", raise_exception=1)
+
+	def validate_entries_for_advance(self):
+		for d in getlist(self.doclist,'entries'):
+			if not d.is_advance and not d.against_voucher and \
+					not d.against_invoice and not d.against_jv:
+				master_type = webnotes.conn.get_value("Account", d.account, "master_type")
+				if (master_type == 'Customer' and flt(d.credit) > 0) or \
+						(master_type == 'Supplier' and flt(d.debit) > 0):
+					msgprint("Message: Please check Is Advance as 'Yes' against \
+						Account %s if this is an advance entry." % d.account)
+
+	def validate_against_jv(self):
+		for d in getlist(self.doclist, 'entries'):
+			if d.against_jv:
+				if d.against_jv == self.doc.name:
+					msgprint("You can not enter current voucher in 'Against JV' column",
+						raise_exception=1)
+				elif not webnotes.conn.sql("""select name from `tabJournal Voucher Detail` 
+						where account = '%s' and docstatus = 1 and parent = '%s'""" % 
+						(d.account, d.against_jv)):
+					msgprint("Against JV: %s is not valid." % d.against_jv, raise_exception=1)
+		
+	def set_against_account(self):
+		# Debit = Credit
+		debit, credit = 0.0, 0.0
+		debit_list, credit_list = [], []
+		for d in getlist(self.doclist, 'entries'):
+			debit += flt(d.debit)
+			credit += flt(d.credit)
+			if flt(d.debit)>0 and (d.account not in debit_list): debit_list.append(d.account)
+			if flt(d.credit)>0 and (d.account not in credit_list): credit_list.append(d.account)
+
+		self.doc.total_debit = debit
+		self.doc.total_credit = credit
+
+		if abs(self.doc.total_debit-self.doc.total_credit) > 0.001:
+			msgprint("Debit must be equal to Credit. The difference is %s" % 
+			 	(self.doc.total_debit-self.doc.total_credit), raise_exception=1)
+		
+		# update against account
+		for d in getlist(self.doclist, 'entries'):
+			if flt(d.debit) > 0: d.against_account = ', '.join(credit_list)
+			if flt(d.credit) > 0: d.against_account = ', '.join(debit_list)
 
 	def create_remarks(self):
 		r = []
 		if self.doc.cheque_no :
 			if self.doc.cheque_date:
-				r.append('Via Reference #%s dated %s' % (self.doc.cheque_no, formatdate(self.doc.cheque_date)))
+				r.append('Via Reference #%s dated %s' % 
+					(self.doc.cheque_no, formatdate(self.doc.cheque_date)))
 			else :
-				msgprint("Please enter Reference date")
-				raise Exception
+				msgprint("Please enter Reference date", raise_exception=1)
 		
 		for d in getlist(self.doclist, 'entries'):
 			if d.against_invoice and d.credit:
-				currency = sql("select currency from `tabSales Invoice` where name = '%s'" % d.against_invoice)
-				currency = currency and currency[0][0] or ''
-				r.append('%s %s against Invoice: %s' % (cstr(currency), fmt_money(flt(d.credit)), d.against_invoice))
+				currency = webnotes.conn.get_value("Sales Invoice", d.against_invoice, "currency")
+				r.append('%s %s against Invoice: %s' % 
+					(cstr(currency), fmt_money(flt(d.credit)), d.against_invoice))
+					
 			if d.against_voucher and d.debit:
-				bill_no = sql("select bill_no, bill_date, currency from `tabPurchase Invoice` where name=%s", d.against_voucher)
-				if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() not in ['na', 'not applicable', 'none']:
+				bill_no = webnotes.conn.sql("""select bill_no, bill_date, currency 
+					from `tabPurchase Invoice` where name=%s""", d.against_voucher)
+				if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() \
+						not in ['na', 'not applicable', 'none']:
 					bill_no = bill_no and bill_no[0]
-					r.append('%s %s against Bill %s dated %s' % (bill_no[2] and cstr(bill_no[2]) or '', fmt_money(flt(d.debit)), bill_no[0], bill_no[1] and formatdate(bill_no[1].strftime('%Y-%m-%d')) or ''))
+					r.append('%s %s against Bill %s dated %s' % 
+						(cstr(bill_no[0][2]), fmt_money(flt(d.debit)), bill_no[0][0], 
+						bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d')) or ''))
 	
 		if self.doc.user_remark:
 			r.append("User Remark : %s"%self.doc.user_remark)
 
 		if r:
 			self.doc.remark = ("\n").join(r)
-	
-	def get_authorized_user(self):
-		if self.is_approving_authority==-1:
-			self.is_approving_authority = 0
 
-			# Fetch credit controller role
-			approving_authority = sql("select value from `tabSingles` where field='credit_controller' and doctype='Global Defaults'")
-			approving_authority = approving_authority and approving_authority[0][0] or ''
-			
-			# Check logged-in user is authorized
-			if approving_authority in webnotes.user.get_roles():
-				self.is_approving_authority = 1
-				
-		return self.is_approving_authority
-			
-	def get_master_type(self, ac):
-		if not self.master_type.get(ac):
-			self.master_type[ac] = sql("select master_type from `tabAccount` where name=%s", ac)[0][0] or 'None'
-		return self.master_type[ac]
-	
-	def get_credit_days_for(self, ac):
-		if not self.credit_days_for.has_key(ac):
-			self.credit_days_for[ac] = sql("select credit_days from `tabAccount` where name='%s'" % ac)[0][0] or 0
-
-		if not self.credit_days_for[ac]:
-			if self.credit_days_global==-1:
-				self.credit_days_global = sql("select credit_days from `tabCompany` where name='%s'" % self.doc.company)[0][0] or 0
-			return self.credit_days_global
+	def set_aging_date(self):
+		if self.doc.is_opening != 'Yes':
+			self.doc.aging_date = self.doc.posting_date
 		else:
-			return self.credit_days_for[ac]
-	
+			# check account type whether supplier or customer
+			exists = False
+			for d in getlist(self.doclist, 'entries'):
+				account_type = webnotes.conn.get_value("Account", d.account, "account_type")
+				if account_type in ["Supplier", "Customer"]:
+					exists = True
+					break
+
+			# If customer/supplier account, aging date is mandatory
+			if exists and not self.doc.aging_date: 
+				msgprint("Aging Date is mandatory for opening entry", raise_exception=1)
+			else:
+				self.doc.aging_date = self.doc.posting_date
+
+	def set_print_format_fields(self):
+		for d in getlist(self.doclist, 'entries'):
+			account_type, master_type = webnotes.conn.get_value("Account", d.account, 
+				["account_type", "master_type"])
+				
+			if master_type in ['Supplier', 'Customer']:
+				if not self.doc.pay_to_recd_from:
+					self.doc.pay_to_recd_from = webnotes.conn.get_value(master_type, 
+						' - '.join(d.account.split(' - ')[:-1]), 
+						master_type == 'Customer' and 'customer_name' or 'supplier_name')
+			
+			if account_type == 'Bank or Cash':
+				company_currency = get_company_currency(self.doc.company)
+				amt = flt(d.debit) and d.debit or d.credit	
+				self.doc.total_amount = company_currency +' '+ cstr(amt)
+				from webnotes.utils import money_in_words
+				self.doc.total_amount_in_words = money_in_words(amt, company_currency)
+
 	def check_credit_days(self):
 		date_diff = 0
 		if self.doc.cheque_date:
@@ -113,48 +198,83 @@
 		if date_diff <= 0: return
 		
 		# Get List of Customer Account
-		acc_list = filter(lambda d: self.get_master_type(d.account)=='Customer', getlist(self.doclist,'entries'))
+		acc_list = filter(lambda d: webnotes.conn.get_value("Account", d.account, 
+		 	"master_type")=='Customer', getlist(self.doclist,'entries'))
 		
 		for d in acc_list:
 			credit_days = self.get_credit_days_for(d.account)
-			
 			# Check credit days
 			if credit_days > 0 and not self.get_authorized_user() and cint(date_diff) > credit_days:
-				msgprint("Credit Not Allowed: Cannot allow a check that is dated more than %s days after the posting date" % credit_days)
-				raise Exception
+				msgprint("Credit Not Allowed: Cannot allow a check that is dated \
+					more than %s days after the posting date" % credit_days, raise_exception=1)
 					
-	def check_account_against_entries(self):
-		for d in getlist(self.doclist,'entries'):
-			if d.against_invoice:
-				acc=sql("select debit_to from `tabSales Invoice` where name='%s'"%d.against_invoice)
-				if acc and acc[0][0] != d.account:
-					msgprint("Debit account is not matching with receivable voucher")
-					raise Exception
-			
-			if d.against_voucher:
-				acc=sql("select credit_to from `tabPurchase Invoice` where name='%s'"%d.against_voucher)
-				if acc and acc[0][0] != d.account:
-					msgprint("Credit account is not matching with payable voucher")
-					raise Exception
-					
-	def validate_cheque_info(self):
-		if self.doc.voucher_type in ['Bank Voucher']:
-			if not self.doc.cheque_no or not self.doc.cheque_date:
-				msgprint("Reference No & Reference Date is required for " + cstr(self.doc.voucher_type))
-				raise Exception
-				
-		if self.doc.cheque_date and not self.doc.cheque_no:
-			msgprint("Reference No is mandatory if you entered Reference Date")
-			raise Exception
-			
-	def validate_entries_for_advance(self):
-		for d in getlist(self.doclist,'entries'):
-			if not d.is_advance and not d.against_voucher and not d.against_invoice and not d.against_jv:
-				master_type = self.get_master_type(d.account)
-				if (master_type == 'Customer' and flt(d.credit) > 0) or (master_type == 'Supplier' and flt(d.debit) > 0):
-					msgprint("Message: Please check Is Advance as 'Yes' against Account %s if this is an advance entry." % d.account)
-				
+	def get_credit_days_for(self, ac):
+		if not self.credit_days_for.has_key(ac):
+			self.credit_days_for[ac] = cint(webnotes.conn.get_value("Account", ac, "credit_days"))
 
+		if not self.credit_days_for[ac]:
+			if self.credit_days_global==-1:
+				self.credit_days_global = cint(webnotes.conn.get_value("Company", 
+					self.doc.company, "credit_days"))
+					
+			return self.credit_days_global
+		else:
+			return self.credit_days_for[ac]
+
+	def get_authorized_user(self):
+		if self.is_approving_authority==-1:
+			self.is_approving_authority = 0
+
+			# Fetch credit controller role
+			approving_authority = webnotes.conn.get_value("Global Defaults", None, 
+				"credit_controller")
+			
+			# Check logged-in user is authorized
+			if approving_authority in webnotes.user.get_roles():
+				self.is_approving_authority = 1
+				
+		return self.is_approving_authority
+
+	def check_account_against_entries(self):
+		for d in self.doclist.get({"parentfield": "entries"}):
+			if d.against_invoice and webnotes.conn.get_value("Sales Invoice", 
+					d.against_invoice, "credit_to") != d.account:
+				msgprint("Debit account is not matching with Sales Invoice", raise_exception=1)
+			
+			if d.against_voucher and webnotes.conn.get_value("Purchase Invoice", 
+						d.against_voucher, "debit_to") != d.account:
+				msgprint("Credit account is not matching with Purchase Invoice", raise_exception=1)
+
+	def make_gl_entries(self, cancel=0, adv_adj=0):
+		from accounts.general_ledger import make_gl_entries
+		gl_map = []
+		for d in self.doclist.get({"parentfield": "entries"}):
+			gl_map.append(
+				self.get_gl_dict({
+					"account": d.account,
+					"against": d.against_account,
+					"debit": d.debit,
+					"credit": d.credit,
+					"against_voucher_type": ((d.against_voucher and "Purchase Invoice") 
+						or (d.against_invoice and "Sales Invoice") 
+						or (d.against_jv and "Journal Voucher")),
+					"against_voucher": d.against_voucher or d.against_invoice or d.against_jv,
+					"remarks": self.doc.remark,
+					"cost_center": d.cost_center
+				}, cancel)
+			)
+			
+		make_gl_entries(gl_map, cancel=cancel, adv_adj=adv_adj)
+
+	def get_outstanding(self, args):
+		args = eval(args)
+		o_s = webnotes.conn.sql("""select outstanding_amount from `tab%s` where name = %s""" % 
+			(args['doctype'], '%s'), args['docname'])
+		if args['doctype'] == 'Purchase Invoice':
+			return {'debit': o_s and flt(o_s[0][0]) or 0}
+		if args['doctype'] == 'Sales Invoice':
+			return {'credit': o_s and flt(o_s[0][0]) or 0}
+	
 	def get_balance(self):
 		if not getlist(self.doclist,'entries'):
 			msgprint("Please enter atleast 1 entry in 'GL Entries' table")
@@ -164,7 +284,7 @@
 			
 			# If any row without amount, set the diff on that row
 			for d in getlist(self.doclist,'entries'):
-				if (d.credit==0 or d.credit is None) and (d.debit==0 or d.debit is None) and (flt(diff) != 0):
+				if not d.credit and not d.debit and flt(diff) != 0:
 					if diff>0:
 						d.credit = flt(diff)
 					elif diff<0:
@@ -185,71 +305,6 @@
 				self.doc.total_credit += flt(d.credit)
 
 			self.doc.difference = flt(self.doc.total_debit) - flt(self.doc.total_credit)
-			
-	def get_against_account(self):
-		# Debit = Credit
-		debit, credit = 0.0, 0.0
-		debit_list, credit_list = [], []
-		for d in getlist(self.doclist, 'entries'):
-			debit += flt(d.debit)
-			credit += flt(d.credit)
-			if flt(d.debit)>0 and (d.account not in debit_list): debit_list.append(d.account)
-			if flt(d.credit)>0 and (d.account not in credit_list): credit_list.append(d.account)
-
-		self.doc.total_debit = debit
-		self.doc.total_credit = credit
-
-		if abs(self.doc.total_debit-self.doc.total_credit) > 0.001:
-			msgprint("Debit must be equal to Credit. The difference is %s" % (self.doc.total_debit-self.doc.total_credit))
-			raise Exception
-		
-		# update against account
-		for d in getlist(self.doclist, 'entries'):
-			if flt(d.debit) > 0: d.against_account = ', '.join(credit_list)
-			if flt(d.credit) > 0: d.against_account = ', '.join(debit_list)
-
-	def set_aging_date(self):
-		if self.doc.is_opening != 'Yes':
-			self.doc.aging_date = self.doc.posting_date
-		else:
-			# check account type whether supplier or customer
-			exists = ''
-			for d in getlist(self.doclist, 'entries'):
-				exists = sql("select name from tabAccount where account_type in ('Supplier', 'Customer') and name = '%s'" % d.account)
-				if exists:
-					break
-
-			# If cus/supp aging dt is mandatory
-			if exists and not self.doc.aging_date: 
-				msgprint("Aging Date is mandatory for opening entry")
-				raise Exception
-			# otherwise aging dt = posting dt
-			else:
-				self.doc.aging_date = self.doc.posting_date
-
-	def set_print_format_fields(self):
-		for d in getlist(self.doclist, 'entries'):
-			#msgprint(self.doc.company)
-			chk_type = sql("select master_type, account_type from `tabAccount` where name='%s'" % d.account)
-			master_type, acc_type = chk_type and cstr(chk_type[0][0]) or '', chk_type and cstr(chk_type[0][1]) or ''
-			if master_type in ['Supplier', 'Customer']:
-				if not self.doc.pay_to_recd_from:
-					self.doc.pay_to_recd_from = webnotes.conn.get_value(master_type, ' - '.join(d.account.split(' - ')[:-1]), master_type == 'Customer' and 'customer_name' or 'supplier_name')
-			
-			if acc_type == 'Bank or Cash':
-				company_currency = get_company_currency(self.doc.company)
-				amt = flt(d.debit) and d.debit or d.credit	
-				self.doc.total_amount = company_currency +' '+ cstr(amt)
-				from webnotes.utils import money_in_words
-				self.doc.total_amount_in_words = money_in_words(amt, company_currency)
-				
-	def get_values(self):
-		cond = (flt(self.doc.write_off_amount) > 0) and ' and outstanding_amount <= '+self.doc.write_off_amount or ''
-		if self.doc.write_off_based_on == 'Accounts Receivable':
-			return sql("select name, debit_to, outstanding_amount from `tabSales Invoice` where docstatus = 1 and company = '%s' and outstanding_amount > 0 %s" % (self.doc.company, cond))
-		elif self.doc.write_off_based_on == 'Accounts Payable':
-			return sql("select name, credit_to, outstanding_amount from `tabPurchase Invoice` where docstatus = 1 and company = '%s' and outstanding_amount > 0 %s" % (self.doc.company, cond))
-
 
 	def get_outstanding_invoices(self):
 		self.doclist = self.doc.clear_table(self.doclist, 'entries')
@@ -272,48 +327,14 @@
 			jd.credit = total
 		jd.save(1)
 
-	def validate(self):
-		if not self.doc.is_opening:
-			self.doc.is_opening='No'
-		self.validate_debit_credit()
-		self.get_against_account()
-		self.validate_cheque_info()
-		self.create_remarks()
-		
-		self.validate_entries_for_advance()
-		self.set_aging_date()
-		
-		self.validate_against_jv()
-		self.set_print_format_fields()
-
-		#FY and Date validation
-		get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year, \
-			self.doc.posting_date, 'Posting Date')
-
-	def validate_debit_credit(self):
-		for d in getlist(self.doclist, 'entries'):
-			if d.debit and d.credit:
-				msgprint("You cannot credit and debit same account at the same time.", 
-				 	raise_exception=1)
-
-	def on_update(self):
-		pass
-				
-	def on_submit(self):
-		if self.doc.voucher_type in ['Bank Voucher', 'Contra Voucher', 'Journal Entry']:
-			self.check_credit_days()
-		self.check_account_against_entries()
-		get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist)
-
-	def validate_against_jv(self):
-		for d in getlist(self.doclist, 'entries'):
-			if d.against_jv:
-				if d.against_jv == self.doc.name:
-					msgprint("You can not enter current voucher in 'Against JV' column")
-					raise Exception
-				elif not sql("select name from `tabJournal Voucher Detail` where account = '%s' and docstatus = 1 and parent = '%s'" % (d.account, d.against_jv)):
-					msgprint("Against JV: "+ d.against_jv + " is not valid. Please check")
-					raise Exception
-	
-	def on_cancel(self):
-		get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist, cancel=1)
\ No newline at end of file
+	def get_values(self):
+		cond = (flt(self.doc.write_off_amount) > 0) and \
+			' and outstanding_amount <= '+ self.doc.write_off_amount or ''
+		if self.doc.write_off_based_on == 'Accounts Receivable':
+			return webnotes.conn.sql("""select name, debit_to, outstanding_amount 
+				from `tabSales Invoice` where docstatus = 1 and company = %s 
+				and outstanding_amount > 0 %s""" % ('%s', cond), self.doc.company)
+		elif self.doc.write_off_based_on == 'Accounts Payable':
+			return webnotes.conn.sql("""select name, credit_to, outstanding_amount 
+				from `tabPurchase Invoice` where docstatus = 1 and company = %s 
+				and outstanding_amount > 0 %s""" % ('%s', cond), self.doc.company)
\ No newline at end of file
diff --git a/accounts/doctype/journal_voucher/test_journal_voucher.py b/accounts/doctype/journal_voucher/test_journal_voucher.py
index e043e9f..4c72092 100644
--- a/accounts/doctype/journal_voucher/test_journal_voucher.py
+++ b/accounts/doctype/journal_voucher/test_journal_voucher.py
@@ -44,6 +44,14 @@
 		"is_pl_account": "No",
 		"group_or_ledger": "Ledger"
 	},
+	"test_cost_center": {
+		"doctype": "Cost Center",
+		"cost_center_name": "Test Cost Center",
+		"parent_cost_center": "Root - %s" % abbr,
+		"company_name": company,
+		"group_or_ledger": "Ledger",
+		"company_abbr": abbr
+	},
 	"journal_voucher": [
 		{
 			"doctype": "Journal Voucher",
@@ -59,7 +67,7 @@
 			"parentfield": "entries",
 			"account": "Test Expense - %s" % abbr,
 			"debit": 5000,
-			"cost_center": "Default CC Ledger - %s" % abbr,
+			"cost_center": "Test Cost Center - %s" % abbr,
 		},
 		{
 			"doctype": "Journal Voucher Detail",
@@ -80,6 +88,7 @@
 		# create a dummy account
 		webnotes.model.insert([data["expense_account"]])
 		webnotes.model.insert([data["supplier_account"]])
+		webnotes.model.insert([data["test_cost_center"]])
 		
 	def tearDown(self):
 		webnotes.conn.rollback()
diff --git a/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py b/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py
index 3978688..d585cea 100644
--- a/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py
+++ b/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py
@@ -20,7 +20,6 @@
 from webnotes.utils import flt
 from webnotes.model.doc import addchild
 from webnotes.model.wrapper import getlist
-from webnotes.model.code import get_obj
 from webnotes import msgprint
 
 class DocType:
@@ -137,7 +136,8 @@
 				lst.append(args)
 		
 		if lst:
-			get_obj('GL Control').reconcile_against_document(lst)
+			from accounts.utils import reconcile_against_document
+			reconcile_against_document(lst)
 			msgprint("Successfully allocated.")
 		else:
 			msgprint("No amount allocated.", raise_exception=1)
diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py
index f144ce9..0db7ea8 100644
--- a/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -20,7 +20,7 @@
 from webnotes.utils import add_days, cint, cstr, flt, formatdate, get_defaults
 from webnotes.model.wrapper import getlist
 from webnotes.model.code import get_obj
-from webnotes import msgprint
+from webnotes import msgprint, _
 from setup.utils import get_company_currency
 
 sql = webnotes.conn.sql
@@ -99,11 +99,9 @@
 				d.expense_head = item and item[0]['purchase_account'] or ''
 				d.cost_center = item and item[0]['cost_center'] or ''
 
-	# Advance Allocation
-	# -------------------
 	def get_advances(self):
-		self.doclist = get_obj('GL Control').get_advances(self, self.doc.credit_to, 'Purchase Invoice Advance','advance_allocation_details','debit')
-		
+		super(DocType, self).get_advances(self.doc.credit_to, 
+			"Purchase Invoice Advance", "advance_allocation_details", "debit")
 		
 	def get_rate(self,arg):
 		return get_obj('Purchase Common').get_rate(arg,self)
@@ -187,16 +185,7 @@
 	# ---------------------
 	def validate_bill_no_date(self):
 		if self.doc.bill_no and not self.doc.bill_date and self.doc.bill_no.lower().strip() not in ['na', 'not applicable', 'none']:
-			msgprint("Please enter Bill Date")
-			raise Exception					
-
-
- 
-	# Clear Advances
-	# ---------------
-	def clear_advances(self):
-		get_obj('GL Control').clear_advances( self, 'Purchase Invoice Advance','advance_allocation_details')
-
+			msgprint(_("Please enter Bill Date"), raise_exception=1)
 
 	# 1. Credit To Account Exists
 	# 2. Is a Credit Account
@@ -326,8 +315,6 @@
 		if self.doc.write_off_amount and not self.doc.write_off_account:
 			msgprint("Please enter Write Off Account", raise_exception=1)
 
-	# VALIDATE
-	# ====================================================================================
 	def validate(self):
 		super(DocType, self).validate()
 		
@@ -338,8 +325,8 @@
 		self.validate_bill_no_date()
 		self.validate_bill_no()
 		self.validate_reference_value()
-		self.clear_advances()
 		self.validate_credit_acc()
+		self.clear_unallocated_advances("Purchase Invoice Advance", "advance_allocation_details")
 		self.check_for_acc_head_of_supplier()
 		self.check_for_stopped_status()
 
@@ -406,8 +393,8 @@
 				lst.append(args)
 		
 		if lst:
-			get_obj('GL Control').reconcile_against_document(lst)
-
+			from accounts.utils import reconcile_against_document
+			reconcile_against_document(lst)
 
 	def on_submit(self):
 		purchase_controller = webnotes.get_obj("Purchase Common")
@@ -427,8 +414,97 @@
 
 
 	def make_gl_entries(self, is_cancel = 0):
-		get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist, cancel = is_cancel, \
-			use_mapper = (self.doc.write_off_account and self.doc.write_off_amount and 'Purchase Invoice with write off' or ''))
+		from accounts.general_ledger import make_gl_entries
+		gl_entries = []
+		valuation_tax = 0
+		auto_inventory_accounting = webnotes.conn.get_value("Global Defaults", None, 
+		 	"automatic_inventory_accounting")
+		abbr = self.get_company_abbr()
+		
+		# parent's gl entry
+		gl_entries.append(
+			self.get_gl_dict({
+				"account": self.doc.credit_to,
+				"against": self.doc.against_expense_account,
+				"credit": self.doc.grand_total,
+				"remarks": self.doc.remarks,
+				"against_voucher": self.doc.name,
+				"against_voucher_type": self.doc.doctype,
+			}, is_cancel)
+		)
+	
+		# tax table gl entries
+		for tax in getlist(self.doclist, "other_charges"):
+			if tax.category in ("Total", "Valuation and Total"):
+				valuation_tax += flt(tax.tax_amount)
+				
+				gl_entries.append(
+					self.get_gl_dict({
+						"account": tax.account_head,
+						"against": self.doc.credit_to,
+						"debit": tax.tax_amount,
+						"remarks": self.doc.remarks,
+						"cost_center": tax.cost_center
+					}, is_cancel)
+				)
+					
+		# item gl entries
+		stock_item_and_auto_accounting = False
+		for item in self.doclist.get({"parentfield": "entries"}):
+			if auto_inventory_accounting and \
+					webnotes.conn.get_value("Item", item.item_code, "is_stock_item")=="Yes":
+				# if auto inventory accounting enabled and stock item, 
+				# then do stock related gl entries, expense will be booked in sales invoice
+				gl_entries.append(
+					self.get_gl_dict({
+						"account": "Stock Received But Not Billed - %s" % (abbr,),
+						"against": self.doc.credit_to,
+						"debit": flt(item.valuation_rate) * flt(item.conversion_factor) \
+							*  item.qty,
+						"remarks": self.doc.remarks or "Accounting Entry for Stock"
+					}, is_cancel)
+				)
+			
+				stock_item_and_auto_accounting = True
+			
+			else:
+				# if not a stock item or auto inventory accounting disabled, book the expense
+				gl_entries.append(
+					self.get_gl_dict({
+						"account": item.expense_head,
+						"against": self.doc.credit_to,
+						"debit": item.amount,
+						"remarks": self.doc.remarks,
+						"cost_center": item.cost_center
+					}, is_cancel)
+				)
+				
+		if stock_item_and_auto_accounting and valuation_tax:
+			# credit valuation tax amount in "Expenses Included In Valuation"
+			# this will balance out valuation amount included in cost of goods sold
+			gl_entries.append(
+				self.get_gl_dict({
+					"account": "Expenses Included In Valuation - %s" % (abbr,),
+					"cost_center": "ERP - %s" % abbr, # to-do
+					"against": self.doc.credit_to,
+					"credit": valuation_tax,
+					"remarks": self.doc.remarks or "Accounting Entry for Stock"
+				}, is_cancel)
+			)
+		
+		# writeoff account includes petty difference in the invoice amount 
+		# and the amount that is paid
+		if self.doc.write_off_account and self.doc.write_off_amount:
+			gl_entries.append(
+				self.get_gl_dict({
+					"account": self.doc.write_off_account,
+					"against": self.doc.credit_to,
+					"credit": self.doc.write_off_amount,
+					"remarks": self.doc.remarks,
+					"cost_center": self.doc.write_off_cost_center
+				}, is_cancel)
+			)
+		make_gl_entries(gl_entries, cancel=is_cancel)
 
 
 	def check_next_docstatus(self):
diff --git a/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index 5781e3b..861c289 100644
--- a/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -20,7 +20,6 @@
 import webnotes
 import webnotes.model
 from webnotes.utils import nowdate
-from accounts.utils import get_fiscal_year
 
 from stock.doctype.purchase_receipt import test_purchase_receipt
 
@@ -30,6 +29,10 @@
 def load_data():
 	test_purchase_receipt.load_data()
 	
+	webnotes.insert({"doctype": "Account", "account_name": "Cost for Goods Sold",
+		"parent_account": "Expenses - %s" % abbr, "company": company,
+		"group_or_ledger": "Ledger"})
+	
 	webnotes.insert({"doctype": "Account", "account_name": "Excise Duty",
 		"parent_account": "Tax Assets - %s" % abbr, "company": company,
 		"group_or_ledger": "Ledger"})
@@ -69,64 +72,67 @@
 		"naming_series": "BILL", "posting_date": nowdate(),
 		"company": company, "fiscal_year": webnotes.conn.get_default("fiscal_year"), 
 		"currency": webnotes.conn.get_default("currency"), "conversion_rate": 1,
-		'grand_total_import': 0
+		'net_total': 1250.00, 'grand_total': 1512.30, 'grand_total_import': 1512.30, 
 	},
 	# items
 	{
 		"doctype": "Purchase Invoice Item", 
-		"item_code": "Home Desktop 100", "qty": 10, "import_rate": 50,
-		"parentfield": "entries", 
-		"uom": "Nos", "item_tax_rate": json.dumps({"Excise Duty - %s" % abbr: 10})
+		"item_code": "Home Desktop 100", "qty": 10, "import_rate": 50, "rate": 50,
+		"amount": 500, "import_amount": 500, "parentfield": "entries", 
+		"uom": "Nos", "item_tax_rate": json.dumps({"Excise Duty - %s" % abbr: 10}),
+		"expense_head": "Cost for Goods Sold - %s" % abbr, 
+		"cost_center": "Default Cost Center - %s" % abbr
 	},
 	{
 		"doctype": "Purchase Invoice Item", 
-		"item_code": "Home Desktop 200", "qty": 5, "import_rate": 150,
-		"parentfield": "entries", 
-		"uom": "Nos"
+		"item_code": "Home Desktop 200", "qty": 5, "import_rate": 150, "rate": 150, 
+		"amount": 750, "import_amount": 750, "parentfield": "entries", "uom": "Nos", 
+		"expense_head": "Cost for Goods Sold - %s" % abbr, 
+		"cost_center": "Default Cost Center - %s" % abbr
 	},
 	# taxes
 	{
 		"doctype": "Purchase Taxes and Charges", "charge_type": "Actual",
-		"account_head": "Shipping Charges - %s" % abbr, "rate": 100, 
-		"category": "Valuation and Total", "parentfield": "purchase_tax_details",
+		"account_head": "Shipping Charges - %s" % abbr, "rate": 100, "tax_amount": 100, 
+		"category": "Valuation and Total", "parentfield": "other_charges",
 		"cost_center": "Default Cost Center - %s" % abbr
 	},
 	{
 		"doctype": "Purchase Taxes and Charges", "charge_type": "On Net Total",
-		"account_head": "Customs Duty - %s" % abbr, "rate": 10,
-		"category": "Valuation", "parentfield": "purchase_tax_details",
+		"account_head": "Customs Duty - %s" % abbr, "rate": 10, "tax_amount": 125.00,
+		"category": "Valuation", "parentfield": "other_charges",
 		"cost_center": "Default Cost Center - %s" % abbr
 	},
 	{
 		"doctype": "Purchase Taxes and Charges", "charge_type": "On Net Total",
-		"account_head": "Excise Duty - %s" % abbr, "rate": 12,
-		"category": "Total", "parentfield": "purchase_tax_details"
+		"account_head": "Excise Duty - %s" % abbr, "rate": 12, "tax_amount": 140.00, 
+		"category": "Total", "parentfield": "other_charges"
 	},
 	{
 		"doctype": "Purchase Taxes and Charges", "charge_type": "On Previous Row Amount",
-		"account_head": "Education Cess - %s" % abbr, "rate": 2, "row_id": 3,
-		"category": "Total", "parentfield": "purchase_tax_details"
+		"account_head": "Education Cess - %s" % abbr, "rate": 2, "row_id": 3, "tax_amount": 2.80,
+		"category": "Total", "parentfield": "other_charges"
 	},
 	{
 		"doctype": "Purchase Taxes and Charges", "charge_type": "On Previous Row Amount",
-		"account_head": "S&H Education Cess - %s" % abbr, "rate": 1, "row_id": 3,
-		"category": "Total", "parentfield": "purchase_tax_details"
+		"account_head": "S&H Education Cess - %s" % abbr, "rate": 1, "row_id": 3, 
+		"tax_amount": 1.4, "category": "Total", "parentfield": "other_charges"
 	},
 	{
 		"doctype": "Purchase Taxes and Charges", "charge_type": "On Previous Row Total",
-		"account_head": "CST - %s" % abbr, "rate": 2, "row_id": 5,
-		"category": "Total", "parentfield": "purchase_tax_details",
+		"account_head": "CST - %s" % abbr, "rate": 2, "row_id": 5, "tax_amount": 29.88, 
+		"category": "Total", "parentfield": "other_charges",
 		"cost_center": "Default Cost Center - %s" % abbr
 	},
 	{
 		"doctype": "Purchase Taxes and Charges", "charge_type": "On Net Total",
-		"account_head": "VAT - Test - %s" % abbr, "rate": 12.5,
-		"category": "Total", "parentfield": "purchase_tax_details"
+		"account_head": "VAT - Test - %s" % abbr, "rate": 12.5, "tax_amount": 156.25, 
+		"category": "Total", "parentfield": "other_charges"
 	},
 	{
 		"doctype": "Purchase Taxes and Charges", "charge_type": "On Previous Row Total",
-		"account_head": "Discount - %s" % abbr, "rate": -10, "row_id": 7,
-		"category": "Total", "parentfield": "purchase_tax_details",
+		"account_head": "Discount - %s" % abbr, "rate": -10, "row_id": 7, "tax_amount": -168.03, 
+		"category": "Total", "parentfield": "other_charges",
 		"cost_center": "Default Cost Center - %s" % abbr
 	},
 ]
@@ -135,125 +141,18 @@
 	def setUp(self):
 		webnotes.conn.begin()
 		load_data()
-		webnotes.conn.set_value("Global Defaults", None, "automatic_inventory_accounting", 1)
-
-	def test_purchase_invoice(self):
-		from webnotes.model.doclist import DocList
-		controller = webnotes.insert(DocList(purchase_invoice_doclist))
-		controller.load_from_db()
-		
-		from controllers.tax_controller import TaxController
-		tax_controller = TaxController(controller.doc, controller.doclist)
-		tax_controller.item_table_field = "entries"
-		tax_controller.calculate_taxes_and_totals()
-		
-		controller.doc = tax_controller.doc
-		controller.doclist = tax_controller.doclist
-		
-		controller.save()
-		controller.load_from_db()
-		dl = controller.doclist
-
-		# test net total
-		self.assertEqual(dl[0].net_total, 1250)
-		
-		# test tax amounts and totals
-		expected_values = [
-			["Shipping Charges - %s" % abbr, 100, 1350],
-			["Customs Duty - %s" % abbr, 125, 1350],
-			["Excise Duty - %s" % abbr, 140, 1490],
-			["Education Cess - %s" % abbr, 2.8, 1492.8],
-			["S&H Education Cess - %s" % abbr, 1.4, 1494.2],
-			["CST - %s" % abbr, 29.88, 1524.08],
-			["VAT - Test - %s" % abbr, 156.25, 1680.33],
-			["Discount - %s" % abbr, -168.03, 1512.30],
-		]		
-		for i, tax in enumerate(dl.get({"parentfield": "purchase_tax_details"})):
-			# print tax.account_head, tax.tax_amount, tax.total
-			self.assertEqual(tax.account_head, expected_values[i][0])
-			self.assertEqual(tax.tax_amount, expected_values[i][1])
-			self.assertEqual(tax.total, expected_values[i][2])
-		
-		# test item tax amount
-		expected_values = [
-			["Home Desktop 100", 90],
-			["Home Desktop 200", 135]
-		]
-		for i, item in enumerate(dl.get({"parentfield": "purchase_invoice_items"})):
-			self.assertEqual(item.item_code, expected_values[i][0])
-			self.assertEqual(item.item_tax_amount, expected_values[i][1])
+		# webnotes.conn.set_value("Global Defaults", None, "automatic_inventory_accounting", 1)
 			
-	def test_purchase_invoice_having_zero_amount_items(self):
-		from webnotes.model.doclist import DocList
-		sample_purchase_invoice_doclist = [] + purchase_invoice_doclist
-		
-		# set rate and amount as 0
-		sample_purchase_invoice_doclist[1]["import_rate"] = 0
-		sample_purchase_invoice_doclist[2]["import_rate"] = 0
-		
-		
-		controller = webnotes.insert(DocList(sample_purchase_invoice_doclist))
-		controller.load_from_db()
-		
-		from controllers.tax_controller import TaxController
-		tax_controller = TaxController(controller.doc, controller.doclist)
-		tax_controller.item_table_field = "entries"
-		tax_controller.calculate_taxes_and_totals()
-		
-		controller.doc = tax_controller.doc
-		controller.doclist = tax_controller.doclist
-		
-		controller.save()
-		controller.load_from_db()
-		dl = controller.doclist
-		
-		# test net total
-		self.assertEqual(dl[0].net_total, 0)
-		
-		# test tax amounts and totals
-		expected_values = [
-			["Shipping Charges - %s" % abbr, 100, 100],
-			["Customs Duty - %s" % abbr, 0, 100],
-			["Excise Duty - %s" % abbr, 0, 100],
-			["Education Cess - %s" % abbr, 0, 100],
-			["S&H Education Cess - %s" % abbr, 0, 100],
-			["CST - %s" % abbr, 2, 102],
-			["VAT - Test - %s" % abbr, 0, 102],
-			["Discount - %s" % abbr, -10.2, 91.8],
-		]
-		for i, tax in enumerate(dl.get({"parentfield": "purchase_tax_details"})):
-			# print tax.account_head, tax.tax_amount, tax.total
-			self.assertEqual(tax.account_head, expected_values[i][0])
-			self.assertEqual(tax.tax_amount, expected_values[i][1])
-			self.assertEqual(tax.total, expected_values[i][2])
-		
-		# test item tax amount
-		expected_values = [
-			["Home Desktop 100", 0],
-			["Home Desktop 200", 0]
-		]
-		for i, item in enumerate(dl.get({"parentfield": "purchase_invoice_items"})):
-			self.assertEqual(item.item_code, expected_values[i][0])
-			self.assertEqual(item.item_tax_amount, expected_values[i][1])
-		
-	def atest_gl_entries(self):
+	def test_gl_entries(self):
 		from webnotes.model.doclist import DocList
 		controller = webnotes.insert(DocList(purchase_invoice_doclist))
-		
-		from controllers.tax_controller import TaxController
-		tax_controller = TaxController(controller.doc, controller.doclist)
-		tax_controller.item_table_field = "entries"
-		tax_controller.calculate_taxes_and_totals()
-
-		controller.doc = tax_controller.doc
-		controller.doclist = tax_controller.doclist
-
 		controller.submit()
 		controller.load_from_db()
 		dl = controller.doclist
 		
-		expected_values = {
+		expected_gl_entries = {
 			"East Wind Inc. - %s" % abbr : [0, 1512.30],
+			"Cost for Goods Sold - %s" % abbr : [1250, 0],
 			"Shipping Charges - %s" % abbr : [100, 0],
 			"Excise Duty - %s" % abbr : [140, 0],
 			"Education Cess - %s" % abbr : [2.8, 0],
@@ -261,14 +160,111 @@
 			"CST - %s" % abbr : [29.88, 0],
 			"VAT - Test - %s" % abbr : [156.25, 0],
 			"Discount - %s" % abbr : [0, 168.03],
-			"Stock Received But Not Billed - %s" % abbr : [1475, 0],
-			"Expenses Included In Valuation - %s" % abbr : [0, 225]
 		}
 		gl_entries = webnotes.conn.sql("""select account, debit, credit from `tabGL Entry`
 			where voucher_type = 'Purchase Invoice' and voucher_no = %s""", dl[0].name, as_dict=1)
 		for d in gl_entries:
-			self.assertEqual(d["debit"], expected_values.get(d['account'])[0])
-			self.assertEqual(d["credit"], expected_values.get(d['account'])[1])
+			self.assertEqual([d.debit, d.credit], expected_gl_entries.get(d.account))
+
+	# def test_purchase_invoice(self):
+	# 	from webnotes.model.doclist import DocList
+	# 	controller = webnotes.insert(DocList(purchase_invoice_doclist))
+	# 	controller.load_from_db()
+	# 	
+	# 	from controllers.tax_controller import TaxController
+	# 	tax_controller = TaxController(controller.doc, controller.doclist)
+	# 	tax_controller.item_table_field = "entries"
+	# 	tax_controller.calculate_taxes_and_totals()
+	# 	
+	# 	controller.doc = tax_controller.doc
+	# 	controller.doclist = tax_controller.doclist
+	# 	
+	# 	controller.save()
+	# 	controller.load_from_db()
+	# 	dl = controller.doclist
+	# 
+	# 	# test net total
+	# 	self.assertEqual(dl[0].net_total, 1250)
+	# 	
+	# 	# test tax amounts and totals
+	# 	expected_values = [
+	# 		["Shipping Charges - %s" % abbr, 100, 1350],
+	# 		["Customs Duty - %s" % abbr, 125, 1350],
+	# 		["Excise Duty - %s" % abbr, 140, 1490],
+	# 		["Education Cess - %s" % abbr, 2.8, 1492.8],
+	# 		["S&H Education Cess - %s" % abbr, 1.4, 1494.2],
+	# 		["CST - %s" % abbr, 29.88, 1524.08],
+	# 		["VAT - Test - %s" % abbr, 156.25, 1680.33],
+	# 		["Discount - %s" % abbr, -168.03, 1512.30],
+	# 	]		
+	# 	for i, tax in enumerate(dl.get({"parentfield": "other_charges"})):
+	# 		self.assertEqual(tax.account_head, expected_values[i][0])
+	# 		self.assertEqual(tax.tax_amount, expected_values[i][1])
+	# 		self.assertEqual(tax.total, expected_values[i][2])
+	# 	
+	# 	# test item tax amount
+	# 	expected_values = [
+	# 		["Home Desktop 100", 90],
+	# 		["Home Desktop 200", 135]
+	# 	]
+	# 	for i, item in enumerate(dl.get({"parentfield": "purchase_invoice_items"})):
+	# 		self.assertEqual(item.item_code, expected_values[i][0])
+	# 		self.assertEqual(item.item_tax_amount, expected_values[i][1])
+	# 
+	# 		
+	# def test_purchase_invoice_having_zero_amount_items(self):
+	# 	from webnotes.model.doclist import DocList
+	# 	sample_purchase_invoice_doclist = [] + purchase_invoice_doclist
+	# 	
+	# 	# set rate and amount as 0
+	# 	sample_purchase_invoice_doclist[1]["import_rate"] = 0
+	# 	sample_purchase_invoice_doclist[2]["import_rate"] = 0
+	# 	
+	# 	
+	# 	controller = webnotes.insert(DocList(sample_purchase_invoice_doclist))
+	# 	controller.load_from_db()
+	# 	
+	# 	from controllers.tax_controller import TaxController
+	# 	tax_controller = TaxController(controller.doc, controller.doclist)
+	# 	tax_controller.item_table_field = "entries"
+	# 	tax_controller.calculate_taxes_and_totals()
+	# 	
+	# 	controller.doc = tax_controller.doc
+	# 	controller.doclist = tax_controller.doclist
+	# 	
+	# 	controller.save()
+	# 	controller.load_from_db()
+	# 	dl = controller.doclist
+	# 	
+	# 	# test net total
+	# 	self.assertEqual(dl[0].net_total, 0)
+	# 	
+	# 	# test tax amounts and totals
+	# 	expected_values = [
+	# 		["Shipping Charges - %s" % abbr, 100, 100],
+	# 		["Customs Duty - %s" % abbr, 0, 100],
+	# 		["Excise Duty - %s" % abbr, 0, 100],
+	# 		["Education Cess - %s" % abbr, 0, 100],
+	# 		["S&H Education Cess - %s" % abbr, 0, 100],
+	# 		["CST - %s" % abbr, 2, 102],
+	# 		["VAT - Test - %s" % abbr, 0, 102],
+	# 		["Discount - %s" % abbr, -10.2, 91.8],
+	# 	]
+	# 	for i, tax in enumerate(dl.get({"parentfield": "other_charges"})):
+	# 		# print tax.account_head, tax.tax_amount, tax.total
+	# 		self.assertEqual(tax.account_head, expected_values[i][0])
+	# 		self.assertEqual(tax.tax_amount, expected_values[i][1])
+	# 		self.assertEqual(tax.total, expected_values[i][2])
+	# 	
+	# 	# test item tax amount
+	# 	expected_values = [
+	# 		["Home Desktop 100", 0],
+	# 		["Home Desktop 200", 0]
+	# 	]
+	# 	for i, item in enumerate(dl.get({"parentfield": "purchase_invoice_items"})):
+	# 		self.assertEqual(item.item_code, expected_values[i][0])
+	# 		self.assertEqual(item.item_tax_amount, expected_values[i][1])
+
 			
 		
 	def tearDown(self):
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index 6171d5e..7cb165b 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -50,13 +50,15 @@
 		sales_com_obj.check_stop_sales_order(self)
 		sales_com_obj.check_active_sales_items(self)
 		sales_com_obj.check_conversion_rate(self)
-		sales_com_obj.validate_max_discount(self, 'entries')	 #verify whether rate is not greater than tolerance
-		sales_com_obj.get_allocated_sum(self)	# this is to verify that the allocated % of sales persons is 100%
-		sales_com_obj.validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date')
+		sales_com_obj.validate_max_discount(self, 'entries')
+		sales_com_obj.get_allocated_sum(self)
+		sales_com_obj.validate_fiscal_year(self.doc.fiscal_year, 
+			self.doc.posting_date,'Posting Date')
 		self.validate_customer()
 		self.validate_customer_account()
 		self.validate_debit_acc()
 		self.validate_fixed_asset_account()
+		self.clear_unallocated_advances("Sales Invoice Advance", "advance_adjustment_details")
 		self.add_remarks()
 		if cint(self.doc.is_pos):
 			self.validate_pos()
@@ -71,7 +73,6 @@
 		if not self.doc.is_opening:
 			self.doc.is_opening = 'No'
 		self.set_aging_date()
-		self.clear_advances()
 		self.set_against_income_account()
 		self.validate_c_form()
 		self.validate_recurring_invoice()
@@ -90,12 +91,13 @@
 		else:
 			# Check for Approving Authority
 			if not self.doc.recurring_id:
-				get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self)
+				get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, 
+				 	self.doc.company, self.doc.grand_total, self)
 
 		self.check_prev_docstatus()
 		get_obj("Sales Common").update_prevdoc_detail(1,self)
 		
-		# this sequence because outstanding may get -ve		
+		# this sequence because outstanding may get -ve
 		self.make_gl_entries()
 
 		if not cint(self.doc.is_pos) == 1:
@@ -194,16 +196,17 @@
 
 	def get_cust_and_due_date(self):
 		"""Set Due Date = Posting Date + Credit Days"""
-		credit_days = 0
-		if self.doc.debit_to:
-			credit_days = webnotes.conn.sql("select credit_days from `tabAccount` where name='%s' and docstatus != 2" % self.doc.debit_to)
-			credit_days = credit_days and cint(credit_days[0][0]) or 0
-		if self.doc.company and not credit_days:
-			credit_days = webnotes.conn.sql("select credit_days from `tabCompany` where name='%s'" % self.doc.company)
-			credit_days = credit_days and cint(credit_days[0][0]) or 0
-		# Customer has higher priority than company
-		# i.e.if not entered in customer will take credit days from company
-		self.doc.due_date = add_days(cstr(self.doc.posting_date), credit_days)
+		if self.doc.posting_date:
+			credit_days = 0
+			if self.doc.debit_to:
+				credit_days = webnotes.conn.get_value("Account", self.doc.debit_to, "credit_days")
+			if self.doc.company and not credit_days:
+				credit_days = webnotes.conn.get_value("Company", self.doc.company, "credit_days")
+				
+			if credit_days:
+				self.doc.due_date = add_days(self.doc.posting_date, credit_days)
+			else:
+				self.doc.due_date = self.doc.posting_date
 		
 		if self.doc.debit_to:
 			self.doc.customer = webnotes.conn.get_value('Account',self.doc.debit_to,'master_name')
@@ -211,17 +214,25 @@
 
 	def pull_details(self):
 		"""Pull Details of Delivery Note or Sales Order Selected"""
-		# Delivery Note
 		if self.doc.delivery_note_main:
 			self.validate_prev_docname('delivery note')
 			self.doclist = self.doc.clear_table(self.doclist,'other_charges')			
-			self.doclist = get_obj('DocType Mapper', 'Delivery Note-Sales Invoice').dt_map('Delivery Note', 'Sales Invoice', self.doc.delivery_note_main, self.doc, self.doclist, "[['Delivery Note', 'Sales Invoice'],['Delivery Note Item', 'Sales Invoice Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]")			
+			self.doclist = get_obj('DocType Mapper', 'Delivery Note-Sales Invoice').dt_map(
+				'Delivery Note', 'Sales Invoice', self.doc.delivery_note_main, self.doc, 
+				self.doclist, """[['Delivery Note', 'Sales Invoice'],
+					['Delivery Note Item', 'Sales Invoice Item'],
+					['Sales Taxes and Charges','Sales Taxes and Charges'],
+					['Sales Team','Sales Team']]""")								
 			self.get_income_account('entries')
-		# Sales Order
+			
 		elif self.doc.sales_order_main:
 			self.validate_prev_docname('sales order')
 			self.doclist = self.doc.clear_table(self.doclist,'other_charges')
-			get_obj('DocType Mapper', 'Sales Order-Sales Invoice').dt_map('Sales Order', 'Sales Invoice', self.doc.sales_order_main, self.doc, self.doclist, "[['Sales Order', 'Sales Invoice'],['Sales Order Item', 'Sales Invoice Item'],['Sales Taxes and Charges','Sales Taxes and Charges'], ['Sales Team', 'Sales Team']]")
+			get_obj('DocType Mapper', 'Sales Order-Sales Invoice').dt_map('Sales Order', 
+				'Sales Invoice', self.doc.sales_order_main, self.doc, self.doclist, 
+				"""[['Sales Order', 'Sales Invoice'],['Sales Order Item', 'Sales Invoice Item'], 
+				['Sales Taxes and Charges','Sales Taxes and Charges'], 
+				['Sales Team', 'Sales Team']]""")
 			self.get_income_account('entries')
 			
 		ret = self.get_debit_to()
@@ -238,9 +249,11 @@
 	def get_income_account(self,doctype):		
 		for d in getlist(self.doclist, doctype):			
 			if d.item_code:
-				item = webnotes.conn.sql("select default_income_account, default_sales_cost_center from tabItem where name = '%s'" %(d.item_code), as_dict=1)
-				d.income_account = item and item[0]['default_income_account'] or ''
-				d.cost_center = item and item[0]['default_sales_cost_center'] or ''				
+				item = webnotes.conn.get_value("Item", d.item_code, 
+					["default_income_account", "default_sales_cost_center"])
+					
+				d.income_account = item['default_income_account'] or ""
+				d.cost_center = item['default_sales_cost_center'] or ""			
 
 
 	def get_item_details(self, args=None):
@@ -319,8 +332,9 @@
 
 
 	def get_advances(self):
-		self.doclist = get_obj('GL Control').get_advances(self, self.doc.debit_to, 'Sales Invoice Advance', 'advance_adjustment_details', 'credit')
-
+		super(DocType, self).get_advances(self.doc.debit_to, 
+			"Sales Invoice Advance", "advance_adjustment_details", "credit")
+		
 	def get_company_abbr(self):
 		return webnotes.conn.sql("select abbr from tabCompany where name=%s", self.doc.company)[0][0]
 		
@@ -361,7 +375,8 @@
 				lst.append(args)
 		
 		if lst:
-			get_obj('GL Control').reconcile_against_document(lst)
+			from accounts.utils import reconcile_against_document
+			reconcile_against_document(lst)
 	
 	
 	def validate_customer(self):
@@ -411,10 +426,6 @@
 				msgprint("Please select income head with account type 'Fixed Asset Account' as Item %s is an asset item" % d.item_code)
 				raise Exception
 
-	def clear_advances(self):
-		get_obj('GL Control').clear_advances(self, 'Sales Invoice Advance','advance_adjustment_details')
-
-
 	def set_aging_date(self):
 		if self.doc.is_opening != 'Yes':
 			self.doc.aging_date = self.doc.posting_date
@@ -620,10 +631,120 @@
 
 
 	def make_gl_entries(self, is_cancel=0):
-		mapper = self.doc.is_pos and self.doc.write_off_account and 'POS with write off' or self.doc.is_pos and not self.doc.write_off_account and 'POS' or ''
-		update_outstanding = self.doc.is_pos and self.doc.write_off_account and 'No' or 'Yes'
-		get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist,cancel = is_cancel, use_mapper = mapper, update_outstanding = update_outstanding, merge_entries = cint(self.doc.is_pos) != 1 and 1 or 0)
+		from accounts.general_ledger import make_gl_entries
+		gl_entries = []
+		auto_inventory_accounting = webnotes.conn.get_value("Global Defaults", None, 
+		 	"automatic_inventory_accounting")
+		abbr = self.get_company_abbr()
 		
+		# parent's gl entry
+		gl_entries.append(
+			self.get_gl_dict({
+				"account": self.doc.debit_to,
+				"against": self.doc.against_income_account,
+				"debit": self.doc.grand_total,
+				"remarks": self.doc.remarks,
+				"against_voucher": self.doc.name,
+				"against_voucher_type": self.doc.doctype,
+			}, is_cancel)
+		)
+	
+		# tax table gl entries
+		for tax in self.doclist.get({"parentfield": "other_charges"}):
+			gl_entries.append(
+				self.get_gl_dict({
+					"account": tax.account_head,
+					"against": self.doc.debit_to,
+					"credit": flt(tax.tax_amount),
+					"remarks": self.doc.remarks,
+					"cost_center": tax.cost_center_other_charges
+				}, is_cancel)
+			)
+		
+		# item gl entries
+		for item in getlist(self.doclist, 'entries'):
+			# income account gl entries
+			gl_entries.append(
+				self.get_gl_dict({
+					"account": item.income_account,
+					"against": self.doc.debit_to,
+					"credit": item.amount,
+					"remarks": self.doc.remarks,
+					"cost_center": item.cost_center
+				}, is_cancel)
+			)
+			# if auto inventory accounting enabled and stock item, 
+			# then do stock related gl entries
+			if auto_inventory_accounting and item.delivery_note and \
+					webnotes.conn.get_value("Item", item.item_code, "is_stock_item")=="Yes":
+				# to-do
+				purchase_rate = webnotes.conn.get_value("Delivery Note Item", 
+					item.dn_detail, "purchase_rate")
+				valuation_amount =  purchase_rate * item.qty
+				# expense account gl entries
+				gl_entries.append(
+					self.get_gl_dict({
+						"account": item.expense_account,
+						"against": "Stock Delivered But Not Billed - %s" % (abbr,),
+						"debit": valuation_amount,
+						"remarks": self.doc.remarks or "Accounting Entry for Stock"
+					}, is_cancel)
+				)
+				gl_entries.append(
+					self.get_gl_dict({
+						"account": "Stock Delivered But Not Billed - %s" % (abbr,),
+						"against": item.expense_account,
+						"credit": valuation_amount,
+						"remarks": self.doc.remarks or "Accounting Entry for Stock"
+					}, is_cancel)
+				)
+		if self.doc.is_pos and self.doc.cash_bank_account and self.doc.paid_amount:
+			# POS, make payment entries
+			gl_entries.append(
+				self.get_gl_dict({
+					"account": self.doc.debit_to,
+					"against": self.doc.cash_bank_account,
+					"credit": self.doc.paid_amount,
+					"remarks": self.doc.remarks,
+					"against_voucher": self.doc.name,
+					"against_voucher_type": self.doc.doctype,
+				}, is_cancel)
+			)
+			gl_entries.append(
+				self.get_gl_dict({
+					"account": self.doc.cash_bank_account,
+					"against": self.doc.debit_to,
+					"debit": self.doc.paid_amount,
+					"remarks": self.doc.remarks,
+				}, is_cancel)
+			)
+			# write off entries, applicable if only pos
+			if self.doc.write_off_account and self.doc.write_off_amount:
+				gl_entries.append(
+					self.get_gl_dict({
+						"account": self.doc.debit_to,
+						"against": self.doc.write_off_account,
+						"credit": self.doc.write_off_amount,
+						"remarks": self.doc.remarks,
+						"against_voucher": self.doc.name,
+						"against_voucher_type": self.doc.doctype,
+					}, is_cancel)
+				)
+				gl_entries.append(
+					self.get_gl_dict({
+						"account": self.doc.write_off_account,
+						"against": self.doc.debit_to,
+						"debit": self.doc.write_off_amount,
+						"remarks": self.doc.remarks,
+						"cost_center": self.doc.write_off_cost_center
+					}, is_cancel)
+				)
+		
+		
+		update_outstanding = self.doc.is_pos and self.doc.write_off_account and 'No' or 'Yes'
+		merge_entries=cint(self.doc.is_pos)!=1 and 1 or 0
+		make_gl_entries(gl_entries, cancel=is_cancel, 
+			update_outstanding=update_outstanding, merge_entries=merge_entries)
 
 	def update_c_form(self):
 		"""Update amended id in C-form"""
diff --git a/accounts/doctype/sales_invoice/test_sales_invoice.py b/accounts/doctype/sales_invoice/test_sales_invoice.py
index fd91b9e..cf0fbda 100644
--- a/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -21,7 +21,6 @@
 import webnotes.model
 from webnotes.model.doclist import DocList
 from webnotes.utils import nowdate
-from accounts.utils import get_fiscal_year
 
 from stock.doctype.purchase_receipt import test_purchase_receipt
 
@@ -40,7 +39,11 @@
 	webnotes.insert({"doctype": "Customer", "customer_name": "West Wind Inc.",
 		"customer_type": "Company", "territory": "Default",
 		"customer_group": "Default Customer Group", "company": company,
-		"credit_days": 0, "credit_limit": 0})
+		"credit_days": 50, "credit_limit": 0})
+	
+	webnotes.insert({"doctype": "Account", "account_name": "Sales",
+		"parent_account": "Income - %s" % abbr, "company": company,
+		"group_or_ledger": "Ledger"})
 	
 	webnotes.insert({"doctype": "Account", "account_name": "Excise Duty",
 		"parent_account": "Tax Assets - %s" % abbr, "company": company,
@@ -82,64 +85,67 @@
 		"company": company, "fiscal_year": webnotes.conn.get_default("fiscal_year"), 
 		"currency": webnotes.conn.get_default("currency"), "conversion_rate": 1.0,
 		"price_list_currency": webnotes.conn.get_default("currency"),
-		"plc_conversion_rate": 1.0,
-		"grand_total_export": 0
+		"plc_conversion_rate": 1.0, "net_total": 1250, "grand_total": 1627.05, 
+		"grand_total_export": 1627.05
 	},
 	# items
 	{
 		"doctype": "Sales Invoice Item", "warehouse": "Default Warehouse",
-		"item_code": "Home Desktop 100", "qty": 10, "export_rate": 50,
-		"parentfield": "sales_invoice_items",
-		"uom": "Nos", "item_tax_rate": json.dumps({"Excise Duty - %s" % abbr: 10})
+		"item_code": "Home Desktop 100", "qty": 10, "basic_rate": 50, "amount": 500, 
+		"parentfield": "entries", "so_detail": None, "dn_detail": None,
+		"uom": "Nos", "item_tax_rate": json.dumps({"Excise Duty - %s" % abbr: 10}),
+		"income_account": "Sales - %s" % abbr, 
+		"cost_center": "Default Cost Center - %s" % abbr
 	},
 	{
 		"doctype": "Sales Invoice Item", "warehouse": "Default Warehouse",
-		"item_code": "Home Desktop 200", "qty": 5, "export_rate": 150,
-		"parentfield": "sales_invoice_items",
-		"uom": "Nos"
+		"item_code": "Home Desktop 200", "qty": 5, "basic_rate": 150, "amount": 750,
+		"so_detail": None, "dn_detail": None, 
+		"parentfield": "entries", "uom": "Nos", "income_account": "Sales - %s" % abbr, 
+		"cost_center": "Default Cost Center - %s" % abbr
 	},
 	# taxes
 	{
 		"doctype": "Sales Taxes and Charges", "charge_type": "Actual",
-		"account_head": "Shipping Charges - %s" % abbr, "rate": 100, 
+		"account_head": "Shipping Charges - %s" % abbr, "rate": 100, "tax_amount": 100,
 		"parentfield": "other_charges",
 		"cost_center_other_charges": "Default Cost Center - %s" % abbr
 	},
 	{
 		"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
-		"account_head": "Customs Duty - %s" % abbr, "rate": 10,
+		"account_head": "Customs Duty - %s" % abbr, "rate": 10, "tax_amount": 125,
 		"parentfield": "other_charges",
 		"cost_center_other_charges": "Default Cost Center - %s" % abbr
 	},
 	{
 		"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
-		"account_head": "Excise Duty - %s" % abbr, "rate": 12,
+		"account_head": "Excise Duty - %s" % abbr, "rate": 12, "tax_amount": 140,
 		"parentfield": "other_charges"
 	},
 	{
 		"doctype": "Sales Taxes and Charges", "charge_type": "On Previous Row Amount",
-		"account_head": "Education Cess - %s" % abbr, "rate": 2, "row_id": 3,
+		"account_head": "Education Cess - %s" % abbr, "rate": 2, "row_id": 3, "tax_amount": 2.8,
 		"parentfield": "other_charges"
 	},
 	{
 		"doctype": "Sales Taxes and Charges", "charge_type": "On Previous Row Amount",
-		"account_head": "S&H Education Cess - %s" % abbr, "rate": 1, "row_id": 3,
-		"parentfield": "other_charges"
+		"account_head": "S&H Education Cess - %s" % abbr, "rate": 1, "row_id": 3, 
+		"tax_amount": 1.4, "parentfield": "other_charges"
 	},
 	{
 		"doctype": "Sales Taxes and Charges", "charge_type": "On Previous Row Total",
-		"account_head": "CST - %s" % abbr, "rate": 2, "row_id": 5,
+		"account_head": "CST - %s" % abbr, "rate": 2, "row_id": 5, "tax_amount": 32.38,
 		"parentfield": "other_charges",
 		"cost_center_other_charges": "Default Cost Center - %s" % abbr
 	},
 	{
 		"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
-		"account_head": "VAT - Test - %s" % abbr, "rate": 12.5,
+		"account_head": "VAT - Test - %s" % abbr, "rate": 12.5, "tax_amount": 156.25,
 		"parentfield": "other_charges"
 	},
 	{
 		"doctype": "Sales Taxes and Charges", "charge_type": "On Previous Row Total",
-		"account_head": "adj_rate - %s" % abbr, "rate": -10, "row_id": 7,
+		"account_head": "adj_rate - %s" % abbr, "rate": -10, "row_id": 7, "tax_amount": -180.78,
 		"parentfield": "other_charges",
 		"cost_center_other_charges": "Default Cost Center - %s" % abbr
 	},
@@ -149,23 +155,12 @@
 	def setUp(self):
 		webnotes.conn.begin()
 		load_data()
-		webnotes.conn.set_value("Global Defaults", None, "automatic_inventory_accounting", 1)
+		#webnotes.conn.set_value("Global Defaults", None, "automatic_inventory_accounting", 1)
 
 	def test_sales_invoice(self):
-		from webnotes.model.doclist import DocList
 		doclist = [] + [d.copy() for d in sales_invoice_doclist]
 		controller = webnotes.insert(DocList(doclist))
-		controller.load_from_db()
-		
-		from controllers.tax_controller import TaxController
-		tax_controller = TaxController(controller.doc, controller.doclist)
-		tax_controller.item_table_field = "entries"
-		tax_controller.calculate_taxes_and_totals()
-		
-		controller.doc = tax_controller.doc
-		controller.doclist = tax_controller.doclist
-		
-		controller.save()
+		controller.submit()
 		controller.load_from_db()
 		dl = controller.doclist
 
@@ -176,24 +171,24 @@
 		expected_values = [
 			{
 				"item_code": "Home Desktop 100",
-				"ref_rate": 50,
-				"adj_rate": 0,
-				"export_amount": 500,
-				"base_ref_rate": 50,
+				# "ref_rate": 50,
+				# "adj_rate": 0,
+				# "export_amount": 500,
+				# "base_ref_rate": 50,
 				"basic_rate": 50,
 				"amount": 500
 			},
 			{
 				"item_code": "Home Desktop 200",
-				"ref_rate": 150,
-				"adj_rate": 0,
-				"export_amount": 750,
-				"base_ref_rate": 150,
+				# "ref_rate": 150,
+				# "adj_rate": 0,
+				# "export_amount": 750,
+				# "base_ref_rate": 150,
 				"basic_rate": 150,
 				"amount": 750
 			},
 		]
-		for i, item in enumerate(dl.get({"parentfield": "sales_invoice_items"})):
+		for i, item in enumerate(dl.get({"parentfield": "entries"})):
 			for key, val in expected_values[i].items():
 				self.assertEqual(item.fields.get(key), val)
 		
@@ -212,323 +207,342 @@
 			# print tax.account_head, tax.tax_amount, tax.total
 			self.assertEqual(tax.account_head, expected_values[i][0])
 			self.assertEqual(tax.tax_amount, expected_values[i][1])
-			self.assertEqual(tax.total, expected_values[i][2])
+			# self.assertEqual(tax.total, expected_values[i][2])
 			
-	def test_inclusive_rate_validations(self):
-		doclist = [] + [d.copy() for d in sales_invoice_doclist]
-		doclist[1]["export_rate"] = 62.5
-		doclist[2]["export_rate"] = 191
-		for i in [3, 5, 6, 7, 8, 9]:
-			doclist[i]["included_in_print_rate"] = 1
+		expected_gl_entries = {
+			"West Wind Inc. - %s" % abbr : [1627.05, 0.0],
+			"Sales - %s" % abbr: [0.0, 1250.00],
+			"Shipping Charges - %s" % abbr: [0.0, 100],
+			"Customs Duty - %s" % abbr: [0, 125.0],
+			"Excise Duty - %s" % abbr: [0, 140],
+			"Education Cess - %s" % abbr: [0, 2.8],
+			"S&H Education Cess - %s" % abbr: [0, 1.4],
+			"CST - %s" % abbr: [0, 32.38],
+			"VAT - Test - %s" % abbr: [0, 156.25],
+			"adj_rate - %s" % abbr: [180.78, 0],
+		}
 		
-		# tax type "Actual" cannot be inclusive
-		self.assertRaises(webnotes.ValidationError, webnotes.insert,
-			DocList(doclist))
+		gl_entries = webnotes.conn.sql("""select account, debit, credit from `tabGL Entry`
+			where voucher_type = %s and voucher_no = %s""", 
+			(controller.doc.doctype, controller.doc.name), as_dict=1)
 		
-		doclist[3]["included_in_print_rate"] = 0
-		# taxes above included type 'On Previous Row Total' should also be included
-		self.assertRaises(webnotes.ValidationError, webnotes.insert,
-			DocList(doclist))
-	
-	def test_sales_invoice_with_inclusive_tax(self):
-		doclist = [
-			# parent
-			{
-				"doctype": "Sales Invoice", 
-				"debit_to": "West Wind Inc. - %s" % abbr,
-				"customer_name": "West Wind Inc.",
-				"naming_series": "INV", "posting_date": nowdate(),
-				"company": company,
-				"fiscal_year": webnotes.conn.get_default("fiscal_year"), 
-				"currency": webnotes.conn.get_default("currency"),
-				"price_list_currency": webnotes.conn.get_default("currency"),
-				"conversion_rate": 1.0, "plc_conversion_rate": 1.0,
-				"grand_total_export": 0
-			},
-			# items
-			{
-				"doctype": "Sales Invoice Item", "warehouse": "Default Warehouse",
-				"item_code": "Home Desktop 100", "qty": 10, "export_rate": 62.503,
-				"parentfield": "sales_invoice_items",
-				"uom": "Nos", "item_tax_rate": json.dumps({"Excise Duty - %s" % abbr: 10})
-			},
-			{
-				"doctype": "Sales Invoice Item", "warehouse": "Default Warehouse",
-				"item_code": "Home Desktop 200", "qty": 5, "export_rate": 190.6608,
-				"parentfield": "sales_invoice_items",
-				"uom": "Nos"
-			},
-			# taxes
-			{
-				"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
-				"account_head": "Excise Duty - %s" % abbr, "rate": 12,
-				"parentfield": "other_charges", "included_in_print_rate": 1
-			},
-			{
-				"doctype": "Sales Taxes and Charges",
-				"charge_type": "On Previous Row Amount",
-				"account_head": "Education Cess - %s" % abbr, "rate": 2, "row_id": 1,
-				"parentfield": "other_charges", "included_in_print_rate": 1
-			},
-			{
-				"doctype": "Sales Taxes and Charges",
-				"charge_type": "On Previous Row Amount",
-				"account_head": "S&H Education Cess - %s" % abbr, "rate": 1, "row_id": 1,
-				"parentfield": "other_charges", "included_in_print_rate": 1
-			},
-			{
-				"doctype": "Sales Taxes and Charges", 
-				"charge_type": "On Previous Row Total",
-				"account_head": "CST - %s" % abbr, "rate": 2, "row_id": 3,
-				"parentfield": "other_charges", "included_in_print_rate": 1,
-				"cost_center_other_charges": "Default Cost Center - %s" % abbr
-			},
-			{
-				"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
-				"account_head": "VAT - Test - %s" % abbr, "rate": 12.5,
-				"parentfield": "other_charges", "included_in_print_rate": 1
-			},
-			{
-				"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
-				"account_head": "Customs Duty - %s" % abbr, "rate": 10,
-				"parentfield": "other_charges",
-				"cost_center_other_charges": "Default Cost Center - %s" % abbr
-			},
-			{
-				"doctype": "Sales Taxes and Charges", "charge_type": "Actual",
-				"account_head": "Shipping Charges - %s" % abbr, "rate": 100, 
-				"parentfield": "other_charges",
-				"cost_center_other_charges": "Default Cost Center - %s" % abbr
-			},
-			{
-				"doctype": "Sales Taxes and Charges",
-				"charge_type": "On Previous Row Total",
-				"account_head": "adj_rate - %s" % abbr, "rate": -10, "row_id": 7,
-				"parentfield": "other_charges",
-				"cost_center_other_charges": "Default Cost Center - %s" % abbr
-			},
-		]
+		for gle in gl_entries:
+			self.assertEqual([gle.debit, gle.credit], expected_gl_entries[gle.account])
 		
-		controller = webnotes.insert(DocList(doclist))
-		controller.load_from_db()
-		
-		from controllers.tax_controller import TaxController
-		tax_controller = TaxController(controller.doc, controller.doclist)
-		tax_controller.item_table_field = "entries"
-		tax_controller.calculate_taxes_and_totals()
-		
-		controller.doc = tax_controller.doc
-		controller.doclist = tax_controller.doclist
-		
-		controller.save()
-		controller.load_from_db()
-		dl = controller.doclist
-
-		# test item values calculation
-		expected_values = [
-			{
-				"item_code": "Home Desktop 100",
-				"ref_rate": 62.503,
-				"adj_rate": 0,
-				"export_amount": 625.03,
-				"base_ref_rate": 50,
-				"basic_rate": 50,
-				"amount": 500
-			},
-			{
-				"item_code": "Home Desktop 200",
-				"ref_rate": 190.6608,
-				"adj_rate": 0,
-				"export_amount": 953.3,
-				"base_ref_rate": 150,
-				"basic_rate": 150,
-				"amount": 750
-			},
-		]
-		for i, item in enumerate(dl.get({"parentfield": "sales_invoice_items"})):
-			for key, val in expected_values[i].items():
-				self.assertEqual(item.fields.get(key), val)
-		
-		# test tax amounts and totals
-		expected_values = [
-			["Excise Duty - %s" % abbr, 140, 1390, 0, 1578.33],
-			["Education Cess - %s" % abbr, 2.8, 1392.8, 0, 1578.33],
-			["S&H Education Cess - %s" % abbr, 1.4, 1394.2, 0, 1578.33],
-			["CST - %s" % abbr, 27.88, 1422.08, 0, 1578.33],
-			["VAT - Test - %s" % abbr, 156.25, 1578.33, 0, 1578.33],
-			["Customs Duty - %s" % abbr, 125, 1703.33, 125, 1703.33],
-			["Shipping Charges - %s" % abbr, 100, 1803.33, 100, 1803.33],
-			["adj_rate - %s" % abbr, -180.33, 1623, -180.33, 1623],
-		]		
-		for i, tax in enumerate(dl.get({"parentfield": "other_charges"})):
-			# print tax.account_head, tax.tax_amount, tax.total, tax.tax_amount_print, \
-			# 	tax.total_print
-			self.assertEqual(tax.account_head, expected_values[i][0])
-			self.assertEqual(tax.tax_amount, expected_values[i][1])
-			self.assertEqual(tax.total, expected_values[i][2])
-			# self.assertEqual(tax.tax_amount_print, expected_values[i][3])
-			self.assertEqual(tax.total_print, expected_values[i][4])
-			
-		# test net total
-		self.assertEqual(dl[0].net_total, 1250)
-		self.assertEqual(dl[0].net_total_print, 1578.33)
-
-		# # test grand total
-		self.assertEqual(dl[0].grand_total, 1623)
-		self.assertEqual(dl[0].grand_total_export, 1623)
-		
-	def test_usd_sales_invoice_with_inclusive_tax(self):
-		# print
-		# print "-"*80
-		# print "test_usd_sales_invoice_with_inclusive_tax"
-		# print "-"*80
-		
-		# Note: below values were obtained through manual calculation and verified by test
-		
-		doclist = [
-			# parent
-			{
-				"doctype": "Sales Invoice", 
-				"debit_to": "West Wind Inc. - %s" % abbr,
-				"customer_name": "West Wind Inc.",
-				"naming_series": "INV", "posting_date": nowdate(),
-				"company": company,
-				"fiscal_year": webnotes.conn.get_default("fiscal_year"), 
-				"currency": "USD", "price_list_currency": "USD", "conversion_rate": 50.0,
-				"plc_conversion_rate": 50.0, "grand_total_export": 0
-			},
-			# items
-			{
-				"doctype": "Sales Invoice Item", "warehouse": "Default Warehouse",
-				"item_code": "Home Desktop 100", "qty": 10, "export_rate": 50,
-				"adj_rate": 10, "parentfield": "sales_invoice_items",
-				"uom": "Nos", "item_tax_rate": json.dumps({"Excise Duty - %s" % abbr: 10})
-			},
-			{
-				"doctype": "Sales Invoice Item", "warehouse": "Default Warehouse",
-				"item_code": "Home Desktop 200", "qty": 5, "export_rate": 150,
-				"adj_rate": 20, "parentfield": "sales_invoice_items",
-				"uom": "Nos"
-			},
-			# taxes
-			{
-				"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
-				"account_head": "Excise Duty - %s" % abbr, "rate": 12,
-				"parentfield": "other_charges", "included_in_print_rate": 1
-			},
-			{
-				"doctype": "Sales Taxes and Charges",
-				"charge_type": "On Previous Row Amount",
-				"account_head": "Education Cess - %s" % abbr, "rate": 2, "row_id": 1,
-				"parentfield": "other_charges", "included_in_print_rate": 1
-			},
-			{
-				"doctype": "Sales Taxes and Charges",
-				"charge_type": "On Previous Row Amount",
-				"account_head": "S&H Education Cess - %s" % abbr, "rate": 1, "row_id": 1,
-				"parentfield": "other_charges", "included_in_print_rate": 1
-			},
-			{
-				"doctype": "Sales Taxes and Charges", 
-				"charge_type": "On Previous Row Total",
-				"account_head": "CST - %s" % abbr, "rate": 2, "row_id": 3,
-				"parentfield": "other_charges", "included_in_print_rate": 1,
-				"cost_center_other_charges": "Default Cost Center - %s" % abbr
-			},
-			{
-				"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
-				"account_head": "VAT - Test - %s" % abbr, "rate": 12.5,
-				"parentfield": "other_charges", "included_in_print_rate": 1
-			},
-			{
-				"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
-				"account_head": "Customs Duty - %s" % abbr, "rate": 10,
-				"parentfield": "other_charges",
-				"cost_center_other_charges": "Default Cost Center - %s" % abbr
-			},
-			{
-				"doctype": "Sales Taxes and Charges", "charge_type": "Actual",
-				"account_head": "Shipping Charges - %s" % abbr, "rate": 100, 
-				"parentfield": "other_charges",
-				"cost_center_other_charges": "Default Cost Center - %s" % abbr
-			},
-			{
-				"doctype": "Sales Taxes and Charges",
-				"charge_type": "On Previous Row Total",
-				"account_head": "adj_rate - %s" % abbr, "rate": -10, "row_id": 7,
-				"parentfield": "other_charges",
-				"cost_center_other_charges": "Default Cost Center - %s" % abbr
-			},
-		]
-		
-		controller = webnotes.insert(DocList(doclist))
-		controller.load_from_db()
-		
-		from controllers.tax_controller import TaxController
-		tax_controller = TaxController(controller.doc, controller.doclist)
-		tax_controller.item_table_field = "entries"
-		tax_controller.calculate_taxes_and_totals()
-		
-		controller.doc = tax_controller.doc
-		controller.doclist = tax_controller.doclist
-		
-		controller.save()
-		controller.load_from_db()
-		dl = controller.doclist
-
-		# test item values calculation
-		expected_values = [
-			{
-				"item_code": "Home Desktop 100",
-				"ref_rate": 55.5556,
-				"adj_rate": 10,
-				"export_amount": 500,
-				"base_ref_rate": 2222.1156,
-				"basic_rate": 1999.904,
-				"amount": 19999.04
-			},
-			{
-				"item_code": "Home Desktop 200",
-				"ref_rate": 187.5,
-				"adj_rate": 20,
-				"export_amount": 750,
-				"base_ref_rate": 7375.664,
-				"basic_rate": 5900.5312,
-				"amount": 29502.66
-			},
-		]
-		for i, item in enumerate(dl.get({"parentfield": "sales_invoice_items"})):
-			for key, val in expected_values[i].items():
-				self.assertEqual(item.fields.get(key), val)
-		
-		# test tax amounts and totals
-		expected_values = [
-			["Excise Duty - %s" % abbr, 5540.22, 55041.92, 0, 1250],
-			["Education Cess - %s" % abbr, 110.81, 55152.73, 0, 1250],
-			["S&H Education Cess - %s" % abbr, 55.4, 55208.13, 0, 1250],
-			["CST - %s" % abbr, 1104.16, 56312.29, 0, 1250],
-			["VAT - Test - %s" % abbr, 6187.71, 62500, 0, 1250],
-			["Customs Duty - %s" % abbr, 4950.17, 67450.17, 99.01, 1349.01],
-			["Shipping Charges - %s" % abbr, 5000, 72450.17, 100, 1449.01],
-			["adj_rate - %s" % abbr, -7245.01, 65205.16, -144.9, 1304.11],
-		]		
-		for i, tax in enumerate(dl.get({"parentfield": "other_charges"})):
-			# print tax.account_head, tax.tax_amount, tax.total, tax.tax_amount_print, \
-			# 	tax.total_print
-			self.assertEqual(tax.account_head, expected_values[i][0])
-			self.assertEqual(tax.tax_amount, expected_values[i][1])
-			self.assertEqual(tax.total, expected_values[i][2])
-			# self.assertEqual(tax.tax_amount_print, expected_values[i][3])
-			self.assertEqual(tax.total_print, expected_values[i][4])
-			
-		# test net total
-		self.assertEqual(dl[0].net_total, 49501.7)
-		self.assertEqual(dl[0].net_total_print, 1250)
-
-		# # test grand total
-		self.assertEqual(dl[0].grand_total, 65205.16)
-		self.assertEqual(dl[0].grand_total_export, 1304.11)
-		
+		# 	
+		# def test_inclusive_rate_validations(self):
+		# 	doclist = [] + [d.copy() for d in sales_invoice_doclist]
+		# 	doclist[1]["export_rate"] = 62.5
+		# 	doclist[2]["export_rate"] = 191
+		# 	for i in [3, 5, 6, 7, 8, 9]:
+		# 		doclist[i]["included_in_print_rate"] = 1
+		# 	
+		# 	# tax type "Actual" cannot be inclusive
+		# 	self.assertRaises(webnotes.ValidationError, webnotes.insert,
+		# 		DocList(doclist))
+		# 	
+		# 	doclist[3]["included_in_print_rate"] = 0
+		# 	# taxes above included type 'On Previous Row Total' should also be included
+		# 	self.assertRaises(webnotes.ValidationError, webnotes.insert,
+		# 		DocList(doclist))
+		# 
+		# def test_sales_invoice_with_inclusive_tax(self):
+		# 	doclist = [
+		# 		# parent
+		# 		{
+		# 			"doctype": "Sales Invoice", 
+		# 			"debit_to": "West Wind Inc. - %s" % abbr,
+		# 			"customer_name": "West Wind Inc.",
+		# 			"naming_series": "INV", "posting_date": nowdate(),
+		# 			"company": company,
+		# 			"fiscal_year": webnotes.conn.get_default("fiscal_year"), 
+		# 			"currency": webnotes.conn.get_default("currency"),
+		# 			"price_list_currency": webnotes.conn.get_default("currency"),
+		# 			"conversion_rate": 1.0, "plc_conversion_rate": 1.0,
+		# 			"grand_total_export": 0
+		# 		},
+		# 		# items
+		# 		{
+		# 			"doctype": "Sales Invoice Item", "warehouse": "Default Warehouse",
+		# 			"item_code": "Home Desktop 100", "qty": 10, "export_rate": 62.503,
+		# 			"parentfield": "entries",
+		# 			"uom": "Nos", "item_tax_rate": json.dumps({"Excise Duty - %s" % abbr: 10})
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Invoice Item", "warehouse": "Default Warehouse",
+		# 			"item_code": "Home Desktop 200", "qty": 5, "export_rate": 190.6608,
+		# 			"parentfield": "entries",
+		# 			"uom": "Nos"
+		# 		},
+		# 		# taxes
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
+		# 			"account_head": "Excise Duty - %s" % abbr, "rate": 12,
+		# 			"parentfield": "other_charges", "included_in_print_rate": 1
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges",
+		# 			"charge_type": "On Previous Row Amount",
+		# 			"account_head": "Education Cess - %s" % abbr, "rate": 2, "row_id": 1,
+		# 			"parentfield": "other_charges", "included_in_print_rate": 1
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges",
+		# 			"charge_type": "On Previous Row Amount",
+		# 			"account_head": "S&H Education Cess - %s" % abbr, "rate": 1, "row_id": 1,
+		# 			"parentfield": "other_charges", "included_in_print_rate": 1
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges", 
+		# 			"charge_type": "On Previous Row Total",
+		# 			"account_head": "CST - %s" % abbr, "rate": 2, "row_id": 3,
+		# 			"parentfield": "other_charges", "included_in_print_rate": 1,
+		# 			"cost_center_other_charges": "Default Cost Center - %s" % abbr
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
+		# 			"account_head": "VAT - Test - %s" % abbr, "rate": 12.5,
+		# 			"parentfield": "other_charges", "included_in_print_rate": 1
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
+		# 			"account_head": "Customs Duty - %s" % abbr, "rate": 10,
+		# 			"parentfield": "other_charges",
+		# 			"cost_center_other_charges": "Default Cost Center - %s" % abbr
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges", "charge_type": "Actual",
+		# 			"account_head": "Shipping Charges - %s" % abbr, "rate": 100, 
+		# 			"parentfield": "other_charges",
+		# 			"cost_center_other_charges": "Default Cost Center - %s" % abbr
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges",
+		# 			"charge_type": "On Previous Row Total",
+		# 			"account_head": "adj_rate - %s" % abbr, "rate": -10, "row_id": 7,
+		# 			"parentfield": "other_charges",
+		# 			"cost_center_other_charges": "Default Cost Center - %s" % abbr
+		# 		},
+		# 	]
+		# 	
+		# 	controller = webnotes.insert(DocList(doclist))
+		# 	controller.load_from_db()
+		# 	
+		# 	from controllers.tax_controller import TaxController
+		# 	tax_controller = TaxController(controller.doc, controller.doclist)
+		# 	tax_controller.item_table_field = "entries"
+		# 	tax_controller.calculate_taxes_and_totals()
+		# 	
+		# 	controller.doc = tax_controller.doc
+		# 	controller.doclist = tax_controller.doclist
+		# 	
+		# 	controller.save()
+		# 	controller.load_from_db()
+		# 	dl = controller.doclist
+		# 
+		# 	# test item values calculation
+		# 	expected_values = [
+		# 		{
+		# 			"item_code": "Home Desktop 100",
+		# 			"ref_rate": 62.503,
+		# 			"adj_rate": 0,
+		# 			"export_amount": 625.03,
+		# 			"base_ref_rate": 50,
+		# 			"basic_rate": 50,
+		# 			"amount": 500
+		# 		},
+		# 		{
+		# 			"item_code": "Home Desktop 200",
+		# 			"ref_rate": 190.6608,
+		# 			"adj_rate": 0,
+		# 			"export_amount": 953.3,
+		# 			"base_ref_rate": 150,
+		# 			"basic_rate": 150,
+		# 			"amount": 750
+		# 		},
+		# 	]
+		# 	for i, item in enumerate(dl.get({"parentfield": "entries"})):
+		# 		for key, val in expected_values[i].items():
+		# 			self.assertEqual(item.fields.get(key), val)
+		# 	
+		# 	# test tax amounts and totals
+		# 	expected_values = [
+		# 		["Excise Duty - %s" % abbr, 140, 1390, 0, 1578.33],
+		# 		["Education Cess - %s" % abbr, 2.8, 1392.8, 0, 1578.33],
+		# 		["S&H Education Cess - %s" % abbr, 1.4, 1394.2, 0, 1578.33],
+		# 		["CST - %s" % abbr, 27.88, 1422.08, 0, 1578.33],
+		# 		["VAT - Test - %s" % abbr, 156.25, 1578.33, 0, 1578.33],
+		# 		["Customs Duty - %s" % abbr, 125, 1703.33, 125, 1703.33],
+		# 		["Shipping Charges - %s" % abbr, 100, 1803.33, 100, 1803.33],
+		# 		["adj_rate - %s" % abbr, -180.33, 1623, -180.33, 1623],
+		# 	]		
+		# 	for i, tax in enumerate(dl.get({"parentfield": "other_charges"})):
+		# 		# print tax.account_head, tax.tax_amount, tax.total, tax.tax_amount_print, \
+		# 		# 	tax.total_print
+		# 		self.assertEqual(tax.account_head, expected_values[i][0])
+		# 		self.assertEqual(tax.tax_amount, expected_values[i][1])
+		# 		self.assertEqual(tax.total, expected_values[i][2])
+		# 		# self.assertEqual(tax.tax_amount_print, expected_values[i][3])
+		# 		self.assertEqual(tax.total_print, expected_values[i][4])
+		# 		
+		# 	# test net total
+		# 	self.assertEqual(dl[0].net_total, 1250)
+		# 
+		# 	# # test grand total
+		# 	self.assertEqual(dl[0].grand_total, 1623)
+		# 	self.assertEqual(dl[0].grand_total_export, 1623)
+		# 	
+		# def test_usd_sales_invoice_with_inclusive_tax(self):
+		# 	# print
+		# 	# print "-"*80
+		# 	# print "test_usd_sales_invoice_with_inclusive_tax"
+		# 	# print "-"*80
+		# 	
+		# 	# Note: below values were obtained through manual calculation and verified by test
+		# 	
+		# 	doclist = [
+		# 		# parent
+		# 		{
+		# 			"doctype": "Sales Invoice", 
+		# 			"debit_to": "West Wind Inc. - %s" % abbr,
+		# 			"customer_name": "West Wind Inc.",
+		# 			"naming_series": "INV", "posting_date": nowdate(),
+		# 			"company": company,
+		# 			"fiscal_year": webnotes.conn.get_default("fiscal_year"), 
+		# 			"currency": "USD", "price_list_currency": "USD", "conversion_rate": 50.0,
+		# 			"plc_conversion_rate": 50.0, "grand_total_export": 0
+		# 		},
+		# 		# items
+		# 		{
+		# 			"doctype": "Sales Invoice Item", "warehouse": "Default Warehouse",
+		# 			"item_code": "Home Desktop 100", "qty": 10, "export_rate": 50,
+		# 			"adj_rate": 10, "parentfield": "entries",
+		# 			"uom": "Nos", "item_tax_rate": json.dumps({"Excise Duty - %s" % abbr: 10})
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Invoice Item", "warehouse": "Default Warehouse",
+		# 			"item_code": "Home Desktop 200", "qty": 5, "export_rate": 150,
+		# 			"adj_rate": 20, "parentfield": "entries",
+		# 			"uom": "Nos"
+		# 		},
+		# 		# taxes
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
+		# 			"account_head": "Excise Duty - %s" % abbr, "rate": 12,
+		# 			"parentfield": "other_charges", "included_in_print_rate": 1
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges",
+		# 			"charge_type": "On Previous Row Amount",
+		# 			"account_head": "Education Cess - %s" % abbr, "rate": 2, "row_id": 1,
+		# 			"parentfield": "other_charges", "included_in_print_rate": 1
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges",
+		# 			"charge_type": "On Previous Row Amount",
+		# 			"account_head": "S&H Education Cess - %s" % abbr, "rate": 1, "row_id": 1,
+		# 			"parentfield": "other_charges", "included_in_print_rate": 1
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges", 
+		# 			"charge_type": "On Previous Row Total",
+		# 			"account_head": "CST - %s" % abbr, "rate": 2, "row_id": 3,
+		# 			"parentfield": "other_charges", "included_in_print_rate": 1,
+		# 			"cost_center_other_charges": "Default Cost Center - %s" % abbr
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
+		# 			"account_head": "VAT - Test - %s" % abbr, "rate": 12.5,
+		# 			"parentfield": "other_charges", "included_in_print_rate": 1
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges", "charge_type": "On Net Total",
+		# 			"account_head": "Customs Duty - %s" % abbr, "rate": 10,
+		# 			"parentfield": "other_charges",
+		# 			"cost_center_other_charges": "Default Cost Center - %s" % abbr
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges", "charge_type": "Actual",
+		# 			"account_head": "Shipping Charges - %s" % abbr, "rate": 100, 
+		# 			"parentfield": "other_charges",
+		# 			"cost_center_other_charges": "Default Cost Center - %s" % abbr
+		# 		},
+		# 		{
+		# 			"doctype": "Sales Taxes and Charges",
+		# 			"charge_type": "On Previous Row Total",
+		# 			"account_head": "adj_rate - %s" % abbr, "rate": -10, "row_id": 7,
+		# 			"parentfield": "other_charges",
+		# 			"cost_center_other_charges": "Default Cost Center - %s" % abbr
+		# 		},
+		# 	]
+		# 	
+		# 	controller = webnotes.insert(DocList(doclist))
+		# 	controller.load_from_db()
+		# 	
+		# 	from controllers.tax_controller import TaxController
+		# 	tax_controller = TaxController(controller.doc, controller.doclist)
+		# 	tax_controller.item_table_field = "entries"
+		# 	tax_controller.calculate_taxes_and_totals()
+		# 	
+		# 	controller.doc = tax_controller.doc
+		# 	controller.doclist = tax_controller.doclist
+		# 	
+		# 	controller.save()
+		# 	controller.load_from_db()
+		# 	dl = controller.doclist
+		# 
+		# 	# test item values calculation
+		# 	expected_values = [
+		# 		{
+		# 			"item_code": "Home Desktop 100",
+		# 			"ref_rate": 55.5556,
+		# 			"adj_rate": 10,
+		# 			"export_amount": 500,
+		# 			"base_ref_rate": 2222.1156,
+		# 			"basic_rate": 1999.904,
+		# 			"amount": 19999.04
+		# 		},
+		# 		{
+		# 			"item_code": "Home Desktop 200",
+		# 			"ref_rate": 187.5,
+		# 			"adj_rate": 20,
+		# 			"export_amount": 750,
+		# 			"base_ref_rate": 7375.664,
+		# 			"basic_rate": 5900.5312,
+		# 			"amount": 29502.66
+		# 		},
+		# 	]
+		# 	for i, item in enumerate(dl.get({"parentfield": "entries"})):
+		# 		for key, val in expected_values[i].items():
+		# 			self.assertEqual(item.fields.get(key), val)
+		# 	
+		# 	# test tax amounts and totals
+		# 	expected_values = [
+		# 		["Excise Duty - %s" % abbr, 5540.22, 55041.92, 0, 1250],
+		# 		["Education Cess - %s" % abbr, 110.81, 55152.73, 0, 1250],
+		# 		["S&H Education Cess - %s" % abbr, 55.4, 55208.13, 0, 1250],
+		# 		["CST - %s" % abbr, 1104.16, 56312.29, 0, 1250],
+		# 		["VAT - Test - %s" % abbr, 6187.71, 62500, 0, 1250],
+		# 		["Customs Duty - %s" % abbr, 4950.17, 67450.17, 99.01, 1349.01],
+		# 		["Shipping Charges - %s" % abbr, 5000, 72450.17, 100, 1449.01],
+		# 		["adj_rate - %s" % abbr, -7245.01, 65205.16, -144.9, 1304.11],
+		# 	]		
+		# 	for i, tax in enumerate(dl.get({"parentfield": "other_charges"})):
+		# 		# print tax.account_head, tax.tax_amount, tax.total, tax.tax_amount_print, \
+		# 		# 	tax.total_print
+		# 		self.assertEqual(tax.account_head, expected_values[i][0])
+		# 		self.assertEqual(tax.tax_amount, expected_values[i][1])
+		# 		self.assertEqual(tax.total, expected_values[i][2])
+		# 		# self.assertEqual(tax.tax_amount_print, expected_values[i][3])
+		# 		self.assertEqual(tax.total_print, expected_values[i][4])
+		# 		
+		# 	# test net total
+		# 	self.assertEqual(dl[0].net_total, 49501.7)
+		# 
+		# 	# # test grand total
+		# 	self.assertEqual(dl[0].grand_total, 65205.16)
+		# 	self.assertEqual(dl[0].grand_total_export, 1304.11)
+		# 	
 
 	def tearDown(self):
 		webnotes.conn.rollback()
\ No newline at end of file
diff --git a/accounts/general_ledger.py b/accounts/general_ledger.py
new file mode 100644
index 0000000..f7932bf
--- /dev/null
+++ b/accounts/general_ledger.py
@@ -0,0 +1,109 @@
+# ERPNext - web based ERP (http://erpnext.com)
+# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import unicode_literals
+import webnotes
+from webnotes.utils import flt, cstr
+from webnotes.model.doc import Document
+
+def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, 
+		update_outstanding='Yes'):
+	if merge_entries:
+		gl_map = merge_similar_entries(gl_map)
+	
+	check_budget(gl_map, cancel)
+	save_entries(gl_map, cancel, adv_adj, update_outstanding)
+
+	if cancel:
+		set_as_cancel(gl_map[0]["voucher_type"], gl_map[0]["voucher_no"])
+		
+def merge_similar_entries(gl_map):
+	merged_gl_map = []
+	for entry in gl_map:
+		# if there is already an entry in this account then just add it 
+		# to that entry
+		same_head = check_if_in_list(entry, merged_gl_map)
+		if same_head:
+			same_head['debit']	= flt(same_head['debit']) + flt(entry['debit'])
+			same_head['credit'] = flt(same_head['credit']) + flt(entry['credit'])
+		else:
+			merged_gl_map.append(entry)
+
+	return merged_gl_map
+
+def check_if_in_list(gle, gl_mqp):
+	for e in gl_mqp:
+		if e['account'] == gle['account'] and \
+				cstr(e.get('against_voucher'))==cstr(gle.get('against_voucher')) \
+				and cstr(e.get('against_voucher_type')) == \
+					cstr(gle.get('against_voucher_type')) \
+				and cstr(e.get('cost_center')) == cstr(gle.get('cost_center')):
+			return e
+
+def check_budget(gl_map, cancel):
+	for gle in gl_map:
+		if gle.get('cost_center'):
+			#check budget only if account is expense account
+			acc_details = webnotes.conn.get_value("Account", gle['account'], 
+				['is_pl_account', 'debit_or_credit'])
+			if acc_details[0]=="Yes" and acc_details[1]=="Debit":
+				webnotes.get_obj('Budget Control').check_budget(gle, cancel)
+
+def save_entries(gl_map, cancel, adv_adj, update_outstanding):
+	total_debit = total_credit = 0.0
+	def _swap(gle):
+		gle.debit, gle.credit = abs(flt(gle.credit)), abs(flt(gle.debit))
+			
+	for entry in gl_map:
+		gle = Document('GL Entry', fielddata=entry)
+		
+		# toggle debit, credit if negative entry
+		if flt(gle.debit) < 0 or flt(gle.credit) < 0:
+			_swap(gle)
+
+		# toggled debit/credit in two separate condition because 
+		# both should be executed at the 
+		# time of cancellation when there is negative amount (tax discount)
+		if cancel:
+			_swap(gle)
+
+		gle_obj = webnotes.get_obj(doc=gle)
+		# validate except on_cancel
+		if not cancel:
+			gle_obj.validate()
+
+		# save
+		gle.save(1)
+		gle_obj.on_update(adv_adj, cancel, update_outstanding)
+
+		# update total debit / credit
+		total_debit += flt(gle.debit)
+		total_credit += flt(gle.credit)
+		
+		# print gle.account, gle.debit, gle.credit, total_debit, total_credit
+		
+	if not cancel:
+		validate_total_debit_credit(total_debit, total_credit)
+	
+def validate_total_debit_credit(total_debit, total_credit):
+	if abs(total_debit - total_credit) > 0.005:
+		webnotes.msgprint("""Debit and Credit not equal for 
+			this voucher: Diff (Debit) is %s""" %
+		 	(total_debit - total_credit), raise_exception=1)
+
+def set_as_cancel(voucher_type, voucher_no):
+	webnotes.conn.sql("""update `tabGL Entry` set is_cancelled='Yes' 
+		where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
\ No newline at end of file
diff --git a/accounts/page/accounts_browser/accounts_browser.js b/accounts/page/accounts_browser/accounts_browser.js
index da045a6..6fd0c66 100644
--- a/accounts/page/accounts_browser/accounts_browser.js
+++ b/accounts/page/accounts_browser/accounts_browser.js
@@ -236,12 +236,15 @@
 			v.master_type = '';
 			v.company = me.company;
 			
-		    $c_obj('GL Control', 'add_ac', v, 
-				function(r,rt) { 
+			wn.call({
+				args: v,
+				method:'accounts.utils.add_ac',
+				callback: function(r) {
 					$(btn).done_working();
 					d.hide();
-					node.trigger('reload'); 	
-				});
+					node.trigger('reload');
+				}
+			});
 		});
 		
 		// show
@@ -280,12 +283,15 @@
 			v.parent_cost_center = node.data('label');
 			v.company_name = me.company;
 			
-		    $c_obj('GL Control', 'add_cc', v, 
-				function(r,rt) { 
+			wn.call({
+				args: v,
+				method:'accounts.utils.add_cc',
+				callback: function(r) {
 					$(btn).done_working();
 					d.hide();
-					node.trigger('reload'); 	
-				});
+					node.trigger('reload');
+				}
+			});
 		});
 		d.show();
 	}
diff --git a/accounts/utils.py b/accounts/utils.py
new file mode 100644
index 0000000..b2a2b2c
--- /dev/null
+++ b/accounts/utils.py
@@ -0,0 +1,199 @@
+# ERPNext - web based ERP (http://erpnext.com)
+# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import unicode_literals
+
+import webnotes
+from webnotes.utils import nowdate, cstr, flt
+from webnotes.model.doc import addchild
+from webnotes import msgprint, _
+
+class FiscalYearError(webnotes.ValidationError): pass
+
+def get_fiscal_year(date, verbose=1):
+	from webnotes.utils import formatdate
+	# if year start date is 2012-04-01, year end date should be 2013-03-31 (hence subdate)
+	fy = webnotes.conn.sql("""select name, year_start_date, 
+		subdate(adddate(year_start_date, interval 1 year), interval 1 day) 
+			as year_end_date
+		from `tabFiscal Year`
+		where %s >= year_start_date and %s < adddate(year_start_date, interval 1 year)
+		order by year_start_date desc""", (date, date))
+	
+	if not fy:
+		error_msg = """%s not in any Fiscal Year""" % formatdate(date)
+		if verbose: webnotes.msgprint(error_msg)
+		raise FiscalYearError, error_msg
+	
+	return fy[0]
+
+@webnotes.whitelist()
+def get_balance_on(account=None, date=None):
+	if not account and webnotes.form_dict.get("account"):
+		account = webnotes.form_dict.get("account")
+		date = webnotes.form_dict.get("date")
+	
+	cond = []
+	if date:
+		cond.append("posting_date <= '%s'" % date)
+	else:
+		# get balance of all entries that exist
+		date = nowdate()
+		
+	try:
+		year_start_date = get_fiscal_year(date, verbose=0)[1]
+	except FiscalYearError, e:
+		from webnotes.utils import getdate
+		if getdate(date) > getdate(nowdate()):
+			# if fiscal year not found and the date is greater than today
+			# get fiscal year for today's date and its corresponding year start date
+			year_start_date = get_fiscal_year(nowdate(), verbose=1)[1]
+		else:
+			# this indicates that it is a date older than any existing fiscal year.
+			# hence, assuming balance as 0.0
+			return 0.0
+		
+	acc = webnotes.conn.get_value('Account', account, \
+		['lft', 'rgt', 'debit_or_credit', 'is_pl_account', 'group_or_ledger'], as_dict=1)
+	
+	# for pl accounts, get balance within a fiscal year
+	if acc.is_pl_account == 'Yes':
+		cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
+			% year_start_date)
+	
+	# different filter for group and ledger - improved performance
+	if acc.group_or_ledger=="Group":
+		cond.append("""exists (
+			select * from `tabAccount` ac where ac.name = gle.account
+			and ac.lft >= %s and ac.rgt <= %s
+		)""" % (acc.lft, acc.rgt))
+	else:
+		cond.append("""gle.account = "%s" """ % (account, ))
+	
+	# join conditional conditions
+	cond = " and ".join(cond)
+	if cond:
+		cond += " and "
+	
+	bal = webnotes.conn.sql("""
+		SELECT sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) 
+		FROM `tabGL Entry` gle
+		WHERE %s ifnull(is_cancelled, 'No') = 'No' """ % (cond, ))[0][0]
+
+	# if credit account, it should calculate credit - debit
+	if bal and acc.debit_or_credit == 'Credit':
+		bal = -bal
+
+	# if bal is None, return 0
+	return bal or 0
+
+@webnotes.whitelist()
+def add_ac(args=None):
+	if not args:
+		args = webnotes.form_dict
+		args.pop("cmd")
+	
+	ac = webnotes.model_wrapper(args)
+	ac.doc.doctype = "Account"
+	ac.doc.old_parent = ""
+	ac.doc.freeze_account = "No"
+	ac.ignore_permissions = 1
+	ac.insert()
+	return ac.doc.name
+
+@webnotes.whitelist()
+def add_cc(args=None):
+	if not args:
+		args = webnotes.form_dict
+		args.pop("cmd")
+		
+	cc = webnotes.model_wrapper(args)
+	cc.doc.doctype = "Cost Center"
+	cc.doc.old_parent = ""
+	cc.ignore_permissions = 1
+	cc.insert()
+	return cc.doc.name
+
+def reconcile_against_document(args):
+	"""
+		Cancel JV, Update aginst document, split if required and resubmit jv
+	"""
+	for d in args:
+		check_if_jv_modified(d)
+
+		against_fld = {
+			'Journal Voucher' : 'against_jv',
+			'Sales Invoice' : 'against_invoice',
+			'Purchase Invoice' : 'against_voucher'
+		}
+		
+		d['against_fld'] = against_fld[d['against_voucher_type']]
+
+		# cancel JV
+		jv_obj = webnotes.get_obj('Journal Voucher', d['voucher_no'], with_children=1)
+		jv_obj.make_gl_entries(cancel=1, adv_adj=1)
+		
+		# update ref in JV Detail
+		update_against_doc(d, jv_obj)
+
+		# re-submit JV
+		jv_obj = webnotes.get_obj('Journal Voucher', d['voucher_no'], with_children =1)
+		jv_obj.make_gl_entries(cancel = 0, adv_adj =1)
+
+
+def check_if_jv_modified(args):
+	"""
+		check if there is already a voucher reference
+		check if amount is same
+		check if jv is submitted
+	"""
+	ret = webnotes.conn.sql("""
+		select t2.%(dr_or_cr)s from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 
+		where t1.name = t2.parent and t2.account = '%(account)s' 
+		and ifnull(t2.against_voucher, '')='' 
+		and ifnull(t2.against_invoice, '')='' and ifnull(t2.against_jv, '')=''
+		and t1.name = '%(voucher_no)s' and t2.name = '%(voucher_detail_no)s'
+		and t1.docstatus=1 and t2.%(dr_or_cr)s = %(unadjusted_amt)s""" % args)
+	
+	if not ret:
+		msgprint(_("""Payment Entry has been modified after you pulled it. 
+			Please pull it again."""), raise_exception=1)
+
+def update_against_doc(d, jv_obj):
+	"""
+		Updates against document, if partial amount splits into rows
+	"""
+
+	webnotes.conn.sql("""
+		update `tabJournal Voucher Detail` t1, `tabJournal Voucher` t2	
+		set t1.%(dr_or_cr)s = '%(allocated_amt)s', 
+		t1.%(against_fld)s = '%(against_voucher)s', t2.modified = now() 
+		where t1.name = '%(voucher_detail_no)s' and t1.parent = t2.name""" % d)
+	
+	if d['allocated_amt'] < d['unadjusted_amt']:
+		jvd = webnotes.conn.sql("""select cost_center, balance, against_account, is_advance 
+			from `tabJournal Voucher Detail` where name = %s""", d['voucher_detail_no'])
+		# new entry with balance amount
+		ch = addchild(jv_obj.doc, 'entries', 'Journal Voucher Detail')
+		ch.account = d['account']
+		ch.cost_center = cstr(jvd[0][0])
+		ch.balance = cstr(jvd[0][1])
+		ch.fields[d['dr_or_cr']] = flt(d['unadjusted_amt']) - flt(d['allocated_amt'])
+		ch.fields[d['dr_or_cr']== 'debit' and 'credit' or 'debit'] = 0
+		ch.against_account = cstr(jvd[0][2])
+		ch.is_advance = cstr(jvd[0][3])
+		ch.docstatus = 1
+		ch.save(1)
\ No newline at end of file
diff --git a/accounts/utils/__init__.py b/accounts/utils/__init__.py
deleted file mode 100644
index 8ad1899..0000000
--- a/accounts/utils/__init__.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# ERPNext - web based ERP (http://erpnext.com)
-# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-# 
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from __future__ import unicode_literals
-
-import webnotes
-from webnotes.utils import nowdate
-
-class FiscalYearError(webnotes.ValidationError): pass
-
-def get_fiscal_year(date, verbose=1):
-	from webnotes.utils import formatdate
-	# if year start date is 2012-04-01, year end date should be 2013-03-31 (hence subdate)
-	fy = webnotes.conn.sql("""select name, year_start_date, 
-		subdate(adddate(year_start_date, interval 1 year), interval 1 day) 
-			as year_end_date
-		from `tabFiscal Year`
-		where %s >= year_start_date and %s < adddate(year_start_date, interval 1 year)
-		order by year_start_date desc""", (date, date))
-	
-	if not fy:
-		error_msg = """%s not in any Fiscal Year""" % formatdate(date)
-		if verbose: webnotes.msgprint(error_msg)
-		raise FiscalYearError, error_msg
-	
-	return fy[0]
-
-@webnotes.whitelist()
-def get_balance_on(account=None, date=None):
-	if not account and webnotes.form_dict.get("account"):
-		account = webnotes.form_dict.get("account")
-		date = webnotes.form_dict.get("date")
-	
-	cond = []
-	if date:
-		cond.append("posting_date <= '%s'" % date)
-	else:
-		# get balance of all entries that exist
-		date = nowdate()
-		
-	try:
-		year_start_date = get_fiscal_year(date, verbose=0)[1]
-	except FiscalYearError, e:
-		from webnotes.utils import getdate
-		if getdate(date) > getdate(nowdate()):
-			# if fiscal year not found and the date is greater than today
-			# get fiscal year for today's date and its corresponding year start date
-			year_start_date = get_fiscal_year(nowdate(), verbose=1)[1]
-		else:
-			# this indicates that it is a date older than any existing fiscal year.
-			# hence, assuming balance as 0.0
-			return 0.0
-		
-	acc = webnotes.conn.get_value('Account', account, \
-		['lft', 'rgt', 'debit_or_credit', 'is_pl_account', 'group_or_ledger'], as_dict=1)
-	
-	# for pl accounts, get balance within a fiscal year
-	if acc.is_pl_account == 'Yes':
-		cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
-			% year_start_date)
-	
-	# different filter for group and ledger - improved performance
-	if acc.group_or_ledger=="Group":
-		cond.append("""exists (
-			select * from `tabAccount` ac where ac.name = gle.account
-			and ac.lft >= %s and ac.rgt <= %s
-		)""" % (acc.lft, acc.rgt))
-	else:
-		cond.append("""gle.account = "%s" """ % (account, ))
-	
-	# join conditional conditions
-	cond = " and ".join(cond)
-	if cond:
-		cond += " and "
-	
-	bal = webnotes.conn.sql("""
-		SELECT sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) 
-		FROM `tabGL Entry` gle
-		WHERE %s ifnull(is_cancelled, 'No') = 'No' """ % (cond, ))[0][0]
-
-	# if credit account, it should calculate credit - debit
-	if bal and acc.debit_or_credit == 'Credit':
-		bal = -bal
-
-	# if bal is None, return 0
-	return bal or 0
\ No newline at end of file
diff --git a/buying/doctype/supplier/supplier.py b/buying/doctype/supplier/supplier.py
index 2255cfd..096a43e 100644
--- a/buying/doctype/supplier/supplier.py
+++ b/buying/doctype/supplier/supplier.py
@@ -17,13 +17,13 @@
 from __future__ import unicode_literals
 import webnotes
 
-from webnotes.utils import cstr, get_defaults
-from webnotes.model.code import get_obj
-from webnotes import msgprint
+from webnotes.utils import cint, get_defaults
+from webnotes import msgprint, _
 from webnotes.model.doc import make_autoname
 
 sql = webnotes.conn.sql
 
+from accounts.utils import add_ac
 from utilities.transaction_base import TransactionBase
 
 class DocType(TransactionBase):
@@ -35,28 +35,18 @@
 		self.add_communication_list()
 
 	def autoname(self):
-		#get default naming conventional from control panel
 		supp_master_name = get_defaults()['supp_master_name']
-
+		
 		if supp_master_name == 'Supplier Name':
-		
-			# filter out bad characters in name
-			#supp = self.doc.supplier_name.replace('&','and').replace('.','').replace("'",'').replace('"','').replace(',','').replace('`','')
-			supp = self.doc.supplier_name
-			
-			cust = sql("select name from `tabCustomer` where name = '%s'" % (supp))
-			cust = cust and cust[0][0] or ''
-		
-			if cust:
-				msgprint("You already have a Customer with same name")
-				raise Exception
-			self.doc.name = supp
-			
+			if webnotes.conn.exists("Customer", self.doc.supplier_name):
+				webnotes.msgprint(_("A Customer exists with same name"), raise_exception=1)
+			self.doc.name = self.doc.supplier_name
 		else:
-			self.doc.name = make_autoname(self.doc.naming_series+'.#####')
+			self.doc.name = make_autoname(self.doc.naming_series + '.#####')
 
 	def update_credit_days_limit(self):
-		sql("update tabAccount set credit_days = '%s' where name = '%s'" % (self.doc.credit_days, self.doc.name + " - " + self.get_company_abbr()))
+		sql("""update tabAccount set credit_days = %s where name = %s""", 
+			(cint(self.doc.credit_days), self.doc.name + " - " + self.get_company_abbr()))
 
 	def on_update(self):
 		if not self.doc.naming_series:
@@ -80,16 +70,16 @@
 		return g
 
 	def add_account(self, ac, par, abbr):
-		arg = {
+		ac = add_ac({
 			'account_name':ac,
 			'parent_account':par,
 			'group_or_ledger':'Group',
 			'company':self.doc.company,
 			'account_type':'',
 			'tax_rate':'0'
-		}
-		t = get_obj('GL Control').add_ac(cstr(arg))
-		msgprint("Created Group " + t)
+		})
+		
+		msgprint(_("Created Group ") + ac)
 	
 	def get_company_abbr(self):
 		return sql("select abbr from tabCompany where name=%s", self.doc.company)[0][0]
@@ -119,7 +109,7 @@
 			if not sql("select name from tabAccount where name=%s", (self.doc.name + " - " + abbr)):
 				parent_account = self.get_parent_account(abbr)
 				
-				arg = {
+				ac = add_ac({
 					'account_name': self.doc.name,
 					'parent_account': parent_account,
 					'group_or_ledger':'Ledger',
@@ -128,10 +118,8 @@
 					'tax_rate': '0',
 					'master_type': 'Supplier',
 					'master_name': self.doc.name,
-				}
-				# create
-				ac = get_obj('GL Control').add_ac(cstr(arg))
-				msgprint("Created Account Head: "+ac)
+				})
+				msgprint(_("Created Account Head: ") + ac)
 				
 		else : 
 			msgprint("Please select Company under which you want to create account head")
diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py
new file mode 100644
index 0000000..a80afc5
--- /dev/null
+++ b/controllers/accounts_controller.py
@@ -0,0 +1,76 @@
+# ERPNext - web based ERP (http://erpnext.com)
+# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import unicode_literals
+import webnotes
+from webnotes.utils import flt
+from webnotes.model.doc import addchild
+from utilities.transaction_base import TransactionBase
+
+class AccountsController(TransactionBase):
+	def get_gl_dict(self, args, cancel):
+		"""this method populates the common properties of a gl entry record"""
+		gl_dict = {
+			'company': self.doc.company, 
+			'posting_date': self.doc.posting_date,
+			'voucher_type': self.doc.doctype,
+			'voucher_no': self.doc.name,
+			'aging_date': self.doc.fields.get("aging_date") or self.doc.posting_date,
+			'remarks': self.doc.remarks,
+			'is_cancelled': cancel and "Yes" or "No",
+			'fiscal_year': self.doc.fiscal_year,
+			'debit': 0,
+			'credit': 0,
+			'is_opening': self.doc.fields.get("is_opening") or "No",
+		}
+		gl_dict.update(args)
+		return gl_dict
+		
+	def get_stock_in_hand_account(self):
+		stock_in_hand = webnotes.conn.get_value("Company", self.doc.company, "stock_in_hand")	
+		if not stock_in_hand:
+			webnotes.msgprint("""Please specify "Stock In Hand" account 
+				for company: %s""" % (self.doc.company,), raise_exception=1)
+		
+		return stock_in_hand
+		
+	def clear_unallocated_advances(self, parenttype, parentfield):
+		for d in self.doclist:
+			if d.parentfield == parentfield and flt(d.allocated_amount) == 0:
+				self.doclist.remove(d)
+			
+		webnotes.conn.sql("""delete from `tab%s` where parent = %s 
+			and ifnull(allocated_amount, 0) = 0""" % (parenttype, '%s'), self.doc.name)			
+		
+	def get_advances(self, account_head, parenttype, parentfield, dr_or_cr):
+		res = webnotes.conn.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' 
+			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""" % 
+			(dr_or_cr, '%s'), account_head, as_dict=1)
+			
+		self.doclist = self.doc.clear_table(self.doclist, parentfield)
+		for d in res:
+			add = addchild(self.doc, parentfield, parenttype, self.doclist)
+			add.journal_voucher = d.jv_no
+			add.jv_detail_no = d.jv_detail_no
+			add.remarks = d.remark
+			add.advance_amount = flt(d.amount)
+			add.allocate_amount = 0
\ No newline at end of file
diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py
index f48b626..a467eb2 100644
--- a/controllers/buying_controller.py
+++ b/controllers/buying_controller.py
@@ -22,9 +22,10 @@
 from buying.utils import get_item_details
 from setup.utils import get_company_currency
 
-from utilities.transaction_base import TransactionBase
-class BuyingController(TransactionBase):
-	def validate(self):
+from controllers.accounts_controller import AccountsController
+
+class BuyingController(AccountsController):
+	def validate(self):		
 		if self.meta.get_field("currency"):
 			self.company_currency = get_company_currency(self.doc.company)
 			self.validate_conversion_rate("currency", "conversion_rate")
diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py
index 8dd1882..5ff5637 100644
--- a/controllers/selling_controller.py
+++ b/controllers/selling_controller.py
@@ -18,8 +18,9 @@
 import webnotes
 from setup.utils import get_company_currency
 
-from utilities.transaction_base import TransactionBase
-class SellingController(TransactionBase):
+from controllers.accounts_controller import AccountsController
+
+class SellingController(AccountsController):
 	def validate(self):
 		self.set_total_in_words()
 		
diff --git a/selling/doctype/customer/customer.py b/selling/doctype/customer/customer.py
index 6aab938..01fa69c 100644
--- a/selling/doctype/customer/customer.py
+++ b/selling/doctype/customer/customer.py
@@ -19,8 +19,7 @@
 
 from webnotes.utils import cstr, get_defaults
 from webnotes.model.doc import Document, make_autoname
-from webnotes.model.code import get_obj
-from webnotes import msgprint
+from webnotes import msgprint, _
 
 sql = webnotes.conn.sql
 
@@ -37,17 +36,9 @@
 	def autoname(self):
 		cust_master_name = get_defaults().get('cust_master_name')
 		if cust_master_name == 'Customer Name':
-			# filter out bad characters in name
-			#cust = self.doc.customer_name.replace('&','and').replace('.','').replace("'",'').replace('"','').replace(',','').replace('`','')
-			cust = self.doc.customer_name
-
-			supp = sql("select name from `tabSupplier` where name = %s", (cust))
-			supp = supp and supp[0][0] or ''
-			if supp:
-				msgprint("You already have a Supplier with same name")
-				raise Exception("You already have a Supplier with same name")
-			else:
-				self.doc.name = cust
+			if webnotes.conn.exists("Supplier", self.doc.customer_name):
+				msgprint(_("A Supplier exists with same name"), raise_exception=1)
+			self.doc.name = self.doc.customer_name
 		else:
 			self.doc.name = make_autoname(self.doc.naming_series+'.#####')
 
@@ -63,7 +54,6 @@
 		return g
 	
 	def validate_values(self):
-		# Master name by naming series -> Series field mandatory
 		if get_defaults().get('cust_master_name') == 'Naming Series' and not self.doc.naming_series:
 			msgprint("Series is Mandatory.")
 			raise Exception
@@ -121,13 +111,21 @@
 	def create_account_head(self):
 		if self.doc.company :
 			abbr = self.get_company_abbr()
-			if not sql("select name from tabAccount where name=%s", (self.doc.name + " - " + abbr)):
+			if not webnotes.conn.exists("Account", (self.doc.name + " - " + abbr)):
 				parent_account = self.get_receivables_group()
-				arg = {'account_name':self.doc.name,'parent_account': parent_account, 'group_or_ledger':'Ledger', 'company':self.doc.company,'account_type':'','tax_rate':'0','master_type':'Customer','master_name':self.doc.name}
 				# create
-				
-				ac = get_obj('GL Control').add_ac(cstr(arg))
-				msgprint("Account Head created for "+ac)
+				from accounts.utils import add_ac
+				ac = add_ac({
+					'account_name':self.doc.name,
+					'parent_account': parent_account, 
+					'group_or_ledger':'Ledger',
+					'company':self.doc.company, 
+					'account_type':'', 
+					'tax_rate':'0', 
+					'master_type':'Customer', 
+					'master_name':self.doc.name
+				})
+				msgprint("Account Head: %s created" % ac)
 		else :
 			msgprint("Please Select Company under which you want to create account head")
 
diff --git a/setup/doctype/company/company.py b/setup/doctype/company/company.py
index 5aa1762..e1919a5 100644
--- a/setup/doctype/company/company.py
+++ b/setup/doctype/company/company.py
@@ -18,11 +18,8 @@
 import webnotes
 
 from webnotes.utils import cstr, get_defaults, set_default
-from webnotes.model import db_exists
 from webnotes.model.doc import Document
-from webnotes.model.wrapper import copy_doclist
 from webnotes.model.code import get_obj
-from webnotes import msgprint
 
 sql = webnotes.conn.sql
 
@@ -197,11 +194,23 @@
 	# Create default cost center
 	# ---------------------------------------------------
 	def create_default_cost_center(self):
-		glc = get_obj('GL Control')
-		cc_list = [{'cost_center_name':'Root','company_name':self.doc.name,'group_or_ledger':'Group','parent_cost_center':''}, {'cost_center_name':'Default CC Ledger','company_name':self.doc.name,'group_or_ledger':'Ledger','parent_cost_center':'Root - ' + self.doc.abbr}]
-		for c in cc_list:
-			glc.add_cc(str(c))
-			
+		from accounts.utils import add_cc
+		cc_list = [
+			{
+				'cost_center_name':'Root',
+				'company_name':self.doc.name,
+				'group_or_ledger':'Group',
+				'parent_cost_center':''
+			}, 
+			{
+				'cost_center_name':'Default CC Ledger', 
+				'company_name':self.doc.name,
+				'group_or_ledger':'Ledger',
+				'parent_cost_center':'Root - ' + self.doc.abbr
+			}
+		]
+		for cc in cc_list:
+			add_cc(cc)
 			
 	def on_update(self):
 		self.set_letter_head()
diff --git a/stock/doctype/purchase_receipt/test_purchase_receipt.py b/stock/doctype/purchase_receipt/test_purchase_receipt.py
index dfd2188..b619cbd 100644
--- a/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -19,8 +19,8 @@
 import unittest
 import webnotes
 import webnotes.model
+from webnotes.model.doclist import DocList
 from webnotes.utils import nowdate
-from accounts.utils import get_fiscal_year
 
 company = webnotes.conn.get_default("company")
 abbr = webnotes.conn.get_value("Company", company, "abbr")
@@ -53,7 +53,7 @@
 		
 	# create default cost center if not exists
 	if not webnotes.conn.exists("Cost Center", "Default Cost Center - %s" % abbr):
-		dl = webnotes.insert({"doctype": "Cost Center", "group_or_ledger": "Ledger",
+		webnotes.insert({"doctype": "Cost Center", "group_or_ledger": "Ledger",
 			"cost_center_name": "Default Cost Center", 
 			"parent_cost_center": "Root - %s" % abbr,
 			"company_name": company, "company_abbr": abbr})
@@ -75,15 +75,14 @@
 		"group_or_ledger": "Ledger"})
 		
 	# create BOM
-	webnotes.insert([
-		{"doctype": "BOM", "item": "Nebula 7", "quantity": 1,
-			"is_active": "Yes", "is_default": 1, "uom": "Nos"},
-		{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
-			"opn_description": "Development"}, 
-		{"doctype": "BOM Item", "item_code": "Android Jack D", "operation_no": 1, 
-			"qty": 5, "rate": 20, "amount": 100, "stock_uom": "Nos", 
-			"parentfield": "bom_materials"}
-	])
+	# webnotes.insert(DocList([
+	# 	{"doctype": "BOM", "item": "Nebula 7", "quantity": 1,
+	# 		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
+	# 	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
+	# 		"opn_description": "Development"}, 
+	# 	{"doctype": "BOM Item", "item_code": "Android Jack D", "operation_no": 1, "qty": 5, 
+	# 		"rate": 20, "amount": 100, "stock_uom": "Nos", "parentfield": "bom_materials"}
+	# ]))
 
 
 base_purchase_receipt = [
@@ -139,8 +138,6 @@
 			acc_name = "%s - %s" % (acc['account_name'], d['abbr'])
 			if not webnotes.conn.exists('Account', acc_name):
 				webnotes.insert(acc)
-			else:
-				print "Account %s already exists" % acc_name
 						
 def make_account_dict(account, parent, company_detail, group_or_ledger):
 	return {
@@ -166,7 +163,6 @@
 	
 	def run_purchase_receipt_test(self, purchase_receipt, debit_account, 
 			credit_account, stock_value):
-		from webnotes.model.doclist import DocList	
 		dl = webnotes.insert(DocList(purchase_receipt))
 		
 		from controllers.tax_controller import TaxController
diff --git a/stock/report/purchase_order_items_pending_to_be_received/__init__.py b/stock/report/purchase_order_items_pending_to_be_received/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/stock/report/purchase_order_items_pending_to_be_received/__init__.py
diff --git a/stock/report/purchase_order_items_pending_to_be_received/purchase_order_items_pending_to_be_received.txt b/stock/report/purchase_order_items_pending_to_be_received/purchase_order_items_pending_to_be_received.txt
new file mode 100644
index 0000000..208909c
--- /dev/null
+++ b/stock/report/purchase_order_items_pending_to_be_received/purchase_order_items_pending_to_be_received.txt
@@ -0,0 +1,20 @@
+[
+ {
+  "creation": "2013-01-29 13:12:48", 
+  "docstatus": 0, 
+  "modified": "2013-01-29 13:16:52", 
+  "modified_by": "Administrator", 
+  "owner": "Administrator"
+ }, 
+ {
+  "doctype": "Report", 
+  "is_standard": "Yes", 
+  "name": "__common__", 
+  "query": "select \n `tabPurchase Order`.`name` as \"Purchase Order:Link/Purchase Order:120\",\n `tabPurchase Order`.`transaction_date` as \"Date:Date:100\",\n `tabPurchase Order`.`supplier` as \"Supplier:Link/Supplier:120\",\n `tabPurchase Order Item`.item_code as \"Item Code:Link/Item:120\",\n `tabPurchase Order Item`.description as \"Description::180\",\n `tabPurchase Order Item`.qty as \"Qty:Float:100\",\n `tabPurchase Order Item`.received_qty as \"Received Qty:Float:100\"\nfrom\n `tabPurchase Order`, `tabPurchase Order Item`\nwhere\n `tabPurchase Order Item`.`parent` = `tabPurchase Order`.`name`\n and `tabPurchase Order`.docstatus = 1\n and ifnull(`tabPurchase Order Item`.received_qty, 0) < ifnull(`tabPurchase Order Item`.qty, 0)\norder by `tabPurchase Order`.transaction_date asc", 
+  "ref_doctype": "Purchase Receipt"
+ }, 
+ {
+  "doctype": "Report", 
+  "name": "Purchase Order Items Pending To Be Received"
+ }
+]
\ No newline at end of file
diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py
index 8502041..b84b374 100644
--- a/utilities/transaction_base.py
+++ b/utilities/transaction_base.py
@@ -16,16 +16,13 @@
 
 from __future__ import unicode_literals
 import webnotes
-from webnotes.utils import load_json, cstr, flt, get_defaults
+from webnotes.utils import load_json, cstr, flt
 from webnotes.model.doc import addchild
-from webnotes.model.wrapper import copy_doclist
 
 from webnotes.model.controller import DocListController
 
 class TransactionBase(DocListController):
-
 	# Get Customer Default Primary Address - first load
-	# -----------------------
 	def get_default_customer_address(self, args=''):
 		address_text, address_name = self.get_address_text(customer=self.doc.customer)
 		self.doc.customer_address = address_name or ''