1

we want to realize an inventory booking process in our Java application with the CloudSDK (Version 1.9.2). We are calling S4 OnPremise System (1709).

1.) we call the create process while using the service DefaultPhysicalInventoryDocumentService() with the method .createPhysInventoryDocHeader().

=> Result: Physical inventory document is created.

2.) The physical inventory objects for the created physical inventory document must be counted. For this we get the corresponding item with the method .getPhysInventoryDocItem(), set the new values and call an update procedure with the method updatePhysInventoryDocItem().

=>Result: Error: "The Data Service Request is required to be conditional. Try using the \"If-Match\" header."

We tried this process once with the Gateway Client from SAP. Here we have to access an instance with an GET process to get an "eTag" out of the response and to be able to specify it as an "If-Match" parameter in the patch method. This process works in the Gateway Client.

Nevertheless, we tried the same process with our Java application. Unfortunately, we do not get an eTag back for a Get Request. According to the trace in the back end, the same OData service is addressed as in the gateway client.

Our implementation is called via PostMan (for test purposes).

Request(Header/Body): Request - Header Request - Body

Response: Response

Patch - Method:

public void doPatch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        ErpConfigContext config = new ErpConfigContext("ErpQueryEndpointHTTP");
        ErpEndpoint endpoint = new ErpEndpoint(config);

        String physDoc = request.getParameter("physicalInventoryDocument");

        String responseUpdate = null;
        PhysInventoryDocItem InvItem;

        BigDecimal quantity = new BigDecimal("25.000");

        try {

            DefaultPhysicalInventoryDocumentService invs = new DefaultPhysicalInventoryDocumentService();

            InvItem = invs
                    .getPhysInventoryDocItemByKey("2018", physDoc , "1")
                    .execute(endpoint);

            logger.info(InvItem.toString());


            InvItem.setQuantityInUnitOfEntry(quantity);
            InvItem.setUnitOfEntry("ST");
            InvItem.setFiscalYear("2018");
            InvItem.setPhysicalInventoryItemIsCounted(true);


                ODataUpdateResult patchResult = invs.updatePhysInventoryDocItem(InvItem).execute(endpoint);

                logger.info(patchResult.toString());

                responseUpdate = new Gson().toJson(patchResult);
                response.setStatus(HttpServletResponse.SC_CREATED);


        } catch (Exception e) {
            responseUpdate = e.getMessage();
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            logger.error(e.getMessage(), e);

        }


        response.setContentType("application/json");
        response.getOutputStream().print(responseUpdate);

        logger.error(response.toString());

    }
Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
N.Kryl
  • 185
  • 9
  • 1
    Unfortunately, ETag handling is currently not supported by the virtual data model of the SAP S/4HANA Cloud SDK. Would it be possible to create the item / object already together with the header? – Henning Heitkötter Mar 27 '18 at 16:24
  • Thanks for the quick response. We have already tried that, but unfortunately you can't give the count when creating it. The API throws an error, e.g. something like: "The property Quantity cannot be set in this section." – N.Kryl Mar 28 '18 at 07:10

2 Answers2

1

The latest version of the SAP S/4HANA Cloud SDK (1.10.0) transparently handles the ETag as version identifier for updating entities.

Upgrade your project to use version 1.10.0 of the S/4HANA Cloud SDK and retry to update the remote entity.

Emdee
  • 1,689
  • 5
  • 22
  • 35
  • We can now perform the count process for the physical inventory documents.However, we still have problems with the last step in the inventory posting process.We always get the following error message: "Precondition required". . We tried this with the methods getVersionIdentifier() and setVersionIdentifier() via CloudSDK, but unfortunately without success. We want to "Post Differences at Header Level". Do you have any ideas? Big thanks. – N.Kryl Apr 18 '18 at 16:24
  • PostDifferences is a function import, for which version 1.10.0 of the SAP S/4HANA Cloud SDK does not support ETag handling. – Henning Heitkötter Apr 25 '18 at 18:43
  • @N.Kryl Version 2.0.0 of the SAP S/4HANA Cloud SDK allows to set custom headers on all OData requests. I have added an answer that reflects this. – Henning Heitkötter May 26 '18 at 08:58
1

As mentioned by Emdee, ETag handling is transparently supported during update requests since verion 1.10.0 of the SAP S/4HANA Cloud SDK.

Version 2.0.0 of the SAP S/4HANA Cloud SDK in addition allows to set custom headers on all OData requests. You can use this for supplying the required ETag header also to a function import as follows:

new DefaultPhysicalInventoryDocumentService()
            .postDifferences(...)
            .withHttpHeader("If-Match", document.getVersionIdentifier())
            .execute()

Manually setting the header like this is only required for OData function imports, not for updating, where it is handled transparently as mentioned above.

  • 1
    Since we have updated our Cloud SDK Version to 2.0.0 we have a problem with the process "Count Phyiscal Inventory Document Items". With the Version 1.10.0 this process works fine. With the Version 2.0.0 the properties for the items are not set correctly. Coding is the same as above (Patch-Method) but not all of them manually set properties beeing included in the request. (IWNFD/TRACES). Are they any changes with the handling of this process? In the api documentation we can see that "material" is a mandatory property. We set this one manually as above but its not included in the request. – N.Kryl May 29 '18 at 13:47
  • Since version 1.11.1, only properties with changed values will be sent to the OData service in order to comply with the specification. If a field is mandatory, you can still include it using the `includingFields` method of the update request fluent helper, even if it has not been changed. For example: `invs.updatePhysInventoryDocItem(InvItem).includingFields(PhysInventoryDocItem.MATERIAL, PhysInventoryDocItem.UNIT_OF_ENTRY).execute()` – Henning Heitkötter May 29 '18 at 15:49