diff --git a/selling/doctype/sales_common/sales_common.py b/selling/doctype/sales_common/sales_common.py
deleted file mode 100644
index ad626da..0000000
--- a/selling/doctype/sales_common/sales_common.py
+++ /dev/null
@@ -1,348 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import webnotes
-
-from webnotes.utils import cint, cstr, flt
-from webnotes.model.doc import addchild
-from webnotes.model.bean import getlist
-from webnotes.model.code import get_obj
-from webnotes import msgprint, _
-from setup.utils import get_company_currency
-
-get_value = webnotes.conn.get_value
-
-from utilities.transaction_base import TransactionBase
-
-class DocType(TransactionBase):
-	def __init__(self,d,dl):
-		self.doc, self.doclist = d, dl
-
-
-	def get_contact_details(self, obj = '', primary = 0):
-		cond = " and contact_name = '"+cstr(obj.doc.contact_person)+"'"
-		if primary: cond = " and is_primary_contact = 'Yes'"
-		contact = webnotes.conn.sql("select contact_name, contact_no, email_id, contact_address from `tabContact` where customer = '%s' and docstatus != 2 %s" %(obj.doc.customer, cond), as_dict = 1)
-		if not contact:
-			return
-		c = contact[0]
-		obj.doc.contact_person = c['contact_name'] or ''
-		obj.doc.contact_no = c['contact_no'] or ''
-		obj.doc.email_id = c['email_id'] or ''
-		obj.doc.customer_mobile_no = c['contact_no'] or ''
-		if c['contact_address']:
-			obj.doc.customer_address = c['contact_address']
-
-	def get_invoice_details(self, obj = ''):
-		if obj.doc.company:
-			acc_head = webnotes.conn.sql("select name from `tabAccount` where name = '%s' and docstatus != 2" % (cstr(obj.doc.customer) + " - " + webnotes.conn.get_value('Company', obj.doc.company, 'abbr')))
-			obj.doc.debit_to = acc_head and acc_head[0][0] or ''
-			
-	def get_tax_details(self, item_code, obj):
-		import json
-		tax = webnotes.conn.sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , item_code)
-		t = {}
-		for x in tax: t[x[0]] = flt(x[1])
-		ret = {
-			'item_tax_rate'		:	tax and json.dumps(t) or ''
-		}
-		return ret
-
-	def get_serial_details(self, serial_no, obj):
-		import json
-		item = webnotes.conn.sql("select item_code, make, label,brand, description from `tabSerial No` where name = '%s' and docstatus != 2" %(serial_no), as_dict=1)
-		tax = webnotes.conn.sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , item[0]['item_code'])
-		t = {}
-		for x in tax: t[x[0]] = flt(x[1])
-		ret = {
-			'item_code'				: item and item[0]['item_code'] or '',
-			'make'						 : item and item[0]['make'] or '',
-			'label'						: item and item[0]['label'] or '',
-			'brand'						: item and item[0]['brand'] or '',
-			'description'			: item and item[0]['description'] or '',
-			'item_tax_rate'		: json.dumps(t)
-		}
-		return ret
-		
-	# To verify whether rate entered in details table does not exceed max discount %
-	# =======================================================================================
-	def validate_max_discount(self,obj, detail_table):
-		for d in getlist(obj.doclist, detail_table):
-			discount = webnotes.conn.sql("select max_discount from tabItem where name = '%s'" %(d.item_code),as_dict = 1)
-			if discount and discount[0]['max_discount'] and (flt(d.adj_rate)>flt(discount[0]['max_discount'])):
-				msgprint("You cannot give more than " + cstr(discount[0]['max_discount']) + " % discount on Item Code : "+cstr(d.item_code))
-				raise Exception
-			
-	# Get Tax rate if account type is TAX
-	# =========================================================================
-	def get_rate(self, arg):
-		arg = eval(arg)
-		rate = webnotes.conn.sql("select account_type, tax_rate from `tabAccount` where name = '%s' and docstatus != 2" %(arg['account_head']), as_dict=1)
-		ret = {'rate' : 0}
-		if arg['charge_type'] == 'Actual' and rate[0]['account_type'] == 'Tax':
-			msgprint("You cannot select ACCOUNT HEAD of type TAX as your CHARGE TYPE is 'ACTUAL'")
-			ret = {
-				'account_head'	:	''
-			}
-		elif rate[0]['account_type'] in ['Tax', 'Chargeable'] and not arg['charge_type'] == 'Actual':
-			ret = {
-				'rate'	:	rate and flt(rate[0]['tax_rate']) or 0
-			}
-		return ret
-
-
-	def get_item_list(self, obj, is_stopped=0):
-		"""get item list"""
-		il = []
-		for d in getlist(obj.doclist, obj.fname):
-			reserved_warehouse = ""
-			reserved_qty_for_main_item = 0
-			
-			if obj.doc.doctype == "Sales Order":
-				if (webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == 'Yes' or 
-					self.has_sales_bom(d.item_code)) and not d.reserved_warehouse:
-						webnotes.throw(_("Please enter Reserved Warehouse for item ") + 
-							d.item_code + _(" as it is stock Item or packing item"))
-				reserved_warehouse = d.reserved_warehouse
-				if flt(d.qty) > flt(d.delivered_qty):
-					reserved_qty_for_main_item = flt(d.qty) - flt(d.delivered_qty)
-				
-			if obj.doc.doctype == "Delivery Note" and d.prevdoc_doctype == 'Sales Order':
-				# if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12.
-				# But in this case reserved qty should only be reduced by 10 and not 12
-				
-				already_delivered_qty = self.get_already_delivered_qty(obj.doc.name, 
-					d.prevdoc_docname, d.prevdoc_detail_docname)
-				so_qty, reserved_warehouse = self.get_so_qty_and_warehouse(d.prevdoc_detail_docname)
-				
-				if already_delivered_qty + d.qty > so_qty:
-					reserved_qty_for_main_item = -(so_qty - already_delivered_qty)
-				else:
-					reserved_qty_for_main_item = -flt(d.qty)
-
-			if self.has_sales_bom(d.item_code):
-				for p in getlist(obj.doclist, 'packing_details'):
-					if p.parent_detail_docname == d.name and p.parent_item == d.item_code:
-						# the packing details table's qty is already multiplied with parent's qty
-						il.append(webnotes._dict({
-							'warehouse': p.warehouse,
-							'reserved_warehouse': reserved_warehouse,
-							'item_code': p.item_code,
-							'qty': flt(p.qty),
-							'reserved_qty': (flt(p.qty)/flt(d.qty)) * reserved_qty_for_main_item,
-							'uom': p.uom,
-							'batch_no': cstr(p.batch_no).strip(),
-							'serial_no': cstr(p.serial_no).strip(),
-							'name': d.name
-						}))
-			else:
-				il.append(webnotes._dict({
-					'warehouse': d.warehouse,
-					'reserved_warehouse': reserved_warehouse,
-					'item_code': d.item_code,
-					'qty': d.qty,
-					'reserved_qty': reserved_qty_for_main_item,
-					'uom': d.stock_uom,
-					'batch_no': cstr(d.batch_no).strip(),
-					'serial_no': cstr(d.serial_no).strip(),
-					'name': d.name
-				}))
-		return il
-
-	def get_already_delivered_qty(self, dn, so, so_detail):
-		qty = webnotes.conn.sql("""select sum(qty) from `tabDelivery Note Item` 
-			where prevdoc_detail_docname = %s and docstatus = 1 
-			and prevdoc_doctype = 'Sales Order' and prevdoc_docname = %s 
-			and parent != %s""", (so_detail, so, dn))
-		return qty and flt(qty[0][0]) or 0.0
-
-	def get_so_qty_and_warehouse(self, so_detail):
-		so_item = webnotes.conn.sql("""select qty, reserved_warehouse from `tabSales Order Item`
-			where name = %s and docstatus = 1""", so_detail, as_dict=1)
-		so_qty = so_item and flt(so_item[0]["qty"]) or 0.0
-		so_warehouse = so_item and so_item[0]["reserved_warehouse"] or ""
-		return so_qty, so_warehouse
-
-	def has_sales_bom(self, item_code):
-		return webnotes.conn.sql("select name from `tabSales BOM` where new_item_code=%s and docstatus != 2", item_code)
-	
-	def get_sales_bom_items(self, item_code):
-		return webnotes.conn.sql("""select t1.item_code, t1.qty, t1.uom 
-			from `tabSales BOM Item` t1, `tabSales BOM` t2 
-			where t2.new_item_code=%s and t1.parent = t2.name""", item_code, as_dict=1)
-
-	def get_packing_item_details(self, item):
-		return webnotes.conn.sql("select item_name, description, stock_uom from `tabItem` where name = %s", item, as_dict = 1)[0]
-
-	def get_bin_qty(self, item, warehouse):
-		det = webnotes.conn.sql("select actual_qty, projected_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (item, warehouse), as_dict = 1)
-		return det and det[0] or ''
-
-	def update_packing_list_item(self,obj, packing_item_code, qty, warehouse, line):
-		bin = self.get_bin_qty(packing_item_code, warehouse)
-		item = self.get_packing_item_details(packing_item_code)
-
-		# check if exists
-		exists = 0
-		for d in getlist(obj.doclist, 'packing_details'):
-			if d.parent_item == line.item_code and d.item_code == packing_item_code and d.parent_detail_docname == line.name:
-				pi, exists = d, 1
-				break
-
-		if not exists:
-			pi = addchild(obj.doc, 'packing_details', 'Delivery Note Packing Item', 
-				obj.doclist)
-
-		pi.parent_item = line.item_code
-		pi.item_code = packing_item_code
-		pi.item_name = item['item_name']
-		pi.parent_detail_docname = line.name
-		pi.description = item['description']
-		pi.uom = item['stock_uom']
-		pi.qty = flt(qty)
-		pi.actual_qty = bin and flt(bin['actual_qty']) or 0
-		pi.projected_qty = bin and flt(bin['projected_qty']) or 0
-		pi.prevdoc_doctype = line.prevdoc_doctype
-		if not pi.warehouse:
-			pi.warehouse = warehouse
-		if not pi.batch_no:
-			pi.batch_no = cstr(line.batch_no)
-		pi.idx = self.packing_list_idx
-		
-		# saved, since this function is called on_update of delivery note
-		pi.save()
-		
-		self.packing_list_idx += 1
-
-
-	def make_packing_list(self, obj, fname):
-		"""make packing list for sales bom item"""
-		self.packing_list_idx = 0
-		parent_items = []
-		for d in getlist(obj.doclist, fname):
-			warehouse = fname == "sales_order_details" and d.reserved_warehouse or d.warehouse
-			if self.has_sales_bom(d.item_code):
-				for i in self.get_sales_bom_items(d.item_code):
-					self.update_packing_list_item(obj, i['item_code'], flt(i['qty'])*flt(d.qty), warehouse, d)
-
-				if [d.item_code, d.name] not in parent_items:
-					parent_items.append([d.item_code, d.name])
-				
-		obj.doclist = self.cleanup_packing_list(obj, parent_items)
-		
-		return obj.doclist
-		
-	def cleanup_packing_list(self, obj, parent_items):
-		"""Remove all those child items which are no longer present in main item table"""
-		delete_list = []
-		for d in getlist(obj.doclist, 'packing_details'):
-			if [d.parent_item, d.parent_detail_docname] not in parent_items:
-				# mark for deletion from doclist
-				delete_list.append(d.name)
-
-		if not delete_list:
-			return obj.doclist
-		
-		# delete from doclist
-		obj.doclist = webnotes.doclist(filter(lambda d: d.name not in delete_list, obj.doclist))
-		
-		# delete from db
-		webnotes.conn.sql("""\
-			delete from `tabDelivery Note Packing Item`
-			where name in (%s)"""
-			% (", ".join(["%s"] * len(delete_list))),
-			tuple(delete_list))
-			
-		return obj.doclist
-		
-
-	def get_month(self,date):
-		"""Get month based on date (required in sales person and sales partner)"""
-		month_list = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
-		month_idx = cint(cstr(date).split('-')[1])-1
-		return month_list[month_idx]
-		
-		
-	# **** Check for Stop SO as no transactions can be made against Stopped SO. Need to unstop it. ***
-	def check_stop_sales_order(self,obj):
-		for d in getlist(obj.doclist,obj.fname):
-			ref_doc_name = ''
-			if d.fields.has_key('prevdoc_docname') and d.prevdoc_docname and d.prevdoc_doctype == 'Sales Order':
-				ref_doc_name = d.prevdoc_docname
-			elif d.fields.has_key('sales_order') and d.sales_order and not d.delivery_note:
-				ref_doc_name = d.sales_order
-			if ref_doc_name:
-				so_status = webnotes.conn.sql("select status from `tabSales Order` where name = %s",ref_doc_name)
-				so_status = so_status and so_status[0][0] or ''
-				if so_status == 'Stopped':
-					msgprint("You cannot do any transaction against Sales Order : '%s' as it is Stopped." %(ref_doc_name))
-					raise Exception
-
-	def check_active_sales_items(self,obj):
-		for d in getlist(obj.doclist, obj.fname):
-			if d.item_code:
-				item = webnotes.conn.sql("""select docstatus, is_sales_item, 
-					is_service_item, default_income_account from tabItem where name = %s""", 
-					d.item_code, as_dict=True)[0]
-				if item.is_sales_item == 'No' and item.is_service_item == 'No':
-					msgprint("Item : '%s' is neither Sales nor Service Item" % (d.item_code))
-					raise Exception
-				if d.income_account and not item.default_income_account:
-					webnotes.conn.set_value("Item", d.item_code, "default_income_account", d.income_account)
-
-
-	def check_credit(self,obj,grand_total):
-		acc_head = webnotes.conn.sql("select name from `tabAccount` where company = '%s' and master_name = '%s'"%(obj.doc.company, obj.doc.customer))
-		if acc_head:
-			tot_outstanding = 0
-			dbcr = webnotes.conn.sql("""select sum(debit), sum(credit) from `tabGL Entry` 
-				where account = %s""", acc_head[0][0])
-			if dbcr:
-				tot_outstanding = flt(dbcr[0][0])-flt(dbcr[0][1])
-
-			exact_outstanding = flt(tot_outstanding) + flt(grand_total)
-			get_obj('Account',acc_head[0][0]).check_credit_limit(acc_head[0][0], obj.doc.company, exact_outstanding)
-
-	def get_prevdoc_date(self, obj):
-		for d in getlist(obj.doclist, obj.fname):
-			if d.prevdoc_doctype and d.prevdoc_docname:
-				if d.prevdoc_doctype in ["Sales Invoice", "Delivery Note"]:
-					date_field = "posting_date"
-				else:
-					date_field = "transaction_date"
-					
-				d.prevdoc_date = webnotes.conn.get_value(d.prevdoc_doctype, 
-					d.prevdoc_docname, date_field)
-
-def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
-	from controllers.queries import get_match_cond
-
-	if filters.has_key('warehouse'):
-		return webnotes.conn.sql("""select batch_no from `tabStock Ledger Entry` sle 
-				where item_code = '%(item_code)s' 
-					and warehouse = '%(warehouse)s' 
-					and batch_no like '%(txt)s' 
-					and exists(select * from `tabBatch` 
-							where name = sle.batch_no 
-								and (ifnull(expiry_date, '')='' or expiry_date >= '%(posting_date)s') 
-								and docstatus != 2) 
-					%(mcond)s
-				group by batch_no having sum(actual_qty) > 0 
-				order by batch_no desc 
-				limit %(start)s, %(page_len)s """ % {'item_code': filters['item_code'], 
-					'warehouse': filters['warehouse'], 'posting_date': filters['posting_date'], 
-					'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype, searchfield), 
-					'start': start, 'page_len': page_len})
-	else:
-		return webnotes.conn.sql("""select name from tabBatch 
-				where docstatus != 2 
-					and item = '%(item_code)s' 
-					and (ifnull(expiry_date, '')='' or expiry_date >= '%(posting_date)s')
-					and name like '%(txt)s' 
-					%(mcond)s 
-				order by name desc 
-				limit %(start)s, %(page_len)s""" % {'item_code': filters['item_code'], 
-				'posting_date': filters['posting_date'], 'txt': "%%%s%%" % txt, 
-				'mcond':get_match_cond(doctype, searchfield),'start': start, 
-				'page_len': page_len})
