Search code examples
axaptax++dynamics-365-operations

Dynamics 365 Finance and Operations SalesOrderLineEntity validation extension


I'm still fairly new to x++ development. I'm trying to add some validation to the SalesOrderLineEntity to stop users importing qty's that are not divisible by multiple qty.

This is how far I've gotten, I can't workout how to write in x++ (if ordered qty not divisible by multiple qty (i.e. not whole number)) then throw an error.

[ExtensionOf(tableStr(SalesOrderLineEntity))]
final class SalesOrderLineEntity_Extension
{
boolean validateWrite()
{
InventItemSalesSetup inventItemSalesSetup;
SalesLine salesLine;

SalesTable salesTable = SalesTable::find(this.SalesOrderNumber);

select firstonly * from salesLine where salesLine.salesid == salesTable.SalesId
join inventItemSalesSetup where inventItemSalesSetup.ItemId == salesLine.ItemId;

if (this.RecId)
{
if (salesLine.QtyOrdered < inventItemSalesSetup.MultipleQty)
{
return checkFailed
("qty ordered less than multiple qty");
}
if (isInteger(salesLine.QtyOrdered / inventItemSalesSetup.MultipleQty))
{
return checkFailed
("qty ordered not divisible by multiple qty");
}
}

next validateWrite();

if (!salesTable.checkUpdate(true, true, true))
{
return false;
}

boolean ret;

//ret = super();

return ret;

}

}

Solution

  • If you are using integers, you need to use the modulo operation (mod) in AX. Make sure to check that you're not dividing by zero (the world could end) and you probably want to check that a non-zero quantity was actually entered.

    if(salesLine.QtyOrdered && inventItemSalesSetup.MultipleQty && (salesLine.QtyOrdered mod inventItemSalesSetup.MultipleQty != 0)
    {
        return checkFailed("qty ordered not divisible by multiple qty");
    }
    

    If you are using reals, then you want to do some basic integer math.

    real            qtyOrdered;
    real            multipleQty;
    int             result;
    
    qtyOrdered  = 321.0; // 321 / 10.7 = 30 exactly
    multipleQty = 10.7;
    result      = qtyOrdered / multipleQty; // This will store the integer and drop any decimals
    
    // If the result multipled by the original multiple is equal to the original value, then you're good
    if (result * multipleQty == qtyOrdered)
    {
        info("All good!");
    }
    else
    {
        info("Bad!");
    }
    

    There may be a standard AX function that does what you want, but it's so basic I just do the math myself.