Saturday, 11 December 2021

Get Enum value from SQL AX 2012 /365

 CREATE FUNCTION [dbo].[ENUM2STR](@name AS varchar(40), @value AS int)

RETURNS varchar(255)
AS
BEGIN
 DECLARE @bin AS varbinary(MAX);
 SET @bin = (SELECT TOP 1 Properties
    FROM MicrosoftDynamicsAXModel.dbo.ModelElement me
    JOIN MicrosoftDynamicsAXModel.dbo.ModelElementData med
     ON med.ElementHandle = me.ElementHandle
    WHERE me.Name = @name
     AND me.ElementType = 40
    ORDER BY med.LayerId DESC);
 DECLARE @pos AS int;
 DECLARE @flags AS int;
 DECLARE @count AS int;
 DECLARE @idx AS int;
 DECLARE @off AS int;
 DECLARE @ret AS varchar(255);
 SET @pos = 3;
 SET @off = CAST(SUBSTRING(@bin, @pos, 1) AS int) - 1;
 SET @pos = @pos + 1;
 WHILE @off > 0 --skip BaseEnum Label/Help/CountryRegionCode
	BEGIN
		WHILE SUBSTRING(@bin, @pos, 2) <> 0x0000
			SET @pos = @pos + 2;
		SET @pos = @pos + 2;
		SET @off = @off - 1;
	END
 SET @flags = CAST(SUBSTRING(@bin, @pos, 3) AS int);
 SET @pos = @pos + 3;
 IF @flags & 0x008000 = 0x008000 --skip BaseEnum ConfigurationKey
	BEGIN
		WHILE SUBSTRING(@bin, @pos, 2) <> 0x0000
			SET @pos = @pos + 2;
		SET @pos = @pos + 2;
	END
 IF @flags & 0x000002 = 0x000002 --skip BaseEnum ConfigurationKey
	SET @pos = @pos + 1;
 SET @pos = @pos + 1; --skip DisplayLength
 SET @count = CAST(SUBSTRING(@bin, @pos, 1) AS int);
 IF @count > 0
	BEGIN
		SET @pos = @pos + 1;
		IF @flags & 0x000200 = 0x000200 --UseEnumValue property
			SET @idx = @value;
		ELSE
			BEGIN
				SET @idx = 0;
				SET @off = 2 + CAST(CAST(REVERSE(SUBSTRING(@bin, @pos, 2)) AS binary(2)) AS int) * 2;
				SET @off = @off + 2 + CAST(CAST(REVERSE(SUBSTRING(@bin, @pos + @off, 2)) AS binary(2)) AS int) * 2;
				WHILE CAST(SUBSTRING(@bin, @pos + @off + @idx, 1) AS int) <> @value AND @idx < @count
					SET @idx = @idx + 1;
				IF CAST(SUBSTRING(@bin, @pos + @off + @idx, 1) AS int) <> @value
					SET @idx = -1;
			END
		IF @idx >= 0
			BEGIN
				SET @pos = @pos + 2;
				WHILE 1 = 1
					BEGIN
						SET @off = 0;
						SET @ret = '';
						WHILE SUBSTRING(@bin, @pos + @off, 2) <> 0x0000
							BEGIN
								SET @ret = @ret + CHAR(CAST(REVERSE(SUBSTRING(@bin, @pos + @off, 2)) AS binary(2)));
								SET @off = @off + 2;
							END
						SET @pos = @pos + @off + 2;
						IF @idx <= 0
							BREAK;
						SET @idx = @idx - 1;
					END
			END
		ELSE
			SET @ret = '<NOT FOUND';
	END
 ELSE
	SET @ret = '<ERROR>';
 IF SUBSTRING(@ret, 1, 1) = '@' --label file
	BEGIN
		DECLARE @module AS varchar(3);
		DECLARE @label AS int;
		SET @module = SUBSTRING(@ret, 2, 3);
		SET @label = CAST(SUBSTRING(@ret, 5, DATALENGTH(@ret) - 4) AS int);
		SET @ret = (SELECT TOP 1 Text FROM MicrosoftDynamicsAXModel.dbo.ModelElementLabel
					WHERE LabelId = @label
						AND Module = @module
						AND Language = 'en_us'
					ORDER BY LayerId DESC);
	END
 RETURN @ret;
END

Sunday, 28 November 2021

Admin provisioning tool can't stop DynamicsAXBatch service

 Admin User Provisioning Tool Error:

  1. If the Admin User Provisioning Tool gives error that can’t stop DynamicsAxBatch.
  2. Go to the Services,
  3. Find out the service with the name: Microsoft Dynamics 365 Unified Operations: Batch Management Service
  4. Stop it.
  5. Now register with the provisioning tool
  6. If you are unable to stop the DynamicsAxBatch Service. Then do the following steps in it:
  • Click the Start menu
  • Click Run or in the search bar type services.msc
  • Press Enter
  • Look for the service and check the Properties and identify its service name. Service name would be DynamicsAxBatch
  • Once found, open a command prompt. Type: sc queryex [servicename].
  • Press Enter
  • Identify the PID
  • In the same command prompt type: taskkill /f /pid [pid number]
  • Press Enter

For reference, see the following picture:

Image

Now start the service and and register yourself in the Admin Provisioning Tool.

Wednesday, 13 October 2021

AX365 Data Entities

Put some logic upon importing from data entity here below first copy event handler as below 



 and but the logic as below

 DataEntityContextEventArgs entityContextEventArgs = _eventArgs as DataEntityContextEventArgs;
        DataEntityRuntimeContext entityCtx = entityContextEventArgs.parmEntityContext();
        DataEntityDataSourceRuntimeContext dataSourceCtx = entityContextEventArgs.parmEntityDataSourceContext();

        if (dataSourceCtx.name() == dataEntityDataSourceStr(PbmIntegrationJournalLinesEntity, PbmIntegrationJournalLines))
        {
            PbmIntegrationJournalLinesEntity SalesOrderLineV2Entity = _sender as PbmIntegrationJournalLinesEntity;
            PbmIntegrationJournalLines _SalesLine = dataSourceCtx.getBuffer();
          

        if (SalesOrderLineV2Entity.BiPbmWBSLineTypes == BiPbmWBSLineTypes::Trans)
        {
            _SalesLine.lineType = PbmWBSLineTypes::Trans;
}

            if (SalesOrderLineV2Entity.BiPbmWBSLineTypes == BiPbmWBSLineTypes::Activity)
            {
                _SalesLine.lineType = PbmWBSLineTypes::Activity;
            }
            if (SalesOrderLineV2Entity.BiPbmWBSLineTypes == BiPbmWBSLineTypes::Summary)
            {
                _SalesLine.lineType = PbmWBSLineTypes::Activity;
            }

            if (SalesOrderLineV2Entity.BiPbmWBSLineTypes == BiPbmWBSLineTypes::Detail)
            {
                _SalesLine.lineType = PbmWBSLineTypes::Activity;
            }

        }

Wednesday, 29 September 2021

AX2012 /AX365 Filter the financial dimension for a security role

 One of the most common needs to restrict the user for specific financial dimension values

create a new query and add a table DimensionFinancialTag as the image below


browse the table to get the category 


after we get the category id to add range into the query as the first step like this



You should set the value as the expression below

((FinancialTagCategory==5637144577)&&(Value>="10000"))&&(Value<="19999"))


then create a new policy and assign the query to the policy and assign also the Security role as below


and make sure that to set the property of the contained table to yes 


and Happy Daxing 






Wednesday, 8 September 2021

MPOS DA3001 - A connectivity error has occurred and your device can't connect to the server. AX365 Retail

 mpos DA3001 - A connectivity error has occurred and your device can't connect to the server. This may be due to one or more of the following reasons. Contact your system administrator. The server URL typed may have some issues, check for typo errors or if it matches the HTTP protocol of the server. Server can't be reached because it is offline; The Application pool has stopped. Restart the pool and try again; The Server host name can't be resolved because the DNS can't be reached; Server is actively refusing the connection because the port you are using is not allowed through the firewall; The local system doesn't have network connectivity; The local system firewall is blocking outgoing connections. Add a firewall exception for the application. Server is not from the same origin of local system so the request is blocked by Cross-Origin Resource Sharing (CORS)

Solution 

first, check the retail server health by the below link 

https://usnconeboxax1ret.cloud.onebox.dynamics.com/healthcheck?testname=ping

the result should be like this 

PING SMOKE TEST SUMMARY RESULTS


TEST NAMEDATARESULT TEXTTEST STATUSTEST SEVERITY
PingDBCheckSuccessSucceededNormal
PingRealtimeServiceCheckSuccessSucceededNormal

Second

To add Dynamics 365 Modern POS to the loopback exemption list. Run Command Prompt as Administrator and copy-paste the below code. Note: Based on my check on multiple machines, the container name for MPOS is the same across all machines

CheckNetIsolation.exe LoopbackExempt –a -n=microsoft.dynamics.retail.pos_8wekyb3d8bbwe
For more details refer the link belowOriginal reference


Tuesday, 17 August 2021

AX 2012 X++ Upload product image from code

 static void Job7(Args _args)

{

 DocuRef docuRef;

DocuValue docuValue;

InventTable inventTable;

EcoResProductImage ecoResProductImage;


System.String[] fileNames;

int fileCount, i;


str fileName, trimmedFileName, fileNameWithExt;

BinData binData;


binData = new BinData();

//fileNames = System.IO.Directory::GetFiles(strFmt(@"%1", StringFilePath.valueStr()));

fileNames = System.IO.Directory::GetFiles(@"C:\hh");



fileCount = fileNames.get_Length();


for (i=0; i<fileCount; i++)

{

fileName = fileNames.GetValue(i);



trimmedFileName = substr(fileName, strscan(fileName, '\\', strlen(fileName), -strlen(fileName))+ 1, strlen(fileName));

fileNameWithExt = trimmedFileName;

if (trimmedFileName)

{

// Assuming file extension is always .jpg, removing it

trimmedFileName = strreplace(trimmedFileName, ".jpg", "");

}

// assuming image name matches item name in AX

inventTable = InventTable::find(trimmedFileName);


if (inventTable)

{

binData.loadFile(fileName);


//docuValue.FileName = trimmedFileName;

docuValue.Name = trimmedFileName;


docuValue.FileType = "jpg";

docuValue.OriginalFileName = fileNameWithExt;

docuValue.File = binData.getData();

docuValue.insert();


docuRef.ValueRecId = docuValue.RecId;

docuRef.RefTableId = tableNum(InventTable);

docuRef.RefRecId = inventTable.RecId;

//docuRef.RefRecord = inventTable.RecId;

docuRef.RefCompanyId = curext();

docuRef.Name = trimmedFileName;

docuRef.TypeId = "File";

docuRef.insert();


ecoResProductImage.clear();

ecoResProductImage.DefaultImage = true;

ecoResProductImage.FileName = fileNameWithExt;

ecoResProductImage.ImageFormat = "jpg";

ecoResProductImage.RefRecId = docuRef.RecId;

ecoResProductImage.RefRecord = docuRef.RefRecId;

ecoResProductImage.Usage = 0; // Base Enum: 0=External, 1=Internal

ecoResProductImage.insert();


}

}

}


Tuesday, 27 July 2021

AX365 X++ add a new dimension value into financial dimensions

 


      DimensionValueContract _contract = new DimensionValueContract();

        _contract.parmDimensionAttribute('Dimension name');

        _contract.parmValue('Dimension value');

        _contract.parmDescription('Dimension Description');

      

        DimensionValueService _service = new DimensionValueService();

        _service.createDimensionValue(_contract);