Step-by-step guide to build an OData Service based on RFCs – Part 2
1. As mentioned we will start with the Query method for the SalesOrderCollection entity-set. Expand the node Service Implementation -> SalesOrderCollection and right-click GetEntitySet (Query) and select Map to Data Source:
Target System | Local |
Data Source Type | Remote Function Call |
Data Source Name | BAPI_EPM_SO_GET_LIST |
Target System | Local |
Data Source Type | Remote Function Call |
Data Source Name | BAPI_EPM_SO_GET_DETAIL |
Expand the HEADERDATA node from the tree on the right-hand side:
RFC Field (right –hand side) | Entity Property |
---|---|
SO_ID | SoId |
NOTE | Note |
BUYER_ID | BuyerId |
BUYER_NAME | BuyerName |
CURRENCY_CODE | CurrencyCode |
GROSS_AMOUNT | GrossAmount |
NET_AMOUNT | NetAmount |
TAX_AMOUNT | TaxAmount |
In any Read Operation we also need to provide the primary key of the underlying entity as an input parameter. For this we have to manually add a new line to the mapping screen.
1. Choose the Append Row pushbutton:
2. On the new line press F4 to select the entity set property. Double-click SoId to select the entry:
3. Expand the SO_ID node from the tree on the right-hand side:
4. Drag&Drop the RFC field SO_ID (from node SO_ID) to the newly-created line:
5. This performs the mapping on the input parameter (Sales Order ID to fetch the Sales Order details):
Now we can move on with mapping the Query operation for the Sales Order Item entity-set
1. Expand the node Service Implementation -> SalesOrderItemCollection and right-click GetEntitySet (Query) and select Map to Data Source:
2. In the Map to Data Source dialog box, enter the following values and choose Enter:
Target System | Local |
Data Source Type | Remote Function Call |
Data Source Name | BAPI_EPM_SO_GET_DETAIL |
3. There is again no default mapping because the data model has been built based on a different RFC module. Expand the ITEMDATA node from the tree on the right-hand side:
4. Drag&drop the following fields from the right-hand tree to the Data Source Parameter column of the grid in the middle of the screen:
RFC Field (right –hand side) | Entity Property |
---|---|
SO_ID | SoId |
SO_ITEM_POS | SoItemPos |
PRODUCT_ID | ProductId |
NOTE | Note |
CURRENCY_CODE | CurrencyCode |
GROSS_AMOUNT | GrossAmount |
NET_AMOUNT | NetAmount |
TAX_AMOUNT | TaxAmount |
QUANTITY | Quantity |
QUANTITY_UNIT | QuantityUnit |
5. In the Direction Column set all fields to Output. Choose Enter:
6. Choose Append Row button:
7. From the input help, select SoId for the new line:
8. Expand the SO_ID node from the right-hand tree:
9. Drag&drop the RFC field SO_ID (from node SO_ID) to the newly created line:
Now we are done with the data provider mapping (at least for the Query and Read operations we need). Now we can re-generate the runtime artifacts and run our OData service.
1. Choose the Generate pushbutton:
2. Verify that the runtime objects have been generated successfully:
3. Start the Gateway Client (Transaction /IWFND/GW_CLIENT) in a separate window to run the service. Provide the following URI to get the Sales Order Collection. This executes the query method of the Sales Order entity-set:
/sap/opu/odata/sap/ZGW100_XX_SO_SRV/SalesOrderCollection
4. Choose any sales order entry and use the URI to navigate to the sales order detail, for example:
/sap/opu/odata/sap/ZGW100_XX_SO_SRV/SalesOrderCollection(‘0500000001’)
5. Get the related sales order line items via the following URL:
/sap/opu/odata/sap/ZGW100_XX_SO_SRV/SalesOrderItemCollection/?$filter=SoId eq ‘0500000001’
hi,
I followed step by step your guide, but it does not work, the service when I call SalesOrderCollection or SalesOrderItemCollection gives me an error like this:
Hi Matteo,
Check with connection of NW & ECC (Back end) system connected properly or not.
Once you cross check with BASIS team if possible.
Check the ST22, most likely you ran into memory space issue since you are trying to list all the records.
Try following URI instead,
/sap/opu/odata/sap/ZEPM_BAPI_SRV/SalesOrderItemCollection/?$filter=SoId eq '0500000000'
Hi Volker,
I followed your blog. i am not getting error but,
/sap/ZSALES_ORDER_SRV/SalesOrderSet
In VBAK i have many Sales Orders but it show only first 2 and without any other deails like
Note,Buyer Id ,Buyer Name all.
Table entries.
If I pass correct Sales order id /sap/ZSALES_ORDER_SRV/SalesOrderSet('0000004975')
I am getting this error
Can you help me out in resolving the problem.
Hello Arshad,
as mentioned in the first part the BAPIs used are accessing the EPM demo content. They are not accessing the SD tables (like VBAK).
Instead you find the sample sales orders of EPM in table SNWD_SO.
Hope this helps.
Best Regards,
Volker
Thanks Volker,
can you suggest me how to access the data from standard tables (like VBAK),
I have to create complete service for Sales Order and Purchase order,
Best Regards,
Arshad Shaikh
Hello Arshad,
I'd propose to access standard tables via the related BAPIs. E.g. for Sales Orders there is the BAPI_SALESORDER_GETLIST function module.
Best Regards,
Volker
Very useful info. Thanks Volker
Super useful! Thanks for the details! 😎
Hi,
We have followed your first blog Step-by-step guide to build an OData Service based on RFCs – Part 1 and are trying to implement the steps mentioned in this blog. While performing the step
1. Expand the node Service Implementation -> SalesOrderItemCollection and right-click GetEntitySet (Query) and select Map to Data Source:
we find that when we right click on GetEntitySet (Query) we see the option Map to Data Source in disabled format.
Can you please let me know what may be the reason for this?
Regards,
Saurabh
Hi Saurabh,
are you still in Edit mode? "Map to Data Source" should be disabled only in Display mode.
Best Regards,
Volker
Or have you already mapped a data source? In this case the menu option is also greyed out.
Regards, Volker
Hi Volker,
I am using a standard BAPI BAPI_PO_GETITEMSREL to get the Release Items where two of the parameters are input. But when I try to compile the data mapping by having them as input, it says that there is no output defined for the two parameters. I am not understanding this concept. Kindly let me know if I am missing out anything.
Thanks and Regards,
Ashok Dhayalaraj
Hi Volker,
Sorry. I had the input parameters as key fields and so it was expecting that those fields also should have an output.
Thanks and Regards,
Ashok Dhayalaraj
Hi Ashok,
great. Thanks for updating us on how you solved the problem.
Best Regards, Volker
Hello,
First of thanks for this nice blog. I followed and this is working fine for Header part but when it is for item, then response says, Sales Order ID is initial.
"Consumer problem: Sales Order Id is initial"
Whereas I am trying with following URI:
/sap/opu/odata/sap/ZGW100_XX_SO_SRV/SalesOrderItemCollection/?$filter=SoId eq '0500000001'
But item works fine when my request URI is:
/sap/opu/odata/sap/ZGW100_XX_SO_SRV/SalesOrderItemCollection('0500000001')
Could anyone help me to understand where problem could be?
- Thanks , Somnath
Hello,
I was trying and found the issue was in mapping for both read as well Query.
Means in case of Item, I had to map the SoId against SO_ID as below:
Hello Paul,
in this example we are not mapping the GetEntity (Read) operation for the SalesOrderItemCollection entity set as there is no suitable RFC that can serve this request. So if you map the SalesOrder-ID as input parameter in the GetEntitySet (Query) it should work fine.
Best Regards,
Volker
Hi Volker,
You have explained it very nicely. I have never done anything in ABAP, still I was able to understand and execute it by following the steps mentioned.
I am facing a small issue while implementing this. My questions may be very silly, but please consider them as some queries from a novice ABAP programmer 🙂 .
When I execute BAPI_EPM_SO_GET_LIST without providing MAX_ROWS from SE37, it is taking very long time to return the result as it is an open query and the system has lots of records. When I executed my oData service, I got the following Connection timeout error.
So, I have added a new property in SalesOrder entity type (MaxRows with type Edm:Int32), and mapped it with import parameter - MAX_ROWS of GET_LIST BAPI. When I tried to pass a constant value for this from mapping ('100'), I am getting error (You can see all the details in the following image. It is not accepting number without apostrophe wrapping).
So my questions are:
1. How can I pass a constant value using mapping (in the above example)
2. If I want to pass MaxRows during this oData url execution (so that the result would become more dynamic in nature), what shall I do?
3. I tried to add some code in GET_ENTITY method (of DPC_EXT class) for experiment purpose. However, the code is always getting erased when I generate Runtime objects. How can I retain the custom code which I have done there during Runtime Object creation?
Can you please explain these with more details?
Thanks
Fahad
Hi Fahad,
let me try to answer your questions:
1.: As the error message says, pass a constant value or an entity set property. If you remove the entity set property it should work.
2.: For this you can use $top (e.g. .../SalesOrderSet?$top=100)
3.: I guess you are editing the DPC base class. The base class will be regenerated every time. If the method name is shown with blue color it points to the base class although you are editing the ext class. You once need to redefine the method (2nd last button) in the ext class (this turns the color of the method name to black).
Hope this help.
Best Regards, Volker
Hi Mark,
Thanks for the response.
I have tried the following url.
/sap/opu/odata/SAP/ZFAH_GW_EPM_RFM_SRV/SalesOrderSet?$top1
However, it took almost a minute to execute and presented Connection Timeout error (screen shot below for rference)
I guess the service url executing the BAPI without any filter (please note the BAPI is freezing if I execute it without passing import parameter in SE37) and then tries to apply the filter on the retrieved result.
Hence I tried to pass the value for MAX_ROWS during service execution. However, I am stuck there as well as it is not accepting the constant value '10' or 10 for the new parameter (throwing the error which I have mentioned before). Also, I am not sure how to pass a user input value for import parameter MAX_ROWS from service url.
Any suggestion on how to resolve this scenario?
Thanks,
Fahad Hamsa
Hi Fahad,
the correct URI is ...?$top=1
In the generated coding the MAX_ROWS parameter is not used. So you need to redefine the generated GET_ENTITYSET method (e.g. copy from the base class) and make sure to set the MAX_ROWS parameter.
Best Regards,
Volker
Hi Volker
Many thanks for your tutorial, it was very helpfull for me.
I'm facing a strange problem...i followed you step by step but my service is not working:
Calling getEntity:
/sap/opu/odata/sap/zfiori_read_orders_srv_02/EtOrdersSet('40502394') it works fine, and in abap side i have the parameter VBELN valorized correctly.
But when i try to call GetEntitites:
/sap/opu/odata/sap/zfiori_read_orders_srv_02/EtOrdersSet?$filter=Vbeln eq '40502394', i'm receiving VBELN truncated at the 5th position:
so, in ABAP side, i0m receiving VBELN = 0000040502.....
i really don't know where i'm doing wrong...any suggestion?
Thanks in advance.
Marco
Hi Volker,
Thanks for the great tutorial. I appreciate your wonderful work.
I am facing a problem. I followed all steps but not getting any data from backend.
Thanks,
Amit
Hi Amit,
it seems that no EPM data exists in your system. Try to run Tx SEPM_DG to generate some.
Regards, Volker
Thanks Volker,
I am getting data now.
Regards,
Amit
Hi Volker
using this format i'm passing only one parameter to the service:
/sap/opu/odata/sap/zfiori_read_orders_srv_02/EtOrdersSet('40502394')
if i wonna pass more then one parameter, something like vbeln and posnr but not using FIlter, how can i do that?
Thanks
Marcp
Hi Marco,
for that you need to flag more than one property as key when defining the entity type of your entity set. In that case the URI would look like:
.../Service/EntitySet(KeyProp1='...',KeyProp2='...',KeyProp3='...') and so on.
Best Regards,
Volker
Hello Volker,
How could I add the messages generated in the Return Table of "BAPI_EPM_SO_GET_DETAIL" for the same filter passed in the URL. For example I want to see if any message exists for SoId = '400001' and show this message in web service.
Thanks and Best Regards,
Puskar Ghosal
How to connect & expose the SAP ECC data to power BI via netweaver gateway. We have created the project under SEGW however we are not able to find any document about the connectivity to build between the ECC and Power BI. Any inputs would be highly appreciated.
https://docs.microsoft.com/en-us/power-bi/desktop-connect-odata