5Performing AIS Form Service Calls

Understanding JD Edwards EnterpriseOne Mobile Framework APIs

The JD Edwards EnterpriseOne Mobile Framework APIs provide Java classes and methods that enable users to call REST services on the AIS Server. There are APIs that handle login authentication and authorization with the AIS Server, APIs for form service requests and media objects, as well as APIs for retrieving processing option values.

The JD Edwards EnterpriseOne Mobile Framework APIs have a dependency on Oracle MAF. They do not function outside of an Oracle MAF environment.

See the Prerequisites section in this guide for information on how to obtain the APIs. A description of the APIs is available in the JD Edwards EnterpriseOne Mobile Framework Java API Reference Javadoc located at:

http://docs.oracle.com/cd/E53430_01/EOTMP/index.html

With EnterpriseOne Tools release 9.2.1.2, the JD Edwards EnterpriseOne Mobile Framework Java API Reference was updated with classes that enable mobile applications to request EnterpriseOne Watchlist data.

Understanding AIS Server Capabilities

The AIS Server exposes various capabilities that client applications may or may not depend on. If your mobile application requires a certain capability, you must include it in the list of required capabilities in the about.properties file.

If you indicated in the about.properties file that you have a required capability, the Login Module verifies that capability is available when the mobile application launches. If the capability is not available, the application returns an error message. If the capability is available, the application continues to the login screen.

You can access the AIS Server capabilities using the following URL:

http://<AIS Server>:<Port>/jderest/defaultconfig

You can also find a complete list of AIS Server capabilities in the "AIS Server Capabilities and Services" section in the JD Edwards EnterpriseOne Application Interface Services Server Reference Guide.

The following example shows the grid and editable capabilities listed in the about.properties:

This image is described in the surrounding text.

Overview

AIS Server calls that retrieve data from forms in the EnterpriseOne web client are referred to as form service requests. Mobile applications use form service requests to interact with EnterpriseOne web client forms. Form service requests, formatted as REST service calls that use POST, contain form service events or commands that invoke actions on an EnterpriseOne form.

A form service request enables you to perform various operations on a single form. By sending an ordered list of commands, a form service request can replicate the actions taken by an EnterpriseOne web client user, including populating fields, pressing buttons, and other actions.

To send a form service request to the AIS Server, send a POST to the following URL and send JSON in the body:

http://<AIS Server>:<Port>/formservice

If testing with a REST testing tool, you can send JSON directly. If using the JDE Mobile Helpers in a mobile application, you need to specify only the URI when calling the jdeRestServiceCall. The URI is "formservice" and you can use the static variable, for example:

JDERestServiceProvider.FORM_SERVICE_URI

Events Used in a Form Service Request

The following table lists the events that you can include in a form service request and describes the action that each event performs.

Event

Description

Parameters (and example values)

Set Control value

Sets the value of a control on a form, like filter fields or any other form control.

controlID ("25")

value ("Bob" or "01/01/2015")

Set QBE Value

Sets the value of a QBE column.

controlID ("1[42]" or "1_2[25]")

value ("Jill" or "55")

Set Checkbox Value

Sets the value of a check box.

controlID ("77")

value ("on" or "off")

Set Radio Button

Sets the value of the radio button.

controllID ("87")

value ("87")

Set Combo Value

Sets the value of a combo box entry.

contolID ("125")

value (2) - Index of the entry.

Do Action

Presses a button or Hyper Item.

controlID ("156")

Select Row

Selects the specified row in a grid.

controlID ("1.30") - ID of the grid, dot (.), row index (zero based).

Select All Rows*

Select all rows in the specified grid (if multiple selection is allowed).

controlID ("1") - ID of the grid.

Un Select All Rows*

Deselects all rows in the specified grid (if multiple selection is allowed).

controlID ("1") - ID of the grid.

Un Select Row*

Deselects the specified row in a grid.

controlID ("1.30") - ID of the grid, dot (.), row index (zero based).

Click Grid Cell**

Clicks the hyperlink in a grid cell if the cell is enabled as a link.

controlID ("1.5.22") - ID of the grid, dot (.), row index, dot (.), grid column ID.

*These events are available only with the selectAllGridRows capability. The JDEMobileFramework API requires these events to be in a try block because they throw a Capability Exception.

**This event is available only with the gridCellClick capability.

Using the Form Service Request Event in FDA

The Form Service Request event is available within FDA for each form. This event occurs after the Post Dialog Initialized event, but before any of the form actions requested in the form service call execute. This event enables you to perform some operations, or business logic, when you know the form that is being called from a form service request.

This event also provides access to the requested form service actions, referred to as CRUD (Create, Read, Update, or Delete) actions, by using the "Get Form Service Request Action" system function. This enables you to create additional logic based on the value sent in the form service request.

Using the Form Service Request event in FDA should be secondary to using events (actions) provided in the Form Service Request from the mobile application. Oracle recommends that you only use the FDA event if you cannot accomplish a desired result with the form action events.

Placing Events in the Proper Order

Place the events in the form service request in the order you want them to execute, for example, populate a filter field value and then press the Find button. Remember that the FDA Form Service Request event occurs before the events you add to this list. Do not set the "Find On Entry" option when using the event model; the extra "find" is not necessary because it executes before the events you requested.

Considering Hidden Filters and Hidden QBE

By default, values are not written to hidden filter fields or hidden QBE columns. You must use the Form Service Request event to show the fields and columns first. Then values can be written to these fields and subsequently applied to the query.

Events on Power Forms

The Form Service Request event and other events that perform actions in a form are also available on power forms so that you can populate a subform value or press a button on a subform.

Control ID Notation for Return Control IDs

You can use the Property Browser in FDA to identify control IDs for fields on each EnterpriseOne form. You can also find control IDs using the Item Help option in the form in the EnterpriseOne web client. In the EnterpriseOne web client form, click the Help button (question mark in the upper right corner of a form) and then click the Item Help option to access field-level help. With the field level help activated, you can click in a field or column to access the control ID and business view information, which is displayed under the Advanced Options section.

For fields on the main form, the control ID will be a single value, such as 25.

Grids also have control IDs. For a traditional form, the grid ID is usually 1. For power forms, subforms, and reusable subforms the grid ID is typically a value other than 1.

The columns within a grid also have unique IDs and are often referenced in conjunction with the grid ID. For example column 28 and 29 in grid 1 would be 1[28,29].

Power forms have more complex IDs. The fields on the main power form are represented with single values. The fields on a subform are complex with an underscore separating them. So field 6 on subform 12 is 12_6. The ID of a re-usable subform is available when viewing the power form that the subform is used on. The IDs of individual fields, a grid, or columns on a re-usable subform is shown in FDA when viewing the subform directly; you cannot get these values when viewing the subform alias.

The returnControlIDs string is bar delimited, without a starting or ending bar.

Example - Requesting fields and grid columns on a traditional form.

formRequest.setReturnControlIDs("19|20|60|125|1[45,49,88]");

In this example, 19|20|60|125 represent field control IDs.

1[45,49,88] represents columns in the grid.

Example - Requesting main form fields, subform fields, main form grid columns, and subform grid columns.

formRequest.setReturnControlIDs("33|34|17[24,26,28]|50_45|50_53|50_9[35,39,41]");

In this example, 33|34 represent fields on the main form.

50_45|50_53 represent fields on the subform.

17[24,26,28] represent main form grid columns.

50_9[35,39,41] represent subform grid columns.

Example of JSON Code in a Form Service Request

The sample code in Example - Executing EnterpriseOne Actions - JSON is an example of JSON code in a form service request that executes EnterpriseOne actions in the following order:

  1. Open the Find/Browse form in P01012.

  2. Enter a value in a QBE field.

  3. Enter a value in a field control.

  4. Select two check boxes.

  5. Click the Find button.

Example - Executing EnterpriseOne Actions - JSON

 {
    "token": "044BlLYkCUcjQGRxvR3r+LH27liC6l6psFHOTp9whmkPxE=MDE4MDA2MTYxMDIwOTQ1MDU2NTc0NDY0U29hcFVJMTM4NDQ0NjU2NTUwNQ==",
    "version": "ZJDE0001",
    "formActions": [
        {
 
            "command": "SetQBEValue",
            "value": "E",
            "controlID": "1[50]"
        },
        {
            "command": "SetControlValue",
            "value": "Al*",
            "controlID": "58"
        },
        {
            "command": "SetCheckboxValue",
            "value": "on",
            "controlID": "62"
        },
        {
            "command": "SetCheckboxValue",
            "value": "on",
            "controlID": "63"
        },
        {
            "command": "DoAction",
            "controlID": "15"
        }
    ],
    "deviceName": "REST Service Testing Tool",
    "formName": "P01012_W01012B"
}

Example - Executing EnterpriseOne Actions - JSON Response

{
    "fs_P01012_W01012B": {
        "title": "Work With Addresses",
        "data": {
            "lblSearchType_53": {
                "id": 53,
                "editable": false,
                "value": "Search Type",
                "title": "Search Type",
                "dataType": 2
            },
            "txtSearchType_54": {
                "id": 54,
                "editable": true,
                "value": "*",
                "internalValue": "null",
                "title": "Search Type",
                "assocDesc": "",
                "staticText": "Search Type",
                "dataType": 2
            },
            "lblAlphaName_57": {
                "id": 57,
                "editable": false,
                "value": "Alpha Name",
                "title": "Alpha Name",
                "dataType": 2
            },
            "txtAlphaName_58": {
                "id": 58,
                "editable": true,
                "value": "Allen*",
                "internalValue": "Allen*",
                "title": "Alpha Name",
                "staticText": "Alpha Name",
                "dataType": 2
            },
            "lblDL01_66": {
                "id": 66,
                "editable": false,
                "value": "",
                "title": "",
                "dataType": 2
            },
            "chkDisplayAddress_63": {
                "id": 63,
                "editable": true,
                "value": "on",
                "internalValue": "1",
                "title": "Display Address",
                "dataType": 1
            },
            "chkDisplayPhone_62": {
                "id": 62,
                "editable": true,
                "value": "on",
                "internalValue": "1",
                "title": "Display Phone",
                "dataType": 1
            },
            "gridData": {
                "titles": {
                    "col_19": "Address Number",
                    "col_20": "Alpha Name",
                    "col_40": "Address Line 1",
                    "col_44": "City",
                    "col_81": "Prefix",
                    "col_46": "Phone Number",
                    "col_47": "Phone Type",
                    "col_48": "Long Address",
                    "col_49": "Industry Class",
                    "col_50": "Sch Typ",
                    "col_51": "Tax ID"
                },
                "rowset": [
                    {
                        "rowIndex": 0,
                        "MOExist": false,
                        "mnAddressNumber_19": {
                            "id": 19,
                            "editable": false,
                            "value": "576",
                            "internalValue": 576,
                            "title": "Address Number",
                            "dataType": 9
                        },
                        "sAlphaName_20": {
                            "id": 20,
                            "editable": false,
                            "value": "Allen",
                            "internalValue": "Allen",
                            "title": "Alpha Name",
                            "dataType": 2
                        },
                        "sAddressLine1_40": {
                            "id": 40,
                            "editable": false,
                            "value": " ",
                            "internalValue": " ",
                            "title": "Address Line 1",
                            "dataType": 2
                        },
                        "sCity_44": {
                            "id": 44,
                            "editable": false,
                            "value": " ",
                            "internalValue": " ",
                            "title": "City",
                            "dataType": 2
                        },
                        "sPrefix_81": {
                            "id": 81,
                            "editable": false,
                            "value": "",
                            "internalValue": "",
                            "title": "Prefix",
                            "dataType": 2
                        },
                        "sPhoneNumber_46": {
                            "id": 46,
                            "editable": false,
                            "value": "",
                            "internalValue": "",
                            "title": "Phone Number",
                            "dataType": 2
                        },
                        "sPhoneType_47": {
                            "id": 47,
                            "editable": false,
                            "value": "",
                            "internalValue": "",
                            "title": "Phone Type",
                            "dataType": 2
                        },
                        "sLongAddress_48": {
                            "id": 48,
                            "editable": false,
                            "value": " ",
                            "internalValue": " ",
                            "title": "Long Address",
                            "dataType": 2
                        },
                        "sIndustryClass_49": {
                            "id": 49,
                            "editable": false,
                            "value": " ",
                            "internalValue": " ",
                            "title": "Industry Class",
                            "dataType": 2
                        },
                        "sSchTyp_50": {
                            "id": 50,
                            "editable": false,
                            "value": "E",
                            "internalValue": "E",
                            "title": "Sch Typ",
                            "dataType": 2
                        },
                        "sTaxID_51": {
                            "id": 51,
                            "editable": false,
                            "value": " ",
                            "internalValue": " ",
                            "title": "Tax ID",
                            "dataType": 2
                        }
                    }
                ],
                "summary": {
                    "records": 1,
                    "moreRecords": false
                }
            }
        },
        "errors": [],
        "warnings": []
    },
    "stackId": 2,
    "stateId": 1,
    "rid": "f199d7dd4210b9af",
    "currentApp": "P01012_W01012B_ZJDE0001",
    "sysErrors": []
}

Example of API Methods for a Form Service Request

Oracle provides API methods that you can use to set the commands when coding mobile applications.

Important: When setting a date field value, use the form field or QBE Date methods that use the java.util.Date for input. These methods format the date value into the proper format for data entry in EnterpriseOne.

Example - API Methods for Setting Commands

        FormRequest formRequest = new FormRequest();
        
        formRequest.setFormName("P01012_W01012B");
        formRequest.setVersion("ZJDE0001");
 
 
	//create event holder
        FSREvent myFSREvent = new FSREvent();
 
        
        //add actions in order
        myFSREvent.setQBEValue("1[50]", searchType);
        myFSREvent.setFieldValue("58", name);        
        myFSREvent.checkBoxChecked ("62");
        myFSREvent.checkBoxChecked ("63");                      
        myFSREvent.doControlAction("15");
 
	 //add event holder to the form request
        formRequest.addFSREvent(myFSREvent);
 
 
        // Execute SEND and RECEIVE operation
        try {
 
            JSONObject jsonObject = (JSONObject)JSONBeanSerializationHelper.toJSON(formRequest);
            String postData = jsonObject.toString();
 
            String response = JDERestServiceProvider.jdeRestServiceCall(postData, JDERestServiceProvider.POST, JDERestServiceProvider.FORM_SERVICE_URI);
 
            P01012_W01012B_FormParent newFormParent =
                ((P01012_W01012B_FormParent)JSONBeanSerializationHelper.fromJSON(P01012_W01012B_FormParent.class,
                                                                                 response));
}

Grid Action Events

In addition to interacting with fields on the form, you can interact with grids using grid action events. If you use a grid action event, you must include "grid" as a required capability in the about.properties. See Understanding AIS Server Capabilities for more information.

The types of grid action events include:

  • Selecting grid rows

    This action enables you to delete records in the grid by sending a row select event, followed by a delete button press event, and then finally an OK button press event. This is the exact sequence that a user would follow to delete a record in an EnterpriseOne application.

  • Inserting grid rows

    This action enables you to insert one or more rows into a grid, setting the column value for each row. This includes text entry columns, drop-down columns, or check box columns. You must include an OK button pressed event to commit the inserts.

  • Updating grid rows

    This action enables you to update one or more existing grid rows by setting the column values for each row. This includes text entry columns, drop-down columns, or check box columns. You must include an OK button pressed event to commit the updates.

The following table describes the commands that you can use in grid column events to set values for a cell in a grid insert or update event:

Grid Column Event

Description

Parameters

Set Grid Cell Value

Sets the value of a cell in a grid.

"value": "720",

"command": "SetGridCellValue",

"columnID": "28"

Set Grid Combo Value

Sets the value of a drop-down column in a grid. The value that you send is in the "Code" for the UDC associated with the column.

"value": "ABC"

"command": "SetGridComboValue",

"columnID": "43"

Example of Grid Action Events

This section provides examples of grid action events in both JSON and Oracle MAF code.

The sample code in Example - Selecting Grid Rows - JSON is an example of JSON that deletes a phone number in the third row of a grid. It is important to note:

  • The row index is zero based.

  • You must get the row index based on a previous fetch (since rows may be hidden and the index may not be consecutive).

  • By sending 3 form actions, first select row 3, then selecting the Delete button, and then selecting the OK button.

  • The form inputs will get the correct set of phone records for address number 6001, who's who line 0.

  • The formServiceAction code is a U for update, so the form is in update mode.

Example - Selecting Grid Rows - JSON
{
    "token": "0443HC90ZH4pq9CScdvJ+nkecflSJI9q+YGbc7lXrGZ7So=MDE5MDA2ODQ4MjcyMDk2MTUwMjg0NDkyOFNvYXBVSTEzOTIwNzE5NzY4NzE=",
     
    "formActions": [
        
           {
            "command": "SelectRow",
            "controlID": "1.3"
        }  
        ,
        {
            "command": "DoAction",
            "controlID": "59"
        },
        {
            "command": "DoAction",
            "controlID": "4"
        }
    ],
    "formInputs": [
        {
            "value": "6001",
            "id": "4"
        },
        {
            "value": "0",
            "id": "5"
        }
    ],
    
    "formServiceAction": "U",
    "deviceName": "RESTclient",
    "formName": "P0115_W0115A"
}
Example - Selecting Grid Rows - JSON Response
{
    "fs_P0115_W0115A": {
        "title": "Phone Numbers",
        "data": {
            "lblDL01_71": {
                "id": 71,
                "editable": false,
                "value": "Ray Allen",
                "title": "Ray Allen",
                "dataType": 2
            },
            "lblWhosWhoLine_52": {
                "id": 52,
                "editable": false,
                "value": "Who's Who Line",
                "title": "Who's Who Line",
                "dataType": 2
            },
            "txtAddressNumber_7": {
                "id": 7,
                "editable": false,
                "value": "6001",
                "internalValue": 6001,
                "title": "Address Number",
                "assocDesc": "Allen, Ray",
                "staticText": "Address Number",
                "dataType": 9
            },
            "lblDL01_54": {
                "id": 54,
                "editable": false,
                "value": "Allen, Ray",
                "title": "Allen, Ray",
                "dataType": 2
            },
            "gridData": {
                "titles": {
                    "col_28": "Prefix",
                    "col_29": "Phone Number",
                    "col_27": "Phone Type",
                    "col_66": "Phone Type Description",
                    "col_26": "Line Number"
                },
                "rowset": [
                    {
                        "rowIndex": 0,
                        "MOExist": false,
                        "sPrefix_28": {
                            "id": 28,
                            "editable": true,
                            "value": "303",
                            "internalValue": "303",
                            "title": "Prefix",
                            "dataType": 2
                        },
                        "sPhoneNumber_29": {
                            "id": 29,
                            "editable": true,
                            "value": "334-4000",
                            "internalValue": "334-4000",
                            "title": "Phone Number",
                            "dataType": 2
                        },
                        "sPhoneType_27": {
                            "id": 27,
                            "editable": true,
                            "value": "HOM",
                            "internalValue": "HOM",
                            "title": "Phone Type",
                            "dataType": 2
                        },
                        "sPhoneTypeDescription_66": {
                            "id": 66,
                            "editable": false,
                            "value": "Home",
                            "internalValue": "Home",
                            "title": "Phone Type Description",
                            "dataType": 2
                        },
                        "mnLineNumber_26": {
                            "id": 26,
                            "editable": false,
                            "value": "1",
                            "internalValue": 1,
                            "title": "Line Number",
                            "dataType": 9
                        }
                    },
                    {
                        "rowIndex": 1,
                        "MOExist": false,
                        "sPrefix_28": {
                            "id": 28,
                            "editable": true,
                            "value": "303",
                            "internalValue": "303",
                            "title": "Prefix",
                            "dataType": 2
                        },
                        "sPhoneNumber_29": {
                            "id": 29,
                            "editable": true,
                            "value": "555-1212",
                            "internalValue": "555-1212",
                            "title": "Phone Number",
                            "dataType": 2
                        },
                        "sPhoneType_27": {
                            "id": 27,
                            "editable": true,
                            "value": "CAR",
                            "internalValue": "CAR",
                            "title": "Phone Type",
                            "dataType": 2
                        },
                        "sPhoneTypeDescription_66": {
                            "id": 66,
                            "editable": false,
                            "value": "Car or Mobile",
                            "internalValue": "Car or Mobile",
                            "title": "Phone Type Description",
                            "dataType": 2
                        },
                        "mnLineNumber_26": {
                            "id": 26,
                            "editable": false,
                            "value": "2",
                            "internalValue": 2,
                            "title": "Line Number",
                            "dataType": 9
                        }
                    }
                ],
                "summary": {
                    "records": 2,
                    "moreRecords": false
                }
            },
            "lblAddressNumber_6": {
                "id": 6,
                "editable": false,
                "value": "Address Number",
                "title": "Address Number",
                "dataType": 9
            },
            "txtWhosWhoLine_32": {
                "id": 32,
                "editable": false,
                "value": "0",
                "internalValue": 0,
                "title": "Who&#39;s Who Line",
                "assocDesc": "Ray Allen",
                "dataType": 9a
            }
        },
        "errors": [],
        "warnings": []
    },
    "stackId": 5,
    "stateId": 1,
    "rid": "c2a9c1c93a6874f0",
    "currentApp": "P0115_W0115A",
    "sysErrors": []
}
Example - Selecting Grid Rows - MAF Application Code

This sample code performs the same delete operation as the JSON request example in the preceding section; it deletes a single phone number in a grid of phone numbers.

public void deletePhone(int key) {
 
        AdfmfJavaUtilities.setELValue("#{pageFlowScope.errors}", "false");
        FormRequest formRequest = new FormRequest();
 
        formRequest.setFormName("P0115_W0115A");
        formRequest.setFormServiceAction("U");
 
        formRequest.addToFISet("4", addressNumber);
        formRequest.addToFISet("5", "0");
 
        FSREvent fsrEvent = new FSREvent();
 
        //get currently selected row
        P0115_W0115A_GridRow selectedRow = getSelectedPhonebyKey(key);
        
        fsrEvent.selectRow("1", selectedRow.getRowIndex());
 
        //press Delete button
        fsrEvent.doControlAction("59");
 
 
        //press OK button
        fsrEvent.doControlAction("4");
 
        //add the FSR event to the request
        formRequest.addFSREvent(fsrEvent);
 
 
        // Execute SEND and RECEIVE operation
        try {
            // For POST request, set data payload is header delimited with | and service input class
 
            JSONObject jsonObject = (JSONObject)JSONBeanSerializationHelper.toJSON(formRequest);
            String postData = jsonObject.toString();
 
            String response = JDERestServiceProvider.jdeRestServiceCall(postData, JDERestServiceProvider.POST, JDERestServiceProvider.FORM_SERVICE_URI); 
            P0115_W0115A_FormParent tempFormParent =
                ((P0115_W0115A_FormParent)JSONBeanSerializationHelper.fromJSON(P0115_W0115A_FormParent.class,
                                                                               response));
            
            if(tempFormParent.getFs_P0115_W0115A().getErrors() != null && tempFormParent.getFs_P0115_W0115A().getErrors().length>0){
                
                AdfmfJavaUtilities.setELValue("#{pageFlowScope.errors}", "true");                
            }else{
 
 
            p0115_W0115A_FormParent.getFs_P0115_W0115A().getData().getGridData().setRowsetList
            (tempFormParent.getFs_P0115_W0115A().getData().getGridData().retrieveRowsetList());
            p0115_W0115A_FormParent.getFs_P0115_W0115A().getData().getGridData().setSummary
            (tempFormParent.getFs_P0115_W0115A().getData().getGridData().getSummary());
 
            }
 
 
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            AdfException adfe = new AdfException(e.getMessage(), AdfException.ERROR);
            throw adfe;
        }
 
 
    }
Example - Insert Rows - JSON

This sample code is an example of adding two phone numbers with two form actions: a grid action that adds two rows followed by an OK button selection. The form inputs will get the correct set of phone records for address number 6001, who's who line 0. Also, it is important to note that the formServiceAction code is a U for update, which indicates that the form is in update mode.

{"token": "044bO2/lCT8FViW5A0Sm5GqcqU3P8BB2kwUv0bZzG84YYU=MDE4MDA2NTIyNTk1NjQyNTc1MjQ2MzM2U29hcFVJMTM5MjE0OTA4MjYyMA==",
      "formInputs": [
        {
            "value": "6001",
            "id": "4"
        },
        {
            "value": "0",
            "id": "5"
        }
    ],
    "formServiceAction": "U",        
      
    "formActions": [
        {
            "gridAction": 
                {
                    "gridID": "1",
                    "gridRowInsertEvents": [
                        {                            
                            "gridColumnEvents": [
                                {
                                    "value": "720",
                                    "command": "SetGridCellValue",
                                    "columnID": "28"
                                },
                                {
                                    "value": "331-4014",
                                    "command": "SetGridCellValue",
                                    "columnID": "29"
                                },
                                {
                                    "value": "CAR",
                                    "command": "SetGridCellValue",
                                    "columnID": "27"
                                }
                            ]
                        },
                        {
                            
                            "gridColumnEvents": [
                                {
                                    "value": "303",
                                    "command": "SetGridCellValue",
                                    "columnID": "28"
                                },
                                {
                                    "value": "421-1010",
                                    "command": "SetGridCellValue",
                                    "columnID": "29"
                                },
                                {
                                    "value": "HOM",
                                    "command": "SetGridCellValue",
                                    "columnID": "27"
                                }
                            ]
                        }
                    ]
                }            
        },
        {
         
            "command": "DoAction",
            "controlID": "4"
        }
        
    ],
    "deviceName": "RESTclient",
    "formName": "P0115_W0115A"
}
Example - Insert Rows - JSON Response
{
   "fs_P0115_W0115A":    {
      "title": "Phone Numbers",
      "data":       {
         "lblDL01_71":          {
            "id": 71,
            "editable": false,
            "value": "Ray Allen",
            "title": "Ray Allen",
            "dataType": 2
         },
         "lblWhosWhoLine_52":          {
            "id": 52,
            "editable": false,
            "value": "Who's Who Line",
            "title": "Who's Who Line",
            "dataType": 2
         },
         "txtAddressNumber_7":          {
            "id": 7,
            "editable": false,
            "value": "6001",
            "internalValue": 6001,
            "title": "Address Number",
            "assocDesc": "Allen, Ray",
            "staticText": "Address Number",
            "dataType": 9
         },
         "lblDL01_54":          {
            "id": 54,
            "editable": false,
            "value": "Allen, Ray",
            "title": "Allen, Ray",
            "dataType": 2
         },
         "gridData":          {
            "titles":             {
               "col_28": "Prefix",
               "col_29": "Phone Number",
               "col_27": "Phone Type",
               "col_66": "Phone Type Description",
               "col_26": "Line Number"
            },
            "rowset":             [
                              {
                  "rowIndex": 0,
                  "MOExist": false,
                  "sPrefix_28":                   {
                     "id": 28,
                     "editable": true,
                     "value": "303",
                     "internalValue": "303",
                     "title": "Prefix",
                     "dataType": 2
                  },
                  "sPhoneNumber_29":                   {
                     "id": 29,
                     "editable": true,
                     "value": "334-4000",
                     "internalValue": "334-4000",
                     "title": "Phone Number",
                     "dataType": 2
                  },
                  "sPhoneType_27":                   {
                     "id": 27,
                     "editable": true,
                     "value": "HOM",
                     "internalValue": "HOM",
                     "title": "Phone Type",
                     "dataType": 2
                  },
                  "sPhoneTypeDescription_66":                   {
                     "id": 66,
                     "editable": false,
                     "value": "Home",
                     "internalValue": "Home",
                     "title": "Phone Type Description",
                     "dataType": 2
                  },
                  "mnLineNumber_26":                   {
                     "id": 26,
                     "editable": false,
                     "value": "1",
                     "internalValue": 1,
                     "title": "Line Number",
                     "dataType": 9
                  }
               },
                              {
                  "rowIndex": 1,
                  "MOExist": false,
                  "sPrefix_28":                   {
                     "id": 28,
                     "editable": true,
                     "value": "303",
                     "internalValue": "303",
                     "title": "Prefix",
                     "dataType": 2
                  },
                  "sPhoneNumber_29":                   {
                     "id": 29,
                     "editable": true,
                     "value": "555-1212",
                     "internalValue": "555-1212",
                     "title": "Phone Number",
                     "dataType": 2
                  },
                  "sPhoneType_27":                   {
                     "id": 27,
                     "editable": true,
                     "value": "CAR",
                     "internalValue": "CAR",
                     "title": "Phone Type",
                     "dataType": 2
                  },
                  "sPhoneTypeDescription_66":                   {
                     "id": 66,
                     "editable": false,
                     "value": "Car or Mobile",
                     "internalValue": "Car or Mobile",
                     "title": "Phone Type Description",
                     "dataType": 2
                  },
                  "mnLineNumber_26":                   {
                     "id": 26,
                     "editable": false,
                     "value": "2",
                     "internalValue": 2,
                     "title": "Line Number",
                     "dataType": 9
                  }
               },
                              {
                  "rowIndex": 2,
                  "MOExist": false,
                  "sPrefix_28":                   {
                     "id": 28,
                     "editable": true,
                     "value": "720",
                     "internalValue": "720",
                     "title": "Prefix",
                     "dataType": 2
                  },
                  "sPhoneNumber_29":                   {
                     "id": 29,
                     "editable": true,
                     "value": "331-4014",
                     "internalValue": "331-4014",
                     "title": "Phone Number",
                     "dataType": 2
                  },
                  "sPhoneType_27":                   {
                     "id": 27,
                     "editable": true,
                     "value": "CAR",
                     "internalValue": "CAR",
                     "title": "Phone Type",
                     "dataType": 2
                  },
                  "sPhoneTypeDescription_66":                   {
                     "id": 66,
                     "editable": false,
                     "value": "Car or Mobile",
                     "internalValue": "Car or Mobile",
                     "title": "Phone Type Description",
                     "dataType": 2
                  },
                  "mnLineNumber_26":                   {
                     "id": 26,
                     "editable": false,
                     "value": "3",
                     "internalValue": 3,
                     "title": "Line Number",
                     "dataType": 9
                  }
               },
                              {
                  "rowIndex": 3,
                  "MOExist": false,
                  "sPrefix_28":                   {
                     "id": 28,
                     "editable": true,
                     "value": "303",
                     "internalValue": "303",
                     "title": "Prefix",
                     "dataType": 2
                  },
                  "sPhoneNumber_29":                   {
                     "id": 29,
                     "editable": true,
                     "value": "421-1010",
                     "internalValue": "421-1010",
                     "title": "Phone Number",
                     "dataType": 2
                  },
                  "sPhoneType_27":                   {
                     "id": 27,
                     "editable": true,
                     "value": "HOM",
                     "internalValue": "HOM",
                     "title": "Phone Type",
                     "dataType": 2
                  },
                  "sPhoneTypeDescription_66":                   {
                     "id": 66,
                     "editable": false,
                     "value": "Home",
                     "internalValue": "Home",
                     "title": "Phone Type Description",
                     "dataType": 2
                  },
                  "mnLineNumber_26":                   {
                     "id": 26,
                     "editable": false,
                     "value": "4",
                     "internalValue": 4,
                     "title": "Line Number",
                     "dataType": 9
                  }
               }
            ],
            "summary":             {
               "records": 4,
               "moreRecords": false
            }
         },
         "lblAddressNumber_6":          {
            "id": 6,
            "editable": false,
            "value": "Address Number",
            "title": "Address Number",
            "dataType": 9
         },
         "txtWhosWhoLine_32":          {
            "id": 32,
            "editable": false,
            "value": "0",
            "internalValue": 0,
            "title": "Who&#39;s Who Line",
            "assocDesc": "Ray Allen",
            "dataType": 9
         }
      },
      "errors": [],
      "warnings": []
   },
   "stackId": 1,
   "stateId": 1,
   "rid": "b7ebc0f0832cfbb",
   "currentApp": "P0115_W0115A",
   "sysErrors": []
}
Example - Insert Rows - MAF Application Code

This sample code is an example of adding one new phone number using grid actions.

Important: Your mobile application should allow adding records only when the record count is below the maximum. You can determine this by checking the moreRecords field in the grid summary when you fetch existing records. You will not receive an error message if you attempt to add a record beyond the maximum allowed. The record will simply not be added.

public void addPhone() {
        
        AdfmfJavaUtilities.setELValue("#{pageFlowScope.errors}", "false");
 
        FormRequest formRequest = new FormRequest();
        
 
        formRequest.setFormName("P0115_W0115A");
        formRequest.setFormServiceAction("U");
 
        formRequest.addToFISet("4", addressNumber);
        formRequest.addToFISet("5", "0");
 
        FSREvent fsrEvent = new FSREvent();
        GridAction gridAction = new GridAction();
 
        GridRowInsertEvent gri = new GridRowInsertEvent();
 
        
        //set the column values
        gri.setGridColumnValue("27", addPhoneType);
        gri.setGridColumnValue("28", addPhonePrefix);
        gri.setGridColumnValue("29", addPhoneNumber);
 
        //add the row
        gridAction.insertGridRow("1", gri);
 
        //add the grid action to the events
        fsrEvent.addGridAction(gridAction);
 
        //press OK button
        fsrEvent.doControlAction("4");
 
        //add the FSR event to the request
        formRequest.addFSREvent(fsrEvent);
 
 
        // Execute SEND and RECEIVE operation
        try {
            // For POST request, set data payload is header delimited with | and service input class
 
            JSONObject jsonObject = (JSONObject)JSONBeanSerializationHelper.toJSON(formRequest);
            String postData = jsonObject.toString();
 
            String response = JDERestServiceProvider.jdeRestServiceCall(postData, JDERestServiceProvider.POST, JDERestServiceProvider.FORM_SERVICE_URI); 
            P0115_W0115A_FormParent tempFormParent =
                ((P0115_W0115A_FormParent)JSONBeanSerializationHelper.fromJSON(P0115_W0115A_FormParent.class,
                                                                               response));
            
            if(tempFormParent.getFs_P0115_W0115A().getErrors() != null && tempFormParent.getFs_P0115_W0115A().getErrors().length>0){
                
                AdfmfJavaUtilities.setELValue("#{pageFlowScope.errors}", "true");
            }else{
 
            p0115_W0115A_FormParent.getFs_P0115_W0115A().getData().getGridData().setRowsetList
            (tempFormParent.getFs_P0115_W0115A().getData().getGridData().retrieveRowsetList());
            p0115_W0115A_FormParent.getFs_P0115_W0115A().getData().getGridData().setSummary
            (tempFormParent.getFs_P0115_W0115A().getData().getGridData().getSummary());
 
            AdfmfJavaUtilities.setELValue("#{pageFlowScope.addready}", "true");
 
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            AdfException adfe = new AdfException(e.getMessage(), AdfException.ERROR);
            throw adfe;
        }
 
 
    } 
Example - Update Rows - JSON

This sample code is an example of updating two phone numbers. You must specify the index of the row you want to update. The row index is included in the information returned when you query the grid. Therefore, you must perform a query before you update a row. In this example, the JSON code updates rows 2 and 4 and sets values in each of the three columns for these rows.

This sample code also includes syntax that shows a column that contains a drop-down selection. The value should be the 'code' value, not the description.

"gridColumnEvents": [
  {
        "value": "30",
        "command": "SetGridComboValue",
        "columnID": "43"
   }
]

This sample code shows the phones update request:

{"token": "044t+mf8cq2gxqvAlH1SziE9EnBfs5QYNlj3ZQpmFAW9tc=MDE5MDA2ODQ0NjQ4MjI5OTYxODQ5MjQxNlNvYXBVSTEzOTIwNzI3MjAzMTM=",
      "formInputs": [
        {
            "value": "6001",
            "id": "4"
        },
        {
            "value": "0",
            "id": "5"
        }
    ],
    "formActions": [
        {
            "gridAction": 
                {
                    "gridID": "1",
                    "gridRowUpdateEvents": [
                        {
                            "rowNumber": 2,
                            "gridColumnEvents": [
                                {
                                    "value": "720",
                                    "command": "SetGridCellValue",
                                    "columnID": "28"
                                },
                                {
                                    "value": "111-1111",
                                    "command": "SetGridCellValue",
                                    "columnID": "29"
                                },
                                {
                                    "value": "CAR",
                                    "command": "SetGridCellValue",
                                    "columnID": "27"
                                }
                            ]
                        },
                        {
                            "rowNumber": 4,
                            "gridColumnEvents": [
                                {
                                    "value": "303",
                                    "command": "SetGridCellValue",
                                    "columnID": "28"
                                },
                                {
                                    "value": "22233333",
                                    "command": "SetGridCellValue",
                                    "columnID": "29"
                                },
                                {
                                    "value": "CAR",
                                    "command": "SetGridCellValue",
                                    "columnID": "27"
                                }
                            ]
                        }
                    ]
                }            
        },
        {
         
            "command": "DoAction",
            "controlID": "4"
        }
        
    ],
    "deviceName": "RESTclient",
    "formName": "P0115_W0115A"
}
Example - Update Rows - JSON Response
{
   "fs_P0115_W0115A":    {
      "title": "Phone Numbers",
      "data":       {
         "lblDL01_71":          {
            "id": 71,
            "editable": false,
            "value": "Ray Allen",
            "title": "Ray Allen",
            "dataType": 2
         },
         "lblWhosWhoLine_52":          {
            "id": 52,
            "editable": false,
            "value": "Who's Who Line",
            "title": "Who's Who Line",
            "dataType": 2
         },
         "txtAddressNumber_7":          {
            "id": 7,
            "editable": false,
            "value": "6001",
            "internalValue": 6001,
            "title": "Address Number",
            "assocDesc": "Allen, Ray",
            "staticText": "Address Number",
            "dataType": 9
         },
         "lblDL01_54":          {
            "id": 54,
            "editable": false,
            "value": "Allen, Ray",
            "title": "Allen, Ray",
            "dataType": 2
         },
         "gridData":          {
            "titles":             {
               "col_28": "Prefix",
               "col_29": "Phone Number",
               "col_27": "Phone Type",
               "col_66": "Phone Type Description",
               "col_26": "Line Number"
            },
            "rowset":             [
                              {
                  "rowIndex": 0,
                  "MOExist": false,
                  "sPrefix_28":                   {
                     "id": 28,
                     "editable": true,
                     "value": "303",
                     "internalValue": "303",
                     "title": "Prefix",
                     "dataType": 2
                  },
                  "sPhoneNumber_29":                   {
                     "id": 29,
                     "editable": true,
                     "value": "334-4000",
                     "internalValue": "334-4000",
                     "title": "Phone Number",
                     "dataType": 2
                  },
                  "sPhoneType_27":                   {
                     "id": 27,
                     "editable": true,
                     "value": "HOM",
                     "internalValue": "HOM",
                     "title": "Phone Type",
                     "dataType": 2
                  },
                  "sPhoneTypeDescription_66":                   {
                     "id": 66,
                     "editable": false,
                     "value": "Home",
                     "internalValue": "Home",
                     "title": "Phone Type Description",
                     "dataType": 2
                  },
                  "mnLineNumber_26":                   {
                     "id": 26,
                     "editable": false,
                     "value": "1",
                     "internalValue": 1,
                     "title": "Line Number",
                     "dataType": 9
                  }
               },
                              {
                  "rowIndex": 1,
                  "MOExist": false,
                  "sPrefix_28":                   {
                     "id": 28,
                     "editable": true,
                     "value": "303",
                     "internalValue": "303",
                     "title": "Prefix",
                     "dataType": 2
                  },
                  "sPhoneNumber_29":                   {
                     "id": 29,
                     "editable": true,
                     "value": "555-1212",
                     "internalValue": "555-1212",
                     "title": "Phone Number",
                     "dataType": 2
                  },
                  "sPhoneType_27":                   {
                     "id": 27,
                     "editable": true,
                     "value": "CAR",
                     "internalValue": "CAR",
                     "title": "Phone Type",
                     "dataType": 2
                  },
                  "sPhoneTypeDescription_66":                   {
                     "id": 66,
                     "editable": false,
                     "value": "Car or Mobile",
                     "internalValue": "Car or Mobile",
                     "title": "Phone Type Description",
                     "dataType": 2
                  },
                  "mnLineNumber_26":                   {
                     "id": 26,
                     "editable": false,
                     "value": "2",
                     "internalValue": 2,
                     "title": "Line Number",
                     "dataType": 9
                  }
               },
                              {
                  "rowIndex": 2,
                  "MOExist": false,
                  "sPrefix_28":                   {
                     "id": 28,
                     "editable": true,
                     "value": "720",
                     "internalValue": "720",
                     "title": "Prefix",
                     "dataType": 2
                  },
                  "sPhoneNumber_29":                   {
                     "id": 29,
                     "editable": true,
                     "value": "111-1111",
                     "internalValue": "111-1111",
                     "title": "Phone Number",
                     "dataType": 2
                  },
                  "sPhoneType_27":                   {
                     "id": 27,
                     "editable": true,
                     "value": "CAR",
                     "internalValue": "CAR",
                     "title": "Phone Type",
                     "dataType": 2
                  },
                  "sPhoneTypeDescription_66":                   {
                     "id": 66,
                     "editable": false,
                     "value": "Car or Mobile",
                     "internalValue": "Car or Mobile",
                     "title": "Phone Type Description",
                     "dataType": 2
                  },
                  "mnLineNumber_26":                   {
                     "id": 26,
                     "editable": false,
                     "value": "3",
                     "internalValue": 3,
                     "title": "Line Number",
                     "dataType": 9
                  }
               },
                              {
                  "rowIndex": 3,
                  "MOExist": false,
                  "sPrefix_28":                   {
                     "id": 28,
                     "editable": true,
                     "value": "303",
                     "internalValue": "303",
                     "title": "Prefix",
                     "dataType": 2
                  },
                  "sPhoneNumber_29":                   {
                     "id": 29,
                     "editable": true,
                     "value": "22233333",
                     "internalValue": "22233333",
                     "title": "Phone Number",
                     "dataType": 2
                  },
                  "sPhoneType_27":                   {
                     "id": 27,
                     "editable": true,
                     "value": "CAR",
                     "internalValue": "CAR",
                     "title": "Phone Type",
                     "dataType": 2
                  },
                  "sPhoneTypeDescription_66":                   {
                     "id": 66,
                     "editable": false,
                     "value": "Car or Mobile",
                     "internalValue": "Car or Mobile",
                     "title": "Phone Type Description",
                     "dataType": 2
                  },
                  "mnLineNumber_26":                   {
                     "id": 26,
                     "editable": false,
                     "value": "4",
                     "internalValue": 4,
                     "title": "Line Number",
                     "dataType": 9
                  }
               }
            ],
            "summary":             {
               "records": 4,
               "moreRecords": false
            }
         },
         "lblAddressNumber_6":          {
            "id": 6,
            "editable": false,
            "value": "Address Number",
            "title": "Address Number",
            "dataType": 9
         },
         "txtWhosWhoLine_32":          {
            "id": 32,
            "editable": false,
            "value": "0",
            "internalValue": 0,
            "title": "Who&#39;s Who Line",
            "assocDesc": "Ray Allen",
            "dataType": 9
         }
      },
      "errors": [],
      "warnings": []
   },
   "stackId": 2,
   "stateId": 1,
   "rid": "b7ebc0f0832cfbb",
   "currentApp": "P0115_W0115A",
   "sysErrors": []
}
Example - Update Rows - MAF Application Code

This sample code is an example of updating a single phone row from an MAF application.

public void updatePhone(int key) {
        
        AdfmfJavaUtilities.setELValue("#{pageFlowScope.errors}", "false");
 
        FormRequest formRequest = new FormRequest();
 
 
        formRequest.setFormName("P0115_W0115A");
        formRequest.setFormServiceAction("U");
 
        formRequest.addToFISet("4", addressNumber);
        formRequest.addToFISet("5", "0");
 
        FSREvent fsrEvent = new FSREvent();
        GridAction gridAction = new GridAction();
 
        GridRowUpdateEvent gru = new GridRowUpdateEvent();
 
        //get currently selected row
        P0115_W0115A_GridRow selectedRow = getSelectedPhonebyKey(key);
        
        //set the column values        
        gru.setGridColumnValue("27", selectedRow.getSPhoneType_27().getValue());
        gru.setGridColumnValue("28", selectedRow.getSPrefix_28().getValue());
        gru.setGridColumnValue("29", selectedRow.getSPhoneNumber_29().getValue());
 
        
        //update the row based on it's index - zero based
        gridAction.updateGridRow("1",
                                 selectedRow.getRowIndex(),
                                 gru);
 
        //add the grid action to the events
        fsrEvent.addGridAction(gridAction);
 
        //press OK button
        fsrEvent.doControlAction("4");
 
        //add the FSR event to the request
        formRequest.addFSREvent(fsrEvent);
 
 
        // Execute SEND and RECEIVE operation
        try {
            // For POST request, set data payload is header delimited with | and service input class
 
            JSONObject jsonObject = (JSONObject)JSONBeanSerializationHelper.toJSON(formRequest);
            String postData = jsonObject.toString();
 
            String response = JDERestServiceProvider.jdeRestServiceCall(postData, JDERestServiceProvider.POST, JDERestServiceProvider.FORM_SERVICE_URI); 
            P0115_W0115A_FormParent tempFormParent =
                ((P0115_W0115A_FormParent)JSONBeanSerializationHelper.fromJSON(P0115_W0115A_FormParent.class,
                                                                               response));
 
            if(tempFormParent.getFs_P0115_W0115A().getErrors() != null && tempFormParent.getFs_P0115_W0115A().getErrors().length>0){
                
                AdfmfJavaUtilities.setELValue("#{pageFlowScope.errors}", "true");
                
            }else{
 
            p0115_W0115A_FormParent.getFs_P0115_W0115A().getData().getGridData().setRowsetList
            (tempFormParent.getFs_P0115_W0115A().getData().getGridData().retrieveRowsetList());
            p0115_W0115A_FormParent.getFs_P0115_W0115A().getData().getGridData().setSummary
            (tempFormParent.getFs_P0115_W0115A().getData().getGridData().getSummary());
 
            }
 
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            AdfException adfe = new AdfException(e.getMessage(), AdfException.ERROR);
            throw adfe;
        }
 
 
    }

Query Events

You can configure a form service request to send ad hoc queries to EnterpriseOne web client application forms that support the query control.

To add a query, you include a single query object in the form service request. A query object includes parameters that contain the same query criteria that you would use to set up a query in EnterpriseOne. The parameters determine:

  • How the query runs. You can configure query option parameters to load grid records in the form or clear all other fields in the form before the query runs. You can also specify whether the results of the query should match all (AND) or any (OR) of the conditions specified in the query.

  • The conditions of the query. The query object includes condition parameters that specify the control ID of the columns or fields that you want to query and an operator for filtering results that are equal to, greater than, or less than a particular value.

    Important: Queries will work only if the field or columns identified in the query are part of the business view.
  • The value used for the search criteria in the query. The query object includes value parameters that specify the value or range of values that you want displayed in the query results.

Before you add a query object to a form service request, access the form in the EnterpriseOne web client and use the query control to gather the criteria for the query object parameters. For more information about setting up a query, see "Understanding the Query Control" in the JD Edwards EnterpriseOne Tools Foundation Guide.

Also, in the EnterpriseOne form, you need to identify the control ID of the field or column that you want to query, and verify that the field or column is part of the business view. To do so, click the Help button (question mark in the upper right corner of a form) and then click the Item Help option to access field-level help. With the field level help activated, you can click in a field or column to access the control ID and business view information, which is displayed under the Advanced Options section as shown in Example - Example of Control ID and Business View Information Displayed under Advanced Options in the EnterpriseOne Web Client Item Help.

Example - Example of Control ID and Business View Information Displayed under Advanced Options in the EnterpriseOne Web Client Item Help

This image is described in the surrounding text.

In the Item Help, the syntax of the control ID is 1.20 with 1 representing the grid ID and 20 representing the column ID, which are separated by a dot (.). In the parameter for the query request, the same control ID must be presented with the following syntax: 1[20]. See the Table 2 for more information.

Query Object Parameters

The following tables describe the parameters for a query object.

Table Query Option Parameters

Parameter

Description

Values

autoFind

Directs the query to automatically press Find on the form to populate the grid records. You do not need to include events to press the Find button if you use autoFind.

true, false

matchType

Determines if you want the query to search for records that match all (AND) or any (OR) of the specified conditions.

MATCH_ALL, MATCH_ANY

autoClear

Do you want to clear all other fields on the form (for example default filter fields).

true, false

Table Query Condition Parameters

Parameter

Description

Value

controlId

The control ID that the condition applies to. This is the field that you add to the query from the form when using the web client to create a Query. It is either a filter field or a grid column that is associated with the business view.

Example of control IDs:

"28", "1[34]"

operator

The comparison operation to use with the query.

For all types, valid values are:

BETWEEN, LIST, EQUAL, NOT_EQUAL, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL

For strings, valid values are:

STR_START_WITH, STR_END_WITH, STR_CONTAIN, STR_BLANK, STR_NOT_BLANK

Table Query Value Parameters

Parameter

Description

Value

content

This is either a literal value to be used in the comparison operation, or it relates to a special value ID.

Examples of values are:

"23", "Joe", "2"

specialValueId

This is a special value, mostly for dates that may be today, or calculated dates from today. For calculated dates, the content field is used in the calculation.

Valid values are:

LITERAL, TODAY, TODAY_PLUS_DAY, TODAY_MINUS_DAY, TODAY_PLUS_MONTH, TODAY_MINUS_MONTH, TODAY_PLUS_YEAR, TODAY_MINUS_YEAR

Query Object Examples

This section contains JSON and API code examples of the query object.

Example - Query - JSON

This is an example of JSON code that executes a query on the W42101C form in EnterpriseOne.

{  
    "token": "044mK8eBlupO2jaE4BAvXzaRXsMAM7edfHybw26zSZga1w=MDE5MDA2MjUyMTQ1MDE0Njg1NzMwODE2MFNvYXBVSTE0MTIzNTc1MDkwMTc=",
        
        "maxPageSize":"20",
"formServiceAction": "R",        
      "returnControlIDs": "350|360|41[129,130,116,125,132,123]",
    "query":{
    "condition": [
        {
            "value": [
                {
                    "content": "2",
                    "specialValueId": "LITERAL"
                }
            ],
            "controlId": "41[129]",
            "operator": "EQUAL"
        },
        {
            "value": [
                {
                    "content": "2",
                    "specialValueId": "TODAY_MINUS_YEAR"
                }
            ],
            "controlId": "41[116]",
            "operator": "GREATER"
        },
        {
            "value": [
                {
                    "content": "7000",
                    "specialValueId": "LITERAL"
                },
                {
                    "content": "8000",
                    "specialValueId": "LITERAL"
                }
            ],
            "controlId": "41[125]",
            "operator": "BETWEEN"
        },
        {
            "value": [
                {
                    "content": "00070",
                    "specialValueId": "LITERAL"
                },
                {
                    "content": "00001",
                    "specialValueId": "LITERAL"
                },
                {
                    "content": "00077",
                    "specialValueId": "LITERAL"
                }
            ],
            "controlId": "360",
            "operator": "LIST"
        }
    ],
    "autoFind": true,
    "matchType": "MATCH_ALL",
    "autoClear": false
},
    
    "deviceName": "RESTclient",
    "formName": "P42101_W42101C"
}
Example - Query - Mobile Framework API

This is an example of API code that executes a query on the W42101C form in EnterpriseOne.

 public void executeQuery() {
       
        FormRequest formRequest = new FormRequest();
 
        formRequest.setReturnControlIDs("350|360|41[129,130,116,125,132,123]");
        formRequest.setFormName("P42101_W42101C");
        formRequest.setVersion("ZJDE0001");
        formRequest.setFormServiceAction("R");
 
 
        // Execute SEND and RECEIVE operation
        try {
            
            Query query = new Query();
            query.setAutoFind(true); //automatically presses find button (don't need to use form action to find)
            query.setMatchType(Query.MATCH_ALL);  //this is an AND operation on all of the conditions
            query.setAutoClear(false); //clears any existing filter values on the form
            
            //find all line numbers matching
            NumberCondition numCon = query.addNumberCondition("41[129]", NumericOperator.EQUAL());
            numCon.setValue(linNo);
            
            //and requested date within num years from today
            DateCondition dateCon = query.addDateCondition("41[116]", DateOperator.GREATER());
            dateCon.setSpecialDateValue(DateSpecialValue.TODAY_MINUS_YEAR(), years);
            
            //and sold to between
            BetweenCondition betCon = query.addBetweenCondition("41[125]");
            betCon.setValues(soldTo1, soltTo2);
            
            //and company in list
            ListCondition listCon = query.addListCondition("360");
            addValuesToList(listCon);
            
            //add the query object to the request
            formRequest.setQuery(query);
            
            formRequest.setMaxPageSize("20");
            // For POST request, set data payload is header delimited with | and service input class
 
            JSONObject jsonObject = (JSONObject) JSONBeanSerializationHelper.toJSON(formRequest);
            String postData = jsonObject.toString();
 
            //Call to JDERestServiceProvider with parameters json string, method (POST), URI (formservice)
            String response = JDERestServiceProvider.jdeRestServiceCall(postData, JDERestServiceProvider.POST, JDERestServiceProvider.FORM_SERVICE_URI);
 
           p41010_W42101C_FormParent=
                (P42101_W42101C_FormParent) JSONBeanSerializationHelper.fromJSON(P42101_W42101C_FormParent.class,
                                                                                 response);
 
            
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            AdfException adfe = new AdfException(e.getMessage(), AdfException.ERROR);
            throw adfe;
        }
    }

Understanding Batch Form Service

If you make several sequential calls to forms without any data dependencies between them, consider using the Batch Form Service. The Batch Form Service will improve your mobile application's performance.

Batch Form Service - JSON Input and Output

The Batch Form Service requires JSON input and output.

The request URL is: POST http://aisserver:port/jderest/batchformservice

You can use this URL in a REST testing tool. In the preceding URL, batchformservice represents the URI, which you define when you perform the jdeRestServiceCall from the API.

The following examples show JSON input and JSON output in a Batch Form Service.

Example - JSON Input in a Batch Form Service

The JSON consists of an array of form requests along with other single form request fields such as token, environment, role, and so forth. You may send as many requests as desired to the same or different form. Each request is executed individually by the EnterpriseOne HTML (JAS) Server and all responses are compiled into a single response.

This example shows a request for two form executions: W54GS220A and W54HS230A. Each have different form interconnect sets, control sets, and so forth. They are completely independent requests.

{
     "formRequests": [
        {
            "formInputs": [
                {
                    "value": "09/17/2013",
                    "id": "3"
                },
                {
                    "value": "1",
                    "id": "4"
                }
            ],
            "returnControlIDs": "1[19,20,21,27,28,92,174,177,178]|324",
            "findOnEntry": "TRUE",
            "formName": "P54HS220_W54HS220A"
        },
        {
            "formInputs": [
                {
                    "value": "09/17/2013",
                    "id": "2"
                },
                {
                    "value": "1",
                    "id": "3"
                }
            ],
            "returnControlIDs": "1[35,36,37,44,102,105,200,201,277]|368",
            "findOnEntry": "TRUE",
            "formName": "P54HS230_W54HS230A"
        }],
    "token": "jkfdjfkd"
    
}

Example - JSON Output in a Batch Form Service

The JSON output contains one form element for each form that is called. The forms are numbered in the order they were requested. This is not an array of elements; they are individually defined.

The following sample code is an example of JSON output. For fs_0_P54HS220_W54HS220A, the 0 indicates it was the first form requested. For fs_1_P54HS230_W54HS230A, the 1 indicates it was the second form requested.

{
   "fs_0_P54HS220_W54HS220A":    {
      "title": "One View Incident Summary Inquiry",
      "data":       {
         "txtAlertDescription":          {
            "id": 324,
            "value": "Recent Incidents",
            "internalValue": "Recent Incidents",
            "title": "Alert Description",
            "dataType": 2
         },
         "gridData":          {
            "titles":             {
               "col_19": "Incident Number",
               "col_20": "Incident Description",
               "col_21": "Incident Date",
               "col_27": "Incident Status",
               "col_28": "Incident Severity",
               "col_92": "Incident Handler Address",
               "col_174": "Incident Handler Name",
               "col_177": "Incident Status Description",
               "col_178": "Incident Severity Description"
            },
            "rowset":             [
                              {
                  "mnIncidentNumber":                   {
                     "id": 19,
                     "value": "113",
                     "internalValue": 113,
                     "title": "Incident Number",
                     "dataType": 9
                  },
                  "sIncidentDescription":                   {
                     "id": 20,
                     "value": "Gallon drums exposed to sea water rusted and leaked motor oil and coolant",
                     "internalValue": "Gallon drums exposed to sea water rusted and leaked motor oil and coolant",
                     "title": "Incident Description",
                     "dataType": 2
                  },
                  "dtIncidentDate":                   {
                     "id": 21,
                     "value": "09/17/2013",
                     "internalValue": 1379397600000,
                     "title": "Incident Date",
                     "dataType": 11
                  },
                  "sIncidentStatus":                   {
                     "id": 27,
                     "value": "01",
                     "internalValue": "01",
                     "title": "Incident Status",
                     "dataType": 2
                  },
                  "sIncidentSeverity":                   {
                     "id": 28,
                     "value": "03",
                     "internalValue": "03",
                     "title": "Incident Severity",
                     "dataType": 2
                  },
                  "mnIncidentHandlerAddress":                   {
                     "id": 92,
                     "value": "6001",
                     "internalValue": 6001,
                     "title": "Incident Handler Address",
                     "dataType": 9
                  },
                  "sIncidentHandlerName":                   {
                     "id": 174,
                     "value": "Allen, Ray                              ",
                     "internalValue": "Allen, Ray                              ",
                     "title": "Incident Handler Name",
                     "dataType": 2
                  },
                  "sIncidentStatusDescription":                   {
                     "id": 177,
                     "value": "Active",
                     "internalValue": "Active",
                     "title": "Incident Status Description",
                     "dataType": 2
                  },
                  "sIncidentSeverityDescription":                   {
                     "id": 178,
                     "value": "Medium",
                     "internalValue": "Medium",
                     "title": "Incident Severity Description",
                     "dataType": 2
                  }
               },
                              {
                  "mnIncidentNumber":                   {
                     "id": 19,
                     "value": "117",
                     "internalValue": 117,
                     "title": "Incident Number",
                     "dataType": 9
                  },
                  "sIncidentDescription":                   {
                     "id": 20,
                     "value": " ",
                     "internalValue": " ",
                     "title": "Incident Description",
                     "dataType": 2
                  },
                  "dtIncidentDate":                   {
                     "id": 21,
                     "value": "10/01/2013",
                     "internalValue": 1380607200000,
                     "title": "Incident Date",
                     "dataType": 11
                  },
                  "sIncidentStatus":                   {
                     "id": 27,
                     "value": " ",
                     "internalValue": " ",
                     "title": "Incident Status",
                     "dataType": 2
                  },
                  "sIncidentSeverity":                   {
                     "id": 28,
                     "value": " ",
                     "internalValue": " ",
                     "title": "Incident Severity",
                     "dataType": 2
                  },
                  "mnIncidentHandlerAddress":                   {
                     "id": 92,
                     "value": "0",
                     "internalValue": 0,
                     "title": "Incident Handler Address",
                     "dataType": 9
                  },
                  "sIncidentHandlerName":                   {
                     "id": 174,
                     "value": "",
                     "internalValue": "null",
                     "title": "Incident Handler Name",
                     "dataType": 2
                  },
                  "sIncidentStatusDescription":                   {
                     "id": 177,
                     "value": "Default",
                     "internalValue": "Default",
                     "title": "Incident Status Description",
                     "dataType": 2
                  },
                  "sIncidentSeverityDescription":                   {
                     "id": 178,
                     "value": "Default",
                     "internalValue": "Default",
                     "title": "Incident Severity Description",
                     "dataType": 2
                  }
               }
            ],
            "summary":             {
               "records": 2,
               "moreRecords": false
            }
         }
      },
      "errors": [],
      "warnings": []
   },
   "fs_1_P54HS230_W54HS230A":    {
      "title": "One View Incident People Inquiry",
      "data":       {
         "txtAlertDescription":          {
            "id": 368,
            "value": "Recent Reportable Incidents",
            "internalValue": "Recent Reportable Incidents",
            "title": "Alert Description",
            "dataType": 2
         },
         "gridData":          {
            "titles":             {
               "col_35": "Incident Number",
               "col_36": "Incident Description",
               "col_37": "Incident Date",
               "col_44": "Incident Status",
               "col_102": "Incident Handler Address",
               "col_105": "Incident Severity",
               "col_200": "Incident Status Description",
               "col_201": "Incident Severity Description"
            },
            "rowset": [],
            "summary":             {
               "records": 0,
               "moreRecords": false
            }
         }
      },
      "errors": [],
      "warnings": []
   }
}

Implementing the Batch Form Service

This section describes how to implement the Batch Form Service in your mobile application.

Batch Request Parent Class

To consume the JSON response, the mobile application must have a class that matches the response. You must manually code this class because you have to provide the forms in the order in which they are being called.

Example - Batch Request Parent Class

The following sample code is an example of what the new class looks like with one member defined, with the form level type for each of the forms called. Notice that the names of the class members match the names returned by the JSON response. This is the most important aspect of the class, to enable the deserialization from JSON to this object.

The form objects, which are P54HS220_W54HS220A and P54HS230_W54HS230A in the following sample code, are the same ones generated by the AIS Client Class Generator and are used for a single form request.

package com.oracle.e1.formservicetypes
 
public class BatchRequestParent {
    
    private P54HS220_W54HS220A fs_0_P54HS220_W54HS220A;
    private P54HS230_W54HS230A fs_1_P54HS230_W54HS230A;
 
    public BatchRequestParent() {
        super();
    }	
   
   //getters and setters for everything
 
}

Performing a Batch Form Request

In the data control class, create a method for performing the batch form request. An example of a method named batchFormRequest() follows the steps below.

To create this method:

  1. Create a BatchFormRequest object.

  2. Add each form request to the list of requests. Each form request is an object called SingleFormRequest.

  3. Populate these requests in the same manner that you would use for a single form request.

  4. Call the service with uri JDERestServiceProvider.BATCH_FORM_SERVICE_URI and marshal the JSON response to an instance of BatchRequestParent class.

Example - Batch Form Request

You can use each member of the BatchRequestParent class the same way you would use the response from a single form request. In the following sample code, each form in the batch is saved to a member variable of the main data control class.

public void batchFormRequest() {
        
        BatchFormRequest batchFormRequest = new BatchFormRequest();
        //Date used for all
        // Format Incident Date to send to E1
        SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
        String sDate = dateFormat.format(getSearchDate());
        
 
        //recentIncidents
        SingleFormRequest formRequest = new SingleFormRequest();
        formRequest.setFindOnEntry("TRUE");
        formRequest.setReturnControlIDs("1[19,20,21,27,28,92,174,177,178]|324");
        formRequest.setFormName("P54HS220_W54HS220A");
        formRequest.addToFISet("3", sDate);
        formRequest.addToFISet("4", "1");        
        batchFormRequest.getFormRequests().add(formRequest);
        
 
        // recentReportableIncidents
        formRequest = new SingleFormRequest();        
        formRequest.setFindOnEntry("TRUE");
        formRequest.setReturnControlIDs("1[35,36,37,44,102,105,200,201,277]|368");
        formRequest.setFormName("P54HS230_W54HS230A");        
        formRequest.addToFISet("2", sDate);
        formRequest.addToFISet("3", "1");        
        batchFormRequest.getFormRequests().add(formRequest);
        try {
            // For POST request, set data payload is header delimited with | and service input class
 
            JSONObject jsonObject = (JSONObject)JSONBeanSerializationHelper.toJSON(batchFormRequest);
            
            String postData = jsonObject.toString();
 
            String response = JDERestServiceProvider.jdeRestServiceCall(postData, JDERestServiceProvider.POST, JDERestServiceProvider.BATCH_FORM_SERVICE_URI);
 
 
            BatchRequestParent batchParent =
                    (BatchRequestParent)JSONBeanSerializationHelper.fromJSON(BatchRequestParent.class, response); 
            
            if(batchParent != null){
                
                //recentIncidents
                this.p54hs220_formIncidents = new P54HS220_W54HS220A_FormParent();
                this.p54hs220_formIncidents.setFs_P54HS220_W54HS220A(batchParent.getFs_0_P54HS220_W54HS220A());
            
                IncidentCount ic = new IncidentCount();
                ic.setCount(p54hs220_formIncidents.getFs_P54HS220_W54HS220A().getData().getGridData().getSummary().getRecords());
                ic.setTitle("Recent");
                ic.setScoreboardNumber("1");
                incidentCounts.add(ic);
                
                
                // recentReportableIncidents
                this.p54hs230_formParent = new  P54HS230_W54HS230A_FormParent();
                this.p54hs230_formParent.setFs_P54HS230_W54HS230A(batchParent.getFs_3_P54HS230_W54HS230A());
                ic = new IncidentCount();
                ic.setCount(p54hs230_formParent.getFs_P54HS230_W54HS230A().getData().getGridData().getSummary().getRecords());
                ic.setTitle("Reportable");
                ic.setScoreboardNumber("4");
                incidentCounts.add(ic);
                
          
            }
            
 
        } catch (Exception e) {
            AdfException adfe = new AdfException("Rest Call Failed" + e.getMessage(), AdfException.ERROR);
            throw adfe;
        }
 
 
 
    }

Working with the EnterpriseOne REST Services Interface

You can make REST calls directly to the AIS Server without using APIs from the JDEMobileFramework.jar. To do so, use a REST service testing tool to send JSON text to AIS Server endpoints. Each endpoint provides a particular service that the mobile application can use to interact with EnterpriseOne applications. You can access AIS Server endpoints using this URL format:

http://<server>:<port>/jderest/<URI>

See EnterpriseOne Rest Services Interface for an illustration of JSON input and output communication between a mobile device and the AIS Server and between the AIS Server and the EnterpriseOne HTML Server.

See the "AIS Services (Endpoints)" section in the JD Edwards EnterpriseOne Application Interface Services Server Reference Guide for a description of the available endpoints on the AIS Server along with the HTTP method used to access them. Unless otherwise stated, the request and response are in the form of JSON strings.

Using a REST Services Client to Interact with AIS

In the text area in the bottom left of the form, enter the JSON string that is the input to the tokenrequest service. Entering an environment and role is optional. Include them only if you want to override the default values.

Example - Acceptable Input for the defaultconfig Service on JSON

The defaultconfig service is the only service that uses an HTTP GET operation. It accepts one parameter for the required capabilities in the client application. If any required capabilities listed in that parameter are missing, the response will indicate the missing capabilities in the "requiredCapabilityMissing" field.

{
   "jasHost": "jasserver.domainexample.com",
   "jasPort": "8412",
   "jasProtocol": "http",
   "defaultEnvironment": "DV910",
   "defaultRole": "*ALL",
   "displayEnvironment": true,
   "displayRole": true,
   "displayJasServer": false,
   "defaultJasServer": "http://jasserver.domainexample.com:port",
   "ssoAllowed": true,
   "allowSelfSignedSsl": false,
   "sessionTimeout": "30",
   "timeToLive": "720",
   "aisVersion": "EnterpriseOne 9.1.4.6",
   "capabilityList":    [
            {
         "name": "grid",
         "shortDescription": "Grid Actions",
         "longDescription": "Ability to update, insert and delete grid records.",
         "asOfRelease": "9.1.4.4"
      },
            {
         "name": "editable",
         "shortDescription": "Enabled/Disabled",
         "longDescription": "Ability to indicate if form field or grid cell is editable (enabled) or not (disabled).",
         "asOfRelease": "9.1.4.4"
      },
            {
         "name": "log",
         "shortDescription": "Logging",
         "longDescription": "Endpoint exposed for logging to AIS server log from client",
         "asOfRelease": "9.1.4.6"
      },
            {
         "name": "processingOption",
         "shortDescription": "Processing Options",
         "longDescription": "Processing Option Service exposed for fetching PO values from E1",
         "asOfRelease": "9.1.4.6"
      },
            {
         "name": "ignoreFDAFindOnEntry",
         "shortDescription": "Ignore FDA Find On Entry",
         "longDescription": "Ability to use the IgnoreFDAFindOnEntry flag",
         "asOfRelease": "9.1.4.6"
      }
   ],
   "requiredCapabilityMissing": false,
   "keepJasSessionOpen": true,
   "jasSessionCookieName": "JSESSIONID"
}

Example - Acceptable Input for the tokenrequest Service in JSON

{
"username":"jde",
"password":"jde",
"deviceName":"RESTclient",
"environment":"JDV910",
"role":"*ALL"
}

Example - Acceptable Input for the tokenrequest Service in JSON Response

{
   "username": "jde",
   "environment": "JDV910",
   "role": "*ALL",
   "jasserver": "http://jasserver.domainexample.com:port",
   "userInfo":    {
      "token": "044kbwMICIsL8P4jttMj/VtpnEhrSK17i7fa2q8V+hVDlc=MDE4MDEwNjA1NTMwODkwMzQ1ODY0MTkyUkVTVGNsaWVudDE0MTI2MDg3MDgzODY=",
      "langPref": "  ",
      "locale": "en",
      "dateFormat": "MDE",
      "dateSeperator": "/",
      "simpleDateFormat": "MM/dd/yyyy",
      "decimalFormat": ".",
      "addressNumber": 2111,
      "alphaName": "Ingram, Paul"
   },
   "userAuthorized": false,
   "version": null,
   "poStringJSON": null,
   "altPoStringJSON": null,
   "aisSessionCookie": "W3XmCk8k6vhb3H-dwxSdBpCGZWAb7kh5D4gzemFoqoFqcoWgwqF_!-1217528743!1412608708388"
}

Form Request Attributes

The following list contains a description of the form request attributes. For an example of a form request, see Example - Form Request.

  • maxPageSize. (optional) If you do not specify a value, then AIS will return a maximum of 100 rows. The maximum number you can enter for this setting is 500.

    Starting with EnterpriseOne Tools 9.2.1, there is no maximum limit for rows returned to the grid. However, a maximum value is required. If you want to retrieve all records, enter No Max for this attribute.

    The value in the "DB Fetch Limit in the Web Runtime Interactivity" setting in the Web Runtime Interactivity section of the EnterpriseOne HTML Server configuration file (jas.ini) supersedes the maxPageSize setting. The "DB Fetch Limit in the Web Runtime Interactivity" setting is typically set to a higher value (2000 is the default), but you might have to modify it if your results are not as expected. See "Configuration Groups" in the JD Edwards EnterpriseOne Tools Server Manager Guide for more information on how to modify server configuration settings.

  • returnControlIDs. (optional) Indicates which form and grid fields the service passes back. Grid is always 1 and has an array of fields. Form fields are bar delimited after grid, for example 1[19,20,50,48]|54|55. For power forms, indicate the control ID of the subform and then underscore and the control within the subform, for example 1_20|1_22[23,34].

  • formInputs. (optional) Collection of ID value pairs that represent the form interconnect input to the form. Associate a string for the FI ID with the value to be passed into that FI.

  • version. The version of the application, for example ZJDE0001.

  • formName. (required) Application and form name, for example P01012_W01012B.

  • formServiceAction. (optional) The CRUD operation the form will perform.

  • token. (required) The EnterpriseOne token that was returned from the tokenrequest service.

  • environment. (optional) EnterpriseOne environment that was used to request the token.

  • role. (optional) The EnterpriseOne role used to request the token.

  • findOnEntry. (optional) Valid values are TRUE or FALSE. Performs a find automatically when the EnterpriseOne application launches. In the EnterpriseOne application this autofind event occurs after post dialog initialized.

  • ignoreFDAFindOnEntry. (optional) Valid values are TRUE or FALSE. Applies to applications that have the box checked for "Automatically Find on Entry" in the gird in FDA. Allows the form service caller to control if that flag is used or not.

  • formActions. (optional) A set of actions to be performed on the form, in the order listed. The actions can include entering a value into a form field, QBE field, selecting a radio button, pressing a button, and selecting a check box value.

Example - Form Request
{
    "token": "044RnByWbW3FbLzpxWjSg55QzZWguAGnYqUNMlyB30IgyU=MDE5MDA2ODg0MDE5NjYwNzM1ODcyNDA5NlNvYXBVSTEzODc0ODc4OTEzNTc=",
    "maxPageSize": "10",
    "returnControlIDs": "1[19,20]58|62",
    "version": "ZJDE0001",
    "formInputs": [
        {
            "value": "E",
            "id": "2"
        }
    ],
    "formActions": [
        {
            "value": "E",
            "command": "SetQBEValue",
            "controlID": "1[50]"
        },
        {
            "value": "Al*",
            "command": "SetControlValue",
            "controlID": "58"
        },
        {
            "value": "on",
            "command": "SetCheckboxValue",
            "controlID": "62"
        },
        {
            "value": "on",
            "command": "SetCheckboxValue",
            "controlID": "63"
        },
        {
            "command": "DoAction",
            "controlID": "15"
        }    ],
            "role": "*ALL",
        "environment": "JDV910",
	   "formsServiceAction":"R",
    "deviceName": "RESTclient",
    "formName": "P01012_W01012B"
}

Calling FormService on Local EnterpriseOne HTML (JAS) Server through the AIS Server

You have the option to use this technique if you have FDA changes locally and want to test the JSON output while still accessing the AIS Server. This is the closest approximation of how the mobile application will call the REST services.

Configure your local EnterpriseOne HTML Server to accept requests from the AIS Server. To do so:

  1. Locate the jas.ini file on the local EnterpriseOne Windows client (development client) machine:

    C:\E910_1\system\OC4J\j2ee\home\applications\webclient.ear\webclient\WEB-INF\classes\jas.ini

  2. Add or modify the form service section like this:

    #specify hosts allowed to call the form service and media object service
    [FORMSERVICE]
    allowedhosts=127.0.0.1|10.123.456.7
    

    The two preceding entries are the local host IP address and the IP address of the AIS Server. This enables you to make calls through the AIS Server to your local EnterpriseOne HTML Server. For the AIS Server, you can also use allowedhosts=* if you do not know the AIS Server IP address or want to allow access for any AIS Server.

  3. Restart the EnterpriseOne Windows client.

  4. Test the configuration by repeating the preceding steps, but include the following change to the JSON requests:

    For tokenrequest: Indicate the JAS server, which is your local EnterpriseOne HTML Server. Also, Oracle recommends that you always include the environment and role because the defaults stored on the AIS Server may not work with a local instance (such as JDV910 vs DV910).

    {"username":"JDE",
    "password":"jde",
    "deviceName":"RESTclient",
    "jasserver":"http://dnnlaurentvm1:8888",
    "environment":"DV910",
    "role":"*ALL"
    }

Understanding Text Media Object Attachments

The AIS Server provides a method to get and update the first text attachment stored for a particular media object data structure key in EnterpriseOne.

The JDEMobileFramework API provides the following two services for managing text media object attachments in mobile applications:

See also:

gettext Service

The URL for getting text media objects is:

http://<ais-server>:<port>/jderest/file/gettext

Only the first text media object is returned; it does not handle multiple text attachments. Only plain text is supported. While the original text media object is stored in HTML or RTF format (based on the settings on the EnterpriseOne HTML Server), the tags will be removed and the response will be in plain text with line breaks in Unicode (UTF-8) format.

The following table describes the expected JSON input for the gettext service:

Field

Value Description

Example

token (String)

The token you received when you executed a token request.

"044TqjlQVSNHKvokvhWFKa8MYckPgG…"

moStructure (String)

The Media Object Structure

"ABGT" or "GT0801A"

moKey (Array of Strings)

The key to that media object structure.

["7"] or ["2015","283", "2"]

formName (String)

The form where this media object is used.

"P01012_W01012B"

version (String)

The version of the app where this media object is used.

"ZJDE0001"

deviceName (String)

The device making the call to the service.

"FUSE" or "iPhoneSimulator"

Example - gettext Service Input

{
    "token": "044TqjlQVSNHKvokvhWFKa8MYckPgGJdrd3CEDkzz2YjLQ=MDE5MDA2Nzg3NjEzOTA2MTY1MzIwMTkyMFNvYXBVSTEzOTk1ODA5MzQ0OTg=",
    "moStructure": "ABGT",
    "moKey": [
        "7"
    ],
    "formName": "P01012_W01012B",
    "version": "ZJDE0001",
    "deviceName": "RESTclient"
}

Example - gettext Service Response

{
   "text": "9.1.4.6 \\u000aFirst Line \\u000aSecond Line \\u000aThird Line \\u000aFourth Line \\u000aFifth line",
   "isRTF": false
}

updatetext Service

The URL for updating text media objects is:

http://<ais-server>:<port>/jderest/file/updatetext

Only plain text is supported.

The following table describes the expected JSON input for the updatetext service:

Field

Value Description

Example

token (String)

The token you received when you executed a token request.

"044TqjlQVSNHKvokvhWFKa8MYckPgG…"

moStructure (String)

The media object structure.

"ABGT" or "GT0801A"

moKey (Array of Strings)

The key to the media object structure.

["7"] or ["2015","283", "2"]

formName (String)

The form where this media object is used.

"P01012_W01012B"

version (String)

The version of the application where the media object is used.

"ZJDE0001"

deviceName (String)

The device making the call to the service.

"RESTClient" or "iPhoneSimulator"

inputText (String)

The text you are updating for the first text media object.

"Update Text"

appendText (Boolean)

A flag to indicate if the text should append to (true) or replace (false) the existing first text attachment.

true or false

Example - Update Text Service Input

{
    "token": "044X9NgLP5VHqIW0zJcWseFjMtjrnZ35TUFmVV3NW9a9g4=MDE5MDA2NDY5MzQ1NjkzNDM1MjE3NjEyOFNvYXBVSTE0MDE3MTc4MDkzNTk=",
    "moStructure": "ABGT",
    "moKey": [
        "7"
    ],
    "formName": "P09E2011_W09E2011A",
    "version": "ZJDE0001",
    "inputText": "\nFirst Line \nSecond Line \nThird Line \nFourth Line \nFifth line",
    "appendText": false,
    "deviceName": "RESTclient"
}

Example - Update Text Service Response

{
    "updateTextStatus": "Success"
}

JDEMobileFramework API Methods for Managing Text Media Objects

The MediaObjectOperations class in the JDEMobileFramework API provide methods for managing text media objects from mobile applications. The same two methods described in the preceding sections, getText and updateText, are exposed in this API.

MediaObjectOperations Class

The following table describes the methods in the MediaObjectOperations class:

Return

Method

Description

MediaObjectGetTextResponse

getTextMediaObject(MediaObjectGetTextRequest mediaObgetTextRequest) throws Exception

Takes a MediaObjectGetTextRequest, calls the get text service, replaces unicode returns and line feeds with system line separator and returns a MediaObjectGetTextResponse with the resulting text attachment value.

MediaObjectUpdateTextResponse

updateTextMediaObject(MediaObjectUpdateTextRequest mediaObgetUpdateTextRequest) throws Exception

Takes a MediaObjectUpdateTextRequest, calls the update text service and returns result in MediaObjectUpdateTextResponse.

Example - Get Example

public void getText() {
        MediaObjectGetTextRequest moGetText = new MediaObjectGetTextRequest();
        
        moGetText.setFormName(formName);
        moGetText.setVersion(version);
        moGetText.setMoStructure(moStructure);
 
        //set mo key
        moGetText.addMoKeyValue(mokey);
 
 
        try {
 
            MediaObjectGetTextResponse response = MediaObjectOperations.getTextMediaObject(moGetText);            
            this.setFirstText(response.getText());
            
 
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            AdfException adfe = new AdfException(e, AdfException.ERROR);
            throw adfe;
        }
 
 
    }

Example - Append Example

public void appendText() {
        MediaObjectUpdateTextRequest moUpdateText = new MediaObjectUpdateTextRequest();
 
        moUpdateText.setFormName(formName);
        moUpdateText.setVersion(version);
        moUpdateText.setMoStructure(moStructure);
 
        //set mo key
        moUpdateText.addMoKeyValue(mokey);
        moUpdateText.setAppendText(true);
        moUpdateText.setInputText(this.getFirstText());
 
 
        try {
 
            MediaObjectUpdateTextResponse response = MediaObjectOperations.updateTextMediaObject(moUpdateText);
 
 
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            AdfException adfe = new AdfException(e, AdfException.ERROR);
            throw adfe;
        }
 
 
    }

Example - Update Example

public void updateText() {
        MediaObjectUpdateTextRequest moUpdateText = new MediaObjectUpdateTextRequest();
        moUpdateText.setFormName(formName);
        moUpdateText.setVersion(version);
        moUpdateText.setMoStructure(moStructure);
 
        //set mo key
        moUpdateText.addMoKeyValue(mokey);
        moUpdateText.setAppendText(false);
        moUpdateText.setInputText(this.getFirstText());
 
 
        try {
 
            MediaObjectUpdateTextResponse response = MediaObjectOperations.updateTextMediaObject(moUpdateText);
 
 
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            AdfException adfe = new AdfException(e, AdfException.ERROR);
            throw adfe;
        }
 
 
    }

Understanding URL Media Object Attachments

You can use the addURLMediaObject method to include URL media object attachments in a mobile application. A URL media object attachment provides a link to a web page or a file located on a server. In EnterpriseOne, a URL media object displays the target of a URL in the Media Object Viewer.

The addURLMediaObject method uses a media object data structure key to identify the record to which the attachment belongs.

The following is a description of the method and the fields that make up the request and the response of the method:

  • Method - addURLMediaObject
  • Description - Adds a media object of the type URL.
  • Returns - MediaObjectAddUrlResponse
  • Parameters - MediaObjectAddUrlRequest

MediaObjectAddUrlRequest

Field

Type

Description

moStructure

String

The media object structure ID, for example GT0801, GT48100.

moKey

ArrayList <String>

The set of key values, as strings, that is the key of the media object. The API will handle formatting into a bar delimited set. Use the JDEmfUtilities.convertMillisecondsToYMDString() method to pass dates.

formName

String

The application and form usually associated with this media object structure, for example P01012_W01012B. This is for security purposes. Security for media objects is based on the form being used.

version

String

The version of the application noted in the formName. This is for security purposes. Security for media objects is based on the form being used.

urlText

String

The text of the URL, for example www.oracle.com or http://www.oracle.com

MediaObjectAddUrlResponse

Field

Type

Description

urlText

String

The text of the url, for example www.oracle.com or http://www.oracle.com

saveUrl

String

The url as it was saved in the media object table F00165.

sequence

int

The sequence number for the newly added url type media object.

Example - URL Media Object - JSON Request and Response

The following code is an example of a JSON request:

{
    "moStructure": "ABGT",
    "moKey": [
        "4242"
    ],
    "formName": "P01012_W01012B",
    "version": "ZJDE0001",
    "token": "044BPeneep/jkkldafjdkla",
    "urlText": "http://www.oracle.com",
    "deviceName": "RESTclient"
}

The following code is an example of a JSON response:

{
   "saveURL": "http://www.oracle.com",
   "urlText": "http://www.oracle.com",
   "sequence": 5
}

Example - URL Media Object - Mobile Framework API

The following is an example of API code for a URL media object.

public void addURL() throws Exception {
 
        //set request info include URLs so they don't have to be fetched later
        MediaObjectAddUrlRequest mediaObjectAddUrlRequest = new MediaObjectAddUrlRequest();
 
        mediaObjectAddUrlRequest.setFormName("P01012_W01012B");
        mediaObjectAddUrlRequest.setVersion("ZJDE00001");        
        mediaObjectAddUrlRequest.setMoStructure("ABGT");
        mediaObjectAddUrlRequest.addMoKeyValue("4242");
        
        mediaObjectAddUrlRequest.setUrlText("http://www.oracle.com");
 
        MediaObjectAddUrlResponse mediaObjectAddUrlResponse = new MediaObjectAddUrlResponse();
        try {
            //get the list of available files for this media object
 
            mediaObjectAddUrlResponse = MediaObjectOperations.addUrlMediaObject(mediaObjectAddUrlRequest);
 
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            AdfException adfe = new AdfException("Media Object addURL Failed " + " " + e, AdfException.ERROR);
            throw adfe;
        }
    }

Understanding the Media Object API for Photo Media Object Attachments

You can incorporate photo attachments into native Oracle MAF mobile applications using the JDEMobileFramework.jar, which is a JDE Mobile Helper. The JDEMobileFramework.jar contains a Media Object API that provides classes and methods that enable access to media objects from EnterpriseOne. It works in conjunction with the AIS Server and the MediaObjectRequest capability of the EnterpriseOne HTML Server.

MediaObjectOperations is an abstract class that contains all of the static methods needed to manage media objects. This section describes the following four main operations:

List

  • Method - getMediaObjectList
  • Description - Returns a list of Media Object details based on the information provided in the request.
  • Returns - MediaObjectListResponse
  • Parameters - MediaObjectListRequest

MediaObjectListRequest

Field

Type

Description

moStructure

String

The Media Object structure ID (such as GT0801, GT48100)

moKey

ArrayList <String>

The set of key values, as strings, that is the key of the media object. The API will handle formatting into a bar delimited set. Use the JDEmfUtilities.convertMillisecondsToYMDString() method to pass dates.

formName

String

The application and form usually associated with this media object structure (e.g. P01012_W01012B). This is for security purposes. Security for media objects is based on the form being used.

version

String

The version of the application noted in the formName. This is for security purposes. Security for media objects is based on the form being used.

includeURLs

boolean

When true, the response will include the JAS URL for each file type media object.

includeData

boolean

When true, the response will include the Base64 encoded data for a 40 X 40 size of the image in the data field of the response.

moTypes

ArrayList <String>

Valid types are 1 and 5, which are the two file type media objects. Type 1 file attachments are from a Media Object Queue. Type 5 attachments are files uploaded individually to the EnterpriseOne HTML Server.

extensions

ArrayList

Use this field to further reduce the data set by indicating the extensions of the files you want to be included in the response (such as "jpg","gif","png","pdf").

thumbnailSize

<String> int

Use this in conjunction with the includeData flag. When data is included in the response you can pass an integer value in this field to control the size of the thumbnail returned in the data field. A value of 0 will return the default size of 40x40. The maximum size is 200, any value over 200 will return images 200x200.

MediaObjectListResponse

Field

Type

Description

mediaObjects

MediaObjectListItem [ }

An array of media object list items.

MediaObjectListItem

Field

Type

Description

downloadUrl

String

When true, the response will include the JAS URL for each file type media object.

file

String

When true, the response will include the Base64 encoded data for any image file in the data field of the response. For text type media objects the text will be include in the data field of the response.

itemName

String

A user given name for the media object item. When viewing media objects on JAS this is the name shown directly under each media object item in the left panel of the MO control.

link

String

moType

int

Type 1 file attachments are from a Media Object Queue. Type 5 attachments are files uploaded individually to the JAS server.

queue

String

For type 1 file attachments from a Media Object Queue the name of the queue.

sequence

int

The sequence the number of that individual attachment in the set of attachments.

updateDate

String

The date that the media object was last updated.

updateHourOfDay

int

The hour that the media object was last updated.

updateMinuteOfHour

int

The minute that the media object was last updated.

updateSecondOfMinute

int

The second that the media object was last updated.

updateUserID

String

The user that last updated that media object.

hasValidTimestamp

boolean

Indicates if time stamp was valid.

isDefaultImage

boolean

Indicates if image is default image.

isMisc

boolean

<unknown>

isOLE

boolean

Is an OLE attachment.

isShortCut

boolean

<unknown>

isText

boolean

Is a text type attachment.

isUpdated

boolean

<unknown>

isURL

boolean

Is a URL type attachment.

data

String

For an image file this is the Base64 encoded string of the image data for a 40x40 size of the image.

thumbFileLocation

String

The location of the thumbnail (40x40) saved on the device. A file is written for each image that has Base64 data included. Files are only written if data is requested.

Download

  • Method - downloadMediaObject
  • Description - Downloads a full sized media object to a file on the device, based on the key information provided in the request.
  • Returns - MediaObjectDownloadResponse
  • Parameters - MediaObjectDownloadRequest

MediaObjectDownloadRequest

Field

Type

Description

moStructure

String

The Media Object structure ID, for example GT0801, GT48100.

moKey

ArrayList <String>

The set of key values, as strings, that is the key of the media object. The API will handle formatting into a bar delimited set. Use the JDEmfUtilities.convertMillisecondsToYMDString() method to pass dates.

formName

String

The application and form usually associated with this media object structure, for example P01012_W01012B. This is for security purposes. Security for media objects is based on the form being used.

version

String

The version of the application noted in the formName. This is for security purposes. Security for media objects is based on the form being used.

downloadURL

String

The downloadURL provided in the list response. When this value is already known, provide it so the service will not do the extra work of getting the URL.

fileName

String

This will be the name of the file saved on the device file system. It is easiest (and uniqueness is guaranteed) to pass the file provided in the list response.

sequence

int

The sequence number of this individual file in the set of attachments.

height

int

When a value is passed in this field, the image will be scaled to this size before it is returned. If you provide only height, the width will be scaled to maintain the aspect ratio.

width

int

When a value is passed in this field, the image will be scaled to his size before it is returned. If you provide only width, the height will be scaled to maintain the aspect ratio.

FileAttachment

Field

Type

Description

fileName

String

The name of the file as stored in the database.

fileLocation

String

The location of the file saved to the device file system. This includes the "file://" prefix so it can be directly used in image tags in an amx page.

itemName

String

A string value the user may provide as the name of the attachment (if not supplied the file name will be used.)

sequence

int

The sequence number of this individual attachment.

thumbFileLocation

String

The file location of the thumbnail image (this value is not updated when the download method is called).

downloadUrl

String

The JAS URL of the file attachment (this value is not populated when the download method is called).

Upload

  • Method - uploadMediaObject
  • Description - Uploads a single file to the media object database based on key values provided in the request.
  • Returns - MediaObjectUploadResponse
  • Parameters - MediaObjectUploadRequest

MediaObjectUploadRequest

Field

Type

Description

moStructure

String

The Media Object structure ID (such as GT0801, GT48100).

moKey

ArrayList <String>

The set of key values, as strings, that is the key of the media object. The API will handle formatting into a bar delimited set. Use the JDEmfUtilities.convertMillisecondsToYMDString() method to pass dates.

formName

String

The application and form usually associated with this media object data structure (such as P01012_W01012B). This is for security purposes. Security for media objects is based on the form being used.

version

String

The version of the application noted in the formName. This is for security purposes. Security for media objects is based on the form being used.

file

FileAttachment

The resulting downloaded file with the name, fileLocation, sequence and itemName fields updated.

FileAttachment

Field

Type

Description

fileName

String

The name of the file as stored in the database. (This value is not required for upload.)

fileLocation

String

The location of the file saved to the device file system. This includes the "file://" prefix so it can be directly used in image tags in an amx page.

itemName

String

A descriptive name. If not passed, the filename will be used. The extension will be added automatically.

sequence

int

The sequence number of this individual attachment (this value is not required for upload).

thumbFileLocation

String

The file location of the thumbnail image (this value is not required for upload).

downloadUrl

String

The JAS URL of the file attachment (this value is not required for upload).

MediaObjectUploadResponse

Field

Type

Description

itemName

String

A user given name for the media object item. When viewing media objects on JAS, this is the name shown directly under each media object item in the left panel of the MO control. The extension will be added automatically. If not passed, the file name is used.

sequence

int

The sequence number of this individual attachment (assigned during the upload).

Delete

  • Method - deleteMediaObject
  • Description - Deletes the file in the media object database based on key values provided in the request. Deletes the file on the device file system also.
  • Returns - MediaObjectDeleteResponse
  • Parameters - MediaObjectDeleteRequest

MediaObjectDeleteRequest

Field

Type

Description

moStructure

String

The Media Object structure ID (e.g. GT0801, GT48100).

moKey

ArrayList <String>

The set of key values, as strings, that is the key of the media object. The API will handle formatting into a bar delimited set. Use the JDEmfUtilities.convertMillisecondsToYMDString() method to pass dates.

formName

String

The application and form usually associated with this media object structure (e.g. P01012_W01012B). This is for security purposes. Security for media objects is based on the form being used.

version

String

The version of the application noted in the formName. This is for security purposes. Security for media objects is based on the form being used.

sequence

int

The sequence number of this individual file in the set of attachments.

fileLocation

String

The location of the file on the device file system.

MediaObjectDeleteResponse

Field

Type

Description

deleteStatus

String

The value 'Success' will be returned for successful deletes. Any other value is a failure.

error

String

In the case of failure details of the error will be included here.

Understanding the Processing Option Service

The processing option service is an AIS service for handling processing options.

The URI for the service is:

http://<AIS Server>:<port>/jderest/poservice

The input JSON is:

{
 "token": "044uZUG2Uk1Vd6hzmAhPfILitA2pVLDVKLOYdh4HR71D7s=MDE5MDA2ODM3NTQ3NzU4MDMwNTg2MzY4MFNvYXBVSTEzOTcwNTYxMTIxMTE=",

  "applicationName":"P01012",
  "version":"ZJDE0001",
  "deviceName":"RESTclient"

}

The response JSON is like this:

{  
   "application": "P01012",
   "version": "ZJDE0001",
   "processingOptions":    {
      "GoToSupplierMaster_5":       {
         "type": 1,
         "value": " "
      },
      "GoToCustomerMaster_6":       {
         "type": 1,
         "value": " "
      },
      "GoToCSMS_8":       {
         "type": 1,
         "value": " "
      },
      "HideTax_4":       {
         "type": 1,
         "value": " "
      },
      "SearchTypeDefault_7":       {
         "type": 2,
         "value": " "
      },
      "cTypeCode_11":       {
         "type": 1,
         "value": "A"
      }

   },
   "errors": ""
}

Using the AIS Service for Processing Options in a Mobile Application

You can call the processing option service passing an application and version. You can obtain the version from the mobile application processing options, which specify the version of the EnterpriseOne application the mobile application uses. For more information about the processing options for mobile applications, see the JD Edwards EnterpriseOne Applications Functionality for Mobile Devices Implementation Guide.

If you use the processing option service, you must add "processingOption" to the list of required capabilities in the about.properties. If you do not do this, you will receive an error at runtime. See Understanding AIS Server Capabilities for more information.

ProcessingOptionRequestpoRequest = new ProcessingOptionRequest();
poRequest.setEnvironment(ApplicationGlobals.getInstance.getLoginResponse().getEnvironment());
poRequest.setRole(ApplicationGlobals.getInstance.getLoginResponse().getRole());
poRequest.setJasserver(ApplicationGlobals.getInstance.getLoginResponse().getJasserver());
poRequest.setToken(ApplicationGlobals.getInstance.getLoginResponse().getUserInfo().getToken());
poRequest.setApplicationName("P5648203");
poRequest.setVersion("GNJ001");
 
 try {
            
  JSONObject jsonObject = (JSONObject) JSONBeanSerializationHelper.toJSON   (poRequest);
  String postData = jsonObject.toString();
 
//send in po Request json, POST and poservice
 String response =
                    JDERestServiceProvider.jdeRestServiceCall(postData, poRequest.POST, poRequest.PO_SERVICE);
 
//response can be serialized to ProcessingOptionSet class
ProcessingOptionsSet poSet =
                    (ProcessingOptionsSet) JSONBeanSerializationHelper. fromJSON (ProcessingOptionsSet.class, response);
 
 if (poSet != null) {
 	//get the individual option and cast it to a variable of matching type                   
String attachmentAllowed = (String)poSet.getOptionValue ("szAttachmentAllowed_1"));
}

Remember to inspect the "errors" element of the response in case an error was encountered when trying to fetch the processing options you requested.

There are six supported data types. These are based on the data item used in the Processing Option Design Aid for each option.

You can get the type of the option before attempting to cast it, which is the recommended method. Or you can just cast it to the type you expect, because it is unlikely to change. The default is String, so you will always be able to get to a string version of the option value.

Type Code

Type Constant

Java Type

JDE DD Type

1

STRING_TYPE

String

String

2

CHAR_TYPE

String

Character

9

BIG_DECIMAL_TYPE

BIG Decimal

Math Numeric

11

DATE_TYPE

Date

Date

15

INTEGER_TYPE

Integer

Integer

55

CALENDAR_TYPE

Calendar

Utime

Understanding the Application Stack Service

The application stack is a service that enables interactive communication with applications running on the EnterpriseOne web client. By using the application stack service, you can perform form interconnects to receive data from the resulting form. You can perform more complex interactions with applications that have cross-form transaction boundaries, for example where you do not want the header saved until the details are added and so forth. Also, with the application stack, you can implement a record reservation in mobile applications that corresponds to a record reservation in the web application.

The purpose of application stack processing is that it enables you to establish a session for a specific application and maintain that session across calls. So you initiate a session or 'open' it with one service call, then you can have any number of service calls to 'execute' actions against the currently running application. Finally, you 'close' the session with a service call.

To accomplish this stateful model, some additional data is managed for each service call, including stack ID, state ID, and rid. Also, each request to execute actions against the running application must be sent with the formOID to ensure the form you are expecting is indeed the currently running form.

Note: You can execute actions on only one form during a stack request. So if your request performs a form interconnect, you will have to submit a subsequent request to operate on the second form running after the interconnect.

Service Endpoint

The application stack service is exposed by the AIS Server at the endpoint:

http://<aishost>:<port>/jderest/appstack

Capability

The application stack capability is exposed in the default configuration as "applicationStack." You must add this to your used or required capability lists within your mobile application to use this capability.

Prerequisite

The AIS Server must be configured to "Keep JAS Sessions Open" so that the session can be maintained across service calls.

JSON Example of an Application Stack Request

This section shows an example of JSON code that performs the following actions:

Open Application: Request and Response

Example - Open Application - Request shows an example of the application stack request. It contains all of the other environment and credential information that is included in a form service request. After this information, it contains a single instance of a form service request called formRequest. You can use this to include any action you want to take on this original form, just like a normal form service request. Most important is the action, which is "open" in this case. This tells the EnterpriseOne web client to keep the form open so that you can interact with it on future requests.

So for this request with the Address Book (P01012), the search type is set to "E to perform a "find" and retrieve the first five records.

Important: The maxPageSize indicated in this originating request will be the max page size for all requests in this stack. If you do not specify a maxPageSize, it uses the form service request default of 100.
Example - Open Application - Request
{
    "token": "044J57pHCCB3AzH7/W6Vetm0+yVG6pnKOPl823587SfY6o=MDE5MDA2MTYxOTE0NTE0NjE2OTEyNTg4OFNvYXBVSTE0MDEyMTA5MDE1MDM=",
    "action": "open",
    "formRequest": {
        "returnControlIDs": "54|1[19,20]",
        "maxPageSize": "5",
        "formName": "P01012_W01012B",
        "version": "ZJDE0001",
        "findOnEntry": "TRUE",
        "formInputs": [
            {
                "value": "E",
                "id": "2"
            }
        ]
    },
    "deviceName": "RESTclient"
}
Example - Open Application - Response
{
   "fs_P01012_W01012B":    {
      "title": "Work With Addresses",
      "data":       {
		… condensed….
      },
      "errors": [],
      "warnings": []
   },
   "stackId": 1,
   "stateId": 1,
   "rid": "e51b593df7a884ea",
   "currentApp": "P01012_W01012B_ZJDE0001",
   "sysErrors": []
}

The response contains the data (including the 5 rows, which are not shown), along with additional information used for all subsequent interactions with the open application.

Execute Actions on Application: Request and Response

Next, the JSON code should contain commands to select one of the records returned and access the row exit to Phones (through a form interconnect). With this service call, make sure to pass in the values for stack ID, state ID and rid from the last call, along with the token. Also, indicate an action of "execute," so it knows you are interacting with an open application.

This execute type request contains an actionRequest which can include returnControlIDs for the form you expect to end on and an array of formActions to execute on the form indicated by formOID.

Example - Execute Actions on Application - Request
{
    "token": "044DCcituJDHbxBhPcgOuhCb0Av/xnNiUFxqPTVD6hDfnU=MDE5MDA2MTc1NjYwMzYwMzk0MTE0OTY5NlNvYXBVSTE0MDEyMTkzOTIxMzA=",
    "stackId": 1,
    "stateId": 1,
    "rid": "e51b593df7a884ea",
    "action": "execute",
    "actionRequest": {
        "returnControlIDs": "32|7|1[28,29,66]",
        "maxPageSize": "4",
        "formOID": "W01012B",
        "formActions": [
            {
                ".type": "com.oracle.e1.jdemf.FormAction",
                "command": "SelectRow",
                "controlID": "1.0"
            },
            {
                ".type": "com.oracle.e1.jdemf.FormAction",
                "command": "DoAction",
                "controlID": "65"
            }
        ]
    },
    "deviceName": "RESTclient"
}
Example - Execute Actions on Application - Response
{
   "fs_P0115_W0115A":    {
      "title": "Phone Numbers",
      "data":       {
         
		….condensed..
            "summary":             {
               "records": 3,
               "moreRecords": false
            }
         }
      },
      "errors": [],
      "warnings": []
   },
   "stackId": 1,
   "stateId": 2,
   "rid": "e51b593df7a884ea",
   "currentApp": "P0115_W0115A_ZJDE0001",
   "sysErrors": []
}

Notice that the state ID has increased after each service call. Also notice that the "currentApp" has changed, and the JSON is representing the Phones application.

Adding a Phone Number

Example - Adding a Phone Number - Request shows how to execute an additional action on this stack that adds a phone number. You can do this as many times as you want, incrementing the state ID each time. The action does not include saving the information; it only populates the grid.

Example - Adding a Phone Number - Request
{
    "token": "044DCcituJDHbxBhPcgOuhCb0Av/xnNiUFxqPTVD6hDfnU=MDE5MDA2MTc1NjYwMzYwMzk0MTE0OTY5NlNvYXBVSTE0MDEyMTkzOTIxMzA=",
    "stackId": 1,
    "stateId": 2,
    "rid": "e51b593df7a884ea",
    "action": "execute",
    "actionRequest": {
        "formOID": "W0115A",
        "formActions": [
            {
                "gridAction": {
                    "gridID": "1",
                    "gridRowInsertEvents": [
                        {
                            "gridColumnEvents": [
                                {
                                    "value": "720",
                                    "command": "SetGridCellValue",
                                    "columnID": "28"
                                },
                                {
                                    "value": "12345",
                                    "command": "SetGridCellValue",
                                    "columnID": "29"
                                },
                                {
                                    "value": "CAR",
                                    "command": "SetGridCellValue",
                                    "columnID": "27"
                                }
                            ]
                        }
                    ]
                }
            }
        ]
    },
    "deviceName": "RESTclient",
    "ssoEnabled": true
}

Execute Close Application: Request and Response

Lastly, the JSON code should contain commands to press the Save button and close the application stack. This saves all phone records that were added to the grid.

Example - Execute Close Application - Request
{
    "token": "044DCcituJDHbxBhPcgOuhCb0Av/xnNiUFxqPTVD6hDfnU=MDE5MDA2MTc1NjYwMzYwMzk0MTE0OTY5NlNvYXBVSTE0MDEyMTkzOTIxMzA=",
    "stackId": 1,
    "stateId": 3,
    "rid": "e51b593df7a884ea",
    "action": "close",
    "actionRequest": {
        "formOID": "W0115A",
        "formActions": [
            {
                "command": "DoAction",
                "controlID": "4"
            }
        ]
    },
    "deviceName": "RESTclient",
    "ssoEnabled": true
}
Example - Execute Close Application - Response
{
   "fs_P0115_W0115A":    {
      "title": "Phone Numbers",
      "data":       {
		 ….condensed…
            ],
            "summary":             {
               "records": 4,
               "moreRecords": false
            }                  
         }
      },
      "errors": [],
      "warnings": []
   },
   "stackId": 0,
   "stateId": 0,
   "rid": "",
   "currentApp": "P0115_W0115A_ZJDE0001",
   "sysErrors": []
}

When the stack is closed, the stack ID, state ID, and rid are cleared, indicating you can no longer interact with that stack.

Mobile Application Example

The application manages the alternate addresses for the 0 contact of an address number. It lists the first 10 "E" type records in the Address Book, and allows the user to select a record where they can add, update, or delete alternate addresses. Notice that the framework handles all of the stack maintenance for you within the ApplicationStack object. You do not need to manually manage the rid, stack ID, or state ID in your mobile application. The API does that for you.

An ApplicationStack variable is defined in the main DC class. You should define one of these for each stack you want to maintain. For example:

ApplicationStack appStackAddress = new ApplicationStack();

When the mobile application opens, it retrieves the Address Book records and saves the response in a data control variable for the P01012_W01102B form.

  public void getABRecords() {
 
        // Retrieve a list of customers from the P03013_W03013A form.
        LoginResponse lr = getLoginResponse();
 
        FormRequest formRequest = new FormRequest();
        formRequest.setReturnControlIDs("1");
        formRequest.setFormName("P01012_W01012B");
        formRequest.setReturnControlIDs("54|1[19,20]");
        formRequest.setFormServiceAction("R");
        formRequest.setMaxPageSize("10");
        FSREvent findFSREvent = new FSREvent();
        String name = lr.getUsername();
        findFSREvent.setFieldValue("54", "E");
        findFSREvent.doControlAction("15"); // Find button
        formRequest.addFSREvent(findFSREvent);
 
 
        try {
            //open P01012_W01012B
            String response = appStackAddress.open(formRequest);
 
            p01012_W01012B_FormParent =
                    (P01012_W01012B_FormParent)JSONBeanSerializationHelper.fromJSON(P01012_W01012B_FormParent.class,
                                                                                    response);
 
 
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            throw new AdfException(e.getMessage(), AdfException.ERROR);
        }
 
    }

When an Address Book record is selected in the mobile application, the mobile application performs a service call to perform the row exit on the open application. It checks to make sure the interconnect happened, and then performs a second interconnect to Work with Alternate Addresses form. Finally, it checks that it is on the addresses form and then deserializes the response to the data control variable for the addresses form. The Address Book application has a multi-select grid, and taking a row exit when multiple records are selected causes issues; therefore the action is to deselect all, and then select the correct one.

public String goToAltAddress() {
 
        String nav = "";
        ActionRequest getAddressAction = new ActionRequest();
        FSREvent selectEvent = new FSREvent();
        try {
            getAddressAction.setFormOID("W01012B");
            Integer rowIndex = (Integer)AdfmfJavaUtilities.evaluateELExpression("#{pageFlowScope.selectedABIndex}");
            if (rowIndex != null) {
                selectEvent.unselectAllGridRows("1");
   //select the row they chose
                selectEvent.selectRow("1", rowIndex.intValue());                //deselect the previous row (W01012B has multi select grid and we are only viewing one at a time
                selectEvent.doControlAction("67"); //whos who exit
                getAddressAction.addFSREvent(selectEvent);
                String response = appStackAddress.executeActions(getAddressAction);
                if (appStackAddress.getLastAppStackResponse().checkSuccess("P0111_W0111A")) {
                    selectWhosWho();
                    if (appStackAddress.getLastAppStackResponse().checkSuccess("P01111_W01111E")) {                        
                        nav = "to_Addresses";
                    }
 
                }
            }
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            throw new AdfException(e.getMessage(), AdfException.ERROR);
        }
 
public void selectWhosWho() {      
        
        if (appStackAddress.getLastAppStackResponse().checkSuccess("P0111_W0111A")) {
 
            try {
                //send another request to go to alt address
                ActionRequest selectAction = new ActionRequest();
                FSREvent findEvent = new FSREvent();
                //findAction.setReturnControlIDs("32|7|1[28,29,66]");
                selectAction.setFormOID("W0111A");
                findEvent.selectRow("1", 0); //first whos who row
                findEvent.doControlAction("148");
                selectAction.addFSREvent(findEvent);
                String response = appStackAddress.executeActions(selectAction);
 
                if (appStackAddress.getLastAppStackResponse().checkSuccess("P01111_W01111E")) {
 
                    p01111_W01111E_FormParent =
                            (P01111_W01111E_FormParent)JSONBeanSerializationHelper.fromJSON(P01111_W01111E_FormParent.class, response);                   
                 
                }
 
            } catch (JDERestServiceException e) {
                JDERestServiceProvider.handleServiceException(e);
            } catch (Exception e) {
                throw new AdfException(e.getMessage(), AdfException.ERROR);
            }
        }
        
        
    } new AdfException(e.getMessage(), AdfException.ERROR);
        }
 
        return nav;
    }

The user can then navigate to an individual address to change or delete it. They can also add a new one.

This method handles saving an existing address or adding a new one. It also handles any errors that were returned from the service.

public String saveAddress() {
        String nav = "";
        String formMode = (String)AdfmfJavaUtilities.evaluateELExpression("#{pageFlowScope.formMode}");
        ActionRequest addAction = new ActionRequest();
        FSREvent saveEvent = new FSREvent();
        Integer rowIndex = null;
 
        if (formMode.equals("A") && this.getArrayError().size() > 0) {
            //there was an error on a previously added one, it may be at the form level so we can't easily identify the record to fix, close the form and open it again
            cancelAddress();
        }
 
                //clear errors each time to try again
                setArrayError(new ArrayList());
 
 
        try {
 
            addAction.setFormOID("W01111E");
            GridAction gridAction = new GridAction();
 
            if (formMode.equals("A")) {
                GridRowInsertEvent gri = new GridRowInsertEvent();
                //set the column values
                gri.setGridColumnValue("34", singleAddressRow.getSAddressType_34().getValue());
                gri.setGridColumnValue("26", singleAddressRow.getSAddressLine1_26().getValue());
                gri.setGridColumnValue("22", singleAddressRow.getSCity_22().getValue());
                gri.setGridColumnValueDate("18", singleAddressRow.getDtBeginDate_18().getDate());
 
                //add the row
                gridAction.insertGridRow("1", gri);
            } else {
                if (rowIndex == null) {
                    rowIndex =
                            (Integer)AdfmfJavaUtilities.evaluateELExpression("#{pageFlowScope.selectedAddressIndex}");
                }
                GridRowUpdateEvent gru = new GridRowUpdateEvent();
                //set the column values
                gru.setGridColumnValue("34", singleAddressRow.getSAddressType_34().getValue());
                gru.setGridColumnValue("26", singleAddressRow.getSAddressLine1_26().getValue());
                gru.setGridColumnValue("22", singleAddressRow.getSCity_22().getValue());
                gru.setGridColumnValueDate("18", singleAddressRow.getDtBeginDate_18().getDate());
 
                //update the row
                gridAction.updateGridRow("1", rowIndex.intValue(), gru);
            }
            //add the grid action to the events
            saveEvent.addGridAction(gridAction);
 
            saveEvent.doControlAction("12"); //OK
            //addAction.setReturnControlIDs("32|7|1[28,29,66]");
            addAction.addFSREvent(saveEvent);
            String response = appStackAddress.executeActions(addAction);
 
            //after save it returns to whos who, open it again to get final list
 
 
            if (appStackAddress.getLastAppStackResponse().checkSuccess("P0111_W0111A")) {
                selectWhosWho();
                if (appStackAddress.getLastAppStackResponse().checkSuccess("P01111_W01111E")) {
                    nav = "__back";
                }
 
            } else {
                if (appStackAddress.getLastAppStackResponse().checkSuccess("P01111_W01111E")) {
 
                    P01111_W01111E_FormParent tempW0111E =
                        (P01111_W01111E_FormParent)JSONBeanSerializationHelper.fromJSON(P01111_W01111E_FormParent.class,
                                                                                        response);
                    //check for errors on the form
                    if (tempW0111E.getFs_P01111_W01111E() != null &&
                        tempW0111E.getFs_P01111_W01111E().getErrors() != null &&
                        tempW0111E.getFs_P01111_W01111E().getErrors().length > 0) {
                        //show error
                        addErrors(tempW0111E.getFs_P01111_W01111E().getErrors());
                    }
                }
 
            }
 
 
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            throw new AdfException(e.getMessage(), AdfException.ERROR);
        }
 
        return nav;
    }

The following sample code shows an example of the method to delete the address. After deleting and saving, the EnterpriseOne form closes, so you have to open it again with the selectWhosWho method.

public String deleteAddress(int key) {
 
        String nav = "";
 
        ActionRequest deleteActionRequest = new ActionRequest();
        FSREvent deleteEvent = new FSREvent();
        deleteActionRequest.setFormOID("W01111E");
        //deleteActionRequest.setReturnControlIDs("32|7|1[28,29,66]");
        deleteEvent.selectRow("1", key);
        //press Delete button
        deleteEvent.doControlAction("41");
        //press OK button
        deleteEvent.doControlAction("12");
        //add the FSR event to the request
        deleteActionRequest.addFSREvent(deleteEvent);
 
        try {
            String response = appStackAddress.executeActions(deleteActionRequest);
 
            if (appStackAddress.getLastAppStackResponse().checkSuccess("P0111_W0111A")) {
                selectWhosWho();
                if (appStackAddress.getLastAppStackResponse().checkSuccess("P01111_W01111E")) {                 
                    nav = "__back";
                } else {
                    //erors on delete?
                }
 
            } else if (appStackAddress.getLastAppStackResponse().checkSuccess("P01012_W01012B")) {
 
                nav = "to_AB";
            }
 
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            AdfException adfe = new AdfException(e.getMessage(), AdfException.ERROR);
            throw adfe;
        }
 
        return nav;
    }
 

After the application finishes working with the set of addresses, the application stack can be closed, as shown in the following example:

     appStackAddress.close();

ApplicationStack Methods

The following table describes the ApplicationStack methods:

Modifier and Type

Method

Description

String

open(FormRequest formRequest)

Opens a form, allowing further interactions with subsequent service calls.

String

executeActions(ActionRequest actionRequest)

Executes actions on an already open form.

String

close(ActionRequest actionRequest)

Closes all applications in the application stack, after executing the actions requested

String

close ()

Closes all applications in the application stack, without doing any further actions

void

setOverrideDefaultFeature(String overrideDefaultFeature)

Use this to set the default feature if you are using an ApplicationStack from a re-usable component. Similar to how you have to override the default feature for a form service call. Do this call before other requests.

ApplicationStackResponse

getLastAppStackResponse()

Returns the last response which includes the stack ID, state ID, rid and system errors.

ApplicationStackResponse Methods

The following table describes the ApplicationStackResponse methods:

Modifier and Type

Method

Description

boolean

checkSuccess (String appForm)

Returns true if the last response was for the appForm (for example P01012_W01012B) if the form does not match it returns false.

Data Service (Release 9.1.5.5)

The AIS Server provides an endpoint called "dataservice" for data query or count requests over tables or business views.

Data service calls are made using the DataRequest object. If you use the data service, you must include the "dataservice" capability in the required or used capabilities list.

Table Data Service Request Required Parameters

Parameter

Description

Values

targetName

The name of the table or view to count or query.

Example values: F0101 or V4210A

targetType

The object type to count or query: table or business view.

DataRequest.TARGET_TABLE

DataRequest.TARGET_VIEW

dataServiceType

The type of operation to be performed: count or query (represented by the value BROWSE).

DataRequest.TYPE_COUNT

DataRequest.TYPE_BROWSE

Table Data Service Request Optional Parameters

Parameter

Description

Values

findOnEntry

This parameter determines if the service performs an automatic find.

FormRequest.TRUE

FormRequest.FALSE

returnControlIDs

Columns to be returned in the form of Table.Column.

Example values:

F0101.AN8|F0101.PA8|F0101.ALPH

maxPageSize

The maximum amount of records to return for a browse operation

query

A query, using the column names (F0101.AN8) for a complex select operation. The only difference between this and the query described in Query Events, is the way the control IDs are passed in.

Example - Data Service Example

This example requests either a count or records (browse) from the F0150 table, using a query for a specific structure type (ES) and parent (PA8). For a count, it uses the helper to get the count value. For the browse, it de-serializes the response into a generated class (generated for data request).

public void executeDataRequest(boolean count) {
 
        try {
 
            //created the data request
            DataRequest children = new DataRequest();
         
 
            //it is a count type
            if(count){
            children.setDataServiceType(DataRequest.TYPE_COUNT);
            }
            else{
                children.setDataServiceType(DataRequest.TYPE_BROWSE);
                children.setReturnControlIDs("F0150.AN8|F0150.OSTP");
            }
 
            //over the F0150 table
            children.setTargetName("F0150");
            //indicate table type
            children.setTargetType(DataRequest.TARGET_TABLE);
 
            //create a query
            Query childrenQ = new Query();
            //set it to do a find
            childrenQ.setAutoFind(true);
            //match all conditions
            childrenQ.setMatchType(Query.MATCH_ALL);
 
            //first condition is value of ES in the OSTP column
            childrenQ.addStringCondition("F0150.OSTP", StringOperator.EQUAL(), "ES");
            //second condition is value of 7500 in the PA8 column
            childrenQ.addStringCondition("F0150.PA8", StringOperator.EQUAL(), "7500");
 
            //set the query to the request
            children.setQuery(childrenQ);
 
            //send the request in, indicatging the data service uri
            String response =
                JDERestServiceProvider.jdeRestServiceCall(children, JDERestServiceProvider.POST,
                                                          JDERestServiceProvider.DATA_SERVICE_URI);
 
 
            if(count){
            //marchal the response to the CountResponse class
            f0150CountResponse childrenCount =
                (f0150CountResponse) JSONBeanSerializationHelper.fromJSON(f0150CountResponse.class, response);
 
            setCount(childrenCount.getDs_F0150().getCount());
            }
            else{
                setF0150fp(
                    (DATABROWSE_F0150_FormParent) JSONBeanSerializationHelper.fromJSON(DATABROWSE_F0150_FormParent.class,
                                                                                     response));
                
 
            }
 
 
        } catch (JDERestServiceException e) {
            JDERestServiceProvider.handleServiceException(e);
        } catch (Exception e) {
            AdfException adfe = new AdfException(e.getMessage(), AdfException.ERROR);
            throw adfe;
        }
    }

Data Service Data Aggregation (API 2.2.1 and EnterpriseOne Tools Release 9.2.0.2)

Data service data aggregation provides the capability to request an aggregation of values in a data service request. To perform aggregation functions over records from tables or business views, you must add both dataservice and dataServiceAggregation to the used capabilities list before using the aggregation APIs.

The following aggregation information is sent in the DataRequest object attribute:

aggregation, AggregationInfo object

An aggregation consists of the following three arrays of objects:

  • aggregations array.

    An array of columns with their associated aggregation type.

  • groupBy array.

    An array of columns to group by.

  • orderBy array.

    An array of columns to order by with the direction.

    You can also order by an aggregation result.

  • having array.

    An array of aggregations with conditions to reduce the result based on aggregation values.

The following table describes the seven column-specific aggregation types that are available. You can combine more than one type in a single request. Based on the results of a find or query, multiple aggregations can be performed over multiple columns.

Table Column-specific Aggregation Types

Aggregation

Constant

Sum

AggregationType.AGG_TYPE_SUM()

Minimum

AggregationType.AGG_TYPE_MIN()

Maximum

AggregationType.AGG_TYPE_MAX()

Average

AggregationType.AGG_TYPE_AVG()

Count Distinct

AggregationType.AGG_TYPE_COUNT_DISTINCT()

Average Distinct

AggregationType.AGG_TYPE_AVG_DISTINCT()

Sum Distinct

AggregationType.AGG_TYPE_SUM_DISTINCT()

In addition, there is an aggregation type for performing a count called Count* that is available through the following API:

AggregationInfo_addCount();

There are two possible directions to order by:

  • Ascending, which uses the following constant:

    OrderByDirection.ORDER_DIRECT_ASCENDING()

  • Descending, which uses the following constant:

    OrderByDirection.ORDER_DIRECT_DESCENDING()

Example - Calling an Aggregation Type Data Request shows how to call an aggregation type data request. In the example, two data requests are sent in a single batch to the AIS Server. The first one is an aggregation of columns in V0101 without a Groupby array. The second is an aggregation request over F060116 with a Groupby array.

At the end of the data request, the AggregationResponseHelper methods are used to get the specific aggregations from the responses. If there is a Groupby array in the response, the helper will return a JDONArray, which you will have to iterate with to get individual aggregate values for each group. Specific AggregationResponseHelper methods are provided for consuming a batch response.

Example - Calling an Aggregation Type Data Request

public void dataRequestBatchAggregation()        {
 
         
            /*** One ****/
            DataRequest dataAggregation = new DataRequest();
            dataAggregation.setDataServiceType(DataRequest.TYPE_AGGREGATION);
            dataAggregation.setTargetName("V0101");
            dataAggregation.setTargetType(DataRequest.TARGET_VIEW);
 
            AggregationInfo aggregation = new AggregationInfo();
 
            aggregation.addAggregationColumn("AN8", AggregationType.AGG_TYPE_SUM());
            aggregation.addAggregationColumn("AN8", AggregationType.AGG_TYPE_AVG());
            aggregation.addAggregationColumn("AT1", AggregationType.AGG_TYPE_COUNT_DISTINCT());
            aggregation.addCount();
 
            dataAggregation.setAggregation(aggregation);
 
            Query an8Query = new Query();
            an8Query.setAutoFind(true);
            an8Query.setMatchType(Query.MATCH_ALL);
 
 
            an8Query.addNumberCondition("F0101.AN8", NumericOperator.LESS(), 6001);
            dataAggregation.setQuery(an8Query);
 
 
            /****TWO*****/
            DataRequest dataAggregation2 = new DataRequest();
            dataAggregation2.setFindOnEntry(true);
            dataAggregation2.setDataServiceType(DataRequest.TYPE_AGGREGATION);
            dataAggregation2.setTargetName("F060116");
            dataAggregation2.setTargetType(DataRequest.TARGET_TABLE);
 
            AggregationInfo aggregation2 = new AggregationInfo();
 
            aggregation2.addAggregationColumn("SAL", AggregationType.AGG_TYPE_SUM());
            aggregation2.addAggregationColumn("SAL", AggregationType.AGG_TYPE_AVG());
            aggregation2.addAggregationColumn("SAL", AggregationType.AGG_TYPE_AVG_DISTINCT());
            aggregation2.addAggregationColumn("SAL", AggregationType.AGG_TYPE_MAX());
            aggregation2.addAggregationColumn("SAL", AggregationType.AGG_TYPE_MIN());
            aggregation2.addAggregationColumn("SAL", AggregationType.AGG_TYPE_SUM_DISTINCT());
            aggregation2.addCount();
            aggregation2.addAggregationColumn("AN8", AggregationType.AGG_TYPE_COUNT_DISTINCT());
 
            aggregation2.addAggregationGroupBy("HMCO");
            aggregation2.addAggregationGroupBy("HMCU");
 
            aggregation2.addAggregationOrderBy("HMCO", OrderByDirection.ORDER_DIRECT_DESCENDING());
 
            dataAggregation2.setAggregation(aggregation2);
 
 
            BatchDataRequest batchDataRequest = new BatchDataRequest();
            batchDataRequest.getDataRequests().add(dataAggregation);
            batchDataRequest.getDataRequests().add(dataAggregation2);
 
 
            String response = JDERestServiceProvider.jdeRestServiceCall(batchDataRequest, JDERestServiceProvider.POST, JDERestServiceProvider.DATA_SERVICE_URI);
 
         
            JSONArray array = AggregationResponseHelper.getAggregateValuesArrayBatch(response, "F060116", 1);
             
            setSalaryChartList(new ArrayList<salaryChart>());
            setCountChartList(new ArrayList<CountChart>());
            for (int i = 0; i < array.length(); i++) {
 
                JSONObject aGroup = array.getJSONObject(i);
                JSONObject groupByInfo = (JSONObject) aGroup.get(AggregationResponseHelper.GROUP_BY);
                Double average = (Double) aGroup.get("SAL_AVG");
                Integer count = (Integer) aGroup.get("COUNT");
 
                salaryChartList.add( new salaryChart( average, groupByInfo.get("HMCU").toString().trim()));
                countChartList.add( new CountChart( count, groupByInfo.get("HMCU").toString().trim()));
              
            }
      
             setAverage(AggregationResponseHelper.getSimpleAggregateValueBatch(response, "V0101", 0, AggregationType.AGG_TYPE_AVG(), "AN8"));
           
        
 
        }

Example - Having Example

This example shows how to reduce the data set with conditions based on the aggregate values, by using a having clause.

public void dataRequestHaving()
 
        DataRequest dataAggregation2 = new DataRequest();
        dataAggregation2.setFindOnEntry(true);
        dataAggregation2.setDataServiceType(DataRequest.TYPE_AGGREGATION);
        dataAggregation2.setTargetName("F060116");
        dataAggregation2.setTargetType(DataRequest.TARGET_TABLE);
 
        //create aggregation info object and add desired aggregations
        AggregationInfo aggregation2 = new AggregationInfo();
 
        aggregation2.addAggregationColumn("SAL", AggregationType.AGG_TYPE_AVG());
        aggregation2.addCount();
 
        //add desired group by columns
        aggregation2.addAggregationGroupBy("HMCU");
 
        //add order by average sal dec and hmcu dec with direction
        aggregation2.addAggregationOrderBy("SAL", AggregationType.AGG_TYPE_AVG(),                                           OrderByDirection.ORDER_DIRECT_DESCENDING());
 
       aggregation2.addAggregationOrderBy("HMCU", OrderByDirection.ORDER_DIRECT_DESCENDING());
        
        //add having average salary greater than 50,000
        Having having = new Having();
        having.addNumberCondition("SAL", AggregationType.AGG_TYPE_AVG(), NumericOperator.GREATER(), 50000);
        dataAggregation2.setHaving(having);
 
        //set the aggregation info in the request
        dataAggregation2.setAggregation(aggregation2);
 
 
        String response =
            JDERestServiceProvider.jdeRestServiceCall(dataAggregation2, JDERestServiceProvider.POST,
                                                      JDERestServiceProvider.DATA_SERVICE_URI);
 
 
		//use helper to get array of values (add them to a list)
            JSONArray array = AggregationResponseHelper.getAggregateValuesArray(response, "F060116");
        setSalaryChartList(new ArrayList<salaryChart>());
        setCountChartList(new ArrayList<CountChart>());
        for (int i = 0; i < array.length(); i++) {
 
            JSONObject aGroup = array.getJSONObject(i);
            JSONObject groupByInfo = (JSONObject) aGroup.get(AggregationResponseHelper.GROUP_BY);
            Double average = (Double) aGroup.get("SAL_AVG");
            Integer count = (Integer) aGroup.get("COUNT");
 
            salaryChartList.add( new salaryChart( average, groupByInfo.get("HMCU").toString().trim()));
            countChartList.add( new CountChart( count, groupByInfo.get("HMCU").toString().trim()));
           
        }
         
 
    }       

Understanding the Preferences Service (API 2.2.1 and EnterpriseOne Tools Release 9.2.0.2)

The preferences service enables the caller to save and retrieve EnterpriseOne user-level information that is stored by user, role, or *PUBLIC in the User Overrides Table (F98950) in EnterpriseOne.

The keys to the information are the Type (UOTY), User ID (USER), Sequence (SEQ) and Object Name (OBNM). The data is a string and is stored in the blob column BINDTA. All preference records are written with Type=PS.

The JDEMobileFramework API enables you to save a serialized HashMap of data to this table using the methods in the PreferencesService object. For the get operation, the data is de-serialized to a HashMap and returned.

It is important to note that the system stores the data as serialized values. For example, a Date object will be stored as a formatted string, which you must convert back to a date after the response is returned.

If a mobile application has multiple sets of data that need to be saved separately, a sequence field is available as a key. The default sequence value is zero if you do not specify a sequence.

Set and put actions are performed on behalf of the logged in user, with user records stored in the USER column. You can use the User Overrides application (P98950) in EnterpriseOne to manage the records. In P98950, you can copy records to different roles including *PUBLIC. The record will be retrieved from P98950 based on the user, role, or *PUBLIC hierarchy.

Preference Service Endpoint

The preference service is exposed by the AIS Server at the endpoint:

http://<aishost>:<port>/jderest/preference

Capability

The preference service capability is exposed in the default configuration as "preferenceService." You must add this to your used or required capability list within your mobile application to use this capability.

JSON Example of a Preference Service Request

The preferenceData element can contain any string. In the examples in this section, the strings are serialized HashMap objects storing name-value pairs for several different preference values.

Get Preferences: Request and Response

Example - Get Preferences - Request and Example - Get Preferences - Response show the JSON representation of the Get Preferences request and response.

Example - Get Preferences - Request
{
    "token": "0440rV4RxUjDA4wDISJAvbhHtIXvju74FHMak7lM64gdsU=MDE5MDEwMTIzNDI0ODcwNTc1Mjg5MTEyNFJFU1RjbGllbnQxNDQ1ODg5ODY0MTYw",
    "action": "GET",
    "objectName": "M55100",
    "sequence": 0,
    "preferenceData": "{\"pref2\":15.45,\"pref1\":\"Preference 1 String\",\"pref3\":8,\"pref4\":1443645908933}",
    "deviceName": "RESTclient"
}	
Example - Get Preferences - Response
{
   "objectName": "M55100",
   "type": "PS",
   "preferenceData": "{\"pref2\":15.45,\"pref1\":\"Preference 1 String\",\"pref3\":8,\"pref4\":1443645908933}",
   "sequence": 0
}

Put Preferences: Request and Response

Example - Put Preferences - Request and Example - Put Preferences - Response provide an example of the JSON representation of the Put Preferences request and response.

Example - Put Preferences - Request
{ 
   "token": "0440rV4RxUjDA4wDISJAvbhHtIXvju74FHMak7lM64gdsU=MDE5MDEwMTIzNDI0ODcwNTc1Mjg5MTEyNFJFU1RjbGllbnQxNDQ1ODg5ODY0MTYw",
    "action": "PUT",
    "objectName": "M55100",
    "preferenceData": "{\"pref2\":15.45,\"pref1\":\"Preference 1 String\",\"pref3\":8,\"pref4\":1443645908933}",
    "deviceName": "RESTclient"
}
Example - Put Preferences - Response
{
   "objectName": "M55100",
   "type": "PS",
   "preferenceData": "{\"pref2\":15.45,\"pref1\":\"Preference 1 String\",\"pref3\":8,\"pref4\":1443645908933}"
}

Examples of APIs Used to Enable Preferences in a Mobile Application

A mobile application can manage storage of preferences as needed by using the APIs. Also, remember that the "preferenceService" capability must be added to the used or required capability list in the mobile application's about.properties to support this functionality.

Example - Preference Variables, HashMap, and Preference Key

This example shows several variables designed to hold preference values along with a HashMap for serializing and saving the values. The key to these preferences is the mobile application ID, which is M55100, as shown here:

private String pref1Str;
 private Integer pref2Int;
 private BigDecimal pref3BigD;
 private Date pref4Date;
 
 private HashMap<String, Object> preferenceMap = new HashMap<String, Object>();
 
 private static final String PREF_KEY = "M55100";

Example - Get Preferences API

A method is defined to retrieve preferences, calling the API with the key. When the method is called, the values will be populated based on the data saved.

public void retrievePreferences() {
 
        try {
            PreferenceService prefService = new PreferenceService();
            this.setPreferenceMap(prefService.getPreferences(PREF_KEY));
 
 
        } catch (Exception e) {
            AdfException adfe = new AdfException(e.getMessage(), AdfException.ERROR);
            throw adfe;
        }
    }

Example - Get Preferences API

A method is defined to save preferences, calling the API with the key. When the method is called, the values in the variables will be saved in the database for that user.

    public void putPreferences() {
        try {
            PreferenceService prefService = new PreferenceService();
 
            prefService.setPreferences(PREF_KEY, this.getPreferenceMap());
 
        } catch (Exception e) {
            AdfException adfe = new AdfException(e.getMessage(), AdfException.ERROR);
            throw adfe;
        }
    }

In the setter for the hash map, the individual variables are updated with values from the map.

public void setPreferenceMap(HashMap<String, Object> preferenceMap) {
        this.preferenceMap = preferenceMap;
        this.pref1Str = (String) preferenceMap.get("pref1Str");
        this.pref2Int = (Integer) preferenceMap.get("pref2Int");
 
        //Big decimal serialized using Double, use Double to de-serialize
        this.pref3BigD = new BigDecimal((Double) preferenceMap.get("pref3BigD"));
 
        //dates are serialized using this format, use the same to de-serialize
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
        String dateString = (String) preferenceMap.get("pref4Date");
 
        try {
 
            this.pref4Date = sdf.parse(dateString);
        } catch (Exception e) {
            AdfException adfe = new AdfException(e.getMessage(), AdfException.ERROR);
            throw adfe;
        }
    }

In the getter for the hash map, the individual variables are set in the map and returned.

    public HashMap<String, Object> getPreferenceMap() {
 
        this.preferenceMap = new HashMap<String, Object>();
        preferenceMap.put("pref1Str", this.pref1Str);
        preferenceMap.put("pref2Int", this.pref2Int);
        preferenceMap.put("pref3BigD", this.pref3BigD);
        preferenceMap.put("pref4Date", this.pref4Date);
        return preferenceMap;
    }