Thursday, 7 October 2021

Export CSV/Text file in D365FO

 Call the below method for file generation


public void accGenerateCheckFile()

    {

        #define.delimiter('|')

        container               cont;

        str                     fileContent, dateStr, timeStr;

        UtcDateTime             creationDateTimeInUserTimeZone;

        date                    creationDate;

        TimeOfDay               creationTime;

        Filename                fileName;

        TextStreamIo            io = TextStreamIo::constructForWrite();

        io.outFieldDelimiter('|');


        //Export file header

        //Export records

            cont = conNull();

            cont = ['AX2009', 'Ax2012', 'D365FO'];

            io.writeExp(cont);

        }


        //Prepare file name

        creationDateTimeInUserTimeZone  = DateTimeUtil::applyTimeZoneOffset(DateTimeUtil::utcNow(), DateTimeUtil::getUserPreferredTimeZone());

        creationDate                    = DateTimeUtil::date(creationDateTimeInUserTimeZone);

        //creationTime                    = DateTimeUtil::time(creationDateTimeInUserTimeZone);

        dateStr                         = date2str(creationDate,213,DateDay::Digits2,DateSeparator::None,DateMonth::Digits2,DateSeparator::None,DateYear::Digits4);

        //timeStr                         = num2str( creationTime div 3600,2,0,0,0)+ num2Str0(creationTime mod 3600 div 60,2,0,0,0) + num2Str0(creationTime mod 3600 mod 60,2,0,0,0);

        fileName                        = dateStr + '.txt';


        // Set stream

        System.IO.Stream stream = io.getStream();

        stream.Position = 0;


        // Set stream reader

        System.IO.StreamReader sReader = new System.IO.StreamReader(stream);


        // Set file contentn string

        fileContent = sReader.ReadToEnd();


        // Save file

        File::SendStringAsFileToUser(fileContent, fileName);

}


Note: If the requirement is to export CSV then use  CommaStreamIo instead TextStreamIo            

Saturday, 15 May 2021

Create Product or Product master with variant and release to Legal entities

 /// <summary>

/// 

/// </summary>

class IHSProductMasterInsertManager extends RunBaseBatch

{

    /// <summary>

    /// 

    /// </summary>

    public void run()

    {

        IHSProductMasterTable   ihsProductMasterTable;

        EcoResProduct           ecoResProduct;

        RefRecId                ecoResDistinctProductVariantRecId;

        InventTable             inventTable;

        InventDimCombination    inventDimCombination;

        str                     messageBody;

        int                     i, j = 1, errorCount = 0, successCount = 0;


        while select ihsProductMasterTable 

            order by ihsProductMasterTable.ProductNumber, ihsProductMasterTable.EntityId

            where ihsProductMasterTable.ItemProcessStatus == IHSItemProcessStatus::Unprocessed

        {


            try

            {

                ttsbegin;

                //Create product

                if (!this.checkIfProductNumberExists(ihsProductMasterTable.ProductNumber))

                {

                    this.createProduct(ihsProductMasterTable);

                }


                //Release product

                changecompany(ihsProductMasterTable.EntityId)

                {

                    if (!InventTable::exist(ihsProductMasterTable.ItemNumber))

                    {

                        this.releaseProduct(ihsProductMasterTable);

                    }

                    //Update tracking details

                    if (!ihsProductMasterTable.ProductStyleVariant)

                    {

                        select firstonly RecId, TableId 

                             from inventTable

                            where inventTable.ItemId == ihsProductMasterTable.ItemNumber;


                        this.assignTrackingDetails(ihsProductMasterTable, inventTable.TableId, inventTable.RecId);

                    }

                }


                //Create prodct variant

                if (ihsProductMasterTable.ProductSubtype == EcoResProductSubtype::ProductMaster && ihsProductMasterTable.ProductStyleVariant)

                {

                    ecoResProduct = EcoResProduct::findByProductNumber(ihsProductMasterTable.ProductNumber);

                    ecoResDistinctProductVariantRecId = this.createProductVariant(ecoResProduct, ihsProductMasterTable.ProductStyleVariant);


                    //Release product variant

                    changecompany (ihsProductMasterTable.EntityId)

                    {

                        this.releaseProductVariant(ecoResDistinctProductVariantRecId);


                        //Update tracking details

                        select firstonly RecId, TableId 

                             from inventDimCombination

                            where inventDimCombination.DistinctProductVariant == ecoResDistinctProductVariantRecId;


                        this.assignTrackingDetails(ihsProductMasterTable, inventDimCombination.TableId, inventDimCombination.RecId);

                    }

                }

                successCount ++;

                ihsProductMasterTable.selectForUpdate(true);

                ihsProductMasterTable.update();

                ttscommit;

            }

            catch

            {

                errorCount ++;

                messageBody = '';


                for (i = j; i <= infolog.line(); i++)

                {

                    messageBody += infolog.text(i);

                }

                j = i;

                ttsbegin;

                ihsProductMasterTable.ItemProcessStatus = IHSItemProcessStatus::Error;

                ihsProductMasterTable.ErrorTxt          = messageBody;

                ihsProductMasterTable.selectForUpdate(true);

                ihsProductMasterTable.update();

                ttscommit;

                continue;

            }

        }

        info (strFmt("Item master import completed with %1 success and %2 errors", successCount, errorCount));

    }


    /// <summary>

    /// 

    /// </summary>

    /// <param name = "_productNumber"></param>

    /// <returns></returns>

    public boolean checkIfProductNumberExists(EcoResProductNumber _productNumber)

    {

        return EcoResProductIdentifier::existsByProductNumber(_productNumber);

    }


    /// <summary>

    /// 

    /// </summary>

    /// <param name = "ihsProductMasterTable"></param>

    public void createProduct(IHSProductMasterTable ihsProductMasterTable)

    {

        EcoResProductV2Entity       ecoResProductV2Entity;


        ecoResProductV2Entity.clear();

        ecoResProductV2Entity.initValue();

        ecoResProductV2Entity.ProductNumber                 = ihsProductMasterTable.ProductNumber;

        ecoResProductV2Entity.ProductName                   = ihsProductMasterTable.ProductName;

        ecoResProductV2Entity.ProductSearchName             = ihsProductMasterTable.ProductSearchName;

       // ecoResProductV2Entity.SearchName                    = ihsProductMasterTable.ProductSearchName;

       // ecoResProductV2Entity.ItemNumber                    = ihsProductMasterTable.ItemNumber;

        ecoResProductV2Entity.ProductType                   = ihsProductMasterTable.ProductType;

        ecoResProductV2Entity.ProductSubType                = ihsProductMasterTable.ProductSubtype;


        if (ecoResProductV2Entity.ProductSubType  == EcoResProductSubtype::ProductMaster)

        {

            ecoResProductV2Entity.VariantConfigurationTechnology = EcoResVariantConfigurationTechnologyType::PredefinedVariants;

            ecoResProductV2Entity.ProductDimensionGroupName      = ihsProductMasterTable.ProductDimensionGroup;

        }

       // ecoResProductV2Entity.ItemModelGroupId              = ihsProductMasterTable.ItemModelGroupId;

        //ecoResProductV2Entity.ProductGroupId                = ihsProductMasterTable.ItemGroupId;


       // ecoResProductV2Entity.InventoryUnitSymbol           = ihsProductMasterTable.UnitId;

        //ecoResProductV2Entity.BOMUnitSymbol                 = ihsProductMasterTable.UnitI;

        //ecoResProductV2Entity.SalesUnitSymbol               = ihsProductMasterTable.UnitId;

        //ecoResProductV2Entity.PurchaseUnitSymbol            = ihsProductMasterTable.UnitId;

        

        ecoResProductV2Entity.TrackingDimensionGroupName    = ihsProductMasterTable.TrackingDimensionGroup;

        ecoResProductV2Entity.StorageDimensionGroupName     = ihsProductMasterTable.StorageDimensionGroup;

        ecoResProductV2Entity.insert();

    }


    /// <summary>

    /// 

    /// </summary>

    /// <param name = "_ecoResProduct"></param>

    /// <param name = "_styleName"></param>

    /// <returns></returns>

    public RefRecId createProductVariant(EcoResProduct _ecoResProduct, EcoResStyleName _styleName)

    {

        EcoResProductMasterStyle        productMasterStyle;

        EcoResStyle                     ecoResStyle;

        EcoResProductDimensionAttribute prodDimensionAttribute;

        container                       productDimensions;

        ecoResDistinctProductVariant    ecoResDistinctProductVariant;

        RefRecId                        ecoResDistinctProductVariantRecId;


        //Create a container to hold dimension values

        productDimensions = EcoResProductVariantDimValue::getDimensionValuesContainer('','','',_styleName);


        ecoResDistinctProductVariantRecId = EcoResProductVariantManager::findDistinctProductVariant(_ecoResProduct.RecId, productDimensions).RecId;


        if (ecoResDistinctProductVariantRecId)

        {

            return ecoResDistinctProductVariantRecId;

        }

        

        //Style - Start

        ecoResStyle = EcoResStyle::findByName(_styleName);

        if (!ecoResStyle.RecId)

        {

            ecoResStyle.Name = _styleName;

            ecoResStyle.insert();

        }


        select * from productMasterStyle 

            where productMasterStyle.Style == ecoResStyle.RecId

               && productMasterStyle.StyleProductMaster == _ecoResProduct.RecId;


        if(!productMasterStyle.RecId)

        {

            select RecId from prodDimensionAttribute

                where prodDimensionAttribute.DimensionTableId == tableNum(EcoResStyle);


            productMasterStyle.Style                            = ecoResStyle.RecId;

            productMasterStyle.StyleProductDimensionAttribute   = prodDimensionAttribute.RecId;

            productMasterStyle.StyleProductMaster               = _ecoResProduct.RecId;

            productMasterStyle.insert();

        }

        

        //Create Product search name

        //ecoResDistinctProductVariant.DisplayProductNumber = EcoResProductNumberBuilderVariant::buildFromProductNumberAndDimensions(_ecoResProduct.productNumber(), productDimensions);

        ecoResDistinctProductVariant.DisplayProductNumber   = _ecoResProduct.productNumber() + "-" + _styleName;


        productDimensions = EcoResProductVariantDimValue::getDimensionValuesContainer('','','',_styleName);

        //Create Product variant with Product and dimensions provided

        ecoResDistinctProductVariantRecId = EcoResProductVariantManager::createProductVariant(_ecoResProduct.RecId,

                                                ecoResDistinctProductVariant.DisplayProductNumber,

                                                productDimensions,ecoResDistinctProductVariant.DisplayProductNumber);



        return ecoResDistinctProductVariantRecId;

    }


    /// <summary>

    /// 

    /// </summary>

    /// <param name = "ihsProductMasterTable"></param>

    public void releaseProduct(IHSProductMasterTable ihsProductMasterTable)

    {

        EcoResReleasedProductV2Entity   ecoResReleasedProductCreationV2Entity;


        ecoResReleasedProductCreationV2Entity.clear();

        ecoResReleasedProductCreationV2Entity.initValue();

        ecoResReleasedProductCreationV2Entity.ProductNumber                 = ihsProductMasterTable.ProductNumber;

        //ecoResReleasedProductCreationV2Entity.ProductName                   = ihsProductMasterTable.ProductName;

        ecoResReleasedProductCreationV2Entity.ProductSearchName             = ihsProductMasterTable.ProductSearchName;

        ecoResReleasedProductCreationV2Entity.SearchName                    = ihsProductMasterTable.ProductSearchName;


        ecoResReleasedProductCreationV2Entity.ItemNumber                    = ihsProductMasterTable.ItemNumber;

        ecoResReleasedProductCreationV2Entity.ProductType                   = ihsProductMasterTable.ProductType;

        ecoResReleasedProductCreationV2Entity.ProductSubType                = ihsProductMasterTable.ProductSubtype;

        ecoResReleasedProductCreationV2Entity.ItemModelGroupId              = ihsProductMasterTable.ItemModelGroupId;

        ecoResReleasedProductCreationV2Entity.ProductGroupId                = ihsProductMasterTable.ItemGroupId;


        ecoResReleasedProductCreationV2Entity.InventoryUnitSymbol           = ihsProductMasterTable.UnitId;

        //ecoResReleasedProductCreationV2Entity.BOMUnitSymbol                 = ihsProductMasterTable.UnitI;

        ecoResReleasedProductCreationV2Entity.SalesUnitSymbol               = ihsProductMasterTable.UnitId;

        ecoResReleasedProductCreationV2Entity.PurchaseUnitSymbol            = ihsProductMasterTable.UnitId;


        ecoResReleasedProductCreationV2Entity.TrackingDimensionGroupName    = ihsProductMasterTable.TrackingDimensionGroup;

        ecoResReleasedProductCreationV2Entity.StorageDimensionGroupName     = ihsProductMasterTable.StorageDimensionGroup;

        ecoResReleasedProductCreationV2Entity.insert();

    }


    /// <summary>

    ///

    /// </summary>

    /// <param name = "_ecoResDistinctProductVariantRecId"></param>

    public void releaseProductVariant(RefRecId _ecoResDistinctProductVariantRecId)

    {

        EcoResDistinctProductVariant        ecoResDistinctProductVariant;

        EcoResProductReleaseManagerBase     releaseManager;


        if (!InventDimCombination::findByDistinctProductVariant(_ecoResDistinctProductVariantRecId))

        {

            ecoResDistinctProductVariant = EcoResDistinctProductVariant::find(_ecoResDistinctProductVariantRecId);

            //Now release the Product variant

            releaseManager = EcoResProductReleaseManagerBase::newFromProduct(ecoResDistinctProductVariant);

            releaseManager.release();

        }

    }


    public void assignTrackingDetails(IHSProductMasterTable ihsProductMasterTable, RefTableId _refTableId, RefRecId _refRecId)

    {

        ihsProductMasterTable.RefTableId        = _refTableId;

        ihsProductMasterTable.RefRecId          = _refRecId;

        ihsProductMasterTable.ItemProcessStatus = IHSItemProcessStatus::Processed;


    }


    /// <summary>

    ///

    /// </summary>

    /// <param name = "calledFrom"></param>

    /// <returns></returns>

    public boolean validate(Object calledFrom = null)

    {

        boolean                         ret;

        IHSProductMasterTable           ihsProductMasterTable, ihsProductMasterTableGroup;

        InventModelGroup                inventModelGroup;

        InventItemGroup                 inventItemGroup;

        EcoResProductDimensionGroup     ecoResProductDimensionGroup;

        EcoResStorageDimensionGroup     ecoResStorageDimensionGroup;

        EcoResTrackingDimensionGroup    ecoResTrackingDimensionGroup;

        UnitOfMeasure                   unitOfMeasure;

        

        ret = super(calledFrom);

        

        while select ihsProductMasterTableGroup

          index hint EntityIdx

            group by ihsProductMasterTableGroup.EntityId

               where ihsProductMasterTableGroup.ItemProcessStatus == IHSItemProcessStatus::Unprocessed

        {

            changecompany (ihsProductMasterTableGroup.EntityId)

            {

                //Item model group

                while select forupdate ItemModelGroupId 

                    from ihsProductMasterTable

                   where ihsProductMasterTable.EntityId == ihsProductMasterTableGroup.EntityId

                      && ihsProductMasterTable.ItemProcessStatus == IHSItemProcessStatus::Unprocessed

                notexists join inventModelGroup

                         where inventModelGroup.ModelGroupId == ihsProductMasterTable.ItemModelGroupId

                            && inventModelGroup.DataAreaId == ihsProductMasterTable.EntityId

                {

                    ttsbegin;

                    ihsProductMasterTable.ItemProcessStatus = IHSItemProcessStatus::Error;

                    ihsProductMasterTable.ErrorTxt = strFmt("The Item model group Id %1 does not exists", ihsProductMasterTable.ItemModelGroupId);

                    ihsProductMasterTable.update();

                    ttscommit;


                    ret = false;

                }


                //Item Group

                if (ret)

                {

                    while select forupdate ItemGroupId

                        from ihsProductMasterTable

                       where ihsProductMasterTable.EntityId == ihsProductMasterTableGroup.EntityId

                          && ihsProductMasterTable.ItemProcessStatus == IHSItemProcessStatus::Unprocessed

                    notexists join inventItemGroup

                             where inventItemGroup.ItemGroupId == ihsProductMasterTable.ItemGroupId

                                && inventItemGroup.DataAreaId == ihsProductMasterTable.EntityId

                    {

                        ttsbegin;

                        ihsProductMasterTable.ItemProcessStatus = IHSItemProcessStatus::Error;

                        ihsProductMasterTable.ErrorTxt         += strFmt("The Item group %1 does not exists", ihsProductMasterTable.ItemGroupId);

                        ihsProductMasterTable.update();

                        ttscommit;

                        ret = false;

                    }

                }


            }


            //ProductDimensionGroup

            if (ret)

            {

                while select forupdate ProductDimensionGroup

                    from ihsProductMasterTable

                   where ihsProductMasterTable.ProductDimensionGroup

                      && ihsProductMasterTable.ItemProcessStatus == IHSItemProcessStatus::Unprocessed

                 notexists join ecoResProductDimensionGroup

                          where ecoResProductDimensionGroup.Name == ihsProductMasterTable.ProductDimensionGroup

                {

                    ttsbegin;

                    ihsProductMasterTable.ItemProcessStatus = IHSItemProcessStatus::Error;

                    ihsProductMasterTable.ErrorTxt         += strFmt("The Product Dimension group %1 does not exists", ihsProductMasterTable.ProductDimensionGroup);

                    ihsProductMasterTable.update();

                    ttscommit;

                    ret = false;

                }

            }

            

            //StorageDimesionGroup

            if (ret)

            {

                while select forupdate StorageDimensionGroup

                    from ihsProductMasterTable

                   where ihsProductMasterTable.StorageDimensionGroup

                      && ihsProductMasterTable.ItemProcessStatus == IHSItemProcessStatus::Unprocessed

                notexists join ecoResStorageDimensionGroup

                         where ecoResStorageDimensionGroup.Name == ihsProductMasterTable.StorageDimensionGroup

                {

                    ttsbegin;

                    ihsProductMasterTable.ItemProcessStatus = IHSItemProcessStatus::Error;

                    ihsProductMasterTable.ErrorTxt += strFmt("The Storage Dimension group %1 does not exists", ihsProductMasterTable.StorageDimensionGroup);

                    ihsProductMasterTable.update();

                    ttscommit;

                    ret = false;

                }

            }


            //TrackingDimesionGroup

            if (ret)

            {

                while select forupdate TrackingDimensionGroup

                    from ihsProductMasterTable

                   where ihsProductMasterTable.TrackingDimensionGroup

                      && ihsProductMasterTable.ItemProcessStatus == IHSItemProcessStatus::Unprocessed

                notexists join ecoResTrackingDimensionGroup

                         where ecoResTrackingDimensionGroup.Name == ihsProductMasterTable.TrackingDimensionGroup

                {

                    ttsbegin;

                    ihsProductMasterTable.ItemProcessStatus = IHSItemProcessStatus::Error;

                    ihsProductMasterTable.ErrorTxt += strFmt("The Storage Dimension group %1 does not exists", ihsProductMasterTable.TrackingDimensionGroup);

                    ihsProductMasterTable.update();

                    ttscommit;

                    ret = false;

                }

            }


            //Unit

            if (ret)

            {

                while select forupdate UnitId

                    from ihsProductMasterTable

                   where ihsProductMasterTable.UnitId

                      && ihsProductMasterTable.ItemProcessStatus == IHSItemProcessStatus::Unprocessed

                    notexists join unitOfMeasure

                    where unitOfMeasure.Symbol == ihsProductMasterTable.UnitId

                {

                    ttsbegin;

                    ihsProductMasterTable.ItemProcessStatus = IHSItemProcessStatus::Error;

                    ihsProductMasterTable.ErrorTxt += strFmt("The Unit Id %1 does not exists", ihsProductMasterTable.UnitId);

                    ihsProductMasterTable.update();

                    ttscommit;

                    ret = false;

                }

            }

            

            //Product number and Item master mismatch

            if (ret)

            {

                while select forupdate ProductNumber, ItemNumber

                    from ihsProductMasterTable

                   where ihsProductMasterTable.ItemProcessStatus == IHSItemProcessStatus::Unprocessed

                      && ihsProductMasterTable.ProductNumber != ihsProductMasterTable.ItemNumber

                {

                    ttsbegin;

                    ihsProductMasterTable.ItemProcessStatus = IHSItemProcessStatus::Error;

                    ihsProductMasterTable.ErrorTxt += strFmt("Product number %1 and Item number %2 does not match", ihsProductMasterTable.UnitId);

                    ihsProductMasterTable.update();

                    ttscommit;

                    ret = false;

                }

            }

        }


        if (!ret)

        {

            warning("Validations are failed. Click on cancel and check error log for more details");

        }


        return ret;

    }


    /// <summary>

    ///

    /// </summary>

    /// 

    public static void main(Args _args)

    {

        IHSProductMasterInsertManager   ihsProductMasterInsertManager = IHSProductMasterInsertManager::construct();


        if (ihsProductMasterInsertManager.prompt())

        {

            ihsProductMasterInsertManager.run();

        }

    }


    public static IHSProductMasterInsertManager construct()

    {

        return new IHSProductMasterInsertManager();

    }


    /// <summary>

    ///

    /// </summary>

    /// <returns></returns>

    public ClassDescription caption()

    {

        ClassDescription ret;

    

        ret = super();


        ret = "Import Item master";

    

        return ret;

    }


}

Friday, 4 December 2020

Open the Journal lines form in D365FO with Jumpref

 Requirement: To open Journal lines form by clicking on view details of the filed on the form.


Development:

1. RegisterOverride the jump ref method on a form

[ExtensionOf(formStr(ProjInvoiceProposalDetail))]

final class ProjInvoiceProposalDetailFormBKA_Extension

{

    public void init()

    {

        next init();


        //ProjProposalCost_BKATrackingID is control name on form

        ProjProposalCost_BKATrackingID.registerOverrideMethod(

                methodStr(FormStringControl, jumpRef),

                methodStr(ProjInvoiceProposalDetailFormBKA_Extension, bkaTrackingIdJumpRef),

                this);

    }


    private void akaTrackingIdJumpRef(FormStringControl _formStringControl)

    {

        VendInvoiceJour::BKATrackingIDJumpRef(ProjProposalCost.BKATrackingId);

        _formStringControl.jumpRef();

    }

}


//I have centralized the jumpref's method on a table

//Opening the journal lines form is bit tricky, so below is the code will work

[ExtensionOf(tableStr(VendInvoiceJour))]

final class VendInvoiceJourBKA_Extension

{

 static void BKATrackingIDJumpRef(BKATrackingID _trackingId)

    {

        Args                        args, transArgs;

        FormRun                     formRun, transFormRun;

        JournalFormTable            journalForm;

        LedgerJournalTrans          ledgerJournalTrans;

        LedgerJournalTable          ledgerJournaltable;

        MenuFunction                menuFunction;

        ;

        


        changecompany (_trackingIdCompany)

        {

            //todo: change code for tracking Id

            select firstonly ledgerJournalTrans

               where ledgerJournalTrans.Voucher == _trackingId;


            ledgerJournaltable = LedgerJournalTable::find(ledgerJournaltrans.JournalNum);

        }


        //Open form

        args = new Args();

        args.name(formStr(LedgerJournalTable));

        args.record(ledgerJournaltable);


        formRun = classfactory.formRunClass(args);

        formRun.init();

        LedgerJournalFormTable journalFormTable = formRun.journalForm();

        journalFormTable.journalTableData(JournalTableData::newTable(ledgerJournalTable));


        transArgs = new Args();

        transArgs.caller(formRun);


        if (ledgerJournaltable.JournalType == LedgerJournalType::Daily)

        {

            transArgs.name(formStr(LedgerJournalTransDaily));

        }

        else if (ledgerJournaltable.JournalType == LedgerJournalType::VendInvoiceRegister)

        {

            transArgs.name(formStr(LedgerJournalTransVendInvoice));

        }

        transArgs.record(ledgerJournaltable);


        transFormRun  = classfactory.formRunClass(transArgs);

        transFormRun.init();

        transFormRun.run();

}

}

Monday, 5 October 2020

Debug a copy of the production database

Sometimes when working, you might need to connect to a managed environment (like UAT) to debug if it is throwing some errors when running your functional process, where the same data may  not be available in your development (Cloud hosted) environment. So, this post will help you to connect the cloud DB of managed environment from your cloud hosted environment.

 

Why we need to connect?

Suppose you are working on any managed services project or support project, based on SLA you might need to provide interim or solution ASAP, may be in few hours.

Now, refreshing the database for your development environment may take time, also there could be some approvals to refresh your development environment, which results in delay in providing the resolution if we like to use the same development environment. In that case we connect to database of the managed environment (UAT) and source code is from Cloud hosted (development) environment.

 

How to connect?

If we remember in AX2012 to connect to different instances, we connect to different configuration files. Here also the same, we create a new config file and we will configure and will connect it.

 

Where can we find config file?

Of course, every machine will have the default config file, where the file contains information of database and server. Check below path for web config file

K:\AosService\WebRoot

 


 

Procedure:

1.      Add your IP to safe list:

By default, all Sandbox Standard Acceptance Test environments use Microsoft Azure SQL Database as their database platform. The databases for these environments are protected by firewalls that restrict access to the Application Object Server (AOS) with which it was originally deployed.

A.     You need to add your IP to the enable list to log into Prod copy and open SSMS and write SQL script to add to safe list

Maintain > Enable access




B.     After logged into the prod copy environment open SSMS,

Get the server name, database name, user and password details from LCS project under Database accounts.






Login,

Server: ‘ServerName’.database.windows.net

Username: axdbadmin

Password: ‘password of axdbadmin from LCS’



Connection Properties,

Connect to database: ‘Database name from LCS’



After connecting to database from above procedure, write the below SQL script

 

EXECUTE sp_set_database_firewall_rule N'Debugging rule for DevTest environment', 'a.b.c.d', 'a.b.c.d';

 

Note: a.b.c.d is the IP address of your dev environment. Actually, it is the range else you can provide single IP.


C.     After executing the above command, log into Dev environment and open SSMS, check whether you have access to database 

 

Login,

Server: ‘ServerName’.database.windows.net

Username: axdbadmin

Password: ‘password of axdbadmin from LCS’


Connection Properties,

                  Connect to database: ‘Database name from LCS’




D.     Now, you are able to connect to UAT database in SSMS of DEV. In order to connect the D365FO application to UAT database, we need to create or modify the config file in Webroot.

 

Duplicate web config file and name it to web_UAT



Now open the web_UAT file in notepad and update the following

Database, DbServer, SqlPwd, SQLUser


E.     Now the config file is ready, in order to connect to UAT DB stop WWW (world wide web) service and rename the web file to web_Orig and web_UAT to web, start the WWW service. Now your F&O application connected to UAT database.




F.     In order to debug the UAT data, attach the process in debug in VS.

 

G.     To connect back to dev database, stop WWW service and change the web config file to web_UAT and web_Orig to web. Start the WWW service.


Reference:  https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/database/dbmovement-scenario-debugdiag

Friday, 18 September 2020

 Hyperlink on Field for SSRS report in D365FO

My requirement is to open a report on sales order or a transfer order depends on the caller.

After running the report it should open the sales order based on SalesId


Change the below properties
1. Color
2. Textbox properties > Action >Go to URl > select URL
    Write the below code in expression
    =Microsoft.Dynamics.Framework.Reports.BuiltInMethods.GenerateDrillThroughLink(Parameters!AX_ReportContext.Value, Parameters!AX_UserContext.Value, "SalesTable", "Display", "SalesTable", "SalesId", First(Fields!AGCReference.Value, "PalletLabelsPrintTmp"))


Format:
3
=Microsoft.Dynamics.Framework.Reports.BuiltInMethods.GenerateDrillThroughLink(
    Parameters!AX_ReportContext.Value, Parameters!AX_UserContext.Value,
    "[MenuItemName]", "[MenuItemType]", "[TableName]", "[FieldName"], "Field value")


Monday, 4 May 2020

Some useful lnfo of D365FO (How to open table browser, Models, Descriptor file)


1. To open the following in browser:
Table Browser
https://-----------.cloudax.dynamics.com/?mi=SysTableBrowser&prt=initial&limitednav=true&TableName=VendReceiptsListJour&cmp=USMF

Action MenuItem
https://---------.cloudax.dynamics.com/?cmp=WLF&mi=action:WHSWorkExecute&limitednav=true

Runnable class
https://--------.cloudax.dynamics.com/?cmp=USMF&mi=SysClassRunner&cls=classname



2. Powershell cmds to Import/Export/delete model in D365FO:
Export
cd K:\AosService\PackagesLocalDirectory\Bin

.\ModelUtil.exe -export -metadatastorepath=K:\AosService\PackagesLocalDirectory -modelname="CustomWithReport" -outputpath=C:\Temp

Import
cd K:\AosService\PackagesLocalDirectory\Bin

.\ModelUtil.exe -import -metadatastorepath=K:\AOSService\PackagesLocalDirectory -file=J:\CustomWithReport.axmodel

Delete
.\ModelUtil.exe -delete -metadatastorepath=K:\AOSService\PackagesLocalDirectory -modelname="CustomWithReport"

else you can delete the model directly by deleting the folder from K:\AosService\PackagesLocalDirectory. Before that stop World wide web service(It will stop AOS), Microsoft Batch service.
After delete restart service, refresh model in visual studio Dynamics 365-> update models-> refresh models and synchronize.

3. To add the model descriptor file to TFS
  1. In Visual Studio, in Team Explorer, open Source Control Explorer, and then right-click on the metadata folder (for example, \Trunk\Main\Metadata).
  2. In the Source Control Explorer toolbar, click Add Item to Folder.
  3. Select your model descriptor file. The model descriptor file is the XML file manifest of your model. It's located in the Descriptor folder of the package that the model belongs to.(K:\AosService\PackagesLocalDirectory\ModelName\Descriptor).

Monday, 20 April 2020

Flight features in D365FO

Flights are used to disable new features which will change the user experience. With this concept we are able to explicitly enable new features and not by default.

Scenario:

With the PU 34 update, MS introduced fights to Journal printing. So the new code is called as flight is disabled by default.

As the flight is not enabled, it will go to else part in the code shown in pic.

To enable flight to it, write the below script:

SQL:

INSERT INTO SYSFLIGHTING (FLIGHTNAME, ENABLED, FLIGHTSERVICEID) VALUES ('LedgerJournal_UseOldLegerJournalDPReport', 1, 12719367)

or

X++ :

if (!SysTestFlightingManager::isFlightEnabled("LedgerJournal_UseOldLegerJournalDPReport"))
        {
            SysTestFlightingManager::setFlightEnabled("LedgerJournal_UseOldLegerJournalDPReport", DefaultNoYes::Yes);
            Info("Flight enabled");
        }


Reference: