jde-api
- AIS client
- Data Service
- Form Service
- Application Stack Service (appstack)
- Business Function Service
- message Service
- orchestrator Service
- Processing Option Service
- udomanager Service
- watchlist Service
- report Service
- Attachments
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.
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.
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.
Form with search
const {data,error,message} = await jdedwards()
.form("W01012B")
.input("id", "value")
.bypassFormServiceEREvent(false)
.maxPageSize(250)
.version("version")
.formServiceDemo("true")
.showActionControls(true)
.stopOnWarning(true)
.actions()
.qbe("qbe", "qbe")
.qbeBoolean("boolean", true)
.qbeBoolean("booleanString", "true")
.qbeNumber("number", 123.45)
.qbeDate("date", new Date("01 Jan 2020 00:00:00 GMT"))
.doFind();
.executeToList({
fieldName1: "fieldID1",
fieldName2: "fieldID2",
});
// server will return fieldID1 and fieldID2 in response.
if (error) {
throw message;
}
return data;
executeToList will return a list of records from the grid. you can use singleResult() before the actions() to get a single record back. you can use maxPageSize(size) to limit the number of records returned. by default it will return all records.
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;
}
Application Stack Service (appstack)
Execute stateful calls to applications including flows from one form to another.
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.
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.
const result = await jdedwards()
.message("subject", "messageText")
.toEmail("to-1@example.com")
.execute();
orchestrator Service
Execute an EnterpriseOne Orchestration
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.
const result = await jdedwards()
.processingOption("application", "version")
.execute();
udomanager Service
Request details of Watchlist or query user defined objects (UDOs).
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.
return await jdedwards().watchlist("watchlist").execute();
report Service
Execute the specified report.
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.
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;
}
}