Patel's Dynamics Blog
Friday, December 13, 2024
Saturday, November 16, 2024
Financial dimension validation in Microsoft Dynamics 365 (D365).
My Requirement is to Ensure correct defaulting, restriction, and error handling for Legal Entity selection in the Purchase Requisition.
When a user selects a legal entity in the Purchase Requisition header, it should default to each line item.
If no legal entity is selected at the header level, prevent the addition of line items and display an error message: “Please select the legal entity from PR header financial dimension.”
The Legal Entity field in the header can only be modified if there are no line items. If line items exist and the user attempts to change the Legal Entity, display an error message: “Cannot change the legal entity after lines have been added.”
validate write method:-
public boolean validateWrite()
{
boolean ret;
str legalEntity,legalEntityLine;
ret = next validateWrite();
PurchReqLine purchReqLine;
select firstonly purchReqLine order by LineNum desc where purchReqLine.PurchReqTable == this.RecId ;
if (this.DefaultDimension != 0 && purchReqLine.LineNum > 0)
{
legalEntity = this.getDimValue(this.DefaultDimension);
legalEntityLine = this.getDimValue(purchReqLine.DefaultDimension);
if(legalEntity != legalEntityLine)
{
ret = checkFailed(strFmt("The Legal entity at the header level cannot be changed"));
}
}
return ret;
}
To get the dimension values:-
public DimensionValue getDimValue(PurchReqDefaultDimensionValueSet purchReqDefaultDimensionValueSet)
{
DimensionAttributeValueSet DimensionAttributeValueSet;
DimensionAttributeValueSetItem DimensionAttributeValueSetItem;
DimensionAttributeValue DimensionAttributeValue;
DimensionAttribute DimensionAttribute;
;
select RecId from DimensionAttributeValueSet
where DimensionAttributeValueSet.RecId == purchReqDefaultDimensionValueSet
join DisplayValue from DimensionAttributeValueSetItem
where DimensionAttributeValueSetItem.DimensionAttributeValueSet == DimensionAttributeValueSet.RecId
join RecId from DimensionAttributeValue
where DimensionAttributeValue.RecId == DimensionAttributeValueSetItem.DimensionAttributeValue
join RecId from DimensionAttribute
where DimensionAttribute.RecId == DimensionAttributeValue.DimensionAttribute
&& DimensionAttribute.Name == "LegalEntity";
return DimensionAttributeValueSetItem.DisplayValue;
}
Tuesday, October 29, 2024
How To make the entire grid non-editable in Dynamics 365 for Finance and Operations (D365 F&O) using X++
Total Grid Non-Editable:-
FormGridControl grid = element.design().controlName(formControlStr(YNV_InternalPuchaseRequisitionForm, YNV_InternalPurchaseRequisitionGrid));
grid.allowEdit(NoYes::No);
============================================================
Only one record is editable at the grid level.
In datasource's init() method after super() simply call:
allowEditFieldsOnFormDS_W(CustInvoiceJour_ds, false);
CustInvoiceJour_ds.object(fieldNum(CustInvoiceJour, PrintedOrginal)).allowEdit(true);
Tuesday, October 22, 2024
My requirement is to filter the datasource by adding conditions for a date range and grouping the results on the data source.
[Form]
public class YNV_ResAvailabilityQueryForm extends FormRun
{
[DataSource]
class ResActivityResourceRequestReservationUnionView
{
/// <summary>
///
/// </summary>
public void executeQuery()
{
QueryBuildDataSource queryBuildDataSource;
TransDate queryDate = today() + 30;
QueryBuildRange queryRange,taskNameRange;
queryBuildDataSource = this.query().dataSourceTable(tablenum(ResActivityResourceRequestReservationUnionView));
queryBuildDataSource.clearRanges();
taskNameRange = queryBuildDataSource.addRange(fieldnum(ResActivityResourceRequestReservationUnionView, TaskName ));
taskNameRange.value("Production");
taskNameRange.status(RangeStatus::Locked);
taskNameRange.status(RangeStatus::Hidden);
queryRange = queryBuildDataSource.addRange(fieldnum(ResActivityResourceRequestReservationUnionView, EndTime ));
queryRange.value(queryRange(dateNull(),queryDate));
queryRange.status(RangeStatus::Locked);
queryRange.status(RangeStatus::Hidden);
// Set order mode to group by
queryBuildDataSource.orderMode(OrderMode::GroupBy);
// Add group by field
queryBuildDataSource.addGroupByField(fieldNum(ResActivityResourceRequestReservationUnionView, Resource));
// Add selection field for max EndTime
queryBuildDataSource.addSelectionField(fieldNum(ResActivityResourceRequestReservationUnionView, EndTime), SelectionField::Max);
super();
}
}
Wednesday, September 18, 2024
My Requirement is Delete option in Vendor Master for all roles except System Administrator
[FormControlEventHandler(formControlStr(VendParameters, VendParameters_YNV_VendorMasterDeletionOption), FormControlEventType::Modified)]
public static void VendParameters_YNV_VendorMasterDeletionOption_OnModified(FormControl sender, FormControlEventArgs e)
{
VendParameters vendParameters;
FormCheckBoxControl formCheckBoxControl = sender as FormCheckBoxControl;
ttsBegin;
while select
forUpdate crossCompany
YNV_VendorMasterDeletionOption,DataAreaId
from
vendParameters where vendParameters.DataAreaId != curExt()
{
changeCompany(vendParameters.dataAreaId)
{
vendParameters.YNV_VendorMasterDeletionOption = formCheckBoxControl.checked();
vendParameters.update();
}
}
ttsCommit;
}
====================
[ExtensionOf(FormDataSourcestr(VendTable, VendTable))]
final class YNV_VendTableFormDatasource_Extension
{
public int active()
{
int ret = next active();
VendTable vendTable = this.cursor();
boolean validate;
VendParameters vendParameters = VendParameters::find();
#SysSystemDefinedButtons
FormCommandButtonControl delete =this.formRun().control(this.formRun().controlId(#SystemDefinedDeleteButton)) as FormCommandButtonControl;
if (!Global::isSystemAdministrator() && vendParameters.YNV_VendorMasterDeletionOption)
{
delete.enabled(NoYes::No);
}
else
{
delete.enabled(NoYes::Yes);
}
=================================================
OutPut:-
Monday, August 5, 2024
Multi selection
My requirement is to move multiple records from one grid to another grid by using the clicked method.
public void clicked()
{
super();
SECURITYROLE sECURITYROLELoc = SECURITYROLE_Ds.cursor();
vendgroup vendgrouploc;
vendgroup vendorgroup;
ynv_xdscustomization xdscustomization;
int recordsCount;
recordsCount = vendgroup_ds.recordsMarked().lastIndex(); // Total number of marked records.
vendgrouploc = vendgroup_ds.getFirst(1);
while (vendgrouploc)
{
ttsbegin;
xdscustomization.vendgroup = vendgrouploc.vendgroup;
xdscustomization.name = vendgrouploc.name;
xdscustomization.securityname = securityroleloc.name;
xdscustomization.insert();
ttscommit;
vendgrouploc = vendgroup_ds.getNext();
}
}
Thursday, May 23, 2024
XML
My requirement is to create XML files for the vend payment journal through code and send them to SharePoint.
using System.IO;
using System.IO.Path;
using Microsoft.Azure;
using Blobstorage = Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.Dynamics.Platform.Integration.SharePoint;
using Microsoft.Dynamics.ApplicationPlatform.Services.Instrumentation;
using Microsoft.DynamicsOnline.Infrastructure.Components.SharedServiceUnitStorage;
using Microsoft.Dynamics.AX.Framework.FileManagement;
internal final class YNV_PoBankIntegration
{
/// <summary>
/// Class entry point. The system will call this method when a designated menu
/// is selected or when execution starts and this class is set as the startup class.
/// </summary>
/// <param name = "_args">The specified arguments.</param>
public static void createXML(LedgerJournalTrans ledgerJournalTrans)
{
XmlDocument doc;
XmlElement Document;
XmlElement CstmrCdtTrfInitn;
XmlElement GrpHdr;
XmlElement oneChild;
XmlElement secondChild;
XmlElement thirdChild;
XmlElement fourthChild;
XmlElement InitgPtyNode;
XmlElement InitgPtyChild;
XmlElement PmtInfList;
XmlElement PmtInfListChild1;
XmlElement PmtInfListChild2;
XmlElement PmtInfListChild3;
XmlElement PmtInfListChild4;
XmlElement PmtInfListChild5;
XmlElement PmtTpInf;
XmlElement SvcLvlList;
XmlElement SvcLvlListChild1;
XmlElement ReqdExctnDt;
XmlElement DbtrList;
XmlElement DbtrListChild1;
XmlElement PstlAdr;
XmlElement Ctry;
XmlElement AdrLine;
XmlElement DbtrAcct;
XmlElement IBAN;
XmlElement Id;
XmlElement DbtrAgt;
XmlElement FinInstnId;
XmlElement BIC;
XmlElement CdtTrfTxInf;
XmlElement PmtId;
XmlElement EndToEndId;
XmlElement Amt;
XmlElement InstdAmt;
XmlElement CdtrAgt;
XmlElement FinInstnIdList;
XmlElement Cdtr;
XmlElement Nm;
XmlElement CdtrAcct;
boolean transactionStatus = NoYes::No;
DimensionAttributeValueCombination combination,combinationOffset;
LedgerJournalTrans ledgerJournalTransLoc,ledgerJournalTransLocSum;
LedgerJournalTable ledgerJournalTable = LedgerJournalTable::find(ledgerJournalTrans.JournalNum);
doc = XmlDocument::newBlank();
Document = doc.createElement('Document');
Document.setAttribute('xsi:schemaLocation','urn:iso:std:iso:20022:tech:xsd:pain.001.001.03 pain.001.001.03.xsd');
Document.setAttribute('xmlns:xsi','http://www.w3.org/2001/XMLSchema-instance');
Document.setAttribute('xmlns','urn:iso:std:iso:20022:tech:xsd:pain.001.001.03');
doc.appendChild(Document);
//CstmrCdtTrfInitn
CstmrCdtTrfInitn = doc.createElement('CstmrCdtTrfInitn');
Document.appendChild(CstmrCdtTrfInitn);
str formatted = System.String::Format(
'{0:yyyyMMddTHHmmss}',
DateTimeUtil::newDateTime(systemDateGet(), timeNow()));
System.DateTime dateTime = System.DateTime::get_UtcNow();
str utcTimeAsStr = dateTime.ToString('yyyyMdHHmmss');
select sum(AmountCurDebit),sum(AmountCurCredit) from ledgerJournalTransLocSum where ledgerJournalTransLocSum.JournalNum == ledgerJournalTable.JournalNum;
// GrpHdr
GrpHdr = doc.createElement('GrpHdr');
CstmrCdtTrfInitn.appendChild(GrpHdr);
utcDateTime todayDate = DateTimeUtil::getSystemDateTime();
oneChild = doc.createElement('MsgId');
oneChild.appendChild(doc.createTextNode(strFmt("%1-%2" ,ledgerJournalTrans.JournalNum , utcTimeAsStr)));
GrpHdr.appendChild(oneChild);
secondChild = doc.createElement('CreDtTm');
secondChild.appendChild(doc.createTextNode(formatted));
GrpHdr.appendChild(secondChild);
thirdChild = doc.createElement('NbOfTxs');
thirdChild.appendChild(doc.createTextNode(any2Str(ledgerJournalTable.numOfLines())));
GrpHdr.appendChild(thirdChild);
fourthChild = doc.createElement('CtrlSum');
fourthChild.appendChild(doc.createTextNode(any2Str(trunc(ledgerJournalTransLocSum.AmountCurDebit - ledgerJournalTransLocSum.AmountCurCredit))));
GrpHdr.appendChild(fourthChild);
// InitgPtyNode
InitgPtyNode = doc.createElement('InitgPtyc');
GrpHdr.appendChild(InitgPtyNode);
InitgPtyChild = doc.createElement('Nm');
InitgPtyChild.appendChild(doc.createTextNode(CompanyInfo::findRecId(CompanyInfo::current()).Name));
InitgPtyNode.appendChild(InitgPtyChild);
PaymentFormatCodeSets_W paymentFormatCodeSets_W = PaymentFormatCodeSets_W::find(VendPaymModeTable::find(ledgerJournalTrans.PaymMode).RecId);
// PmtInfList Node
PmtInfList = doc.createElement('PmtInf');
CstmrCdtTrfInitn.appendChild(PmtInfList);
PmtInfListChild1 = doc.createElement('PmtInfId');
PmtInfListChild1.appendChild(doc.createTextNode(strFmt('0%1%2 020240515-01',ledgerJournalTrans.JournalNum,paymentFormatCodeSets_W.Code)));
PmtInfList.appendChild(PmtInfListChild1);
PmtInfListChild2 = doc.createElement('PmtMtd');
PmtInfListChild2.appendChild(doc.createTextNode('TRF'));
PmtInfList.appendChild(PmtInfListChild2);
PmtInfListChild3 = doc.createElement('BtchBookg');
PmtInfListChild3.appendChild(doc.createTextNode('false'));
PmtInfList.appendChild(PmtInfListChild3);
PmtInfListChild4 = doc.createElement('NbOfTxs');
PmtInfListChild4.appendChild(doc.createTextNode(any2Str(ledgerJournalTable.numOfLines())));
PmtInfList.appendChild(PmtInfListChild4);
PmtInfListChild5 = doc.createElement('CtrlSum');
PmtInfListChild5.appendChild(doc.createTextNode(any2Str(trunc(ledgerJournalTransLocSum.AmountCurDebit - ledgerJournalTransLocSum.AmountCurCredit))));
PmtInfList.appendChild(PmtInfListChild5);
// PmtTpInf
PmtTpInf = doc.createElement('PmtTpInf');
PmtInfList.appendChild(PmtTpInf);
// SvcLvlList
SvcLvlList = doc.createElement('SvcLvl');
PmtTpInf.appendChild(SvcLvlList);
SvcLvlListChild1 = doc.createElement('Cd');
SvcLvlListChild1.appendChild(doc.createTextNode(paymentFormatCodeSets_W.Code));
SvcLvlList.appendChild(SvcLvlListChild1);
// ReqdExctnDt
ReqdExctnDt = doc.createElement('ReqdExctnDt');
ReqdExctnDt.appendChild(doc.createTextNode(any2Str((systemDateGet()))));
PmtInfList.appendChild(ReqdExctnDt);
// DbtrList
DbtrList = doc.createElement('Dbtr');
PmtInfList.appendChild(DbtrList);
DbtrListChild1 = doc.createElement('Nm');
DbtrListChild1.appendChild(doc.createTextNode(CompanyInfo::findByCompany_IN(ledgerJournalTrans.Company).Name));
DbtrList.appendChild(DbtrListChild1);
//PstlAdr
PstlAdr = doc.createElement('PstlAdr');
DbtrList.appendChild(PstlAdr);
Ctry = doc.createElement('Ctry');
Ctry.appendChild(doc.createTextNode(SysCountryRegionCode::countryInfo(ledgerJournalTrans.Company)));
PstlAdr.appendChild(Ctry);
AdrLine = doc.createElement('AdrLine');
AdrLine.appendChild(doc.createTextNode(CompanyInfo::findByCompany_IN(ledgerJournalTrans.Company).postalAddress().Address));
PstlAdr.appendChild(AdrLine);
//
DbtrAcct = doc.createElement('DbtrAcct');
PmtInfList.appendChild(DbtrAcct);
Id = doc.createElement('Id');
DbtrAcct.appendChild(Id)
;
IBAN = doc.createElement('IBAN');
combinationOffset = DimensionAttributeValueCombination::find(ledgerJournalTrans.OffsetLedgerDimension);
IBAN.appendChild(doc.createTextNode(BankAccountTable::find(combinationOffset.DisplayValue).AccountNum));
Id.appendChild(IBAN);
DbtrAgt = doc.createElement('DbtrAgt');
PmtInfList.appendChild(DbtrAgt);
FinInstnId = doc.createElement('FinInstnId');
DbtrAgt.appendChild(FinInstnId);
BIC = doc.createElement('BIC');
BIC.appendChild(doc.createTextNode(BankAccountTable::find(combinationOffset.DisplayValue).SWIFTNo));
FinInstnId.appendChild(BIC);
while select ledgerJournalTransLoc where ledgerJournalTransLoc.JournalNum == ledgerJournalTrans.JournalNum
{
transactionStatus = NoYes::Yes;
combination = DimensionAttributeValueCombination::find(ledgerJournalTransLoc.LedgerDimension);
CdtTrfTxInf = doc.createElement('CdtTrfTxInf');
PmtInfList.appendChild(CdtTrfTxInf);
PmtId = doc.createElement('PmtId');
CdtTrfTxInf.appendChild(PmtId);
EndToEndId = doc.createElement('EndToEndId');
EndToEndId.appendChild(doc.createTextNode(strFmt('%1-%2-05',ledgerJournalTransLoc.Voucher,ledgerJournalTransLoc.RecId)));
PmtId.appendChild(EndToEndId);
Amt = doc.createElement('Amt');
CdtTrfTxInf.appendChild(Amt);
InstdAmt = doc.createElement('InstdAmt');
InstdAmt.setAttribute("Ccy",ledgerJournalTransLoc.CurrencyCode);
if (ledgerJournalTransLoc.AmountCurDebit != 0)
{
InstdAmt.appendChild(doc.createTextNode(any2Str(trunc(ledgerJournalTransLoc.AmountCurDebit))));
}
else
{
InstdAmt.appendChild(doc.createTextNode(strFmt("-%1",any2Str(trunc(ledgerJournalTransLoc.AmountCurCredit)))));
}
Amt.appendChild(InstdAmt);
CdtrAgt = doc.createElement('CdtrAgt');
CdtTrfTxInf.appendChild(CdtrAgt);
FinInstnIdList = doc.createElement('FinInstnId');
CdtrAgt.appendChild(FinInstnIdList);
BIC = doc.createElement('BIC');
BIC.appendChild(doc.createTextNode(VendBankAccount::find(combination.displayValue,ledgerJournalTransLoc.CustVendBankAccountId).SWIFTNo));
FinInstnIdList.appendChild(BIC);
Nm = doc.createElement('Nm');
Nm.appendChild(doc.createTextNode(VendBankAccount::find(combination.displayValue,ledgerJournalTransLoc.CustVendBankAccountId).Name));
FinInstnIdList.appendChild(Nm);
PstlAdr = doc.createElement('PstlAdr');
FinInstnIdList.appendChild(PstlAdr);
Ctry = doc.createElement('Ctry');
Ctry.appendChild(doc.createTextNode(LogisticsAddressCountryRegion::find(LogisticsPostalAddress::findByLocation(VendBankAccount::find(combination.displayValue,ledgerJournalTransLoc.CustVendBankAccountId).Location).CountryRegionId).ISOcode));
PstlAdr.appendChild(Ctry);
AdrLine = doc.createElement('AdrLine');
AdrLine.appendChild(doc.createTextNode(LogisticsPostalAddress::findByLocation(VendBankAccount::find(combination.displayValue,ledgerJournalTransLoc.CustVendBankAccountId).Location).Address));
PstlAdr.appendChild(AdrLine);
Cdtr = doc.createElement('Cdtr');
CdtTrfTxInf.appendChild(Cdtr);
Nm = doc.createElement('Nm');
Nm.appendChild(doc.createTextNode('...... ..'));
Cdtr.appendChild(Nm);
PstlAdr = doc.createElement('PstlAdr');
Cdtr.appendChild(PstlAdr);
Ctry = doc.createElement('Ctry');
Ctry.appendChild(doc.createTextNode(LogisticsAddressCountryRegion::find(DirParty::primaryPostalAddress(VendTable::find(ledgerJournalTransLoc.accountDisplay()).Party).CountryRegionId).ISOcode));
PstlAdr.appendChild(Ctry);
AdrLine = doc.createElement('AdrLine');
AdrLine.appendChild(doc.createTextNode(DirParty::primaryPostalAddress(VendTable::find(ledgerJournalTransLoc.accountDisplay()).Party).Address));
PstlAdr.appendChild(AdrLine);
CdtrAcct = doc.createElement('CdtrAcct');
CdtTrfTxInf.appendChild(CdtrAcct);
Id = doc.createElement('Id');
CdtrAcct.appendChild(Id)
;
IBAN = doc.createElement('IBAN');
IBAN.appendChild(doc.createTextNode(VendBankAccount::find(combination.displayValue,ledgerJournalTransLoc.CustVendBankAccountId).BankIBAN));
Id.appendChild(IBAN);
}
Info("File sent to sharepoint");
System.Byte[] reportBytes = new System.Byte[0]();
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
reportBytes = enc.GetBytes(doc.outerXml());
System.IO.Stream streamLoc = new System.IO.MemoryStream(reportBytes);
if (transactionStatus == NoYes::Yes)
{
YNV_PoBankIntegration::sendFileToSharePoint(streamLoc,ledgerJournalTrans.JournalNum);
}
}
public static void sendFileToSharePoint(System.IO.Stream stream, LedgerJournalId ledgerJournalId)
{
Filename fileName;
FileUploadTemporaryStorageResult fileUploadResult;
VendParameters vendParameters =VendParameters::find();
if (fileUploadResult == null)
{
//fileName = System.Text.RegularExpressions.Regex::Replace(strFmt("%1-%2",ledgerJournalId,utcTimeAsStr), @"[\W_]", "");
System.DateTime dateTime = System.DateTime::get_UtcNow();
str utcTimeAsStr = dateTime.ToString('yyyyMdHHmmss');
str flileNameLoc = strFmt("%1%2.Xml",ledgerJournalId,utcTimeAsStr);
try
{
str defaultSPServer = vendParameters.YNV_SharePointURL; //'tekexperts.sharepoint.com';
str spSite = vendParameters.YNV_SharePointSite; //'sites/YNVArchitectureAndDesign';
str spFolderPath = vendParameters.YNV_FileLocation; //"Shared Documents/Finance/Integration/POC_BankIntegration";
str fileContetType = System.Web.MimeMapping::GetMimeMapping(flileNameLoc);
str externalId = xUserInfo::getExternalId(vendParameters.YNV_UserForSharepointUser);
Microsoft.Dynamics.AX.Framework.FileManagement.IDocumentStorageProvider storageProvider = new Microsoft.Dynamics.AX.Framework.FileManagement.SharePointDocumentStorageProvider(
defaultSPServer,
spSite,
spFolderPath,
externalId);
storageProvider.ProviderId = DocuStorageProviderType::SharePoint;
if (storageProvider != null)
{
str uniqueFilename = storageProvider.GenerateUniqueName(filename);
Microsoft.Dynamics.AX.Framework.FileManagement.DocumentLocation location = storageProvider.SaveFile(
newGuid(),
flileNameLoc,
fileContetType,
stream);
}
}
catch(Exception::Error)
{
error("Upload failed.");
}
}
}
}
output:-
-
change company:- If you're working on one company within your code but need to insert data into another company, you'd indeed uti...
-
In this blog, I'm explaining how to Use the trace parser tool in D365FO. Any application at some point faces slow performance issues. It...