diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index 8301392d144..3cfb5a527ab 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -411,7 +411,7 @@ def get_project_name( if filters.get("company"): qb_filter_and_conditions.append(proj.company == filters.get("company")) - qb_filter_and_conditions.append(proj.status.notin(["Completed", "Cancelled"])) + qb_filter_and_conditions.append(proj.status.notin(["Completed", "Cancelled", "On hold"])) q = qb.from_(proj) diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py index d8d11f3ffa0..96a74ec5d0d 100644 --- a/erpnext/projects/doctype/project/test_project.py +++ b/erpnext/projects/doctype/project/test_project.py @@ -332,6 +332,23 @@ class TestProject(ERPNextTestSuite): self.assertEqual(project.percent_complete, 100) self.assertEqual(project.status, "Cancelled") + def test_on_hold_project_keeps_status(self): + project, tasks = self._project_with_tasks("Task Completion", 4) + + # an On hold project is not auto-flipped to Completed even at 100% + project.status = "On hold" + for task in tasks: + frappe.db.set_value("Task", task, "status", "Completed") + project.update_percent_complete() + self.assertEqual(project.percent_complete, 100) + self.assertEqual(project.status, "On hold") + + # nor auto-flipped back to Open when below 100% + frappe.db.set_value("Task", tasks[0], "status", "Open") + project.update_percent_complete() + self.assertEqual(project.percent_complete, 75) + self.assertEqual(project.status, "On hold") + def test_percent_complete_by_task_progress(self): project, tasks = self._project_with_tasks("Task Progress", 2) diff --git a/erpnext/projects/doctype/task/task.js b/erpnext/projects/doctype/task/task.js index 2f5fa6db6b0..c8e30cb3259 100644 --- a/erpnext/projects/doctype/task/task.js +++ b/erpnext/projects/doctype/task/task.js @@ -14,6 +14,12 @@ frappe.ui.form.on("Task", { }; }, onload: function (frm) { + frm.set_query("project", function () { + return { + query: "erpnext.controllers.queries.get_project_name", + }; + }); + frm.set_query("task", "depends_on", function () { let filters = { name: ["!=", frm.doc.name], diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js index 8001dffad86..bc63ba79a80 100644 --- a/erpnext/projects/doctype/timesheet/timesheet.js +++ b/erpnext/projects/doctype/timesheet/timesheet.js @@ -30,6 +30,7 @@ frappe.ui.form.on("Timesheet", { return { filters: { company: frm.doc.company, + status: "Open", }, }; }; @@ -122,6 +123,7 @@ frappe.ui.form.on("Timesheet", { return { filters: { customer: doc.customer, + status: "Open", }, }; }); diff --git a/erpnext/projects/report/project_summary/project_summary.js b/erpnext/projects/report/project_summary/project_summary.js index 072098d5db5..e9ff05857ae 100644 --- a/erpnext/projects/report/project_summary/project_summary.js +++ b/erpnext/projects/report/project_summary/project_summary.js @@ -22,7 +22,7 @@ frappe.query_reports["Project Summary"] = { fieldname: "status", label: __("Status"), fieldtype: "Select", - options: "\nOpen\nCompleted\nCancelled", + options: "\nOpen\nOn hold\nCompleted\nCancelled", default: "Open", }, {