You can do this by two ways in x++ given below.
Method 1:
static void purchCancel(Args _args)
{
// purchtable.purchid =='000039'
PurchTable purchtable;
PurchLine purchLine;
PurchPrepayTable purchPrepayTable;
PurchQty purchQty;
boolean hasLines = false;
boolean messageShown = false;
PdsCWInventQty pdsCWQty;
MarkupTrans markupTrans;
McrOrderEventTable mcrOrderEventTable;
ttsbegin;
//selects a prepayment definition which does not have a paid or settled prepayment invoice
select firstonly forupdate PrepayApplicationRemaining from purchPrepayTable
where purchPrepayTable.PurchTable == '000039'
&& purchPrepayTable.IsDeleted == NoYes::No;
if (purchPrepayTable)
{
if (purchPrepayTable.PrepayApplicationRemaining == 0.0)
{
//reverses the prepayment invoices which have not been paid or settled
PurchPrepayTable::reverseUnpaidPostedAdvances('000039');
purchPrepayTable.Value = 0.0;
purchPrepayTable.PrepayLimit = 0.0;
purchPrepayTable.PrepayAvailable = 0.0;
purchPrepayTable.Description = '';
purchPrepayTable.PrepayCategoryId = 0;
purchPrepayTable.update();
}
else
{
//throws error and returns with message that a paid prepayment invoice exists therefore purchase order cannot be cancelled
error(strFmt("@SYS341265", 000039));
return;
}
}
if (purchTable.ChangeRequestRequired && purchTable.DocumentState >= VersioningDocumentState::Approved)
{
if (!purchTable.selectForUpdate())
{
purchTable = PurchTable::findRecId(purchTable.RecId, true);
}
VersioningPurchaseOrder::newPurchaseOrder(purchTable).createChangeRequest();
}
else if (!VersioningPurchaseOrder::newPurchaseOrder(purchTable).isLastVersionArchived() && purchTable.DocumentState == VersioningDocumentState::Confirmed)
{
// force archiving to avoid it during line cancellation as that would lead to update conflicts.
purchTable.update();
}
// do not cancel invoice matched lines.
while select forupdate purchLine
where purchLine.PurchId == '000039'
&& purchLine.IsDeleted == NoYes::No
{
hasLines = true;
if (purchLine.IsInvoiceMatched == NoYes::Yes)
{
if (purchLine.PurchStatus != PurchStatus::Invoiced)
{
if (!messageShown)
{
info("@SYS342633");
messageShown = true;
}
info(strFmt("@SYS342634", purchLine.LineNumber, purchLine.ItemId));
}
}
else
{
if (pdsIsCWItem(purchLine.ItemId))
{
pdsCWQty = purchLine.pdsCWReceivedInTotal() + purchLine.pdsCWArrived() + purchLine.pdsCWRegistered();
}
else
{
pdsCWQty = 0;
}
purchQty = purchLine.receivedInTotal() + purchLine.arrivedInPurchUnit() + purchLine.registeredInPurchUnit();
if (purchQty)
{
// if anything was recieved, arrived or registered then write down to what was recieved, arrived and registered.
purchLine.PurchQty = purchQty;
purchLine.PdsCWQty = pdsCWQty;
purchLine.LineAmount = purchLine.calcLineAmountForced();
}
else
{
purchLine.PurchQty = 0;
purchLine.LineAmount = 0;
purchLine.PdsCWQty = 0;
purchLine.PurchStatus = PurchStatus::Canceled;
if (purchLine.isDropShipment() &&
purchTable.InterCompanyDirectDelivery == NoYes::Yes)
{
purchTable.InterCompanyDirectDelivery = NoYes::No;
purchTable.doUpdate();
}
}
InventMovement::bufferSetTransQtyUnit(purchLine);
InventMovement::bufferSetRemainQty(purchLine);
// now cancel the markup
while select forupdate * from markupTrans
where markupTrans.TransRecId == purchTable.RecId
&& markupTrans.TransTableId == purchLine.TableId
&& markupTrans.MarkupCategory == MarkupCategory::Fixed
&& !markupTrans.IsDeleted
{
markupTrans.Value = 0;
markupTrans.update();
}
purchLine.update(false, true, false);
}
}
if (!hasLines)
{
purchTable.PurchStatus = PurchStatus::Canceled;
purchTable.update();
}
if ( purchTable.MCRDropShipment )
{
mcrOrderEventTable.insertFromDropShipment(purchTable.referenceSalesTable().SalesId, '000039', MCROrderEventType::CancelDropShipPO);
}
ttscommit;
PurchPrepayTable::checkApplicationRemaining(purchTable.PurchId, purchTable.InvoiceAccount);
info('done');
}
Method 2:
1) Make a class and extends from PurchCancel class
2) PurchCancel purchCancel;
purchCancel = PurchCancel::construct();
purchCancel.parmPurchTable(_purchTable);
purchCancel.run();
Please share results. Thanks