Processings

Backend processings perform tasks like canceling orders or importing data via GraphQL mutations, potentially running long and requiring specific table fields like order_processings.

Processings are business logic operations that are performed in the backend. Examples of processings include canceling or finishing an order, validating or updating batches, importing data into a company, or create payment suggestions. In GraphQL, these are available as mutations.

Warning

Processings are potentially long-running operations. Depending on the nature of the processing and the volume of data it has to process (and return) may increase significantly and exceed the timeout for the HTTP request. In this case, you would get back an error status even though the process continues to run in the background and may finish successfully.

Processings are associated with a table and a table can have multiple processes. For each table, a field called <tablename>_processings is available. This is a field of the type <tablename>Processings. For instance, for the Order table, the field is called order_processings and its type is called OrderProcessings. You can see this in the following image:

Mutation schema

Under this field, there is one field for each available processing. These fields have the name of the processing. For instance, the Order table has processings called finish, cancel, confirm. These are available as fields under the order_processings field. This is exemplified here:

Processings schema

Processing example

Here is an example for executing a processing. The following GraphQL requests executes the finish process on an order.

Query

mutation finish_order($cid : Int!,
                      $orderno : Int!)
{
  useCompany(no : $cid)
  {
    order_processings
    {
      finish(
        args :
        {
          finishType :0
        },
        filter :
        {
          orderNo : {_eq : $orderno}
        }
      )
      {
        succeeded
        items
        {
          handledOrderLine
          {
            lineNo
            finishedNow
          }
        }
      }
    }
  }
}
Result

{
  "data": {
    "useCompany": {
      "order_processings": {
        "finish": {
          "succeeded": true,
          "items": [
            {
              "handledOrderLine": [
                {
                  "lineNo": 1,
                  "finishedNow": 1
                }
              ]
            }
          ]
        }
      }
    }
  }
}

Each processing field has one or two arguments, as follows:

  • filter: allows for selecting the table rows that will be processed. This is the same filter used for querying data from the table. You can read more about that here: Filtering.
  • args: is an optional argument present for the processings that have parameters. When present, this is an object of a type with the name having the form <tablename>Processing_<processingname>_Parameters, such as in OrderProcessing_Transfer_Parameters. The fields of this type are different for each processing.

The args field allows to specify arguments for the processing. This could be either:

  • arguments for the overall processing, which are available in the root, or
  • arguments for each processed row, which are provided as an array, one element for each row. It is possible to have recursive data, i.e. arrays of arrays, on multiple levels.

The following example shows possible arguments for the finish order processing:

mutation run_processing($cid : Int!, $orderno : Int)
{
  useCompany(no : $cid)
  {   
    order_processings
    {
      finish(
        args:
        {
          finishType : 0
          group : [
            {
              key : "1"
              quantity : 1
            },
            {
              key : "2"
              quantity : 1
            },
            {
              key : "3"
              quantity : 2
            }            
          ]          
        },
        filter :
        {
          orderNo : { _gte : $orderno}
        }
      )
      {
        succeeded
        items
        {
          handledOrderLine
          {
            lineNo
            finishedNow
          }
        }
      }
    }
  }
}

In this example:

  • finishType is an argument for the entire processing
  • group is a node containing a collection of objects with two properties, key and quantity. Each object in this collection is used for one processed row (which are selected here with a filter). If the number of rows is greater than the provided arguments (elements of the array) the rest of the rows are processed as if no arguments were supplied.

A similar structure is used for returning results. There are results:

  • per processing, available directly in the root of the result object. All processings have a Boolean field called succeeded that indicate whether the processing completed successfully or not. Additional results, are available at this level.
  • per row, available under the items field, which is an array. Each element in the array represents the result for a processed row.

For the previous request of order finishing, the following is a potential result:

{
  "data": {
    "useCompany": {
      "order_processings": {
        "finish": {
          "succeeded": true,
          "items": [
            {
              "handledOrderLine": [
                {
                  "lineNo": 1,
                  "finishedNow": 1
                },
                {
                  "lineNo": 2,
                  "finishedNow": 1
                }
              ]
            },
            {
              "handledOrderLine": [
                {
                  "lineNo": 1,
                  "finishedNow": 1
                },
                {
                  "lineNo": 2,
                  "finishedNow": 1
                },
                {
                  "lineNo": 3,
                  "finishedNow": 2
                }
              ]
            },
            {
              "handledOrderLine": [
                {
                  "lineNo": 1,
                  "finishedNow": 1
                }
              ]
            }
          ]
        }
      }
    }
  }
}

You can see here that for each order that was processed, there is an object in the items array. The property handledOrderLine is also an array and contains one object for each order line.

The following table shows another example of a process running on the CompanyInformation table that fetches access restrictions.

Mutation

mutation get_access($cid : Int!)
{
  useCompany(no : $cid)
  {
    companyInformation_processings
    {
      getAccessRestrictions
      {
        succeeded
        tableAccess
        {
          tableNo
          noTableRead
          noInsert
          noUpdate
          noDelete
        }
        functionAccess
        {
          processingAccess
          {
            processingNo
            noProcessingAccess
          }
          reportAccess
          {
            reportNo
            noReportAccess
          }
        }
      }
    }
  }
}
Result

{
  "data": {
    "useCompany": {
      "companyInformation_processings": {
        "getAccessRestrictions": {
          "succeeded": true,
          "tableAccess": [
            {
              "tableNo": 361,
              "noTableRead": 0,
              "noInsert": 1,
              "noUpdate": 1,
              "noDelete": 1
            },
            {
              "tableNo": 362,
              "noTableRead": 0,
              "noInsert": 1,
              "noUpdate": 1,
              "noDelete": 1
            },
            ...
          ],
          "functionAccess": [
            {
              "processingAccess": [
                {
                  "processingNo": 754,
                  "noProcessingAccess": 1
                },
                {
                  "processingNo": 1045,
                  "noProcessingAccess": 1
                },
                ...
              ],
              "reportAccess": [
                {
                  "reportNo": 251,
                  "noReportAccess": 0
                },
                {
                  "reportNo": 162,
                  "noReportAccess": 0
                },
                ...
              ]
            }
          ]
        }
      }
    }
  }
}

From this snippet, you can see that:

  • the processing returns information about access restrictions to tables, processings, and reports
  • table access information is gathered under the tableAccess field, which is an array of objects, each containing information about a single table
  • processing and report access information is available under the processingAccess and reportAccess fields, both being children of the functionAccess field. Also, like tableAccess, both processingAccess and reportAccess are arrays

This example shows a pattern that defines the general structure of processing results. Notice that even though tableAccess and functionAccess are themselves arrays, they represent overall processing data, and not results per row.

Tip

If you don’t know what processings are available for each table, or what each process is doing, you can get this information using the schema explorer, available in both GraphiQL and Insomnia. The images at the beginning of this page demonstrate this.

Last modified September 24, 2024