Tuesday, February 20, 2018

Dimension Development in DAX 365 FO


Dimension Development in DAX 365 FO

Types:

1.     Financial Dimension
2.     Ledger Dimension (Segmented entry Control)
3.     Ledger Dimension Account lookup Based on Account Type selection in Table
4.     Inventory Dimension display
a.      In New From, using new table
b.      In Standard form using new table (Extension)

Steps:
1.     Financial Dimension
a.       In Table
                                                              i.      Add new field in table as “DefaultDimension”
                                                            ii.      Add new relation with relation table “DimensionAttributeValueSet”
Table.DefaultDimension == DimensionAttributeValueSet.RecId
b.      In Form
                                                              i.      Add new Tab in Form Design
                                                            ii.      Set Auto declaration property to yes for Tab control
1.      Add New control Dimension Entry Control
2.      Set Following properties
a.       DS
b.      Label (Caption Text)
c.        view field
2.     Ledger Dimension (Segmented entry Control)
a.       In Table
                                                              i.      Added new field in table
1.      LedgerDimension (EDT: DimensionDynamicAccount)
2.      AccountType (EDT: LedgerJournalACType) (For Dummy and set field Properties visible, AllowEdit to No)
Note: Add With relation to DimensionAttributeValueCombination table as   Table.LedgerDimension == DimensionAttributeValueCombination.RecId
b.      In Form
                                                              i.      Add newly created field in form design node(Form Grid Control)
1.      Auto declaration = Yes
2.      Controller class = DimensionDynamicAccountController
3.      Filter expression = %1
4.      Is Default Account = False (lookup Show Segmented Entry with dimension combination as per account structure setup)
3.     Ledger Dimension Account lookup Based on Account Type selection in Table
a.       In Table
                                                              i.      Added new fields in table
                                                            ii.      AccountType (EDT: LedgerJournalACType)
                                                          iii.      LedgerDimension (EDT: DimensionDynamicAccount)
Note: Add With relation to DimensionAttributeValueCombination table as   Table.LedgerDimension == DimensionAttributeValueCombination.RecId
b.      In Form
                                                              i.      Add newly created field in form design node(Form Grid Control)
1.       Auto declaration = Yes
2.      Controller class = DimensionDynamicAccountController
3.      Account Type field = AccountType
4.      Filter expression = %1
5.      Is Default Account = True (Lookup show only Main Accounts list).
6.      Add Override method on Form Data source Field
a.       Method: Modified (Code Snippet)
                                                                                                                                      i.       Table_ds.refresh();
       7.   Add Override method on Form Design node Field
Method: Lookup (Code Snippet)

switch (Table.AccountType)
            {
                case LedgerJournalACType::Bank:
                    BankAccountTable::lookupBankAccount(this); break;
                case LedgerJournalACType::Cust:
                    CustTable::lookupCustomer(this); break;
                case LedgerJournalACType::FixedAssets:
                    AssetTable::lookupAccountNum(this); break;
                case LedgerJournalACType::Project:
                    ProjTable::lookupProjId(this, Table); break;
               case LedgerJournalACType::Vend:
                    VendTable::lookupVendor(this); break;
                default:
                    super(); break;
            }

Method: checkUserCustomLookup (Code Snippet)

boolean returnValue;          
LedgerJournalACType
accountType = any2Enum(_accountTypeEnumValue);
                                                                                switch (accountType)           
{
case
LedgerJournalACType::Bank || LedgerJournalACType::Cust || LedgerJournalACType::FixedAssets || LedgerJournalACType::Project || LedgerJournalACType::Vend:
                                                                                                                                returnValue = true; break;
                                                                                                default:               returnValue = false; break;
                                                                                }          
                                                                                return returnValue;

4.     Inventory Dimension display
a.      Display inventory dimensions dynamically in D365
                                                              i.      For New Table and New Form
1.      Create new fields in table using (InventDimId) and create relation with InventDim
2.      Add InventDim datasource in form and join (Inner Join) it with datasource which contains your item id (new Table)
3.      Create a new group under your gird. Set its datasource property to InventDim and Data group property to InventoryDimesions
4.      Add InventDimParmFixed Display menu item to your Tab->action pane menu.
5.      Write code  on form Methods
Code:

Method à Class Declaration:
//Declare variables in form class declaration
InventDimCtrl_Frm_EditDimensions        inventDimFormSetup;

Method à inventDimSetupObject (New)
public InventDimCtrl_Frm_EditDimensions inventDimSetupObject()
{
    return inventDimFormSetup;
}

Method à init (New)
public void init()
{
    super();
    // This method will be used to show default fields at form startup
    element.updateDesign(InventDimFormDesignUpdate::Init);
}

Method à updateDesign (New)
void updateDesign(InventDimFormDesignUpdate mode)
{
    InventDimParm inventDimParmVisible;

    switch (mode)
    {
        // Form Init
        case InventDimFormDesignUpdate::Init    :
            if (!inventDimFormSetup)
                inventDimFormSetup  = InventDimCtrl_Frm_EditDimensions::newFromForm(element);
                inventDimFormSetup.parmSkipOnHandLookUp( true);

                // Use the methods on InventDimParm
                // to set which dimensions to show when form is initialized
                inventdimparmvisible.inventsiteidflag       = true;
                inventDimFormSetup.parmDimParmVisibleGrid(inventDimParmVisible);

        // Datasource Active
        case InventDimFormDesignUpdate::Active  :
            inventDimFormSetup.formActiveSetup(InventDimGroupSetup::newItemId(<TableName>.ItemId));            
inventDimFormSetup.formSetControls( true);
            break;

        // Datasource Field change
        case InventDimFormDesignUpdate::FieldChange :
            inventDimFormSetup.formActiveSetup(InventDimGroupSetup::newItemId(<TableName>.ItemId));
            InventDim.clearNotSelectedDim(inventDimFormSetup.parmDimParmEnabled()); // InventDim is referring to datasource name
            inventDimFormSetup.formSetControls( true);
            break;

        default :
            throw error(strFmt ("@SYS54195", funcName()));
    }
}

Method à Data source Method à active (New) - (Note: which is having itemId)
public int active()
{
    int ret;
    ret = super();
    element.updateDesign(InventDimFormDesignUpdate::Active);
    return ret;
}

Method à Data source Method à Fieldà ItemId à Modified (new)
public void modified()
{
    super();    
    element.updateDesign(InventDimFormDesignUpdate::FieldChange);
    InventDim.clearNotSelectedDim(element.inventDimSetupObject().parmDimParmEnabled());
}

Open New created FORM and check the option

                                                            ii.      For New Table on Standard Form (Extension)
1.      Create new table and field with using (InventDimId & ItemId) and create relation with InventDim
2.      Add InventDim and new table datasource in standard form and join (Inner Join) it with datasource which contains your item id & inventDimid  (new Table)
3.      Create a new group under your gird. Set its datasource property to InventDim and Data group property to InventoryDimesions
4.      Add InventDimParmFixed Display menu item to your Tab->action pane menu.
5.      Add new and delete line command tab on Tab page
6.      Write code  on form Methods
Code:
·         Create new extension class for standard FORM
Code:
                                                            Public  InventDimCtrl_Frm_EditDimensions           inventDimFormSetup;

    public Object inventDimSetupObject()
    {
        return inventDimFormSetup;
    }

    public void init()
    {
        FormRun             formRun                 = this as FormRun;
        next  init();
        formRun.updateDesign(InventDimFormDesignUpdate::Init);
    }

    public void updateDesign(InventDimFormDesignUpdate mode)
    {
        InventDimParm inventDimParmVisible;
        FormRun             formRun                 = this as FormRun;
        FormDataSource      formDataSourceParent    = formRun.dataSource(tableStr(<TableName>));
        <TableName>         <TableName>             = formDataSourceParent.cursor();

        switch (mode)
        {
            // Form Init
            case InventDimFormDesignUpdate::Init    :
                if (!inventDimFormSetup)
                    inventDimFormSetup  = InventDimCtrl_Frm_EditDimensions::newFromForm(formRun);
                    inventDimFormSetup.parmSkipOnHandLookUp( true);
                    inventdimparmvisible.InventColorIdFlag = true;
                    inventdimparmvisible.inventsiteidflag       = true;
                    inventdimparmvisible.InventLocationIdFlag       = true;
                    inventDimFormSetup.parmDimParmVisibleGrid(inventDimParmVisible);
                    break;

            // Datasource Active
            case InventDimFormDesignUpdate::Active  :
                inventDimFormSetup.formActiveSetup(InventDimGroupSetup::newItemId(<TableName>.ItemId));
                inventDimFormSetup.formSetControls( true);
                inventoryDimensionsGrid.allowEdit(true);

            // Datasource Field change
            case InventDimFormDesignUpdate::FieldChange :
                inventDimFormSetup.formActiveSetup(InventDimGroupSetup::newItemId(<TableName>.ItemId));
                InventDim.clearNotSelectedDim(inventDimFormSetup.parmDimParmEnabled());
                inventDimFormSetup.formSetControls( true);
                inventoryDimensionsGrid.allowEdit(true);
                break;

            default :
                throw error(strFmt ("@SYS54195", funcName()));

        }
    }

    /// <summary>
    /// Modifies inventory dimension field.
    /// </summary>
    public void modifyInventDimField(FieldId _fieldId)
    {
        FormRun             formRun                 = this as FormRun;
        FormDataSource      formDataSourceParent    = formRun.dataSource(tableStr(<TableName>));
        <TableName>         <TableName>             = formDataSourceParent.cursor();
        FormDataSource      formDataSourceChild     = formRun.dataSource(tableStr(InventDim));
        InventDim           inventDim               = formDataSourceChild.cursor();

        if (<TableName>.modifyInventDim(inventDim, _fieldId))
        {
            inventDim.data(<TableName>.inventDim());
        }
    }

·         Create new extension class for Standard Form, Chlid DataSource (InventDim) using FORM COC
Code:
void initValue()
    {
        FormDataSource      formDataSourceParent    = this;
        FormRun             formRun                 = formDataSourceParent.formRun() as FormRun;
        FormDataSource      formDataSource          = formRun.dataSource(tableStr(<TableName>));
        <TableName>         <TableName>             = formDataSource.cursor();
        InventDim           inventDim               = formDataSourceParent.cursor();

        InventDim.data(InventDim::find(<TableName>.InventDimId));

        formDataSourceParent.setCurrent();

        next initValue();
    }

    [FormDataFieldEventHandler(formDataFieldStr(<FormName>, InventDim, configId), FormDataFieldEventType::Modified)]
    public static void configId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormRun     formRun = sender.datasource().formRun() as FormRun;
        formRun.modifyInventDimField(fieldNum(InventDim, ConfigId));
    }

    [FormDataFieldEventHandler(formDataFieldStr(<FormName>, InventDim, inventBatchId), FormDataFieldEventType::Modified)]
    public static void inventBatchId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormRun     formRun = sender.datasource().formRun() as FormRun;
        formRun.modifyInventDimField(fieldNum(InventDim, inventBatchId));
    }

    [FormDataFieldEventHandler(formDataFieldStr(<FormName>, InventDim, InventColorId), FormDataFieldEventType::Modified)]
    public static void InventColorId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    { 
        FormRun     formRun = sender.datasource().formRun() as FormRun;
        formRun.modifyInventDimField(fieldNum(InventDim, InventColorId));
    }
    [FormDataFieldEventHandler(formDataFieldStr(<FormName>, InventDim, InventLocationId), FormDataFieldEventType::Modified)]
    public static void InventLocationId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormRun     formRun = sender.datasource().formRun() as FormRun;
        formRun.modifyInventDimField(fieldNum(InventDim, InventLocationId));
    }

    [FormDataFieldEventHandler(formDataFieldStr(<FormName>, InventDim, inventSerialId), FormDataFieldEventType::Modified)]
    public static void inventSerialId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormRun     formRun = sender.datasource().formRun() as FormRun;
        formRun.modifyInventDimField(fieldNum(InventDim, inventSerialId));
    }

    [FormDataFieldEventHandler(formDataFieldStr(<FormName>, InventDim, InventSiteId), FormDataFieldEventType::Modified)]
    public static void InventSiteId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormRun     formRun = sender.datasource().formRun() as FormRun;
        formRun.modifyInventDimField(fieldNum(InventDim, InventSiteId));
    }

    [FormDataFieldEventHandler(formDataFieldStr(<FormName>, InventDim, InventSizeId), FormDataFieldEventType::Modified)]
    public static void InventSizeId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormRun     formRun = sender.datasource().formRun() as FormRun;
        formRun.modifyInventDimField(fieldNum(InventDim, InventSizeId));
    }

    [FormDataFieldEventHandler(formDataFieldStr(<FormName>, InventDim, InventStatusId), FormDataFieldEventType::Modified)]
    public static void InventStatusId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormRun     formRun = sender.datasource().formRun() as FormRun;
        formRun.modifyInventDimField(fieldNum(InventDim, InventStatusId));
    }

    [FormDataFieldEventHandler(formDataFieldStr(<FormName>, InventDim, InventStyleId), FormDataFieldEventType::Modified)]
    public static void InventStyleId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormRun     formRun = sender.datasource().formRun() as FormRun;
        formRun.modifyInventDimField(fieldNum(InventDim, InventStyleId));
    }
    [FormDataFieldEventHandler(formDataFieldStr(<FormName>, InventDim, wMSLocationId), FormDataFieldEventType::Modified)]
    public static void wMSLocationId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormRun     formRun = sender.datasource().formRun() as FormRun;
        formRun.modifyInventDimField(fieldNum(InventDim, wMSLocationId));
    }

    [FormDataFieldEventHandler(formDataFieldStr(<FormName>, InventDim, wMSPalletId), FormDataFieldEventType::Modified)]
    public static void wMSPalletId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormRun     formRun = sender.datasource().formRun() as FormRun;
        formRun.modifyInventDimField(fieldNum(InventDim, wMSPalletId));
    }

·         Create new extension class for Standard FORM Parent Datasource and write below code methods using Form COC (new table)
Code:
    void initValue()
    {       
        FormDataSource      formDataSource          = this;
        FormRun             formRun                 = formDataSource.formRun() as FormRun;
        FormDataSource      formDataSourceParent    = formRun.dataSource(tableStr(MCRHoldCodeTable));
        <TableName>         <TableName>             = formDataSource.cursor();
        <Parent Form Table>    <ParentTable>        = formDataSourceParent.cursor();

        next initValue();
        <TableName>.<Unique Field> = <ParentTable>.<Unique Field>;
    }

    int  active()
    {
        int                                 ret;

        ret = next  active();
        FormDataSource      formDataSource          = this;
        FormRun             formRun                 = formDataSource.formRun() as FormRun;

        formRun.UpdateDesign(InventDimFormDesignUpdate::Active);

        return ret;
    }

    public void init()
    {
        next init();
    }

    /// <summary>
    /// Updates <c>InventDim</c> with new data which has been set due to modification of <c>form name</c>.
    /// </summary>
    public void initInventDim()
    {
        FormDataSource      formDataSource          = this;
        FormRun             formRun                 = formDataSource.formRun() as FormRun;
        <TableName>         <TableName>             = formDataSource.cursor();
        FormDataSource      formDataSourceParent    = formRun.dataSource(tableStr(InventDim));
        InventDim           inventDim               = formDataSourceParent.cursor();

        InventDim.data(InventDim::find(<TableName>.InventDimId));

        formDataSourceParent.setCurrent();
    }

    void  write()
    {
        FormDataSource      formDataSource          = this;
        FormRun             formRun                 = formDataSource.formRun() as FormRun;
        <TableName>         <TableName>             = formDataSource.cursor();
        FormDataSource      formDataSourceParent    = formRun.dataSource(tableStr(InventDim));
        InventDim           inventDim               = formDataSourceParent.cursor();

        next write();

        <TableName>.InventDimId = InventDim::findOrCreate(inventDim).InventDimId;

        if (<TableName>.InventDimId != inventDim.InventDimId)
        {
            inventDim.data(InventDim::find(<TableName>.InventDimId));
            formDataSourceParent.setCurrent();
        }

        formDataSource.reread();
        formDataSource.reread();
    }

            FormDataFieldEventHandler(formDataFieldStr(<FormName>, <TableName>, ItemId), FormDataFieldEventType::Modified)]
    public static void ItemId_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        FormRun     formRun = sender.datasource().formRun() as FormRun;

        FormDataSource      formDataSourceChild     = formRun.dataSource(tableStr(InventDim));
        InventDim           inventDim               = formDataSourceChild.cursor();

        formRun.updateDesign(InventDimFormDesignUpdate::FieldChange);
        inventDim.clearNotSelectedDim(formRun.inventDimSetupObject().parmDimParmEnabled());
    }




Upload data from Excel in D365FO X++

 Action Menu Item: SAN_UploadExcelData Object type: Class Object: <Controller class name> Label: <> Class: Controller class clas...