Thursday 23 December 2021

AX 2012 X++ Adjust sales order line Tax

 SalesTable              _SalesTable; 

    SalesLine               _SalesLine;

    TaxRegulation           taxRegulation;

    super();

    

   

 

    _SalesTable = SalesTable::find(SalesTable.SalesId);

    _SalesLine  = SalesLine::find(_SalesTable.SalesId,SalesLine.LineNum);

     

    taxRegulation = TaxRegulation::newTaxRegulation(

           SalesTotals::getTax(_SalesTable),

            null,                                                    

            tableNum(SalesLine),

            SalesLine.RecId

    );

 

    if(taxRegulation)

    {

        taxRegulation.allocateAmount(20);

        taxRegulation.saveTaxRegulation();

    }

Sunday 19 December 2021

AX 365 Deploy SSRS report through Power Shell

 C:\AosService\PackagesLocalDirectory\Plugins\AxReportVmRoleStartupTask\DeployAllReportsToSSRS.ps1 -PackageInstallLocation "C:\AosService\PackagesLocalDirectory" -ReportName SalesInvoiceCopy1*

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

Tuesday 29 June 2021

AX365 create a notification to user

  SystemNotificationDataContract notification = new SystemNotificationDataContract();

        notification.Users().value(1, curUserId());

        notification.Title("Export to Excel finished");

        notification.RuleId('ExcelStaticExport');

        notification.Message("We finished your export from the Customers page");

        notification.ExpirationDateTime(DateTimeUtil::addHours(DateTimeUtil::utcNow(), 48));

        notification.ReminderInterval(5);

    

        SystemNotificationsManager::AddNotification(notification);

Tuesday 18 May 2021

AX 2012 X++ Consume aif web service by passing list of objects

 1- Create data contract class as below

[DataContractAttribute]

class HP_TestContract

{

    str Id;

    str Name;


[DataMemberAttribute('Id'), SysOperationDisplayOrderAttribute('1')]

public str ParamId(str _Id = Id)

{

    Id = _Id;

    return Id;

}

[DataMemberAttribute('Name'), SysOperationDisplayOrderAttribute('2')]

public str ParamName(str _Name = Name)

{

    Name = _Name;

    return Name;

}

}

2-Add an AIF service method

[SysEntryPointAttribute(true),
DataMemberAttribute("HP_TestContract"),
AifCollectionTypeAttribute("_contactList",Types::Class, classStr(HP_TestContract)),
AifCollectionTypeAttribute("return",Types::Class, classStr(HP_TestContract))]
public List HeshamList(List _contactList)
{
//_contactList = contactList;
return _contactList;
}

Tuesday 6 April 2021

AX365 Dev machine import restore a DB .bacpac file from the UAT

 Download the  Get sqlpackage .NET Core for Windows


extract the folder and run the command prompt as an administrator and run the below command


SqlPackage.exe /a:import /sf:D:\Hesham\SafariUATbackup.bacpac /tsn:localhost /tdn:AxDB /p:CommandTimeout=1200  /ttsc:True

Tuesday 30 March 2021

AX 365 local Dev VM open AX from outside the network

 In case we need to access the local dev machine F&O go to the below path 


C:\Windows\System32\drivers\etc


edit the host file and add the below last line


10.0.1.120 usnconeboxax1aos.cloud.onebox.dynamics.com


the IP of the dev machine 


Enjoy DAXing

Wednesday 3 February 2021

AX365 Deploy a package locally

 1-Create a temp folder

2-Extract the package inside the temp folder

3-open the command prompt as administrator and navigate into the temp folder and run the below scripts as below

AXUpdateInstaller.exe generate -runbookid="Safarirunbook" -topologyfile="DefaultTopologyData.xml" -servicemodelfile="DefaultServiceModelData.xml" -runbookfile="Safarirunbook-runbook.xml"


AXUpdateInstaller.exe import -runbookfile="Safarirunbook-runbook.xml"


AXUpdateInstaller.exe execute -runbookid="Safarirunbook"

in case you want to rerun a step call the below

AXUpdateInstaller.exe execute -runbookid=Safarirunbook -rerunstep=7

Tuesday 2 February 2021

AX365/2012 X++ SQL select statement inside AX

 

  Connection      connection;

        Statement       statement;

        str             query;

        Resultset       resultSet;

        container conComm;

        ;


        // create connection object

        connection = new Connection();


        // create statement

        statement = connection.createStatement();


        // Set the SQL statement

        query = "select ACQUISITIONPRICE,BookID,BookType,Status from AssetBookMerge where AssetID = '" + strAssetId + "'";


        // assert SQL statement execute permission

        new SqlStatementExecutePermission(query).assert();


        // when the query returns result,

        // loop all results for processing

        //BP Deviation documented

        resultSet = statement.executeQuery(query);


        while(resultSet.next())

        {

            // do something with the result

            conComm =[resultSet.getString(1),resultSet.getString(2),resultSet.getString(3),resultSet.getString(4)] ;

        }


        // limit the scope of the assert call

        CodeAccessPermission::revertAssert();

        return conComm;

Wednesday 13 January 2021

AX X++ get value from Financial dimension

  public str getDimValue(RecId _DefaultDim)

    {

        DimensionAttributeValueSetStorage    dimStorage;

        // ProjTable                                            ProjTable;

        Counter                                               i;

        str ret="";

        // ProjTable = ProjTable::find("10005");    //  To display value for ProjectId "10005" only

        dimStorage = DimensionAttributeValueSetStorage::find(_DefaultDim);


        for (i=1 ; i<= dimStorage.elements() ; i++)

        {

            // info(DimensionAttribute::find(dimStorage.getAttributeByIndex(i)).Name +"----" +dimStorage.getDisplayValueByIndex(i));

            if(DimensionAttribute::find(dimStorage.getAttributeByIndex(i)).Name == "Project")

            {

                ret =dimStorage.getDisplayValueByIndex(i));

            }

        

        }

        return ret;

    }


Reference

Monday 11 January 2021

AX 365 Create general journal from code x++

   LedgerJournalTable _ledgerJournalTable;

        JournalTableData _journalTableData;

        LedgerjournalTrans _ledgerjournalTrans;

       

        MCRLedgerJournal        journalTable;

        LedgerJournalTableData LedgerJournalTableData;

        NumberSeq _numberSeq;

        LedgerJournalACType _ledgerJournalACType;

        

        RecId _RecId;

        NumberSequenceTable _NumberSequenceTable;      

           


 _LedgerJournalTable.JournalName = 'Journal Name';//HpSetup::getSetup().HpCheque;

             

            _LedgerJournalTable.initFromLedgerJournalName();

            _ledgerJournalTable.Name=strJournalDesc;

            _LedgerJournalTable.insert();

            if (_ledgerJournalTable.RecId)

            {


                //_numberSeq = NumberSeq::newGetVoucherFromCode("Alloc_01");

                _RecId =  LedgerJournalName::find(HpSetup::getSetup().HpCheque).NumberSequenceTable;


                select firstonly  _NumberSequenceTable

                    where _NumberSequenceTable.RecId == _RecId;


                _numberSeq = NumberSeq::newGetVoucherFromCode(_NumberSequenceTable.NumberSequence);


                _ledgerjournalTrans.clear();

                _ledgerjournalTrans.initvalue();

                _LedgerJournalTrans.voucher = _numberSeq.voucher();

                _ledgerjournalTrans.JournalNum = _ledgerJournalTable.JournalNum;

                //_ledgerjournalTrans.Company = curext();

                _ledgerjournalTrans.TransDate = HpCheque.TransDate;

                _ledgerjournalTrans.CurrencyCode = CompanyInfoHelper::standardCurrency();

                _ledgerjournalTrans.Txt = "Transafer to cash";

                _ledgerjournalTrans.AccountType = LedgerJournalACType::Cust;

                _ledgerjournalTrans.LedgerDimension = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(HpCheque.CustAccount,LedgerJournalACType::Cust);

                _ledgerjournalTrans.OffsetAccountType = LedgerJournalACType::Bank;

                _ledgerjournalTrans.OffsetLedgerDimension = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(dialogField.value(),LedgerJournalACType::Bank) ;

                _ledgerjournalTrans.AmountCurCredit = HpCheque.TrxAmount;

                    

                _ledgerjournalTrans.insert();

AX 365 x++ upload from Excel sheet

 using System.IO;

using OfficeOpenXml;

using OfficeOpenXml.ExcelPackage;

using OfficeOpenXml.ExcelRange;



 System.IO.Stream                     stream;

            ExcelSpreadsheetName            sheeet;

            FileUploadBuild                       fileUpload;

            DialogGroup                             dlgUploadGroup;

            FileUploadBuild                       fileUploadBuild;

            FormBuildControl                    formBuildControl;  

HpCheque  _HpCheque;

            COMVariantType                     type;

            Dialog                      dialog =    new Dialog('Import Cheques'); 


            dlgUploadGroup          = dialog.addGroup('@SYS54759');

            formBuildControl        = dialog.formBuildDesign().control(dlgUploadGroup.name());

            fileUploadBuild           = formBuildControl.addControlEx(classstr(FileUpload), 'Upload');

            fileUploadBuild.style(FileUploadStyle::MinimalWithFilename);

            fileUploadBuild.fileTypesAccepted('.xlsx'); 

            str COMVariant2Str(COMVariant _cv)

            {

                switch (_cv.variantType())

                {

                    case COMVariantType::VT_BSTR:

                        return _cv.bStr();

                    case COMVariantType::VT_EMPTY:

                        return'';

                   default:

                        throw error(strfmt('@SYS26908', _cv.variantType()));

                }

            }

            if (dialog.run() && dialog.closedOk())

            {


                FileUpload fileUploadControl     = dialog.formRun().control(dialog.formRun().controlId('Upload'));

                FileUploadTemporaryStorageResult fileUploadResult = fileUploadControl.getFileUploadResult(); 

                if (fileUploadResult != null && fileUploadResult.getUploadStatus())

                {

                    stream = fileUploadResult.openResult();

                    using (ExcelPackage Package = new ExcelPackage(stream))

                    {


                        int                         rowCount, i,columncount,j;

                        Package.Load(stream);

                        ExcelWorksheet   worksheet   = package.get_Workbook().get_Worksheets().get_Item(1);

                        OfficeOpenXml.ExcelRange    range       = worksheet.Cells;

                        rowCount           = (worksheet.Dimension.End.Row) - (worksheet.Dimension.Start.Row)  + 1;

                        columncount      = (worksheet.Dimension.End.Column);


                        for (i = 2; i<= rowCount; i++)

                        {

                            //info(range.get_Item(i, 1).value);

                            ttsbegin;

                            _HpCheque.initValue();

                            _HpCheque.clear();

                            _HpCheque.ChequeNumber =range.get_Item(i, 1).value;

                            _HpCheque.TransDate = str2DateDMY(range.get_Item(i, 2).value);

                            _HpCheque.CustAccount =range.get_Item(i, 3).value;

                            _HpCheque.DueDate = str2DateDMY(range.get_Item(i, 4).value);

                            _HpCheque.CurrencyCode = range.get_Item(i, 5).value;

                            _HpCheque.UnitID = range.get_Item(i, 6).value;

                            _HpCheque.insert();

                            ttscommit;                         

}

                    }

                }

                else

                {

                    error('Error here');

                } 

            }