cancel
Showing results for 
Search instead for 
Did you mean: 

How to use exit_cancelled macro option in a class method?

afsar_ashraf
Participant

Hi experts,

I have a decision step in my workflow.We are using a screen where user has the option to Approve,Reject or use the back/cancel button.The screen is displayed

through a FM call in an abap class method which is inturn attached to a standard task. I have designed the outcomes to handle Approve/Reject option & is working fine.Now my requirement is,if the user choose back/cancel button,the workitem should stay in his inbox for a later processing.

I know that exit_cancelled macro can be used to achieve this functionality,but it can be used only inside a BOR method. Tried to Include the "INCLUDE <OBJECT> in the class method to access this macro, but system doesnt allow me to use that include.I do not want to tick "Confirm end processing" checkbox in the task either,because it presents one more screen and will be irritating for the users. Would really appreciate if someone can suggest an alternative for exit_cancelled macro..Thanks!

Regards,

Afsar

Accepted Solutions (1)

Accepted Solutions (1)

anjan_paul
Active Contributor

Is it solved

afsar_ashraf
Participant
0 Kudos

Dirk, I am not using the standard decision task,instead a  custom screen because we need to display certain details for the approver.

Anjan&Vinoth: Thanks for suggesting the exception CX_BO_ACTION_CANCELLED.But I will end up in a design issue if I go for class based exceptions!!

Let me explain how I desinged the Approval step:-

My activity has got 4 outcomes-Approved/Rejected/Error/Put back to original users(if some approver forward the workitem to a user who is not authorized to approve the amount, I will put back the workitem to original approver list,so activity is in a loop)

As you know an activity step will have 2 standard outcomes-Step executed & Processing obsolete.

In my class method I have created the exceptions "Rejected","Error" and "Put back" so that these outcomes also appear in the activity. Now I raise these exceptions based on the user decision.

If user rejects the workitem.

  Raise "Rejected"

elseif error occurs

Raise "Error"

elseif wrong approver tries to execute

Raise "Put back"

Endif.

If no exceptions are raised in the method,I use the Step executed outcome as "Approved".

Since we cannot use the old and class based exceptions together in the method,I dont think I can go for CX_BO_ACTION_CANCELLED exception approach.

In that case, I will have to use an exception class which will give a single outcome(exception class name) in the activity, apart from the standard 2 outcomes(Step executed & Processing obsolete).And I cannot model my 4 different outcomes as per the requirement.

More over if I raise CX_BO_ACTION_CANCELLED exception, I will have to catch it inside the method & perform some action to pass this to the workflow activity(which I am not sure how I can achieve).Otherwise workitem ends up in error status.

Kindly suggest if someone has a workaround/better design for this.Appreciate your feedback!!

Regards,

Afsar

dirk_wittenberg
Contributor
0 Kudos

Hi Afsar,

why don't you display the details needed by the approver in the task description?

Regards,

Dirk

afsar_ashraf
Participant
0 Kudos

Hi Dirk,

There is actually more to it than just displaying certain fields/details.We are displaying the line items of a document& the approver should be able to drill down to each line item by clicking on it & verify them.Thats why we designed a custom screen.

Regards,

Afsar

anjan_paul
Active Contributor
0 Kudos

Hi,

you cant directly use CX_BO_ACTION_CANCELLED like that way.

you declare the exception in class and raise it like

WHEN 01.

       RAISE EXCEPTION TYPE cx_bo_error.

WHEN 02.

       RAISE EXCEPTION TYPE cx_bo_action_cancelled.



anjan_paul
Active Contributor
0 Kudos

With addtion to previous one.

For Approve and reject you are returning some data type from class.. Take it as SWX_PROCST. It will work for you.

dirk_wittenberg
Contributor
0 Kudos

That doesn't solve the problem that raising an exception will put the workitem into status error.

Maybe that can be handled within a program-exit class ( tab strip "Program Exits" within the step definition ),

but I'm not sure wether you can change the status of the workitem there.

Regards,

Dirk

anjan_paul
Active Contributor
0 Kudos

Hi Dirk,

       I just show how to use Exception. That does not mean I ask him to raise cx_bo_error.

He can only raise cx_bo_action_cancelled.

It will put into Error status.

You can try it.

anjan_paul
Active Contributor
0 Kudos

Hi Afsar,

  Did you try it.

afsar_ashraf
Participant
0 Kudos

Hi Anjan,

I tried it, but as Dirk mentioned Raising an exception will end the workitem in error status. Even if we raise cx_bo_action_cancelled, I should catch this exception in the method.This will in effect result in the Approval outcome(kindly look at the design I explained above)

For Approve and Reject , I am not returning any data type.No exception means outcome Step executed and have "Approved" status.

Regards,

Afsar

anjan_paul
Active Contributor
0 Kudos

Hi Afsar,

Design like that way. Take a method suppose Approve method. In this method Take a parameter of Returning type SWX_PROCST. Take Exception cx_bo_action_cancelled.

Then put your logic.

And use the method in your workflow. Try it.

afsar_ashraf
Participant
0 Kudos

Hi Anjan,

If I understand correctly, you are suggesting to use the activity step just to return the processing status-like a flag holding status = A(Approved), R(Rejected), E(Error), P(put back). The activity step will have a "single outcome" in that case & below that we have to use a multiple condition step to check the flag & spread the branches, right? But here also, the exception cx_bo_action_cancelled should be modeled, which result in the workitem in executed/completed status if the user press cancel button.This is what I feel,nevertheless I will give it a try!!

If I use a BOR method, the macro exit_cancelled would have allowed me to handle the Cancel option easily.I don't need to model an exception for cancel option.I am very surprised why such a simple scenario cannot be handled in class method,sometimes SAP make you scratch your head right:-)

Regards,

Afsar

anjan_paul
Active Contributor
0 Kudos

Hi,

No need to use Multiple condition.

Just use it as I say, It will handle same way. After using the method. Go to the Step outcome you will see all the outcome approve reject and exeption will come. You need to activate it

In SWX_PROCST in domain level approve reject is defined.

anjan_paul
Active Contributor
0 Kudos

Is it working

afsar_ashraf
Participant
0 Kudos

Hi Anjan,

I tried your suggestion,unfortunately it doesnt work the way you expected.

Here is what I did..In my class method I created an exception for CX_BO_ACTION_CANCELLED and also created an exporting parameter e_result of type SWX_PROCST.I set the e_result flag with A/R/N values in the method based on the function codes. Did the binding of this flag in the task container to a workflow container element of same type. The outcome doesnt show the Approve/Reject option. Only the exception appears as an outcome apart from the 2 standard outcomes.

Regards,

Afsar

dirk_wittenberg
Contributor
0 Kudos

But then you should have a value in your container element e_result which you can use in a multi-branch ?

I tried Anjans solution also in a small test workflow and for me it works.

I used function module POPUP_TO_CONFIRM for the user decision.

I get either a value 1 or 2 depending of my decision in a container element or the workitem stays in status STARTED when the user aborts the decision step. To receive this behavior you  must not model the outcome for the exception CX_BO_ACTION_CANCELLED .

When you modell the outcome for the exception CX_BO_ACTION_CANCELLED and the user aborts, the workitem will be completed and the workflow continues in the outcome for the exception.

Regards,

Dirk

afsar_ashraf
Participant
0 Kudos

Dirk, how you got this worked? Did you set the result 1 or 2 to the _WI_Result element? And did you use a class method in your standard task? For me the _WI_Result element doesn't appear in the task container!!

dirk_wittenberg
Contributor
0 Kudos

I defined a exporting parameter in the method of my abap-oo class I'm using in my workflow.

this parameter is being filled directly from the function module.

afsar_ashraf
Participant
0 Kudos

Hi Dirk,

Thanks a lot for sharing the screen. I just want to know how the e_answer parameter in the method is bound to the task container i.e. to which task container element? Is it  _WI_Result? Or are you binding to a user defined element? Because I tried to bind the e_result value to a user defined element(for me _WI_Result element doesn't exist) in task container and subsequently to WF container,therefore Approve/Reject option doesn't appear in the outcomes.One more point,my class is a utility class.So a static method is what I am using.

Regards,

Afsar

dirk_wittenberg
Contributor
0 Kudos

Hi Afsar,

I'm using a user define element in the task and workflow-container.

What do you mean with utitility class? Whether your method is static or an instance method shouldn't be of importance.

Regards,

Dirk

afsar_ashraf
Participant
0 Kudos

Hi Dirk,

Utility class is nothing but a common class used across different workflows,so interface IF_WORKFLOW is used but the methods like BI_PERSISTENT~LPOR are not implemented.So all the class methods we define will be static.

Anyway it seems like we have done exactly the same steps.

But the outcome appears like below(no Approve/Reject option which is supposed to be transferred from the domain values)

This is the issue which I was referring to,probably the non modeled exception will keep the workitem in the inbox when user cancels the processing.

I think you are also getting the same outcomes as above, because it looks like you have used result value of type CHAR.

So the problem here is we cannot model the user decision steps Approve/Reject.

Regards,

Afsar

dirk_wittenberg
Contributor
0 Kudos

But you get the result value back? Why don't you  use it in a branch following in the "Step executed" outcome?

The outcomes in my workflow look like the ones in your.

-----

But I just got a totally different solution that might work for your problem:

Why don't you declare your action task as asynchronous and use two completing events in your class - one for approval and one for rejection?

If the user aborts no completing event will be triggered and the workitem stays in the inbox.

And you get two outcomes - one for each event?

Regards,

Dirk

afsar_ashraf
Participant
0 Kudos

Hi Dirk,

Thanks for the suggestion-to mark task as asynchronous & use the terminating events. In fact I was aware about this, but I didn't want to complicate things by raising different events for all the possible outcomes!!

Meanwhile the suggestion given by Anjan will work, it will also display the possible outcomes.The mistake I did was e_result parameter was not "Returning", it was "Exporting" type. I changed it to "Returning", now the outcomes are displayed with the values in the domain.

Regards,

Afsar

Answers (4)

Answers (4)

afsar_ashraf
Participant

Thanks to all for your kind help, especially Anjan & Dirk

Just to summarize & make the next person's life easier- If anyone is using a custom screen for Approval/Rejection process in a workitem, the following options can be used to keep the workitem in the processor's inbox , if he/she clicks the Cancel button.

1.If the logic is written in a BOR method, use the exit_cancelled macro.

2.If the logic is written in a class method, 1st option:-

  a) Raise the exception cx_bo_action_cancelled, when the user clicks on Cancel/Exit button on the screen. Do not model this outcome in your workflow step.

  b) Use a RETURNING parameter of type SWX_PROCST to pass back the user decision  

     (Approve/Reject) to workflow.The domain values of SWX_PROCST will appear as the outcomes &

     you can model them. If you want to have multiple outcomes other than Approve/Reject, create 

     your own data element with the required domain values,instead of using SWX_PROCST.

    

      This approach can be compared with marking the "Result parameter" option in BOR method.

   In the above case, task container will have an additional parameter _WI_Result

3.If the logic is written in a class method, 2nd option:-

  a) Make the task as asynchronous & specify the terminating events

  b) Terminating events appear as outcomes in the workflow step

  c) If user clicks Cancel/exit, no terminating events are raised, so the workitem stays in the user

     inbox.

Regards,

Afsar

dirk_wittenberg
Contributor
0 Kudos

Hi Afsar,

good to hear that you finally got your workflow flowing.

Regards,

Dirk

former_member185167
Active Contributor
0 Kudos

Thanks for the summary!

Former Member
0 Kudos

Hi

I would like to correct the point 2.

[.If the logic is written in a class method, 1st option:-

  a) Raise the exception cx_bo_action_cancelled, when the user clicks on Cancel/Exit button on the screen. Do not model this outcome in your workflow step.

  b) Use a RETURNING parameter of type SWX_PROCST to pass back the user decision 

     (Approve/Reject) to workflow.The domain values of SWX_PROCST will appear as the outcomes &

     you can model them. If you want to have multiple outcomes other than Approve/Reject, create

     your own data element with the required domain values,instead of using SWX_PROCST.]

   

I have made a small test and in fact, I have not use a returning parameter or any parameter and it is working fine.

So basically all you need to do is raise the exception and then it works !

Cheers

Stephane

former_member183917
Active Contributor
0 Kudos

Hi,

Is this the custom screen, are you giving options like Approve, Reject or Cancel and this custom screen is getting called from workflow class?

If yes, you can raise exception like:

RAISE EXCEPTION TYPE cx_bo_action_cancelled

(You can also pass exporting parameters like textid..... )

Vinoth

dirk_wittenberg
Contributor
0 Kudos

Hi,

why don't you use the standard user-decision step? This kind of workflow step has by default an option     "Cancel and keep workitem in inbox".

Regards,

Dirk

anjan_paul
Active Contributor
0 Kudos

Hi,

For class you have to use CX_BO_ACTION_CANCELLED exception.