diff --git a/selling/doctype/sales_common/sales_common.py b/selling/doctype/sales_common/sales_common.py
deleted file mode 100644
index 3be27b2..0000000
--- a/selling/doctype/sales_common/sales_common.py
+++ /dev/null
@@ -1,343 +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 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:
-			dbcr = webnotes.conn.sql("""select sum(debit), sum(credit) from `tabGL Entry` 
-				where account = %s""", acc_head[0][0])
-			tot_outstanding = flt(dbcr[0][0])-flt(dbcr[0][1]) if dbcr else 0
-
-			exact_outstanding = flt(tot_outstanding) + flt(grand_total)
-			get_obj('Account',acc_head[0][0]).check_credit_limit(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})
