Please note:
By leveraging CDS views you will be able to reuse the data modelling part to a large extent in the new ABAP programming model once this supports OData V4 even if you are currently using AS ABAP 750. In addition your service will support most query options out of the box by using the code samples shown in this blog.
# | name | role | Details: |
1 | ZE2E001_C_SalesOrder | CDS consumption view - sales order | reads data from SEPM_I_SALESORDER_E |
2 | ZE2E001_C_SalesOrderItem | CDS consumption view - sales order item | reads data from SEPM_I_SALESORDERITEM_E |
3 | zif_e2e001_odata_v4_so_types | Interface | is used by the data provider class as well as the model provider class |
4 | zcm_e2e001odatav4_so | Message class | contains 2 messages |
5 | zcx_e2e001_odata_v4_so | Exception class | inherits from: /iwbep/cx_gateway |
6 | zcl_e2e001_odata_v4_so_model | Model provider class | inherits from: /iwbep/cl_v4_abs_model_prov |
7 | zcl_e2e001_odata_v4_so_data | Data provider class | inherits from: /iwbep/cl_v4_abs_data_provider |
@AbapCatalog.sqlViewName: 'ZE2E001CSO'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'OData V4 Demo Service - SalesOrder Root'
define view ZE2E001_C_SalesOrder
as select from SEPM_I_SalesOrder_E
association [1..*] to ZE2E001_C_SALESORDERITEM as _Item on _Item.SalesOrder = $projection.SalesOrder
association [0..*] to SEPM_I_SalesOrderText_E as _Text on $projection.SalesOrder = _Text.SalesOrder
{
//SEPM_I_SalesOrder_E
key SalesOrder,
CreatedByUser,
CreationDateTime,
LastChangedByUser,
LastChangedDateTime,
IsCreatedByBusinessPartner,
IsLastChangedByBusinessPartner,
Customer,
CustomerContact,
TransactionCurrency,
@Semantics.amount.currencyCode: 'TransactionCurrency'
GrossAmountInTransacCurrency,
@Semantics.amount.currencyCode: 'TransactionCurrency'
NetAmountInTransactionCurrency,
@Semantics.amount.currencyCode: 'TransactionCurrency'
TaxAmountInTransactionCurrency,
SalesOrderLifeCycleStatus,
SalesOrderBillingStatus,
SalesOrderDeliveryStatus,
SalesOrderOverallStatus,
Opportunity,
SalesOrderPaymentMethod,
SalesOrderPaymentTerms,
BillToParty,
BillToPartyRole,
ShipToParty,
ShipToPartyRole,
/* Associations */
_Item,
_Text
}
@AbapCatalog.sqlViewName: 'ZE2E001CSOI'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'OData V4 Demo Service - SalesOrder Items'
define view Ze2e001_C_Salesorderitem
as select from SEPM_I_SalesOrderItem_E
association [0..*] to SEPM_I_SalesOrderItemText_E as _Text on $projection.SalesOrder = _Text.SalesOrder
and $projection.SalesOrderItem = _Text.SalesOrderItem
{
//SEPM_I_SalesOrderItem_E
key SalesOrder,
key SalesOrderItem,
Product,
TransactionCurrency,
@Semantics.amount.currencyCode: 'TransactionCurrency'
GrossAmountInTransacCurrency,
@Semantics.amount.currencyCode: 'TransactionCurrency'
NetAmountInTransactionCurrency,
@Semantics.amount.currencyCode: 'TransactionCurrency'
TaxAmountInTransactionCurrency,
ProductAvailabilityStatus,
OpportunityItem,
/* Associations */
_Text
}
interface zif_e2e001_odata_v4_so_types
public .
types:
begin of gty_cds_views,
salesorderitem type ze2e001_c_salesorderitem,
salesorder type ze2e001_c_salesorder,
end of gty_cds_views.
types: begin of gty_s_so_soi .
include type gty_cds_views-salesorder.
types:
_item type standard table of gty_cds_views-salesorderitem with default key,
end of gty_s_so_soi .
types:
begin of gt_key_range,
salesorder type range of gty_cds_views-salesorder-salesorder,
itemposition type range of gty_cds_views-salesorderitem-salesorderitem,
end of gt_key_range.
constants:
begin of gcs_cds_view_names,
salesorderitem type /iwbep/if_v4_med_element=>ty_e_med_internal_name value 'SEPM_ODATA_C_SALESORDERITEM',
salesorder type /iwbep/if_v4_med_element=>ty_e_med_internal_name value 'SEPM_ODATA_C_SALESORDER',
end of gcs_cds_view_names,
begin of gcs_entity_type_names,
begin of internal,
salesorderitem type /iwbep/if_v4_med_element=>ty_e_med_internal_name value 'SEPM_ODATA_C_SALESORDERITEM',
salesorder type /iwbep/if_v4_med_element=>ty_e_med_internal_name value 'SEPM_ODATA_C_SALESORDER',
end of internal,
begin of edm,
salesorderitem type /iwbep/if_v4_med_element=>ty_e_med_edm_name value 'SalesOrderItemType',
salesorder type /iwbep/if_v4_med_element=>ty_e_med_edm_name value 'SalesOrderType',
end of edm,
end of gcs_entity_type_names,
begin of gcs_entity_set_names,
begin of internal,
salesorderitem type /iwbep/if_v4_med_element=>ty_e_med_internal_name value 'SEPM_ODATA_C_SALESORDERITEM',
salesorder type /iwbep/if_v4_med_element=>ty_e_med_internal_name value 'SEPM_ODATA_C_SALESORDER',
end of internal,
begin of edm,
salesorderitem type /iwbep/if_v4_med_element=>ty_e_med_edm_name value 'SalesOrderItem',
salesorder type /iwbep/if_v4_med_element=>ty_e_med_edm_name value 'SalesOrder',
end of edm,
end of gcs_entity_set_names ,
begin of gcs_nav_prop_names,
begin of internal,
salesorder_to_items type /iwbep/if_v4_med_element=>ty_e_med_internal_name value '_ITEM',
end of internal,
begin of edm,
salesorder_to_items type /iwbep/if_v4_med_element=>ty_e_med_edm_name value '_Item',
end of edm,
end of gcs_nav_prop_names.
endinterface.
Message Number | Short Text | Self Explanatory |
050 | Entity &1 not found in entiy set &2 | X |
051 | filter, top or navigation must be used to access entity set &1 | X |
052 | Entity key &1 does not match key in payload | X |
class zcx_e2e001_odata_v4_so definition
public
inheriting from /iwbep/cx_gateway
final
create public .
public section.
constants:
begin of entity_not_found,
msgid type symsgid value 'ZCM_E2E001ODATAV4_SO',
msgno type symsgno value '050',
attr1 type scx_attrname value 'ENTITY_KEY',
attr2 type scx_attrname value 'EDM_ENTITY_SET_NAME',
attr3 type scx_attrname value '',
attr4 type scx_attrname value '',
end of entity_not_found.
constants:
begin of use_filter_top_or_nav,
msgid type symsgid value 'ZCM_E2E001ODATAV4_SO',
msgno type symsgno value '051',
attr1 type scx_attrname value 'EDM_ENTITY_SET_NAME',
attr2 type scx_attrname value '',
attr3 type scx_attrname value '',
attr4 type scx_attrname value '',
end of use_filter_top_or_nav .
constants:
begin of entity_keys_do_not_match,
msgid type symsgid value 'ZCM_E2E001ODATAV4_SO',
msgno type symsgno value '052',
attr1 type scx_attrname value 'EDM_ENTITY_KEY',
attr2 type scx_attrname value '',
attr3 type scx_attrname value '',
attr4 type scx_attrname value '',
end of entity_keys_do_not_match .
data: entity_set_name type /iwbep/if_v4_med_element=>ty_e_med_internal_name,
edm_entity_set_name type /iwbep/if_v4_med_element=>ty_e_med_edm_name,
user_name type syuname,
entity_key type string read-only.
methods constructor
importing
!textid like if_t100_message=>t100key optional
!previous like previous optional
!exception_category type ty_exception_category default gcs_excep_categories-provider
!http_status_code type ty_http_status_code default gcs_http_status_codes-sv_internal_server_error
!is_for_user type abap_bool default abap_true
!message_container type ref to /iwbep/if_v4_message_container optional
!sap_note_id type ty_sap_note_id optional
!edm_entity_set_name type /iwbep/if_v4_med_element=>ty_e_med_edm_name optional
!entity_set_name type /iwbep/if_v4_med_element=>ty_e_med_internal_name optional
!user_name type syuname optional
!entity_key type string optional.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ZCX_E2E001_ODATA_V4_SO IMPLEMENTATION.
METHOD constructor ##ADT_SUPPRESS_GENERATION.
CALL METHOD super->constructor
EXPORTING
previous = previous
exception_category = exception_category
http_status_code = http_status_code
is_for_user = is_for_user
message_container = message_container
sap_note_id = sap_note_id.
me->entity_key = entity_key.
me->user_name = user_name.
me->entity_set_name = entity_set_name .
me->edm_entity_set_name = edm_entity_set_name.
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.
method /iwbep/if_v4_mp_basic~define.
define_salesorder( io_model ).
define_salesorderitem( io_model ).
endmethod.
method define_salesorder.
data: lt_primitive_properties type /iwbep/if_v4_med_element=>ty_t_med_prim_property,
lo_entity_set type ref to /iwbep/if_v4_med_entity_set,
lo_nav_prop type ref to /iwbep/if_v4_med_nav_prop,
lo_entity_type type ref to /iwbep/if_v4_med_entity_type,
lv_referenced_cds_view type gty_cds_views-salesorder .
" As internal ABAP name we use the name of the CDS view
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Create entity type
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
lo_entity_type = io_model->create_entity_type_by_struct(
exporting
iv_entity_type_name = gcs_entity_type_names-internal-salesorder
is_structure = lv_referenced_cds_view
iv_add_conv_to_prim_props = abap_true
iv_add_f4_help_to_prim_props = abap_true
iv_gen_prim_props = abap_true ).
lo_primitive_property = lo_entity_type->get_primitive_property( 'SALESORDER' ).
lo_primitive_property->set_is_key( ).
lo_nav_prop = lo_entity_type->create_navigation_property( gcs_nav_prop_names-internal-salesorder_to_items ).
lo_nav_prop->set_edm_name( gcs_nav_prop_names-edm-salesorder_to_items ).
lo_nav_prop->set_target_entity_type_name( gcs_entity_type_names-internal-salesorderitem ).
lo_nav_prop->set_target_multiplicity( /iwbep/if_v4_med_element=>gcs_med_nav_multiplicity-to_many_optional ).
lo_nav_prop->set_on_delete_action( /iwbep/if_v4_med_element=>gcs_med_on_delete_action-none ).
io_request->get_todos( importing es_todo_list = ls_todo_list ).
" $skip / $top handling
if ls_todo_list-process-skip = abap_true.
ls_done_list-skip = abap_true.
io_request->get_skip( importing ev_skip = lv_skip ).
endif.
if ls_todo_list-process-top = abap_true.
ls_done_list-top = abap_true.
io_request->get_top( importing ev_top = lv_top ).
endif.
io_request->get_entity_set( importing ev_entity_set_name = lv_entityset_name ).
case lv_entityset_name.
when gcs_entity_set_names-internal-salesorder.
read_list_salesorder(
exporting
io_request = io_request
io_response = io_response
iv_orderby_string = lv_orderby_string
iv_select_string = lv_select_string
iv_where_clause = lv_where_clause
iv_skip = lv_skip
iv_top = lv_top
is_done_list = ls_done_list ).
lt_key_range_salesorder type zif_e2e001_odata_v4_so_types=>gt_key_range-salesorder,
ls_key_range_salesorder type line of zif_e2e001_odata_v4_so_types=>gt_key_range-salesorder,
lt_salesorder type standard table of gty_cds_views-salesorder,
lt_key_salesorder type standard table of gty_cds_views-salesorder.
"generic data types
data: ls_todo_list type /iwbep/if_v4_requ_basic_list=>ty_s_todo_list,
ls_done_list type /iwbep/if_v4_requ_basic_list=>ty_s_todo_process_list,
lv_count type i,
lv_max_index type i.
if ls_todo_list-process-filter = abap_false
and ls_todo_list-process-key_data = abap_false
and iv_top = 0.
raise exception type zcx_e2e001_odata_v4_so
exporting
textid = zcx_e2e001_odata_v4_so=>use_filter_top_or_nav
http_status_code = zcx_e2e001_odata_v4_so=>gcs_http_status_codes-bad_request
edm_entity_set_name = gcs_entity_set_names-edm-salesorder.
endif.
"OFFSET is only supported as of NW751
select (iv_select_string) from ze2e001_c_salesorder
where (iv_where_clause)
and salesorder in @lt_key_range_salesorder
order by (iv_orderby_string)
into corresponding fields of table @lt_salesorder
up to @iv_top rows
offset @iv_skip.
io_response->set_busi_data( it_busi_data = lt_salesorder ).
io_request->get_entity_set( importing ev_entity_set_name = lv_entityset_name ).
case lv_entityset_name.
when gcs_entity_set_names-internal-salesorder.
read_entity_salesorder(
exporting
io_request = io_request
io_response = io_response ).
method read_entity_salesorder.
"entity type specific data types
data: ls_salesorder type gty_cds_views-salesorder,
ls_key_salesorder type gty_cds_views-salesorder,
lv_salesorder_key_edm type string,
lv_helper_int type i.
"generic data types
data: ls_todo_list type /iwbep/if_v4_requ_basic_read=>ty_s_todo_list,
ls_done_list type /iwbep/if_v4_requ_basic_read=>ty_s_todo_process_list.
io_request->get_todos( importing es_todo_list = ls_todo_list ).
" read the key data
io_request->get_key_data( importing es_key_data = ls_key_salesorder ).
ls_done_list-key_data = abap_true.
select single * from ze2e001_c_salesorder
into corresponding fields of @ls_salesorder
where salesorder = @ls_key_salesorder-salesorder.
if ls_salesorder is not initial.
io_response->set_busi_data( is_busi_data = ls_salesorder ).
else.
"Move data first to an integer to remove leading zeros from the response
lv_salesorder_key_edm = lv_helper_int = ls_key_salesorder-salesorder.
raise exception type zcx_e2e001_odata_v4_so
exporting
textid = zcx_e2e001_odata_v4_so=>entity_not_found
http_status_code = zcx_e2e001_odata_v4_so=>gcs_http_status_codes-not_found
edm_entity_set_name = gcs_entity_set_names-edm-salesorder
entity_key = lv_salesorder_key_edm.
endif.
" Report list of request options handled by application
io_response->set_is_done( ls_done_list ).
endmethod.
method /iwbep/if_v4_dp_basic~read_ref_target_key_data_list.
data: lv_source_entity_name type /iwbep/if_v4_med_element=>ty_e_med_internal_name.
io_request->get_source_entity_type( importing ev_source_entity_type_name = lv_source_entity_name ).
case lv_source_entity_name.
when gcs_entity_type_names-internal-salesorder.
read_ref_key_list_salesorder(
exporting
io_request = io_request
io_response = io_response ).
when others.
super->/iwbep/if_v4_dp_basic~read_ref_target_key_data_list(
exporting
io_request = io_request
io_response = io_response ).
endcase.
endmethod.
method read_ref_key_list_salesorder.
"entity type specific data types
data: ls_salesorder_key_data type gty_cds_views-salesorder,
lt_salesorderitem_key_data type standard table of gty_cds_views-salesorderitem,
ls_todo_list type /iwbep/if_v4_requ_basic_ref_l=>ty_s_todo_list.
"generic data types
data: ls_done_list type /iwbep/if_v4_requ_basic_ref_l=>ty_s_todo_process_list,
lv_nav_property_name type /iwbep/if_v4_med_element=>ty_e_med_internal_name.
" Get the request options the application should/must handle
io_request->get_todos( importing es_todo_list = ls_todo_list ).
if ls_todo_list-process-source_key_data = abap_true.
io_request->get_source_key_data( importing es_source_key_data = ls_salesorder_key_data ).
ls_done_list-source_key_data = abap_true.
endif.
io_request->get_navigation_prop( importing ev_navigation_prop_name = lv_nav_property_name ).
case lv_nav_property_name.
when gcs_nav_prop_names-internal-salesorder_to_items.
select salesorder , salesorderitem from ze2e001_c_salesorderitem
into corresponding fields of table @lt_salesorderitem_key_data
where salesorder = @ls_salesorder_key_data-salesorder.
io_response->set_target_key_data( lt_salesorderitem_key_data ).
when others.
raise exception type zcx_e2e001_odata_v4_so
exporting
http_status_code = zcx_e2e001_odata_v4_so=>gcs_http_status_codes-sv_not_implemented.
endcase.
" Report list of request options handled by application
io_response->set_is_done( ls_done_list ).
endmethod.
Field | Value |
Service ID | ZE2E001_SALESORDER |
Service Version | 1 |
Model Provider Class | ZCL_E2E001_ODATA_V4_SO_MODEL |
Data Provider Class | ZCL_E2E001_ODATA_V4_SO_DATA |
Description | OData V4 demo service |
Package | ZE2E001 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
29 | |
13 | |
13 | |
10 | |
9 | |
9 | |
9 | |
8 | |
7 | |
7 |