fix: Commonfied code for inter-company-transaction
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 0af273c..95d49a4 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -21,8 +21,8 @@
 from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_disabled
 from frappe.model.mapper import get_mapped_doc
 from six import iteritems
-from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_invoice,\
-	unlink_inter_company_invoice
+from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\
+	unlink_inter_company_doc
 from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
 from erpnext.accounts.deferred_revenue import validate_service_stop_date
 
@@ -348,7 +348,7 @@
 		self.make_gl_entries()
 
 		self.update_project()
-		update_linked_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
+		update_linked_doc(self.doctype, self.name, self.inter_company_invoice_reference)
 
 	def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
 		if not self.grand_total:
@@ -778,7 +778,7 @@
 		self.update_project()
 		frappe.db.set(self, 'status', 'Cancelled')
 
-		unlink_inter_company_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
+		unlink_inter_company_doc(self.doctype, self.name, self.inter_company_invoice_reference)
 
 	def update_project(self):
 		project_list = []
@@ -917,5 +917,5 @@
 
 @frappe.whitelist()
 def make_inter_company_sales_invoice(source_name, target_doc=None):
-	from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_invoice
-	return make_inter_company_invoice("Purchase Invoice", source_name, target_doc)
+	from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
+	return make_inter_company_transaction("Purchase Invoice", source_name, target_doc)
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 2089f15..31a9c66 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -179,7 +179,7 @@
 		if frappe.db.get_single_value('Selling Settings', 'sales_update_frequency') == "Each Transaction":
 			update_company_current_month_sales(self.company)
 			self.update_project()
-		update_linked_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
+		update_linked_doc(self.doctype, self.name, self.inter_company_invoice_reference)
 
 		# create the loyalty point ledger entry if the customer is enrolled in any loyalty program
 		if not self.is_return and self.loyalty_program:
@@ -243,7 +243,7 @@
 			against_si_doc.delete_loyalty_point_entry()
 			against_si_doc.make_loyalty_point_entry()
 
-		unlink_inter_company_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
+		unlink_inter_company_doc(self.doctype, self.name, self.inter_company_invoice_reference)
 
 		# Healthcare Service Invoice.
 		domain_settings = frappe.get_doc('Domain Settings')
@@ -1165,21 +1165,29 @@
 
 		self.set_missing_values(for_validate = True)
 
-def validate_inter_company_party(doctype, party, company, inter_company_invoice_reference):
-	if doctype == "Sales Invoice":
+def validate_inter_company_party(doctype, party, company, inter_company_reference):
+	if doctype in ["Sales Invoice", "Sales Order"]:
 		partytype, ref_partytype, internal = "Customer", "Supplier", "is_internal_customer"
-		ref_doc =  "Purchase Invoice"
+
+		if doctype == "Sales Invoice":
+			ref_doc = "Purchase Invoice"
+		else:
+			ref_doc = "Purchase Order"
 	else:
 		partytype, ref_partytype, internal = "Supplier", "Customer", "is_internal_supplier"
-		ref_doc =  "Sales Invoice"
 
-	if inter_company_invoice_reference:
-		doc = frappe.get_doc(ref_doc, inter_company_invoice_reference)
-		ref_party = doc.supplier if doctype == "Sales Invoice" else doc.customer
+		if doctype == "Purchase Invoice":
+			ref_doc = "Sales Invoice"
+		else:
+			ref_doc = "Sales Order"
+
+	if inter_company_reference:
+		doc = frappe.get_doc(ref_doc, inter_company_reference)
+		ref_party = doc.supplier if doctype in ["Sales Invoice", "Sales Order"] else doc.customer
 		if not frappe.db.get_value(partytype, {"represents_company": doc.company}, "name") == party:
-			frappe.throw(_("Invalid {0} for Inter Company Invoice.").format(partytype))
+			frappe.throw(_("Invalid {0} for Inter Company Transaction.").format(partytype))
 		if not frappe.get_cached_value(ref_partytype, ref_party, "represents_company") == company:
-			frappe.throw(_("Invalid Company for Inter Company Invoice."))
+			frappe.throw(_("Invalid Company for Inter Company Transaction."))
 
 	elif frappe.db.get_value(partytype, {"name": party, internal: 1}, "name") == party:
 		companies = frappe.db.sql("""select company from `tabAllowed To Transact With`
@@ -1188,18 +1196,29 @@
 		if not company in companies:
 			frappe.throw(_("{0} not allowed to transact with {1}. Please change the Company.").format(partytype, company))
 
-def update_linked_invoice(doctype, name, inter_company_invoice_reference):
-	if inter_company_invoice_reference:
-		frappe.db.set_value(doctype, inter_company_invoice_reference,\
-			"inter_company_invoice_reference", name)
+def update_linked_doc(doctype, name, inter_company_reference):
 
-def unlink_inter_company_invoice(doctype, name, inter_company_invoice_reference):
-	ref_doc = "Purchase Invoice" if doctype == "Sales Invoice" else "Sales Invoice"
-	if inter_company_invoice_reference:
-		frappe.db.set_value(doctype, name,\
-			"inter_company_invoice_reference", "")
-		frappe.db.set_value(ref_doc, inter_company_invoice_reference,\
-			"inter_company_invoice_reference", "")
+	if doctype in ["Sales Invoice", "Purchase Invoice"]:
+		ref_field = "inter_company_invoice_reference"
+	else:
+		ref_field = "inter_company_order_reference"
+
+	if inter_company_reference:
+		frappe.db.set_value(doctype, inter_company_reference,\
+			ref_field, name)
+
+def unlink_inter_company_doc(doctype, name, inter_company_reference):
+
+	if doctype in ["Sales Invoice", "Purchase Invoice"]:
+		ref_doc = "Purchase Invoice" if doctype == "Sales Invoice" else "Sales Invoice"
+		ref_field = "inter_company_invoice_reference"
+	else:
+		ref_doc = "Purchase Order" if doctype == "Sales Order" else "Sales Order"
+		ref_field = "inter_company_order_reference"
+
+	if inter_company_reference:
+		frappe.db.set_value(doctype, name, ref_field, "")
+		frappe.db.set_value(ref_doc, inter_company_reference, ref_field, "")
 
 def get_list_context(context=None):
 	from erpnext.controllers.website_list_for_contact import get_list_context
@@ -1299,7 +1318,7 @@
 			data.account = get_bank_cash_account(data.mode_of_payment, self.company).get("account")
 
 def get_inter_company_details(doc, doctype):
-	if doctype == "Sales Invoice":
+	if doctype in ["Sales Invoice", "Sales Order"]:
 		party = frappe.db.get_value("Supplier", {"disabled": 0, "is_internal_supplier": 1, "represents_company": doc.company}, "name")
 		company = frappe.get_cached_value("Customer", doc.customer, "represents_company")
 	else:
@@ -1312,21 +1331,21 @@
 	}
 
 
-def validate_inter_company_invoice(doc, doctype):
+def validate_inter_company_transaction(doc, doctype):
 
 	details = get_inter_company_details(doc, doctype)
-	price_list = doc.selling_price_list if doctype == "Sales Invoice" else doc.buying_price_list
+	price_list = doc.selling_price_list if doctype in ["Sales Invoice", "Sales Order"] else doc.buying_price_list
 	valid_price_list = frappe.db.get_value("Price List", {"name": price_list, "buying": 1, "selling": 1})
 	if not valid_price_list:
 		frappe.throw(_("Selected Price List should have buying and selling fields checked."))
 
 	party = details.get("party")
 	if not party:
-		partytype = "Supplier" if doctype == "Sales Invoice" else "Customer"
+		partytype = "Supplier" if doctype in ["Sales Invoice", "Sales Order"] else "Customer"
 		frappe.throw(_("No {0} found for Inter Company Transactions.").format(partytype))
 
 	company = details.get("company")
-	default_currency = frappe.get_cached_value('Company',  company,  "default_currency")
+	default_currency = frappe.get_cached_value('Company', company, "default_currency")
 	if default_currency != doc.currency:
 		frappe.throw(_("Company currencies of both the companies should match for Inter Company Transactions."))
 
@@ -1334,17 +1353,17 @@
 
 @frappe.whitelist()
 def make_inter_company_purchase_invoice(source_name, target_doc=None):
-	return make_inter_company_invoice("Sales Invoice", source_name, target_doc)
+	return make_inter_company_transaction("Sales Invoice", source_name, target_doc)
 
-def make_inter_company_invoice(doctype, source_name, target_doc=None):
-	if doctype == "Sales Invoice":
-		source_doc = frappe.get_doc("Sales Invoice", source_name)
-		target_doctype = "Purchase Invoice"
+def make_inter_company_transaction(doctype, source_name, target_doc=None):
+	if doctype in ["Sales Invoice", "Sales Order"]:
+		source_doc = frappe.get_doc(doctype, source_name)
+		target_doctype = "Purchase Invoice" if doctype == "Sales Invoice" else "Purchase Order"
 	else:
-		source_doc = frappe.get_doc("Purchase Invoice", source_name)
-		target_doctype = "Sales Invoice"
+		source_doc = frappe.get_doc(doctype, source_name)
+		target_doctype = "Sales Invoice" if doctype == "Purchase Invoice" else "Sales Order"
 
-	validate_inter_company_invoice(source_doc, doctype)
+	validate_inter_company_transaction(source_doc, doctype)
 	details = get_inter_company_details(source_doc, doctype)
 
 	def set_missing_values(source, target):
@@ -1352,7 +1371,7 @@
 
 	def update_details(source_doc, target_doc, source_parent):
 		target_doc.inter_company_invoice_reference = source_doc.name
-		if target_doc.doctype == "Purchase Invoice":
+		if target_doc.doctype in ["Purchase Invoice", "Purchase Order"]:
 			target_doc.company = details.get("company")
 			target_doc.supplier = details.get("party")
 			target_doc.buying_price_list = source_doc.selling_price_list
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index ae610f8..e5156a3 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -17,8 +17,8 @@
 from six import string_types
 from erpnext.stock.doctype.item.item import get_item_defaults
 from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
-from erpnext.selling.doctype.sales_order.sales_order import validate_inter_company_party, update_linked_order,\
-	unlink_inter_company_order
+from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\
+	unlink_inter_company_doc
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -222,7 +222,7 @@
 
 		self.update_blanket_order()
 
-		update_linked_order(self.doctype, self.name, self.inter_company_order_reference)
+		update_linked_doc(self.doctype, self.name, self.inter_company_order_reference)
 
 	def on_cancel(self):
 		super(PurchaseOrder, self).on_cancel()
@@ -248,7 +248,7 @@
 
 		self.update_blanket_order()
 
-		unlink_inter_company_order(self.doctype, self.name, self.inter_company_order_reference)
+		unlink_inter_company_doc(self.doctype, self.name, self.inter_company_order_reference)
 
 	def on_update(self):
 		pass
@@ -498,6 +498,6 @@
 
 @frappe.whitelist()
 def make_inter_company_sales_order(source_name, target_doc=None):
-	from erpnext.selling.doctype.sales_order.sales_order import make_inter_company_order
-	return make_inter_company_order("Purchase Order", source_name, target_doc)
+	from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
+	return make_inter_company_transaction("Purchase Order", source_name, target_doc)
 
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 6b51b96..fc11e11 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -19,6 +19,8 @@
 from erpnext.stock.doctype.item.item import get_item_defaults
 from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
 from erpnext.manufacturing.doctype.production_plan.production_plan import get_items_for_material_requests
+from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\
+	unlink_inter_company_doc
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -183,7 +185,7 @@
 
 		self.update_blanket_order()
 
-		update_linked_order(self.doctype, self.name, self.inter_company_order_reference)
+		update_linked_doc(self.doctype, self.name, self.inter_company_order_reference)
 
 	def on_cancel(self):
 		super(SalesOrder, self).on_cancel()
@@ -201,7 +203,7 @@
 
 		self.update_blanket_order()
 
-		unlink_inter_company_order(self.doctype, self.name, self.inter_company_order_reference)
+		unlink_inter_company_doc(self.doctype, self.name, self.inter_company_order_reference)
 
 	def update_project(self):
 		if frappe.db.get_single_value('Selling Settings', 'sales_update_frequency') != "Each Transaction":
@@ -460,42 +462,6 @@
 				Item {0} is added with and without Ensure Delivery by \
 				Serial No.").format(item.item_code))
 
-def validate_inter_company_party(doctype, party, company, inter_company_order_reference):
-	if doctype == "Sales Order":
-		partytype, ref_partytype, internal = "Customer", "Supplier", "is_internal_customer"
-		ref_doc =  "Purchase Order"
-	else:
-		partytype, ref_partytype, internal = "Supplier", "Customer", "is_internal_supplier"
-		ref_doc =  "Sales Order"
-
-	if inter_company_order_reference:
-		doc = frappe.get_doc(ref_doc, inter_company_order_reference)
-		ref_party = doc.supplier if doctype == "Sales Order" else doc.customer
-		if not frappe.db.get_value(partytype, {"represents_company": doc.company}, "name") == party:
-			frappe.throw(_("Invalid {0} for Inter Company Order.").format(partytype))
-		if not frappe.get_cached_value(ref_partytype, ref_party, "represents_company") == company:
-			frappe.throw(_("Invalid Company for Inter Company Order."))
-
-	elif frappe.db.get_value(partytype, {"name": party, internal: 1}, "name") == party:
-		companies = frappe.db.sql("""select company from `tabAllowed To Transact With`
-			where parenttype = '{0}' and parent = '{1}'""".format(partytype, party), as_list = 1) #nosec
-		companies = [d[0] for d in companies]
-		if not company in companies:
-			frappe.throw(_("{0} not allowed to transact with {1}. Please change the Company.").format(partytype, company))
-
-def update_linked_order(doctype, name, inter_company_order_reference):
-	if inter_company_order_reference:
-		frappe.db.set_value(doctype, inter_company_order_reference,\
-			"inter_company_order_reference", name)
-
-def unlink_inter_company_order(doctype, name, inter_company_order_reference):
-	ref_doc = "Purchase Order" if doctype == "Sales Order" else "Sales Order"
-	if inter_company_order_reference:
-		frappe.db.set_value(doctype, name,\
-			"inter_company_order_reference", "")
-		frappe.db.set_value(ref_doc, inter_company_order_reference,\
-			"inter_company_order_reference", "")
-
 def get_list_context(context=None):
 	from erpnext.controllers.website_list_for_contact import get_list_context
 	list_context = get_list_context(context)
@@ -1014,86 +980,7 @@
 	material_request.submit()
 	return material_request
 
-def get_inter_company_details(doc, doctype):
-	if doctype == "Sales Order":
-		party = frappe.db.get_value("Supplier", {"disabled": 0, "is_internal_supplier": 1, "represents_company": doc.company}, "name")
-		company = frappe.get_cached_value("Customer", doc.customer, "represents_company")
-	else:
-		party = frappe.db.get_value("Customer", {"disabled": 0, "is_internal_customer": 1, "represents_company": doc.company}, "name")
-		company = frappe.get_cached_value("Supplier", doc.supplier, "represents_company")
-
-	return {
-		"party": party,
-		"company": company
-	}
-
-def validate_inter_company_order(doc, doctype):
-
-	details = get_inter_company_details(doc, doctype)
-	price_list = doc.selling_price_list if doctype == "Sales Order" else doc.buying_price_list
-	valid_price_list = frappe.db.get_value("Price List", {"name": price_list, "buying": 1, "selling": 1})
-	if not valid_price_list:
-		frappe.throw(_("Selected Price List should have buying and selling fields checked."))
-
-	party = details.get("party")
-	if not party:
-		partytype = "Supplier" if doctype == "Sales Order" else "Customer"
-		frappe.throw(_("No {0} found for Inter Company Transactions.").format(partytype))
-
-	company = details.get("company")
-	default_currency = frappe.get_cached_value('Company',  company,  "default_currency")
-	if default_currency != doc.currency:
-		frappe.throw(_("Company currencies of both the companies should match for Inter Company Transactions."))
-
-	return
-
 @frappe.whitelist()
 def make_inter_company_purchase_order(source_name, target_doc=None):
-	return make_inter_company_order("Sales Order", source_name, target_doc)
-
-def make_inter_company_order(doctype, source_name, target_doc=None):
-	if doctype == "Sales Order":
-		source_doc = frappe.get_doc("Sales Order", source_name)
-		target_doctype = "Purchase Order"
-	else:
-		source_doc = frappe.get_doc("Purchase Order", source_name)
-		target_doctype = "Sales Order"
-
-	validate_inter_company_order(source_doc, doctype)
-	details = get_inter_company_details(source_doc, doctype)
-
-	def set_missing_values(source, target):
-		target.run_method("set_missing_values")
-
-	def update_details(source_doc, target_doc, source_parent):
-		target_doc.inter_company_order_reference = source_doc.name
-		if target_doc.doctype == "Purchase Order":
-			target_doc.company = details.get("company")
-			target_doc.supplier = details.get("party")
-			target_doc.buying_price_list = source_doc.selling_price_list
-		else:
-			target_doc.company = details.get("company")
-			target_doc.customer = details.get("party")
-			target_doc.selling_price_list = source_doc.buying_price_list
-
-	doclist = get_mapped_doc(doctype, source_name,	{
-		doctype: {
-			"doctype": target_doctype,
-			"postprocess": update_details,
-			"field_no_map": [
-				"taxes_and_charges"
-			]
-		},
-		doctype +" Item": {
-			"doctype": target_doctype + " Item",
-			"field_no_map": [
-				"income_account",
-				"expense_account",
-				"cost_center",
-				"warehouse"
-			]
-		}
-
-	}, target_doc, set_missing_values)
-
-	return doclist
\ No newline at end of file
+	from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
+	return make_inter_company_transaction("Sales Order", source_name, target_doc)