Wednesday, March 26, 2014

Update Customer and Vendor Dimension in AX 2012 from CSV

static void UpdateCustomerDimension(Args _args)
{
    CommaTextIO          csvFile;
    container                  readCon;
    counter                    icount;
    Dialog                      dialog;
    DialogField               dfFileName;
    FileName                 fileName;
   
    Struct                      struct;
    DimensionDefault      DimensionDefault;

    CustAccount  custAccount;//VendAccount
    CustTable      custTable; //VendTable
   
    container    ledgerDimension;    
    int i;   

    #File 


    dialog = new Dialog("Pick the file");
    dfFileName = dialog.addField(extendedTypeStr("FilenameOpen"));
    dialog.filenameLookupFilter(["All files", #AllFiles]);


    if (dialog.run())
    {
        csvFile = new CommaTextIo(dfFileName.value(), 'r');
        csvFile.inFieldDelimiter(',');
        readCon = csvFile.read();
        ttsBegin;
        while(csvFile.status() == IO_Status::OK)
        {
            readCon = csvFile.read();

            if(readCon)
            {
                icount++;

                custAccount = conPeek(readCon,1);             

                custTable = CustTable::find(custAccount,true);                

                struct = new Struct();
                struct.add('Sector',conPeek(readCon,3)); //(DimensionName,Value)
                struct.add('Division', conPeek(readCon,4)); 
                struct.add('SubDivision', conPeek(readCon,5));
                struct.add('SubDivision', conPeek(readCon,6));

                ledgerDimension = conNull();
                ledgerDimension += struct.fields();

                for (i = 1; i <= struct.fields(); i++)
                {
                    ledgerDimension += struct.fieldName(i);
                    ledgerDimension += struct.valueIndex(i);
                }

                DimensionDefault = AxdDimensionUtil::getDimensionAttributeValueSetId(ledgerDimension);
                custTable.DefaultDimension = DimensionDefault;
                
                custTable.update();
                
            }

        }
        ttsCommit;
    }

}

X++ code to read the data from Active Directory in AX 2012

static void ReadingDataFromActiveDirectory(Args _args)
{
System.DirectoryServices.DirectorySearcher DirectorySearcher;
System.DirectoryServices.SearchScope SearchScope;
System.DirectoryServices.DirectoryEntry DirectoryEntry;

System.DirectoryServices.SearchResultCollection SearchResultCollection;
System.DirectoryServices.SearchResult SearchResult;

System.DirectoryServices.PropertyCollection PropertyCollection;
System.DirectoryServices.PropertyValueCollection PropertyValueCollection;

str networkDomain="bosco.com";
str prefix = 'LDAP://';

int totalCount;
int counter;

str mysamaccountname;
str myusername;
str myMobileNum;
;

try
{
SearchScope = CLRInterop::parseClrEnum('System.DirectoryServices.SearchScope', 'Subtree');
DirectoryEntry = new System.DirectoryServices.DirectoryEntry(prefix + networkDomain);


DirectorySearcher = new System.DirectoryServices.DirectorySearcher(DirectoryEntry);
DirectorySearcher.set_PageSize(65535);
DirectorySearcher.set_CacheResults(false);
DirectorySearcher.set_SearchScope(searchScope);
DirectorySearcher.set_Filter(strfmt('(&(objectClass=user))'));

SearchResultCollection = DirectorySearcher.FindAll();

totalCount = SearchResultCollection.get_Count();
for (counter=0; counter < totalcount; counter++)
{
SearchResult = SearchResultCollection.get_Item(counter);
DirectoryEntry = SearchResult.GetDirectoryEntry();

if (DirectoryEntry)
{
PropertyCollection = DirectoryEntry.get_Properties();

if (PropertyCollection)
{
PropertyValueCollection = PropertyCollection.get_Item('samaccountname');
mysamaccountname=PropertyValueCollection.get_Value();

PropertyValueCollection = PropertyCollection.get_Item('name');
myusername=PropertyValueCollection.get_Value();
 
PropertyValueCollection = PropertyCollection.get_Item('Mobile');
if(PropertyValueCollection.get_Value())
{
          myMobileNum=PropertyValueCollection.get_Value();
}
else
{
         myMobileNum= "";
}

info(strfmt('%1 - %2 -%3',mysamaccountname,myusername,myMobileNum));
}
}
}

DirectorySearcher.Dispose();
SearchResultCollection.Dispose();
}
catch (Exception::CLRError)
{
error("Error reading AD");
return;
}

}



You may get error while trying to access Active Directory on the below line

searchResultCollection = directorySearcher.FindAll();

Kindly check the AOS instance (In service) whether its running under a Network Service Account, which did not have all the permissions to deal with the Active Directory.

To resolve this issue kindly change the login method of your service to use the local service instead of the Network Service.

Tuesday, March 25, 2014

How to bring Lookup form in lookup in AX 2012

1.Create a Form like below based on the requirement.

       

2.Create a lookup method in Form design Field, paste the below code

    Args args;
    FormRun formRun;
    ;
    args = new args();
    args.parm( strFmt("%1",value)); // pass the argument if required to filter lookup Form
    args.name( formstr(InventSerialLookup) );     //Lookup Form name
    formRun = classFactory.formRunClass( Args );
    this.performFormLookup(formRun);

3. In Lookup Forms init method 

    public void init()
    {
          str            parms;    
          canSelect = false;
          super();
          if( element.args() )
          {
                parms = element.args().parm();
          }
         element.selectMode(sELECTEDFieldName);//to fetch the selected field value
    }

Error : Number Sequence has been exceeded AX 2012



Error Thrown:



Solution:

1. Goto AOT - Tables - NUMBERSEQUENCETABLE  filter by recid from errored recid.
2. Find the NumberSequence value from the table.
3. Go to ORGANIZATION ADMINISTRATION-->COMMON-->NUMBER SEQUENCE
4. Edit the record and increase the LARGEST  value to maximum and save.

Sunday, March 23, 2014

Importing Custom Financial Dimension in AX 2012

static void importCustomDimensionfromCSV(Args _args) // Costcentre,Department,Business Unit
{
    CommaTextIO                 csvFile;
    container                   readCon;
    counter                     icount,inserted;
    Dialog                      dialog;
    DialogField                 dfFileName;
   
    DimensionAttribute              dimAttr;
    DimensionAttributeDirCategory   dimAttrCategory;
    DimensionFinancialTag           dimFinancialTag;
    Name _name; 
    DimensionValue _value; 
    Description _desc;

    FileName                    fileName; 
   
    #File

    dialog = new Dialog("Pick the file");
    dfFileName = dialog.addField(extendedTypeStr("FilenameOpen"));
    dialog.filenameLookupFilter(["All files", #AllFiles]);
    
    if (dialog.run())
    {
        csvFile = new CommaTextIo(dfFileName.value(), 'r');
        csvFile.inFieldDelimiter(',');

        ttsBegin;
        while (csvFile.status() == IO_Status::Ok)
        {
            readCon = csvFile.read();           
            
            _name = conPeek(readCon,1); //"CustomDimensionName"
            _value = conPeek(readCon,2); //"CustomDimensionValue"
            _desc  = conPeek(readCon,3); //"CustomDimensionDescription"
            
            dimAttr = DimensionAttribute::findByName(_name);

            select dimAttrCategory where dimAttrCategory.DimensionAttribute == dimAttr.RecId;

            if(dimAttrCategory)    
            {        
                select dimFinancialTag where dimFinancialTag.FinancialTagCategory == dimAttrCategory.DirCategory
                                          && dimFinancialTag .Value == _value;
                if (!dimFinancialTag)
                {
                    dimFinancialTag.Description             = _desc;
                    dimFinancialTag.Value                   = _value;
                    dimFinancialTag.FinancialTagCategory    = dimAttrCategory.DirCategory;
                    dimFinancialTag.insert();
                }
            }
       
        }
        ttsCommit;
    }
   
}

Importing Standard Financial Dimension in AX 2012 using X++

static void importDepartmentfromCSV(Args _args) // Costcentre,Department,Business Unit, from csv
{
    CommaTextIO                 csvFile;
    container                   readCon;
    counter                     icount,inserted;
    Dialog                      dialog;
    DialogField                 dfFileName;
   
    OMOperatingUnit             OMOperatingUnit;

    FileName                    fileName; 
   
    #File

    dialog = new Dialog("Pick the file");
    dfFileName = dialog.addField(extendedTypeStr("FilenameOpen"));
    dialog.filenameLookupFilter(["All files", #AllFiles]);
    
    if (dialog.run())
    {
        csvFile = new CommaTextIo(dfFileName.value(), 'r');
        csvFile.inFieldDelimiter(',');

        ttsBegin;
        while (csvFile.status() == IO_Status::Ok)
        {
            readCon = csvFile.read();

            OMOperatingUnit.clear();
            
            OMOperatingUnit.OMOperatingUnitNumber = conPeek(readCon,1); //"OU_4771"
            OMOperatingUnit.Name = conPeek(readCon,2); //"Accounting"
            OMOperatingUnit.NameAlias = conPeek(readCon,2); //"Accounting"
            OMOperatingUnit.OMOperatingUnitType  = OMOperatingUnitType::OMDepartment; //Department;
            OMOperatingUnit.LanguageId = 'en-us'; //language
            OMOperatingUnit.insert();
        }

        ttsCommit;
    }
   
}

Import Customer into AX 2012 using X++ with Address and Contact information

static void UploadCustomer(Args _args)
{
    CommaTextIO         csvFile;
    container                   readCon;
    counter                     icount,inserted;
    Dialog                      dialog;
    DialogField               dfFileName;


    FileName                    fileName;
     Name                        name;

    DirPartyContactInfoView     contactView;
    CustTable                            CustTable;
    DirParty                               dirParty;
    DirPartyRecId                      partyRecId;

    LogisticsPostalAddress        address;
    DirPartyPostalAddressView addressView;

    inserted =0;

    #File


    dialog = new Dialog("Pick the file");
    dfFileName = dialog.addField(extendedTypeStr("FilenameOpen"));
    dialog.filenameLookupFilter(["All files", #AllFiles]);


    if (dialog.run())
    {
        csvFile = new CommaTextIo(dfFileName.value(), 'r');
        csvFile.inFieldDelimiter(',');
        readCon = csvFile.read();
        ttsBegin;
        while(csvFile.status() == IO_Status::OK)
        {
            readCon = csvFile.read();

            if(readCon)
            {
                icount++;

                name = conPeek(readCon,2);
                partyRecId = DirPartyTable::createNew( DirPartyType::Organization, name).RecId;

                custTable.clear();
                custTable.initValue();
                custTable.Party      = partyRecId;
                custTable.AccountNum = conPeek(readCon,1);
                custTable.CustGroup  = conPeek(readCon,3);
                custTable.Currency   = conPeek(readCon,7);
                custTable.DlvMode    = conPeek(readCon,8);
                custTable.PaymTermId = conPeek(readCon,9);
                custTable.insert();

                custTable = Custtable::find(conPeek(readCon,1));
                partyRecId = custTable.Party;

                DirParty = DirParty::constructFromPartyRecId(partyRecId );
                address.clear();
                //address.PostBox = strLRTrim(conPeek(readCon,13));
                address.CountryRegionId = strLRTrim(conPeek(readCon,5));
                if( address.CountryRegionId != "")
                {
                    address.State = strLRTrim(conPeek(readCon,15));
                    address.ZipCode = strLRTrim(conPeek(readCon,15));
                    address.Street  = strLRTrim(conPeek(readCon,4));
                    address.City    = strLRTrim(conPeek(readCon,18));
                    
                    //address.Address =  conPeek(readCon,4);
    
                    addressView.LocationName = "Address";
                    addressView.IsPrimary = NoYes::Yes;
                    addressView.Party = partyRecId;
                    addressview.initFromPostalAddress(address);


                    DirParty = DirParty::constructFromPartyRecId(addressView.Party );
                    DirParty.createOrUpdatePostalAddress(addressView);
                }

                contactView.clear();

                if(conPeek(readCon,5) != "")
                {
                    contactView.LocationName = "Phone Number";
                    contactView.Locator      = strLRTrim(conPeek(readCon,5));
                    contactView.Type         = LogisticsElectronicAddressMethodType::Phone;
                    contactView.Party        = partyRecId;
                    contactView.IsPrimary    = NoYes::Yes;
                    dirParty.createOrUpdateContactInfo(contactView);
                }

                if(conPeek(readCon,3) != "")
                {
                    contactView.LocationName = "Fax Number";
                    contactView.Locator      = strLRTrim(conPeek(readCon,3));
                    contactView.Type         = LogisticsElectronicAddressMethodType::Fax;
                    contactView.Party        = partyRecId;
                    contactView.IsPrimary    = NoYes::Yes;
                    dirParty.createOrUpdateContactInfo(contactView);
                }

                if(conPeek(readCon,4) != "")
                {
                    contactView.LocationName = "Website";
                    contactView.Locator      = strLRTrim(conPeek(readCon,4));
                    contactView.Type         = LogisticsElectronicAddressMethodType::URL;
                    contactView.Party        = partyRecId;
                    contactView.IsPrimary    = NoYes::Yes;
                    dirParty.createOrUpdateContactInfo(contactView);
                }

                if(conPeek(readCon,6) != "")
                {
                    contactView.LocationName = "Email";
                    contactView.Locator      = strLRTrim(conPeek(readCon,6));
                    contactView.Type         = LogisticsElectronicAddressMethodType::Email;
                    contactView.Party        = partyRecId;
                    contactView.IsPrimary    = NoYes::Yes;
                    dirParty.createOrUpdateContactInfo(contactView);
                }

            }

        }
        ttsCommit;
    }

}

Importing Fixed Asset Value Model in AX 2012 using X++

static void FixedAssetValueModelUpload(Args _args)
{

    SysExcelApplication             application;
    SysExcelWorkbooks               workbooks;
    SysExcelWorkbook                workbook;
    SysExcelWorksheets              worksheets;
    SysExcelWorksheet               worksheet;
    SysExcelCells                   cells;
    COMVariantType                  type;

    FilenameOpen                    filename;
    dialogField                     dialogFilename;

    Dialog                          dialog;

    itemId                          itemId;
    Dialog                          d;
    DialogField                     df1;
    CommaTextIo                     file;
    container                       rec;
    BudgetTransactionHeader         BudgetTransactionHeader;
    BudgetTransactionLine           BudgetTransactionLine;
    ledgerAccountContract           ledgerAccountContract;
    assetBook                       assetBook;
    PurchTable                      purchTable;


    int                             i,num,coun,lineCount = 1;
    Integer                         row = 1;
    str                             ledgerAcc,departmentval,event,service,phase,department;
    AssetTable                      assetTable;
    NumberSeq assetIdNumberSeq;
    NumberSequenceTable numberSequenceTable;
    NumberSequenceReference numberSequenceReference;
    Struct                      struct;

    DimensionDefault            DimensionDefault;
     container   ledgerDimension;
    //int i;


    //(PYLVacation).VacationTransId



    str COMVariant2Str(COMVariant _cv,int _decimals = 0, int _characters = 0, int _separator1 = 0, int _separator2 = 0)
    {
        switch (_cv.variantType())
        {
            case (COMVariantType::VT_BSTR):
                return _cv.bStr();

            case (COMVariantType::VT_R8):
                return num2str(_cv.double(),_characters,_decimals,_separator1,_separator2);

            case (COMVariantType::VT_DATE):
                return date2str(_cv.date(),123,2,1,2,1,4);

            case (COMVariantType::VT_EMPTY):
                return '';

            default:
                throw error(strfmt("@SYS26908", _cv.variantType()));
        }
    }
   ;

    dialog              =   new Dialog('Budget Upload');
    dialogFilename      =   dialog.addField(ExtendedTypeStr("FilenameOpen"));

    dialog.filenameLookupTitle('Import from excel.');
    dialog.caption('Import From Excel');
    //dialog.addText("This is to import General Journal Account Entry records directly\n");
    //dialog.addText("Following are mandatory in the display value :\n1. MainAccount\n2. LineOfBusiness Dimension\n3. Investment Dimension\n4. Department dimension is optional").displayHeight(6);
    //dialog.addText("Template order:\n");
    //dialog.addText(strFmt("%1\n%2\n%3\n%4\n","DisplayValue","AccountingCurrencyAmount","GeneralJournalEntryRecid","Currency Code - Hardcoded here")).displayHeight(15);

    dialogFilename.value(filename);

    if(dialog.run())
    {
        filename            =   dialogFilename.value();

        application         =   SysExcelApplication::construct();
        workbooks           =   application.workbooks();

        try
        {
            workbooks.open(filename);
        }
        catch (Exception::Error)
        {
            throw error('File cannot be opened.');
        }

        workbook            =   workbooks.item(1);
        worksheets          =   workbook.worksheets();
        worksheet           =   worksheets.itemFromNum(1);
        cells               =   worksheet.cells();

        try
        {
            ttsbegin;
            do
            {
                row++;
                type = cells.item(row+1, 1).value().variantType();
                //ledgerAcc = (COMVariant2Str(cells.item(row, 5).value()));
                //departmentval = (COMVariant2Str(cells.item(row, 6).value()));
                //service  = (COMVariant2Str(cells.item(row, 7).value()));
                //event = (COMVariant2Str(cells.item(row, 8).value()));
                assetIdNumberSeq = assetTable.initAssetNumberSeq((COMVariant2Str(cells.item(row, 1).value())));

                if (assetIdNumberSeq)
                {

                assetTable.AssetId = assetIdNumberSeq.num();
                assetIdNumberSeq.used();

                }

                assetTable.AssetGroup = (COMVariant2Str(cells.item(row, 1).value()));
                assetTable.Name = (COMVariant2Str(cells.item(row, 3).value()));
                assetTable.NameAlias = (COMVariant2Str(cells.item(row, 3).value()));
                assetTable.AssetType = AssetType::Tangible;
                assetTable.PropertyType = AssetPropertyType::FixedAsset;
                assetTable.Quantity = 1;//((cells.item(row, 8).value().double()));
                assetTable.UnitOfMeasure = "PIECE";//(COMVariant2Str(cells.item(row, 8).value()));
                assetTable.UnitCost = ((cells.item(row, 5).value().double()));
                //assetTable.Location = (COMVariant2Str(cells.item(row, 8).value()));
                assettable.insert();


                //assetid = conPeek(readCon,1);
                //bookid = conPeek(readCon,2);
                assetBook.clear();

                assetBook = AssetBook::find(assetTable.AssetId,"ALL",true);
                select forUpdate assetBook where assetBook.AssetId == assetTable.AssetId;

                if(!assetBook)
                {
                    info(strFmt("%1",assetTable.AssetId));
                    continue;
                }
                assetBook.AssetGroup = (COMVariant2Str(cells.item(row, 1).value()));
                assetBook.Status = AssetStatus::NoAcquisition;
                department = (COMVariant2Str(cells.item(row, 6).value()));
                Event= (COMVariant2Str(cells.item(row, 7).value()));
                Service = (COMVariant2Str(cells.item(row, 8).value()));
                phase = (COMVariant2Str(cells.item(row, 9).value()));

                struct = new Struct();
                struct.add('Department',(COMVariant2Str(cells.item(row, 6).value())));
                struct.add('Event', (COMVariant2Str(cells.item(row, 7).value())));
                struct.add('Phase', (COMVariant2Str(cells.item(row, 8).value())));
                struct.add('Service', (COMVariant2Str(cells.item(row, 9).value())));

                ledgerDimension = conNull();
                ledgerDimension += struct.fields();

                for (i = 1; i <= struct.fields(); i++)
                {
                    ledgerDimension += struct.fieldName(i);
                    ledgerDimension += struct.valueIndex(i);
                }

                DimensionDefault = AxdDimensionUtil::getDimensionAttributeValueSetId(ledgerDimension);
                assetBook.DefaultDimension = DimensionDefault;
                assetBook.PostingProfile        = "FA";//Confirm for other companies
                assetBook.Depreciation          = NoYes::Yes;

                //assetBook.LifeTime              = conPeek(readCon,12);
                //assetBook.DepreciationStartDate = str2Date(conPeek(readCon,13),213);

                assetBook.AcquisitionPrice      = (cells.item(row, 5).value().double());
                assetBook.AcquisitionDate       =  str2date(COMVariant2Str(cells.item(row, 4).value()),123);
                //assetBook.UsedFromDate          =  str2Date(conPeek(readCon,17),213);
                //assetBook.ServiceLife           = conPeek(readCon,18);
                PurchTable  = PurchTable::find((COMVariant2Str(cells.item(row, 13).value())));
                assetBook.PurchId = (COMVariant2Str(cells.item(row, 13).value()));
                assetBook.VendAccount           = PurchTable.OrderAccount;
                assetBook.VendInvoiceId  = COMVariant2Str(cells.item(row, 11).value());
                assetBook.update();

                num++;
                info(strFmt("%1^%2^%3^%4^%5^%6^%7^%8^%9^%10^%11^%12^%13^%14^%15",num,assetBook.AssetId,assetTable.Name,assetTable.Quantity,assetTable.UnitCost,assetTable.UnitOfMeasure,department,event,phase,service,
                assetBook.AcquisitionPrice,assetBook.AcquisitionDate,assetBook.PurchId,assetBook.VendAccount,assetBook.VendInvoiceId));

                coun++;
                print(coun);


            } // do

          // info(strFmt(" %1 Records Updated", num));

            while (type != COMVariantType::VT_EMPTY);
                    info(strFmt("No of records updated - %1",num));
            ttscommit;
            application.quit();
        }// try
        catch
        {
            throw error('Error in Update.');
        }
    }
    pause;
}

Importing Product Master into AX 2012 using X++ job

static void UploadProductMaster(Args _args)
{
    CommaTextIO         csvFile;
    container                  readCon;
    counter                     icount,inserted;
    Dialog                      dialog;
    DialogField             dfFileName;
    FileName                 fileName;

    InventTable                            inventTable;
    EcoResProduct                      ecoResProduct;
    EcoResProductMaster          EcoResProductMaster;
    EcoResProductTranslation  ecoResProductTranslation;    
    InventModelGroupItem        InventModelGroupItemLoc;
    
    EcoResDistinctProductVariant                    EcoResDistinctProductVariant;   
    EcoResProductDimensionGroupProduct  ecoResProductDimensionGroupProduct;
    EcoResStorageDimensionGroupItem         ecoResStorageDimensionGroupItem;
    EcoResTrackingDimensionGroupItem       ecoResTrackingDimensionGroupItem;
    EcoResStorageDimensionGroupProduct   ecoResStorageDimensionGroupProduct;
    EcoResTrackingDimensionGroupProduct ecoResTrackingDimensionGroupProduct;
    
    InventTableModule           inventTableModule;
    inventItemGroupItem         inventItemGroupItem;
    InventItemSetupSupplyType   inventItemSetupSupplyType;
    ecoResProductIdentifier     ecoResProductIdentifier;
    

    ItemId                      itemID ;
    str       name,Description,itemtype,productDimensionGroup,StorageDimensionGroup,TrackingDimensiongroup,modelGroupId,itemGroupId,unit,price,searchname;
    
    inserted =0;
    #File


    dialog = new Dialog("Pick the file");
    dfFileName = dialog.addField(extendedTypeStr("FilenameOpen"));
    dialog.filenameLookupFilter(["All files", #AllFiles]);


    if (dialog.run())
    {
        csvFile = new CommaTextIo(dfFileName.value(), 'r');
        csvFile.inFieldDelimiter(',');
        readCon = csvFile.read();
        ttsBegin;
        while(csvFile.status() == IO_Status::OK)
        {
            readCon = csvFile.read();

            if(readCon)
            {
                icount++;

                itemId                = "ABC9";//conPeek(readCon,1); 
                name                  = "ABC9name";//conPeek(readCon,2);
                searchname      = "searchname";
                Description      = "DEscription";
                itemtype            = "BOM";
                productDimensionGroup   = "PG_4";//conPeek(readCon,3);
                StorageDimensionGroup   = "PDG_001";//conPeek(readCon,4);
                TrackingDimensiongroup  = "PDG_001";//conPeek(readCon,5);
                modelGroupId    = "FIFO";//conPeek(readCon,6);
                itemGroupId     = "Television";//conPeek(readCon,7);
                unit            = "ea";//conPeek(readCon,8);
                price           = "0";//conPeek(readCon,9);
                
                 select firstOnly ecoResProduct where EcoResProduct.DisplayProductNumber == itemId; 

                if(!ecoResProduct)
                {
                    EcoResProductMaster.initValue();
                    EcoResProductMaster.DisplayProductNumber = itemId;
                    EcoResProductMaster.SearchName = searchname;
                    EcoResProductMaster.ProductType = EcoResProductType::Item;
                    EcoResProductMaster.VariantConfigurationTechnology = EcoResVariantConfigurationTechnologyType::PredefinedVariants;
                    EcoResProductMaster.insert();
                    ecoResProduct= EcoResProductMaster;
                }

                ecoResProductTranslation.Product = ecoResProduct.RecId;
                ecoResProductTranslation.Name = name;
                EcoResProductTranslation.Description = Description;
                ecoResProductTranslation.setDefaultLanguage();
                ecoResProductTranslation.insert();

                EcoResDistinctProductVariant.DisplayProductNumber = itemId ;
                EcoResDistinctProductVariant.ProductMaster = ecoResProduct.RecId;
                EcoResDistinctProductVariant.ProductType = ecoResProduct.ProductType;
                EcoResDistinctProductVariant.insert();

                inventTable.initValue();
                inventTable.initFromEcoResProduct(ecoResProduct);
                inventTable.ItemId = itemId;
                inventTable.NameAlias = ecoResProduct.SearchName;
                if(ItemType == "BOM")
                    inventTable.PmfProductType = PmfProductType::BOM;
                else
                    inventTable.PmfProductType = PmfProductType::None;
                inventTable.insert(true);

                inventTableModule.initValue();
                inventTableModule.ItemId = inventTable.ItemId;
                inventTableModule.ModuleType = ModuleInventPurchSales::Invent;
                InventTableModule.UnitId = unit;
                InventTableModule.Price = any2real(Price);
                inventTableModule.insert();

                inventTableModule.initValue();
                inventTableModule.ItemId = inventTable.ItemId;
                inventTableModule.ModuleType = ModuleInventPurchSales::Purch;
                InventTableModule.UnitId = unit;
                InventTableModule.Price =  any2real(Price);
                inventTableModule.insert();

                inventTableModule.initValue();
                inventTableModule.ItemId = inventTable.ItemId;
                inventTableModule.ModuleType = ModuleInventPurchSales::Sales;
                InventTableModule.UnitId = unit;
                InventTableModule.Price = any2real(Price);
                inventTableModule.insert();

                //Create inventItemLocation
                InventItemLocation::createDefault(inventTable.ItemId);

                // Creates a new item default order type for the product that is released.

                inventItemSetupSupplyType.initValue();
                inventItemSetupSupplyType.ItemId = inventTable.ItemId;
                inventItemSetupSupplyType.ItemDataAreaId = inventTable.DataAreaId;
                inventItemSetupSupplyType.insert();

                //create relationship tables to dimension groups.

                ecoResStorageDimensionGroupProduct = EcoResStorageDimensionGroupProduct::findByProduct(ecoResProduct.RecId);
                ecoResTrackingDimensionGroupProduct = EcoResTrackingDimensionGroupProduct::findByProduct(ecoResProduct.RecId);

                if (ecoResStorageDimensionGroupProduct.RecId)
                {
                    // mandatory storage dimension group for the product
                    ecoResStorageDimensionGroupItem.ItemDataAreaId = inventTable.DataAreaId;
                    ecoResStorageDimensionGroupItem.ItemId = inventTable.ItemId;
                    ecoResStorageDimensionGroupItem.StorageDimensionGroup = ecoResStorageDimensionGroupProduct.StorageDimensionGroup;
                    ecoResStorageDimensionGroupItem.insert();
                }

                if (ecoResTrackingDimensionGroupProduct.RecId)
                {
                    // mandatory tracking dimension group for the product
                    ecoResTrackingDimensionGroupItem.ItemDataAreaId = inventTable.DataAreaId;
                    ecoResTrackingDimensionGroupItem.ItemId = inventTable.ItemId;
                    ecoResTrackingDimensionGroupItem.TrackingDimensionGroup = ecoResTrackingDimensionGroupProduct.TrackingDimensionGroup;
                    ecoResTrackingDimensionGroupItem.insert();
                }


                InventModelGroupItemLoc.ItemDataAreaId = inventTable.dataAreaId;
                InventModelGroupItemLoc.ItemId = inventTable.ItemId;
                InventModelGroupItemLoc.ModelGroupId =modelGroupId;
                InventModelGroupItemLoc.ModelGroupDataAreaId = curext();
                InventModelGroupItemLoc.initValue();
                InventModelGroupItemLoc.insert();

                 //Item group
                inventItemGroupItem.clear();
                inventItemGroupItem.initValue();
                inventItemGroupItem.ItemDataAreaId = inventTable.dataAreaId;
                inventItemGroupItem.ItemId = inventTable.ItemId;
                inventItemGroupItem.ItemGroupId = itemGroupId;
                inventItemGroupItem.ItemGroupDataAreaId = curext();
                inventItemGroupItem.insert();

                //write product to dimension group relation
                ecoResProductDimensionGroupProduct.initFromProduct(ecoResProduct);
                ecoResProductDimensionGroupProduct.ProductDimensionGroup = EcoResProductDimensionGroup::findByDimensionGroupName(productDimensionGroup).RecId;// "PG_4";
                ecoResProductDimensionGroupProduct.insert();

                ecoResStorageDimensionGroupItem.initValue();
                ecoResStorageDimensionGroupItem.ItemDataAreaId = inventTable.dataAreaId;
                ecoResStorageDimensionGroupItem.ItemId = inventTable.ItemId;
                ecoResStorageDimensionGroupItem.StorageDimensionGroup = EcoResStorageDimensionGroup::findByDimensionGroupName(StorageDimensionGroup).RecId;
                ecoResStorageDimensionGroupItem.insert();

                ecoResTrackingDimensionGroupItem.initValue();
                ecoResTrackingDimensionGroupItem.ItemDataAreaId = inventTable.dataAreaId;
                ecoResTrackingDimensionGroupItem.ItemId = inventTable.ItemId;
                ecoResTrackingDimensionGroupItem.TrackingDimensionGroup = EcoResTrackingDimensionGroup::findByDimensionGroupName(TrackingDimensiongroup).RecId;
                ecoResTrackingDimensionGroupItem.insert();
                
                ecoResProductIdentifier.clear();
                ecoResProductIdentifier.initValue();
                ecoResProductIdentifier.ProductNumber = itemId;
                ecoResProductIdentifier.Product = EcoResProductMaster.RecId; //ecoResProductMaster.RecId;
                ecoResProductIdentifier.insert();
                
            }

        }
        ttsCommit;
    }

}