Merge pull request #5529 from saurabh6790/module_flow

[fix] previous document links
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 71e9c42..1e02415 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -35,6 +35,25 @@
 			'percent_join_field': 'purchase_order',
 			'overflow_type': 'billing'
 		}]
+		
+		self.prev_link_mapper = {
+			"Purchase Order": {
+				"fieldname": "purchase_order",
+				"doctype": "Purchase Invoice Item",
+				"filters": [
+					["Purchase Invoice Item", "parent", "=", self.name],
+					["Purchase Invoice Item", "purchase_order", "!=", ""]
+				]
+			},
+			"Purchase Receipt": {
+				"fieldname": "purchase_receipt",
+				"doctype": "Purchase Invoice Item",
+				"filters": [
+					["Purchase Invoice Item", "parent", "=", self.item],
+					["Purchase Invoice Item", "purchase_receipt", "!=", ""]
+				]
+			}
+		}
 
 	def validate(self):
 		if not self.is_opening:
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 8f7c341..2f1ecf1 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -38,6 +38,25 @@
 			'keyword': 'Billed',
 			'overflow_type': 'billing'
 		}]
+		
+		self.prev_link_mapper = {
+			"Sales Order": {
+				"fieldname": "sales_order",
+				"doctype": "Sales Invoice Item",
+				"filters": [
+					["Sales Invoice Item", "parent", "=", self.name],
+					["Sales Invoice Item", "sales_order", "!=", ""]
+				]
+			},
+			"Delivery Note": {
+				"fieldname": "delivery_note",
+				"doctype": "Sales Invoice Item",
+				"filters": [
+					["Sales Invoice Item", "parent", "=", self.name],
+					["Sales Invoice Item", "delivery_note", "!=", ""]
+				]
+			}
+		}
 
 	def set_indicator(self):
 		"""Set indicator for portal"""
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 6184236..d4b2221 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -32,6 +32,17 @@
 			'percent_join_field': 'prevdoc_docname',
 			'overflow_type': 'order'
 		}]
+		
+		self.prev_link_mapper = {
+			"Supplier Quotation": {
+				"fieldname": "supplier_quotation",
+				"doctype": "Purchase Order Item",
+				"filters": [
+					["Purchase Order Item", "parent", "=", self.name],
+					["Purchase Order Item", "supplier_quotation", "!=", ""]
+				]
+			}
+		}
 
 	def validate(self):
 		super(PurchaseOrder, self).validate()
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 2e0a272..8103756 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -21,6 +21,20 @@
 class WarehouseRequired(frappe.ValidationError): pass
 
 class SalesOrder(SellingController):
+	def __init__(self, arg1, arg2=None):
+		super(SalesOrder, self).__init__(arg1, arg2)
+		
+		self.prev_link_mapper = {
+			"Quotation": {
+				"fieldname": "prevdoc_docname",
+				"doctype": "Sales Order Item",
+				"filters": [
+					["Sales Order Item", "parent", "=", self.name],
+					["Sales Order Item", "prevdoc_docname", "!=", ""]
+				]
+			}
+		}
+		
 	def validate(self):
 		super(SalesOrder, self).validate()
 
@@ -306,7 +320,7 @@
 		mcount = month_map[reference_doc.recurring_type]
 		self.set("delivery_date", get_next_date(reference_doc.delivery_date, mcount,
 						cint(reference_doc.repeat_on_day_of_month)))
-
+		
 def get_list_context(context=None):
 	from erpnext.controllers.website_list_for_contact import get_list_context
 	list_context = get_list_context(context)
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 6c6a3b3..d8defc0 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -60,7 +60,19 @@
 			'source_field': '-1 * qty',
 			'extra_cond': """ and exists (select name from `tabDelivery Note` where name=`tabDelivery Note Item`.parent and is_return=1)"""
 		}]
+		
+		self.prev_link_mapper = {
+			"Sales Order": {
+				"fieldname": "against_sales_order",
+				"doctype": "Delivery Note Item",
+				"filters": [
+					["Delivery Note Item", "parent", "=", self.name],
+					["Delivery Note Item", "against_sales_order", "!=", ""]
+				]
+			}
+		}
 
+		
 	def before_print(self):
 		def toggle_print_hide(meta, fieldname):
 			df = meta.get_field(fieldname)
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 70cef36..6c72d6b 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -45,6 +45,17 @@
 			# 'overflow_type': 'receipt',
 			'extra_cond': """ and exists (select name from `tabPurchase Receipt` where name=`tabPurchase Receipt Item`.parent and is_return=1)"""
 		}]
+		
+		self.prev_link_mapper = {
+			"Purchase Order": {
+				"fieldname": "prevdoc_docname",
+				"doctype": "Purchase Receipt Item",
+				"filters": [
+					["Purchase Receipt Item", "parent", "=", self.name],
+					["Purchase Receipt Item", "prevdoc_docname", "!=", ""]
+				]
+			}
+		}
 
 	def validate(self):
 		super(PurchaseReceipt, self).validate()
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index d088f59..3cc79ef 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -107,6 +107,24 @@
 						frappe.throw(_("Row #{0}: Rate must be same as {1}: {2} ({3} / {4}) ")
 							.format(d.idx, ref_dt, d.get(ref_dn_field), d.rate, ref_rate))
 
+	def get_link_filters(self, for_doctype):
+		if hasattr(self, "prev_link_mapper") and self.prev_link_mapper.get(for_doctype):
+			fieldname = self.prev_link_mapper[for_doctype]["fieldname"]
+			
+			values = filter(None, tuple([item.as_dict()[fieldname] for item in self.items]))
+
+			if values:
+				ret = {
+					for_doctype : {
+						"filters": [[for_doctype, "name", "in", values]]
+					}
+				}
+			else:
+				ret = None
+		else:
+			ret = None
+		
+		return ret
 
 def delete_events(ref_type, ref_name):
 	frappe.delete_doc("Event", frappe.db.sql_list("""select name from `tabEvent`