Wednesday, April 6, 2016

Handle table validations in X++

When we try to insert a record in a table by using X++, we use the insert method, but when we call the insert method, it won’t consider all mandatory fields are entered or not. It allows the empty values even the field is mandatory. This mandatory validation logic are developed on the validate write method. Think is that validate method is not called default when we call the insert or update method.

So, as per the Microsoft best practice document, we need to call the validate write method before we call the insert or update method.

Note: AX forms call the validatewrite method default when we insert or update the records through form.


For example:

static void Hari_TestInsertMethod(Args _args)
{
    Hari_ClassTest   classTest;
   
    classTest.Class = '2nd';
    classTest.Description = 'Description';

    if(classTest.validateWrite())
    {
        classTest.insert();
        info('Record inserted successfully');
    }
}


The second point is that we can build the validation for each field by using validatefield method. This method is called default when we enter the value in the form. But this validatefield method is not called default when we use the insert or update method even if we call the validatewrite method.


For validate field example, I have created one validation in the table validatefield method.

public boolean validateField(FieldId _fieldIdToCheck)
{
    boolean ret;

    ret = super(_fieldIdToCheck);
   
    if(ret)
    {
        switch (_fieldIdToCheck)
        {
            case fieldNum(Hari_ClassTest, Description):
                if(this.Description == 'Description')
                {
                    checkFailed("The value shouldn't be description");
                    ret = false;
                }
                break;
        }
    }

    return ret;
}


To call the validatefield and validatewrite method when we call the insert or update method, we can create a new validate method in a new class. Refer the below method named validateRecord. The functionality is that this method call all field’s validatefield method and validatewrite method manually.

public static boolean validateRecord(common _common)
{
    boolean     ret = true;
    DictTable   dictTable = new DictTable(_common.TableId);
    int         fields;
    int         i;

    fields = dictTable.fieldCnt();
    //iterate through each field and validate it
    for(i = 1; i<= fields; i++)
    {
        ret = ret && _common.validateField(dictTable.fieldCnt2Id(i));
    }

    //validate the record itself over here
    ret = ret && _common.validateWrite();

    return ret;
}


Insert the value by using validateRecord method:

static void Hari_TestInsertMethod(Args _args)
{
    Hari_ClassTest   classTest;
   
    classTest.Class = '2nd';
    classTest.Description = 'Description';
    if(Hari_TableValidations::validateRecord(classTest))
    {
        classTest.insert();
        info('Record inserted successfully');
    }
}