> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sample scripts

> JavaScript samples for common Advanced Script Rule scenarios — field presence, numeric comparisons, conditional requirements, and table validation.

The following JavaScript samples illustrate common patterns for Advanced Script Rules — checking field presence, comparing numeric values, applying conditional validation, and validating table data. Copy and adapt them to your own field names and business rules.

## Check that a field is present

For example, check that the `MyField` field is found and filled in:

```javascript theme={null}
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

Comparing floating-point numbers directly can yield unpredictable results. Use methods from the built-in `Math` object to compare numbers — especially money values — reliably.

```javascript theme={null}
// 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 can become required based on another field's value. For example, if `MaritalStatus` is `Married`, the spouse name fields should be filled in.

This script rule verifies that when `MaritalStatus` is `Married`, both `SpouseFirstName` and `SpouseLastName` are filled in:

```javascript theme={null}
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 a field is located on the document

Rules can also fill in field values, even if the value isn't 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 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:

```javascript theme={null}
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 equals the sum of all taxes can be done with a predefined rule (**Check Sum**). But if one of the taxes can have a negative value in certain countries, only a script rule can handle both cases — adding all taxes, or adding and subtracting a return tax, depending on the country of origin.

This script checks that the sum of two taxes equals the total tax, except for receipts from Spain, where either the sum or the difference of the two can equal the total tax:

```javascript theme={null}
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 a column sum to an external field

Scripts can reference table values, not just regular fields. To speed up rule checks, save tables as variables and reference the variables instead of re-fetching the table. If a variable holds an entire table, use the [`Instances`](/vantage/documentation/skill-designer/document/rule-verification/field#instances) property to access rows, then use [`GetChild`](/vantage/documentation/skill-designer/document/rule-verification/field#getchild) to get a specific cell in a row.

The sample below sums all values in the `Total Price` column and compares the result to the `Total` field:

```javascript theme={null}
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 column cells to an external field and list failing rows

Reference table columns with [`Context.GetFields`](/vantage/documentation/skill-designer/document/rule-verification/context#getfields) to get every cell in the column, which is useful for looping.

The sample below compares each row's tax rate to the overall tax rate. When values don't match, the script continues instead of failing immediately, collecting the row numbers with mismatches and reporting them in the error message:

```javascript theme={null}
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 row values to another row value

You can perform operations on different columns in a table row-by-row without using explicit loops — reference each column using [`Context.GetField`](/vantage/documentation/skill-designer/document/rule-verification/context#getfield). This creates a repeating rule that runs automatically for each row. All columns referenced this way must belong to the same table.

The sample below multiplies unit quantity by unit price for each row and compares the result to the line item's total price:

```javascript theme={null}
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";
}
```

## Related topics

<CardGroup cols={2}>
  <Card title="Business rules automation" icon="code" href="/vantage/documentation/skill-designer/document/rule-verification/business-rules-automation">
    Add scripted rules to a Document skill, configure readable and writable fields, and reference table columns.
  </Card>

  <Card title="Object model" icon="diagram-project" href="/vantage/documentation/skill-designer/document/rule-verification/object-model">
    Full JavaScript object reference for use in Advanced Script Rules.
  </Card>

  <Card title="Context" icon="braces" href="/vantage/documentation/skill-designer/document/rule-verification/context">
    The Context global object — access the document, fields, and skill parameters from inside a rule.
  </Card>

  <Card title="Field" icon="font" href="/vantage/documentation/skill-designer/document/rule-verification/field">
    The Field object — inspect and modify a document field during rule execution.
  </Card>
</CardGroup>
