/// <summary> /// Clicked /// </summary> public void clicked() { next clicked(); MedVisit visit; MenuFunction menuFunction; visit = this.formRun().dataSource(formDataSourceStr(MedVisit, MedVisit)).cursor(); FormRun formRun; Args args = new Args(); // Set the query to the form args.name(formStr(CASEvents)); // args.caller(this.formRun()); // Open the form with the specified query formRun = classFactory.formRunClass(args); formRun.init(); FormDataSource formDataSource = formRun.datasource(); formDataSource.query().dataSourceNo(1).addRange(fieldNum(CASEventsTable, EventID)).value(visit.CIAEventID); formDataSource.executeQuery(); formDataSource.getFirst(); formDataSource=formDataSource.getFirst().dataSource(); args.record(formDataSource.getFirst()); formRun.run(); formRun.wait(); }
This blog is contains coding reference related to Microsoft AX 2012 and D365 finance and operations and Power platform
Wednesday, October 15, 2025
Open form through code y passing filtered query using X++
Thursday, October 2, 2025
Run ER Report through code and send as an Email attachment
str subject = strFmt("Subject: %1 [Ref#]", AccountNum); str body = "<body><p>Dear Sir/Madam,</p><p>Please find attached.</p><p>Yours sincerely,<br>XXXX</p></body>"; if (email) { var fileDestination = ERObjectsFactory::createFileDestinationAttachmentWithOtherDocuType(CustTable); Query query = new Query(); query.addDataSource(tableNum(CustTable)) .addRange(fieldNum(CustTable, AccountNum)) .value(CustTable.AccountNum); str attachmentName = strFmt("OP-%1-%2", CustTable.AccountNum , DateTimeUtil::getSystemDateTime()); str fileName = strFmt("%1.docx",attachmentName); ERObjectsFactory::createFormatMappingRunByFormatMappingId((select ERFormatMappingTable where ERFormatMappingTable.Name == CASParameters::find().ERCorporatePreSuspensionFormatName).RecId, fileName) .withFileDestination(fileDestination) .withParameter(new ERModelDefinitionDatabaseContext() .addQuery(tableNum(CustTable), query)) .run(); EmailService_XX::sendEmailAttachment(subject, body, email, this.getAttachmentData(member,fileName), attachmentName); } else { throw error(strFmt("No primary email found for : %1", AccountNum)); } public static void sendEmailAttachment( str _subject, str _body, SysEmailAddress _emailAddr, DocuRef _docuRef, str _fileName) { SysMailerMessageBuilder mailer = new SysMailerMessageBuilder(); mailer.setSubject(_subject); mailer.setFrom(SysEmailParameters::find().SMTPUserName); mailer.setBody(_body); mailer.addTo(_emailAddr); var conversionResult = ERPdfConversionService::convertFileToPdf(DocumentManagement::getAttachmentStream(_docuRef), ".docx"); mailer.addAttachment(conversionResult.ResultStream,strFmt("%1.pdf",_fileName)); try { SysMailerFactory::sendNonInteractive(mailer.getMessage()); } catch(Exception::CLRError) { System.Exception ex = CLRInterop::getLastException(); error(ex.Message); ttsbegin; _docuRef.selectForUpdate(true); _docuRef.delete(); ttscommit; } finally { ttsbegin; _docuRef.selectForUpdate(true); _docuRef.delete(); ttscommit; } } //////////Another class using Microsoft.Dynamics365.LocalizationFramework; using TL = Microsoft.Dynamics365.LocalizationFramework.Telemetry; using BCS = Microsoft.Dynamics365.LocalizationFramework.ExternalApi.BCS; using DC = Microsoft.Dynamics365.LocalizationFramework.Services.DocumentConversion; using EA = Microsoft.Dynamics365.LocalizationFramework.ExternalApi; /// <summary> /// Class to provide access to PDF conversion process for Office documents. /// </summary> static class ERPdfConversionService { private static EA.MicrosoftInternalUseOnly.IOfficeConversionClient conversionClient; /// <summary> /// Converts given Microsoft Word or Excel file stream to PDF. /// </summary> /// <param name = "_stream">A given file stream.</param> /// <param name = "_fileExtension">A given file extension.</param> /// <param name = "_requestId">A request id to track request; optional.</param> /// <param name = "_conversionSettings">Conversion settings; optional.</param> /// <param name = "_localeIdentifier">The locale identifier.</param> /// <returns>The conversion result.</returns> [Hookable(false)] static BCS.ConvertToPdfResponse convertFileToPdf( System.IO.Stream _stream, str _fileExtension, guid _requestId = newGuid(), // ERFormatFileDestinationPdfConversionSettings _conversionSettings = null, int _localeIdentifier = 0 ) { BCS.ConvertToPdfRequest request = new BCS.ConvertToPdfRequest(); request.FileStream = _stream; request.ClientCorrelationId = _requestId; request.ClientName = identifierStr(DynamicsAxElectronicReporting); request.FileExtension = _fileExtension; request.PageOptions = null; request.LocaleIdentifier = _localeIdentifier; var conversionClient1 = CASERPdfConversionService::getClient(); return conversionClient1.ConvertToPdf(request, TL.ElectronicReportingMappingTelemetryLogger::Log); } /// <summary> /// Gets the client. /// </summary> /// <returns>Office conversion client.</returns> internal static EA.MicrosoftInternalUseOnly.IOfficeConversionClient getClient() { if (conversionClient == null) { conversionClient = EA.BCS.BcsApiClient::Instance; } return conversionClient; } /// <summary> /// Sets the client. /// </summary> /// <param name = "_conversionClient">A conversion client.</param> /// <remarks>For testing purpose.</remarks> internal static void setClient(EA.MicrosoftInternalUseOnly.IOfficeConversionClient _conversionClient) { conversionClient = _conversionClient; } } ///////
Currency Exchange Helper
CurrencyExchangeHelper currencyExchangeHelper; CurrencyCode toCurrency = _claimLine.CurrencyClaimed; CurrencyCode FromCurrency = modifierAward.FixedAmountCurrencyCode; currencyExchangeHelper = CurrencyExchangeHelper::newExchangeDate(Ledger::current(), _claimLine.TreatmentDate); fixedAmt = currencyExchangeHelper.calculateCurrencyToCurrency(toCurrency, fromCurrency,modifierAward.FixedAmount,true);
Sort a Map Descending order in X++
public static Map sortbasedonRVUlevel(Map _unsortedMap, SortOrder _sortOrder = SortOrder::Descending) { // Initialize map with key=int, value=real Map sortedMap = new Map(Types::Int64, Types::Real); MapEnumerator e; container pairs = conNull(); int64 key; int counter, i, j; real valueA, valueB; container temp; // Insert test data //m.insert(1, 10); //m.insert(2, 50); //m.insert(3, 20); //m.insert(4, 80); //m.insert(5, 40); //m.insert(6, 40); // Gather all entries into the main container e = _unsortedMap.getEnumerator(); while (e.moveNext()) { key = e.current(); pairs += [[key, _unsortedMap.lookup(key)]]; } // Sort container pairs by value descending (bubble sort for demonstration) counter = conLen(pairs); for (i = 1; i < counter; i++) { for (j = i + 1; j <= counter; j++) { valueA = conPeek(conPeek(pairs, i), 2); valueB = conPeek(conPeek(pairs, j), 2); if(_sortOrder == SortOrder::Descending) { if (valueA < valueB) // For descending order { temp = conPeek(pairs, i); pairs = conPoke(pairs, i, conPeek(pairs, j)); pairs = conPoke(pairs, j, temp); } } else { if (valueA > valueB) // For ascending order { temp = conPeek(pairs, i); pairs = conPoke(pairs, i, conPeek(pairs, j)); pairs = conPoke(pairs, j, temp); } } } } // Output sorted pairs for (i = 1; i <= counter; i++) { key = conPeek(conPeek(pairs, i), 1); valueA = conPeek(conPeek(pairs, i), 2); sortedMap.add(key, valueA); info(strFmt("Key: %1, Value: %2", key, valueA)); } return sortedMap; }
Generate custom URL D365 FO
public static str generateFTILink(RecId _invoiceIdentifier, DataAreaId _dataAreaId)
{
//gets the generator instance
var generator = new Microsoft.Dynamics.AX.Framework.Utilities.UrlHelper.UrlGenerator();
var currentHost = new System.Uri(UrlUtility::getUrl());
generator.HostUrl = currentHost.GetLeftPart(System.UriPartial::Authority);
generator.Company = _dataAreaId;
generator.MenuItemName = menuItemDisplayStr(CustFreeInvoiceListPage);
generator.Partition = getCurrentPartition();
generator.PageType = FormViewOption::Details;
var requestQueryParameterCollection = generator.RequestQueryParameterCollection;
requestQueryParameterCollection.AddRequestQueryParameter(
formDataSourceStr(CustFreeInvoice, CustInvoiceTable),
'RecId', int642Str(_invoiceIdentifier));
System.Uri fullURI = generator.GenerateFullUrl();
// to get the encoded URI, use the following code
return fullURI.AbsoluteUri;
}
Thursday, January 30, 2025
Reserve and unreserve Item using X++
public void reserveItem(ItemId _itemId,InventTransId _inventTransId, Purchline _purchline) { InventTrans inventTrans; InventTransOrigin inventTransOrigin; InventMovement inventMovement; InventUpd_Reservation inventUpd_Reservation ; InventDim inventdim; // Reserve an item select inventTrans where inventTrans.ItemId == _itemId && inventTrans.StatusReceipt == StatusReceipt::None && inventTrans.StatusIssue == StatusIssue::OnOrder exists join inventTransOrigin where inventTransOrigin.RecId == inventTrans.InventTransOrigin && inventTransOrigin.InventTransId == _inventTransId && inventTrans.MarkingRefInventTransOrigin == InventTransOrigin::findByInventTransId(_purchline.InventTransId).RecId; inventdim = inventTrans.inventDim(); inventdim.inventBatchId = strFmt("%1-%2",_purchline.PurchId,_purchline.InventTransId ); inventdim = inventdim::findDim(inventdim); if(inventTrans.RecId) { Inventmovement = inventTrans.inventmovement(true); inventUpd_Reservation = InventUpd_Reservation::newInventDim(inventmovement,inventdim ? inventdim : inventTrans.inventDim(),inventTrans.Qty, false); inventUpd_Reservation.updatenow(); } } public void removeReserveItem(ItemId _itemId,InventTransId _inventTransId) { InventTrans inventTrans; InventTransOrigin inventTransOrigin; InventMovement inventMovement; InventUpd_Reservation inventUpd_Reservation ; // Remove reservations and markings on a reserved transfer order while select inventTrans where inventTrans.ItemId == _itemId && inventTrans.StatusReceipt == StatusReceipt::None && (inventTrans.StatusIssue == StatusIssue::ReservPhysical || inventTrans.StatusIssue == StatusIssue::ReservOrdered) exists join inventTransOrigin where inventTransOrigin.RecId == inventTrans.InventTransOrigin && inventTransOrigin.InventTransId == _inventTransId { if (inventTrans.StatusIssue == StatusIssue::ReservPhysical || inventTrans.StatusIssue == StatusIssue::ReservOrdered) { Inventmovement = inventTrans.inventmovement(true); inventUpd_Reservation = InventUpd_Reservation::newInventDim(inventmovement,inventTrans.inventDim(), -1 * inventTrans.Qty, false); inventUpd_Reservation.updatenow(); } } }
Trigger Sysoperation through button click
class PurchTableForm_EventHandler { /// <summary> /// run business logic for ConnectTransferOrder button /// </summary> /// <param name="sender">sender</param> /// <param name="e">e</param> [FormControlEventHandler(formControlStr(PurchTable, ConnectTransferOrder), FormControlEventType::Clicked),SuppressBPWarning('BPParameterNotUsed', 'Parameter required')] public static void ConnectTransferOrder_OnClicked(FormControl sender, FormControlEventArgs e) { FormDataSource formds = sender.formRun().dataSource(formDataSourceStr(PurchTable, PurchTable)); PurchTable purchTable = PurchTable::findRecId(formds.cursor().RecId); CreateUpdateTransferOrderController controller; SysOperationStartResult sysOperationStartResult; Args args = new Args(); args.caller(sender.formRun()); args.record(purchTable); controller = CreateUpdateTransferOrderController::newFromArgs(args); controller.parmExecutionMode(SysOperationExecutionMode::Synchronous); sysOperationStartResult = controller.startOperation(); formds.refresh(); formds.reread(); } }
Parse JSON response using X++ to vairables
str output =//JSON String; output = strRem(output, "["); output = strRem(output, "]"); Map jsonData; jsonData = RetailCommonWebAPI::getMapFromJsonString(output); container Error,Log,LinkIds,currentReponse; ListEnumerator listEnumerator,listenum; MapEnumerator mapEnumerator; mapEnumerator = jsonData.getEnumerator(); int AccNum; int Name; int Phone; int address; str errorTxt; str logTxt; str hasErrorStr; while (mapEnumerator.moveNext()) { switch (mapEnumerator.currentKey()) { case "Error": hasErrorStr = mapEnumerator.currentValue(); break; case "Log": logTxt = mapEnumerator.currentValue(); break; case "CustomerDetails"://json array currentReponse = mapEnumerator.currentValue(); if(currentReponse) { for (int i=1; i <= conlen(currentReponse); i++) { switch(conpeek(currentReponse, i)) { case "AccNum": AccNum = conPeek(currentReponse,i+1); break; case "Name": Name = conPeek(currentReponse,i+1); break; case "Phone": Phone = conPeek(currentReponse,i+1); break; case "address": address = conPeek(currentReponse,i+1); break; } } } break; } }
Sysoperation multithread using subtasks
class CustInvoiceProcessBaseService extends SysOperationServiceBase { public void process(CustInvoiceProcessContract _contract) { Query query; QueryRun queryRun; CustInvoiceJour custInvoiceJour; int defaultBundleSize = _contract.parmbundleSize(); int defaultRecordLimit = _contract.parmRecordLimit(); query = _contract.getQuery(); queryRun = new QueryRun(query); int counter = 0, lineCount = 0; BatchHeader batchHeader = this.getCurrentBatchHeader(); List customerInvoiceList = new List(Types::Int64); while (queryRun.next()) { custInvoiceJour = queryRun.get(tableNum(CustInvoiceJour)); if (batchHeader) { counter++; customerInvoiceList.addEnd(custInvoiceJour.RecId); if (counter == DefaultBundleSize) { CustInvoiceProcessSubTaskController accountResolver = CustInvoiceProcessSubTaskController::newTaskController(customerInvoiceList, strFmt("@DistITServices:BundleSize", lineCount == 0 ? 1 : lineCount, lineCount + counter)); batchHeader.addRuntimeTask(accountResolver, BatchHeader::getCurrentBatchTask().RecId); customerInvoiceList = new List(Types::Int64); lineCount = lineCount + counter; counter = 0; } if (lineCount >= DefaultRecordLimit) { break; } } else { lineCount++; CustInvoiceProcessSubTaskService::run(custInvoiceJour); } } if (batchHeader) { //To add last lines if (counter != 0 && counter <= DefaultBundleSize) { CustInvoiceProcessSubTaskController accountResolver = CustInvoiceProcessSubTaskController::newTaskController(customerInvoiceList, strFmt("@DistITServices:BundleSize",lineCount == 0 ? 1 : lineCount, lineCount + counter)); batchHeader.addRuntimeTask(accountResolver, BatchHeader::getCurrentBatchTask().RecId); customerInvoiceList = new List(Types::Int64); lineCount = lineCount + counter; counter = 0; } if (batchHeader) { batchHeader.save(); if (lineCount) { info(strFmt("%1 : %2", "@DMP1153", lineCount)); } } } else if (lineCount) { info(strFmt("%1 : %2", "@DMF:NumberOfRecordsProcessed", lineCount)); } } } /////////////////////////// [DataContractAttribute] class CustInvoiceProcessSubTaskContract extends SysOperationDataContractBase { List custInvoiceJourList = new List(Types::Int64); [ DataMemberAttribute, SysOperationControlVisibilityAttribute(false), AifCollectionTypeAttribute('return', Types::Int64) ] public List parmCustInvoiceJourList( List _custInvoiceJourList = custInvoiceJourList ) { custInvoiceJourList = _custInvoiceJourList; return custInvoiceJourList; } } ////////////////////////// class CustInvoiceProcessSubTaskController extends SysOperationServiceController { public ClassDescription defaultCaption() { return "@DistITServices:CustInvoiceProcess"; } private void new() { super(); this.parmClassName(classStr(CustInvoiceProcessSubTaskService_DIS)); this.parmMethodName(methodStr(CustInvoiceProcessSubTaskService_DIS, process)); this.parmExecutionMode(SysOperationExecutionMode::Synchronous); } public static SysOperationController newTaskController(List _list, str _taskDesc) { CustInvoiceProcessSubTaskControllercontroller = new CustInvoiceProcessSubTaskController_DIS(); CustInvoiceProcessSubTaskContract contract = controller.getDataContractObject() as CustInvoiceProcessSubTaskContract_DIS; controller.parmDialogCaption(strFmt("@DistITServices:BatchTaskDescription", _taskDesc)); contract.parmCustInvoiceJourList(_list); return controller; } [Hookable(false)] public boolean canGoBatch() { return true; } protected boolean canRunInNewSession() { return true; } [Hookable(false)] public boolean parmShowDialog(boolean _showDialog = showDialog) { return false; } [Hookable(false)] public boolean parmShowProgressForm(boolean _showProgressForm = showProgressForm) { return false; } } ////////////////////////////////////////// class CustInvoiceProcessSubTaskService extends SysOperationServiceBase { public void process(CustInvoiceProcessSubTaskContract _contract) { ListIterator custInvoiceJourListIterator = new ListIterator(_contract.parmCustInvoiceJourList()); container conCompleted, conEDIFailed, conEmailFailed, conNotSent; while (custInvoiceJourListIterator.more()) { custInvoiceJourListIterator.next(); } } public static void run(CustInvoiceJour _custInvoiceJour) { #OCCRetryCount try { } catch (Exception::Error) { throw Error("@SYS138340"); } catch (Exception::Deadlock) { if (xSession::currentRetryCount() >= #RetryNum) { throw Exception::Deadlock; } else { retry; } } catch(Exception::UpdateConflict) { if (appl.ttsLevel() == 0) { if (xSession::currentRetryCount() >= #RetryNum) { throw Exception::UpdateConflictNotRecovered; } else { retry; } } else { throw Exception::UpdateConflict; } } } }
Subscribe to:
Comments (Atom)