Showing posts with label All About Custom Actions. Show all posts
Showing posts with label All About Custom Actions. Show all posts

Sunday, 5 July 2015

Utilizing CRM Custom Action for Transaction Rollback Purposes

Introduction

In CRM 2013, we have a new feature, so-called Custom Action.

Well, I have posted about this feature long ago.


That time I was rarely using that because got problem in deploying the Custom Action which I believed has been fixed and now my colleague’s opening again my mind to re-consider using this feature.

Custom Action Features

Do you know that beside its great features such as:

1.  For replacing Configuration entity
2. Or even to validate something that need server side code which you are no longer need plugin again since its capacity to be called without triggering it by creating or changing field value like what plugin does,
3. Or to call this using javascript,
4. Plus even new amusing feature in CRM 2015 Update 1 to call it through Workflow,
5. Again, you can add more action as well as what workflow has been doing for you the whole time.

What I want to emphasize and spot in this post is its capability to do rollback.

Example or Scenario

Imagine, in daily transaction, in CRM, you have Header and Detail, Parent and Child, and Main and Line Item, Transaction and Transaction Detail.

Then also for major impact transactions, such as Bank Account, posting to Finance, Order and Order Detail, you need to secure that all of records must be done properly and 100% success rate, otherwise fail it! You cannot deliver an Order to customer if not all the details were created successfully and also very common situation you need to flag a record that you have updated in other entity, you need to make sure both are success, you cannot just in halfway, success in one transaction while fail to another, you need BOTH of them SUCCESS and EITHER one is FAIL, ALL must be stated FAIL and roll it back as the original one. This table is very important because it is Financial record, a –finance-related means A Money related, so both must be in sync, one fail, both must fail.

Well, CRM also gives good example in term of reciprocal and must done transaction, that is fund transferring:

“The classic example is transferring funds between two bank accounts. If you withdraw funds from one account you must deposit them in the other. If either fails, both must fail.”

The Research and The Implementation

I think what you all are waiting for is the real example in term of coding or implementation

Now, let’s say I have two entities, Entity A and B.

If Entity A is fail created and I need to make sure B also fail and vice versa.

I have 5 Entity A records and 5 Entity B records.
1 of them is failed then I must fail them.

*All of the example is within the CRM DB Context, not other system (external) involved that can be rolled-back, okay.

Standard CRM Transaction CRUD Request

There is no rollback for this standard CRUD Request because it’s processing one by one record.

Execute Multiple Request CRM

Well, now let’s move little bit to more advance, what will happen if we use the Execute Multiple Request, will it be rolled-back?

The answer is no..It will stop you to the next action if you use the skip or ignore error parameter to No, but in fact, it does not roll back the previous made transaction.

Custom Action

This is what I want to emphasize.
Assuming, I have this Action:

image

*For creating an action you can refer to my blog posts or other good example through the internet and good explanation from Power Object:

Then, inside the Custom Action code, I have the Create Record like I did in the Code-1 but I put in the CRM Action by parsing the EntityCollection as input

image

*Inside the collapsed region:

image

This one if you enable, means “no error” so that it won’t enable roll-ed back because assuming this action never throw an error, so you might need to re-think when you implement this.

For roll-back purposes, do not catch error for each single transaction.

You can do that in lump sum then just throw it all!

Okay, now, so what happened to my record after I trigger this action through executing it programmatically?

Well, it throw me error and there is no record at all!

*First entity
image

*Second Entity

image

*Well, as we can see here is, one fail, make the others also fail.

Other Research

Now, to make it lively, I increase the number of record to 800.
Then I make the failure in 789th row.
image
See what happened when I keep refreshing… then in fact I failed in almost the last row.
*First Refresh
image
*as you can see we have 130 records here
Then..
keep refreshing
*Second Refresh…
image

208 records here..

*Third time..

image

667 records here..

And until my code was stopped..

image

Yeah, it does stop in the record no 789.

And now..

I try to refresh again the advanced find..

And guess what…

All records….It’s gone..

image

So, it has the concept, once one is failed, then the other must failed as well!

What if I disable the Roll-Back

To ensure my curiosity and my doubt about the rollback function (well even for such example I still have doubt little bit but annoying) then I try to disable the rollback checkbox to ensure this usage.
image
And here is the result when I turn it off.
image

*As you can see here is the record is created anyway, no rollback same as what CRM Normal CRUD or Execute Multiple did before.

This does stop the transaction, but not rollback the previous committed transaction, so it proves the concept of rollback that Custom Action has.

So, hopefully this article is not so long for you to read and you can get advantage by reading it.

I intend to document it because in case I forgot it will become our e-memory and to encourage anyone to keep using this feature for your important couple of transactions that needs rollback each other.

Thanks and have a nice day!

Tuesday, 13 May 2014

CRM 2013 Custom Action as Next Action

As we know that Custom Action gives you a special capability to extend xRM Platform and it gives a great future.

At My Previous Post I was talking about Custom Action as Validation Gate and many of my posts are related to Custom Action.

Now, I would like to show you about Custom Action that not only as validation, but also can give you a new idea to do next action.

Now, start with my previous custom action, but I will not only use that for giving this Business Error :

image

I would like to put 5600 to fill one of my field value in Quote :

image

Because actually, I already did pass the Quote entity to my Custom Action, remember this snippet :

image

Actually, there are two possibility ways to do :

1. Getting an Output, still getting an output from the custom action then in my plugin I set my Revenue field value based on the output from my custom action, rather than I just throwing an error, which is I get that 5600.0

2. I use my custom action to update my Revenue field.

This is what I did is using the number 2, because I want my plugin is only calling my custom action and all of the logic will be done by my custom action, my plugin no need to do anything anymore since this custom action will be called by anywhere, for example if I have an calculator apps in my web or my agent desktop app, etc.

Then, I modify my code in Action Code :

public class Action_SimpleCalculation : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            #region must to have

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            // Create service with context of current user
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            //create linq context
            KonicaBaseContext baseContext = new KonicaBaseContext(service);

            //create tracing service
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            #endregion

            //To get access to the image of the Quote record
            EntityReference entityRef = context.InputParameters["Target"] as EntityReference;
            
            //To read the input parameter
            Money money1 = context.InputParameters["Money1"] as Money;
            Money money2 = context.InputParameters["Money2"] as Money;

            //Capture Discount Rate
            decimal discount = 0;
            discount = (decimal) context.InputParameters["Discount"];

            //Now, I am talking about Custom Action as Validation Gate
            if(discount >= 100)
            {
                throw new InvalidPluginExecutionException("Hi, are you crazy to give such discount? We will not gain any profit, do you realize that?!");
            }

            else{
                //This is how the calculation works and custom action as a Calculation Formula
                Money sum = new Money(money1.Value + money2.Value);
                Money sumafterDiscount = new Money();
                sumafterDiscount = new Money(sum.Value - ((sum.Value) * (discount / 100)));

                //using this as a response output
                context.OutputParameters["MoneySum"] = sumafterDiscount;

                //rather than only giving me an output, I would like to call next action, that is update the revenue field in my quot
                //I already have my quote Id

                Quote myQuote = new Quote();
                myQuote.Id = entityRef.Id;
                myQuote.tfp_Revenue = sumafterDiscount;
                service.Update(myQuote);
           }
        }
    }

Then in my Plugin I just call my Action

//create target entity as early bound
                    Quote TargetEntity = entity.ToEntity<Quote>();

                    //call Business Layer
                    QuoteBL quoteBL = new QuoteBL();
                    
                    //Money moneySum = quoteBL.ExecuteCustomAction_SimpleCalculation(service, new Money(2000), new Money(5000), TargetEntity.Id) ;
                    //throw new InvalidPluginExecutionException("Hi, your total Amount will be = " + moneySum.Value.ToString());

                    //this one to prevent infinite loop, because custom action will update the revenue
                    if (TargetEntity.tfp_Revenue != null)
                    {
                        return;
                    }

                    //just call my custom action
                    quoteBL.ExecuteCustomAction_SimpleCalculation(service, new Money(2000), new Money(5000), TargetEntity.Id);

I don’t call the “throw new InvalidPluginExecutionException” anymore, but I call my Custom Action, instead.

After you saved to trigger plugin and custom action, you can test it and here is your expected result :

image

Hope it helps!

CRM 2013 Custom Action as Validation Gate

In My Previous Post I was talking about Custom Action in Microsoft Dynamics CRM 2013 as Custom Message and also I give example about utilizing Custom Action as Calculation Formula.

Now, I will still using the same Custom Action as Example, but I will add some logic to make it as Validation Gate.

Imagine that you have several application that need connect to your CRM and do the same calculation, then you have to copy paste your custom code to all of the apps and do the validation.

Let’s go to the example with still using same custom action but adding some sauce : Discount

image

Then, I amend my code to give some validation :
public class Action_SimpleCalculation : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            #region must to have

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            // Create service with context of current user
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            //create linq context
            KonicaBaseContext baseContext = new KonicaBaseContext(service);

            //create tracing service
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            #endregion

            //To get access to the image of the Quote record
            EntityReference entityRef = context.InputParameters["Target"] as EntityReference;
            
            //To read the input parameter
            Money money1 = context.InputParameters["Money1"] as Money;
            Money money2 = context.InputParameters["Money2"] as Money;

            //Capture Discount Rate
            decimal discount = 0;
            discount = (decimal) context.InputParameters["Discount"];

            //Now, I am talking about Custom Action as Validation Gate
            if(discount >= 100)
            {
                throw new InvalidPluginExecutionException("Hi, are you crazy to give such discount? We will not gain any profit, do you realize that?!");
            }

            else{
                //This is how the calculation works and custom action as a Calculation Formula
                Money sum = new Money(money1.Value + money2.Value);
                Money sumafterDiscount = new Money();
                sumafterDiscount = new Money(sum.Value - ((sum.Value) * (discount / 100)));

                //using this as a response output
                context.OutputParameters["MoneySum"] = sumafterDiscount;
            }
        }
    }

Then, I also add parameter to call this action :
#region custom action execution

        //EARLY BOUND
        public Money ExecuteCustomAction_SimpleCalculation(IOrganizationService service, Money money1Param, Money money2Param, Guid quoteId)
        {
            tfp_Action_SimpleCalculationRequest request = new tfp_Action_SimpleCalculationRequest()
            {
                Money1 = money1Param,
                Money2 = money2Param,
                Target = new EntityReference("quote", quoteId),
                //new parameter
                Discount = 120
            };

            tfp_Action_SimpleCalculationResponse response = service.Execute(request) as tfp_Action_SimpleCalculationResponse;
            //Processing of response
            return response.MoneySum;
        }
        #endregion



Update your Plugin Assembly then see the result.

And yeah, this is the result

image

Now, change the discount again to less than 100.

image

Then Update your plugin.

Here is the result :

image

Hope it helps!
Thank you.

CRM 2013 Register Custom Action as an Advance Custom Message

Action in CRM 2013 is a great feature.
In my previous posts, I have talked about Action :

All about Custom Action

Then I also have many example to utilize Action to cater my idea extending xRM Platform.
Now, I am explaining Custom Action as Custom Message that enable for developer to Register as a Step in Plugin Registration Tool!

This is very useful when you want to do integration or calling a server side complex business logic, for example Calculation and Validation.

But, there is a doubt that in Steps, you can only do simple thing, nothing to do? Then, how?
These standard steps of CRM 2013 Action are very limited and nothing much different with other Workflow.

image

If you think that Available Steps in Action is not be able to accommodate what you want, then? Then, Customize it, do advance customization on it.

Now, first let me guide you. I give you example how to extend Custom Action as Custom Message, I don’t want to give a complex sample now, just give you a concept to understand.

I give you sample how to do calculation with Formula : Money1 + Money2 = MoneySum.

Two input arguments : Money 1 and Money 2
One outpur argument : Money Sum

1. Create an Action (You can refer to my above links, and also from that link you can see any links to talk about Action in CRM 2013)

Create your own Message : SimpleCalculation, for example (and give some prefix to indicate it)
(Remember, this is will be your custom message, a verb, a message, that you will use as your universal code contract to be registered to be used by any custom code, just make sure you give them a proper name).
Define your argument as well


image

2. Why no steps?

I want to let you know that you also can create your logic instead using those standard steps.

3. Activate it.

4. Generate an Early Bound Class to get your action in your class library

Please refer to this article :

Generate Custom Action as Early Bound

You also can use Early Bound and Late Bound, but for easier way, I use Early Bound as a sample.

5. Create a Plugin Class and put this code :

public class Action_SimpleCalculation : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            #region must to have

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            // Create service with context of current user
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            //create linq context
            KonicaBaseContext baseContext = new KonicaBaseContext(service);

            //create tracing service
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            #endregion

            //To get access to the image of the Quote record
            EntityReference entityRef = context.InputParameters["Target"] as EntityReference;
            
            //To read the input parameter
            Money money1 = context.InputParameters["Money1"] as Money;
            Money money2 = context.InputParameters["Money2"] as Money;

            Money sum = new Money(money1.Value + money2.Value);

            //using this as a response output
            context.OutputParameters["MoneySum"] = sum;
        }
    }

6. Register Your Class as Plugin using Plugin Registration Tool
(You might have to refresh your Plugin Registration Tool until you can see your Action as Message)

image

Register your step :

image

7. Call your Action from your Code

image

8. Pass to your Execution Code your own parameter

image

For example : 2000 and 5000, and pass your Quote Id as Target Entity (if you have this specific entity when you create your Action)

Then, your Total Amount will be : 7000 from 2000 + 5000
Throw an error message for capturing your Total Amount.

Let’s test it, run your code!

9. Test your code by triggering your custom code (In this case I call my Action after my Quote updated)

Here is the result :

image

Here, I don’t put any logic in my Plugin, I just using one single point, that is Custom Action.

Next time, my logic has been changed, I don’t need to change my plugin logic or any custom code about my calculation, because I only implement my code in this Action.

Hope it is informative for you!

CRM 2013 Error : Workflow associated with this custom operation is not activated

When you are triggering a plugin that call a Custom Action, you might have this error :
“Workflow associated with this custom operation is not activated”

image

Resolution :
Go back to your Custom Action and Activate it.

CRM 2013 Utilize Custom Action as Dynamics Error Message

Many times during my project development and implementation, I have requirement to Alert user if they have to input some field, those some fields sometimes is not mandatory during the Form, but it is mandatory for our Logic.

For example, in the Account entity creation or update.

- In Contact entity, City is not mandatory for some accounts type.

- If Contact Role is an Influencer, then their address will be very important to you, including City, State, and Country to complete your Addresses.

- If Contact Role is an Owner, then same as well, their complete address will be mandatory.

- If Contact Roles is not an Influencer nor an Owner then, Address fields will be only Optional or Recommendation.

So, you cannot make the Address fields as Mandatory for all of Situation, yes, you can achieve this by using JS or Business Rules, but remember that if you Form script, then let’s say user do inserting using backend such as other application or using excel import wizard, then you are forced to use Plugin to validate. Lets say you have to implement this in Lead, Account, and Contact, then this is applied to Create and Update Messages, right.

So, what possible situation is by creating a plugin that calls this :

image_thumb1

And I put them to all of my coding.
That’s fine, yes that’s Okay, and it worked.

Then what happened if my user said : Hi, I don’t want to use that messages.
Often, developer use their own way and words to spread an alert, that is not acceptable by some business users because this is till blur and unclear.

So, let’s say first you say : “Please input ‘blabla’ Value!!”, then user said, please change to : “‘blabla’ Value Cannot be Blank”, then change again to more polite command : “Hi Sir/Madam, Please don’t forget to fill the ‘blabla’ Value. Thanks”, then what will you do?

Okay, you have to change all of your Code, it is fine since you just copy paste, but you have various word for ‘blabla’ right? It can be City, State, Country, Fax, Mobile Phone, Membership ID, or whatever you have. So, yes, this is sometimes annoying.

Then, what I did in CRM 2011 is I create an entity, similar to Configuration entity to store my own Error Messages

Key Name
Key Value
Parameter Type
Description
CityBlank
Please input ‘City’ Value
Error Message
Error message if City Blank
StateBlank
Please input ‘State Value
Error Message
Error message if State Blank
CountryBlank
Please input ‘Country Value
Error Message
Error message if Country Blank

Imagine you have many fields, then you have to change all of the Key Value.
It is okay, maybe you can utilize the string.format Message to make the City, State, Country, etc as dynamic value.

But, do you know that in CRM 2013, you can utilize custom action to make your own Error Message more dynamic? This is the more elegant idea to work with Action to get some dynamic Error Message.
If you have known familiar with Action, please refer to this link :

http://aileengusni.blogspot.com/2014/05/crm-2013-let-me-introduce-nice-new_2810.html
http://aileengusni.blogspot.com/2014/05/crm-2013-custom-action-as-configuration.html

Here are the steps :

1. Create an Action

Create-custom-action1_thumb2

2. Define your Arguments

Input : FieldName – String – Required – Input
Output : MessageOutput – String – Required – Output

Define Argument custom action 2_thumb

3. Define your Steps by Assigning the Value

Set-Message-Output-3_thumb2

In this step, using your Input Argument you can create a Dynamic Output, using that FieldName input argument as dynamic value, based on what you pass as input.

4. After define your arguments and Activate your Custom Action

Activate-CA-4_thumb4

5. Using .NET in Plugin you can call your Custom Action

Early Bound

coding-to-call2_thumb3

Late Bound
Call-custom-action-late-bound_thumb3

Call that action in your Plugin
coding-to-call1_thumb2

Here is the code
//EARLY BOUND
        public string ExecuteCustomAction_PleaseInputValue(IOrganizationService service, string strFieldName)
        {
            tfp_Action_PleaseInputValueRequest request = new tfp_Action_PleaseInputValueRequest()
            {
                FieldName = strFieldName
            };

            tfp_Action_PleaseInputValueResponse response = service.Execute(request) as tfp_Action_PleaseInputValueResponse;
            //Processing of response
            return response.MessageOutput;
        }

 //LATE BOUND
        public string ExecuteCustomAction_PleaseInputValue(IOrganizationService service, string strInputParameter, string strInputParameterValue, string strOutputParameter)
        {
            OrganizationRequest req = new OrganizationRequest("tfp_Action_PleaseInputValue");
                    req[strInputParameter] = strInputParameterValue;
                    //execute the request
                    OrganizationResponse response = service.Execute(req);
            return response[strOutputParameter].ToString();
        }

For Reference :

http://a33ik.blogspot.co.il/2013/10/custom-actions-walkthrough-for-net-and.html

To generate Action in Early Bound Class :

http://aileengusni.blogspot.com/2014/05/crm-2013-generate-custom-action-as.html

6. Here is your result

When City is Blank

Business-Process-output-5_thumb4

7. Here if you want to change your Error Message, just change it :

- Go back to your Action
- Deactivate first

image_thumb[1]

- Change the steps

image_thumb[3]

8. Here is your result

image_thumb[6]

Enjoy it!

For your information, for importing Action it can be a big deal in CRM 2013, at least until Rollup 2
Please refer to this :

http://aileengusni.blogspot.com/2014/05/crm-2011crm-2013-import-solution-error.html

Hope it helps!

CRM 2013 Generate Custom Action as Early Bound

I really love to use Custom Action, it opens my mind to extend xRM Platform capability and make my job for Integration and Dynamic job easier.

I can use Action for Integration Message make it as single verb and key integration single point, and also can utilize this to combine my logic and show error message.

Because of that, I think I have to include custom action to my custom development, and sometimes, Early Bound is making my life easier.

Here is the steps you to generate Custom Actions as your Early Bound class library.

1. Download CRM 2013 SDK
2. Using CrmSvcUtil.exe

Generate Early Bound Custom Action

3. Define your own Server URL and Output file (location and namespace).

Don’t forget to add this parameter :

/generateActions

4. Here is my complete commands as example :

CrmSvcUtil.exe /url:"http://aileengusnidev:5555/contoso/XRMServices/2011/Organization.svc" /out:"../Crosscutting/BaseContext.cs" /domain:mycrmdev /username:administrator /password:mypassword /serviceContextName:"BaseContext" /namespace:TFP.Xrm.Contoso /generateActions


Remember you can save this as .bat file, so every time you need it, just run it!

For smart way, you can refer to this link : http://missdynamicscrm.blogspot.com/2014/05/crm-sdk-smart-way-to-use-crmsvcutilexe.html

Monday, 12 May 2014

CRM 2013 Custom Action as Configuration Entity Replacement

In My Previous Post, I talked about Action in overview. It has great potential and power to extend your xRM Platform. Now, I want to share my experience to use Action to replace a Configuration Entity.

Many thing you can do with Action, this website gives a good example :
http://blog.sonomapartners.com/2013/11/crm-2013-custom-actions-the-end-of-configuration-entities.html

It gives me a good idea and inspiration.

And here is my example :

1. Create a New Process with Type = Action, make it as Global if you have not decided what specific entity you will use.

image

2. Add Input Arguments, in my case : I have 1 input and 1 Output

image

3. Go to step and make a condition as you did before, to create Workflow

image

4. Then after checking condition, create an action message, in this case I put Assign Value.

image

5. Here is the place to assign your value

image

6. Repeat the same steps for SAP as well

image[22]


7. Here is your complete Action
image

8. Using .NET or Javascript you can call this action, remember Custom Action only be triggered by a Code.
This is a good reference :

http://a33ik.blogspot.co.il/2013/10/custom-actions-walkthrough-for-net-and.html

This is like a ‘Code Contract’ that only developers (CRM and Other Party Developer that will use it) to accept desire inputs to result an output, and it is single manageable, that is inside that Action itself.

You can manage your logic here, another application who wants to connect and call this action will only need to give input what do you want and give the output, otherwise, they will be failed to call this action, because you also can do validation inside your Custom Action, I will give you another example later.

But, if you have requirement that User can change it easily and very often, then my recommendation is you are suggested to still use Configuration Entity, since it is easy to be managed and can be managed using Import Wizard (Excel functionality) and no need to do activation then do deactivation again.
My example is for configuration that is not in high frequency changing rate.

Hope this post can give you another inspiration!
Thank you.

CRM 2013 Let Me Introduce a Nice New Feature : Custom Actions

CRM 2013 is not merely about UI Refreshment. It’s also coming with new great features.
In this post, I would like to you know about one of the great features : CUSTOM ACTIONS.

Overview

Action in CRM 2013 is definitely a process that allows a non developer user to create it and add some logic same as well as Workflow, but Action is only be able to be called or triggered by a custom code, it can be client or server code, meaning that Javascript and C# can call Action.

So, we can combine logic from developer and non-developer to implement a business logic using Action. Actions can be defined for an entity, but Actions also can support for Global entity, meaning that not merely tied to a specific entity. Actions can be used to several CRM messages, such as CRUD, Assign, Set State, etc. It enables solution architect to extend and explore the xRM platform.

Here are some posts that can help you to understand Custom Action and how to setup this.
Specification

1. Action can be used to Global entity and a specific entity.
2. Custom Action can help you to extend xRM Platform
3. Custom Action can be triggered using Javascript or C#, or another language using CRM API, such as SOAP or REST methods.
4. Custom Action need to be activated first and can be edited later
5. Custom Action can be used to set static and dynamic field value
6. The most interesting thing is Custom Action can be used as Custom Message or Event Handle and can be registered by using Plugin Registration Tool! It means that you can extend xRM and do anything using this new custom message.
Such as : onSubmittedApproval Message, onCalculatedField, or whatever you want.
7. Do you know that you also can use Action to receive some input, do validation, and then manipulate the output? For example, for Approval Process needs validation and formula calculation.

Why We Should Use Action and When?

You can use Action anywhere and anytime. Wherever and whenever you need it since both client and server code supports this calling.

What scenario or business idea you can achieve using custom Action?

1. Say partial good-bye to Custom Entity that so-called as Configuration Entity

Last time using CRM 4 or CRM 2011, I remember I always use Configuration Entity or Configurable Parameter to store some information that can be called by third party application, such as Console or Web App or event Web Part from SharePoint that we can develop. Or for outside application, I can use web.config or app.config with encryption, etc.

For example : to store server URL, username and password, additional settings, such as : maximum permitted credit card account for each Customer, maximum Membership card for each Member, minimum monthly fee for rental as commitment, enable for approval checkin (yes/no) then if Yes, do something, if No then stops it, due date for submitting an activity for each month, etc. There are real condition that we often face and we cannot do hard-coding, right.

Let’s say after an Order created, then pass the information to Navision (integration to Navision), then we have to detect in the Plugin onCreate, pass information to which Navision Server? Then what we do is by reading a custom entity so-called Configuration. It’s fine to use this conventional way, but don’t forget to make validation as well, cannot have more than one record to store Navision Server URL, don’t want to make system being confused.

Now, you can achieve this.

2. To show a Custom Error Messages

Many times, we have plugin and we should show a error messages, for example : “Please input ‘City’ value! or ‘City’ cannot be blank!

Then, what we do often is do hard-code in the Plugin or again, using the first method, reading Configuration entity that store some error messages.

Imagine, you have many plugins and you have to reading that entity and imagine that you have to change your words later. For example, now the message is “Please input ‘City’ value!, then later your customer says I don’t want to use that statement, I want a more polite word : “Sir/Madam, please fill the ‘City’ value. The developers statement for some errors can be different from what customer want, and what happened if you hard-code it.

3. Custom action as Custom Message

Several times, I was being forced to trigger a plugin using JavaScript by creating a dummy record to fix a complex business flow requiring a complex code. Custom action can be used as custom action and you can register your action same as well you register your Plugin Message.

4. Custom action to solve complex Business Requirement

I often have requirement that should be easier if I code it using server code, for example : Calculation, Approval, Third Party Integration, such as SMS, Product Configuration, the want they I can do is I have to write a custom code of workflow activity, a custom web service, a batch scheduler job, or trigger a plugin.

Using action, based on point number #3, since Custom action can be used as custom message, then we can use Custom Action to implement our complex logic and it is easy to call custom action. To know more about this, I promise I will give you example on my next posts.

5. Custom action is a single point of integration.

Can you imagine if you are trying to do integration for other system, both inbound or outbound that you should write many custom code.

For example, if you want to pass information from your website to CRM, then you can do either you write code in your website code call CRM API, or you use web service, let’s say you are trying to have a business logic for creating a lead from several websites and POS System, and as well you can create directly using CRM Import Wizard. How many point of gate you have?

Imagine, you have 3 websites (one for case support and enquiry, one is forum discussion, one is public official website), 2 Desktop Apps (one is for Agent at a branch and one is you put at kiosk), and 1 Console Job Application (for retrieving data every day collecting Social Media interaction), then you have at least 6 gates from your another application that customer wants you to let them generating lead or contact from all of six apps.

Then what you is you can implement your code of all of your 6 apps, imagine you have 6 apps but all of them having one purpose and having a lot of Input Arguments that should be same, then you have to do 6 times, implement your code, or smart way is you can use a web service to be called by them. Instead using web service, you can using Action (refer to point number #2, you can use Custom Action as Custom Message).
Let’s say other example, you have a Quotation that you should let the salesperson to input : Total Amount, Tenure, Interest Rate, and Discount Rate to calculate Net Monthly Rental. For CRM apps, every time you create quotation or every changes of those 4 fields, you have to re-calculate again, so meaning that you have to create a plugin onCreate and onUpdate then you have to implement the code for two of them.

Then, your customer also have another web apps, mobile apps, and a desktop apps to calculate Net Monthly Rental using same Formula and Same Inputs as well to get one Output, that is Net Monthly Rental.

Imagine, you have to write code and put into all of them, including two plugins and 3 apps, yes you can copy paste, but later let’s say your formula has been changed, now your monthly rental is not only about Total Amount plus interest divide by tenure, but your salesperson also can quote a committed amount, for example additional installment 1% of Total Amount if the Monthly Rental is less than USD 10,000, etc.

Then, you have to re-develop again your logic in every part you put in, 2 plugins and 3 apps at least. In this scenario, actually you can using custom action to put your calculation logic inside then all of your apps can call this action, including using Javascript or Server Code. You just input arguments and get the output. The arguments will be the input and be used for calculation inside the custom action logic to get the output as a result.

Okay, I think better if we got an example, please refer to my next posts.

Note

During import a solution that containing a Custom Action, you might be facing an error : Workflow with Id {Guid} does not exist.

To avoid that error, please refer to use this blog link to guide you :

Hope it helps!