internal final class DMFImport { /// <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 main(Args _args) { str fileExtWithoutDot; str contentType; str fileId; guid fileGuid = newGuid(); DMFDefinitionGroup definitionGroup; DMFDefinitionGroupEntity definitionGroupEntityTable; //Creates DMF project str _defintionGroupName = "Test8"; ttsbegin; definitionGroup.initValue(); definitionGroup.DefinitionGroupName = _defintionGroupName; definitionGroup.OperationType = DMFOperationType::Import; definitionGroup.insert(); ttscommit; fileExtWithoutDot = DMFDataSource::getFormatFileExtension('XML-Element'); contentType = strFmt('application/%1', fileExtWithoutDot); DMFEntity DMFEntity;// = DMFEntity::find("Customer groups"); select firstonly dmfEntity order by dmfEntity.EntityName asc where dmfEntity.targetEntity == "CUSTCUSTOMERGROUPENTITY";; // str _entityName = "CUSTCUSTOMERGROUPENTITY"; str _entityName = DMFEntity.EntityName; str _fileName = "Test8"; fileId = guid2str(fileGuid); str _fileBase64 = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RG9jdW1lbnQ+PENVU1RDVVNUT01FUkdST1VQRU5USVRZPjxDTEVBUklOR1BFUklPRFBBWU1FTlRURVJNTkFNRT48L0NMRUFSSU5HUEVSSU9EUEFZTUVOVFRFUk1OQU1FPjxDVVNUT01FUkFDQ09VTlROVU1CRVJTRVFVRU5DRT48L0NVU1RPTUVSQUNDT1VOVE5VTUJFUlNFUVVFTkNFPjxDVVNUT01FUkdST1VQSUQ+RXhEZWJCUnVwdDwvQ1VTVE9NRVJHUk9VUElEPjxERUZBVUxURElNRU5TSU9ORElTUExBWVZBTFVFPjwvREVGQVVMVERJTUVOU0lPTkRJU1BMQVlWQUxVRT48REVTQ1JJUFRJT04+QWNjb3VudHMgcmVjZWl2YWJsZSBleHRlcm5hbCAtIGJhZCBkZWJ0PC9ERVNDUklQVElPTj48SVNTQUxFU1RBWElOQ0xVREVESU5QUklDRT5ObzwvSVNTQUxFU1RBWElOQ0xVREVESU5QUklDRT48UEFZTUVOVFRFUk1JRD48L1BBWU1FTlRURVJNSUQ+PFRBWEdST1VQSUQ+PC9UQVhHUk9VUElEPjxXUklURU9GRlJFQVNPTj48L1dSSVRFT0ZGUkVBU09OPjwvQ1VTVENVU1RPTUVSR1JPVVBFTlRJVFk+PC9Eb2N1bWVudD4="; //Creates a file from Base64 System.Byte[] reportBytes = System.Convert::FromBase64String(_fileBase64); System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(reportBytes); FileUploadTemporaryStorageStrategy fileUploadStrategy = new FileUploadTemporaryStorageStrategy(); FileUploadTemporaryStorageResult fileUploadResult = fileUploadStrategy.uploadFile(memoryStream, _fileName,contentType); //Adds the entity and file to the DMF Project ttsbegin; definitionGroupEntityTable.initValue(); definitionGroupEntityTable.DefinitionGroup = _defintionGroupName; definitionGroupEntityTable.Entity = _entityName; definitionGroupEntityTable.Source = 'XML-Element'; definitionGroupEntityTable.SampleFilePath = fileUploadResult.getFileId(); definitionGroupEntityTable.EntityXMLName = DMFEntity.TargetEntity; definitionGroupEntityTable.RunInsertLogic = NoYes::Yes; definitionGroupEntityTable.RunValidateWrite = NoYes::Yes; DIS_DMFImport::GenerateAndValidateMapping(definitionGroupEntityTable); definitionGroupEntityTable.insert(); ttscommit; DMFExecutionId executionId = DMFUtil::setupNewExecution(_defintionGroupName); DMFDefinitionGroupExecution execution = DMFDefinitionGroupExecution::find(_defintionGroupName, definitionGroupEntityTable.Entity,executionId, true); //execution.DataProjectId = journalId; execution.FilePath = fileId; execution.update(); //DMFQuickImportExport::doPGImport(_defintionGroupName, executionId); } /// <summary> /// Generates mapping for a definition group entity. /// </summary> /// <param name = "definitionGroupEntity">The definition group entity to generate mapping for.</param> public static void GenerateAndValidateMapping(DMFDefinitionGroupEntity definitionGroupEntity) { // Generate the mapping DMFXmlGeneration::generateMappingV2(definitionGroupEntity, '', true, true, false); // Validate generated mapping DMFQuickImportExport::validateXML(definitionGroupEntity.Source, definitionGroupEntity.SampleFilePath, definitionGroupEntity.Entity, definitionGroupEntity); } }
This blog is contains coding reference related to Microsoft AX 2012 and D365 finance and operations and Power platform
Friday, April 26, 2024
create DMF import data project dynamically and map using XML
Tuesday, April 23, 2024
Sysoperation framework with Aot query
public class UpdatePriceFormulaIdOnItemsService__Custom extends SysOperationServiceBase { #OCCRetrycount public void processOperation(UpdatePriceFormulaIdOnItemsContract__Custom _contract) { Query orderQuery; orderQuery = _contract.getQuery(); container compCon = str2con(_contract.parmCompany(), SysAppUtilities__Custom::semiColon); QueryRun queryRun = new QueryRun(orderQuery); while (queryRun.Next()) { InventTable inventTable = queryRun.get(tableNum(InventTable)); try { PriceFormulaId__Custom priceFormulaIdMaster = this.getPriceFormulaId(inventTable); //DSSE if (inventTable && inventTable.PriceFormulaIdMaster__Custom != priceFormulaIdMaster) { ttsbegin; inventTable.selectForUpdate(true); inventTable.PriceFormulaIdMaster__Custom = priceFormulaIdMaster; inventTable.PriceFormulaId__Custom = priceFormulaIdMaster; inventTable.doUpdate(); ttscommit; } for (int i=1; i<=conLen(compCon); i++) { DataAreaId company = conPeek(compCon, i); changecompany(company) { InventTable inventTableSales = InventTable::find(inventTable.ItemId); PriceFormulaId__Custom priceFormulaId = this.getPriceFormulaId(inventTableSales); if (inventTableSales && inventTableSales.PriceFormulaId__Custom != priceFormulaId) { ttsbegin; inventTableSales.selectForUpdate(true); inventTableSales.PriceFormulaIdMaster__Custom = priceFormulaIdMaster; inventTableSales.PriceFormulaId__Custom = priceFormulaId; inventTableSales.doUpdate(); ttscommit; } } } info(strfmt("@_CustomtITServices:SucessUpdateItem", inventTable.ItemId)); } catch (Exception::Deadlock) { retry; } catch (Exception::UpdateConflict) { if (appl.ttsLevel() == 0) { if (xSession::currentRetryCount() >= #RetryNum) { warning(strFmt("@_CustomtITServices:FaliedUpdateItem", inventTable.ItemId)); continue; } else { retry; } } else { warning(strFmt("@_CustomtITServices:FaliedUpdateItem", inventTable.ItemId)); continue; } } catch (Exception::Error) { warning(strFmt("@_CustomtITServices:FaliedUpdateItem", inventTable.ItemId)); continue; } } } public PriceFormulaId__Custom getPriceFormulaId(InventTable _inventTable) { DimensionValue brandDim; EcoResCategoryId ecoResCategoryId; container catCon = conNull(); if (_inventTable) { brandDim = _CustomtITServicesUtility__Custom::getDimension_CustomplayValue(_inventTable.DefaultDimension, SysAppUtilities__Custom::dimensionAttributeNameBrand); catCon = _CustomtITServicesUtility__Custom::getProdCategories(_inventTable.ItemId); } ItemPriceFormula__Custom itemPriceFormula; if (_inventTable.ItemId) { itemPriceFormula = ItemPriceFormula__Custom::findByItem(_inventTable.ItemId); } if (!itemPriceFormula && catCon != conNull() && brandDim) { for (int i=1; i<=conLen(catCon); i++) { ecoResCategoryId = EcoResCategory::find(conPeek(catCon, i)).RecId; itemPriceFormula = ItemPriceFormula__Custom::findByCategoryBrand(ecoResCategoryId, brandDim); if (itemPriceFormula) { break; } } } if (!itemPriceFormula && brandDim) { itemPriceFormula = ItemPriceFormula__Custom::findByBrand(brandDim); } if (!itemPriceFormula && catCon != conNull()) { for (int i=1; i<=conLen(catCon); i++) { ecoResCategoryId = conPeek(catCon, i); itemPriceFormula = ItemPriceFormula__Custom::findByCategory(ecoResCategoryId); if (itemPriceFormula) { break; } } } return itemPriceFormula.PriceFormulaId; } } ===================== public class UpdatePriceFormulaIdOnItemsController__Custom extends SysOperationServiceController { // <summary> /// Creates a new instance of <c>UpdateEndOfLifeOnItemsController__Custom</c> class. /// </summary> /// <param name = "_args">A controller arguments.</param> /// <returns>A instance of <c>SysOperationController</c> class.</returns> public static UpdatePriceFormulaIdOnItemsController__Custom construct(Args _args) { UpdatePriceFormulaIdOnItemsController__Custom controller = new UpdatePriceFormulaIdOnItemsController__Custom(); controller.parmArgs(_args); return controller; } /// <summary> /// Instantiate controller. /// </summary> protected void new() { super(classStr(UpdatePriceFormulaIdOnItemsService__Custom), methodStr(UpdatePriceFormulaIdOnItemsService__Custom, processOperation)); this.parmDialogCaption("@_CustomtITServices:UpdatePriceFormulaIdItem"); } /// <summary> /// Runs the class with the specified arguments. /// </summary> /// <param name = "_args">The specified arguments.</param> public static void main(Args _args) { UpdatePriceFormulaIdOnItemsController__Custom controller = UpdatePriceFormulaIdOnItemsController__Custom::newFromArgs(_args); controller.parmExecutionMode(SysOperationExecutionMode::Synchronous); controller.startOperation(); } /// <summary> /// Instantiate and initialize controller class. /// </summary> /// <param name = "_args">The specified arguments.</param> /// <returns> /// returns controller class. /// </returns> public static UpdatePriceFormulaIdOnItemsController__Custom newFromArgs(Args _args) { UpdatePriceFormulaIdOnItemsController__Custom controller = UpdatePriceFormulaIdOnItemsController__Custom::construct(_args); return controller; } } ================== [DataContractAttribute, SysOperationContractProcessingAttribute(ClassStr(UpdatePriceFormulaIdOnItemsUIbuilder__Custom))] public class UpdatePriceFormulaIdOnItemsContract__Custom { str packedQuery; Str company; /// <summary> /// Initialize query /// </summary> public void initQuery() { Query newQuery; newQuery = new Query(queryStr(InventTable)); this.setQuery(newQuery); } /// <summary> /// Get/Set the packed query /// </summary> /// <param name = "_packedQuery">query</param> /// <returns>string</returns> [ DataMemberAttribute, AifQueryTypeAttribute('_packedQuery', queryStr(InventTable)) ] public str parmPackedQuery(str _packedQuery = packedQuery) { packedQuery = _packedQuery; return packedQuery; } /// <summary> /// Get the query /// </summary> /// <returns>Query</returns> public Query getQuery() { return new Query(SysOperationHelper::base64Decode(packedQuery)); } /// <summary> /// Set the query /// </summary> /// <param name = "_query">query</param> public void setQuery(Query _query) { packedQuery = SysOperationHelper::base64Encode(_query.pack()); } // <summary> /// Gets or sets the value of the datacontract parameter company. /// </summary> /// <param name="_company"> /// The new value of the datacontract parameter company; optional. /// </param> /// <returns> /// The current value of datacontract parameter company /// </returns> [ DataMemberAttribute, SysOperationLabelAttribute(literalStr("@_CustomtITServices:Company")), SysOperation_CustomplayOrderAttribute("1") ] public Str parmCompany(Str _company = company) { company = _company; return company; } }
Iterate through extended child classes dynamically using X++
/// <summary> /// Base class for search /// </summary> class searchBaseClass { const private Integer priorityMax = 99; /// <summary> /// Method that searches for values /// </summary> protected void search(//your parmeters) { } /// <summary> /// Method that indicates the class priority and therefor the number in which it is executed /// </summary> /// <returns> /// An integer indicating the class priority and therefor the number in which it is executed /// </returns> protected Priority priority() { return searchBaseClass::PriorityMax; } /// <summary> /// Method that creates a map of search classes to be executed in a priorized way /// </summary> /// <returns> /// A map containing class objects to execute /// </returns> private Map createExecutionMap() { DictClass dictClass; searchBaseClass searchBase; ListEnumerator listEnumerator; List listClass = new DictClass(classnum(searchBaseClass)).extendedBy(); Map mapExecutionClasses = new Map(Types::Integer, Types::Class); listEnumerator = listClass.getEnumerator(); while (listEnumerator.moveNext()) { dictClass = new DictClass(listEnumerator.current()); if (dictClass) { searchBase = dictClass.makeObject(); if (searchBase) { // Add class object to execution list unless the priority is already added if (!mapExecutionClasses.exists(searchBase.priority())) { mapExecutionClasses.insert(searchBase.priority(), searchBase); } else { warning(strFmt("SearchSkipped", dictClass.name(), searchBase.priority())); } } } } return mapExecutionClasses; } /// <summary> /// Method that run through all classes that searches for data /// </summary> public void run() { searchBaseClass searchBase; Map mapExecutionClasses; mapExecutionClasses = this.createExecutionMap(); for (int i = 1; i <= searchBase::priorityMax; i++) { if (mapExecutionClasses.exists(i)) { searchBase = mapExecutionClasses.lookup(i); if (searchBase) { searchBase.search(); } } } } } /// <summary> /// child Class searching /// </summary> class searchChildClass extends searchBaseClass { /// <summary> /// Method that indicates the class priority and therefor the number in which it is executed /// </summary> /// <returns> /// An integer indicating the class priority and therefor the number in which it is executed /// </returns> protected Priority priority() { return 1; } /// <summary> /// Method searching /// </summary> protected void search(//your parmeters) { //your logic }
Monday, April 22, 2024
Find smallest date from a set of dates using X++
ListEnumerator listEnumerator; list listDates = new list(Types::Date); listDates.addEnd(Date1); listDates.addEnd(Date2); listDates.addEnd(Date3); listDates.addEnd(Date4); TransDate lowestDate = dateMax(); if (listDates.elements() > 0) { listEnumerator = listDates.getEnumerator(); while (listEnumerator.moveNext()) { if(listEnumerator.current() <= lowestDate && listEnumerator.current() != dateNull()) { lowestDate = listEnumerator.current(); } } } if(lowestDate != dateNull() && lowestDate != dateMax()) { info(lowestDate); }
Validate multiple emails using X++ , Regex
/// /// </summary> /// <param name = "_fieldIdToCheck"></param> /// <returns></returns> public boolean validateField(FieldId _fieldIdToCheck) { boolean ret; ret = super(_fieldIdToCheck); switch (_fieldIdToCheck) { case fieldNum(Reporting, Email) : container email = str2con(this.Email, SysAppUtilities::semiColon); for (int i = 1; i <= conLen(email); i++) { if (!Reporting::isValidEmail(conPeek(email, i))) { ret = checkFailed(strFmt("%1: %2", "@SYS334523", conPeek(email, i))); } } break; } return ret; } /// <summary> /// This method accepts a email and validates this using REGEX /// </summary> /// <returns> /// true or false based on Regex match /// </returns> static server boolean isValidEmail(Email _email) { System.Text.RegularExpressions.Match match; System.Boolean netBool; boolean xppBool; str matchEmailPattern = @"^(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))@" + @"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]? [0-9]{1,2}|25[0-5]|2[0-4][0-9])\." + @"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]? [0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|" + @"([\w-]+\.)+[a-zA-Z]{2,4})$"; new InteropPermission(InteropKind::ClrInterop).assert(); match = System.Text.RegularExpressions.Regex::Match(_email, matchEmailPattern); netBool = match.get_Success(); xppBool = netBool; CodeAccessPermission::revertAssert(); return xppBool; }
Tuesday, April 16, 2024
Calculate FromDate/ToDate based on Daily,Weelkly,Monthly in X++
boolean canRun = false; TransDate fromDate, toDate, prevDate; TransDate currentDate = DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()); switch (Reporting.Schedule) { case ReportingSchedule::Daily : fromDate = currentDate - 1; toDate = currentDate - 1; canRun = true; break; case ReportingSchedule::Weekly : PreferredLocale preferredLocale = (new xSession()).PreferredLocale(); prevDate = HcmDateTimeUtil::calculateDateWithOffset(PeriodUnit::Day,7,false, currentDate); fromDate = DateTimeUtil::getStartOfWeekDate(preferredLocale, prevDate); toDate = DateTimeUtil::getEndOfWeekDate(preferredLocale, prevDate); canRun = dayOfWk(currentDate) == 1; //1 for monday break; case ReportingSchedule::Monthly : prevDate = prevMth(currentDate); fromDate = DateStartMth(prevDate); toDate = endmth(prevDate); canRun = dayOfMth(currentDate) == 1; //1 for first day of the month break; }
Thursday, April 11, 2024
Computed column in View/DataEntity
private static server str compPurchQtyInvoiced() { //return SysComputedColumn::sum(SysComputedColumn::returnField( // tableStr(InboundOrderLinesOverview), // identifierStr(InventTransPurchLine), // fieldStr(InventTrans, Qty))); SysDictTable InventTrans = new SysDictTable(tableNum(InventTrans)); SysDictTable InventTransOriginPurchLineLoc = new SysDictTable(tableNum(InventTransOriginPurchLine)); str val; str inventtransid = SysComputedColumn::returnField(dataentityviewstr(InboundOrderLinesOverview), identifierstr(PurchLine), fieldstr(PurchLine, InventTransId)); //select SUM(QTY) from inventtrans // join InventTransOriginPurchLine on InventTransOriginPurchLine.INVENTTRANSORIGIN = inventtrans.INVENTTRANSORIGIN // where InventTransOriginPurchLine.PURCHLINEINVENTTRANSID = 'L00834739' // AND inventtrans.STATUSRECEIPT in (1,2) val = strFmt("select SUM(%1) from %2 join %3 on %3.%4 = %2.%5 where %3.%6 = %7 AND %2.%8 = %9", InventTrans.fieldName(fieldNum(InventTrans, Qty), DbBackend::Sql), InventTrans.name(DbBackend::Sql), InventTransOriginPurchLineLoc.name(DbBackend::Sql), InventTransOriginPurchLineLoc.fieldName(fieldNum(InventTransOriginPurchLine, INVENTTRANSORIGIN), DbBackend::Sql), InventTrans.fieldName(fieldNum(InventTrans, INVENTTRANSORIGIN), DbBackend::Sql), InventTransOriginPurchLineLoc.fieldName(fieldNum(InventTransOriginPurchLine, PURCHLINEINVENTTRANSID), DbBackend::Sql), inventtransid, InventTrans.fieldName(fieldNum(InventTrans, StatusReceipt), DbBackend::Sql), SysComputedColumn::returnLiteral(1)); return val; }
Wednesday, January 17, 2024
Send Http request with JSON payload using X++
Public class BizNodeIntegration_Custom { public static void CreditRatingUpdate (CustTable _custTable) { URL url = strLTrim(@'https://test-integrations-syncoperations.azurewebsites.net/api/companyRating?code=fgfgfgfgfgfg'); //URL url = SysAppUtilities_Custom::getKeyVaultSecret(SysAppUtilities_Custom::IntegrationsFunctionsBaseUrl) + '/api/creditRating?code=' + SysAppUtilities_Custom::getKeyVaultSecret(SysAppUtilities_Custom::IntegrationsFunctionAppMasterKey); System.IO.StringWriter stringWriter; Newtonsoft.Json.JsonTextWriter jsonWriter; System.Byte[] bytes; System.Text.Encoding utf8; stringWriter = new System.IO.StringWriter(); jsonWriter = new Newtonsoft.Json.JsonTextWriter(stringWriter); str jsonString = ""; jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName("RegistrationNumber"); jsonWriter.WriteValue(_custTable.registrationNumber()); jsonWriter.WritePropertyName("CountryCode"); jsonWriter.WriteValue(strDel(_custTable.VATNum,3,strLen(_custTable.VATNum))); jsonWriter.WriteEndObject(); jsonString = stringWriter.ToString(); str method = 'POST'; str contentType = @'application/json'; RetailWebRequest webRequest = RetailWebRequest::newUrl(url); utf8 = System.Text.Encoding::get_UTF8(); bytes = utf8.GetBytes(jsonString); webRequest.parmMethod(method); webRequest.parmContentType(contentType); webRequest.setContentBytes(bytes); RetailCommonWebAPI webApi = RetailCommonWebAPI::construct(); RetailWebResponse webResponse = webApi.getResponse(webRequest); str responseData = webResponse.parmData(); info(responseData); if (webResponse.parmHttpStatus() == 200) { Map responseMap = RetailCommonWebAPI::getMapFromJsonString(responseData); MapEnumerator mapEnumerator; mapEnumerator = responseMap.getEnumerator(); while (mapEnumerator.moveNext()) { switch (mapEnumerator.currentKey()) { case "payload" : container con = mapEnumerator.currentValue(); CustomerCreditInsuranceUpdate_Custom::updateCustomerCreditInsurance(conPeek(con,conFind(con,'companyRating') + 1),_custTable.registrationNumber()); break; default: break; } } } else { info(responseData); } } }
Tuesday, January 16, 2024
Execute SQL statement from X++
Connection connection; Statement statement; str query; connection = new Connection(); statement = connection.createStatement(); query = "update EnumValueTable set EnumValueTable.enumValue = '75'"; new SqlStatementExecutePermission(query).assert(); statement.executeUpdate(query); CodeAccessPermission::revertAssert();
User multiselect lookup on UI Builder class
class UpdateEndOfLifeOnItemsUIBuilder_Custom extends SysOperationAutomaticUIBuilder { UpdateEndOfLifeOnItemsContract_Custom contract; DialogField usersDF; public void postBuild() { super(); contract = this.dataContractObject() as UpdateEndOfLifeOnItemsContract_Custom; usersDF = this.bindInfo().getDialogField(contract, methodStr(UpdateEndOfLifeOnItemsContract_Custom, parmUsers)); usersDF.lookupButton(FormLookupButton::Always); } public void postRun() { super(); this.lookupUsr(); } /// <summary> /// Creates a multi-select users lookup dialog box field /// </summary> public void lookupUsr() { Query query = new Query(); QueryBuildDataSource qbdsLegalEntity = query.addDataSource(tableNum(UserInfo)); qbdsLegalEntity.fields().addField(fieldNum(UserInfo, id)); qbdsLegalEntity.fields().addField(fieldNum(UserInfo, Name)); container selectedFields = [tableNum(UserInfo), fieldNum(UserInfo, id)]; SysLookupMultiSelectCtrl::constructWithQuery(this.dialog().dialogForm().formRun(), usersDF.control(), query, false, selectedFields); } /// <summary> /// Gets or sets the value of the datacontract parameter users. /// </summary> /// <param name="_users"> /// The new value of the datacontract parameter users; optional. /// </param> /// <returns> /// The current value of datacontract parameter users /// </returns> [ DataMemberAttribute, SysOperationLabelAttribute(literalStr("@SYS25412")), SysOperationDisplayOrderAttribute("2") ] public str parmUsers(str _users = users) { users = _users; return users; } }
Generate CSV file and send as an attachment using X++
class UpdateEndOfLifeOnItemsService_Custom extends SysOperationServiceBase { public void processOperation(UpdateEndOfLifeOnItemsContract_Custom _contract) { Query orderQuery; QueryRun queryRun; boolean closeWSLItem; Str users; orderQuery = _contract.getQuery(); closeWSLItem = _contract.parmCloseWSLItem(); users = _contract.parmUsers(); queryRun = new QueryRun(orderQuery); container userCon = str2con(users, SysAppUtilities_Custom::semiColon); System.Byte[] byteArray; CommaStreamIo io = CommaStreamIo::constructForWrite(); io.outFieldDelimiter(SysAppUtilities_Custom::comma); io.outRecordDelimiter('\r\n'); io.writeExp(['@MCR23630', '@SYS319915' , '@Custom:PLCStat']); Filename fileName = strFmt('@Custom:EOLUpdateFileName', DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone())); fileName = fileName + ".csv"; while (queryRun.Next()) { ItemId itemId = strMin(); InventTable inventTableMaster = queryRun.get(tableNum(InventTable)); itemId = inventTableMaster.ItemId; EcoResProductLifecycleStateId productLifecycleStateId; if (!this.OnhandQty(inventTableMaster) == 0) { PurchLine purchLine; PurchTable purchTable; select firstonly purchLine where purchLine.ItemId == itemId exists join purchTable where purchTable.PurchId == purchLine.PurchId && purchTable.PurchStatus == PurchStatus::Backorder; if (!purchLine) { if (closeWSLItem) { productLifecycleStateId = EcoResProductLifecycleState::find("40_EOL_int").StateId; SalesLine salesLine; InventTrans inventTrans; InventTransOrigin inventTransOrigin; select firstonly inventTrans where inventTrans.ItemId == itemId && inventTrans.StatusIssue == StatusIssue::ReservPhysical join inventTransOrigin where inventTransOrigin.RecId == inventTrans.InventTransOrigin exists join salesLine where inventTransOrigin.InventTransId == salesLine.InventTransId; if (!inventTrans) { UpdateEndOfLifeOnItemsService_Custom::updateSalesStopped(itemId); } UpdateEndOfLifeOnItemsService_Custom::updatePLCStatus(itemId, productLifecycleStateId); } } io.writeExp([itemId, inventTableMaster.itemName(), productLifecycleStateId]); } } System.IO.Stream stream = iO.getStream(); stream.Position = 0; System.IO.StreamReader reader = new System.IO.StreamReader(stream); str csv = reader.ReadToEnd(); System.Text.Encoding encoding = System.Text.Encoding::get_UTF8(); byteArray = encoding.GetBytes(csv); using(System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(byteArray)) { this.sendEmailNotification(userCon, memoryStream, fileName); } info("@SYS9265"); } public Qty OnhandQty(InventTable _inventtable) { Qty availPhysical; CompanyInfo companyInfo; ItemId item = _inventtable.ItemId; select firstonly companyInfo where companyInfo.IsMasterCompany_Custom == NoYes::Yes; changecompany(companyInfo.DataArea) { InventDim inventDimLoc; InventDimParm inventDimParm; InventTable inventTableMaster = InventTable::find(item); InventLocationId inventLocationId = inventTableMaster.InventItemSalesSetup().inventDimDefault().InventLocationId; InventLocation inventLocation = InventLocation::find(inventLocationId); if (inventLocationId) { inventDimLoc.InventLocationId = inventLocationId; inventDimLoc.InventSiteId = inventLocation.InventSiteId; inventDimLoc = InventDim::findOrCreate(inventDimLoc); inventDimParm.initFromInventDim(InventDim::find(inventDimLoc.inventDimId)); return InventSum::findSum(item, inventDimLoc, inventDimParm).AvailPhysical; } } return 0; } /// <summary> /// Send emails notification about the base cost update to user/user group. /// </summary> /// <param name = "_notifyCon"> /// Container which holds users to whom email notification to be sent. /// </param> /// <param name = "_messageBody"> /// Contains information about the method of calculation to be send to user in email. /// </param> /// <returns> /// boolean true, if sends the notification of users successfully. /// </returns> public boolean sendEmailNotification(container _notifyCon, System.IO.MemoryStream _memoryStream, Filename _fileName) { UserInfo sysUser; boolean messageSent = false; str messageBody; str subject = strFmt('@Custom:EOLUpdateFileName', DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone())); for (int i = 1; i <= conLen(_notifyCon); i++) { str notifyEmailsStr = conPeek(_notifyCon, i); select firstonly RecId, NetworkAlias from sysUser where sysUser.Id == notifyEmailsStr; if (sysUser.RecId && sysUser.NetworkAlias) { UpdateEndOfLifeOnItemsService_Custom::sendEmail(_fileName, subject, messageBody, _memoryStream, sysUser.NetworkAlias); messageSent = true; } } return messageSent; } public static void sendEmail(str _fileName, str _subject, str _body, System.IO.MemoryStream _memoryStream, Email _toEmail) { SysMailerMessageBuilder mailer = new SysMailerMessageBuilder(); try { mailer.setSubject(_subject); mailer.setBody(_body); mailer.addTo(_toEmail); mailer.addAttachment(_memoryStream, _fileName); SysMailerFactory::sendNonInteractive(mailer.getMessage()); Info("@SYS58551"); } catch (Exception::CLRError) { System.Exception ex = ClrInterop::getLastException(); if (ex != null) { ex = ex.get_InnerException(); if (ex != null) { error(ex.ToString()); } } } catch (Exception::Error) { Error("@CustomASCS:ErrorOccurredFailedSendEmail"); } } public static void updatePLCStatus(ItemId _itemId, EcoResProductLifecycleStateId _productLifecycleStateId) { InventTable inventTable; inventTable.skipDatabaseLog(true); inventTable.skipDataMethods(true); inventTable.skipBusinessEvents(true); inventTable.skipAosValidation(true); inventTable.skipEvents(true); update_recordset crosscompany inventTable setting ProductLifecycleStateId = _productLifecycleStateId where inventTable.ItemId == _itemId; } public static void updateSalesStopped(ItemId _itemId) { InventItemSalesSetup inventItemSalesSetup; inventItemSalesSetup.skipDatabaseLog(true); inventItemSalesSetup.skipDataMethods(true); inventItemSalesSetup.skipBusinessEvents(true); inventItemSalesSetup.skipAosValidation(true); inventItemSalesSetup.skipEvents(true); update_recordset crosscompany inventItemSalesSetup setting Stopped = true where inventItemSalesSetup.ItemId == _itemId && inventItemSalesSetup.InventDimId == InventDim::inventDimIdBlank() && inventItemSalesSetup.DataAreaId != SysAppUtilities_Custom::companyDSSE; } }
Upload SSRS report to SFTP using Renci.SShnet DLL in path /Folder/
using Renci.SshNet; using Renci.SshNet.SftpClient; using Renci.SshNet.Common; using Renci.SshNet.Sftp; using Renci.SshNet.Sftp.SftpFile; using System.IO; class UploadSSRSReportToSFTPService_Custom extends SysOperationServiceBase { public void processOperation(UploadSSRSReportToSFTPContract_Custom _contract) { Query orderQuery; QueryRun queryRun; date processedDate; orderQuery = _contract.getQuery(); queryRun = new QueryRun(orderQuery); processedDate = DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()); while (queryRun.Next()) { custInvoiceJour custInvoiceJour = queryRun.get(tableNum(custInvoiceJour)); this.sendFileToSFTP(custInvoiceJour); } } public void sendFileToSFTP(custInvoiceJour _custInvoiceJour) { str ext = SRSPrintDestinationSettings::findFileNameType(SRSReportFileFormat::PDF, SRSImageFileFormat::BMP); Filename filename = _custInvoiceJour.InvoiceId + ext; System.Byte[] reportBytes = this.renderReportToBinaryArray(_custInvoiceJour, filename); if (reportBytes) { using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(reportBytes)) { try { str success = 'fail'; CustParameters parameter = CustParameters::find(); str host, username, password, destinationPath; int port; host = parameter.SFTPHostName_Custom; port = str2Int(parameter.SFTPPort_Custom); username = parameter.SFTPUserName_Custom; password = parameter.SFTPPassword_Custom; destinationPath = parameter.SFTPDestinationPath_Custom; SftpClient sftpClient = new SftpClient(host, port, username, password); sftpClient.OperationTimeout = System.TimeSpan::FromMilliseconds(60000); sftpClient.connect(); sftpClient.ChangeDirectory(destinationPath); if (sftpClient.IsConnected) { sftpClient.UploadFile(memoryStream , destinationPath + "@SYS35673" + fileName , null); success = 'pass'; } sftpClient.Disconnect(); sftpClient.Dispose(); if(success == 'pass') { Info(strFmt('@@Custom:UploadReportToSFTPSuccess', filename)); } else { Error('@@Custom:UploadReportToSFTPError'); } } catch (Exception::CLRError) { System.Exception ex = ClrInterop::getLastException(); if (ex != null) { ex = ex.get_InnerException(); if (ex != null) { error(ex.ToString()); } } } catch (Exception::Error) { Error("@@Custom:UploadReportToSFTPError"); } } } } /// <summary> /// Render report to byte array /// </summary> /// <param name = "_contract">contract class object</param> /// <param name = "_documentType">document type</param> /// <param name = "_filename">filename for the report</param> /// <returns>report as a byte array</returns> // private System.Byte[] renderReportToBinaryArray(Object _contract, PrintMgmtDocumentType _documentType, filename _filename) private System.Byte[] renderReportToBinaryArray(custInvoiceJour _custInvoiceJour, Filename _fileName) { SalesInvoiceContract rdpContract = new salesInvoiceContract(); rdpContract.parmRecordId(_custInvoiceJour.RecId); PrintMgmtReportFormatName printMgmtReportFormatName = PrintMgmtDocType::construct(PrintMgmtDocumentType::SalesOrderInvoice).getDefaultReportFormat(); SrsReportRunController srsReportRunController = new SrsReportRunController(); srsReportRunController.parmReportName(printMgmtReportFormatName); srsReportRunController.parmExecutionMode(SysOperationExecutionMode::Synchronous); srsReportRunController.parmShowDialog(false); srsReportRunController.parmReportContract().parmRdpContract(rdpContract); srsReportRunController.parmReportContract().parmReportExecutionInfo(new SRSReportExecutionInfo()); srsReportRunController.parmReportContract().parmReportServerConfig(SRSConfiguration::getDefaultServerConfiguration()); SRSPrintDestinationSettings printerSettings = srsReportRunController.parmReportContract().parmPrintSettings(); printerSettings.printMediumType(SRSPrintMediumType::File); printerSettings.fileFormat(SRSReportFileFormat::PDF); printerSettings.parmFileName(_fileName); SRSReportRunService srsReportRunService = new SrsReportRunService(); srsReportRunService.getReportDataContract(srsReportRunController.parmReportContract().parmReportName()); srsReportRunService.preRunReport(srsReportRunController.parmReportContract()); Map reportParametersMap = srsReportRunService.createParamMapFromContract(srsReportRunController.parmReportContract()); Microsoft.Dynamics.AX.Framework.Reporting.Shared.ReportingService.ParameterValue[] parameterValueArray = SrsReportRunUtil::getParameterValueArray(reportParametersMap); SRSProxy srsProxy = SRSProxy::constructWithConfiguration(srsReportRunController.parmReportContract().parmReportServerConfig()); System.Byte[] reportBytes = srsproxy.renderReportToByteArray(srsReportRunController.parmreportcontract().parmreportpath(), parameterValueArray, printerSettings.fileFormat(), printerSettings.deviceinfo()); return reportBytes; } }
Subscribe to:
Posts (Atom)