mirror of
https://github.com/frappe/erpnext.git
synced 2026-07-24 05:05:03 +00:00
Co-authored-by: nishkagosalia <nishka.gosalia@gmail.com>
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -222,6 +222,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))
|
||||
|
||||
@@ -244,6 +244,61 @@ class TestProject(ERPNextTestSuite):
|
||||
project.save()
|
||||
self.assertEqual(project.status, "Completed")
|
||||
|
||||
def _project_with_tasks(self, method, count):
|
||||
name = f"_Test PercentComplete {frappe.generate_hash(length=8)}"
|
||||
project = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Project",
|
||||
"project_name": name,
|
||||
"status": "Open",
|
||||
"percent_complete_method": method,
|
||||
"company": "_Test Company",
|
||||
"expected_start_date": nowdate(),
|
||||
}
|
||||
).insert()
|
||||
task_names = []
|
||||
for i in range(count):
|
||||
task = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Task",
|
||||
"subject": f"{name} Task {i}",
|
||||
"project": project.name,
|
||||
"status": "Open",
|
||||
"exp_start_date": nowdate(),
|
||||
"exp_end_date": nowdate(),
|
||||
}
|
||||
).insert()
|
||||
task_names.append(task.name)
|
||||
return project, task_names
|
||||
|
||||
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 _create_portal_user(self, email):
|
||||
"""A user with no Project-related role, so read access can only come from
|
||||
control_access_for_project_users() sharing the doc with them."""
|
||||
|
||||
Reference in New Issue
Block a user