Monday, 29 July 2019

SAP HANA XSJS SourceCode Automation


SAP HANA XSJS SourceCode Automation

Hello folks, Recently I have been working extensively on the SAP Cloud Platform using the Classic Neo environment for developing. What I have seen is we have xsodata that supports most of the CRUD operations using the user exits and modification exits, but still there are scenarios where we cannot rely on the xsodata. This is where the xsjs comes into picture.

With xsjs we can create our custom insert, update or perhaps Deep Insert logic to name a few. And when it comes to larger tables, we have to write the custom insert or update logic accordingly, test the application for any errors in the code. Most of times its the datatype missmatch. Integer field is been specified as string and so on. This is very tedious and time consuming work, especially when you have too many tables to work on in a project.

But then I thought why not automate the code!!! Simply mention the table name and table structure and get the entire functionality built for the custom insert, update or even deep insert or automate the entire source code for header item relation in xsjs. This could save a lot of coding efforts and help you focus on business functionality more. So I built a website out of it to do just that. You can visit the website at:
www.xscodegen.codes

SAP HANA XS Code Generator provides list of tools for auto code generation for xsjs. Its completely free to use,  you have auto code generators for xsjs (Server side javascript) that can generate source code based on your table structure. You have the option to choose CDS or hdbtable. Mention your table structure and the SAP HANA XS code generator creates entire source code for you.
I have also included INSERT SQL script generator.
Link:  www.xscodegen.codes/#!/upload

Upload your CSV file and provide your table structure and you have the insert scripts created for all the records. This is specially handy if you want to replicate data from one system to another.

Just give it a try and let me know if you face any problems. Also if you have any ideas that you want me to add do let me know. And the website doesn't store any of your information, the cookies used mostly are for Facebook like buttons and processing the inputs or so...

Thanks,
Mayur


Thursday, 4 December 2014

BOPF - Creating Delegate Node

I have demonstrated how to create a delegate node (Text Collection in our case) and have added records in the Text Collection, created a test report program to demonstrate usage of helper class and retrieve by associations to retrieve the text contents, going further we are consuming the Dependent BO in FPM. 
I Here we are embedding the Dependent Object /BOBF/TEXT_COLLECTION in our BO.
Right click Root node → Select Delegate node.
Provide node name, node prefix, under “Cross BO Relationship” select “Ref. Business Object” as /BOBF/TEXT_COLLECTION.
We can choose from the available Dependent Objects:
Node Prefix: The node prefix is used by BOPF at runtime in order to identify the Dependent Object which is called by the consumer.
When you create the Delegated Node as described above BOPF automatically creates the required association to the root node of the Dependent Object.
This is possible since the Text Collection Dependent Object supports a standard linkage to a hosting Business Object. The standard linkage is supported for each Dependent Object that fulfils the following requirement:
The embedded Dependent Object must have an alternative key on its root node that uses /BOBF/S_LIB_K_DELEGATION as DATA_TYPE and /BOBF/T_LIB_K_DELEGATION as DATA_TABLE_TYPE. The Alternative Key must be set to "Not-unique" to enable one-to-many usages of it.
We can see that in the Dependent BO for Text Collection.
Activate and regenerate the BOPF constant interface.


Adding Delegate Node instance using T-code BOBT:
Select the BO ZMAY1_TRQ and provide query select all. Select the Root node and click edit button.
Navigate to ROOT_LONG_TEXT.
Click Create node instance, we may get the error.
Provide with the Test Schema ID as “DEFAULT” and “TEXT_EXISTS_IND” = “X” and click check. Save.
Now Opening the ROOT_LONG_TEXT we see:
Under “TEXT” create node instance and provide “TEXT_TYPE” and “”LANGUAGE_CODE”. I have added as:
Now Select the TEXT_CONTENT and create instance. Provide the Text “Demo Text”. Save. The records are now saved.


Testing the BO to get the Text available in TEXT_CONTENT:
The structure and table types used in our program are from ROOT and ITEM nodes:
Add the below code:
*&---------------------------------------------------------------------*
*& Report  ZTEST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT ztest2.
*Association to a Delegated node.
DATA: lt_mod TYPE /bobf/t_frw_modification,
      ls_mod TYPE /bobf/s_frw_modification,
      lo_message TYPE REF TO /bobf/if_frw_message,
      lo_chg TYPE REF TO /bobf/if_tra_change,
      lr_srv_mgr TYPE REF TO /bobf/if_tra_service_manager,
      lt_key TYPE /bobf/t_frw_key,
      lt_target_key TYPE /bobf/t_frw_key.

DATA: lv_text_node_key TYPE /bobf/conf_key,
      lv_content_node_key TYPE /bobf/conf_key,
      lv_text_assoc_key  TYPE /bobf/obm_assoc_key,
      lt_txc_text_key TYPE /bobf/t_frw_key,
      lv_content_assoc_key TYPE /bobf/obm_assoc_key,
      lt_txc_content TYPE /bobf/t_txc_con_k.

DATA: lt_root_data TYPE zmay1_t_root,
      ls_root_data TYPE zmay1_s_root,
      lt_item_data TYPE zmay1_t_item,
      ls_item_data TYPE zmay1_s_item.

*Get dependent object keys for retrieve by association calling helper method
*Helper method /scmtms/cl_common_helper=>get_do_keys_4_rba
*/bobf/if_txc_c = Interface of Dependent BO= /BOBF/TEXT_COLLECTION
*zif_may1_trq_c = Interface of our BO= ZMAY1_TRQ
*Flow:
*ZMAY1_TRQ ->ROOT -> ROOT_LONG_TEXT -> TEXT -> TEXT_CONTENT
*/BOBF/TEXT_COLLECTION -> ROOT -> TEXT -> TEXT_CONTENT

*Helper method to fetch node and keys
/scmtms/cl_common_helper=>get_do_keys_4_rba(
  EXPORTING
    iv_host_bo_key      =   zif_may1_trq_c=>sc_bo_key
    iv_host_do_node_key =   zif_may1_trq_c=>sc_node-root_long_text
    iv_do_node_key      =   /bobf/if_txc_c=>sc_node-text
    iv_do_assoc_key     =   /bobf/if_txc_c=>sc_association-root-text
  IMPORTING
    ev_node_key         =  lv_text_node_key
    ev_assoc_key        =  lv_text_assoc_key
).

/scmtms/cl_common_helper=>get_do_keys_4_rba(
  EXPORTING
    iv_host_bo_key      =   zif_may1_trq_c=>sc_bo_key
    iv_host_do_node_key =   zif_may1_trq_c=>sc_node-root_long_text
    iv_do_node_key      =  /bobf/if_txc_c=>sc_node-text_content
    iv_do_assoc_key     =  /bobf/if_txc_c=>sc_association-text-text_content
  IMPORTING
    ev_node_key         =    lv_content_node_key
    ev_assoc_key        =    lv_content_assoc_key ).


IF ( lr_srv_mgr IS NOT BOUND ).
  lr_srv_mgr = /bobf/cl_tra_serv_mgr_factory=>get_service_manager(
  zif_may1_trq_c=>sc_bo_key ).
ENDIF.

lr_srv_mgr->query(
  EXPORTING
    iv_query_key            = zif_may1_trq_c=>sc_query-root-select_all
    iv_fill_data            = abap_true      
IMPORTING
    et_data                 = lt_root_data     
   et_key                  = lt_key 
).

*RETRIEVE_BY_ASSOCIATION - 1.  ROOT to ROOT_LONG_TEXT
lr_srv_mgr->retrieve_by_association(
  EXPORTING
    iv_node_key             =    zif_may1_trq_c=>sc_node-root
    it_key                  =    lt_key " Key Table
    iv_association          =    zif_may1_trq_c=>sc_association-root- root_long_text
  IMPORTING
    et_target_key           =     lt_target_key  "Retrieved key of root_long_text
).

*RETRIEVE_BY_ASSOCIATION - 2.  ROOT_LONG_TEXT to TEXT
lr_srv_mgr->retrieve_by_association(
  EXPORTING
    iv_node_key             =    zif_may1_trq_c=>sc_node-root_long_text
    it_key                  =    lt_target_key " ROOT_LONG_TEXT key
    iv_association          =    lv_text_assoc_key
  IMPORTING
    et_target_key           =    lt_txc_text_key ).

*RETRIEVE_BY_ASSOCIATION - 3.  TEXT to TEXT_CONTENT
lr_srv_mgr->retrieve_by_association(
  EXPORTING
    iv_node_key             =    lv_text_node_key
    it_key                  =    lt_txc_text_key
    iv_association          =    lv_content_assoc_key
    iv_fill_data             =     abap_true
  IMPORTING
    et_data                  =  lt_txc_content ).

BREAK-POINT.

The Output in Debugger shows “Demo Text”:


Consuming the Delegated BO in FPM:
Pre-requisite: Please follow the link to get started with FPM BOPF Integration.
Enter T-code: FPM_WB to open the FPM Workbench.
Create a Tabbed UIBB component.

Search for the Text Collection Config ID and add /BOFU/TEXT_COLLECTION_TAB.
Select the Wire Schema Tab and add a new wire with the below details. 
Save and Test the application.

Testing the Delegate Node:
Enter the TRQ ID and click continue.
On the Next screen we see the Text Collection delegate node with the text content.
Thank you.. :)