Monday, September 12, 2016

New Customize Scripts Method for AX Develper in ax 2012

//New Customize Sys Develper Method in ax 2012

//Adding new method in Scripts method in ax Development window
Image :

//Class-> xppsource
 New method -> Find (Ex)

public Source findMethod(TableName _tableName)
{
    str method;
    DictTable dictTable;
    DictIndex dictIndex;
    DictField dictField;
    FieldName fieldName;
    DictType dictType;
    DictEnum dictEnum;
    int fieldCount;
    int i;
    container fields1;
    container fields2;
    container fields3;
    IdentifierName varName;
    IdentifierName varType;
    ;
    method = 'public static %1 find' + '(%2, boolean _forUpdate = false)%5' + '{%5' + ' %1 table;%5' +  '%5' + ' if (%3)%5' +
            ' {%5' +' if (_forUpdate)%5' + ' table.selectForUpdate(_forUpdate);%5' + '%5' + ' select firstOnly table%5' + ' where %4;%5' +
            ' }%5' + ' return table;%5' + '}';
    dictTable = new DictTable(tableName2id(_tableName));
    dictIndex = dictTable.indexObject(
    dictTable.replacementKey() ?
    dictTable.replacementKey() :
    dictTable.primaryIndex());
    if (dictIndex)
    {
        fieldCount = dictIndex.numberOfFields();
        for (i = 1; i <= fieldCount; i++)
        {
            dictField = new dictField(
            dictTable.id(),
            dictIndex.field(i));
            fieldName = dictField.name();
            varName = '_' + strLwr(subStr(fieldName,1,1)) +
            subStr(fieldName,2,strLen(fieldName)-1);
            if (dictField.typeId())
            {
                dictType = new DictType(dictField.typeId());
                varType = dictType.name();
            }
            else if (dictField.enumId())
            {
                dictEnum = new DictEnum(dictField.enumId());
                varType = dictEnum.name();
            }
            else
            {
                throw error(strfmt("Field '%1' type is not defined",fieldName));
            }
            fields1 += strFmt('%1 %2',varType,varName);
            fields2 += varName;
            fields3 += strFmt('table.%1 == %2',fieldName,varName);
        }
    }
    source = strFmt(method,_tableName,con2Str(fields1,', '),con2Str(fields2, ' && '),con2Str(fields3, #newLine + strRep(' ', 14) + '&& '),#newLine);
    return source;
}


// Class->EditorScrpts
public void template_method_find(Editor _editor)
{
    TreeNode objNode;
    xppSource xpp;
    Source template;
    objNode = EditorScripts::getApplObjectNode(_editor);
    if (!objNode)
    {
        return;
    }
    _editor.gotoLine(1);
    _editor.firstLine();
    while (_editor.moreLines())
    {
        _editor.deleteLines(1);
        _editor.nextLine();
    }
    xpp = new xppSource();
    template = xpp.findMethod(objNode.AOTname());
    _editor.insertLines(template);
}

//Class->EditorScripts->Method(isApplicableMethod)
case methodStr(EditorScripts, template_method_find):
            return (_aotNode && _aotNode.treeNodeType().id() == #NT_DBTABLE);


//Final Output in Ax development Workspace

Image:


Enjoy...

To add New Tool menu in ax 2012

// To add New Tool menu in ax 2012

Ax->Menu Bar-Tools (to Add new menu)

// AOT/menu/DevelomentTools/(Add new menu)

AX Retail Data Export to excel without excel addins

//AX Retail Data Export to excel without excel addins

using (SaveFileDialog sfdExport = new SaveFileDialog())
{
    sfdExport.Filter = "Excel (2003)(.xls)|*.xls";
    if (sfdExport.ShowDialog() != DialogResult.Cancel)
    {
        try
        {
            DataTable dtExport = new DataTable();
            //You can get your data and fill it here

            using (DevExpress.XtraGrid.GridControl grExport = new DevExpress.XtraGrid.GridControl())
            {
                using (DevExpress.XtraGrid.Views.Grid.GridView gvExport = new DevExpress.XtraGrid.Views.Grid.GridView())
                {
                    gvExport.OptionsBehavior.AutoPopulateColumns = true;
                    gvExport.GridControl = grExport;

                    grExport.BindingContext = new BindingContext();
                    grExport.DataSource = dtExport;
                    grExport.MainView = gvExport;
                    grExport.ForceInitialize();

                    gvExport.PopulateColumns();
                    gvExport.ExportToXls(strExportFilePath);
                }
            }
        }
        catch (Exception ex)
        {
            LSRetailPosis.ApplicationExceptionHandler.HandleException(this.ToString(), ex);
            throw;
        }
    }
}

Restricting Default cheque print

//Restricting Default cheque print

Class--> VendOutPaym->Close

//this.printDocument();

Enable remote errors in SQL(Query)

//Enable remote errors in SQL

//Report DB -

dbo.ConfigurationInfo

Deploy POS Report AX

// Deploy POS Report AX

Retail > Periodic > Data distribution > Distribution schedule.
Select job, click Run

Changing Customer Accoount Posted customer Transaction in GL ax 2012

// Changing Posted customer Transaction in GL ax 2012

Updating Posted customer transaction Payments with different customer Account .

Note:
1) Both Customers  should lie on same customer Posting profile account then only below logic will work.
2) If there is settlement update settlement Table also(CustSettlement)
3) Applicable only when customer transaction created and posted in Gl and AR Payment Journal. Not for customer invoice.

    LedgerJournalTrans          jourTrans;
    CustTrans           custTrans;
    LedgerDimensionAccount  ledgerDim;
    ;
    ledgerDim = DimensionStorage::getDynamicAccount("CustomerAccount", LedgerJournalACType::Cust);
   
    update_recordSet jourTrans setting LedgerDimension = ledgerDim
        where jourTrans.Voucher == "VoucherNum";
    update_recordSet custTrans setting AccountNum = "CustomerAccount",OrderAccount = "CustomerAccount"
        where custTrans.Voucher == "VocuherNum";

Aging bucket through ssrs ax 2012

//Aging bucket through ssrs ax 2012

1-30 days

=Sum(iif((Fields!TransDate.Value <= Parameters!ToDate.Value)
and (Fields!TransDate.Value >= DateAdd("d",-30,Parameters!ToDate.Value))
,Fields!Debit.Value,0))
+
Sum(iif((Fields!TransDate.Value <= Parameters!ToDate.Value)
and (Fields!TransDate.Value >= DateAdd("d",-30,Parameters!ToDate.Value))
,Fields!Credit.Value,0))

30-60 days

=Sum(iif((Fields!TransDate.Value <= DateAdd("d",-31,Parameters!ToDate.Value))
and (Fields!TransDate.Value >= DateAdd("d",-30,DateAdd("d",-30,Parameters!ToDate.Value)))
and instr(Fields!Txt.Value, "Sales"),Fields!Debit.Value,0))
+
Sum(iif((Fields!TransDate.Value <= DateAdd("d",-31,Parameters!ToDate.Value))
and (Fields!TransDate.Value >= DateAdd("d",-30,DateAdd("d",-30,Parameters!ToDate.Value))
and instr(Fields!Txt.Value, "Sales")),Fields!Credit.Value,0))


so on

Sales Order Total Discount ax 2012

//Sales Order Total Discount ax 2012
//Scenario -1 - spliting in line level
switch (_fieldId)
    {
        case fieldNum(SalesTable, TotalSalesDiscount):
            if(this.TotalSalesDiscount > 0)
            {
                this.write();
                sumSalesLine.clear();
                Select sum(SalesPrice),sum(SalesQty),sum(LineAmount) from sumSalesLine
                        where sumSalesLine.SalesId == this.SalesId;
                ttsBegin;
                salesline.clear();
                while select forUpdate salesline
                    where salesline.SalesId == this.SalesId
                        && salesline.SalesStatus == SalesStatus::Backorder
                {
                    salesline.FccSalesPrice = decRound((this.TotalSalesDiscount) * ((((salesline.LineAmount)/sumSalesLine.LineAmount)*100)/100),3);
                    salesline.update();
                }
                ttsCommit;
                sumSalesLine.clear();
                Select sum(SalesPrice),sum(SalesQty),sum(FccSalesPrice),sum(LineAmount) from sumSalesLine
                        where sumSalesLine.SalesId == this.SalesId;
                saleeslinerecid.clear();
                select RecId from saleeslinerecid order by RecId Desc;
                ttsBegin;
                salesline.clear();
                while select forUpdate salesline
                    where salesline.SalesId == this.SalesId
                        && salesline.SalesStatus == SalesStatus::Backorder
                {
                    if(sumSalesLine.FccSalesPrice != this.TotalSalesDiscount)
                    {
                        if(saleeslinerecid.RecId == salesline.recid)
                        {
                            salesline.FccSalesPrice = salesline.FccSalesPrice +(this.TotalSalesDiscount - sumSalesLine.FccSalesPrice);
                        }
                        else
                        {
                            salesline.FccSalesPrice = salesline.FccSalesPrice;
                        }
                    }
                    salesline.LinePercent = 0;
                    salesline.LineDisc = salesline.FccSalesPrice/salesline.SalesQty;
                    salesline.modifiedField(fieldNum(SalesLine,LineDisc));
                    salesline.update();
                }
                ttsCommit;
                this.dataSource().reread();
            }
            else
            {
                this.write();
                ttsBegin;
                while select forUpdate salesline
                    where salesline.SalesId == this.SalesId
                            && salesline.SalesStatus == SalesStatus::Backorder
                {
                    salesline.LinePercent = 0;
                    salesline.LineDisc = 0;
                    salesline.FccSalesPrice = 0;
                    salesline.modifiedField(fieldNum(SalesLine,LineDisc));
                    salesline.update();
                }
                ttsCommit;
                this.dataSource().reread();
            }
            break;
    }
//Scenario -2
Populating total discout Amount by finding discount percent - Default Total disc percent field to affect header discount
//Scenario -3
switch (_fieldId)
    {
        case fieldNum(SalesTable, TotalSalesDiscount):
                if(this.TotalSalesDiscount > 0)
                {
                    Select sum(LineAmount) from sumSalesLine
                            where sumSalesLine.SalesId == this.SalesId;
                    ttsBegin;
                    while select forUpdate salesline
                        where salesline.SalesId == this.SalesId
                    {
                        salesline.LineDisc = (this.TotalSalesDiscount) * ((((salesline.LineAmount)/sumSalesLine.LineAmount)*100)/100);
                        salesline.LineAmount = (salesline.SalesQty * salesline.SalesPrice) - salesline.LineDisc;
                        salesline.update();
                    }
                    ttsCommit;
                    this.dataSource().research(true);
                }
            break;
    }

Clean up Ax Build Log file ax 2012

//Clean up Ax Build Log file ax 2012

ax32.exe -startupCmd=importandcompileaxbuildlog_C:\Program Files\MicrosoftDynamicsAX\60\Server\FCCTEST\Log\AxCompileAll.html

Function to create default dimnesion ax 2012

//Function for default dimnesion ax 2012
    DimensionDefault DefaultDimensionCreate(Description _BU,Description _CC,Description _Department)
    {
        DimensionAttributeValueSetStorage valueSetStorage = new DimensionAttributeValueSetStorage();
        DimensionDefault result;
        int i;
        DimensionAttribute dimensionAttribute;
        DimensionAttributeValue dimensionAttributeValue; //DimensionAttributeValueCombination
        container conAttr = ["BusinessUnit","CostCenter","Department"]; //101,106,1
        container conValue;
        str dimValue;
        conValue = [_BU,_CC,_Department];
        dimValue = "";
        i = 0;
        for (i = 1; i <= conLen(conAttr); i++)
        {
            dimensionAttribute = dimensionAttribute::findByName(conPeek(conAttr,i));
            if (dimensionAttribute.RecId == 0)
            {
                continue;
                //control will not go down
            }
            dimValue = conPeek(conValue,i);
            if (dimValue != "")
            {
                dimensionAttributeValue =
                dimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,dimValue,false,true);
                valueSetStorage.addItem(dimensionAttributeValue);
            }
        }
        result = valueSetStorage.save();

        return result;
    }

Sync Issue after upgrade Model store ax 2012 R3 TFS BUILD Process

// Sync Issue after upgrade Model store ax 2012 R3 TFS BUILD Process

Source :
http://dev.goshoom.net/en/2011/11/id-change/
https://community.dynamics.com/ax/f/33/p/209562/550639#550639

static void SyncIssue(Args _args)
{
    Dictionary dictionary = new Dictionary();
    SysDictTable dictTable;
    DictField dictField;
    TableId tableId;
    FieldId fieldId;
    Counter fieldCnt;
    SqlDictionary sqlDictionaryTable;
    SqlDictionary sqlDictionaryField;
    setPrefix("Update of data dictionary IDs");
    tableId = dictionary.tableNext(0);
    ttsbegin;
    while (tableId)
    {
        dictTable = new SysDictTable(tableId);
        setPrefix(dictTable.name());
        if ( dictTable.isSystemTable()
        ||   dictTable.isView()
        ||   dicttable.isTempDb()
        ||   dictTable.isTmp()
           )
        {
            tableId = dictionary.tableNext(tableId);
            continue;
        }
        ///////////
        //Finds table in SqlDictionary by name in AOT, if ID was changed.
        //Empty field ID represents a table.
        select sqlDictionaryTable
            where sqlDictionaryTable.name == dictTable.name()
            && sqlDictionaryTable.fieldId == 0
            && sqlDictionaryTable.tabId != dictTable.id();
        if (sqlDictionaryTable)
        {
            //Updates table ID in SqlDictionary
            if (ReleaseUpdateDB::changeTableId(
                sqlDictionaryTable.tabId,
                dictTable.id(),
                dictTable.name()))
            {
                info(strFmt("Table ID changed (%1 -> %2)", sqlDictionaryTable.tabId, dictTable.id()));
            }
        }
        ////////////
        // Delete Fields that no more exists in AOT
        while select forUpdate sqlDictionaryTable
            where sqlDictionaryTable.tabId == dictTable.id()
            &&    sqlDictionaryTable.fieldId
        {
            If ( ! dictTable.fieldName2Id( sqlDictionaryTable.name ) )
            {
                sqlDictionaryTable.delete();
            }
        }
        ////////////
        //fieldId = dictTable.fieldNext(0);
        fieldCnt = dictTable.fieldCnt();
        fieldId = dictTable.fieldCnt2Id(fieldCnt);
        //For all fields in table
        while (fieldCnt)
        {
            dictField = dictTable.fieldObject(fieldId);
            if (dictField.isSql() && !dictField.isSystem())
            {
                //Finds fields in SqlDictionary by name and compares IDs
                select sqlDictionaryField
                    where sqlDictionaryField.tabId == dictTable.id()
                    && sqlDictionaryField.name == dictField.name()
                    && sqlDictionaryField.fieldId != 0
                    && sqlDictionaryField.fieldId != dictField.id();
                if (sqlDictionaryField)
                {
                    //Updates field ID in SqlDictionary
                    if (ReleaseUpdateDB::changeFieldId(
                        dictTable.id(),
                        sqlDictionaryField.fieldId,
                        dictField.id(),
                        dictTable.name(),
                        dictField.name()))
                    {
                        info(strFmt("Field %1 - ID changed (%2 -> %3)",
                            dictField.name(),
                            sqlDictionaryField.fieldId,
                            dictField.id()));
                    }
                }
            }
            //fieldId = dictTable.fieldNext(fieldId);
            fieldCnt--;
            fieldId = dictTable.fieldCnt2Id(fieldCnt);
        }
        tableId = dictionary.tableNext(tableId);
    }
    ttscommit;
}

Connect Multiple AX clients with different Versions on Same Client PC

// Connect Multiple AX clients with different Versions on Same Client PC

Source :
https://community.dynamics.com/ax/b/eskosblog/archive/2014/09/17/how-to-install-multiple-ax-clients-for-different-versions-on-same-computer

1. AX 2012 client folder is by default located in C:\Program Files (x86)\Microsoft Dynamics AX\60\Client
Now we have to create a new folder with a different name (e.g. Client_R3)
2.Install AX 2012 R3 client to a computer that does not have previous versions of AX 2012 client installed. (e.g. the R3 AOS server)
3.Create a configuration file (.axc) for your AX 2012 R3 environment with Microsoft Dynamics AX Configuration Utility
4.Copy the content of your R3 Client folder to your computer to Client_R3 folder that you just created.
5.Copy the configuration file for the R3 environment to your computer
6.Create a shortcut for your R3 Client and add the path to your configuration file after the target application path (e.g. "C:\Program Files (x86)\Microsoft Dynamics AX\60\Client_R3\Bin\Ax32.exe" "C:\AX client configurations\AX2012R3.axc")
Rename the shortcut to correspond the environment it is connecting to.
7.Repeat to get a client for each service version that you need to get connected to.

Worker Managerial Hirearchy Above and below Levels ax 2012

//Worker Managerial Hirearchy Above and below Levels ax 2012
static void CheckManagerialHirearchy(Args _args)
{
    Query       query = new Query();
    QueryBuildDataSource    qbdsWorker;
    QueryRun        qr;
    HcmWorker           hcmWorker,hcmWorkerChk;
    HcmPositionWorkerAssignment         HcmPositionWorkerAssignment;
    container           allowedworkers,conWorker;
    int i;
   
    //Use AX default view HcmWkrPositionHierarchyView
    container allowedworkersCHeck(RecId _RecId,NoYes    _noYes = NoYes::Yes)
    {
        container allowedWorker = conNull();
        ReportingEmployees  reportemployee; //View
        //View Dataasource HCMPositionHirearchy,HCmPosition,HCMWorkerAssignment,HCMWorker)
        //View fields--> 1) HCMPositionHirearchy-ParentPosition 2) HCMPositionHirearchy-POsition 3) HCMWorker-PersonnelNumber
        ;
        if(_noYes == NoYes::Yes)        // Above level
        {
            while select reportemployee where reportemployee.Position == _RecId
            {  
                allowedWorker += HcmPositionWorkerAssignment::findByPosition(reportemployee.ParentPosition).Worker;
            }
        }
        else // Below level
        {
            while select reportemployee where reportemployee.ParentPosition == _RecId
            {  
                allowedWorker += HcmPositionWorkerAssignment::findByPosition(reportemployee.Position).Worker;
            }   
        }
        return allowedWorker;
    }
    ;
    qbdsWorker  = query.addDataSource(tableNum(HcmWorker));
    hcmWorker   =  HcmWorker::find(DirPersonuser::findUserWorkerReference(curUserId()));
    //info(curUserId());
    if(hcmWorker)
    {
        //info(strFmt("%1",hcmWorker.RecId));
        select firstOnly Position from HcmPositionWorkerAssignment
                where HcmPositionWorkerAssignment.Worker == hcmworker.RecId;
        //qbdsWorker.addRange(fieldNum(HcmWorker,RecId)).value(queryValue(hcmWorker.RecId));
        allowedworkers = allowedworkersCHeck(HcmPositionWorkerAssignment.Position,NoYes::No);
        //info(strFmt("%1",HcmPositionWorkerAssignment.Position));
        for(i =1;i<=conLen(allowedworkers);i++)
        {
            qbdsWorker.addRange(fieldNum(HcmWorker,RecId)).value(queryValue(conPeek(allowedworkers,i)));
        }
    }
    else
    {
        qbdsWorker.addRange(fieldNum(HcmWorker,RecId)).value(queryValue(0));
    }
    qr = New QueryRun(query);
    while (qr.next())
    {
        hcmWorkerChk = qr.get(tableNum(HcmWorker));
        info(strFmt("%1,%2,%3,%4,%5",hcmWorkerChk.PersonnelNumber,hcmWorkerChk.Person,hcmWorkerChk.name(),hcmWorkerChk.primaryDepartmentName(),HcmpositionDetail::findByPosition(HcmPosition::findByPosition(hcmWorkerChk.primaryPositionId()).RecId).Description));//,hcmWorkerChk.
    }
   
   
}

Get Active Record in ListPage Ax 2012

//Active Record in ListPage Ax 2012

ListPage        listPage                = this.listPage();
Tablename activeRecordTab;
;
activeRecordTab = listPage.activeRecord(#TableName);

Get Workflow Comment ax 2012

//Workflow Comment ax 2012

WorkflowTrackingStatusTable trackingStatusTable;
 WorkflowTrackingTable trackingTable;
 WorkflowTrackingCommentTable trackingCommentTable;
    WorkflowComment comment;
while select trackingStatusTable
            where trackingStatusTable.ContextRecId == 5637154368
    join trackingTable
        where trackingTable.WorkflowTrackingStatusTable == trackingStatusTable.RecId
            join trackingCommentTable
                where trackingCommentTable.WorkflowTrackingTable == trackingTable.RecId
 {
    comment = trackingCommentTable.Comment;
     info(strFmt("%1",comment));
 }

Dimension Combination Field enable based On Dimension selection Hirerarchy ax 2012

//Dimension Combination Field enable based ax 2012

public void displayDimensionAttributeValueColumns()
{
    int                     i,levelCount;
    FormStringControl       dimensionFormControl;
    DimensionSetSegmentName dimensionSetSegmentNames;
    if (DisplaySeparateDimensionValues.value())
    {
        DimensionAttributeValueCombination_DisplayValue.visible(false);
        dimensionSetSegmentNames = DimensionHierarchyLevel::getDimensionHierarchyLevelNames(dimHier.RecId);
       levelCount = DimensionHierarchy::getLevelCount(dimHier.RecId);
        for (i = 1; i <= #MaxDimensionHierarchyLevelsInStructure; i++)
        {
            if (i <= levelCount)
            {
                dimensionFormControl = this.getDimensionAttributeControl(i);
                dimensionFormControl.label(dimensionSetSegmentNames[i]);
                dimensionFormControl.visible(true);
            }
            else
            {
                dimensionFormControl = this.getDimensionAttributeControl(i);
                dimensionFormControl.visible(false);
            }
        }
    }
    else
    {
        DimensionAttributeValueCombination_DisplayValue.visible(true);
        for (i = 1; i <= #MaxDimensionHierarchyLevelsInStructure; i++)
        {
            dimensionFormControl = this.getDimensionAttributeControl(i);
            dimensionFormControl.visible(false);
        }
    }
}

private FormStringControl getDimensionAttributeControl(int _Level)
{
    if (_Level <= 9)
    {
        return element.design().controlName(strFmt('Dimensionocom0%1', _Level));
    }
    else
    {
        return element.design().controlName(strFmt('Dimensioncom%1', _Level));
    }
}

Convert Call stack to readable format in D365FO X++

//Input --container _xppCallStack = xSession::xppCallStack();  Public static str POL_formatXppCallStack(container _xppCallStack, int _skipFr...