Showing posts with label Administration of AX 2012. Show all posts
Showing posts with label Administration of AX 2012. Show all posts

Friday, January 4, 2013

Business Benefits of Microsoft Dynamics AX 2012 R2

 
 
Hi There!
 
As we all very well know by now, the release of AX 2012 R2 (You can get more informtion about AX 2012 R2 on the What's New in Microsoft Dynamics AX 2012 for Developers) came to a reality last December, and I wanted to share the four most important business benefits of this release.
 
You can access the original post here, which was written by the Microsoft Dynamics AX Product Team.
 
New functionality for Industries and Administrative Processes
  • Manufacturing: Improve manufacturing operations for process manufacturing. AX 2012 R2 introduces new capability for management of potency, traceability and product batch sequencing to help process manufacturing streamline operations.
  • Retail: Assorment management across channels in your retail operations. New multi- and cross-channel capabilities for retail organizations, including catalogue management, cross-channel workflows, and integrated sales channel management will include a new “out of the box” web storefront.
  • Public Sector: AX 2012 R2 simplifies the financial budgeting process in public sector organizations. By combining the power of Microsoft Excel with the power of the workflow engine inside of Microsoft Dynamics AX 2012, AX 2012 R2 supports new capabilities in budget formulation with workflow approvals, flexible tracking, and reporting.
  • Professional Services: AX 2012 R2 improves in the intercompany scheduling capability of project resources will specifically benefit services organization with resources and projects across multiple entities and will improve utilization of your resources.

Improve Business Insights for all Users

New and updated KPI content is offered, and updated KPIs will come with the SQL BI cubes shipped with the release. These KPIs will surface on the different role centers.

Enabling the usage of the new Power view technology (You can learn more about this from the Murray Fife's post Creating PowerView Dashboards Against Dynamics AX 2012) introduced in Microsoft SQL Server 2012. This will help users to discover new insights through a highly interactive and familiar data visualization technology.

Increase Global Reach and Simplify International Operations

AX 2012 R2 has increased the global reach of Microsoft Dynamics AX 2012 by adding localization for 11 new markets (Brazil, Czech Republic, China, Estonia, Hungary, India, Japan, Latvia, Lithuania, Poland, and Russia), extending the reach for Microsoft Dynamics AX 2012 to support 36 localizations worldwide.


Simplify the Application Lifecycle for Customers

This goes from simplifying single instance international ERP deployment scenarios up to simplifying setup and functional implementation with new and improved lifecycle services.

Also, in AX 2012R2, we’ll see:

  • The Code Analyzer that will help us analyze the performance of custom code based on rules in the design phase of an extension by customers or partners.
  • The Data Migration Framework will support import, export and migration of data to/from Microsoft Dynamics AX 2012 in the deployment phase. It will cover over 20 scenarios including customer, vendor, product, employee, BOM, open sales and purchase order data, which can be extended by partners and customers.
  • The Diagnostics Framework will assist by analyzing data collected from the installation’s servers based on rules in the maintenance phase.

It is really exciting to see all these improvements in new release, as it will add more value to customer acros the board and it will help AX 2012 R2 to be used in other countries based on the localization improvements.

Take care and until the next post!



Friday, September 14, 2012

Delete User Layer with AX 2012 Management Shell

 

Hi there,

I hope you are ready for a great weekend. I will have to work, but this is why we love what we do, and believe that our customers should get the best of us.

Anyway, this is going to be a short post about how to delete a user layer from the model store in AX 2012. I have to say that I miss the flexibility of AX 2009 when it comes to application files and layers. The good news is that for the Microsoft Dynamics AX R2 release, we are supposed to have the code in a different database.

Ok, so going back to our topic, to delete a user layer from the model you first need to install the Management Tools from your AX 2012 setup. Once this is done, you can access the Microsoft Dynamics AX Management Shell and write the following script:

axutil delete /layer:Usr

See the picture below for more details:

 

As you can see, deleting a layer is not difficult at all and it happens fairly quick too. Also, it is very important that you have a backup of the database before performing this action.

That's all for now folks.




Thursday, September 6, 2012

Zip Codes Upload in AX 2012

 

Hi there,

Today I would like to discuss how to load Zip Codes to AX 2012 from a Text file and also point out what happens in the background.



In AX 2012, this task is fairly simple as there is an abstract class (AdressZipCodeImport) that takes care of this function. In addition to the abstract class, there is another class (AdressZipCodeImport_US) for each specific country that overwrites the ReadFile() method in the AddressZipCodeImport abstract class. In AX 2012, there only 4 countries available for Zip Code upload.

AddressZipCodeImport Class:

 
 


AddressZipCodeImport_US Class:




The AdressZipCodeImport_US class ReadFile() method contains a while loop that will allocate the data from the file being read  into the LogisticsAddress variables. To accomplish this, you will have to have your zip code, city, state and county name in an Excel file where you create the required spaces between fields and then save it as space delimiter file.

ReadFile() Method:




The following is an example of this sequence:


 

The following is the ReadFile() sub string coordinates:

 

When your file is ready, you can upload it by going to Organization Administration > Setup > Addresses > Import Zip/Postal codes:


Once you run this, the data will be in the LogisticsAddressZipCode table

 

It is very interesting to see how the AX 2012 team has put a lot of thought into these common tasks as they help us be more efficient on something we don't need to really spend a lot of time figuring out.

Until the next time!



Friday, August 17, 2012

Working with the AX 2012 EDT relation migration tool



Hi there!

This week I was faced with a couple of problems related to the relationships between tables made under an Extended Data Type (EDT). In my case, I learned that when relationships between tables exist through EDTs, they only capture a single field relationship and not necessarily a “real” relationship between tables.

A good example of this is when we assign an ItemId EDT to a custom field in a custom table. In this case, AX 2012 will ask you to create an EDT relationship, so I did. Later on the week, I was getting an error related to a violation of a primary key in the custom table I created when data was being inserted to it.

The error was related to the relationships being defined under an EDT as the kernel was have issues defining which relationship to examine first.

It took me a while to understand that the problem was the EDT relationship and after looking at some documentation it was easy to catch the issue as EDT relationships do not contain relationship metadata, such as cardinality and relationship type, and more often than not, they cannot be included in the relations node.

Luckily for us, AX 2012 provides a simple way to fix the EDT relations issues fairly easy. In fact, the migration can be done both manually or using the new EDT relation migration tool. However, if the data model is not correct, there are cases where we are going to have to fix the EDT’s manually.

To begin using the EDT relation migration tool, open the form for the tool by using the navigation path Tools > Code upgrade > EDT relation migration tool as seen in the picture below.



NOTE: Just keep in mind that if you are using this tool for the first time, AX 2012 will ask you if you want to refresh all the EDT relationships data, click yes and the EDT Migration tool will open.


When the form has opened, follow the next steps:
  1. Select a table from the Table name pane.
  2. Select each relation in the EDT relations table and choose an action from the Migration action drop-down menu for each of them.
  3. After you have set an action on all the relations for that table, click the Migrate single table button on the ribbon at the top of the form.

See Image for clarification:



What happens in the background?

  1. The migration tool attempts to find a match for the EDT relation in the existing relations in the selected table. If a match is found, the SourceEDT property on the table relation is set to the name of the EDT.
  2. However, if there is no match found in the table, the EDT migration tool will create a new table relationship only if the index (IndexType ) on the referenced table (shown by “”) is set to the correct table relationship.
  3. Finally, the tool will not create a new table relation if the matching index for the EDT field on the referenced table is set to NoIndex, Unique, NonUnique.

Example: Migrating an EDT relation to a new table relation.

This example shows the case in which an EDT relation is migrated to a table where the table relation was previously not defined. The result from this example will be the creation of a new table relation.

The EDT PKTableField1 defines a relation to the PKTable.Field1 field, which is an alternate key AK1.


In addition, before the EDT migration, the FKTable.Field1 field uses the EDT PKTableField1, which makes it a foreign key into PKTable. However, there is no table relation defined on the FKTable, and the ExtendedDataType property on FKTable.Field1 is set to PKTableField1 instead.



We choose the FKTablle and under the Migration Action, we choose Migrate.



What happens in the background?

The EDT relation migration tool performs the following actions:
  • The EDT migration tool creates the new relation to the PKTable under the Relations node of the FKTable. This relation will be of type Normal because the key is not the primary key.
  • Then, the EDT migration tool will set the EDTRelation property of the PKTable relation to Yes. This is because the tool performs the direct migration of an EDT relation to the table relation.
  • Then, the EDT migration tool creates one field link, FKTable.Field1 == PKTable.Field1, for the PKTable relation.
  • Finally, the EDT migration tool will set the SourceEDT property of the field link to PKTableField1.

What to expect the next time we use the tables?
  • All the APIs that used the EDT relation first on FKTable.Field1 will now find the same relation with the same field link under the PKTable relation by examining its SourceEDT property.
  • If a table relation that refers to PKTable already exists in FKTable, all the APIs that used those table relations will not pick up the PKTable relation because it is flagged as an EDTRelation, and the PKTable relation to the Relations node of the FKTable, with its EDTRelation property set to Yes.



In addition to the above, we can also double check the outcome of the EDT migration tool by looking at the SourceEDT property of FKTable.Field1. This should have been set to PKTableField1 to maintain a relationship with the EDT.



Let recap for a minute on what we just went over. The EDT relation migration tool can be used to automate the following actions:

  • Copy an EDT relation to all hosting tables.
  • Automatically set the EDT migration properties (markers) to reflect migration status.
  • Automatically populate relation metadata.
  • Derive cardinality from the index on the foreign key.
  • Derive the relationship type from the delete action/key composition.
  • Determine role names.
  • Report AOT objects impacted by the migration, depending on the relation used. The objects that can be affected include:
    • Queries:
    • Forms
    • Delete actions on tables
    • Data sets
    • X++ reports
Well folks, I think this is it for now. I really hope you like this article and that can help you at some point in your AX 2012 adventure. Also, I will be writing a bit more about AX 2012 Retail and Inventory and Product management in AX 2012 soon, so don’t miss it!



Have a great and restful weekend!




Friday, August 10, 2012

Working with the LedgerGeneralJournalService AX 2012



Hi There!

I hope everyone had a good week and that you are ready for an excellent weekend.

As you may well be aware by now, in AX 2012 you can import data by using services. You can use these services to import Customers, GL transactions, Products, etc.

You can learn more about services and AIF in one of my posts called Microsoft Dynamics AX 2012 Services and (Application Integration Framework) AIF architecture , and you might want to take a look into Services and Application Integration Framework .

On this post, I would like to share with you some code to import GL transactions into AX 2012 using the LedgerGeneralJournalService available in AX 2012.


static void ImportGLTransWithLedgerGeneralJournalService(Args _args)
{

    // Set these variables.
    LedgerJournalNameId                     journalName = 'GenJrn';
    SelectableDataArea                        company = 'CEU';
    TransDate                                     transactionDate = 10\10\2012;

    str                                     line1MainAccount = '256369';
    str                                     line1FullAccount = '256369--';
    str                                     line2MainAccount = '400090';
    str                                     line2FullAccount = '400090-10-';
    str                                     line2Dimension1Name = 'BusinessUnit';
    str                                     line2Dimension1Value = '10';


    LedgerGeneralJournalService             ledgerGeneralJournalService;
    LedgerGeneralJournal                       ledgerGeneralJournal;

    AfStronglyTypedDataContainerList              journalHeaderCollection;
    LedgerGeneralJournal_LedgerJournalTable   journalHeader;
    AifEntityKeyList                                         journalHeaderCollectionKeyList;
    RecId                                                       journalHeaderRecId;


    AfStronglyTypedDataContainerList                   journalLineCollection;
    LedgerGeneralJournal_LedgerJournalTrans       journalLine1;
    AifMultiTypeAccount                                       journalLine1LedgerDimension;
    LedgerGeneralJournal_LedgerJournalTrans       journalLine2;
    AifMultiTypeAccount                                       journalLine2LedgerDimension;
    AifDimensionAttributeValue                             journalLine2Dim;
    AfStronglyTypedDataContainerList                   journalLine2DimCollection;
    ;

    ledgerGeneralJournalService = LedgerGeneralJournalService::construct();
    ledgerGeneralJournal = new LedgerGeneralJournal();

    // Create journal header.
    journalHeaderCollection = ledgerGeneralJournal.createLedgerJournalTable();
    journalHeader = journalHeaderCollection.insertNew(1);
    journalHeader.parmJournalName(journalName);

    // Create journal lines.
    journalLineCollection = journalHeader.createLedgerJournalTrans();
    // Line 1
    journalLine1 = journalLineCollection.insertNew(1);
    journalLine1.parmLineNum(1.00);
    journalLine1.parmCompany(company);
    journalLine1.parmTransDate(transactionDate);
    journalLine1.parmAccountType(LedgerJournalACType::Ledger);
    journalLine1.parmTxt('AX Wonders Journal Import test');
    journalLine1.parmAmountCurDebit(235.00);

 
    // Define Ledger Dimensions
    journalLine1LedgerDimension = journalLine1.createLedgerDimension();
    journalLine1LedgerDimension.parmAccount(line1MainAccount);
    journalLine1LedgerDimension.parmDisplayValue(line1FullAccount);
    journalLine1.parmLedgerDimension(journalLine1LedgerDimension);


    // Line 2
    journalLine2 = journalLineCollection.insertNew(2);
    journalLine2.parmLineNum(2.00);
    journalLine2.parmCompany(company);
    journalLine2.parmTransDate(transactionDate);
    journalLine2.parmAccountType(LedgerJournalACType::Ledger);
    journalLine2.parmTxt('AX Wonders Journal Import test');
    journalLine2.parmAmountCurCredit(500.00);
    journalLine2LedgerDimension = journalLine2.createLedgerDimension();
    journalLine2DimCollection= journalLine2LedgerDimension.createValues();

    journalLine2Dim= new AifDimensionAttributeValue();
    journalLine2Dim.parmName(line2Dimension1Name);
    journalLine2Dim.parmValue(line2Dimension1Value);
    journalLine2DimCollection.add(journalLine2Dim);

      // Define Ledger Dimensions
    journalLine2LedgerDimension.parmAccount(line2MainAccount);
    journalLine2LedgerDimension.parmDisplayValue(line2FullAcct);
    journalLine2LedgerDimension.parmValues(journalLine2DimCollection);
    journalLine2.parmLedgerDimension(journalLine2LedgerDimension);


    // Insert records.
    journalHeader.parmLedgerJournalTrans(journalLineCollection);
    ledgerGeneralJournal.parmLedgerJournalTable(journalHeaderCollection);
    journalHeaderCollectionKeyList =
        LedgerGeneralJournalService.create(ledgerGeneralJournal);

    journalHeaderRecId =
        journalHeaderCollectionKeyList.getEntityKey(1).parmRecId();

    info(strFmt("LedgerJournalTable.Recid = %1", int642str(journalHeaderRecId)));

}



That's all for now folks!



Friday, May 25, 2012

AX 2012 Retail Event Trace Parser - Missing?



Hi there,

I hope everybody had a great week and that you are ready for a well-deserved long and restful weekend.

As you already know, I will be working on a series of articles related to the Microsoft Dynamics AX 2012 POS application. Last week I wrote an article called
AX 2012 POS Development - Application Triggers. Please check it out if you haven’t already done so.

In the course of this week I have been gathering a lot of information about the AX 2012 POS application, and the more I work with it, the more sense it makes to me. There are many different layers to this application, but this will be covered in future articles.

Anyway, this week I was working on a new instance of the AX 2012 POS application. To run it from Visual Studio, I followed the steps outlined in my last article AX 2012 POS Development - Application Triggers.

When all the setup steps were completed, I started the solution, keyed my user name and password and all of the sudden I got the following error:



This was odd as I went back to the demo instance I have and after following the same steps, I did not get this error. Luckily, there is LOG table called RETAILLOG in the AX 2012 POS application that can tell you what’s going on, and for my surprise, I was missing the Microsoft.Dynamics.Retail.EventTraceParser.dll as depicted in the following picture (from a working application).




The solution was easy; I just placed the missing dll to my AX 2012 POS application root folder. So, the Event Trace Parser enables rapid analysis of traces to find the longest running code, longest running SQL query, highest call count and other metrics useful in debugging a performance problem.

The Microsoft.Dynamics.Retail.EventTraceParser.dll is installed when installing AX 2012 for Retail and you can find it in your AX 2012 client folder.

The Walk through major features of Microsoft Dynamics AX 2012 article will give you a good introduction to its basic concepts.

That’s it for now folks. I hope you have a wonderful weekend. And stay tune for more to come on AX 2012 POS development. Next week I will post about how to use the AX 2012 POS System.Settings dynamics library and its in-memory functions.

Also, the following week I will write about Blank Operations by going through a really cool simple project.
Take Care!



Thursday, March 15, 2012

Security For Developers - Part II - Code Access Security

 

As promised, this is the second portion on Security for Developers. If you missed the first part of this series, you can get it HERE.

Today we are going to learn about code access security in Microsoft Dynamics AX 2012. And to start I would like to talk about a little bit about code access security in C#.

In C# (.NET) as well as in AX 2012, we work with security demands. And what is a security demand?

We can probably figure that demands are used to ensure that every caller who calls your code (directly or indirectly) has been granted the demanded permission.

 In a regular environment this happens when demanded for permission; the runtime's security system walks the call stack, by comparing the granted permissions of each caller to the permission being demanded. At this point, like in any high security building in New York City, if any caller in the call stack is found without the demanded permission then a SecurityException is thrown.  In the case of a New York City building, you will be thrown out of the building. Simple ah?

 Well, the same type of process exists in AX 2012 as AX 2012 Code Access Security is used by developers to protect Secured APIs from being invoked by un-trusted code (code that does not originate from the AOT). Code access security does this by verifying the following:

  1. The code asserted the appropriate permission on the call stack to use the secured class.
  2. The assert (the request to use the secured class) is executed in trusted code and saved in the AOT.
  3. The assert is executed on the same tier as the secured class.
In addition, Code Access Security covers the use of secured classes on the server tier only and we don’t need to modify client callas of secured classes, which is cool and scalable.

So here is how this works:
  1. Code Access Security must be implemented by the secured class owner and all consumers of the secured class.
  2. The owner secures the secured class by implementing a specific type of permission class and calling the demand()  (remember the C# demands above?) method on that class.
  3. Each class consumer must explicitly request permission to invoke a secured class by calling the assert() method on the permission class.  (this is where the permissions are compared)
  4. Application code will break unless both of these steps are completed. (This is similar to the  SecurityException in .NET)

NOTE: Code Access Security does not guarantee the validity of any data or parameters passed to the secured class. Data validation is still the responsibility of the consumer. 

Now, in AX 2012, there are six groups of protected classes in AX 2012 Code Access Security:
  • Direct SQL
  • Run-time compilation and execution of X++
  • Data-controlled execution of X++
  • File handling
  • Win32 Interop
  • Windows API
The follow first code shows how to consume the TextBuffer class. So, we first need to create a new FileIOPermission object, then pass the file name as a parameter, and then we call the assert() method. The second example shows how to call a CAS-enabled API.

server void MyServerFunction()
{

  // Declare the code access security permission object.
  FileIOPermission fileIOPermission;
  TextBuffer txtb = new TextBuffer();
  Filename filename ="c:\\temp\\myfile.txt";

  // Assert that it is okay to read and write files
  fileIOPermission = new   FileIOPermission(filename, 'rw');
  fileIOPermission.assert();


  // From file will demand CAS permission (read)
  txtb.fromFile(filename); // Read text from file

  // To clipboard will demand CAS permission (write)
  txtb.toClipboard(); // Copy it to the clipboard

  // To file will demand CAS permission (write)
  txtb.toFile(filename); // Write text to file
}



server void callCASEnabledAPI()
{

    DictClass dictClass;
    anytype   retVal;
    str       resultOutput;

    // Variable for the permission class.
    ExecutePermission perm;
    ;


    perm = new ExecutePermission();

    // Grants permission to execute the DictClass.callObject method.
    // DictClass.callObject is protected by code access security.

    perm.assert();
    dictClass = new DictClass(classidget(infolog));

    if (dictClass != null)

    {
        retVal       = dictClass.callObject("toString", infolog);
        resultOutput = strfmt("Return value of is %1", retVal);
        print resultOutput;
        pause;
   }

                // Closes the code access permission scope.
                CodeAccessPermission::revertAssert();
}


In the above example, if permission to use the API is not asserted, the following error is generated:
Request for the permission of type '%1' failed.
 
The following, and sadly, the last example shows how to execute permissions to a direct SQL statement within X++.

static void getCustomersDirectSQL(Args _args)
{

  Connection   userConnection;
  Statement    stmt;
  str     sqlString;
  ;

  userConnection = new Connection();
  stmt = userConnection.createStatement();

  sqlString = 'select * from custTable';

  new SqlStatementExecutePermission(sqlString).assert();
  stmt.executeQuery(sqlString);
  CodeAccessPermission::revertAssert();

}


It is important to remember that these tools are critical when developing our modifications to the system (AX 2012). Now that AX 2012 X++ language is compiled in the IL, we need to take advantage of the .NET CLR code access security when integration internal/external applications with AX 2012.

I hope you enjoyed reading this post and stay tune for my last post of this series about display methods authorizations in AX 2012.

Have a great and safe weekend!