Wednesday, March 21, 2012

Update service in quotation document (RFQ)

A quotation document can have service lines instead of normal material lines. It is an external component of the document, here we will see how to update service line.

The functionality for managing services is in the function group MLSP. How service is integrated is described here.

These are following steps to update service line:

  1. Read service data in internal table of the function group. This is achieved by function module MS_GET_SERVICES.
  2. Set data in the internal table by calling function module MS_FILL_TABS_FROM_EXT_DATA and MS_CHANGE_SERVICE_PACKAGE.
  3. After that save by calling MS_SAVE_SERVICE_PACKAGE.

The function call requires communication structure COMSRV. This can be filled from the structure EKKO and EKPO. It is important that COMSRV-REF_BSTYP is set to ‘C’ (change). Refer function module BAPI_PO_CHANGE.

Friday, September 10, 2010

WebDynpro: Progress indicator (similar to SAPGUI_PROGRESS_INDICATOR)

Within normal ABAP reporting, if we are doing some long queries or posting a lot of transactions we would use the FM SAPGUI_PROGRESS_INDICATOR to stop the report from timing out. The same scenario can happen in WebDynpro as well. By default a WebDynpro application times out in 5 minutes. So posting a lot of transaction becomes a problem here too. WebDynpro does not provide a similar function to SAPGUI_PROGRESS_INDICATOR yet (coming in 7.1?).

So we would have to implement our own progress indicator by creating a WebDynpro component using UI elements TimedTrigger and ProgressIndicator. UI element TimedTrigger is an invisible element which when placed on a view, triggers an event every given number of seconds. This is an expensive UI element to have as it creates additional burden on the server, but we have no choice so we will use this. UI element ProgressIndicator is used to show a progress bar. So the idea is to split big job into chunks that can be done in small amount of time (less than the time out period). Every time TimedTrigger fires an event we process the next available chunk of work and set the progress bar and so on.

The calling WD component will use this component for displaying the progress bar and getting a timed wake up call. The calling WD will already have the dataset ready. It would decide how many chunks the dataset will be needed divide into. So once the user triggers the action this progress indicator (PI) WD component is called in a dialog window. The calling WD subscribes to the PI WD event of timed trigger so that it wakes up to send next chunk of data. Using the assistance class of PI WD the calling WD will set the percentage of data completion as well so that the progress bar will keep on increasing.

Let’s see what we need to create in this PI WD component:

clip_image002 UI elements in the view

clip_image004 Layout

image Components

image Context

image Events

Methods of the Component Controller

ACTION_KEEP_ALIVE call from timed trigger
GET_MODEL Return the model class
INIT_PROG_VIEW Initialise progress view
RAISE_WINDOW_CLOSE Raise event for window closed
SET_PERCENTAGE Set percentage complete
SET_PROGRESS_MSG Set progress message
ACTION_KEEP_ALIVE
  1. METHOD action_keep_alive .
  2. set_percentage( ).
  3. wd_this->fire_keep_alive_evt( ).


GET_MODEL
  1. METHOD get_model .
  2. r_o_model = wd_assist.


INIT_PROG_VIEW
  1. method INIT_PROG_VIEW .
  2. wd_assist->set_percent_comp( 0 ).
  3. wd_this->set_percentage( ).
  4. wd_this->set_progress_msg( ).


RAISE_WINDOW_CLOSE
  1. METHOD raise_window_close .
  2. wd_this->fire_window_close_evt(
  3. ).


SET_PERCENTAGE
  1. METHOD set_percentage .
  2. DATA lo_nd_progress TYPE REF TO if_wd_context_node.
  3. DATA lo_el_progress TYPE REF TO if_wd_context_element.
  4. DATA ls_progress TYPE wd_this->element_progress.
  5. DATA lv_percent LIKE ls_progress-percent.
  6. * navigate from <CONTEXT> to <PROGRESS> via lead selection
  7. lo_nd_progress = wd_context->get_child_node( name = wd_this->wdctx_progress ).
  8. * get element via lead selection
  9. lo_el_progress = lo_nd_progress->get_element( ).
  10. lv_percent = wd_assist->get_percent_comp( ).
  11. * get single attribute
  12. lo_el_progress->set_attribute(
  13. EXPORTING
  14. name = `PERCENT`
  15. value = lv_percent ).


SET_PROGRESS_MSG
  1. METHOD set_progress_msg .
  2. DATA lo_nd_progress TYPE REF TO if_wd_context_node.
  3. DATA lo_el_progress TYPE REF TO if_wd_context_element.
  4. DATA ls_progress TYPE wd_this->element_progress.
  5. DATA lv_message LIKE ls_progress-message.
  6. * navigate from <CONTEXT> to <PROGRESS> via lead selection
  7. lo_nd_progress = wd_context->get_child_node( name = wd_this->wdctx_progress ).
  8. * get element via lead selection
  9. lo_el_progress = lo_nd_progress->get_element( ).
  10. lv_message = wd_assist->get_progress_msg( ).
  11. * get single attribute
  12. lo_el_progress->set_attribute(
  13. EXPORTING
  14. name = `MESSAGE`
  15. value = lv_message ).
The assistance class has these methods:

GET_PROGRESS_MSG

Get the progress message
SET_PROGRESS_MSG Set the message in the progress bar
SET_PERCENT_COMP Returns the percentage done
GET_PERCENT_COMP Returns the percentage done


These are just getter and setter methods for the filling the Context variables. The calling WD component can set the percentage and message to be displayed. The PI WD will read these values and set in the context.

Usage

Let’s look at the usage of the progress indicator in a example WD component. Create a new WD where we will use the PI WD component. Add the PI WD component in the properties.

image

In the component controller properties add it as used component comptroller.

image

Subscribe to the events of the PI WD component.

image

This catches events for timed trigger and window close in case user cancels before 100% completion of the process.

CATCH_TIMED_TRIGGER
  1. METHOD catch_timed_trigger .
  2. DATA l_percentage TYPE i.
  3. l_percentage = wd_this->o_zcl_rc_library->get_percent_comp( ).
  4. IF l_percentage >= 100.
  5. wd_this->o_progress_window->close( ).
  6. ENDIF.
  7. l_percentage = l_percentage + 10.
  8. wd_this->o_zcl_rc_library->set_percent_comp( l_percentage ).
  9. ENDMETHOD.
We are here just incrementing the percentage by 10% each time the trigger is activated. But in real situation one would increment to the next dataset that is planned to be processed. The percentage will be according to that.

CATCH_WINDOW_CLOSE
  1. METHOD catch_window_close .
  2. * Check action is over because it is finished or
  3. * killed in between
  4. CHECK wd_this->flag_action_start = abap_true. " Action is killed
  5. " ERROR
  6. * get message manager
  7. DATA lo_api_controller TYPE REF TO if_wd_controller.
  8. DATA lo_message_manager TYPE REF TO if_wd_message_manager.
  9. lo_api_controller ?= wd_this->wd_get_api( ).
  10. lo_message_manager = lo_api_controller->get_message_manager( ).
  11. * report message
  12. lo_message_manager->report_error_message(
  13. message_text = 'Window cancelled before process completion'
  14. ).
  15. * Clear variables
  16. CASE wd_this->action.
  17. WHEN 1. " Validate
  18. WHEN 2. " Action
  19. WHEN OTHERS.
  20. ENDCASE.
  21. ENDMETHOD.
If the progress window is closed before all data has been processed you can alert the user that with that error.

Let’s look at the component controllers methods.


WDDOINIT
  1. METHOD wddoinit .
  2. DATA lo_cmp_usage TYPE REF TO if_wd_component_usage.
  3. lo_cmp_usage = wd_this->wd_cpuse_zwdrc_progress_window( ).
  4. IF lo_cmp_usage->has_active_component( ) IS INITIAL.
  5. lo_cmp_usage->create_component( ).
  6. ENDIF.
  7. DATA lo_interfacecontroller TYPE REF TO ziwci_wdrc_progress_window .
  8. lo_interfacecontroller = wd_this->wd_cpifc_zwdrc_progress_window( ).
  9. wd_this->o_zcl_rc_library = lo_interfacecontroller->get_model( ).
  10. ENDMETHOD.
This will initialise the PI WD component and get the assistance class handler.

We have a simple example which has a button that will launch the progress window.

image

The action attached to the button is:

ONACTIONCALL_PROGRESS
  1. METHOD onactioncall_progress .
  2. wd_comp_controller->open_progress_window( ).
  3. ENDMETHOD.
Here the real application would start the working of whatever transaction was planned. The progress window is further opened as:

OPEN_PROGRESS_WINDOW
  1. METHOD open_progress_window .
  2. DATA lo_componentinterface TYPE REF TO if_wd_component_usage.
  3. lo_componentinterface = wd_this->wd_cpuse_zwdrc_progress_window( ).
  4. DATA lo_interface TYPE REF TO ziwci_wdrc_progress_window.
  5. lo_interface = wd_this->wd_cpifc_zwdrc_progress_window( ).
  6. wd_this->o_zcl_rc_library->set_progress_msg( 'We are doing it ').
  7. wd_this->o_zcl_rc_library->set_percent_comp( 0 ).
  8. DATA lo_cont TYPE REF TO if_wd_controller.
  9. * if_wd_controller = lo_interface->wd_get_api( ).
  10. DATA lo_api_componentcontroller TYPE REF TO if_wd_component.
  11. lo_api_componentcontroller = wd_this->wd_get_api( ).
  12. DATA l_window_manager TYPE REF TO if_wd_window_manager.
  13. l_window_manager = lo_api_componentcontroller->get_window_manager( ).
  14. wd_this->o_progress_window = l_window_manager->create_window_for_cmp_usage(
  15. interface_view_name = 'W_MAIN'
  16. component_usage_name = 'ZWDRC_PROGRESS_WINDOW'
  17. title = 'We are doing it'
  18. * close_in_any_case = ABAP_TRUE
  19. * message_display_mode = message_display_mode
  20. ).
  21. * wd_this->o_progress_window->set_window_title( title = 'Test' ).
  22. wd_this->o_progress_window->open( ).
  23. ENDMETHOD.
Here the window W_MAIN of PI WD component is being called. The title is set and so is the message that will come in the message bar.

Here is the example of the output:

image 10% done

image 20% done

Thursday, August 05, 2010

WebDynpro: Upload and Download file, part III (usage)

Let’s see how to make use of the download and upload components in this section. We will upload a file to show it on the browser and then change contents of the file and download it.

image Upload Screen which leads to…Download Screen

image Download Screen which goes back to…Upload screen

image Used WebDynpro components

image Controller usage

image Component list

image Window layout

image Context for Component controller

In the init of the component controller we will initiate the used components and get reference to the respective assistance class. For the download component we fill the file node with the file name and mime type.

  1. METHOD wddoinit .
  2. DATA lo_cmp_usage TYPE REF TO if_wd_component_usage.
  3. * Download component
  4. lo_cmp_usage = wd_this->wd_cpuse_download_file( ).
  5. IF lo_cmp_usage->has_active_component( ) IS INITIAL.
  6. lo_cmp_usage->create_component( ).
  7. DATA lo_ziwci_wdrc_download_file TYPE REF TO ziwci_wdrc_download_file .
  8. lo_ziwci_wdrc_download_file = wd_this->wd_cpifc_download_file( ).
  9. wd_this->o_model_download = lo_ziwci_wdrc_download_file->get_model(
  10. ).
  11. * Give file name and specify mime type
  12. DATA lo_nd_file TYPE REF TO if_wd_context_node.
  13. DATA lo_el_file TYPE REF TO if_wd_context_element.
  14. DATA ls_file TYPE wd_this->element_file.
  15. * navigate from <CONTEXT> to <FILE> via lead selection
  16. lo_nd_file = wd_context->get_child_node( name = wd_this->wdctx_file ).
  17. * get element via lead selection
  18. lo_el_file = lo_nd_file->get_element( ).
  19. ls_file-filename = 'up_down_text.txt'.
  20. ls_file-mimetype = 'Text'.
  21. * set all declared attributes
  22. lo_el_file->set_static_attributes(
  23. EXPORTING
  24. static_attributes = ls_file ).
  25. * Upload component
  26. lo_cmp_usage = wd_this->wd_cpuse_upload_file( ).
  27. IF lo_cmp_usage->has_active_component( ) IS INITIAL.
  28. lo_cmp_usage->create_component( ).
  29. DATA lo_ziwci_wdrc_upload_file TYPE REF TO ziwci_wdrc_upload_file .
  30. lo_ziwci_wdrc_upload_file = wd_this->wd_cpifc_upload_file( ).
  31. wd_this->o_model_upload = lo_ziwci_wdrc_upload_file->get_model(
  32. ).
image Events handler

Upload event handler reads the data by calling the assistance class method get_mapped_file and binds the node table_data to the returned table.

  1. METHOD catch_upload .
  2. DATA lo_nd_table_data TYPE REF TO if_wd_context_node.
  3. DATA lo_el_table_data TYPE REF TO if_wd_context_element.
  4. DATA ls_table_data TYPE wd_this->element_table_data.
  5. DATA lt_data TYPE TABLE OF wd_this->element_table_data.
  6. wd_this->o_model_upload->get_mapped_file( IMPORTING e_t_mapped_file = lt_data ).
  7. * navigate from <CONTEXT> to <TABLE_DATA> via lead selection
  8. lo_nd_table_data = wd_context->get_child_node( name = wd_this->wdctx_table_data ).
  9. lo_nd_table_data->bind_table( EXPORTING new_items = lt_data ).
Download event handler does a bit more than upload event catcher. It has to convert the data in the node table_data into file structure. It does that by calling the method covert_struc2file in the assistance class. Once the conversion is done then call the interface method download_file of download WD component that will push the file out of the browser.
  1. METHOD catch_download .
  2. DATA lo_nd_table_data TYPE REF TO if_wd_context_node.
  3. DATA lo_el_table_data TYPE REF TO if_wd_context_element.
  4. DATA ls_table_data TYPE wd_this->element_table_data.
  5. DATA lt_data TYPE TABLE OF wd_this->element_table_data.
  6. * navigate from <CONTEXT> to <TABLE_DATA> via lead selection
  7. lo_nd_table_data = wd_context->get_child_node( name = wd_this->wdctx_table_data ).
  8. * @TODO handle not set lead selection
  9. IF lo_nd_table_data IS INITIAL.
  10. * Get table data
  11. lo_nd_table_data->get_static_attributes_table( IMPORTING table = lt_data ).
  12. * Send data to be converted
  13. TRY .
  14. wd_this->o_model_download->convert_struc2file( EXPORTING i_t_data = lt_data
  15. i_seperator = cl_abap_char_utilities=>horizontal_tab
  16. i_flag_header = abap_true ).
  17. CATCH zcx_library.
  18. * get message manager
  19. DATA lo_api_controller TYPE REF TO if_wd_controller.
  20. DATA lo_message_manager TYPE REF TO if_wd_message_manager.
  21. lo_api_controller ?= wd_this->wd_get_api( ).
  22. lo_message_manager = lo_api_controller->get_message_manager( ).
  23. * report message
  24. lo_message_manager->report_error_message(
  25. message_text = 'Error in conversion'
  26. ).
  27. * Start download
  28. DATA lo_interfacecontroller TYPE REF TO ziwci_wdrc_download_file .
  29. lo_interfacecontroller = wd_this->wd_cpifc_download_file( ).
  30. lo_interfacecontroller->download_file(
  31. ).
The views are simple, they just have a view container to display the component WD and a table element to display edit. There is also button to navigate between the views.
image Upload view

image Download view