From 88d8310a475eae6b223ffb7d72f9ecc47758519d Mon Sep 17 00:00:00 2001 From: Nishka Gosalia Date: Tue, 9 Dec 2025 16:20:20 +0530 Subject: [PATCH 1/3] fix: updating base amounts through python for timesheet --- .../projects/doctype/timesheet_detail/timesheet_detail.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py index 1ce2e7977d5..4e6bfa801c9 100644 --- a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py +++ b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py @@ -91,6 +91,11 @@ class TimesheetDetail(Document): self.billing_amount = self.billing_rate * (self.billing_hours or 0) self.costing_amount = self.costing_rate * (self.hours or 0) + exchange_rate = flt(frappe.get_value("Timesheet", self.parent, "exchange_rate")) or 1.0 + self.base_billing_rate = flt(self.billing_rate) * exchange_rate + self.base_costing_rate = flt(self.costing_rate) * exchange_rate + self.base_billing_amount = flt(self.billing_amount) * exchange_rate + self.base_costing_amount = flt(self.costing_amount) * exchange_rate def validate_dates(self): """Validate that to_time is not before from_time.""" From 4568114ba84668296a0124bac301a56447f48c9a Mon Sep 17 00:00:00 2001 From: Nishka Gosalia Date: Wed, 10 Dec 2025 12:57:34 +0530 Subject: [PATCH 2/3] test: test cases added for checking the base amounts in timesheet --- erpnext/projects/doctype/timesheet/test_timesheet.py | 10 ++++++++++ .../doctype/timesheet_detail/timesheet_detail.py | 5 ----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py index f9c631b00a8..4d1f82e7041 100644 --- a/erpnext/projects/doctype/timesheet/test_timesheet.py +++ b/erpnext/projects/doctype/timesheet/test_timesheet.py @@ -22,6 +22,15 @@ class TestTimesheet(ERPNextTestSuite): def setUp(self): frappe.db.delete("Timesheet") + def test_timesheet_base_amount(self): + emp = make_employee("test_employee_6@salary.com") + timesheet = make_timesheet(emp, simulate=True, is_billable=1) + + self.assertEqual(timesheet.time_logs[0].base_billing_rate, 50) + self.assertEqual(timesheet.time_logs[0].base_costing_rate, 20) + self.assertEqual(timesheet.time_logs[0].base_billing_amount, 100) + self.assertEqual(timesheet.time_logs[0].base_costing_amount, 40) + def test_timesheet_billing_amount(self): emp = make_employee("test_employee_6@salary.com") timesheet = make_timesheet(emp, simulate=True, is_billable=1) @@ -241,4 +250,5 @@ def make_timesheet( def update_activity_type(activity_type): activity_type = frappe.get_doc("Activity Type", activity_type) activity_type.billing_rate = 50.0 + activity_type.costing_rate = 20.0 activity_type.save(ignore_permissions=True) diff --git a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py index 4e6bfa801c9..1ce2e7977d5 100644 --- a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py +++ b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py @@ -91,11 +91,6 @@ class TimesheetDetail(Document): self.billing_amount = self.billing_rate * (self.billing_hours or 0) self.costing_amount = self.costing_rate * (self.hours or 0) - exchange_rate = flt(frappe.get_value("Timesheet", self.parent, "exchange_rate")) or 1.0 - self.base_billing_rate = flt(self.billing_rate) * exchange_rate - self.base_costing_rate = flt(self.costing_rate) * exchange_rate - self.base_billing_amount = flt(self.billing_amount) * exchange_rate - self.base_costing_amount = flt(self.costing_amount) * exchange_rate def validate_dates(self): """Validate that to_time is not before from_time.""" From e8a8d3947ca6409aa3666034957a83199d8ea2f7 Mon Sep 17 00:00:00 2001 From: Nishka Gosalia Date: Wed, 10 Dec 2025 13:12:47 +0530 Subject: [PATCH 3/3] fix: updating base amount in timesheet --- .../doctype/timesheet_detail/timesheet_detail.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py index 1ce2e7977d5..dc4c07bf376 100644 --- a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py +++ b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.py @@ -92,6 +92,16 @@ class TimesheetDetail(Document): self.billing_amount = self.billing_rate * (self.billing_hours or 0) self.costing_amount = self.costing_rate * (self.hours or 0) + exchange_rate = flt(frappe.get_value("Timesheet", self.parent, "exchange_rate")) or 1.0 + self.base_billing_rate = flt(self.billing_rate * exchange_rate, self.precision("base_billing_rate")) + self.base_costing_rate = flt(self.costing_rate * exchange_rate, self.precision("base_costing_rate")) + self.base_billing_amount = flt( + self.billing_amount * exchange_rate, self.precision("base_billing_amount") + ) + self.base_costing_amount = flt( + self.costing_amount * exchange_rate, self.precision("base_costing_amount") + ) + def validate_dates(self): """Validate that to_time is not before from_time.""" if self.from_time and self.to_time and time_diff_in_hours(self.to_time, self.from_time) < 0: