Search your query

Monday, August 26, 2024

How to create Self Signed Certificate (.cer) file for License code and activate the ISV Solution in Dynamics 365 F&O Development Server

Follow below steps to create SSL certificate for DEV server:

1. Login into Development Server (Either Cloud Hosted or OnPremises)


2. Goto Windows Powershell and execute below code to create our own certificate.

$cert = New-SelfSignedCertificate -CertStoreLocation cert:\LocalMachine\My -DnsName "MyISVSolutionCert" -Type CodeSigningCert -KeyExportPolicy Exportable -HashAlgorithm Sha256 -KeyLength 2048 -KeySpec Signature -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotBefore (Get-Date -Year 2024 -Month 8 -Day 1) -NotAfter (Get-Date -Year 2025 -Month 12 -Day 31)


3. Click Start > Manage computer certificates path > Personal (Folder) > Certificates (sub folder) and Find the new certificate which we created just now - "MyISVSolutionCert".


4. Once you find it, Execute the below code to add reference to this new certificate file.

[String]$certpath = join-path -Path "cert:\LocalMachine\My\" -childpath "$($cert.Thumbprint)"


5. Create the secure string password that the certificate uses. (Replace "###############" with your defined certificate password)

[System.Security.SecureString]$certPassword = ConvertTo-SecureString -String "###############" -Force -AsPlainText


6. Export the certificate private key as .pfx file using password and store this file into C:\Temp folder.

Export-pfxCertificate -Cert $certPath -FilePath "C:\Temp\MyISVSolutionCert.pfx" -Password $certPassword


7. Export the certificate public key as a .cer file by using below powershell command

Export-Certificate -Cert $certPath -FilePath "C:\Temp\MyISVSolutionCert.cer"


8. Add this new certificate to the root store:

certutil -addstore root C:\Temp\MyISVSolutionCert.cer


9. Now we can see this certificate in "Trusted Root Certificates" folder in "Manage computer certificates" form from windows.


10. System is now generated new certificate and placed at "Trusted Root Certificates". 


11. Create New Resource from AOT (Name: MyISVSolutionCertResource) from AOT and choose the certificate file (.cer) from C:/Temp folder.


12. Create License code from AOT (For example: MyISVSolutionCertLicense) and select Resource property of License code and Lookup and select the newly created Resource (MyISVSolutionCertResource).


13. Give some meaningful name into Certificate name property.


14. Create Configuration key from AOT and assigned this License code into this Configuration.


15. Still you are unable to see your custom configuration key in System Admin > Setup > License information form.

<< Close powershell window>>


16. Then, Go to Browser > Application Page - Home > Help and Support (? mark logo) > About > Click - Licenses and find below details

DNS: (Domain or Customer (licensed for)): myworkingcompany.ae

Serial number: for example: 84atef28-09f4-1jk6-387d-b01cfa66c24x


17. **Open command prompt and Copy the below code: till bin folder: (To initialize customer and serial number for this license)

K:\AosService\PackagesLocalDirectory\bin\axutil genlicense /file:c:\Temp\MyISVSolutionCert.txt /certificatepath:c:\Temp\MyISVSolutionCert.pfx /licensecode:MyISVSolutionCertLicense /customer:myworkingcompany.ae /serialnumber:84atef28-09f4-1jk6-387d-b01cfa66c24x /password:mypassword@123


18. ** The same command prompt and Copy the below code: till bin folder: (To Import the license into the target environment):


* Prerequisites : Open SQL Server create new login under Security: Create new username and password and give "SysAdmin" Role access.

For example:

username: MyCompanyNameAdmin

Password: pass@word1


** The same command prompt and Copy below code and execute:

K:\AosService\PackagesLocalDirectory\bin\Microsoft.Dynamics.AX.Deployment.Setup.exe --setupmode importlicensefile --metadatadir K:\AosService\PackagesLocalDirectory --bindir K:\AosService\PackagesLocalDirectory --sqlserver . --sqldatabase AxDB --sqluser MyCompanyNameAdmin --sqlpwd pass@word1 --licensefilename c:\Temp\MyISVSolutionCert.txt

Wednesday, August 14, 2024

Generate and Place QR Code in D365 F&O Form and SSRS Reports

 Need to follow below steps to generate QR code by using X++ in D365 F&O.

1. Create one container field (QRCodeField) in required Table (Either Regular Table for Form or Temp Table for SSRS report) and set Extended data type property to "BitMap"

2. Create One Class and copy below codes for generating QR Code in X++.

/// <summary>

/// Generate QR Code

/// </summary>

class MyQRCodeHelper

{

    public static container QRCodeGenerator(String255 _qRCodeContainer)

    {

            Microsoft.Dynamics.ApplicationSuite.QRCode.Encoder Encoder;

            System.Drawing.Bitmap bm = null;

            try

            {

                var qrCodeEncoder = new Microsoft.Dynamics.ApplicationSuite.QRCode.Encoder();

                bm = qrCodeEncoder.Encode(_qRCodeContainer);

            }

            catch (Exception::CLRError)

            {

                error(CLRInterop::getLastException().ToString());

            }

           using (var stream = new System.IO.MemoryStream())

            {

                bm.Save(stream, System.Drawing.Imaging.ImageFormat::Bmp);

                bm.Dispose();

                return Binary::constructFromMemoryStream(stream).getContainer();

            }

    }

}

3. Goto Form - init() method or For SSRS report, Goto Insert Temp Table method and write below code to initialize and generate QR code.

    Form init() method:

    {

        str qrCodeInformation;

        super();

        qrCodeInformation    =  strFmt("This is QR code generation development and more information visit: %1", "http://mohamedhussaindynamics365.blogspot.in/");

        MyQRCodeTable.QRCode = MyQRCodeHelper::QRCodeGenerator(qrCodeInformation);

    }


>> Place this container filed in form or report and scan the QR code.

Friday, March 1, 2024

D365 F&O: Virtual Machine (VM) - Software Deployable Package Deployment by command - (When this error comes: "‘The devInstall option is not applicable to the current deployable package")

D365 F&O: Virtual Machine (VM) - Software Deployable Package Deployment by command - (When this error comes: "‘The devInstall option is not applicable to the current deployable package")

    When AxUpdateInstaller.exe devinstall command prompt is not working in VM or Applying software deployable package for cloud hosted dev environment is not working or unable to deploy your package then try the following steps:

Steps:

1. Open Command prompt, as administrator and type below commands.

2. Example > cd C:\Hussain\AXDeployablePackage_20240301_05_05_05 (cd and file path (Specify your deployable package location (unzip your software deployable package) ) 

3. C:\Hussain\AXDeployablePackage_20240301_05_05_05> AXUpdateInstaller.exe generate -runbookid ="DevelopmentPackage" topologyfile="DefaultTopologyData.xml" -servicemodelfile="DefaultServiceModelData.xml" -runbookfile="DevelopmentPackage-runbook.xml" 

4C:\Hussain\AXDeployablePackage_20240301_05_05_05> AXUpdateInstaller.exe import -runbookfile=DevelopmentPackage-runbook.xml

4If already runbook exist, just replace the runbook by typing Yes in command prompt.

5.  C:\Hussain\AXDeployablePackage_20240301_05_05_05> AXUpdateInstaller.exe execute -runbookid=DevelopmentPackage


Note: Please ensure that all kind of "Visual studio services" must be stopped and Stop: Microsoft Dynamics services (Data Import, Export and Batch services)

Monday, February 19, 2024

X++ code to create Ledger Journal Line (General Journal) for any ledger account type (Ledger, Vendor, Customer.. etc)

 Find below code will help you with Dimensions when you create GL Journal lines.

 

public void createJournalLines()

{

    LedgerJournalTrans                  ledgerJournalTrans;

    HcmWorker                           HcmWorker;

    Amount                              tmpAmount = 100;

    LedgerJournalTransTaxExtensionIN    ledgerJournalTransTaxExtensionIN;

    LedgerDimensionAccount              ledgerAccount;

    Boolean                             isLedgerTransaction = false;

    accountNum                          ledgerAccountNum_NonLedgerType;

    ledgerJournalCheckPost              ledgerJournalCheckPost;

 

    #ISOCountryRegionCodes

   

    ledgerJournalTrans.Voucher      = NumberSeq::newGetVoucherFromCode(numberSequenceTable.NumberSequence).voucher();

    ledgerJournalTrans.JournalNum   = headerJournal.JournalNum; //From Journal Header Table; //NumberSeq::newGetNum(LedgerParameters::numRefJournalNum()).num();        ledgerJournalTrans.CurrencyCode         = CompanyInfoHelper::standardCurrency();

    ledgerJournalTrans.ExchRate     = ExchangeRateHelper::exchRate(ledgerJournalTrans.CurrencyCode);

       

     //if (General Ledger Journal – Type is Ledger)

     {

         ledgerJournalTrans.AccountType = LedgerJournalACType::Ledger;

         isLedgerTransaction = Yes;

     }

     //else if (Customer, vendor)

     {

        ledgerJournalTrans.AccountType = LedgerJournalACType::Vendor; // select appropriate type based on input of Ledger dimension and account type of Posting profile.

        isLedgerTransaction = false;

    }

    ledgerJournalTrans.DefaultDimension     = // Input: Default dimension from Hcmworker in our example;

     if (isLedgerTransaction)

     {

            ledgerAccount = LedgerDimensionFacade::serviceCreateLedgerDimension(_ledgerJournalTrans.JournalNum, ledgerJournalTrans.DefaultDimension);

           ledgerJournalTrans.LedgerDimension = ledgerAccount;

     }

     else

     {

            ledgerAccountNum_ NonLedgerType  = LedgerDimensionFacade::getDisplayValueForLedgerDimension(ledgerAccount); // either vendor, customer or bank id

             ledgerAccount = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(ledgerAccountNum, ledgerJournalTrans.AccountType);

      }

     //if (if Debit amount)

    {

        ledgerJournalTrans.AmountCurDebit   = CurrencyExchangeHelper::amount(100, ledgerJournalTrans.CurrencyCode);

    }

    // else -- if credit amount.

    {

        ledgerJournalTrans.AmountCurCredit  = CurrencyExchangeHelper::amount(100, ledgerjournalTrans.CurrencyCode);

    }

     ledgerJournalTrans.TransDate                = Today();

    ledgerJournalTrans.Txt                      = "Create a Journal Line";

    ledgerJournalTrans.BankNegInstRecipientName = HcmWorker.name();

    ledgerJournalTrans.insert();

    if (SysCountryRegionCode::isLegalEntityInCountryRegion([#isoIN]))

    {                           

                                       ledgerJournalTransTaxExtensionIN.TaxModelDocLineExtensionIN::initFromBaseTable (ledgerJournalTrans);

                    ledgerJournalTransTaxExtensionIN.TaxModelDocLineExtensionIN::initFromExtensionTable(LedgerJournalTransTaxExtensionIN::findByLedgerJournalTrans(ledgerJournalTrans.RecId));

    ledgerJournalTransTaxExtensionIN.insert();

}

       

    // If post this journal..

    //Post the Journal

    ledgerJournalCheckPost = ledgerJournalCheckPost::newLedgerJournalTable(ledgerJournalTable,NoYes::Yes); // Header Journal Table.

    ledgerJournalCheckPost.run();

}


Wednesday, January 17, 2024

Extract All Dimension values from one ledger dimension and merge them with another Main Account (LedgerDimension, OffsetDimension)

 

// Step-1: Separate all dimensions from Source Main Account from Ledger Dimension and keep it as "OnlyDefaultDimension"


//Step-2: Merge this OnlyDefaultDimension with another Main Account Rec Id.


public static RecId createLedgerDimensionCombination(RecId _sourceLedgerDimension, RecId _targetMainAccountRecId)

    {

        RecId                   onlyDefaultDimension, targetLedgerDimension;

        DimensionHierarchyId    accountStructureId;


 // Extract from source ledger dimension

        onlyDefaultDimension    = LedgerDimensionFacade::getDefaultDimensionFromLedgerDimension(_sourceLedgerDimension);

 

        accountStructureId      = DimensionHierarchy:: getAccountStructure(_targetMainAccountRecId);

 

 // Adding with another main account.

        targetLedgerDimension   = LedgerDimensionDefaultingEngine:: getLedgerDimensionFromAccountAndDim(_targetMainAccountRecId, accountStructureId, onlyDefaultDimension);

 

        return targetLedgerDimension;

    }