cancel
Showing results for 
Search instead for 
Did you mean: 

Class /SAPSRM/CL_WF_PROCESS_LEVEL method IS_LAST_LEVEL not working

Former Member
0 Kudos

We are running SRM 7.0 SP 8 with Process Controlled Workflow.

I am trying to use object with reference to class /SAPSRM/CL_WF_PROCESS_LEVEL, method IS_LAST_LEVEL to determine if the current workflow process level is the last in an N-step approval. But the method does not return what I am expected, instead, it is always returning abap_true. I am puzzled for a while for this. Following is my code excerpt with this call:


        data:ls_process_level    type /sapsrm/s_wf_process_level,
             lo_curr_proc_level  type ref to /sapsrm/cl_wf_process_level.

          call method /sapsrm/cl_wf_apv_facade=>get_current_process_level
            exporting
              iv_document_guid = iv_doc_guid
            importing
              es_process_level = ls_process_level.

          try.
              lo_curr_proc_level = /sapsrm/cl_wf_process_level=>getpersistent_by_oid( ls_process_level-level_guid ).

              if lo_curr_proc_level->is_last_level( ) eq 'X'.
                lv_final_step = 'X'.
              endif.

            catch cx_root.
              raise exception type /sapsrm/cx_wf_not_found.
          endtry.

Note: After the call to /sapsrm/cl_wf_process_level=>getpersistent_by_oid, lo_curr_proc_level is returned with the actual valid object. The issue is only with the next call to IS_LAST_LEVEL.

If you can shed some light as to what might be wrong with this code, OR, how else you would determine whether the current process level is the last step in an N-step approval, I'd really appreciate it.

Thanks.

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi,

Try the below code

DATA lo_first_level TYPE REF TO /sapsrm/cl_wf_process_level.

DATA lo_temp_level TYPE REF TO /sapsrm/cl_wf_process_level.

DATA lo_obsolete_level TYPE REF TO /sapsrm/cl_wf_process_level.

DATA lv_process_status TYPE /sapsrm/wf_process_status.

DATA lo_process_config TYPE REF TO /sapsrm/cl_wf_configuration.

DATA lv_process_scheme TYPE /sapsrm/wf_process_scheme.

DATA lv_document_guid TYPE /sapsrm/wf_document_guid.

DATA lv_document_type TYPE /sapsrm/wf_document_type.

DATA lo_object_service TYPE REF TO /sapsrm/cl_wf_object_service.

DATA lo_runtime_config TYPE REF TO /sapsrm/if_wf_runtime_hdl.

DATA ls_config_value TYPE /sapsrm/s_wf_runtime_result.

DATA lv_config_value TYPE /sapsrm/wf_conf_attr_val.

DATA lv_restart_process_scheme TYPE /sapsrm/wf_process_scheme.

DATA lv_first_level_id TYPE os_guid.

DATA lv_final_acceptance_registered TYPE /sapsrm/wf_conf_attr_val.

CONSTANTS:

lc_prc_level_class_name TYPE seoclskey VALUE '/SAPSRM/CL_WF_PROCESS_LEVEL',

lc_scheme_attribute TYPE /sapsrm/wf_conf_attr VALUE 'PRC_RSTSCE', " Process restart scheme

lc_level_attribute TYPE /sapsrm/wf_conf_attr VALUE 'PRC_RSTLVL'. " Process restart first level

rv_updated = abap_false.

lv_document_type = io_process->getdocument_type( ).

lv_document_guid = io_process->getdocument_guid( ).

CREATE OBJECT lo_object_service.

CREATE OBJECT lo_process_config

EXPORTING

iv_document_type = lv_document_type

iv_document_guid = lv_document_guid

io_process = io_process.

lv_process_scheme = lo_process_config->get_process_scheme( ).

IF lv_process_scheme EQ io_process->getprocess_scheme( ) AND iv_force_update EQ abap_false.

RETURN.

ENDIF.

lv_process_status = /sapsrm/cl_wf_process_manager=>get_process_status( lv_document_guid ).

"--- Get the OID of the first process level

TRY.

lo_runtime_config = /sapsrm/cl_wf_process_manager=>get_runtime_config(

io_process = io_process

).

IF lo_runtime_config IS NOT BOUND.

RAISE EXCEPTION TYPE /sapsrm/cx_wf_abort.

ENDIF.

CLEAR ls_config_value.

lo_runtime_config->get_attribute(

EXPORTING

iv_attribute = lc_level_attribute

IMPORTING

es_attribute_result = ls_config_value

).

lv_first_level_id = ls_config_value-attribute_value.

CATCH /sapsrm/cx_wf_error. "EC NO_HANDLER

CLEAR ls_config_value.

ENDTRY.

"-- Get the Flag of FINAL_ACCEPTANCE_REGISTERED

TRY .

CLEAR ls_config_value.

lo_runtime_config->get_attribute(

EXPORTING

iv_attribute = /sapsrm/if_wf_process_c=>gc_wf_runtime_attrib_010 "'ACP_FINAL'

IMPORTING

es_attribute_result = ls_config_value

).

lv_final_acceptance_registered = ls_config_value-attribute_value.

CATCH /sapsrm/cx_wf_error. "EC NO_HANDLER

CLEAR ls_config_value..

ENDTRY.

"--- Determine current object state of the process instance

IF ( lo_object_service->is_new_instance( io_process ) EQ abap_true OR

lo_object_service->is_changed_instance( io_process ) EQ abap_true ) AND

lv_process_status EQ /sapsrm/if_wf_process_c=>gc_process_status_initial.

"--- Delete obsolete process levels in case process instance is still in initial state

lo_temp_level = io_process->getfirst_level( ).

DO.

IF lo_temp_level IS NOT BOUND.

EXIT.

ENDIF.

tif this field lo_temp_level->is_last_level( ) is 'X'

Saravanan

Former Member
0 Kudos

Hello Saravanan,

Thanks for the codes. There are some hints of potential object references in it. But I have tried to utilize those object references and the NEXT_LEVEL reference is never reliable. It is always bound but with initial values to all the fields, regardless if this is actually the last level or not. I have the feeling that these codes are rather for internal use only when some particular states were maintained. When they are called from outside of the workflow framework, those states are not maintained. Are these codes your custom codes or from standard?

In your following code sample,

"--- Delete obsolete process levels in case process instance is still in initial state

lo_temp_level = io_process->getfirst_level( ).

DO.

IF lo_temp_level IS NOT BOUND.

EXIT.

ENDIF.

tif this field lo_temp_level->is_last_level( ) is 'X'

This field lo_temp_level would be the first level, not the current level. How is calling is_last_level( ) for this level making sense? Would you explain please? Thanks.

Former Member
0 Kudos

Hi,

This is standard code. i'll try to get back to you with my suggestion.

Saravanan

Former Member
0 Kudos

Update: The OSS message we created to SAP for the same issue has been bounced back to us stating that the class and method mentioned in this thread are not "meant to be used" as we had intended. But of course, they didn't come up with any further suggestions as to what to use.

So my question remains and I would rephrase it to "how can I determine if the current workflow process level is the last step at run time", e.g. is there a function module or a table to look into for such determination?

Any of your suggestions would be appreciated!

Former Member
0 Kudos

Hi,

May i know your requirement?

Saravanan

Former Member
0 Kudos

Certainly. What we are trying to achieve is to invoke Document Builder and change the document status over there when the SRM document, such as PO or RFx is changing its status to "Ordered" (PO) or "Published" (RFx). We must make the check at the very last stage (hence in BBP_DOC_SAVE_BADI implementation) just to make sure that in the case of update failure for the SRM document, the Document Builder document status is not getting changed either. Thanks.

Former Member
0 Kudos

Hi,

Nice , i am also implmenting Document Builder at my current customer. You can only goto document builder cockpit to add element to document when the PO, RFX and Contract is in Saved status. Once you release the DB and logoff from my cockpit then document will be transferred to respective business document in the attachment tab. let me research further and get back to you..

Saravanan

laurent_burtaire
Active Contributor
0 Kudos

Hello Jay,

If you still have problem with method IS_LAST_LEVEL, one solution could be to get the SC instance from the PDO buffer ( /SAPSRM/CL_PDO_FACTORY_SC_ADV=>GET_BUFFERED_INSTANCE ).

If the instance is bound, get the source document instance ( /SAPSRM/CL_WF_PDO_IMPL_FACTORY=>GET_INSTANCE ).

Then, get the process info if the SC is intanciated ( /SAPSRM/IF_PDO_DO_APV_EXT~GET_PROCESS_INFO ).

With the exporting parameter ES_PROCESS_INFO, check if PROC_DETAIL_LIST has a Forecast time indicator. If not, you current process level is the last one.

Regards.

Laurent.

Former Member
0 Kudos

Thanks a lot Laurent! This approach worked like a charm. I was at the brink of giving up... I really appreciate your help!

May I ask what the call to "/sapsrm/cl_wf_pdo_impl_factory=>get_instance" is for in this case? The object reference returned from this call is not utilized to determine the process info.

Thanks again,

Jay

laurent_burtaire
Active Contributor
0 Kudos

Hello Jay

(...) May I ask what the call to "/sapsrm/cl_wf_pdo_impl_factory=>get_instance" is for in this case? The object reference returned from this call is not utilized to determine the process info.

(...)

Your are totally correct.

In ABAP code i use, source document instance is used to get source document responsible. This process is done just before the SC process info determination.

That's why i gave you this call method which has no use in your case: sorry

Regards.

Laurent.

Former Member
0 Kudos

Thanks for clarifying.

Former Member
0 Kudos

Hi Laurent,

I know this is a very old thread already but I hope you can help me. I'm new to SRM and I have a requirement to get

SEQUENCE WF

STATUS WF

PROCESSOR

RECEIVED ON

PROCESS ON

FORWARDED BY

from /SAPSRM/IF_PDO_DO_APV_EXT- GET_PROCESS_INFO. However, I don't know how to access the class and method. I've tried the typical ways of accessing it, however I get dump that object is null. Is there a specific way to access data from this?

Please advise. Or any input would be highly appreciated.

Answers (1)

Answers (1)

Former Member
0 Kudos

Hi Jay Yang,

I am also facing the same problem but not able to implement the solution mentioned by you. The last call to "Get_process_info" , by which instance you are calling this method. Can you copy your code segment here ?

Thanks in advance.

Rakesh