Use REST API with Order Management Extensions
Apply these guidelines when your extension calls REST API.
Create Connector
-
Go to Home > My Enterprise > Setup and Maintenance > Manage External Interface Web Service Details.
You must use this task.
-
Set these values:
Attribute
Value
Connector Name
QUERYPARAM
Connector URL
https://host:port/fscmRestApi/resources/latest/itemsV2
User Name
Enter the user name that you use to access REST API.
Password
Enter the password that you use to access REST API.
Invocation Mode
Synchronous Service
Send Attachments No Response Processing Option Use the default value. For details, see Manage Connector Details Between Order Management and Your Fulfillment System.
-
Use the invokeRestService method in your extension to call REST API.
For details and examples, go to REST API for Oracle Supply Chain Management Cloud, expand Order Management, then click Sales Orders for Order Hub.
Use invokeRestService to Call REST API
Order Management will automatically select the correct version according to the arguments that you send in your extension.
JSON Object
Use this format when you script a JSON object:
invokeRestService(String integrationName,
String restResourcePath,
JSONObject jsonObj,
String method,
Map<String, String> headers,
Map<String, Object> queryParams,
Map<String, Object> pathParams);
For example:
def response = context.invokeRestService("ItemsV2", "", null, "GET", headers, queryParams, pathParams);
def response = context.invokeRestService("InventoryReservations", "", jsonObject, "POST", headers, queryParams, pathParams);
JSON Array
Use this format when you script a JSON array:
invokeRestService(String integrationName,
String restResourcePath,
JSONArray jsonArray,
String method,
Map<String, String> headers,
Map<String, Object> queryParams,
Map<String, Object> pathParams) ;
For example:
def response = context.invokeRestService("RestPatchConnector", "", jsonArrayObject, "PATCH", headers, queryParams, pathParams);
REST Request
You can use these parameters in invokeRestService's request:
| Position | Parameter | Type | Description |
|---|---|---|---|
| 1 | ConnectorName | String | Name of the connector, such as QUERYPARAM. |
| 2 | restResourcePath | String | Placeholder. Use an empty string: "". You must include this value for the connector, but the extension's logic ignores is. |
| 3 | JsonObj | JSON Object |
Include your JSON's object payload for the request. If you don't need a payload, then leave it empty. For example, for a GET request. |
| 3 | JsonArray | JSON Array | Include your JSON's array payload for the request. |
| 4 | Operation | String |
Specify one of these HTTP methods:
|
| 5 | Headers | Map string, string | Include a value pair for the HTTP header. |
| 6 | QueryParams | Map string, object | Specify your URL query parameters that you want to append to the URL. For example, status=ACTIVE. |
| 7 | PathParams | Map string, object |
Specify a variable that you want to use to replace a part of the URL path. For example:
|
REST Response
Use these methods in invokeRestService's response to extract data and implement logic:
| Method | Type | Description |
|---|---|---|
| getStatus() | String | Result of the call. Contains SUCCESS or ERROR. |
| getResponseStatusCode() | Integer |
Standard HTTP status code. For example, 200 for OK, 201 for Created, or 400 for Bad Request. |
| getPayload() | JSON Object | Contains the JSON object that you sent in REST request. |
| getPayloadArray() | JSON Array | Contains the JSON array that you sent in REST request. |
| getResponse() | String | Contains the response payload when the status is SUCCESS. |
| getErrorMessage() | String | Contains the response payload when the status is ERROR. |
Get Example
This example uses a connector named ItemsV2 to get item details, and then writes the response into the Shipping Instructions attribute. It uses this connector URL:
https://host:port/fscmRestApi/resources/latest/itemsV2
The extension script uses seven parameters in invokeRestService, and it uses null values in the GET payload.
It creates this URL at run time:
https://host:port/fscmRestApi/resources/latest/itemsV2?
q=ItemNumber=AS54888;OrganizationCode=V1&onlyData=true&fields=ItemNumber,ItemDescription
Here's the extension's script:
import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException
import org.json.simple.JSONObject;
// 1. Filter the condition:
def poNumber = header.getAttribute("CustomerPONumber");
if (poNumber == null || poNumber != "ItemsV2") return;
String connectorName = "ItemsV2";
// 2. Specify the query parameters:
// Matches: ?q=ItemNumber=AS54888;OrganizationCode=V1&onlyData=true&fields=ItemNumber,ItemDescription
Map<String, Object> queryParams = new HashMap<>();
queryParams.put("q", "ItemNumber=AS54888;OrganizationCode=V1");
queryParams.put("onlyData", "true");
queryParams.put("fields", "ItemNumber,ItemDescription");
//Map string, object pathParams = new HashMap<>();
//pathParams.put("itemsV2UniqID", "00040000000EACED0005770800005B0A5D2711C80000000EACED000577");
//Assumes you want to use this connector url: https://host:port/fscmRestApi/resources/latest/itemsV2/{itemsV2UniqID}/child/ItemDFF
// 3. Use a GET request. Parameter 3 is empty for a GET:
def response = context.invokeRestService(connectorName, "", null, "GET", null, queryParams, null);
// 4. Process the result:
def status = response.getStatus();
def data = "Response Status : " + status + ", Response Status Code : " + response.getResponseStatusCode() + ". ";
if ("SUCCESS".equals(status)) {
def resp = response.getResponse(); // Access the response payload
// See whether the "items" in the array contain data:
if (resp.get("items") != null && resp.get("items").length > 0) {
// Extract data from the first item in the array
def itemRow = resp.get("items")[0];
def itemInfo = itemRow.get("ItemNumber") + "-" + itemRow.get("ItemDescription");
data = data + itemInfo;
} else {
data = data + "Could not fetch item information using connector " + connectorName + " with query parameters " + queryParams;
}
} else { // ERROR
// Capture error details:
data = data + " ErrorMessage : " + response.getErrorMessage() + " Response : " + response.getResponse();
}
// 5. Update Order Header
header.setAttribute("ShippingInstructions", data);
POST Example
This example uses a connector named InventoryReservations to create an inventory reservation. It uses this connector URL:
https://host:port/fscmRestApi/resources/latest/inventoryReservations/
The extension script uses seven parameters in invokeRestService, and it includes a JSON payload values in the POST request.
It creates this URL at run time:
https://host:port/fscmRestApi/resources/latest/itemsV2?
q=ItemNumber=AS54888;OrganizationCode=V1&onlyData=true&fields=ItemNumber,ItemDescription
Here's the extension's script:
import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException
import org.json.simple.JSONObject;
import org.json.simple.JSONArray;
// 1. Filter the condition:
def poNumber = header.getAttribute("CustomerPONumber");
if (poNumber != "InventoryReservations") return;
//Map string, object pathParams = new HashMap<>();
//Map string, object queryParams = new HashMap<>();
Map<String, String> headers = new HashMap<>();
headers.put("REST-Framework-Version", "4");
// 2. Create the JSON Object's request payload:
JSONObject jObj = new JSONObject();
jObj.put("OrganizationId", 204);
jObj.put("ItemNumber", "AS54888");
jObj.put("ReservationQuantity", 10000000);
jObj.put("ReservationUOMCode", "Ea");
jObj.put("SupplySourceType", "On Hand");
jObj.put("DemandSourceType", "User Defined");
jObj.put("DemandSourceName", "27210");
// 3. Send a POST request:
def response = context.invokeRestService("InventoryReservations", "", jObj, "POST", headers, null, null);
// As an option, you can read all the attributes from the response:
List<Message> msgs = new ArrayList<Message>();
msgs.add(new Message( Message.MessageType.WARNING, "Input Payload : " + response.getPayload() ));
msgs.add(new Message( Message.MessageType.WARNING, "Input Payload Array : " + response.getPayloadArray() ));
msgs.add(new Message( Message.MessageType.WARNING, "Response Status : " + response.getStatus() ));
msgs.add(new Message( Message.MessageType.WARNING, "Response Status Code : " + response.getResponseStatusCode() ));
msgs.add(new Message( Message.MessageType.WARNING, "Error Message : " + response.getErrorMessage() ));
msgs.add(new Message( Message.MessageType.WARNING, "Success Message : " + response.getResponse() ));
// 4. Evaluate the response:
def statusCode = response.getResponseStatusCode();
if (statusCode == 200 || statusCode == 201) {
// Success. Get the specific ID from the response:
def successMessage = response.getResponse();
msgs.add(new Message(Message.MessageType.WARNING, "Reservation done successfully with ReservationID : " + successMessage.get("ReservationId")));
} else {
// Error. Parse the error details from the service:
def errorMessage = response.getErrorMessage();
msgs.add(new Message(Message.MessageType.ERROR, "Error Message - " + errorMessage));
if ( errorMessage != null && errorMessage.trim().startsWith("{")) {
JSONParser parser = new JSONParser();
JSONObject root = (JSONObject) parser.parse(errorMessage);
// Use errorDetails to navigate through the error structure.
// The structure and the node names depend on what's in the REST response:
JSONArray errorDetails = (JSONArray) root.get("o:errorDetails");
if (errorDetails != null && !errorDetails.isEmpty()) {
JSONObject errorInfo = (JSONObject) errorDetails.get(0);
def errorCode = errorInfo.get("o:errorCode");
def detail = errorInfo.get("detail");
msgs.add(new Message(Message.MessageType.ERROR, "ErrorCode - " + errorCode + ". ErrorDetail - " + detail));
}
}
}
// 5. Send the collected messages to the caller:
if(!msgs.isEmpty()) throw new ValidationException(msgs);