AX2012 – On Reassign: Failed to create a session

23 01 2014

When trying to reassign a record via workflow history in AX2012 we received the error: Failed to create session; confirm that the user has the proper privileges to log in to Microsoft Dynamics.

Screen Shot 2014-01-23 at 2.31.28 PM

The cause of our problem was a faulty CIL. We performed a full CIL compile, restarted AX and then were then able to perform the re-assign

Advertisements




Customize your AX Workflow Email Templates

12 12 2012

A number of our clients have made requests of us to provide more meaningful information available on the Email notifications that are sent to the workflow work-item assignees. The typical information that they would like to see is line item information for workflow relating to Purchase Requisitions etc.

The easiest way is to modify the various task and step instructions in your workflow configuration. You can select tags relating to the lines such as %Purchase Requisition.Purchase requisition lines.ItemId% etc. These instructions can be displayed in your workflow email notification by including the %message% tag in your email template.

Screen Shot 2012-12-12 at 10.11.38 AM

However using this approach is not very flexible or visually appealing as each tag is replaced by a comma separated list of the values from the various lines. Most of our clients have required a more tabular format for the lines. My approach to solving their issue is by using a code based solution that I will describe below.

I’d like to say at the outset that the disadvantages to this approach is that it doesn’t easily allow for multi-language, its fairly rigid, and it is a more hard-coded solution making it not very flexible.

Step 1. Create a method ‘wfDescription’.

Create a ‘wfDescription’ method on each Workflow Document table that you are using. This method should return an block of html (or plain text) with the content that you would like to display for the given document type. E.G. For a purchase requisition add the following method to the PurchReqTable table.

str wfDescription() 
{
 PurchReqLine line;
 str ret="";
 ;
 ret = ret + strfmt("<strong>Motivation: </strong>%1<br/>", this.businessJustification()); ret = ret + "<strong>Lines:</strong><br/>";
 while select line where line.PurchReqId==this.PurchReqId
 {
   ret = ret + strfmt("%1. %2 <span style='color: #009966'> (%3 @ %4 %5) - %6</span><br/>",num2str(line.LineNum,0,0,1,3), line.itemName(), line.PurchQty, line.CurrencyCode, line.PurchPrice, line.LedgerAccount);
 }
 return ret;
}

Step 2: Add a description tag to your email template

Open up your email template and place a %documentdescription% tag in the place where you would like the text/html block from Step 1 to appear in your emails.

Step 3: Enable the %documentdescription% tage

This is the key step in the whole process. To enable workflow to replace the new %documentdescription% tag created in Step2 with the contents from the method in Step 1. To do this we will be customizing the ‘EventNotificationWorkflow’ class:

  • Open the ‘EventNotificationWorkflow’ class.
  • Edit the sendMail method.
  • Add the line ‘this.addCustomMergeValues();’ after the line ‘this.addBaseMergeValues();’
  • Create a new method named ‘private void addCustomMergeValues()’ to the ‘EventNotificationWorkflow’ class.
    This method will determine whether the workflow document has the ‘wfDescription’ method and will replace the tag with what the method returns.
private void addCustomMergeValues2()
{
  SysDictTable dictTable; 
  str description;
  ;
  dictTable = new SysDictTable(tablenum(PurchReqTable));

  if (dictTable.isMethodActual('wfDescription'))
  {
     description = dictTable.callObject('wfDescription',record);
  }
  else
  {
    description = "";
  }
  mergeValues.insert("documentdescription", description);
}

The final step is to prevent the html from your return method from being escaped. To do so:

  • Open up the SysEmailTable (Table) in the AOT
  • edit the HTMLEncodeParameters method
  • Add a conditional statement before the line ‘encodedMap.insert(mapEnum.currentKey(), SysEmailTable::htmlEncode(mapEnum.currentValue()));’ so that your new tag %documentdescription% is not html encoded.
if (mapEnum.currentKey() == 'documentdescription')
    encodedMap.insert(mapEnum.currentKey(), mapEnum.currentValue());
else 
    encodedMap.insert(mapEnum.currentKey(), SysEmailTable::htmlEncode(mapEnum.currentValue()));

If all goes well you should now receive more detailed information in your email notification.
Let me know if you have any better ways of accomplishing this or comments on my solution.

Happy daxing.





Setup User workflow email notifications in AX2012

23 08 2012

In order for users to be notified of new work-items that have been assigned to them you will need to ensure that they have their notification settings enabled. To do this you can follow the following procedure.

  • Navigate to the user options screen.
    • If this is for yourself, you can locate user options from the File -> Tools -> Options menu.
    • If this is for other users you can access the form via System Administration -> Common -> Users -> Select the correct user -> Click options on the toolbar
  • Select the notifications tab
  • Check the “Send notifications in email” checkbox. By default this is disabled.

N.B. Please ensure that you your email templates and outgoing mail server have also been configured and in AX.





Organisation-wide Workflow Email Templates

22 08 2012

If you make use of organisation wide workflow configurations in AX2012 you may have come across an issue where users are not notified of their new work-items via Email.

To set this up you will need to:

1. Navigate to your email templates under the Setup menu of “Organisation Administration”.
2. Select the “Show system email templates”
3. Create a new Email template.

Image

4. Navigate to “System Administration” -> “Setup” -> “Workflow Parameters” and select your newly created email template. (For company specific configuration AX looks at the template selected under “Organisation Administration” -> Setup -> Workflow Parameters)

Your users should now be notified of “Organisation-wide” workflow workitems.





Error executing code: FormDataSourceObject not initialised

25 11 2011

Your workflow quick fix for the day:

Ok, so you’ve developed your workflow template, enabled your form for workflow, setup a configuration and are ready to give your workflow its first test run. You open your form and the first thing you get is the debugger with an error message: “Error executing code: FormDataSourceObject not initialized” Called from the SysWorkflowFormControls\initControls class.

Error executing code: FormDataSourceObject not initialized

Don’t worry, this is a very quick fix, and you, like I did, may kick yourself for forgetting. Open up your workflow enabled form in the AOT, navigate to Designs, Design, right click, select properties and select a valid data source. e.g.

No data source selected

Data source selected

 





‘Go to Origin’ Button for Workflow History Form

18 11 2011

For workflow administrators out there, you have no doubt found the need to jump from the workflow history form (Basic -> Periodic -> Workflow History) to the original document that the workflow relates to. Especially for debugging errors. So today’s post provides you with just that… A “Go to origin” button for your workflow history form.

Go to origin button on workflow history form

Seeing as this is a standard AX form, I don’t think I’m allowed to simply export and provide an XPO on my blog so here are the instructions on how to do it.

1. Open the form WorkflowStatus in the AOT.
2. Create a standard button at the following location on the form Designs -> Design -> Group -> GridGroup -> Button group called DrillDown with the label @SYS88047 in its text property.

Insert Button

Insert Button

3. Right click on the button’s method node, click Over ride method , Clicked.
4. Overwrite the method code with the following.

void clicked()
{
    Common buffer;
    selectableDataArea company = curExt();
    Args args = new Args();
    SysDictTable dictTable;
    FormRun formRun;
    WorkflowTrackingStatusTable trackingStatus;
    ;
    trackingStatus = WorkflowTrackingStatusTable::findByCorrelation(WorkflowTrackingStatusTable.CorrelationId);
    if (trackingStatus.RecId)
    {
        changecompany(trackingStatus.ContextCompanyId)
        {
            dictTable = new SysDictTable(trackingStatus.ContextTableId);
            buffer = dictTable.makeRecord();
            select buffer where buffer.RecId == trackingStatus.ContextRecId;
            if (! buffer)
            {
                 info('You cannot go to the origin of the workflow instance. The record no longer exists or you do not have sufficient access.');
return;
            }
            dictTable.formRef();
            args.lookupRecord(buffer);

            args.name(dictTable.formRef());
            formRun = ClassFactory.formRunClass(args);
            formRun.init();
            formRun.run();
            formRun.detach();
        }
    }
}

If you cannot read the above you can view it in this text file: clickedWF.txt

5. Save the form.
6. You’re done!! Quick and easy.

Disclaimer: Please note that this is really just an code suggestion and that you should test it thoroughly before introducing to any live environment.





DLLs used in Batch processes

13 10 2011

I know this doesn’t have a lot to do with workflow in specific, but I struggled through this issue for a while without finding any other results on the net, so I’m posting it just in case somebody else struggles with the same issue.

We are running a batch job that makes use of a 3rd party DLL file. The batch process runs quite ok if we run it manually from the client, however as soon as we try and run it in batch mode it fails with a “CLR Error: cannot create object”.

The reason for this is that the batch server cannot find the DLL file to use. All the recommendations that I found to solve this error involved placing the DLL in the Global Assembly Cache (GAC) on the batch server. I understand that this would be the best way to overcome the error and should normally be the approach. However the DLL we have is not Strongly Named, so we received constant errors when trying to add it to the GAC. Unfortunately the vendor is not shipping a strongly named version of the DLL so a different approach has to be followed.

Where for client side execution of the DLL you need to place the file in C:\Program Files (x86)\Microsoft Dynamics AX\50\Client\Bin if you would like the server to access it, simply place it in C:\Program Files\Microsoft Dynamics AX\50\Server\[AOS name]\Bin on the batch server.

And like magic the batch job works. (Ok i had to restart the batch server AOS as well)

I hope this assists somebody in the near future.








%d bloggers like this: