Merge pull request #22601 from deepeshgarg007/payment_reco_company

fix: Payment reco error in multi-company setup
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index db91b66..b764eff 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -388,7 +388,7 @@
 	from erpnext.accounts.doctype.tax_rule.tax_rule import get_tax_template, get_party_details
 	args = {
 		party_type.lower(): party,
-		"company":			company
+		"company": company
 	}
 
 	if tax_category:
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 9ae5a87..0bd03a8 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -35,11 +35,9 @@
 		if not self.booked_fixed_asset and self.validate_make_gl_entry():
 			self.make_gl_entries()
 
-	def before_cancel(self):
-		self.cancel_auto_gen_movement()
-
 	def on_cancel(self):
 		self.validate_cancellation()
+		self.cancel_movement_entries()
 		self.delete_depreciation_entries()
 		self.set_status()
 		self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry')
@@ -134,19 +132,6 @@
 				Please do not book expense of multiple assets against one single Asset.")
 				.format(frappe.bold("equal"), "<br>"), title=_("Invalid Gross Purchase Amount"))
 
-	def cancel_auto_gen_movement(self):
-		movements = frappe.db.sql(
-			"""SELECT asm.name, asm.docstatus
-			FROM `tabAsset Movement` asm, `tabAsset Movement Item` asm_item
-			WHERE asm_item.parent=asm.name and asm_item.asset=%s and asm.docstatus=1""", self.name, as_dict=1)
-		if len(movements) > 1:
-			frappe.throw(_('Asset has multiple Asset Movement Entries which has to be \
-				cancelled manually to cancel this asset.'))
-		if movements:
-			movement = frappe.get_doc('Asset Movement', movements[0].get('name'))
-			movement.flags.ignore_validate = True
-			movement.cancel()
-
 	def make_asset_movement(self):
 		reference_doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
 		reference_docname = self.purchase_receipt or self.purchase_invoice
@@ -413,6 +398,16 @@
 		if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"):
 			frappe.throw(_("Asset cannot be cancelled, as it is already {0}").format(self.status))
 
+	def cancel_movement_entries(self):
+		movements = frappe.db.sql(
+			"""SELECT asm.name, asm.docstatus
+			FROM `tabAsset Movement` asm, `tabAsset Movement Item` asm_item
+			WHERE asm_item.parent=asm.name and asm_item.asset=%s and asm.docstatus=1""", self.name, as_dict=1)
+
+		for movement in movements:
+			movement = frappe.get_doc('Asset Movement', movement.get('name'))
+			movement.cancel()
+
 	def delete_depreciation_entries(self):
 		for d in self.get("schedules"):
 			if d.journal_entry:
diff --git a/erpnext/assets/doctype/asset_movement/asset_movement.py b/erpnext/assets/doctype/asset_movement/asset_movement.py
index 3da355e..b2de250 100644
--- a/erpnext/assets/doctype/asset_movement/asset_movement.py
+++ b/erpnext/assets/doctype/asset_movement/asset_movement.py
@@ -87,33 +87,9 @@
 
 	def on_submit(self):
 		self.set_latest_location_in_asset()
-	
-	def before_cancel(self):
-		self.validate_last_movement()
 		
 	def on_cancel(self):
 		self.set_latest_location_in_asset()
-	
-	def validate_last_movement(self):
-		for d in self.assets:
-			auto_gen_movement_entry = frappe.db.sql(
-				"""
-				SELECT asm.name
-				FROM  `tabAsset Movement Item` asm_item, `tabAsset Movement` asm
-				WHERE 
-					asm.docstatus=1 and
-					asm_item.parent=asm.name and
-					asm_item.asset=%s and
-					asm.company=%s and
-					asm_item.source_location is NULL and
-					asm.purpose=%s
-				ORDER BY
-					asm.transaction_date asc
-				""", (d.asset, self.company, 'Receipt'), as_dict=1)
-
-			if auto_gen_movement_entry and auto_gen_movement_entry[0].get('name') == self.name:
-				frappe.throw(_('{0} will be cancelled automatically on asset cancellation as it was \
-					auto generated for Asset {1}').format(self.name, d.asset))
 
 	def set_latest_location_in_asset(self):
 		current_location, current_employee = '', ''
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index 8f8dafd..221300b 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -113,6 +113,14 @@
 	cur_frm.cscript.calculate_total(doc,cdt,cdn);
 };
 
+cur_frm.fields_dict['cost_center'].get_query = function(doc) {
+	return {
+		filters: {
+			"company": doc.company
+		}
+	}
+};
+
 erpnext.expense_claim = {
 	set_title: function(frm) {
 		if (!frm.doc.task) {
diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json
index f4b3d3e..4db1f19 100644
--- a/erpnext/projects/doctype/task/task.json
+++ b/erpnext/projects/doctype/task/task.json
@@ -183,7 +183,8 @@
   {
    "fieldname": "progress",
    "fieldtype": "Percent",
-   "label": "% Progress"
+   "label": "% Progress",
+   "no_copy": 1
   },
   {
    "default": "0",
@@ -356,6 +357,7 @@
    "fieldname": "completed_by",
    "fieldtype": "Link",
    "label": "Completed By",
+   "no_copy": 1,
    "options": "User"
   }
  ],
@@ -364,7 +366,7 @@
  "is_tree": 1,
  "links": [],
  "max_attachments": 5,
- "modified": "2020-03-18 18:08:44.153211",
+ "modified": "2020-07-03 12:36:04.960457",
  "modified_by": "Administrator",
  "module": "Projects",
  "name": "Task",
diff --git a/erpnext/public/js/utils/party.js b/erpnext/public/js/utils/party.js
index 99c1b8a..0653267 100644
--- a/erpnext/public/js/utils/party.js
+++ b/erpnext/public/js/utils/party.js
@@ -4,7 +4,7 @@
 frappe.provide("erpnext.utils");
 
 erpnext.utils.get_party_details = function(frm, method, args, callback) {
-	if(!method) {
+	if (!method) {
 		method = "erpnext.accounts.party.get_party_details";
 	}
 
@@ -22,12 +22,12 @@
 		}
 	}
 
-	if(!args) {
-		if((frm.doctype != "Purchase Order" && frm.doc.customer)
+	if (!args) {
+		if ((frm.doctype != "Purchase Order" && frm.doc.customer)
 			|| (frm.doc.party_name && in_list(['Quotation', 'Opportunity'], frm.doc.doctype))) {
 
 			let party_type = "Customer";
-			if(frm.doc.quotation_to && frm.doc.quotation_to === "Lead") {
+			if (frm.doc.quotation_to && frm.doc.quotation_to === "Lead") {
 				party_type = "Lead";
 			}
 
@@ -36,7 +36,7 @@
 				party_type: party_type,
 				price_list: frm.doc.selling_price_list
 			};
-		} else if(frm.doc.supplier) {
+		} else if (frm.doc.supplier) {
 			args = {
 				party: frm.doc.supplier,
 				party_type: "Supplier",
@@ -78,13 +78,17 @@
 			args.posting_date = frm.doc.posting_date || frm.doc.transaction_date;
 		}
 	}
-	if(!args || !args.party) return;
+	if (!args || !args.party) return;
 
-	if(frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
-		if(!erpnext.utils.validate_mandatory(frm, "Posting/Transaction Date",
+	if (frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
+		if (!erpnext.utils.validate_mandatory(frm, "Posting / Transaction Date",
 			args.posting_date, args.party_type=="Customer" ? "customer": "supplier")) return;
 	}
 
+	if (!erpnext.utils.validate_mandatory(frm, "Company", frm.doc.company, args.party_type=="Customer" ? "customer": "supplier")) {
+		return;
+	}
+
 	args.currency = frm.doc.currency;
 	args.company = frm.doc.company;
 	args.doctype = frm.doc.doctype;
@@ -92,14 +96,14 @@
 		method: method,
 		args: args,
 		callback: function(r) {
-			if(r.message) {
+			if (r.message) {
 				frm.supplier_tds = r.message.supplier_tds;
 				frm.updating_party_details = true;
 				frappe.run_serially([
 					() => frm.set_value(r.message),
 					() => {
 						frm.updating_party_details = false;
-						if(callback) callback();
+						if (callback) callback();
 						frm.refresh();
 						erpnext.utils.add_item(frm);
 					}
@@ -110,9 +114,9 @@
 }
 
 erpnext.utils.add_item = function(frm) {
-	if(frm.is_new()) {
+	if (frm.is_new()) {
 		var prev_route = frappe.get_prev_route();
-		if(prev_route[1]==='Item' && !(frm.doc.items && frm.doc.items.length)) {
+		if (prev_route[1]==='Item' && !(frm.doc.items && frm.doc.items.length)) {
 			// add row
 			var item = frm.add_child('items');
 			frm.refresh_field('items');
@@ -124,23 +128,23 @@
 }
 
 erpnext.utils.get_address_display = function(frm, address_field, display_field, is_your_company_address) {
-	if(frm.updating_party_details) return;
+	if (frm.updating_party_details) return;
 
-	if(!address_field) {
-		if(frm.doctype != "Purchase Order" && frm.doc.customer) {
+	if (!address_field) {
+		if (frm.doctype != "Purchase Order" && frm.doc.customer) {
 			address_field = "customer_address";
-		} else if(frm.doc.supplier) {
+		} else if (frm.doc.supplier) {
 			address_field = "supplier_address";
 		} else return;
 	}
 
-	if(!display_field) display_field = "address_display";
-	if(frm.doc[address_field]) {
+	if (!display_field) display_field = "address_display";
+	if (frm.doc[address_field]) {
 		frappe.call({
 			method: "frappe.contacts.doctype.address.address.get_address_display",
 			args: {"address_dict": frm.doc[address_field] },
 			callback: function(r) {
-				if(r.message) {
+				if (r.message) {
 					frm.set_value(display_field, r.message)
 				}
 			}
@@ -151,15 +155,15 @@
 };
 
 erpnext.utils.set_taxes_from_address = function(frm, triggered_from_field, billing_address_field, shipping_address_field) {
-	if(frm.updating_party_details) return;
+	if (frm.updating_party_details) return;
 
-	if(frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
-		if(!erpnext.utils.validate_mandatory(frm, "Lead/Customer/Supplier",
+	if (frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
+		if (!erpnext.utils.validate_mandatory(frm, "Lead / Customer / Supplier",
 			frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name, triggered_from_field)) {
 			return;
 		}
 
-		if(!erpnext.utils.validate_mandatory(frm, "Posting/Transaction Date",
+		if (!erpnext.utils.validate_mandatory(frm, "Posting / Transaction Date",
 			frm.doc.posting_date || frm.doc.transaction_date, triggered_from_field)) {
 			return;
 		}
@@ -175,8 +179,8 @@
 			"shipping_address": frm.doc[shipping_address_field]
 		},
 		callback: function(r) {
-			if(!r.exc){
-				if(frm.doc.tax_category != r.message) {
+			if (!r.exc){
+				if (frm.doc.tax_category != r.message) {
 					frm.set_value("tax_category", r.message);
 				} else {
 					erpnext.utils.set_taxes(frm, triggered_from_field);
@@ -187,13 +191,17 @@
 };
 
 erpnext.utils.set_taxes = function(frm, triggered_from_field) {
-	if(frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
-		if(!erpnext.utils.validate_mandatory(frm, "Lead/Customer/Supplier",
+	if (frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
+		if (!erpnext.utils.validate_mandatory(frm, "Company", frm.doc.company, triggered_from_field)) {
+			return;
+		}
+
+		if (!erpnext.utils.validate_mandatory(frm, "Lead / Customer / Supplier",
 			frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name, triggered_from_field)) {
 			return;
 		}
 
-		if(!erpnext.utils.validate_mandatory(frm, "Posting/Transaction Date",
+		if (!erpnext.utils.validate_mandatory(frm, "Posting / Transaction Date",
 			frm.doc.posting_date || frm.doc.transaction_date, triggered_from_field)) {
 			return;
 		}
@@ -230,7 +238,7 @@
 			"shipping_address": frm.doc.shipping_address_name
 		},
 		callback: function(r) {
-			if(r.message){
+			if (r.message){
 				frm.set_value("taxes_and_charges", r.message)
 			}
 		}
@@ -238,14 +246,14 @@
 };
 
 erpnext.utils.get_contact_details = function(frm) {
-	if(frm.updating_party_details) return;
+	if (frm.updating_party_details) return;
 
-	if(frm.doc["contact_person"]) {
+	if (frm.doc["contact_person"]) {
 		frappe.call({
 			method: "frappe.contacts.doctype.contact.contact.get_contact_details",
 			args: {contact: frm.doc.contact_person },
 			callback: function(r) {
-				if(r.message)
+				if (r.message)
 					frm.set_value(r.message);
 			}
 		})
@@ -253,10 +261,10 @@
 }
 
 erpnext.utils.validate_mandatory = function(frm, label, value, trigger_on) {
-	if(!value) {
+	if (!value) {
 		frm.doc[trigger_on] = "";
 		refresh_field(trigger_on);
-		frappe.msgprint(__("Please enter {0} first", [label]));
+		frappe.throw({message:__("Please enter {0} first", [label]), title:__("Mandatory")});
 		return false;
 	}
 	return true;
@@ -271,12 +279,12 @@
 				address: frm.doc.shipping_address
 			},
 			callback: function(r){
-				if(r.message){
+				if (r.message){
 					frm.set_value("shipping_address", r.message[0]) //Address title or name
 					frm.set_value("shipping_address_display", r.message[1]) //Address to be displayed on the page
 				}
 
-				if(callback){
+				if (callback){
 					return callback();
 				}
 			}
diff --git a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.js b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.js
index 63747af..dac6ac4 100644
--- a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.js
+++ b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.js
@@ -5,21 +5,28 @@
 	refresh: function(frm) {
 		frm.set_value("date", frappe.datetime.get_today());
 	},
-	template: function(frm){
-		frappe.call({
-			"method": "frappe.client.get",
-			args: {
-				doctype: "Quality Feedback Template",
-				name: frm.doc.template
-			},
-			callback: function(data){
-				frm.fields_dict.parameters.grid.remove_all();
-				for (var i in data.message.parameters){
-					frm.add_child("parameters");
-					frm.fields_dict.parameters.get_value()[i].parameter = data.message.parameters[i].parameter;
+
+	template: function(frm) {
+		if (frm.doc.template) {
+			frappe.call({
+				"method": "frappe.client.get",
+				args: {
+					doctype: "Quality Feedback Template",
+					name: frm.doc.template
+				},
+				callback: function(data) {
+					if (data && data.message) {
+						frm.fields_dict.parameters.grid.remove_all();
+
+						// fetch parameters from template and autofill
+						for (let template_parameter of data.message.parameters) {
+							let row = frm.add_child("parameters");
+							row.parameter = template_parameter.parameter;
+						}
+						frm.refresh();
+					}
 				}
-				frm.refresh();
-			}
-		});
+			});
+		}
 	}
 });
diff --git a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.json b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.json
index 460438a..ab9084f 100644
--- a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.json
+++ b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "autoname": "format:FDBK-{#####}",
  "creation": "2019-05-26 21:23:05.308379",
  "doctype": "DocType",
@@ -53,12 +54,13 @@
   {
    "fieldname": "document_name",
    "fieldtype": "Dynamic Link",
-   "label": "Name",
+   "label": "Feedback By",
    "options": "document_type",
    "reqd": 1
   }
  ],
- "modified": "2019-05-28 15:16:01.161662",
+ "links": [],
+ "modified": "2020-07-03 15:50:58.589302",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Quality Feedback",
diff --git a/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.json b/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.json
index 31efd04..bdc9dba 100644
--- a/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.json
+++ b/erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "autoname": "format:TMPL-{template}",
  "creation": "2019-05-26 21:17:24.283061",
  "doctype": "DocType",
@@ -30,10 +31,12 @@
    "fieldname": "parameters",
    "fieldtype": "Table",
    "label": "Parameters",
-   "options": "Quality Feedback Template Parameter"
+   "options": "Quality Feedback Template Parameter",
+   "reqd": 1
   }
  ],
- "modified": "2019-05-26 21:48:47.770610",
+ "links": [],
+ "modified": "2020-07-03 16:06:03.749415",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Quality Feedback Template",
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 0ed3b27..0af018b 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -636,6 +636,10 @@
 	if args.get('transaction_date'):
 		conditions += """ and %(transaction_date)s between
 			ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')"""
+		
+	if args.get('posting_date'):
+		conditions += """ and %(posting_date)s between
+			ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')"""
 
 	return frappe.db.sql(""" select name, price_list_rate, uom
 		from `tabItem Price` {conditions}
@@ -657,6 +661,7 @@
 			"supplier": args.get('supplier'),
 			"uom": args.get('uom'),
 			"transaction_date": args.get('transaction_date'),
+			"posting_date": args.get('posting_date'),
 	}
 
 	item_price_data = 0
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index 2359648..5bf85d1 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -120,6 +120,16 @@
 
 
 	def validate_rate_with_reference_doc(self, ref_details):
+		buying_doctypes = ["Purchase Order", "Purchase Invoice", "Purchase Receipt"]
+		selling_doctypes = ["Sales Invoice", "Delivery Note"]
+
+		if self.doctype in buying_doctypes:
+			to_disable = "Maintain same rate throughout Purchase cycle"
+			settings_page = "Buying Settings"
+		else:
+			to_disable = "Maintain same rate throughout Sales cycle"
+			settings_page = "Selling Settings"
+
 		for ref_dt, ref_dn_field, ref_link_field in ref_details:
 			for d in self.get("items"):
 				if d.get(ref_link_field):
@@ -129,8 +139,8 @@
 						frappe.msgprint(_("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))
 						frappe.throw(_("To allow different rates, disable the {0} checkbox in {1}.")
-							.format(frappe.bold(_("Maintain Same Rate Throughout Sales Cycle")),
-							get_link_to_form("Selling Settings", "Selling Settings", frappe.bold("Selling Settings"))))
+							.format(frappe.bold(_(to_disable)),
+							get_link_to_form(settings_page, settings_page, frappe.bold(settings_page))))
 
 	def get_link_filters(self, for_doctype):
 		if hasattr(self, "prev_link_mapper") and self.prev_link_mapper.get(for_doctype):