feat: Multi currency in landed cost voucher
diff --git a/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json b/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json
index 0cc243d..ae8747f 100644
--- a/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json
+++ b/erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json
@@ -1,12 +1,16 @@
 {
+ "actions": [],
  "creation": "2014-07-11 11:51:00.453717",
  "doctype": "DocType",
  "editable_grid": 1,
  "engine": "InnoDB",
  "field_order": [
   "expense_account",
+  "account_currency",
+  "exchange_rate",
   "description",
   "col_break3",
+  "base_amount",
   "amount"
  ],
  "fields": [
@@ -27,7 +31,7 @@
    "fieldtype": "Currency",
    "in_list_view": 1,
    "label": "Amount",
-   "options": "Company:company:default_currency",
+   "options": "account_currency",
    "reqd": 1
   },
   {
@@ -37,10 +41,34 @@
    "label": "Expense Account",
    "options": "Account",
    "reqd": 1
+  },
+  {
+   "fieldname": "account_currency",
+   "fieldtype": "Link",
+   "label": "Account Currency",
+   "options": "Currency",
+   "read_only": 1,
+   "reqd": 1
+  },
+  {
+   "fieldname": "exchange_rate",
+   "fieldtype": "Float",
+   "label": "Exchange Rate",
+   "precision": "9"
+  },
+  {
+   "fieldname": "base_amount",
+   "fieldtype": "Currency",
+   "label": "Base Amount",
+   "options": "Company:company:default_currency",
+   "read_only": 1,
+   "reqd": 1
   }
  ],
+ "index_web_pages_for_search": 1,
  "istable": 1,
- "modified": "2019-09-30 18:28:32.070655",
+ "links": [],
+ "modified": "2020-12-13 21:04:01.769989",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Landed Cost Taxes and Charges",
diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js
index 5de1352..a5ac60c 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js
+++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.js
@@ -32,9 +32,8 @@
 
 		this.frm.set_query("expense_account", "taxes", function() {
 			return {
-				query: "erpnext.controllers.queries.tax_account_query",
 				filters: {
-					"account_type": ["Tax", "Chargeable", "Income Account", "Expenses Included In Valuation", "Expenses Included In Asset Valuation"],
+					"account_type": ['in', ["Tax", "Chargeable", "Income Account", "Expenses Included In Valuation", "Expenses Included In Asset Valuation"]],
 					"company": me.frm.doc.company
 				}
 			};
@@ -97,7 +96,7 @@
 	set_total_taxes_and_charges: function() {
 		var total_taxes_and_charges = 0.0;
 		$.each(this.frm.doc.taxes || [], function(i, d) {
-			total_taxes_and_charges += flt(d.amount)
+			total_taxes_and_charges += flt(d.base_amount)
 		});
 		cur_frm.set_value("total_taxes_and_charges", total_taxes_and_charges);
 	},
@@ -134,7 +133,58 @@
 	items_remove: () => {
 		this.trigger('set_applicable_charges_for_item');
 	}
-
 });
 
 cur_frm.script_manager.make(erpnext.stock.LandedCostVoucher);
+
+frappe.ui.form.on('Landed Cost Voucher', {
+	set_account_currency: function(frm, cdt, cdn) {
+		let row = locals[cdt][cdn];
+		if (row.expense_account) {
+			frappe.db.get_value('Account', row.expense_account, 'account_currency', function(value) {
+				frappe.model.set_value(cdt, cdn, "account_currency", value.account_currency);
+				frm.events.set_exchange_rate(frm, cdt, cdn);
+			});
+		}
+	},
+
+	set_exchange_rate: function(frm, cdt, cdn) {
+		let row = locals[cdt][cdn];
+		let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
+
+		if(row.account_currency == company_currency) {
+			row.exchange_rate = 1;
+		} else if (!row.exchange_rate || row.exchange_rate == 1) {
+			frappe.call({
+				method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_exchange_rate",
+				args: {
+					posting_date: frm.doc.posting_date,
+					account: row.expense_account,
+					account_currency: row.account_currency,
+					company: frm.doc.company
+				},
+				callback: function(r) {
+					if(r.message) {
+						frappe.model.set_value(cdt, cdn, "exchange_rate", r.message);
+					}
+				}
+			})
+		}
+	},
+
+	set_base_amount: function(frm, cdt, cdn) {
+		let row = locals[cdt][cdn];
+		frappe.model.set_value(cdt, cdn, "base_amount",
+			flt(flt(row.amount)*row.exchange_rate, precision("base_amount", row)));
+	}
+})
+
+frappe.ui.form.on('Landed Cost Taxes and Charges', {
+	expense_account: function(frm, cdt, cdn) {
+		frm.events.set_account_currency(frm, cdt, cdn);
+	},
+
+	amount: function(frm, cdt, cdn) {
+		frm.events.set_base_amount(frm, cdt, cdn);
+	}
+});
diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json
index 0149280..6a7994b 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json
+++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "autoname": "naming_series:",
  "creation": "2014-07-11 11:33:42.547339",
  "doctype": "DocType",
@@ -7,6 +8,9 @@
  "field_order": [
   "naming_series",
   "company",
+  "column_break_2",
+  "posting_date",
+  "section_break_5",
   "purchase_receipts",
   "purchase_receipt_items",
   "get_items_from_purchase_receipts",
@@ -86,7 +90,7 @@
   {
    "fieldname": "total_taxes_and_charges",
    "fieldtype": "Currency",
-   "label": "Total Taxes and Charges",
+   "label": "Total Taxes and Charges (Company Currency)",
    "options": "Company:company:default_currency",
    "read_only": 1,
    "reqd": 1
@@ -119,11 +123,29 @@
    "fieldname": "landed_cost_help",
    "fieldtype": "HTML",
    "label": "Landed Cost Help"
+  },
+  {
+   "fieldname": "column_break_2",
+   "fieldtype": "Column Break"
+  },
+  {
+   "default": "Today",
+   "fieldname": "posting_date",
+   "fieldtype": "Date",
+   "label": "Posting Date",
+   "reqd": 1
+  },
+  {
+   "fieldname": "section_break_5",
+   "fieldtype": "Section Break",
+   "hide_border": 1
   }
  ],
  "icon": "icon-usd",
+ "index_web_pages_for_search": 1,
  "is_submittable": 1,
- "modified": "2019-11-21 15:34:10.846093",
+ "links": [],
+ "modified": "2020-12-13 23:18:47.442466",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Landed Cost Voucher",
diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
index bc3d326..e392089 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
+++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
@@ -9,6 +9,7 @@
 from frappe.model.document import Document
 from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
 from erpnext.accounts.doctype.account.account import get_account_currency
+from erpnext.accounts.doctype.journal_entry.journal_entry import get_exchange_rate
 
 class LandedCostVoucher(Document):
 	def get_items_from_purchase_receipts(self):
@@ -39,12 +40,13 @@
 
 	def validate(self):
 		self.check_mandatory()
+		self.set_exchange_rate()
+		self.set_amounts_in_company_currency()
 		if not self.get("items"):
 			self.get_items_from_purchase_receipts()
 		else:
 			self.validate_applicable_charges_for_item()
 		self.validate_purchase_receipts()
-		self.validate_expense_accounts()
 		self.set_total_taxes_and_charges()
 
 	def check_mandatory(self):
@@ -73,16 +75,25 @@
 				frappe.throw(_("Row {0}: Cost center is required for an item {1}")
 					.format(item.idx, item.item_code))
 
-	def validate_expense_accounts(self):
-		company_currency = erpnext.get_company_currency(self.company)
-		for account in self.taxes:
-			if get_account_currency(account.expense_account) != company_currency:
-				frappe.throw(msg=_(""" Row {0}: Expense account currency should be same as company's default currency.
-					Please select expense account with account currency as {1}""")
-					.format(account.idx, frappe.bold(company_currency)), title=_("Invalid Account Currency"))
-
 	def set_total_taxes_and_charges(self):
-		self.total_taxes_and_charges = sum([flt(d.amount) for d in self.get("taxes")])
+		self.total_taxes_and_charges = sum([flt(d.base_amount) for d in self.get("taxes")])
+
+	def set_exchange_rate(self):
+		company_currency = erpnext.get_company_currency(self.company)
+		for d in self.get('taxes'):
+			if d.account_currency == company_currency:
+				d.exchange_rate = 1
+			elif not d.exchange_rate or d.exchange_rate == 1 or self.posting_date:
+				d.exchange_rate = get_exchange_rate(self.posting_date, account=d.expense_account,
+					account_currency=d.account_currency, company=self.company)
+
+			if not d.exchange_rate:
+				frappe.throw(_("Row {0}: Exchange Rate is mandatory").format(d.idx))
+
+	def set_amounts_in_company_currency(self):
+		for d in self.get('taxes'):
+			d.amount = flt(d.amount, d.precision("amount"))
+			d.base_amount = flt(d.amount * flt(d.exchange_rate), d.precision("base_amount"))
 
 	def validate_applicable_charges_for_item(self):
 		based_on = self.distribute_charges_based_on.lower()