fix: delete existing children first to avoid UniqueValidationError (#24140)

This commit is contained in:
Sagar Vora 2024-01-08 16:30:54 +00:00 committed by GitHub
parent 0932bbf10c
commit 417fce091a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -420,36 +420,35 @@ class Document(BaseDocument):
def update_child_table(self, fieldname: str, df: Optional["DocField"] = None):
"""sync child table for given fieldname"""
rows = []
df: "DocField" = df or self.meta.get_field(fieldname)
for d in self.get(df.fieldname):
d: Document
d.db_update()
rows.append(d.name)
if (
df.options in (self.flags.ignore_children_type or [])
or frappe.get_meta(df.options).is_virtual == 1
):
# do not delete rows for this because of flags
# hack for docperm :(
return
all_rows = self.get(df.fieldname)
# delete rows that do not match the ones in the document
tbl = frappe.qb.DocType(df.options)
qry = (
frappe.qb.from_(tbl)
.where(tbl.parent == self.name)
.where(tbl.parenttype == self.doctype)
.where(tbl.parentfield == fieldname)
.delete()
)
# if the doctype isn't in ignore_children_type flag and isn't virtual
if not (
df.options in (self.flags.ignore_children_type or ())
or frappe.get_meta(df.options).is_virtual == 1
):
existing_row_names = [row.name for row in all_rows if row.name and not row.is_new()]
if rows:
qry = qry.where(tbl.name.notin(rows))
tbl = frappe.qb.DocType(df.options)
qry = (
frappe.qb.from_(tbl)
.where(tbl.parent == self.name)
.where(tbl.parenttype == self.doctype)
.where(tbl.parentfield == fieldname)
.delete()
)
qry.run()
if existing_row_names:
qry = qry.where(tbl.name.notin(existing_row_names))
qry.run()
# update / insert
for d in all_rows:
d: Document
d.db_update()
def get_doc_before_save(self) -> "Document":
return getattr(self, "_doc_before_save", None)