Adding code templates/shortcuts in AX 2012

19 03 2012

If you’ve got any blocks of code that you use frequently, e.g. specific comment blocks, you can very easily add code short cuts in AX 2012 to auto-insert the them in to your X++ code.

For example you can setup AX to automatically create surrounding comment such as

whenever you type “mycom” and press the tab key.

How do you accomplish this. Very easily!

Step1: Locate the class EditorScripts in the AOT.
Step2: Create a new method with the format public void template_flow_[shortcut](Editor editor)
Step3: User the editor parameter to add code the code that you would like inserted. e.g. editor.insertLines(“\\test comment”);
Step4: Add your method to the case statement in the isApplicableMethod method in the section relating to template “editor scripts that does not apply to Macros” 

Thats it, now if you type your shortcut into any editor in AX and press tab, the “\\test comment” code will be inserted.

Here’s a full example method

The above creates the following output:





How do I select from table Common in AX?

16 11 2011

Workflow quite often uses fields such as ContextTableId and ContextRecId to reference the original document. I’ve been needing to get hold of the original database record as a Common object from which I can then do various things, but the question is how do i get that common object?

I’ve tried something like this

Common buffer;
;
select buffer where buffer.TableId == _tableId && buffer.RecId == _recId;

This however always return an empty buffer regardless of whether or not the record does exist. I eventually managed to retrieve a common record with the following method.

Common buffer;
SysDictTable dictTable;
;
dictTable = new SysDictTable(_tableId); buffer = dictTable.makeRecord(); select buffer where buffer.RecId == _recId;

I’ve needed to do this a couple of times in the past and kept forgetting, so I’m posting it here for myself and who ever else wants to accomplish this. Enjoy!





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.





The Request Failed with HTTP status 401: Unauthorized

20 09 2011

I’ve been battling through “fixing” a clients Workflow setup. Its been working for the last while but just stopped all of a sudden. I tried to validate the workflow website and received the message “The Request Failed with HTTP status 401: Unauthorized”. I went through some of the suggestions made by Amer over at his blog to fix the error before reviewing the server name specified for the workflow website. It happened to be set to the server’s IP address, after changing this back to the valid server name all was well!

E..G:
Old: http://10.0.0.1:80/MicrosoftDynamicsAXWorkflow50
New: http://CLIENTAOS_SERVER:80/MicrosoftDynamicsAXWorkflow50

I hope this helps somebody.

 





Business Connector code refresh

15 04 2011

While developing business connector applications you may come across issues where you code changes in AX do not seem to be taking effect or the caching is taking too long to refresh. I’ve tried restarting the AOS, restarting IIS, restarting Application pools even restarting the entire server and nothing seemed to have helped. However, an easy way to ensure that your changes are always available to the business connector code is to add the following line at the beginning of your .NET code, after loggin in, but before executing your custom code:
DynAx.CallStaticClassMethod(“SysFlushAOD”, “doFlush”);

(where DynAx is a logged in instance of Microsoft.Dynamics.BusinessConnectorNet.Axapta)

I hope that helps someone.





Some pointers on developing your own ledger journal workflows

18 03 2011

I did a couple of developments on ledger journal workflows a while ago and wrote down these pointers for myself to remember when doing it again.

1) Remember that your workflow must be linked to the same module / workflow category that the journal you wish to workflow is linked to i.e Customer, Vendor or Ledger
2) The template that is used for each LedgerJournalType must be defined in the LedgerJournalWFApprovalTemplates macro. (examined from: LedgerJournalName::findJournalTemplate)





Security Keys for Workflow History

22 12 2010

I’ve recently been working on a client site setting up security in Dynamics AX workflow and the question of access to the workflow history form (accessed via yellow workflow bar) as well as the re-assign, resume and cancel buttons on that form was raised. After a few minutes investigation I found them under the SecurityKey BasicMisc.

Remember that turning off access to workflow history via the security key will remove the Workflow History button from Basic -> Enquiries as well as from your Yellow Workflow Bar

Summarised: (Label, Key)
“View History” – > WorkflowViewHistory (key)
“Resume” -> WorkflowStatusResume (key)
“Reassign” -> WorkflowStatusReassignWorkItem (key)





Workflow Wishlist #2 – onDelegateEvent

5 10 2010

Wish:
The second item on my wishlist for Dynamics AX workflow is to have an “onDelegateEventHandler” option available for tasks and approvals. I must admit that this would most probably not be a very widely used function within AX workflow, but here is why I would like to have one.

Given the way that workflow manages the assignment of workitems, there is no way of determining when and to whom tasks are assigned to people, in order to perform some type of custom action like updating an external system or table. Even making use of custom ParticipantProviders, one does not have a guarantee that it will end up at the person that your provider class is returning, due to delegation settings.

Thus an onDelegate event handler would be very useful. Unfortunately workflow does not have any eventhandlers for individual workitems, rather just set on tasks, so this may be difficult to accomplish.

My workaround:
It is relatively easy to tap into the WorkflowTrackingTable’s (Table) saveTracking Method and kick off some custom action using the record ‘trackingTable’. The trackingTable record contains a useful field  called TrackingType (enum WorkflowTrackingType) which can provide you with more informations as to what has just occurred. E.g. WorkflowTrackingType::Delegate, WorkflowTrackingType::EscalationPath, WorkflowTrackingType::Creation. Using this you can then perform whatever action you would like to do e.g.

if (trackingTable.TrackingContext == WorkflowTrackingContext::WorkItem)
{
  if (trackingTable.TrackingType == WorkflowTrackingType::Creation)
  {
        doAction(trackingTable.User); //this is the user to whom the workitem has finally been assigned 
  }
  else if ((trackinTable.TrackingType == WorkflowTrackingType::Delegation) || (trackingTable.TrackingType == WorkflowTrackingType::EscalationPath))
  {
       doAction(trackingTable.ToUser); //to whom the workitem is now assigned (delegated/escalated)
  }
}
N.B. Be warned, you are modifying system classes so be careful when you are installing new hotfixes or upgrading.
Happy Daxing
Comments Suggestions?




Useful Methods to determine whether a user is assigned to a record

29 04 2010

Just a quick post about two useful methods that one can use to determine whether a user is assigned to either a task or an approval workitem for any given record. They are both found in the WorkflowWorkItem class.

1) WorkflowWorkItem::isUserTaskOwner(Common record, WorkflowUser user = curuserid())
2) WorkflowWorkItem::isUserApprovalOwner(Common record, WorkflowUser user = curuserid())

These two methods are primarily used by workflow for populating the yellow workflow bar on your forms.





How to create an assigned to filter on your workflow enabled form.

16 03 2010

Do you have the need to create either a customised form or add an additional filter to an existing form that only displays records that have been assigned to you or a specific user.

The basic concept is that you need to join your document’s table to the WorkflowWorkItemTable on the RefRecId and RefTableId.

You then need to add 3 filters (query ranges):
1) Filter where WorkflowWorkItemTable.Status = WorkflowWorkItemStatus::Pending
2) Filter where WorkflowWorkItemTable.UserId = [userid of the person you want to filter for e.g. curuserid()]
3) Filter on current companyid.

To check out a full selection of code in practice, checkout how they do it for Purchase Requisitions is Dynamics AX Classes -> PurchReqShowRequisitionsFilter -> filterAssignedToMe

Hope this useful to someone.








Follow

Get every new post delivered to your Inbox.

Join 135 other followers