SBX - Search With Button

SBX - Forum Post Title

Referencing object created in lower stack

Microsoft Dynamics AX Forum

Jonx1000 asked a question on 13 Jul 2018 1:34 PM

Question Status

Verified

I apologize I am new too programming in general let alone x++. I want to modify the way the InventMovement\checkDImPhysical method handles some productions when I am posting reported as finished productions in the production module. When I am debugging I see that when I validate the RAF journal it originally calls the ProdJournalCheckPostProd class. Eventually in the call stack it uses the checkDimPhysical method from the InventMovement class and "this" contains the prodJournalProd table with a single production journal selected. When I try to edit the checkDimPhysical method by adding this.prodJournalProd I get a syntax error. If I print "this" I get no error.

The table isn't mentioned anywhere in this method or class I don't know how but is it possible that the object is from another class in the call stack. How can I use this information in this method or do I have to declare the table as variable and run a query to find it? 

I'm sorry if I am not clear if I need to reword this or provide more information please me know. 

if (this.dimSearch().dimPrimaryStocking())
                    {
                        okTmp = checkFailed(strfmt("@SYS54776",fieldid2pname(_inventDim.TableId, x)));


This is the line in the InventMovement\checkDimPhysical method that I want to add on to. The IDE isn't providing me the option for prodjournaltable when I type "this" as well, but it providing me other methods and properties instead.

Thank you.

Reply
Verified Answer

Hi Jonx1000,

InventMovement is a base class, for each table type it has a derived class that handles it. For prodJournalProd there are 3: InventMov_Prod_JournalProd, InventMov_Prod_JournalProd_CoBy, InventMov_Prod_JournalProd_Process. To find out which one you can put a breakpoint into InventMovement::constructNoThrow() method and see with one is created. Then you can override checkDImPhysical  method in one of those classes and do your check, don;t forget to call super() otherwise you would skip validation that is done in base method. Since prodJournalProd  is a variable you dont need to write "this.prodJournalProd" just "prodJournalProd" is enough.

Reply
Jonx1000 responded on 14 Jul 2018 3:34 AM

Thank you it was InventMov_Prod_JournalProd.

I overrided the method but theres no way I can use the okfailed variabke information from the base class right? I wanted to update the record based on that expression I quoted in my post.

Reply
Suggested Answer

Why not ? You can do something like:

public boolean checkDimPhysical(

   InventQty   _qty,

   InventDim   _inventDim,

   boolean     _finalCheck,

   boolean     _showError = true,

   boolean     _checkPalletLocation = true,

   Set         _specificDimensionsToCheck = null

   )

{

   boolean ok = super();

   ok = ok && //you code here;

   return ok;

}

So boolean ok = super(); will execute base(standard) code and return result of execution.

Reply
Jonx1000 responded on 14 Jul 2018 7:26 AM
When I tried to set super without any parameters its throwing an error. "ok" seems to be just returning a boolean, but not the
checkFailed(strfmt("@SYS54776",fieldid2pname(_inventDim.TableId, x))); warning I was looking for. I've seen methods overried in the AOT with the same pattern you described not sure why its not working.
Reply

It was not the exact code you should use, just an example. You have to pass all the parameters to the super, like 

boolean ok = super(_qty, _inventDim, _finalCheck, _showError, _checkPalletLocation, _specificDimensionsToCheck ); 

unless you want to change them before passing to the base method.

checkFailed returns a boolean and adds message to the infolog, so if in the super you will hit next line

checkFailed(strfmt("@SYS54776",fieldid2pname(_inventDim.TableId, x)));

then ok would be false, because it's a boolean and message would be added to the infolog. 

Reply
Jonx1000 responded on 14 Jul 2018 3:54 PM

Okay sorry I took it literally, I filled the parameters in for super and it worked. Thank you so now the overriden method works and I am able to access the prodJournalProd records thank you, but my last question is how can I access only those that are being triggered by that particular error. If ok returns false I'm assuming it can trigger false cause of another error it may not always be @SYS54776. Should I parse the infobox if possible or is there a better way I should perform this?

Reply

Why do you need to know what the error was ?

Reply
Jonx1000 responded on 14 Jul 2018 4:11 PM

I want to either delete the journal or subtract quantity from it based on the amount that has not actually been registered.

Reply
Verified Answer

Then the easiest way for you (easiest not best) is to copy paste method from InventMovement to InventMov_Prod_JournalProd (forget about super()) and put your code wherever you need.

Reply
Jonx1000 responded on 14 Jul 2018 5:10 PM

Okay i was able to modify those records on our development server. Just curious what would be a better method?

Reply

Its not the best because you are hiding parent method and if you will install a hotfix that add some code your version won't have it or even if your fallow developer will do a mod in that method that should affect all inventMov classes you wont be affected because you not calling super. I would say better approach is to call super, check that it return false and then do your check again (without info message). If it falls into your check conditions do your code, otherwise do nothing because it is false because of a different reason.

Reply
Jonx1000 responded on 15 Jul 2018 10:07 AM

Okay I am almost done this is what I have so far:

boolean checkDimPhysical(InventQty _qty, InventDim _inventDim, boolean finalCheck, boolean _showError, boolean _checkPalletLocation)
{
    boolean ret;
    ProdJournalCheckPostProd prodJournalCheckPostProd;
    ;

    ret = super(_qty, _inventDim, finalCheck, _showError, _checkPalletLocation);

    if ("first condition" && this.dimSearch().dimPrimaryStocking())
    {
        if (prodJournalProd.QtyGood - _qty == 0)
        {
            ttsBegin;
                print prodJournalProd.ProdId;
                info(strfmt("%1 removed RAF Journal %2", prodJournalProd.ProdId, prodJournalProd.JournalId));
                prodJournalProd.delete();
                prodJournalProd.update();
            ttsCommit;
        }
        else if (prodJournalProd.QtyGood - _qty < 0)
        {
        }
        else
        {
            ttsBegin;
                print prodJournalProd.ProdId;
                info(strfmt("%1 removed %2 qty left %3", prodJournalProd.ProdId, _qty, prodJournalProd.QtyGood - _qty));
                prodJournalProd.QtyGood -= _qty;
                prodJournalProd.update();
            ttsCommit;

/*
            prodJournalCheckPostProd = new ProdJournalCheckPostProd();
            prodJournalCheckPostProd.run();
*/
        }
    }

    return ret;
}


You can ignore the else if statement I didn't come up with an error message to provide for it yet, but my issue is with the else statement. At the end I wanted to basically rerun the validate process, but I do not know how to rerun it. When I tried with the code I commented out it brings up the dialog box again and throws an error when I click okay. I get the error "Error executing code: InventMov_Prod_JournalProd (object) has no valid runable code in method 'checkDimPhysical'".

Which makes sense I did not pass any parameters too it, but I did not see the option to and there wasn't a construct method available either. What I am trying to do is run the validate process again without bringing up the dialog box again. Once this is done the code should be completed.

Reply
Jonx1000 responded on 15 Jul 2018 10:26 AM

I found a method in the ProdJournalCheckPostProd class called newJournalCheckPost. But, when I use it I get an error message for one of the parameters.  

prodJournalCheckPostProd::newJournalCheckPost(False, True, _journalCheckPostType::Check, prodJournalProd.TableId, prodJournalProd.JournalId);

_journalCheckPostType::Check  when I try to complie the debugger throws the error "the enumeration does not exist" whether I declare it as a variable or not it throws the error either way.

Reply
Jonx1000 responded on 15 Jul 2018 10:44 AM

I I was able to correct it, but I may just choose to manually click the validate button each time because in order to recall the validate process it seems to be very complex.

I got a different error now after running this :

 prodJournalCheckPostProd = new ProdJournalCheckPostProd();
            prodJournalCheckPostProd::newJournalCheckPost(False, True,_journalCheckPostType, prodJournalProd.TableId, prodJournalProd.JournalId);
            prodJournalCheckPostProd.run();


The error is Buffer not specified for call of JournalStatic::findJournalTableId

So for now I may just stop.

Reply
Jonx1000 responded on 15 Jul 2018 10:59 AM

Okay I was passing the wrong table ID i was passing the ProdJournalProd table id i needed to pass the ProdJournalTable table id. THe method is fully functional now just going to put it through some test cases before putting it on the production server thank you again for everything.

Reply
Verified Answer

Hi Jonx1000,

InventMovement is a base class, for each table type it has a derived class that handles it. For prodJournalProd there are 3: InventMov_Prod_JournalProd, InventMov_Prod_JournalProd_CoBy, InventMov_Prod_JournalProd_Process. To find out which one you can put a breakpoint into InventMovement::constructNoThrow() method and see with one is created. Then you can override checkDImPhysical  method in one of those classes and do your check, don;t forget to call super() otherwise you would skip validation that is done in base method. Since prodJournalProd  is a variable you dont need to write "this.prodJournalProd" just "prodJournalProd" is enough.

Reply
Verified Answer

Then the easiest way for you (easiest not best) is to copy paste method from InventMovement to InventMov_Prod_JournalProd (forget about super()) and put your code wherever you need.

Reply
Suggested Answer

Why not ? You can do something like:

public boolean checkDimPhysical(

   InventQty   _qty,

   InventDim   _inventDim,

   boolean     _finalCheck,

   boolean     _showError = true,

   boolean     _checkPalletLocation = true,

   Set         _specificDimensionsToCheck = null

   )

{

   boolean ok = super();

   ok = ok && //you code here;

   return ok;

}

So boolean ok = super(); will execute base(standard) code and return result of execution.

Reply

SBX - Two Col Forum

SBX - Migrated JS