web
You’re offline. This is a read only version of the page.
close
Skip to main content
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,160 Moderator on at
    RE: Runbase batch validation

    Well, if you look at row 29 in your code, you notice that it always returns true. Could you try to carefully compare it with my illustration above, trying to spot other differences yourself? Thanks!

  • Riyas ahamed F Profile Picture
    1,215 on at
    RE: Runbase batch validation

       public boolean validate(Object _calledFrom = null)
    {
        boolean ret = true;
        MPWorkerTransHeader     row;
        if (callerDs.anyMarked())
            {
                row   = callerDs.getFirst( 1, false);
    
                if (false)
                return checkFailed("");
                while (row)
                {
                    if(!row.LeaveFromDate)
                    {
                        ret = checkFailed("Must be filled in From date");
                    }
                    else if(!row.LeaveToDate)
                    {
                        ret = checkFailed("Must be filled in to date");
                    }
                    else if(!row.MPLeaveTypeId)
                    {
                        ret = checkFailed("Must be filled in leave type");
                    }
                    row = callerDs.getNext();
                }
            }
    
        return true;
    }

    also its not working what am i missing ?

  • nmaenpaa Profile Picture
    101,160 Moderator on at
    RE: Runbase batch validation

    Well, the code works just as well even if you selected only one record. Please keep in mind that you use this exact logic in your update method. So, why would you share that with us if that's not the code that you are going to use?

    Your question was about validation in Runbase batch, and we illustrated how to do it, using your own code as a basis. Should we have done something differently?

  • Riyas ahamed F Profile Picture
    1,215 on at
    RE: Runbase batch validation

    Thanks for your answer, but i dont want multiselect how to ignore above u mentioned in code ??

  • Verified answer
    nmaenpaa Profile Picture
    101,160 Moderator on at
    RE: Runbase batch validation

    Anyway, here's the code that you could put in the validate method. Please keep in mind that it's just an illustration, you still need to do the thinking and apply it so that it works in your situation. Can you now see how we can use similar logic in two different places to iterate the records? Please let me know if you still need some clarification.

    public boolean validate(Object _calledFrom = null)
    {
        MPWorkerTransHeader     row;
    
        if (callerDs.anyMarked())
        {
            row   = callerDs.getFirst( 1, false );
    
            while (row)
            {
                // Here you can validate anything you want to
    	        if (row.MyField != myValue)
    	        {
                    return checkFailed("Error");
                }
                row = callerDs.getNext();
            }
        }
        else
        {
            return checkFailed("No records selected.");
        }
    }

  • Suggested answer
    nmaenpaa Profile Picture
    101,160 Moderator on at
    RE: Runbase batch validation

    What do you mean by "we can't"? Can you explain us why you can't? And what do you mean by args? You don't need any args to iterate the records of the caller data source.

    Technically you definetely can iterate the records in the validate method, just like you did in the update method.

  • Riyas ahamed F Profile Picture
    1,215 on at
    RE: Runbase batch validation

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

  • Suggested answer
    nmaenpaa Profile Picture
    101,160 Moderator on at
    RE: Runbase batch validation

    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
    RE: Runbase batch validation

        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 ?

  • Gunjan Bhattachayya Profile Picture
    35,421 on at
    RE: Runbase batch validation

    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 ;
    }

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…

Andrés Arias – Community Spotlight

We are honored to recognize Andrés Arias as our Community Spotlight honoree for…

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

#1
Sohaib Cheema Profile Picture

Sohaib Cheema 844 User Group Leader

#2
André Arnaud de Calavon Profile Picture

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

#3
CA Neeraj Kumar Profile Picture

CA Neeraj Kumar 553

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans