跳转到主要内容

检查字段是否存在

例如,我们来检查是否找到了 MyField 字段并已为其填充值:
var field = Context.GetField("MyField");

if (!field) {
  Context.CheckSucceeded = false;
  Context.ErrorMessage = 'MyField 字段未找到';
} else if (!field.Value) {
  Context.CheckSucceeded = false;
  Context.ErrorMessage = 'MyField 字段为空';
}

比较浮点数

直接比较浮点数可能会导致不可预期的结果。我们建议使用内置的 Math 对象的方法来正确比较数值,尤其是金额数值。
// 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 = '值不同';
}

// 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 = '值不同';
}

根据另一个字段的值要求非空值

一个可选字段可能会在另一个字段的取值要求下变为必填。例如,如果婚姻状况为“married”,则应填写配偶姓名。或者,如果根据出生日期计算出的年龄显示该人为未成年人,则需要监护人的签名。 此脚本规则用于验证:对于婚姻状况字段值为“Married”的文档,配偶的名字和姓氏都必须已填写:
function checkFieldValuePresence(field) {
    if (!field.Value) {
        Context.ErrorMessage = '字段 ' + field.Name + ' 的值不能为空';
        return false;
    }
    return true;
}

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

if (conditionField === null) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = '未找到 MaritalStatus 字段';
} 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 = '未找到配偶姓名字段';
        } else if (!checkFieldValuePresence(lastName) || !checkFieldValuePresence(firstName)) {
            Context.CheckSucceeded = false;
        }
    }
} else { // 婚姻状况未填写,检查失败
    Context.CheckSucceeded = false;
}

检查字段是否已在文档上定位

规则可用于填充字段值,即使该值实际上并未打印在文档上。例如,如果适用多种税种,则可以自动计算总税额。但是,一些国家要求在文档上打印总税额。 此脚本规则会检查,对于来自德国的收据,总税额不仅被计算出来,而且确实出现在图像上。对于其他国家,则不需要额外检查,因为总税额字段已启用 Required field 标志:
function checkFieldRegion(field) {
    if (!field || !field.HasRegion) {
        Context.ErrorMessage = '字段 (' + field.Name + ') 未出现在文档图像上';
        return false;
    }
    return true;
}

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

if (!conditionField.Value) {
    Context.ErrorMessage = '原产国未知,无法检查税额';
    Context.CheckSucceeded = false;
} else {
    var totalTaxField = Context.GetField("TotalTax");
    if (conditionField.Text === "DE" && !checkFieldRegion(totalTaxField)) {
        Context.CheckSucceeded = false;
    }
}

在特定情况下验证数据

检查总税额是否等于所有税额之和,可以通过使用预定义规则(Check Sum)来完成。但如果在某些国家,其中一种税可能为负值,就只能使用脚本规则同时考虑这两种情况。根据文档所属国家/地区,要么将所有税额相加,要么在加总时将退税作为负值参与计算(即相加并扣减退税)。 此示例脚本检查两项税额之和是否等于总税额;但如果收据来自西班牙,则这两项税额的和或差都可以等于总税额:
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 = '无法检查税费';
    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));
    }
}

将表格列的合计与表格外的数值进行比较

脚本不仅可以引用表格外普通字段中的数值,还可以引用表格中的数值。为了加快规则校验,我们建议先将表格保存为变量,然后引用这些变量,而不是直接引用原始表格。如果某个变量包含整个表格,您可以使用 Instances 属性访问该表格的行,然后使用 Field GetChild 方法获取某一行中特定单元格的数值。 下面的示例脚本将 “Total Price” 列中的所有数值求和,并将结果与 “Total” 字段的数值进行比较:
var totalField = Context.GetField("Total");
var tableField = Context.GetField("MyTable");

if (!totalField) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "未找到 Total 字段";
    return;
}

if (!tableField) {
    Context.CheckSucceeded = false;
    Context.ErrorMessage = "未找到 MyTable 字段";
    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 = "表格中 Total Price 的总和与 Total 不匹配";
}

将列中各个单元格的值与表格外部的值进行比较并显示包含错误的行号

也可以使用 Field GetFields 方法来引用表格列。此方法可让你获取表格中所有单元格的列表,这对于设置循环非常有用。 下面的示例脚本会将每个明细行的税率与总税率进行比较。如果数值不匹配,脚本不会被中断。相反,发生不匹配的行号会被传递给一个特殊变量,规则可以使用该变量来检查整列。示例脚本中的错误消息将列出所有包含错误的行号:
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 = "以下行的税率有误:" + wrongLines.join(", ");
}

比较同一行中多个字段的乘积与另一字段的值

您可以在不使用循环的情况下,依次(按行)对表格中的不同列执行各种操作。为此,您需要使用 Field GetField 方法引用每一列。这样就会创建一个重复规则,并自动应用于表格的每一行。以这种方式引用的所有列都必须来自同一张表。 下面的示例脚本将每行的单位数量与单价相乘,并将得到的值与该行明细的总价进行比较:
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 = "数量 * 单价不等于总价";
}