diff --git a/erpnext/projects/report/project_summary/test_project_summary.py b/erpnext/projects/report/project_summary/test_project_summary.py new file mode 100644 index 00000000000..66dff87e1e6 --- /dev/null +++ b/erpnext/projects/report/project_summary/test_project_summary.py @@ -0,0 +1,65 @@ +# Copyright (c) 2026, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +import frappe +from frappe import _ + +from erpnext.projects.report.project_summary.project_summary import execute +from erpnext.tests.utils import ERPNextTestSuite + + +class TestProjectSummary(ERPNextTestSuite): + """Lists projects with their total / completed / overdue task counts.""" + + def make_project(self): + return frappe.get_doc( + { + "doctype": "Project", + "project_name": f"_Test PS {frappe.generate_hash(length=6)}", + "company": "_Test Company", + } + ).insert() + + def make_task(self, project, status="Open"): + task = frappe.get_doc( + { + "doctype": "Task", + "subject": f"Task {frappe.generate_hash(length=6)}", + "project": project.name, + } + ).insert() + if status != "Open": + # set the status directly; the report counts tasks by their stored status + frappe.db.set_value("Task", task.name, "status", status) + return task + + def run_report(self, project): + return execute(frappe._dict({"name": project.name})) + + def project_row(self, project): + _columns, data, *_rest = self.run_report(project) + return next((r for r in data if r["name"] == project.name), None) + + def test_task_counts(self): + project = self.make_project() + self.make_task(project, "Completed") + self.make_task(project, "Completed") + self.make_task(project, "Open") + self.make_task(project, "Overdue") + + row = self.project_row(project) + self.assertIsNotNone(row, "Project missing from report") + self.assertEqual(row["total_tasks"], 4) + self.assertEqual(row["completed_tasks"], 2) + self.assertEqual(row["overdue_tasks"], 1) + + def test_report_summary_totals(self): + project = self.make_project() + self.make_task(project, "Completed") + self.make_task(project, "Open") + + _columns, _data, _message, _chart, report_summary = self.run_report(project) + summary = {s["label"]: s["value"] for s in report_summary} + self.assertEqual(summary[_("Total Tasks")], 2) + self.assertEqual(summary[_("Completed Tasks")], 1) + self.assertEqual(summary[_("Overdue Tasks")], 0)