Skip to main content

Check that a field is present

For example, let us check that the MyField field is found and filled in:
var field = Context.GetField("MyField");

if (!field) {
  Context.CheckSucceeded = false;
  Context.ErrorMessage = 'MyField field not found';
} else if (!field.Value) {
  Context.CheckSucceeded = false;
  Context.ErrorMessage = 'MyField field empty';
}

Compare floating-point numbers

Directly comparing numbers with a floating point may lead to unpredictable results. We recommend using methods of the built-in Math object to compare numbers and especially money values correctly.
// compare two floating-point numbers
var floatField1 = Context.GetField("Number Field 1");
var floatField2 = Context.GetField("Number Field 2");
var floatVal1 = floatField1.Value;
var floatVal2 = floatField2.Value;

if (Math.round(floatVal1) === Math.round(floatVal2)) {
    return;
} else {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = 'The values are different';
}

// compare two money values
var moneyField1 = Context.GetField("Money Field 1");
var moneyField2 = Context.GetField("Money Field 2");
var value1 = moneyField1.Value.Amount;
var value2 = moneyField2.Value.Amount;

if (Math.abs(value1 - value2) <= 0.0001) {
    return;
} else {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = 'The values are different';
}

Require a non-empty value depending on another field

An optional field may become required if the value of another field demands it. For example, if the marital status reads as “married,” the name of the spouse should be filled in. Or, if the person’s age calculated from their birth date shows that they are under age, the guardian’s signature is needed. This script rule verifies that for documents where the marital status field has the value “Married” the spouse first and last name are both filled in:
function checkFieldValuePresence(field) {
    if (!field.Value) {
        Context.ErrorMessage = 'Value of ' + field.Name + ' field should not be empty';
        return false;
    }
    return true;
}

var conditionField = Context.GetField("MaritalStatus");

if (conditionField === null) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = 'MaritalStatus field not found';
} else if (checkFieldValuePresence(conditionField)) {
    var lastName = Context.GetField("SpouseLastName");
    var firstName = Context.GetField("SpouseFirstName");
    if (conditionField.Text === "Married") {
        if (lastName === null || firstName === null) {
            Context.CheckSucceeded = false;
            Context.ErrorMessage = 'Spouse name field not found';
        } else if (!checkFieldValuePresence(lastName) || !checkFieldValuePresence(firstName)) {
            Context.CheckSucceeded = false;
        }
    }
} else { // marital status not filled in, check failed
    Context.CheckSucceeded = false;
}

Check that the field has been located on the document

The rules may be used to fill in the field values, even if the value is not actually printed on the document. For example, if several taxes apply, the total tax can be calculated automatically. However, some countries require the total tax amount to be printed on the document. This script rule checks that for receipts from Germany the total tax is not just calculated but present on the image. For other countries, no additional check is needed because the Required field flag is turned on for the total tax field:
function checkFieldRegion(field) {
    if (!field || !field.HasRegion) {
        Context.ErrorMessage = 'The (' + field.Name + ') field is not present on the document image';
        return false;
    }
    return true;
}

var conditionField = Context.GetField("CountryOfOrigin");

if (!conditionField.Value) {
    Context.ErrorMessage = 'Country of origin unknown, cannot check taxes';
    Context.CheckSucceeded = false;
} else {
    var totalTaxField = Context.GetField("TotalTax");
    if (conditionField.Text === "DE" && !checkFieldRegion(totalTaxField)) {
        Context.CheckSucceeded = false;
    }
}

Validate the data in particular cases

Checking that the total tax is equal to the sum of all taxes can be done by using a predefined rule (Check Sum). But if for some countries one of the taxes may have a negative value, only a script rule could take both cases into account. Depending on the document’s country of origin, it may either add up all of the taxes or add up and subtract the negative of a return tax. This sample script checks that the sum of two taxes is equal to the total tax, except if the receipt is from Spain, in which case either the sum or the difference of the two may be equal to the total tax:
var conditionField = Context.GetField("CountryOfOrigin");
var totalTaxField = Context.GetField("TotalTax");
var tax1Field = Context.GetField("Tax1");
var tax2Field = Context.GetField("Tax2");

if (!conditionField.Value || !totalTaxField.Value || !tax1Field.Value || !tax2Field.Value) {
    Context.ErrorMessage = 'Cannot check taxes';
    Context.CheckSucceeded = false;
} else {
    if (conditionField.Text === "ES") {
        Context.CheckSucceeded = ((Math.round(tax1Field.Value - tax2Field.Value) === Math.round(totalTaxField.Value))
            || (Math.round(tax1Field.Value + tax2Field.Value) === Math.round(totalTaxField.Value)));
    } else {
        Context.CheckSucceeded = (Math.round(tax1Field.Value + tax2Field.Value) === Math.round(totalTaxField.Value));
    }
}

Compare table column sums to values located outside of the table

Scripts can reference values located inside tables and not just regular fields. To speed up rule checks, we recommend saving tables as variables and then referencing such variables instead of the original tables. If a variable contains an entire table, you can use the Instances property to access the table’s rows and then use the Field GetChild method to get the value of a particular cell in a row. The sample script below sums up all values in the Total Price column and compares the result to the value of the Total field:
var totalField = Context.GetField("Total");
var tableField = Context.GetField("MyTable");

if (!totalField) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "Total field is not found";
    return;
}

if (!tableField) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "MyTable field is not found";
    return;
}

var sum = 0;

for (var i = 0; i < tableField.Instances.length; i++) {
    var tableTotalField = tableField.Instances[i].GetChild("MyTable/Total Price");
    sum += tableTotalField.Value.Amount;
}

if (Math.abs(sum - totalField.Value.Amount) > 0.02) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "The sum of Total Price in the table doesn't match Total";
}

Compare individual values from column cells to values located outside of tables and display the numbers of rows that contain errors

Referencing table columns can also be done using the Field GetFields method. This method lets you get a list of all cells in a table, which can be useful for setting up loops. The sample script below compares tax rates for each line item to the overall tax rate. If the values don’t match, the script is not interrupted. Instead, the number of the row where the mismatch occurred is passed to a special variable, which the rule can use to check the whole column. The error message in the sample script will list the numbers of all rows that contain errors:
var taxRateFields = Context.GetFields("MyTable/TaxRate");
var taxRateField = Context.GetField("TaxRate");

if (!taxRateFields || !taxRateField)
    return;

var taxRate = taxRateField.Value ? taxRateField.Value : 0;
var wrongLines = [];
for (var i = 0; i < taxRateFields.length; i++) {
    if (taxRateFields[i].Value != taxRate)
        wrongLines.push(i + 1);
}

if (wrongLines.length > 0) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "Wrong tax rate in lines: " + wrongLines.join(", ");
}

Compare the product of several fields in a row to the value of a different field in the same row

You can carry out various operations with different columns in a table sequentially (row-by-row) without using loops. To do so, you need to reference each column using the Field GetField method. This will be a repeating rule that will be carried out automatically for each row of the table. All columns referenced this way need to be from the same table. The sample script below multiplies the unit quantity by the unit price for each row and compares the resulting value to the total price for the line item:
var quantityField = Context.GetField("MyTable/Quantity");
var unitPriceField = Context.GetField("MyTable/Unit Price");
var totalField = Context.GetField("MyTable/Total Price");

if (!quantityField || !unitPriceField || !totalField)
    return;

var quantity = quantityField.Value ? quantityField.Value : 0;
var unitPrice = unitPriceField.Value?.Amount ? unitPriceField.Value.Amount : 0;
var total = totalField.Value?.Amount ? totalField.Value.Amount : 0;

var result = quantity * unitPrice;

if (Math.abs(result - total) > 0.01) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "Quantity * Unit price is not equal to Total";
}