Spend Management Blogs by SAP
Stay current on SAP Ariba for direct and indirect spend, SAP Fieldglass for workforce management, and SAP Concur for travel and expense with blog posts by SAP.
cancel
Showing results for 
Search instead for 
Did you mean: 
joedutra
Advisor
Advisor
0 Kudos
Following the previous post (BSAO Text formating - part 1), I’ll discuss the challenges and proposed solution to get all line breaks form SAP pong texts to the Ariba Network Comments section.

In this example, I'll show how to map the texts on the cXML Comments tag, but this can easily be used to map the long texts to different cXML tags and extrinsics.

 

Previously we saw that on BADI ARBERP_BADI_OUTB_MAP, method FORMAT_COMMENTS we can only add text to the beginning and end of each Text ID, but we cannot control the text content itself.

We can however, change the Comments content is on the document mapping methods from BADI ARBERP_BADI_OUTB_MAP. Let us take it for instance the Purchase Order mapping method MAP_BUS2012_TO_ORDR_OUT.

 

We could rewrite the standard logic mapping the PO Texts ID to the AN Comments here, but then we would lose the Configuration options of mapping the Text Ids, and what we already implemented on the FORMAT_COMMENTS BADI method.

Instead, I decided to leverage what the standard Add-on code does, and change only the line breaker character. The line breaker is a space character on the default code. I would it to be a line break character instead (cl_abap_char_utilities=>cr_lf).

 

We can use this solution to map the long text of any type of outbound document to the Ariba Network. This solution may also be used if the customer wants the long texts split into extrinsic on the Ariba Network cXML document.

The text mapping from Text ID to the Ariba Comments string takes place on the Class CL_ARBERP_MAP_OUT.



 

Method MOVE_TEXT_TO_COMMENT concatenates the text lines for each Text ID to a string. It also call the FORMAT_COMMENTS BADI method.

Here is the piece of code I would like to replace the <space> for <line break> as the line break separator.

Method, MAP_COMMENTS, receives the PO Text tables (header or item), filter what was setup on the Configuration (SPRO Activity: “Map Texts of SAP ERP and Ariba Network”), and calls MOVE_TEXT_TO_COMMENT.

Here I only want to call the updated method MOVE_TEXT_TO_COMMENT.

 

There is probably other routes to achieve this – such as enhancements – but here is what I suggested:

Create a Z class inheriting form CL_ARBERP_MAP_OUT, as public.



 

Ideally, I would be able to redefine methods MOVE_TEXT_TO_COMMENT and MAP_COMMENTS on my Z class to achieve what we want. However, the developers were nice enough to define these methods as final, so we cannot redefine them. Instead, I had to create the ZMAP_COMMENTS and ZMOVE_TEXT_TO_COMMENT as a copy of the original methods.



 

Here is the snippet of the addition to method ZMOVE_TEXT_TO_COMMENT.
*-- New paragraph means: add one space after the last text
IF ls_text-tdformat = '*' AND NOT
ls_text-tdline IS INITIAL AND NOT
lv_comment_content IS INITIAL.
*>>>>>>>--------------------------------------------------------------------*
* when we get a paragraph, we will concatenate the break line.
lv_add_breakline = abap_true.
* lv_add_space_char_after_text = abap_true.
*--------------------------------------------------------------------<<<<<<<*
ENDIF.
And
*-- Add the text to the comment
IF lv_add_space_char_after_text = abap_true AND NOT
lv_comment_content IS INITIAL.
CONCATENATE lv_comment_content ls_text-tdline INTO lv_comment_content SEPARATED BY space. " with a space between the texts
*>>>>>>>--------------------------------------------------------------------*
* if there is a paragraph, a break line will be inserted
ELSEIF lv_add_breakline = abap_true AND NOT
lv_comment_content IS INITIAL.
CONCATENATE lv_comment_content ls_text-tdline INTO lv_comment_content SEPARATED BY cl_abap_char_utilities=>cr_lf.
*--------------------------------------------------------------------<<<<<<<*
ELSE.
CONCATENATE lv_comment_content ls_text-tdline INTO lv_comment_content. " without a space between the texts
ENDIF.
*>>>>>>>--------------------------------------------------------------------*
* clearing the break line
CLEAR: lv_add_space_char_after_text, lv_add_breakline.
*--------------------------------------------------------------------<<<<<<<*

 

Here is the snippet that was added to method ZMAP_COMMENTS.
        CALL METHOD me->zmove_text_to_comment
EXPORTING
iv_cxml_msg_type = iv_cxml_msg_type
it_text = lt_text_map_call
is_cxml_cmnts_type = ls_comments_type
IMPORTING
es_comment = ls_cxml_comment.

 

There were also two other points that needed to be taken care of. Since this is not a real mapping class for a documents going to Ariba, only need to instantiate it to run the two methods enhanced above. To do this, we should:

  1. Create a blank implementation of method CREATE_CXML_MESSAGE

  2. Create a Constructor with the following code:

    • This code will instantiate the helper classes, making the text mapping methods work as expected (getting the Configuration data and calling the FORMAT_COMMENTS BADI method.




*--------------------------------------------------------------------*
* Get reference to internal helper interface
*--------------------------------------------------------------------*
CALL METHOD cl_arberp_helper_factory_int=>get_instance_helper_int_out
IMPORTING
eo_instance = mo_helper_out_instance.
*---------------------------------------------------------------------*
* Get configuration access
*---------------------------------------------------------------------*
mo_config_instance = cl_arberp_config_factory=>get_instance( ).
mo_fnd_config_instance = cl_arbfnd_config_factory=>get_instance( ).
*--------------------------------------------------------------------*
* Get BAdI instances for outbound processing
*--------------------------------------------------------------------*
CALL METHOD mo_helper_out_instance->badi_get_instances
IMPORTING
er_internal_mapping_badi = mr_internal_mapping_badi
er_customer_mapping_badi = mr_customer_mapping_badi.

 

The final piece of the puzzle is now to call my Z class inside the Outbound Document BADI. Is this example, the PO mapping method. We need to read the PO data, map the Header and Item texts to the corresponding structures, call the Z class ZMAP_COMMENTS method and map the result to the corresponding cXML Comments sections.

The sipper bellow will do just that.
*--------------------------------------------------------------------*
* Adding comments with line breaks in an extrinsic
*--------------------------------------------------------------------*
DATA: lc_ponum TYPE EBELN,
lt_htext TYPE TABLE OF BAPIMEPOTEXTHEADER,
ls_htext TYPE BAPIMEPOTEXTHEADER,
lt_itext TYPE TABLE OF BAPIMEPOTEXT,
ls_itext TYPE BAPIMEPOTEXT,
lt_arbtext TYPE ARBERP_T_TEXT_CMN,
ls_arbtext TYPE ARBERP_S_TEXT_CMN,
lo_text_map TYPE REF TO ZCL_ARBERP_MAP_OUT,
lt_final_text type ARBERP_T_COMMENTS_CMN,
ls_final_text type ARBERP_S_COMMENTS_CMN,
ls_header type BAPIMEPOHEADER.

FIELD-SYMBOLS <fs_item> TYPE ARBERP_XORDR_S_ITEM_OUT.

* get the PO texts
lc_ponum = IV_OBJECT_KEY.
CALL FUNCTION 'BAPI_PO_GETDETAIL1'
EXPORTING
PURCHASEORDER = lc_ponum
ITEM_TEXT = 'X'
HEADER_TEXT = 'X'
IMPORTING
POHEADER = ls_header
TABLES
POTEXTHEADER = lt_htext
POTEXTITEM = lt_itext.
*-- Prepare texts for mapping
CLEAR lt_arbtext.
LOOP AT lt_htext INTO ls_htext.
CLEAR: ls_arbtext.
ls_arbtext-tdobject = 'EKKO'. " EKKO header text object
ls_arbtext-tdid = ls_htext-text_id.
ls_arbtext-tdline = ls_htext-text_line.
ls_arbtext-langu_iso = ls_header-LANGU.
ls_arbtext-tdformat = ls_htext-text_form.
APPEND ls_arbtext TO lt_arbtext.
ENDLOOP.

* Split the Header texts
* this is a copy of Class CL_ARBERP_MAP_OUT, with changes in methods MAP_COMMENTS and MOVE_TEXT_TO_COMMENT
* this will get the text Configuration settings and call the TEXT mapping BADI
TRY.
CREATE OBJECT lo_text_map TYPE ZCL_ARBERP_MAP_OUT.
CALL METHOD lo_text_map->ZMAP_COMMENTS
EXPORTING
IV_CXML_MSG_TYPE = IV_CXML_MSG_TYPE
IV_CXML_ELEMENT_ID = if_arberp_cxml_element_id_c=>gc_header_cmnts
IV_OBJECT_TYPE = IV_OBJECT_TYPE
IV_OBJECT_NODE = if_arberp_object_nodes_c=>gc_header
IT_TEXT = lt_arbtext
IMPORTING
ET_CXML_COMMENTS = lt_final_text.
CATCH CX_ARBFND_APPL .
ENDTRY.

* map the result to the Header Comment
READ TABLE lt_final_text INDEX 1 INTO ls_final_text.
IF sy-subrc IS INITIAL.
CS_ORDR-REQUEST-ORDER_REQUEST-ORDER_REQUEST_HEADER-COMMENTS-CONTENT = ls_final_text-CONTENT.
ENDIF.


* prepare the item texts
CLEAR lt_arbtext.
LOOP AT lt_itext INTO ls_itext.
CLEAR: ls_arbtext.
ls_arbtext-tdobject = 'EKPO'. " EKKO item text object
ls_arbtext-tdid = ls_itext-text_id.
ls_arbtext-tdline = ls_itext-text_line.
ls_arbtext-langu_iso = ls_header-LANGU.
ls_arbtext-tdformat = ls_itext-text_form.
APPEND ls_arbtext TO lt_arbtext.
ENDLOOP.
* Split the item texts
LOOP AT CS_ORDR-REQUEST-ORDER_REQUEST-ITEM_OUT ASSIGNING <fs_item>.
CLEAR: lt_final_text, ls_final_text.
TRY.
CALL METHOD lo_text_map->ZMAP_COMMENTS
EXPORTING
IV_CXML_MSG_TYPE = IV_CXML_MSG_TYPE
IV_CXML_ELEMENT_ID = if_arberp_cxml_element_id_c=>GC_ITEM_OUT_CMNTS
IV_OBJECT_TYPE = IV_OBJECT_TYPE
IV_OBJECT_NODE = if_arberp_object_nodes_c=>GC_ITEM
IT_TEXT = lt_arbtext
IMPORTING
ET_CXML_COMMENTS = lt_final_text.
* map the result to the Item Comment
READ TABLE lt_final_text INDEX 1 INTO ls_final_text.
IF sy-subrc IS INITIAL.
<fs_item>-COMMENTS-CONTENT = ls_final_text-CONTENT.
ENDIF.
CATCH CX_ARBFND_APPL .
ENDTRY.
ENDLOOP.
*--------------------------------------------------------------------*

 

The result of this customization on the Ariba Network will look like something like this.



Note that all paragraphs inserted on SAP long texts are maintained, and AN UI will automatically format the extra line breaks (not paragraphs) depending on the screen size.

 
1 Comment