Hello Pros,
I have been ask to come up with a way to "age" our inventory into buckets based on receipt date using FIFO. "Current" inventory has been received in the last 29 days. Inventory received between 30 and 59 days ago would go into the "30 day" bucket and etc. I have approached doing this by going through the receipt transactions in our Transaction History table in descending date order and comparing the transaction Qty to the onhand qty. The following SQL is almost getting me what I want. It works fine as long as there are more than 1 receipt for a part. If it is a part that has been purchased and received only once, the AgeQty calculation fails and returns 0. Here are the fields in the query and a brief description of each:
SeqID is an alias for MaxID which is the primary key in the transaction history table. It is autonumber.
TDate - Transaction Date (Receipt Date)
TNXCDE_15 - Transaction Code. "R" is an inventory receipt
Cost_01 - The cost of the part. Used to value the inventory.
TNXQTY_15 - The quantity of the part being received.
RunTotal - The sum of the parts received starting with the most recent receipt in descending date order
Onhand_01 - The total number of parts we currently have onhand
D - a Boolean as to whether this receipt should be included in the aging.
LeftSum - How many are left to allocate
AgeQty - how many are in this age bucket.
Part Master is the table with the parts records
Transaction History is the table with the receipt records.
Here is the SQL for the query:
SELECT [Transaction History].MAXID AS SeqID, [Transaction History].PRTNUM_15 AS PartID, [Part Master].PMDES1_01, [Transaction History].TNXDTE_15 AS TDate, [Transaction History].TNXCDE_15, [Part Master].COST_01, [Transaction History].TNXQTY_15, DSum("tnxqty_15","Transaction History","PrtNum_15='" & [PartID] & "'and TNXCDE_15 = '" & "R" & "' and MAXID >= '" & [SeqID] & "'") AS RunTotal, [Part Master].onhand_01, IIf(Nz([leftSum],0)<=0,True,False) AS D, Nz((DSum("tnxqty_15","Transaction History","PrtNum_15='" & [PartID] & "'and TNXCDE_15 = '" & "R" & "' and MAXID > '" & [SeqID] & "'")-[onhand_01]),0) AS LeftSum, IIf([RunTotal]<[Onhand_01],[TNXQTY_15],Abs([Leftsum])) AS AgeQty
FROM [Part Master] INNER JOIN [Transaction History] ON [Part Master].PRTNUM_01 = [Transaction History].PRTNUM_15
WHERE ((([Transaction History].TNXCDE_15)="R"))
ORDER BY [Transaction History].PRTNUM_15, [Transaction History].TNXDTE_15 DESC;
The query results all look good except for the LeftSum calculation and the AgeQty calculation and they are correct for all parts that have more than one receipt. If a part has only been received once, the calculations show zero.
How can I get this query to correctly age all receipts? Is this the best approach to my request? I adapted this approach from this post I found on Experts Exchange. https://www.experts-exchange.com/questions/27920676/Inventory-Aging.html
Doyce