I have one that is really making me scratch my head. It seems that my data directive BPM on the MtlQueue table that enables creation of another MtlQueue record via the Move Inventory Request methods is being skipped on the newly generated record.
Some more details. For replenishments or Stock Requests, our materials group wants to pick Lot tracked parts in a FIFO manner, so they want the Material Queue to find the oldest lot (lease numerical value 000001 the 000002, etc). The Material Queue out-of-box process will sort the bins in the Supply warehouse alphanumerically and pick the first one with on hand inventory. I created a data directive BPM that will reassign the Lot and Bin based on the oldest lot in the supply warehouse, which is working great.
The issue comes in when there isnāt enough of that Lot to satisfy the move request. I built some logic that will create a new move record with the remainder and, in theory, send it back through the same logic. What Iām seeing is the first process works great and generates the new record, but that new record will then completely bypass the data directive logic I have in place. No pop up messages, no assignments, just a clean record using the base logic.
Am I missing something? Shouldnāt any new record fire a data directive BPM thatās set to watch for new (rowmod = āAā) records?
The BPM is mostly widgets, except for the Oldest Lot Assignment part. The Lot assignment is happening In-Tran, then enabling a Standard to generate the new record.
Whenever this happens to me, I remove my condition and put in a message box to display the row mod and whatever other details of the record. I usually find out that my assumptions are wrong.
So thatās the fun part. I put a info message right off the Start block that gives me the RowMod and TranType values. It runs for the first pass perfectly, but the record added by the logic doesnāt pop that message at all. Deleted records work great too.
It seems like either the logic doesnāt get picked up because itās still processing the first one, or the second one magically bypasses it.
Frankly, Iām grasping at straws since Iāve never come across this, at least not for a very long time. Iām not sure how tracing would work here as thereās no client side actions happening, everything is server side and Iām not smart enough to know how to trace that activity.
Iām following my initial trace very specifically as it was giving errors if I left out any step.
Some caveats first. One, Iām not a developer so my code probably looks like it was written by someone who didnāt know when to give up. Two, this is the version I had ChatGPT help me with, and I think it did a decent enough job. Last, Iām in the process of adding a check to not select the previously assigned lot in the subsequent runs, but it doesnāt seem to be working yet.
This is the code that looks like the oldest lot and bin then sets the MtlQueue record. Seems to work as expected on the first record generated but not anything after.
Going back to your original question, I donāt understand how this fits in with the code you posted. This code looks like its doing some updates on the mtlqueue record when it is first created.
How are you expecting the second mtlqueue record to get created exactly?
I mentioned before that the majority of the BPM structure is in widgets, so no code was written by me. There is the one block where custom code was used, so thatās what I posted when asked for it.
Hereās the In Tran portion of the BPM, which is setting that Oldest Lot logic onto the MtlQueue table:
This is the Standard part of the BPM, which is branching based on the TranType value (STK-STK or RAU-STK) as we want both Move Inventory Requests and Replenishments to follow this path. The logic is then calling widgets to create the new MtlQueue records as we couldnāt get a direct creation of a MtlQueue record to work.
Apologies for the mess, I have a bunch of pop-ups in place to assist in troubleshooting and havenāt cleaned it up yet for production. However, hopefully this helps get you all a better idea of the process.
Ummm, ya you got code chunks hanging that never get used (Find Oldest Lot 1) that and Find Oldest Lot 2 both feeding the Set FromWhse?
Why not? How did you try to do this? IF this is all part of the same logic/process why in two separate directives? Also one is In-Tran and one is Standard. Only seeing 1 chunk of code posted and 4 separate code widgets.
Without a clear picture how do you expect someone to provide assistance with this? At least the widgets are named somewhat helpfully, but take a step back and explain your goal and the business objective.
I guess Iāll hold everyoneās hand a bit more then.
In Tran logic checks for an added record and the desired TranTypes (STK-STK or RAU-STK). If TRUE, it will run the Oldest Lot logic that is in the previously shared code block that looks in the Supply Warehouse and sorts by smallest Lot number then selects the Lot and Bin to assign to the MtlQueue record. If the Move Qty is less than the On Hand of the Lot in that bin, it only assigns the Lot and Bin. If the Move Qty is more than the On Hand of the lot in that bin, it will assign the Lot Qty and set a context field with the original amount. It then does a check on the Qty and if the original is more than the assigned, it sends it to a Standard BPM.
The Standard logic checks the TranType and then routes it to the correct BO.Method calls. RAU-STK goes to Replenishment.GenerateManual, STK-STK goes down the waterfall path on the MoveRequest BO methods.
In theory, the result from the Standard BPM should send the created record back through the In Tran logic. However, all of my testing seems to show that it is being bypassed for some reason. A new record is created with the correct Qty but the next oldest lot is not assigned.
@elfrykman
I can really appreciate what you are trying to do here⦠makes sense.
For troubleshooting this, put a BPM on the Method Call that you expect (In Theory) to create your record and just have it pop a message when itās hit with all the various variables/arguments and data set⦠to confirm itās actually getting it⦠your Theory may not be correct, or the method is failing to make the create⦠or there is another broken link in your chain of method calls.
Iāve seen something like this before.
To @jkane point⦠if itās available you might need to use the āComplete Callā widget to close out this call and then enable another Directive to pick it up? Grasping at Straws
Oldest Lot 1 is my original code that I was using that I wrote by hand. The Oldest Lot 2 code block is the ChatGPT assisted code. The BPM isnāt cleaned up yet as itās in the testing mess stage.
Using both widgets and code, written by someone a lot smarter than me, we were getting errors about a missing warehouse that wasnāt missing. It was a roadblock we couldnāt find a way around.
The Use Case is that Out of Box functionality when a MtlQueue record is created is to search Alphanumerically by Bin, find the first bin with On Hand inventory, and assign that location. We need to always pick the Oldest Lot first and want the Material Queue to tell the handlers where to go and what lot to grab. They are currently forced to open part tracker before any picks can be made for lot tracked parts to make sure they are getting the oldest lot. I ran this through Epicor Support and they said itās working as expected, so I added an idea for it but we canāt wait for that to maybe get implemented. (Here is the created Idea: Add Lot FIFO logic to Material Queue)
This is way to much for me to read at the moment, but Iāll target a single question at the start.
Why isnt this running after the first pass?
A possible cause is triggers getting turned off (Epicor does this in certain processes) or bypassing the facade (when you are calling a BO yourself, you can do this, which effectively skips BPMs)
Also, perhaps someone else has already mentioned this, but this seems to be too much load in an In-Trans. It will affect performance.
You should either ensure you can do everything you need async, or queue this up to be handled outside of the initial transaction.
Thatās a fun little nugget. Is there a way to see if the process is bypassing the facade?
What part is too much load? The code block is simply doing a few queries and setting fields, the new record creation is over in the Standard part of the BPM.
Iāve started dipping my toe in the function space, but is the idea to have this do more of the transacting, including the Lot Bin assignment, in order to keep it out of the data directive?