Skip to Content
Technical Articles
Author's profile photo Alexander Duemont

Step 11 with SAP Cloud SDK: Virtual Data Model for BAPI

Disclaimer: This blog post is only applicable for the SAP Cloud SDK version of at most 2.19.2. With version 3.0.0 and later this feature is discontinued, so there will be no updated tutorial. Feel free to check out our other Tutorials on the SAP Cloud SDK.

The following steps will explain how to use the SAP Cloud SDK’s Virtual Data Model (VDM) to simplify the communication with your SAP S/4HANA System.

Note: This post is part of a series. For a complete overview visit the SAP Cloud SDK Overview.

Goal of this blog post

In this blog post we will take a look at how BAPI works for reading and writing data from an SAP S/4HANA system, especially when OData is not yet available but BAPI endpoints are. You will understand how to use the Virtual Data Model (VDM), why it is the recommended way and where to find more details about it.

! Note ! In general, SAP S/4HANA Cloud exposes APIs in the form of OData and SOAP services. In addition, you can access selected BAPIs explicitly mentioned in the overview table below using the SAP Cloud SDK. BAPIs in SAP S/4HANA Cloud are otherwise not accessible from applications on SAP Cloud Platform, except for the selected BAPIs mentioned below. If you want to submit an improvement request for additional APIs (in the form of OData services), kindly refer to the customer influence program “SAP S/4HANA Cloud Integration”.

We will advance the example application from Step 5: Resilience to demonstrate the usage of the BAPI VDM inside your SAP S/4HANA Cloud application on SAP Cloud Platform. You will be able to create new cost centers with underlying BAPI operations.

If you want to follow this tutorial, we highly recommend checking out these previous tutorials:

For a complete overview visit the SAP Cloud SDK Overview.

Note: This tutorial requires access to an SAP ERP system and an activated communication scenario 0180 from the finance domain – “SAP Cloud Platform – Financials Integration (SAP_COM_0180)“. The activation of this scenario will be covered very soon in an upcoming blog post.

 

Virtual Data Model

The data stored in an S/4HANA system is inherently complexly structured and therefore difficult to query manually. Therefore, SAP Cloud SDK introduces a Virtual Data Model (VDM) that aims to abstract from this complexity and provide data in a semantically meaningful and easy to consume way.

The preferred way to consume data from an S/4HANA system is via the OData protocol, see Step 10: Virtual Data Model for OData. But when OData is not yet provided in a suitable way for specific operations, then often enough BAPIs present a useful, already implemented alternative to establishing ERP interactivity. Although considered as bridge technology, you can use BAPIs as a functional second choice. In case of SAP S/4HANA Cloud, only selected BAPIs are accessible as described below.

Since the official SAP strategy is to gradually replace BAPI with OData, an established BAPI operation may be discontinued at some point in the future. For this compatibility issue, SAP Cloud SDK has a developer oriented solution: a BAPI Virtual Data Model. With the enabled data model library, BAPI function calls – and BAPI complexity in general – can be hidden from the developer. This allows, to easily update, replace or migrate internal functionality with newer SAP system versions, without having the software architect bother about compatibility. The benefits are outstanding. But before we dive into the example source code about cost center creation, let’s briefly introduce BAPI first.

 

Introduction to BAPI

A BAPI (Business Application Programming Interface) is a programming interface that enables external access to business processes and data in the ERP system. BAPIs are defined by methods, given by the Business Object Repository. They offer an object-oriented view of business components in the system.

You may also know BAPIs from the convenient BAPI Explorer in your SAP GUI. Just use the transaction code “BAPI“, and the program starts:

Here you can browse the BAPIs of your SAP system, in a hierarchical order:

  • Business Object
  • BAPI
  • Parameters / Description / Remote function details

In order to examine BAPI details, like implementation, parameter types and tables, you can take a look into the function module itself. By double clicking on the name, the SAP GUI opens an elaborate overview window with all of its details.

The following information about function modules is provided:

  • General properties
  • Function parameters: Import, Export, ChangingTables
  • Exception
  • Sources

To correctly operate a single BAPI, you need to have some knowledge about its structure and field constraints. Of course the details about parameters can be looked up, but any mistake will result in an error response. Now, to lower the risk of making mistakes during development, the SAP Cloud SDK provides the VDM for BAPI. By using the relevant Java classes you effectively operate on prepared BAPI function calls, which guarantees to produce valid queries. By using this library, time and resources will be saved during your software developing process.

 

Virtual Data Model: Queries to BAPI

Try it out, by working with one of our archetypes; it automatically adds the Maven dependency s4hana-all to your application class path. That’s how you are able to use the BAPI VDM from the start. You will find the service interfaces and default implementation classes in the following Java package:

import com.sap.cloud.sdk.s4hana.datamodel.bapi.services.*;

Next, before we continue with the showcase project of the CostCenter, we’ll have a look at a short code sample, the FinancialTransactionService.

Sample: “getList” by FinancialTransactionService

The easiest way to get started, is to check and run the BAPI VDM by using some very basic BAPI function. An example function, which does not invoke changes or require any mandatory parameter, can be called with the BAPI method getList() from the DefaultFinancialTransactionService class.

final ErpConfigContext erpConfigContext = ...
return new DefaultFinancialTransactionService().getList().execute(erpConfigContext).getListOfSelectedTransactions();

Here, DefaultFinancialTransactionService is the implementation class of the interface FinancialTransactionService representing the accessible Business Object in your S/4HANA system, by applying the published getList() function module. Since no further mandatory parameters are needed, the function call can be prepared just like this. The execution itself happens with the execute method. Internally, the SAP Cloud SDK serializes the function query to SOAP for HTTP destinations on CloudEdition or to JCo for RFC destinations on OnPremise systems. Connection, authentication, processing and deserialization is done automatically. Only a reference to an ERP configuration context is required. This variable is usually provided by your application. Here, we decide to read the list of selected transactions as result.

The general API usage stays the same for all BAPI VDM queries [optional]:

  1. Instantiate Business object service class (or use provided instance, for example with dependency injection)
  2. BAPI name [mandatory parameters]
  3. [parameters]
  4. execute( ErpConfigContext )
  5. [function query result]

Showcase: “createMultiple” by CostCenterService

In order to extend the CostCenter showcase project, let’s take advantage of the BAPI VDM. It allows us to easily create new cost center items.

import com.sap.cloud.sdk.s4hana.datamodel.bapi.structures.*;
import com.sap.cloud.sdk.s4hana.datamodel.bapi.types.*;

final ErpConfigContext erpConfigContext = ...
final String id = ...
final String description = ...

final ControllingArea controllingArea = ControllingArea.of("A000"); // ERP type "CACCD"

final CostCenterCreateInput costCenterInput = CostCenterCreateInput
        .builder()
        .validFrom(new LocalDate())
        .validTo(new LocalDate().plusYears(1))
        .costcenter(CostCenter.of(id))
        .name(id)
        .descript(description)
        .currency(CurrencyKey.of("EUR"))                    // ERP type "WAERS"
        .costcenterType(IndicatorForCostCenterType.of("E")) // ERP type "KOSAR"
        .personInCharge(CostCenterManager.of("USER"))       // ERP type "VERAK"
        .costctrHierGrp(SetId.of("0001"))                   // ERP type "SETNR"
        .compCode(CompanyCode.of("1010"))                   // ERP type "BUKRS"
        .profitCtr(ProfitCenter.of("YB101"))                // ERP type "PRCTR"
        .build();

List<ReturnParameter> messages = new DefaultCostCenterService()
        .createMultiple(controllingArea, costCenterInput)
        .execute(erpConfigContext)
        .getMessages();

To start at the beginning, let’s assume you have an ERP configuration context, like previously stated. Also consider a cost center id and description as user input. Although, as you can see here, the VDM powered source code is already descriptive, let’s roughly summarize the control flow:

  • Instantiation of Controlling Area. This will later be used as first mandatory BAPI parameter. This class wraps a primitive String type. It automatically applies formatting and basic validation rules inherent to domain types in the SAP system.
  • Instantiation of CostCenter CreateInput. This will be used as second mandatory BAPI parameter. This class wraps a custom set of available values for the function call. By using the builder pattern you can easily instantiate your desired object, while keeping type safety. Such classes, which provide a set of values, are inherent to structure types in the SAP system.
  • Call to CostCenterService, to prepare a createMultiple BAPI remote function module call. The mandatory values are provided. With no further customization, execute the query. We decide to retrieve the default BAPI result messages, to check for notifications from the SAP system, like internal error messages.

Please note, the values for BAPI parameters may look different for your S/4HANA system. To help you finding the correct values, the domain types are commented above.

 

Use the VDM for your resilient BAPI call

You can simply wrap the previous VDM request into an ErpCommand, making it resilient like in Step 5: Resilience with Hystrix. Just like in the blog posts before, we create a new class and take ErpConfigContext as constructor parameter, as well as user provided variables:

package com.sap.cloud.sdk.tutorial;

import java.util.List;

import javax.annotation.Nonnull;

import org.joda.time.LocalDate;

import com.sap.cloud.sdk.s4hana.connectivity.ErpCommand;
import com.sap.cloud.sdk.s4hana.connectivity.ErpConfigContext;
import com.sap.cloud.sdk.s4hana.datamodel.bapi.services.CostCenterService;
import com.sap.cloud.sdk.s4hana.datamodel.bapi.services.DefaultCostCenterService;
import com.sap.cloud.sdk.s4hana.datamodel.bapi.structures.*;
import com.sap.cloud.sdk.s4hana.datamodel.bapi.types.*;

public class CreateCostCenterCommand extends ErpCommand<List<ReturnParameter>>
{
    private final String id;
    private final String description;

    public CreateCostCenterCommand(
            @Nonnull final ErpConfigContext configContext,
            @Nonnull final String id,
            @Nonnull final String description )
    {
        super(CreateCostCenterCommand.class, configContext);
        this.id = id;
        this.description = description;
    }

    @Override
    protected List<ReturnParameter> run() throws Exception {
        final ControllingArea controllingArea = ControllingArea.of("A000"); // ERP type "CACCD"

        final CostCenterCreateInput costCenterInput = CostCenterCreateInput
                .builder()
                .costcenter(CostCenter.of(id))
                .name(id)
                .descript(description)
                .validFrom(new LocalDate())
                .validTo(new LocalDate().plusYears(1))
                .currency(CurrencyKey.of("EUR"))                    // ERP type "WAERS"
                .costcenterType(IndicatorForCostCenterType.of("E")) // ERP type "KOSAR"
                .personInCharge(CostCenterManager.of("USER"))       // ERP type "VERAK"
                .costctrHierGrp(SetId.of("0001"))                   // ERP type "SETNR"
                .compCode(CompanyCode.of("1010"))                   // ERP type "BUKRS"
                .profitCtr(ProfitCenter.of("YB101"))                // ERP type "PRCTR"
                .build();

        return new DefaultCostCenterService()
                .createMultiple(controllingArea, costCenterInput)
                .execute(getConfigContext())
                .getMessages();
    }
}

This can already be used in your own CostCenter showcase project. All it takes is an additional servlet HTTP method definition inside CostCenterServlet.java with doPost(...) similar to doGet(...):

@WebServlet( "/costcenters" )
public class CostCenterServlet extends HttpServlet
{
    ...

    @Override
    protected void doPost( final HttpServletRequest request, final HttpServletResponse response )
            throws ServletException,
            IOException
    {
        final ErpConfigContext configContext = new ErpConfigContext();

        final List<ReturnParameter> result = new CreateCostCenterCommand(
                configContext,
                request.getParameter("id"),
                request.getParameter("description")
        ).execute();

        // reset cached get results
        new GetCachedCostCentersCommand(configContext).getCache().invalidateAll();

        response.setContentType("application/json");
        response.getWriter().write(new Gson().toJson(result));
    }
}

Now you are able to easily create CostCenters with predefined values by having a simple HTTP post request. All it takes are user provided values for id and description. Already, our backend work is done!

 

Comparison to the generic way of implementing a BAPI requests

The whole cost center creation could have been realized without the help of BAPI VDM, but then we wouldn’t have been able to take advantage of the very useful comfort features. To visualize the impressive difference, let’s take a look into the direct comparison.

Generic BAPI query approach with SAP Cloud SDK
final ErpEndpoint erpEndpoint = ...

final BapiQuery query = new BapiQuery("BAPI_COSTCENTER_CREATEMULTIPLE")
        .withExporting("CONTROLLINGAREA", "KOKRS", "A000");

query.withTable("COSTCENTERLIST", "BAPI0012_CCINPUTLIST")
    .row()
    .field("COSTCENTER", "KOSTL", id)
    .field("NAME", "KTEXT", id)
    .field("DESCRIPT", "KLTXT", description)
    .field("VALID_FROM", "DATAB", new LocalDate())
    .field("VALID_TO", "DATBI", new LocalDate().plusYears(1))
    .field("COSTCENTER_TYPE", "KOSAR", "E")
    .field("CURRENCY", "WAERS", "EUR")
    .field("PERSON_IN_CHARGE", "VERAK", "USER")
    .field("COSTCTR_HIER_GRP", "KHINR", "0001")
    .field("COMP_CODE", "BUKRS", "1010")
    .field("PROFIT_CTR", "PRCTR", "YB101")
    .end();

query.withTableAsReturn("BAPIRET2");

return query.execute( erpEndpoint )
        .get("RETURN")
        .getAsCollection()
        .asList(ReturnParameter.class);

 

BAPI VDM query with SAP Cloud SDK
final ErpConfigContext erpConfigContext = ...
final ControllingArea controllingArea = ControllingArea.of("A000");

final CostCenterCreateInput costCenterInput = CostCenterCreateInput
        .builder()
        .costcenter(CostCenter.of(id))
        .name(id)
        .descript(description)
        .validFrom(new LocalDate())
        .validTo(new LocalDate().plusYears(1))
        .currency(CurrencyKey.of("EUR"))
        .costcenterType(IndicatorForCostCenterType.of("E"))
        .personInCharge(CostCenterManager.of("USER"))
        .costctrHierGrp(SetId.of("0001"))
        .compCode(CompanyCode.of("1010"))
        .profitCtr(ProfitCenter.of("YB101"))
        .build();

return new DefaultCostCenterService()
        .createMultiple(controllingArea, costCenterInput)
        .execute( erpConfigContext )
        .getMessages();

The differences appear quite obvious. Without the VDM a developer depends on expert knowledge about SAP table and function schematics. Not only are the definite table-, column- and parameter-names required, but you will also need to provide the data type name to each of them. And these String values are very cryptic and difficult to maintain. Fortunately we have the virtual data model.

Advantages

For the developer

  • Descriptive language naming for java classes, methods and fields (English)
    – to maintain code and logic
  • Javadoc on all VDM functions
    – to look up details and usage
  • Fluent programming and code completion
    – to allow rapid development
  • Implicit ERP types
    – to hide BAPI protocol complexity
  • Deserialized BAPI function query result data
    – to process information without parsing manually
  • Separation of required and optional parameters
    – to prevent error cases
  • Predefined values for individual types
    – to improve programming comfort
  • Java type safety for primitives
    – to strengthen API reliability and code quality
  • Java interfaces for each BAPI
    – to allow dependency injection and easy mocking of SAP S/4HANA during testing

 

Available VDM classes for BAPI

There is a limited set of VDM interfaces available for BAPI. The SAP Cloud SDK features all BAPIs from communication arrangement 0180, which is part of the finance domain: “SAP Cloud Platform – Financials Integration (SAP_COM_0180)“.

For each interface from the following overview, there is a default implementation class with the name of the interface prefixed with Default.

Business Object Service Interface BAPI Method
AccountingActivityAllocationService check
post
AccountingDocumentService check
post
AccountingManualCostAllocationService check
post
AccountingPrimaryCostsService check
post
CostCenterService createMultiple
FixedAssetService change
createFromData1
getList
ForeignExchangeOptionService change
create
getDetail
ForeignExchangeService createSwap
dealChange
dealCreate
dealGet
FinancialTransactionService getList

 

Please keep in mind, even with enabled VDM most BAPI methods still require some knowledge about the SAP S/4HANA system. You will need to know what values to fill in which parameters. That’s why depending on the BAPI, the effort may differ.

See the next tutorial in the series here: Step 12 with SAP Cloud SDK: Logging with SAP Cloud SDK.

 

Appendix: Required Changes to UI5 Frontend

In case you have already followed the instructions from blog post Step 9: Implement and Deploy a Frontend Application, you can simply advance your application to also run the BAPI function calls, we have established here. What we only want to change, are two existing files to make the cost center creation work as expected:

  • controller/View1.controller.js
  • view/View1.view.xml

 

  1. Edit the controller/View1.controller.js to add the createCostCenter action. Also please notice the additional MessageToast inclusion in the controller header. This allows us to display popup messages.
    sap.ui.define([
        "sap/ui/core/mvc/Controller",
        "sap/ui/model/json/JSONModel",
        "sap/m/MessageToast"
    ], function(Controller, JSONModel, MessageToast) {
        "use strict";
        return Controller.extend("blog-tutorial.controller.View1", {
    
            createCostCenter: function () {
                var that = this;
    
                var costCenterData = {
                    id : this.getView().byId("inputCostCenterId").getValue(),
                    description : this.getView().byId("inputCostCenterDescription").getValue()
                };
    
                return jQuery.ajax({
                        type: "POST",
                        url: "/costcenters",
                        data: costCenterData
                    })
                    .then(function (costCenters) {
                        that.onInit();
                        MessageToast.show("Successfully created new cost center!");
                    })
                    .fail(function () {
                        MessageToast.show("Failed to create cost center!");
                    });
            },
    
    
            onInit: function () {
                var view = this.getView();
                jQuery.get({
                        url: "/costcenters",
                        headers: {"X-CSRF-Token":"Fetch"}
                    })
                    .done(function (data, status, jqXHR) {
                        var csrfToken = jqXHR.getResponseHeader("X-CSRF-Token");
                        $.ajaxSetup({
                            headers: {"X-CSRF-Token": csrfToken}
                        });
                        var model = new JSONModel(data);
                        view.setModel(model, "costCenter");
                    });
            }
        });
    });
    

     

  2. Edit the view/View1.view.xml to add two input fields and a submit button:
    <mvc:View controllerName="blog-tutorial.controller.View1" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
    	displayBlock="true" xmlns="sap.m">
    	<App>
    		<pages>
    			<Page title="Cost Center Explorer">
    				<content>
    
    					<!-- Add input to create new cost centers -->
    					<HBox width="500px" justifyContent="SpaceAround" alignItems="End" id="__hbox1">
    						<VBox>
    							<Label text="Cost Center ID" />
    							<Input width="100%" id="inputCostCenterId" />
    						</VBox>
    						<VBox>
    							<Label text="Cost Center Long Text" />
    							<Input width="100%" id="inputCostCenterDescription" />
    						</VBox>
    						<Button text="Create" width="80px" id="__button0" press="createCostCenter" />
    					</HBox>
    					
    					<!-- Add this between the content tags -->
    					<List headerText="Cost Centers"
                            items="{costCenter>/}" >
                            <StandardListItem
                                title="{costCenter>costCenterDescription}"
                                description="{costCenter>costCenterID}" />
                        </List>
    				</content>
    			</Page>
    		</pages>
    	</App>
    </mvc:View>

     

  3. You’re done! It’s time to compile, package and deploy the application.

 

Troubleshooting

If the BAPI connection fails, please follow the checklist:

  • Is a network connection possible?
    Please check with your browser or any other custom HTTP query testing tool. Check whether a proxy is in use. Or overly strict firewall settings are in place.
  • Are you using the correct BAPI destination type?
    For SAP S/4HANA OnPremise systems your configured destination variable should be of type “RFC” instead of “HTTP” (Cloud Edition).
  • Are you using the correct ERP destination?
    When not specified, the default is used: ErpQueryEndpoint
    Is a destination with this name configured?
  • Are you using the correct ERP credentials?
    Does the user have access to the BAPI?

 

Assigned Tags

      24 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Henning Heitkoetter
      Henning Heitkoetter

      Change log (November 9, 2017):

      •  Updated to account for changes in version 1.3.0 of the SAP S/4HANA Cloud SDK (see release notes)
        • Instantiate new DefaultCostCenterService() instead of static CostCenterService (similar for DefaultFinancialTransactionService)
      • Explain separation of service interfaces and default implementation classes in VDM
      Author's profile photo Srdjan Boskovic
      Srdjan Boskovic

      Where to maintain ABAP backend system parameters, for calling BAPIs?

      Author's profile photo Alexander Duemont
      Alexander Duemont
      Blog Post Author

      Dear Srdjan,

      thank you for your interest in the S/4HANA Cloud SDK.

      In blog post #4 "Calling an OData Service" we described how to set up the ERP endpoint connection parameters like URL, username and password.

      For CloudEdition this is achieved by setting the environment variable "destinations", e.g.

      destinations=[{name: "ErpQueryEndpoint", url: "https://URL", username: "USER", password: "PASSWORD"}]

      For OnPremise the recommended way is to use the custom "erp.url" parameter for Maven commands, e.g.

      // you will be asked for username and password
      mvn scp:clean scp:push -pl application -Derp.url=https://URL
      
      // in case you got tired of being asked for credentials
      mvn scp:clean scp:push -pl application -Derp.url=https://URL -Derp.username=USER -Derp.password=PASSWORD

       

      The "sapClient" parameter usually is provided in application layer, e.g.

      new ErpConfigContext(new SapClient("132"))

      Please let me know, if you have follow up questions.

      Best regards

      Alexander

      Author's profile photo Srdjan Boskovic
      Srdjan Boskovic

      Thank you Alexander. Are RFC destinations already supported in Cloud Connector, on Cloud Foundry? Can I already try s4h cloud sdk on CF, with my backend BAPIs?

      Author's profile photo Sander Wozniak
      Sander Wozniak

      Hi Srdjan,

      I'm sorry to say that, at the time of this writing, no RFC support exists on Cloud Foundry.

      Best regards,
      Sander

       

      Author's profile photo Sijin Chandran
      Sijin Chandran

      Hi Alexander,

      Is there a standalone BAPI concept in S/4 HANA Cloud ?

      With standalone I mean without accessing BAPIs from ECC ( as you have mentioned in this blog ) instead accessing BAPIs of S/4 HANA Cloud ( of course if BAPI concepts exists in S/4 Hana ).

      As per our requirement we want to extract some Pricing Master Details like information on  Condition Type etc. and we were not able to find any APIs for the same, so that's why we were asked to check for BAPIs in S/4 Hana Cloud systems and host them as SOAP Webservices. Is something like this possible ?

      Would be very helpful if you can provide an insight on this, as I am from pure ECC ABAP background and as of now at ground zero level considering my experience in  SAP S/4 HANA  developer role.

      Thanks,

      Sijin

       

      Author's profile photo Marco Dahms
      Marco Dahms

      Hi Sijin,

      in case you're missing an API, kindly refer to SAP note 2483157.

      Access to BAPIs is possible using this Virtual Data Model. Direct access and via SOAP web services is not possible.

       

      Thanks

      Marco

      Author's profile photo Sijin Chandran
      Sijin Chandran

      Hi Marco,

      First very thanks for you time and comments.

       Access to BAPIs is possible using this Virtual Data Model.

      So BAPIs are available  there in S4 Hana Cloud ?

      We only have S4 Hana Cloud ( No ECC ERP , No S4 Hana On-Premise),

      Author's profile photo Marco Dahms
      Marco Dahms

      Hi Sijin,

      as mentioned, you can access BAPIs via the presented Virtual Data Model.

      You can find all available APIs in this blog post above.

      If you require access to additional APIs, kindly refer to the mentioned SAP note.

      Thanks

      Marco

       

      Author's profile photo Amit Kulkarni
      Amit Kulkarni

      Hi Alexander and Team,

      I am working on requirement to call below 2 BAPI's via SAP S4Hana Cloud SDK

      BAPI BAPI_SALESORDER_SIMULATE

      BAPI_SALESORDER_CREATEFROMDAT2

      our requirement is to sales order simulation and creation

      Alternative Customer Tax Classification at header level

      and Profit Center at Item level

      for order creation

      we need to have structure for the "billing plan"

      that is at header level

      which is not possible to through ODdata API

      I got the reply from SAP team for incident which we have raised below

       

      unfortunately no sales order BAPIs were enabled to used with cloud SDK.

      But for creating sales orders, there already is the OData API Service API_SALES_ORDER_SRV available, which should describe many of the functionalities the BAPI offered.

      Could you please confirm if there are only specific BAPI's only we can call through SDK.

      Regards,

      Author's profile photo Marco Dahms
      Marco Dahms

      Dear Amit,

      kindly let us know if you're having SAP S/4HANA or SAP S/4HANA Cloud in mind.

      When it comes to SAP S/4HANA Cloud, the BAPI VDM allows to use the classes mentioned in the table under headline "Available VDM classes for BAPI" only.

      When it comes to SAP S/4HANA, the SAP S/4HANA Cloud SDK allows to invoke all exposed BAPIs, either through the BAPI VDM described in this blog or through direct use of BapiQuery.

       

      Kind regards

      Marco

       

      Author's profile photo Amit Kulkarni
      Amit Kulkarni

      Hi Macro,

       

      Thanks for your prompt reply we are using SAP S/4HANA cloud in our case. can't we use BAPI Query in our S/4 Hana Cloud as I can see the libraries

       

      import com.sap.cloud.sdk.s4hana.datamodel.bapi.structures.*;

      import com.sap.cloud.sdk.s4hana.datamodel.bapi.types.*;

      in above code. Also could you please suggest workaround if it is not possible through Hana Cloud SDK.

      Regards,

       

      Author's profile photo Marco Dahms
      Marco Dahms

      Dear Amit,

      as mentioned in my reply above, you can only invoke the BAPIs over our BAPI VDM which are mentioned in the table above.

      Kind regards

      Marco Dahms

      Author's profile photo Amit Kulkarni
      Amit Kulkarni

      Hi Experts,

      Could you please confirm we can call  BAPI_QUOTATION_CREATEFROMDATA2 from S/4 Hana Cloud using S/4 Hana Cloud SK.

      Regards,

      Author's profile photo Marco Dahms
      Marco Dahms

      Hi Amit,

      as per my replies above, we cannot  confirm this, as this BAPI is not listed in the table above.

      Kind regards

      Marco Dahms

      Author's profile photo Henning Heitkoetter
      Henning Heitkoetter

      Change log (July 7, 2018):

      • Clarified that for SAP S/4HANA Cloud, only the explicitly listed BAPIs can be consumed from applications on SAP Cloud Platform via the SAP S/4HANA Cloud SDK

       

       

      Author's profile photo Amit Kulkarni
      Amit Kulkarni

      Hi Experts,

      We are trying to use below sales orders BAPI however it is not mention in above VDM classes . could you please confirm if we can not use these sales orders BAPI's through SDK. I got the feedback from SAP experts that we can only use VDM classes mention in this blog but still I am trying to understand why cannot do BapiQuery for SalesOrder BAPI's below

      if I cannot use SDK to call sales order BAPI's is there any work around using HANA Cloud Connector

       

      Regards,

       

       

      Author's profile photo Marco Dahms
      Marco Dahms

      Dear Amit,

      as already pointed out, as the BAPIs shown in your screenshot are not mentioned in the table above, you cannot invoke them through the SAP S/4HANA Cloud SDK.

      I am not aware of any workaround using the SAP Cloud Connector. The SAP Cloud Connector exists for connecting SAP S/4HANA (i.e., the on-premise version) to an app on SAP Cloud Platform.

       

      Kind regards

      Marco Dahms

      Author's profile photo Martín Rouaux
      Martín Rouaux

      Hey Marco,

      I don’t follow, you are saying that is not possible to invoke other RFC functions from an on-premise S4 Hana ERP backend. Is that correct?  From my understanding there should be a way to use JCO Destinations to call whatever BAPI is needed. How can achieve that? Im following the approach suggested by the following link https://blogs.sap.com/2015/07/13/cloud-connector-a-brief-guide-for-beginners/

      I have to create a Sales Order and also check material availabiility. Any help would be appreciated.

      Author's profile photo Marco Dahms
      Marco Dahms

      Dear Martin,

      with the S/4HANA Cloud SDK you may call every exposed remote-enabled function module, that also includes BAPIs, from SAP S/4HANA (on-premise). You are right, for this purpose you may use JCO destinations.

      What is your particular question and what have you tried so far?

      Kind regards

      Marco Dahms

      Author's profile photo Martín Rouaux
      Martín Rouaux

      Dear Marco,

      Thanks for your quick response. I'm having issues to access JCODestinations, the app throws an Illegal access please check the trace below. I tried with different neo sdk version without success. I also followed some of the sap examples https://github.com/SAP/cloud-s4-sdk-examples/tree/master/Cost-Center-Creation-Neo but all of them have compilation issues or doesnt work properly on neo. Any feedback would be appreciated.

      2018 09 10 20:44:31#+00#ERROR#org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/sap-connector].[resteasy-servlet]##anonymous#http-nio-8041-exec-8#na#p2000242101trial#proxy#web#p2000242101trial#na#na#na#na#Servlet.service() for servlet [resteasy-servlet] in context with path [/sap-connector] threw exception org.jboss.resteasy.spi.UnhandledException: java.lang.IllegalAccessError: tried to access method com.sap.conn.jco.JCoInterface.getDestinationManager()Lcom/sap/conn/jco/JCoDestinationManager; (class loader java.net.URLClassLoader@10015, resolved java.net.URLClassLoader@10015) from class com.sap.conn.jco.JCo (class loader org.apache.catalina.loader.WebappClassLoader@52721)
      at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:78)
      at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:222)
      at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:175)
      at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:418)
      at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:209)
      at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227)
      at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
      at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
      at com.sap.core.communication.server.CertValidatorFilter.doFilter(CertValidatorFilter.java:331)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
      at com.sap.core.jpaas.security.auth.service.lib.AbstractAuthenticator.invoke(AbstractAuthenticator.java:170)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:1025)
      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:1025)
      at com.sap.core.tenant.valve.TenantValidationValve.invokeNextValve(TenantValidationValve.java:182)
      at com.sap.core.tenant.valve.TenantValidationValve.invoke(TenantValidationValve.java:97)
      at com.sap.js.statistics.tomcat.valve.RequestTracingValve.callNextValve(RequestTracingValve.java:101)
      at com.sap.js.statistics.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:57)
      at com.sap.core.js.monitoring.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:27)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
      at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1136)
      at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1775)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1734)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:836)
      Caused by: java.lang.IllegalAccessError: tried to access method com.sap.conn.jco.JCoInterface.getDestinationManager()Lcom/sap/conn/jco/JCoDestinationManager; (class loader java.net.URLClassLoader@10015, resolved java.net.URLClassLoader@10015) from class com.sap.conn.jco.JCo (class loader org.apache.catalina.loader.WebappClassLoader@52721)
      at com.sap.conn.jco.JCo.getDestinationManager(JCo.java:82)
      at com.sap.conn.jco.JCoDestinationManager.getDestination(JCoDestinationManager.java:56)
      at com.unioncrate.sap.rfc.RfcService.productAvailability(RfcService.java:35)
      at com.unioncrate.sap.api.ProductAvailabilityService.runATP(ProductAvailabilityService.java:22)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140)
      at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:294)
      at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:248)
      at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:235)
      at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:402)

       

      Author's profile photo Marco Dahms
      Marco Dahms

      Dear Martin,

      may I ask you to open a question on Stackoverflow using tag s4sdk.

      Kindly provide there more details about your project:

      • Which version of S/4HANA Cloud SDK are you using?
      • You mentioned the Neo SDK. That is something else than the S/4HANA Cloud SDK. So what’s up with that?
      • Kindly share the destination configuration with us.
      • Also kindly post your code where you call the BAPAI.

      Kind regards
      Marco Dahms

      Author's profile photo Martín Rouaux
      Martín Rouaux

      Sure, I will! Thanks again for your time. What I need to do is to run an application on the Neo environment that invoke RFC/BAPI on a S4/Hana 1511 on-premise. Now you said, Im not sure what sdk I should used. Would you please tell me that?

      Is the following a valid example? https://www.sap.com/latinamerica/developer/tutorials/hcp-scc-onpremise-extension-jco-rfc.html

      Author's profile photo Marco Dahms
      Marco Dahms

      Dear Martin,

      you may use the S/4HANA Cloud SDK for that purpose. This blog series tells you all details about application development with that SDK. The Neo SDK is something else.

      The S/4HANA Cloud SDK provides the classes RfcQuery and BapiQuery which you may use to invoke an RFC module or a BAPI.

      The example you refer to above uses the Java Connector (JCo) library which is also used by the S/4HANA Cloud SDK.

      Kind regards

      Marco Dahms