使用 "API_PHYSICAL_INVENTORY_DOC_SRV" 修补库存项目时出错(eTag - CloudSDK)
Error while patching an inventory item with "API_PHYSICAL_INVENTORY_DOC_SRV" (eTag - CloudSDK)
我们希望使用 CloudSDK(版本 1.9.2)在我们的 Java 应用程序中实现库存预订流程。我们正在调用 S4 OnPremise System (1709)。
1.) 我们在使用服务 DefaultPhysicalInventoryDocumentService() 和方法 .createPhysInventoryDocHeader() 时调用创建过程。
=>结果:实物盘点凭证创建。
2.) 创建的盘点单的盘点对象必须进行盘点。为此,我们使用方法 .getPhysInventoryDocItem() 获取相应的项目,设置新值并使用方法 updatePhysInventoryDocItem() 调用更新过程。
=>结果:错误:"The Data Service Request is required to be conditional. Try using the \"If-Match\" header."
我们用 SAP 的 Gateway Client 尝试过一次这个过程。在这里,我们必须使用 GET 过程访问一个实例,以从响应中获取 "eTag" 并能够将其指定为补丁方法中的 "If-Match" 参数。此过程适用于网关客户端。
尽管如此,我们在 Java 应用程序中尝试了相同的过程。不幸的是,我们不会为 Get 请求取回 eTag。根据后端的跟踪,相同的 OData 服务被寻址为网关客户端中的地址。
我们的实现是通过 PostMan 调用的(出于测试目的)。
请求(Header/Body):
响应:
补丁-方法:
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());
}
最新版本的 SAP S/4HANA Cloud SDK (1.10.0) 透明地处理 ETag 作为更新实体的版本标识符。
升级您的项目以使用 1.10.0 版 S/4HANA Cloud SDK 并重试更新远程实体。
正如 Emdee 所提到的,自 SAP S/4HANA Cloud SDK 1.10.0 版本以来,在更新请求期间透明地支持 ETag 处理。
版本 2.0.0 的 SAP S/4HANA Cloud SDK 还允许对所有 OData 请求设置自定义 header。
您可以使用它来为函数导入提供所需的 ETag header,如下所示:
new DefaultPhysicalInventoryDocumentService()
.postDifferences(...)
.withHttpHeader("If-Match", document.getVersionIdentifier())
.execute()
像这样手动设置 header 仅在 OData 函数导入时需要,而不是在更新时需要,在更新时会像上面提到的那样透明处理。
我们希望使用 CloudSDK(版本 1.9.2)在我们的 Java 应用程序中实现库存预订流程。我们正在调用 S4 OnPremise System (1709)。
1.) 我们在使用服务 DefaultPhysicalInventoryDocumentService() 和方法 .createPhysInventoryDocHeader() 时调用创建过程。
=>结果:实物盘点凭证创建。
2.) 创建的盘点单的盘点对象必须进行盘点。为此,我们使用方法 .getPhysInventoryDocItem() 获取相应的项目,设置新值并使用方法 updatePhysInventoryDocItem() 调用更新过程。
=>结果:错误:"The Data Service Request is required to be conditional. Try using the \"If-Match\" header."
我们用 SAP 的 Gateway Client 尝试过一次这个过程。在这里,我们必须使用 GET 过程访问一个实例,以从响应中获取 "eTag" 并能够将其指定为补丁方法中的 "If-Match" 参数。此过程适用于网关客户端。
尽管如此,我们在 Java 应用程序中尝试了相同的过程。不幸的是,我们不会为 Get 请求取回 eTag。根据后端的跟踪,相同的 OData 服务被寻址为网关客户端中的地址。
我们的实现是通过 PostMan 调用的(出于测试目的)。
请求(Header/Body):
响应:
补丁-方法:
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());
}
最新版本的 SAP S/4HANA Cloud SDK (1.10.0) 透明地处理 ETag 作为更新实体的版本标识符。
升级您的项目以使用 1.10.0 版 S/4HANA Cloud SDK 并重试更新远程实体。
正如 Emdee 所提到的,自 SAP S/4HANA Cloud SDK 1.10.0 版本以来,在更新请求期间透明地支持 ETag 处理。
版本 2.0.0 的 SAP S/4HANA Cloud SDK 还允许对所有 OData 请求设置自定义 header。 您可以使用它来为函数导入提供所需的 ETag header,如下所示:
new DefaultPhysicalInventoryDocumentService()
.postDifferences(...)
.withHttpHeader("If-Match", document.getVersionIdentifier())
.execute()
像这样手动设置 header 仅在 OData 函数导入时需要,而不是在更新时需要,在更新时会像上面提到的那样透明处理。