viernes, 19 de diciembre de 2014

Debug an AX 2012 SSRS report, data generation

A quick code example to enable you to debug the process of generating data for an SSRS report...

static void ZZZ_DebugReport(Args _args)
{
    TaxListTmp          tempTable;
    TaxListDP           dataProvider    = new TaxListDP();
    TaxListContract     contract        = new TaxListContract();
    ;
    
    contract.parmDisplaySalesTaxCharge(true);
    
    dataProvider.parmDataContract(contract);
    dataProvider.processReport();
        
    /*
    tempTable = dataProvider.getTaxListTmp();
    
    while select tempTable
    {
        info(strFmt("%1", tempTable.AccountName));
    }
    */
}


viernes, 24 de octubre de 2014

Missing: USR layer

Well...  At least I don´t have to look for changes in the USR layer.
SYS, SYP, BUS, VAR, VAP, CUS
...  But then I've not actully copied these entities across to the Production environment in Russia yet.

lunes, 20 de octubre de 2014

Error closing inventory, AX 2009

Attempting to close inventory in an AX 2009 installation.

Error executing code: The method has been called with an invalid number of parameters.
Seguimiento de pila: Se ha llamado al método con un número no válido de parámetros.

(S)\Classes\InventMov_Vir_Transfer_Closing\checkDimPhysical
(S)\Classes\InventUpd_Financial\updateFinancialReceipt - line 28
(S)\Classes\InventUpd_Financial\updateNow - line 67
(S)\Classes\InventUpd_Financial\updateVirtuelTransferClosing - line 69
(S)\Classes\InventCostItemDim\updateModelAverage - line 198
(S)\Classes\InventCostItemDim\updateModel - line 18
(S)\Classes\InventCostItemDim\updateItem - line 74
(S)\Classes\InventCostItemDim\run - line 35
(S)\Classes\InventCostHelp\run - line 139
(S)\Classes\InventCostClosing\run - line 44
(C)\Classes\InventCostClosing\main - line 13
(C)\Classes\FormFunctionButtonControl\Clicked
(C)\Classes\FormMenuButtonControl\Clicked

Resolution:
Modify the InventMov_Vir_Transfer_Closing class, checkDimPhysical method and add two optional parameters, thereby having the same signature as it's parent class InventMovement which was modified by a patch in the SYP layer:
//<ZZZ> IDS 15/10/2014 Correct inventory close error.
//boolean checkDimPhysical(InventQty _qty, InventDim _inventDim, boolean finalCheck)
boolean checkDimPhysical(InventQty _qty, InventDim _inventDim, boolean finalCheck, boolean _showError = true, boolean _checkPalletLocation = true)
//</ZZZ> IDS 15/10/2014 Correct inventory close error.
{
    return true;
}

SYP Changes applied to the InventMovement.checkDimPhysical method signature


viernes, 1 de agosto de 2014

AIF new enumaration field value

In the Microsoft MSDN document How to: Update a Service After Adding a Table Field it details the process as to how...  Well, update the AIF web service after adding a new table field.

Adding a new enumeration value, however, this process is thankfully unnecessary.
A shiney new Enum value
No AX classes are required to be updated, therefore just the published service requires to reflect the change.

Navigate to Basic > Setup > Application Integration Framework > Services and click Generate to create the necessary artefacts of all of the selected services that are published.  Don't forget to take a copy of the web.config file beforehand should you have made any necessary changes (example 2).



As a side note, I've been suffering a lot due to the AIF framework recently, and would recommend that if you are considering the option of AIF versus direct access to the database for read-only operation, in AX 2009, go for the latter in many use cases.  I'd recommend a proxy web service to handle the database calls (that includes pagination for example), just like AIF.  AIF isn't bad, it's just not of the same quality code as we're used to - some excellent examples.

viernes, 18 de julio de 2014

Export to Excel Error

There are multiple reasons for failures when exporting to Excel from AX 2012.  It's difficult to detect the reason why as it's part of the system, however there is a forum post that details a few reasons as to why the failure may occur.

Today I found yet another.  We had a strange 'empty' column in the PurchLine (Purchase order lines) form.  It was a field that ended with '_MX' and assumed it to be Mexican functionality.  We just changed the control's visibility in the form and the export to excel worked without problems.

Excel Export Error
Perhaps the omission was at the table field level, however, and we should have added MX to the CountryRegionCodes list.  The Base Enum 'VendorOperationType_MX' DOES have the Country Code applied, however.

viernes, 11 de julio de 2014

AX 2009 PDF conversion

Converting our finely honed AX 2009 report to PDF produces a number of formatting differences.  The worst 'error', if you're an accountant, can be the lack of bold text in parts of the report.

AX 2009 Report

AX 2009 Report, exported to PDF
The solution is simple, by embedding the font into the PDF.  This can be done manually
(Image stolen from Gerrit's AX blog, see link below) 
To do this via code is also trivial change:
Use the PDF_EMBED_FONTS option

Our end result in PDF is pretty good...  But they may ask me to move stuff around by 1 mm once more...  Ye gods!

Finally, in AX4.0 SP1 there is a small bug that when changing to this option where you may lose the .pdf file extension.

miércoles, 9 de julio de 2014

Microsoft.Dynamics.Performance.Reporting.Security.EvaluationPeriodExpiredException: Evaluation license period expired.

Error:


Event viewer:

Solution:
Restart Sql Server Reporting Services
Edit: Also check that both the Managerment Reporter Process and Application services are Instanctiated...

lunes, 7 de julio de 2014

Backup and restore MorphX Version control II (AX 2009)

I refer you to Shashi's excellent post about how to set up version control with MorphX, when it is necessary to restore the production database over the development one, for example.

It worked for me!  I can't live without version control, and don't understand my colleagues when they don't activate it.

The only addition that I would make is that if Step 5 can't be done because there are no SYSVERSIONCONTROLMORPHXREV2543 rows in the systemSequences table, use the following database inserts to create the dummy rows and THEN execute step 5.

INSERT INTO [SYSTEMSEQUENCES]
     ([ID],[NEXTVAL],[MINVAL],[MAXVAL],[CYCLE],[NAME],[TABID],[DATAAREAID],[RECVERSION],[RECID])
     VALUES
     (-1, 5637144826, 1, 9223372036854775807, 0, 'SEQNO', 2541, 'dat', 1, -1)
GO
INSERT INTO [SYSTEMSEQUENCES]
     ([ID],[NEXTVAL],[MINVAL],[MAXVAL],[CYCLE],[NAME],[TABID],[DATAAREAID],[RECVERSION],[RECID])
     VALUES
     (-1, 5637144826, 1, 9223372036854775807, 0, 'SEQNO', 2543, 'dat', 1, -1)
GO

viernes, 4 de julio de 2014

White or no text appears in the PDF generated file from an AX 2009 report

Below is the report in the AX 2009 viewer. All good....

...Producing what is apparently an empty report when converting to PDF. Here I have selected the text so that it is highlighted in blue.

The solution that I have found is to move the shapes in the report to the top of the control list.  We presume that they are therefore rendered first.  Below I have already moved one box control , highlighted in yellow, up to the top.


There is a downside to this, however. Now when we print the report in the AX views we can see the text overwriting the borders.  It looks good in PDF format, but we have some micro management to do here, moving controls down or across a half a millimetre.  It's a time sink producing little value, but it must be done.

I find that when working with multiple shapes overlaying each other, it's a good idea to change one of their border colours.
We're nearly there!  There last changes can now be made by simply moving the second string control above the first.

Next time as soon as I see that the Analyst has drawn lines on an AX 2009 report, I'll be adding 2.5 hours to my estimation.

lunes, 30 de junio de 2014

AIF Woes: The class method for the specified action '%1' could not be found.

Error.

In AX 2009 after restoring the production server over the development one I found that none of my custom AIF services were working.  Curious, after having compiled and synchronised all.  Also more frustrating as the base AX AIF services that I have subsequently modified actually seem to work.

The first place to go was to change the web site that actually publishes the AIF beast and update those root values...  And don't forget to Validate that it works.
Base > Configuration > AIF > Web Sites
Updating and regenerating our services all appeared to go well...  But wait.  No service operations?
Base > Configuration > AIF > Services

We can find an error message, finally. by passing down the Extreme end point > Action directive methods.
An error message is generated moving down the list
Open up the message into the dev environment, and remember that the breakpoint is our friend here..
The class method for the specified action '%1' could not be found.
Here I identified that our ClassId was 30073, yet in my development environment it was identified as 30226

Looking directly in to the AifService and AifAction table (shared across companies), the DirContacPersonsService classId equated between the value in the table and the id of the class while my own classes did not have corresponding values with those of the table.  There was a difference for my custom classes!
Updating ClassId 30073 to 30226 in tables: AifService & AIFAction
Either I could ALT-F9 and delete these rows, then update/regenerate the services...  Or swallow a mouthful of whisky and directly update the ClassId value in the table...
UPDATE [DynamicsAxDEV].[dbo].[AIFACTION]
   SET [CLASSID] = 30226
 WHERE [ACTIONID] IN ( 'HIECustNameService.find', 'HIECustNameService.read')
GO

...And the result feels great!
Note the relationship between the AIFService ClassId reference between entities...

There are more steps however as the above 'CustomerName' service is one that is used across all companies, using a virtual company.

Cannot find the schema parameter.
Other services published via the company specific local end points has ClassIds stored in another entity,  AifEndpointActionParameterSchema.  Let's update those DocumentClassId fields but this is across multiple company instances.  Just remember that this table may be cached...

Identify the matching class from the source environment and update directly in SQL if you're already on your third whisky.  It'll all turn out okay in the end!

 UPDATE [DynamicsAxDEV].[dbo].[AIFENDPOINTACTIONPARAMETER2257]
SET DOCUMENTCLASSID = 30245
WHERE DOCUMENTCLASSID = 30123

Finally, avoid having to manually regenerate the fields published by the action directives by updating the AIFDataPolicy table....  There MAY be differences between the custom table field ids as well of course and it'll be inevitable to update these things by hand.

UPDATE [DynamicsAxDEV].[dbo].[AIFDATAPOLICY]
  SET DOCUMENTCLASSID = 30245
  WHERE DOCUMENTCLASSID = 30123
GO

viernes, 25 de abril de 2014

AX2009 AIF Custom Service Schema Error

After creating an AXD custom query and running the AIF wizard I received the following error in the list of services:
SchemaError: The base type of the method parmItemId is different to the corresponding field...
I realised that the newly created Ax<Table>_InventBatch class was missing the ItemId methods: existsItemId and parmItemId.  Copying these from an existing class and Refreshing (Actualizar, in the image above) the service list was sufficient to remove the schema error.

lunes, 17 de marzo de 2014

Activating (Sending/Submitting) Workflows

Gosh, workflows are hard.  There is a separate service that manages the framework which is a good thing for the users as it's more robust, however makes the developers life a little more complicated.  This can also mean that the changes we send to the system are not immediately visible on the AX forms until the process has been executed by the batch job called “Workflow Message processing”.

All that we would like to do is to submit to the workflow, as if approving a project quotation.

Running the code below works...  But the changes may not be immediately apparent:
static void ZZZ_WorkflowApprove(Args _args)
{
    // Variable declaration.
    recId                   _recId = SalesQuotationTable::find(@'P120139-2').RecId;
    WorkflowTypeName        _workflowTypeName = workflowtypestr("PSAProjQuotationTemplate");
    WorkflowComment         _initialNote = strFmt("Accepted");
    WorkflowCorrelationId   _workflowCorrelationId;
    
    // Activate the workflow from a template.
    _workflowCorrelationId = Workflow::activateFromWorkflowType(
                                _workflowTypeName, _recId, _initialNote, NoYes::No);
}
We can find the name of our workflow in the WorkflowTable entity, looking up the DocumentTableName field value, and obtaining the corresponding Name...  Excuse my ignorance with Workflows but I couldn't find an AX form to list them all.

To Approve/Reject a work item that is submitted to the workflow try the following snippet, for example approving a project budget:
    ProjId                  _projId = '120152';
    ProjBudget              _projBudget = ProjBudget::findOrCreateProjectBudget(_projId);
    
    while select workflowWorkItemTable where
        (workflowWorkItemTable.Type == WorkflowWorkItemType::WorkItem) &&
        (workflowWorkItemTable.Status == WorkflowWorkItemStatus::Pending) &&
        //workflowWorkItemTable.DueDateTime < DateTimeUtil::getSystemDateTime() &&
        workflowWorkItemTable.RefRecId == _projBudget.RecId &&
        workflowWorkItemTable.RefTableId == _projBudget.TableId
    {
        WorkflowWorkItemActionManager::dispatchWorkItemAction(
                            workflowWorkItemTable, 
                            "@SYS325206",//Approved budget 
                            curUserId(), 
                            WorkflowWorkItemActionType::Complete, 
                            "ProjBudgetOrigWorkflowApprove",
                            false);
    }


As indicated above, I'm ignorant as to workflows and had to spend a while investigating how to 'launch' the process behind them.  A quick look for AX 2009 and AX 2012 appears to be the same, yet for me still I still couldn't control properly the parallelism of handling the two separate processes.  Use the following at your own risk (a progress bar would be nice):
private void waitWorkFlow(Common _common)
{
    SysWorkflowMessageQueueManager  queueManager;
    WorkflowWorkItemDueDateJob      workItemDueDateJob;
    
    int                             seconds     = 0;
    int                             sleepTime   = (1 * 1000); //Milliseconds
    int                             maxWaitTime = 60;

    // "Microsoft internal use only."
    queueManager = SysWorkflowMessageQueueManager::construct();
    queueManager.run();

    workItemDueDateJob = new WorkflowWorkItemDueDateJob();
    workItemDueDateJob.run();
    
    // Check for 'Completed' status, otherwise wait...
    while (Workflow::findTrackingStatusForDocument(_common)
                .TrackingStatus != WorkflowTrackingStatus::Completed
            && seconds < maxWaitTime)
    {
        sleep(sleepTime);
        seconds += 1;
    }
}

Finally a few useful workflow related links:

martes, 11 de febrero de 2014

Exam MB6-869 :: Microsoft Dynamics AX 2012 Development Introduction

Got it!  Yeah!
“Microsoft is a registered trademark of Microsoft Corporation in the United States and other countries."

Below are a few exam tips, from my personal experience.


* Unfortunately no Packt Publishing MB6-869 exam cookbook exists so we have to go to MSDN for our study material.  The links below are no way complete (or we have links with too much information related to the published exam content), but these may help you quickly locate topics covered within the exam for AX 2012.

* Your important first steps would be to take a look at the two Microsoft Development I & II e-learning courses if you have access to them, while a few errors exist in them they are excellent at summarising the MSDN documentation.

* If, like me, you work in a non-English company I suspect that the exam will be a tiny bit more difficult as it’s only available in English, Japanese and Chinese.  Why not change your MorphX settings to English and familiarise yourself with those terms used in the exam?  It took me a while to get used to the changes from the Spanish setting, and I’m a native English guy!

* Pay particular attention to the relative percentages of the exam.  Putting a bit of effort in the Exception handling section is a steal compared to some of the other exam topics that we need to trawl through.  However, even this apparently simple section will have it’s nuances to be aware of

* Go play.  For example, the sections related to Valid time state tables, Security, Eventing and Form parts you may never have encountered these in your day-to-day job so you could then either make an excuse to work with them, or go home and construct them on a virtual machine.

* No one will ever accuse you of ‘slacking off’ at work if they find you reading MSDN!  I have found that 15 minutes preparing for the exam during my 11 hour a day working week can provide a great foundation for not only exam study but also for gaining useful knowledge that can be later applied to your daily work tasks/responsibilities.  In fact this whole exercise has given me more confidence when making technical recommendations to other staff.

* If the company that you work for is associated with the Microsoft Partner Network, you can associate their name after passing the exam.  If it’s a serious organisation you should ask your supervisor if they can pay the exam fees for you and give you the time off to actually take the exam, as they will benefit from your certification as well.

* Last minute exam cramming?  Try diving into the fantastic "Microsoft Dynamics AX Topology and architecture diagrams". Or consume like a velociraptor these slide-shows 1, 2, 3.

* Feel free to add any suggestions and corrections to the comments below, as it’s obvious that I haven’t got a 100% handle on some sections…  Good luck!


Microsoft Dynamics AX 2012 Development Introduction (correct as of August 29, 2011)

Microsoft E-Learning (PartnerSource):
* 80304AE: Development II in Microsoft Dynamics AX 2012 (4 Hours)
* 80303AE: Development I in Microsoft Dynamics AX 2012 (3 Hours)

Exam Topics Covered -  The following list includes the topic areas covered on this exam:
* Understanding Dynamics AX 2012 Architecture
* Managing the Data Dictionary
* Managing the User Interface
* Managing Security
* Working with X++ Control Statements
* Managing Objects and Classes
* Accessing the Database
* Managing Exception Handling


+Understanding Dynamics AX 2012 Architecture (13 percent)
- Identify key development features and functionality.
  This topic may include: development workspace; IntelliMorph(1); MorphX(1,2); object-oriented design(1); navigation(1?)
- Demonstrate understanding of the data architecture.
  This topic may include: working with data in forms; sorting records; filtering records(2); finding records
- Demonstrate understanding of architecture components.
  This topic may include: layers; models(1); labels(1); Help system (1,2); reporting (1)
- Work with customization tools.
  This topic may include: using MorphX to customize the user interface; using the X++ editor to develop customizations; identifying best practices(1); using the Type Hierarchy Browser and Type Hierarchy Context tools; using the reverse engineering tool
+Managing the Data Dictionary (13 percent)
- Work with MorphX, the Application Object Tree (AOT), and projects.
  This topic may include: working with development projects; features of the AOT (1); Microsoft Visual Studio projects node(1,2,3); objects in the data dictionary; navigating the AOT and data dictionary
- Work with tables and relations.
  This topic may include: table structure and components(1,2); fields; field groups (1); indexes (1); delete actions(1,2,3); creating tables; creating relations(2, 3, 1, 4, 5); (1) primary keys; foreign keys; surrogate keys
- Work with data types and base enumerations.
  This topic may include: primitive types; extended types(1,2); creating data types(3); using data types(1); creating base enumerations(1,2,3); using base enumerations
- Work with maps and views(1).
  This topic may include: map functionality(1); map advantages; view functionality(1); view advantages
+Managing the User Interface (13 percent)
- Work with menus and menu items.
  This topic may include: creating and using menu items(1,2,3,4); menu functionality(1,2); creating menus
- Manage forms.
  This topic may include: data sources(1); design(1,2,3); document view(3?,1&2?); editing data in a form
- Work with forms.
  This topic may include: form types(2,1); list pages(1) and list page metadata(1); working with the action pane; form parts(1)
+Managing Security (11 percent)
  This topic may include(1,2): identifying key concepts, terms, and benefits(1); working with roles(1), process cycles(1), and duties(1,2); working with privileges(1,2), entry points(1), and permissions(1,2,3)
- Understand security concepts and settings.
  This topic may include: default security settings(1?,2? (search: ‘default’ - see standard roles : -SYSADMIN-, SystemUser, HCMEmployee),3?); sample security settings
- Work with XDS and server enforcement of security.
  This topic may include: server-based code authentication(1,3,2); data security filters; org model(1,2(see section ‘Extensible data security’)); effective date(1,2(select ‘Date Effective Patterns’ to download))
+Working with X++ Control Statements (13 percent)
- Work with variables.
- Work with operators.
- Work with conditional statements(1) and loops(1).
- Work with communication tools.
This topic may include: print; boxes(1); infolog(1!,2,(3),4,5); dialog(3,4,2,1)
+Managing Objects and Classes (12 percent)
- Work with classes(2,1,3), objects, and inheritance.
  This topic may include: defining key attributes(2,1,3!); method access control((1,2,3,4?)); extending a class(1); expression operators for inheritance(1); referencing object methods(2,1); method types(1); inheritance among tables(1,2,3)
- Work with scoping, events, and parameters in X++.
  This topic may include: scope of objects within a class(1,2); events in X++(1)
+Accessing the Database (15 percent)
  This topic may include: table buffers; select statements(1,2); field lists(1,(2)); while select statements; sorting; joins(1,2); cross-company data access(1)
- Manipulate data.
- Work with queries(1).
  This topic may include: executing a query(1); building a query(1,2); QueryBuildDataSource(1); QueryBuildRange(1)
+Managing Exception Handling(1,2) (10 percent)
- Work with exceptions and optimistic concurrency(1) exceptions.
  This topic may include: handling errors(1,2,3,4,5)
- Work with throw and try/catch commands.
  This topic may include: handling errors