test: Basic report data testing
diff --git a/erpnext/projects/report/employee_hours_utilisation_based_on_timesheet/employee_hours_utilisation_based_on_timesheet.py b/erpnext/projects/report/employee_hours_utilisation_based_on_timesheet/employee_hours_utilisation_based_on_timesheet.py
index 8124c7a..1979391 100644
--- a/erpnext/projects/report/employee_hours_utilisation_based_on_timesheet/employee_hours_utilisation_based_on_timesheet.py
+++ b/erpnext/projects/report/employee_hours_utilisation_based_on_timesheet/employee_hours_utilisation_based_on_timesheet.py
@@ -99,7 +99,10 @@
if self.filters.project:
additional_filters += f"AND ttd.project = '{self.filters.project}'"
-
+
+ if self.filters.company:
+ additional_filters += f"AND tt.company = '{self.filters.company}'"
+
self.filtered_time_logs = frappe.db.sql('''
SELECT tt.employee AS employee, ttd.hours AS hours, ttd.billable AS billable, ttd.project AS project
FROM `tabTimesheet Detail` AS ttd
@@ -134,6 +137,8 @@
data['per_util'] = flt(((data['billed_hours'] + data['non_billed_hours']) / TOTAL_HOURS) * 100, 2)
def generate_report_summary(self):
+ self.report_summary = []
+
if not self.data:
return
diff --git a/erpnext/projects/report/employee_hours_utilisation_based_on_timesheet/test_employee_util.py b/erpnext/projects/report/employee_hours_utilisation_based_on_timesheet/test_employee_util.py
new file mode 100644
index 0000000..7b310fa
--- /dev/null
+++ b/erpnext/projects/report/employee_hours_utilisation_based_on_timesheet/test_employee_util.py
@@ -0,0 +1,147 @@
+from __future__ import unicode_literals
+import unittest
+import frappe
+
+from frappe.utils.make_random import get_random
+from frappe.utils import get_timestamp
+from erpnext.projects.report.employee_hours_utilisation_based_on_timesheet.employee_hours_utilisation_based_on_timesheet import execute
+from erpnext.hr.doctype.employee.test_employee import make_employee
+from erpnext.projects.doctype.project.test_project import make_project
+
+class TestEmployeeUtilisation(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ # Create test employee
+ cls.test_emp1 = make_employee("test@example.com", "_Test Company")
+ cls.test_emp2 = make_employee("test1@example.com", "_Test Company")
+
+ # Create test project
+ cls.test_project = make_project({"project_name": "_Test Project"})
+
+ # Create test timesheets
+ cls.create_test_timesheets()
+
+ @classmethod
+ def create_test_timesheets(cls):
+ timesheet1 = frappe.new_doc("Timesheet")
+ timesheet1.employee = cls.test_emp1
+ timesheet1.company = '_Test Company'
+
+ timesheet1.append("time_logs", {
+ "activity_type": get_random("Activity Type"),
+ "hours": 5,
+ "billable": 1,
+ "from_time": '2021-04-01 13:30:00.000000',
+ "to_time": '2021-04-01 18:30:00.000000'
+ })
+
+ timesheet1.save()
+ timesheet1.submit()
+
+ timesheet2 = frappe.new_doc("Timesheet")
+ timesheet2.employee = cls.test_emp2
+ timesheet2.company = '_Test Company'
+
+ timesheet2.append("time_logs", {
+ "activity_type": get_random("Activity Type"),
+ "hours": 10,
+ "billable": 0,
+ "from_time": '2021-04-01 13:30:00.000000',
+ "to_time": '2021-04-01 23:30:00.000000',
+ "project": cls.test_project.name
+ })
+
+ timesheet2.save()
+ timesheet2.submit()
+
+ @classmethod
+ def tearDownClass(cls):
+ # Delete time logs
+ frappe.db.sql("""
+ DELETE FROM `tabTimesheet Detail`
+ WHERE parent IN (
+ SELECT name
+ FROM `tabTimesheet`
+ WHERE company = '_Test Company'
+ )
+ """)
+
+ frappe.db.sql("DELETE FROM `tabTimesheet` WHERE company='_Test Company'")
+ frappe.db.sql(f"DELETE FROM `tabProject` WHERE name='{cls.test_project.name}'")
+ print(f"DELETE FROM `tabProject` WHERE name='{cls.test_project.name}'")
+
+ def test_utilisation_report_with_required_filters_only(self):
+ filters = {
+ "company": "_Test Company",
+ "from_date": "2021-04-01",
+ "to_date": "2021-04-03"
+ }
+
+ report = execute(filters)
+
+ expected_data = [
+ {
+ 'employee': 'EMP-00002',
+ 'billed_hours': 0.0,
+ 'non_billed_hours': 10.0,
+ 'total_hours': 18.0,
+ 'untracked_hours': 8.0,
+ 'per_util': 55.56
+ },
+ {
+ 'employee': 'EMP-00001',
+ 'billed_hours': 5.0,
+ 'non_billed_hours': 0.0,
+ 'total_hours': 18.0,
+ 'untracked_hours': 13.0,
+ 'per_util': 27.78
+ }
+ ]
+
+ self.assertEqual(report[1], expected_data)
+
+ def test_utilisation_report_for_single_employee(self):
+ filters = {
+ "company": "_Test Company",
+ "from_date": "2021-04-01",
+ "to_date": "2021-04-03",
+ "employee": self.test_emp1
+ }
+
+ report = execute(filters)
+
+ expected_data = [
+ {
+ 'employee': 'EMP-00001',
+ 'billed_hours': 5.0,
+ 'non_billed_hours': 0.0,
+ 'total_hours': 18.0,
+ 'untracked_hours': 13.0,
+ 'per_util': 27.78
+ }
+ ]
+
+ self.assertEqual(report[1], expected_data)
+
+ def test_utilisation_report_for_project(self):
+ filters = {
+ "company": "_Test Company",
+ "from_date": "2021-04-01",
+ "to_date": "2021-04-03",
+ "project": self.test_project.name
+ }
+
+ report = execute(filters)
+
+ expected_data = [
+ {
+ 'employee': 'EMP-00002',
+ 'billed_hours': 0.0,
+ 'non_billed_hours': 10.0,
+ 'total_hours': 18.0,
+ 'untracked_hours': 8.0,
+ 'per_util': 55.56
+ }
+ ]
+
+ self.assertEqual(report[1], expected_data)
\ No newline at end of file