Display SSRS report based on customer/Vendor specific language [Dynamics AX 2012]


Common requirement is to show the reports in customer’s language [example : Quotations, sales confirmations, invoices, Free text invoices, Return order acknowledgements , Agreements,  Purchase order confirmations etc].
This was easily achievable in Dynamics AX 2009 reports by using
element.design().languageID(custConfirmJour.LanguageId); // language id
Well, how do I achieve the same thing  in AX 2012 SSRS Reports? image
Its simple , we still have one liner code only in AX 2012image
We need to use the controller classes, runPrintMgmt() method or preRunModifyContract() method which changes the contract class before report is run and am leaving this to you based on the requirements.
this.parmReportContract().parmRdlContract().parmLanguageId(custConfirmJour.Language);
Below is the screen shot for reference:image
image

Do you want Dynamics AX to speak out messages for you ?(Text to speech) – Dynamics AX 2012 @ X++


I was just trying my hands on text to speech library and developed a small class which will help to speak out the messages easily for you. This post will explain quickly how to convert text to speech using X++ by using System.Speech Library and you can explore from there Smile 
First, let’s add this library to our references Node. Go to AOT>> References >> Add references
clip_image001
Search for System.Speech in the list of assemblies, select it and click on Ok button
clip_image002
Now, let’s create a simple class by name SRSpeechSynthesizer
class SRSpeechSynthesizer
{
}

Add a new static method called speakAsync as shown below

public static void speakAsync(str _textToSpeak)
{
    System.Speech.Synthesis.SpeechSynthesizer synthesizer = new System.Speech.Synthesis.SpeechSynthesizer();

    synthesizer.set_Volume(100);  // 0…100
    synthesizer.set_Rate(-2);     // -10…10

    // Synchronous
    //you cannot perform any other function in your Windows Form until the "reader" object has completed the speech.
    //synthesizer.Speak(_textToSpeak);

    // Asynchronous
    synthesizer.SpeakAsync(_textToSpeak);
}

Now, you can use this class and method wherever you want.

For the sake of demo, I have used it in info class >> add method. The reason why I have added here is to speak out all the messages that get added during the any process. I know it’s annoying if there are many messages that gets added to the Infolog stack. (But choice is yours clip_image003 )

You can customize further by parameterizing this option specific to users (in the user options form).
Add the below lines of code to the add method.
if (session.clientKind() == ClientType::Client)
{
    SRSpeechSynthesizer::SpeakAsync(_txt);
}
clip_image004

That’s it. You can explore more on the System.Speech Library.
When you create a new SpeechSynthesizer object, it uses the default system voice. To configure the SpeechSynthesizer to use one of the installed speech synthesis (text-to-speech) voices, use the SelectVoice or SelectVoiceByHints method. To get information about which voices are installed, use the GetInstalledVoices method and the VoiceInfo class. (msdn). Also, ensure that audio device is installed and working fine.

X++ Code Identify The Workflow Is Active (Or) Not In AX-2012 R3

static void RB_ActiveWorkflow(Args _args)
{
    WorkflowVersionTable        WorkflowVersionTable;
    WorkflowTable               WorkflowTable;
    #define.SalesCategory('SalesCategory')

    select firstonly DataArea,CategoryName,DefaultConfiguration from WorkflowTable
        where WorkflowTable.DataArea == curext()
        &&    WorkflowTable.CategoryName == #SalesCategory
        &&    WorkflowTable.DefaultConfiguration == NoYes::Yes
    join WorkflowTable, Enabled from WorkflowVersionTable
        where WorkflowVersionTable.WorkflowTable == WorkflowTable.RecId
        &&    WorkflowVersionTable.Enabled == NoYes::Yes;

    if (WorkflowTable)
    {
        info('Workflow Active in this company');
    }
}

X++ Code to remove the Role for single or multiple user [Dynamics AX 2012]




Removing a role to all or multiple users using X++ Code [Dynamics AX 2012]


static void RB_RemoveRoleAccessToUsers(Args _args)
{
    SecurityRole            role;
    SecurityUserRole    userRole;
    UserInfo                   userInfo;

    void removeFromSelectedUser(UserId  _userId, RecId  _recId)
    {
        fieldName                                                userId;
        SysSecTreeRoles                                     roleTree;
        SecurityUserRole                                     securityUserRole;
        OMUserRoleOrganization                       org;
        SecurityUserRoleCondition                     condition;
        SecuritySegregationOfDutiesConflict     conflict;
        RecId                                                        recId;

        userId  = _userId;
        recId   = _recId;

        ttsbegin;

        delete_from condition
                        exists join  securityUserRole
                        where  condition.SecurityUserRole == securityUserRole.RecId                                                               &&     securityUserRole.User == userId
                        &&     securityUserRole.SecurityRole == recId;


        while select OMInternalOrganization, SecurityRole from org
                   where org.User == userId && org.SecurityRole == recid
        {
               EePersonalDataAccessLogging::logUserRoleChange(org.SecurityRole,                org.omInternalOrganization, userid, AddRemove::Remove);
        }
     

        delete_from org where org.User == userId && org.SecurityRole == recId;

        delete_from conflict where conflict.User == userId && ((conflict.ExistingRole == recId) || (conflict.NewRole == recId));

     
        EePersonalDataAccessLogging::logUserRoleChange(recId, 0, userId, AddRemove::Remove);
 

        delete_from securityUserRole
               where    securityUserRole.User == userId                                                
                &&       securityUserRole.SecurityRole == recId;

        ttscommit;

    }
  // provide the role name to remove below
    select role where role.Name == "System administrator";
 
    // ensure that you have admin role to run this job
    while select userInfo where (userInfo.id != 'Admin'
        &&  userInfo.id != 'rbalakri')
    {
           removeFromSelectedUser(userInfo.id, role.RecId);
    }
    info("Removal process of role is complete.");
}

How to update Default Financial Dimension in AX 2012 using X++ code


static void DefaultFinancialDim(Args _args)
{
DimensionAttributeValue dimAttrBUValue,dimAtrrCCValue,dimAtrrDepValue,dimAttrIGValue,dimAtrrProjValue;
DimensionAttribute dimAttrBU,dimAtrrCC,dimAtrrDep,dimAttrIG,dimAtrrProj;
DimensionAttributeValueSetStorage davss;
RecId defaultDimension;
InventTable  inventTable;
davss = DimensionAttributeValueSetStorage::find(InventTable::find(“1000″).DefaultDimension);
dimAttrBU = DimensionAttribute::findByName(‘BusinessUnit’);
dimAtrrCC = DimensionAttribute::findByName(‘CostCenter’);
dimAtrrDep = DimensionAttribute::findByName(‘Department’);
dimAttrIG = DimensionAttribute::findByName(‘ItemGroup’);
dimAtrrProj = DimensionAttribute::findByName(‘Project’);
dimAttrBUValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimAttrBU, “003”, false, true);
dimAtrrCCValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimAtrrCC, “009”, false, true);
dimAtrrDepValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimAtrrDep, “024”, false, true);
dimAttrIGValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimAttrIG, “AudioRM”, false, true);
dimAtrrProjValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimAtrrProj, “000006”, false, true);
if(dimAttrBUValue || dimAtrrCCValue ||dimAtrrDepValue || dimAttrIGValue || dimAtrrProjValue)
{
davss.addItem(dimAttrBUValue);
davss.addItem(dimAtrrCCValue);
davss.addItem(dimAtrrDepValue);
davss.addItem(dimAttrIGValue);
davss.addItem(dimAtrrProjValue);
InventTable = InventTable::find("1000", true);
InventTable .DefaultDimension = davss.save();
InventTable .update();
}
}

AX 2012 By using X++ code Converting Word file to PDF file.,


void WordtoPDFfile()
{
     Com      document;
     str          pdfPath;
     str         finalPath;
     int         length;
     int         minus;
     str         filePath;
   
     container    confilter = ["DOC","*.doc"];
     filePath        = Winapi::getSaveFileName(0,conFilter,"","Save As",".doc","contracts");

    document.saveas(filePath);
    document.activate();
    document.save();
    length = strlen(filePath);
    minus = length - 3;
    pdfPath = strdel(filePath,minus,4);
    finalPath = pdfPath + ".pdf";
    document.ExportAsFixedFormat(finalPath,17);
    document.close();
    word.quit();
    WinAPI::deleteFile(filePath);
}

How to create production order in AX 2012

Create a simple Production Order Video

Please click the below link.

https://www.youtube.com/watch?v=G0j6Q5oCGUE

X++ Code For Importing CSV file into AX Table Using RunBase Batch


Create a Class :
class ImportCsv extends Runbasebatch
{
    Filename        ItemFileName;
    Filename        filename;
    DialogField     dialogFilename;
    #define.CurrentVersion(1)
    #define.Version1(1)
    #localmacro.CurrentList
        fileName
    #endmacro
}
public Object dialog()
{
    DialogRunbase       dialog = super();
    ;
    dialogFilename   = dialog.addField(typeId(FilenameOpen));
    dialogFilename.value(filename);
    return dialog;
}
public boolean getFromDialog()
{
    ;
    fileName = dialogFileName.value();
    return super();
}
void ImportInventtable()
{
    CommaIo                 file = new commaIo(ItemFileName,’r’);
    Container               con;
    InventTable             inventTable;
    Inventtable         Inventtable;
    int                     x,y;
    ;
    file.inFieldDelimiter(‘,’);
    if (file)
    {
 ttsbegin;
 while(file.status() == IO_Status::OK)
 {
 con = file.read();
        if (con)
        {
        
         Inventtable = Inventtable::find(conpeek(con,2));
         if(Inventtable)
         {
                     Inventtable.InventTableId     =   conpeek(con,1);
                     Inventtable.ItemId            =   conpeek(con,2);
                     Inventtable.Name              =   conpeek(con,4);
                     Inventtable.validateWrite();
                     Inventtable.insert();
                     x++;
                }
                else
                {
                     y++;
                }
         }
        }
    }
    
    ttscommit;
    info(strfmt("%1 record(s) imported, %2 record(s) not found",x,y));
  }
public container pack()
{
    return [#CurrentVersion,#CurrentList];
}
public void run()
{
 this.ImportInventtable();
 super();
}
public boolean unpack(container packedClass)
{
    Version version = runbase::getVersion(packedClass);
    ;
    switch (version)
    {
        case #CurrentVersion:
           [version,#CurrentList] = packedClass;
           break;
        default:
           return false;
   }
    return true;
}
public boolean validate()
{
    if (false)
        return checkFailed("");
   return true;
}
static void main(Args _args)
{
        ImportCsv      ImportCsv ;
        FormRun formRun;
        Args    args;
        ;
        ImportCsv = new ImportCsv ();
        if (ImportCsv .prompt())
       {
        ImportCsv .run();
       }
}

X++ Code for manipulate String function in Dynamics AX



// Adding "-" between each four digit
static void RB_StringSplitFuntions1(Args _args)

{
    str AccountCode = '1234567812312';

    str inputCode,BankAccount;

    int strlength,strsplitValue,i,j;

    str output;

    ;

   strlength = strLen(AccountCode);  

   strsplitValue = strLen(AccountCode) / 4;                           

   for (i=0;i<=strsplitValue;i++)

  {

    BankAccount = subStr(AccountCode,j+1,4);     j = j+4;    

    if (BankAccount)

     inputCode += BankAccount +"-";


  }


inputCode = substr(inputCode,1,strlen(inputCode)-1);

info(strfmt("%1",inputCode));

}

How to get Table field properties through X++ Code

static void RB_TableFieldProperties(Args _args)
{
    TreeNode custFldsRoot = treeNode::findNode(@"\Data Dictionary\Tables\CustTable\Fields");
    TreeNodeIterator              custFldsIterator;
    TreeNode                         custFlds;
    NoYes                              visibleProp;
 
    ;
   custFldsIterator   =   custFldsRoot.AOTiterator();
   custFlds              =   custFldsIterator.next();
   while(custFlds)
   {
        if(custFlds.AOTgetProperty('Mandatory') == 'Yes')
        info(strfmt("field %1", custFlds.treeNodeName()));
        custFlds = custFldsIterator.next();
  }
}

How do you delete a DirParty record in Ax2012?

static void DirParty_Delete(Args _args)

{

DirPartyTable dirPartyTable;

DirPerson dirPerson;

Common partyRecord;

DirParty dirPartyClass;

DirPersonRecId personRecId;

;



select firstOnly * from dirPerson where dirPerson.name == "ABCDEFG";

personRecId = DirPerson.RecId;



//This is after the worker has been deleted on the HcmWorkerListPage form on HRM

dirPartyTable = DirPartyTable::findRec(DirPerson::find(personRecId).RecId);



if (dirPartyTable)

{

partyRecord = dirPartyTable;

dirPartyClass = new DirParty(partyRecord);



if (DirParty::canDeleteParty(dirPartyClass.getPartyRecId(),true))

{

DirParty::autoDeleteParty(dirPartyTable.RecId);

}

}

}

AX2012 Enterprise Portal Development Cookbook


Hi Friends,

Click on the below link to download AX2012 Enterprise Portal Development Cookbook.



AX2012 Enterprise Portal Development Book

(Or)


http://www.microsoft.com/en-us/download/details.aspx?id=30171

Creating Shared Project With All The AOT Elements in AX 2012

Creating Shared Project With All The AOT Elements in AX 2012


Project Name : DEV_CreateNewProject

This Project contains :

Class  Name                : DEV_CreateNewProject

Form Name                 : DEV_CreateNewProjectDlg

Menu Item => Action : DEV_CreateNewProject


Open the Action Menu , Run the Dev_CreateNewProject in the action menu .  you will find the screen like below.


You can give the name of the project which needs to be created. After providing the Project name, select the AOT elements which ever you need , and then  Press Ok  button , The new shared project will be created.

Go to Shared Project , you can find your newly created shared project their. 

You can find the XPO file  from the below link.


SharedProject_DEV_CreateNewProjectAX2012








How to make the Dialog field mandatory in Axapta reports


Dialog field Mandatory

In the below , i have marked in yellow shows you , how to make the dialog field mandatory.

public Object dialog(Object _dialog)
{
    int                                  i;
    DialogRunbase              dialog = _dialog;
    DialogField                   checkField;
    FormDateControl          control;
    ;
    dialog.addGroup("@SYS119346");
    fieldConversionDate = dialog.addFieldValue(typeid(InventStdCostConvEndDate),  conversionDate);
    control = fieldConversionDate.fieldControl();
    control.mandatory(true);
    control.allowEdit(false);

      return dialog;
}

D365 F&O - Restart PPAC UDE Environment

D365 F&O - Restart PPAC UDE Environment    As developers working in the Unified Development Experience (UDE) for Dynamics 365 Finance...