Modifying Data

The OData service supports Create, Update and Delete operations for some or all exposed entities. Please note that data modification via the API is only available in Priority version 17.2 and above.

Creating an Entity

To create an entity in a collection, the client sends a POST request to that collection’s URL. The POST body MUST contain a single valid entity’s information. The request below creates a new part family in the Part Families form.

POST serviceRoot/FAMILY_LOG 
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json

{
    "FAMILYNAME": "765",
    "FAMILYDESC": "My OData Family"
}

Response Payload

{
  "@odata.context": "serviceRoot/$metadata#FAMILY_LOG/$entity",
  "FAMILYNAME": "765",
  "FAMILYDESC": "My OData Family",
  "EFAMILYDES": null,
  "TECHFLAG": null,
  "DEBITFLAG": null,
  "PROJPROCESS": null,
  ...
  "FAMILY": 26
}

To create an entity related to an entity (for example, an ORDERITEM that is part of an ORDER), navigate to the entity using its identifying key property, then specify the related resource in which to insert a new line.

POST serviceroot/ORDERS('SO18000002')/ORDERITEMS_SUBFORM 
Content-Type: application/json

{
  "PARTNAME": "TR0001",
  "TQUANT": 5,
  "DUEDATE": "2018-03-15T00:00:00+02:00"
}

Response Payload

{
    "@odata.context": "serviceroot/$metadata#ORDERS('SO18000002')/ORDERITEMS_SUBFORM/$entity",
    "PARTNAME": "TR0001",
    "PDES": "Almonds, mascarpone & strawberries tart",
    "TQUANT": 5,
    "TUNITNAME": "ea",
    "PRICE": 33,
    "ICODE": "$",
    "DUEDATE": "2018-03-15T00:00:00+02:00",
    ...
    "KLINE": 1
}

Composite Keys

Certain entities might have a composite key comprised of multiple properties.To specify a composite key, separate the different properties with a comma(,). Key property information is available in the $metadata of the entity.

POST serviceroot/AINVOICES(IVNUM='T9696',IVTYPE='A',DEBIT='D')/AINVOICEITEMS_SUBFORM  

Content-Type: application/json

{
  "PARTNAME": "TR0001",
  "TQUANT": 3
}

You can create an entity with multiple related child entities (for example, an ORDER with the relevant ORDERITEMS). To do so, specify the values for the related resources as part of the request.

POST serviceRoot/ORDERS 
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json
{
    "CUSTNAME": "007",
    "ORDERITEMS_SUBFORM": [
        {
            "PARTNAME": "111-001",
            "DUEDATE": "2016-08-01T00:00:00+03:00"
        },
        {
            "PARTNAME": "111-002",
            "DUEDATE": "2016-08-01T00:00:00+03:00"
        }
     ]
}

Response Payload

{
  "@odata.context": "serviceRoot/$metadata#ORDERS/$entity",
  "CUSTNAME": "007",
  "CDES": "ACME Inc.",
  "NAME": null,
  "POSITIONDES": null,
  "CURDATE": "2016-08-07T00:00:00+03:00",
  "ORDNAME": "SO16000007",
  "BOOKNUM": null,
  "DOCNO": null,
  "PROJDES": null,
  "ORDSTATUSDES": "Draft",
  "BOOLCLOSED": null,
  ...
  "PIKORDER": 0,
  "FOLLOWUPIV": 88
}

‘21.1’

If you create or update both the parent entity and its child entity at the same time, the response includes both the parent and child entities.

POST /ui/odata/Priority/tabmob.ini/usdemo/ORDERS HTTP/1.1
Host: www.eshbelsaas.com
Content-Type: application/json
Authorization: Basic YXBpZGVtbzoxMjM=
Cookie: GCLB=CMbzkMzAjKf7ygE
Content-Length: 350

{
    "CUSTNAME" : "00000002",
    "ORDERITEMS_SUBFORM" : 
    [
        {
            "PARTNAME": "TR0001",
            "TQUANT": 10,
            "DUEDATE": "2021-08-30T00:00:00+02:00"
        },
        {
            "PARTNAME": "TR0001",
            "TQUANT": 11,
            "DUEDATE": "2021-09-30T00:00:00+02:00"
        }
    ]
}

Response Payload

"@odata.context": "https://www.eshbelsaas.com/ui/odata/Priority/tabmob.ini/usdemo/$metadata#ORDERS(ORDERITEMS_SUBFORM())/$entity",
    "CUSTNAME": "00000002",
    "CDES": "AACompany",
    ...
    "ORDERITEMS_SUBFORM": [
        {
            "PARTNAME": "TR0001",
            "PDES": "Almonds, mascarpone & strawberries tart",
            ...
        },
        {
            "PARTNAME": "TR0001",
            "PDES": "Almonds, mascarpone & strawberries tart",
            "TQUANT": 11,
            ...
        }
    ]
}

Updating an Entity

To update an existing entity, send a PATCH request with the values you wish to modify.

Note: You cannot refer to an entity using its Auto-unique key when sending a PATCH request, as it is a read-only property. Use the unique key instead.

PATCH serviceRoot/FAMILY_LOG('765')
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json

{
    "FAMILYDESC": "My Updated Family"
}

Response Payload

{
  "@odata.context": "serviceRoot/$metadata#FAMILY_LOG/$entity",
  "FAMILYNAME": "765",
  "FAMILYDESC": "My Updated Family",
  "EFAMILYDES": null,
  "TECHFLAG": null,
  "DEBITFLAG": null,
  "PROJPROCESS": null,
  ...
  "FAMILY": 26
}

To update an entity related to an entity (for example, an ORDERITEM that is part of an ORDER), navigate to the entity using its identifying key property, then specify the related resource you are updating.

PATCH serviceroot/ORDERS('SO18000002')/ORDERITEMS_SUBFORM(1)
Content-Type: application/json
Authorization: Basic YXBpZGVtbzoxMjM=

{
  "TQUANT": 10
}

Response Payload

{
    "@odata.context": "serviceroot/$metadata#ORDERS('SO18000002')/ORDERITEMS_SUBFORM/$entity",
    "PARTNAME": "TR0001",
    "PDES": "Almonds, mascarpone & strawberries tart",
    "TQUANT": 10,
    "TUNITNAME": "ea",
    "PRICE": 33,
    "ICODE": "$",
    "DUEDATE": "2018-03-15T00:00:00+02:00",
    ...
    "KLINE": 1
}

Attaching Files

‘21.0’

To attach a file in an attachments form, provide its data URL in the body of your POST request. Note the URL in the example below has been trimmed to keep things short.

Supported file types are based on MIME types allowed by the application server. A list of common MIME types can be found here

POST serviceroot/ORDERS('SO21000113')/EXTFILES_SUBFORM 

Content-Type: application/json

{
    "EXTFILEDES": "myorder",
    "EXTFILENAME": "data:application/vnd.openxmlformats-
    officedocument.wordprocessingml.document;base64,UEsDBBQAAAAIAMhJhUzM9xURzwsAACxjAAAT AAAAY3VzdG9tWG1sL2l0ZW0xLnhtbO1dS28ktxHmhQc..........."
}

‘22.0’

Starting with version 22.0, you can provide an extension in the optional SUFFIX field. In this case the system will use the provided extension rather than identfying by MIME type.

POST serviceroot/ORDERS('SO21000113')/EXTFILES_SUBFORM 

Content-Type: application/json

{
    "EXTFILEDES": "myorder",
    "EXTFILENAME": "data:application/vnd.openxmlformats-
    officedocument.wordprocessingml.document;base64,UEsDBBQAAAAIAMhJhUzM9xURzwsAACxjAAAT AAAAY3VzdG9tWG1sL2l0ZW0xLnhtbO1dS28ktxHmhQc...........",
    "SUFFIX": "docx"
}

Adding or Modifying Text

[20.0]

To work with text, provide a JSON object that contains the text you would like to add. The JSON object should provide the following properties:

Property Explanation Example
TEXT HTML text, including tags. Some text
more text.
SIGNATURE Determines whether to appends the user’s signature to the the inserted text. Possible values are true or false false
APPEND Determines whether the text will replace the existing text or be appened to it. Possible values are true or false true

Important: If you accessed text forms before version 20.0 of Priority, you needed to use square brackets [] to access text forms. This is no longer necessary; you should ensure your code no longer includes square brackets.

Notes:

  • If you are working with RTL languages (e.g. Hebrew), it is important that you insert proper direction tags in the text body.
  • There is no difference between PATCH and POST for the purpose of working with text. The APPEND property governs whether text is replaced or added.

Example:

PATCH serviceroot/ORDERS('SO20000422')/ORDERSTEXT_SUBFORM
Content-Type: application/json
Authorization: Basic YXBwZGVtbzoxMjM=

  {
      "TEXT": "This is my order. <br> There are many like it, but this one is mine.",
      "APPEND": true,
      "SIGNATURE": false
  }

Response Payload

{
    "@odata.context": "serviceroot/$metadata#ORDERS('SO20000422')/ORDERSTEXT_SUBFORM/$entity",
    "TEXT": "<style> p,div,li {margin:0cm;font-size:10.0pt;font-family:'Arial';}li > font > p {display: inline-block;}</style><p dir=rtl><p dir=rtl>This is my order.<br> There are many like it, but this one is mine.</p> <p dir=rtl><font color=\"#0000ff\"><p dir=\"ltr\"><!--pdt-->06/04/20 14:00<!--edt--></p><p dir=\"ltr\">This is how the text looks like when retrieved by the REST API.&nbsp;</p><p dir=\"ltr\"><!--psi-->Sincerely,</p><p dir=\"ltr\">A Humble Documentarian</p><p dir=\"ltr\"></p><p dir=\"ltr\"><!--esi--></p></font><hr ss=\"\">&nbsp;<p dir=\"rtl\"><font color=\"#0000ff\"></font></p><p dir=\"rtl\" style=\"direction: ltr;\"><br></p> </p> ",
    "APPEND": null,
    "SIGNATURE": null
}

Images

To add images to text forms, insert them as a data URL as part of the text, e.g.:

"TEXT": "<p>This is my order. <br> There are many like it, but this one is mine.</p>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQEAAACvCAYAAAD9jWvXAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAI+SURBVHhe7dSxEYQwEARB8TEo/0Dl6KsAEwOXmm5nL4GbY865B/A5e1+v+7RrrfN+43cvECUCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCECcCkDbGHxJTEXuI/f4kAAAAAElFTkSuQmCC" alt="">"

Text Only Forms

Certain specialized text forms in Priority operate in Text-only mode (the :$.NOHTML.T variable is set to 1 for this form). In this case, the text retrieved will not contain any HTML tags, and line breaks are represented by \n.

When working with these forms, inputted text should be in plain text only. Additionally, these forms do not support signatures, and as such SIGNATURE is always treated as false.

Performing Batch Operations

19.1

$batch enables you to combine multiple requests into a single request and receiving multiple responses in a single response. For example, to path a part family and retrieve that part family with a single request such as in the request and response payload below.

For more information on $batch, see the official documentation on the OASIS website.

Batch commands are limited to 100 operations in one batch call. In versions before 21.0, this limit was 1,000 operations.

The Priority REST API supports the following features of batch operations:

  • Referencing new entities

Note: Once a change is saved by Priority to the database, it cannot be undone (although it may be overwritten). As such, batch operations do not support rollback, be it of the entire batch or inidivdual atomicity groups.

POST serviceRoot/$batch

Request

{
  "requests": [{
    "method": "PATCH",
    "url": "serviceRoot/FAMILY_LOG('765')",
    "headers": {
      "content-type": "application/json; odata.metadata=minimal; odata.streaming=true",
      "odata-version": "4.0"
    },
    "id": "g1",
    "body": {
      "FAMILYNAME": "765",
      "FAMILYDESC": "My OData Family"
    }
    },
    {
      "id": "r8",
      "method": "GET",
      "url": "serviceRoot/FAMILY_LOG('765')",
      "headers": {
        "content-type": "application/json; odata.metadata=minimal; odata.streaming=true",
        "odata-version": "4.0"
      },
      "dependsOn": ["g1"]
    }]
  }

Response Payload

  --batchresponse_8e86ef59-cb2c-4e46-b442-c8919a2826e9
Content-Type: multipart/mixed; boundary=changesetresponse_8917b75c-eae7-42a0-bbd8-443db93f1ca6

--changesetresponse_8917b75c-eae7-42a0-bbd8-443db93f1ca6
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: g1-r1

HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true
OData-Version: 4.0

{"@odata.context":"https://www.eshbelsaas.com/ui/odata/Priority/tabmob.ini/usdemo/$metadata#FAMILY_LOG/$entity","FAMILYNAME":"765","FAMILYDESC":"My OData Family","EFAMILYDES":null,"TECHFLAG":null,"DEBITFLAG":null,"PROJPROCESS":null,"TECHNICIANLOGIN":null,"FTCODE":null,"FTNAME":null,"DISTRFLAG":null,"DUTYPERCENT":0.00,"DUTYPERCENT1":0.00,"DUTYPERCENT2":0.00,"DUTYPERCENTTYPE":null,"SELLFLAG":null,"NEGBALFLAG":null,"FORECAST":null,"PARTNAME":null,"PARTDES":null,"STORAGETYPECODE":null,"STORAGETYPEDES":null,"SERIALMONTHEXPIRY":null,"ISMFAMILY":null,"MFAMILYNAME":null,"MFAMILYDES":null,"INACTIVE":null,"METERFLAG":null,"FAMILY":198}
--changesetresponse_8917b75c-eae7-42a0-bbd8-443db93f1ca6--
--batchresponse_8e86ef59-cb2c-4e46-b442-c8919a2826e9
Content-Type: application/http
Content-Transfer-Encoding: binary

Handling Dependencies with $Batch

One issue with creating an entity with related subentities is that it can be difficult to find where exactly an error occured. By splitting the creation process to distinct chunks using Batch, you can get more relevant error messages and have a clear understanding which command failed and why.

The following request demonstrates adding a new sales order, with each record inserted receiving its own ID:

{
  "requests": [{
      "id" : "1",
    "method": "POST",
    "url": "https://www.eshbelsaas.com/ui/odata/Priority/tabmob.ini/usdemo/ORDERS",
    "headers": {
      "content-type": "application/json; odata.metadata=minimal; odata.streaming=true; odata.continue-on-error=false",
      "odata-version": "4.0"
    },"body":{
        "CUSTNAME": "T000001"
    }
    },
    {
      "id": "2",
      "dependsOn": ["1"],
      "method": "POST",
      "url": "$1/ORDERITEMS_SUBFORM",
      "headers": {
        "content-type": "application/json; odata.metadata=minimal; odata.streaming=true; odata.continue-on-error=false",
        "odata-version": "4.0"
      },"body": {
          "PARTNAME": "MS0001",
            "DUEDATE": "2022-08-01T00:00:00+03:00"
      }
    }]
  }

As you can see, the url of the second requests references the new entity created by the first request (with $1). The response payload shown here is in JSON format.

Response Payload

{
    "responses": [
        {
            "id": "1",
            "status": 201,
            "headers": {
                "location": "https://www.eshbelsaas.com/ui/odata/Priority/tabmob.ini/usdemo/ORDERS(%27SO23000209%27)",
                "content-type": "application/json; odata.metadata=minimal; odata.streaming=true",
                "odata-version": "4.0"
            },
            "body": {
                "@odata.context": "https://www.eshbelsaas.com/ui/odata/Priority/tabmob.ini/usdemo/$metadata#ORDERS/$entity",
                "CUSTNAME": "T000001",
                "CDES": "Joshua P. Atkins",
                "NAME": null,
                "POSITIONDES": null,
                "CURDATE": "2023-02-22T00:00:00+02:00",
                "ORDNAME": "SO23000209",
                ...
                "ORD": 19811
            }
        },
        {
            "id": "2",
            "status": 201,
            "headers": {
                "location": "https://www.eshbelsaas.com/ui/odata/Priority/tabmob.ini/usdemo/ORDERS(%27SO23000209%27)/ORDERITEMS_SUBFORM(1)",
                "content-type": "application/json; odata.metadata=minimal; odata.streaming=true",
                "odata-version": "4.0"
            },
            "body": {
                "@odata.context": "https://www.eshbelsaas.com/ui/odata/Priority/tabmob.ini/usdemo/$metadata#ORDERS('SO23000209')/ORDERITEMS_SUBFORM/$entity",
                "PARTNAME": "MS0001",
                "PDES": "Lemon & Coconut mousse",
                ...
                "KLINE": 1
            }
        }
    ]
}

Deleting an Entity

To remove a resource, send an HTTP Delete to the resource URL.

DELETE serviceRoot/FAMILY_LOG('765')

To remove a related resource (e.g. an order item for a specific order), treat it as updating a related entity, specifying both the key for the resource and related resource.

DELETE serviceroot/ORDERS('SO18000002')/ORDERITEMS_SUBFORM(1)

Remember to take composite keys into consideration.

Error Handling

Since the API is essentially a wrapper around the Priority screens, any errors generated by the screens are included in the response. The example below demonstrates an attempt to create a new FAMILY_LOG entity with an invalid value for the DEBITFLAG field.

POST serviceRoot/FAMILY_LOG 
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json

{
    "FAMILYNAME": "765",
    "FAMILYDESC": "My OData Family"
    "DEBITFLAG": "Q"
}

Response Payload

<FORM
  TYPE="FAMILY_LOG">
    <FAMILY_LOG>
        <FAMILYNAME>790</FAMILYNAME>
        <FAMILYDESC>My invalid OData Family</FAMILYDESC>
        <DEBITFLAG>Q</DEBITFLAG>
        <FAMILY>0</FAMILY>
    </FAMILY_LOG>
    <InterfaceErrors>
        <text>Specify 'N' or 'Y' as the default value that will be filled in the Billable column of the "Reports of Project Hrs/Expenses" form. /n Leave the column blank if you do not want to have a default.</text>
    </InterfaceErrors>
</FORM>

Priority Software Cloud - Refreshing Metadata

‘22.0’

Whenever private customizations add fields to a form, these new fields will not appear in the REST API until the REST metadata is rebuilt for that form.

To ease development in Priority environments hosted in Priority Software’s Cloud, these environments support a special API action for refreshing the metadata.

POST serviceRoot/ClearEntityMetadata

In the body of the request, specify the entity where the metadata should be refreshed.

{
  "Entity": "NAME_OF_PARENT_ENTITY"
}

For example:

POST serviceRoot/ClearEntityMetadata

{
  "Entity": "ORDERS"
}

This deletes the current metadata for that entity. The metadata will be rebuilt when next API request is made to this entity.

If no body is specified in the request, metadata for all entities will be deleted.

There is no need to delete metadata for subforms, as they are included in their parent.

If you need to clear metadata for multiple entities, send multiple such requests (either individually or as a batch), specifying a single entity in each request.