Showing posts with label D365F&O. Show all posts
Showing posts with label D365F&O. Show all posts

Sunday, June 16, 2024

D365FO: Add financial dimension range in Query using X++

protected void createReportLines()
{
	Query                q;
	QueryRun             qr;
	QueryBuildDataSource qbds, qbdsInventTrans;
	RecId                dimAttrRecId = AgreementHeaderExt_RU::getAgreementDimensionAttribute();

	q = new Query();

	qbdsInventTrans = q.addDataSource(tableNum(InventTrans));

	findOrCreateRange_W(qbdsInventTrans, fieldNum(InventTrans, TableId), strFmt(issueReceiptValue,
																				qbdsInventTrans.name(),
																				enum2int(StatusIssue::Sold),
																				enum2int(StatusReceipt::Purchased)));
	findOrCreateRange_W(qbdsInventTrans, fieldNum(InventTrans, DateFinancial), queryRange(commReportJour.StartDate, commReportJour.EndDate));

	qbds = qbdsInventTrans.addDataSource(tableNum(InventTransOrigin));
	qbds.addLink(fieldNum(InventTrans, InventTransOrigin), fieldNum(InventTransOrigin, RecId));
	qbds.joinMode(JoinMode::InnerJoin);
	qbds.fetchMode(QueryFetchMode::One2One);

	qbds = qbds.addDataSource(tableNum(CustInvoiceTrans));
	qbds.addLink(fieldNum(InventTransOrigin, InventTransId), fieldNum(CustInvoiceTrans, InventTransId));
	qbds.addLink(fieldNum(InventTrans, InvoiceId), fieldNum(CustInvoiceTrans, InvoiceId), qbdsInventTrans.name());
	qbds.joinMode(JoinMode::InnerJoin);

	qbds = qbds.addDataSource(tableNum(CustInvoiceJour));
	qbds.relations(true);
	qbds.joinMode(JoinMode::InnerJoin);

	findOrCreateRange_W(qbds, fieldNum(CustInvoiceJour, InvoiceAccount), queryValue(commReportJour.PartnerCode));

	SysQuery::addDimensionAttributeRange(q,
	qbds.name(),
	fieldStr(CustInvoiceJour, DefaultDimension),
	DimensionComponent::DimensionAttribute,
	commReportJour.AgreementId,
	DimensionAttribute::find(dimAttrRecId).Name);

	qbds = qbds.addDataSource(tableNum(CustInvoiceJour_RU));
	qbds.relations(true);
	qbds.joinMode(JoinMode::ExistsJoin);

	findOrCreateRange_W(qbds, fieldNum(CustInvoiceJour_RU, InventProfileType_RU), con2Str([InventProfileType_RU::CommissionAgent,
																					   InventProfileType_RU::CommissionPrincipalAgent]));

	qbds = qbdsInventTrans.addDataSource(tableNum(InventDim));
	qbds.addLink(fieldNum(InventTrans, InventDimId), fieldNum(InventDim, InventDimId));
	qbds.joinMode(JoinMode::InnerJoin);
	qbds.fetchMode(QueryFetchMode::One2One);

	qr = new QueryRun(q);

	while (qr.next())
	{
		inventTrans         = qr.get(tableNum(InventTrans));
		inventTransOrigin   = qr.get(tableNum(InventTransOrigin));
		custInvoiceTrans    = qr.get(tableNum(CustInvoiceTrans));
		custInvoiceJour     = qr.get(tableNum(CustInvoiceJour));
		inventDim           = qr.get(tableNum(inventDim));

		this.processVendShipments();
	}
}

Get all menu items and its label metadata under a module D365F&O

using Microsoft.Dynamics.AX.Metadata.MetaModel;
using Microsoft.Dynamics.AX.Security.Management;
internal final class RunnableClass1
{
    /// <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)
    {
        AxMenu Menu = Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenu(menuStr(AccountsReceivable));

        SecurityRepository sr = new SecurityRepository();
        sr   = SysSecurity::GetSecurityRepository();

        var allPrivileges = sr.Privileges;
        var allPrivilegesEnumerator = allPrivileges.LoadAll().GetEnumerator();

        var   f = Menu.Elements.GetEnumerator();
        container conMenuItem ;
        int pos;
        while (f.MoveNext())
        {
            AxMenuElementSubMenu subMenu = f.Current;

            var   s= subMenu.Elements.GetEnumerator();
            while (s.MoveNext())
            {
                pos++;
                AxMenuElement menuElement = s.Current;

                if (Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenuItemDisplay(menuElement.Name) ||
                    Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenuItemOutput(menuElement.Name) ||
                    Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenuItemAction(menuElement.Name))
                {
                    AxMenuElementMenuItem menuElementMenuItem = s.Current;
                    Label label = new Label(infolog.language());
                    switch (menuElementMenuItem.MenuItemType)
                    {
                       

                        case MenuItemType::Display:
                        if (Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenuItemDisplay(menuElementMenuItem.MenuItemName))
                        {
                            AxMenuItemDisplay MenuItemDisplay = Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenuItemDisplay(menuElementMenuItem.MenuItemName);

                                info(strFmt("%1-%2-%3-%4-%5",Menu.Name, subMenu.Name,label.extractString(MenuItemDisplay.Label)  ,MenuItemDisplay.Name, MenuItemDisplay.Object));
                        }
                        break;
                        case  MenuItemType::Output:
                        if (Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenuItemOutput(menuElementMenuItem.MenuItemName))
                        {
                            AxMenuItemOutput MenuItemOutput = Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenuItemOutput(menuElementMenuItem.MenuItemName);

                            //info(strFmt("%1-%2-%3",Menu.Name, subMenu.Name, menuElementMenuItem.MenuItemName));

                                info(strFmt("%1-%2-%3-%4-%5",Menu.Name, subMenu.Name, label.extractString(MenuItemOutput.Label) ,MenuItemOutput.Name, MenuItemOutput.Object));
                        }
                        break;
                        case  MenuItemType::Action:
                        if (Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenuItemAction(menuElementMenuItem.MenuItemName))
                        {
                            AxMenuItemAction MenuItemAction = Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetMenuItemAction(menuElementMenuItem.MenuItemName);

                            //info(strFmt("%1-%2-%3",Menu.Name, subMenu.Name, menuElementMenuItem.MenuItemName));
                                info(strFmt("%1-%2-%3-%4-%5",Menu.Name, subMenu.Name, label.extractString(MenuItemAction.Label) ,MenuItemAction.Name, MenuItemAction.Object));
                        }
                        break;
                    }

                    //info(strFmt("%1-%2-%3",Menu.Name, subMenu.Name, menuElement.Name));

                    conMenuItem += strFmt("%1",menuElement.Name);
                   // conIns(conMenuItem,pos, menuElement.Name);
                }
                else
                {
                    pos++;
                    info(strFmt("%1-%2-%3",Menu.Name, subMenu.Name, menuElement.Name));

                    conMenuItem += strFmt("%1",menuElement.Name);
                   // conIns(conMenuItem,pos, menuElement.Name);
                }

                
            }
        }

        //for (int i = 1 ; i <= conLen(conMenuItem) ; i++)
        //{
        //    while (allPrivilegesEnumerator.MoveNext())
        //    {
        //        var securityPrivilege = allPrivilegesEnumerator.Current;

        //        //while (securityPrivilege.MoveNext())
        //        //{

        //        //}
        //    }
        //   // print conPeek(c, i);
        //}

    }

}

way to remove special characters from a string using X++

static void RemoveAllSpecialChararcters(Args _args)
{
	str sometext = "ABC#DE%F_$#G@1&23";

	str x = System.Text.RegularExpressions.Regex::Replace(sometext, @"[#,_,$,%,@,&]”, """);
	info(x);
}
static void Dev_ReplaceTxt(Args _args)
{
	TextBuffer buffer = new TextBuffer();
	Str message;
	;

	message = " hi hello's how r u's ";
	message += " How r u doing's wujer's * ? ' what ur mot's anbej's";

	buffer.setText(message);
	buffer.replace("[*?']","\\'"); // replace special character with escape sequence
	info(buffer.getText());

}

strRem('String','*');

If you want to delete the special characters from string, you can use "strAlpha" function. This copies only the alphanumeric characters from a string.

Ex : info(strFmt("%1", strAlpha("?a*b!!!!cD123.")));

results in "abcD123".

Friday, April 26, 2024

create DMF import data project dynamically and map using XML

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);
    }

}

Tuesday, April 23, 2024

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;
    }

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;
}

Table browser URL in D365FO

Critical Thinking icon icon by Icons8