Search This Blog

Thursday, December 4, 2014

Get Multiple files from Folder

static container Krishh_findMatchingFiles(str _folderPath,   str _filePattern   = '*.*')
{
    System.IO.DirectoryInfo     directory;
    System.IO.FileInfo[]        files;
    System.IO.FileInfo          file;
    InteropPermission           permission;

    str         fileName;
    counter     filesCount;
    counter     loop;
    container   mathchingFiles;
    ;

    permission  = new InteropPermission(InteropKind::ClrInterop);
    permission.assert();

    directory   = new System.IO.DirectoryInfo(_folderPath);
    files       = directory.GetFiles(_filePattern);
    filesCount  = files.get_Length();

    for (loop = 0; loop < filesCount; loop++)
    {
        file            = files.GetValue(loop);
        fileName        = file.get_FullName();
        mathchingFiles  = conins(mathchingFiles, conlen(mathchingFiles) + 1, fileName);
    }

    CodeAccessPermission::revertAssert();

    return mathchingFiles;
}

I placed the above method in Global class, so we can use that in your classes.
Make sure your folder should have access permissions when you are running in the batch.


static void Krishh_fetchFiles(Args _args)
{
    container   files;
    counter     loop;
    str         fileName;
    ;
   //Assign the folder path with the file pattern if you want to filter by ex *.txt or k*.txt or m*.*..etc.
    files = Global::Krishh_findMatchingFiles(AxdDocumentParameters::find().PaymJournalFile);

    for (loop = 1; loop <= conlen(files); loop++)
    {
        fileName = conpeek(files, loop);
        info(fileName);
    }


}

Friday, July 25, 2014

Useful functions to use in AX2012

public static container list2Con (List _list)
{
    container con;
    ListEnumerator listEnum;

    listEnum = _list.getEnumerator();

    while (listEnum.moveNext())
    {
        con += listEnum.current();
    }

    return con;
}

///Creates a file named _file with the content specified in _content parameter.
//See the class SysImportUtil class for file related functions like get temfolder,tempfilename..etc.
public static void createFile(str _file, str _content)
{
    #File
    TextIo file = null;
    ;
    new FileIOPermission(_file, #io_write).assert();

    // BP Deviation Documented
    file = new TextIo(_file, #io_write);
    file.write(_content);
    file.finalize();
}

///Creates an XML file named _file with the content specified in _content parameter. If the XML file
///can't be created then it will try to create a normal file by calling createFile method.
public static void createXmlFile(str _file, str _content)
{
    #File

    XmlDocument document = null;
    ;
    try
    {
        document = XmlDocument::newXml(_content, false);

        new FileIOPermission(_file, #io_write).assert();
        // BP Deviation Documented
        document.save(_file);
    }
    catch
    {
        SysImportUtil::createFile(_file, _content);
    }
}

///Reads an XML file specified by _file parameter.
public static str readXmlFile(str _file)
{
    #File

    XmlDocument file = null;
    ;
    try
    {
        new FileIOPermission(_file, #io_read).assert();
        // BP Deviation Documented
        file = XmlDocument::newFile(_file);
        return file.xml();
    }
    catch
    {
        return '';
    }
}

/// <summary>
/// Opens Bing maps with the address.
/// </summary>
/// <param name="_address">
/// The address to map.
/// </param>
public static void mapIt(LogisticsPostalAddress _address)
{
    #DEFINE.MapURL('http://maps.bing.com/default.aspx?where1=\%1')
    #DEFINE.comma(',')
    #DEFINE.newLine('\n')

    str     address;
    ;
    if (_address)
    {
        address = _address.Street + #comma +
                  _address.City + #comma +
                  _address.State + #comma +
                  _address.ZipCode + #comma +
                  _address.CountryRegionId;

        // Replace the newline with comma
        address = strReplace(address, #newline, #comma);
        // URL encode
        address = System.Web.HttpUtility::UrlEncode(address);
        // Add the address to the URL
        infolog.urlLookup(strFmt(#MapURL, address));
    }
}



/// <summary>
/// Function to get the list of Tables in AOT
/// </summary>
/// <returns>
/// In case the table is derived its parent i.e. base table is appended to it delimited by comma (,)
/// Output example
/// :Table1,Table1's Base Table : Table2 : Table3 : Table4 , Table4's Base Table
/// </returns>
static str getAOTTables()
{
    TreeNode            node;
    TreeNode            childNode;
    TreeNodeIterator    nodeIt;
    FilePath            path;
    TableId             tableId;
    Dictionary      dict = new Dictionary();
    str parentName;
    str fieldArr;

    path        = @'\Data dictionary\Tables';
    node        = TreeNode::findNode(path);
    nodeIt      = node.AOTiterator();
    childNode   = nodeIt.next();
    fieldArr ='';
    while(childNode)
    {
        tableId = tableName2id(childNode.treeNodeName());

        if ( !dict.tableObject(tableId).isTmp()  && !dict.tableObject(tableId).isMap() && !dict.tableObject(tableId).isView())
        {
            parentName = RetailUtils::getAOTTableParentName(tableId);
            if (parentName)
            {
                //Creating formated output , refer explaination and example on header
                fieldArr = fieldArr + ':' + strUpr(childNode.treeNodeName()) + "," + strUpr(parentName);
            }
            else
            {
                fieldArr = fieldArr + ':' + strUpr(childNode.treeNodeName());
            }
        }
        childNode = nodeIt.next();
    }
    return fieldArr;
}


/// <summary>
/// This method receives a table id and find the corresponding Base Table from AOT
/// This method takes care of Multilevel inheritence
/// </summary>
/// <param name="tableid">
/// tableid of derived table.
/// </param>
/// <returns>
/// Name of parent table.
/// </returns>
static str getAOTTableParentName(TableId tableid)
{
    Dictionary  dict = new Dictionary();
    TableId parentId, temp;
    str result;

    parentId = dict.tableObject(tableid).extends();

    // Loop until reached to the table for whcih Extends property is not defined
    while (parentId)
    {
        temp = dict.tableObject(parentId).extends();
        if (temp)
        {
            parentId = temp;
        }
        else
        {
            break;
        }
    }

    if (parentId)
    {
        result = tableId2name(parentId);
    }
    else
    {
        result = '';
    }
    return result;
}


/// <summary>
/// Function to accepts a table name and returns all its field
/// </summary>
/// <param name="tableName">
/// Table name for which field are to be retreived.
/// </param>
/// <returns>
/// Field are arranged in a : delimited string and passed back
/// Fields are read from AOT structure and defaults field are manually added
/// as those are not present in the tree structure
/// Example =  :Field1:Field2:Field3:Field4
/// </returns>
static str getAOTTableFields(str tableName)
{
    TreeNode            node;
    TreeNode            childNode;
    TreeNodeIterator    nodeIt;
    FilePath            path;
    TableId             tableId;
    str fieldArr;
    Dictionary      dict = new Dictionary();
    fieldArr = '';

    if (!tableName)
    {
        return fieldArr;
    }

    // Construct the path till table fields node
    path        = @'\Data dictionary\Tables\\' + tableName + '\\Fields' ;
    node        = TreeNode::findNode(path);
    nodeIt      = node.AOTiterator();
    childNode   = nodeIt.next();

    while(childNode)
    {
        fieldArr =  fieldArr + ':' + strUpr(childNode.treeNodeName());
        childNode = nodeIt.next();
    }

    tableId = tableName2id(tableName);
    if (dict.tableObject(tableId).dataPrCompany())
    {
        //Append the default Fields
        fieldArr =  fieldArr + ':' + 'DATAAREAID';
    }

    if (dict.tableObject(tableId).dataPerPartition())
    {
        fieldArr =  fieldArr + ':' + 'PARTITION';
    }

    return fieldArr;
}




// get enum values to container
static void Enum2container(Args _args)
{
   
    int         i = 0;
    DictEnum    dimCode;
    container   ret;
    ;

    dimCode = new DictEnum(enumnum(SysDimension));
    while(i < dimCode.values())
    {
        ret += dimCode.index2Name(i);
        i++;
    }
    info(strfmt("%1",con2Str(ret)));
}

public static boolean checkDateIsInPeriod(TransDate _transDate,
                                            PeriodCode  _periodCode = PeriodCode::Regular)
{
    return BudgetTransactionManager::validateTransactionDate(_transDate);
}


// New method for returning ledgerperiod last date
static transDate findLastOpenPeriod(transdate _ledgerTransDate)
{
    FiscalCalendarRecId     fiscalCalendarRecId;

    fiscalCalendarRecId = Ledger::fiscalCalendar(CompanyInfo::find().RecId);
    return FiscalCalendars::findLastDayofPeriod( fiscalCalendarRecId, _ledgerTransDate);
}

// New method for returning first open ledgerperiod first date
static transDate findFirstOpenPeriod(transdate _ledgerTransDate)
{
    FiscalCalendarRecId     fiscalCalendarRecId;

    fiscalCalendarRecId = Ledger::fiscalCalendar(CompanyInfo::find().RecId);
    return FiscalCalendars::findFirstDayofPeriod( fiscalCalendarRecId, _ledgerTransDate);

}


//Calculate Hash for the string.
public static str CalculateHash(str tb)
{

    str s;
    ClrObject obj;
    ClrObject md5;
    System.Text.StringBuilder sBuilder;
    ClrObject clrStr;
    ClrObject clrStrObject;
    System.Exception clrException;
    System.Array resultByteArray;
    int i;
    int arrayLength ;
    InteropPermission perm;

    perm = new InteropPermission(InteropKind::ClrInterop);
    perm.assert();
    try
    {
        obj = System.Text.Encoding::get_ASCII().GetBytes(tb);
        md5 = System.Security.Cryptography.MD5::Create();
        resultByteArray = md5.ComputeHash(obj);
        //BP deviation documented
        sBuilder = new System.Text.StringBuilder();
        arrayLength = resultByteArray.get_Length() ;
        // Loop through each byte of the hashed data
        // and format each one as a hexadecimal string.
        for (i = 0; i <arrayLength; i++)
        {
            clrStrObject = resultByteArray.GetValue(i);
            clrStr = clrStrObject.ToString('x2');
            sBuilder.Append(clrStr);
        }

        // Return the hexadecimal string.
        s = sBuilder.ToString();
    }
    catch (Exception::CLRError)
    {
        //BP deviation documented
        clrException = CLRInterop::getLastException();
        s = clrException.get_Message();
        error(s);
        throw error("@SYS106158");
    }

    CodeAccessPermission::revertAssert();
    return s;

}


//Transforms xml to another format of xml using xslt.
public static str transform(str aifXml, str xsltResourceName)
{
    #define.XsltArgumentList("System.Xml.Xsl.XsltArgumentList")
    #AOT

    ResourceNode resourceNode;
    TreeNode resourcesNode;
    container data;
    str xsltString;
    str doXml;

    System.Xml.Xsl.XslCompiledTransform transform;
    System.Text.StringBuilder           stringBuilder;
    System.IO.StringWriter              stringWriter;
    System.IO.StringReader              stringReader;
    System.Xml.XmlTextReader            xmlTextReader;
    System.IO.StringReader              stringReaderForXslt;
    System.Xml.XmlTextReader            xmlTextReaderForXslt;
    System.Xml.Xsl.XsltArgumentList     xsltArguments;
    System.IDisposable                  disposableObj;

    ;
    // Get the top Resource node in the AOT
    resourcesNode = infolog.findNode(#ResourcesPath);

    if (resourcesNode)
    {
        // Get the XML string holding the data from the resource item
        resourceNode = resourcesNode.AOTfindChild(xsltResourceName);
        if (resourceNode)
        {
            resourceNode.AOTload();
            data = SysResource::getResourceNodeData(resourceNode);
            xsltString = conpeek(data, 1);

        }
    }
    try
    {
        //Local XSLT
        transform = new System.Xml.Xsl.XslCompiledTransform();
        stringReaderForXslt = new System.IO.StringReader(xsltString);
        xmlTextReaderForXslt = new System.Xml.XmlTextReader(stringReaderForXslt);
        transform.Load(xmlTextReaderForXslt);

        //Transform the input AIF XML
        stringReader = new System.IO.StringReader(aifXml);
        xmlTextReader = new System.Xml.XmlTextReader(stringReader);
        stringBuilder = new System.Text.StringBuilder();
        stringWriter = new System.IO.StringWriter(stringBuilder);

        xsltArguments = ClrInterop::Null(#XsltArgumentList);

        transform.Transform(xmlTextReader, xsltArguments, stringWriter);

        doXml = stringBuilder.ToString();
    }
    catch (Exception::CLRError)
    {
        throw Global::error(ClrInterop::getLastException().toString());
    }

    if (!ClrInterop::isNull(xmlTextReaderForXslt))
    {
        disposableObj = xmlTextReaderForXslt;
        disposableObj.Dispose();
    }

    if (!ClrInterop::isNull(stringReaderForXslt))
    {
        disposableObj = stringReaderForXslt;
        disposableObj.Dispose();
    }

    if (!ClrInterop::isNull(xmlTextReader))
    {
        disposableObj = xmlTextReader;
        disposableObj.Dispose();
    }

    if (!ClrInterop::isNull(stringReader))
    {
        disposableObj = stringReader;
        disposableObj.Dispose();
    }

    if (!ClrInterop::isNull(stringWriter))
    {
        disposableObj = stringWriter;
        disposableObj.Dispose();
    }

    return doXml;
}




//Converts from string to Time.
static int str2Time(str 8 _timeStr)
{
    int     time;
    ;

    time += str2int(substr(_timeStr,0,2)) * 3600;
    time += str2int(substr(_timeStr,4,2)) * 60;
    time += str2int(substr(_timeStr,7,2));

    return time;
}

//This function is used to get xml string from xml file.
static public str getXMLstringFromFile(str _filepath)
{
    str xmlstring='';
    XmlDocument document=new XmlDocument();
    document.load(_filepath);
    xmlstring=document.innerXml();
    return xmlstring;
}

// this function is used to convert string to array.
public static Array str2array(str _inputString, str _delimiter = '","')
{
    List            list        = AmcBankFunctions::strSplit(_inputString, _delimiter);
    ListEnumerator  enumerator  = list.getEnumerator();

    Array           a           = new Array(Types::String);
    int             i           = 1;
    str             tmpString;
    ;

    if (strLen(_inputString) == 0 || strScan(_inputString, _delimiter, 1, strLen(_inputString)) == 0)
        return a; // this is not a XTL record
    enumerator.reset();
    while (enumerator.moveNext())
    {
        tmpString = enumerator.current();

        // Removes first substring's preceding " and last substring's succeeding "
        if (strLen(tmpString) > 0)
        {
            if (i == 1 && tmpString)
                tmpString = subStr(tmpString, 2, strLen(tmpString));
            if (i == list.elements())
                tmpString = subStr(tmpString, 1, strLen(tmpString)-1);
        }

        a.value(i, tmpString);
        i++;
    }

    return a;
}


/// <summary>
///     Prefixes a string with a parameter provided character
/// </summary>
/// <param name="inputString">
///     The integer that is to be converted into a string
/// </param>
/// <param name="outputStringLength">
///     The length of the final string being returned
/// </param>
/// <param name="prefixWithChar">
///     The character which to prefix the output string with
/// </param>
/// <returns>
///     The converted integer as a string with the parameter provided length (possible prefixed with provided

char)
/// </returns>
public static str prefixString(str inputString, int outputStringLength, str 1 prefixWithChar)
{
    str outputString = inputString;

    if (prefixWithChar == '')
        return outputString;

    while (strLen(outputString) < outputStringLength)
    {
        outputString = prefixWithChar + outputString;
    }

    return outputString;
}


// to test that we have access right for the the file or folder.
public static client IO_Status writeFileAndClose(Filename filename)
{
    TextIo textIo;
    ;

    new FileIOPermission(filename,'rw').assert();

    textIo = new TextIo(filename,'w');

    if (textIo!=null)
        textIo.write('This is a test file for checking the access rights');

    CodeAccessPermission::revertAssert();

    if (textIo!=null)
        return textIo.status();

    return IO_Status::WriteError;
}


// send email using smtp
//Please change the parameters accordingly for your client
public static boolean emailSmtpSend(str         _receiver,
                                    str         _subject,
                                    str         _body,
                                    Filename    _attachment = '')
{
    AmcBankParameters                       amcBankParameters;

    System.Net.Mail.Attachment              attachment;
    System.Net.Mail.AttachmentCollection    attachmentCollection;
    System.Net.Mail.MailAddress             mailFrom;
    System.Net.Mail.MailAddress             mailTo;
    System.Net.Mail.MailMessage             mailMessage;
    System.Net.Mail.SmtpClient              smtpClient;
    ;

    if (!_receiver)
        return checkFailed("@ABA32081");

    amcBankParameters = AmcBankParameters::find();

    try
    {
        mailFrom    = new System.Net.Mail.MailAddress(amcBankParameters.SmtpSenderAddress);
        mailTo      = new System.Net.Mail.MailAddress(_receiver);
        mailMessage = new System.Net.Mail.MailMessage(mailFrom, mailTo);
        mailmessage.set_Subject(_subject);
        mailmessage.set_Body(_body);

        // Adding attachment
        if (_attachment)
        {
            attachment = new System.Net.Mail.Attachment(_attachment);
            attachmentCollection = mailMessage.get_Attachments();
            attachmentCollection.Add(attachment);
        }

        smtpClient = new System.Net.Mail.SmtpClient(amcBankParameters.SmtpServerName,

amcBankParameters.SmtpPortNumber);
        smtpClient.Send(mailmessage);

        info(strFmt("@SYS80635", _receiver));

        attachmentCollection.Dispose(); // Releases attachement resources (files)

    }
    catch (Exception::CLRError)
    {
        // If a CLR exception occurs it is important that the exceptions is shown (which it is not per default)
        error(CLRInterop::getLastException());
        attachmentCollection.Dispose(); // Releases attachement resources (files)

        return checkFailed(strFmt("@ABA32082",  _receiver));
    }
    catch
    {
        attachmentCollection.Dispose(); // Releases attachement resources (files)

        return checkFailed(strFmt("@ABA32082",  _receiver));
    }

    return true;
}


// archive the files.
public static void fileArchive(Filename _file, FilePath _archivePath)
{
    Filename            filenameArchive;

    InteropPermission   interopPermission = new InteropPermission(InteropKind::ClrInterop);
    Set                 interopPermissionSet = new Set(Types::Class);
    ;
    if (!_archivePath)
        return;

    // Granting file permission rights
    interopPermissionSet.add(interopPermission);
    CodeAccessPermission::assertMultiple(interopPermissionSet);

    filenameArchive = _archivePath + AmcBankFile::getFileNameAndExtension(_file);

    System.IO.File::Delete(filenameArchive);
    System.IO.File::Move(_file, filenameArchive);

    // Reverting file permission rights
    CodeAccessPermission::revertAssert();
}

// getting the filename and extesion in container.
public static Filename getFileNameAndExtension(Filename _filename)
{
    ;
    if (!_filename)
        return '';

    return strFmt('%1%2', conPeek(Global::fileNameSplit(_filename), 2),     // Filename
                          conPeek(Global::fileNameSplit(_filename), 3));    // File extension (including

prefixed dot (.))
}

//FolderExists
public static boolean folderExists(FilePath _directory)
{
    boolean             dirExists;

    InteropPermission   interopPermission = new InteropPermission(InteropKind::ClrInterop);
    Set                 interopPermissionSet = new Set(Types::Class);
    ;

    // Granting file permission rights
    interopPermissionSet.add(interopPermission);
    CodeAccessPermission::assertMultiple(interopPermissionSet);

    dirExists = System.IO.Directory::Exists(_directory);

    // Reverting file permission rights
    CodeAccessPermission::revertAssert();

    return dirExists;
}


/// <summary>
///  internal use only.
/// </summary>
/// <param name="text">
/// A String value.
/// </param>
/// <returns>
/// A String value.
/// </returns>
private str trimLeadingTabs(str text)
{
    int len = strlen(text);
    int start = 1;

    while ((start <= len) && (substr(text, start, 1) == '\t'))
        start++;

    text = substr(text, start, len - start + 1);

    return text;
}


/// <summary>
///  internal use only.
/// </summary>
/// <returns>
/// A String value.
/// </returns>
public static str getClrErrorMessage()
{
    #File
    str exceptionMessage;
    System.Exception exObject, innerException;
    ;

    new InteropPermission(InteropKind::ClrInterop).assert();

    // BP deviation documented
    exObject = CLRInterop::getLastException();
    if(exObject)
    {
        // We will ignore the first message since it is always a fixed message of
        // "Exception has been thrown from target of invocation", this is from the reflection API being used
        // "ClrObject could not be created." - This is also of no use in most cases
        innerException = exObject.get_InnerException();
        while(innerException)
        {
            // BP deviation documented
            exceptionMessage = exceptionMessage + #delimiterSpace + CLRInterop::getAnyTypeForObject

(innerException.get_Message());
            innerException = innerException.get_InnerException();
        }
    }

    CodeAccessPermission::revertAssert();

    return exceptionMessage;

}

//Parse date from string
public static date parseDate(str dateText)
{
    str dateTimeText;
    ClrObject dateTimeObject;
    utcdatetime dateTimeValue;
    date dateValue;


    dateTimeText = strFmt('%1T00:00:00Z', dateText);

    // BP Deviation Documented
    dateTimeObject = Microsoft.Dynamics.IntegrationFramework.Util::ParseXmlDateTime(dateTimeText, false);

    // If the returned object is null, then deserialization failed
    if (CLRInterop::isNull(dateTimeObject))
    {
        throw error(strfmt("@SYS112380", dateText, enum2str(Types::Date)));
    }

    dateTimeValue = CLRInterop::getAnyTypeForObject(dateTimeObject);

    // If the utcdatetime value is null, then the value is outside the valid range
    // unless the input was a null datetime
    if (dateTimeValue == utcDateTimeNull() && !AifUtil::isNullDateTime(dateTimeObject))
    {
        throw error(strfmt("@SYS112380", dateText, enum2str(Types::Date)));
    }

    dateValue = DateTimeUtil::date(dateTimeValue);

    return dateValue;
}

//Parse DateTime from string
public static utcdatetime parseDateTime(str dateTimeText, System.DateTimeKind expectedDateTimeKind)
{
    ClrObject dateTimeObject;
    utcdatetime dateTimeValue;
    System.DateTime systemDateTimeValue;

    // BP Deviation Documented
    dateTimeObject = Microsoft.Dynamics.IntegrationFramework.Util::ParseXmlDateTime(dateTimeText, false);

    // If the returned object is null, then deserialization failed
    if (CLRInterop::isNull(dateTimeObject))
    {
        throw error(strfmt("@SYS112380", dateTimeText, enum2str(Types::UtcDateTime)));
    }

    dateTimeValue = CLRInterop::getAnyTypeForObject(dateTimeObject);

    // If the utcdatetime value is null, then the value is outside the valid range
    // unless the input was a null datetime
    if (dateTimeValue == utcDateTimeNull() && !AifUtil::isNullDateTime(dateTimeObject))
    {
        throw error(strfmt("@SYS112380", dateTimeText, enum2str(Types::UtcDateTime)));
    }

    // If the value is of unexpected kind, throw an error.
    systemDateTimeValue = dateTimeObject;
    if (systemDateTimeValue.get_Kind() != expectedDateTimeKind)
    {
        throw error(strfmt("@SYS112380", dateTimeText, enum2str(Types::UtcDateTime)));
    }

    return dateTimeValue;
}

// get the sequence number for the dateformat.
public static int getSequenceForDateFormat( DateFormat _dateFormat)
{
    ;

    switch (_dateFormat)
    {
        case DateFormat::YMD:
            return 321;
        case DateFormat::DMY:
            return 123;
        case DateFormat::DYM:
            return 132;
        case DateFormat::MDY:
            return 213;
        case DateFormat::MYD:
            return 231;
        case DateFormat::YDM:
            return 312;
        default:
            return 123;
    }
}

// returns time from str.
static int str2Time(str 8 _timeStr)
{
    int     time;
    ;

    time += str2int(substr(_timeStr,0,2)) * 3600;
    time += str2int(substr(_timeStr,4,2)) * 60;
    time += str2int(substr(_timeStr,7,2));

    return time;
}

// <CostCenter:Department> _dimaatributesString,
// <1010:MBS> dimValueString
public static RecId generateDefaultDimension(Str                        _dimValueString,
                                             str                        _dimaatributesString,
                                             str                        _delimeter)
{
    container                           dimAttributeList,
                                        dimValueList;
    int                                 j;

    RecId                               defDimRecId;
    DimensionAttributeValueSetStorage   storage;

    if (_dimaatributesString && _dimValueString)
    {
        dimAttributeList = str2con(_sourceProperties, _delimeter,false);
        dimValueList     = str2con(_dimValueString, _delimeter,false);

        if(!dimValueList)
        {
            throw error(strFmt("This dimvalue string was not available"));
        }

        storage = new DimensionAttributeValueSetStorage();

        for (j=1;j<=conLen(dimValueList);j++)
        {
            if(conPeek(dimValueList,j))
            {
                DMFDimensionHelper::dynamicDimensionCreation(dimAttributeList, dimValueList, j);

                storage.addItem(DimensionAttributeValue::findByDimensionAttributeAndValue(DimensionAttribute::findByName(conPeek(dimAttributeList,j)), conPeek(dimValueList,j), false, true));
            }
        }

        defDimRecId = storage.save();
    }
    return defDimRecId;

}


//Generate the Dimension String from default dimension
// <CostCenter:Department> dimAttributeString
// <1010:MBS> dimValueString
public static str generateDefaultDimensionStr(RefRecId  _defaultDimension,str _dimattrString,
                                                  str _delimeter)
{
    DMFDefaultDimensionStr              defaultDimensionStr;
    DimensionAttributeValueSetItem      setItem;
    DimensionAttributeValue             dimAttrValue;
    DimensionAttribute                  dimAttr;
    container                           con;
    Int                                 i;
    DimensionValue                      displayValue;

    con = str2con(_dimattrString,_delimeter,false);

    if (_dimattrString && _defaultDimension)
    {
        for( i = 1; i <= conLen(con); i ++)
        {
            displayValue = conPeek(con,i);

            select RecId, DisplayValue from setItem where setItem.DimensionAttributeValueSet == _defaultDimension
                join RecId from dimAttrValue where
                     dimAttrValue.RecId == setItem.DimensionAttributeValue &&
                     dimAttrValue.IsDeleted == false
                 join RecId from dimAttr
                    where  dimAttr.RecId == dimAttrValue.DimensionAttribute
                       &&  dimAttr.Name  == displayValue;

                if (defaultDimensionStr)
                {
                    defaultDimensionStr += _delimeter;
                }

                defaultDimensionStr += setItem.DisplayValue;
        }
    }

    return defaultDimensionStr;
}


static int strLineCount(str freeTxt)
{
    int  start  = 1;
    int  end;
    int  length;
    int  lines  = 0;

    length=strLen(freeTxt);

    end = strScan(freeTxt, '\n', start, length);

    while (start)
    {
        lines+=1;
        if (end)
        {
            start=end+1;
            end = strScan(freeTxt, '\n', start, length);
        }
        else
            start=0;
    }

    if (!lines)
        lines=1;

    return lines;
}


/// <summary>
/// Determines whether the specified string is a date time string.
/// </summary>
/// <param name="_value">
/// The string to check.
/// </param>
/// <returns>
/// true if it is date time; otherwise, false.
/// </returns>
/// <remarks>
/// Input can have a format like "5/7/2010 12:00:00 AM" or "2010-05-07T00:00:00”. Both cases will be
/// handled.
/// </remarks>
public static boolean isDateTimeStr(str _value)
{
    boolean isDateTime;
    System.Text.RegularExpressions.Regex regex;
    System.Text.RegularExpressions.Match regexMatch;
    #define.MatchTimeRegex(@"[\sT]\d{1,2}:\d{1,2}:\d{1,2}")
    #define.ISODateTimeIdentifier("T")
    #define.ZeroTime("00:00:00")
    #define.DefaultLCID(1033)

    // check if in ISO format.
    isDateTime = strFind(_value, #ISODateTimeIdentifier, 0, strLen(_value)) > 0;
    if(!isDateTime)
    {

        // search for a time on the value
        // BP deviation documented
        regex = new System.Text.RegularExpressions.Regex(#MatchTimeRegex);

        // BP deviation documented
        regexMatch = regex.Match(_value);
        isDateTime = regexMatch.get_Success();
    }

    return isDateTime;
}


//Swapping the key value from map
/// <summary>
/// Creates a <c>Map</c> class with the value and key swapped.
/// </summary>
/// <param name="_key2ValueMap">
/// Map that has the keys and values swapped.
/// </param>
/// <returns>
/// A map that has the value switched with the keys.
/// </returns>
public static Map getValue2KeyMap(Map _key2ValueMap)
{
    // reverses the valid values map. The original map contains <key, label>, we will create a <label, key>
    Map value2KeyMap;
    MapEnumerator mapEnum;

    if(_key2ValueMap)
    {
        value2KeyMap = new Map(_key2ValueMap.valueType(), _key2ValueMap.keyType());
        mapEnum = _key2ValueMap.getEnumerator();
        while(mapEnum.moveNext())
        {
            value2KeyMap.insert(mapEnum.currentValue(), mapEnum.currentKey());
        }
    }

    return value2KeyMap;
}

Tuesday, July 1, 2014

Microsoft Dynamics AX 2012 R2 Services


Dear Friends,

·        Thanks to Packt Publishing team for forwarding me this book for review.

If you are a Dynamics AX developer, new or experienced who wants to implement services with Microsoft Dynamics AX 2012, then this book is for you. This book is a tutorial guide that covers each topic in depth with examples. The step-by-step approach will help you better understand each task as you will have to perform them frequently when utilizing the services. A basic understanding of MorphX and X++ is assumed, but the step-by-step instructions are easy to follow even for beginners. Some examples use C# and .NET, if you have an experience with Visual Studio it would be great buts it is not must.
        In every implementation we should integrate Ax2012 with other applications will always  be necessary within any organization and “Services” was the best option for achieving this. With AX2012 its became more flexible than earlier versions of AX while integration. This book will help you to know more like when and where we have to use the services. This book will help you to understand the service architecture, deployment, Creating custom services and take you through document services. We can learn to how to use OData Query Service, load balancing, clustering, NLB for services..etc. we can learn how to trace and debug the Services also.
      
      I recommend this book for mastering in the services for AX2012.

      you can order this book on Amazon, Goodreads, O'Reilly, Barnes&Noble, Google Books


Monday, June 30, 2014

Packt’s celebrates 10 years with a special $10 offer




This month marks 10 years since Packt Publishing embarked on its mission to deliver effective learning and information services to IT professionals. In that time it’s published over 2000 titles and helped projects become household names, awarding over $400,000 through its Open Source Project Royalty Scheme.
To celebrate this huge milestone, from June 26th Packt is offering all of its eBooks and Videos at just $10 each for 10 days – this promotion covers every title and customers can stock up on as many copies as they like until July 5th.
Dave Maclean, Managing Director explains ‘From our very first book published back in 2004, we’ve always focused on giving IT professionals the actionable knowledge they need to get the job done. As we look forward to the next 10 years, everything we do here at Packt will focus on helping those IT professionals, and the wider world, put software to work in innovative new ways.
We’re very excited to take our customers on this new journey with us, and we would like to thank them for coming this far with this special 10-day celebration, when we’ll be opening up our comprehensive range of titles for $10 each.

If you’ve already tried a Packt title in the past, you’ll know this is a great opportunity to explore what’s new and maintain your personal and professional development. If you’re new to Packt, then now is the time to try our extensive range – we’re confident that in our 2000+ titles you’ll find the knowledge you really need , whether that’s specific learning on an emerging technology or the key skills to keep you ahead of the competition in more established tech. 


Thursday, May 8, 2014

Find Records using TableID and Recid

Finding the record of the Table if you have only tableId and Recid
I have the scenario when I import using AIF and I want to find which record and which table its imported we can find by using its messageID in the AIFCorrelation table and in that table we can find the reference record that imported using that AIFDocumentService. In that table it will store the referenceTableID and recid.

public Common findRecordOfTableID(TableId _tableId, RecId _recId, Boolean _forUpdate = false)
{
    Common      common;
    DictTable   dictTable;
    ;
    dictTable = new DictTable(_tableId);
    common = dictTable.makeRecord();

    common.selectForUpdate(_forUpdate);

    select common
    where common.RecId == _recId;

    return common;
}

//This method is used to update the table based on the tableID and recid of that table.
public void updateValueOfTableId(TableId _tableId, RecId _recId, str _field, AnyType _value)
{
    Common      common;
    Int         fieldId;
    ;
    ttsbegin;
    common = this.findRecord(_tableId, _recId, true);
    fieldId = fieldname2id(_tableId,_field);

    if (fieldId && _value)
    {
        common.(fieldId) = _value;
        common.update();
    }
    ttscommit;
}

Tuesday, March 25, 2014

PacktPub - celebrate their 2000th title with an exclusive offer

Buy One, Get One Free" on all of #Packt’s 2000 eBooks! #Packt2k - http://bit.ly/1j26nPN

During this offer we are giving all our customers a chance to enjoy our books by giving them a free e-book copy for every purchase - "Buy One, Get One Free".

*Hurry up*……*Hurry up*….*Hurry up*........Lot of Dynamics AX2012 E-Books are available.

The campaign began on 18th-Mar-2014 and will continue up until 26th-Mar-2014. Following are the benefits readers can avail during this campaign.

  •     Unlimited purchases during the offer period
  •     Offer is automatically applied at checkout

Monday, March 24, 2014

AX2012 Financial Dimension Service classes.

Explaining some financial dimension Classes that used to validate,Build dimensions.

Validate LedgerAccount against account structure.
FinancialDimensionService class:- ValidateLedgerAccount(LedgerAccountValidationContract)

DimensionServiceProvider: This class provides multiple methods to build DimensionStorage object based on our dimension values list with different combinations ex: buildDimensionStorageAttributesAndValues(List _values, Map _dimensionSpecifiers),buildDimensionStorageForLedgerAccount( LedgerAccountContract   _ledgerAccount,    boolean                 _createForDefaultAccount = false)

DimensionValidation: this class manages the validation for dimension combinations.ex: validateByTreeForCombination(Validates the specified combination against the constraint trees and also validates the ledger    account rules).validateByTree(dimcombinationRecid).


Wednesday, March 19, 2014

Explore Dynamics World With Krishh: AIF service, Importing, grouping data while import...

Explore Dynamics World With Krishh: AIF service, Importing, grouping data while import...: Requirement. We have a Fixed positioned flat file from external system which have more than 1 million records where I have to import into...

AIF service, Importing, grouping data while importing.Problem and required solution

Requirement.

We have a Fixed positioned flat file from external system which have more than 1 million records where I have to import into LEDGERJOURNAL, customer doesn't want the all records as they want to group by the CURamt,DebtAmt based on the fields and date and load into the journal using  Standard AIF Service.

Environment: AX2012 R2 CU7.

I have one solution.
My Idea is.
1. Build the .net component that parse the flat file and do group by on that generate the XML using XSLT and use this component and xsl in transformations in AIFInbound port.

Do any one have any other Idea. Please provide the solution.

krishna.

Monday, February 24, 2014

AX2012 Get dimension Values


To get the master Data for Dimension attributes we can use two service classes.
1. DimensionService
2. DimenisionValueService

we will see what Dimension Service class is providing
1. getActiveDimensionsFromLedger()- Gets active dimensions in current company which will return the DimensionContract class collection List.
2. getDimensions(AccountStructureContract _accountStructureContract)-Processes an incoming account structure contract and return a list of financial dimensions for a specific account structure.
3. getDimensionsAll()-Gets a list of all financial dimensions, which returns a A String list of dimension values using DimensionContract class.

we will see what DimensionValue Service class is providing
using this class we can create/Get DimensionValues for the specific dimension attribute.

Methods:
1. createDimensionValue(DimensionValueContract _dimensionValueContract)-Processes an incoming dimension value contract and creates a financial dimension value for a specific financial dimension.
2. getDimensionValues(DimensionContract _dimensionContract)- processes an incoming dimension contract and returns a list of financial dimension values for a specific financial dimension. and returns the list of the dimension values for that specific dimension attribute.

we can use this service classes and consume in any external application and call this service methods.


by using these two services we can get the dimension values easily.


static void Krishh_getDimensionValues(Args _args)
{

    List                            dimensionAttributeList;
    ListEnumerator                  listEnumerator;

    DimensionService                dimensionService;
    DimensionContract               dimensionContract;
    AccountStructureContract        accountStructureContract;

   
    dimensionService            = new dimensionService();

    accountStructureContract    = new AccountStructureContract();
    accountStructureContract.parmName("Account Structure - P&L");

    dimensionAttributeList      = dimensionService.getDimensions(accountStructureContract);

    listEnumerator  = dimensionAttributeList.getEnumerator();
    while (listEnumerator.moveNext())
    {
        dimensionContract   = listEnumerator.current();
        info(strFmt("%1, %2",dimensionAttributeList.elements(), dimensionContract.parmDimensionName()));
    }

}