How to: Fix issues related to Intercompany chain and clean up broken inventory transcations
For those who have worked in Intercompany SO-POs know it very well that sometimes users across different legal entities face challenges in IC SO and IC PO. Issues with qty, statuses of lines or statuses of headers, broken inventory transactions for which nothing can be done.
Below is the script to fix the status on lines, the status on the header, and delete broken inventory transactions:
static void Job1(Args _args)
{
PurchLine purchLine,purchLineGB;
InventTrans inventTrans,inventTransGB;
InventTransOrigin inventTransOrigin,inventTransOriginGB;
SalesLine salesLine,salesLineGB;
SalesTable salestable,salestableGB;
PurchTable purchTable,purchTableGB;
void updateSO(inventTransId _inventTransId, SalesStatus _lineSalesStatus, SalesStatus _orderSalesStatus)
{
select forupdate salesLine where salesLine.InventTransId == _inventTransId;
salesLine.RemainInventPhysical = 0;
salesLine.RemainSalesPhysical = 0;
salesLine.SalesStatus =_lineSalesStatus;
salesLine.doUpdate();
info(strFmt("Salesline with inventtrans %1 updated ",SalesLine.InventTransId));
while select InventTransOrigin where inventTransOrigin.InventTransId == salesLine.InventTransId
join forUpdate inventTrans
where inventTrans.InventTransOrigin == InventTransOrigin.RecId
&& (inventTrans.StatusIssue == StatusIssue::OnOrder ||
inventTrans.StatusIssue == StatusIssue::ReservOrdered)
{
info(strFmt("InventTrans recid %1 %2 deleted",inventTrans.RecId,inventTrans.dataAreaId));
InventTrans.doDelete();
}
select forUpdate salesTable where salesTable.SalesId == salesLine.SalesId;
SalesTable.SalesStatus = _orderSalesStatus;
SalesTable.doUpdate();
info(strFmt("SalesTable with salesId %1 updated ",SalesLine.SalesId));
info(strFmt("---------------------------------------------------------"));
}
void updatePO(inventTransId _inventTransId, PurchStatus _linePurchStatus, PurchStatus _orderPurchStatus)
{
select forupdate purchLine where purchLine.InventTransId == _inventTransId;
purchLine.RemainPurchPhysical = 0;
purchLine.RemainInventPhysical = 0;
purchLine.PurchStatus = _linePurchStatus;
purchLine.doUpdate();
info(strFmt("PurchLine with inventtrans %1 updated ",PurchLine.InventTransId));
while select InventTransOrigin where inventTransOrigin.InventTransId == purchLine.InventTransId
join forUpdate inventTrans
where inventTrans.InventTransOrigin == InventTransOrigin.RecId
&& inventTrans.StatusReceipt == StatusReceipt::Ordered
{
info(strFmt("InventTrans recid %1 %2 deleted",inventTrans.RecId,inventTrans.dataAreaId));
InventTrans.doDelete();
}
select forUpdate purchTable where purchTable.PurchId == purchLine.purchId;
purchTable.PurchStatus = _orderPurchStatus;
purchTable.doUpdate();
info(strFmt("PurchTable with purchId %1 updated ",purchLine.purchId));
info(strFmt("---------------------------------------------------------"));
}
void updateSOGB(inventTransId _inventTransId, SalesStatus _lineSalesStatus, SalesStatus _orderSalesStatus)
{
select forupdate salesLineGB where salesLineGB.InventTransId == _inventTransId;
salesLineGB.RemainInventPhysical = 0;
salesLineGB.RemainSalesPhysical = 0;
salesLineGB.SalesStatus = _lineSalesStatus;
salesLineGB.doUpdate();
info(strFmt("Salesline with inventtrans %1 updated ",salesLineGB.InventTransId));
while select InventTransOriginGB where InventTransOriginGB.InventTransId == salesLineGB.InventTransId
join forUpdate inventTransGB
where inventTransGB.InventTransOrigin == InventTransOriginGB.RecId
&& (inventTransGB.StatusIssue == StatusIssue::OnOrder ||
inventTransGB.StatusIssue == StatusIssue::ReservOrdered)
{
info(strFmt("InventTransGB recid %1 %2 deleted",inventTransGB.RecId,inventTransGB.dataAreaId));
InventTransGB.doDelete();
}
select forUpdate salesTableGB where salesTableGB.SalesId == salesLineGB.SalesId;
SalesTableGB.SalesStatus = _orderSalesStatus;
SalesTableGB.doUpdate();
info(strFmt("SalesTable with salesId %1 updated ",SalesLineGB.SalesId));
info(strFmt("---------------------------------------------------------"));
}
void updatePOGB(inventTransId _inventTransId, PurchStatus _linePurchStatus, PurchStatus _orderPurchStatus)
{
select forupdate purchLineGB where purchLineGB.InventTransId == _inventTransId;
purchLineGB.RemainPurchPhysical = 0;
purchLineGB.RemainInventPhysical = 0;
purchLineGB.PurchStatus = _linePurchStatus;
purchLineGB.doUpdate();
info(strFmt("PurchLine with inventtrans %1 updated ",purchLineGB.InventTransId));
while select InventTransOriginGB where InventTransOriginGB.InventTransId == purchLineGB.InventTransId
join forUpdate inventTransGB
where inventTransGB.InventTransOrigin == InventTransOriginGB.RecId
&& inventTransGB.StatusReceipt == StatusReceipt::Ordered
{
info(strFmt("InventTrans recid %1 %2 deleted",inventTransGB.RecId,inventTransGB.dataAreaId));
InventTransGB.doDelete();
}
select forUpdate purchTableGB where purchTableGB.PurchId == purchLineGB.purchId;
purchTableGB.PurchStatus = _orderPurchStatus;
purchTableGB.doUpdate();
info(strFmt("PurchTable with purchId %1 updated ",purchLineGB.purchId));
info(strFmt("---------------------------------------------------------"));
}
ttsBegin;
changeCompany('FR01')
{
updateSO('inventTransId in FR01 LE',SalesStatus::Canceled,SalesStatus::Invoiced); //('lotid', Line status, Header status)
updatePO('inventTransId in FR01 LE',PurchStatus::Canceled,PurchStatus::Canceled); //('lotid', Line status, Header status)
}
changeCompany('GB01')
{
updateSOGB('inventTransId in GB01 LE',SalesStatus::Canceled ,SalesStatus::Canceled); //('lotid', Line status, Header status)
updatePOGB('inventTransId in FR01 LE',PurchStatus::Canceled,PurchStatus::Canceled); //('lotid', Line status, Header status)
}
ttsCommit;
}
Please note this does not break IC chain, just fixes the transcations. Usually this is done when SO and PO are in final state like Invoiced and some opne transcations remain which keeps it open. Also when SO/PO is cancelled in 1 LE and its open in other LE. I have used this script numerous times usually to fix the status to Invoice or Cancelled.
Note: Always test the results in Testing env before making changes in production enviroment.
If you need to break the IC chain and process the SO/PO then script is different. Thats for next blog.
Comments
Post a Comment