[Fix] Currency field in Pricing rule (#14004)

* some minor changes

* Set query for price list based on currency

* Validate Price list with currency
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.js b/erpnext/accounts/doctype/pricing_rule/pricing_rule.js
index 4be09de..86694e6 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.js
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.js
@@ -109,9 +109,112 @@
 			return {
 				filters: {
 					'selling': doc.selling,
-					'buying': doc.buying
+					'buying': doc.buying,
+					'currency': doc.currency
 				}
-			}
+			};
+		};
+	},
+
+	refresh: function(frm) {
+		var help_content =
+			`<table class="table table-bordered" style="background-color: #f9f9f9;">
+				<tr><td>
+					<h4>
+						<i class="fa fa-hand-right"></i>
+						${__('Notes')}
+					</h4>
+					<ul>
+						<li>
+							${__("Pricing Rule is made to overwrite Price List / define discount percentage, based on some criteria.")}
+						</li>
+						<li>
+							${__("If selected Pricing Rule is made for 'Rate', it will overwrite Price List. Pricing Rule rate is the final rate, so no further discount should be applied. Hence, in transactions like Sales Order, Purchase Order etc, it will be fetched in 'Rate' field, rather than 'Price List Rate' field.")}
+						</li>
+						<li>
+							${__('Discount Percentage can be applied either against a Price List or for all Price List.')}
+						</li>
+						<li>
+							${__('To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled.')}
+						</li>
+					</ul>
+				</td></tr>
+				<tr><td>
+					<h4><i class="fa fa-question-sign"></i>
+						${__('How Pricing Rule is applied?')}
+					</h4>
+					<ol>
+						<li>
+							${__("Pricing Rule is first selected based on 'Apply On' field, which can be Item, Item Group or Brand.")}
+						</li>
+						<li>
+							${__("Then Pricing Rules are filtered out based on Customer, Customer Group, Territory, Supplier, Supplier Type, Campaign, Sales Partner etc.")}
+						</li>
+						<li>
+							${__('Pricing Rules are further filtered based on quantity.')}
+						</li>
+						<li>
+							${__('If two or more Pricing Rules are found based on the above conditions, Priority is applied. Priority is a number between 0 to 20 while default value is zero (blank). Higher number means it will take precedence if there are multiple Pricing Rules with same conditions.')}
+						</li>
+						<li>
+							${__('Even if there are multiple Pricing Rules with highest priority, then following internal priorities are applied:')}
+							<ul>
+								<li>
+									${__('Item Code > Item Group > Brand')}
+								</li>
+								<li>
+									${__('Customer > Customer Group > Territory')}
+								</li>
+								<li>
+									${__('Supplier > Supplier Type')}
+								</li>
+							</ul>
+						</li>
+						<li>
+							${__('If multiple Pricing Rules continue to prevail, users are asked to set Priority manually to resolve conflict.')}
+						</li>
+					</ol>
+				</td></tr>
+			</table>`;
+
+		set_field_options("pricing_rule_help", help_content);
+		frm.events.set_options_for_applicable_for(frm);
+	},
+
+	rate_or_discount: function(frm) {
+		if(frm.doc.rate_or_discount == 'Rate') {
+			frm.set_value('for_price_list', "");
 		}
+	},
+
+	selling: function(frm) {
+		frm.events.set_options_for_applicable_for(frm);
+	},
+
+	buying: function(frm) {
+		frm.events.set_options_for_applicable_for(frm);
+	},
+
+	//Dynamically change the description based on type of margin
+	margin_type: function(frm){
+		frm.set_df_property('margin_rate_or_amount', 'description', frm.doc.margin_type=='Percentage'?'In Percentage %':'In Amount');
+	},
+
+	set_options_for_applicable_for: function(frm) {
+		var options = [""];
+		var applicable_for = frm.doc.applicable_for;
+
+		if(frm.doc.selling) {
+			options = $.merge(options, ["Customer", "Customer Group", "Territory", "Sales Partner", "Campaign"]);
+		}
+		if(frm.doc.buying) {
+			$.merge(options, ["Supplier", "Supplier Type"]);
+		}
+	
+		set_field_options("applicable_for", options.join("\n"));
+	
+		if(!in_list(options, applicable_for)) applicable_for = null;
+		frm.set_value("applicable_for", applicable_for);
 	}
-})
+	
+});
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 9b73fcd..93c0da4 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -23,6 +23,7 @@
 		self.cleanup_fields_value()
 		self.validate_rate_or_discount()
 		self.validate_max_discount()
+		self.validate_price_list_with_currency()
 
 		if not self.margin_type: self.margin_rate_or_amount = 0.0
 
@@ -73,6 +74,11 @@
 			if max_discount and flt(self.discount_percentage) > flt(max_discount):
 				throw(_("Max discount allowed for item: {0} is {1}%").format(self.item_code, max_discount))
 
+	def validate_price_list_with_currency(self):
+		if self.currency and self.for_price_list:
+			price_list_currency = frappe.db.get_value("Price List", self.for_price_list, "currency")
+			if not self.currency == price_list_currency:
+				throw(_("Currency should be same as Price List Currency: {0}").format(price_list_currency))
 
 #--------------------------------------------------------------------------------
 
@@ -178,11 +184,8 @@
 		item_details.pricing_rule = pricing_rule.name
 		item_details.pricing_rule_for = pricing_rule.rate_or_discount
 
-		if pricing_rule.margin_type == 'Amount' and pricing_rule.currency == args.currency:
-			item_details.margin_type = pricing_rule.margin_type
-			item_details.margin_rate_or_amount = pricing_rule.margin_rate_or_amount
-
-		elif pricing_rule.margin_type == 'Percentage':
+		if (pricing_rule.margin_type == 'Amount' and pricing_rule.currency == args.currency)\
+				or (pricing_rule.margin_type == 'Percentage'):
 			item_details.margin_type = pricing_rule.margin_type
 			item_details.margin_rate_or_amount = pricing_rule.margin_rate_or_amount
 		else:
@@ -190,17 +193,13 @@
 			item_details.margin_rate_or_amount = 0.0
 
 		if pricing_rule.rate_or_discount == 'Rate':
+			pricing_rule_rate = 0.0
 			if pricing_rule.currency == args.currency:
-				item_details.update({
-					"price_list_rate": pricing_rule.rate,
-					"discount_percentage": 0.0
-				})
-
-			else:
-				item_details.update({
-					"price_list_rate": 0.0,
-					"discount_percentage": 0.0
-				})
+				pricing_rule_rate = pricing_rule.rate
+			item_details.update({
+				"price_list_rate": pricing_rule_rate,
+				"discount_percentage": 0.0
+			})
 		else:
 			item_details.discount_percentage = pricing_rule.discount_percentage or args.discount_percentage
 
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 658c7b4..d1c42b8 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -518,10 +518,8 @@
 			if item.pricing_rule and not self.doc.ignore_pricing_rule:
 				pricing_rule = frappe.get_doc('Pricing Rule', item.pricing_rule)
 
-				if pricing_rule.margin_type == 'Amount' and pricing_rule.currency == self.doc.currency:
-					item.margin_type = pricing_rule.margin_type
-					item.margin_rate_or_amount = pricing_rule.margin_rate_or_amount
-				elif pricing_rule.margin_type == 'Percentage':
+				if (pricing_rule.margin_type == 'Amount' and pricing_rule.currency == self.doc.currency)\
+						or (pricing_rule.margin_type == 'Percentage'):
 					item.margin_type = pricing_rule.margin_type
 					item.margin_rate_or_amount = pricing_rule.margin_rate_or_amount
 				else:
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index 536ab00..72b2764 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -355,8 +355,8 @@
 		{"start": start, "end": end}, as_dict=True, update={"allDay": 0})
 	for item in data:
 		item.end = item.start + datetime.timedelta(minutes = item.duration)
-	return data
 
+	return data
 @frappe.whitelist()
 def get_procedure_prescribed(patient):
 	return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.physician,
diff --git a/erpnext/patches/v10_0/workflow_expense_claim.py b/erpnext/patches/v10_0/workflow_expense_claim.py
index 9aa2cee..2e99fbf 100644
--- a/erpnext/patches/v10_0/workflow_expense_claim.py
+++ b/erpnext/patches/v10_0/workflow_expense_claim.py
@@ -37,14 +37,20 @@
 				'states': [{
 					"state": 'Draft',
 					"doc_status": 0,
+					"update_field": "approval_status",
+					"update_value": "Draft",
 					"allow_edit": 'Employee'
 				}, {
 					"state": 'Approved',
 					"doc_status": 1,
+					"update_field": "approval_status",
+					"update_value": "Approved",
 					"allow_edit": 'Expense Approver'
 				}, {
 					"state": 'Rejected',
 					"doc_status": 0,
+					"update_field": "approval_status",
+					"update_value": "Rejected",
 					"allow_edit": 'Expense Approver'
 				}],
 				'transitions': [{
diff --git a/erpnext/patches/v10_0/workflow_leave_application.py b/erpnext/patches/v10_0/workflow_leave_application.py
index 0d33402..637c076 100644
--- a/erpnext/patches/v10_0/workflow_leave_application.py
+++ b/erpnext/patches/v10_0/workflow_leave_application.py
@@ -8,54 +8,60 @@
 	if frappe.db.a_row_exists("Leave Application"):
 		frappe.reload_doc("hr", "doctype", "leave_application")
 		frappe.reload_doc("workflow", "doctype", "workflow")
-		states = {'Approved': 'Success', 'Rejected': 'Danger', 'Open': 'Warning'}
+		states = {"Approved": "Success", "Rejected": "Danger", "Open": "Warning"}
 
 		for state, style in states.items():
 			if not frappe.db.exists("Workflow State", state):
 				frappe.get_doc({
-					'doctype': 'Workflow State',
-					'workflow_state_name': state,
-					'style': style
+					"doctype": "Workflow State",
+					"workflow_state_name": state,
+					"style": style
 				}).insert(ignore_permissions=True)
 
-		for action in ['Approve', 'Reject']:
+		for action in ["Approve", "Reject"]:
 			if not frappe.db.exists("Workflow Action", action):
 				frappe.get_doc({
-					'doctype': 'Workflow Action',
-					'workflow_action_name': action
+					"doctype": "Workflow Action",
+					"workflow_action_name": action
 				}).insert(ignore_permissions=True)
 
 		if not frappe.db.exists("Workflow", "Leave Approval"):
 			frappe.get_doc({
-				'doctype': 'Workflow',
-				'workflow_name': 'Leave Approval',
-				'document_type': 'Leave Application',
-				'is_active': 1,
-				'workflow_state_field': 'workflow_state',
-				'states': [{
-					"state": 'Open',
+				"doctype": "Workflow",
+				"workflow_name": "Leave Approval",
+				"document_type": "Leave Application",
+				"is_active": 1,
+				"workflow_state_field": "workflow_state",
+				"states": [{
+					"state": "Open",
 					"doc_status": 0,
-					"allow_edit": 'Employee'
+					"update_field": "status",
+					"update_value": "Open",
+					"allow_edit": "Employee"
 				}, {
-					"state": 'Approved',
+					"state": "Approved",
 					"doc_status": 1,
-					"allow_edit": 'Leave Approver'
+					"update_field": "status",
+					"update_value": "Approved",
+					"allow_edit": "Leave Approver"
 				}, {
-					"state": 'Rejected',
+					"state": "Rejected",
 					"doc_status": 0,
-					"allow_edit": 'Leave Approver'
+					"update_field": "status",
+					"update_value": "Rejected",
+					"allow_edit": "Leave Approver"
 				}],
-				'transitions': [{
-					"state": 'Open',
-					"action": 'Approve',
-					"next_state": 'Approved',
-					"allowed": 'Leave Approver'
+				"transitions": [{
+					"state": "Open",
+					"action": "Approve",
+					"next_state": "Approved",
+					"allowed": "Leave Approver"
 				},
 				{
-					"state": 'Open',
-					"action": 'Reject',
-					"next_state": 'Rejected',
-					"allowed": 'Leave Approver'
+					"state": "Open",
+					"action": "Reject",
+					"next_state": "Rejected",
+					"allowed": "Leave Approver"
 				}]
 			}).insert(ignore_permissions=True)