Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
dishankmalde
Participant
Requirement

We had an interesting requirement to combine multiple orders (belonging to a single ship-to party) into a single delivery note. This can be achieved using standard transaction ‘VL10’ but the custom requirement was to only be able to combine the orders that had a similar payment type. Payment type is a custom field in the Sales Order (in our case VBAK-ZPAYM_TYPE) which can be either Cash, Credit Card, Debit Card or so on.

In this blog post, I’ll show how I used ALV tree for displaying orders belonging to Ship-to in a hierarchical form.

Why ALV tree?

To display the orders which could be combined/ bundled together into a single Delivery Note, ALV tree seemed to be the perfect option for the hierarchy with the Ship-to Party being the Parent node and the orders with the same Ship-to Party to be the children nodes.

While developing this report I referred to SAP Standard reports “SALV_DEMO_TREE* “which are of great help.

Selection Screen


 

All the data that is needed is fetched. We have a type ‘ty_final’ which has Ship-to Party, Ship-to Name, Sales order, time, Material, Qty, Unit, Payment type, Delivery and others. In order to combine multiple orders into a single Delivery note, the Order Combination flag (VBKD-KZAZU) of the Sales Order must be set. Hence, we select only those orders.

This is how the Order Combination screen looks like


 

Creation of tree structure:

Step 1. Create an instance of ALV tree (go_tree). The table needs to be empty at this point (gt_final1 is empty)
DATA: gt_final1 TYPE TABLE OF ty_final,
go_tree TYPE REF TO cl_salv_tree.

* Create ALV tree
TRY.
cl_salv_tree=>factory(
IMPORTING
r_salv_tree = go_tree
CHANGING
t_table = gt_final1 ).
CATCH cx_salv_error.
LEAVE LIST-PROCESSING.
ENDTRY.

Step 2. Set the heading for the report
DATA: lo_settings TYPE REF TO cl_salv_tree_settings. 

lo_settings = go_tree->get_tree_settings( ).

lo_settings->set_hierarchy_header( ‘Ship-to’ ).
lo_settings->set_hierarchy_tooltip( ‘Ship-to’ ).

lo_settings->set_header( ‘Order Combination Report’ ).

Step 3. Register LINK_CLICK event
DATA: lo_events TYPE REF TO cl_salv_events_tree.

lo_events = go_tree->get_event( ).

SET HANDLER go_create->on_link_click FOR lo_events.

Step 4. The building blocks of an ALV tree are called nodes.

The Ship-to Party is a parent node and the Orders are the children nodes.

Supply the data and build the hierarchy
    LOOP AT gt_final ASSIGNING <ls_final>.

* Check if there is a change in Ship-to or Payment type
* in which case a new folder needs to be created
IF <ls_final>-kunwe NE ls_prev-kunwe
OR <ls_final>-zpaym_type NE ls_prev-zpaym_type.

* Get the Ship-to text
CLEAR lv_text.
CONCATENATE ‘Ship to’
<ls_final>-kunwe
<ls_final>-name1
INTO lv_text SEPARATED BY space.
* Here we get the key to the Ship-to node, we will use it for Orders
* belonging to this Ship-to
* Create new folder for Ship-to
lv_kunwe_key = go_create->add_tree_node( iv_text = lv_text ).
ENDIF.

* Keep changing the flag to get alternate background color
* Changing colors as Order no. changes
IF ls_prev-vbeln NE <ls_final>-vbeln.
IF lv_set_style IS INITIAL.
lv_set_style = abap_true.
ELSE.
lv_set_style = abap_false.
ENDIF.
ENDIF.

* Add new item in the folder
* Add the node with the relevant data
* Here we give the key to the Ship-to node, this way the Order
* becomes the child of the Ship-to node
go_create->add_tree_node( iv_nkey = lv_kunwe_key
is_data = <ls_final>
iv_set_type = if_salv_c_item_type=>checkbox
iv_set_style = lv_set_style ).

* Store the current line as "previous" for further processing
ls_prev = <ls_final>.

ENDLOOP.

Below is the code along with comments for method ADD_TREE_NODE.

The idea is to distinguish between orders by changing background colors with changing Sales Orders, to set a text for Ship-to Node, to create a button at Ship-to node Delivery Column, and create checkboxes at Sales Order nodes.
 METHOD add_tree_node.
*---------------------------------------------------------
* Add a node to the ALV tree
*---------------------------------------------------------

DATA: lo_nodes TYPE REF TO cl_salv_nodes,
lo_node TYPE REF TO cl_salv_node,
lo_item TYPE REF TO cl_salv_item,
lo_item_delivery TYPE REF TO cl_salv_item.

lo_nodes = go_tree->get_nodes( ).

* We use the standard method to add the node
TRY.
lo_node = lo_nodes->add_node(
related_node = iv_nkey
relationship = if_salv_c_node_relation=>last_child
data_row = is_data
collapsed_icon = '@5F@' "space
expanded_icon = '@5F@' "space
text = iv_text ).
CATCH cx_salv_msg.
LEAVE LIST-PROCESSING.
ENDTRY.

* We provided text only for Ship-to node.
* The below code will set the text of the node (viz. Ship-to 12345 ABC Org.)
* Set the text for the node
IF iv_text IS NOT INITIAL.
lo_node->set_text( iv_text ).
ENDIF.

* In order to distinguish between Orders, we set different background colors.
* The below code sets blue color as background
IF iv_set_style IS NOT INITIAL.
lo_node->set_row_style( if_salv_c_tree_style=>emphasized_b ).
ENDIF.


lo_item = lo_node->get_hierarchy_item( ).


IF iv_nkey IS INITIAL.
* For the Ship-to node, we take the Delivery column and set it to Button
TRY.
lo_item_delivery = lo_node->get_item( 'DELIVERY' ).
CATCH cx_salv_msg.
EXIT.
ENDTRY.
lo_item_delivery->set_type( if_salv_c_item_type=>button ).
lo_item_delivery->set_value( ‘Delivery Creation’ ).

ELSE.
* For the order nodes, we get the entire row and Set it as editable checkbox
lo_item->set_type( if_salv_c_item_type=>checkbox ).
lo_item->set_editable( abap_true ).

* Set the data of the node
lo_node->set_data_row( is_data ).
lo_nodes->expand_all( ).

ENDIF.

* Return the node key
rv_nkey = lo_node->get_key( ).

ENDMETHOD. "add_tree_node

 

Once the orders are selected, and the corresponding “Delivery Creation” button is clicked, it is a link_click event for which we have the below method.


 

METHODS: on_link_click FOR EVENT link_click
OF cl_salv_events_tree
IMPORTING columnname
node_key.

We have registered an event for this method (step 3 in create tree structure)
METHOD on_link_click.
*---------------------------------------------------------
* Method when the user clicks on Link or button
*---------------------------------------------------------

DATA: lo_nodes TYPE REF TO cl_salv_nodes,
lo_node TYPE REF TO cl_salv_node.

lo_nodes = go_tree->get_nodes( ).

* Get the parent node
TRY.
lo_node = lo_nodes->get_node( node_key ).
CATCH cx_salv_msg.
EXIT.
ENDTRY.

go_create->create_delivery( lo_node ).

ENDMETHOD. "on_link_click

 

Delivery Creation Logic

The BAPI used for the delivery creation was BAPI_OUTB_DELIVERY_CREATE_SLS.

The method CREATE_DELIVERY is explained below.

The idea is to loop at all the nodes, and get the orders that were selected and pass them to the BAPI. Once the delivery is created, we display it in the 'Delivery' column corresponding to the sales orders
  METHOD create_delivery.
*---------------------------------------------------------
* Create the delivery from the selected Orders
*---------------------------------------------------------

DATA: lt_nodes TYPE salv_t_nodes,
lo_item TYPE REF TO cl_salv_item,
lo_data TYPE REF TO data,
lv_delivery TYPE vbeln_vl,
lv_number TYPE vbnum,
lt_sales_orders TYPE STANDARD TABLE OF bapidlvreftosalesorder,
lt_created_items TYPE STANDARD TABLE OF bapidlvitemcreated,
lt_return TYPE STANDARD TABLE OF bapiret2.

FIELD-SYMBOLS: <ls_nodes> TYPE salv_s_nodes,
<ls_data> TYPE ty_final,
<ls_orders> TYPE bapidlvreftosalesorder,
<ls_items> TYPE bapidlvitemcreated.

* Get the entire subtree
TRY.
lt_nodes = io_node->get_subtree( ).
CATCH cx_salv_msg.
EXIT.
ENDTRY.

* Here we will loop at all the nodes, find the ones that were selected
* and pass those orders to BAPI for Delivery creation
LOOP AT lt_nodes ASSIGNING <ls_nodes>.

* Get the item details
lo_item = <ls_nodes>-node->get_hierarchy_item( ).

* Get the node data if it is checked
IF lo_item->is_enabled( ) = abap_true
AND lo_item->is_checked( ) = abap_true.

lo_data = <ls_nodes>-node->get_data_row( ).
ASSIGN lo_data->* TO <ls_data>.
IF sy-subrc EQ 0.

* Get the sales order and item
APPEND INITIAL LINE TO lt_sales_orders ASSIGNING <ls_orders>.
<ls_orders>-ref_doc = <ls_data>-vbeln.
<ls_orders>-ref_item = <ls_data>-posnr.

ENDIF.
ENDIF.

ENDLOOP.

* Call the BAPI for Delivery Creation
CALL FUNCTION 'BAPI_OUTB_DELIVERY_CREATE_SLS'
IMPORTING
delivery = lv_delivery
num_deliveries = lv_number
TABLES
sales_order_items = lt_sales_orders
created_items = lt_created_items
return = lt_return.


SORT lt_created_items BY ref_doc ref_item.

IF lv_delivery IS NOT INITIAL.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ENDIF.

* Next, loop at the nodes and display the delivery
LOOP AT lt_nodes ASSIGNING <ls_nodes>.
lo_item = <ls_nodes>-node->get_hierarchy_item( ).
IF lo_item->is_checked( ) = abap_true.
lo_item->set_checked( abap_false ).
lo_data = <ls_nodes>-node->get_data_row( ).
ASSIGN lo_data->* TO <ls_data>.
IF sy-subrc EQ 0.
* Set the delivery
READ TABLE lt_created_items ASSIGNING <ls_items>
WITH KEY ref_doc = <ls_data>-vbeln
ref_item = <ls_data>-posnr
BINARY SEARCH.
IF sy-subrc EQ 0.
<ls_data>-delivery = <ls_items>-deliv_numb.
<ls_nodes>-node->set_data_row( <ls_data> ).
ENDIF.
ENDIF.

* Disable the checkbox if the delivery is created,
IF <ls_data>-delivery IS NOT INITIAL.
lo_item->set_enabled( abap_false ).
lo_item->set_icon( '@0V\QOK@' ). "OK
ENDIF.
ENDIF.
ENDLOOP.

ENDMETHOD. "create_delivery

 

Final Output


The purpose was to show how one can create a basic report using ALV tree.

I have implemented other functionalities of ALV tree which makes this report quite user friendly. Some of these enhancements are:

  1. Expand/ Collapse all the nodes in a single button click

  2. Select/ unselect all the nodes in a single button click

  3. Navigate to the created Delivery

  4. Display error log in case an order cannot be delivered

  5. Reset button in case of error and resolve error by navigating to order with error


And the best part is all these can be implemented with only a few lines of code, but makes the report look more appealing. If you wish to see the above mentioned points, please check this post.

I hope this blog post helps you and makes you explore more about ALV tree. 😊

Please let me know in the comments if you liked this post and wish to see the enhancements I made.
6 Comments