Skip to main content

jde-api

The JD Edwards EnterpriseOne Application Interface Services (AIS) Server REST APIs provide services that AIS clients can use to interact with EnterpriseOne applications. JD Edwards calls it REST APIs, but they are not following the REST standard. It is actually a http-based API which mimics the user interactions in the JD Edwards website.

The documentation cam be found on REST API for JD Edwards EnterpriseOne AIS Server

AIS client​

Appshare uses an AIS client with a fluent interface to make interaction with the AIS services easier.

import​

import {jdedwards} from "@appshare/jde-api";

The AIS client features are:

  • All services of AIS are present in this API.
  • The service selects the versioned endpoints based on the AIS server version
  • The client handles network errors
  • The client refreshes the token before expiry
  • Numbers and Dates are converted in the way AIS requires it.
  • The client has request based cache support.
  • UDC support

All interaction with AIS starts by importing and calling the jdedwards() function. The code completion will help when you add the dots after each call.

A basic example to call a service

const { data, error, message } = await jdedwards()
.cache(`W01012B-${category}`)
.form("W01012B")
.returns("1[19,20,40,44]")
.allResults()
.actions()
.value("54", category)
.checkboxOn("63")
.add((builder) => {
if (condition === "true") {
builder.value("add", "add");
}
})
.doFind("15")
.executeToList({
alphaName: "20",
address: "19",
});

if (error) {
return message;
}

return data;

JD Edwards uses IDs for all form elements and controls. These are accessible though the "Help" -> "Item Help" in JD Edwards. To find these IDs more quickly we developed a Chrome extension Steltix JDE Reveal.

Data Service​

Execute queries over EnterpriseOne tables and business views.

See https://docs.oracle.com/en/applications/jd-edwards/cross-product/9.2/rest-api/op-v2-dataservice-post.html

Simple query data request​

This data request will return a list with records matching the condition.

const { data, error, message } = await jdedwards()
.data("F0006")
.query()
.equal("MCU", "businessUnit")
.executeToList();
if (error) {
throw message;
}

return data;

Simple query data request on a view.​

This data request will return a list with records matching the condition.

info

When querying a business view, you must use the table alias in the condition.

const { data, error, message } = await jdedwards()
.data("V0101XPI")
.query()
.equal("F0101.AN8", "addressNumber")
.executeToList({
addressLine: "F0116.ADD1",
});
if (error) {
throw message;
}

return data;

Paged query data request​

This example shows how to fetch data in easily manageable chunks over several successive service calls. For data service calls you must indicate on the first call that you expect to receive next page links, this indication on the request keeps the data set open waiting to receive the next requests. Set the 'enableNextPageProcessing' to true. It is important to note that the size of each data set is determined up front, with the first request to that form/grid. The 'maxPageSize' indicates the chunk size for each call.

let result;
if (nextPageLink == "") {
result = await jdedwards()
.data("V0101XPI")
.maxPageSize("20")
.enableNextPageProcessing(true)
.query()
.equal("AT1", category)
.execute();
} else {
resp = await jdedwards().dataNextPage(nextPageLink, "V0101XPI");
}

const resultList = result.toList();
return {
data: resultList.data,
moreRecords: resultList.summary.moreRecords,
nextPageLink: resp.getLinkNext(),
};

Aggregate data request​

The following shows an example of an aggregation data request.

  const request = await jdedwards()
.data("F4311")
.allResults()
.query()
.stringNotBlank("MCU")
.less("NXTR", "999")
.less("LTTR", "980")
.aggregation()
.countDistinct("MCU")
.orderByAggregation("MCU", "COUNT_DISTINCT", "DESC")
.orderByColumn("MCU", "ASC")
.groupBy("MCU");

const rawResult = await request.execute();

if (rawResult.isAggregationSuccess()) {
const dataResult = rawResult.getAggregation();
...
}

Form Service​

Request to execute an EnterpriseOne form. Optionally, perform actions on the form and receive data from the form in the response.

See https://docs.oracle.com/en/applications/jd-edwards/cross-product/9.2/rest-api/op-v2-formservice-post.html

Get Control values outside the grid use the executeToObject method.​

  const { data, error, message } = await jdedwards()
.form("W01012B")
.singleResult() // to get a single record
.actions()
.qbe("1[19]", addressNumber) // qbe on grid id 1 field id 19
.doFind("15"); // do find action with action id 15
.executeToObject({
fieldName1: "123", // map field id 123 to fieldName1
fieldName2: "3", // map field id 3 to fieldName2
});

if (error) {
throw message;
}
return data; `{ fieldName1: "value", fieldName2: "value" }`

Get Grid and Control values use the execute method​

const result = await jdedwards()
.form("W01012B")
.returns("123|1[19,123]") // * The returnControlIDs string is bar delimited, without a starting or ending bar. Form fields are just a single value. Grid fields are indicated with a grid id, followed by a bracketed list of grid columns. Subform fields are indicated with subform id underscore field id. @example 33|34|17[24,26,28]|50_45|50_53|50_9[35,39,41]
.actions()
.qbe("1[19]", addressNumber) // qbe on grid id 1 field id 19
.doFind("15") // do find action with action id 15
.executeV2();

if (error) {
throw message;
}

const { data, error, message } = result.toList({
fieldName1: "123",
fieldName2: "456",
});
if (error) {
throw message;
}

// data is now [{ fieldName1: "value", fieldName2: "value" }, ...] from the grid.

const headerValue = result.toObject({
fieldName1: "123",
fieldName2: "456",
}).data;

// headerValue is now { fieldName1: "value", fieldName2: "value" } from the header.

Form with conditional actions​

  const { data, error, message } = await jdedwards()
.form("W01012B")
.actions()
.add((builder) => {
if (condition === "true") {
builder.value("add", "add");
}
})
.doFind();
.executeToList();


if (error) {
throw message;
}
return data;


Form with update​

  const { data, error, message } = await jdedwards()
.form("W01012B")
.returns(["123", "456"])
.singleResult()
.actions()
.value("field1_123", "value")
.boolean("field1_123", true)
.number("field1_123", 123.45)
.date("field1_123", new Date("01 Jan 2020 00:00:00 GMT"))
.checkboxOn("field1_123")
.combo("field1_123", "combo")
.radio("field1_123")
.doOk();
.executeToList();

if (error) {
throw message;
}
return data;

Form with grid update​

const { data, error, message } = await jdedwards()
.form("W01012B")
.returns("1[19,20,40,44]")
.allResults()
.actions()
.grid("1") // grid id
.insertRow()
.cell("18", "promotion")
.cell("19", "requestDate")
.cell("23", "quantity")
.updateRow(1) // Update the first row
.cell("18", "promotion")
.cell("19", "requestDate")
.cell("23", "quantity")
.end()
.end()
.doOk()
.executeToList();

Form with Delete​

const { error, message } = await jdedwards()
.form("W01012B")
.singleResult()
.actions()
.qbe("1[19]", addressNumber)
.value("54", "*")
.doFind("15")
.selectFirstRow()
.doDelete("61")
.executeToList();

if (error) {
throw message;
}

Using query()​

The query() method allows you to build complex search conditions for forms. It supports various operators and can be combined with logical operators like and(), and or(), to create sophisticated filtering.

Logical Operators:​

  • and()...end() - All conditions must be true
  • or()...end() - At least one condition must be true

Basic Query Example:​

const { data, error, message } = await jdedwards()
.form("W01012B")
.query()
.equal("54", category)
.stringContain("1[19]", searchText)
.actions()
.doFind("15")
.executeToList({
name: "20",
address: "19",
});

Complex Query with Multiple Conditions:​

const { data, error, message } = await jdedwards()
.form("W01012B")
.query()
.and()
.stringNotBlank("1[19]")
.greater("1[25]", 100)
.end()
.or()
.equal("54", "ACTIVE")
.equal("54", "PENDING")
.end()
.actions()
.doFind("15")
.executeToList();

Application Stack Service (appstack)​

Execute stateful calls to applications including flows from one form to another.

See https://docs.oracle.com/en/applications/jd-edwards/cross-product/9.2/rest-api/op-v2-appstack-post.html

Multiple forms in one call​

const appstack = jdedwards().appstack();
appstack
.start("W01012B")
.returns("1[19,20,40,44]")
.allResults()
.actions()
.add((builder) => {
if (condition === "true") {
builder.value("add", "add");
}
})
.value("54", "category");
appstack
.next("W01012B")
.returns("1[19,20,40,44]")
.actions()
.value("54", "category");
appstack
.next("W01012B")
.returns("1[19,20,40,44]")
.actions()
.value("54", "category");
const result = await appstack.executeToList();

Multiple forms with client side decision​

appstack
.start("W01012B")
.showActionControls(true)
.aliasNaming(false)
.useWarnings(true)
.returns("1[19,20,40,44]")
.allResults()
.actions()
.value("54", "category");
appstack
.next("W01012B")
.showActionControls(true)
.aliasNaming(false)
.useWarnings(true)
.returns("1[19,20,40,44]")
.actions()
.value("54", "category");
const result = await appstack.execute();

// Do some logic on the result and continue the appstack

appstack
.continue("W01012B", result)
.returns("1[19,20,40,44]")
.actions()
.value("54", "category");
appstack
.next("W01012B")
.returns("1[19,20,40,44]")
.actions()
.value("54", "category");
const resultContinued = await appstack.execute();

Business Function Service​

Execute an EnterpriseOne Business Function.

See https://docs.oracle.com/en/applications/jd-edwards/cross-product/9.2/rest-api/op-v2-bsfnservice-post.html

const result = await jdedwards()
.businessFunction("FormatLocation")
.input(1, branch)
.input(2, location)
.input(15, "2")
.outputIds([3])
.execute();

return result.getStringValue(3);

message Service​

Sends an EnterpriseOne message (PPAT) to external email systems or the EnterpriseOne Work Center email system.

See https://docs.oracle.com/en/applications/jd-edwards/cross-product/9.2/rest-api/op-v2-message-post.html

const result = await jdedwards()
.message("subject", "messageText")
.toEmail("to-1@example.com")
.execute();

orchestrator Service​

Execute an EnterpriseOne Orchestration

See https://docs.oracle.com/en/applications/jd-edwards/cross-product/9.2/rest-api/op-orchestrator-orchestration-post.html

const result = await jdedwards()
.orchestrator("orchestration")
.inputs([{ name: "10", value: "inputArray" }])
.input("1", "inoutValue")
.body({ "custom:": "value" })
.execute();

discover Orchestrations​

const response = await jdedwards().discover().execute();
return response?.orchestrations;

Processing Option Service​

Enables the caller to get the processing option values for an application and version.

See https://docs.oracle.com/en/applications/jd-edwards/cross-product/9.2/rest-api/op-v2-poservice-post.html

const result = await jdedwards()
.processingOption("application", "version")
.execute();

udomanager Service​

Request details of Watchlist or query user defined objects (UDOs).

See https://docs.oracle.com/en/applications/jd-edwards/cross-product/9.2/rest-api/op-v2-udomanager-operation-post.html

Simple request​

return await jdedwards().udomanager().execute();

All Queries request​

return await jdedwards().udomanager().allQueries().execute();

All Watchlists request​

return await jdedwards().udomanager().allWatchlists().execute();

Watchlist request​

return await jdedwards().udomanager().watchlist("ube").execute();

query request​

return await jdedwards().udomanager().query("q").execute();

watchlist Service​

Execute the specified Watchlist. The response includes record count as well as Watchlist definition metadata.

See https://docs.oracle.com/en/applications/jd-edwards/cross-product/9.2/rest-api/op-v2-watchlist-post.html

return await jdedwards().watchlist("watchlist").execute();

report Service​

Execute the specified report.

See https://docs.oracle.com/en/applications/jd-edwards/cross-product/9.2/rest-api/op-v2-report-execute-post.html

const report = jdedwards()
.report("R55HMRLBN")
.version(getParameterValue("R55HMRLBL_H1"))
.dataSelection()
.criterion()
.subject("V46L10A", "LPNU", "F46L10")
.operator("AND")
.compare("VALUE_IN_LIST", "LIST")
.in(printLPNUList);

return await report.execute();

reportStatus Service​

Use the batch job number to get the completion status of the report.

See https://docs.oracle.com/en/applications/jd-edwards/cross-product/9.2/rest-api/op-v2-report-status-post.html

return await jdedwards().reportStatus("jobNumber").execute();

Attachments​

Get the text attachments​

export async function getTextAttachments({
structure = "",
keys = [],
form = "",
preserveHtml = false,
}) {
try {
return await jdedwards()
.attachment(structure, keys, form)
.text()
.list(preserveHtml);
} catch (error) {
return [];
}
}

Update text attachments​

export async function updateTextAttachment({
structure = "",
keys = [],
form = "",
itemName = "",
text = "",
sequence = -1,
}) {
try {
await jdedwards()
.attachment(structure, keys, form)
.text()
.sequence(sequence)
.itemName(itemName)
.update(text);
return true;
} catch (error) {
return false;
}
}

insert text attachment​

export async function insertTextAttachment({
structure = "",
keys = [],
form = "",
itemName = "",
text = "",
}) {
const returnObject = {
error: true,
message: translate("Error inserting text attachment"),
sequence: -1,
};
try {
const response = await jdedwards()
.attachment(structure, keys, form)
.text()
.itemName(itemName)
.insert(text);
if (response.hasOwnProperty("sequence")) {
returnObject.error = false;
returnObject.message = "";
returnObject.sequence = response.sequence;
}
return returnObject;
} catch (error) {
return returnObject;
}
}

delete attachment​

export async function deleteAttachment({
structure = "",
keys = [],
form = "",
sequence = -1,
}) {
try {
await jdedwards().attachment(structure, keys, form).delete(sequence);
return true;
} catch (error) {
return false;
}
}

Get the file attachments​

export async function getFileAttachments({
structure = "",
keys = [],
form = "",
includeData = false,
thumbnailSize = undefined,
cache = false,
}) {
try {
const jde = cache
? jdedwards().cache(`${structure}-${keys.join("-")}-${form}`)
: jdedwards();
return await jde.attachment(structure, keys, form).file().list({
includeUrls: true,
includeData,
thumbnailSize,
});
} catch (error) {
return [];
}
}

Update file attachment​

export async function uploadFileAttachment({
structure = "",
keys = [],
form = "",
image = null,
itemName = "",
}) {
const returnObject = {
error: true,
message: translate("Error uploading file attachment"),
sequence: -1,
uniquefilename: "",
itemName: "",
};
try {
const response = await jdedwards()
.attachment(structure, keys, form)
.file()
.itemName(itemName)
.upload(image);
if (response.hasOwnProperty("sequence")) {
returnObject.error = false;
returnObject.message = "";
returnObject.sequence = response.sequence;
returnObject.uniquefilename = response.uniquefilename;
returnObject.itemName = response.itemName;
}
return returnObject;
} catch (error) {
return returnObject;
}
}

download file attachment​

export async function downloadFileAttachment({
structure = "",
keys = [],
form = "",
sequence = -1,
returnBlob = false,
}) {
try {
return await jdedwards()
.attachment(structure, keys, form)
.file()
.sequence(sequence)
.download(returnBlob);
} catch (error) {
return null;
}
}