As you rightly mentioned, there is no direct link between InventTrans and WHSWorkLine in D365 SCM which creates ambiguity during partial registrations and work cancellations.
To answer the first part of the question you can leverage the below mentioned approach:
InventTrans and WHSWorkLine can be linked through InventTransOrigin.
- InventTrans and InventTransOrigin (InventTrans.InventTransOrigin == InventTransOrigin.RecId)
- WHSWorkLine and InventTransOrigin (WHSWorkLine.InventTransId == InventTransOrigin.InventTransId)
You can use the class InventMov_Purch::workLineExistsForInventTransId for validating the workLine against the inventory transaction id.
The required conditions for posting the for the given InventTrans that are registered will be:
For scenario 1 and scenario 2:
1. Checking sum of WHSWorkLine.CompleteQty against the POLine that considers InventTrans.Qty registered (This query will be for work item lines that are completed and for purchase order lines that are registered).
2. Ignore the Work orderLines in status Cancelled or tied historically for Unregistered quantities. When the work lines are registered again then follow step number 1.
For getting the registered list of items from Purchase order lines you can use
//For Purchase Order Lines
select sum(InventQty) from inventTrans
where inventTrans.PurchLineRecId == purchLine.RecId
&& inventTrans.StatusReceipt == InventTransStatusReceipt::Registered;
//For Work Order Lines - Would recommend using the Query model
while select whsWorkLine
join whsWorkTable on whsWorkTable.WorkId == whsWorkLine.WorkId
where whsWorkLine.InventTransId == inventTrans.InventTransId
&& whsWorkLine.WorkStatus != whsWorkStatus::Closed
{
//For open lines skip posting
}
else
{
//Post the pending PO Lines
}
Hope this helps. Happy to answer questions, if any.