Sunday, December 6, 2015

The out of the box Sales order confirmation functionality allows us to either confirm Sales order using a click of a button (on Sales order form/list page) or we can schedule the confirmation of Sales order using a batch job (it also supports late selection query). This all works fine. However, if you want to perform additional tasks on each Sales order once it is confirmed, you will need to write some code. The class structure is something like that

FormLetterService
SalesFormLetter
SalesFormLetter_Confirmation

Any developer familiar to inheritance would go and override the run method of SalesFormLetter_Confirmation class to perform the additional updates after the super call and it will work perfect when a Sales order is confirmed using a button. However, it will NOT work as expected when runs under a batch. It is because, batch creates multi threaded tasks and leaves them to execute later. The code written in run method of SalesFormLetter_Confirmation class would run before the Sales order is actually confirmed (under different thread) and you will not achieve your desired results as code would not be execute for SOs being confirmed under a batch.

To overcome this issue, the code must be executed when the thread actually confirms the Sales order. After performing some debugging using Visual Studio and analysing the threads I found few ways to achieve the desired results and execute the custom code for each and every Sales order under the batch right after it gets Confirmed.

There is a class called "FormLetterServiceBatchTaskManager". It has run method - write your code there after the base class' run gets executed. Better check the this.ParmDocumentStatus to execute your code only for the document type you are working on. (if this.ParmDocumentStatus() == DocumentStatus::Confirmation)

Working with Single AOS environment and Load balanced environment is very different. Specially, when it comes to releasing code in production environment or making changes in AIF service data policies. Following are few things which I learnt in my recent project:

If running multiple AOSs for load balancing and you need to make data policy changes (i-e need to enable or disable fields in a web service), you must bring all AOSs down and restart the service when change is made and CIL is performed.

If running multiple AOSs and made some code change that needs CIL change. Again, must bring all AOSs down and restart them when change is made to make the change effective in all environments (servers)

If running multiple AOSs and modified workflow (i-e a new workflow version is added), Must refresh cache in all other environments. You don't need to bring production environment down for that purpose and just login to all servers and refresh the cache (Tools > Cache > Refresh AOD, data, dictionary)

If you are using load balancing and you have written custom .net API which calls AIF services. The custom .Net API MUST be deployed on physical cluster and not the load balanced one. Otherwise, it won't be able to authenticate and you will get NTLM authentication error.