Script collection for Straatos

 

This page contains some samples and help for Scripts that can be used in Straatos..

 

Adjust Height of Table in Web Validation

Line items from Database

Onwards (move document to next step)

Sequence Numbering

Show/Hide Fields

Timer

Hide Table Columns in Web Validation
Enable/Disable Mandatory Option in Fields in Web Validation
Blank Page Removal

Error handling with Error Event

AJAX call with XML data and Ampersand (&)

Start New Workflow From Script

Table Updates in Script Task

Table Updates in MyHome

Split Document 

Get Filesize

 

Adjust Height of Table in Web Validation

Sometimes it is useful to adjust the default height of the table in Web Validation (see red box area):

You can do this by copying the following script into the 'PreScript' section of the workflow:

document.Tables[0].PanelHeight = 100;
cpapp.showHideTable(document);
cpviewer.reload();

 

If you use multiple web validation steps in a single process and want to display the table with different heights in different steps, you can use an if statement to do that:

if (cpapp._step.Name == "Name of WebValidation Step")

 

 
 
 

Line Items from Database

This script can be used to populate line items from a database. For example if a PO Number is entered as an index field, the line items associated to this PO number can be retrieved from a database and displayed as line items in web validation.

 

Go to the specific index field which should trigger the population of the line items. In the example above, this is the index field 'PONumber'. In the index field go to teh 'Change Script' section.

Set the following options to on:

 

In the 'Change Script', use the follwoing code:

populateTable(field, fields);

function fieldByName(line, name) {
    return line.Fields.filter(function (field) { return field.Name === name; })[0];
}

function populateTable(field, fields){
    // Retrieve data from matching table 
    var query = {
        User: 'DB user ID',
        Password: 'login password',
        SqlQuery: 'select * from DB table name where PONumber = @PONumber ' ,
        Parameters: {
            '@PONumber': value
        }   
    };

    try {
        var data = straatos.data.query(query);    
        if (data.ErrorMessage) {
            fields.PONumber.ErrorMessage = data.ErrorMessage;
        } else if (data.Records.length > 0) {

            var table = document.Tables[0];
            table.Body.Lines = [];
            for (var i=0; i<data.Records.length; i++) {

                var line = cpapp.addTableLine(table, table.Body.Lines);
                fieldByName(line, 'PONumber').Value = data.Records[i].PONumber ;
                fieldByName(line, 'LineNumber').Value = data.Records[i].LineNumber;
                fieldByName(line, 'Description').Value = data.Records[i].Description;
                fieldByName(line, 'PartNumber').Value = data.Records[i].PartNumber;
                fieldByName(line, 'Quantity').Value = data.Records[i].Quantity ;
                fieldByName(line, 'UOM').Value = data.Records[i].UOM;
                fieldByName(line, 'UnitPrice').Value = data.Records[i].UnitPrice;
                fieldByName(line, 'NetPrice').Value = data.Records[i].NetPrice;
            }       
        }
        finished();
    } catch(err) {
        fields.PONumber.ErrorMessage = err;
        finished();
    }
}

 

 

 

 

Onwards

onwards = false;

Onwards is a boolean value. By default i is 'true'. It indicates if the workflow instance/document should be forwarded to the next activity in the flow when this script has finished. This can for example be used to keep a document in the same workflow step in case an error occured.

 

Sequence Numbering

straatos.nextSequenceNumber('someIdentifier’)

Generates an increasing number for the specified identifier. The Identifier can be reused in multiple processes, the number is unique. It is up to th euser to come up with a globally unique <someIdentifier>.

 

Show/Hide Fields

This script applies to WebValidation Scripting

Sometimes it is necessary to show or hide fields in web validation dynamically, based on index field values. For example, if a user selects a document type 'Invoice' different index fields should be displayed compared to a user selects a document type 'Correspondence'.

First, in the workflow level script library define the functions of hiding/unhiding the fields based on the document type selected. Note, is is recommended to define this in the Script Library so the function can be called from different places within the script.

Enter this code:

function hideInvoiceFields(fields, hide) {
    fields.InvoiceNumber.Hide = hide;
    fields.InvoiceDate.Hide = hide;
    fields.Subject.Hide = !hide;
    fields.Attention.Hide = !hide;
    fields.Reference.Hide = !hide;
}

function hideCorrespondenceFields(fields, hide) {
    fields.InvoiceNumber.Hide = !hide;     
    fields.InvoiceDate.Hide = !hide;
    fields.Subject.Hide = hide;
    fields.Attention.Hide = hide;
    fields.Reference.Hide = hide;
}

The above code inserts two functions. One to hide/unhide fields for Document type and the second function hides/unhides the fields for the Document type Correspondence. Both functions accept two parameters, firstly the fields, which is a collection of all index fields for the workflow, and secondly 'hide' which is a boolean true/false.

 

On the workflow level, go to the 'Change Script' section and set the following options to 'ON':

Change Script Changes Field Definition

Change Script Changes Field Values

With those options set to 'on', we system knows that the UI will be updated by the script.

In the 'Change Script' enter the following code:

hideCorrespondenceFields(fields, fields.DocumentType.Value == 'Invoice');
hideInvoiceFields(fields, fields.DocumentType.Value == 'Correspondence');

 

The code will call the functions defined before and passes all the fields. Furthermore, depending on what the value is in the DocumentType field, the boolean 'hide' is set to true or false.

 

Timer

Straatos supports a timer event. The timer event (officially the 'Timer Boundary Event') allows a task or document to be delayed a predefined time.

Example use: Send an Invoice only on the invoice Date. Delay an error retry by 5 Minutes.

 

 

The timer event can be setup based on three generic option

Duration (in days, hours, minutes). This delays a task for a certain number of time from the time the task reaches this step.

Time Cycoe based on a Cron Expressen: Supporting a delay to be sent on a specific time/date. For example every 1st of the Month, Every 10 Minutes etc.)

Workflow/Index field: Based on a date/time of an index field.

 

Details on Index field date.

The value can be set in the following way:

2016-12-06T09:00:00+01:00

The Time is optional. For example the following is valid:

2016-12-06. In this case, the documents waiting in the timer event are released at midnight on the 6 December 2016. Midnight refers to UTC/GMT.

2016-12-06T09:00:00: In this case, the time is set to 09:00 am UTC/GMT time.

2016-12-06T09:00:00+01:00: In this case, the time is set to 09:00 UTC/GMT +1 (timezone).

 

Script to use to set a date:

DueDate = '2016-12-06T09:00:00+10';

 

Hide Table Columns in Web Validation

If you have created a table and want to display/hide certain columns depending on the workflow step, here is how it is done:

 
Inline image 2
 
Example:
 
User Task (Accounting Coding) will see the following table column fields:
User Task (PO Exception) will see the following table column fields:
  • ArtikelNr
  • Bezeichnung
  • Menge
  • ME
  • Preis
  • BetragCHF
Script Library:
 
function hideLineItemFields(fields, hide) {  
    $('#itable table tr > *:nth-child(4)').hide();
    $('#itable table tr > *:nth-child(5)').hide();
    $('#itable table tr > *:nth-child(6)').hide();
    $('#itable table tr > *:nth-child(7)').hide();
    $('#itable table tr > *:nth-child(8)').hide();
    $('#itable table tr > *:nth-child(9)').hide();
}
 
function hideAccountingFields(fields, hide) {
    $('#itable table tr > *:nth-child(1)').hide();
    $('#itable table tr > *:nth-child(2)').hide();
    $('#itable table tr > *:nth-child(3)').hide();
}
 
Note: Table column field start from 1
 
Pre Script:
 
if (cpapp._step.Name == 'Kontrolle und Kontierung'') {    
    hideLineItemFields(fields, true);
} else if (cpapp._step.Name == 'PO Exception' ) {
    hideAccountingFields(fields, true);
}

 

Enable/Disable Mandatory Option for Fields in Web Validation

Here is a script which enables/disables the field mandatory property.
 
Below is the script.'mandatory' shall be call from function as 'true'.
 
function EnableMandatory (fields,mandatory){
    fields.InvoiceNumber.IsRequired = mandatory;
}

function DisableMandatory (fields,mandatory){
    fields.InvoiceNumber.IsRequired = !mandatory;
}

 

Blank Page Removal

The following script removes blank pages from a document.

1) Before runing the script, make sure the Start event has the 'Create Separate Pages from PDF' enabled.

2) Use the following script to determine and remove blank pages


try {
    var documentInfo = straatos.adapter.getDocumentInfo();
        
    for (var p = documentInfo.documentPages.length - 1; p >= 0; p--) {
        var magickDetectInput = {
            DocumentId: _documentId,
            OutputFormat: 'info',
            ReturnOutput: true,
            PageIndex: p,
            Parameters: 
            '-format "%[fx:mean>0.99?1:0]"'  //adjust parameters here to change blank page detection
        };

        
        try {
            var output = straatos.adapter.magick(magickDetectInput);
            if ('"1"' == output) {
                console.log('Magick output: ' + output + ', page index ' + p + ' should be removed.');

                var deletePageInput = {
                    PageIndex: p
                };
                try {
                    console.log(JSON.stringify(deletePageInput));
                    var deletePage = straatos.adapter.deleteDocumentPage(deletePageInput);
                    console.log(JSON.stringify(deletePage));
                } catch(error) {
                    straatos.setError('deletePage error:' + error);
                }

            }  
        } catch(error) {
            straatos.setError('Magick error: ' + error);
        }
    }    
} catch(error) {
    straatos.setError('documentInfo error: ' + error);
}

 

 

Error handling with Error Event

 The error event is able to catch the error in a module and to route a task/document to a different flow in the process. The diagram below is a simple flow that catches an error event and routes it to a different step:

The step 'Script simulate error' produces an error. The Error Event catches the error and routes the documen to the step 'Read error message'.

The script error event is triggered by most modules automatically. When using a script task, then an error can be triggered as follows:

 

straatos.setError("Simulated error message");

 

In order to display the original error message (or to use the original error message in script) in the step 'Read error message', use the following code to retrieve the message:

ErrorMessage = _errorMessage;

 

Note: The variable 'ErrorMessage' above is a Workflow Index field.

 

Start New Workflow from Script

var configUniqueId = straatos.uuid();
    var docUniqueId = straatos.uuid();

    straatos.ajax({
        url: 'https://effektif-connector.cumuluspro.net/ConnectorService.svc/json/UploadMetadata',
        data: JSON.stringify({
            ConfigurationUniqueId: '5ac4f9ab-7b0b-4982-bd75-533c1a2.....',
            UniqueId: configUniqueId,
            Documents: [{
                DocumentTypeUniqueId: '48e8c45d-ca8a-4106-8aec-fb741be.....',
                UniqueId: docUniqueId,
                DocumentFormat: 'PDF',
                Fields: [{
                    Name: 'OriginalDocumentId',
                    Value: '' + _documentId
                },{
                    Name: 'SupplierName',
                    Value: '' + SupplierName
                },{
                    Name: 'SupplierCode',
                    Value: '' + SupplierCode
                },{
                    Name: 'TranType',
                    Value: '' + TranType
                },{
                    Name: 'InvNo',
                    Value: '' + InvNo
                },{
                    Name: 'InvDate',
                    Value: '' + InvDate.format('YYYY-MM-DD')
                },{
                    Name: 'PONum',
                    Value: '' + PONum
                },{
                    Name: 'NET',
                    Value: '' + NET
                },{
                    Name: 'VAT',
                    Value: '' + VAT
                },{
                    Name: 'Gross',
                    Value: '' + Gross
                },{
                    Name: 'CostCentre',
                    Value: '' + CostCentre
                },{
                    Name: 'NominalCode',
                    Value: '' + NominalCode
                },{
                    Name: 'Department',
                    Value: '' + Department
                },{
                    Name: 'RowID',
                    Value: '' + RowID
                },{
                    Name: 'Table',
                    Value: JSON.stringify(table)
                }]
            }]
        }),
        method: 'POST'
    }).done(function (result) {
        console.log ('UploadMetadata ' + result);
        effektif.ajax({
            url: 'https://effektif-connector.cumuluspro.net/ConnectorService.svc/json/UploadDocument',
            data: pdf,
            contentType: 'application/pdf',
            headers: {
                'X-Configuration-Unique-Id': configUniqueId,
                'X-Document-Unique-Id': docUniqueId,
                'X-Page-Number': '1',
                'X-Number-Of-Pages': '1'
            },
            method: 'POST'
        }).done(function (result) {
            console.log ('UploadDocument ' + result);
        }).fail(function (jqXHR, error) {
            _errorMessage = 'UploadDocument ' + error;
            onwards = false;
        });
    }).fail(function (jqXHR, error) {
        _errorMessage = 'UploadMetadata ' + error;
        onwards = false;
    });
}).fail(function (jqXHR, error) {
    _errorMessage = 'Webmerge ' + error;
    onwards = false;
});

 

AJAX call with XML data and Ampersand (&)

This is a special case when sending data with special character ampersand (&) via an AJAX call and content type application/x-www-form-urlencoded.

Assuming your content you want to send is something like this:

<SupplierName>Johnson & Johnson</SupplierName>

 

In normal XML conversion, the & will be converted to &amp; and hence the special character & will be able to be sent as an XML So, the result would be <SupplierName>Johnson &amp; Johnson</SupplierName>. However, if you send it as an x-www-form-urlencoded., the ampersand in &amp; is still an issue as the & is  used to separate different parameters.

 

in order to make it work, you will need to encode the & of amp; to %26. So, your XML will then look like this when sending:

<SupplierName>Johnson %26amp; Johnson</SupplierName>

 

With this, you are then able to send the data.

 

A sample code is below:

var strOutput = '<SupplierName>Johnson & Johnson</SupplierName>';
    
    var encodedData = strOutput.replace('&','%26amp;');
    var formData = straatos.newFormData();
    formData.append('api_key=' + apiKey + '&document_id=' + xtractaDocumentId + '&document_status=' + vDocStatus  + '&submit=Submit' + "&field_data=" + encodedData);

    straatos.ajax({
        url: '<your URL>',
        method: 'POST',
        contentType: 'application/x-www-form-urlencoded',
        data: formData
    }).done(function (responseXML) {
        console.log('Xtracta Response: '+responseXML);
        var returnedStatus =  straatos.parseXML(responseXML).documentElement.selectSingleElement('status').text; 
        console.log(returnedStatus);
        if (returnedStatus == '200'){
            }
        else{
            straatos.SetError('Error: ' + response.documents_response.message); 
        }
    }).fail(function (jqXHR, error) {
        console.log('Error:' + error);
        straatos.setError('Error: ' + error);

    });

Note, the var xOutput would be your XML body. The important line are the encodedData where all & are replaced by '%26amp;'

then the form data is assigned. In teh formData.append, you can add all the fields that need to be sent. At the end is th eencodedData which contains to modified XML.

 

Table Updates in Script Task

The table fields in Straatos can be updated via script. The following two scripts show how to access the table, line items and fields and how to assign values to it.

 

The script below first checks if there are any line items. If there are line items, the script iterates through each line item and retrieves the Field LineTotal. This field is the added (summed up) in the variable invlinesum.

Once all line items are processed, the invlinesum variable contains the Sum of the field (column) LineTotal. This sum is then assigned to the index field 'NetTotal'. The same is written into the conolse log.

if (_table.body.lines.length) {   
    for (var i = 0; i < _table.body.lines.length; i++) {
        invlinesum += parseFloat(_table.body.lines[i].LineTotal.value);
    }
    NetTotal = roundAmount(invlinesum);
    console.log('invlinesum:' + invlinesum);
    console.log('Net Total:' + NetTotal);
}

 

The script below is used to update a line numbering as the first field 'LineNumber' so the line numbering is a continous number. This is done after the user edited the fields in a MyHome task and might have deleted lines.

The script iterates through all line items,

For each line item, it retrieves the value '_table.body.lines[i].Match.value '

and checks if the value exists (e.g. not returning 'null' or 'undefined'): {value: _table.body.lines[i].Match?

then assigns teh value to the variable tableLine. the Name needs to match the column name.

 

For the first column 'LineNumber' it assigns the value of the counter.

 

At the end (starting with _table ={) the values are assigned to the table.

 

if (_table.body.lines.length) {       
    for (var i = 0; i < _table.body.lines.length; i++) {
        counter = counter + 1;
        if(_table.body.lines[i]) {
            var tableLine = {
                LineNumber: { value: counter },
                Match : {value: _table.body.lines[i].Match? _table.body.lines[i].Match.value : ''},
                Quantity : {value: _table.body.lines[i].Quantity? _table.body.lines[i].Quantity.value : 0},
                PO : {value: _table.body.lines[i].PO ? _table.body.lines[i].PO.value : ''},
                VATRate : {value: _table.body.lines[i].VATRate ? _table.body.lines[i].VATRate.value : 0}
            };
            tableLines.push(tableLine);
        }
    }
    
    _table = {
        body: {
            lines: tableLines
        }
    };
}

 

Table Updates in MyHome

The following function can be defined in the Script Library and used in MyHome to update the table lines.

 

The script goes through each line item and sums up the LineTotal into the variable invlinesum. The invlinesum, after all amounts of the table are added is populted into the header field 'NetTotal'. This script can be executed when the table is updated to show the sum of an amount in a table.

 

// Check Sum Line item 
function sumLineItem(fields, table) {
    var invlinesum = 0;
    
    if (table.body.rows.length > 0) {
        for (var i = 0; i < table.body.rows.length; i++) {
            if (table.body.rows[i].LineTotal) {
                invlinesum = invlinesum + parseFloat(table.body.rows[i].LineTotal);    
            }
        }
           
        // Check if Net Total = POP Total Net
        fields.NetTotal.Value = invlinesum;
        console.log('NetTotal: ' + fields.NetTotal.Value);
        
    }
} 

 

The script below updates the line item values in MyHome based on a lookup. In the AJAX call, a webserivce is called to return the Supplier data.

Based on teh returned values, 4 table line items are updated.

 

function fillGRNLineItemFields(poNumber, itemCode, rowIndex, fields, table, finished) {

     $.ajax({
        url: 'https://effektif-connector.cumuluspro.net/ConnectorService.svc/json/Interact/<your ID>/lookupGRNSupplierPartRef',
        method: 'POST',
        headers: {'X-Session-Id': Utils.readCookie('s')},
        data: JSON.stringify({ poNumber: poNumber, itemCode: itemCode })
    }).done(function (dataString) {
        var data = JSON.parse(dataString);

        if (data.ErrorMessage) {
            console.log('fillLineItemFields Query Error: ' + data.ErrorMessage);
        } else if (data.Records && data.Records.length == 1 ){
            table.body.fieldsForRow[rowIndex].GRNQuantity.Value = data.Records[0].Quantity;
            table.body.fieldsForRow[rowIndex].GRNItemDescription.Value = data.Records[0].ItemDescription;
            table.body.fieldsForRow[rowIndex].GRNUnitPrice.Value = data.Records[0].UnitPrice;
            table.body.fieldsForRow[rowIndex].GRNLineTotalNet.Value = data.Records[0].LineTotalValue;
        }

        finished();
    }).fail(function (jqXHR, error) {
        finished();
    });
}

 

Split Document

function splitDocument(index, documentType) {
    var docID = _documentId;
    try {

        var splitInput = {
            WorkflowInstanceId :straatos.getWorkflowInstanceIdByDocumentId(docID),
            PageIndex: index
        };

        var splitResult =  straatos.adapter.splitDocument(splitInput);

        var messageInput = {
            workflowId: workflowId,
            activityId: activityId,
            workflowInstances: [{
                workflowInstanceId: JSON.parse(splitResult).WorkflowInstanceId,
                variables: [{
                    id: 'DocumentType',
                    value: documentType
                }, {
                    id: 'PolicyNo',
                    value: PolicyNo
                }, {
                    id: 'OutputPath',
                    value: OutputPath
                }, {
                    id: 'BatchNo',
                    value: BatchNo
                }, {
                    id: 'POSNo',
                    value: POSNo
                }, {
                    id: 'ScanDate',
                    value: ScanDate
                }, {
                    id: 'SeqNo',
                    value: SeqNo
                }
                           ]
            }]
        };

        effektif.ajax({
            url: 'https://effektif-cpro-qa.azurewebsites.net/effektif-web/cp/message',
            data: JSON.stringify(messageInput),
            method: 'POST'
        }).done(function (messageResultString) {
            console.log('messageResultString: ' + messageResultString);
        }).fail(function (jqXHR, error) {
            _errorMessage = 'Message error: ' + error;
            onwards = false;
        });

    } catch (error) {
        _errorMessage = 'Delete page error: ' + error;
        onwards = false;
    }
}

splitDocument(NbDocPageIndex, 'DTB-NBDOC');
splitDocument(SuppDocPageIndex, 'DTB-SUPPDOC');

DocumentType = 'DTB-APPLFORM';

 

Get File Size

If you need to get the filesize of a document received, you can do this with the following script:

straatos.ajax({ url: url, method: 'GET'}).done(function(data, nothing, response) { 
    console.log('Length: ' + data.length);
});
 
Create your own Knowledge Base