Merge pull request #57274 from nishkagosalia/gh-57206

fix: project % complete field allowing modification when manual method
This commit is contained in:
Nishka Gosalia
2026-07-20 11:46:20 +05:30
committed by GitHub
3 changed files with 32 additions and 2 deletions

View File

@@ -121,7 +121,7 @@
"in_list_view": 1,
"label": "% Completed",
"no_copy": 1,
"read_only": 1
"read_only_depends_on": "eval:doc.percent_complete_method != 'Manual'"
},
{
"fieldname": "column_break_5",
@@ -484,7 +484,7 @@
"index_web_pages_for_search": 1,
"links": [],
"max_attachments": 4,
"modified": "2026-07-14 14:32:11.328347",
"modified": "2026-07-21 11:23:22.000000",
"modified_by": "Administrator",
"module": "Projects",
"name": "Project",

View File

@@ -278,6 +278,8 @@ class Project(Document):
if self.percent_complete_method == "Manual":
if self.status == "Completed":
self.percent_complete = 100
elif flt(self.percent_complete) < 0 or flt(self.percent_complete) > 100:
frappe.throw(_("% Complete must be between 0 and 100"))
return
total = frappe.db.count("Task", dict(project=self.name))

View File

@@ -349,6 +349,34 @@ class TestProject(ERPNextTestSuite):
self.assertEqual(project.percent_complete, 75)
self.assertEqual(project.status, "On hold")
def test_percent_complete_manual(self):
project, tasks = self._project_with_tasks("Manual", 2)
# manual value is preserved on save, even with linked tasks
project.percent_complete = 42
project.save()
self.assertEqual(project.percent_complete, 42)
# task updates do not overwrite the manual value
frappe.db.set_value("Task", tasks[0], "status", "Completed")
project.update_percent_complete()
self.assertEqual(project.percent_complete, 42)
# out-of-range values are rejected
project.percent_complete = 150
self.assertRaises(frappe.ValidationError, project.save)
project.reload()
project.percent_complete = -10
self.assertRaises(frappe.ValidationError, project.save)
project.reload()
# Completed status forces 100 regardless of the manual value
project.percent_complete = 42
project.status = "Completed"
project.save()
self.assertEqual(project.percent_complete, 100)
def test_percent_complete_by_task_progress(self):
project, tasks = self._project_with_tasks("Task Progress", 2)