Child Table Fields Not Updating

Hi everyone,

I’m implementing a sub-workflow inside a main workflow in my custom app. When the document transitions into the “Pending” state, the sub-workflow kicks in and activates.

I’ve also implemented an approval trail inside a child table. You can refer to this previous issue here:
:link: My child table data disappears after a few seconds

Issue:

When an approver approves the document, the following is supposed to happen:

  • The current approver’s row in the approval_trail child table should get its status updated to "Approved".
  • The document should be assigned to the next approver listed in the table.

But nothing is happening in the child table — the fields are not updating and no new assignment is being made.

Code Snippet:

def handle_approval(doc, approving_user, transition_flow):
    frappe.logger().info(f"Processing approval for {doc.name} by {approving_user}")
    
    updated = False
    current_idx = -1
    
    for idx, entry in enumerate(doc.approval_trail):
        if isinstance(entry, dict) and entry.get('user') == approving_user:
            entry['status'] = 'Approved'
            entry['datetime'] = get_datetime_str(now_datetime())
            entry['comments'] = doc.get('approval_comments', '') or 'Approved'
            current_idx = idx
            updated = True
            break

    if not updated:
        frappe.msgprint(_("You are not authorized to approve this document"), alert=True)
        return

    all_approved = all(
        isinstance(e, dict) and e.get('status') == 'Approved'
        for e in doc.approval_trail if e.get('user')
    )

    clear_assignments(doc.doctype, doc.name)

    if all_approved:
        doc.workflow_state = "Approved"
        doc.current_approver = ""
        doc.in_transition_flow = 0
        frappe.msgprint(_("All approvers have approved this document"))
    else:
        approvers = get_all_approvers(transition_flow)
        next_approver = next(
            (e.get('user') for e in doc.approval_trail[current_idx+1:] if e.get('status') == 'Pending'),
            None
        )
        if next_approver:
            doc.current_approver = next_approver
            assign_task({
                "assign_to": [next_approver],
                "doctype": doc.doctype,
                "name": doc.name,
                "description": _("Approval requested for {0}").format(doc.name),
                "priority": "High"
            })
            frappe.msgprint(_("Document approved and forwarded to next approver"))
    
    doc.save()
    frappe.db.commit()

What I’ve Tried:

  • Logging confirms the right user is detected and status is updated in the loop.
  • doc.save() and frappe.db.commit() are both being called.
  • Still, the changes are not reflected in the UI or database.

Any idea what could be causing this? Do I need to use doc.set() or something else to force child table changes to be recognized?

Thanks in advance! :pray: