Tuesday 31 May 2016

Applying Document Management Framework in Microsoft Dynamics AX 2012

https://www.dynamics101.com/applying-document-management-framework-microsoft-dynamics-ax-2012/

http://dynamicsaxforum.blogspot.in/2012/04/document-handling-in-ax-setup-and.html

https://community.dynamics.com/ax/b/axaptavsme/archive/2013/03/07/document-handling-via-x

http://theaxapta.blogspot.in/2013/04/x-code-for-document-attachment.html

https://arungarg1987.wordpress.com/2012/06/20/open-document-handling-docuview-for-other-datasourcetable-than-caller/

Friday 27 May 2016

Computed Columns in View

For Enum type field :

 private static server str  TypeLabel()
    {
        DictEnum dictEnum = new DictEnum(enumNum(LedgerTransType));
        int enumIdx;
        Map valuesMap = new Map(Types::String, Types::String);
        for (enumIdx = 1; enumIdx <= dictEnum.values(); enumIdx++)
        {
            valuesMap.insert(int2str(dictEnum.index2Value(enumIdx)), SysComputedColumn::returnLiteral(dictEnum.index2Symbol(enumIdx)));
        }
        return SysComputedColumn::switch(
        SysComputedColumn::returnField(tableStr(CITVendPaymentEntity), identifierStr(VendTransInvoice),
        fieldStr(CITVendPaymentEntity, TransType)),
        valuesMap,
        SysComputedColumn::returnLiteral('[unknown value]'));
       
    }


   public static server str  TypeLabel()
    {
        DictEnum dictEnum = new DictEnum(enumNum(CustVendACType));
        int enumIdx;
        Map valuesMap = new Map(Types::String, Types::String);
        for (enumIdx = 0; enumIdx <= dictEnum.values()-1; enumIdx++)
        {
            valuesMap.insert(int2str(dictEnum.index2Value(enumIdx)), SysComputedColumn::returnLiteral(dictEnum.index2Symbol(enumIdx)));
        }
        return SysComputedColumn::switch(
            SysComputedColumn::returnLiteral(CustVendACType::Vend),
        valuesMap,
        SysComputedColumn::returnLiteral('[unknown value]'));
    }
    public static server str Remaininginvoicebalance()
    {
        return SysComputedColumn::Subtract(
        SysComputedColumn::returnfield(tablestr(CITVendPaymentEntity),identifierStr(VendTransPayment),fieldstr(CITVendPaymentEntity,AmountCur)),
        SysComputedColumn::returnfield(tablestr(CITVendPaymentEntity),identifierStr(VendTransPayment),fieldstr(CITVendPaymentEntity,SettleAmountCur)));
    }

}=====================================================================
public static server str salesStatus()
{
    DictView    dv = new DictView(tableNum(DocuSalesOrderOpenInquiryView));
    str     a,b,c;
    DictEnum dictEnum = new DictEnum(enumNum(SalesStatus));
    int enumIdx;
    Map valuesMap = new Map(Types::String, Types::String);

    for (enumIdx = 1; enumIdx <= dictEnum.values(); enumIdx++)
    {
        valuesMap.insert(int2str(dictEnum.index2Value(enumIdx)), SysComputedColumn::returnLiteral(dictEnum.index2Symbol(enumIdx)));
    }

    a = dv.computedColumnString(identifierStr(Docuref),fieldStr(DocuRef,RefRecId));
    b = SysComputedColumn::returnField(tableStr(DocuSalesOrderOpenInquiryView),identifierStr(SalesTable),fieldStr(SalesTable,RecId));

    c = SysComputedColumn::compareExpressions(a,'=',b);
    return SysComputedColumn::if(c,
    SysComputedColumn::switch(
        SysComputedColumn::returnField(tableStr(DocuSalesOrderOpenInquiryView), identifierStr(SalesTable), fieldStr(SalesTable, SalesStatus)),
        valuesMap,
        SysComputedColumn::returnLiteral('[unknown value]')),
    SysComputedColumn::switch(
        SysComputedColumn::returnField(tableStr(DocuSalesOrderOpenInquiryView), identifierStr(SalesLine), fieldStr(SalesLine,   SalesStatus)),
        valuesMap,
        SysComputedColumn::returnLiteral('[unknown value]')));

}

 For String type field :

public static server str salesStatus()
{
    DictView    dv = new DictView(tableNum(DocuSalesOrderOpenInquiryView));
    str     a,b,c;
    DictEnum dictEnum = new DictEnum(enumNum(SalesStatus));
    int enumIdx;
    Map valuesMap = new Map(Types::String, Types::String);

    for (enumIdx = 1; enumIdx <= dictEnum.values(); enumIdx++)
    {
        valuesMap.insert(int2str(dictEnum.index2Value(enumIdx)), SysComputedColumn::returnLiteral(dictEnum.index2Symbol(enumIdx)));
    }

    a = dv.computedColumnString(identifierStr(Docuref),fieldStr(DocuRef,RefRecId));
    b = SysComputedColumn::returnField(tableStr(DocuSalesOrderOpenInquiryView),identifierStr(SalesTable),fieldStr(SalesTable,RecId));

    c = SysComputedColumn::compareExpressions(a,'=',b);
    return SysComputedColumn::if(c,
    SysComputedColumn::switch(
        SysComputedColumn::returnField(tableStr(DocuSalesOrderOpenInquiryView), identifierStr(SalesTable), fieldStr(SalesTable, SalesStatus)),
        valuesMap,
        SysComputedColumn::returnLiteral('[unknown value]')),
    SysComputedColumn::switch(
        SysComputedColumn::returnField(tableStr(DocuSalesOrderOpenInquiryView), identifierStr(SalesLine), fieldStr(SalesLine, SalesStatus)),
        valuesMap,
        SysComputedColumn::returnLiteral('[unknown value]')));

}


Thursday 26 May 2016

General Ledger > Periodic > Ledger Settlements

If you select any of the two trasactions ( positive/ negative) , and click include it moves in to lower temporary grid. Then if balance field is zero then only "Accept " Button is enabled else no. 

So if the balances are different then also it should settle the required amount is the new requirement.So for that we need to add the new method,


public static void partialLedgerTransSettle(
    GeneralJournalAccountEntry _temporaryGeneralJournalAccountEntry,
    Map _temporaryTransRecIdToTransRecId)
{
    LedgerTransSettlement   ledgerTransSettlement;
    RecordInsertList        settlementCollection;
    Amount                  postiveBal,negativebal;
    RefRecId                refRecId;
    GeneralJournalAccountEntry  accountEntry;

    ttsbegin;

    settlementCollection = new RecordInsertList(tablenum(LedgerTransSettlement));

    ledgerTransSettlement.SettleId = NumberSeq::newGetNum(CompanyInfo::numRefParmId()).num();

    //Get sum of Positive records
    select sum(AccountingCurrencyAmount) from _temporaryGeneralJournalAccountEntry
        where _temporaryGeneralJournalAccountEntry.AccountingCurrencyAmount > 0;

    postiveBal = _temporaryGeneralJournalAccountEntry.AccountingCurrencyAmount;

   //Get Sum of Negative records
    select sum(AccountingCurrencyAmount) from _temporaryGeneralJournalAccountEntry
        where _temporaryGeneralJournalAccountEntry.AccountingCurrencyAmount < 0;

    negativebal = _temporaryGeneralJournalAccountEntry.AccountingCurrencyAmount;

    //If (Positive value is greater than negative),find positive record
    //where difference of Positive and negative is greater than record amount.
    //Update the selected record with Difference amount

    if (abs(negativebal) < abs(postiveBal)    )
    {
        postiveBal = abs(postiveBal)-abs(negativebal);

        select forUpdate _temporaryGeneralJournalAccountEntry
            where _temporaryGeneralJournalAccountEntry.AccountingCurrencyAmount > 0
                && _temporaryGeneralJournalAccountEntry.AccountingCurrencyAmount > postiveBal;

        _temporaryGeneralJournalAccountEntry.AccountingCurrencyAmount   =   postiveBal;
        _temporaryGeneralJournalAccountEntry.TransactionCurrencyAmount  =   postiveBal;
        _temporaryGeneralJournalAccountEntry.ReportingCurrencyAmount    =   postiveBal;
        _temporaryGeneralJournalAccountEntry.update();
        refRecid = _temporaryGeneralJournalAccountEntry.RecId;
       
         //Update Record of GL account Entry with Amount as Amount - Balance Amount
        select accountEntry where
            accountEntry.RecId  ==  _temporaryTransRecIdToTransRecId.lookup(refRecId);
        accountEntry.selectForUpdate(true);      
        accountEntry.TransactionCurrencyAmount  =   accountEntry.TransactionCurrencyAmount - postiveBal;
        accountEntry.AccountingCurrencyAmount   =   accountEntry.AccountingCurrencyAmount - postiveBal;
        accountEntry.ReportingCurrencyAmount    =   accountEntry.ReportingCurrencyAmount - postiveBal;
        accountEntry.update();
    }
    //Find Negative record where difference of Positive and negative is greater than record amount
    //Update the selected record with Difference amount
    //Record the Recid of selected record
    else
    {
        postiveBal = abs(negativebal)-abs(postiveBal);

        select RecId from _temporaryGeneralJournalAccountEntry
            where _temporaryGeneralJournalAccountEntry.AccountingCurrencyAmount < 0
                && _temporaryGeneralJournalAccountEntry.AccountingCurrencyAmount < -postiveBal;
        _temporaryGeneralJournalAccountEntry.AccountingCurrencyAmount   =  -postiveBal;
        _temporaryGeneralJournalAccountEntry.TransactionCurrencyAmount  =  -postiveBal;
        _temporaryGeneralJournalAccountEntry.ReportingCurrencyAmount    =  -postiveBal;
        _temporaryGeneralJournalAccountEntry.update();
        refRecid = _temporaryGeneralJournalAccountEntry.RecId;
       
        select accountEntry where
        accountEntry.RecId  ==  _temporaryTransRecIdToTransRecId.lookup(refRecId);
        accountEntry.selectForUpdate(true);
        accountEntry.TransactionCurrencyAmount  =   -postiveBal;
        accountEntry.AccountingCurrencyAmount   =   -postiveBal;
        accountEntry.ReportingCurrencyAmount    =   -postiveBal;
        accountEntry.update();
    }
    while select RecId from _temporaryGeneralJournalAccountEntry
    {
        ledgerTransSettlement.TransRecId = _temporaryTransRecIdToTransRecId.lookup(_temporaryGeneralJournalAccountEntry.RecId);

        settlementCollection.add(ledgerTransSettlement);
    }

    settlementCollection.insertDatabase();
    //Delete_From code to exclude recId which was selected/updated in code above
     delete_from _temporaryGeneralJournalAccountEntry
        where _temporaryGeneralJournalAccountEntry.RecId != refRecId;
 
    //Insert Record in to GL account Entry with Balance Amount
    select _temporaryGeneralJournalAccountEntry where _temporaryGeneralJournalAccountEntry.RecId == refRecId;
    accountEntry.data(_temporaryGeneralJournalAccountEntry);
    accountEntry.insert();
   
    ttscommit;
}


Data Migration Framework – Create a Custom Entity For Migration

https://community.dynamics.com/ax/b/k3retailtechnicalblog/archive/2012/10/17/data-migration-framework-create-a-custom-entity-for-migration

1. Go to Data Migration Framework –> Common –> Create a custom entity for migration.
2. Select the table you wish to create as an entity and click finish.
image
3. Click on Yes to define the relationships.
image N.B. This seems to error occasionally.  If it does, you must manually create any elements the wizard has not created for you.  The structure of your project should look like the screen shot below.  Your project may contain EDTs which is fine.  You project is created as a private project.
image

The Staging Table

4. The table which is created is the table you will load the staging data into.  I have removed the fields I do not require for the data import, but this is not a necessary step.
5. The wizard creates four standard fields which are used in the DMF.  Definition group, ExecutionId, TransferStatus and IsSelected.
  • Change the EDT on the isSelected Field to DMFIsSelected.
  • Change the enumType of the TransferStatus field to DMFTransferStatus.
6. Remove the relation DMFExecution1.
7. Create a relation between the staging table and the table you are populating.
image

Custom Method/Function

In this example, I want the Description field to be populated by the itemID.  I am therefore going to generate a method to do this.
8. In the class which is created, create a new method.  The method must be prefixed with Generate…….
1
2
3
4
5
6
7
8
9
10
11
12
13
public container generateDescription()
{
    Container       ret = conNull();
 
    if (entity.itemId != '')
    {
        target.description = entity.itemId;
 
        ret = [target.description];
    }
 
    return ret;
}
9. Create a FieldGroup on your staging table with the same name as the method you have just created.  Add the fields you wish to pass into the method.
image 10. Create a new method in the class named getReturnFields.  This tells the migration tool which table and field the value passed back from the the generate method should go.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static container getReturnFields(Name _entity, MethodName _name)
{
    DataSourceName dataSourceName = queryDataSourceStr(DMFInventItemBarcodeTargetEntity, InventItemBarcode);
    Container      con            = [dataSourceName];
 
    Name fieldstrToTargetXML(FieldName _fieldName)
    {
        return DMFTargetXML::findEntityTargetField(_entity,dataSourceName,_fieldName).XMLField;
    }
 
    switch (_name)
    {
 
        case methodStr(DMFInventItemBarcodeEntityClass, generateDescription) :
            con += [fieldstrToTargetXML(fieldStr(InventItemBarcode, Description))];
            break;
 
        default :
            con = conNull();
    }
 
    return con;
}

The Import

8. Go to Data Migration Framework –> Setup–> Target Entities.
9. Create a new custom Entity with the objects you have created.
image 10. Go to Modify Target Mapping and check your fields are mapped correctly.  Although you can change the mapping here, if it is not correct, it is likely there is something missing from your project.
image 11. You can now go to Data Migration Framework –> Common –> Processing Group and create a new processing group.  Click on Entities and create a new entity for the processing group.
12. Go to Generate Source Mapping and select the fields you are importing and the order you are importing them.  Generate Sample File to get the structure required for your data import.  You can add data here and save it locally.
image 13. Click Finish and enter your source file into the entity record for the processing group.
image 14. Click Generate Source mapping.
15.  Go back to your processing group and click get Staging Data.  Click OK, Run on AOS and then OK again.
16.  Your data should now be loaded into the staging table.
image 17. In the processing group, click on Copy Data To target. Select your job ID, click OK, Run on AOS and the OK.
18.  Your  data should now be loaded into your target table.
image

Wednesday 25 May 2016

Get lookup for one dimension dimension

public void lookup()
{
  Query query = new Query();
    QueryBuildDataSource                queryBuildDataSource;
    QueryBuildRange                         qbrForAccount;
    SysTableLookup                           sysTableLookup;
    String255                                        dimType;
    DimensionAttribute                        dimensionAttribute;
    DimensionAttributeDirCategory       dimAttributeDirCategory;
    ;

 
    sysTableLookup = SysTableLookup::newParameters(tableNum(OMOperatingUnit),this,true);
            sysTableLookup.parmUseLookupValue(false);
            sysTableLookup.addLookupfield(fieldNum(OMOperatingUnit, OMOperatingUnitNumber));
            sysTableLookup.addLookupfield(fieldNum(OMOperatingUnit, Name));
            queryBuildDataSource = query.addDataSource(tableNum(OMOperatingUnit));
            queryBuildDataSource.addSortField(fieldnum(OMOperatingUnit,OMOperatingUnitNumber));
            queryBuildDataSource.addRange(fieldNum(OMOperatingUnit,      OMOperatingUnitType)).value(int2str(any2int(OMOperatingUnitType::OMBusinessUnit)));
            sysTableLookup.parmQuery(query);
            sysTableLookup.performFormLookup();
}
====================================================================
http://ax2009developer.blogspot.in/2014/02/how-create-customize-look-up-for.html

How Create Customize Look up for Financial Dimension in Ax2012

Following lookup help for dimension filtration according to enum value over here
DimType  is customized filed which contain  Department, CostCenter, Project, Account  and BusinessUnit.
Select any one option then use following code of lookup for filter                                                                

public void lookup()
{

    Query query = new Query();
    QueryBuildDataSource                queryBuildDataSource;
    QueryBuildRange                         qbrForAccount;
    SysTableLookup                           sysTableLookup;
    DimType                                        dimType;
    DimensionAttribute                        dimensionAttribute;
    DimensionAttributeDirCategory       dimAttributeDirCategory;
    ;

    dimType = str2enum(dimType,FilterGroup_Type.valueStr());

    switch(dimType)
    {
        case  DimType::Department:

            sysTableLookup = SysTableLookup::newParameters(tableNum(OMOperatingUnit),this,true);
            sysTableLookup.parmUseLookupValue(false);
            sysTableLookup.addLookupfield(fieldNum(OMOperatingUnit, OMOperatingUnitNumber));
            sysTableLookup.addLookupfield(fieldNum(OMOperatingUnit, Name));
            queryBuildDataSource = query.addDataSource(tableNum(OMOperatingUnit));
            queryBuildDataSource.addSortField(fieldnum(OMOperatingUnit,OMOperatingUnitNumber));
            queryBuildDataSource.addRange(fieldNum(OMOperatingUnit,      OMOperatingUnitType)).value(int2str(any2int(OMOperatingUnitType::OMDepartment)));
            sysTableLookup.parmQuery(query);
            sysTableLookup.performFormLookup();
            break;

        case  DimType::BusinessUnit:

            sysTableLookup = SysTableLookup::newParameters(tableNum(OMOperatingUnit),this,true);
            sysTableLookup.parmUseLookupValue(false);
            sysTableLookup.addLookupfield(fieldNum(OMOperatingUnit, OMOperatingUnitNumber));
            sysTableLookup.addLookupfield(fieldNum(OMOperatingUnit, Name));
            queryBuildDataSource = query.addDataSource(tableNum(OMOperatingUnit));
            queryBuildDataSource.addSortField(fieldnum(OMOperatingUnit,OMOperatingUnitNumber));
            queryBuildDataSource.addRange(fieldNum(OMOperatingUnit, OMOperatingUnitType)).value(int2str(any2int(OMOperatingUnitType::OMBusinessUnit)));
            sysTableLookup.parmQuery(query);
            sysTableLookup.performFormLookup();
            break;

        case  DimType::CostCenter:


            sysTableLookup = SysTableLookup::newParameters(tableNum(OMOperatingUnit),this,true);
            sysTableLookup.parmUseLookupValue(false);
            sysTableLookup.addLookupfield(fieldNum(OMOperatingUnit, OMOperatingUnitNumber));
            sysTableLookup.addLookupfield(fieldNum(OMOperatingUnit, Name));
            queryBuildDataSource = query.addDataSource(tableNum(OMOperatingUnit));
            queryBuildDataSource.addSortField(fieldnum(OMOperatingUnit,OMOperatingUnitNumber));
            queryBuildDataSource.addRange(fieldNum(OMOperatingUnit, OMOperatingUnitType)).value(int2str(any2int(OMOperatingUnitType::OMCostCenter)));
            sysTableLookup.parmQuery(query);
            sysTableLookup.performFormLookup();
            break;
        case  DimType::Project:

            dimensionAttribute = DimensionAttribute::findByName("Project");
            if (dimensionAttribute.Type == DimensionAttributeType::CustomList)
            {
            select firstonly DirCategory from dimAttributeDirCategory where dimAttributeDirCategory.DimensionAttribute == dimensionAttribute.RecId;
            sysTableLookup = SysTableLookup::newParameters(tableNum(DimensionFinancialTag), this,true);
            sysTableLookup.addLookupfield(fieldNum(DimensionFinancialTag, Value));
            sysTableLookup.addLookupfield(fieldNum(DimensionFinancialTag, Description));
            query = new Query();
            query.addDataSource(tableNum(DimensionFinancialTag)).addRange(fieldNum(DimensionFinancialTag, FinancialTagCategory)).value(queryValue(dimAttributeDirCategory.DirCategory));
            sysTableLookup.parmQuery(query);
            sysTableLookup.performFormLookup();
            }
            break;


        case DimType::Account:

            sysTableLookup = SysTableLookup::newParameters(tableNum(MainAccount),this,true);
            sysTableLookup.parmUseLookupValue(false);
            sysTableLookup.addLookupfield(fieldNum(MainAccount, MainAccountId));
            sysTableLookup.addLookupMethod(tableMethodStr(MainAccount, localizedName));
            sysTableLookup.addLookupfield(fieldNum(MainAccount, Type));
            queryBuildDataSource = query.addDataSource(tableNum(MainAccount));
            qbrForAccount = queryBuildDataSource.addRange(fieldNum(MainAccount,LedgerChartOfAccounts));
            qbrForAccount.value(queryValue(Ledger::current()));
            queryBuildDataSource.addSortField(fieldnum(MainAccount,MainAccountId));
            sysTableLookup.parmQuery(query);
            sysTableLookup.performFormLookup();
            break;

     
}

Tuesday 24 May 2016

Data migration Framework Walkthrough Vedio

1. Check Parameters: 
services - MicrosoftDynamicsaxdataimport/export framework service

USMF >> Data import export framework >> setup >>Data import/ export framework parameters .
we need to set up shared working directory.when we install Data migration framework , it fills the service connection url.
Paste the url in Internet explorer and check the response of it.

2. Check Source data formats :
We need to set up data source formats.
USMF >> Data import export framework >> setup >>source data formats
New  record >> source name - ax , description - ax , Type - ax. save.
New record >> CSV  , Description - Comma test, file - file.
General >> file format : delimited , first row header - checked, Row delimeter - {CR}{LF},Column Delimeter - Comma {,}, Text qualifier - ".
Application - Here we need to select the dimensions.
Dimension Code - check Business unit, department, cost centre.
3. Target Entities :

what we are going to import. We target to entities here.
We need to check Entity. (table name i think)
we have 3 concepts for each entity
i) Staging table - the data comes in
ii) Entity Class - we need to do additional processing/ addition modification can be done with this class
iii) Target entity - Is the query to the target tables.

Example :

  • Copy data to single entity : 

Select Asset in Target entities >> Modify target mappings.

click Mapping details ...
We can change mapping/ change classes . But once done we need to click Generate mappings >> yes.
And then save.close .

Entity Strutcure  - this shows us the target tables it is going to . Levels are important  order the data it enter in to different tables. When we process the functions , we process based on levels mentioned here.
Run business validations, Run business logic in insert or update method - will be checked in some entities and some it is not. Depending on entity , we need to decide it.
We need to check the same in processing group. both areas should be checked / not checked.

Click >>Target fields

USMF >> Data import export framework >> Common>> Processing groups

Create a new processing group .
Group name - ProductsAX , Description - Products AX
Click on Entities . We can select no. of entities to be included in processing group. for this ex i select one.

Select entity - Product , source data format - ax  and click select.

Select item id - 1000 and click ok. close the form.

Click on "Get stating data" in processing group form .click ok.Click Run . You can run in batch or directly. I run directly with out clicking batch processing. Click Ok.

infolog  - "1 product record inserted in staging. ".

In processing group >> Click on Execution history. click View staging data , we can see the record inserted.

we want to populate csv file from the template.,

Create a new processing group >> Group name - Products CSV ,Description - Products CSV.
Click on Entities .
Entity - Product,Change format - CSV,
Sample file path - we need to select below folder where we pasted the product entity .
Ex  here - C:\BJU

Click on Generate source sample file.Choose the fields  and click "Generate sample file". Click notepad. So this can be used as sample file.

We can fine lot of sample files in below folder
C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\DemoFiles\Delimited

Copy - Product entity from this folder to C:\BJU or C:\DIXF.
====================
Click on Generate source mapping - infolog "Product entity mapping is done successfully.
Click on Modify source mapping  just to see mappings .
Click on Preview source file. Then we can see the data in preview.

=======================================================
Go to processing group >> Select ProductsAX . >> click on Execution history>>View staging data >> Export to file >> select procesing group - Product csv and click ok. File is generated on your desktop.
Go to that file, modify the file, create one more line for other product changing the Product name . we can even update the previous record existed.
Click on save.
Copy this file to C:\BJU
Select Processing group  to Products CSV >> sample file path to the new file we pasted.

Click on Preview source file . we can see the 2 records.  "Preview error details" give the errors while doing the process.

Click on Processing group >> Product CSV >> Generate stagin data . Click ok.Click run >> OK.
Infolog - "2 product' record inserted in staging\".
Go to execution history >> view staging data >>  you can see 2 records now.

Now to go Execution history screen >> copy data to target.>> click Run >>
Infolog - "Data written to target 'Product' ('1' records created, '1' records updated)"


You can check one new product created and 1000 product is modified.
https://www.youtube.com/watch?v=TZiAAIk35Qg  - Customer table Import
========================================================================
  • Copy data to  Composite entity : 
where we can copy from single file to 2 different entities.
---------------------------------------------------------------------
Creating new entities & other features.
Create a custom entity 
Compare data between companies 
Copy data between companies
Quick import/export 
Staging clean up.
--------------------------------------------------------------------

USMF >> Data import export framework >> Common>> Create a custom entity for data import/ export

Click next >> select Custtable >> Select Menu item

Important Links on DIXF :

https://stoneridgesoftware.com/generating-voucher-numbers-when-importing-general-journals-with-dief-in-ax-2012/


How to get the price from Trade agreements set for purch for an item

PriceDisc::findItemPriceAgreement(
                    ModuleInventPurchSales::Purch,
                    ProductsAndVariants.itemid,InventDim::find(InventDim::inventDimIdBlank()),
                    inventTableModule.UnitId,SystemDateGet(),1,inventtableloc.PrimaryVendorId,
                    CompanyInfo::standardCurrency(),vendtable.PriceGroup);

Thursday 19 May 2016

Enable and disable of the field in grid based on check box field in dialog


  if(cbNewforecastmodel.checked())
       ReqDemPlanImportForecastTmp_ds.object(fieldNum(ReqDemPlanImportForecastTmp,ForecastModelId)).enabled(false);

Reference Link :
http://community.dynamics.com/ax/f/33/t/112656

Wednesday 18 May 2016

Conversions from UTCdate time to string and vice versa.

static void datetime2str()
{
 str resultstr;
utcDateTime result;
resultstr   =  DateTimeUtil::toFormattedStr(result,321, DateDay::Digits2, DateSeparator::Hyphen, DateMonth::Digits2, DateSeparator::Hyphen, DateYear::Digits4, TimeSeparator::Colon, TimeSeparator::Colon, DateFlags::None);
info(resultstr);
}
The function date2str  take following parameters :
1- the date .
2- the date style dmy or ymd or....etc .
3- number of digits for day .
4- separator
5- number of digits for month.
6- separator 
7- number of digits for year. 
================================================================
static void string2datetime()
{
     System.Globalization.CultureInfo culture
    = System.Globalization.CultureInfo::get_InvariantCulture();
    str resultstr;
   utcDateTime result;
   try
    {
     
         result= System.DateTime::ParseExact(
                             "2007-05-28 X 23:59:04",
                            "yyyy-MM-dd X HH:mm:ss",
                            culture);
     
         info(strFmt("%1",result));
    }
    catch (Exception::CLRError)
    {
        throw error(AifUtil::getClrErrorMessage());
    }
}
https://community.dynamics.com/ax/f/33/t/125802
============================================================

https://msdn.microsoft.com/en-us/library/cc553823.aspx

static void JobDateTimeGlobalMarshal(Args _args)
{
    System.DateTime netDttm;
    utcdatetime xppDttm;
    str xppString;
    ;
    xppDttm = 2007-06-05T23:22:21; // ISO standard format.
    
    // Convert X++ to .NET.
    netDttm = Global::utcDateTime2SystemDateTime(xppDttm);
    
    // Convert .NET to X++.
    xppDttm = Global::CLRSystemDateTime2UtcDateTime(netDttm);
    
    xppString = DateTimeUtil::toStr(xppDttm);
    info("xppDttm: " + xppString);
}

===========================================================================

static void FormatUtcdatetime(Args _args)
{
    
     System.Globalization.CultureInfo culture
    = System.Globalization.CultureInfo::get_InvariantCulture();
    str resultstr,frstpart,secondpart;
    utcDateTime result;
    result =    DateTimeUtil::getSystemDateTime();
     //info(strFmt("%1",result));
    resultstr   =  DateTimeUtil::toFormattedStr(result,321, DateDay::Digits2, DateSeparator::Hyphen, DateMonth::Digits2, DateSeparator::Hyphen, DateYear::Digits4, TimeSeparator::Colon, TimeSeparator::Colon, DateFlags::None);
    frstpart    = subStr(resultstr,0,10);
    secondpart    = subStr(resultstr,11,9);
    resultstr   =   frstpart+"T"+"09:20:06";//+"09:16:30";
     result = DateTimeUtil::parse(frstpart+"T"+"09:20:06");
     
    //info(secondpart);
    // info(frstpart+"T"+secondpart);
    try
    {
        /* result= System.DateTime::ParseExact(
                            "2007-05-28T23:59:04",
                            "yyyy'-'MM'-'dd'T'HH':'mm':'ss",
                            culture);*/
  result= System.DateTime::ParseExact(
                             "2007-05-28 X 23:59:04",
                            "yyyy-MM-dd X HH:mm:ss",
                            culture);
    //result  =   DateTimeUtil::parse(resultstr);
    info(strFmt("%1",result));
    }
    catch (Exception::CLRError)
    {
        throw error(AifUtil::getClrErrorMessage());
    }
    //yyyy'-'MM'-'dd'T'HH':'mm':'ss
}

https://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.sortabledatetimepattern(v=vs.100).aspx
https://msdn.microsoft.com/en-us/library/system.datetime.parseexact(v=vs.110).aspx

Monday 16 May 2016

Requirement to Get Location in Invent onhand item when form is initialized.

if (element.args().caller().name() == "OnhandLocation")
            {
                inventDimParmEnabled.clear();
                inventDimParmEnabled.WMSLocationIdFlag = NoYes::Yes;
                element.inventDimSetupObject().parmDimParmVisibleGrid(inventDimParmEnabled, true);
                element.inventDimSetupObject().saveLast();
            }

Sunday 15 May 2016

Open the Form with Grid View using x++ code

void clicked()
{
    Args args = new Args();
    super();
    args.record(InventTable);
    args.caller(this);
    args.formViewOption(FormViewOption::Grid); // Opens the form with Grid as default View
    new MenuFunction(menuitemDisplayStr(EcoResProductDetailsExtended), MenuItemType::Display).run(args);
}

Thursday 12 May 2016

Copy the address from one customer to others customers

public void mergeDeliveryAddresses(CustAccount  custAccount,
                                   CustAccount  retCustAccount)
{
    CustTable custTable;
    DirParty dirParty;
    DirPartyPostalAddressView PostalAddress, PostalAddressDest;
    ;

    custTable = CustTable::find(custAccount);

    while select PostalAddress
        where PostalAddress.Party == CustTable.Party
    {
        buf2Buf(PostalAddress, PostalAddressDest);
        PostalAddressDest.Party = CustTable::find(retCustAccount).Party;
        PostalAddressDest.IsPrimary = NoYes::No;       
        PostalAddressDest.LocationName =  PostalAddress.LocationName;
        dirParty = DirParty::constructFromCommon(custTable);
        dirParty.createOrUpdatePostalAddress(PostalAddressDest);

    }


}

To Add Button click method to LP

How to add button clicked method to LP :

Set the property of Button in LP - "Display Target"  to "Client "

Tuesday 10 May 2016

How to duplicate the SSRS report

We all know that we will have requirements to modify an existing SSRS report but would not like to alter the original, rather create a duplicate and work on it.
But, Do we have the option in AX 2012? The answer is “NO” and it’s a real problem/hectic job for a developer to create it from scratch. Even when we try to do this from visual studio 2010, it is not allowed to change the report name as it says it exists in another layer.
Well, I have created a utility to duplicate the SSRS reports from AX. It works all fine and gets built successfully and was able to render the data as well. Once the report is duplicated, you can change the design in Visual studio.
[Note: I have posted a recent article on Duplicating SSRS with the help of wizard with all its artifacts (DP classes, Contract, UIBuilder and CSharp project)] – Here is the link
This really helps the developer in not creating the DP classes, contract classes etc. and can customize the existing DP classes by adding the new fields in temp tables.
Below is them new utility walk through:
Go to Tools >> Business Intelligence Tools >> Create duplicate SSRS reports
image
This will open all existing SSRS reports in the picker
image
Select any report : a new dialog will open with the new report name as “CopyOf” select report Name, you can modify the report name here
based on your requirements.Click on Ok button.
image
A new report gets created in SSRS reports as shown below
image
Nice right! Now lets us open this in Visual studio 2010 and you can play with the design.
You can see the new report in the Application Explorer as shown below:
image
Add this report to your project and build it. It builds successfully and is ready for preview as well.
image

Below is the link to get the xpo of Duplicating SSRS report.
https://drive.google.com/open?id=0Bz2gDlDZfIivc2xVWHd3V0t0a2c