I have written code that is supposed to help us automate some specific cases. It will create a addresstag for the customer and change the status of the case to "Address Tag Sent".
All this works as intended, but for some reason the status of the case is changed back to "New".
As you can see here there is an event called "Activate" that changes the status.
I haven't found what this event is or why it occurs. I have gone through all the Workflows we got, all processes, all code (As good as I can) and spent a good amount of time trying to google it but I still come out empty handed.
Is there someone who might know what this event is? Or maybe got any idea how to access/modify it?
'Activate' will essentially re-activate any record and put the statuscode back to the default statuscode\status reason - I am guessing your default is set to 'New'.
I would investigate in these directions:
Since “changed by” showing as “CRM migration account”, this maybe an ETL job like SSIS, or Scribe which is syncing data changes from outside integration
Maybe the same service account is used by plugin, to reset the StateCode and StatusCode on some business logic
Is there some Business process flow stages available in your form, as I see “Service stage” attribute in audit before that, there may be logics coupled with that
Verify the dependencies of statecode attribute in customizations to see any SDK steps or workflows referencing that. Check in your code repos and check with any long timers in your project for any business logics implemented in the past.
Related
I am working on designing a lengthy approval system in CRM using a combination of OOB workflows (designed using CRM UI Workflow Designer) and custom actions (actions written using .NET code). Idea is to keep the entire branching/simpler logic in OOB workflow and call custom Actions wherever necessary. However I have few questions with this approach:
How can I handle run-time errors generated in the action code?
For example, one of my Actions contain the code to push data to an external system via web service. In case this web service call fails, I need to perform some steps in the parent workflow.
How can I handle 'if conditions' which can't be handled by 'Check Condition' step? For example, suppose that before performing a certain workflow step I need to check some data which can't be queried within CRM. I can create an Action which will return true/false based on the custom logic which can then be checked in parent workflow.
An alternate approach would be to use plugins but I am inclined towards using OOB functionalities as much as possible. Any inputs would be helpful.
First of all let's clear the semantics, because I'm not sure if you understand what are you talking about - there are Actions (you can refer to them as custom actions, but then you should refer to every workflow you create as custom and I figured out of your post that you are describing them as OOB, which also is semantically wrong - every workflow you create is a custom workflow, maybe it's using OOB steps, but that's a different story) and Custom Workflow Activities. I'm assuming that you want to use Custom Workflow Activities, because the are more suited for what you are trying to achieve here. Also you tagged your question as CRM 2011 and CRM 2013 - not sure what you meant, because Actions were not available for CRM 2011.
So basically Custom Workflow Activities can have Input and Output parameters. Output parameters are answer to both your questions, because you can use them to get the error message after your custom processing or use then in conditional statements later in your workflow. Output parameters can be defined like that:
[Output("Error message")]
public OutArgument<string> ErrorMessage { get; set; }
You can find more examples here:
https://technet.microsoft.com/en-us/library/gg327842.aspx
You can of course set this properties simply by calling
ErrorMessage.Set(executionContext, messageText)
So now when you define your workflow, wherever you need something not configurable in OOB blocks, you can put your Custom block, after it's done simply check it's output for the error (this is just an example, you can pimp it up by adding additional output parameters, to make it more generic), if it's empty then do something, if not then do something else for example send email with the error message. It all depends on what are you trying to achieve.
Actions are serving different purposes, they are useful to create a logic that can be easily called through plugin or javascript (webAPI) and allows you to also put a plugin on it alongside doing everything within one transaction. Maybe it will be useful somewhere in your workflow, but as far as I remember in CRM 2013 actions could not be called from a workflow...
UPDATE:
Ok so if we are dealing with CRM 2016, we can call Action from a workflow. What is best in this situation really depends on the scenario and what we are trying to achieve, but to make it easier to decide let me highlight main differences:
1) Activities are simply a blocks of code that can be put inside your workflow. Actions by themself are not code, they are custom Messages that you can call. Of course you can register a plugin on this custom Message and do there any custom logic you want, but this is another step to take
2) Actions can be run in transaction, Activities not (but you can run Activities inside Actions, so in this case they can run in transaction)
3) Actions can be called directly from Javascript, plugins and workflows. It's a great thing, but if you will make let's say 10 custom Actions which you will be using ONLY inside you one workflow, they will be visible when you will be registering plugins (and also any js developer will be able to call them with JS)
So basically Actions are a big, fat feature that can serve many purposes (including running Activities on their own!), Activities are much simpler but in your case they will also do their job. So you should ask yourself questions:
Do I need my logic to run inside transaction?
And
Do I need to call this logic somewhere else than my workflow?
If you have any "Yes" then go for Actions, of no, then go for Activities, because you will be overcomplicating things without any good reason.
I need to sync entities from Ms Dynamics Crm 2015 - On Premise to my 3rd party application, for this I have set a JavaScript function on the OnSave event of the Entites( eg. account) I can access all of the attributes and send them to my webservice, but the Id (GuId) of the entity!
how can I access the Id (or set it manually) on this event?!
Xrm.Page.getAttribute("accountid") or Xrm.Page.getAttribute("id") both return null, so I can not setValue using them.
Also Xrm.Page.data.entity.getId() returns "" which is probably logical, since Object has not been inserted in the db yet, this is the reason which makes inserting a runtime generated guid for the entety seems doable !
P.S.
I know I can do same thing with plugins, which I have gone through, but the problem there is that when I register my plugin for Update message it gets called a lot of times, (mostly when it has been set for invoice), this is the reason that made me go with the JScript, since the OnSave Event seems more logical than the Update Message of the plugin
As you already found out, records which have not yet been saved have no ID. That's by design (and obvious).
Also, IDs being PKs in the database, they are handled by the system and cannot be touched or hand-crafted.
Your best bet to keep a similar behavior would be a Post-Operation Create plugin living outside the sandbox (Isolation mode: None).
Another good option would be to pull data instead of pushing it: the 3rd party application can periodically fetch new records through any of the exposed APIs (REST, SOAP, SDK ... there are many options).
I have a simple plugin for a custom entity that is set to trigger on Update of my custom entity. It is registered in the Post Operation stage. I have noticed some strange behaviour when I make changes to the Owner field of the record in addition to other standard fields (e.g. text boxes, dates etc).
The plugin fires the first time and the only attributes that come across in the image are all the regular fields. The owner field does not come across.
The plugin then fires again, but the Depth property of the context is still only one (i.e. the plugin is not getting triggered by changes made in the plugin code). In this run of the plugin, the attribute that come across is only the Owner field.
My theory is that because the owner fields are 'special', the CRM is doing two different requests - one to change the regular fields, and then another request for changing the owner via an AssignRequest. However, I cannot find any 'official' documentation for this behaviour.
Can someone explain why this is happening?
I am running Dynamcs CRM 2013 UR2
The Update event fires during the Assign event. So if an assignment takes place your plug-in will execute. The same is true for SetState - if you activate/deactivate a record an Update event takes place. These items are not documented in the SDK.
A good practice is to use Attribute Filtering on your Update plugin so it only fires for the fields it is concerned about - this will, assuming it is isn't looking at the owner related fields, avoid it firing twice. If you have logic specific to record ownership you would put it in a plugin that is registered on the Assign event.
I was not able to find official documentation about this, but I think Assign message is what you are looking for (if the entity is user-owned. See http://msdn.microsoft.com/en-us/library/gg328576.aspx. I would strongly recommend that you specify Filtering Attributes if you are registering a plugin on Update message. You could also debug your plugin and inspect MessageName property of plugin context and see what message gets triggered. I hope this helps.
I understand that a plugin registered for pre-validation executes outside of the database transaction but I'm not sure I can think of a scenario when this would be preferable to pre-operation. Can someone give me an example of where pre-validation registration might be useful?
We have a few plugins registered on the 'PreValidation' event although this is on premise, not online.
I did not write these specific plugins myself but I can describe one and give the justification for using 'PreValidation' rather than 'PreOperation'.
Entity: Account
Event: Delete
Logic: Plugin runs pre validation. Checks that there are no contacts referencing any of the account's addresses. If any are found, stop execution. If not, delete account.
e.g.
Account 'Stackoverflow' has address 'Jeff Attwood's House' and Contact 'glosrob'. 'glosrob' is referencing 'Jeff Attwood's House' through a customisation. If a user selects to delete 'StackOverflow', we should detect 'glosrob' is referencing an address and prevent the delete.
The reasoning behind this was the developer found that at the PreOperation stage, some aspects of the delete had already happened, namely the cascade deletes. The logic of the plugin requires us to check all contacts - by registering at PreOperation, contacts under the account had already been deleted, rendering the check obsolete.
In our previous scenario, when the user selected to delete 'StackOverflow' Account, the Contact 'glosrob' would be deleted before the plugin runs. Therefore when the plugin did run afterwards, it would allow the delete.
As with most things in CRM, it all comes down to requirements and solutions, but I think that gives you an idea of why/when you might use a PreValidation stage. We have a few others with similar reasoning that run on the 'Delete' event.
I know its very old post, came here while digging for an answer for the same question...
Later I found one key point from MSDN on the same topic and i thought it would be helpful If I post the infromation over here for all..
The Prevalidation plugin would happen prior to the security checks. For ex: If an account is "VIP" account and you dont want this account record to be deleted (no matter even he is a super user/admin), then this better can happen in pre validation. Because at that time you are not really bothered about who the user is and what sort of permissions he has (even he may not have any permissions to delete any records in the system), CRM will go and check the database for the user's security roles during the pre operation and that is where the first database hit would happen.. before that it self, we can stop the exucution of the plugin based on our validation rules..
I hope that make sense...
Thank you
Regards
Srikanth
We're using CRM On-Demand for our Service Group and I'm running into an application limitation and am wondering if anyone has a workaround or just some general ideas on how to accomplish our goal.
In the application, our major focus is around the Service Request and driving for users to create Tasks for all Activities related to working towards closure. For example, a customer calls in and we need a technical resource to make a return call to diagnose the issue in detail, so a Task is assigned to that resource. Once that Task has been marked as completed, I'd like the Status to be updated. I tried creating a workflow using JoinFieldValue(), which wasn't working. I tried a more basic approach and tried to just have a field on the Service Request be populated with the Status of the Task, but that did not work either.
Upon further investigation in the Help File, there is a relationship from the Activity object to the Service Request object, but not one the other way.
So, has anyone else run into this limitation and found some other method to have a Status change on the Task update the Status of a Service Request?
(Also, I'd like to try and avoid writing a custom web service for this purpose, which is why I'm trying to use the tools in the app)
Thanks in advance for any ideas!
actually, if I well understood your issue is related on workflow cross object.
OCOD doesn't manage this type of workflow when you need to use workaround.
In order to cover a cross object worklflow you have many possibilities:
webservices as you said, but you could imagine a js code that will run WS and hosted directly into OCOD (in R19 you could hoste that in Client Side extension). That could be a good solution
Another one could be using Report with a custom look up functionnality with the usage of "Callback" function
I would prefer the 1st solution.