web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

Runbase batch validation

(0) ShareShare
ReportReport
Posted on by 1,215

Hi guys,

i have a scenario before post i need it validation Fromdate, todate, leavetype should be filled but in my form post button Runbase batch class mentioned 

how to validate below my code : table name  MPWorkerTransHeader    rec; buffer.

// This is a framework class. Customizing this class may cause problems with future upgrades to the software.
class MPPostMulti extends RunBaseBatch
{
    // Packed variables
    FormDataSource      callerDs;
    TransDate           trDate;


    // Dialog fields
    //DialogField     dlgCustAccount;
    //DialogField     dlgTransDate;

    #define.CurrentVersion(2)
    #define.Version1(2)
    #localmacro.CurrentList
        trDate
    #endmacro
    /// 
///    Indicates whether the class is shown in the list of Journal types.
/// 
/// 
///    true if the class is shown in the list of Journal types; otherwise, false.
/// 
/// 
///    A class that can be used in a batch journal is a class where the same parameters can be used
///    repeatedly. The dialog box can be shown and the parameters can be changed, but parameters of some
///    classes might build on data that is only valid for a short time. Running a class two times with the
///    same parameters is not always possible. If the RunBaseBatch.canGoBatch method is false, this
///    method will not have any effect.
/// 
public boolean canGoBatchJournal()
{
    return true;
}

    /// 
///    Returns a class that contains the methods that are described by the RunBaseDialogable
///    interface.
/// 
/// 
///    A class that contains the methods that are described by the RunBaseDialogable interface.
/// 
/// 
///    A dialog box can be either built by using the Dialog class or by using a class that is
///    created in the Application Object Tree (AOT).
/// 
public Object dialog()
{
    DialogRunbase       dialog = super();
    #resAppl
;
    /*dialog.addImage(#ImageEmployee);
    dialog.addInfoImage();
    dlgTransDate = dialog.addFieldValue(extendedTypeStr(TransDate),transDate);

    dialog.addTabPage("@SYS76580");
    dlgCustAccount = dialog.addFieldValue(extendedTypeStr(CustAccount),custAccount);*/

    return dialog;
}

    public void dialogPostRun(DialogRunbase dialog)
{
;
    super(dialog);
}

    public boolean getFromDialog()
{
;
    /*transDate   = dlgTransDate.value();
    custAccount = dlgCustAccount.value();*/

    return super();
}

    public boolean init()
{
    return true;
}

    protected void new(FormDataSource  ds)
{
    super();
    callerDs = ds;
}

    public container pack()
{
    return [#CurrentVersion,#CurrentList];
}

    /// 
///    Contains the code that does the actual job of the class.
/// 
public void run()
{
    #OCCRetryCount
    if (! this.validate())
        throw error("");

    try
    {
        ttsbegin;

         this.Update();

        ttscommit;
    }
    catch (Exception::Deadlock)
    {
        retry;
    }
    catch (Exception::UpdateConflict)
    {
        if (appl.ttsLevel() == 0)
        {
            if (xSession::currentRetryCount() >= #RetryNum)
            {
                throw Exception::UpdateConflictNotRecovered;
            }
            else
            {
                retry;
            }
        }
        else
        {
            throw Exception::UpdateConflict;
        }
    }

}

    public boolean runsImpersonated()
{
    return true;
}

    public boolean unpack(container packedClass)
{
    Version version = RunBase::getVersion(packedClass);
;
    switch (version)
    {
        case #CurrentVersion:
            [version,#CurrentList] = packedClass;
            break;
        default:
            return false;
    }

    return true;
}

    private void update()
{
    MPWorkerTransHeader     row;
    MPPostEmplTransaction   postTrans;
    Args                    args;
    if (callerDs.anyMarked())
    {
        //Obtains the first query result and then assign it to table buffer
        row   = callerDs.getFirst( 1, false );

        //True if purchLineView contains RecId
        while (row)
        {
            args = new args();
            args.record(row);
            postTrans = MPPostEmplTransaction::construct(args);
            postTrans.initParmDefault();

            postTrans.parmTransHeader(row);
            postTrans.run();
            //Shows all RecIds from selected grid rows
            //info( strFmt('%1' , row.RecId));
            //Gets next record
            row = callerDs.getNext();
        }
    }
    else
    {
        info("@MPL514");
    }
    callerDs.reread();
    callerDs.refresh();

}

    public boolean validate(Object _calledFrom = null)
{
    if (false)
        return checkFailed("");

    return true;
}

    server static MPPostMulti construct(FormDataSource  ds)
{
    return new MPPostMulti(ds);
}

    // Here goes a description of the class
static ClassDescription description()
{
    return "@MPL98";
}

    static void main(Args args)
{
    MPPostMulti    MPPostMulti;
    MPPostEmplTransaction   postTrans;
    MPWorkerTransHeader               rec;
    FormDataSource          trans_ds;
    ;
    if(!args
        || !args.record())
    {
        error("@MPL513");
        return;
    }
    //Check if the Args.Record() has the same TableID as the Table Buffer(custTable).
    if  (args.record().TableId == tableNum(MPWorkerTransHeader))
    {
        //Assign the args records to table buffer and then pass it to salesLine_ds(FormDataSource)
        rec         = args.record();
        trans_ds    = rec.dataSource();
        if(trans_ds.anyMarked())
        {
            MPPostMulti = MPPostMulti::construct(trans_ds);

            if (MPPostMulti.prompt())
            {
                MPPostMulti.run();
            }
        }
        else if(rec.RecId)
        {
            ttsBegin;
            args = new args();
            args.record(rec);
            postTrans = MPPostEmplTransaction::construct(args);
            postTrans.initParmDefault();

            postTrans.parmTransHeader(rec);
            postTrans.run();
            ttsCommit;
        }
        else
        {
            error("@MPL514");
        }
    }

}

}
 

Thanks

I have the same question (0)
  • Suggested answer
    nmaenpaa Profile Picture
    101,162 Moderator on at

    Just put those validations in the validate method (which you already have).

  • Suggested answer
    nmaenpaa Profile Picture
    101,162 Moderator on at

    Also, if some of these values (such as leave type) are coming from the caller data source, one option is to declare such fields as mandatory in the underlying table. This way your batch doesn't need to check the validity of your table data. Instead your table itself is defined in a way that you can only enter valid data. This makes much more sense, because the validations will then apply everywhere, not just when your batch is executed.

    Of course, the exact details depend on your exact requirements.

  • Riyas ahamed F Profile Picture
    1,215 on at

    thanks for your replay,

    which validate method could you please example ?  

  • Suggested answer
    nmaenpaa Profile Picture
    101,162 Moderator on at

    The validate method that is in your own code that you shared in your initial message.

  • Riyas ahamed F Profile Picture
    1,215 on at

    i'm asking validate method in runbase batch class validate method ?

  • Suggested answer
    nmaenpaa Profile Picture
    101,162 Moderator on at

    No, you should never customize the RunBaseBatch class. Instead you override it in your own class (in this case MPPostMulti) and write your validation logic there.

  • Gunjan Bhattachayya Profile Picture
    35,423 on at

    Hi Riyas,

    Nikolaos is referring to this method in your class. You can do the validations like this-

    public boolean validate(Object _calledFrom = null)
    {
        boolean ret = true;
        if (fromDate == dateNull())
        {
            ret =  checkFailed("From date must be filled.");
        }
        
        //Do the additional validations here.
    
        return ret ;
    }

  • Riyas ahamed F Profile Picture
    1,215 on at

        public boolean validate(Object _calledFrom = null)
    {
        boolean ret = true;
        MPWorkerTransHeader       transHeader;
        if (false)
            return checkFailed("");
         if(!transHeader.LeaveFromDate  || !transHeader.LeaveToDate)
            {
                ret = checkFailed("Must be filled in from date and to date");
            }
    
        return true;
    }

    we can declare directly in table name in class ?

  • Suggested answer
    nmaenpaa Profile Picture
    101,162 Moderator on at

    In your code the transHeader variable is always an empty table buffer. So your validation would always fail.

    You need to initialize the caller record(s) - you already have a logic for this in the update method. So you can use similar code to iterate all the caller records in the validate method.

    You also need to decide whether the whole processing should fail if one of the records fails validation.

    As suggested before, for the table field validations you always have the option to validate them already when the table is being inserted/updated. That could make much more sense. Do you have some reason to allow users to enter empty values in LeaveFromDate or LeaveToDate? If not, just declare them as mandatory in your table. This way you don't need to validate them in your batch.

  • Riyas ahamed F Profile Picture
    1,215 on at

    No we can't use Update method args another method how ?  please give us a Example.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Martin Dráb Profile Picture

Martin Dráb 451 Most Valuable Professional

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 428 Super User 2025 Season 2

#3
BillurSamdancioglu Profile Picture

BillurSamdancioglu 239 Most Valuable Professional

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans