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; } } ///////
This blog is contains coding reference related to Microsoft AX 2012 and D365 finance and operations and Power platform
Thursday, October 2, 2025
Run ER Report through code and send as an Email attachment
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; }
Subscribe to:
Posts (Atom)