Merge pull request #55897 from nabinhait/fix/project-sales-order-link-overwrite

fix(projects): don't overwrite existing Sales Order project link
This commit is contained in:
Nabin Hait
2026-06-19 15:15:35 +05:30
committed by GitHub
2 changed files with 42 additions and 2 deletions

View File

@@ -240,8 +240,29 @@ class Project(Document):
def after_insert(self):
self.copy_from_template("after_insert")
if self.sales_order:
frappe.db.set_value("Sales Order", self.sales_order, "project", self.name)
self.link_with_sales_order()
def link_with_sales_order(self) -> None:
"""Back-link the source Sales Order to this project.
The link is set only when the Sales Order is not already tied to another
project, so projects created concurrently for the same Sales Order cannot
overwrite each other's reference.
"""
if not self.sales_order:
return
existing_project = frappe.db.get_value("Sales Order", self.sales_order, "project")
if existing_project and existing_project != self.name:
frappe.msgprint(
_("Sales Order {0} is already linked to Project {1}, skipping the link.").format(
self.sales_order, existing_project
),
alert=True,
)
return
frappe.db.set_value("Sales Order", self.sales_order, "project", self.name)
def on_trash(self):
frappe.db.set_value("Sales Order", {"project": self.name}, "project", "")

View File

@@ -174,6 +174,25 @@ class TestProject(ERPNextTestSuite):
so.reload()
self.assertFalse(so.project)
def test_sales_order_link_is_not_overwritten_by_second_project(self):
so = make_sales_order()
first_project = make_project_from_so(so.name).save()
so.reload()
self.assertEqual(so.project, first_project.name)
# A second project for the same sales order must not steal the link.
second_project = frappe.get_doc(
doctype="Project",
project_name="Second project for same sales order",
company=so.company,
sales_order=so.name,
).insert()
self.assertEqual(second_project.sales_order, so.name)
so.reload()
self.assertEqual(so.project, first_project.name)
def test_project_with_template_tasks_having_common_name(self):
# Step - 1: Create Template Parent Tasks
template_parent_task1 = create_task(subject="Parent Task - 1", is_template=1, is_group=1)