Wednesday, August 31, 2011

Tip - Retrieve Deleted ABAP Program



Problem

Sometimes crazy things happen. People just delete the program assuming it is no longer required. Few days later, the same program is needed. But it doesn’t exist anymore. 

Solution

Create a program with the same name as it existed before. Once the program is created, we can go into version history. The previous program version still exists. So we can retrieve that version, activate and transport using a new transport request.

System user WEBDAV - Logon error



Whenever any new CRM system is set up or system is copied from production or quality, there are quite a few things that won’t work on the new system. Some of them like transaction launchers and attachments on Web UI. Everyone knows how to fix the transaction launcher settings. It can be fixed easily by going into transaction CRMS_IC_CROSS_SYS. Here I will explain how to fix the attachments error.

Problem
On the new system, when we try to open the attachments, we get the below error.



It says that logon was performed using user WEBDAV and the logon was failed. That was the reason we couldn’t open the attachments on web UI.

How to fix this Error?

After some research, I found the below solution.
1.       Go to transaction code SICF. Navigate to the service default_host/sap/bc/contenserver. Activate this service if it is not already active.





2.       Double click on that service and goto the tab Logon Data. Click on change mode. Select the procedure as ‘Standard’ and then maintain the logon details as shown below.




\
3. Now I thought it is done and tested the attachments on Web UI. But still I got the same error as shown in the first screenshot. Then I went to my Basis experts and explained the problem. After doing some research they came back to me saying that the logon details also need to be maintained in aliases as explained below.

4.       In transaction code SICF, Click on ‘External Aliases’ on the application toolbar. That will take you to the below screen. Select ‘/sap/bc/contentserver’ and maintain the logon details for user ‘WEBDAV’.




When I tested the attachments again, it worked. The next time we get this WEBDAV logon error, we know the process of how to fix it.


EEWB & AET



Both EEWB (Easy Enhancement Workbench) and AET (Application Enhancement Tools) tools are used to add custom fields to any CRM object. Going back to history, EEWB was provided by SAP from CRM 4.0 (I only started working from CRM 4, not sure if it existed before) and was very handy tool to add new fields on CRM 4, 5.  EEWB was mainly used by developers as it still required some technical knowledge for adding fields. AET has taken the wizard to next level by enabling to directly add fields on CRM UI. AET is quite easy to use and was mainly designed with the idea to simplify adding of custom fields to any CRM object. Any person with fair amount of CRM knowledge can use AET to add custom fields.

I like both of these tools and worked extensively of EEWB. Using EEWB, I added fields. Then I created tables, tabstrips and included those custom fields on the Additional Data tab in CRMD_ORDER. This was possible as we were still working on GUI and I could play around in any way according to the requirement. We can’t add tables using AET as of now. If SAP can provide this option in the future releases, that would be great.

Below are few things that I want to highlight about these two tools.

1.       Any custom fields added using AET doesn’t exist on Additional Data/Customer Fields Tab on CRMD_ORDER. This is a bit strange and I really didn’t understand why SAP didn’t provide this feature. I know SAP wants to drive CRM only through web UI. But still I would like to have this feature of displaying custom fields added using AET on GUI as well. This is the only concern that I have with AET.
2.       AET has made life much simpler if we want to add dropdown boxes, Search Helps, Currency and Quantity fields.  Using EEWB, it was a bit more complicated in having these features.
3.       Using AET, we can reuse the custom fields in other objects. This is really cool thing which prevents us to recreate the same custom field if required in any other object.

For now, I’m enjoying AET more than EEWB. AET is future ahead for adding new fields. Maybe AET will have the capability to add assignment blocks directly some day.

ABAP wed dynpro framework vs CRM UI framework



I have been doing development on CRM UI for quite a while. Recently I started to work on ABAP Web dynro developments. At first, I thought it would be quite similar to CRM UI development as I knew both of them were based on MVC (Model View Controller) Architecture. Although both of them were developed by using MVC technology, there are quite a few differences that I found out.

1.     The output screen of ABAP web dynpro is not fancy like CRM web UI screen. The CRM web UI screen has got more AJAX features in it and that is what it makes look so good. The output screen of webdynpro has got more screens flickering and we can’t use it in a more robust environment. For robust environments and high usage, SAP recommends using Java wed dynpro.
2.     AWD (ABAP web dynpro) doesn’t use BSP to design the view. It uses more of SE51 screen painter extension to design the view.
3.   AWD view hasn’t got good control over its view attributes. I mean CRM UI framework provides methods like SET, GET, VALUE etc. to handle each attribute independently. But we don’t have that feature in AWD.
4.      From a development perspective, there is a tool called BSP Component Workbench in CRM which is very good to enhance the SAP standard solution. Also all the developments done using BSP component workbench will be supported during the upgrade.
5.      The best thing that I liked in AWD is the wizard. It generates the code as per requirement in most of the cases.

There are lot of features on CRM UI framework which doesn’t exist on AWD. Maybe both of them were developed for completely different objectives by SAP and I should embrace them differently than comparing them against each other.

For now, I’m a big fan of CRM UI framework and a bit unhappy about AWD. Maybe if I spend a bit of time on AWD, then I may develop more liking towards it.

Navigation and Pop up on CRM WEB UI


Below example is only for CRM Web UI.

In SAP CRM 7, when a document is being created with reference to another document, there might be a requirement to check whether there is already a document which was already created with reference to that document. (For example if you want to create a Complaint on CRM with reference to an ECC Invoice document, and we want to check if there is already a Complaint created against that Invoice. Below is an example in the screenshot where we need to create a Complaint after an invoice is selected. We need to now check if a Complaint already exists for this invoice and then trigger a pop up and then navigate based on the selections made by the user in the pop up.)


I know it’s not a complex requirement. But still I thought of posting here as I enjoyed doing it and maybe it can be useful to someone.

My approach to the requirement is as follows
1. Create a pop up if a document already exists.
2. Pop up has two options called ‘yes’ and ‘no’.
3. If user clicks on ‘yes’ button, it should continue creating a new document which is continuation of the normal process.
4. If user clicks on ‘no’ button, it should navigate to the existing Complaint document that was already created with reference to that invoice.

How to create a pop up and handle it

We first need to identify where to start the process of creating the pop up. For that first we need to identify the component, the view and the method of the controller class where the popup needs to be raised. In my case, I needed to trigger it in the method that got raised after user clicks on the create Complaint button.

To trigger pop up using the controller class, we need to add an attribute to the controller class. Below is attribute details.

CONFIRM_POPUP Instance Type Ref To IF_BSP_WD_POPUP.

In the Complaint create method; I checked if a Complaint already exists for the selected Invoice document. If there was a Complaint already, I called the method EH_ONCONFIRM_POPUP () to raise a pop up. Below is the extract of the code in that method.

method EH_ONCONFIRM_POPUP.

IF CONFIRM_POPUP IS NOT BOUND.

DATA: LV_SAVE TYPE STRING,
LV_TEXT TYPE STRING.

LV_SAVE = CL_WD_UTILITIES=>GET_OTR_TEXT_BY_ALIAS( 'CRM_UIU_GRM_GAG/SAVE' ). "#EC N
LV_TEXT = CL_WD_UTILITIES=>GET_OTR_TEXT_BY_ALIAS( 'CRM_UIU_GRM_GAG/CONFRIM_SAVE' ).

CALL METHOD COMP_CONTROLLER->WINDOW_MANAGER->CREATE_POPUP_2_CONFIRM
EXPORTING
IV_TITLE = 'EXISTING COMPLAINT'
IV_TEXT = 'A COMPLAINT ALREADY EXISTS FOR THIS INVOICE'
IV_BTNCOMBINATION = IF_BSP_WD_WINDOW_MANAGER=>CO_BTNCOMB_YESNOCANCEL
RECEIVING
RV_RESULT = CONFIRM_POPUP.

CONFIRM_POPUP->SET_ON_CLOSE_EVENT(
IV_EVENT_NAME = 'CONFIRM_POPUP_CLOSED'
IV_VIEW = ME ).

ENDIF.

CONFIRM_POPUP->OPEN( ).

endmethod.

Now the pop up is raised, we need to handle what the user has clicked and then navigate based on the user response. Once user selects any option, we can check the method DO_HANDLE_EVENT in order to trigger the follow up method based on the event ‘CONFIRM_POPUP_CLOSED’. Below is the extract of the code in DO_HANDLE_EVENT method.


From the above screenshot, we can see that EH_ONCONFIRM_POPUP_CLOSED () is called. In this method, we will handle the navigation based on the user selection of ‘yes’ or ‘no’ options.

METHOD EH_ONCONFIRM_POPUP_CLOSED.

DATA: LV_ANSWER TYPE STRING,
LV_SAVE_RESULT TYPE ABAP_BOOL,
LR_APPLICATION TYPE REF TO CL_CRM_BOL_ENTITY,
LR_TX TYPE REF TO IF_BOL_TRANSACTION_CONTEXT,
LR_CUCO TYPE REF TO CL_BT120H_C_CUCOCOMPLAINT_IMPL, "CL_CRMCMP_G_BSPWDCOMPONE0_IMPL,
LR_CUCO_WRP TYPE REF TO CL_BSP_WD_COLLECTION_WRAPPER,
LR_ENTITY TYPE REF TO CL_CRM_BOL_ENTITY,
LR_CUWRP TYPE REF TO CL_BSP_WD_COLLECTION_WRAPPER,
LR_WDW TYPE REF TO CL_BSP_WD_WINDOW,
LV_GUID TYPE CRMT_GENIL_OBJECT_GUID,
LR_CORE TYPE REF TO CL_CRM_BOL_CORE,
LR_COLLECTION TYPE REF TO IF_BOL_BO_COL."CL_CRM_BOL_BO_COL.

INCLUDE: CRM_OBJECT_TYPES_CON.

LV_GUID = 'E0752CF1A89EFAF1AE30005056B31BED'.

LV_ANSWER = CONFIRM_POPUP->GET_FIRED_OUTBOUND_PLUG( ).

CASE LV_ANSWER.

WHEN CL_GS_PTC_BSPWDCOMPONENT_CN01=>CO_EVENT_YES.
*Here we can call the method to continue normal creation of the document (Complaint)
CALL METHOD ME->EH_ONCREATECOMPLAINT
EXPORTING
HTMLB_EVENT = HTMLB_EVENT
HTMLB_EVENT_EX = HTMLB_EVENT_EX.

WHEN CL_GS_PTC_BSPWDCOMPONENT_CN01=>CO_EVENT_NO.
*Now we need to navigate to the existing Complaint

LR_CORE = CL_CRM_BOL_CORE=>GET_INSTANCE( ).
LR_ENTITY = LR_CORE->GET_ROOT_ENTITY( IV_OBJECT_NAME = 'BTOrder' IV_OBJECT_GUID = LV_GUID ).
CHECK LR_ENTITY IS BOUND.

CREATE OBJECT LR_COLLECTION TYPE CL_CRM_BOL_BO_COL.
LR_COLLECTION->ADD( LR_ENTITY ).
OP_OVERVIEW( IV_DATA_COLLECTION = LR_COLLECTION ).

WHEN OTHERS.

ENDCASE.


ENDMETHOD.

From the above method we can get the value of what the user has selected using ‘LV_ANSWER’. If the option selected by user is ‘Yes’, we should allow the user to create a new document by following the normal process of creation of the document. If the option selected by user is ‘no’, then the user should automatically navigate to the existing Complaint which was already created which reference to that invoice document.

Automatic navigation to the existing Document (Complaint)

To navigate to the existing complaint document, we need to do the following things.
1. Create an outbound plug on the component that we are working on.
2. Create a navigational link between the outbound plug of your current component and the inbound plug of the component where you want to navigate.

To create an outbound plug, navigate to the component workbench and then you can create an outbound plug. For example I created the outbound plug called ‘OP_OVERVIEW’ so that we can navigate to the main page of the existing document. Below is the extract of the code in the outbound plug method ‘OP_OVERVIEW’.


To create a navigational link, we need to go to runtime repository editor in the component workbench and click on create navigational link. Below is the screenshot of the navigation link that is similar to which we need to create according to our individual requirement.


We need to understand how to use the outbound plug. If we just go back to our method EH_ONCONFIRM_POPUP_CLOSED, we can see the code where an entity (LR_ENTITY) is created using the guid number. Then this entity needs to be added to the collection and then passed onto the outbound plug method.

That's it. Now we know how to create a pop up in web ui, how to handle it and then how to navigate to any page view on web ui.

Hari