Custom Root Entity Use case along with custom messages in RAP

A Custom Entity has no real table linked to it, RAP cannot read it automatically. Instead, it creates an empty structure and hands over the control to you. You then write your own ABAP code inside a Query Provider class

Custom Root Entity Example

@EndUserText.label: ‘Custom Root Entity’

 

@ObjectModel: {

query: {

implementedBy: ‘ABAP:ZCL_SALES_STATUS’

}

}

 

@ui: {

headerInfo: {

typeName: ‘Flight’,

typeNamePlural: ‘Flights’,

title: { value: ‘Salesorder’ },

description: { value: ‘Salesorder’ }

}

}

 

define root custom entity ZCR_CUSTSO_VIEW

 

{

 

@ui.lineItem: [{ position: 10 , type: #FOR_ACTION, dataAction: ‘EditStatus’ , label: ‘Edit Status’}]

@Consumption.filter.mandatory: true

@search.defaultSearchElement: true

@ui.identification:[{ position: 10 , label: ‘Sales Order’}]

key Salesorder : vbeln_va;

@Consumption.filter.mandatory: true

@search.defaultSearchElement: true

@ui.lineItem: [{ position: 20 , label: ‘Sales Order Item’ }]

@ui.identification: [{ position: 20 , label: ‘Sales Order Item’ }]

key Itemno : posnr_va;

@Consumption.valueHelpDefinition: [{

entity: {

name: ‘ZStatus_VH’, // Your Value Help View

element: ‘Value’ // Source field for Status

},

additionalBinding: [{

localElement: ‘Statusdesc’, // Target field in your app

element: ‘Description’, // Source field from Value Help View

usage: #RESULT // Passes data on selection

}]

}]

@ui.lineItem: [{ position: 30 , label: ‘Sales Order Status’ }]

@ui.identification: [{ position: 30 , label: ‘Sales Order Status’ }]

Status : abap.char( 1 );

@ui.lineItem: [{ position: 40 , label: ‘Time Stamp’ }]

@ui.identification: [{ position: 40 , label: ‘Time Stamp’ }]

Timestamp : timestampl;

@ui.identification: [{ position: 50 , label: ‘Status Description’ }]

@ui.lineItem: [{ position: 50 , label: ‘Status Description’ }]

Statusdesc : abap.char(20);

}

 

As you have created a custom root entity you are not forced to fetch data from source ,

you can validate it , you can write a code along with fetching data because you are writing a query

you can loop over it modify it , whatever you wanted to do you can go for it.

CLASS zcl_sales_status DEFINITION

PUBLIC

FINAL

CREATE PUBLIC .

 

PUBLIC SECTION.

 

INTERFACES if_rap_query_provider .

PROTECTED SECTION.

PRIVATE SECTION.

ENDCLASS.

 

 

 

CLASS zcl_sales_status IMPLEMENTATION.

 

 

METHOD if_rap_query_provider~select.

DATA(lv_top) = io_request->get_paging( )->get_page_size( ).

IF lv_top < 0.

lv_top = 1.

ENDIF.

 

DATA(lv_skip) = io_request->get_paging( )->get_offset( ).

 

DATA(lt_sort) = io_request->get_sort_elements( ).

 

DATA : lv_orderby TYPE string.

LOOP AT lt_sort INTO DATA(ls_sort).

IF ls_sortdescending = abap_true.

lv_orderby = |{ lv_orderby } { ls_sortelement_name } DESCENDING ‘|.

ELSE.

lv_orderby = |{ lv_orderby } { ls_sortelement_name } ASCENDING ‘|.

ENDIF.

ENDLOOP.

IF lv_orderby IS INITIAL.

lv_orderby = ‘Salesorder’.

ENDIF.

 

DATA(lv_conditions) = io_request->get_filter( )->get_as_sql_string( ).

 

SELECT FROM zebst_status_log

FIELDS salesorder , itemno , status , statusdesc ,timestamp

WHERE (lv_conditions)

ORDER BY (lv_orderby)

INTO TABLE @DATA(lt_status)

UP TO @lv_top ROWS OFFSET @lv_skip.

IF lt_status IS INITIAL.

 

IF lv_conditions IS NOT INITIAL.

RAISE EXCEPTION TYPE zcx_rap_exception_provider

EXPORTING

textid = VALUE scx_t100key(

“msgid = sy-msgid

“msgno = sy-msgno

“attr1 = sy-msgv1

“HOW TO ADD CUSTOM MESSAGE I HAVE CREATED ON SE91 ZMSG_STATUS 000 NUMBER

msgid = ‘ZMSG_STATUS’

msgno = ‘000’

)

previous = NEW cx_sadl_contract_violation( ).

 

ELSEIF lv_conditions IS INITIAL.

RAISE EXCEPTION TYPE zcx_rap_exception_provider

EXPORTING

textid = VALUE scx_t100key(

“msgid = sy-msgid

“msgno = sy-msgno

“attr1 = sy-msgv1

“HOW TO ADD CUSTOM MESSAGE I HAVE CREATED ON SE91 ZMSG_STATUS 000 NUMBER

msgid = ‘ZMSG_STATUS’

msgno = ‘001’

)

previous = NEW cx_sadl_contract_violation( ).

ENDIF.

 

ELSE.

IF io_request->is_total_numb_of_rec_requested( ).

io_response->set_total_number_of_records( lines( lt_status ) ).

io_response->set_data( lt_status ).

ENDIF.

ENDIF.

ENDMETHOD.

ENDCLASS.

“”You can add custom message while clicking on go button MANAGED and UNMANGED scenarios can’t provide such

kind of messages.

 

For Messages you need to create a custom exception class over standard RAP Exception class

CLASS zcx_rap_exception_provider DEFINITION

PUBLIC

INHERITING FROM cx_rap_query_provider

FINAL

CREATE PUBLIC .

 

PUBLIC SECTION.

 

METHODS constructor

IMPORTING

!textid LIKE if_t100_message=>t100key OPTIONAL

!previous LIKE previous OPTIONAL .

PROTECTED SECTION.

PRIVATE SECTION.

ENDCLASS.

 

 

 

CLASS zcx_rap_exception_provider IMPLEMENTATION.

 

 

METHOD constructor ##ADT_SUPPRESS_GENERATION.

CALL METHOD super->constructor

EXPORTING

previous = previous.

CLEAR me->textid.

IF textid IS INITIAL.

if_t100_message~t100key = if_t100_message=>default_textid.

ELSE.

if_t100_message~t100key = textid.

ENDIF.

ENDMETHOD.

ENDCLASS.

 

​ A Custom Entity has no real table linked to it, RAP cannot read it automatically. Instead, it creates an empty structure and hands over the control to you. You then write your own ABAP code inside a Query Provider classCustom Root Entity Example@EndUserText.label: ‘Custom Root Entity’ @ObjectModel: {query: {implementedBy: ‘ABAP:ZCL_SALES_STATUS’}} @ui: {headerInfo: {typeName: ‘Flight’,typeNamePlural: ‘Flights’,title: { value: ‘Salesorder’ },description: { value: ‘Salesorder’ }}} define root custom entity ZCR_CUSTSO_VIEW { @ui.lineItem: [{ position: 10 , type: #FOR_ACTION, dataAction: ‘EditStatus’ , label: ‘Edit Status’}]@Consumption.filter.mandatory: true@search.defaultSearchElement: true@ui.identification:[{ position: 10 , label: ‘Sales Order’}]key Salesorder : vbeln_va;@Consumption.filter.mandatory: true@search.defaultSearchElement: true@ui.lineItem: [{ position: 20 , label: ‘Sales Order Item’ }]@ui.identification: [{ position: 20 , label: ‘Sales Order Item’ }]key Itemno : posnr_va;@Consumption.valueHelpDefinition: [{entity: {name: ‘ZStatus_VH’, // Your Value Help Viewelement: ‘Value’ // Source field for Status},additionalBinding: [{localElement: ‘Statusdesc’, // Target field in your appelement: ‘Description’, // Source field from Value Help Viewusage: #RESULT // Passes data on selection}]}]@ui.lineItem: [{ position: 30 , label: ‘Sales Order Status’ }]@ui.identification: [{ position: 30 , label: ‘Sales Order Status’ }]Status : abap.char( 1 );@ui.lineItem: [{ position: 40 , label: ‘Time Stamp’ }]@ui.identification: [{ position: 40 , label: ‘Time Stamp’ }]Timestamp : timestampl;@ui.identification: [{ position: 50 , label: ‘Status Description’ }]@ui.lineItem: [{ position: 50 , label: ‘Status Description’ }]Statusdesc : abap.char(20);} As you have created a custom root entity you are not forced to fetch data from source ,you can validate it , you can write a code along with fetching data because you are writing a queryyou can loop over it modify it , whatever you wanted to do you can go for it.CLASS zcl_sales_status DEFINITIONPUBLICFINALCREATE PUBLIC . PUBLIC SECTION. INTERFACES if_rap_query_provider .PROTECTED SECTION.PRIVATE SECTION.ENDCLASS.   CLASS zcl_sales_status IMPLEMENTATION.  METHOD if_rap_query_provider~select.DATA(lv_top) = io_request->get_paging( )->get_page_size( ).IF lv_top < 0.lv_top = 1.ENDIF. DATA(lv_skip) = io_request->get_paging( )->get_offset( ). DATA(lt_sort) = io_request->get_sort_elements( ). DATA : lv_orderby TYPE string.LOOP AT lt_sort INTO DATA(ls_sort).IF ls_sort-descending = abap_true.lv_orderby = |'{ lv_orderby } { ls_sort-element_name } DESCENDING ‘|.ELSE.lv_orderby = |'{ lv_orderby } { ls_sort-element_name } ASCENDING ‘|.ENDIF.ENDLOOP.IF lv_orderby IS INITIAL.lv_orderby = ‘Salesorder’.ENDIF. DATA(lv_conditions) = io_request->get_filter( )->get_as_sql_string( ). SELECT FROM zebst_status_logFIELDS salesorder , itemno , status , statusdesc ,timestampWHERE (lv_conditions)ORDER BY (lv_orderby)INTO TABLE @DATA(lt_status)UP TO @lv_top ROWS OFFSET @lv_skip.IF lt_status IS INITIAL. IF lv_conditions IS NOT INITIAL.RAISE EXCEPTION TYPE zcx_rap_exception_providerEXPORTINGtextid = VALUE scx_t100key(“msgid = sy-msgid”msgno = sy-msgno”attr1 = sy-msgv1″HOW TO ADD CUSTOM MESSAGE I HAVE CREATED ON SE91 ZMSG_STATUS 000 NUMBERmsgid = ‘ZMSG_STATUS’msgno = ‘000’)previous = NEW cx_sadl_contract_violation( ). ELSEIF lv_conditions IS INITIAL.RAISE EXCEPTION TYPE zcx_rap_exception_providerEXPORTINGtextid = VALUE scx_t100key(“msgid = sy-msgid”msgno = sy-msgno”attr1 = sy-msgv1″HOW TO ADD CUSTOM MESSAGE I HAVE CREATED ON SE91 ZMSG_STATUS 000 NUMBERmsgid = ‘ZMSG_STATUS’msgno = ‘001’)previous = NEW cx_sadl_contract_violation( ).ENDIF. ELSE.IF io_request->is_total_numb_of_rec_requested( ).io_response->set_total_number_of_records( lines( lt_status ) ).io_response->set_data( lt_status ).ENDIF.ENDIF.ENDMETHOD.ENDCLASS.””You can add custom message while clicking on go button MANAGED and UNMANGED scenarios can’t provide suchkind of messages. For Messages you need to create a custom exception class over standard RAP Exception classCLASS zcx_rap_exception_provider DEFINITIONPUBLICINHERITING FROM cx_rap_query_providerFINALCREATE PUBLIC . PUBLIC SECTION. METHODS constructorIMPORTING!textid LIKE if_t100_message=>t100key OPTIONAL!previous LIKE previous OPTIONAL .PROTECTED SECTION.PRIVATE SECTION.ENDCLASS.   CLASS zcx_rap_exception_provider IMPLEMENTATION.  METHOD constructor ##ADT_SUPPRESS_GENERATION.CALL METHOD super->constructorEXPORTINGprevious = previous.CLEAR me->textid.IF textid IS INITIAL.if_t100_message~t100key = if_t100_message=>default_textid.ELSE.if_t100_message~t100key = textid.ENDIF.ENDMETHOD.ENDCLASS.   Read More Technology Blog Posts by SAP articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author