fix: pricing rule not working for production discount
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
index 971d308..f73fb10 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "allow_rename": 1,
  "autoname": "field:title",
@@ -439,19 +440,20 @@
   },
   {
    "default": "0",
-   "depends_on": "eval:!doc.mixed_conditions",
+   "depends_on": "eval:!doc.mixed_conditions && doc.price_or_product_discount == 'Price'",
    "fieldname": "same_item",
    "fieldtype": "Check",
    "label": "Same Item"
   },
   {
-   "depends_on": "eval:!doc.same_item || doc.mixed_conditions",
+   "depends_on": "eval:(!doc.same_item || doc.apply_on == 'Transaction') || doc.mixed_conditions",
    "fieldname": "free_item",
    "fieldtype": "Link",
    "label": "Free Item",
    "options": "Item"
   },
   {
+   "default": "0",
    "fieldname": "free_qty",
    "fieldtype": "Float",
    "label": "Qty"
@@ -554,7 +556,8 @@
  ],
  "icon": "fa fa-gift",
  "idx": 1,
- "modified": "2019-10-15 12:39:40.399792",
+ "links": [],
+ "modified": "2019-12-13 15:48:48.331495",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Pricing Rule",
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index e871d98..af6e4c8 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -182,7 +182,7 @@
 
 def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=False):
 	from erpnext.accounts.doctype.pricing_rule.utils import (get_pricing_rules,
-		get_applied_pricing_rules, get_pricing_rule_items)
+		get_applied_pricing_rules, get_pricing_rule_items, get_product_discount_rule)
 
 	if isinstance(doc, string_types):
 		doc = json.loads(doc)
@@ -241,9 +241,11 @@
 			if pricing_rule.coupon_code_based==1 and args.coupon_code==None:
 				return item_details
 				
-			if (not pricing_rule.validate_applied_rule and
-				pricing_rule.price_or_product_discount == "Price"):
-				apply_price_discount_pricing_rule(pricing_rule, item_details, args)
+			if not pricing_rule.validate_applied_rule:
+				if pricing_rule.price_or_product_discount == "Price":
+					apply_price_discount_rule(pricing_rule, item_details, args)
+				else:
+					get_product_discount_rule(pricing_rule, item_details)
 
 		item_details.has_pricing_rule = 1
 
@@ -293,7 +295,7 @@
 		'child_docname': args.get('child_docname')
 	})
 
-def apply_price_discount_pricing_rule(pricing_rule, item_details, args):
+def apply_price_discount_rule(pricing_rule, item_details, args):
 	item_details.pricing_rule_for = pricing_rule.rate_or_discount
 
 	if ((pricing_rule.margin_type == 'Amount' and pricing_rule.currency == args.currency)
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 637e503..346eba2 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -7,7 +7,7 @@
 import frappe, copy, json
 from frappe import throw, _
 from six import string_types
-from frappe.utils import flt, cint, get_datetime
+from frappe.utils import flt, cint, get_datetime, get_link_to_form
 from erpnext.setup.doctype.item_group.item_group import get_child_item_groups
 from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
 from erpnext.stock.get_item_details import get_conversion_factor
@@ -408,7 +408,8 @@
 	conditions = get_other_conditions(conditions, values, doc)
 
 	pricing_rules = frappe.db.sql(""" Select `tabPricing Rule`.* from `tabPricing Rule`
-		where {conditions} """.format(conditions = conditions), values, as_dict=1)
+		where  {conditions} and `tabPricing Rule`.disable = 0
+	""".format(conditions = conditions), values, as_dict=1)
 
 	if pricing_rules:
 		pricing_rules = filter_pricing_rules_for_qty_amount(doc.total_qty,
@@ -420,39 +421,59 @@
 					doc.set('apply_discount_on', d.apply_discount_on)
 
 				for field in ['additional_discount_percentage', 'discount_amount']:
-					if not d.get(field): continue
-
 					pr_field = ('discount_percentage'
 						if field == 'additional_discount_percentage' else field)
 
+					if not d.get(pr_field): continue
+
 					if d.validate_applied_rule and doc.get(field) < d.get(pr_field):
 						frappe.msgprint(_("User has not applied rule on the invoice {0}")
 							.format(doc.name))
 					else:
 						doc.set(field, d.get(pr_field))
+
+				doc.calculate_taxes_and_totals()
 			elif d.price_or_product_discount == 'Product':
-				apply_pricing_rule_for_free_items(doc, d)
+				item_details = frappe._dict()
+				get_product_discount_rule(d, item_details)
+				apply_pricing_rule_for_free_items(doc, item_details.free_item_data)
+				doc.set_missing_values()
 
 def get_applied_pricing_rules(item_row):
 	return (item_row.get("pricing_rules").split(',')
 		if item_row.get("pricing_rules") else [])
 
-def apply_pricing_rule_for_free_items(doc, pricing_rule):
-	if pricing_rule.get('free_item'):
+def get_product_discount_rule(pricing_rule, item_details):
+	free_item = (pricing_rule.free_item
+		if not pricing_rule.same_item or pricing_rule.apply_on == 'Transaction' else item_details.item_code)
+
+	if not free_item:
+		frappe.throw(_("Free item not set in the pricing rule {0}")
+			.format(get_link_to_form("Pricing Rule", pricing_rule.name)))
+
+	item_details.free_item_data = {
+		'item_code': free_item,
+		'qty': pricing_rule.free_qty or 1,
+		'rate': pricing_rule.free_item_rate or 0,
+		'price_list_rate': pricing_rule.free_item_rate or 0,
+		'is_free_item': 1
+	}
+
+	item_data = frappe.get_cached_value('Item', free_item, ['item_name',
+		'description', 'stock_uom'], as_dict=1)
+
+	item_details.free_item_data.update(item_data)
+	item_details.free_item_data['uom'] = pricing_rule.free_item_uom or item_data.stock_uom
+	item_details.free_item_data['conversion_factor'] = get_conversion_factor(free_item, 
+		item_details.free_item_data['uom']).get("conversion_factor", 1)
+
+def apply_pricing_rule_for_free_items(doc, pricing_rule_args, set_missing_values=False):
+	if pricing_rule_args.get('item_code'):
 		items = [d.item_code for d in doc.items
-			if d.item_code == (d.item_code
-			if pricing_rule.get('same_item') else pricing_rule.get('free_item')) and d.is_free_item]
+			if d.item_code == (pricing_rule_args.get("item_code")) and d.is_free_item]
 
 		if not items:
-			doc.append('items', {
-				'item_code': pricing_rule.get('free_item'),
-				'qty': pricing_rule.get('free_qty'),
-				'uom': pricing_rule.get('free_item_uom'),
-				'rate': pricing_rule.get('free_item_rate') or 0,
-				'is_free_item': 1
-			})
-
-			doc.set_missing_values()
+			doc.append('items', pricing_rule_args)
 
 def get_pricing_rule_items(pr_doc):
 	apply_on_data = []
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 75564af..6150516 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -319,8 +319,8 @@
 					if item.get('discount_amount'):
 						item.rate = item.price_list_rate - item.discount_amount
 
-			elif pricing_rule_args.get('free_item'):
-				apply_pricing_rule_for_free_items(self, pricing_rule_args)
+			elif pricing_rule_args.get('free_item_data'):
+				apply_pricing_rule_for_free_items(self, pricing_rule_args.get('free_item_data'))
 
 		elif pricing_rule_args.get("validate_applied_rule"):
 			for pricing_rule in get_applied_pricing_rules(item):
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 3ec7aff..17fba8e 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -735,10 +735,6 @@
 		if not self.get("items"):
 			return
 
-		earliest_schedule_date = min([d.schedule_date for d in self.get("items")])
-		if earliest_schedule_date:
-			self.schedule_date = earliest_schedule_date
-
 		if self.schedule_date:
 			for d in self.get('items'):
 				if not d.schedule_date:
@@ -750,6 +746,10 @@
 		else:
 			frappe.throw(_("Please enter Reqd by Date"))
 
+		earliest_schedule_date = min([d.schedule_date for d in self.get("items")])
+		if earliest_schedule_date:
+			self.schedule_date = earliest_schedule_date
+
 	def validate_items(self):
 		# validate items to see if they have is_purchase_item or is_subcontracted_item enabled
 		if self.doctype=="Material Request": return
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 46a58fb..1be4f27 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1305,6 +1305,10 @@
 				me.remove_pricing_rule(frappe.get_doc(d.doctype, d.name));
 			}
 
+			if (d.free_item_data) {
+				me.apply_product_discount(d.free_item_data);
+			}
+
 			if (d.apply_rule_on_other_items) {
 				items_rule_dict[d.name] = d;
 			}
@@ -1334,6 +1338,20 @@
 		}
 	},
 
+	apply_product_discount: function(free_item_data) {
+		const items = this.frm.doc.items.filter(d => (d.item_code == free_item_data.item_code
+			&& d.is_free_item)) || [];
+
+		if (!items.length) {
+			let row_to_modify = frappe.model.add_child(this.frm.doc,
+				this.frm.doc.doctype + ' Item', 'items');
+
+			for (let key in free_item_data) {
+				row_to_modify[key] = free_item_data[key];
+			}
+		}
+	},
+
 	apply_price_list: function(item, reset_plc_conversion) {
 		// We need to reset plc_conversion_rate sometimes because the call to
 		// `erpnext.stock.get_item_details.apply_price_list` is sensitive to its value