Showing posts with label solutions. Show all posts
Showing posts with label solutions. Show all posts

Tuesday, October 29, 2013

Filtering activities by type in CRM views

In some scenarios you might want to wish to filter your activity views by activity types. While it sounds very trivial it can be a bit more complex in the context of solutions because activity type is stored as objecttypecode (OTC) which is different in each environment for custom activities.



I defined a custom activity called “Follow-up” and I would like a view/sub-grid in the account form which shows me all the related Follow-ups to the account (I don’t want to see any other activity there). I also don’t want to create an additional relationship between Account and Follow-up but rather use the generic “Regarding” lookup that is used by all custom activities.


Solution #1

I can simply define or edit an existing view and use the field “Activity Type” (activitytypecode) to filter and show only the activity type that I desire:


After I do this I can use my view in a sub-grid and voila, very simple, I now have a sub-grid in the form which displays related activities but only those of type “Task” and “Follow-up”:



The problem with solution #1

The problem now is that when I transport this view and form to QA/Prod or to another CRM organization, it might break. The reason is that the view uses the activitytypecode field to filter on activity type. This field references an objecttypecode (OTC) which is a unique number given to each entity. For system entities (task, accounts, etc) the OTC is the same in all environments. However, for custom entities, new OTCs are assigned incrementally so there is no guarantee that they are consistent across environments. In my dev environment, this is what my view definition looks like in the exported solution:image

While I can be sure that 4212 is always “task” in all environments, I cannot be sure that 10007 is my custom activity “Follow-up'” in all environments. In fact, an entity with OTC 10007 might not even exist in other environments, even if my custom “Follow-up” entity does exist (but with a different OTC).


Solution #2

If I would like to avoid my solution referencing a hard-coded OTC, I can use linked-entity in my view as a work-around. However, I cannot edit the views in the view designer of the application because it does not support joins. I would need to export my solution and edit the view XML in the solution file and then import it back. I will update the XML of the view I defined above in order to retrieve all tasks and follow-ups but without using the activitytypecode attribute:


Note that there is no reference to any objecttypecode in the view definition above, but it will automatically filter to show only activities of type new_followup because of the inner join. In order to update the view XML you will need to include the Activity entity to a solution, export the solution and then look for your view in the customizations.xml file and update the view definition fetchxml.

The problem with solution #2

Although solution #2 will work in all environments and will not break even if you transport the solution to another organization (as long as the new_followup entity exists), there are some disadvantages of this approach: First, the view filter criteria cannot be edited using the application view designer (so you will always need to update the XML if changes are required). Second, this only works if you want to filter to display a single activity type. However, if your requirement is to filter the activities to show 2 or more activity types (e.g. Follow-ups and tasks) then you will not be able to do this solution and only then I’d recommend solution #3.


Solution #3

Thanks Jukka for suggesting this. Every activity has at least on activity party (at least the owner). Therefore, we can leverage the activity party relationship to display “all activities which have an activity party which has a parent activity of type X”. This is what the query would look like if I only want to display Follow-up activities for example:


The problem with solution #3

The only problem with this solution is that it only works if you want to display a single activity type. If for example you have multiple custom activities and you want a view to display only follow-up and task activities then this will not be possible. Note however that if you want to display only custom activities you can easily filter out the out-of-the-box activities using solution #1 with a filter of “Does Not Equal (task,appointment, etc).” and that will be fine to transport across organizations because OTC for out-of-the-box activities are always constant.


Solution #4

You might be disappointed but if you need to filter to display more than 1 activity type but not all activity types, and you are using custom activities in your filter, then the only other solution would be to stick to solution #1 (see above) and then create a tool that automatically remaps the objecttypecode in the views xml to replace it with the appropriate objecttypecode in the target environment. You could do so as a stand-alone tool or you can have a post-solution action which does this for you (using the solution configuration page web resource).

Tuesday, June 5, 2012

CRM 2011: Transporting System Settings with Solutions

When you export a solution you are given the option to include various system settings to be transported with your solution and take effect in the target environment. This post provides some insights into what these system settings are and provides a list of the settings that are transported with the solution.

Upon solution export you are presented with the following dialog for exporting organization system settings:

However, the list above does not correspond exactly to the tabs of the system settings dialog:
So for example, if you want to transport the Date format with your solution, which of the above settings should you include in the solution? Is it even possible to transport all system settings with the solution? The following screenshots of all the system settings specify which system settings are included in which section of the solution export settings, and which ones are not transported at all. Here are the possible settings you can include and I’m using a color code to identify them later on:


Note that the red rectangle means that those system settings cannot be transported with a solution. So here are all the different sections of the system settings mapped according to the color codes above:


Thanks to Jim Daly from Microsoft team for gathering this information and agreeing for me to share it publically. The behaviour might change with future versions or updates of CRM, but I have tested this with CRM 2011 UR6.

Monday, May 7, 2012

CRM 2011: Deleting Attributes, Entities, Relationships or OptionSets from Managed Solutions

Once you install a managed solution you are not allowed to delete any of its entities, attributes, relationships, reports and OptionSets. This post provides a simple and supported workaround if you absolutely need to delete one of these components from a deployed managed solution.

Working with managed solutions in production environments bring multiple advantages (see previous post on managed vs. unmanaged solutions), however, one of the disadvantages is that once you deploy a managed solution, you are no longer able to delete some of its components. A typical example is that you deploy a solution with a custom entity and you figure out that you must change the data type of an attribute. CRM in general will not allow you to change the data type of an attribute, you will need to delete the attribute and re-create it with the new type (even if you use unmanaged solutions); however if your managed solution is already deployed you cannot delete the attribute, so what do you do? I will offer 3 different alternatives I have used in the past:

1. Hide instead of delete. The easiest solution is to simply create the new attribute with the correct data type and completely hide the old attribute from all views, forms, reports, etc. In many cases, deleting an attribute in production is unacceptable because of data loss so this alternative is the safest and most conservative as you get to keep the old data. The disadvantage is that you will have useless columns in your database and the old attribute will continue to appear in Advanced Find.

2. Use a holding solution to delete any component from your deployed managed solution. This is my favourite approach as it has the advantage of completely deleting from the system the unwanted components without losing any data. This is how it works: Assume you have a solution XXX which contains a custom entity and one of the attributes is of type “Single Line of Text” but you want to change it to “Multiple Lines of Text”. In your target environment you should have solution XXX as managed and in your development environment you should have solution XXX as unmanaged.
  1. In your development environment create a new solution “XXX_holding”. The publisher must be the same as the publisher of your XXX solution.
  2. Add all the components of the XXX solution to your XXX_holding solution*.
  3. Export XXX_holding as managed.
  4. Import XXX_holding to your target environment.
  5. Delete XXX solution from your target environment. No data is lost because all the customizations remain in the holding solution.
  6. In your development environment delete the attribute (you will need to adjust views, forms, etc.).
  7. Export XXX as managed.
  8. Import XXX to your target environment
  9. Delete XXX_holding from your target environment. The attribute will now be deleted from all environments. There is no data loss except for the data that was saved in the old attribute which was deleted.
  10. Now that the attribute is deleted, if you want the attribute back but with a different data type you just need to re-create it in dev and promote the solution to your target environment.
* Note: You can avoid steps 1-3 if you simply open your XXX solution zip file and in the solution.xml file you update the solution unique name to “XXX_holding”. This way you guarantee that you have all the components of XXX also in XXX_holding.

3. Uninstall and re-install solution. If you absolutely need to wipe out the old attribute from the system, you could also uninstall the entire managed solution, make the appropriate changes in your development environment and then re-deploy a clean and correct version of your managed solution. The big disadvantage here is that you will lose your data if it relies on the customizations of your solution, which is usually unacceptable unless you have no data to retain or the data is not important.

4. Use unmanaged solutions instead of managed solutions. While it is true that with unmanaged solutions it is simpler to manually delete any component, it is also true that deploying unmanaged solutions to a production environment has multiple disadvantages and is not a good practice in my perspective. It might also be too late for you to switch to unmanaged solutions. You can read more on best practices around managed vs. unmanaged solutions here. There’s also an interesting white paper from Microsoft for building ISV solutions.

Some posts in the MSDN forums additionally suggest that Microsoft is aware of this limitation and might consider a better solution in the future. For the time being I have found the holding solution approach to work well, please let me know if you have other experiences or suggestions!

Monday, February 13, 2012

Duplicate Detection in CRM 2011

The Duplicate Detection feature has improved considerably since CRM 4.0 but it is often not given much attention. I would like to highlight in this post what has improved in Duplicate Detection, how to use it and what is still missing (areas of improvement for future releases).

Synchronous MatchCode Generation
MatchCodes allow the CRM platform to detect duplicates in the create/update operations. In CRM 4.0 the MatchCode generation was implemented asynchronously with a recurring system job which would generate the MatchCodes. The implication of that process is that if you create a record and then create a new duplicate record within a few seconds, the platform would not detect the duplicate because the MatchCode was not yet generated. This blog post talks about how to work around this limitation by making use of the PersistInSyncOptionalParameter; however, when creating/updating a record through the UI, the parameter was not enabled by default so you would need to write code to force the MatchCode generation in a synchronous manner. In CRM 2011 the PersistInSyncOptionalParameter (or CalculateMatchCodeSynchronously) parameters no longer apply because MatchCode generation is always done synchronously. What this means is that regardless of how fast you are creating one record after the other (and theoretically how many threads you have), the CRM platform will always be able to detect immediately if you are creating a duplicate. The fact that you can rely on the Duplicate Detection Engine to capture all your duplicates without having to consider any time variable is a huge relief in my opinion.

Different Way to Specify Whether to Run Duplicate Detection on Record Create/Update
Not much has changed here except perhaps the syntax. By default, when you execute a create or an update request against the CRM Web Service, the record will be created/updated without checking for duplicates. If you want to override this behaviour so that you force the platform to check for duplicates you would need to set the SuppressDuplicateDetection optional parameter to “false”. Not specifying this optional parameter has the same effect as if you would set it to “true” (bypasses duplicate detection):
CreateRequest req = new CreateRequest();
Account acc = new Account()
    Name = name,
req.Target = acc;
req.Parameters["SuppressDuplicateDetection"] = false;

catch (FaultException<OrganizationServiceFault> ex)
    if (ex.Detail.ErrorCode == -2147220685)
        // duplicate detected: Handle it here

Enhanced Duplicate Detection Processing (UR5+)
With the release of UR5, there have been some other improvements to Duplicate Detection:
  1. You can specify in a rule whether or not duplicate detection should consider two null (blank) values as identical
  2. You can select to detect duplicates only from active records, this can be useful to improve performance.
    What is Still Missing?
    In my opinion, the most fundamental feature that Duplicate Detection still lacks is the ability to package duplicate detection rules as part of a solution. It is quite painful to have to replicate the rules in all environments an having to do it directly in production can be scary, some rules are quite complex and error prone. I hope Microsoft has plans for improving their solution framework in the future to include “solutionizing” duplicate detection rules!

    Monday, February 6, 2012

    How to Prevent Broken Workflow References in CRM 2011

    You might have noticed a very annoying behaviour when you promote processes (workflows or dialogs) across environments and many references in the workflow definition get broken because of the differences in the environment.

    For example, assume you have a workflow that assigns an account to the Sales Team on certain conditions. Your assign step will look like this in your development environment:

    Now you include your workflow in a solution and promote to a Test (or any other) environment. Even if the target environment contains the same team with the same name, your workflow will now contain a broken reference and cannot be activated. In fact, if you try to automatically activate the workflow on solution import you will get the following error:

    This workflow has errors and cannot be published. Please remove the errors and try again.

    The reason why the reference is broken is because workflow keeps track of referenced records by GUID, not by name. So unless you have a team with the same GUID in both environments then the reference will be broken. Your workflow step would look like this after import:

    You can go ahead and fix the lookup and then activate the workflow, but here are some bad news of that manual approach:
    • Each time you import an update to the solution that contains the workflow you have to manually update the workflow again.
    • This can happen for teams, queues and many other records referenced in a workflow.
    • Trying to find the GUID in the workflow definition XAML is tedious and risky, there is no documented schema or process on how to do this.
    Ideally, I would like to see a way to add my “Sales Team” to the solution, so it will be automatically created in every environment and it will preserve its GUID across multiple environments. However, team records are unfortunately not solution aware. the workaround I have been using is to export the teams from the development environment and import to all the other environments (preserving the GUID). Once this is done, I can import the above workflow as many times as I need and the references will not be broken.

    To export the teams you need to go create a query that excludes all default teams:

    After executing the query, click the Export Teams button. Make sure to select the option to make data available for re-importing:

    Now here is the tricky part, you need to modify the Excel file to be able to import it to another environment. This is what you need to do:

    1. Save the file as CSV. Close and re-open the CSV file.
    2. Rename column A header to “Team”. If there is another column that already has a header called “Team” you should delete that other column and leave column A.
    3. Delete all other columns whose header starts by “(Do No Modify)”.
    4. If your Business Units don’t have the same name in all environments then you should also delete the “Business Unit” column. The teams will by default belong to the root Business Unit.
    5. Save.
    Now you just need to import the CSV file in each of your environments, this will create the teams with the same GUID as the source environment. You can re-use the same file for all environments, and you only need to this once per environment. During import you will need to map it to the “Team” entity, but all the fields should be automatically mapped. Now when you open back your “broken” workflow you will see that it is no longer broken! You can import the teams before or after you import the solution.

    One little nuisance I have found is that you cannot import the teams if your Sales Person role does not exist. This looks like a bug, but you should be fine unless you have deleted that role, in which case you’d need to bring it back, at least while you import the teams.

    Note that the broken references only occur when the workflow references entities which are not solution aware (teams, queues, etc.) but, it will not be a problem with solution aware entities (e.g. email templates) because you can include the record in the solution itself. Additionally in CRM 2011 there is a mechanism to prevent broken links to users and currencies, so even when you cannot include currencies and users in solutions, when importing a workflow that references these 2 records, the mapping will be done based on name instead of GUID so the references will resolve. For example if you have an “Assign” step that assigns an account to “Gonzalo Ruiz”, even if the user “Gonzalo Ruiz” exists in multiple environments with different GUID, it will still be automatically mapped. But all other entities are referenced by GUID.

    Monday, January 16, 2012

    Setting up your development environment for a CRM 2011 project

    Following a series of recent articles I have posted about solutions, I wanted to share some information about how you can set up an efficient development environment for your CRM 2011 project. Managing the solution synchronization among multiple environments (dev, test, prod, et.) is not always straight forward and it depends on multiple factors such as the scope of your project and the size of your team. In general, I have found an environment topology that facilitates an efficient development team and applies to most CRM projects:


    Note that in the table above, each of the “environments” are not necessarily separate servers. If you have a multi-tenant CRM server you could host one or more of these environments in the same box. the only caveat is that you need to make sure that an activity happening in one environment will not interfere with an activity in another environment. For example, all environments in which the developers need to debug on the server side should be separate box since you don’t want to block testers and Business Analysts due to the debugging session in one of the CRM organizations. Thus, as a minimum, the “Individual Development Boxes” should be separate CRM servers.
    Remember this is not applicable 100% all of the time exactly as shown, but it is a good start to define your development environment strategy.

    Monday, January 9, 2012

    Cannot delete components of managed solutions

    With the introduction of managed solutions in CRM 2011, I have noticed that it is common in the CRM community to perceive a sense of "danger" in managed solutions. While it is true that managed solutions can give you a lot of pain in some scenarios, it is also true that some of that pain can be avoided by understanding exactly what managed solutions are about, what are their limitations and dangers. I have challenged colleagues to explain to me why they prefer to not use managed solutions and I found out that in some cases it came down to a miss-use of the managed solution concept, in some other cases it was simply fear and lack of trust for new features while in other cases they pointed out a particular disadvantage of managed solutions.

    The one valid problem that most people find in managed solutions (which you don't have with unmanaged solutions) is the inability to delete solution components. Once you install a managed solution, you will never be able to delete the following components:
        • Entities
        • Attributes
        • Relationship
        • OptionSets
        • Reports
    So what should you do if you run into that situation? In my experience, most enterprises will anyway not allow the deletion of any production data and because deleting entities/attributes will delete all the related data, this scenario is usually not allowed by the business anyway. However, if you run into this scenario and you really need to delete those components from a managed solution then you have two options:

        1. Uninstall the managed solution: You can always remove the components from the originating unmanaged solution, then uninstall the managed solution and re-install the new version of the managed solution which does not contain the unwanted components. This option can be long and tedious and will certainly delete all your data related to the solution so it is usually unacceptable to do so.
        2. Hide the unwanted components: You can always hide the components so they become invisible to the end user. For example, you can remove the entities from the sitemap, remove attributes from forms and views and hide the reports. However, these components still exist and can be visible from Advanced Find. Additionally, you can revoke privileges to all users for the entities that you are hiding.
    I also hope Microsoft will in the near future remove this limitation. I would be interested to find out from other community peers if they have other specific scenarios for which managed solutions are a problem and help identify potential improvements that Microsoft should look at.

    Tuesday, January 3, 2012

    Managed or unmanaged solutions in CRM 2011: Best Practices

    When it comes to the solutions framework in CRM 2011 the question I get asked the most often is: “Should I use a managed or unmanaged solution?” and like all questions around best practices the answer is often “it depends”. The differences between the two are quite fundamental; however, there is still plenty of confusion in the community around this. A Microsoft colleague once gave a great analogy I would like to quote: Think of unmanaged solutions as source code and think of managed solutions as compiled, versioned and signed assemblies.

    Unmanaged solutions
    Similar to source code when writing a program, unmanaged solutions is your only choice during development: Every solution was once an unmanaged solution just like any binary was once source code. As long as your solution remains unmanaged, it is “open” (editable) so you can add/remove/edit components, update the publisher, the configuration and the managed properties of the solution. You will also be able to update the version of the solution and you will be able to export it. Additionally, if you are working on a multi-language solution, you can export and import the solution translation labels. Since CRM solutions now contain the translation labels in the same zip file, you should always import your labels into the unmanaged version of the solution; this way, each time you export the solution it will contain all the labels so you will not need to repeat the translation steps for every environment.
    Another typical use of unmanaged solutions is to work as an integration solution to which multiple developers or teams contribute with different components. However, once your solution is ready to go into UAT or production, the solution should be installed as managed because it will no longer need to be editable, this will allow a more rigorous release control because it will force all updates to be made in a development environment and then promoted to UAT/Production as opposed to making direct changes in production environments (a fundamental best practice in IT).

    Managed solutions
    These are similar to .net assemblies in the sense that you do not directly edit a managed solution; it is “closed” to development. Additionally, managed solutions provide a sort of read-only signature which includes the version and the publisher of the solution. You should always make use of a consistent publisher to uniquely identify you or your company as the entity that released the solution; there are also additional privileges granted to the solution when the publisher matches the publisher of an existing managed solution in the system and it works in a similar (but more primitive) way as strong name validation in .net assemblies.
    One of the advantages of leveraging managed solutions is the managed properties feature. Managed properties allow you to restrict changes in the solution by an unauthorized publisher. This is particularly useful if you have an undisciplined IT department that does not apply a thorough change management process when making changes to a solution. By making use of managed properties you can ensure that you (as the solution publisher) will remain in full control of the solution and prevent other from making breaking changes to your solution.
    Another great feature of managed solutions is that it is able to create layers of customizations. In the unmanaged model, all customizations are at the same layer, so making any customization will overwrite what is currently in the system. However, managed solutions have the capability to keep track of which customizations belong to which solution. To the end user, only the top layer (latest solution installed) is visible, but under that layer there can be multiple layers of customizations so you can build a solution on top of another solution without mixing up all the changes. You can think of this capability as using reference assemblies in .net. You can develop a solution by referencing an existing managed solution. The end result is that you will have two solutions (one depends on another) but there can be a clear distinction of which customizations belong to which solution. Solution layering also means that you can revert-back to a previous system state. If you uninstall a solution, all its components will be removed but the customizations from other solutions in a lower layer will surface back.

    To summarize, these are some of the reasons why I very much prefer to use managed solutions in all environments that are not development environments:
    • Solutions can be installed into multiple layers.
    • You can build solutions on top of other solutions (solution-level dependencies).
    • Additional change management control.
    • Option to turn on managed properties on solution components.
    • Capability to uninstall a solution and roll-back to a previous customization state.
    • Solution publisher can truly own solution components.
    The only disadvantage I have found so far with managed solutions is that certain solution components, such as entities, attributes and reports cannot be deleted directly once they are managed. In order to delete such components from managed solutions you need to follow a set of steps described here. Feel free to add your personal experiences to this post!