Skip to Content
Technical Articles

Custom FIORI App – ODATA for Create PR using external catalog Ariba (Punch Out Catalog)

This blog focuses only on the technical details of using the external procurement catalog ARIBA in FIORI (ECC) and not on Create PR. For procurement, the user launches the external catalog (punch out), selects the items and return from the catalog using OCI (Open Catalog Interface). There are many blogs explaining the OCI concepts so we will not go deep in this. In simple words, the OCI interface is a simple protocol that launches a supplier catalog using a simple HTTP get or post command, also the return from the catalog is a simple post back.

This blog highlights the technical approach used to

  • Call the external catalog (ARIBA) from FIORI – Simple HTTP POST
  • Return the catalog items back to FIORI – Capturing the response form data from HTTP Post
  1. Calling the external catalog (ARIBA) from FIORI

Let’s understand the process flow first. The HTTP POST call structure is maintained in SPRO. For Purchase Requisition, the path is SPRO->Materials Management->Purchasing->Environment Data->Web Services: ID and Description.  These parameters are read with their respective values maintained in SPRO (fixed or runtime) and a simple HTML form POST is done. This calls the ARIBA catalog.

Here the most important part is the HOOK_URL, this will contain the path where the catalog must return with the response items.

Technically, in ECC WSI_CALL is the FM that is used to call the external catalog by specifying the web service id and the HOOK_URL. WSI_CALL internally calls WSI_CUSTOMIZING_READ to read the SPRO call structure.

The approach used here in Odata service is to reuse the same FM WSI_CUSTOMIZING_READ and the parameters (as in the above screen shot with values) are returned to UI that builds a HTML POST same as it is done in ECC.  This HTML form POST launches external catalog ARIBA. The HTML form built in UI with the inputs from ODATA looks like this:

<form action="ARIBA URL" name="jump"method="POST">
<input type="hidden" name="EmailAddress" value="runtime">
<input type="hidden" name="~returntarget" value="as maintained in SPRO">
<input type="hidden" name="PunchinPassword" value=" as maintained in SPRO ">
<input type="hidden" name="PunchinId" value=" as maintained in SPRO ">
<input type="hidden" name="SupplierDomain" value=" as maintained in SPRO ">
<input type="hidden" name="User.Address.UniqueN" value="as maintained in SPRO ">
<input type="hidden" name="realm" value=" as maintained in SPRO ">
<input type="hidden" name="FullName" value=" runtime ">
<input type="hidden" name="UniqueName" value=" runtime ">
<input type="hidden" name="~caller" value=" as maintained in SPRO ">
<input type="hidden" name="~target" value="as maintained in SPRO ">
<input type="hidden" name="~OkCode" value=" as maintained in SPRO ">
<input type="hidden" name="ModifyURL" value=" as maintained in SPRO ">
<input type="hidden" name="BYPASS_INB_HANDLER" value=" as maintained in SPRO ">
<input type="hidden" name="BYPASS_OUTB_HANDLER" value=" as maintained in SPRO ">
<input type="hidden" name="HOOK_URL" value="URL where the catalog must return">
<input type="hidden" name="OCI_VERSION" value=" as maintained in SPRO ">
<input type="hidden" name="OPI_VERSION" value=" as maintained in SPRO ">
<input type="hidden" name="returntarget" value=" as maintained in SPRO ">
</form>

 

2. Return the catalog items back to FIORI – Capturing the response HTTP POST

After the catalog is launched and the shopping cart is created, after checkout the cart items are returned back using OCI. UI5 does not have the capability to read this. So the approach used is to redirect the catalog to a BSP application (HOOK_URL) that reads the request form fields and return this to FIORI.

In simple HTTP post the BSP application URL is specified. This BSP application is developed on Gateway server.

<input type=”hidden” name=”HOOK_URL” value=”BSP Application URL”>

The approach used is to read the HTTP form data in BSP on Gateway and use the same standard FM’s to map that data by using a custom RFC FM developed on ECC.  FM is developed in ECC as all the standard OCI FMs are available on ECC and not on gateway.

Step 1: Read the Response FORM data

In OnInitialization Event of BSP , the form data is read using the below code.

CALL METHOD request->get_form_fields
  CHANGING
    fields = gt_myattr.
LOOP AT gt_myattr INTO DATA(lwa_attr).
  CONCATENATE lv_string lwa_attr-name lc_equal lwa_attr-value lc_ampersand INTO lv_string.
ENDLOOP.

This internal table gt_myattr contains all the shopping cart items in name value pair. This table is then converted into a string of above format as expected in standard FM.

Step 2: RFC for mapping the ARIBA response to required format and return in JSON object format to Gateway

CALL FUNCTION ’TEST’ DESTINATION lv_rfcdest
  EXPORTING
    iv_string = lv_string
  IMPORTING
    ex_json   = gv_json_c.

The FM follows the standard code approach :

Data : lt_str             TYPE TABLE OF swastrtab.
DATA :cnht_post_data_line(256) TYPE c.
DATA : cnht_post_data_tab TYPE TABLE OF cnht_post_data_line.

*Split string in required internal table format  
CALL FUNCTION 'SWA_STRING_SPLIT'       EXPORTING
      input_string                 = iv_string
      max_component_length         = 255
    TABLES
      string_components            = lt_str
    EXCEPTIONS
      max_component_length_invalid = 1
      OTHERS                       = 2.

  LOOP AT lt_str INTO DATA(ls_str).
    cnht_post_data_line = ls_str-str.
    APPEND cnht_post_data_line TO cnht_post_data_tab.
  ENDLOOP.
*Pass this to the FM for mapping
  DATA : ltr_fields TYPE TABLE OF savwctxt.
  CALL FUNCTION 'WSI_MAP_REQUEST'
    EXPORTING
      it_request    = cnht_post_data_tab
    TABLES
      et_its_fields = ltr_fields.
  LOOP AT ltr_fields ASSIGNING FIELD-SYMBOL(<lwa_fields>).
    TRANSLATE <lwa_fields>-fieldname TO UPPER CASE.
  ENDLOOP.
  LOOP AT ltr_fields INTO DATA(ls_fields).
    CHECK ls_fields-fieldname(17) EQ 'NEW_ITEM-LONGTEXT'
       OR ls_fields-fieldname     EQ 'NEW_ITEM-DESCRIPTION'
       OR ls_fields-fieldname     EQ 'NEW_ITEM-VENDORMAT'
       OR ls_fields-fieldname     EQ 'NEW_ITEM-MANUFACTMAT'.

    REPLACE ALL OCCURRENCES OF:
     lc_html_amp IN ls_fields-fieldcont WITH lc_amper IN CHARACTER MODE,
     lc_html_equ IN ls_fields-fieldcont WITH lc_equal IN CHARACTER MODE.
  ENDLOOP.
* This FM maps the data as per the DDIC structure 
  CALL FUNCTION 'WSI_IMPORT_DATA'
    EXPORTING
      iv_structure_name    = 'MMPUR_OCI_CAT_RETURN_TYPE'
    TABLES
      it_form_fields       = ltr_fields
      et_ws_item_data      = lt_items
      et_longtext          = lt_text
    EXCEPTIONS
      no_webservice_active = 0
      no_ddic_info         = 0
      import_error         = 0
      OTHERS               = 0.

Map these lt_items & lt_text to your required output table structure that needs to be sent to UI for display. For ex :
  LOOP AT lt_items INTO DATA(lwa_items).
    CLEAR : lwa_pritems.
    lwa_pritems-preq_item = lwa_items-line.
    lwa_pritems-currency = lwa_items-currency.
    lwa_pritems-quantity = lwa_items-quantity.
    lwa_pritems-unit = lwa_items-unit.
    lwa_pritems-preq_price = lwa_items-price.
    lwa_pritems-short_text = lwa_items-description.
    LOOP AT lt_text INTO DATA(lwa_text) WHERE line = lwa_items-line.
      CONCATENATE lwa_pritems-itemtext lwa_text-text_line INTO lwa_pritems-       itemtext SEPARATED BY space.
    ENDLOOP.
    APPEND lwa_pritems TO lt_pritems.
    CLEAR lwa_items.
  ENDLOOP.
*Convert the internal table to JSON Object
  DATA(lo_json_writer) = cl_sxml_string_writer=>create(
                            type = if_sxml=>co_xt_json ).
  CALL TRANSFORMATION id SOURCE = lt_pritems RESULT XML lo_json_writer.

  ex_json = cl_abap_codepage=>convert_from( lo_json_writer->get_output( ) ).

 

Step 3: Passing the JSON Object to UI5 application so that it can be used to bind data in the required UI elements ( form or table )

The variable gv_json_c contains the JSON data. After getting JSON data from RFC , next step is to pass this to UI5 application. When this BSP renders the abap variables are not recognized and error is thrown in the console . So a work around is used here instead of directly passing the abap variable in Javascript,  a textedit is used and variable gv_json_c is bind to that BSP element.  The javascript displayPopup is called on BSP page onLoad event(highlighted).

As soon as BSP page is loaded the displayPopup javascript function is called . The value of the textedit is read in a variable and is passed to UI5 app using the window.opener.CallParent(value). In UI5 this JSON object value is read and displayed either in table or other UI control.

BSP Layout:
<%@page language="abap" %>
<%@extension name="htmlb" prefix="htmlb" %>
<SCRIPT language="JavaScript">
function displayPopup()
{
 var id = document.getElementById('tv2');
 var value = id.value;
 window.opener.CallParent(value);
}
</SCRIPT>

<htmlb:content design="design2003" >
  <htmlb:page title  = "Welcome"
              onLoad = "displayPopup()" >
    <htmlb:form>
      <htmlb:gridLayout columnSize = "1"
                        rowSize    = "2" >
        <htmlb:gridLayoutCell columnIndex = "1"
                              rowIndex    = "1" >
          <htmlb:textView id     = "tv1"
                          design = "HEADER1"
                          text   = "Do not close this window. Your shopping cart is being transferred to your procurement application..." />
        </htmlb:gridLayoutCell>
        <htmlb:gridLayoutCell columnIndex = "1"
                              rowIndex    = "2" >
          <htmlb:textEdit id       = "tv2"
                          text     = "<%= gv_json_c %>"
                          disabled = "FALSE" />
        </htmlb:gridLayoutCell>
      </htmlb:gridLayout>
    </htmlb:form>
  </htmlb:page>
</htmlb:content>

 

This completes the cycle of calling the external catalog from FIORI, creating shopping cart and returning the items back to FIORI app from the Odata side.

For the UI code, please refer Rabin’s blog:

https://blogs.sap.com/2019/01/02/integrate-ariba-catalog-with-custom-ui5-application/

 

 

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.