Registering/Receiving Inventory with X++ - AX 2012

This question is answered

We are trying to register some product (Site, Warehouse, Location, Serial Number) for a receiving service in AX 2012.  What is the proper way to do this? 

I have it working if the product doesn't require serial number, I just update the line's Receive Now quantity and PurchFormLetter.update using PurchUpdate::ReceiveNow quantity.

But for things that require a serial number, I have to register that product first, then use the PurchUpdate::Recorded quantity to receive in. 

Basically, I need to perform the function of the InventTransRegister Form in X++ code.  How is this accomplished?

Thanks

 

Verified Answer
  • To answer this question, it was a mix of a lot of things, starting with dolee's code:

    "Hi Andy,
    For some reason I can't post code here. Please check this post (domhk.blogspot.hk/.../ax2012-update-invent-registration-from.html) for an example that you can try in your development or testing environment."

    Which caused the following error, but got me on the right track:

    "Posting  Purchase order: PO-000001  Item: TestItem  Transaction has already been posted physically.  Posting An error occurred during update"

    This error was caused by:

    "InventTrans             inventTrans = InventTrans::findTransId();
    This bit of code simply grabs the first InventTransOrigin record where the InventTransID's match, then grabs the FIRST record of the InventTrans table where it matches up with the origin... regardless of status. The issue I was running into was even if it was received/registered, whatever status, it would grab the first InventTrans and override the record and it's InventDim record as well.
    So... It works, but not really because it totally messes up all your transactions if you receive more than once against the same PO line."

    Which I resolved in this post:

    "So I think I got it.  InventTrans::findTransId() wasn't cutting it for the above explained reason.  So, I used a similar query from that method, but made an addition to the where clause to grab inventTrans.StatusReceipt == StatusReceipt::Ordered.
    Also, instead of setting the inventDim = inventTrans.inventDim(), I created a brand new InventDim to set all my registration variables (SerialNumber, Location, Warehouse, etc etc)  This seems to help prevent the occasional overriding of serial numbers (Invent Dims). 
    The entire code is quite lengthy, but these two things fixed the major issues I was having."

    As I stated, my entire service is much more complex, but the above should help get you on your way!

All Replies
  • Hi Andy,

    I haven't done this before myself, but after looking at the AOT, you can try investigate the InventTransWMS and InventTransWMS_Register class for starters.

    My blog | PBC

    This posting is provided "AS IS" with no warranties, and confers no rights.

  • I've already been looking at that.  I can get the inventory dimensions in  (Site, Warehouse, Location, Serial Number), but the status is still "Ordered"... can't figure out how to get it registered.

    If you open a PO, click the Receive tab, click Product receipt, click the lines tab, click update line -> Registration, this is the process I'm talking about doing in code.  I can get everything set in the upper half of the grid, but I can't figure out how to then register it.  

  • Hi Andy,

    For some reason I can't post code here. Please check this post (domhk.blogspot.hk/.../ax2012-update-invent-registration-from.html) for an example that you can try in your development or testing environment.

    My blog | PBC

    This posting is provided "AS IS" with no warranties, and confers no rights.

  • Thanks dolee!

    This seems to be working better than what I had.  My only issue is, and I'm not sure if it's something to do with the code or something's messed up in the system, that some (16 out of 115) records throw an error saying:

    "Posting  Purchase order: PO-000001  Item: TestItem  Transaction has already been posted physically.  Posting An error occurred during update"

    I never got this one while doing things my old way.  Any ideas into this error?  

    Thanks,

  • Nope, haven't seen any error when I wrote the job.

    Any hints from the debugger?

    My blog | PBC

    This posting is provided "AS IS" with no warranties, and confers no rights.

  • Nope.  I'm 80% sure it's something messed up with 2 of my orders though.  Otherwise, your solution works great!  Thanks for the help!

  • So I turned out to be wrong.. the code you provided has one flaw:  

    InventTrans             inventTrans = InventTrans::findTransId();

    This bit of code simply grabs the first InventTransOrigin record where the InventTransID's match, then grabs the FIRST record of the InventTrans table where it matches up with the origin... regardless of status. The issue I was running into was even if it was received/registered, whatever status, it would grab the first InventTrans and override the record and it's InventDim record as well.

    So... It works, but not really because it totally messes up all your transactions if you receive more than once against the same PO line.

  • Thanks for the update, really appreciate it. I will update my post with your findings.

    I hope things turn out ok for you once this flaw is taken care of. :)

    My blog | PBC

    This posting is provided "AS IS" with no warranties, and confers no rights.

  • So I think I got it.  InventTrans::findTransId() wasn't cutting it for the above explained reason.  So, I used a similar query from that method, but made an addition to the where clause to grab inventTrans.StatusReceipt == StatusReceipt::Ordered.

    Also, instead of setting the inventDim = inventTrans.inventDim(), I created a brand new InventDim to set all my registration variables (SerialNumber, Location, Warehouse, etc etc)  This seems to help prevent the occasional overriding of serial numbers (Invent Dims). 

    The entire code is quite lengthy, but these two things fixed the major issues I was having. 

  • Now the question is how to unregister if receiving the line fails? New post here:

    community.dynamics.com/.../101762.aspx

  • To answer this question, it was a mix of a lot of things, starting with dolee's code:

    "Hi Andy,
    For some reason I can't post code here. Please check this post (domhk.blogspot.hk/.../ax2012-update-invent-registration-from.html) for an example that you can try in your development or testing environment."

    Which caused the following error, but got me on the right track:

    "Posting  Purchase order: PO-000001  Item: TestItem  Transaction has already been posted physically.  Posting An error occurred during update"

    This error was caused by:

    "InventTrans             inventTrans = InventTrans::findTransId();
    This bit of code simply grabs the first InventTransOrigin record where the InventTransID's match, then grabs the FIRST record of the InventTrans table where it matches up with the origin... regardless of status. The issue I was running into was even if it was received/registered, whatever status, it would grab the first InventTrans and override the record and it's InventDim record as well.
    So... It works, but not really because it totally messes up all your transactions if you receive more than once against the same PO line."

    Which I resolved in this post:

    "So I think I got it.  InventTrans::findTransId() wasn't cutting it for the above explained reason.  So, I used a similar query from that method, but made an addition to the where clause to grab inventTrans.StatusReceipt == StatusReceipt::Ordered.
    Also, instead of setting the inventDim = inventTrans.inventDim(), I created a brand new InventDim to set all my registration variables (SerialNumber, Location, Warehouse, etc etc)  This seems to help prevent the occasional overriding of serial numbers (Invent Dims). 
    The entire code is quite lengthy, but these two things fixed the major issues I was having."

    As I stated, my entire service is much more complex, but the above should help get you on your way!

  • Have you find an answer :)? I'm trying to solve the same issue

    If I fail to get a quick answer, I'll resort to receive it normally without registration then run an inventory transfer code to move it to the right batch/serial. The only thin it looks very pathetic to do it this way :(:(

  • Yes, I was able to get this part working. See the marked answer.. the problem was with the findInventTransId().  Copy the query in that method, but then add the extra bit for inventTrans.StatusReceipt == StatusReceipt::Ordered.

    As I also said, instead of assigning your inventDim to be your inventTrans.inventDim(), create a new InventDim so you don't override anything.

  • I tried this code, but I'm getting an error when I run it:

    "Cannot edit a record in Batched (InventBatch). The record has never been selected

  • Sounds like you haven't selected a record forupdate somewhere.  Are you inserting batch sets with your code, or trying to update one?  I don't think that was in the example we were using but like I said: sound like a missing "forupdate" in a select somewhere.