fix: timesheet fetching in sales invoice

(cherry picked from commit 216c32f4bc13376335ae31bd09fe6b5c01855ba2)
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index e30289a..9dde85f 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -861,27 +861,44 @@
 
 	set_timesheet_data: function(frm, timesheets) {
 		frm.clear_table("timesheets")
-		timesheets.forEach(timesheet => {
+		timesheets.forEach(async (timesheet) => {
 			if (frm.doc.currency != timesheet.currency) {
-				frappe.call({
-					method: "erpnext.setup.utils.get_exchange_rate",
-					args: {
-						from_currency: timesheet.currency,
-						to_currency: frm.doc.currency
-					},
-					callback: function(r) {
-						if (r.message) {
-							exchange_rate = r.message;
-							frm.events.append_time_log(frm, timesheet, exchange_rate);
-						}
-					}
-				});
+				const exchange_rate = await frm.events.get_exchange_rate(
+					frm, timesheet.currency, frm.doc.currency
+				)
+				frm.events.append_time_log(frm, timesheet, exchange_rate)
 			} else {
 				frm.events.append_time_log(frm, timesheet, 1.0);
 			}
 		});
 	},
 
+	async get_exchange_rate(frm, from_currency, to_currency) {
+		if (
+			frm.exchange_rates
+			&& frm.exchange_rates[from_currency]
+			&& frm.exchange_rates[from_currency][to_currency]
+		) {
+			return frm.exchange_rates[from_currency][to_currency];
+		}
+
+		return frappe.call({
+			method: "erpnext.setup.utils.get_exchange_rate",
+			args: {
+				from_currency,
+				to_currency
+			},
+			callback: function(r) {
+				if (r.message) {
+					// cache exchange rates
+					frm.exchange_rates = frm.exchange_rates || {};
+					frm.exchange_rates[from_currency] = frm.exchange_rates[from_currency] || {};
+					frm.exchange_rates[from_currency][to_currency] = r.message;
+				}
+			}
+		});
+	},
+
 	append_time_log: function(frm, time_log, exchange_rate) {
 		const row = frm.add_child("timesheets");
 		row.activity_type = time_log.activity_type;
@@ -892,7 +909,7 @@
 		row.billing_hours = time_log.billing_hours;
 		row.billing_amount = flt(time_log.billing_amount) * flt(exchange_rate);
 		row.timesheet_detail = time_log.name;
-    row.project_name = time_log.project_name;
+		row.project_name = time_log.project_name;
 
 		frm.refresh_field("timesheets");
 		frm.trigger("calculate_timesheet_totals");