So a little background, first.
We have an on-prem instance of Epicor and my job (amongst others) is building/expending our own internal BI platform.
This includes a lot of delicate Epicor DB queries.
Recently, we got to thinking - it would be REALLY handy to be able to know all our exact inventory levels for any given point-in-time, and that made me think even more.
Couple weeks later and I came up with an algorithm that scans the PartTran table for each given part and “replays” all the actions - carefully tracking each part that was removed, and each part that was placed into inventory.
Surprisingly, it actually works… for the most part.
The only issue - the only parts that are “incorrect” when compared to current inventory levels, are parts that went into DMR and… well… they never came out.
In other words, I have a few dozen parts that were placed into DMR and - although Epicor removed them from inventory, there is no actual record of it in the PartTran history table.
What I look for is an entry in the PartTran table that has TranType of “DMR-REJ”. I then take the TranQty and subtract that from the bin.
But here is where things get hairy. You see, when a part is placed into inventory - there is an entry in the PartTran table. When a part is taken out for a sales order, or an inspection, or pretty much ANY other task… there is a corresponding entry created on-the-spot in the PartTran table.
But the instant that a DMR is created for a part - although Epicor REMOVES (de-incrementing) the part from the PartBin table accordingly, it DOES NOT create an entry in the PartTran table. In fact, it seems that a part may get DMR’d on a Monday - but no mention of this is in the PartTran table until the part is rejected.
There have also been a couple fringe cases where a DMR was cancelled and the part was placed back into inventory - which also throws off my logic.
It seems to me that any time the PartBin table is manipulated (parts removed or added), there should ALWAYS be an entry in PartTran to log the instant that part left “available inventory”.
So I dug deeper and realized: maybe I can query the DMRHead table and see when the DMR was created. Well, easier said than done. Even more ironically, the DMRHead table HAS NO CREATION timestamp! As it turns out, we have a handful of DMR’s that were started, but no action was actually taken against the DMR. (In other words, there is a DMRHead record, but nothing in DMRActn) Even though Epicor already took the parts out of inventory.
Another issue that I uncovered (and I realize this is largely user-error on behalf of the sales and warehouse guys that use Epicor) is this: sometimes 10 parts may get removed from inventory for DMR. All 10 are actually removed from the Bin and sent back for RMA… but only 5 are “Rejected”. This further skews my calculations.
Again, I understand a lot of this is the result of incorrect end-user-usage of the product. Nonetheless, if there is a reliable way I can query around this, that would be great.
Out of 60k+ parts, I have only ran into this issue on less than 200. Not too bad, but I would like to zero in on this a bit more.
So my questions are:
- How can I reliably query to see exactly when any given DMR was created? Date/time preferred. If only a date is available, I will take what I can get.
- Am I looking at the PartTran table wrongly? Currently, my algorithm says “INS-DMR” is “Adding a part to the specified bin”, and “DMR-REJ” is taking it back out. Seems there should be some other entry that I am missing? Seems Epicor has a hole in how it logs the data to PartTran? Seems to me, any time any QTY of parts is added or removed from PartBin, that exact amount should always be reflected in PartTran.
- TranDate seems to be Workstation date/time - correct? SysDate and SysTime is the date/time of the server - correct?
- The SysTime fields are seconds-since-midnight - correct? This is what I assumed from looking at the data.
If I could just reliably know each date/time every DMR is created, I can then join that data into my “PartTran replay logic” and - based on the DMRHead.TotDiscrepantQty value, I could use THAT as the “point-in-time” a DMR’d part was removed from the PartBin records.
Any help would be greatly valued!