Dynamics365 Multiple ways to implement purchase receipt through X++
There are some way to purchase receipt in portal. I am summarize these various methods.
The simple way to purchase receipt. But the only one purchase order can be receipt.
public void purchReceiptOnePO(PurchId _purchId, Num _packingSlipId)
{
PurchTable purchTable;
purchTable = PurchTable::find(_purchId);
PurchFormLetter purchFormLetter;
purchFormLetter = purchFormLetter::construct(DocumentStatus::PackingSlip);
purchFormLetter.showQueryForm(false);
purchFormLetter.update(purchTable,
_packingSlipId,
purchTable.AccountingDate,
PurchUpdate::All,
AccountOrder::None,
false,
false);
}
2. Using SysQuery
You can purchase receipt to multiple purchase order simply. I hope you customize parameter section to your situation.
public void purchReceiptUsingQuery(container _purchIdCon)
{
Query query;
SysQueryRun queryRun;
PurchFormLetter purchFormLetter;
PurchTable purchTable;
int i;
// Set query
query = new Query(queryStr(PurchUpdate));
// Select purchase order
for(i = 1 ; i <= conLen(_purchIdCon) ; i++)
{
query.dataSourceTable(tableNum(PurchTable)).addRange(fieldNum(PurchTable, PurchId)).value(conPeek(_purchIdCon, i));
}
queryRun = new SysQueryRun(query);
// Post purchase receipt
purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);
purchFormLetter.chooseLinesQuery(queryRun);
purchFormLetter.chooseLines();
purchFormLetter.createParmUpdateFromParmUpdateRecord(purchFormLetter.purchParmUpdate());
if(purchFormLetter.prompt())
{
purchFormLetter.run();
}
}
3. Partial purchase receipt with item registration
领英推荐
In many articles, they wrote down various ways to do Purchase Receipt. However, I tried to make a standard code that could be done Purchase Receipt with registration to use PurchParmTable, and I was able to make the code as below.
First, you should create contract class. Because I standardize code to use List (Class types).
[DataContractAttribute]
internal final class HDGPurchReceipt_PurchReceiptContract
{
private PurchId purchId;
private TradeLineNumber lineNumber;
private TransDate transDate;
private Num num;
private PurchQty receiveQty;
private boolean register;
private InventSiteId inventSiteId;
private InventLocationId inventLocationId;
private WMSLocationId wMSLocationId;
[DataMemberAttribute("PurchId")]
public PurchId PurchId(PurchId _purchId = purchId)
{
purchId = _purchId;
return purchId;
}
[DataMemberAttribute("LineNumber")]
public TradeLineNumber LineNumber(TradeLineNumber _lineNumber = lineNumber)
{
lineNumber = _lineNumber;
return lineNumber;
}
[DataMemberAttribute("TransDate")]
public TransDate TransDate(TransDate _transDate = transDate)
{
transDate = _transDate;
return transDate;
}
[DataMemberAttribute("Num")]
public Num Num(Num _num = num)
{
num = _num;
return num;
}
[DataMemberAttribute("ReceiveQty")]
public PurchQty ReceiveQty(PurchQty _receiveQty = receiveQty)
{
receiveQty = _receiveQty;
return receiveQty;
}
[DataMemberAttribute('Register')]
public boolean Register(boolean _register = register)
{
register = _register;
return register;
}
[DataMemberAttribute('InventSiteId')]
public InventSiteId InventSiteId(InventSiteId _inventSiteId = inventSiteId)
{
inventSiteId = _inventSiteId;
return inventSiteId;
}
[DataMemberAttribute('InventLocationId')]
public InventLocationId InventLocationId(InventLocationId _inventLocationId = inventLocationId)
{
inventLocationId = _inventLocationId;
return inventLocationId;
}
[DataMemberAttribute('wMSLocationId')]
public WMSLocationId wMSLocationId(WMSLocationId _wMSLocationId = wMSLocationId)
{
wMSLocationId = _wMSLocationId;
return wMSLocationId;
}
}
After list is serialized, you can purchase receipt yo use below code.
internal final class HDGPurchReceipt_PurchReceiptPartialHelper
{
PurchParmUpdate purchParmUpdate;
private List gList;
public List parmPurchReceiptList(List _list)
{
gList = _list;
return gList;
}
public void run()
{
HDGPurchReceipt_PurchReceiptPartialContract contract;
PurchFormLetterParmData purchFormLetterParmData;
PurchParmTable purchParmTable, purchParmTableDuplicate;
PurchParmLine purchParmLine;
ListEnumerator listEnumerator = gList.getEnumerator();
ttsbegin;
purchFormLetterParmData = PurchFormletterParmData::newData(DocumentStatus::PackingSlip, VersioningUpdateType::Initial);
purchFormLetterParmData.parmOnlyCreateParmUpdate(true);
purchFormLetterParmData.createData(false);
purchParmUpdate = purchFormLetterParmData.parmParmUpdate();
while(listEnumerator.moveNext())
{
contract = listEnumerator.current();
PurchLine purchLine = PurchLine::find(contract.PurchId(), contract.LineNumber());
// Validate
if(!purchLine)
{
throw error('Purchase order information is not valid.');
}
// If you need register before receipt, set Register to true
if(contract.Register())
{
this.registerPurchLine(contract);
}
// Check there is already created proper parmtable
select firstonly TableRefId, ParmId, RecId
from purchParmTableDuplicate
where purchParmTableDuplicate.ParmId == purchParmUpdate.ParmId
&& purchParmTableDuplicate.PurchId == contract.PurchId()
&& purchParmTableDuplicate.TransDate == contract.TransDate();
// If no, create parmtable
if(!purchParmTableDuplicate)
{
PurchTable purchTable = PurchTable::find(contract.PurchId());
purchParmTable.clear();
purchParmTable.TransDate = contract.TransDate();
purchParmTable.Ordering = DocumentStatus::PackingSlip;
purchParmTable.ParmJobStatus = ParmJobStatus::Waiting;
purchParmTable.Num = contract.Num();
purchParmTable.PurchId = purchTable.PurchId;
purchParmTable.PurchName = purchTable.PurchName;
purchParmTable.OrderAccount = purchTable.OrderAccount;
purchParmTable.CurrencyCode = purchTable.CurrencyCode;
purchParmTable.InvoiceAccount = purchTable.InvoiceAccount;
purchParmTable.DeliveryName = purchTable.DeliveryName;
purchParmTable.DeliveryPostalAddress = purchTable.DeliveryPostalAddress;
purchParmTable.ParmId = purchParmUpdate.ParmId;
purchParmTable.insert();
}
// If Yes, use created parmtable
else
{
purchParmTable = PurchParmTable::findRecId(purchParmTableDuplicate.RecId);
}
// Create parmline
purchParmLine.clear();
purchParmLine.initFromPurchLine(purchLine);
purchParmLine.ReceiveNow = contract.ReceiveQty();
purchParmLine.ParmId = purchParmTable.ParmId;
purchParmLine.TableRefId = purchParmTable.TableRefId;
purchParmLine.setQty(DocumentStatus::PackingSlip, false, true);
purchParmLine.setLineAmount();
if(contract.Register())
{
InventDim receivedInventDim;
receivedInventDim.InventSiteId = contract.InventSiteId();
receivedInventDim.InventLocationId = contract.InventLocationId();
receivedInventDim.wMSLocationId = contract.wMSLocationId();
purchParmLine.InventDimId = InventDim::findOrCreate(receivedInventDim).inventDimId;
}
purchParmLine.insert();
}
// Post purchase receipt
this.postPurchReceipt();
ttscommit;
}
private void registerPurchLine(HDGPurchReceipt_PurchReceiptPartialContract _contract)
{
PurchLine purchLine;
InventTrans inventTranslocal;
InventDim inventDimlocal;
purchLine = PurchLine::find(_contract.PurchId(), _contract.LineNumber());
// Get original InventTransId, InventDim
inventTranslocal = InventTrans::findTransId(purchLine.InventTransId, true);
inventDimlocal = inventTranslocal.inventDim();
// Set InventDim to InventTrans record
inventDimlocal.wMSLocationId = _contract.wMSLocationId();
inventDimlocal.InventLocationId = _contract.InventLocationId();
inventDimlocal.InventSiteId = _contract.InventSiteId();
inventDimlocal = InventDim::findOrCreate(inventDimlocal);
inventTranslocal.inventDimId = inventDimlocal.inventDimId;
// Create register data
InventTransWMS_Register inventTransWMS_register;
TmpInventTransWMS tmpInventTransWMS;
inventTransWMS_register = inventTransWMS_register::newStandard(tmpInventTransWMS);
tmpInventTransWMS.clear();
tmpInventTransWMS.initFromInventTrans(inventTranslocal);
tmpInventTransWMS.ItemId = inventTranslocal.ItemId;
tmpInventTransWMS.InventQty = _contract.ReceiveQty();
tmpInventTransWMS.insert();
inventTransWMS_register.writeTmpInventTransWMS(tmpInventTransWMS,
inventTranslocal,
inventDimlocal);
inventTransWMS_register.updateInvent(inventTranslocal);
}
private void postPurchReceipt()
{
PurchFormLetter purchFormLetter;
purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);
purchFormLetter.transDate(DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));
purchFormLetter.specQty(PurchUpdate::All);
purchFormLetter.parmParmTableNum(purchParmUpdate.ParmId);
purchFormLetter.parmId(purchParmUpdate.ParmId);
purchFormLetter.purchParmUpdate(purchParmUpdate);
purchFormLetter.run();
}
}
I write the comment on code, please refer that.
Also, you can check on GitHub too. (HDG_Dynamics365-Xpp-Samples/Purch_Receipt_MutipleWay/AxClass at main · ans1148/HDG_Dynamics365-Xpp-Samples (github.com))
Thanks for reading!