feat: Link blanket order and quotation
diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.js b/erpnext/manufacturing/doctype/blanket_order/blanket_order.js
index 1cd9446..4c31bd0 100644
--- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.js
+++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.js
@@ -14,27 +14,37 @@
 	refresh: function(frm) {
 		erpnext.hide_company();
 		if (frm.doc.customer && frm.doc.docstatus === 1) {
-			frm.add_custom_button(__('View Orders'), function() {
-				frappe.set_route('List', 'Sales Order', {blanket_order: frm.doc.name});
-			});
-			frm.add_custom_button(__("Create Sales Order"), function(){
+			frm.add_custom_button(__("Sales Order"), function() {
 				frappe.model.open_mapped_doc({
-					method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_sales_order",
-					frm: frm
+					method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order",
+					frm: frm,
+					args: {
+						doctype: 'Sales Order'
+					}
 				});
-			}).addClass("btn-primary");
+			}, __('Create'));
+
+			frm.add_custom_button(__("Quotation"), function() {
+				frappe.model.open_mapped_doc({
+					method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order",
+					frm: frm,
+					args: {
+						doctype: 'Quotation'
+					}
+				});
+			}, __('Create'));
 		}
 
 		if (frm.doc.supplier && frm.doc.docstatus === 1) {
-			frm.add_custom_button(__('View Orders'), function() {
-				frappe.set_route('List', 'Purchase Order', {blanket_order: frm.doc.name});
-			});
-			frm.add_custom_button(__("Create Purchase Order"), function(){
+			frm.add_custom_button(__("Purchase Order"), function(){
 				frappe.model.open_mapped_doc({
-					method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_purchase_order",
-					frm: frm
+					method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order",
+					frm: frm,
+					args: {
+						doctype: 'Purchase Order'
+					}
 				});
-			}).addClass("btn-primary");
+			}, __('Create'));
 		}
 	},
 
diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
index 38118bd..5eb4c51 100644
--- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
+++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py
@@ -17,7 +17,7 @@
 
 	def validate_dates(self):
 		if getdate(self.from_date) > getdate(self.to_date):
-			frappe.throw(_("From date cannot be greater than To date")) 
+			frappe.throw(_("From date cannot be greater than To date"))
 
 	def update_ordered_qty(self):
 		ref_doctype = "Sales Order" if self.blanket_order_type == "Selling" else "Purchase Order"
@@ -35,7 +35,14 @@
 			d.db_set("ordered_qty", item_ordered_qty.get(d.item_code, 0))
 
 @frappe.whitelist()
-def make_sales_order(source_name):
+def make_order(source_name):
+	doctype = frappe.flags.args.doctype
+
+	def update_doc(source_doc, target_doc, source_parent):
+		if doctype == 'Quotation':
+			target_doc.quotation_to = 'Customer'
+			target_doc.party_name = source_doc.customer
+
 	def update_item(source, target, source_parent):
 		target_qty = source.get("qty") - source.get("ordered_qty")
 		target.qty = target_qty if not flt(target_qty) < 0 else 0
@@ -49,10 +56,11 @@
 
 	target_doc = get_mapped_doc("Blanket Order", source_name, {
 		"Blanket Order": {
-			"doctype": "Sales Order"
+			"doctype": doctype,
+			"postprocess": update_doc
 		},
 		"Blanket Order Item": {
-			"doctype": "Sales Order Item",
+			"doctype": doctype + " Item",
 			"field_map": {
 				"rate": "blanket_order_rate",
 				"parent": "blanket_order"
@@ -62,31 +70,31 @@
 	})
 	return target_doc
 
-@frappe.whitelist()
-def make_purchase_order(source_name):
-	def update_item(source, target, source_parent):
-		target_qty = source.get("qty") - source.get("ordered_qty")
-		target.qty = target_qty if not flt(target_qty) < 0 else 0
-		item = get_item_defaults(target.item_code, source_parent.company)
-		if item:
-			target.item_name = item.get("item_name")
-			target.description = item.get("description")
-			target.uom = item.get("stock_uom")
-			target.warehouse = item.get("default_warehouse")
-			target.against_blanket_order = 1
-			target.blanket_order = source_name
+# @frappe.whitelist()
+# def make_purchase_order(source_name):
+# 	def update_item(source, target, source_parent):
+# 		target_qty = source.get("qty") - source.get("ordered_qty")
+# 		target.qty = target_qty if not flt(target_qty) < 0 else 0
+# 		item = get_item_defaults(target.item_code, source_parent.company)
+# 		if item:
+# 			target.item_name = item.get("item_name")
+# 			target.description = item.get("description")
+# 			target.uom = item.get("stock_uom")
+# 			target.warehouse = item.get("default_warehouse")
+# 			target.against_blanket_order = 1
+# 			target.blanket_order = source_name
 
-	target_doc = get_mapped_doc("Blanket Order", source_name, {
-		"Blanket Order": {
-			"doctype": "Purchase Order"
-		},
-		"Blanket Order Item": {
-			"doctype": "Purchase Order Item",
-			"field_map": {
-				"rate": "blanket_order_rate",
-				"parent": "blanket_order"
-			},
-			"postprocess": update_item
-		}
-	})
-	return target_doc
\ No newline at end of file
+# 	target_doc = get_mapped_doc("Blanket Order", source_name, {
+# 		"Blanket Order": {
+# 			"doctype": "Purchase Order"
+# 		},
+# 		"Blanket Order Item": {
+# 			"doctype": "Purchase Order Item",
+# 			"field_map": {
+# 				"rate": "blanket_order_rate",
+# 				"parent": "blanket_order"
+# 			},
+# 			"postprocess": update_item
+# 		}
+# 	})
+# 	return target_doc
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py
index ed319a0..d9aa0ca 100644
--- a/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py
+++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order_dashboard.py
@@ -6,7 +6,7 @@
 		'fieldname': 'blanket_order',
 		'transactions': [
 			{
-				'items': ['Purchase Order', 'Sales Order']
+				'items': ['Purchase Order', 'Sales Order', 'Quotation']
 			}
 		]
 	}
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 9a5b750..dbe48ec 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -6,7 +6,7 @@
 
 	apply_pricing_rule_on_item: function(item){
 		let effective_item_rate = item.price_list_rate;
-		if (item.parenttype === "Sales Order" && item.blanket_order_rate) {
+		if (in_list(["Sales Order", "Quotation"], item.parenttype) && item.blanket_order_rate) {
 			effective_item_rate = item.blanket_order_rate;
 		}
 		if(item.margin_type == "Percentage"){
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index b79c91c..7c47b8a 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -155,6 +155,11 @@
 	def update_item(obj, target, source_parent):
 		target.stock_qty = flt(obj.qty) * flt(obj.conversion_factor)
 
+		if obj.against_blanket_order:
+			target.against_blanket_order = obj.against_blanket_order
+			target.blanket_order = obj.blanket_order
+			target.blanket_order_rate = obj.blanket_order_rate
+
 	doclist = get_mapped_doc("Quotation", source_name, {
 			"Quotation": {
 				"doctype": "Sales Order",
diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json
index 3ff5555..d50397c 100644
--- a/erpnext/selling/doctype/quotation_item/quotation_item.json
+++ b/erpnext/selling/doctype/quotation_item/quotation_item.json
@@ -55,6 +55,9 @@
   "weight_uom",
   "reference",
   "warehouse",
+  "against_blanket_order",
+  "blanket_order",
+  "blanket_order_rate",
   "column_break_30",
   "prevdoc_doctype",
   "prevdoc_docname",
@@ -573,12 +576,38 @@
    "fieldname": "image_section",
    "fieldtype": "Section Break",
    "label": "Image"
+  },
+  {
+   "depends_on": "eval:doc.against_blanket_order",
+   "fieldname": "blanket_order",
+   "fieldtype": "Link",
+   "label": "Blanket Order",
+   "no_copy": 1,
+   "options": "Blanket Order",
+   "print_hide": 1
+  },
+  {
+   "depends_on": "eval:doc.against_blanket_order",
+   "fieldname": "blanket_order_rate",
+   "fieldtype": "Currency",
+   "label": "Blanket Order Rate",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "against_blanket_order",
+   "fieldtype": "Check",
+   "label": "Against Blanket Order",
+   "no_copy": 1,
+   "print_hide": 1
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-03-05 14:18:58.783751",
+ "modified": "2020-03-30 18:40:28.782720",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Quotation Item",