Forum OpenACS Development: how to get the resolver_id from a role?

In attempt to retrieve the user_id of the resolver of a ticket on bug-tracker. I needed to understand how the page bug.tcl display the correct user who is assigned to the ticket

i debugged some APIs on workflow package.
The process started at file bug.tcl line 319
it has the API call workflow::role::add_assignee_widgets

workflow::role::add_assignee_widgets -workflow_id $workflow_id -form_name bug -roles resolver

I went to the file workflow/tcl/role-procs.tcl where the API is located. At line 888, it calls another API in the same file called workflow::role::get_assignee_widget

ad_form -extend -name $form_name -form [list [get_assignee_widget -role_id $role_id -prefix $prefix -mode $mode]]

it is clear that apis are mounting extra ad_form extended fields with the workflow roles.

I went to the new API code and it has the line 743
set picklist [workflow::role::get_picklist -role_id $role_id]

This line takes to another API called workflow::role::get_picklist in the same file line 779. This API holds the resolver user_id info.

However, how does the code set the correct user by default on ad_form display mode?

Collapse
Posted by Iuri Sampaio on
The rest of the ad_form field is the output of API
workflow::role::get_assignee_widget

which is

return [list "${element}:search(search),optional" [list label $role(pretty_name)] [list mode $mode] \
[list search_query $query] [list options $picklist]]

as you can see no clues of how ad_form display the correct values by default.

Collapse
Posted by Dave Bauer on
Aha, this is a simple answer! ad_form will use either

1) The values of a variable with the same name as the form element in the scope the ad_form is called

OR

2) You can explicitly set the values in on_request block of ad_form by setting a variable with the same name as the form element.

Collapse
Posted by Iuri Sampaio on
Yes, i understand.

1. if you look at API picklist, it brings 4 values to the scope to fill the select widget of ad_form.
[workflow::role::get_picklist -role_id $role_id]

But in the first view (display mode), the field is not a select widget. It's a simple text field that shows the correct value among the 4 values. This is the behavior i don't get. How the correct values is set among 4

Only if you hit "edit form" then the select button shows up and the 4 values become available to be chosen

2. ad_form "bug" on bug.tcl has no on_request block.

Collapse
Posted by Dave Bauer on
I already explained that. The value of the variable for the select element is set to the user_id for the selected user.

The select widget in display mode, displays the correct selection. You can check out the code if you want to learn exactly how it works.

So you need to

1) Figure out the name of the select form element
2) Find out where the matching variable is set.

Collapse
Posted by Iuri Sampaio on
Dave, good to know we think alike. We are in the same page.

I need to:
1) Figure out the name of the select form element

The name of the form element is mounted in this line
set element "${prefix}$role(short_name)"
the output is: role_resolver

API workflow::role::get_assignee_widget
file wrokflow/tcl/role_procs.tcl line 740

2) Find out where the matching variable is set.
This is exactly what i was trying to do all the time i am debuging the APIs listed before
There's no matching of variables, or at least i haven't found it yet


Two main procs build the ad_form element
1. workflow::role::add_assignee_widgets
2. workflow::role::get_assignee_widget


1. It has the line
ad_form -extend -name $form_name -form [list [get_assignee_widget -role_id $role_id -prefix $prefix -mode $mode]]


2. It has the line

return [list "${element}:search(search),optional" [list label $role(pretty_name)] [list mode $mode] [list search_query $query] [list options $picklist]]

If we combine the output of 1 and 2 we have

ad_form -extend -name $form_name -form {

{role_submitter:search(search),optional {
label #bug-tracker.Submitter#}
{mode display}
{search_query {select distinct acs_object__name(p.party_id) || ' (' || p.email || ')' as label, p.party_id
from cc_users p
where upper(coalesce(acs_object__name(p.party_id) || ' ', '') || p.email) like upper('%'||:value||'%')
order by label}}
{options {
{ "Unassigned" "" }
{{carl manager (mailto:iuri_sampaio@yahoo.com.br)} 1134}
{{iuri sampaio (mailto:iuri.sampaio@gmail.com)} 643}
{{jim dispatcher (mailto:iuri_sampaio@computer.org)} 1137}
{{john dispatcher (mailto:iuri.sampaio@computer.org)} 1795}
{ "Other..." ":search:"}}
}}
}
}

That's everything the APIs do. Where is the matching that sets the correct values to show up on display mode then?

At first i thought the var list $query would do the match but i confirmed it doesn't by removing it from the code and i didn't get errors.

But then I see it is acs-templating that does the magic! The matching is in the API ad_proc -public template::widget::search

input type="hidden" name="role_resolver:select" value="t" select name="role_resolver" id="role_resolver"
option value="" Unassigned /option
option value="1127" selected="selected" bob technician (mailto:iuri@dcc.ufba.br)</option>
option value=":search:" Other.../option
/select


option value="1127" selected="selected" bob technician (mailto:iuri@dcc.ufba.br) /option

Now i need to figure out how to get the selected user id

Collapse
Posted by Deds Castillo on
It's returned as a list using the workflow::case::role::get_assignees api. This is used by workflow::case::role::set_assignee_values and extracts the first element to set it during display mode.
Collapse
Posted by Dave Bauer on
Or, I was wrong and Deds knows exactly how it works....
Collapse
Posted by Iuri Sampaio on
Deds,

workflow::case::role::get_assignees
workflow::case::role::set_assignee_values

Both procs use case_id as parameter and i don't have it from advance. I have only workflow_id, role_id and bug_id

How would i get the user_id of the resolver in the display mode?
I want to get the user_id, to pass it as parameter of an API, to use it in another field of the ad_form.

something like:

workflow::role::add_assignee_widgets -workflow_id $workflow_id -form_name bug -roles resolver

which is the API that returns the the ad_form element of the resolver on display mode.

Then i want to use the resolver info, only user_id.

ad_form -extend -name bug -form {
{item:text(select),optional
{label "Equipment"}
{options {[bug_tracker::get_items -user_id $role_resolver(user_id) -bug_id $bug(bug_id) -workflow_id $workflow_id]}}
{mode display}
}

I created the API bug_tracker::get_items
Attention to parameter $role_resolver(user_id)
This is a guess! Precisely what I am trying to figure out.

How to access the data structure (ad_form element) that holds the resolver info, in order to use it?

Collapse
Posted by Deds Castillo on
Iuri,

You can get the case_id so that you can use it as parameter to workflow::case::role::get_assignees in addition to role_id.

Check the code in bug-tracker/www/bug.tcl then just use your values for bug_id

set case_id [workflow::case::get_id -object_id $bug(bug_id) -workflow_short_name [bug_tracker::bug::workflow_short_name]]

Collapse
Posted by Iuri Sampaio on
Deds and Dave,

Problem solved. I ended up creating an API
ad_proc bug_tracker::get_items

the main part of it is:

set role_id [workflow::role::get_id -short_name $role -workflow_id $workflow_id]

set user_id [lindex [lindex [workflow::case::role::get_assignees -case_id $case_id -role_id $role_id] 0] 3]

the rest, i followed your tips above in this thread to get the parameters here and there

Thanks a lot!

Collapse
Posted by Dave Bauer on
You still need to trace all those procedures to find where the element value is set. There isn't any other way to do it. You'll need to carefully review all the code.

Unfortunately there isn't anyone who is intimately familiar with the workflow code who can give you an easy answer.