How to get workflow approvals user names to display in report

Suppose I have a doctype name workflow Test. It has a workflow approvals system. I want to add every approvals user name on the docs report view.
When user A approves first step then his/her name will be added on that doc
then user B approves 2nd step then his/her name will be added on that doc also dynamically.

How can I do this?

Might not be the best approach but can be very effective and easily implemented, you can do this through custom fields.

yap, But the client requirement was something like this. So I have to do this. Anyway thanks for your suggestion.

Not sure what specially your client is asking for but my proposed solution is to create 2 custom fields in your doc let’s call them “first_approver” & “second_approver” which will hold the user who did the workflow action.

Then map them based on your workflow states (let’s say “Primary Approval”, “Approved”);

frappe.ui.form.on("Whatever doc this is", {
  validate: (frm) => {
    if(frm.doc.workflow_state === 'Primary Approval'){
      frm.doc.first_approver = frappe.session.user
    } else if(frm.doc.workflow_state === 'Approved'){
      frm.doc.second_approver = frappe.session.user
    }
  }
})

Disable the visibility of those fields, then add them to your report/print.
Not tested, might not be the best solution.

Good Luck

it’s not working… :frowning_face:
is there any default system or efficient way to show the approvals name on the print format?

This could help

# Get the first comment that matches the specified filters
comment = frappe.db.get_all("Comment", filters={
    "comment_type": "Workflow",
    "reference_doctype": reference_doctype,
    "reference_name": reference_name,
    "content": comment_content
}, fields=["comment_email"], limit=1)  # Limit to 1 to get only the first entry

# Initialize a variable for the email
email = None

if comment:
    email = comment[0].get("comment_email")  # Get the first email if available

# Initialize a variable for the full name
full_name = None

if email:
    # Fetch the user's full name using the email
    full_name = frappe.db.get_value("User", {"email": email}, "full_name")

# Log the email and full name
log(f"Email: {email}, Full Name: {full_name}")

not working

{% set list =frappe.db.get_list('Comment',filters={'reference_doctype': 'Purchase Order','reference_name': doc.name,'comment_type': 'Workflow'},
order_by='creation ASC') %}
<h4 style="text-align: center;">AUDIT TRAIL</h4>
<table class='table table-bordered' style='margin:0px;border:0px solid black'>
    <thead>
        <tr>
            <th width="15%">Level</th>
            <th width="18%">User Name</th>
            <th width="18%">Email</th>
            <th width="18%">Date & Time</th>
            <th width="12%">Status</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Initiator</td>
            <td>{{frappe.get_fullname(doc.owner) }}</td>
            <td>{{doc.owner }}</td>
            <td>{{doc.get_formatted("creation")}}</td>
            <td>Submitted</td>
        </tr>
        {% for l in list %}
            {% set d = frappe.get_doc("Comment", {"name": l.name}) %}
            {% if d.content == "Pending - 1st Approver" %}
            <tr>
                {% set dc = frappe.get_doc("User Role", {"name": d.comment_email}) %}
                <td>{{dc.custom_role}}</td>
                <td>{{frappe.get_fullname(d.comment_email) }}</td>
                <td>{{d.comment_email}}</td>
                <td>{{d.get_formatted("creation")}}</td>
                <td>Approved</td>
            </tr>
            {% endif %}
            {% if d.content == "Pending - Final Approver" %}
            <tr>
                {% set dc = frappe.get_doc("User Role", {"name": d.comment_email}) %}
                <td>{{dc.custom_role}}</td>
                <td>{{frappe.get_fullname(d.comment_email) }}</td>
                <td>{{d.comment_email}}</td>
                <td>{{d.get_formatted("creation")}}</td>
                <td>Approved</td>
            </tr>
            {% endif %}
            {% if d.content == "Final Approved" %}
            <tr>
                {% set dc = frappe.get_doc("User Role", {"name": d.comment_email}) %}
                <td>{{dc.custom_role}}</td>
                <td>{{frappe.get_fullname(d.comment_email) }}</td>
                <td>{{d.comment_email}}</td>
                <td>{{d.get_formatted("creation")}}</td>
                <td>Approved</td>
            </tr>
            {% endif %}
            {% if d.content == "Rejected" %}
            <tr>
                {% set dc = frappe.get_doc("User Role", {"name": d.comment_email}) %}
                <td>{{dc.custom_role}}</td>
                <td>{{frappe.get_fullname(d.comment_email) }}</td>
                <td>{{d.comment_email}}</td>
                <td>{{d.get_formatted("creation")}}</td>
                <td>Rejected</td>
            </tr>
            {% endif %}    
        {% endfor %}
    </tbody>
</table>

I did for print format
it’s working fine.
Get idea from here and write according in report

i needed for purchase invoice doc.type.
i guess i need to create 3-4 custom field and then apply the script ?

Thank You

If workflow applied on your Purchase Invoice Doctype
No need of create custom fields

In filter user

'reference_doctype': 'Purchase Invoice'
1 Like

i understand but this script is for the print,i dont want that,ijust want to display the names in some fields of the purchase invoice, i can view that via activity tab but still i dont want to scrolldown and add a field in whcih the names of the approvers should be there.

Then you have to create field and set value accordingly. then show in the listview

YEah,if possible can you help me a bit regarding the script ?

I created 2 custom fields.

1- PM Approver

2- PC Approver

And now i want to fetch the Pm & PC field whenever the invoice got submit by the pm as well as pc.

Thank You

Just create the fields, then update them when you submit the document.
Then you can easily fetch them and display in print format