jhowe
jhowe

Reputation: 10828

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;

}

}

Upvotes: 0

Views: 406

Answers (2)

jhowe
jhowe

Reputation: 10828

Please see finished code, I believe this is now doing what I want. Thanks for the help. Any suggestions/efficiencies/improvements to this would be greatly appreciated!

[ExtensionOf(dataentityviewstr(SalesOrderLineEntity))]
final class SalesOrderLineEntity_Extension
{
    boolean validateWrite()
    {
        InventItemSalesSetup    inventItemSalesSetup;
        SalesLine               salesLine;
    select firstonly * from salesLine where salesLine.Salesid == this.SalesOrderNumber
        && salesLine.ItemId == this.ItemNumber
        join inventItemSalesSetup where inventItemSalesSetup.ItemId == this.ItemNumber;

    boolean ret = next validateWrite();

    if (ret)
    {
        if (ret && this.OrderedSalesQuantity < inventItemSalesSetup.MultipleQty)
        {
            ret = checkFailed ("qty ordered less than multiple qty");
        }
        if (ret && this.OrderedSalesQuantity mod inventItemSalesSetup.MultipleQty != 0)
        {
            ret = checkFailed ("qty ordered not divisible by multiple qty");
        }
    }

    return ret;

}

}

Upvotes: 0

Alex Kwitny
Alex Kwitny

Reputation: 11544

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.

Upvotes: 3

Related Questions